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,120 @@
1
+ """
2
+ 部署 Provider 注册表
3
+
4
+ 使用装饰器模式自动注册 Provider,支持动态扩展。
5
+ """
6
+
7
+ from typing import Dict, Type, List, Optional
8
+ from ksadk.deployment.base import BaseDeployProvider
9
+
10
+
11
+ class DeployProviderRegistry:
12
+ """Provider 注册表
13
+
14
+ 使用方式:
15
+ @DeployProviderRegistry.register("my-provider")
16
+ class MyProvider(BaseDeployProvider):
17
+ ...
18
+ """
19
+
20
+ _providers: Dict[str, Type[BaseDeployProvider]] = {}
21
+ _instances: Dict[str, BaseDeployProvider] = {}
22
+
23
+ @classmethod
24
+ def register(cls, name: str):
25
+ """装饰器: 注册 Provider
26
+
27
+ Args:
28
+ name: Provider 名称 (如 "serverless", "k8s", "docker")
29
+ """
30
+ def decorator(provider_class: Type[BaseDeployProvider]):
31
+ if not issubclass(provider_class, BaseDeployProvider):
32
+ raise TypeError(f"{provider_class} must inherit from BaseDeployProvider")
33
+
34
+ provider_class.name = name
35
+ cls._providers[name] = provider_class
36
+ return provider_class
37
+
38
+ return decorator
39
+
40
+ @classmethod
41
+ def get(cls, name: str, config: Dict = None) -> BaseDeployProvider:
42
+ """获取 Provider 实例
43
+
44
+ Args:
45
+ name: Provider 名称
46
+ config: Provider 配置
47
+
48
+ Returns:
49
+ Provider 实例
50
+ """
51
+ if name not in cls._providers:
52
+ available = ", ".join(cls._providers.keys())
53
+ raise ValueError(f"Unknown provider: {name}. Available: {available}")
54
+
55
+ # 缓存实例 (相同 name 返回相同实例)
56
+ cache_key = f"{name}:{hash(str(config))}"
57
+ if cache_key not in cls._instances:
58
+ cls._instances[cache_key] = cls._providers[name](config)
59
+
60
+ return cls._instances[cache_key]
61
+
62
+ @classmethod
63
+ def get_class(cls, name: str) -> Type[BaseDeployProvider]:
64
+ """获取 Provider 类 (不实例化)
65
+
66
+ Args:
67
+ name: Provider 名称
68
+
69
+ Returns:
70
+ Provider 类
71
+ """
72
+ if name not in cls._providers:
73
+ raise ValueError(f"Unknown provider: {name}")
74
+ return cls._providers[name]
75
+
76
+ @classmethod
77
+ def list_providers(cls) -> List[str]:
78
+ """列出所有已注册的 Provider 名称
79
+
80
+ Returns:
81
+ Provider 名称列表
82
+ """
83
+ return list(cls._providers.keys())
84
+
85
+ @classmethod
86
+ def get_provider_info(cls) -> List[Dict]:
87
+ """获取所有 Provider 的详细信息
88
+
89
+ Returns:
90
+ Provider 信息列表
91
+ """
92
+ result = []
93
+ for name, provider_class in cls._providers.items():
94
+ result.append({
95
+ "name": name,
96
+ "display_name": getattr(provider_class, "display_name", name),
97
+ "description": getattr(provider_class, "description", ""),
98
+ "supports_streaming": getattr(provider_class, "supports_streaming", False),
99
+ "supports_scaling": getattr(provider_class, "supports_scaling", False),
100
+ "requires_image_registry": getattr(provider_class, "requires_image_registry", False),
101
+ })
102
+ return result
103
+
104
+ @classmethod
105
+ def has_provider(cls, name: str) -> bool:
106
+ """检查 Provider 是否存在
107
+
108
+ Args:
109
+ name: Provider 名称
110
+
111
+ Returns:
112
+ 是否存在
113
+ """
114
+ return name in cls._providers
115
+
116
+ @classmethod
117
+ def clear(cls):
118
+ """清空注册表 (主要用于测试)"""
119
+ cls._providers.clear()
120
+ cls._instances.clear()
@@ -0,0 +1,78 @@
1
+ """
2
+ 部署状态管理
3
+
4
+ 用于管理本地 .agentengine.state 文件,记录已部署的 Agent/MCP 信息。
5
+ """
6
+
7
+ import yaml
8
+ from pathlib import Path
9
+ from typing import Optional, Dict, Any
10
+ from datetime import datetime
11
+
12
+
13
+ STATE_FILE_NAME = ".agentengine.state"
14
+
15
+
16
+ def get_state_file_path(project_dir: Path) -> Path:
17
+ """获取状态文件路径"""
18
+ return project_dir / STATE_FILE_NAME
19
+
20
+
21
+ def load_state(project_dir: Path) -> Dict[str, Any]:
22
+ """加载状态文件"""
23
+ state_file = get_state_file_path(project_dir)
24
+ if not state_file.exists():
25
+ return {}
26
+
27
+ try:
28
+ with open(state_file, 'r', encoding='utf-8') as f:
29
+ return yaml.safe_load(f) or {}
30
+ except Exception:
31
+ return {}
32
+
33
+
34
+ def save_state(project_dir: Path, data: Dict[str, Any]) -> None:
35
+ """保存状态文件"""
36
+ state_file = get_state_file_path(project_dir)
37
+
38
+ # 自动添加 updated_at
39
+ if "updated_at" not in data:
40
+ data["updated_at"] = datetime.now().isoformat()
41
+
42
+ with open(state_file, 'w', encoding='utf-8') as f:
43
+ yaml.dump(data, f, default_flow_style=False, allow_unicode=True)
44
+
45
+
46
+ def update_state(project_dir: Path, updates: Dict[str, Any]) -> Dict[str, Any]:
47
+ """更新状态文件 (增量更新)"""
48
+ current_state = load_state(project_dir)
49
+ current_state.update(updates)
50
+ save_state(project_dir, current_state)
51
+ return current_state
52
+
53
+
54
+ def clear_state(project_dir: Path, key: str = None) -> bool:
55
+ """清理状态文件
56
+
57
+ Args:
58
+ project_dir: 项目目录
59
+ key: 如果指定,仅当状态中的 ID 与 key 匹配时才删除
60
+
61
+ Returns:
62
+ bool: 是否实际删除了状态文件
63
+ """
64
+ state_file = get_state_file_path(project_dir)
65
+ if not state_file.exists():
66
+ return False
67
+
68
+ if key:
69
+ # 检查是否匹配
70
+ state = load_state(project_dir)
71
+ # 检查 agent_id 或 mcp_id
72
+ if state.get("agent_id") == key or state.get("mcp_id") == key:
73
+ state_file.unlink()
74
+ return True
75
+ return False
76
+ else:
77
+ state_file.unlink()
78
+ return True
@@ -0,0 +1,21 @@
1
+ """Backward-compatible import path for UI configuration helpers."""
2
+
3
+ from ksadk.ui_config import ( # noqa: F401
4
+ SUPPORTED_UI_PROFILES,
5
+ UIConfig,
6
+ UI_PROFILE_ADK,
7
+ UI_PROFILE_AUTO,
8
+ UI_PROFILE_CUSTOM,
9
+ UI_PROFILE_HERMES,
10
+ UI_PROFILE_LANGCHAIN,
11
+ UI_PROFILE_OPENCLAW,
12
+ default_ui_path,
13
+ extract_ui_state,
14
+ infer_ui_profile_from_framework,
15
+ is_same_origin,
16
+ normalize_ui_path,
17
+ normalize_ui_profile,
18
+ normalize_ui_url,
19
+ resolve_ui_config,
20
+ ui_config_to_state_fields,
21
+ )
@@ -0,0 +1,7 @@
1
+ """
2
+ KsADK Detection - 框架自动检测模块
3
+ """
4
+
5
+ from ksadk.detection.detector import FrameworkDetector, DetectionResult, FrameworkType
6
+
7
+ __all__ = ["FrameworkDetector", "DetectionResult", "FrameworkType"]
@@ -0,0 +1,431 @@
1
+ """
2
+ 框架检测器 - 自动检测 LangChain / LangGraph / DeepAgents / ADK 项目
3
+ """
4
+
5
+ import ast
6
+ import json
7
+ from dataclasses import dataclass
8
+ from enum import Enum
9
+ from pathlib import Path
10
+ from typing import Optional
11
+
12
+ import yaml
13
+
14
+
15
+ class FrameworkType(Enum):
16
+ """支持的框架类型"""
17
+
18
+ ADK = "adk"
19
+ LANGCHAIN = "langchain"
20
+ LANGGRAPH = "langgraph"
21
+ DEEPAGENTS = "deepagents"
22
+ HERMES = "hermes"
23
+ UNKNOWN = "unknown"
24
+
25
+
26
+ @dataclass
27
+ class DetectionResult:
28
+ """检测结果"""
29
+
30
+ type: FrameworkType
31
+ name: str
32
+ entry_point: str
33
+ package_path: str
34
+ agent_variable: str = "root_agent"
35
+ runner_class: str = ""
36
+ confidence: float = 0.0
37
+
38
+ @property
39
+ def is_valid(self) -> bool:
40
+ return self.type != FrameworkType.UNKNOWN
41
+
42
+
43
+ class FrameworkDetector:
44
+ """框架检测器"""
45
+
46
+ _ENTRY_FILES = ("agent.py", "main.py", "app.py")
47
+
48
+ def __init__(self, project_dir: str):
49
+ self.project_dir = Path(project_dir).resolve()
50
+
51
+ def detect(self) -> DetectionResult:
52
+ """检测项目使用的框架类型"""
53
+
54
+ # 1. 检查 ksadk.yaml 配置文件 (显式声明)
55
+ config_result = self._check_config()
56
+ if config_result:
57
+ return config_result
58
+
59
+ graph_config_result = self._check_langgraph_json()
60
+ if graph_config_result:
61
+ return graph_config_result
62
+
63
+ # 2. 查找 Python 包目录
64
+ package_path = self._find_package_dir()
65
+ if not package_path:
66
+ return DetectionResult(
67
+ type=FrameworkType.UNKNOWN, name="Unknown", entry_point="", package_path=""
68
+ )
69
+
70
+ # 3. 查找 agent.py 或 __init__.py
71
+ agent_file = self._find_agent_file(package_path)
72
+ if not agent_file:
73
+ return DetectionResult(
74
+ type=FrameworkType.UNKNOWN,
75
+ name="Unknown",
76
+ entry_point="",
77
+ package_path=str(package_path),
78
+ )
79
+
80
+ # 4. 分析代码确定框架类型
81
+ return self._analyze_code(agent_file, package_path)
82
+
83
+ def _check_config(self) -> Optional[DetectionResult]:
84
+ """检查配置文件 (agentengine.yaml 或 ksadk.yaml)"""
85
+ # 优先检查 agentengine.yaml
86
+ config_path = self.project_dir / "agentengine.yaml"
87
+ if not config_path.exists():
88
+ config_path = self.project_dir / "ksadk.yaml"
89
+ if not config_path.exists():
90
+ config_path = self.project_dir / "ksadk.yml"
91
+
92
+ if not config_path.exists():
93
+ return None
94
+
95
+ try:
96
+ # 使用 utf-8-sig 自动处理 BOM,确保 Windows 兼容性
97
+ with open(config_path, "r", encoding="utf-8-sig") as f:
98
+ config = yaml.safe_load(f)
99
+
100
+ framework = config.get("framework", "adk").lower()
101
+ framework_type = {
102
+ "adk": FrameworkType.ADK,
103
+ "langchain": FrameworkType.LANGCHAIN,
104
+ "langgraph": FrameworkType.LANGGRAPH,
105
+ "deepagents": FrameworkType.DEEPAGENTS,
106
+ "hermes": FrameworkType.HERMES,
107
+ }.get(framework, FrameworkType.UNKNOWN)
108
+
109
+ artifact_type = str(config.get("artifact_type") or "").strip().lower()
110
+ is_hermes_container = (
111
+ framework_type == FrameworkType.HERMES and artifact_type == "container"
112
+ )
113
+ default_entry_point = (
114
+ "runtime/app.py"
115
+ if is_hermes_container and (self.project_dir / "runtime" / "app.py").is_file()
116
+ else "agent.py"
117
+ )
118
+ entry_point = config.get("entry_point", default_entry_point)
119
+ agent_variable = config.get("agent_variable", "root_agent")
120
+ runner_class = str(config.get("runner_class") or "").strip()
121
+ entry_path = self.project_dir / str(entry_point).replace("\\", "/")
122
+ if not entry_path.exists() or not entry_path.is_file():
123
+ return None
124
+ if not is_hermes_container and not self._entry_exposes_variable(
125
+ entry_path, agent_variable
126
+ ):
127
+ return None
128
+ package = str(config.get("package") or "").strip()
129
+ if package:
130
+ package_path = self.project_dir / package
131
+ elif is_hermes_container:
132
+ package_path = entry_path.parent
133
+ else:
134
+ package_path = self.project_dir / self.project_dir.name.replace("-", "_")
135
+
136
+ return DetectionResult(
137
+ type=framework_type,
138
+ name=config.get("name", self.project_dir.name),
139
+ entry_point=entry_point,
140
+ package_path=str(package_path),
141
+ agent_variable=agent_variable,
142
+ runner_class=runner_class,
143
+ confidence=1.0,
144
+ )
145
+ except Exception:
146
+ return None
147
+
148
+ def _find_package_dir(self) -> Optional[Path]:
149
+ """查找 Python 包目录"""
150
+ # 优先查找与项目同名的包 (下划线版本)
151
+ expected_name = self.project_dir.name.replace("-", "_")
152
+ expected_path = self.project_dir / expected_name
153
+ if expected_path.exists() and expected_path.is_dir():
154
+ if (expected_path / "__init__.py").exists() or any(
155
+ (expected_path / entry_file).exists() for entry_file in self._ENTRY_FILES
156
+ ):
157
+ return expected_path
158
+
159
+ # 查找任何包含 __init__.py 的子目录
160
+ for item in self.project_dir.iterdir():
161
+ if (
162
+ item.is_dir()
163
+ and not item.name.startswith(".")
164
+ and item.name not in ("tests", "test", "__pycache__")
165
+ and (
166
+ (item / "__init__.py").exists()
167
+ or any((item / entry_file).exists() for entry_file in self._ENTRY_FILES)
168
+ )
169
+ ):
170
+ return item
171
+
172
+ # 当前目录本身也可能是一个包
173
+ if (self.project_dir / "__init__.py").exists():
174
+ return self.project_dir
175
+
176
+ # 兼容脚本式项目: 当前目录直接包含 agent.py/main.py/app.py
177
+ if any((self.project_dir / entry_file).exists() for entry_file in self._ENTRY_FILES):
178
+ return self.project_dir
179
+
180
+ src_dir = self.project_dir / "src"
181
+ if src_dir.is_dir():
182
+ expected_src_path = src_dir / expected_name
183
+ if expected_src_path.exists() and expected_src_path.is_dir():
184
+ if (expected_src_path / "__init__.py").exists() or any(
185
+ (expected_src_path / entry_file).exists() for entry_file in self._ENTRY_FILES
186
+ ):
187
+ return expected_src_path
188
+
189
+ for item in src_dir.iterdir():
190
+ if (
191
+ item.is_dir()
192
+ and not item.name.startswith(".")
193
+ and item.name not in ("tests", "test", "__pycache__")
194
+ and (
195
+ (item / "__init__.py").exists()
196
+ or any((item / entry_file).exists() for entry_file in self._ENTRY_FILES)
197
+ )
198
+ ):
199
+ return item
200
+
201
+ return None
202
+
203
+ def _find_agent_file(self, package_path: Path) -> Optional[Path]:
204
+ """查找 agent.py 文件"""
205
+ # 优先查找常见入口文件
206
+ for entry_file in self._ENTRY_FILES:
207
+ entry_path = package_path / entry_file
208
+ if entry_path.exists():
209
+ return entry_path
210
+
211
+ # 检查 __init__.py 是否导出 root_agent
212
+ init_py = package_path / "__init__.py"
213
+ if init_py.exists():
214
+ try:
215
+ content = init_py.read_text(encoding="utf-8-sig")
216
+ if "root_agent" in content or "graph" in content or "app" in content:
217
+ return init_py
218
+ except Exception:
219
+ pass
220
+
221
+ return None
222
+
223
+ @staticmethod
224
+ def _detect_agent_variable(content: str) -> str | None:
225
+ import re
226
+
227
+ patterns = [
228
+ (r"^\s*(root_agent)\s*=", "root_agent"),
229
+ (r"^\s*(root_agent)\s*:\s*[^=]+\s*=", "root_agent"),
230
+ (r"^\s*(\w+)\s*=\s*\w*graph\w*\.compile\(", None),
231
+ (r"^\s*(\w+)\s*=\s*StateGraph", None),
232
+ (r"^\s*(\w+)\s*=\s*Agent\(", None),
233
+ (r"^\s*(\w+)\s*=\s*create_react_agent\(", None),
234
+ (r"^\s*(\w+)\s*=\s*create_deep_agent\(", None),
235
+ (r"^\s*(\w+)\s*=\s*create_agent\(", None),
236
+ ]
237
+ for pattern, fixed_name in patterns:
238
+ match = re.search(pattern, content, re.MULTILINE | re.IGNORECASE)
239
+ if match:
240
+ return fixed_name if fixed_name else match.group(1)
241
+ return None
242
+
243
+ @classmethod
244
+ def _has_agent_variable(cls, content: str, agent_var: str) -> bool:
245
+ import re
246
+
247
+ if not agent_var:
248
+ return False
249
+ escaped = re.escape(agent_var)
250
+ patterns = [
251
+ rf"^\s*{escaped}\s*=",
252
+ rf"^\s*{escaped}\s*:\s*[^=]+=",
253
+ rf"^\s*from\s+[\.\w]+\s+import\s+.*\b{escaped}\b",
254
+ rf"^\s*import\s+[\.\w]+\s+as\s+{escaped}\b",
255
+ ]
256
+ return (
257
+ any(re.search(pattern, content, re.MULTILINE) for pattern in patterns)
258
+ or cls._detect_agent_variable(content) == agent_var
259
+ )
260
+
261
+ def _entry_exposes_variable(self, entry_path: Path, agent_var: str) -> bool:
262
+ try:
263
+ content = entry_path.read_text(encoding="utf-8-sig")
264
+ except Exception:
265
+ return False
266
+ return self._has_agent_variable(content, agent_var)
267
+
268
+ def _framework_from_entry(
269
+ self, entry_path: Path, fallback: FrameworkType = FrameworkType.UNKNOWN
270
+ ) -> FrameworkType:
271
+ try:
272
+ content = entry_path.read_text(encoding="utf-8-sig")
273
+ tree = ast.parse(content, filename=str(entry_path))
274
+ imports = self._extract_imports(tree)
275
+ except Exception:
276
+ return fallback
277
+ if self._is_deepagents(imports, content):
278
+ return FrameworkType.DEEPAGENTS
279
+ if self._is_langgraph(imports, content):
280
+ return FrameworkType.LANGGRAPH
281
+ if self._is_adk(imports, content):
282
+ return FrameworkType.ADK
283
+ if self._is_langchain(imports, content):
284
+ return FrameworkType.LANGCHAIN
285
+ return fallback
286
+
287
+ def _check_langgraph_json(self) -> Optional[DetectionResult]:
288
+ config_path = self.project_dir / "langgraph.json"
289
+ if not config_path.exists():
290
+ return None
291
+ try:
292
+ config = json.loads(config_path.read_text(encoding="utf-8-sig"))
293
+ except Exception:
294
+ return None
295
+ graphs = config.get("graphs")
296
+ if not isinstance(graphs, dict):
297
+ return None
298
+ for target in graphs.values():
299
+ if not isinstance(target, str) or ":" not in target:
300
+ continue
301
+ path_part, agent_var = target.rsplit(":", 1)
302
+ path_part = path_part.strip().removeprefix("./")
303
+ agent_var = agent_var.strip() or "root_agent"
304
+ entry_path = self.project_dir / Path(path_part.replace("\\", "/"))
305
+ if not entry_path.exists() or not entry_path.is_file():
306
+ continue
307
+ if not self._entry_exposes_variable(entry_path, agent_var):
308
+ continue
309
+ return DetectionResult(
310
+ type=self._framework_from_entry(entry_path, FrameworkType.LANGGRAPH),
311
+ name=self.project_dir.name,
312
+ entry_point=str(entry_path.relative_to(self.project_dir)),
313
+ package_path=str(entry_path.parent),
314
+ agent_variable=agent_var,
315
+ confidence=0.95,
316
+ )
317
+ return None
318
+
319
+ def _analyze_code(self, agent_file: Path, package_path: Path) -> DetectionResult:
320
+ """分析代码确定框架类型"""
321
+ try:
322
+ # 使用 utf-8-sig 自动处理 BOM,兼容 Windows/编辑器带 BOM 的脚本
323
+ content = agent_file.read_text(encoding="utf-8-sig")
324
+ tree = ast.parse(content, filename=str(agent_file))
325
+ except Exception:
326
+ return DetectionResult(
327
+ type=FrameworkType.UNKNOWN,
328
+ name=self.project_dir.name,
329
+ entry_point=str(agent_file.relative_to(self.project_dir)),
330
+ package_path=str(package_path),
331
+ )
332
+
333
+ imports = self._extract_imports(tree)
334
+
335
+ # 检测 ADK
336
+ if self._is_adk(imports, content):
337
+ return DetectionResult(
338
+ type=FrameworkType.ADK,
339
+ name=package_path.name,
340
+ entry_point=str(agent_file.relative_to(self.project_dir)),
341
+ package_path=str(package_path),
342
+ agent_variable="root_agent",
343
+ confidence=0.9,
344
+ )
345
+
346
+ # 检测 DeepAgents (LangChain 生态, 底层基于 LangGraph)
347
+ if self._is_deepagents(imports, content):
348
+ return DetectionResult(
349
+ type=FrameworkType.DEEPAGENTS,
350
+ name=package_path.name,
351
+ entry_point=str(agent_file.relative_to(self.project_dir)),
352
+ package_path=str(package_path),
353
+ agent_variable="root_agent",
354
+ confidence=0.9,
355
+ )
356
+
357
+ # 检测 LangGraph
358
+ if self._is_langgraph(imports, content):
359
+ return DetectionResult(
360
+ type=FrameworkType.LANGGRAPH,
361
+ name=package_path.name,
362
+ entry_point=str(agent_file.relative_to(self.project_dir)),
363
+ package_path=str(package_path),
364
+ agent_variable="root_agent",
365
+ confidence=0.9,
366
+ )
367
+
368
+ # 检测 LangChain
369
+ if self._is_langchain(imports, content):
370
+ return DetectionResult(
371
+ type=FrameworkType.LANGCHAIN,
372
+ name=package_path.name,
373
+ entry_point=str(agent_file.relative_to(self.project_dir)),
374
+ package_path=str(package_path),
375
+ agent_variable="root_agent",
376
+ confidence=0.8,
377
+ )
378
+
379
+ return DetectionResult(
380
+ type=FrameworkType.UNKNOWN,
381
+ name=self.project_dir.name,
382
+ entry_point=str(agent_file.relative_to(self.project_dir)),
383
+ package_path=str(package_path),
384
+ )
385
+
386
+ def _extract_imports(self, tree: ast.AST) -> set:
387
+ """提取导入的模块"""
388
+ imports = set()
389
+ for node in ast.walk(tree):
390
+ if isinstance(node, ast.Import):
391
+ for alias in node.names:
392
+ imports.add(alias.name.split(".")[0])
393
+ elif isinstance(node, ast.ImportFrom):
394
+ if node.module:
395
+ imports.add(node.module.split(".")[0])
396
+ return imports
397
+
398
+ def _is_adk(self, imports: set, content: str) -> bool:
399
+ """检测是否为 ADK 项目"""
400
+ # 检查 google.adk 导入
401
+ if "google" in imports and ("google.adk" in content or "from google.adk" in content):
402
+ return True
403
+ return False
404
+
405
+ def _is_langgraph(self, imports: set, content: str) -> bool:
406
+ """检测是否为 LangGraph 项目"""
407
+ if "langgraph" in imports:
408
+ return True
409
+ if "StateGraph" in content or "langgraph.graph" in content:
410
+ return True
411
+ return False
412
+
413
+ def _is_langchain(self, imports: set, content: str) -> bool:
414
+ """检测是否为 LangChain 项目"""
415
+ langchain_modules = {
416
+ "langchain",
417
+ "langchain_openai",
418
+ "langchain_core",
419
+ "langchain_community",
420
+ }
421
+ if langchain_modules & imports:
422
+ return True
423
+ return False
424
+
425
+ def _is_deepagents(self, imports: set, content: str) -> bool:
426
+ """检测是否为 DeepAgents 项目"""
427
+ if "deepagents" in imports:
428
+ return True
429
+ if "from deepagents import" in content or "create_deep_agent(" in content:
430
+ return True
431
+ return False