agentengine-sdk-python 0.7.0__py3-none-any.whl → 0.8.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 (371) hide show
  1. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/METADATA +36 -20
  2. agentengine_sdk_python-0.8.0.dist-info/RECORD +578 -0
  3. ksadk/a2a/__init__.py +178 -11
  4. ksadk/a2a/bootstrap.py +334 -0
  5. ksadk/a2a/card.py +120 -0
  6. ksadk/a2a/context_store.py +203 -0
  7. ksadk/a2a/control_plane.py +818 -0
  8. ksadk/a2a/credential.py +99 -0
  9. ksadk/a2a/event_adapter.py +149 -0
  10. ksadk/a2a/executor.py +406 -89
  11. ksadk/a2a/external_transport.py +516 -0
  12. ksadk/a2a/identity.py +304 -0
  13. ksadk/a2a/ids.py +22 -0
  14. ksadk/a2a/langgraph.py +285 -0
  15. ksadk/a2a/resume_store.py +201 -0
  16. ksadk/a2a/routes.py +105 -0
  17. ksadk/a2a/server.py +107 -60
  18. ksadk/a2a/space_client.py +1101 -0
  19. ksadk/a2a/task_adapter.py +423 -0
  20. ksadk/a2a/task_event_dispatcher.py +167 -0
  21. ksadk/a2a/task_event_outbox.py +326 -0
  22. ksadk/a2a/task_store.py +206 -0
  23. ksadk/a2ui/__init__.py +27 -0
  24. ksadk/a2ui/core.py +186 -0
  25. ksadk/a2ui/models.py +166 -0
  26. ksadk/a2ui/renderer.py +198 -0
  27. ksadk/agui/__init__.py +9 -0
  28. ksadk/agui/a2ui_projection.py +92 -0
  29. ksadk/agui/agent.py +857 -0
  30. ksadk/agui/config.py +86 -0
  31. ksadk/agui/routes.py +55 -0
  32. ksadk/api/client.py +233 -191
  33. ksadk/builders/__init__.py +2 -0
  34. ksadk/builders/base.py +16 -14
  35. ksadk/builders/code_builder.py +318 -236
  36. ksadk/builders/container_builder.py +187 -167
  37. ksadk/builders/framework_requirements.py +29 -11
  38. ksadk/builders/ks3_uploader.py +58 -27
  39. ksadk/builders/managed_runtime_builder.py +145 -0
  40. ksadk/builders/mcp_builder.py +91 -92
  41. ksadk/builders/requirements_utils.py +1 -5
  42. ksadk/cli/__init__.py +89 -171
  43. ksadk/cli/cmd_a2a.py +254 -70
  44. ksadk/cli/cmd_agent.py +19 -5
  45. ksadk/cli/cmd_build.py +158 -29
  46. ksadk/cli/cmd_completion.py +47 -35
  47. ksadk/cli/cmd_config.py +267 -198
  48. ksadk/cli/cmd_create.py +500 -720
  49. ksadk/cli/cmd_dashboard.py +120 -45
  50. ksadk/cli/cmd_deploy.py +117 -58
  51. ksadk/cli/cmd_destroy.py +44 -14
  52. ksadk/cli/cmd_files.py +63 -24
  53. ksadk/cli/cmd_hermes.py +168 -89
  54. ksadk/cli/cmd_invoke.py +184 -122
  55. ksadk/cli/cmd_launch.py +64 -28
  56. ksadk/cli/cmd_mcp.py +98 -64
  57. ksadk/cli/cmd_model.py +14 -5
  58. ksadk/cli/cmd_openclaw.py +483 -227
  59. ksadk/cli/cmd_replay.py +71 -0
  60. ksadk/cli/cmd_run.py +33 -10
  61. ksadk/cli/cmd_status.py +80 -31
  62. ksadk/cli/cmd_version.py +20 -13
  63. ksadk/cli/cmd_web.py +89 -13
  64. ksadk/cli/deploy_utils.py +20 -20
  65. ksadk/cli/dry_run.py +5 -3
  66. ksadk/cli/error_utils.py +37 -12
  67. ksadk/cli/global_options.py +1 -2
  68. ksadk/cli/local_runtime.py +1 -2
  69. ksadk/cli/model_catalog.py +6 -2
  70. ksadk/cli/network_options.py +34 -14
  71. ksadk/cli/resource_common.py +6 -2
  72. ksadk/cli/storage.py +0 -1
  73. ksadk/cli/ui.py +5 -3
  74. ksadk/cli/workflow_common.py +51 -17
  75. ksadk/codex/__init__.py +12 -0
  76. ksadk/codex/client.py +408 -0
  77. ksadk/codex/phase.py +143 -0
  78. ksadk/codex/runtime.py +449 -0
  79. ksadk/common/aicp_env.py +0 -1
  80. ksadk/common/auth.py +2 -2
  81. ksadk/common/constants.py +1 -3
  82. ksadk/common/llm_utils.py +17 -13
  83. ksadk/compat/__init__.py +5 -0
  84. ksadk/compat/adk_compat.py +200 -0
  85. ksadk/compat/copilotkit_a2ui.py +330 -0
  86. ksadk/configs/__init__.py +12 -12
  87. ksadk/configs/env_registry.py +500 -100
  88. ksadk/configs/global_config.py +2 -1
  89. ksadk/configs/settings.py +151 -124
  90. ksadk/conversations/__init__.py +7 -5
  91. ksadk/conversations/attachment_storage.py +16 -11
  92. ksadk/conversations/attachments.py +44 -36
  93. ksadk/conversations/compaction_pipeline.py +12 -12
  94. ksadk/conversations/compaction_prompt.py +9 -5
  95. ksadk/conversations/context.py +221 -6
  96. ksadk/conversations/message_projection.py +438 -51
  97. ksadk/conversations/model_context.py +12 -6
  98. ksadk/conversations/model_options.py +0 -1
  99. ksadk/conversations/normalize.py +20 -16
  100. ksadk/conversations/reasoning_markup.py +1 -1
  101. ksadk/conversations/runtime.py +339 -5255
  102. ksadk/conversations/runtime_compaction.py +333 -0
  103. ksadk/conversations/runtime_constants.py +27 -0
  104. ksadk/conversations/runtime_governance.py +185 -0
  105. ksadk/conversations/runtime_input.py +652 -0
  106. ksadk/conversations/runtime_invocation.py +395 -0
  107. ksadk/conversations/runtime_metadata.py +475 -0
  108. ksadk/conversations/runtime_observability.py +355 -0
  109. ksadk/conversations/runtime_payloads.py +272 -0
  110. ksadk/conversations/runtime_persistence.py +440 -0
  111. ksadk/conversations/runtime_preparation.py +418 -0
  112. ksadk/conversations/runtime_resume.py +816 -0
  113. ksadk/conversations/runtime_stream_events.py +902 -0
  114. ksadk/conversations/runtime_streaming.py +547 -0
  115. ksadk/conversations/semantic_summary.py +17 -5
  116. ksadk/conversations/session_title.py +6 -3
  117. ksadk/deployment/__init__.py +15 -16
  118. ksadk/deployment/agent_access.py +12 -23
  119. ksadk/deployment/base.py +51 -38
  120. ksadk/deployment/manager.py +63 -65
  121. ksadk/deployment/providers/serverless.py +309 -202
  122. ksadk/deployment/registry.py +38 -32
  123. ksadk/deployment/state.py +11 -11
  124. ksadk/deployment/ui_config.py +1 -1
  125. ksadk/detection/__init__.py +1 -1
  126. ksadk/detection/detector.py +146 -83
  127. ksadk/detection/mcp_detector.py +9 -6
  128. ksadk/events/__init__.py +25 -0
  129. ksadk/events/parser.py +191 -0
  130. ksadk/events/replay.py +37 -0
  131. ksadk/events/runtime_event.py +264 -0
  132. ksadk/events/store.py +317 -0
  133. ksadk/harness/__init__.py +34 -0
  134. ksadk/harness/app.py +278 -0
  135. ksadk/harness/config.py +181 -0
  136. ksadk/harness/reasoner.py +105 -0
  137. ksadk/harness/runner.py +211 -0
  138. ksadk/harness/sandbox.py +141 -0
  139. ksadk/harness/tools.py +222 -0
  140. ksadk/hermes_terminal.py +23 -12
  141. ksadk/identity/resolver.py +15 -9
  142. ksadk/ids.py +32 -0
  143. ksadk/knowledge_base/adk_tool.py +1 -1
  144. ksadk/knowledge_base/client.py +23 -29
  145. ksadk/managed_runtime.py +188 -0
  146. ksadk/markdown.py +5 -2
  147. ksadk/mcp_runtime/__init__.py +9 -6
  148. ksadk/memory/__init__.py +1 -1
  149. ksadk/memory/adk/__init__.py +2 -0
  150. ksadk/memory/adk/backends/base_ltm_backend.py +2 -6
  151. ksadk/memory/adk/backends/http_ltm_backend.py +13 -21
  152. ksadk/memory/adk/backends/inmemory_ltm_backend.py +7 -13
  153. ksadk/memory/adk/backends/sdk_ltm_backend.py +26 -33
  154. ksadk/memory/adk/long_term_memory.py +31 -35
  155. ksadk/memory/adk/resilient_session_service.py +4 -5
  156. ksadk/memory/adk/short_term_memory.py +12 -21
  157. ksadk/memory/adk_tool.py +3 -2
  158. ksadk/memory/backends/base.py +19 -19
  159. ksadk/memory/backends/memory.py +24 -25
  160. ksadk/memory/backends/redis.py +31 -30
  161. ksadk/memory/langchain_tool.py +2 -1
  162. ksadk/memory/manager.py +52 -47
  163. ksadk/memory/service.py +10 -8
  164. ksadk/model_policy.py +15 -7
  165. ksadk/model_proxy/__init__.py +51 -0
  166. ksadk/model_proxy/bootstrap.py +80 -0
  167. ksadk/model_proxy/cache.py +165 -0
  168. ksadk/model_proxy/config.py +45 -0
  169. ksadk/model_proxy/demo_webui.py +115 -0
  170. ksadk/model_proxy/detect.py +145 -0
  171. ksadk/model_proxy/gate.py +68 -0
  172. ksadk/model_proxy/namespace.py +173 -0
  173. ksadk/model_proxy/protocol_proxy.py +22 -0
  174. ksadk/model_proxy/server.py +300 -0
  175. ksadk/model_proxy/transform.py +691 -0
  176. ksadk/openclaw_gateway.py +29 -14
  177. ksadk/runners/adk_runner.py +345 -120
  178. ksadk/runners/base_runner.py +46 -29
  179. ksadk/runners/codex_runner.py +132 -0
  180. ksadk/runners/deepagents_runner.py +0 -1
  181. ksadk/runners/factory.py +17 -5
  182. ksadk/runners/langchain_runner.py +29 -742
  183. ksadk/runners/langgraph_runner.py +352 -90
  184. ksadk/runners/patch_langchain.py +16 -16
  185. ksadk/runners/remote_runner.py +134 -33
  186. ksadk/runners/usage_accumulator.py +1 -0
  187. ksadk/runners/utils/langfuse.py +3 -3
  188. ksadk/runners/utils/loader.py +7 -7
  189. ksadk/runtime/__init__.py +41 -0
  190. ksadk/runtime/adapter.py +345 -0
  191. ksadk/runtime/framework_adapters.py +124 -0
  192. ksadk/runtime/preprocessing.py +118 -0
  193. ksadk/runtime/runner_adapter.py +873 -0
  194. ksadk/runtime_context.py +18 -3
  195. ksadk/runtime_state.py +0 -1
  196. ksadk/sandbox/__init__.py +4 -1
  197. ksadk/sandbox/backends/__init__.py +4 -1
  198. ksadk/sandbox/backends/e2b.py +13 -5
  199. ksadk/sandbox/backends/local_process.py +11 -3
  200. ksadk/sandbox/base.py +10 -15
  201. ksadk/sandbox/factory.py +14 -4
  202. ksadk/sandbox/registry.py +57 -6
  203. ksadk/server/api_models.py +15 -5
  204. ksadk/server/app.py +455 -3885
  205. ksadk/server/composition.py +21 -0
  206. ksadk/server/factory.py +624 -0
  207. ksadk/server/routes/__init__.py +1 -0
  208. ksadk/server/routes/checkpoint_resolution.py +116 -0
  209. ksadk/server/routes/common.py +713 -0
  210. ksadk/server/routes/control.py +327 -0
  211. ksadk/server/routes/dependencies.py +98 -0
  212. ksadk/server/routes/misc.py +448 -0
  213. ksadk/server/routes/models.py +443 -0
  214. ksadk/server/routes/openai_compat.py +207 -0
  215. ksadk/server/routes/projection.py +795 -0
  216. ksadk/server/routes/routers.py +52 -0
  217. ksadk/server/routes/run.py +726 -0
  218. ksadk/server/routes/sessions.py +649 -0
  219. ksadk/server/routes/streaming.py +223 -0
  220. ksadk/server/routes/workspace.py +381 -0
  221. ksadk/server/static/assets/{ArtifactsPanel-D-SSn2ee.js → ArtifactsPanel-Cjnqt-8W.js} +1 -1
  222. ksadk/server/static/assets/CodeBlock-BqyqZfuB.js +9 -0
  223. ksadk/server/static/assets/MathMessageMarkdown-BpH7jiFM.js +8 -0
  224. ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +303 -0
  225. ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +1 -0
  226. ksadk/server/static/assets/{arc-BA13sHc9.js → arc-CFKwSk_B.js} +1 -1
  227. ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +1 -0
  228. ksadk/server/static/assets/{architectureDiagram-3BPJPVTR-DzJzgVoL.js → architectureDiagram-3BPJPVTR-Dej8jX8c.js} +1 -1
  229. ksadk/server/static/assets/{blockDiagram-GPEHLZMM-UTdVcZhn.js → blockDiagram-GPEHLZMM-1F64jqvy.js} +1 -1
  230. ksadk/server/static/assets/{c4Diagram-AAUBKEIU-Dix0GD4m.js → c4Diagram-AAUBKEIU-9q7AUAKb.js} +1 -1
  231. ksadk/server/static/assets/channel-iUGv2N24.js +1 -0
  232. ksadk/server/static/assets/{chunk-2J33WTMH-C2JxuZ42.js → chunk-2J33WTMH-6qgwJm7Q.js} +1 -1
  233. ksadk/server/static/assets/{chunk-4BX2VUAB-Be57QPgD.js → chunk-4BX2VUAB-CsWIQRhc.js} +1 -1
  234. ksadk/server/static/assets/{chunk-55IACEB6-WjSuy4nv.js → chunk-55IACEB6-BK8paA20.js} +1 -1
  235. ksadk/server/static/assets/{chunk-727SXJPM-BOovP-b5.js → chunk-727SXJPM-B-JEhy7h.js} +1 -1
  236. ksadk/server/static/assets/{chunk-AQP2D5EJ-DOmZNmWj.js → chunk-AQP2D5EJ-DYBvMHAa.js} +1 -1
  237. ksadk/server/static/assets/{chunk-FMBD7UC4-DzwlodkU.js → chunk-FMBD7UC4-BGhvzDYt.js} +1 -1
  238. ksadk/server/static/assets/{chunk-ND2GUHAM-DMqAikEU.js → chunk-ND2GUHAM-D98vPd-E.js} +1 -1
  239. ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +1 -0
  240. ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +1 -0
  241. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +1 -0
  242. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-Zhy2GBnP.js → cose-bilkent-S5V4N54A-CX3yotHq.js} +1 -1
  243. ksadk/server/static/assets/{dagre-BM42HDAG-CbKrtIUz.js → dagre-BM42HDAG-C7TguAWo.js} +1 -1
  244. ksadk/server/static/assets/{diagram-2AECGRRQ-BRApgQRK.js → diagram-2AECGRRQ-Dd17_kws.js} +1 -1
  245. ksadk/server/static/assets/{diagram-5GNKFQAL-D0xbnDiK.js → diagram-5GNKFQAL-DVIClIil.js} +1 -1
  246. ksadk/server/static/assets/{diagram-KO2AKTUF-CVugVI9L.js → diagram-KO2AKTUF-Df_3gYQa.js} +1 -1
  247. ksadk/server/static/assets/{diagram-LMA3HP47-DozUGgee.js → diagram-LMA3HP47-BhLk6ZtA.js} +1 -1
  248. ksadk/server/static/assets/{diagram-OG6HWLK6-ZOYsKlru.js → diagram-OG6HWLK6-D4GNGvuu.js} +1 -1
  249. ksadk/server/static/assets/{dist-DmFaq_Iy.js → dist-6CVKuTAe.js} +1 -1
  250. ksadk/server/static/assets/{dist-8EEyGgDx.js → dist-BUHRxvDG.js} +1 -1
  251. ksadk/server/static/assets/{dist-B0NP_Z0z.js → dist-BZ9n9AjO.js} +1 -1
  252. ksadk/server/static/assets/{dist-DMezvBGJ.js → dist-BibcG1V9.js} +1 -1
  253. ksadk/server/static/assets/{dist-C3HIIaN5.js → dist-Bs-jQcRX.js} +1 -1
  254. ksadk/server/static/assets/{dist-BrCcQ47T.js → dist-C2xjE7cO.js} +1 -1
  255. ksadk/server/static/assets/{dist-Dp0k7bWI.js → dist-C7-3jInC.js} +1 -1
  256. ksadk/server/static/assets/{dist-D-xOD048.js → dist-C99THtIA.js} +1 -1
  257. ksadk/server/static/assets/{dist-CkEKJFtk.js → dist-CGcp2ex8.js} +1 -1
  258. ksadk/server/static/assets/{dist-DyOkZmze.js → dist-CVQRZjPu.js} +1 -1
  259. ksadk/server/static/assets/{dist-BssVmjIo.js → dist-Cf23NY4L.js} +1 -1
  260. ksadk/server/static/assets/{dist-BIJVDMuB.js → dist-CgF3fj15.js} +1 -1
  261. ksadk/server/static/assets/{dist-2hInLS_J.js → dist-Cwt7koer.js} +1 -1
  262. ksadk/server/static/assets/{dist-DyWsb78Q.js → dist-D82mtD2s.js} +1 -1
  263. ksadk/server/static/assets/{dist-D-JMdWPQ.js → dist-DF06ORQo.js} +1 -1
  264. ksadk/server/static/assets/{dist-BmlMPsCc.js → dist-DHn6nBzr.js} +1 -1
  265. ksadk/server/static/assets/{dist-gX6GOLKq.js → dist-Djgl2wVZ.js} +1 -1
  266. ksadk/server/static/assets/{dist-DpKtt4Bo.js → dist-DlzCRy0S.js} +1 -1
  267. ksadk/server/static/assets/{dist-8_SfK1IP.js → dist-DqNnNFrw.js} +1 -1
  268. ksadk/server/static/assets/{dist-D57wnGWd.js → dist-DyvYLMW9.js} +1 -1
  269. ksadk/server/static/assets/{dist-CPBtqRTW.js → dist-eoW6tZXA.js} +1 -1
  270. ksadk/server/static/assets/{dist-DL_NKc_z.js → dist-ivOya1LD.js} +1 -1
  271. ksadk/server/static/assets/{erDiagram-TEJ5UH35-Bk-9bgE5.js → erDiagram-TEJ5UH35-CnfRcY2M.js} +1 -1
  272. ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +1 -0
  273. ksadk/server/static/assets/{flowDiagram-I6XJVG4X-Dn9kZVuZ.js → flowDiagram-I6XJVG4X-DGaJjGNJ.js} +1 -1
  274. ksadk/server/static/assets/{ganttDiagram-6RSMTGT7-BGxXlJqm.js → ganttDiagram-6RSMTGT7-DpCoB2g9.js} +1 -1
  275. ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +1 -0
  276. ksadk/server/static/assets/{gitGraphDiagram-PVQCEYII-C7Q0X-wi.js → gitGraphDiagram-PVQCEYII-9IKVFBVT.js} +1 -1
  277. ksadk/server/static/assets/index-QSwCHuB8.js +177 -0
  278. ksadk/server/static/assets/index-jOPmTOZH.css +2 -0
  279. ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +1 -0
  280. ksadk/server/static/assets/{infoDiagram-5YYISTIA-BO_CSqq5.js → infoDiagram-5YYISTIA-CYIIsb8y.js} +1 -1
  281. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-eYLPLd46.js → ishikawaDiagram-YF4QCWOH-DLOHGvWw.js} +1 -1
  282. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-De9geSb0.js → journeyDiagram-JHISSGLW-BIzKeejT.js} +1 -1
  283. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-Cs80kQto.js → kanban-definition-UN3LZRKU-BWHoFSw2.js} +1 -1
  284. ksadk/server/static/assets/{katex-DSrCFD8n.js → katex-DATssjp1.js} +1 -1
  285. ksadk/server/static/assets/{linear-CN9sbKTF.js → linear-CvMBw9cA.js} +1 -1
  286. ksadk/server/static/assets/{mermaid-parser.core-DlgSBU8l.js → mermaid-parser.core-mGAcEwcq.js} +2 -2
  287. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-9afz7Oug.js → mindmap-definition-RKZ34NQL-CSAQxEAe.js} +1 -1
  288. ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +1 -0
  289. ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +1 -0
  290. ksadk/server/static/assets/{pieDiagram-4H26LBE5-DPv_VstN.js → pieDiagram-4H26LBE5-By-ra07M.js} +1 -1
  291. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-o77wZ1XK.js → quadrantDiagram-W4KKPZXB-CxIR4JXI.js} +1 -1
  292. ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +1 -0
  293. ksadk/server/static/assets/{requirementDiagram-4Y6WPE33-BYVw81VC.js → requirementDiagram-4Y6WPE33-DpW90iu3.js} +1 -1
  294. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-B7nZFMKT.js → sankeyDiagram-5OEKKPKP-DpGa6EAV.js} +1 -1
  295. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-BGRRrFw5.js → sequenceDiagram-3UESZ5HK-NTKNGGe5.js} +1 -1
  296. ksadk/server/static/assets/{stateDiagram-AJRCARHV-BUfHCoPs.js → stateDiagram-AJRCARHV-DGpd9yFG.js} +1 -1
  297. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +1 -0
  298. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-FbCTGrf9.js → timeline-definition-PNZ67QCA-jqoYs3jQ.js} +1 -1
  299. ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +1 -0
  300. ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +1 -0
  301. ksadk/server/static/assets/{vennDiagram-CIIHVFJN-DWgwtPsJ.js → vennDiagram-CIIHVFJN-l3Z7-wbP.js} +1 -1
  302. ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +1 -0
  303. ksadk/server/static/assets/{wardleyDiagram-YWT4CUSO-2x8G-tTM.js → wardleyDiagram-YWT4CUSO-BR54GPmr.js} +1 -1
  304. ksadk/server/static/assets/{xychartDiagram-2RQKCTM6-Drma3AYl.js → xychartDiagram-2RQKCTM6-SkiH8GsK.js} +1 -1
  305. ksadk/server/static/index.html +2 -2
  306. ksadk/server/terminal_sessions.py +111 -58
  307. ksadk/sessions/__init__.py +69 -19
  308. ksadk/sessions/base.py +31 -11
  309. ksadk/sessions/continuity.py +2 -3
  310. ksadk/sessions/in_memory.py +46 -2
  311. ksadk/sessions/local_service.py +148 -17
  312. ksadk/sessions/postgres_service.py +143 -25
  313. ksadk/sessions/resilient.py +36 -8
  314. ksadk/skills/models.py +17 -5
  315. ksadk/skills/package_store.py +5 -2
  316. ksadk/skills/runtime/agent.py +20 -5
  317. ksadk/skills/runtime/artifacts.py +1 -5
  318. ksadk/skills/runtime/backends/e2b.py +10 -4
  319. ksadk/skills/runtime/backends/local.py +15 -3
  320. ksadk/skills/runtime/base.py +1 -2
  321. ksadk/skills/runtime/executor.py +10 -3
  322. ksadk/skills/runtime/factory.py +4 -2
  323. ksadk/skills/runtime/loader.py +1 -2
  324. ksadk/skills/runtime/registry.py +15 -10
  325. ksadk/skills/runtime/request.py +3 -1
  326. ksadk/skills/service_client.py +38 -17
  327. ksadk/skills/tool_defs.py +15 -10
  328. ksadk/terminal_exec_policy.py +3 -4
  329. ksadk/tools/gateway.py +92 -15
  330. ksadk/tools/result_budget.py +12 -4
  331. ksadk/toolsets/__init__.py +134 -36
  332. ksadk/toolsets/platform.py +21 -5
  333. ksadk/toolsets/sandbox.py +82 -16
  334. ksadk/toolsets/skills.py +200 -39
  335. ksadk/toolsets/web.py +123 -26
  336. ksadk/toolsets/workspace.py +212 -101
  337. ksadk/tracing/exporters/inmemory_exporter.py +62 -51
  338. ksadk/tracing/exporters/langfuse_exporter.py +91 -76
  339. ksadk/tracing/setup.py +69 -53
  340. ksadk/tracing/span_utils.py +5 -2
  341. ksadk/tui/loop.py +78 -30
  342. ksadk/tui/stream_render.py +1 -0
  343. ksadk/ui_config.py +5 -3
  344. ksadk/version.py +1 -1
  345. ksadk_runtime_common/schemas/runtime_event_v1.json +95 -0
  346. agentengine_sdk_python-0.7.0.dist-info/RECORD +0 -482
  347. ksadk/server/static/assets/CodeBlock-P16VOLYi.js +0 -9
  348. ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +0 -8
  349. ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +0 -303
  350. ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +0 -1
  351. ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +0 -1
  352. ksadk/server/static/assets/channel-CTuydARX.js +0 -1
  353. ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +0 -1
  354. ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +0 -1
  355. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +0 -1
  356. ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +0 -1
  357. ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +0 -1
  358. ksadk/server/static/assets/index-C00Lwg3L.js +0 -165
  359. ksadk/server/static/assets/index-DAURbCsP.css +0 -1
  360. ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +0 -1
  361. ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +0 -1
  362. ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +0 -1
  363. ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +0 -1
  364. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +0 -1
  365. ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +0 -1
  366. ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +0 -1
  367. ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +0 -1
  368. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/WHEEL +0 -0
  369. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/entry_points.txt +0 -0
  370. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/licenses/LICENSE +0 -0
  371. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/top_level.txt +0 -0
ksadk/toolsets/sandbox.py CHANGED
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import logging
3
4
  import os
4
5
  import shlex
5
6
  import time
6
- import logging
7
7
  from typing import Any
8
8
  from uuid import uuid4
9
9
 
@@ -15,7 +15,6 @@ from ksadk.tools.result_budget import budget_text_fields
15
15
  from ksadk.toolsets._langchain import as_tool
16
16
  from ksadk.toolsets.workspace import workspace_root
17
17
 
18
-
19
18
  logger = logging.getLogger(__name__)
20
19
 
21
20
 
@@ -30,11 +29,19 @@ def _gateway():
30
29
  return default_tool_gateway(_SANDBOX_TOOL_POLICIES)
31
30
 
32
31
 
32
+ def _dict_result(value: Any, *, tool_name: str) -> dict[str, Any]:
33
+ if not isinstance(value, dict):
34
+ raise TypeError(f"{tool_name} returned {type(value).__name__}, expected dict")
35
+ return dict(value)
36
+
37
+
33
38
  def sandbox_backend_name() -> str:
34
39
  explicit = os.environ.get("KSADK_SANDBOX_BACKEND", "").strip().lower()
35
40
  if explicit:
36
41
  return explicit
37
- if os.environ.get("KSADK_SANDBOX_TEMPLATE_ID") or os.environ.get("KSADK_SKILL_RUNTIME_TEMPLATE_ID"):
42
+ if os.environ.get("KSADK_SANDBOX_TEMPLATE_ID") or os.environ.get(
43
+ "KSADK_SKILL_RUNTIME_TEMPLATE_ID"
44
+ ):
38
45
  return "e2b"
39
46
  return "none"
40
47
 
@@ -47,15 +54,26 @@ def _sandbox_execution_backend_name() -> str:
47
54
  def sandbox_status() -> dict:
48
55
  """Report configured AgentEngine sandbox status and boundaries."""
49
56
 
50
- return _gateway().invoke("sandbox_status", _sandbox_status_impl)
57
+ return _dict_result(
58
+ _gateway().invoke("sandbox_status", _sandbox_status_impl),
59
+ tool_name="sandbox_status",
60
+ )
51
61
 
52
62
 
53
63
  def _sandbox_status_impl() -> dict[str, Any]:
54
64
  backend = sandbox_backend_name()
55
- timeout = int(os.environ.get("KSADK_SANDBOX_TIMEOUT") or os.environ.get("KSADK_SKILL_RUNTIME_TIMEOUT") or "600")
65
+ timeout = int(
66
+ os.environ.get("KSADK_SANDBOX_TIMEOUT")
67
+ or os.environ.get("KSADK_SKILL_RUNTIME_TIMEOUT")
68
+ or "600"
69
+ )
56
70
  idle_ttl = _int_env("KSADK_SANDBOX_IDLE_TTL_SECONDS", 300)
57
71
  max_sessions = _int_env("KSADK_SANDBOX_MAX_SESSIONS", 0)
58
- template_id = os.environ.get("KSADK_SANDBOX_TEMPLATE_ID") or os.environ.get("KSADK_SKILL_RUNTIME_TEMPLATE_ID") or ""
72
+ template_id = (
73
+ os.environ.get("KSADK_SANDBOX_TEMPLATE_ID")
74
+ or os.environ.get("KSADK_SKILL_RUNTIME_TEMPLATE_ID")
75
+ or ""
76
+ )
59
77
  isolated = backend not in {"local", "local_process", "pod", "pod_process"}
60
78
  latest = GLOBAL_SANDBOX_REGISTRY.latest()
61
79
  now = time.time()
@@ -89,7 +107,19 @@ def run_command(
89
107
  ) -> dict[str, Any]:
90
108
  """Run a shell command inside the configured isolated sandbox."""
91
109
 
92
- return _gateway().invoke("run_command", _run_command_impl, command, cwd, timeout, env, background, approval=approval)
110
+ return _dict_result(
111
+ _gateway().invoke(
112
+ "run_command",
113
+ _run_command_impl,
114
+ command,
115
+ cwd,
116
+ timeout,
117
+ env,
118
+ background,
119
+ approval=approval,
120
+ ),
121
+ tool_name="run_command",
122
+ )
93
123
 
94
124
 
95
125
  def _run_command_impl(
@@ -102,11 +132,15 @@ def _run_command_impl(
102
132
  command_text = str(command or "").strip()
103
133
  if not command_text:
104
134
  return {"ok": False, "error_message": "command is required"}
105
- policy = check_command_policy(command_text)
135
+ policy = _dict_result(check_command_policy(command_text), tool_name="check_command_policy")
106
136
  if not policy.get("ok"):
107
137
  return policy
108
138
  if background:
109
- return {"ok": False, "error_type": "background_not_supported", "error_message": "background commands are not supported in P0"}
139
+ return {
140
+ "ok": False,
141
+ "error_type": "background_not_supported",
142
+ "error_message": "background commands are not supported in P0",
143
+ }
110
144
  try:
111
145
  entry, _created = _sandbox_entry("ksadk-direct")
112
146
  result = entry.session.run_command(command_text, timeout=timeout, env=env, cwd=cwd)
@@ -119,7 +153,15 @@ def _run_command_impl(
119
153
  "stderr": result.stderr,
120
154
  "exit_code": result.exit_code,
121
155
  }
122
- return budget_text_fields(payload, tool_name="run_command", fields=("stdout", "stderr"), metadata={"tool_use_id": entry.sandbox_id})
156
+ return _dict_result(
157
+ budget_text_fields(
158
+ payload,
159
+ tool_name="run_command",
160
+ fields=("stdout", "stderr"),
161
+ metadata={"tool_use_id": entry.sandbox_id},
162
+ ),
163
+ tool_name="run_command",
164
+ )
123
165
  except SandboxError as exc:
124
166
  return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
125
167
  except Exception as exc:
@@ -135,7 +177,12 @@ def run_code(
135
177
  ) -> dict[str, Any]:
136
178
  """Run a code snippet through the sandbox; this is not a shell replacement."""
137
179
 
138
- return _gateway().invoke("run_code", _run_code_impl, code, language, timeout, env, approval=approval)
180
+ return _dict_result(
181
+ _gateway().invoke(
182
+ "run_code", _run_code_impl, code, language, timeout, env, approval=approval
183
+ ),
184
+ tool_name="run_code",
185
+ )
139
186
 
140
187
 
141
188
  def _run_code_impl(
@@ -152,7 +199,10 @@ def _run_code_impl(
152
199
  return {
153
200
  "ok": False,
154
201
  "error_type": "isolated_sandbox_required",
155
- "error_message": "run_code requires an isolated sandbox backend; local_process and pod_process are not supported for snippet execution",
202
+ "error_message": (
203
+ "run_code requires an isolated sandbox backend; local_process and "
204
+ "pod_process are not supported for snippet execution"
205
+ ),
156
206
  "backend": backend_name,
157
207
  "boundary": _sandbox_boundary(backend_name),
158
208
  }
@@ -181,7 +231,15 @@ def _run_code_impl(
181
231
  "stderr": result.stderr,
182
232
  "exit_code": result.exit_code,
183
233
  }
184
- return budget_text_fields(payload, tool_name="run_code", fields=("stdout", "stderr"), metadata={"tool_use_id": entry.sandbox_id})
234
+ return _dict_result(
235
+ budget_text_fields(
236
+ payload,
237
+ tool_name="run_code",
238
+ fields=("stdout", "stderr"),
239
+ metadata={"tool_use_id": entry.sandbox_id},
240
+ ),
241
+ tool_name="run_code",
242
+ )
185
243
  except SandboxError as exc:
186
244
  return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
187
245
  except Exception as exc:
@@ -300,10 +358,18 @@ def _int_env(name: str, default: int) -> int:
300
358
 
301
359
  def _sandbox_boundary(backend: str) -> str:
302
360
  if backend in {"local", "local_process"}:
303
- return "executes as a local child process; shares local filesystem, env allowlist, and network"
361
+ return (
362
+ "executes as a local child process; shares local filesystem, env allowlist, and network"
363
+ )
304
364
  if backend in {"pod", "pod_process"}:
305
- return "executes inside the agent pod; shares pod filesystem, env allowlist, network, and service account"
306
- return "Sandbox tools execute commands and code only through the configured isolated sandbox backend; they never expose the host shell."
365
+ return (
366
+ "executes inside the agent pod; shares pod filesystem, env allowlist, "
367
+ "network, and service account"
368
+ )
369
+ return (
370
+ "Sandbox tools execute commands and code only through the configured isolated "
371
+ "sandbox backend; they never expose the host shell."
372
+ )
307
373
 
308
374
 
309
375
  def get_sandbox_tools() -> list:
ksadk/toolsets/skills.py CHANGED
@@ -18,15 +18,18 @@ from ksadk.skills.service_env import (
18
18
  user_skill_space_ids,
19
19
  )
20
20
  from ksadk.skills.tool_defs import (
21
- build_execute_skills_tool as build_runtime_execute_skills_tool,
21
+ _skill_manifest_item,
22
22
  load_remote_skill_manifests,
23
23
  resolve_skill_space_ids,
24
24
  )
25
+ from ksadk.skills.tool_defs import (
26
+ build_execute_skills_tool as build_runtime_execute_skills_tool,
27
+ )
25
28
  from ksadk.tools.gateway import ToolPolicy, default_tool_gateway
26
29
  from ksadk.toolsets._langchain import as_tool
27
30
 
28
-
29
31
  _SKILL_TOOL_POLICIES = {
32
+ "list_skill_spaces": ToolPolicy(risk_level="low"),
30
33
  "list_skills": ToolPolicy(risk_level="low"),
31
34
  "search_skills": ToolPolicy(risk_level="low"),
32
35
  "load_skill": ToolPolicy(risk_level="low", side_effects=("skill_cache_write",)),
@@ -38,27 +41,132 @@ def _gateway():
38
41
  return default_tool_gateway(_SKILL_TOOL_POLICIES)
39
42
 
40
43
 
41
- def list_skills() -> dict[str, Any]:
42
- """List skills discoverable from configured Skill Spaces."""
44
+ def _dict_result(value: Any, *, tool_name: str) -> dict[str, Any]:
45
+ if not isinstance(value, dict):
46
+ raise TypeError(f"{tool_name} returned {type(value).__name__}, expected dict")
47
+ return dict(value)
48
+
43
49
 
50
+ def list_skill_spaces() -> dict[str, Any]:
51
+ """List visible Skill Spaces with id/name/description, so the model can pick one by intent.
52
+
53
+ 多 space 场景下,先调用本工具了解可选 space,再按用户意图用
54
+ ``search_skills(query, space_id=...)`` 或 ``load_skill(name, space_id=...)`` 定向查找。
55
+ """
56
+
57
+ configured = resolve_skill_space_ids()
44
58
  try:
45
- manifests = load_remote_skill_manifests(resolve_skill_space_ids())
59
+ client = _skill_service_client()
60
+ payload = client.list_skill_spaces()
61
+ spaces = _parse_skill_spaces(payload)
62
+ configured_set = set(configured)
63
+ for space in spaces:
64
+ space["configured"] = space["space_id"] in configured_set
65
+ if not spaces:
66
+ # 服务不支持 ListSkillSpaces 时,退化为返回已配置的 space id。
67
+ spaces = [
68
+ {"space_id": sid, "space_name": "", "description": "", "configured": True}
69
+ for sid in configured
70
+ ]
71
+ return {
72
+ "ok": True,
73
+ "configured_space_ids": configured,
74
+ "spaces": spaces,
75
+ "usage": (
76
+ "根据用户意图从这些 space 中选一个 space_id,再用 "
77
+ "search_skills(query, space_id=...) 在该 space 内搜索,或用 "
78
+ "load_skill(skill_name, space_id=...) 精确加载该 space 下的 skill。"
79
+ ),
80
+ }
81
+ except Exception as exc:
82
+ return {
83
+ "ok": False,
84
+ "error_type": type(exc).__name__,
85
+ "error_message": str(exc),
86
+ "configured_space_ids": configured,
87
+ "spaces": [
88
+ {"space_id": sid, "space_name": "", "description": "", "configured": True}
89
+ for sid in configured
90
+ ],
91
+ }
92
+
93
+
94
+ def _parse_skill_spaces(payload: dict[str, Any]) -> list[dict[str, Any]]:
95
+ data = payload.get("Data") or payload.get("data") or {}
96
+ raw = (
97
+ data.get("SkillSpaces")
98
+ or data.get("skill_spaces")
99
+ or data.get("Spaces")
100
+ or data.get("spaces")
101
+ or data.get("Items")
102
+ or data.get("items")
103
+ or []
104
+ )
105
+ spaces: list[dict[str, Any]] = []
106
+ for item in raw:
107
+ if not isinstance(item, dict):
108
+ continue
109
+ spaces.append(
110
+ {
111
+ "space_id": str(
112
+ item.get("SkillSpaceId")
113
+ or item.get("skill_space_id")
114
+ or item.get("SpaceId")
115
+ or item.get("space_id")
116
+ or ""
117
+ ),
118
+ "space_name": str(
119
+ item.get("SkillSpaceName")
120
+ or item.get("skill_space_name")
121
+ or item.get("SpaceName")
122
+ or item.get("space_name")
123
+ or ""
124
+ ),
125
+ "description": str(item.get("Description") or item.get("description") or ""),
126
+ }
127
+ )
128
+ return spaces
129
+
130
+
131
+ def list_skills(space_id: str | None = None) -> dict[str, Any]:
132
+ """List skills discoverable from configured Skill Spaces, optionally limited to one space.
133
+
134
+ ``space_id`` 指定时只列该 space(user space id 或 ``"public"``);缺省列出全部已配置 space。
135
+ """
136
+
137
+ space_ids = [space_id] if space_id else resolve_skill_space_ids()
138
+ try:
139
+ if space_id:
140
+ client = _skill_service_client()
141
+ manifests = [
142
+ _skill_manifest_item(skill, space_id=sid)
143
+ for sid, skill in _iter_remote_skills(client, space_id=space_id)
144
+ if skill.name
145
+ ]
146
+ else:
147
+ manifests = load_remote_skill_manifests(space_ids)
46
148
  return {
47
149
  "ok": True,
48
150
  "skills": manifests,
49
- "skill_space_ids": resolve_skill_space_ids(),
151
+ "skill_space_ids": space_ids,
152
+ "space_id": space_id,
50
153
  }
51
154
  except Exception as exc:
52
155
  return {
53
156
  "ok": False,
54
157
  "error_type": type(exc).__name__,
55
158
  "error_message": str(exc),
56
- "skill_space_ids": resolve_skill_space_ids(),
159
+ "skill_space_ids": space_ids,
160
+ "space_id": space_id,
57
161
  }
58
162
 
59
163
 
60
- def load_skill(skill_name: str) -> dict[str, Any]:
61
- """Download and load a skill's SKILL.md instructions from configured Skill Spaces."""
164
+ def load_skill(skill_name: str, space_id: str | None = None) -> dict[str, Any]:
165
+ """Download and load a skill's SKILL.md instructions from configured Skill Spaces.
166
+
167
+ ``space_id`` 指定时只在该 space 内按名匹配,用于多 space 下精确定位、避免同名冲突;
168
+ 缺省按配置顺序(user space 优先于 public)取第一个匹配。
169
+ """
62
170
 
63
171
  target = str(skill_name or "").strip().lower()
64
172
  if not target:
@@ -66,7 +174,7 @@ def load_skill(skill_name: str) -> dict[str, Any]:
66
174
  try:
67
175
  client = _skill_service_client()
68
176
  available: list[str] = []
69
- for space_id, skill in _iter_remote_skills(client):
177
+ for sid, skill in _iter_remote_skills(client, space_id=space_id):
70
178
  if not skill.name:
71
179
  continue
72
180
  available.append(skill.name)
@@ -79,7 +187,7 @@ def load_skill(skill_name: str) -> dict[str, Any]:
79
187
  "execution_context": "outer_agent",
80
188
  "name": local_skill.name,
81
189
  "description": local_skill.description,
82
- "space_id": space_id,
190
+ "space_id": sid,
83
191
  "skill_id": skill.skill_id,
84
192
  "version_id": skill.version_id,
85
193
  "version": skill.version,
@@ -88,31 +196,52 @@ def load_skill(skill_name: str) -> dict[str, Any]:
88
196
  "has_scripts_dir": (local_skill.root_dir / "scripts").is_dir(),
89
197
  "script_files": _script_files(local_skill.root_dir),
90
198
  "instructions": local_skill.body,
91
- "usage": "Read these instructions and complete the user's task in the outer agent unless the skill explicitly requires isolated execution.",
199
+ "usage": (
200
+ "Read these instructions and complete the user's task in the outer "
201
+ "agent unless the skill explicitly requires isolated execution."
202
+ ),
92
203
  }
93
204
  return {
94
205
  "ok": False,
95
206
  "error_message": f"Skill not found: {skill_name}",
207
+ "space_id": space_id,
96
208
  "available_skills": available,
97
209
  }
98
210
  except Exception as exc:
99
211
  return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
100
212
 
101
213
 
102
- def search_skills(query: str, max_results: int = 10) -> dict[str, Any]:
103
- """Search skills by name, aliases, tags, description, and examples."""
214
+ def search_skills(query: str, max_results: int = 10, space_id: str | None = None) -> dict[str, Any]:
215
+ """Search skills by name, aliases, tags, description, and examples.
216
+
217
+ ``space_id`` 指定时只在该 space 内搜索;缺省聚合全部已配置 space。结果带 ``space_id``,
218
+ 便于后续 ``load_skill(name, space_id=...)`` 精确定位。
219
+ """
104
220
 
105
221
  query_text = str(query or "").strip()
106
222
  if not query_text:
107
223
  return {"ok": False, "error_message": "query is required"}
108
224
  try:
109
225
  client = _skill_service_client()
110
- refs = [skill for _, skill in _iter_remote_skills(client)]
226
+ pairs = list(_iter_remote_skills(client, space_id=space_id))
227
+ # 建立 skill 标识 -> space_id 映射,给结果回填来源 space(cache_key 与 match 去重一致)。
228
+ space_of: dict[str, str] = {}
229
+ for sid, skill in pairs:
230
+ space_of.setdefault(skill.cache_key or skill.skill_id or skill.name, sid)
231
+ refs = [skill for _, skill in pairs]
111
232
  matches = match_skill_refs(refs, query_text, limit=max_results)
233
+ results = []
234
+ for match in matches:
235
+ item = match.to_dict()
236
+ item["space_id"] = space_of.get(
237
+ match.skill.cache_key or match.skill.skill_id or match.skill.name, ""
238
+ )
239
+ results.append(item)
112
240
  return {
113
241
  "ok": True,
114
242
  "query": query,
115
- "results": [match.to_dict() for match in matches],
243
+ "space_id": space_id,
244
+ "results": results,
116
245
  }
117
246
  except Exception as exc:
118
247
  return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
@@ -125,43 +254,64 @@ def execute_skills(
125
254
  ) -> dict[str, Any]:
126
255
  """Execute a workflow through the configured Skill Runtime."""
127
256
 
128
- return _gateway().invoke(
129
- "execute_skills",
130
- _execute_skills_impl,
131
- workflow_prompt,
132
- skill_names,
133
- approval=approval,
257
+ return _dict_result(
258
+ _gateway().invoke(
259
+ "execute_skills",
260
+ _execute_skills_impl,
261
+ workflow_prompt,
262
+ skill_names,
263
+ approval=approval,
264
+ ),
265
+ tool_name="execute_skills",
134
266
  )
135
267
 
136
268
 
137
- def _execute_skills_impl(workflow_prompt: str, skill_names: list[str] | str | None = None) -> dict[str, Any]:
269
+ def _execute_skills_impl(
270
+ workflow_prompt: str, skill_names: list[str] | str | None = None
271
+ ) -> dict[str, Any]:
138
272
  try:
139
273
  backend = create_skill_runtime_backend()
140
274
  raw_tool = build_runtime_execute_skills_tool(backend=backend)
141
275
  result = raw_tool(workflow_prompt, skill_names)
142
- if isinstance(result, dict):
143
- result.setdefault("execution_context", f"skill-runtime/{_skill_execution_backend()}")
144
- return result
276
+ if not isinstance(result, dict):
277
+ return {
278
+ "ok": False,
279
+ "error_type": "invalid_skill_runtime_result",
280
+ "error_message": (f"skill runtime returned {type(result).__name__}, expected dict"),
281
+ }
282
+ result.setdefault("execution_context", f"skill-runtime/{_skill_execution_backend()}")
283
+ return dict(result)
145
284
  except SkillRuntimeError as exc:
146
285
  return {
147
286
  "ok": False,
148
287
  "error_type": "skill_runtime_disabled",
149
288
  "error_message": str(exc),
150
- "hint": "Configure KSADK_SKILL_RUNTIME_BACKEND=local_process/e2b or KSADK_SANDBOX_TEMPLATE_ID for isolated Skill workflow execution.",
289
+ "hint": (
290
+ "Configure KSADK_SKILL_RUNTIME_BACKEND=local_process/e2b or "
291
+ "KSADK_SANDBOX_TEMPLATE_ID for isolated Skill workflow execution."
292
+ ),
151
293
  }
152
294
  except Exception as exc:
153
295
  return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
154
296
 
155
297
 
156
298
  def get_skill_tools() -> list:
157
- return [as_tool(list_skills), as_tool(search_skills), as_tool(load_skill), as_tool(execute_skills)]
299
+ return [
300
+ as_tool(list_skills),
301
+ as_tool(list_skill_spaces),
302
+ as_tool(search_skills),
303
+ as_tool(load_skill),
304
+ as_tool(execute_skills),
305
+ ]
158
306
 
159
307
 
160
308
  def _skill_execution_backend() -> str:
161
309
  explicit = os.environ.get("KSADK_SKILL_RUNTIME_BACKEND", "").strip().lower()
162
310
  if explicit:
163
311
  return explicit
164
- if os.environ.get("KSADK_SANDBOX_TEMPLATE_ID") or os.environ.get("KSADK_SKILL_RUNTIME_TEMPLATE_ID"):
312
+ if os.environ.get("KSADK_SANDBOX_TEMPLATE_ID") or os.environ.get(
313
+ "KSADK_SKILL_RUNTIME_TEMPLATE_ID"
314
+ ):
165
315
  return "e2b"
166
316
  return "disabled"
167
317
 
@@ -177,21 +327,34 @@ def _skill_service_client() -> SkillServiceClient:
177
327
  )
178
328
 
179
329
 
180
- def _iter_remote_skills(client: SkillServiceClient):
181
- for space_id in user_skill_space_ids():
330
+ def _iter_space_skills(client: SkillServiceClient, space_id: str):
331
+ """遍历单个 space 的 active skill;space_id="public" 走 premade 列表。"""
332
+
333
+ if space_id == "public":
334
+ listing = client.list_available_premade_skills()
335
+ for skill in select_public_skill_refs(listing.active_skills()):
336
+ yield listing.space_id or "public", skill
337
+ else:
182
338
  listing = client.list_skills_by_space_id(space_id)
183
339
  for skill in listing.active_skills():
184
340
  yield space_id, skill
341
+
342
+
343
+ def _iter_remote_skills(client: SkillServiceClient, space_id: str | None = None):
344
+ """遍历配置的 space;space_id 指定时只遍历该 space(user 或 "public")。"""
345
+
346
+ if space_id:
347
+ yield from _iter_space_skills(client, space_id)
348
+ return
349
+ for user_space_id in user_skill_space_ids():
350
+ yield from _iter_space_skills(client, user_space_id)
185
351
  if public_skill_space_ids():
186
- listing = client.list_available_premade_skills()
187
- for skill in select_public_skill_refs(listing.active_skills()):
188
- yield listing.space_id or "public", skill
352
+ yield from _iter_space_skills(client, "public")
189
353
 
190
354
 
191
355
  def _get_or_download_package(client: SkillServiceClient, skill):
192
356
  cache_dir = Path(
193
- os.environ.get("KSADK_SKILL_CACHE_DIR")
194
- or Path(tempfile.gettempdir()) / "ksadk-skill-cache"
357
+ os.environ.get("KSADK_SKILL_CACHE_DIR") or Path(tempfile.gettempdir()) / "ksadk-skill-cache"
195
358
  )
196
359
  store = PackageStore(cache_dir=cache_dir)
197
360
  package = store.get_cached(skill)
@@ -211,7 +374,5 @@ def _script_files(root_dir: Path) -> list[str]:
211
374
  if not scripts_dir.is_dir():
212
375
  return []
213
376
  return [
214
- str(path.relative_to(root_dir))
215
- for path in sorted(scripts_dir.rglob("*"))
216
- if path.is_file()
377
+ str(path.relative_to(root_dir)) for path in sorted(scripts_dir.rglob("*")) if path.is_file()
217
378
  ][:20]