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
ksadk/a2a/executor.py ADDED
@@ -0,0 +1,201 @@
1
+ """A2A executor that adapts a KsADK runner to the A2A server contract."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import logging
7
+ from collections.abc import AsyncIterator
8
+ from typing import Any
9
+
10
+ from a2a.server.agent_execution import AgentExecutor, RequestContext
11
+ from a2a.server.events import EventQueue
12
+ from a2a.server.tasks import TaskUpdater
13
+ from a2a.types import Part, TextPart
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class KsAgentExecutor(AgentExecutor):
19
+ """Execute a KsADK runner inside the A2A request lifecycle."""
20
+
21
+ def __init__(self, runner: Any, prefer_stream: bool = True) -> None:
22
+ self.runner = runner
23
+ self.prefer_stream = prefer_stream
24
+
25
+ async def execute(
26
+ self,
27
+ context: RequestContext,
28
+ event_queue: EventQueue,
29
+ ) -> None:
30
+ updater = TaskUpdater(
31
+ event_queue=event_queue,
32
+ task_id=context.task_id or "unknown-task",
33
+ context_id=context.context_id or "unknown-context",
34
+ )
35
+
36
+ try:
37
+ await updater.start_work()
38
+ runner_input = self._build_runner_input(context)
39
+ output = await self._run_runner(context, updater, runner_input)
40
+ completion_message = (
41
+ updater.new_agent_message(parts=[Part(root=TextPart(text=output))])
42
+ if output
43
+ else None
44
+ )
45
+ await updater.complete(message=completion_message)
46
+ except Exception as exc:
47
+ logger.exception("A2A task execution failed")
48
+ error_text = self._coerce_text(exc)
49
+ await updater.failed(
50
+ message=updater.new_agent_message(
51
+ parts=[Part(root=TextPart(text=error_text))]
52
+ )
53
+ )
54
+
55
+ async def cancel(
56
+ self,
57
+ context: RequestContext,
58
+ event_queue: EventQueue,
59
+ ) -> None:
60
+ updater = TaskUpdater(
61
+ event_queue=event_queue,
62
+ task_id=context.task_id or "unknown-task",
63
+ context_id=context.context_id or "unknown-context",
64
+ )
65
+ await updater.cancel(
66
+ message=updater.new_agent_message(
67
+ parts=[Part(root=TextPart(text="Request canceled"))]
68
+ )
69
+ )
70
+
71
+ async def _run_runner(
72
+ self,
73
+ context: RequestContext,
74
+ updater: TaskUpdater,
75
+ runner_input: dict[str, Any],
76
+ ) -> str:
77
+ stream = getattr(self.runner, "stream", None)
78
+ if self.prefer_stream and callable(stream):
79
+ return await self._run_streaming(context, updater, stream, runner_input)
80
+
81
+ result = await self.runner.invoke(runner_input)
82
+ text = self._coerce_text(result)
83
+ if text:
84
+ await updater.add_artifact(
85
+ parts=[Part(root=TextPart(text=text))],
86
+ artifact_id=f"{context.task_id}-response",
87
+ name="response",
88
+ last_chunk=True,
89
+ )
90
+ return text
91
+
92
+ async def _run_streaming(
93
+ self,
94
+ context: RequestContext,
95
+ updater: TaskUpdater,
96
+ stream: Any,
97
+ runner_input: dict[str, Any],
98
+ ) -> str:
99
+ output_text = ""
100
+ emitted_chunks = 0
101
+ artifact_id = f"{context.task_id}-response"
102
+
103
+ async for chunk, last_chunk in self._with_last_flag(stream(runner_input)):
104
+ chunk_type = chunk.get("type") if isinstance(chunk, dict) else None
105
+ if chunk_type == "final":
106
+ final_text = (
107
+ self._coerce_text(chunk.get("output"))
108
+ if isinstance(chunk, dict)
109
+ else ""
110
+ )
111
+ if not final_text:
112
+ continue
113
+ if not output_text:
114
+ output_text = final_text
115
+ elif final_text.startswith(output_text):
116
+ suffix = final_text[len(output_text) :]
117
+ output_text = final_text
118
+ if suffix:
119
+ emitted_chunks += 1
120
+ await updater.add_artifact(
121
+ parts=[Part(root=TextPart(text=suffix))],
122
+ artifact_id=artifact_id,
123
+ name="response",
124
+ append=bool(emitted_chunks > 1),
125
+ last_chunk=last_chunk,
126
+ )
127
+ continue
128
+ else:
129
+ output_text = final_text
130
+ await updater.add_artifact(
131
+ parts=[Part(root=TextPart(text=final_text))],
132
+ artifact_id=artifact_id,
133
+ name="response",
134
+ append=False,
135
+ last_chunk=last_chunk,
136
+ )
137
+ continue
138
+
139
+ text = self._coerce_text(chunk)
140
+ if not text:
141
+ continue
142
+ output_text += text
143
+ emitted_chunks += 1
144
+ await updater.add_artifact(
145
+ parts=[Part(root=TextPart(text=text))],
146
+ artifact_id=artifact_id,
147
+ name="response",
148
+ append=bool(emitted_chunks > 1),
149
+ last_chunk=last_chunk,
150
+ )
151
+
152
+ return output_text
153
+
154
+ async def _with_last_flag(
155
+ self,
156
+ iterator: AsyncIterator[Any],
157
+ ) -> AsyncIterator[tuple[Any, bool]]:
158
+ try:
159
+ previous = await anext(iterator)
160
+ except StopAsyncIteration:
161
+ return
162
+
163
+ while True:
164
+ try:
165
+ current = await anext(iterator)
166
+ except StopAsyncIteration:
167
+ yield previous, True
168
+ return
169
+ yield previous, False
170
+ previous = current
171
+
172
+ @staticmethod
173
+ def _build_runner_input(context: RequestContext) -> dict[str, Any]:
174
+ metadata = dict(context.metadata)
175
+ state = metadata.get("state", {})
176
+ if not isinstance(state, dict):
177
+ state = {}
178
+
179
+ return {
180
+ "input": context.get_user_input(),
181
+ "task_id": context.task_id,
182
+ "context_id": context.context_id,
183
+ "session_id": context.context_id,
184
+ "state": dict(state),
185
+ "branch": metadata.get("branch", ""),
186
+ "metadata": metadata,
187
+ }
188
+
189
+ @classmethod
190
+ def _coerce_text(cls, payload: Any) -> str:
191
+ if payload is None:
192
+ return ""
193
+ if isinstance(payload, str):
194
+ return payload
195
+ if isinstance(payload, dict):
196
+ for key in ("output", "delta", "data"):
197
+ value = payload.get(key)
198
+ if value is not None:
199
+ return cls._coerce_text(value)
200
+ return json.dumps(payload, ensure_ascii=False, default=str)
201
+ return str(payload)
ksadk/a2a/server.py ADDED
@@ -0,0 +1,79 @@
1
+ """High-level server helpers for exposing a KsADK runner over A2A."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Sequence
6
+ from typing import Any
7
+
8
+ from a2a.server.apps import A2AStarletteApplication
9
+ from a2a.server.request_handlers import DefaultRequestHandler
10
+ from a2a.server.tasks import InMemoryTaskStore
11
+ from starlette.applications import Starlette
12
+
13
+ from ksadk.a2a.card_builder import AgentCardBuilder
14
+ from ksadk.a2a.executor import KsAgentExecutor
15
+
16
+
17
+ class KsA2AServer:
18
+ """Expose a KsADK runner as an A2A-compatible ASGI app."""
19
+
20
+ def __init__(
21
+ self,
22
+ runner: Any,
23
+ app_name: str,
24
+ url: str,
25
+ description: str = "",
26
+ skills: Sequence[str] | None = None,
27
+ version: str = "1.0.0",
28
+ ) -> None:
29
+ self.runner = runner
30
+ self.app_name = app_name
31
+ self.url = url
32
+ self.description = description
33
+ self.skills = list(skills or [])
34
+ self.version = version
35
+
36
+ self.agent_card = AgentCardBuilder(
37
+ name=app_name,
38
+ url=url,
39
+ description=description,
40
+ skills=self.skills,
41
+ version=version,
42
+ ).build()
43
+ self.executor = KsAgentExecutor(runner=runner)
44
+ self.task_store = InMemoryTaskStore()
45
+ self.request_handler = DefaultRequestHandler(
46
+ agent_executor=self.executor,
47
+ task_store=self.task_store,
48
+ )
49
+ self.application = A2AStarletteApplication(
50
+ agent_card=self.agent_card,
51
+ http_handler=self.request_handler,
52
+ )
53
+
54
+ def build(self, **kwargs: Any) -> Starlette:
55
+ """Build the Starlette application with the standard A2A routes."""
56
+ return self.application.build(**kwargs)
57
+
58
+ def add_routes_to_app(self, app: Starlette) -> None:
59
+ """Attach the A2A routes to an existing Starlette application."""
60
+ self.application.add_routes_to_app(app)
61
+
62
+
63
+ def to_a2a(
64
+ runner: Any,
65
+ app_name: str,
66
+ url: str,
67
+ description: str = "",
68
+ skills: Sequence[str] | None = None,
69
+ version: str = "1.0.0",
70
+ ) -> KsA2AServer:
71
+ """Convenience helper for building a KsA2AServer."""
72
+ return KsA2AServer(
73
+ runner=runner,
74
+ app_name=app_name,
75
+ url=url,
76
+ description=description,
77
+ skills=skills,
78
+ version=version,
79
+ )
@@ -0,0 +1,20 @@
1
+ """原生多 Agent 编排层。"""
2
+
3
+ from ksadk.agents.base import BaseOrchestrationAgent
4
+ from ksadk.agents.context import OrchestrationContext
5
+ from ksadk.agents.event import AgentEvent, EventType
6
+ from ksadk.agents.loop_agent import LoopAgent
7
+ from ksadk.agents.parallel_agent import ParallelAgent
8
+ from ksadk.agents.runner_adapter import RunnerAgent
9
+ from ksadk.agents.sequential_agent import SequentialAgent
10
+
11
+ __all__ = [
12
+ "AgentEvent",
13
+ "BaseOrchestrationAgent",
14
+ "EventType",
15
+ "LoopAgent",
16
+ "OrchestrationContext",
17
+ "ParallelAgent",
18
+ "RunnerAgent",
19
+ "SequentialAgent",
20
+ ]
ksadk/agents/base.py ADDED
@@ -0,0 +1,370 @@
1
+ """编排 agent 基类。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import inspect
6
+ import keyword
7
+ import logging
8
+ import re
9
+ from abc import ABC, abstractmethod
10
+ from collections.abc import AsyncGenerator, AsyncIterator, Callable
11
+ from dataclasses import replace
12
+ from typing import Any
13
+
14
+ from ksadk.agents.context import OrchestrationContext
15
+ from ksadk.agents.event import AgentEvent, EventType
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ SubAgentType = Any
20
+ _CAMEL_BOUNDARY_RE = re.compile(r"(?<!^)(?=[A-Z])")
21
+ _TOP_LEVEL_NAME_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_-]*$")
22
+
23
+
24
+ class BaseOrchestrationAgent(ABC):
25
+ """多 agent 编排基类。"""
26
+
27
+ def __init__(
28
+ self,
29
+ name: str,
30
+ sub_agents: list[SubAgentType] | None = None,
31
+ description: str = "",
32
+ before_run_hook: Callable[[OrchestrationContext], Any] | None = None,
33
+ after_run_hook: Callable[[OrchestrationContext], Any] | None = None,
34
+ ):
35
+ self._validate_top_level_name(name)
36
+ self.name = name
37
+ self.description = description
38
+ self.sub_agents = sub_agents or []
39
+ self.before_run_hook = before_run_hook
40
+ self.after_run_hook = after_run_hook
41
+ self._validate_sub_agents(self.sub_agents)
42
+
43
+ async def run_async(
44
+ self, context: OrchestrationContext | None = None
45
+ ) -> AsyncGenerator[AgentEvent, None]:
46
+ run_context = context or OrchestrationContext()
47
+ logger.info("[%s] orchestration started", self.name)
48
+ yield AgentEvent(
49
+ agent_name=self.name,
50
+ event_type=EventType.AGENT_START,
51
+ branch=run_context.branch,
52
+ )
53
+
54
+ try:
55
+ async for hook_event in self._run_hook(self.before_run_hook, run_context):
56
+ yield hook_event
57
+
58
+ async for event in self._run_impl(run_context):
59
+ yield self._ensure_event_branch(event, run_context.branch)
60
+
61
+ async for hook_event in self._run_hook(self.after_run_hook, run_context):
62
+ yield hook_event
63
+ except Exception as exc:
64
+ yield AgentEvent(
65
+ agent_name=self.name,
66
+ event_type=EventType.ERROR,
67
+ data=str(exc),
68
+ branch=run_context.branch,
69
+ metadata={"exception_type": type(exc).__name__},
70
+ )
71
+ raise
72
+
73
+ logger.info("[%s] orchestration finished", self.name)
74
+ yield AgentEvent(
75
+ agent_name=self.name,
76
+ event_type=EventType.AGENT_END,
77
+ branch=run_context.branch,
78
+ )
79
+
80
+ @abstractmethod
81
+ async def _run_impl(self, context: OrchestrationContext) -> AsyncGenerator[AgentEvent, None]:
82
+ if False:
83
+ yield AgentEvent(agent_name=self.name, event_type=EventType.TEXT_OUTPUT)
84
+
85
+ async def _run_sub_agent(
86
+ self, agent: SubAgentType, context: OrchestrationContext
87
+ ) -> AsyncGenerator[AgentEvent, None]:
88
+ agent_name = self._get_agent_name(agent)
89
+
90
+ if isinstance(agent, BaseOrchestrationAgent):
91
+ async for event in agent.run_async(context):
92
+ yield self._apply_event_state(event, context)
93
+ return
94
+
95
+ if self._is_runner_like(agent):
96
+ async for event in self._run_runner_like(agent_name, agent, context):
97
+ yield event
98
+ return
99
+
100
+ if callable(agent):
101
+ async for event in self._run_callable(agent_name, agent, context):
102
+ yield event
103
+ return
104
+
105
+ raise TypeError(f"Unsupported sub-agent type: {type(agent)!r}")
106
+
107
+ @classmethod
108
+ def _get_agent_name(cls, agent: SubAgentType) -> str:
109
+ if isinstance(agent, BaseOrchestrationAgent):
110
+ cls._validate_identifier_name(agent.name)
111
+ return agent.name
112
+
113
+ explicit_name = getattr(agent, "name", None)
114
+ if isinstance(explicit_name, str) and explicit_name:
115
+ cls._validate_identifier_name(explicit_name)
116
+ return explicit_name
117
+
118
+ if inspect.isfunction(agent) or inspect.ismethod(agent):
119
+ inferred_name = getattr(agent, "__name__", "")
120
+ cls._validate_identifier_name(inferred_name)
121
+ return inferred_name
122
+
123
+ class_name = agent.__class__.__name__
124
+ inferred_name = _CAMEL_BOUNDARY_RE.sub("_", class_name).lower().lstrip("_")
125
+ cls._validate_identifier_name(inferred_name)
126
+ return inferred_name
127
+
128
+ @classmethod
129
+ def _validate_identifier_name(cls, name: str) -> None:
130
+ if not isinstance(name, str) or not name:
131
+ raise ValueError("Agent name must be a non-empty string")
132
+ if not name.isidentifier() or keyword.iskeyword(name):
133
+ raise ValueError(f"Agent name must be a valid identifier: {name}")
134
+
135
+ @classmethod
136
+ def _validate_top_level_name(cls, name: str) -> None:
137
+ if not isinstance(name, str) or not name:
138
+ raise ValueError("Agent name must be a non-empty string")
139
+ if not _TOP_LEVEL_NAME_RE.match(name):
140
+ raise ValueError(f"Agent name must be a valid identifier: {name}")
141
+
142
+ @classmethod
143
+ def _validate_sub_agents(cls, sub_agents: list[SubAgentType]) -> None:
144
+ names: list[str] = []
145
+ for agent in sub_agents:
146
+ if cls._is_runner_like(agent):
147
+ names.append(cls._get_agent_name(agent))
148
+ continue
149
+
150
+ if callable(agent):
151
+ names.append(cls._get_agent_name(agent))
152
+ if not (inspect.iscoroutinefunction(agent) or inspect.isasyncgenfunction(agent)):
153
+ raise TypeError("Custom callable sub-agents must be async")
154
+ continue
155
+
156
+ if isinstance(agent, BaseOrchestrationAgent):
157
+ names.append(cls._get_agent_name(agent))
158
+ continue
159
+
160
+ raise TypeError(f"Unsupported sub-agent type: {type(agent)!r}")
161
+
162
+ if len(names) != len(set(names)):
163
+ raise ValueError(f"Sub-agent names must be unique: {names}")
164
+
165
+ @staticmethod
166
+ def _is_runner_like(agent: Any) -> bool:
167
+ invoke = getattr(agent, "invoke", None)
168
+ return callable(invoke)
169
+
170
+ async def _run_callable(
171
+ self,
172
+ agent_name: str,
173
+ agent: Callable[[OrchestrationContext], Any],
174
+ context: OrchestrationContext,
175
+ ) -> AsyncGenerator[AgentEvent, None]:
176
+ try:
177
+ result = agent(context)
178
+ if inspect.isasyncgen(result):
179
+ async for item in result:
180
+ yield self._apply_event_state(
181
+ self._coerce_event(agent_name, item, context.branch),
182
+ context,
183
+ )
184
+ return
185
+
186
+ if not inspect.isawaitable(result):
187
+ raise TypeError("Custom callable sub-agents must be async")
188
+
189
+ value = await result
190
+ except Exception as exc:
191
+ yield AgentEvent(
192
+ agent_name=agent_name,
193
+ event_type=EventType.ERROR,
194
+ data=str(exc),
195
+ branch=context.branch,
196
+ metadata={"exception_type": type(exc).__name__},
197
+ )
198
+ raise
199
+
200
+ if value is None:
201
+ return
202
+
203
+ if isinstance(value, (list, tuple)):
204
+ for item in value:
205
+ yield self._apply_event_state(
206
+ self._coerce_event(agent_name, item, context.branch),
207
+ context,
208
+ )
209
+ return
210
+
211
+ yield self._apply_event_state(
212
+ self._coerce_event(agent_name, value, context.branch),
213
+ context,
214
+ )
215
+
216
+ async def _run_runner_like(
217
+ self,
218
+ agent_name: str,
219
+ runner: Any,
220
+ context: OrchestrationContext,
221
+ ) -> AsyncGenerator[AgentEvent, None]:
222
+ output_parts: list[Any] = []
223
+ runner_input = self._build_runner_input(context)
224
+
225
+ try:
226
+ stream = getattr(runner, "stream", None)
227
+ if callable(stream):
228
+ async for chunk in stream(runner_input):
229
+ event = self._apply_event_state(
230
+ self._coerce_event(agent_name, chunk, context.branch),
231
+ context,
232
+ )
233
+ if event.event_type == EventType.TEXT_OUTPUT:
234
+ output_parts.append(event.data)
235
+ yield event
236
+ else:
237
+ result = await runner.invoke(runner_input)
238
+ event = self._apply_event_state(
239
+ self._coerce_event(agent_name, result, context.branch),
240
+ context,
241
+ )
242
+ if event.event_type == EventType.TEXT_OUTPUT:
243
+ output_parts.append(event.data)
244
+ yield event
245
+ except Exception as exc:
246
+ yield AgentEvent(
247
+ agent_name=agent_name,
248
+ event_type=EventType.ERROR,
249
+ data=str(exc),
250
+ branch=context.branch,
251
+ metadata={"exception_type": type(exc).__name__},
252
+ )
253
+ raise
254
+
255
+ if output_parts:
256
+ context.set(f"{agent_name}_output", self._merge_output_parts(output_parts))
257
+
258
+ async def _run_hook(
259
+ self,
260
+ hook: Callable[[OrchestrationContext], Any] | None,
261
+ context: OrchestrationContext,
262
+ ) -> AsyncIterator[AgentEvent]:
263
+ if hook is None:
264
+ return
265
+
266
+ result = hook(context)
267
+ if inspect.isawaitable(result):
268
+ result = await result
269
+
270
+ if result is None:
271
+ return
272
+
273
+ if isinstance(result, (list, tuple)):
274
+ for item in result:
275
+ yield self._coerce_event(self.name, item, context.branch)
276
+ return
277
+
278
+ yield self._coerce_event(self.name, result, context.branch)
279
+
280
+ @staticmethod
281
+ def _build_runner_input(context: OrchestrationContext) -> dict[str, Any]:
282
+ return {
283
+ "input": context.get("input", ""),
284
+ "state": dict(context.state),
285
+ "session_id": context.session_id,
286
+ "branch": context.branch,
287
+ }
288
+
289
+ @staticmethod
290
+ def _merge_output_parts(parts: list[Any]) -> Any:
291
+ if all(isinstance(part, str) for part in parts):
292
+ return "".join(parts)
293
+ if len(parts) == 1:
294
+ return parts[0]
295
+ return parts
296
+
297
+ @classmethod
298
+ def _coerce_event(
299
+ cls,
300
+ agent_name: str,
301
+ payload: Any,
302
+ branch: str,
303
+ ) -> AgentEvent:
304
+ if isinstance(payload, AgentEvent):
305
+ event = payload
306
+ if not event.agent_name:
307
+ event = replace(event, agent_name=agent_name)
308
+ if not event.branch:
309
+ event = replace(event, branch=branch)
310
+ return event
311
+
312
+ if isinstance(payload, dict):
313
+ raw_event_type = payload.get("event_type")
314
+ event_type = cls._coerce_event_type(raw_event_type)
315
+ data = payload.get("data")
316
+ if data is None:
317
+ data = payload.get("output", payload.get("delta"))
318
+ state_delta = dict(payload.get("state_delta", {}))
319
+ metadata = dict(payload.get("metadata", {}))
320
+
321
+ if "type" in payload and "chunk_type" not in metadata:
322
+ metadata["chunk_type"] = payload["type"]
323
+
324
+ if event_type is None:
325
+ event_type = (
326
+ EventType.STATE_CHANGE
327
+ if state_delta and data is None
328
+ else EventType.TEXT_OUTPUT
329
+ )
330
+
331
+ if data is None and event_type == EventType.STATE_CHANGE and state_delta:
332
+ data = state_delta
333
+
334
+ escalate = bool(payload.get("escalate", False) or event_type == EventType.ESCALATE)
335
+ return AgentEvent(
336
+ agent_name=agent_name,
337
+ event_type=event_type,
338
+ data=data,
339
+ branch=branch,
340
+ metadata=metadata,
341
+ state_delta=state_delta,
342
+ escalate=escalate,
343
+ )
344
+
345
+ return AgentEvent(
346
+ agent_name=agent_name,
347
+ event_type=EventType.TEXT_OUTPUT,
348
+ data=payload,
349
+ branch=branch,
350
+ )
351
+
352
+ @staticmethod
353
+ def _coerce_event_type(raw_event_type: Any) -> EventType | None:
354
+ if raw_event_type is None:
355
+ return None
356
+ if isinstance(raw_event_type, EventType):
357
+ return raw_event_type
358
+ return EventType(str(raw_event_type))
359
+
360
+ @staticmethod
361
+ def _ensure_event_branch(event: AgentEvent, branch: str) -> AgentEvent:
362
+ if event.branch or not branch:
363
+ return event
364
+ return replace(event, branch=branch)
365
+
366
+ @staticmethod
367
+ def _apply_event_state(event: AgentEvent, context: OrchestrationContext) -> AgentEvent:
368
+ if event.state_delta:
369
+ context.update(event.state_delta)
370
+ return event