agentengine-sdk-python 0.6.2__py3-none-any.whl → 0.6.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (490) hide show
  1. agentengine_sdk_python-0.6.9.dist-info/METADATA +179 -0
  2. agentengine_sdk_python-0.6.9.dist-info/RECORD +487 -0
  3. {agentengine_sdk_python-0.6.2.dist-info → agentengine_sdk_python-0.6.9.dist-info}/WHEEL +1 -1
  4. agentengine_sdk_python-0.6.9.dist-info/entry_points.txt +3 -0
  5. agentengine_sdk_python-0.6.9.dist-info/licenses/LICENSE +175 -0
  6. agentengine_sdk_python-0.6.9.dist-info/top_level.txt +2 -0
  7. ksadk/__init__.py +13 -0
  8. ksadk/__main__.py +4 -0
  9. ksadk/a2a/__init__.py +15 -0
  10. ksadk/a2a/card_builder.py +64 -0
  11. ksadk/a2a/client.py +309 -0
  12. ksadk/a2a/executor.py +201 -0
  13. ksadk/a2a/server.py +79 -0
  14. ksadk/agents/__init__.py +20 -0
  15. ksadk/agents/base.py +370 -0
  16. ksadk/agents/context.py +38 -0
  17. ksadk/agents/event.py +35 -0
  18. ksadk/agents/loop_agent.py +71 -0
  19. ksadk/agents/parallel_agent.py +109 -0
  20. ksadk/agents/runner_adapter.py +24 -0
  21. ksadk/agents/sequential_agent.py +34 -0
  22. ksadk/api/__init__.py +3 -0
  23. ksadk/api/client.py +2227 -0
  24. ksadk/builders/__init__.py +20 -0
  25. ksadk/builders/base.py +66 -0
  26. ksadk/builders/code_builder.py +1990 -0
  27. ksadk/builders/container_builder.py +786 -0
  28. ksadk/builders/framework_requirements.py +59 -0
  29. ksadk/builders/ks3_uploader.py +389 -0
  30. ksadk/builders/mcp_builder.py +476 -0
  31. ksadk/builders/requirements_utils.py +75 -0
  32. ksadk/cli/__init__.py +531 -0
  33. ksadk/cli/__main__.py +4 -0
  34. ksadk/cli/agent_ref.py +204 -0
  35. ksadk/cli/cmd_a2a.py +167 -0
  36. ksadk/cli/cmd_agent.py +201 -0
  37. ksadk/cli/cmd_build.py +270 -0
  38. ksadk/cli/cmd_completion.py +304 -0
  39. ksadk/cli/cmd_config.py +758 -0
  40. ksadk/cli/cmd_create.py +2277 -0
  41. ksadk/cli/cmd_dashboard.py +900 -0
  42. ksadk/cli/cmd_deploy.py +704 -0
  43. ksadk/cli/cmd_destroy.py +345 -0
  44. ksadk/cli/cmd_files.py +1227 -0
  45. ksadk/cli/cmd_hermes.py +1259 -0
  46. ksadk/cli/cmd_invoke.py +1336 -0
  47. ksadk/cli/cmd_launch.py +564 -0
  48. ksadk/cli/cmd_mcp.py +1174 -0
  49. ksadk/cli/cmd_model.py +302 -0
  50. ksadk/cli/cmd_openclaw.py +3918 -0
  51. ksadk/cli/cmd_run.py +232 -0
  52. ksadk/cli/cmd_status.py +588 -0
  53. ksadk/cli/cmd_version.py +522 -0
  54. ksadk/cli/cmd_web.py +288 -0
  55. ksadk/cli/deploy_utils.py +87 -0
  56. ksadk/cli/dry_run.py +214 -0
  57. ksadk/cli/env_options.py +82 -0
  58. ksadk/cli/error_utils.py +525 -0
  59. ksadk/cli/global_options.py +31 -0
  60. ksadk/cli/local_runtime.py +97 -0
  61. ksadk/cli/model_catalog.py +136 -0
  62. ksadk/cli/network_options.py +410 -0
  63. ksadk/cli/resource_common.py +621 -0
  64. ksadk/cli/storage.py +84 -0
  65. ksadk/cli/ui.py +431 -0
  66. ksadk/cli/workflow_common.py +552 -0
  67. ksadk/common/__init__.py +14 -0
  68. ksadk/common/aicp_env.py +128 -0
  69. ksadk/common/auth.py +190 -0
  70. ksadk/common/constants.py +84 -0
  71. ksadk/common/llm_utils.py +61 -0
  72. ksadk/configs/__init__.py +61 -0
  73. ksadk/configs/env_registry.py +342 -0
  74. ksadk/configs/global_config.py +200 -0
  75. ksadk/configs/settings.py +706 -0
  76. ksadk/conversations/__init__.py +95 -0
  77. ksadk/conversations/attachment_storage.py +379 -0
  78. ksadk/conversations/attachments.py +774 -0
  79. ksadk/conversations/compaction_pipeline.py +387 -0
  80. ksadk/conversations/compaction_prompt.py +128 -0
  81. ksadk/conversations/context.py +303 -0
  82. ksadk/conversations/model_context.py +360 -0
  83. ksadk/conversations/model_options.py +136 -0
  84. ksadk/conversations/normalize.py +446 -0
  85. ksadk/conversations/reasoning_markup.py +91 -0
  86. ksadk/conversations/run_kinds.py +61 -0
  87. ksadk/conversations/run_status.py +53 -0
  88. ksadk/conversations/runtime.py +5208 -0
  89. ksadk/conversations/semantic_summary.py +359 -0
  90. ksadk/conversations/session_title.py +254 -0
  91. ksadk/deployment/__init__.py +83 -0
  92. ksadk/deployment/agent_access.py +226 -0
  93. ksadk/deployment/base.py +229 -0
  94. ksadk/deployment/manager.py +332 -0
  95. ksadk/deployment/providers/__init__.py +10 -0
  96. ksadk/deployment/providers/serverless.py +1105 -0
  97. ksadk/deployment/registry.py +120 -0
  98. ksadk/deployment/state.py +78 -0
  99. ksadk/deployment/ui_config.py +21 -0
  100. ksadk/detection/__init__.py +7 -0
  101. ksadk/detection/detector.py +431 -0
  102. ksadk/detection/mcp_detector.py +250 -0
  103. ksadk/hermes_terminal.py +467 -0
  104. ksadk/identity/__init__.py +17 -0
  105. ksadk/identity/resolver.py +385 -0
  106. ksadk/knowledge_base/__init__.py +62 -0
  107. ksadk/knowledge_base/adk_tool.py +47 -0
  108. ksadk/knowledge_base/client.py +297 -0
  109. ksadk/knowledge_base/langchain_tool.py +55 -0
  110. ksadk/knowledge_base/service.py +66 -0
  111. ksadk/knowledge_base/tool.py +50 -0
  112. ksadk/markdown.py +169 -0
  113. ksadk/mcp_runtime/__init__.py +231 -0
  114. ksadk/memory/__init__.py +57 -0
  115. ksadk/memory/adk/__init__.py +51 -0
  116. ksadk/memory/adk/backends/__init__.py +5 -0
  117. ksadk/memory/adk/backends/base_ltm_backend.py +52 -0
  118. ksadk/memory/adk/backends/http_ltm_backend.py +183 -0
  119. ksadk/memory/adk/backends/inmemory_ltm_backend.py +96 -0
  120. ksadk/memory/adk/backends/sdk_ltm_backend.py +456 -0
  121. ksadk/memory/adk/long_term_memory.py +273 -0
  122. ksadk/memory/adk/short_term_memory.py +289 -0
  123. ksadk/memory/adk_tool.py +31 -0
  124. ksadk/memory/backends/__init__.py +6 -0
  125. ksadk/memory/backends/base.py +103 -0
  126. ksadk/memory/backends/memory.py +112 -0
  127. ksadk/memory/backends/redis.py +146 -0
  128. ksadk/memory/langchain_tool.py +39 -0
  129. ksadk/memory/ltm_backend_factory.py +24 -0
  130. ksadk/memory/manager.py +215 -0
  131. ksadk/memory/service.py +172 -0
  132. ksadk/memory/tool.py +96 -0
  133. ksadk/model_policy.py +223 -0
  134. ksadk/openclaw_gateway.py +378 -0
  135. ksadk/runners/__init__.py +8 -0
  136. ksadk/runners/adk_runner.py +1135 -0
  137. ksadk/runners/base_runner.py +305 -0
  138. ksadk/runners/deepagents_runner.py +13 -0
  139. ksadk/runners/factory.py +73 -0
  140. ksadk/runners/langchain_runner.py +539 -0
  141. ksadk/runners/langgraph_runner.py +852 -0
  142. ksadk/runners/patch_langchain.py +187 -0
  143. ksadk/runners/remote_runner.py +667 -0
  144. ksadk/runners/usage_accumulator.py +38 -0
  145. ksadk/runners/utils/__init__.py +19 -0
  146. ksadk/runners/utils/langfuse.py +230 -0
  147. ksadk/runners/utils/loader.py +62 -0
  148. ksadk/runtime_context.py +166 -0
  149. ksadk/runtime_state.py +25 -0
  150. ksadk/sandbox/__init__.py +28 -0
  151. ksadk/sandbox/backends/__init__.py +9 -0
  152. ksadk/sandbox/backends/e2b.py +154 -0
  153. ksadk/sandbox/backends/local_process.py +131 -0
  154. ksadk/sandbox/base.py +101 -0
  155. ksadk/sandbox/factory.py +53 -0
  156. ksadk/sandbox/registry.py +187 -0
  157. ksadk/server/__init__.py +7 -0
  158. ksadk/server/api_models.py +73 -0
  159. ksadk/server/app.py +3789 -0
  160. ksadk/server/static/assets/ArtifactsPanel-C0meuOdi.js +1 -0
  161. ksadk/server/static/assets/CodeBlock-BbI4HPtJ.js +9 -0
  162. ksadk/server/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  163. ksadk/server/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  164. ksadk/server/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  165. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  166. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  167. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  168. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  169. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  170. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  171. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  172. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  173. ksadk/server/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  174. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  175. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  176. ksadk/server/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  177. ksadk/server/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  178. ksadk/server/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  179. ksadk/server/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  180. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  181. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  182. ksadk/server/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  183. ksadk/server/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  184. ksadk/server/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  185. ksadk/server/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  186. ksadk/server/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  187. ksadk/server/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  188. ksadk/server/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  189. ksadk/server/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  190. ksadk/server/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  191. ksadk/server/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  192. ksadk/server/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  193. ksadk/server/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  194. ksadk/server/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  195. ksadk/server/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  196. ksadk/server/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  197. ksadk/server/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  198. ksadk/server/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  199. ksadk/server/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  200. ksadk/server/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  201. ksadk/server/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  202. ksadk/server/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  203. ksadk/server/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  204. ksadk/server/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  205. ksadk/server/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  206. ksadk/server/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  207. ksadk/server/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  208. ksadk/server/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  209. ksadk/server/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  210. ksadk/server/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  211. ksadk/server/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  212. ksadk/server/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  213. ksadk/server/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  214. ksadk/server/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  215. ksadk/server/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  216. ksadk/server/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  217. ksadk/server/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  218. ksadk/server/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  219. ksadk/server/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  220. ksadk/server/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  221. ksadk/server/static/assets/MathMessageMarkdown-DMLQYoLp.js +8 -0
  222. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +1 -0
  223. ksadk/server/static/assets/MermaidBlock-DCR8WZ17.js +303 -0
  224. ksadk/server/static/assets/NativeTerminalPanel-CHOd7Rch.css +1 -0
  225. ksadk/server/static/assets/NativeTerminalPanel-CKUvWhUz.js +1 -0
  226. ksadk/server/static/assets/addon-fit-DthTIhi3.js +1 -0
  227. ksadk/server/static/assets/apl-CnwPGSsG.js +1 -0
  228. ksadk/server/static/assets/arc-bj2rZnP5.js +1 -0
  229. ksadk/server/static/assets/architecture-7EHR7CIX-Cr6Xz1_c.js +1 -0
  230. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-2u1ltDIj.js +36 -0
  231. ksadk/server/static/assets/asciiarmor-qTkVPQu6.js +1 -0
  232. ksadk/server/static/assets/asn1-Dr8qZg38.js +1 -0
  233. ksadk/server/static/assets/asterisk-Bja0s6e1.js +1 -0
  234. ksadk/server/static/assets/blockDiagram-GPEHLZMM-D6fvdK20.js +132 -0
  235. ksadk/server/static/assets/brainfuck-D5EjA2JK.js +1 -0
  236. ksadk/server/static/assets/c4Diagram-AAUBKEIU-BK82L5n5.js +10 -0
  237. ksadk/server/static/assets/channel-BSSOwFIb.js +1 -0
  238. ksadk/server/static/assets/chunk-2J33WTMH-DLVdkeyQ.js +1 -0
  239. ksadk/server/static/assets/chunk-4BX2VUAB-BbwsYcbW.js +1 -0
  240. ksadk/server/static/assets/chunk-55IACEB6-DOairxzw.js +1 -0
  241. ksadk/server/static/assets/chunk-727SXJPM-hCO487gs.js +206 -0
  242. ksadk/server/static/assets/chunk-AQP2D5EJ-XU8vDOuG.js +231 -0
  243. ksadk/server/static/assets/chunk-FMBD7UC4-PrapyfMu.js +15 -0
  244. ksadk/server/static/assets/chunk-ND2GUHAM-CboKhTZ3.js +1 -0
  245. ksadk/server/static/assets/chunk-QZHKN3VN-XXpdiwUL.js +1 -0
  246. ksadk/server/static/assets/classDiagram-4FO5ZUOK-C5HvGiyK.js +1 -0
  247. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-C5HvGiyK.js +1 -0
  248. ksadk/server/static/assets/clike-DHH8Ad3s.js +1 -0
  249. ksadk/server/static/assets/clojure-BflJGmDX.js +1 -0
  250. ksadk/server/static/assets/cmake-CyVbuzPu.js +1 -0
  251. ksadk/server/static/assets/cobol-B_OZ4V-R.js +1 -0
  252. ksadk/server/static/assets/coffeescript-B2pKbFk8.js +1 -0
  253. ksadk/server/static/assets/commonlisp-CcllspGY.js +1 -0
  254. ksadk/server/static/assets/cose-bilkent-S5V4N54A-_N8bJ-EU.js +1 -0
  255. ksadk/server/static/assets/crystal-M5-qzICs.js +1 -0
  256. ksadk/server/static/assets/css-CYpP4FRV.js +1 -0
  257. ksadk/server/static/assets/cypher-p9eYesGn.js +1 -0
  258. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +321 -0
  259. ksadk/server/static/assets/d-BhMjBjQP.js +1 -0
  260. ksadk/server/static/assets/dagre-BM42HDAG-FoDlo5J2.js +4 -0
  261. ksadk/server/static/assets/dagre-Bx709z4p.js +1 -0
  262. ksadk/server/static/assets/defaultLocale-C8Fc0cco.js +1 -0
  263. ksadk/server/static/assets/diagram-2AECGRRQ-BBp6ebBw.js +43 -0
  264. ksadk/server/static/assets/diagram-5GNKFQAL-CqOvG1PR.js +10 -0
  265. ksadk/server/static/assets/diagram-KO2AKTUF-O9T3t6ba.js +3 -0
  266. ksadk/server/static/assets/diagram-LMA3HP47-CGG8ekBO.js +24 -0
  267. ksadk/server/static/assets/diagram-OG6HWLK6-4BmH1EEg.js +24 -0
  268. ksadk/server/static/assets/diff-ChtP43wD.js +1 -0
  269. ksadk/server/static/assets/dist-6kSZvCZh.js +1 -0
  270. ksadk/server/static/assets/dist-B67uF2uK.js +1 -0
  271. ksadk/server/static/assets/dist-BMKM66B4.js +1 -0
  272. ksadk/server/static/assets/dist-BVzcWa6D.js +1 -0
  273. ksadk/server/static/assets/dist-Bk1l05Ni.js +1 -0
  274. ksadk/server/static/assets/dist-BkJjNih3.js +1 -0
  275. ksadk/server/static/assets/dist-BmuTWcm7.js +9 -0
  276. ksadk/server/static/assets/dist-C2DKRFVK.js +1 -0
  277. ksadk/server/static/assets/dist-CWiTDN_V.js +6 -0
  278. ksadk/server/static/assets/dist-CZ6C3x8B.js +23 -0
  279. ksadk/server/static/assets/dist-CiZHB6ZW.js +1 -0
  280. ksadk/server/static/assets/dist-Cp1_jKwf.js +1 -0
  281. ksadk/server/static/assets/dist-Cwhk4lwI.js +2 -0
  282. ksadk/server/static/assets/dist-D5JGcxBx.js +11 -0
  283. ksadk/server/static/assets/dist-D99wf6_X.js +1 -0
  284. ksadk/server/static/assets/dist-DCpZrjaK.js +1 -0
  285. ksadk/server/static/assets/dist-DI-oVAXw.js +1 -0
  286. ksadk/server/static/assets/dist-DLMjL01k.js +1 -0
  287. ksadk/server/static/assets/dist-DLeM1OCK.js +1 -0
  288. ksadk/server/static/assets/dist-DM0rEQPk.js +1 -0
  289. ksadk/server/static/assets/dist-DbaH3p5h.js +1 -0
  290. ksadk/server/static/assets/dist-S4klkK5W.js +1 -0
  291. ksadk/server/static/assets/dockerfile-BLkNEvjs.js +1 -0
  292. ksadk/server/static/assets/dtd-DTF72YNO.js +1 -0
  293. ksadk/server/static/assets/dylan-C6jEEEk-.js +1 -0
  294. ksadk/server/static/assets/ebnf-D4c0_ac3.js +1 -0
  295. ksadk/server/static/assets/ecl-BSZaIHnp.js +1 -0
  296. ksadk/server/static/assets/eiffel-BEjRio4Q.js +1 -0
  297. ksadk/server/static/assets/elm-Cshzl8qu.js +1 -0
  298. ksadk/server/static/assets/erDiagram-TEJ5UH35-oJhaci7S.js +85 -0
  299. ksadk/server/static/assets/erlang-DaB2Rkuy.js +1 -0
  300. ksadk/server/static/assets/eventmodeling-FCH6USID-CIgwHJLL.js +1 -0
  301. ksadk/server/static/assets/factor-D7LVTn2l.js +1 -0
  302. ksadk/server/static/assets/fcl-ClOhbFR7.js +1 -0
  303. ksadk/server/static/assets/flowDiagram-I6XJVG4X-DtTmUan-.js +162 -0
  304. ksadk/server/static/assets/forth-Cezjo90N.js +1 -0
  305. ksadk/server/static/assets/fortran-Bt6PBEDR.js +1 -0
  306. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-BSsb_eij.js +292 -0
  307. ksadk/server/static/assets/gas-BHEdbvp9.js +1 -0
  308. ksadk/server/static/assets/gherkin-oBAE_ms0.js +1 -0
  309. ksadk/server/static/assets/gitGraph-WXDBUCRP-BVAJ7uo0.js +1 -0
  310. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-BR5s6Pws.js +106 -0
  311. ksadk/server/static/assets/graphlib-B8gBHxth.js +1 -0
  312. ksadk/server/static/assets/groovy-BC3IOsC8.js +1 -0
  313. ksadk/server/static/assets/haskell-BRsoo5mP.js +1 -0
  314. ksadk/server/static/assets/haxe-DIz0ZZqd.js +1 -0
  315. ksadk/server/static/assets/http-CLVgA2GD.js +1 -0
  316. ksadk/server/static/assets/idl-BUZw3wgd.js +1 -0
  317. ksadk/server/static/assets/index-BH7-pC0B.js +165 -0
  318. ksadk/server/static/assets/index-DAURbCsP.css +1 -0
  319. ksadk/server/static/assets/info-J43DQDTF-MT80V4ge.js +1 -0
  320. ksadk/server/static/assets/infoDiagram-5YYISTIA-DYPc5cvh.js +2 -0
  321. ksadk/server/static/assets/init-D6jRqBbL.js +1 -0
  322. ksadk/server/static/assets/ishikawaDiagram-YF4QCWOH-MoBdALDg.js +70 -0
  323. ksadk/server/static/assets/javascript-9Tg8ixDm.js +1 -0
  324. ksadk/server/static/assets/journeyDiagram-JHISSGLW-DgLiQT8l.js +139 -0
  325. ksadk/server/static/assets/julia-CQfgDRfP.js +1 -0
  326. ksadk/server/static/assets/kanban-definition-UN3LZRKU-CsFx112F.js +89 -0
  327. ksadk/server/static/assets/katex-DRsiwpM2.js +265 -0
  328. ksadk/server/static/assets/linear-TNRQ5Orv.js +1 -0
  329. ksadk/server/static/assets/livescript-BXxG0Yva.js +1 -0
  330. ksadk/server/static/assets/lua-CiA1ziua.js +1 -0
  331. ksadk/server/static/assets/mathematica-u8YMmbU0.js +1 -0
  332. ksadk/server/static/assets/mbox-BEMVcqjs.js +1 -0
  333. ksadk/server/static/assets/mermaid-parser.core-D2eMVOgo.js +161 -0
  334. ksadk/server/static/assets/mindmap-definition-RKZ34NQL-BtByYFhL.js +96 -0
  335. ksadk/server/static/assets/mirc-C9zpzAZU.js +1 -0
  336. ksadk/server/static/assets/mllike-B45xgp2S.js +1 -0
  337. ksadk/server/static/assets/modelica-CqHI_q-D.js +1 -0
  338. ksadk/server/static/assets/mscgen-qgSLujhx.js +1 -0
  339. ksadk/server/static/assets/mumps-CW_TBmxz.js +1 -0
  340. ksadk/server/static/assets/nginx-BMaDbqW3.js +1 -0
  341. ksadk/server/static/assets/nsis-AQ_alPln.js +1 -0
  342. ksadk/server/static/assets/ntriples-d28e9m0E.js +1 -0
  343. ksadk/server/static/assets/octave-D2Q8cUp1.js +1 -0
  344. ksadk/server/static/assets/ordinal-hYBb2elL.js +1 -0
  345. ksadk/server/static/assets/oz-BwTct_5T.js +1 -0
  346. ksadk/server/static/assets/packet-YPE3B663-BLKhbXZB.js +1 -0
  347. ksadk/server/static/assets/pascal-Dp_KdFgX.js +1 -0
  348. ksadk/server/static/assets/perl-CdEHsPfU.js +1 -0
  349. ksadk/server/static/assets/pie-LRSECV5Y-DFOikjSY.js +1 -0
  350. ksadk/server/static/assets/pieDiagram-4H26LBE5-DPnuCB8c.js +30 -0
  351. ksadk/server/static/assets/pig-AF4Hwhju.js +1 -0
  352. ksadk/server/static/assets/powershell-CzG71I4L.js +1 -0
  353. ksadk/server/static/assets/properties-C357ku5U.js +1 -0
  354. ksadk/server/static/assets/protobuf-D1ij_kNL.js +1 -0
  355. ksadk/server/static/assets/pug-Bugr-47h.js +1 -0
  356. ksadk/server/static/assets/puppet-B4hC2X4m.js +1 -0
  357. ksadk/server/static/assets/python-BqYw9LYJ.js +1 -0
  358. ksadk/server/static/assets/q-B9NhS7L_.js +1 -0
  359. ksadk/server/static/assets/quadrantDiagram-W4KKPZXB-miFpCPv4.js +7 -0
  360. ksadk/server/static/assets/r-DADKenSm.js +1 -0
  361. ksadk/server/static/assets/radar-GUYGQ44K-095b1Ikw.js +1 -0
  362. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-mjB_yYkW.js +84 -0
  363. ksadk/server/static/assets/rpm-gpDK5sbt.js +1 -0
  364. ksadk/server/static/assets/ruby-DsYpTuWg.js +1 -0
  365. ksadk/server/static/assets/sankeyDiagram-5OEKKPKP-D7hSlZZZ.js +40 -0
  366. ksadk/server/static/assets/sas-C2OyD2Y6.js +1 -0
  367. ksadk/server/static/assets/scheme-CyDdOh7e.js +1 -0
  368. ksadk/server/static/assets/sequenceDiagram-3UESZ5HK-D9Cx6hC3.js +162 -0
  369. ksadk/server/static/assets/shell-Du5Qg9im.js +1 -0
  370. ksadk/server/static/assets/sieve-BAxa3IjF.js +1 -0
  371. ksadk/server/static/assets/simple-mode-DRpGK0lJ.js +1 -0
  372. ksadk/server/static/assets/smalltalk-BLp5-jwC.js +1 -0
  373. ksadk/server/static/assets/solr-BBopId9w.js +1 -0
  374. ksadk/server/static/assets/sparql-Dz-mlCAC.js +1 -0
  375. ksadk/server/static/assets/spreadsheet-CTIncYxj.js +1 -0
  376. ksadk/server/static/assets/sql-DcCJ9jop.js +1 -0
  377. ksadk/server/static/assets/stateDiagram-AJRCARHV-D_zrg47o.js +1 -0
  378. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-J9kCb0nC.js +1 -0
  379. ksadk/server/static/assets/stex-sDrdk2BW.js +1 -0
  380. ksadk/server/static/assets/stylus-DLLZ8dgm.js +1 -0
  381. ksadk/server/static/assets/swift-DKB6_1j6.js +1 -0
  382. ksadk/server/static/assets/tcl-BGfruO1u.js +1 -0
  383. ksadk/server/static/assets/textile-DWBqthVk.js +1 -0
  384. ksadk/server/static/assets/tiddlywiki-VlUiK86J.js +1 -0
  385. ksadk/server/static/assets/tiki-CxVlf5KZ.js +1 -0
  386. ksadk/server/static/assets/timeline-definition-PNZ67QCA-CwSec0Wa.js +120 -0
  387. ksadk/server/static/assets/toml-LvoKBwCs.js +1 -0
  388. ksadk/server/static/assets/treeView-BLDUP644-yinfJEY6.js +1 -0
  389. ksadk/server/static/assets/treemap-LRROVOQU-DosUqN1Q.js +1 -0
  390. ksadk/server/static/assets/troff-C2dAgh7P.js +1 -0
  391. ksadk/server/static/assets/ttcn-BePYh-hG.js +1 -0
  392. ksadk/server/static/assets/ttcn-cfg-CY0aot7Q.js +1 -0
  393. ksadk/server/static/assets/turtle-BDLWE2cD.js +1 -0
  394. ksadk/server/static/assets/vb-BthdM_4N.js +1 -0
  395. ksadk/server/static/assets/vbscript-D9f6rSsU.js +1 -0
  396. ksadk/server/static/assets/velocity-CqftRsjg.js +1 -0
  397. ksadk/server/static/assets/vennDiagram-CIIHVFJN-agCVobiF.js +34 -0
  398. ksadk/server/static/assets/verilog-D-x6ne0Z.js +1 -0
  399. ksadk/server/static/assets/vhdl-CMrOq2q1.js +1 -0
  400. ksadk/server/static/assets/wardley-L42UT6IY-Bvp7-5uH.js +1 -0
  401. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-TmrlhWNt.js +78 -0
  402. ksadk/server/static/assets/webidl-D5jiJvOU.js +1 -0
  403. ksadk/server/static/assets/xquery-fj_R-kMw.js +1 -0
  404. ksadk/server/static/assets/xterm-DooSxjI5.js +36 -0
  405. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-DV71V-ah.js +7 -0
  406. ksadk/server/static/assets/yacas-CXXgtw0p.js +1 -0
  407. ksadk/server/static/assets/z80-CL1naaMV.js +1 -0
  408. ksadk/server/static/favicon.svg +1 -0
  409. ksadk/server/static/icons.svg +24 -0
  410. ksadk/server/static/index.html +14 -0
  411. ksadk/server/terminal_sessions.py +551 -0
  412. ksadk/sessions/__init__.py +283 -0
  413. ksadk/sessions/base.py +354 -0
  414. ksadk/sessions/continuity.py +313 -0
  415. ksadk/sessions/errors.py +7 -0
  416. ksadk/sessions/in_memory.py +273 -0
  417. ksadk/sessions/local_service.py +949 -0
  418. ksadk/sessions/postgres_service.py +838 -0
  419. ksadk/sessions/sqlite_service.py +13 -0
  420. ksadk/skills/__init__.py +9 -0
  421. ksadk/skills/loader.py +46 -0
  422. ksadk/skills/models.py +120 -0
  423. ksadk/skills/package_store.py +104 -0
  424. ksadk/skills/runtime/__init__.py +17 -0
  425. ksadk/skills/runtime/agent.py +183 -0
  426. ksadk/skills/runtime/artifacts.py +39 -0
  427. ksadk/skills/runtime/backends/__init__.py +1 -0
  428. ksadk/skills/runtime/backends/disabled.py +8 -0
  429. ksadk/skills/runtime/backends/e2b.py +168 -0
  430. ksadk/skills/runtime/backends/local.py +95 -0
  431. ksadk/skills/runtime/base.py +103 -0
  432. ksadk/skills/runtime/executor.py +219 -0
  433. ksadk/skills/runtime/factory.py +37 -0
  434. ksadk/skills/runtime/loader.py +131 -0
  435. ksadk/skills/runtime/registry.py +150 -0
  436. ksadk/skills/runtime/request.py +67 -0
  437. ksadk/skills/service_client.py +239 -0
  438. ksadk/skills/service_env.py +58 -0
  439. ksadk/skills/tool_defs.py +221 -0
  440. ksadk/terminal_client.py +69 -0
  441. ksadk/terminal_exec_policy.py +229 -0
  442. ksadk/tools/__init__.py +17 -0
  443. ksadk/tools/gateway.py +230 -0
  444. ksadk/tools/result_budget.py +154 -0
  445. ksadk/toolsets/__init__.py +852 -0
  446. ksadk/toolsets/_langchain.py +11 -0
  447. ksadk/toolsets/platform.py +93 -0
  448. ksadk/toolsets/sandbox.py +310 -0
  449. ksadk/toolsets/skills.py +217 -0
  450. ksadk/toolsets/web.py +266 -0
  451. ksadk/toolsets/workspace.py +878 -0
  452. ksadk/toolsets/workspace_state.py +44 -0
  453. ksadk/tracing/__init__.py +37 -0
  454. ksadk/tracing/exporters/__init__.py +1 -0
  455. ksadk/tracing/exporters/inmemory_exporter.py +116 -0
  456. ksadk/tracing/exporters/langfuse_exporter.py +445 -0
  457. ksadk/tracing/setup.py +829 -0
  458. ksadk/tracing/span_utils.py +114 -0
  459. ksadk/tui/__init__.py +12 -0
  460. ksadk/tui/app.py +400 -0
  461. ksadk/tui/clipboard.py +100 -0
  462. ksadk/tui/widgets/__init__.py +22 -0
  463. ksadk/tui/widgets/assistant.py +89 -0
  464. ksadk/tui/widgets/base.py +54 -0
  465. ksadk/tui/widgets/chat_input.py +246 -0
  466. ksadk/tui/widgets/history.py +156 -0
  467. ksadk/tui/widgets/system.py +87 -0
  468. ksadk/tui/widgets/thinking.py +110 -0
  469. ksadk/tui/widgets/tool_call.py +161 -0
  470. ksadk/tui/widgets/user.py +37 -0
  471. ksadk/ui_config.py +168 -0
  472. ksadk/version.py +4 -0
  473. ksadk_runtime_common/__init__.py +20 -0
  474. ksadk_runtime_common/memory_backend/__init__.py +29 -0
  475. ksadk_runtime_common/memory_backend/manifest.py +79 -0
  476. ksadk_runtime_common/memory_backend/providers/__init__.py +6 -0
  477. ksadk_runtime_common/memory_backend/providers/lancedb.py +151 -0
  478. ksadk_runtime_common/memory_backend/providers/mem0.py +74 -0
  479. ksadk_runtime_common/memory_backend/registry.py +56 -0
  480. ksadk_runtime_common/memory_backend/render.py +71 -0
  481. ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -0
  482. ksadk_runtime_common/workspace_files/__init__.py +29 -0
  483. ksadk_runtime_common/workspace_files/bootstrap.py +56 -0
  484. ksadk_runtime_common/workspace_files/constants.py +9 -0
  485. ksadk_runtime_common/workspace_files/path_utils.py +71 -0
  486. ksadk_runtime_common/workspace_files/preview.py +96 -0
  487. ksadk_runtime_common/workspace_files/router.py +254 -0
  488. agentengine_sdk_python-0.6.2.dist-info/METADATA +0 -46
  489. agentengine_sdk_python-0.6.2.dist-info/RECORD +0 -4
  490. agentengine_sdk_python-0.6.2.dist-info/top_level.txt +0 -1
@@ -0,0 +1,949 @@
1
+ """Local persistent session backend for embedded KSADK runtimes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import json
7
+ import os
8
+ import sqlite3
9
+ import time
10
+ from contextlib import closing, contextmanager
11
+ from pathlib import Path
12
+ from collections.abc import Iterator
13
+ from typing import Optional
14
+
15
+ from ksadk.sessions.base import (
16
+ BaseSessionService,
17
+ Session,
18
+ SessionEvent,
19
+ SessionState,
20
+ generate_id,
21
+ )
22
+
23
+ KSADK_SESSIONS_TABLE = "ksadk_sessions"
24
+ KSADK_EVENTS_TABLE = "ksadk_events"
25
+ KSADK_STATES_TABLE = "ksadk_states"
26
+
27
+ LEGACY_SESSIONS_TABLE = "sessions"
28
+ LEGACY_EVENTS_TABLE = "events"
29
+ LEGACY_STATES_TABLE = "states"
30
+
31
+ DEFAULT_SESSION_DB_NAME = "sessions.sqlite"
32
+
33
+
34
+ def resolve_local_session_dir(project_dir: Optional[str] = None) -> Path:
35
+ configured = (os.getenv("AGENTENGINE_UI_DIR") or "").strip()
36
+ if configured:
37
+ return Path(configured).expanduser().resolve()
38
+
39
+ root = Path(project_dir or os.getenv("KSADK_PROJECT_DIR") or os.getcwd()).resolve()
40
+ return root / ".agentengine" / "ui"
41
+
42
+
43
+ def resolve_local_session_path(project_dir: Optional[str] = None) -> Path:
44
+ configured_ui_dir = (os.getenv("AGENTENGINE_UI_DIR") or "").strip()
45
+ if configured_ui_dir:
46
+ return Path(configured_ui_dir).expanduser().resolve() / DEFAULT_SESSION_DB_NAME
47
+
48
+ explicit_path = (os.getenv("KSADK_STM_PATH") or os.getenv("KSADK_STM_DB_PATH") or "").strip()
49
+ if explicit_path:
50
+ return Path(explicit_path).expanduser().resolve()
51
+
52
+ return resolve_local_session_dir(project_dir) / DEFAULT_SESSION_DB_NAME
53
+
54
+
55
+ class LocalSessionService(BaseSessionService):
56
+ def __init__(self, db_path: Optional[Path] = None, *, project_dir: Optional[str] = None):
57
+ self.db_path = (
58
+ Path(db_path).expanduser().resolve()
59
+ if db_path is not None
60
+ else resolve_local_session_path(project_dir)
61
+ )
62
+ self.db_path.parent.mkdir(parents=True, exist_ok=True)
63
+ self._lock = asyncio.Lock()
64
+ self._ensure_schema()
65
+
66
+ async def create_session(
67
+ self,
68
+ agent_id: str,
69
+ user_id: str,
70
+ session_id: Optional[str] = None,
71
+ ) -> Session:
72
+ async with self._lock:
73
+ return await asyncio.to_thread(self._create_session_sync, agent_id, user_id, session_id)
74
+
75
+ async def get_session(self, session_id: str) -> Optional[Session]:
76
+ async with self._lock:
77
+ return await asyncio.to_thread(self._get_session_sync, session_id)
78
+
79
+ async def list_sessions(
80
+ self,
81
+ agent_id: str,
82
+ user_id: Optional[str] = None,
83
+ offset: Optional[int] = None,
84
+ limit: Optional[int] = None,
85
+ ) -> list[Session]:
86
+ async with self._lock:
87
+ return await asyncio.to_thread(
88
+ self._list_sessions_sync,
89
+ agent_id,
90
+ user_id,
91
+ offset,
92
+ limit,
93
+ )
94
+
95
+ async def count_sessions(
96
+ self,
97
+ agent_id: str,
98
+ user_id: Optional[str] = None,
99
+ ) -> int:
100
+ async with self._lock:
101
+ return await asyncio.to_thread(self._count_sessions_sync, agent_id, user_id)
102
+
103
+ async def delete_session(self, session_id: str) -> bool:
104
+ async with self._lock:
105
+ return await asyncio.to_thread(self._delete_session_sync, session_id)
106
+
107
+ async def update_session_metadata(
108
+ self,
109
+ session_id: str,
110
+ *,
111
+ title: Optional[str] = None,
112
+ title_source: Optional[str] = None,
113
+ summary: Optional[str] = None,
114
+ first_prompt: Optional[str] = None,
115
+ last_prompt: Optional[str] = None,
116
+ ) -> Session:
117
+ async with self._lock:
118
+ return await asyncio.to_thread(
119
+ self._update_session_metadata_sync,
120
+ session_id,
121
+ title,
122
+ title_source,
123
+ summary,
124
+ first_prompt,
125
+ last_prompt,
126
+ )
127
+
128
+ async def append_event(self, session_id: str, event: SessionEvent) -> SessionEvent:
129
+ async with self._lock:
130
+ return await asyncio.to_thread(self._append_event_sync, session_id, event)
131
+
132
+ async def get_events(
133
+ self,
134
+ session_id: str,
135
+ offset: Optional[int] = None,
136
+ limit: Optional[int] = None,
137
+ after_seq_id: Optional[int] = None,
138
+ before_seq_id: Optional[int] = None,
139
+ ) -> list[SessionEvent]:
140
+ async with self._lock:
141
+ return await asyncio.to_thread(
142
+ self._get_events_sync,
143
+ session_id,
144
+ offset,
145
+ limit,
146
+ after_seq_id,
147
+ before_seq_id,
148
+ )
149
+
150
+ async def count_events(
151
+ self,
152
+ session_id: str,
153
+ after_seq_id: Optional[int] = None,
154
+ before_seq_id: Optional[int] = None,
155
+ ) -> int:
156
+ async with self._lock:
157
+ return await asyncio.to_thread(
158
+ self._count_events_sync,
159
+ session_id,
160
+ after_seq_id,
161
+ before_seq_id,
162
+ )
163
+
164
+ async def get_state(
165
+ self,
166
+ agent_id: str,
167
+ user_id: Optional[str],
168
+ session_id: Optional[str],
169
+ scope: str = "session",
170
+ ) -> Optional[SessionState]:
171
+ async with self._lock:
172
+ return await asyncio.to_thread(
173
+ self._get_state_sync,
174
+ agent_id,
175
+ user_id,
176
+ session_id,
177
+ scope,
178
+ )
179
+
180
+ async def update_state(
181
+ self,
182
+ *,
183
+ agent_id: str,
184
+ user_id: Optional[str],
185
+ session_id: Optional[str],
186
+ scope: str,
187
+ state_delta: dict,
188
+ ) -> SessionState:
189
+ async with self._lock:
190
+ return await asyncio.to_thread(
191
+ self._update_state_sync,
192
+ agent_id,
193
+ user_id,
194
+ session_id,
195
+ scope,
196
+ state_delta,
197
+ )
198
+
199
+ async def aclose(self) -> None:
200
+ return None
201
+
202
+ def _connect(self) -> sqlite3.Connection:
203
+ connection = sqlite3.connect(str(self.db_path))
204
+ connection.row_factory = sqlite3.Row
205
+ connection.execute("PRAGMA foreign_keys = ON")
206
+ return connection
207
+
208
+ @contextmanager
209
+ def _connection(self) -> Iterator[sqlite3.Connection]:
210
+ with closing(self._connect()) as connection:
211
+ with connection:
212
+ yield connection
213
+
214
+ @staticmethod
215
+ def _table_exists(connection: sqlite3.Connection, table_name: str) -> bool:
216
+ row = connection.execute(
217
+ "SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?",
218
+ (table_name,),
219
+ ).fetchone()
220
+ return row is not None
221
+
222
+ @classmethod
223
+ def _table_columns(cls, connection: sqlite3.Connection, table_name: str) -> set[str]:
224
+ if not cls._table_exists(connection, table_name):
225
+ return set()
226
+ rows = connection.execute(f"PRAGMA table_info({table_name})").fetchall()
227
+ return {str(row["name"]) for row in rows}
228
+
229
+ @staticmethod
230
+ def _ensure_columns(
231
+ connection: sqlite3.Connection,
232
+ table_name: str,
233
+ required_columns: dict[str, str],
234
+ ) -> None:
235
+ existing_columns = {
236
+ str(row["name"])
237
+ for row in connection.execute(f"PRAGMA table_info({table_name})").fetchall()
238
+ }
239
+ for column_name, ddl in required_columns.items():
240
+ if column_name not in existing_columns:
241
+ connection.execute(f"ALTER TABLE {table_name} ADD COLUMN {column_name} {ddl}")
242
+
243
+ def _migrate_legacy_schema(self, connection: sqlite3.Connection) -> None:
244
+ legacy_session_columns = self._table_columns(connection, LEGACY_SESSIONS_TABLE)
245
+ if (
246
+ legacy_session_columns
247
+ and not self._table_exists(connection, KSADK_SESSIONS_TABLE)
248
+ and "agent_id" in legacy_session_columns
249
+ and "app_name" not in legacy_session_columns
250
+ ):
251
+ connection.execute(
252
+ f"ALTER TABLE {LEGACY_SESSIONS_TABLE} RENAME TO {KSADK_SESSIONS_TABLE}"
253
+ )
254
+
255
+ legacy_event_columns = self._table_columns(connection, LEGACY_EVENTS_TABLE)
256
+ if (
257
+ legacy_event_columns
258
+ and not self._table_exists(connection, KSADK_EVENTS_TABLE)
259
+ and {"session_id", "author", "event_type"}.issubset(legacy_event_columns)
260
+ ):
261
+ connection.execute(
262
+ f"ALTER TABLE {LEGACY_EVENTS_TABLE} RENAME TO {KSADK_EVENTS_TABLE}"
263
+ )
264
+
265
+ legacy_state_columns = self._table_columns(connection, LEGACY_STATES_TABLE)
266
+ if (
267
+ legacy_state_columns
268
+ and not self._table_exists(connection, KSADK_STATES_TABLE)
269
+ and {"scope", "agent_id", "state_json"}.issubset(legacy_state_columns)
270
+ ):
271
+ connection.execute(
272
+ f"ALTER TABLE {LEGACY_STATES_TABLE} RENAME TO {KSADK_STATES_TABLE}"
273
+ )
274
+
275
+ def _ensure_schema(self) -> None:
276
+ with self._connection() as connection:
277
+ self._migrate_legacy_schema(connection)
278
+ connection.executescript(
279
+ f"""
280
+ CREATE TABLE IF NOT EXISTS {KSADK_SESSIONS_TABLE} (
281
+ id TEXT PRIMARY KEY,
282
+ agent_id TEXT NOT NULL,
283
+ user_id TEXT NOT NULL,
284
+ title TEXT NOT NULL DEFAULT '',
285
+ title_source TEXT NOT NULL DEFAULT '',
286
+ summary TEXT NOT NULL DEFAULT '',
287
+ first_prompt TEXT NOT NULL DEFAULT '',
288
+ last_prompt TEXT NOT NULL DEFAULT '',
289
+ state_json TEXT NOT NULL DEFAULT '{{}}',
290
+ created_at REAL NOT NULL,
291
+ updated_at REAL NOT NULL,
292
+ version INTEGER NOT NULL DEFAULT 0
293
+ );
294
+
295
+ CREATE TABLE IF NOT EXISTS {KSADK_EVENTS_TABLE} (
296
+ id TEXT PRIMARY KEY,
297
+ session_id TEXT NOT NULL,
298
+ author TEXT NOT NULL,
299
+ event_type TEXT NOT NULL,
300
+ content_json TEXT NOT NULL DEFAULT '{{}}',
301
+ timestamp REAL NOT NULL,
302
+ state_delta_json TEXT NOT NULL DEFAULT '{{}}',
303
+ seq_id INTEGER NOT NULL,
304
+ invocation_id TEXT,
305
+ metadata_json TEXT NOT NULL DEFAULT '{{}}',
306
+ FOREIGN KEY(session_id) REFERENCES {KSADK_SESSIONS_TABLE}(id) ON DELETE CASCADE
307
+ );
308
+
309
+ CREATE INDEX IF NOT EXISTS idx_ksadk_events_session_seq
310
+ ON {KSADK_EVENTS_TABLE} (session_id, seq_id);
311
+
312
+ CREATE TABLE IF NOT EXISTS {KSADK_STATES_TABLE} (
313
+ scope TEXT NOT NULL,
314
+ agent_id TEXT NOT NULL,
315
+ user_id TEXT NOT NULL DEFAULT '',
316
+ session_id TEXT NOT NULL DEFAULT '',
317
+ state_json TEXT NOT NULL DEFAULT '{{}}',
318
+ version INTEGER NOT NULL DEFAULT 0,
319
+ updated_at REAL NOT NULL,
320
+ PRIMARY KEY (scope, agent_id, user_id, session_id)
321
+ );
322
+ """
323
+ )
324
+ self._ensure_columns(
325
+ connection,
326
+ KSADK_SESSIONS_TABLE,
327
+ {
328
+ "title": "TEXT NOT NULL DEFAULT ''",
329
+ "title_source": "TEXT NOT NULL DEFAULT ''",
330
+ "summary": "TEXT NOT NULL DEFAULT ''",
331
+ "first_prompt": "TEXT NOT NULL DEFAULT ''",
332
+ "last_prompt": "TEXT NOT NULL DEFAULT ''",
333
+ "state_json": "TEXT NOT NULL DEFAULT '{}'",
334
+ "version": "INTEGER NOT NULL DEFAULT 0",
335
+ },
336
+ )
337
+ self._ensure_columns(
338
+ connection,
339
+ KSADK_EVENTS_TABLE,
340
+ {
341
+ "state_delta_json": "TEXT NOT NULL DEFAULT '{}'",
342
+ "invocation_id": "TEXT",
343
+ "metadata_json": "TEXT NOT NULL DEFAULT '{}'",
344
+ },
345
+ )
346
+ self._ensure_columns(
347
+ connection,
348
+ KSADK_STATES_TABLE,
349
+ {
350
+ "version": "INTEGER NOT NULL DEFAULT 0",
351
+ "updated_at": "REAL NOT NULL DEFAULT 0",
352
+ },
353
+ )
354
+ connection.commit()
355
+
356
+ def _create_session_sync(
357
+ self,
358
+ agent_id: str,
359
+ user_id: str,
360
+ session_id: Optional[str],
361
+ ) -> Session:
362
+ with self._connection() as connection:
363
+ if session_id:
364
+ existing = self._get_session_sync(session_id, connection=connection)
365
+ if existing is not None:
366
+ return existing
367
+
368
+ now = time.time()
369
+ session = Session(
370
+ id=session_id or generate_id(),
371
+ agent_id=agent_id,
372
+ user_id=user_id,
373
+ created_at=now,
374
+ updated_at=now,
375
+ )
376
+ connection.execute(
377
+ f"""
378
+ INSERT INTO {KSADK_SESSIONS_TABLE} (
379
+ id, agent_id, user_id, title, title_source, summary, first_prompt, last_prompt,
380
+ state_json, created_at, updated_at, version
381
+ )
382
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
383
+ """,
384
+ (
385
+ session.id,
386
+ session.agent_id,
387
+ session.user_id,
388
+ session.title,
389
+ session.title_source,
390
+ session.summary,
391
+ session.first_prompt,
392
+ session.last_prompt,
393
+ json.dumps(session.state),
394
+ session.created_at,
395
+ session.updated_at,
396
+ session.version,
397
+ ),
398
+ )
399
+ connection.execute(
400
+ f"""
401
+ INSERT OR REPLACE INTO {KSADK_STATES_TABLE} (
402
+ scope, agent_id, user_id, session_id, state_json, version, updated_at
403
+ )
404
+ VALUES (?, ?, ?, ?, ?, ?, ?)
405
+ """,
406
+ ("session", session.agent_id, session.user_id, session.id, "{}", 0, now),
407
+ )
408
+ connection.commit()
409
+ return session
410
+
411
+ def _get_session_sync(
412
+ self,
413
+ session_id: str,
414
+ *,
415
+ connection: Optional[sqlite3.Connection] = None,
416
+ ) -> Optional[Session]:
417
+ owns_connection = connection is None
418
+ connection = connection or self._connect()
419
+ try:
420
+ row = connection.execute(
421
+ f"""
422
+ SELECT
423
+ id, agent_id, user_id, title, title_source, summary, first_prompt, last_prompt,
424
+ state_json, created_at, updated_at, version
425
+ FROM {KSADK_SESSIONS_TABLE}
426
+ WHERE id = ?
427
+ """,
428
+ (session_id,),
429
+ ).fetchone()
430
+ if row is None:
431
+ return None
432
+ return Session(
433
+ id=row["id"],
434
+ agent_id=row["agent_id"],
435
+ user_id=row["user_id"],
436
+ title=row["title"],
437
+ title_source=row["title_source"],
438
+ summary=row["summary"],
439
+ first_prompt=row["first_prompt"],
440
+ last_prompt=row["last_prompt"],
441
+ state=json.loads(row["state_json"] or "{}"),
442
+ events=self._get_events_sync(session_id, connection=connection),
443
+ created_at=row["created_at"],
444
+ updated_at=row["updated_at"],
445
+ version=row["version"],
446
+ )
447
+ finally:
448
+ if owns_connection:
449
+ connection.close()
450
+
451
+ def _list_sessions_sync(
452
+ self,
453
+ agent_id: str,
454
+ user_id: Optional[str],
455
+ offset: Optional[int] = None,
456
+ limit: Optional[int] = None,
457
+ ) -> list[Session]:
458
+ with self._connection() as connection:
459
+ query = f"""
460
+ SELECT
461
+ id, agent_id, user_id, title, title_source, summary, first_prompt, last_prompt,
462
+ state_json, created_at, updated_at, version
463
+ FROM {KSADK_SESSIONS_TABLE}
464
+ WHERE agent_id = ?
465
+ """
466
+ params: list[object] = [agent_id]
467
+ if user_id is not None:
468
+ query += " AND user_id = ?"
469
+ params.append(user_id)
470
+ query += " ORDER BY updated_at DESC, created_at DESC"
471
+ if limit is not None:
472
+ query += " LIMIT ?"
473
+ params.append(limit)
474
+ if offset is not None:
475
+ query += " OFFSET ?"
476
+ params.append(offset)
477
+ elif offset is not None:
478
+ query += " LIMIT -1 OFFSET ?"
479
+ params.append(offset)
480
+ rows = connection.execute(query, params).fetchall()
481
+ return [
482
+ Session(
483
+ id=row["id"],
484
+ agent_id=row["agent_id"],
485
+ user_id=row["user_id"],
486
+ title=row["title"],
487
+ title_source=row["title_source"],
488
+ summary=row["summary"],
489
+ first_prompt=row["first_prompt"],
490
+ last_prompt=row["last_prompt"],
491
+ state=json.loads(row["state_json"] or "{}"),
492
+ events=[],
493
+ created_at=row["created_at"],
494
+ updated_at=row["updated_at"],
495
+ version=row["version"],
496
+ )
497
+ for row in rows
498
+ ]
499
+
500
+ def _count_sessions_sync(self, agent_id: str, user_id: Optional[str]) -> int:
501
+ with self._connection() as connection:
502
+ query = f"""
503
+ SELECT COUNT(*) AS total
504
+ FROM {KSADK_SESSIONS_TABLE}
505
+ WHERE agent_id = ?
506
+ """
507
+ params: list[object] = [agent_id]
508
+ if user_id is not None:
509
+ query += " AND user_id = ?"
510
+ params.append(user_id)
511
+ row = connection.execute(query, params).fetchone()
512
+ return int(row["total"] if row else 0)
513
+
514
+ def _delete_session_sync(self, session_id: str) -> bool:
515
+ with self._connection() as connection:
516
+ row = connection.execute(
517
+ f"SELECT 1 FROM {KSADK_SESSIONS_TABLE} WHERE id = ?",
518
+ (session_id,),
519
+ ).fetchone()
520
+ if row is None:
521
+ return False
522
+
523
+ connection.execute(f"DELETE FROM {KSADK_EVENTS_TABLE} WHERE session_id = ?", (session_id,))
524
+ connection.execute(f"DELETE FROM {KSADK_STATES_TABLE} WHERE session_id = ?", (session_id,))
525
+ connection.execute(f"DELETE FROM {KSADK_SESSIONS_TABLE} WHERE id = ?", (session_id,))
526
+ connection.commit()
527
+ return True
528
+
529
+ def _append_event_sync(self, session_id: str, event: SessionEvent) -> SessionEvent:
530
+ with self._connection() as connection:
531
+ session_row = connection.execute(
532
+ f"""
533
+ SELECT agent_id, user_id, state_json, version
534
+ FROM {KSADK_SESSIONS_TABLE}
535
+ WHERE id = ?
536
+ """,
537
+ (session_id,),
538
+ ).fetchone()
539
+ if session_row is None:
540
+ raise ValueError(f"Session {session_id} not found")
541
+
542
+ next_seq = int(
543
+ connection.execute(
544
+ f"SELECT COALESCE(MAX(seq_id), 0) + 1 FROM {KSADK_EVENTS_TABLE} WHERE session_id = ?",
545
+ (session_id,),
546
+ ).fetchone()[0]
547
+ )
548
+ stored = SessionEvent(
549
+ id=event.id or generate_id(),
550
+ session_id=session_id,
551
+ author=event.author,
552
+ event_type=event.event_type,
553
+ content=dict(event.content),
554
+ timestamp=event.timestamp,
555
+ state_delta=dict(event.state_delta),
556
+ seq_id=next_seq,
557
+ invocation_id=event.invocation_id,
558
+ metadata=dict(event.metadata),
559
+ )
560
+ connection.execute(
561
+ f"""
562
+ INSERT INTO {KSADK_EVENTS_TABLE} (
563
+ id, session_id, author, event_type, content_json, timestamp,
564
+ state_delta_json, seq_id, invocation_id, metadata_json
565
+ )
566
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
567
+ """,
568
+ (
569
+ stored.id,
570
+ stored.session_id,
571
+ stored.author,
572
+ stored.event_type,
573
+ json.dumps(stored.content),
574
+ stored.timestamp,
575
+ json.dumps(stored.state_delta),
576
+ stored.seq_id,
577
+ stored.invocation_id,
578
+ json.dumps(stored.metadata),
579
+ ),
580
+ )
581
+
582
+ updated_at = time.time()
583
+ state = json.loads(session_row["state_json"] or "{}")
584
+ version = int(session_row["version"] or 0)
585
+ if stored.state_delta:
586
+ state.update(stored.state_delta)
587
+ version += 1
588
+
589
+ connection.execute(
590
+ f"""
591
+ UPDATE {KSADK_SESSIONS_TABLE}
592
+ SET state_json = ?, updated_at = ?, version = ?
593
+ WHERE id = ?
594
+ """,
595
+ (json.dumps(state), updated_at, version, session_id),
596
+ )
597
+
598
+ if stored.state_delta:
599
+ connection.execute(
600
+ f"""
601
+ INSERT OR REPLACE INTO {KSADK_STATES_TABLE} (
602
+ scope, agent_id, user_id, session_id, state_json, version, updated_at
603
+ )
604
+ VALUES (?, ?, ?, ?, ?, ?, ?)
605
+ """,
606
+ (
607
+ "session",
608
+ session_row["agent_id"],
609
+ session_row["user_id"],
610
+ session_id,
611
+ json.dumps(state),
612
+ version,
613
+ updated_at,
614
+ ),
615
+ )
616
+
617
+ connection.commit()
618
+ return stored
619
+
620
+ def _update_session_metadata_sync(
621
+ self,
622
+ session_id: str,
623
+ title: Optional[str],
624
+ title_source: Optional[str],
625
+ summary: Optional[str],
626
+ first_prompt: Optional[str],
627
+ last_prompt: Optional[str],
628
+ ) -> Session:
629
+ with self._connection() as connection:
630
+ row = connection.execute(
631
+ f"""
632
+ SELECT
633
+ id, agent_id, user_id, title, title_source, summary, first_prompt, last_prompt,
634
+ state_json, created_at, updated_at, version
635
+ FROM {KSADK_SESSIONS_TABLE}
636
+ WHERE id = ?
637
+ """,
638
+ (session_id,),
639
+ ).fetchone()
640
+ if row is None:
641
+ raise ValueError(f"Session {session_id} not found")
642
+
643
+ updated_at = time.time()
644
+ next_title = row["title"] if title is None else title
645
+ next_title_source = row["title_source"] if title_source is None else title_source
646
+ next_summary = row["summary"] if summary is None else summary
647
+ next_first_prompt = row["first_prompt"] if first_prompt is None else first_prompt
648
+ next_last_prompt = row["last_prompt"] if last_prompt is None else last_prompt
649
+
650
+ connection.execute(
651
+ f"""
652
+ UPDATE {KSADK_SESSIONS_TABLE}
653
+ SET title = ?, title_source = ?, summary = ?, first_prompt = ?, last_prompt = ?,
654
+ updated_at = ?
655
+ WHERE id = ?
656
+ """,
657
+ (
658
+ next_title,
659
+ next_title_source,
660
+ next_summary,
661
+ next_first_prompt,
662
+ next_last_prompt,
663
+ updated_at,
664
+ session_id,
665
+ ),
666
+ )
667
+ connection.commit()
668
+ return Session(
669
+ id=row["id"],
670
+ agent_id=row["agent_id"],
671
+ user_id=row["user_id"],
672
+ title=next_title,
673
+ title_source=next_title_source,
674
+ summary=next_summary,
675
+ first_prompt=next_first_prompt,
676
+ last_prompt=next_last_prompt,
677
+ state=json.loads(row["state_json"] or "{}"),
678
+ events=[],
679
+ created_at=row["created_at"],
680
+ updated_at=updated_at,
681
+ version=row["version"],
682
+ )
683
+
684
+ def _get_events_sync(
685
+ self,
686
+ session_id: str,
687
+ offset: Optional[int] = None,
688
+ limit: Optional[int] = None,
689
+ after_seq_id: Optional[int] = None,
690
+ before_seq_id: Optional[int] = None,
691
+ *,
692
+ connection: Optional[sqlite3.Connection] = None,
693
+ ) -> list[SessionEvent]:
694
+ owns_connection = connection is None
695
+ connection = connection or self._connect()
696
+ try:
697
+ # seq 过滤先应用,再对结果集应用"最新 N 条" offset/limit 语义。
698
+ seq_clauses: list[str] = []
699
+ seq_params: list[object] = []
700
+ if after_seq_id is not None:
701
+ seq_clauses.append("AND seq_id > ?")
702
+ seq_params.append(after_seq_id)
703
+ if before_seq_id is not None:
704
+ seq_clauses.append("AND seq_id < ?")
705
+ seq_params.append(before_seq_id)
706
+ seq_clause = " ".join(seq_clauses)
707
+ if limit is not None:
708
+ query = f"""
709
+ SELECT id, session_id, author, event_type, content_json, timestamp,
710
+ state_delta_json, seq_id, invocation_id, metadata_json
711
+ FROM (
712
+ SELECT id, session_id, author, event_type, content_json, timestamp,
713
+ state_delta_json, seq_id, invocation_id, metadata_json
714
+ FROM {KSADK_EVENTS_TABLE}
715
+ WHERE session_id = ? {seq_clause}
716
+ ORDER BY seq_id DESC
717
+ LIMIT ? OFFSET ?
718
+ )
719
+ ORDER BY seq_id ASC
720
+ """
721
+ params: list[object] = [session_id, *seq_params]
722
+ params.extend([limit, offset or 0])
723
+ elif offset is not None:
724
+ query = f"""
725
+ SELECT id, session_id, author, event_type, content_json, timestamp,
726
+ state_delta_json, seq_id, invocation_id, metadata_json
727
+ FROM (
728
+ SELECT id, session_id, author, event_type, content_json, timestamp,
729
+ state_delta_json, seq_id, invocation_id, metadata_json
730
+ FROM {KSADK_EVENTS_TABLE}
731
+ WHERE session_id = ? {seq_clause}
732
+ ORDER BY seq_id DESC
733
+ LIMIT -1 OFFSET ?
734
+ )
735
+ ORDER BY seq_id ASC
736
+ """
737
+ params = [session_id, *seq_params]
738
+ params.append(offset)
739
+ else:
740
+ query = f"""
741
+ SELECT id, session_id, author, event_type, content_json, timestamp,
742
+ state_delta_json, seq_id, invocation_id, metadata_json
743
+ FROM {KSADK_EVENTS_TABLE}
744
+ WHERE session_id = ? {seq_clause}
745
+ ORDER BY seq_id ASC
746
+ """
747
+ params = [session_id, *seq_params]
748
+
749
+ rows = connection.execute(query, params).fetchall()
750
+ return [
751
+ SessionEvent(
752
+ id=row["id"],
753
+ session_id=row["session_id"],
754
+ author=row["author"],
755
+ event_type=row["event_type"],
756
+ content=json.loads(row["content_json"] or "{}"),
757
+ timestamp=row["timestamp"],
758
+ state_delta=json.loads(row["state_delta_json"] or "{}"),
759
+ seq_id=row["seq_id"],
760
+ invocation_id=row["invocation_id"],
761
+ metadata=json.loads(row["metadata_json"] or "{}"),
762
+ )
763
+ for row in rows
764
+ ]
765
+ finally:
766
+ if owns_connection:
767
+ connection.close()
768
+
769
+ def _count_events_sync(
770
+ self,
771
+ session_id: str,
772
+ after_seq_id: Optional[int] = None,
773
+ before_seq_id: Optional[int] = None,
774
+ ) -> int:
775
+ with self._connection() as connection:
776
+ seq_clauses: list[str] = []
777
+ params: list[object] = [session_id]
778
+ if after_seq_id is not None:
779
+ seq_clauses.append("AND seq_id > ?")
780
+ params.append(after_seq_id)
781
+ if before_seq_id is not None:
782
+ seq_clauses.append("AND seq_id < ?")
783
+ params.append(before_seq_id)
784
+ seq_clause = " ".join(seq_clauses)
785
+ row = connection.execute(
786
+ f"""
787
+ SELECT COUNT(*) AS total
788
+ FROM {KSADK_EVENTS_TABLE}
789
+ WHERE session_id = ? {seq_clause}
790
+ """,
791
+ params,
792
+ ).fetchone()
793
+ return int(row["total"] if row else 0)
794
+
795
+ def _get_state_sync(
796
+ self,
797
+ agent_id: str,
798
+ user_id: Optional[str],
799
+ session_id: Optional[str],
800
+ scope: str,
801
+ ) -> Optional[SessionState]:
802
+ with self._connection() as connection:
803
+ if scope == "session" and session_id:
804
+ session = self._get_session_sync(session_id, connection=connection)
805
+ if session is None:
806
+ return None
807
+ return SessionState(
808
+ scope="session",
809
+ agent_id=session.agent_id,
810
+ user_id=session.user_id,
811
+ session_id=session.id,
812
+ state=dict(session.state),
813
+ version=session.version,
814
+ updated_at=session.updated_at,
815
+ )
816
+
817
+ row = connection.execute(
818
+ f"""
819
+ SELECT scope, agent_id, user_id, session_id, state_json, version, updated_at
820
+ FROM {KSADK_STATES_TABLE}
821
+ WHERE scope = ? AND agent_id = ? AND user_id = ? AND session_id = ?
822
+ """,
823
+ (scope, agent_id, user_id or "", session_id or ""),
824
+ ).fetchone()
825
+ if row is None:
826
+ return None
827
+
828
+ return SessionState(
829
+ scope=row["scope"],
830
+ agent_id=row["agent_id"],
831
+ user_id=row["user_id"],
832
+ session_id=row["session_id"],
833
+ state=json.loads(row["state_json"] or "{}"),
834
+ version=row["version"],
835
+ updated_at=row["updated_at"],
836
+ )
837
+
838
+ def _update_state_sync(
839
+ self,
840
+ agent_id: str,
841
+ user_id: Optional[str],
842
+ session_id: Optional[str],
843
+ scope: str,
844
+ state_delta: dict,
845
+ ) -> SessionState:
846
+ with self._connection() as connection:
847
+ updated_at = time.time()
848
+
849
+ if scope == "session":
850
+ if not session_id:
851
+ raise ValueError("session_id is required for session scope")
852
+ session = self._get_session_sync(session_id, connection=connection)
853
+ if session is None:
854
+ raise ValueError(f"Session {session_id} not found")
855
+
856
+ next_state = dict(session.state)
857
+ next_state.update(state_delta)
858
+ next_version = session.version + 1
859
+ connection.execute(
860
+ f"""
861
+ UPDATE {KSADK_SESSIONS_TABLE}
862
+ SET state_json = ?, updated_at = ?, version = ?
863
+ WHERE id = ?
864
+ """,
865
+ (json.dumps(next_state), updated_at, next_version, session_id),
866
+ )
867
+ connection.execute(
868
+ f"""
869
+ INSERT OR REPLACE INTO {KSADK_STATES_TABLE} (
870
+ scope, agent_id, user_id, session_id, state_json, version, updated_at
871
+ )
872
+ VALUES (?, ?, ?, ?, ?, ?, ?)
873
+ """,
874
+ (
875
+ "session",
876
+ session.agent_id,
877
+ session.user_id,
878
+ session.id,
879
+ json.dumps(next_state),
880
+ next_version,
881
+ updated_at,
882
+ ),
883
+ )
884
+ connection.commit()
885
+ return SessionState(
886
+ scope="session",
887
+ agent_id=session.agent_id,
888
+ user_id=session.user_id,
889
+ session_id=session.id,
890
+ state=next_state,
891
+ version=next_version,
892
+ updated_at=updated_at,
893
+ )
894
+
895
+ row = connection.execute(
896
+ f"""
897
+ SELECT state_json, version
898
+ FROM {KSADK_STATES_TABLE}
899
+ WHERE scope = ? AND agent_id = ? AND user_id = ? AND session_id = ?
900
+ """,
901
+ (scope, agent_id, user_id or "", session_id or ""),
902
+ ).fetchone()
903
+ next_state = json.loads(row["state_json"] or "{}") if row else {}
904
+ next_state.update(state_delta)
905
+ next_version = (int(row["version"] or 0) + 1) if row else 1
906
+
907
+ connection.execute(
908
+ f"""
909
+ INSERT OR REPLACE INTO {KSADK_STATES_TABLE} (
910
+ scope, agent_id, user_id, session_id, state_json, version, updated_at
911
+ )
912
+ VALUES (?, ?, ?, ?, ?, ?, ?)
913
+ """,
914
+ (
915
+ scope,
916
+ agent_id,
917
+ user_id or "",
918
+ session_id or "",
919
+ json.dumps(next_state),
920
+ next_version,
921
+ updated_at,
922
+ ),
923
+ )
924
+ connection.commit()
925
+ return SessionState(
926
+ scope=scope,
927
+ agent_id=agent_id,
928
+ user_id=user_id or "",
929
+ session_id=session_id or "",
930
+ state=next_state,
931
+ version=next_version,
932
+ updated_at=updated_at,
933
+ )
934
+
935
+
936
+ def create_local_session_service(*, project_dir: Optional[str] = None) -> BaseSessionService:
937
+ return LocalSessionService(project_dir=project_dir)
938
+
939
+
940
+ __all__ = [
941
+ "DEFAULT_SESSION_DB_NAME",
942
+ "KSADK_EVENTS_TABLE",
943
+ "KSADK_SESSIONS_TABLE",
944
+ "KSADK_STATES_TABLE",
945
+ "LocalSessionService",
946
+ "create_local_session_service",
947
+ "resolve_local_session_dir",
948
+ "resolve_local_session_path",
949
+ ]