agentengine-sdk-python 0.6.4__py3-none-any.whl → 0.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. agentengine_sdk_python-0.7.0.dist-info/METADATA +181 -0
  2. agentengine_sdk_python-0.7.0.dist-info/RECORD +482 -0
  3. {agentengine_sdk_python-0.6.4.dist-info → agentengine_sdk_python-0.7.0.dist-info}/WHEEL +1 -1
  4. agentengine_sdk_python-0.7.0.dist-info/entry_points.txt +3 -0
  5. agentengine_sdk_python-0.7.0.dist-info/licenses/LICENSE +175 -0
  6. agentengine_sdk_python-0.7.0.dist-info/top_level.txt +2 -0
  7. ksadk/__init__.py +13 -0
  8. ksadk/__main__.py +4 -0
  9. ksadk/a2a/__init__.py +15 -0
  10. ksadk/a2a/card_builder.py +64 -0
  11. ksadk/a2a/client.py +309 -0
  12. ksadk/a2a/executor.py +201 -0
  13. ksadk/a2a/server.py +79 -0
  14. ksadk/agents/__init__.py +20 -0
  15. ksadk/agents/base.py +370 -0
  16. ksadk/agents/context.py +38 -0
  17. ksadk/agents/event.py +35 -0
  18. ksadk/agents/loop_agent.py +71 -0
  19. ksadk/agents/parallel_agent.py +109 -0
  20. ksadk/agents/runner_adapter.py +24 -0
  21. ksadk/agents/sequential_agent.py +34 -0
  22. ksadk/api/__init__.py +3 -0
  23. ksadk/api/client.py +2246 -0
  24. ksadk/builders/__init__.py +20 -0
  25. ksadk/builders/base.py +66 -0
  26. ksadk/builders/code_builder.py +1990 -0
  27. ksadk/builders/container_builder.py +786 -0
  28. ksadk/builders/framework_requirements.py +59 -0
  29. ksadk/builders/ks3_uploader.py +389 -0
  30. ksadk/builders/mcp_builder.py +476 -0
  31. ksadk/builders/requirements_utils.py +75 -0
  32. ksadk/cli/__init__.py +531 -0
  33. ksadk/cli/__main__.py +4 -0
  34. ksadk/cli/agent_ref.py +204 -0
  35. ksadk/cli/cmd_a2a.py +167 -0
  36. ksadk/cli/cmd_agent.py +201 -0
  37. ksadk/cli/cmd_build.py +270 -0
  38. ksadk/cli/cmd_completion.py +304 -0
  39. ksadk/cli/cmd_config.py +758 -0
  40. ksadk/cli/cmd_create.py +2304 -0
  41. ksadk/cli/cmd_dashboard.py +900 -0
  42. ksadk/cli/cmd_deploy.py +704 -0
  43. ksadk/cli/cmd_destroy.py +345 -0
  44. ksadk/cli/cmd_files.py +1227 -0
  45. ksadk/cli/cmd_hermes.py +1263 -0
  46. ksadk/cli/cmd_invoke.py +1503 -0
  47. ksadk/cli/cmd_launch.py +564 -0
  48. ksadk/cli/cmd_mcp.py +1179 -0
  49. ksadk/cli/cmd_model.py +302 -0
  50. ksadk/cli/cmd_openclaw.py +3922 -0
  51. ksadk/cli/cmd_run.py +239 -0
  52. ksadk/cli/cmd_status.py +588 -0
  53. ksadk/cli/cmd_version.py +522 -0
  54. ksadk/cli/cmd_web.py +288 -0
  55. ksadk/cli/deploy_utils.py +87 -0
  56. ksadk/cli/dry_run.py +214 -0
  57. ksadk/cli/env_options.py +82 -0
  58. ksadk/cli/error_utils.py +525 -0
  59. ksadk/cli/global_options.py +31 -0
  60. ksadk/cli/local_runtime.py +97 -0
  61. ksadk/cli/model_catalog.py +136 -0
  62. ksadk/cli/network_options.py +412 -0
  63. ksadk/cli/resource_common.py +621 -0
  64. ksadk/cli/storage.py +84 -0
  65. ksadk/cli/ui.py +431 -0
  66. ksadk/cli/workflow_common.py +552 -0
  67. ksadk/common/__init__.py +14 -0
  68. ksadk/common/aicp_env.py +128 -0
  69. ksadk/common/auth.py +190 -0
  70. ksadk/common/constants.py +84 -0
  71. ksadk/common/llm_utils.py +61 -0
  72. ksadk/configs/__init__.py +61 -0
  73. ksadk/configs/env_registry.py +343 -0
  74. ksadk/configs/global_config.py +200 -0
  75. ksadk/configs/settings.py +706 -0
  76. ksadk/conversations/__init__.py +95 -0
  77. ksadk/conversations/attachment_storage.py +379 -0
  78. ksadk/conversations/attachments.py +774 -0
  79. ksadk/conversations/compaction_pipeline.py +387 -0
  80. ksadk/conversations/compaction_prompt.py +128 -0
  81. ksadk/conversations/context.py +303 -0
  82. ksadk/conversations/message_projection.py +269 -0
  83. ksadk/conversations/model_context.py +370 -0
  84. ksadk/conversations/model_options.py +136 -0
  85. ksadk/conversations/normalize.py +446 -0
  86. ksadk/conversations/reasoning_markup.py +91 -0
  87. ksadk/conversations/run_kinds.py +61 -0
  88. ksadk/conversations/run_status.py +53 -0
  89. ksadk/conversations/runtime.py +5276 -0
  90. ksadk/conversations/semantic_summary.py +359 -0
  91. ksadk/conversations/session_title.py +254 -0
  92. ksadk/deployment/__init__.py +83 -0
  93. ksadk/deployment/agent_access.py +226 -0
  94. ksadk/deployment/base.py +229 -0
  95. ksadk/deployment/manager.py +332 -0
  96. ksadk/deployment/providers/__init__.py +10 -0
  97. ksadk/deployment/providers/serverless.py +1115 -0
  98. ksadk/deployment/registry.py +120 -0
  99. ksadk/deployment/state.py +78 -0
  100. ksadk/deployment/ui_config.py +21 -0
  101. ksadk/detection/__init__.py +7 -0
  102. ksadk/detection/detector.py +431 -0
  103. ksadk/detection/mcp_detector.py +250 -0
  104. ksadk/hermes_terminal.py +467 -0
  105. ksadk/identity/__init__.py +17 -0
  106. ksadk/identity/resolver.py +385 -0
  107. ksadk/knowledge_base/__init__.py +62 -0
  108. ksadk/knowledge_base/adk_tool.py +47 -0
  109. ksadk/knowledge_base/client.py +297 -0
  110. ksadk/knowledge_base/langchain_tool.py +55 -0
  111. ksadk/knowledge_base/service.py +66 -0
  112. ksadk/knowledge_base/tool.py +50 -0
  113. ksadk/markdown.py +169 -0
  114. ksadk/mcp_runtime/__init__.py +231 -0
  115. ksadk/memory/__init__.py +57 -0
  116. ksadk/memory/adk/__init__.py +51 -0
  117. ksadk/memory/adk/backends/__init__.py +5 -0
  118. ksadk/memory/adk/backends/base_ltm_backend.py +52 -0
  119. ksadk/memory/adk/backends/http_ltm_backend.py +183 -0
  120. ksadk/memory/adk/backends/inmemory_ltm_backend.py +96 -0
  121. ksadk/memory/adk/backends/sdk_ltm_backend.py +456 -0
  122. ksadk/memory/adk/long_term_memory.py +273 -0
  123. ksadk/memory/adk/resilient_session_service.py +268 -0
  124. ksadk/memory/adk/short_term_memory.py +304 -0
  125. ksadk/memory/adk_tool.py +31 -0
  126. ksadk/memory/backends/__init__.py +6 -0
  127. ksadk/memory/backends/base.py +103 -0
  128. ksadk/memory/backends/memory.py +112 -0
  129. ksadk/memory/backends/redis.py +146 -0
  130. ksadk/memory/langchain_tool.py +39 -0
  131. ksadk/memory/ltm_backend_factory.py +24 -0
  132. ksadk/memory/manager.py +215 -0
  133. ksadk/memory/service.py +172 -0
  134. ksadk/memory/tool.py +96 -0
  135. ksadk/model_policy.py +223 -0
  136. ksadk/openclaw_gateway.py +378 -0
  137. ksadk/runners/__init__.py +8 -0
  138. ksadk/runners/adk_runner.py +1994 -0
  139. ksadk/runners/base_runner.py +305 -0
  140. ksadk/runners/deepagents_runner.py +13 -0
  141. ksadk/runners/factory.py +73 -0
  142. ksadk/runners/langchain_runner.py +751 -0
  143. ksadk/runners/langgraph_runner.py +985 -0
  144. ksadk/runners/patch_langchain.py +187 -0
  145. ksadk/runners/remote_runner.py +792 -0
  146. ksadk/runners/usage_accumulator.py +38 -0
  147. ksadk/runners/utils/__init__.py +19 -0
  148. ksadk/runners/utils/langfuse.py +230 -0
  149. ksadk/runners/utils/loader.py +62 -0
  150. ksadk/runtime_context.py +166 -0
  151. ksadk/runtime_state.py +25 -0
  152. ksadk/sandbox/__init__.py +28 -0
  153. ksadk/sandbox/backends/__init__.py +9 -0
  154. ksadk/sandbox/backends/e2b.py +154 -0
  155. ksadk/sandbox/backends/local_process.py +131 -0
  156. ksadk/sandbox/base.py +101 -0
  157. ksadk/sandbox/factory.py +53 -0
  158. ksadk/sandbox/registry.py +187 -0
  159. ksadk/server/__init__.py +7 -0
  160. ksadk/server/api_models.py +73 -0
  161. ksadk/server/app.py +3931 -0
  162. ksadk/server/static/assets/ArtifactsPanel-D-SSn2ee.js +1 -0
  163. ksadk/server/static/assets/CodeBlock-P16VOLYi.js +9 -0
  164. ksadk/server/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  165. ksadk/server/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  166. ksadk/server/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  167. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  168. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  169. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  170. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  171. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  172. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  173. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  174. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  175. ksadk/server/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  176. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  177. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  178. ksadk/server/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  179. ksadk/server/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  180. ksadk/server/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  181. ksadk/server/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  182. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  183. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  184. ksadk/server/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  185. ksadk/server/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  186. ksadk/server/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  187. ksadk/server/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  188. ksadk/server/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  189. ksadk/server/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  190. ksadk/server/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  191. ksadk/server/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  192. ksadk/server/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  193. ksadk/server/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  194. ksadk/server/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  195. ksadk/server/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  196. ksadk/server/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  197. ksadk/server/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  198. ksadk/server/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  199. ksadk/server/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  200. ksadk/server/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  201. ksadk/server/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  202. ksadk/server/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  203. ksadk/server/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  204. ksadk/server/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  205. ksadk/server/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  206. ksadk/server/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  207. ksadk/server/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  208. ksadk/server/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  209. ksadk/server/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  210. ksadk/server/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  211. ksadk/server/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  212. ksadk/server/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  213. ksadk/server/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  214. ksadk/server/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  215. ksadk/server/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  216. ksadk/server/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  217. ksadk/server/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  218. ksadk/server/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  219. ksadk/server/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  220. ksadk/server/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  221. ksadk/server/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  222. ksadk/server/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  223. ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +8 -0
  224. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +1 -0
  225. ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +303 -0
  226. ksadk/server/static/assets/NativeTerminalPanel-CHOd7Rch.css +1 -0
  227. ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +1 -0
  228. ksadk/server/static/assets/addon-fit-DthTIhi3.js +1 -0
  229. ksadk/server/static/assets/apl-CnwPGSsG.js +1 -0
  230. ksadk/server/static/assets/arc-BA13sHc9.js +1 -0
  231. ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +1 -0
  232. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-DzJzgVoL.js +36 -0
  233. ksadk/server/static/assets/asciiarmor-qTkVPQu6.js +1 -0
  234. ksadk/server/static/assets/asn1-Dr8qZg38.js +1 -0
  235. ksadk/server/static/assets/asterisk-Bja0s6e1.js +1 -0
  236. ksadk/server/static/assets/blockDiagram-GPEHLZMM-UTdVcZhn.js +132 -0
  237. ksadk/server/static/assets/brainfuck-D5EjA2JK.js +1 -0
  238. ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dix0GD4m.js +10 -0
  239. ksadk/server/static/assets/channel-CTuydARX.js +1 -0
  240. ksadk/server/static/assets/chunk-2J33WTMH-C2JxuZ42.js +1 -0
  241. ksadk/server/static/assets/chunk-4BX2VUAB-Be57QPgD.js +1 -0
  242. ksadk/server/static/assets/chunk-55IACEB6-WjSuy4nv.js +1 -0
  243. ksadk/server/static/assets/chunk-727SXJPM-BOovP-b5.js +206 -0
  244. ksadk/server/static/assets/chunk-AQP2D5EJ-DOmZNmWj.js +231 -0
  245. ksadk/server/static/assets/chunk-FMBD7UC4-DzwlodkU.js +15 -0
  246. ksadk/server/static/assets/chunk-ND2GUHAM-DMqAikEU.js +1 -0
  247. ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +1 -0
  248. ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +1 -0
  249. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +1 -0
  250. ksadk/server/static/assets/clike-DHH8Ad3s.js +1 -0
  251. ksadk/server/static/assets/clojure-BflJGmDX.js +1 -0
  252. ksadk/server/static/assets/cmake-CyVbuzPu.js +1 -0
  253. ksadk/server/static/assets/cobol-B_OZ4V-R.js +1 -0
  254. ksadk/server/static/assets/coffeescript-B2pKbFk8.js +1 -0
  255. ksadk/server/static/assets/commonlisp-CcllspGY.js +1 -0
  256. ksadk/server/static/assets/cose-bilkent-S5V4N54A-Zhy2GBnP.js +1 -0
  257. ksadk/server/static/assets/crystal-M5-qzICs.js +1 -0
  258. ksadk/server/static/assets/css-CYpP4FRV.js +1 -0
  259. ksadk/server/static/assets/cypher-p9eYesGn.js +1 -0
  260. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +321 -0
  261. ksadk/server/static/assets/d-BhMjBjQP.js +1 -0
  262. ksadk/server/static/assets/dagre-BM42HDAG-CbKrtIUz.js +4 -0
  263. ksadk/server/static/assets/dagre-Bx709z4p.js +1 -0
  264. ksadk/server/static/assets/defaultLocale-C8Fc0cco.js +1 -0
  265. ksadk/server/static/assets/diagram-2AECGRRQ-BRApgQRK.js +43 -0
  266. ksadk/server/static/assets/diagram-5GNKFQAL-D0xbnDiK.js +10 -0
  267. ksadk/server/static/assets/diagram-KO2AKTUF-CVugVI9L.js +3 -0
  268. ksadk/server/static/assets/diagram-LMA3HP47-DozUGgee.js +24 -0
  269. ksadk/server/static/assets/diagram-OG6HWLK6-ZOYsKlru.js +24 -0
  270. ksadk/server/static/assets/diff-ChtP43wD.js +1 -0
  271. ksadk/server/static/assets/dist-2hInLS_J.js +9 -0
  272. ksadk/server/static/assets/dist-8EEyGgDx.js +1 -0
  273. ksadk/server/static/assets/dist-8_SfK1IP.js +1 -0
  274. ksadk/server/static/assets/dist-B0NP_Z0z.js +23 -0
  275. ksadk/server/static/assets/dist-BIJVDMuB.js +1 -0
  276. ksadk/server/static/assets/dist-BmlMPsCc.js +2 -0
  277. ksadk/server/static/assets/dist-BrCcQ47T.js +1 -0
  278. ksadk/server/static/assets/dist-BssVmjIo.js +6 -0
  279. ksadk/server/static/assets/dist-C3HIIaN5.js +1 -0
  280. ksadk/server/static/assets/dist-CPBtqRTW.js +1 -0
  281. ksadk/server/static/assets/dist-CkEKJFtk.js +1 -0
  282. ksadk/server/static/assets/dist-D-JMdWPQ.js +1 -0
  283. ksadk/server/static/assets/dist-D-xOD048.js +1 -0
  284. ksadk/server/static/assets/dist-D57wnGWd.js +1 -0
  285. ksadk/server/static/assets/dist-DL_NKc_z.js +1 -0
  286. ksadk/server/static/assets/dist-DMezvBGJ.js +1 -0
  287. ksadk/server/static/assets/dist-DmFaq_Iy.js +1 -0
  288. ksadk/server/static/assets/dist-Dp0k7bWI.js +1 -0
  289. ksadk/server/static/assets/dist-DpKtt4Bo.js +1 -0
  290. ksadk/server/static/assets/dist-DyOkZmze.js +11 -0
  291. ksadk/server/static/assets/dist-DyWsb78Q.js +1 -0
  292. ksadk/server/static/assets/dist-gX6GOLKq.js +1 -0
  293. ksadk/server/static/assets/dockerfile-BLkNEvjs.js +1 -0
  294. ksadk/server/static/assets/dtd-DTF72YNO.js +1 -0
  295. ksadk/server/static/assets/dylan-C6jEEEk-.js +1 -0
  296. ksadk/server/static/assets/ebnf-D4c0_ac3.js +1 -0
  297. ksadk/server/static/assets/ecl-BSZaIHnp.js +1 -0
  298. ksadk/server/static/assets/eiffel-BEjRio4Q.js +1 -0
  299. ksadk/server/static/assets/elm-Cshzl8qu.js +1 -0
  300. ksadk/server/static/assets/erDiagram-TEJ5UH35-Bk-9bgE5.js +85 -0
  301. ksadk/server/static/assets/erlang-DaB2Rkuy.js +1 -0
  302. ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +1 -0
  303. ksadk/server/static/assets/factor-D7LVTn2l.js +1 -0
  304. ksadk/server/static/assets/fcl-ClOhbFR7.js +1 -0
  305. ksadk/server/static/assets/flowDiagram-I6XJVG4X-Dn9kZVuZ.js +162 -0
  306. ksadk/server/static/assets/forth-Cezjo90N.js +1 -0
  307. ksadk/server/static/assets/fortran-Bt6PBEDR.js +1 -0
  308. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-BGxXlJqm.js +292 -0
  309. ksadk/server/static/assets/gas-BHEdbvp9.js +1 -0
  310. ksadk/server/static/assets/gherkin-oBAE_ms0.js +1 -0
  311. ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +1 -0
  312. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-C7Q0X-wi.js +106 -0
  313. ksadk/server/static/assets/graphlib-B8gBHxth.js +1 -0
  314. ksadk/server/static/assets/groovy-BC3IOsC8.js +1 -0
  315. ksadk/server/static/assets/haskell-BRsoo5mP.js +1 -0
  316. ksadk/server/static/assets/haxe-DIz0ZZqd.js +1 -0
  317. ksadk/server/static/assets/http-CLVgA2GD.js +1 -0
  318. ksadk/server/static/assets/idl-BUZw3wgd.js +1 -0
  319. ksadk/server/static/assets/index-C00Lwg3L.js +165 -0
  320. ksadk/server/static/assets/index-DAURbCsP.css +1 -0
  321. ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +1 -0
  322. ksadk/server/static/assets/infoDiagram-5YYISTIA-BO_CSqq5.js +2 -0
  323. ksadk/server/static/assets/init-D6jRqBbL.js +1 -0
  324. ksadk/server/static/assets/ishikawaDiagram-YF4QCWOH-eYLPLd46.js +70 -0
  325. ksadk/server/static/assets/javascript-9Tg8ixDm.js +1 -0
  326. ksadk/server/static/assets/journeyDiagram-JHISSGLW-De9geSb0.js +139 -0
  327. ksadk/server/static/assets/julia-CQfgDRfP.js +1 -0
  328. ksadk/server/static/assets/kanban-definition-UN3LZRKU-Cs80kQto.js +89 -0
  329. ksadk/server/static/assets/katex-DSrCFD8n.js +265 -0
  330. ksadk/server/static/assets/linear-CN9sbKTF.js +1 -0
  331. ksadk/server/static/assets/livescript-BXxG0Yva.js +1 -0
  332. ksadk/server/static/assets/lua-CiA1ziua.js +1 -0
  333. ksadk/server/static/assets/mathematica-u8YMmbU0.js +1 -0
  334. ksadk/server/static/assets/mbox-BEMVcqjs.js +1 -0
  335. ksadk/server/static/assets/mermaid-parser.core-DlgSBU8l.js +161 -0
  336. ksadk/server/static/assets/mindmap-definition-RKZ34NQL-9afz7Oug.js +96 -0
  337. ksadk/server/static/assets/mirc-C9zpzAZU.js +1 -0
  338. ksadk/server/static/assets/mllike-B45xgp2S.js +1 -0
  339. ksadk/server/static/assets/modelica-CqHI_q-D.js +1 -0
  340. ksadk/server/static/assets/mscgen-qgSLujhx.js +1 -0
  341. ksadk/server/static/assets/mumps-CW_TBmxz.js +1 -0
  342. ksadk/server/static/assets/nginx-BMaDbqW3.js +1 -0
  343. ksadk/server/static/assets/nsis-AQ_alPln.js +1 -0
  344. ksadk/server/static/assets/ntriples-d28e9m0E.js +1 -0
  345. ksadk/server/static/assets/octave-D2Q8cUp1.js +1 -0
  346. ksadk/server/static/assets/ordinal-hYBb2elL.js +1 -0
  347. ksadk/server/static/assets/oz-BwTct_5T.js +1 -0
  348. ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +1 -0
  349. ksadk/server/static/assets/pascal-Dp_KdFgX.js +1 -0
  350. ksadk/server/static/assets/perl-CdEHsPfU.js +1 -0
  351. ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +1 -0
  352. ksadk/server/static/assets/pieDiagram-4H26LBE5-DPv_VstN.js +30 -0
  353. ksadk/server/static/assets/pig-AF4Hwhju.js +1 -0
  354. ksadk/server/static/assets/powershell-CzG71I4L.js +1 -0
  355. ksadk/server/static/assets/properties-C357ku5U.js +1 -0
  356. ksadk/server/static/assets/protobuf-D1ij_kNL.js +1 -0
  357. ksadk/server/static/assets/pug-Bugr-47h.js +1 -0
  358. ksadk/server/static/assets/puppet-B4hC2X4m.js +1 -0
  359. ksadk/server/static/assets/python-BqYw9LYJ.js +1 -0
  360. ksadk/server/static/assets/q-B9NhS7L_.js +1 -0
  361. ksadk/server/static/assets/quadrantDiagram-W4KKPZXB-o77wZ1XK.js +7 -0
  362. ksadk/server/static/assets/r-DADKenSm.js +1 -0
  363. ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +1 -0
  364. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-BYVw81VC.js +84 -0
  365. ksadk/server/static/assets/rpm-gpDK5sbt.js +1 -0
  366. ksadk/server/static/assets/ruby-DsYpTuWg.js +1 -0
  367. ksadk/server/static/assets/sankeyDiagram-5OEKKPKP-B7nZFMKT.js +40 -0
  368. ksadk/server/static/assets/sas-C2OyD2Y6.js +1 -0
  369. ksadk/server/static/assets/scheme-CyDdOh7e.js +1 -0
  370. ksadk/server/static/assets/sequenceDiagram-3UESZ5HK-BGRRrFw5.js +162 -0
  371. ksadk/server/static/assets/shell-Du5Qg9im.js +1 -0
  372. ksadk/server/static/assets/sieve-BAxa3IjF.js +1 -0
  373. ksadk/server/static/assets/simple-mode-DRpGK0lJ.js +1 -0
  374. ksadk/server/static/assets/smalltalk-BLp5-jwC.js +1 -0
  375. ksadk/server/static/assets/solr-BBopId9w.js +1 -0
  376. ksadk/server/static/assets/sparql-Dz-mlCAC.js +1 -0
  377. ksadk/server/static/assets/spreadsheet-CTIncYxj.js +1 -0
  378. ksadk/server/static/assets/sql-DcCJ9jop.js +1 -0
  379. ksadk/server/static/assets/stateDiagram-AJRCARHV-BUfHCoPs.js +1 -0
  380. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +1 -0
  381. ksadk/server/static/assets/stex-sDrdk2BW.js +1 -0
  382. ksadk/server/static/assets/stylus-DLLZ8dgm.js +1 -0
  383. ksadk/server/static/assets/swift-DKB6_1j6.js +1 -0
  384. ksadk/server/static/assets/tcl-BGfruO1u.js +1 -0
  385. ksadk/server/static/assets/textile-DWBqthVk.js +1 -0
  386. ksadk/server/static/assets/tiddlywiki-VlUiK86J.js +1 -0
  387. ksadk/server/static/assets/tiki-CxVlf5KZ.js +1 -0
  388. ksadk/server/static/assets/timeline-definition-PNZ67QCA-FbCTGrf9.js +120 -0
  389. ksadk/server/static/assets/toml-LvoKBwCs.js +1 -0
  390. ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +1 -0
  391. ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +1 -0
  392. ksadk/server/static/assets/troff-C2dAgh7P.js +1 -0
  393. ksadk/server/static/assets/ttcn-BePYh-hG.js +1 -0
  394. ksadk/server/static/assets/ttcn-cfg-CY0aot7Q.js +1 -0
  395. ksadk/server/static/assets/turtle-BDLWE2cD.js +1 -0
  396. ksadk/server/static/assets/vb-BthdM_4N.js +1 -0
  397. ksadk/server/static/assets/vbscript-D9f6rSsU.js +1 -0
  398. ksadk/server/static/assets/velocity-CqftRsjg.js +1 -0
  399. ksadk/server/static/assets/vennDiagram-CIIHVFJN-DWgwtPsJ.js +34 -0
  400. ksadk/server/static/assets/verilog-D-x6ne0Z.js +1 -0
  401. ksadk/server/static/assets/vhdl-CMrOq2q1.js +1 -0
  402. ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +1 -0
  403. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-2x8G-tTM.js +78 -0
  404. ksadk/server/static/assets/webidl-D5jiJvOU.js +1 -0
  405. ksadk/server/static/assets/xquery-fj_R-kMw.js +1 -0
  406. ksadk/server/static/assets/xterm-DooSxjI5.js +36 -0
  407. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-Drma3AYl.js +7 -0
  408. ksadk/server/static/assets/yacas-CXXgtw0p.js +1 -0
  409. ksadk/server/static/assets/z80-CL1naaMV.js +1 -0
  410. ksadk/server/static/favicon.svg +1 -0
  411. ksadk/server/static/icons.svg +24 -0
  412. ksadk/server/static/index.html +14 -0
  413. ksadk/server/terminal_sessions.py +551 -0
  414. ksadk/sessions/__init__.py +279 -0
  415. ksadk/sessions/base.py +354 -0
  416. ksadk/sessions/continuity.py +337 -0
  417. ksadk/sessions/errors.py +7 -0
  418. ksadk/sessions/in_memory.py +273 -0
  419. ksadk/sessions/local_service.py +949 -0
  420. ksadk/sessions/postgres_service.py +901 -0
  421. ksadk/sessions/resilience.py +52 -0
  422. ksadk/sessions/resilient.py +360 -0
  423. ksadk/sessions/sqlite_service.py +13 -0
  424. ksadk/skills/__init__.py +9 -0
  425. ksadk/skills/loader.py +46 -0
  426. ksadk/skills/models.py +120 -0
  427. ksadk/skills/package_store.py +104 -0
  428. ksadk/skills/runtime/__init__.py +17 -0
  429. ksadk/skills/runtime/agent.py +183 -0
  430. ksadk/skills/runtime/artifacts.py +39 -0
  431. ksadk/skills/runtime/backends/__init__.py +1 -0
  432. ksadk/skills/runtime/backends/disabled.py +8 -0
  433. ksadk/skills/runtime/backends/e2b.py +168 -0
  434. ksadk/skills/runtime/backends/local.py +95 -0
  435. ksadk/skills/runtime/base.py +103 -0
  436. ksadk/skills/runtime/executor.py +219 -0
  437. ksadk/skills/runtime/factory.py +37 -0
  438. ksadk/skills/runtime/loader.py +131 -0
  439. ksadk/skills/runtime/registry.py +150 -0
  440. ksadk/skills/runtime/request.py +67 -0
  441. ksadk/skills/service_client.py +239 -0
  442. ksadk/skills/service_env.py +58 -0
  443. ksadk/skills/tool_defs.py +221 -0
  444. ksadk/terminal_client.py +69 -0
  445. ksadk/terminal_exec_policy.py +229 -0
  446. ksadk/tools/__init__.py +17 -0
  447. ksadk/tools/gateway.py +230 -0
  448. ksadk/tools/result_budget.py +154 -0
  449. ksadk/toolsets/__init__.py +854 -0
  450. ksadk/toolsets/_langchain.py +11 -0
  451. ksadk/toolsets/platform.py +93 -0
  452. ksadk/toolsets/sandbox.py +310 -0
  453. ksadk/toolsets/skills.py +217 -0
  454. ksadk/toolsets/web.py +266 -0
  455. ksadk/toolsets/workspace.py +917 -0
  456. ksadk/toolsets/workspace_state.py +44 -0
  457. ksadk/tracing/__init__.py +37 -0
  458. ksadk/tracing/exporters/__init__.py +1 -0
  459. ksadk/tracing/exporters/inmemory_exporter.py +116 -0
  460. ksadk/tracing/exporters/langfuse_exporter.py +445 -0
  461. ksadk/tracing/setup.py +892 -0
  462. ksadk/tracing/span_utils.py +114 -0
  463. ksadk/tui/__init__.py +27 -0
  464. ksadk/tui/loop.py +1877 -0
  465. ksadk/tui/stream_render.py +68 -0
  466. ksadk/ui_config.py +168 -0
  467. ksadk/version.py +4 -0
  468. ksadk_runtime_common/__init__.py +20 -0
  469. ksadk_runtime_common/memory_backend/__init__.py +29 -0
  470. ksadk_runtime_common/memory_backend/manifest.py +79 -0
  471. ksadk_runtime_common/memory_backend/providers/__init__.py +6 -0
  472. ksadk_runtime_common/memory_backend/providers/lancedb.py +151 -0
  473. ksadk_runtime_common/memory_backend/providers/mem0.py +74 -0
  474. ksadk_runtime_common/memory_backend/registry.py +56 -0
  475. ksadk_runtime_common/memory_backend/render.py +71 -0
  476. ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -0
  477. ksadk_runtime_common/workspace_files/__init__.py +29 -0
  478. ksadk_runtime_common/workspace_files/bootstrap.py +56 -0
  479. ksadk_runtime_common/workspace_files/constants.py +9 -0
  480. ksadk_runtime_common/workspace_files/path_utils.py +71 -0
  481. ksadk_runtime_common/workspace_files/preview.py +96 -0
  482. ksadk_runtime_common/workspace_files/router.py +254 -0
  483. agentengine_sdk_python/__init__.py +0 -3
  484. agentengine_sdk_python-0.6.4.dist-info/METADATA +0 -48
  485. agentengine_sdk_python-0.6.4.dist-info/RECORD +0 -5
  486. agentengine_sdk_python-0.6.4.dist-info/top_level.txt +0 -1
ksadk/model_policy.py ADDED
@@ -0,0 +1,223 @@
1
+ from __future__ import annotations
2
+
3
+ import copy
4
+ import json
5
+ import os
6
+ from typing import Any, Mapping
7
+
8
+ from ksadk.configs.settings import DEFAULT_MODEL_NAME
9
+
10
+ DEFAULT_MULTIMODAL_MODEL = "kimi-k2.7-code"
11
+ DEFAULT_FALLBACK_MODEL = "deepseek-v4-pro"
12
+
13
+ DEFAULT_MODEL_POLICY: dict[str, Any] = {
14
+ "version": "v1",
15
+ "primary": {"model": DEFAULT_MODEL_NAME},
16
+ "multimodal": {"model": DEFAULT_MULTIMODAL_MODEL},
17
+ "fallback": {
18
+ "model": DEFAULT_FALLBACK_MODEL,
19
+ "fallback_errors": [
20
+ "timeout",
21
+ "temporarily unavailable",
22
+ "temporary unavailable",
23
+ "model unavailable",
24
+ "rate limit",
25
+ "too many requests",
26
+ "503",
27
+ "504",
28
+ ],
29
+ "on_errors": [
30
+ "timeout",
31
+ "temporarily unavailable",
32
+ "temporary unavailable",
33
+ "model unavailable",
34
+ "rate limit",
35
+ "too many requests",
36
+ "503",
37
+ "504",
38
+ ],
39
+ },
40
+ "models": {
41
+ DEFAULT_MODEL_NAME: {
42
+ "reasoning": True,
43
+ "options": {},
44
+ },
45
+ DEFAULT_MULTIMODAL_MODEL: {
46
+ "input": ["text", "image"],
47
+ "reasoning": True,
48
+ "options": {"temperature": 1},
49
+ },
50
+ DEFAULT_FALLBACK_MODEL: {
51
+ "reasoning": True,
52
+ "options": {},
53
+ },
54
+ },
55
+ }
56
+
57
+
58
+ def _deep_merge(base: dict[str, Any], override: Mapping[str, Any]) -> dict[str, Any]:
59
+ merged = copy.deepcopy(base)
60
+ for key, value in override.items():
61
+ if (
62
+ isinstance(value, Mapping)
63
+ and isinstance(merged.get(key), dict)
64
+ ):
65
+ merged[key] = _deep_merge(merged[key], value)
66
+ else:
67
+ merged[key] = copy.deepcopy(value)
68
+ return merged
69
+
70
+
71
+ def normalize_model_policy(raw: str | Mapping[str, Any] | None = None) -> dict[str, Any]:
72
+ if raw is None or raw == "":
73
+ return copy.deepcopy(DEFAULT_MODEL_POLICY)
74
+ if isinstance(raw, str):
75
+ try:
76
+ parsed = json.loads(raw)
77
+ except json.JSONDecodeError:
78
+ return copy.deepcopy(DEFAULT_MODEL_POLICY)
79
+ else:
80
+ parsed = raw
81
+ if not isinstance(parsed, Mapping):
82
+ return copy.deepcopy(DEFAULT_MODEL_POLICY)
83
+ normalized = _deep_merge(DEFAULT_MODEL_POLICY, parsed)
84
+ fallback = normalized.get("fallback")
85
+ if isinstance(fallback, dict):
86
+ raw_errors = fallback.get("fallback_errors") or fallback.get("on_errors")
87
+ if isinstance(raw_errors, list):
88
+ fallback["fallback_errors"] = list(raw_errors)
89
+ fallback["on_errors"] = list(raw_errors)
90
+ return normalized
91
+
92
+
93
+ def _unqualified_model_name(model: str) -> str:
94
+ return str(model or "").strip().rsplit("/", 1)[-1]
95
+
96
+
97
+ def model_policy_options_for_model(
98
+ model: str,
99
+ policy: str | Mapping[str, Any] | None = None,
100
+ ) -> dict[str, Any]:
101
+ normalized = normalize_model_policy(policy)
102
+ models = normalized.get("models")
103
+ if not isinstance(models, Mapping):
104
+ return {}
105
+
106
+ candidates = [str(model or "").strip(), _unqualified_model_name(model)]
107
+ for candidate in candidates:
108
+ config = models.get(candidate)
109
+ if isinstance(config, Mapping) and isinstance(config.get("options"), Mapping):
110
+ return dict(config["options"])
111
+ return {}
112
+
113
+
114
+ def fallback_model_for_exception(
115
+ exc: BaseException,
116
+ *,
117
+ current_model: str,
118
+ policy: str | Mapping[str, Any] | None = None,
119
+ ) -> str | None:
120
+ normalized = normalize_model_policy(policy)
121
+ fallback = normalized.get("fallback")
122
+ if not isinstance(fallback, Mapping):
123
+ return None
124
+
125
+ fallback_model = str(fallback.get("model") or "").strip()
126
+ if not fallback_model or fallback_model == str(current_model or "").strip():
127
+ return None
128
+
129
+ message = str(exc or "").strip().lower()
130
+ if not message:
131
+ return None
132
+ if "400" in message or "invalid request" in message or "bad request" in message:
133
+ return None
134
+
135
+ transient_markers = fallback.get("fallback_errors") or fallback.get("on_errors")
136
+ if not isinstance(transient_markers, list):
137
+ transient_markers = DEFAULT_MODEL_POLICY["fallback"]["on_errors"]
138
+
139
+ if any(str(marker).lower() in message for marker in transient_markers):
140
+ return fallback_model
141
+ return None
142
+
143
+
144
+ def _provider_ref(model: str, provider: str = "ksyun") -> str:
145
+ value = str(model or "").strip()
146
+ if not value or "/" in value:
147
+ return value
148
+ return f"{provider}/{value}"
149
+
150
+
151
+ def _role_model(policy: Mapping[str, Any], role: str) -> str:
152
+ value = policy.get(role)
153
+ if isinstance(value, Mapping):
154
+ return str(value.get("model") or "").strip()
155
+ return str(value or "").strip()
156
+
157
+
158
+ def _catalog_from_policy(policy: Mapping[str, Any]) -> list[dict[str, Any]]:
159
+ models = policy.get("models") if isinstance(policy.get("models"), Mapping) else {}
160
+ catalog: list[dict[str, Any]] = []
161
+ seen: set[str] = set()
162
+ for role in ("primary", "multimodal", "fallback"):
163
+ model = _role_model(policy, role)
164
+ if not model or model in seen:
165
+ continue
166
+ seen.add(model)
167
+ metadata = dict(models.get(model) or {}) if isinstance(models, Mapping) else {}
168
+ item = {
169
+ "id": model,
170
+ "name": model,
171
+ "api": metadata.get("api") or "openai-completions",
172
+ "input": metadata.get("input") or ["text"],
173
+ }
174
+ if isinstance(metadata.get("reasoning"), bool):
175
+ item["reasoning"] = metadata["reasoning"]
176
+ if isinstance(metadata.get("options"), Mapping) and metadata["options"]:
177
+ item["options"] = dict(metadata["options"])
178
+ catalog.append(item)
179
+ return catalog
180
+
181
+
182
+ def build_runtime_model_policy_env(
183
+ env_vars: Mapping[str, str] | None,
184
+ *,
185
+ runtime: str,
186
+ policy: str | Mapping[str, Any] | None = None,
187
+ ) -> dict[str, str]:
188
+ env = dict(env_vars or {})
189
+ normalized = normalize_model_policy(policy or os.getenv("AGENTENGINE_MODEL_POLICY_JSON"))
190
+ env.setdefault(
191
+ "AGENTENGINE_MODEL_POLICY_JSON",
192
+ json.dumps(normalized, ensure_ascii=False, sort_keys=True, separators=(",", ":")),
193
+ )
194
+ primary = _role_model(normalized, "primary")
195
+ fallback = _role_model(normalized, "fallback")
196
+ multimodal = _role_model(normalized, "multimodal")
197
+ has_primary = any(
198
+ str(env.get(key) or "").strip()
199
+ for key in ("OPENCLAW_DEFAULT_MODEL", "HERMES_DEFAULT_MODEL", "OPENAI_MODEL_NAME", "MODEL_NAME")
200
+ )
201
+ runtime_name = str(runtime or "").strip().lower()
202
+ if runtime_name == "openclaw":
203
+ if primary and not has_primary:
204
+ env["OPENAI_MODEL_NAME"] = _provider_ref(primary)
205
+ if fallback:
206
+ env.setdefault("OPENCLAW_FALLBACK_MODEL", _provider_ref(fallback))
207
+ if multimodal:
208
+ env.setdefault("OPENCLAW_IMAGE_MODEL", _provider_ref(multimodal))
209
+ env.setdefault("OPENCLAW_MODEL_CATALOG_JSON", json.dumps(_catalog_from_policy(normalized), ensure_ascii=False))
210
+ return env
211
+ if runtime_name == "hermes":
212
+ if primary and not has_primary:
213
+ env["OPENAI_MODEL_NAME"] = primary
214
+ env["HERMES_DEFAULT_MODEL"] = primary
215
+ if fallback:
216
+ env.setdefault("HERMES_FALLBACK_MODEL", fallback)
217
+ env.setdefault("HERMES_MODEL_CATALOG_JSON", json.dumps(_catalog_from_policy(normalized), ensure_ascii=False))
218
+ return env
219
+ if primary and not has_primary:
220
+ env["OPENAI_MODEL_NAME"] = primary
221
+ if fallback:
222
+ env.setdefault("OPENAI_FALLBACK_MODEL_NAME", fallback)
223
+ return env
@@ -0,0 +1,378 @@
1
+ """Thin OpenClaw gateway client for Dashboard short-link sessions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import json
7
+ import platform
8
+ import uuid
9
+ from dataclasses import dataclass
10
+ from typing import Any, Optional
11
+ from urllib.parse import urlsplit, urlunsplit
12
+
13
+ import requests
14
+
15
+ from ksadk.api import AgentEngineClient
16
+ from ksadk.version import VERSION as KSADK_VERSION
17
+
18
+
19
+ DEFAULT_CLIENT_NAME = "openclaw-control-ui"
20
+ DEFAULT_CLIENT_MODE = "webchat"
21
+ DEFAULT_SCOPES = ("operator.admin",)
22
+ GATEWAY_PROTOCOL_VERSION = 4
23
+
24
+
25
+ class OpenClawGatewayError(RuntimeError):
26
+ """Gateway connection or protocol error."""
27
+
28
+
29
+ class OpenClawGatewayRequestError(OpenClawGatewayError):
30
+ """Structured gateway RPC error."""
31
+
32
+ def __init__(self, message: str, *, code: Any = None, details: Any = None):
33
+ self.code = code
34
+ self.details = details
35
+ super().__init__(message)
36
+
37
+
38
+ @dataclass
39
+ class DashboardAccessInfo:
40
+ agent_id: str
41
+ agent_name: Optional[str]
42
+ access_url: str
43
+ ws_url: str
44
+ cookie_header: str
45
+ origin: str
46
+ link_id: Optional[str] = None
47
+ expires_at: Optional[str] = None
48
+
49
+
50
+ def derive_gateway_ws_url(access_url: str) -> str:
51
+ """Derive the router websocket URL from a Dashboard short-link URL."""
52
+ parsed = urlsplit((access_url or "").strip())
53
+ if not parsed.scheme or not parsed.netloc:
54
+ raise OpenClawGatewayError("Dashboard access URL is invalid")
55
+
56
+ marker = "/s/"
57
+ path = parsed.path or "/"
58
+ marker_idx = path.find(marker)
59
+ base_path = path[:marker_idx] if marker_idx >= 0 else path
60
+ if not base_path:
61
+ base_path = "/"
62
+ if not base_path.endswith("/"):
63
+ base_path = f"{base_path}/"
64
+
65
+ ws_scheme = "wss" if parsed.scheme == "https" else "ws"
66
+ return urlunsplit((ws_scheme, parsed.netloc, base_path, "", ""))
67
+
68
+
69
+ class OpenClawGatewayClient:
70
+ """Minimal cookie-session websocket client for a managed OpenClaw gateway."""
71
+
72
+ def __init__(
73
+ self,
74
+ *,
75
+ region: str,
76
+ agent_id: str,
77
+ agent_name: Optional[str] = None,
78
+ client_name: str = DEFAULT_CLIENT_NAME,
79
+ client_mode: str = DEFAULT_CLIENT_MODE,
80
+ ):
81
+ self.region = region
82
+ self.agent_id = agent_id
83
+ self.agent_name = agent_name
84
+ self.client_name = client_name
85
+ self.client_mode = client_mode
86
+ self.instance_id = str(uuid.uuid4())
87
+ self.session = requests.Session()
88
+ self._ws: Any = None
89
+ self.connection_info: Optional[DashboardAccessInfo] = None
90
+ self.hello: Optional[dict[str, Any]] = None
91
+ self.challenge_nonce: Optional[str] = None
92
+
93
+ async def __aenter__(self) -> "OpenClawGatewayClient":
94
+ return self
95
+
96
+ async def __aexit__(self, exc_type, exc_val, exc_tb) -> bool:
97
+ await self.close()
98
+ return False
99
+
100
+ async def close(self) -> None:
101
+ if self._ws is not None:
102
+ try:
103
+ await self._ws.close()
104
+ except Exception:
105
+ pass
106
+ self._ws = None
107
+ self.session.close()
108
+
109
+ @property
110
+ def methods(self) -> list[str]:
111
+ features = (self.hello or {}).get("features") or {}
112
+ methods = features.get("methods")
113
+ if isinstance(methods, list):
114
+ return [str(item) for item in methods]
115
+ return []
116
+
117
+ def has_method(self, method: str) -> bool:
118
+ return method in set(self.methods)
119
+
120
+ async def build_access_info(
121
+ self,
122
+ *,
123
+ path: Optional[str] = None,
124
+ expires_seconds: Optional[int] = None,
125
+ link_type: str = "private",
126
+ force_new: bool = False,
127
+ ) -> DashboardAccessInfo:
128
+ async with AgentEngineClient(region=self.region) as client:
129
+ link = await client.create_dashboard_access_link(
130
+ agent_id=self.agent_id,
131
+ name=self.agent_name,
132
+ link_type=link_type,
133
+ path=path,
134
+ expires_seconds=expires_seconds,
135
+ force_new=force_new,
136
+ )
137
+
138
+ access_url = str(link.get("access_url") or "").strip()
139
+ if not access_url:
140
+ raise OpenClawGatewayError("CreateDashboardAccessLink returned an empty access URL")
141
+
142
+ response = await asyncio.to_thread(
143
+ self.session.get,
144
+ access_url,
145
+ allow_redirects=False,
146
+ timeout=30,
147
+ )
148
+ if response.status_code >= 400 or response.status_code < 300:
149
+ raise OpenClawGatewayError(
150
+ f"Dashboard short-link bootstrap failed: HTTP {response.status_code}"
151
+ )
152
+
153
+ cookie_header = self._build_cookie_header()
154
+ if not cookie_header:
155
+ raise OpenClawGatewayError("Dashboard short-link bootstrap did not produce a session cookie")
156
+
157
+ parsed = urlsplit(access_url)
158
+ self.connection_info = DashboardAccessInfo(
159
+ agent_id=self.agent_id,
160
+ agent_name=self.agent_name,
161
+ access_url=access_url,
162
+ ws_url=derive_gateway_ws_url(access_url),
163
+ cookie_header=cookie_header,
164
+ origin=f"{parsed.scheme}://{parsed.netloc}",
165
+ link_id=str(link.get("link_id") or "").strip() or None,
166
+ expires_at=str(link.get("expires_at") or "").strip() or None,
167
+ )
168
+ return self.connection_info
169
+
170
+ async def connect(
171
+ self,
172
+ *,
173
+ path: Optional[str] = None,
174
+ expires_seconds: Optional[int] = None,
175
+ link_type: str = "private",
176
+ ) -> dict[str, Any]:
177
+ info = self.connection_info or await self.build_access_info(
178
+ path=path,
179
+ expires_seconds=expires_seconds,
180
+ link_type=link_type,
181
+ )
182
+
183
+ headers = {
184
+ "Cookie": info.cookie_header,
185
+ "User-Agent": f"ksadk/{KSADK_VERSION}",
186
+ "Origin": info.origin,
187
+ }
188
+ self._ws = await self._connect_ws(info.ws_url, headers)
189
+ self.challenge_nonce = await self._wait_for_connect_challenge()
190
+ self.hello = await self.request(
191
+ "connect",
192
+ {
193
+ "minProtocol": GATEWAY_PROTOCOL_VERSION,
194
+ "maxProtocol": GATEWAY_PROTOCOL_VERSION,
195
+ "client": {
196
+ "id": self.client_name,
197
+ "displayName": "ksadk openclaw channel",
198
+ "version": KSADK_VERSION,
199
+ "platform": platform.system().lower() or "unknown",
200
+ "mode": self.client_mode,
201
+ "instanceId": self.instance_id,
202
+ },
203
+ "caps": [],
204
+ "role": "operator",
205
+ "scopes": list(DEFAULT_SCOPES),
206
+ },
207
+ timeout_ms=10_000,
208
+ )
209
+ return self.hello
210
+
211
+ async def channels_status(self, *, probe: bool = False, timeout_ms: Optional[int] = None) -> dict[str, Any]:
212
+ params: dict[str, Any] = {"probe": bool(probe)}
213
+ if timeout_ms is not None:
214
+ params["timeoutMs"] = int(timeout_ms)
215
+ return await self.request("channels.status", params)
216
+
217
+ async def config_get(self) -> dict[str, Any]:
218
+ return await self.request("config.get", {})
219
+
220
+ async def config_apply(
221
+ self,
222
+ *,
223
+ config: dict[str, Any],
224
+ base_hash: str,
225
+ note: Optional[str] = None,
226
+ session_key: Optional[str] = None,
227
+ restart_delay_ms: Optional[int] = None,
228
+ ) -> dict[str, Any]:
229
+ params: dict[str, Any] = {
230
+ "raw": json.dumps(config, ensure_ascii=False, indent=2),
231
+ "baseHash": base_hash,
232
+ }
233
+ if note:
234
+ params["note"] = note
235
+ if session_key:
236
+ params["sessionKey"] = session_key
237
+ if restart_delay_ms is not None:
238
+ params["restartDelayMs"] = int(restart_delay_ms)
239
+ return await self.request("config.apply", params, timeout_ms=20_000)
240
+
241
+ async def web_login_start(
242
+ self,
243
+ *,
244
+ force: bool = False,
245
+ timeout_ms: Optional[int] = None,
246
+ ) -> dict[str, Any]:
247
+ params: dict[str, Any] = {"force": bool(force)}
248
+ if timeout_ms is not None:
249
+ params["timeoutMs"] = int(timeout_ms)
250
+ return await self.request("web.login.start", params, timeout_ms=(timeout_ms or 30_000) + 5_000)
251
+
252
+ async def web_login_wait(
253
+ self,
254
+ *,
255
+ account_id: Optional[str] = None,
256
+ session_key: Optional[str] = None,
257
+ timeout_ms: Optional[int] = None,
258
+ ) -> dict[str, Any]:
259
+ params: dict[str, Any] = {}
260
+ effective_account_id = account_id or session_key
261
+ if effective_account_id:
262
+ params["accountId"] = effective_account_id
263
+ if timeout_ms is not None:
264
+ params["timeoutMs"] = int(timeout_ms)
265
+ return await self.request("web.login.wait", params, timeout_ms=(timeout_ms or 120_000) + 5_000)
266
+
267
+ async def request(
268
+ self,
269
+ method: str,
270
+ params: Optional[dict[str, Any]] = None,
271
+ *,
272
+ timeout_ms: int = 30_000,
273
+ ) -> dict[str, Any]:
274
+ if self._ws is None:
275
+ raise OpenClawGatewayError("Gateway websocket is not connected")
276
+
277
+ request_id = uuid.uuid4().hex
278
+ payload = {
279
+ "type": "req",
280
+ "id": request_id,
281
+ "method": method,
282
+ "params": params or {},
283
+ }
284
+ await self._ws.send(json.dumps(payload, ensure_ascii=False))
285
+ return await self._wait_for_response(request_id, timeout_ms=timeout_ms)
286
+
287
+ async def wait_for_disconnect(self, *, timeout_ms: int = 5_000) -> bool:
288
+ """Wait briefly for the current websocket to close, typically after config-triggered restart."""
289
+ if self._ws is None:
290
+ return True
291
+
292
+ deadline = asyncio.get_running_loop().time() + (timeout_ms / 1000)
293
+ while True:
294
+ remaining = deadline - asyncio.get_running_loop().time()
295
+ if remaining <= 0:
296
+ return False
297
+ try:
298
+ await self._recv_json(timeout=remaining)
299
+ except OpenClawGatewayError as exc:
300
+ return "timed out" not in str(exc).lower()
301
+
302
+ def _build_cookie_header(self) -> str:
303
+ cookies = self.session.cookies.get_dict()
304
+ return "; ".join(f"{name}={value}" for name, value in cookies.items())
305
+
306
+ async def _connect_ws(self, ws_url: str, headers: dict[str, str]):
307
+ try:
308
+ import websockets
309
+ except Exception as exc: # pragma: no cover - exercised only when dependency missing
310
+ raise OpenClawGatewayError(
311
+ "Missing dependency `websockets`; reinstall ksadk with channel support enabled"
312
+ ) from exc
313
+
314
+ connect_kwargs = {
315
+ "open_timeout": 10,
316
+ "ping_interval": 20,
317
+ "ping_timeout": 20,
318
+ "max_size": 50 * 1024 * 1024,
319
+ }
320
+ try:
321
+ return await websockets.connect(ws_url, additional_headers=headers, **connect_kwargs)
322
+ except TypeError:
323
+ return await websockets.connect(ws_url, extra_headers=headers, **connect_kwargs)
324
+
325
+ async def _wait_for_connect_challenge(self, *, timeout_ms: int = 10_000) -> str:
326
+ deadline = timeout_ms / 1000
327
+ while True:
328
+ frame = await self._recv_json(timeout=deadline)
329
+ if frame.get("type") != "event":
330
+ continue
331
+ if frame.get("event") != "connect.challenge":
332
+ continue
333
+ payload = frame.get("payload") or {}
334
+ nonce = str(payload.get("nonce") or "").strip()
335
+ if nonce:
336
+ return nonce
337
+ raise OpenClawGatewayError("Gateway connect challenge missing nonce")
338
+
339
+ async def _wait_for_response(self, request_id: str, *, timeout_ms: int) -> dict[str, Any]:
340
+ deadline = timeout_ms / 1000
341
+ while True:
342
+ frame = await self._recv_json(timeout=deadline)
343
+ if frame.get("type") != "res":
344
+ continue
345
+ if frame.get("id") != request_id:
346
+ continue
347
+ if frame.get("ok"):
348
+ payload = frame.get("payload")
349
+ if isinstance(payload, dict):
350
+ return payload
351
+ return {"value": payload}
352
+ error = frame.get("error") or {}
353
+ raise OpenClawGatewayRequestError(
354
+ str(error.get("message") or "Gateway request failed"),
355
+ code=error.get("code"),
356
+ details=error.get("details"),
357
+ )
358
+
359
+ async def _recv_json(self, *, timeout: float) -> dict[str, Any]:
360
+ if self._ws is None:
361
+ raise OpenClawGatewayError("Gateway websocket is not connected")
362
+
363
+ try:
364
+ raw = await asyncio.wait_for(self._ws.recv(), timeout=timeout)
365
+ except asyncio.TimeoutError as exc:
366
+ raise OpenClawGatewayError("Gateway websocket timed out") from exc
367
+ except Exception as exc:
368
+ raise OpenClawGatewayError(f"Gateway websocket receive failed: {exc}") from exc
369
+
370
+ if isinstance(raw, bytes):
371
+ raw = raw.decode("utf-8", errors="replace")
372
+ try:
373
+ parsed = json.loads(raw)
374
+ except Exception as exc:
375
+ raise OpenClawGatewayError("Gateway websocket returned invalid JSON") from exc
376
+ if not isinstance(parsed, dict):
377
+ raise OpenClawGatewayError("Gateway websocket returned an unexpected frame")
378
+ return parsed
@@ -0,0 +1,8 @@
1
+ """
2
+ KsADK Runners - 统一运行时模块
3
+ """
4
+
5
+ from ksadk.runners.base_runner import BaseRunner
6
+ from ksadk.runners.factory import create_runner
7
+
8
+ __all__ = ["BaseRunner", "create_runner"]