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
@@ -0,0 +1,52 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ import os
5
+ from collections.abc import Iterator
6
+
7
+ from ksadk.sessions.errors import SessionBackendUnavailable
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ def session_backend_timeout_seconds() -> float:
13
+ raw = (
14
+ os.getenv("KSADK_SESSION_CONNECT_TIMEOUT")
15
+ or os.getenv("KSADK_SESSION_PG_CONNECT_TIMEOUT")
16
+ or ""
17
+ ).strip()
18
+ if not raw:
19
+ return 5.0
20
+ try:
21
+ value = float(raw)
22
+ except ValueError:
23
+ logger.warning("Invalid KSADK_SESSION_CONNECT_TIMEOUT=%r; using 5 seconds", raw)
24
+ return 5.0
25
+ return max(0.1, value)
26
+
27
+
28
+ def _exception_chain(exc: BaseException) -> Iterator[BaseException]:
29
+ seen: set[int] = set()
30
+ current: BaseException | None = exc
31
+ while current is not None and id(current) not in seen:
32
+ seen.add(id(current))
33
+ yield current
34
+ original = getattr(current, "orig", None)
35
+ if isinstance(original, BaseException) and id(original) not in seen:
36
+ current = original
37
+ continue
38
+ current = current.__cause__ or current.__context__
39
+
40
+
41
+ def is_session_backend_failure(exc: BaseException) -> bool:
42
+ """Return whether an exception represents an unavailable database backend."""
43
+ for current in _exception_chain(exc):
44
+ if isinstance(
45
+ current,
46
+ (SessionBackendUnavailable, TimeoutError, OSError, ConnectionError),
47
+ ):
48
+ return True
49
+ module = type(current).__module__
50
+ if module.startswith("asyncpg.") or module.startswith("sqlalchemy."):
51
+ return True
52
+ return False
@@ -0,0 +1,360 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import logging
5
+ from typing import Any, Optional, cast
6
+
7
+ from ksadk.sessions.base import BaseSessionService, Session, SessionEvent, SessionState
8
+ from ksadk.sessions.in_memory import InMemorySessionService
9
+ from ksadk.sessions.resilience import is_session_backend_failure
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class ResilientSessionService(BaseSessionService):
15
+ """Keep live agent sessions available when durable persistence is unavailable.
16
+
17
+ The in-memory service is authoritative for the lifetime of this process. The
18
+ configured durable service is used as a read-through source and a best-effort
19
+ write-through sink. After its first failure it stays disabled until a
20
+ background probe confirms the durable backend is reachable again, at which
21
+ point it is re-enabled and an INFO log is emitted.
22
+ """
23
+
24
+ _probe_interval_seconds: float = 30.0
25
+
26
+ def __init__(
27
+ self,
28
+ primary: BaseSessionService,
29
+ fallback: InMemorySessionService | None = None,
30
+ ) -> None:
31
+ self.primary = primary
32
+ self.fallback = fallback or InMemorySessionService()
33
+ self._primary_enabled = True
34
+ self._hydrate_lock = asyncio.Lock()
35
+ self._primary_session_lock = asyncio.Lock()
36
+ self._primary_session_ids: set[str] = set()
37
+ self._probe_task: asyncio.Task[None] | None = None
38
+
39
+ @property
40
+ def degraded(self) -> bool:
41
+ return not self._primary_enabled
42
+
43
+ async def _call_primary(self, method_name: str, *args: Any, **kwargs: Any) -> tuple[bool, Any]:
44
+ if not self._primary_enabled:
45
+ return False, None
46
+ try:
47
+ method = getattr(self.primary, method_name)
48
+ return True, await method(*args, **kwargs)
49
+ except Exception as exc:
50
+ if not is_session_backend_failure(exc):
51
+ raise
52
+ self._disable_primary(exc)
53
+ return False, None
54
+
55
+ def _disable_primary(self, exc: Exception) -> None:
56
+ if not self._primary_enabled:
57
+ return
58
+ self._primary_enabled = False
59
+ logger.error(
60
+ "KSADK session persistence degraded; using in-memory live session: %s",
61
+ exc,
62
+ extra={
63
+ "session_backend_state": "degraded",
64
+ "session_backend": type(self.primary).__name__,
65
+ },
66
+ )
67
+ self._start_probe()
68
+
69
+ def _start_probe(self) -> None:
70
+ if self._probe_task is not None and not self._probe_task.done():
71
+ return
72
+ self._probe_task = asyncio.create_task(self._probe_loop())
73
+
74
+ async def _probe_loop(self) -> None:
75
+ while not self._primary_enabled:
76
+ await asyncio.sleep(self._probe_interval_seconds)
77
+ if self._primary_enabled:
78
+ break
79
+ try:
80
+ await self.primary.get_session("__ksadk_probe__")
81
+ except Exception:
82
+ continue
83
+ self._primary_enabled = True
84
+ logger.info(
85
+ "KSADK session persistence recovered; durable backend re-enabled",
86
+ extra={
87
+ "session_backend_state": "recovered",
88
+ "session_backend": type(self.primary).__name__,
89
+ },
90
+ )
91
+
92
+ async def _hydrate(self, session: Session) -> Session:
93
+ async with self._hydrate_lock:
94
+ self._primary_session_ids.add(session.id)
95
+ existing = await self.fallback.get_session(session.id)
96
+ if existing is None:
97
+ await self.fallback.create_session(
98
+ session.agent_id,
99
+ session.user_id,
100
+ session_id=session.id,
101
+ )
102
+ existing_events = await self.fallback.get_events(session.id)
103
+ existing_ids = {event.id for event in existing_events}
104
+ for event in sorted(session.events, key=lambda item: item.seq_id):
105
+ if event.id not in existing_ids:
106
+ await self.fallback.append_event(session.id, event)
107
+ await self.fallback.update_session_metadata(
108
+ session.id,
109
+ title=session.title,
110
+ title_source=session.title_source,
111
+ summary=session.summary,
112
+ first_prompt=session.first_prompt,
113
+ last_prompt=session.last_prompt,
114
+ )
115
+ current = await self.fallback.get_session(session.id)
116
+ if current is not None and session.state != current.state:
117
+ await self.fallback.update_state(
118
+ agent_id=session.agent_id,
119
+ user_id=session.user_id,
120
+ session_id=session.id,
121
+ scope="session",
122
+ state_delta=session.state,
123
+ )
124
+ hydrated = await self.fallback.get_session(session.id)
125
+ if hydrated is None:
126
+ raise RuntimeError(f"Failed to hydrate live session {session.id}")
127
+ return hydrated
128
+
129
+ async def create_session(
130
+ self,
131
+ agent_id: str,
132
+ user_id: str,
133
+ session_id: Optional[str] = None,
134
+ ) -> Session:
135
+ if session_id:
136
+ ok, durable = await self._call_primary("get_session", session_id)
137
+ if ok and durable is not None:
138
+ return await self._hydrate(durable)
139
+ existing = await self.fallback.get_session(session_id)
140
+ if existing is not None:
141
+ return existing
142
+
143
+ live = await self.fallback.create_session(agent_id, user_id, session_id=session_id)
144
+ ok, durable = await self._call_primary(
145
+ "create_session",
146
+ agent_id,
147
+ user_id,
148
+ session_id=live.id,
149
+ )
150
+ if ok and durable is not None:
151
+ self._primary_session_ids.add(durable.id)
152
+ return await self._hydrate(durable)
153
+ return live
154
+
155
+ async def get_session(self, session_id: str) -> Optional[Session]:
156
+ live = await self.fallback.get_session(session_id)
157
+ ok, durable = await self._call_primary("get_session", session_id)
158
+ if ok and durable is not None:
159
+ return await self._hydrate(durable)
160
+ return live
161
+
162
+ async def list_sessions(
163
+ self,
164
+ agent_id: str,
165
+ user_id: Optional[str] = None,
166
+ offset: Optional[int] = None,
167
+ limit: Optional[int] = None,
168
+ ) -> list[Session]:
169
+ ok, durable_sessions = await self._call_primary(
170
+ "list_sessions",
171
+ agent_id,
172
+ user_id,
173
+ offset,
174
+ limit,
175
+ )
176
+ if ok:
177
+ for session in durable_sessions or []:
178
+ await self._hydrate(session)
179
+ return cast(
180
+ list[Session],
181
+ await self.fallback.list_sessions(agent_id, user_id, offset, limit),
182
+ )
183
+
184
+ async def count_sessions(self, agent_id: str, user_id: Optional[str] = None) -> int:
185
+ sessions = await self.list_sessions(agent_id, user_id)
186
+ return len(sessions)
187
+
188
+ async def delete_session(self, session_id: str) -> bool:
189
+ deleted = await self.fallback.delete_session(session_id)
190
+ ok, durable_deleted = await self._call_primary("delete_session", session_id)
191
+ if ok:
192
+ self._primary_session_ids.discard(session_id)
193
+ return deleted or bool(durable_deleted) if ok else deleted
194
+
195
+ async def update_session_metadata(
196
+ self,
197
+ session_id: str,
198
+ *,
199
+ title: Optional[str] = None,
200
+ title_source: Optional[str] = None,
201
+ summary: Optional[str] = None,
202
+ first_prompt: Optional[str] = None,
203
+ last_prompt: Optional[str] = None,
204
+ ) -> Session:
205
+ if await self.fallback.get_session(session_id) is None:
206
+ await self.get_session(session_id)
207
+ live = await self.fallback.update_session_metadata(
208
+ session_id,
209
+ title=title,
210
+ title_source=title_source,
211
+ summary=summary,
212
+ first_prompt=first_prompt,
213
+ last_prompt=last_prompt,
214
+ )
215
+ await self._ensure_primary_session(session_id)
216
+ await self._call_primary(
217
+ "update_session_metadata",
218
+ session_id,
219
+ title=title,
220
+ title_source=title_source,
221
+ summary=summary,
222
+ first_prompt=first_prompt,
223
+ last_prompt=last_prompt,
224
+ )
225
+ return live
226
+
227
+ async def _ensure_primary_session(self, session_id: str) -> None:
228
+ """Create the session in PG if it only exists in memory (degraded-era)."""
229
+ if not self._primary_enabled or session_id in self._primary_session_ids:
230
+ return
231
+ async with self._primary_session_lock:
232
+ if not self._primary_enabled or session_id in self._primary_session_ids:
233
+ return
234
+ ok, durable = await self._call_primary("get_session", session_id)
235
+ if not ok:
236
+ return
237
+ if durable is None:
238
+ live = await self.fallback.get_session(session_id)
239
+ if live is None:
240
+ return
241
+ ok, durable = await self._call_primary(
242
+ "create_session",
243
+ live.agent_id,
244
+ live.user_id,
245
+ session_id=live.id,
246
+ )
247
+ if not ok or durable is None:
248
+ return
249
+ self._primary_session_ids.add(session_id)
250
+
251
+ async def append_event(self, session_id: str, event: SessionEvent) -> SessionEvent:
252
+ if await self.fallback.get_session(session_id) is None:
253
+ await self.get_session(session_id)
254
+ live = await self.fallback.append_event(session_id, event)
255
+ await self._ensure_primary_session(session_id)
256
+ await self._call_primary("append_event", session_id, event)
257
+ return live
258
+
259
+ async def get_events(
260
+ self,
261
+ session_id: str,
262
+ offset: Optional[int] = None,
263
+ limit: Optional[int] = None,
264
+ after_seq_id: Optional[int] = None,
265
+ before_seq_id: Optional[int] = None,
266
+ ) -> list[SessionEvent]:
267
+ await self.get_session(session_id)
268
+ return cast(
269
+ list[SessionEvent],
270
+ await self.fallback.get_events(
271
+ session_id,
272
+ offset,
273
+ limit,
274
+ after_seq_id,
275
+ before_seq_id,
276
+ ),
277
+ )
278
+
279
+ async def count_events(
280
+ self,
281
+ session_id: str,
282
+ after_seq_id: Optional[int] = None,
283
+ before_seq_id: Optional[int] = None,
284
+ ) -> int:
285
+ await self.get_session(session_id)
286
+ return cast(
287
+ int,
288
+ await self.fallback.count_events(session_id, after_seq_id, before_seq_id),
289
+ )
290
+
291
+ async def get_state(
292
+ self,
293
+ agent_id: str,
294
+ user_id: Optional[str],
295
+ session_id: Optional[str],
296
+ scope: str = "session",
297
+ ) -> Optional[SessionState]:
298
+ if session_id:
299
+ await self.get_session(session_id)
300
+ live = await self.fallback.get_state(agent_id, user_id, session_id, scope)
301
+ if live is not None or not self._primary_enabled:
302
+ return live
303
+ ok, durable = await self._call_primary(
304
+ "get_state",
305
+ agent_id,
306
+ user_id,
307
+ session_id,
308
+ scope,
309
+ )
310
+ if ok and durable is not None:
311
+ return await self.fallback.update_state(
312
+ agent_id=agent_id,
313
+ user_id=user_id,
314
+ session_id=session_id,
315
+ scope=scope,
316
+ state_delta=durable.state,
317
+ )
318
+ return live
319
+
320
+ async def update_state(
321
+ self,
322
+ *,
323
+ agent_id: str,
324
+ user_id: Optional[str],
325
+ session_id: Optional[str],
326
+ scope: str,
327
+ state_delta: dict[str, Any],
328
+ ) -> SessionState:
329
+ if session_id and await self.fallback.get_session(session_id) is None:
330
+ await self.get_session(session_id)
331
+ live = await self.fallback.update_state(
332
+ agent_id=agent_id,
333
+ user_id=user_id,
334
+ session_id=session_id,
335
+ scope=scope,
336
+ state_delta=state_delta,
337
+ )
338
+ if session_id:
339
+ await self._ensure_primary_session(session_id)
340
+ await self._call_primary(
341
+ "update_state",
342
+ agent_id=agent_id,
343
+ user_id=user_id,
344
+ session_id=session_id,
345
+ scope=scope,
346
+ state_delta=state_delta,
347
+ )
348
+ return live
349
+
350
+ async def aclose(self) -> None:
351
+ if self._probe_task is not None and not self._probe_task.done():
352
+ self._probe_task.cancel()
353
+ try:
354
+ await self._probe_task
355
+ except asyncio.CancelledError:
356
+ pass
357
+ for service in (self.primary, self.fallback):
358
+ close = getattr(service, "aclose", None)
359
+ if close is not None:
360
+ await close()
@@ -0,0 +1,13 @@
1
+ """Compatibility wrapper for the legacy sqlite-backed local session service path."""
2
+
3
+ from ksadk.sessions.local_service import (
4
+ LocalSessionService,
5
+ create_local_session_service,
6
+ resolve_local_session_dir,
7
+ )
8
+
9
+ __all__ = [
10
+ "LocalSessionService",
11
+ "create_local_session_service",
12
+ "resolve_local_session_dir",
13
+ ]
@@ -0,0 +1,9 @@
1
+ """Skill Center runtime consumption helpers."""
2
+
3
+ from ksadk.skills.models import ContentHash, SkillListResponse, SkillRef
4
+
5
+ __all__ = [
6
+ "ContentHash",
7
+ "SkillListResponse",
8
+ "SkillRef",
9
+ ]
ksadk/skills/loader.py ADDED
@@ -0,0 +1,46 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from pathlib import Path
5
+
6
+
7
+ @dataclass(frozen=True)
8
+ class LocalSkill:
9
+ name: str
10
+ description: str
11
+ root_dir: Path
12
+ skill_md: Path
13
+ body: str
14
+
15
+
16
+ def load_local_skill(root_dir: str | Path) -> LocalSkill:
17
+ root = Path(root_dir)
18
+ skill_md = root / "SKILL.md"
19
+ if not skill_md.exists():
20
+ raise FileNotFoundError(f"SKILL.md not found: {skill_md}")
21
+ content = skill_md.read_text(encoding="utf-8")
22
+ metadata, body = _parse_frontmatter(content)
23
+ return LocalSkill(
24
+ name=metadata.get("name") or root.name,
25
+ description=metadata.get("description") or "",
26
+ root_dir=root,
27
+ skill_md=skill_md,
28
+ body=body,
29
+ )
30
+
31
+
32
+ def _parse_frontmatter(content: str) -> tuple[dict[str, str], str]:
33
+ if not content.startswith("---\n"):
34
+ return {}, content
35
+ end = content.find("\n---\n", 4)
36
+ if end == -1:
37
+ return {}, content
38
+ raw_meta = content[4:end]
39
+ body = content[end + 5 :]
40
+ metadata: dict[str, str] = {}
41
+ for line in raw_meta.splitlines():
42
+ if ":" not in line:
43
+ continue
44
+ key, value = line.split(":", 1)
45
+ metadata[key.strip()] = value.strip().strip("\"'")
46
+ return metadata, body
ksadk/skills/models.py ADDED
@@ -0,0 +1,120 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any
5
+
6
+
7
+ @dataclass(frozen=True)
8
+ class ContentHash:
9
+ algorithm: str
10
+ value: str
11
+
12
+ @classmethod
13
+ def parse(cls, raw: str | None) -> "ContentHash | None":
14
+ normalized = str(raw or "").strip()
15
+ if not normalized:
16
+ return None
17
+ if ":" not in normalized:
18
+ return cls("sha256", normalized.lower())
19
+ algorithm, value = normalized.split(":", 1)
20
+ return cls(algorithm.strip().lower(), value.strip().lower())
21
+
22
+ def render(self) -> str:
23
+ return f"{self.algorithm}:{self.value}"
24
+
25
+
26
+ @dataclass(frozen=True)
27
+ class SkillRef:
28
+ skill_id: str
29
+ version_id: str
30
+ version: str
31
+ name: str
32
+ description: str = ""
33
+ status: str = ""
34
+ content_hash: ContentHash | None = None
35
+ archive_uri: str = ""
36
+ aliases: tuple[str, ...] = ()
37
+ tags: tuple[str, ...] = ()
38
+ examples: tuple[str, ...] = ()
39
+ input_schema: dict[str, Any] | None = None
40
+ runtime_requirements: dict[str, Any] | None = None
41
+
42
+ @classmethod
43
+ def from_payload(cls, payload: dict[str, Any]) -> "SkillRef":
44
+ return cls(
45
+ skill_id=str(payload.get("SkillId") or payload.get("skill_id") or ""),
46
+ version_id=str(payload.get("VersionId") or payload.get("version_id") or ""),
47
+ version=str(payload.get("Version") or payload.get("version") or ""),
48
+ name=str(payload.get("Name") or payload.get("name") or ""),
49
+ description=str(payload.get("Description") or payload.get("description") or ""),
50
+ status=str(payload.get("Status") or payload.get("status") or ""),
51
+ content_hash=ContentHash.parse(payload.get("ContentHash") or payload.get("content_hash")),
52
+ archive_uri=str(payload.get("ArchiveUri") or payload.get("archive_uri") or ""),
53
+ aliases=_string_tuple(payload.get("Aliases") or payload.get("aliases")),
54
+ tags=_string_tuple(payload.get("Tags") or payload.get("tags")),
55
+ examples=_string_tuple(payload.get("Examples") or payload.get("examples")),
56
+ input_schema=_dict_or_none(payload.get("InputSchema") or payload.get("input_schema")),
57
+ runtime_requirements=_dict_or_none(
58
+ payload.get("RuntimeRequirements") or payload.get("runtime_requirements")
59
+ ),
60
+ )
61
+
62
+ @property
63
+ def cache_key(self) -> str:
64
+ identity = self.skill_id or self.name
65
+ version_key = self.version_id or self.version
66
+ if not version_key and self.content_hash:
67
+ version_key = self.content_hash.value
68
+ return "__".join(part.replace("/", "_").replace(":", "_") for part in (identity, version_key) if part)
69
+
70
+ @property
71
+ def is_active(self) -> bool:
72
+ return not self.status or self.status.lower() in {"active", "available", "enabled"}
73
+
74
+
75
+ @dataclass(frozen=True)
76
+ class SkillListResponse:
77
+ request_id: str
78
+ space_id: str
79
+ space_name: str
80
+ skills: list[SkillRef]
81
+ code: int = 0
82
+ message: str = ""
83
+
84
+ @classmethod
85
+ def from_payload(
86
+ cls,
87
+ payload: dict[str, Any],
88
+ *,
89
+ space_id: str = "",
90
+ space_name: str = "",
91
+ ) -> "SkillListResponse":
92
+ data = payload.get("Data") or payload.get("data") or {}
93
+ skills_payload = data.get("Skills") or data.get("skills") or data.get("Items") or data.get("items") or []
94
+ return cls(
95
+ code=int(payload.get("Code") or payload.get("code") or 0),
96
+ message=str(payload.get("Message") or payload.get("message") or ""),
97
+ request_id=str(payload.get("RequestId") or payload.get("request_id") or ""),
98
+ space_id=str(data.get("SkillSpaceId") or data.get("skill_space_id") or space_id),
99
+ space_name=str(data.get("SkillSpaceName") or data.get("skill_space_name") or space_name),
100
+ skills=[SkillRef.from_payload(item) for item in skills_payload if isinstance(item, dict)],
101
+ )
102
+
103
+ def active_skills(self) -> list[SkillRef]:
104
+ return [skill for skill in self.skills if skill.is_active]
105
+
106
+
107
+ def _string_tuple(raw: Any) -> tuple[str, ...]:
108
+ if raw is None:
109
+ return ()
110
+ if isinstance(raw, str):
111
+ values = raw.split(",")
112
+ elif isinstance(raw, (list, tuple, set)):
113
+ values = raw
114
+ else:
115
+ return ()
116
+ return tuple(value for value in (str(item).strip() for item in values) if value)
117
+
118
+
119
+ def _dict_or_none(raw: Any) -> dict[str, Any] | None:
120
+ return dict(raw) if isinstance(raw, dict) else None