agentengine-sdk-python 0.8.1__py3-none-any.whl → 0.8.3__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 (476) hide show
  1. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/METADATA +25 -12
  2. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/RECORD +421 -232
  3. ksadk/_build_provenance.json +1 -0
  4. ksadk/a2a/_space_client_events.py +381 -0
  5. ksadk/a2a/event_adapter.py +156 -64
  6. ksadk/a2a/executor.py +179 -63
  7. ksadk/a2a/space_client.py +6 -333
  8. ksadk/a2ui/core.py +222 -53
  9. ksadk/agui/_agent_helpers.py +247 -0
  10. ksadk/agui/a2ui_projection.py +12 -5
  11. ksadk/agui/agent.py +443 -259
  12. ksadk/api/client.py +528 -27
  13. ksadk/builders/code_builder.py +284 -8
  14. ksadk/builders/container_builder.py +8 -1
  15. ksadk/builders/managed_runtime_builder.py +42 -35
  16. ksadk/cli/__init__.py +23 -0
  17. ksadk/cli/cmd_dashboard.py +15 -1
  18. ksadk/cli/cmd_deploy.py +10 -2
  19. ksadk/cli/cmd_eval.py +66 -9
  20. ksadk/cli/cmd_evalset.py +284 -0
  21. ksadk/cli/cmd_files.py +5 -1
  22. ksadk/cli/cmd_hermes.py +1 -126
  23. ksadk/cli/cmd_invoke.py +28 -38
  24. ksadk/cli/cmd_managed_runtime.py +95 -0
  25. ksadk/cli/cmd_observe.py +85 -0
  26. ksadk/cli/cmd_openclaw.py +1 -435
  27. ksadk/cli/cmd_plugin.py +657 -0
  28. ksadk/cli/cmd_replay.py +28 -4
  29. ksadk/cli/cmd_studio.py +99 -8
  30. ksadk/cli/cmd_web.py +10 -2
  31. ksadk/cli/hermes_env.py +151 -0
  32. ksadk/cli/invoke_payload.py +49 -0
  33. ksadk/cli/openclaw_env.py +458 -0
  34. ksadk/codex/client.py +180 -30
  35. ksadk/codex/runtime.py +475 -331
  36. ksadk/configs/env_registry.py +94 -12
  37. ksadk/configs/env_registry_pcm.py +181 -0
  38. ksadk/configs/env_var_spec.py +18 -0
  39. ksadk/configs/global_config.py +5 -0
  40. ksadk/configs/settings.py +9 -0
  41. ksadk/context_engine/__init__.py +98 -0
  42. ksadk/context_engine/assembler.py +176 -0
  43. ksadk/context_engine/baseline.py +419 -0
  44. ksadk/context_engine/cache_observability.py +228 -0
  45. ksadk/context_engine/capabilities.py +443 -0
  46. ksadk/context_engine/contributors.py +409 -0
  47. ksadk/context_engine/hosted_pipeline.py +417 -0
  48. ksadk/context_engine/models.py +117 -0
  49. ksadk/context_engine/planner.py +698 -0
  50. ksadk/context_engine/policies.py +319 -0
  51. ksadk/context_engine/projection.py +31 -0
  52. ksadk/context_engine/shadow_plan.py +266 -0
  53. ksadk/context_engine/tokenizer.py +164 -0
  54. ksadk/conversations/__init__.py +19 -0
  55. ksadk/conversations/context.py +230 -30
  56. ksadk/conversations/contracts.py +266 -0
  57. ksadk/conversations/message_projection.py +308 -26
  58. ksadk/conversations/model_context.py +49 -3
  59. ksadk/conversations/projector.py +616 -0
  60. ksadk/conversations/reducer.py +98 -0
  61. ksadk/conversations/runtime_compaction.py +207 -5
  62. ksadk/conversations/runtime_input.py +184 -2
  63. ksadk/conversations/runtime_invocation.py +81 -3
  64. ksadk/conversations/runtime_observability.py +141 -0
  65. ksadk/conversations/runtime_payloads.py +42 -0
  66. ksadk/conversations/runtime_preparation.py +272 -2
  67. ksadk/conversations/runtime_resume.py +20 -1
  68. ksadk/conversations/runtime_stream_events.py +94 -9
  69. ksadk/conversations/semantic_summary.py +311 -1
  70. ksadk/conversations/session_lock.py +51 -0
  71. ksadk/deployment/env_forward.py +72 -0
  72. ksadk/deployment/managed_runtime.py +5 -0
  73. ksadk/deployment/providers/serverless.py +143 -69
  74. ksadk/evaluation/__init__.py +32 -0
  75. ksadk/evaluation/a2a_adapter.py +9 -1
  76. ksadk/evaluation/adapters.py +18 -5
  77. ksadk/evaluation/agent_eval_client.py +395 -0
  78. ksadk/evaluation/cloud_binding.py +80 -0
  79. ksadk/evaluation/cloud_converter.py +194 -0
  80. ksadk/evaluation/cloud_service.py +199 -0
  81. ksadk/evaluation/contracts.py +73 -4
  82. ksadk/evaluation/evaluators.py +183 -17
  83. ksadk/evaluation/evidence.py +258 -0
  84. ksadk/evaluation/executor.py +31 -6
  85. ksadk/evaluation/local_adapter.py +550 -0
  86. ksadk/evaluation/service_env.py +27 -0
  87. ksadk/evaluation/studio_build_adapter.py +253 -0
  88. ksadk/evaluation/target.py +15 -6
  89. ksadk/events/__init__.py +13 -13
  90. ksadk/events/_v1_compat/__init__.py +1 -0
  91. ksadk/events/_v1_compat/models.py +299 -0
  92. ksadk/events/_v1_compat/parser.py +247 -0
  93. ksadk/events/_v1_compat/projection.py +755 -0
  94. ksadk/events/adapters/__init__.py +34 -0
  95. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  96. ksadk/events/adapters/_a2a_support.py +275 -0
  97. ksadk/events/adapters/_codex_interactions.py +375 -0
  98. ksadk/events/adapters/_codex_items.py +801 -0
  99. ksadk/events/adapters/_codex_validators.py +311 -0
  100. ksadk/events/adapters/_langgraph_support.py +785 -0
  101. ksadk/events/adapters/a2a.py +841 -0
  102. ksadk/events/adapters/adk.py +503 -0
  103. ksadk/events/adapters/codex.py +907 -0
  104. ksadk/events/adapters/langgraph.py +745 -0
  105. ksadk/events/canonical.py +440 -0
  106. ksadk/events/canonical_replay.py +497 -0
  107. ksadk/events/canonical_store.py +468 -0
  108. ksadk/events/cold_recovery.py +257 -0
  109. ksadk/events/content.py +89 -0
  110. ksadk/events/identity.py +86 -0
  111. ksadk/events/pipeline.py +455 -0
  112. ksadk/events/projections.py +66 -0
  113. ksadk/events/reducer.py +661 -0
  114. ksadk/events/replay.py +3 -36
  115. ksadk/events/runtime_event.py +20 -265
  116. ksadk/events/session_event.py +324 -0
  117. ksadk/events/store.py +3 -316
  118. ksadk/events/v1_compat.py +41 -0
  119. ksadk/harness/__init__.py +45 -35
  120. ksadk/harness/runtime.py +220 -58
  121. ksadk/identity/resolver.py +4 -3
  122. ksadk/interaction/__init__.py +28 -0
  123. ksadk/interaction/contracts.py +136 -0
  124. ksadk/interaction/ledger.py +189 -0
  125. ksadk/interaction/provider.py +122 -0
  126. ksadk/interaction/providers/__init__.py +52 -0
  127. ksadk/interaction/providers/adk.py +40 -0
  128. ksadk/interaction/providers/codex.py +94 -0
  129. ksadk/interaction/providers/langgraph.py +58 -0
  130. ksadk/kernel/__init__.py +117 -0
  131. ksadk/kernel/authorization.py +258 -0
  132. ksadk/kernel/bootstrap.py +1074 -0
  133. ksadk/kernel/contract_fingerprints.py +62 -0
  134. ksadk/kernel/contracts.py +370 -0
  135. ksadk/kernel/control.py +220 -0
  136. ksadk/kernel/errors.py +79 -0
  137. ksadk/kernel/ingress.py +1123 -0
  138. ksadk/kernel/mapping.py +111 -0
  139. ksadk/kernel/memory_store.py +1134 -0
  140. ksadk/kernel/postgres_store.py +1757 -0
  141. ksadk/kernel/recovery.py +452 -0
  142. ksadk/kernel/runtime_identity.py +103 -0
  143. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  144. ksadk/kernel/sqlite_store.py +1411 -0
  145. ksadk/kernel/state.py +145 -0
  146. ksadk/kernel/store.py +232 -0
  147. ksadk/kernel/worker.py +964 -0
  148. ksadk/knowledge_base/client.py +7 -0
  149. ksadk/knowledge_base/service.py +32 -5
  150. ksadk/memory/__init__.py +61 -0
  151. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  152. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  153. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  154. ksadk/memory/adk/backends/sdk_ltm_backend.py +384 -2
  155. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  156. ksadk/memory/coordinator.py +461 -0
  157. ksadk/memory/events.py +202 -0
  158. ksadk/memory/extraction.py +228 -0
  159. ksadk/memory/ltm_backend_factory.py +16 -3
  160. ksadk/memory/models.py +316 -0
  161. ksadk/memory/policy.py +215 -0
  162. ksadk/memory/provider.py +47 -0
  163. ksadk/memory/provider_adapter.py +159 -0
  164. ksadk/memory/provider_resolver.py +71 -0
  165. ksadk/memory/providers/__init__.py +5 -0
  166. ksadk/memory/providers/local_sqlite.py +497 -0
  167. ksadk/memory/resolved_policy.py +145 -0
  168. ksadk/memory/service.py +188 -6
  169. ksadk/model_proxy/bootstrap.py +16 -9
  170. ksadk/model_proxy/detect.py +202 -9
  171. ksadk/model_proxy/namespace.py +39 -15
  172. ksadk/model_proxy/server.py +24 -5
  173. ksadk/model_proxy/transform.py +60 -2
  174. ksadk/observability/__init__.py +25 -0
  175. ksadk/observability/session_log.py +420 -0
  176. ksadk/observability/trajectory.py +105 -0
  177. ksadk/plugins/__init__.py +167 -0
  178. ksadk/plugins/bridges/__init__.py +45 -0
  179. ksadk/plugins/bridges/codex.py +552 -0
  180. ksadk/plugins/bridges/dsh.py +1116 -0
  181. ksadk/plugins/builtins.py +747 -0
  182. ksadk/plugins/bundle.py +246 -0
  183. ksadk/plugins/bundle_security.py +167 -0
  184. ksadk/plugins/composition.py +529 -0
  185. ksadk/plugins/context_contributor.py +437 -0
  186. ksadk/plugins/contracts.py +451 -0
  187. ksadk/plugins/dsh_toolchain.py +935 -0
  188. ksadk/plugins/ecosystem_bridge.py +1105 -0
  189. ksadk/plugins/ecosystem_probe.py +191 -0
  190. ksadk/plugins/host.py +724 -0
  191. ksadk/plugins/providers/__init__.py +85 -0
  192. ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
  193. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
  194. ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
  195. ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
  196. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
  197. ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
  198. ksadk/plugins/providers/codex.py +722 -0
  199. ksadk/plugins/providers/codex_dsh.py +83 -0
  200. ksadk/plugins/providers/dsh.py +951 -0
  201. ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
  202. ksadk/plugins/providers/harness.py +627 -0
  203. ksadk/plugins/providers/harness_dsh.py +91 -0
  204. ksadk/plugins/providers/legacy.py +215 -0
  205. ksadk/plugins/providers/legacy_catalog.py +100 -0
  206. ksadk/plugins/providers/shipped_dsh.py +370 -0
  207. ksadk/plugins/resolver.py +331 -0
  208. ksadk/plugins/subagent_providers/__init__.py +12 -0
  209. ksadk/plugins/subagent_providers/codex.py +443 -0
  210. ksadk/plugins/subagents.py +333 -0
  211. ksadk/prompts/__init__.py +71 -0
  212. ksadk/prompts/compiler.py +215 -0
  213. ksadk/prompts/models.py +82 -0
  214. ksadk/prompts/projection.py +89 -0
  215. ksadk/prompts/resolved.py +137 -0
  216. ksadk/prompts/sources.py +233 -0
  217. ksadk/runners/_langgraph_runner_streams.py +822 -0
  218. ksadk/runners/adk_runner.py +5 -5
  219. ksadk/runners/base_runner.py +16 -0
  220. ksadk/runners/factory.py +1 -2
  221. ksadk/runners/langgraph_runner.py +198 -437
  222. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  223. ksadk/runtime/_runner_adapter/stream_mapping.py +797 -0
  224. ksadk/runtime/adapter.py +119 -2
  225. ksadk/runtime/conversation_execution.py +316 -182
  226. ksadk/runtime/executor.py +144 -3
  227. ksadk/runtime/factory.py +268 -8
  228. ksadk/runtime/framework_adapters.py +18 -0
  229. ksadk/runtime/hosted_finalizer.py +268 -0
  230. ksadk/runtime/launch.py +14 -1
  231. ksadk/runtime/preprocessing.py +25 -3
  232. ksadk/runtime/runner_adapter.py +293 -508
  233. ksadk/runtime/usage.py +33 -0
  234. ksadk/sandbox/__init__.py +2 -1
  235. ksadk/sandbox/backends/e2b.py +35 -2
  236. ksadk/sandbox/factory.py +72 -0
  237. ksadk/scheduler/__init__.py +18 -0
  238. ksadk/scheduler/calendar.py +102 -0
  239. ksadk/scheduler/contracts.py +254 -0
  240. ksadk/scheduler/dispatcher.py +129 -0
  241. ksadk/scheduler/engine.py +416 -0
  242. ksadk/scheduler/sqlite_store.py +563 -0
  243. ksadk/server/composition.py +8 -0
  244. ksadk/server/factory.py +69 -6
  245. ksadk/server/routes/kernel_ingress.py +258 -0
  246. ksadk/server/routes/openai_compat.py +88 -8
  247. ksadk/server/routes/projection.py +35 -20
  248. ksadk/server/routes/run.py +94 -0
  249. ksadk/server/routes/sessions.py +2 -0
  250. ksadk/server/routes/streaming.py +5 -2
  251. ksadk/server/static/assets/{ArtifactsPanel-CakCqxEN.js → ArtifactsPanel-10GPXIJ6.js} +1 -1
  252. ksadk/server/static/assets/{CodeBlock-CynLknyO.js → CodeBlock-BXk1l-G1.js} +4 -4
  253. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  254. ksadk/server/static/assets/{MathMessageMarkdown-3sQdOysS.js → MathMessageMarkdown-D9uB55Oh.js} +4 -4
  255. ksadk/server/static/assets/MermaidBlock--OEYoXIJ.js +312 -0
  256. ksadk/server/static/assets/NativeTerminalPanel-DrEe1syq.js +1 -0
  257. ksadk/server/static/assets/abnfDiagram-VCTEODGH-eeTFJLvo.js +1 -0
  258. ksadk/server/static/assets/arc-S3ZNbIAd.js +1 -0
  259. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +1 -0
  260. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-CRjgEJDX.js +36 -0
  261. ksadk/server/static/assets/blockDiagram-NRAW4CY4-C7bsBoNH.js +129 -0
  262. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-BX3c33Ob.js +38 -0
  263. ksadk/server/static/assets/channel-s354Yo6o.js +1 -0
  264. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +1 -0
  265. ksadk/server/static/assets/{chunk-FMBD7UC4-B_fH2YuH.js → chunk-5VM5RSS4-bZ7ws-8m.js} +1 -1
  266. ksadk/server/static/assets/{chunk-ND2GUHAM-D6rFLaVV.js → chunk-F27PBJKO-D2r0pvhY.js} +1 -1
  267. ksadk/server/static/assets/chunk-G27WJ6UU-CZwF3oUP.js +231 -0
  268. ksadk/server/static/assets/{chunk-4BX2VUAB-B9drTgOW.js → chunk-JWPE2WC7-DigFYCML.js} +1 -1
  269. ksadk/server/static/assets/chunk-LCL6LL3I-CnorGV5q.js +206 -0
  270. ksadk/server/static/assets/chunk-POPQ4Y6H-CexntQA-.js +1 -0
  271. ksadk/server/static/assets/chunk-RHFEMEQ7-CHTC7UxA.js +168 -0
  272. ksadk/server/static/assets/chunk-SVP7TREG-BC1EWt_-.js +88 -0
  273. ksadk/server/static/assets/chunk-XXDRQBXY-BTG24xN0.js +1 -0
  274. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +1 -0
  275. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +1 -0
  276. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-ChNs_Mdk.js → cose-bilkent-JH36ORCC-CkonRdAS.js} +1 -1
  277. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +1 -0
  278. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-DEOCBe15.js +62 -0
  279. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  280. ksadk/server/static/assets/dagre-3AP2YEHR-DBThPuLa.js +4 -0
  281. ksadk/server/static/assets/dagre-ClTPrTht.js +1 -0
  282. ksadk/server/static/assets/diagram-S7CK7UJ4-DsZHrnpJ.js +30 -0
  283. ksadk/server/static/assets/diagram-UQ7AKVKN-BJR4nhVr.js +41 -0
  284. ksadk/server/static/assets/diagram-VSXAHHWV-xzcERX0a.js +3 -0
  285. ksadk/server/static/assets/diagram-VX7I27RA-tn2xM1xu.js +24 -0
  286. ksadk/server/static/assets/diagram-Z3DM3KII-BZPGBkw5.js +24 -0
  287. ksadk/server/static/assets/{dist-gLnrGsoU.js → dist-4zN1_tq5.js} +1 -1
  288. ksadk/server/static/assets/{dist-C1sz5Eo3.js → dist-8VWI-2bZ.js} +1 -1
  289. ksadk/server/static/assets/{dist-BjOdlDjj.js → dist-B-46q3Hk.js} +1 -1
  290. ksadk/server/static/assets/{dist-o2OVmKvt.js → dist-B0gdk4rl.js} +1 -1
  291. ksadk/server/static/assets/{dist-4N2NMVYg.js → dist-B1oWRmrH.js} +1 -1
  292. ksadk/server/static/assets/{dist-CmZHzlwZ.js → dist-BI1qQH4n.js} +1 -1
  293. ksadk/server/static/assets/{dist-X4TnqwOK.js → dist-BJLUwH6W.js} +1 -1
  294. ksadk/server/static/assets/{dist-B5oS1zcj.js → dist-Bbwqa8TG.js} +1 -1
  295. ksadk/server/static/assets/{dist-j6Dxmf_j.js → dist-Btyo4vX4.js} +1 -1
  296. ksadk/server/static/assets/{dist-DQU9EWw-.js → dist-C71CsujO.js} +1 -1
  297. ksadk/server/static/assets/{dist-BIlKoW0k.js → dist-CXpH_Rdd.js} +1 -1
  298. ksadk/server/static/assets/{dist-DJN_6Y39.js → dist-Cq4OL6nO.js} +1 -1
  299. ksadk/server/static/assets/{dist-Dli7qW-B.js → dist-D1V3f1B4.js} +1 -1
  300. ksadk/server/static/assets/{dist-fhOuWds5.js → dist-DJmCPRVB.js} +1 -1
  301. ksadk/server/static/assets/{dist-CWV4lDr1.js → dist-DQAB0qn_.js} +2 -2
  302. ksadk/server/static/assets/{dist-D6MpCZtz.js → dist-DUwKa_l6.js} +1 -1
  303. ksadk/server/static/assets/dist-DdRBIceA.js +1 -0
  304. ksadk/server/static/assets/{dist-DWKByxWV.js → dist-DfGFrb0v.js} +1 -1
  305. ksadk/server/static/assets/{dist-DsHPdk3W.js → dist-DjhwGUgZ.js} +1 -1
  306. ksadk/server/static/assets/{dist-B-jNR6Vn.js → dist-DyqV4fL4.js} +1 -1
  307. ksadk/server/static/assets/{dist-BB3-OwTQ.js → dist-M67Hwu0n.js} +1 -1
  308. ksadk/server/static/assets/{dist-_pHPTyZ-.js → dist-u8tVH5Ak.js} +1 -1
  309. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-DVfMsLge.js +1 -0
  310. ksadk/server/static/assets/erDiagram-SSCWMZ5O-CWEZSYaw.js +99 -0
  311. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +1 -0
  312. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +1 -0
  313. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-TWIxoyYL.js +292 -0
  314. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +1 -0
  315. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-DDh2hd2S.js +106 -0
  316. ksadk/server/static/assets/index-B2k_urY8.js +241 -0
  317. ksadk/server/static/assets/index-ILPt6IWF.css +2 -0
  318. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +1 -0
  319. ksadk/server/static/assets/infoDiagram-RXCK75RN-CgoyWiDR.js +2 -0
  320. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-K0OOfVna.js → ishikawaDiagram-5VMMS53U-CyRIu_om.js} +6 -6
  321. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-8LeOJaZp.js → journeyDiagram-EYS64GPL-DN5JXHzN.js} +6 -6
  322. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-C6uCgZrW.js → kanban-definition-3QL26DDD-CNP3ui66.js} +10 -10
  323. ksadk/server/static/assets/katex-DWEzQy1d.js +257 -0
  324. ksadk/server/static/assets/{linear-hdBcYzM8.js → linear-C-qHp7d2.js} +1 -1
  325. ksadk/server/static/assets/mermaid-parser.core-Cl-K943T.js +166 -0
  326. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-Bjy_2v4_.js → mindmap-definition-FBJOCRG2-D5DB5mYm.js} +29 -29
  327. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +1 -0
  328. ksadk/server/static/assets/pegDiagram-XKGWAZYB-BQVc9ia_.js +1 -0
  329. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +1 -0
  330. ksadk/server/static/assets/pieDiagram-E7YTZNPT-B6UCAvtY.js +39 -0
  331. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-BmkRbwCg.js → quadrantDiagram-AXDQQJYC-mIr2d3eb.js} +6 -6
  332. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +1 -0
  333. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +1 -0
  334. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +1 -0
  335. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +1 -0
  336. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +1 -0
  337. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-Dt3FFDmK.js +1 -0
  338. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-Cz_vQtgF.js +84 -0
  339. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-l6iXmU65.js → sankeyDiagram-P5KCCOFB-wlO1TsH5.js} +7 -7
  340. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-Cq6UBeQB.js → sequenceDiagram-WJ2MYXX4-CHRbElYq.js} +10 -10
  341. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-DXX54iyO.js +1 -0
  342. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-Dp_lw9II.js +1 -0
  343. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +1 -0
  344. ksadk/server/static/assets/swimlanes-XN3QIQJK-D8O5UlLG.js +1 -0
  345. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +8 -0
  346. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-DEz24vV0.js → timeline-definition-24CTP7MA-8mfKcxvG.js} +7 -7
  347. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +1 -0
  348. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +1 -0
  349. ksadk/server/static/assets/vennDiagram-4TSXK5OY-EnNl0DE7.js +34 -0
  350. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +1 -0
  351. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DBu5fbYr.js +78 -0
  352. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-BSVXs4IY.js +7 -0
  353. ksadk/server/static/index.html +2 -2
  354. ksadk/sessions/__init__.py +26 -9
  355. ksadk/sessions/_local_service_sync.py +688 -0
  356. ksadk/sessions/_local_tables.py +21 -0
  357. ksadk/sessions/_postgres_schema.py +305 -0
  358. ksadk/sessions/_postgres_tables.py +15 -0
  359. ksadk/sessions/base.py +80 -1
  360. ksadk/sessions/in_memory.py +53 -2
  361. ksadk/sessions/local_service.py +63 -604
  362. ksadk/sessions/postgres_service.py +58 -148
  363. ksadk/sessions/resilient.py +35 -1
  364. ksadk/skills/service_client.py +48 -0
  365. ksadk/studio/agent_lifecycle.py +26 -20
  366. ksadk/studio/api.py +1063 -69
  367. ksadk/studio/api_catalog_routes.py +5 -0
  368. ksadk/studio/api_contracts.py +148 -6
  369. ksadk/studio/api_memory_routes.py +82 -0
  370. ksadk/studio/api_plugin_routes.py +480 -0
  371. ksadk/studio/attachment_store.py +187 -0
  372. ksadk/studio/authoring.py +259 -28
  373. ksadk/studio/authoring_coordinator.py +809 -67
  374. ksadk/studio/builder.py +197 -40
  375. ksadk/studio/capabilities.py +17 -0
  376. ksadk/studio/cloud.py +1920 -95
  377. ksadk/studio/codex_agent_service.py +137 -15
  378. ksadk/studio/codex_authoring.py +469 -0
  379. ksadk/studio/codex_builder.py +177 -25
  380. ksadk/studio/codex_manifest.py +71 -22
  381. ksadk/studio/codex_run.py +59 -4
  382. ksadk/studio/compatibility_report.py +445 -0
  383. ksadk/studio/compiler.py +7 -1
  384. ksadk/studio/contracts.py +234 -4
  385. ksadk/studio/dsh_provider_registration.py +768 -0
  386. ksadk/studio/event_store.py +79 -101
  387. ksadk/studio/framework_run.py +264 -3
  388. ksadk/studio/hosted_kernel.py +317 -0
  389. ksadk/studio/manifest_resolver.py +131 -0
  390. ksadk/studio/model_client.py +95 -9
  391. ksadk/studio/model_profile_service.py +1 -1
  392. ksadk/studio/operations.py +47 -5
  393. ksadk/studio/otel_trace.py +348 -42
  394. ksadk/studio/pcm_memory.py +85 -0
  395. ksadk/studio/plugin_composition.py +301 -0
  396. ksadk/studio/plugin_kernel_adapter.py +128 -0
  397. ksadk/studio/plugin_runtime.py +652 -0
  398. ksadk/studio/repository.py +23 -2
  399. ksadk/studio/resource_catalog.py +49 -1
  400. ksadk/studio/run_service.py +1266 -202
  401. ksadk/studio/runtime_source.py +51 -17
  402. ksadk/studio/scheduler_runtime.py +374 -0
  403. ksadk/studio/scheduler_service.py +211 -0
  404. ksadk/studio/service.py +1815 -117
  405. ksadk/studio/shared_web.py +199 -50
  406. ksadk/studio/soul.py +52 -0
  407. ksadk/studio/static/assets/index-DXs1Eq4M.css +1 -0
  408. ksadk/studio/static/assets/index-DeDqwTsD.js +283 -0
  409. ksadk/studio/static/index.html +2 -2
  410. ksadk/studio/templates.py +100 -8
  411. ksadk/studio/validator.py +20 -1
  412. ksadk/studio/workspace.py +31 -32
  413. ksadk/tracing/setup.py +304 -3
  414. ksadk/version.py +1 -1
  415. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  416. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  417. ksadk_runtime_common/workspace_files/path_utils.py +41 -0
  418. ksadk/events/parser.py +0 -191
  419. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  420. ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +0 -303
  421. ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +0 -1
  422. ksadk/server/static/assets/arc-DrgjcKhl.js +0 -1
  423. ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +0 -1
  424. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-BXoVRbQ6.js +0 -36
  425. ksadk/server/static/assets/blockDiagram-GPEHLZMM-BnaB3Ywv.js +0 -132
  426. ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dw4weZcp.js +0 -10
  427. ksadk/server/static/assets/channel-Dt3rQTFI.js +0 -1
  428. ksadk/server/static/assets/chunk-2J33WTMH-ChjpLK7j.js +0 -1
  429. ksadk/server/static/assets/chunk-55IACEB6-CK4ROATy.js +0 -1
  430. ksadk/server/static/assets/chunk-727SXJPM-B9KtTTgw.js +0 -206
  431. ksadk/server/static/assets/chunk-AQP2D5EJ-1O1mki3m.js +0 -231
  432. ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +0 -1
  433. ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +0 -1
  434. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +0 -1
  435. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  436. ksadk/server/static/assets/dagre-BM42HDAG-D0QXg_MQ.js +0 -4
  437. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  438. ksadk/server/static/assets/diagram-2AECGRRQ-DBDDKwBQ.js +0 -43
  439. ksadk/server/static/assets/diagram-5GNKFQAL-BkwDOxmO.js +0 -10
  440. ksadk/server/static/assets/diagram-KO2AKTUF-Bv8waYvY.js +0 -3
  441. ksadk/server/static/assets/diagram-LMA3HP47-e1VECDdu.js +0 -24
  442. ksadk/server/static/assets/diagram-OG6HWLK6-Ds9adfRl.js +0 -24
  443. ksadk/server/static/assets/dist-B5J2uhNk.js +0 -1
  444. ksadk/server/static/assets/erDiagram-TEJ5UH35-BPItFKH6.js +0 -85
  445. ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +0 -1
  446. ksadk/server/static/assets/flowDiagram-I6XJVG4X-BbYB9w5Y.js +0 -162
  447. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-TQXa0KXv.js +0 -292
  448. ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +0 -1
  449. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-bKblCnpa.js +0 -106
  450. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  451. ksadk/server/static/assets/index-R52pJJvg.js +0 -177
  452. ksadk/server/static/assets/index-jJr3_955.css +0 -2
  453. ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +0 -1
  454. ksadk/server/static/assets/infoDiagram-5YYISTIA-BGVT7J_i.js +0 -2
  455. ksadk/server/static/assets/katex-CYWseY5E.js +0 -265
  456. ksadk/server/static/assets/mermaid-parser.core-BWrDjSZM.js +0 -161
  457. ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +0 -1
  458. ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +0 -1
  459. ksadk/server/static/assets/pieDiagram-4H26LBE5-GmmqNiVH.js +0 -30
  460. ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +0 -1
  461. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DSWFqL7c.js +0 -84
  462. ksadk/server/static/assets/stateDiagram-AJRCARHV-qzTQpg3Y.js +0 -1
  463. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +0 -1
  464. ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +0 -1
  465. ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +0 -1
  466. ksadk/server/static/assets/vennDiagram-CIIHVFJN-CMCixki2.js +0 -34
  467. ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +0 -1
  468. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-CVzB8F9K.js +0 -78
  469. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-BFBqBLc1.js +0 -7
  470. ksadk/studio/evaluation.py +0 -192
  471. ksadk/studio/static/assets/index-CaEN0eTR.css +0 -1
  472. ksadk/studio/static/assets/index-DI2eY_NH.js +0 -252
  473. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/WHEEL +0 -0
  474. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/entry_points.txt +0 -0
  475. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/licenses/LICENSE +0 -0
  476. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/top_level.txt +0 -0
@@ -6,31 +6,29 @@ import asyncio
6
6
  import json
7
7
  import os
8
8
  import sqlite3
9
- import time
10
9
  from collections.abc import Iterator
11
10
  from contextlib import closing, contextmanager
12
11
  from pathlib import Path
13
12
  from typing import Optional
14
13
 
15
- from ksadk.ids import new_session_id
14
+ from ksadk.sessions._local_service_sync import _LocalServiceSyncMixin
15
+ from ksadk.sessions._local_tables import (
16
+ DEFAULT_SESSION_DB_NAME,
17
+ KSADK_EVENTS_TABLE,
18
+ KSADK_SESSIONS_TABLE,
19
+ KSADK_STATES_TABLE,
20
+ LEGACY_EVENTS_TABLE,
21
+ LEGACY_SESSIONS_TABLE,
22
+ LEGACY_STATES_TABLE,
23
+ )
16
24
  from ksadk.sessions.base import (
25
+ CANONICAL_EVENT_STORAGE_CAPABILITIES,
17
26
  BaseSessionService,
18
27
  Session,
19
28
  SessionEvent,
20
29
  SessionState,
21
- generate_id,
22
30
  )
23
31
 
24
- KSADK_SESSIONS_TABLE = "ksadk_sessions"
25
- KSADK_EVENTS_TABLE = "ksadk_events"
26
- KSADK_STATES_TABLE = "ksadk_states"
27
-
28
- LEGACY_SESSIONS_TABLE = "sessions"
29
- LEGACY_EVENTS_TABLE = "events"
30
- LEGACY_STATES_TABLE = "states"
31
-
32
- DEFAULT_SESSION_DB_NAME = "sessions.sqlite"
33
-
34
32
 
35
33
  def resolve_local_session_dir(project_dir: Optional[str] = None) -> Path:
36
34
  configured = (os.getenv("AGENTENGINE_UI_DIR") or "").strip()
@@ -53,7 +51,9 @@ def resolve_local_session_path(project_dir: Optional[str] = None) -> Path:
53
51
  return resolve_local_session_dir(project_dir) / DEFAULT_SESSION_DB_NAME
54
52
 
55
53
 
56
- class LocalSessionService(BaseSessionService):
54
+ class LocalSessionService(_LocalServiceSyncMixin, BaseSessionService):
55
+ storage_capabilities = CANONICAL_EVENT_STORAGE_CAPABILITIES
56
+
57
57
  def __init__(self, db_path: Optional[Path] = None, *, project_dir: Optional[str] = None):
58
58
  self.db_path = (
59
59
  Path(db_path).expanduser().resolve()
@@ -138,6 +138,27 @@ class LocalSessionService(BaseSessionService):
138
138
  async with self._lock:
139
139
  return await asyncio.to_thread(self._append_event_sync, session_id, event)
140
140
 
141
+ async def get_event_by_id(self, session_id: str, event_id: str) -> Optional[SessionEvent]:
142
+ async with self._lock:
143
+ return await asyncio.to_thread(self._get_event_by_id_sync, session_id, event_id)
144
+
145
+ async def get_events_by_invocation_id(
146
+ self,
147
+ session_id: str,
148
+ invocation_id: str,
149
+ *,
150
+ after_seq_id: Optional[int] = None,
151
+ before_seq_id: Optional[int] = None,
152
+ ) -> list[SessionEvent]:
153
+ async with self._lock:
154
+ return await asyncio.to_thread(
155
+ self._get_events_by_invocation_id_sync,
156
+ session_id,
157
+ invocation_id,
158
+ after_seq_id,
159
+ before_seq_id,
160
+ )
161
+
141
162
  async def get_events(
142
163
  self,
143
164
  session_id: str,
@@ -385,6 +406,29 @@ class LocalSessionService(BaseSessionService):
385
406
  ):
386
407
  connection.execute(f"ALTER TABLE {LEGACY_STATES_TABLE} RENAME TO {KSADK_STATES_TABLE}")
387
408
 
409
+ @staticmethod
410
+ def _ensure_event_seq_unique_index(connection: sqlite3.Connection) -> None:
411
+ index_name = "idx_ksadk_events_session_seq"
412
+ existing = next(
413
+ (
414
+ row
415
+ for row in connection.execute(
416
+ f"PRAGMA index_list('{KSADK_EVENTS_TABLE}')"
417
+ ).fetchall()
418
+ if str(row[1]) == index_name
419
+ ),
420
+ None,
421
+ )
422
+ if existing is not None and not bool(existing[2]):
423
+ # ``CREATE UNIQUE INDEX IF NOT EXISTS`` does not upgrade the old
424
+ # ordinary index with the same name. Replace it explicitly so
425
+ # reopened pre-v2 databases gain the durable cursor invariant.
426
+ connection.execute(f"DROP INDEX {index_name}")
427
+ connection.execute(
428
+ f"CREATE UNIQUE INDEX IF NOT EXISTS {index_name} "
429
+ f"ON {KSADK_EVENTS_TABLE} (session_id, seq_id)"
430
+ )
431
+
388
432
  def _ensure_schema(self) -> None:
389
433
  with self._connection() as connection:
390
434
  self._migrate_legacy_schema(connection)
@@ -418,7 +462,7 @@ class LocalSessionService(BaseSessionService):
418
462
  FOREIGN KEY(session_id) REFERENCES {KSADK_SESSIONS_TABLE}(id) ON DELETE CASCADE
419
463
  );
420
464
 
421
- CREATE INDEX IF NOT EXISTS idx_ksadk_events_session_seq
465
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_ksadk_events_session_seq
422
466
  ON {KSADK_EVENTS_TABLE} (session_id, seq_id);
423
467
 
424
468
  -- 跨会话事件查询(get_events_for_agent)JOIN sessions 按
@@ -427,6 +471,9 @@ class LocalSessionService(BaseSessionService):
427
471
  CREATE INDEX IF NOT EXISTS idx_ksadk_events_session_ts
428
472
  ON {KSADK_EVENTS_TABLE} (session_id, timestamp, id);
429
473
 
474
+ CREATE INDEX IF NOT EXISTS idx_ksadk_events_session_invocation_seq
475
+ ON {KSADK_EVENTS_TABLE} (session_id, invocation_id, seq_id);
476
+
430
477
  -- ListSessions 按 agent_id 过滤 + updated_at DESC 排序。
431
478
  CREATE INDEX IF NOT EXISTS idx_ksadk_sessions_agent_updated
432
479
  ON {KSADK_SESSIONS_TABLE} (agent_id, updated_at DESC, id);
@@ -472,597 +519,9 @@ class LocalSessionService(BaseSessionService):
472
519
  "updated_at": "REAL NOT NULL DEFAULT 0",
473
520
  },
474
521
  )
522
+ self._ensure_event_seq_unique_index(connection)
475
523
  connection.commit()
476
524
 
477
- def _create_session_sync(
478
- self,
479
- agent_id: str,
480
- user_id: str,
481
- session_id: Optional[str],
482
- ) -> Session:
483
- with self._connection() as connection:
484
- if session_id:
485
- existing = self._get_session_sync(session_id, connection=connection)
486
- if existing is not None:
487
- return existing
488
-
489
- now = time.time()
490
- session = Session(
491
- id=session_id or new_session_id(),
492
- agent_id=agent_id,
493
- user_id=user_id,
494
- created_at=now,
495
- updated_at=now,
496
- )
497
- connection.execute(
498
- f"""
499
- INSERT INTO {KSADK_SESSIONS_TABLE} (
500
- id, agent_id, user_id, title, title_source, summary, first_prompt, last_prompt,
501
- state_json, created_at, updated_at, version
502
- )
503
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
504
- """,
505
- (
506
- session.id,
507
- session.agent_id,
508
- session.user_id,
509
- session.title,
510
- session.title_source,
511
- session.summary,
512
- session.first_prompt,
513
- session.last_prompt,
514
- json.dumps(session.state),
515
- session.created_at,
516
- session.updated_at,
517
- session.version,
518
- ),
519
- )
520
- connection.execute(
521
- f"""
522
- INSERT OR REPLACE INTO {KSADK_STATES_TABLE} (
523
- scope, agent_id, user_id, session_id, state_json, version, updated_at
524
- )
525
- VALUES (?, ?, ?, ?, ?, ?, ?)
526
- """,
527
- ("session", session.agent_id, session.user_id, session.id, "{}", 0, now),
528
- )
529
- connection.commit()
530
- return session
531
-
532
- def _get_session_sync(
533
- self,
534
- session_id: str,
535
- *,
536
- connection: Optional[sqlite3.Connection] = None,
537
- include_events: bool = True,
538
- ) -> Optional[Session]:
539
- owns_connection = connection is None
540
- connection = connection or self._connect()
541
- try:
542
- row = connection.execute(
543
- f"""
544
- SELECT
545
- id, agent_id, user_id, title, title_source, summary, first_prompt, last_prompt,
546
- state_json, created_at, updated_at, version
547
- FROM {KSADK_SESSIONS_TABLE}
548
- WHERE id = ?
549
- """,
550
- (session_id,),
551
- ).fetchone()
552
- if row is None:
553
- return None
554
- return Session(
555
- id=row["id"],
556
- agent_id=row["agent_id"],
557
- user_id=row["user_id"],
558
- title=row["title"],
559
- title_source=row["title_source"],
560
- summary=row["summary"],
561
- first_prompt=row["first_prompt"],
562
- last_prompt=row["last_prompt"],
563
- state=json.loads(row["state_json"] or "{}"),
564
- events=(
565
- self._get_events_sync(session_id, connection=connection)
566
- if include_events
567
- else []
568
- ),
569
- created_at=row["created_at"],
570
- updated_at=row["updated_at"],
571
- version=row["version"],
572
- )
573
- finally:
574
- if owns_connection:
575
- connection.close()
576
-
577
- def _list_sessions_sync(
578
- self,
579
- agent_id: str,
580
- user_id: Optional[str],
581
- offset: Optional[int] = None,
582
- limit: Optional[int] = None,
583
- ) -> list[Session]:
584
- with self._connection() as connection:
585
- query = f"""
586
- SELECT
587
- id, agent_id, user_id, title, title_source, summary, first_prompt, last_prompt,
588
- state_json, created_at, updated_at, version
589
- FROM {KSADK_SESSIONS_TABLE}
590
- WHERE agent_id = ?
591
- """
592
- params: list[object] = [agent_id]
593
- if user_id is not None:
594
- query += " AND user_id = ?"
595
- params.append(user_id)
596
- query += " ORDER BY updated_at DESC, created_at DESC, id DESC"
597
- if limit is not None:
598
- query += " LIMIT ?"
599
- params.append(limit)
600
- if offset is not None:
601
- query += " OFFSET ?"
602
- params.append(offset)
603
- elif offset is not None:
604
- query += " LIMIT -1 OFFSET ?"
605
- params.append(offset)
606
- rows = connection.execute(query, params).fetchall()
607
- return [
608
- Session(
609
- id=row["id"],
610
- agent_id=row["agent_id"],
611
- user_id=row["user_id"],
612
- title=row["title"],
613
- title_source=row["title_source"],
614
- summary=row["summary"],
615
- first_prompt=row["first_prompt"],
616
- last_prompt=row["last_prompt"],
617
- state=json.loads(row["state_json"] or "{}"),
618
- events=[],
619
- created_at=row["created_at"],
620
- updated_at=row["updated_at"],
621
- version=row["version"],
622
- )
623
- for row in rows
624
- ]
625
-
626
- def _count_sessions_sync(self, agent_id: str, user_id: Optional[str]) -> int:
627
- with self._connection() as connection:
628
- query = f"""
629
- SELECT COUNT(*) AS total
630
- FROM {KSADK_SESSIONS_TABLE}
631
- WHERE agent_id = ?
632
- """
633
- params: list[object] = [agent_id]
634
- if user_id is not None:
635
- query += " AND user_id = ?"
636
- params.append(user_id)
637
- row = connection.execute(query, params).fetchone()
638
- return int(row["total"] if row else 0)
639
-
640
- def _delete_session_sync(self, session_id: str) -> bool:
641
- with self._connection() as connection:
642
- row = connection.execute(
643
- f"SELECT 1 FROM {KSADK_SESSIONS_TABLE} WHERE id = ?",
644
- (session_id,),
645
- ).fetchone()
646
- if row is None:
647
- return False
648
-
649
- connection.execute(
650
- f"DELETE FROM {KSADK_EVENTS_TABLE} WHERE session_id = ?", (session_id,)
651
- )
652
- connection.execute(
653
- f"DELETE FROM {KSADK_STATES_TABLE} WHERE session_id = ?", (session_id,)
654
- )
655
- connection.execute(f"DELETE FROM {KSADK_SESSIONS_TABLE} WHERE id = ?", (session_id,))
656
- connection.commit()
657
- return True
658
-
659
- def _append_event_sync(self, session_id: str, event: SessionEvent) -> SessionEvent:
660
- with self._connection() as connection:
661
- session_row = connection.execute(
662
- f"""
663
- SELECT agent_id, user_id, state_json, version
664
- FROM {KSADK_SESSIONS_TABLE}
665
- WHERE id = ?
666
- """,
667
- (session_id,),
668
- ).fetchone()
669
- if session_row is None:
670
- raise ValueError(f"Session {session_id} not found")
671
-
672
- next_seq = int(
673
- connection.execute(
674
- f"SELECT COALESCE(MAX(seq_id), 0) + 1 "
675
- f"FROM {KSADK_EVENTS_TABLE} WHERE session_id = ?",
676
- (session_id,),
677
- ).fetchone()[0]
678
- )
679
- stored = SessionEvent(
680
- id=event.id or generate_id(),
681
- session_id=session_id,
682
- author=event.author,
683
- event_type=event.event_type,
684
- content=dict(event.content),
685
- timestamp=event.timestamp,
686
- state_delta=dict(event.state_delta),
687
- seq_id=next_seq,
688
- invocation_id=event.invocation_id,
689
- metadata=dict(event.metadata),
690
- )
691
- connection.execute(
692
- f"""
693
- INSERT INTO {KSADK_EVENTS_TABLE} (
694
- id, session_id, author, event_type, content_json, timestamp,
695
- state_delta_json, seq_id, invocation_id, metadata_json
696
- )
697
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
698
- """,
699
- (
700
- stored.id,
701
- stored.session_id,
702
- stored.author,
703
- stored.event_type,
704
- json.dumps(stored.content),
705
- stored.timestamp,
706
- json.dumps(stored.state_delta),
707
- stored.seq_id,
708
- stored.invocation_id,
709
- json.dumps(stored.metadata),
710
- ),
711
- )
712
-
713
- updated_at = time.time()
714
- state = json.loads(session_row["state_json"] or "{}")
715
- version = int(session_row["version"] or 0)
716
- if stored.state_delta:
717
- state.update(stored.state_delta)
718
- version += 1
719
-
720
- connection.execute(
721
- f"""
722
- UPDATE {KSADK_SESSIONS_TABLE}
723
- SET state_json = ?, updated_at = ?, version = ?
724
- WHERE id = ?
725
- """,
726
- (json.dumps(state), updated_at, version, session_id),
727
- )
728
-
729
- if stored.state_delta:
730
- connection.execute(
731
- f"""
732
- INSERT OR REPLACE INTO {KSADK_STATES_TABLE} (
733
- scope, agent_id, user_id, session_id, state_json, version, updated_at
734
- )
735
- VALUES (?, ?, ?, ?, ?, ?, ?)
736
- """,
737
- (
738
- "session",
739
- session_row["agent_id"],
740
- session_row["user_id"],
741
- session_id,
742
- json.dumps(state),
743
- version,
744
- updated_at,
745
- ),
746
- )
747
-
748
- connection.commit()
749
- return stored
750
-
751
- def _update_session_metadata_sync(
752
- self,
753
- session_id: str,
754
- title: Optional[str],
755
- title_source: Optional[str],
756
- summary: Optional[str],
757
- first_prompt: Optional[str],
758
- last_prompt: Optional[str],
759
- ) -> Session:
760
- with self._connection() as connection:
761
- row = connection.execute(
762
- f"""
763
- SELECT
764
- id, agent_id, user_id, title, title_source, summary, first_prompt, last_prompt,
765
- state_json, created_at, updated_at, version
766
- FROM {KSADK_SESSIONS_TABLE}
767
- WHERE id = ?
768
- """,
769
- (session_id,),
770
- ).fetchone()
771
- if row is None:
772
- raise ValueError(f"Session {session_id} not found")
773
-
774
- updated_at = time.time()
775
- next_title = row["title"] if title is None else title
776
- next_title_source = row["title_source"] if title_source is None else title_source
777
- next_summary = row["summary"] if summary is None else summary
778
- next_first_prompt = row["first_prompt"] if first_prompt is None else first_prompt
779
- next_last_prompt = row["last_prompt"] if last_prompt is None else last_prompt
780
-
781
- connection.execute(
782
- f"""
783
- UPDATE {KSADK_SESSIONS_TABLE}
784
- SET title = ?, title_source = ?, summary = ?, first_prompt = ?, last_prompt = ?,
785
- updated_at = ?
786
- WHERE id = ?
787
- """,
788
- (
789
- next_title,
790
- next_title_source,
791
- next_summary,
792
- next_first_prompt,
793
- next_last_prompt,
794
- updated_at,
795
- session_id,
796
- ),
797
- )
798
- connection.commit()
799
- return Session(
800
- id=row["id"],
801
- agent_id=row["agent_id"],
802
- user_id=row["user_id"],
803
- title=next_title,
804
- title_source=next_title_source,
805
- summary=next_summary,
806
- first_prompt=next_first_prompt,
807
- last_prompt=next_last_prompt,
808
- state=json.loads(row["state_json"] or "{}"),
809
- events=[],
810
- created_at=row["created_at"],
811
- updated_at=updated_at,
812
- version=row["version"],
813
- )
814
-
815
- def _get_events_sync(
816
- self,
817
- session_id: str,
818
- offset: Optional[int] = None,
819
- limit: Optional[int] = None,
820
- after_seq_id: Optional[int] = None,
821
- before_seq_id: Optional[int] = None,
822
- *,
823
- connection: Optional[sqlite3.Connection] = None,
824
- ) -> list[SessionEvent]:
825
- owns_connection = connection is None
826
- connection = connection or self._connect()
827
- try:
828
- # seq 过滤先应用,再对结果集应用"最新 N 条" offset/limit 语义。
829
- seq_clauses: list[str] = []
830
- seq_params: list[object] = []
831
- if after_seq_id is not None:
832
- seq_clauses.append("AND seq_id > ?")
833
- seq_params.append(after_seq_id)
834
- if before_seq_id is not None:
835
- seq_clauses.append("AND seq_id < ?")
836
- seq_params.append(before_seq_id)
837
- seq_clause = " ".join(seq_clauses)
838
- if limit is not None:
839
- query = f"""
840
- SELECT id, session_id, author, event_type, content_json, timestamp,
841
- state_delta_json, seq_id, invocation_id, metadata_json
842
- FROM (
843
- SELECT id, session_id, author, event_type, content_json, timestamp,
844
- state_delta_json, seq_id, invocation_id, metadata_json
845
- FROM {KSADK_EVENTS_TABLE}
846
- WHERE session_id = ? {seq_clause}
847
- ORDER BY seq_id DESC
848
- LIMIT ? OFFSET ?
849
- )
850
- ORDER BY seq_id ASC
851
- """
852
- params: list[object] = [session_id, *seq_params]
853
- params.extend([limit, offset or 0])
854
- elif offset is not None:
855
- query = f"""
856
- SELECT id, session_id, author, event_type, content_json, timestamp,
857
- state_delta_json, seq_id, invocation_id, metadata_json
858
- FROM (
859
- SELECT id, session_id, author, event_type, content_json, timestamp,
860
- state_delta_json, seq_id, invocation_id, metadata_json
861
- FROM {KSADK_EVENTS_TABLE}
862
- WHERE session_id = ? {seq_clause}
863
- ORDER BY seq_id DESC
864
- LIMIT -1 OFFSET ?
865
- )
866
- ORDER BY seq_id ASC
867
- """
868
- params = [session_id, *seq_params]
869
- params.append(offset)
870
- else:
871
- query = f"""
872
- SELECT id, session_id, author, event_type, content_json, timestamp,
873
- state_delta_json, seq_id, invocation_id, metadata_json
874
- FROM {KSADK_EVENTS_TABLE}
875
- WHERE session_id = ? {seq_clause}
876
- ORDER BY seq_id ASC
877
- """
878
- params = [session_id, *seq_params]
879
-
880
- rows = connection.execute(query, params).fetchall()
881
- return [
882
- SessionEvent(
883
- id=row["id"],
884
- session_id=row["session_id"],
885
- author=row["author"],
886
- event_type=row["event_type"],
887
- content=json.loads(row["content_json"] or "{}"),
888
- timestamp=row["timestamp"],
889
- state_delta=json.loads(row["state_delta_json"] or "{}"),
890
- seq_id=row["seq_id"],
891
- invocation_id=row["invocation_id"],
892
- metadata=json.loads(row["metadata_json"] or "{}"),
893
- )
894
- for row in rows
895
- ]
896
- finally:
897
- if owns_connection:
898
- connection.close()
899
-
900
- def _count_events_sync(
901
- self,
902
- session_id: str,
903
- after_seq_id: Optional[int] = None,
904
- before_seq_id: Optional[int] = None,
905
- ) -> int:
906
- with self._connection() as connection:
907
- seq_clauses: list[str] = []
908
- params: list[object] = [session_id]
909
- if after_seq_id is not None:
910
- seq_clauses.append("AND seq_id > ?")
911
- params.append(after_seq_id)
912
- if before_seq_id is not None:
913
- seq_clauses.append("AND seq_id < ?")
914
- params.append(before_seq_id)
915
- seq_clause = " ".join(seq_clauses)
916
- row = connection.execute(
917
- f"""
918
- SELECT COUNT(*) AS total
919
- FROM {KSADK_EVENTS_TABLE}
920
- WHERE session_id = ? {seq_clause}
921
- """,
922
- params,
923
- ).fetchone()
924
- return int(row["total"] if row else 0)
925
-
926
- def _get_state_sync(
927
- self,
928
- agent_id: str,
929
- user_id: Optional[str],
930
- session_id: Optional[str],
931
- scope: str,
932
- ) -> Optional[SessionState]:
933
- with self._connection() as connection:
934
- if scope == "session" and session_id:
935
- session = self._get_session_sync(session_id, connection=connection)
936
- if session is None:
937
- return None
938
- return SessionState(
939
- scope="session",
940
- agent_id=session.agent_id,
941
- user_id=session.user_id,
942
- session_id=session.id,
943
- state=dict(session.state),
944
- version=session.version,
945
- updated_at=session.updated_at,
946
- )
947
-
948
- row = connection.execute(
949
- f"""
950
- SELECT scope, agent_id, user_id, session_id, state_json, version, updated_at
951
- FROM {KSADK_STATES_TABLE}
952
- WHERE scope = ? AND agent_id = ? AND user_id = ? AND session_id = ?
953
- """,
954
- (scope, agent_id, user_id or "", session_id or ""),
955
- ).fetchone()
956
- if row is None:
957
- return None
958
-
959
- return SessionState(
960
- scope=row["scope"],
961
- agent_id=row["agent_id"],
962
- user_id=row["user_id"],
963
- session_id=row["session_id"],
964
- state=json.loads(row["state_json"] or "{}"),
965
- version=row["version"],
966
- updated_at=row["updated_at"],
967
- )
968
-
969
- def _update_state_sync(
970
- self,
971
- agent_id: str,
972
- user_id: Optional[str],
973
- session_id: Optional[str],
974
- scope: str,
975
- state_delta: dict,
976
- ) -> SessionState:
977
- with self._connection() as connection:
978
- updated_at = time.time()
979
-
980
- if scope == "session":
981
- if not session_id:
982
- raise ValueError("session_id is required for session scope")
983
- session = self._get_session_sync(session_id, connection=connection)
984
- if session is None:
985
- raise ValueError(f"Session {session_id} not found")
986
-
987
- next_state = dict(session.state)
988
- next_state.update(state_delta)
989
- next_version = session.version + 1
990
- connection.execute(
991
- f"""
992
- UPDATE {KSADK_SESSIONS_TABLE}
993
- SET state_json = ?, updated_at = ?, version = ?
994
- WHERE id = ?
995
- """,
996
- (json.dumps(next_state), updated_at, next_version, session_id),
997
- )
998
- connection.execute(
999
- f"""
1000
- INSERT OR REPLACE INTO {KSADK_STATES_TABLE} (
1001
- scope, agent_id, user_id, session_id, state_json, version, updated_at
1002
- )
1003
- VALUES (?, ?, ?, ?, ?, ?, ?)
1004
- """,
1005
- (
1006
- "session",
1007
- session.agent_id,
1008
- session.user_id,
1009
- session.id,
1010
- json.dumps(next_state),
1011
- next_version,
1012
- updated_at,
1013
- ),
1014
- )
1015
- connection.commit()
1016
- return SessionState(
1017
- scope="session",
1018
- agent_id=session.agent_id,
1019
- user_id=session.user_id,
1020
- session_id=session.id,
1021
- state=next_state,
1022
- version=next_version,
1023
- updated_at=updated_at,
1024
- )
1025
-
1026
- row = connection.execute(
1027
- f"""
1028
- SELECT state_json, version
1029
- FROM {KSADK_STATES_TABLE}
1030
- WHERE scope = ? AND agent_id = ? AND user_id = ? AND session_id = ?
1031
- """,
1032
- (scope, agent_id, user_id or "", session_id or ""),
1033
- ).fetchone()
1034
- next_state = json.loads(row["state_json"] or "{}") if row else {}
1035
- next_state.update(state_delta)
1036
- next_version = (int(row["version"] or 0) + 1) if row else 1
1037
-
1038
- connection.execute(
1039
- f"""
1040
- INSERT OR REPLACE INTO {KSADK_STATES_TABLE} (
1041
- scope, agent_id, user_id, session_id, state_json, version, updated_at
1042
- )
1043
- VALUES (?, ?, ?, ?, ?, ?, ?)
1044
- """,
1045
- (
1046
- scope,
1047
- agent_id,
1048
- user_id or "",
1049
- session_id or "",
1050
- json.dumps(next_state),
1051
- next_version,
1052
- updated_at,
1053
- ),
1054
- )
1055
- connection.commit()
1056
- return SessionState(
1057
- scope=scope,
1058
- agent_id=agent_id,
1059
- user_id=user_id or "",
1060
- session_id=session_id or "",
1061
- state=next_state,
1062
- version=next_version,
1063
- updated_at=updated_at,
1064
- )
1065
-
1066
525
 
1067
526
  def create_local_session_service(*, project_dir: Optional[str] = None) -> BaseSessionService:
1068
527
  return LocalSessionService(project_dir=project_dir)