agentengine-sdk-python 0.8.2__py3-none-any.whl → 0.8.4__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 (563) hide show
  1. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +22 -28
  2. agentengine_sdk_python-0.8.4.dist-info/RECORD +1070 -0
  3. ksadk/_build_provenance.json +1 -0
  4. ksadk/agui/_agent_helpers.py +4 -0
  5. ksadk/api/client.py +108 -91
  6. ksadk/builders/code_builder.py +36 -9
  7. ksadk/builders/framework_requirements.py +2 -1
  8. ksadk/builders/ks3_uploader.py +36 -7
  9. ksadk/builders/managed_runtime_builder.py +4 -0
  10. ksadk/cli/__init__.py +38 -3
  11. ksadk/cli/cmd_managed_runtime.py +13 -1
  12. ksadk/cli/cmd_plugin.py +662 -0
  13. ksadk/cli/cmd_web.py +2 -5
  14. ksadk/cli/runtime_bootstrap.py +23 -1
  15. ksadk/codex/client.py +424 -96
  16. ksadk/codex/projection.py +24 -0
  17. ksadk/codex/runtime.py +83 -283
  18. ksadk/common/auth.py +16 -10
  19. ksadk/configs/env_registry.py +59 -3
  20. ksadk/configs/settings.py +9 -0
  21. ksadk/context_engine/contributors.py +73 -8
  22. ksadk/conversations/__init__.py +19 -0
  23. ksadk/conversations/context.py +104 -24
  24. ksadk/conversations/contracts.py +266 -0
  25. ksadk/conversations/message_projection.py +154 -15
  26. ksadk/conversations/projector.py +614 -0
  27. ksadk/conversations/reducer.py +98 -0
  28. ksadk/conversations/runtime_invocation.py +5 -0
  29. ksadk/conversations/runtime_payloads.py +1 -0
  30. ksadk/conversations/runtime_preparation.py +30 -27
  31. ksadk/conversations/runtime_resume.py +50 -2
  32. ksadk/conversations/runtime_stream_events.py +5 -0
  33. ksadk/conversations/runtime_streaming.py +25 -7
  34. ksadk/deployment/env_forward.py +2 -2
  35. ksadk/deployment/providers/serverless.py +1 -1
  36. ksadk/events/_v1_compat/projection.py +2 -0
  37. ksadk/events/adapters/_codex_validators.py +18 -7
  38. ksadk/events/adapters/codex.py +190 -0
  39. ksadk/events/adapters/langgraph.py +15 -1
  40. ksadk/events/canonical_store.py +3 -1
  41. ksadk/events/projections.py +1 -1
  42. ksadk/harness/__init__.py +45 -35
  43. ksadk/harness/config.py +2 -2
  44. ksadk/harness/runtime.py +75 -16
  45. ksadk/harness/tools.py +38 -13
  46. ksadk/interaction/provider.py +1 -0
  47. ksadk/interaction/providers/langgraph.py +1 -0
  48. ksadk/kernel/bootstrap.py +28 -4
  49. ksadk/kernel/contract_fingerprints.py +5 -4
  50. ksadk/kernel/contracts.py +8 -0
  51. ksadk/kernel/control.py +1 -0
  52. ksadk/kernel/ingress.py +36 -2
  53. ksadk/kernel/memory_store.py +1 -0
  54. ksadk/kernel/postgres_store.py +1 -0
  55. ksadk/kernel/sqlite_store.py +28 -0
  56. ksadk/kernel/store.py +3 -0
  57. ksadk/kernel/worker.py +76 -10
  58. ksadk/knowledge_base/client.py +57 -27
  59. ksadk/mcp_runtime/__init__.py +12 -4
  60. ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
  61. ksadk/memory/adk/resilient_session_service.py +25 -17
  62. ksadk/memory/adk/short_term_memory.py +26 -9
  63. ksadk/memory/models.py +7 -4
  64. ksadk/memory/provider_resolver.py +3 -0
  65. ksadk/memory/providers/local_sqlite.py +7 -0
  66. ksadk/model_proxy/server.py +10 -5
  67. ksadk/plugins/__init__.py +171 -0
  68. ksadk/plugins/artifacts.py +275 -0
  69. ksadk/plugins/bridges/__init__.py +47 -0
  70. ksadk/plugins/bridges/codex.py +659 -0
  71. ksadk/plugins/bridges/dsh.py +1300 -0
  72. ksadk/plugins/builtins.py +746 -0
  73. ksadk/plugins/bundle.py +246 -0
  74. ksadk/plugins/bundle_security.py +191 -0
  75. ksadk/plugins/codex_manifest.py +983 -0
  76. ksadk/plugins/composition.py +537 -0
  77. ksadk/plugins/context_contributor.py +437 -0
  78. ksadk/plugins/contracts.py +569 -0
  79. ksadk/plugins/delivery.py +153 -0
  80. ksadk/plugins/dsh_installation_digest.py +71 -0
  81. ksadk/plugins/dsh_toolchain.py +1024 -0
  82. ksadk/plugins/ecosystem_bridge.py +1105 -0
  83. ksadk/plugins/ecosystem_probe.py +191 -0
  84. ksadk/plugins/host.py +787 -0
  85. ksadk/plugins/kernel_adapter.py +205 -0
  86. ksadk/plugins/providers/__init__.py +108 -0
  87. ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
  88. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
  89. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
  90. ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
  91. ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
  92. ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
  93. ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
  94. ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
  95. ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
  96. ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
  97. ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
  98. ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
  99. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -0
  100. ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
  101. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
  102. ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
  103. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/cordis.patch.yml +3 -0
  104. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +870 -0
  105. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
  106. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +92 -0
  107. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +15 -0
  108. ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -0
  109. ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
  110. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
  111. ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
  112. ksadk/plugins/providers/codex.py +988 -0
  113. ksadk/plugins/providers/codex_dsh.py +83 -0
  114. ksadk/plugins/providers/codex_native.py +368 -0
  115. ksadk/plugins/providers/codex_turn.py +301 -0
  116. ksadk/plugins/providers/dsh.py +951 -0
  117. ksadk/plugins/providers/dsh_capabilities.py +1389 -0
  118. ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
  119. ksadk/plugins/providers/dsh_mcp.py +467 -0
  120. ksadk/plugins/providers/harness.py +632 -0
  121. ksadk/plugins/providers/harness_dsh.py +91 -0
  122. ksadk/plugins/providers/legacy.py +215 -0
  123. ksadk/plugins/providers/legacy_catalog.py +100 -0
  124. ksadk/plugins/providers/mcp_projection.py +150 -0
  125. ksadk/plugins/providers/platform_resources.py +657 -0
  126. ksadk/plugins/providers/shipped_dsh.py +370 -0
  127. ksadk/plugins/resolver.py +338 -0
  128. ksadk/plugins/subagent_providers/__init__.py +12 -0
  129. ksadk/plugins/subagent_providers/codex.py +443 -0
  130. ksadk/plugins/subagents.py +333 -0
  131. ksadk/resource_runtime/__init__.py +4 -0
  132. ksadk/resource_runtime/broker.py +616 -0
  133. ksadk/resource_runtime/build_artifacts.py +165 -0
  134. ksadk/resource_runtime/contracts.py +138 -0
  135. ksadk/resource_runtime/discovery_receipts.py +100 -0
  136. ksadk/resource_runtime/discovery_skills.py +172 -0
  137. ksadk/resource_runtime/errors.py +6 -0
  138. ksadk/resource_runtime/ipc.py +142 -0
  139. ksadk/resource_runtime/kernel_approval.py +165 -0
  140. ksadk/resource_runtime/knowledge.py +114 -0
  141. ksadk/resource_runtime/langgraph.py +94 -0
  142. ksadk/resource_runtime/leases.py +191 -0
  143. ksadk/resource_runtime/managed_projection.py +186 -0
  144. ksadk/resource_runtime/mcp_server.py +138 -0
  145. ksadk/resource_runtime/memory_provider.py +318 -0
  146. ksadk/resource_runtime/memory_receipts.py +34 -0
  147. ksadk/resource_runtime/operation_ledger.py +211 -0
  148. ksadk/resource_runtime/plugin_config.py +48 -0
  149. ksadk/resource_runtime/policy_authorization.py +54 -0
  150. ksadk/resource_runtime/process.py +110 -0
  151. ksadk/resource_runtime/skill_artifacts.py +153 -0
  152. ksadk/resource_runtime/skill_runtime.py +42 -0
  153. ksadk/resource_runtime/skill_workspace.py +118 -0
  154. ksadk/resource_runtime/skills.py +215 -0
  155. ksadk/resource_runtime/snapshots.py +180 -0
  156. ksadk/resource_runtime/socket_server.py +103 -0
  157. ksadk/resource_runtime/supervisor.py +380 -0
  158. ksadk/resource_runtime/worker.py +504 -0
  159. ksadk/runners/_langgraph_runner_streams.py +74 -6
  160. ksadk/runners/adk_runner.py +149 -11
  161. ksadk/runners/base_runner.py +29 -1
  162. ksadk/runners/langgraph_runner.py +475 -145
  163. ksadk/runtime/_runner_adapter/stream_mapping.py +193 -60
  164. ksadk/runtime/adapter.py +3 -0
  165. ksadk/runtime/conversation_execution.py +92 -16
  166. ksadk/runtime/executor.py +78 -2
  167. ksadk/runtime/factory.py +30 -200
  168. ksadk/runtime/framework_adapters.py +41 -0
  169. ksadk/runtime/preprocessing.py +10 -2
  170. ksadk/runtime/runner_adapter.py +78 -14
  171. ksadk/runtime_context.py +40 -2
  172. ksadk/sandbox/__init__.py +2 -1
  173. ksadk/sandbox/backends/e2b.py +52 -11
  174. ksadk/sandbox/backends/local_process.py +9 -0
  175. ksadk/sandbox/base.py +2 -0
  176. ksadk/sandbox/e2b_connection.py +66 -0
  177. ksadk/sandbox/factory.py +72 -0
  178. ksadk/scheduler/__init__.py +18 -0
  179. ksadk/scheduler/calendar.py +102 -0
  180. ksadk/scheduler/contracts.py +254 -0
  181. ksadk/scheduler/dispatcher.py +129 -0
  182. ksadk/scheduler/engine.py +416 -0
  183. ksadk/scheduler/sqlite_store.py +581 -0
  184. ksadk/server/composition.py +2 -0
  185. ksadk/server/factory.py +5 -0
  186. ksadk/server/persistence_capability.py +516 -0
  187. ksadk/server/routes/control.py +210 -46
  188. ksadk/server/routes/dependencies.py +15 -0
  189. ksadk/server/routes/models.py +47 -4
  190. ksadk/server/routes/projection.py +252 -12
  191. ksadk/server/routes/sessions.py +284 -107
  192. ksadk/server/routes/streaming.py +43 -9
  193. ksadk/server/static/assets/{ArtifactsPanel-DSU1sWD_.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
  194. ksadk/server/static/assets/{CodeBlock-DOH6MVcn.js → CodeBlock-b4C7upmO.js} +3 -3
  195. ksadk/server/static/assets/{MathMessageMarkdown-BL8my1R2.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
  196. ksadk/server/static/assets/{MermaidBlock-Dz4IP-Tx.js → MermaidBlock-BEBN4Ksz.js} +6 -6
  197. ksadk/server/static/assets/{NativeTerminalPanel-DUrK0JpZ.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
  198. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-g20pFzNV.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
  199. ksadk/server/static/assets/{arc-C4FzinUA.js → arc-bTohInsS.js} +1 -1
  200. ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
  201. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-DpIqL5h4.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
  202. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-BjkljTNz.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
  203. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-Dk_ieq2X.js → c4Diagram-UCG6FXSJ-8uSRIODv.js} +1 -1
  204. ksadk/server/static/assets/channel-CF5Up3hQ.js +1 -0
  205. ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +1 -0
  206. ksadk/server/static/assets/{chunk-5VM5RSS4-BVHAchFb.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
  207. ksadk/server/static/assets/{chunk-F27PBJKO-C-ipQzuS.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
  208. ksadk/server/static/assets/{chunk-G27WJ6UU-C2EyJbIK.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
  209. ksadk/server/static/assets/{chunk-JWPE2WC7-vYvVJb_M.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
  210. ksadk/server/static/assets/{chunk-LCL6LL3I-BcI6ysPT.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
  211. ksadk/server/static/assets/{chunk-POPQ4Y6H-C030x_Z1.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
  212. ksadk/server/static/assets/{chunk-RHFEMEQ7-yyGpsz4n.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
  213. ksadk/server/static/assets/{chunk-SVP7TREG-BLTlmMU7.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
  214. ksadk/server/static/assets/{chunk-XXDRQBXY-C_32ArgP.js → chunk-XXDRQBXY-DVaeafZk.js} +1 -1
  215. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +1 -0
  216. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +1 -0
  217. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-9YQYwdl0.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
  218. ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
  219. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-ErLF5N13.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
  220. ksadk/server/static/assets/{dagre-3AP2YEHR-DFiQF-6f.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
  221. ksadk/server/static/assets/{dagre-BuhGnRI1.js → dagre-UBpgon5q.js} +1 -1
  222. ksadk/server/static/assets/{diagram-S7CK7UJ4-Bt1v8-GC.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
  223. ksadk/server/static/assets/{diagram-UQ7AKVKN-DSCxJdBK.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
  224. ksadk/server/static/assets/{diagram-VSXAHHWV-DHfYwp_9.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
  225. ksadk/server/static/assets/{diagram-VX7I27RA-DdzD-4Le.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
  226. ksadk/server/static/assets/{diagram-Z3DM3KII-Du-nAJ9F.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
  227. ksadk/server/static/assets/{dist-B7seoj3d.js → dist-B2_CVgKv.js} +1 -1
  228. ksadk/server/static/assets/{dist-CSh_DE14.js → dist-B3FR1SKK.js} +1 -1
  229. ksadk/server/static/assets/{dist-DUX-id_F.js → dist-BIr4DSRq.js} +1 -1
  230. ksadk/server/static/assets/{dist-C_wsv-Qd.js → dist-BgV_owcB.js} +1 -1
  231. ksadk/server/static/assets/{dist-W-TIVntx.js → dist-Bj730Ib4.js} +1 -1
  232. ksadk/server/static/assets/{dist-BytlxIDT.js → dist-BnaTiyzN.js} +1 -1
  233. ksadk/server/static/assets/{dist-CXYYBw3_.js → dist-C1NMAY5a.js} +1 -1
  234. ksadk/server/static/assets/{dist-dDdADKFA.js → dist-C5_ZAZsG.js} +1 -1
  235. ksadk/server/static/assets/{dist-BVDffZ0U.js → dist-CB9iJrvg.js} +1 -1
  236. ksadk/server/static/assets/{dist-Bf2M8m3N.js → dist-CFzsn6BG.js} +1 -1
  237. ksadk/server/static/assets/{dist-ngtN0DJB.js → dist-Cf125P_m.js} +1 -1
  238. ksadk/server/static/assets/{dist-BE7bu-DL.js → dist-ClYUxfeK.js} +1 -1
  239. ksadk/server/static/assets/{dist-DNp6rLRA.js → dist-DFD6Qa6T.js} +1 -1
  240. ksadk/server/static/assets/{dist-BX8z72IC.js → dist-DVCOWtha.js} +1 -1
  241. ksadk/server/static/assets/{dist-dydu68Fl.js → dist-D_ctSS2i.js} +1 -1
  242. ksadk/server/static/assets/{dist-ClxGviKw.js → dist-DiixqL0J.js} +1 -1
  243. ksadk/server/static/assets/{dist-BjU6y-A2.js → dist-DoVSwoDb.js} +1 -1
  244. ksadk/server/static/assets/{dist-Dq9gLD7L.js → dist-DvFK7p5S.js} +1 -1
  245. ksadk/server/static/assets/{dist-8hqcx0sU.js → dist-QfkEHOlb.js} +1 -1
  246. ksadk/server/static/assets/{dist-CttYUqzS.js → dist-btbmmX5O.js} +1 -1
  247. ksadk/server/static/assets/{dist-DmldrHd_.js → dist-fBO2v5Kt.js} +1 -1
  248. ksadk/server/static/assets/{dist-DnfXs8Vn.js → dist-ufY3F5p6.js} +1 -1
  249. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Da9C9NO1.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
  250. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-EAGqqR79.js → erDiagram-SSCWMZ5O-CCIOhLZG.js} +1 -1
  251. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +1 -0
  252. ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +1 -0
  253. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-DqJsKb59.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
  254. ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
  255. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-B6g4dtDi.js → gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js} +1 -1
  256. ksadk/server/static/assets/index-DcTML1Up.css +2 -0
  257. ksadk/server/static/assets/index-Dh2XHqPK.js +244 -0
  258. ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +1 -0
  259. ksadk/server/static/assets/{infoDiagram-RXCK75RN-Djm_nbd5.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
  260. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-DWya9SG2.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
  261. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DutxhSNI.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
  262. ksadk/server/static/assets/{kanban-definition-3QL26DDD-DJdOF8Fm.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
  263. ksadk/server/static/assets/{katex-vFWytM5c.js → katex-B4weu383.js} +1 -1
  264. ksadk/server/static/assets/{linear-BHjG8b-J.js → linear-V-MgYHW1.js} +1 -1
  265. ksadk/server/static/assets/{mermaid-parser.core-KGSy4jWT.js → mermaid-parser.core-CBijEX_c.js} +2 -2
  266. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-9-HC88D4.js → mindmap-definition-FBJOCRG2-Bc-pQvpp.js} +1 -1
  267. ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +1 -0
  268. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-DrEZd4fD.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
  269. ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
  270. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-DpjqOFFp.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
  271. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BiNhgOXX.js → quadrantDiagram-AXDQQJYC-BURv2mGh.js} +1 -1
  272. ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +1 -0
  273. ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +1 -0
  274. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +1 -0
  275. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +1 -0
  276. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +1 -0
  277. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-_Y3Ojg6G.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
  278. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-DeCFdg9K.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
  279. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-CPH75rhw.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
  280. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-OEpQQdr4.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
  281. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-heUErzhI.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
  282. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DvA3jSMB.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
  283. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
  284. ksadk/server/static/assets/{swimlanes-XN3QIQJK-CR-dfN_t.js → swimlanes-XN3QIQJK-Cssf_CsU.js} +1 -1
  285. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +8 -0
  286. ksadk/server/static/assets/{timeline-definition-24CTP7MA-DAVJf1TX.js → timeline-definition-24CTP7MA-BWTHzyS1.js} +1 -1
  287. ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +1 -0
  288. ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +1 -0
  289. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-DwM8eDkh.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
  290. ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
  291. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DZL-Zz2t.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
  292. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js → xychartDiagram-S5SC5T6Z-eYqrQ-v4.js} +1 -1
  293. ksadk/server/static/index.html +2 -2
  294. ksadk/session_context.py +66 -0
  295. ksadk/sessions/__init__.py +11 -21
  296. ksadk/sessions/_local_service_sync.py +263 -1
  297. ksadk/sessions/base.py +176 -0
  298. ksadk/sessions/errors.py +4 -0
  299. ksadk/sessions/in_memory.py +309 -19
  300. ksadk/sessions/local_service.py +83 -1
  301. ksadk/sessions/persistence.py +275 -0
  302. ksadk/sessions/postgres_service.py +358 -0
  303. ksadk/sessions/resilience.py +8 -0
  304. ksadk/sessions/resilient.py +362 -4
  305. ksadk/sessions/topology.py +135 -0
  306. ksadk/skills/models.py +26 -4
  307. ksadk/skills/package_store.py +186 -38
  308. ksadk/skills/runtime/agent.py +31 -6
  309. ksadk/skills/runtime/artifact_delivery.py +139 -0
  310. ksadk/skills/runtime/backends/e2b.py +98 -6
  311. ksadk/skills/runtime/backends/local.py +73 -8
  312. ksadk/skills/runtime/base.py +3 -0
  313. ksadk/skills/runtime/executor.py +2 -0
  314. ksadk/skills/runtime/loader.py +10 -2
  315. ksadk/skills/runtime/pinned.py +114 -0
  316. ksadk/skills/runtime/request.py +31 -0
  317. ksadk/skills/service_client.py +211 -24
  318. ksadk/studio/agent_lifecycle.py +26 -20
  319. ksadk/studio/api.py +714 -90
  320. ksadk/studio/api_catalog_routes.py +23 -0
  321. ksadk/studio/api_contracts.py +34 -1
  322. ksadk/studio/api_plugin_routes.py +911 -0
  323. ksadk/studio/api_resource_connections.py +183 -0
  324. ksadk/studio/attachment_store.py +187 -0
  325. ksadk/studio/authoring.py +10 -4
  326. ksadk/studio/authoring_coordinator.py +31 -16
  327. ksadk/studio/builder.py +199 -43
  328. ksadk/studio/cloud.py +346 -104
  329. ksadk/studio/cloud_shared_web.py +565 -0
  330. ksadk/studio/codex_agent_service.py +140 -27
  331. ksadk/studio/codex_builder.py +294 -16
  332. ksadk/studio/codex_credentials.py +90 -0
  333. ksadk/studio/codex_manifest.py +51 -4
  334. ksadk/studio/codex_plugin_store.py +746 -0
  335. ksadk/studio/codex_provider_build.py +231 -0
  336. ksadk/studio/codex_run.py +200 -29
  337. ksadk/studio/compatibility_report.py +456 -0
  338. ksadk/studio/compiler.py +84 -15
  339. ksadk/studio/contracts.py +249 -4
  340. ksadk/studio/dsh_application.py +137 -0
  341. ksadk/studio/dsh_capability_service.py +1107 -0
  342. ksadk/studio/dsh_models.py +59 -0
  343. ksadk/studio/dsh_provider_registration.py +1075 -0
  344. ksadk/studio/event_store.py +54 -6
  345. ksadk/studio/framework_run.py +37 -4
  346. ksadk/studio/hosted_kernel.py +89 -14
  347. ksadk/studio/mcp_runtime.py +11 -3
  348. ksadk/studio/model_client.py +2 -2
  349. ksadk/studio/operations.py +12 -2
  350. ksadk/studio/plugin_composition.py +468 -0
  351. ksadk/studio/plugin_kernel_adapter.py +28 -0
  352. ksadk/studio/plugin_runtime.py +831 -0
  353. ksadk/studio/resource_authority.py +637 -0
  354. ksadk/studio/resource_binding_validation.py +77 -0
  355. ksadk/studio/resource_build_admission.py +196 -0
  356. ksadk/studio/resource_build_materializer.py +149 -0
  357. ksadk/studio/resource_catalog.py +149 -3
  358. ksadk/studio/resource_connections.py +220 -0
  359. ksadk/studio/run_service.py +1144 -96
  360. ksadk/studio/runtime_source.py +24 -8
  361. ksadk/studio/scheduler_assistant.py +317 -0
  362. ksadk/studio/scheduler_runtime.py +383 -0
  363. ksadk/studio/scheduler_service.py +214 -0
  364. ksadk/studio/service.py +1131 -95
  365. ksadk/studio/shared_web.py +610 -87
  366. ksadk/studio/soul.py +52 -0
  367. ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +41 -0
  368. ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  369. ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  370. ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  371. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  372. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  373. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  374. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  375. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  376. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  377. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  378. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  379. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  380. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  381. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  382. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  383. ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  384. ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  385. ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  386. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  387. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  388. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  389. ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  390. ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  391. ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  392. ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  393. ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  394. ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  395. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  396. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  397. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  398. ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  399. ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  400. ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  401. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  402. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  403. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  404. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  405. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  406. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  407. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  408. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  409. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  410. ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  411. ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  412. ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  413. ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  414. ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  415. ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  416. ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  417. ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  418. ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  419. ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  420. ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  421. ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  422. ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  423. ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  424. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  425. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  426. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  427. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--BEOyPC3w.css +1 -0
  428. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +8 -0
  429. ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +44 -0
  430. ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +3 -0
  431. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +1 -0
  432. ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
  433. ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +1 -0
  434. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +36 -0
  435. ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
  436. ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CFmPl1de.js +129 -0
  437. ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BRrGu8qt.js +38 -0
  438. ksadk/studio/static/assets/channel-BqO-gtEw.js +1 -0
  439. ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  440. ksadk/studio/static/assets/chunk-4HAMMTFA-D220vUtq.js +62 -0
  441. ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  442. ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +2 -0
  443. ksadk/studio/static/assets/chunk-DU6HZSFF-C4DtVpCu.js +128 -0
  444. ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +1 -0
  445. ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
  446. ksadk/studio/static/assets/chunk-GMAD6QVW-DiQA-u2N.js +72 -0
  447. ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +1 -0
  448. ksadk/studio/static/assets/chunk-IMKFNOWR-BSlbjT_b.js +231 -0
  449. ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  450. ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +1 -0
  451. ksadk/studio/static/assets/chunk-OSK3NFVY-M2m6G3j4.js +10 -0
  452. ksadk/studio/static/assets/chunk-P2QGCYS3-DezaQxiK.js +1 -0
  453. ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +1 -0
  454. ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +1 -0
  455. ksadk/studio/static/assets/chunk-SHT3W25Y-DAyIVp5H.js +168 -0
  456. ksadk/studio/static/assets/chunk-SVP7TREG-DulomOrS.js +88 -0
  457. ksadk/studio/static/assets/chunk-TICWLB2K-bHJYoflj.js +206 -0
  458. ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +1 -0
  459. ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  460. ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +1 -0
  461. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +1 -0
  462. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +1 -0
  463. ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +1 -0
  464. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +62 -0
  465. ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
  466. ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +4 -0
  467. ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
  468. ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
  469. ksadk/studio/static/assets/diagram-S7CK7UJ4-0BZ98mya.js +30 -0
  470. ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +41 -0
  471. ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +3 -0
  472. ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +24 -0
  473. ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +24 -0
  474. ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
  475. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +1 -0
  476. ksadk/studio/static/assets/erDiagram-RLTQ6QDP-DLGry2Ap.js +99 -0
  477. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +1 -0
  478. ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +1 -0
  479. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +292 -0
  480. ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +1 -0
  481. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +106 -0
  482. ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
  483. ksadk/studio/static/assets/index-CeHL9ARV.css +2 -0
  484. ksadk/studio/static/assets/index-D9QEcVpL.js +320 -0
  485. ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +1 -0
  486. ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +2 -0
  487. ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
  488. ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-CljI2wyf.js +70 -0
  489. ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-D50Fo2sL.js +139 -0
  490. ksadk/studio/static/assets/kanban-definition-UXKFOSKX-DimfOTam.js +89 -0
  491. ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
  492. ksadk/studio/static/assets/line-CX5BOOUP.js +1 -0
  493. ksadk/studio/static/assets/linear-BCxN9JLv.js +1 -0
  494. ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +7 -0
  495. ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-Bizzqy5R.js +96 -0
  496. ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
  497. ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +1 -0
  498. ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
  499. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +1 -0
  500. ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +1 -0
  501. ksadk/studio/static/assets/pieDiagram-E7YTZNPT-B9mrFSDF.js +39 -0
  502. ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-NzUfCbMR.js +7 -0
  503. ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +1 -0
  504. ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +1 -0
  505. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +1 -0
  506. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +1 -0
  507. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +1 -0
  508. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +1 -0
  509. ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-BF3d103U.js +84 -0
  510. ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
  511. ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
  512. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +40 -0
  513. ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js +162 -0
  514. ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  515. ksadk/studio/static/assets/src-SFn9St9H.js +1 -0
  516. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +1 -0
  517. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +1 -0
  518. ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +1 -0
  519. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +8 -0
  520. ksadk/studio/static/assets/timeline-definition-24CTP7MA-DxmSSjRB.js +120 -0
  521. ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +1 -0
  522. ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +1 -0
  523. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +34 -0
  524. ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +1 -0
  525. ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-Ba1AOWoe.js +78 -0
  526. ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js +7 -0
  527. ksadk/studio/static/index.html +2 -2
  528. ksadk/studio/validator.py +1 -1
  529. ksadk/studio/workspace.py +1 -0
  530. ksadk/version.py +1 -1
  531. ksadk_runtime_common/workspace_files/path_utils.py +41 -0
  532. agentengine_sdk_python-0.8.2.dist-info/RECORD +0 -778
  533. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +0 -1
  534. ksadk/server/static/assets/channel-4cQHKtx1.js +0 -1
  535. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +0 -1
  536. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +0 -1
  537. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +0 -1
  538. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +0 -1
  539. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +0 -1
  540. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +0 -1
  541. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +0 -1
  542. ksadk/server/static/assets/index-8ipRcQ-M.js +0 -240
  543. ksadk/server/static/assets/index-ByFCqjlh.css +0 -2
  544. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +0 -1
  545. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +0 -1
  546. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +0 -1
  547. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +0 -1
  548. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +0 -1
  549. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +0 -1
  550. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +0 -1
  551. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +0 -1
  552. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +0 -1
  553. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +0 -8
  554. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +0 -1
  555. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +0 -1
  556. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +0 -1
  557. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
  558. ksadk/studio/static/assets/index-BLpcdrgW.css +0 -1
  559. ksadk/studio/static/assets/index-CYekR2Xv.js +0 -260
  560. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
  561. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
  562. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
  563. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
@@ -52,7 +52,8 @@ DEFAULT_SCENE_ID = "_sys_general"
52
52
  # "记忆不存在"识别模式(方案 §17.4:准确错误码待真实 fixture 固化,
53
53
  # 首版按保守中英文模式匹配,fixture 到位后收敛为精确匹配)。
54
54
  _NOT_EXIST_RE = re.compile(
55
- r"not[ _]?exist|does not exist|memory.*不存在|记忆不存在|记忆已被删除|resourcenotfound|notfound",
55
+ r"not[ _]?exist|does not exist|memory.*不存在|记忆不存在|记忆已被删除|"
56
+ r"resourcenotfound|notfound",
56
57
  re.IGNORECASE,
57
58
  )
58
59
 
@@ -98,6 +99,7 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
98
99
  agent_id: str = ""
99
100
  scene_id: str = DEFAULT_SCENE_ID
100
101
  last_error: str = ""
102
+ last_http_status: int | None = None
101
103
  last_create_response: dict[str, Any] = Field(default_factory=dict)
102
104
  last_session_status: dict[str, Any] = Field(default_factory=dict)
103
105
 
@@ -176,7 +178,16 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
176
178
  client_profile = ClientProfile()
177
179
  client_profile.httpProfile = http_profile
178
180
 
179
- self._aicp_client = aicp_module.AicpClient(cred, self.region, profile=client_profile)
181
+ owner = self
182
+
183
+ class ObservedAicpClient(aicp_module.AicpClient):
184
+ def _check_status(self, response):
185
+ # Preserve the status that the upstream SDK's generic exception
186
+ # otherwise discards. No response content is used as authority.
187
+ owner.last_http_status = response.status
188
+ return super()._check_status(response)
189
+
190
+ self._aicp_client = ObservedAicpClient(cred, self.region, profile=client_profile)
180
191
 
181
192
  # 强制覆写 API 版本为记忆库 API 所需的 2025-11-14
182
193
  self._aicp_client._apiVersion = "2025-11-14"
@@ -246,6 +257,7 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
246
257
 
247
258
  try:
248
259
  self.last_error = ""
260
+ self.last_create_response = {}
249
261
  conversation = self._build_conversation(event_strings)
250
262
  if not conversation:
251
263
  logger.info("No valid conversation items to save")
@@ -278,6 +290,11 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
278
290
 
279
291
  response = client.call("CreateMemorySdk", params, options={"IsPostJson": True})
280
292
  self.last_create_response = self._parse_json_response(response) or {}
293
+ if kwargs.get("strict", False):
294
+ data = self.last_create_response
295
+ if not self._confirmed_mutation_response(data):
296
+ self.last_error = "MEMORY_WRITE_RESPONSE_UNKNOWN"
297
+ return False
281
298
  self.last_session_status = {
282
299
  "SessionId": session_id,
283
300
  "AgentUserId": user_id,
@@ -290,8 +307,8 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
290
307
  return True
291
308
 
292
309
  except Exception as e:
293
- self.last_error = str(e)
294
- logger.error(f"CreateMemorySdk failed: {e}")
310
+ self.last_error = "MEMORY_WRITE_UNKNOWN" if kwargs.get("strict", False) else str(e)
311
+ logger.error("CreateMemorySdk did not return a confirmed acknowledgment")
295
312
  return False
296
313
 
297
314
  def search_memory(self, user_id: str, query: str, top_k: int = 5, **kwargs) -> list[str]:
@@ -379,7 +396,9 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
379
396
  "SceneId": self._effective_scene_id(),
380
397
  }
381
398
  response = client.call("QueryMemorySdk", params, options={"IsPostJson": True})
382
- records = self._parse_query_records_response(response, user_id=user_id)
399
+ records = self._parse_query_records_response(
400
+ response, user_id=user_id, strict=kwargs.get("strict", False)
401
+ )
383
402
  logger.info(
384
403
  f"QueryMemorySdk structured: user={user_id}, records={len(records)}"
385
404
  )
@@ -452,9 +471,16 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
452
471
  )
453
472
 
454
473
  data = self._parse_json_response(response)
474
+ if kwargs.get("strict", False) and not self._confirmed_mutation_response(data):
475
+ return MemoryMutationResult(
476
+ ok=False, memory_id=memory_id, status="failed",
477
+ message="记忆更新结果未确认",
478
+ )
455
479
  response_memory_id = self._parse_new_memory_id(data)
456
480
  new_memory_id = response_memory_id
457
- if not response_memory_id or response_memory_id == memory_id:
481
+ if not kwargs.get("strict", False) and (
482
+ not response_memory_id or response_memory_id == memory_id
483
+ ):
458
484
  # The service can merge an edited memory into another record while
459
485
  # returning no new ID (or echoing the old one). Do not expose that
460
486
  # stale handle to callers: confirm the current handle by listing
@@ -512,7 +538,7 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
512
538
  "AgentUserId": user_id,
513
539
  }
514
540
  try:
515
- client.call("DeleteMemory", params, options={"IsPostJson": True})
541
+ response = client.call("DeleteMemory", params, options={"IsPostJson": True})
516
542
  except Exception as exc:
517
543
  if self._is_not_exist_error(exc):
518
544
  return MemoryMutationResult(
@@ -529,6 +555,13 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
529
555
  status="failed",
530
556
  message="记忆删除失败",
531
557
  )
558
+ if kwargs.get("strict", False) and not self._confirmed_mutation_response(
559
+ self._parse_json_response(response)
560
+ ):
561
+ return MemoryMutationResult(
562
+ ok=False, memory_id=memory_id, status="failed",
563
+ message="记忆删除结果未确认",
564
+ )
532
565
  return MemoryMutationResult(
533
566
  ok=True,
534
567
  memory_id=memory_id,
@@ -536,6 +569,19 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
536
569
  message="已删除",
537
570
  )
538
571
 
572
+ @staticmethod
573
+ def _confirmed_mutation_response(data: Any) -> bool:
574
+ metadata = data.get("ResponseMetadata", {}) if isinstance(data, dict) else {}
575
+ return bool(
576
+ isinstance(data, dict) and isinstance(metadata, dict)
577
+ and not data.get("Error") and not metadata.get("Error")
578
+ and ("Success" not in data or data["Success"] is True)
579
+ and type(data.get("Code")) is not bool
580
+ and data.get("Code") in (None, 0, "0", 200, "200")
581
+ and isinstance(data.get("RequestId", metadata.get("RequestId")), str)
582
+ and data.get("RequestId", metadata.get("RequestId"))
583
+ )
584
+
539
585
  def get_extraction_status(
540
586
  self,
541
587
  *,
@@ -547,16 +593,21 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
547
593
  State 映射 0/50/100/-50/-100;未找到 Session 返回 unknown。
548
594
  searchable 需 Service 层结合 ListMemories 确认后置位。
549
595
  """
550
- item = self.get_session_status(user_id=user_id, session_id=session_id)
596
+ item, error_code = self._lookup_session_status(user_id=user_id, session_id=session_id)
551
597
  if not isinstance(item, dict):
552
598
  return MemoryExtractionStatus(
553
599
  session_id=session_id,
554
600
  state=None,
555
601
  status="unknown",
556
- message="Session 状态未知",
602
+ message="Session 状态查询未完成" if error_code else "Session 状态未知",
603
+ error_code=error_code,
557
604
  )
558
605
  state = item.get("State")
559
- state_int = int(state) if isinstance(state, (int, float, str)) and str(state).lstrip("-").isdigit() else None
606
+ state_int = (
607
+ int(state)
608
+ if isinstance(state, (int, float, str)) and str(state).lstrip("-").isdigit()
609
+ else None
610
+ )
560
611
  status = map_session_state(state_int)
561
612
  message = {
562
613
  "queued": "排队中",
@@ -617,19 +668,29 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
617
668
  return ""
618
669
 
619
670
  def _parse_query_records_response(
620
- self, response: Any, *, user_id: str
671
+ self, response: Any, *, user_id: str, strict: bool = False
621
672
  ) -> List[LongTermMemoryRecord]:
622
673
  """严格解析 QueryMemorySdk 结构化响应:Data[].Memories[]。"""
623
674
  try:
624
675
  data = self._parse_json_response(response)
625
676
  except (json.JSONDecodeError, TypeError):
677
+ if strict:
678
+ raise ValueError("MEMORY_SEARCH_RESPONSE_INVALID") from None
626
679
  logger.error("QueryMemorySdk records: invalid JSON response")
627
680
  return []
628
681
  if not isinstance(data, dict):
682
+ if strict:
683
+ raise ValueError("MEMORY_SEARCH_RESPONSE_INVALID")
629
684
  logger.error("QueryMemorySdk records: unexpected payload type")
630
685
  return []
631
686
  items = data.get("Data")
687
+ if strict and (
688
+ data.get("Error") or data.get("Code") not in (None, 0, "0", 200, "200")
689
+ ):
690
+ raise ValueError("MEMORY_SEARCH_RESPONSE_INVALID")
632
691
  if not isinstance(items, list):
692
+ if strict:
693
+ raise ValueError("MEMORY_SEARCH_RESPONSE_INVALID")
633
694
  logger.warning(
634
695
  "QueryMemorySdk records: unknown schema, keys=%s; fail closed",
635
696
  list(data.keys()),
@@ -639,11 +700,15 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
639
700
  for item in items:
640
701
  memories = item.get("Memories") if isinstance(item, dict) else None
641
702
  if not isinstance(memories, list):
703
+ if strict:
704
+ raise ValueError("MEMORY_SEARCH_RESPONSE_INVALID")
642
705
  continue
643
706
  for memory in memories:
644
707
  record = self._record_from_item(memory, user_id=user_id)
645
708
  if record is not None:
646
709
  records.append(record)
710
+ elif strict:
711
+ raise ValueError("MEMORY_SEARCH_RESPONSE_INVALID")
647
712
  return records
648
713
 
649
714
  def _parse_list_memories_response(
@@ -717,38 +782,93 @@ class SdkLTMBackend(BaseLongTermMemoryBackend):
717
782
  user_id: str,
718
783
  session_id: str,
719
784
  page_size: int = 20,
785
+ max_pages: int = 20,
720
786
  ) -> dict[str, Any] | None:
721
- """Return raw AICP session status for a recently submitted memory session."""
722
- if not session_id:
723
- return None
724
-
725
- client = self._get_client()
726
- memory_collection_id = self._effective_memory_collection_id()
727
- params = {
728
- "MemoryCollectionId": memory_collection_id,
729
- "AgentUserId": user_id,
730
- "Page": 1,
731
- "PageSize": page_size,
732
- }
733
-
787
+ """Look up a session across bounded pages; preserve legacy raw return shape."""
788
+ item, error_code = self._lookup_session_status(
789
+ user_id=user_id, session_id=session_id, page_size=page_size, max_pages=max_pages
790
+ )
791
+ self.last_error = error_code
792
+ self.last_session_status = dict(item or {})
793
+ return item
794
+
795
+ def _lookup_session_status(
796
+ self, *, user_id: str, session_id: str, page_size: int = 20, max_pages: int = 20
797
+ ) -> tuple[dict[str, Any] | None, str]:
798
+ if (type(page_size) is not int or not 1 <= page_size <= 100
799
+ or type(max_pages) is not int or not 1 <= max_pages <= 1000):
800
+ raise ValueError("Invalid memory status pagination budget")
801
+ if not user_id or not session_id:
802
+ return None, "MEMORY_STATUS_IDENTITY_REQUIRED"
803
+ seen: set[str] = set()
804
+ previous_total = None
734
805
  try:
735
- response = client.call("ListSessions", params, options={"IsPostJson": True})
736
- data = self._parse_json_response(response)
737
- except Exception as e:
738
- self.last_error = str(e)
739
- logger.warning(f"ListSessions failed while checking memory status: {e}")
740
- return None
741
-
742
- payload = data.get("Data") if isinstance(data, dict) else None
743
- items = payload.get("Items") if isinstance(payload, dict) else None
744
- if not isinstance(items, list):
745
- return None
746
-
747
- for item in items:
748
- if isinstance(item, dict) and item.get("SessionId") == session_id:
749
- self.last_session_status = item
750
- return item
751
- return None
806
+ client = self._get_client()
807
+ collection = self._effective_memory_collection_id()
808
+ for page in range(1, max_pages + 1):
809
+ response = client.call("ListSessions", {
810
+ "MemoryCollectionId": collection, "AgentUserId": user_id,
811
+ "Page": page, "PageSize": page_size,
812
+ }, options={"IsPostJson": True})
813
+ data = self._parse_json_response(response)
814
+ metadata = data.get("ResponseMetadata", {}) if isinstance(data, dict) else {}
815
+ if (
816
+ not isinstance(data, dict) or data.get("Error")
817
+ or not isinstance(metadata, dict) or metadata.get("Error")
818
+ or type(data.get("Code")) is bool
819
+ or data.get("Code") not in (None, 0, "0", 200, "200")
820
+ ):
821
+ return None, "MEMORY_STATUS_QUERY_FAILED"
822
+ payload = data.get("Data")
823
+ items = payload.get("Items") if isinstance(payload, dict) else None
824
+ if not isinstance(items, list) or len(items) > page_size or any(
825
+ not isinstance(item, dict) or not isinstance(item.get("SessionId"), str)
826
+ or not item["SessionId"] for item in items
827
+ ):
828
+ return None, "MEMORY_STATUS_RESPONSE_INVALID"
829
+ total_count = payload.get("TotalCount")
830
+ total_alias = payload.get("Total")
831
+ if total_count is not None and total_alias is not None:
832
+ normalized_count = (
833
+ int(total_count)
834
+ if isinstance(total_count, str) and total_count.isdigit()
835
+ else total_count
836
+ )
837
+ normalized_alias = (
838
+ int(total_alias)
839
+ if isinstance(total_alias, str) and total_alias.isdigit()
840
+ else total_alias
841
+ )
842
+ if normalized_count != normalized_alias:
843
+ return None, "MEMORY_STATUS_RESPONSE_INVALID"
844
+ total = total_count if total_count is not None else total_alias
845
+ if isinstance(total, str) and total.isdigit():
846
+ total = int(total)
847
+ if total is not None and (type(total) is not int or total < 0):
848
+ return None, "MEMORY_STATUS_RESPONSE_INVALID"
849
+ if page > 1 and total != previous_total:
850
+ return None, "MEMORY_STATUS_DIRECTORY_CHANGED"
851
+ previous_total = total
852
+ ids = [item["SessionId"] for item in items]
853
+ if len(set(ids)) != len(ids) or seen.intersection(ids):
854
+ return None, "MEMORY_STATUS_PAGINATION_REPEATED"
855
+ seen.update(ids)
856
+ for item in items:
857
+ if item["SessionId"] == session_id:
858
+ if (
859
+ item.get("AgentUserId", user_id) != user_id
860
+ or item.get("MemoryCollectionId", collection) != collection
861
+ ):
862
+ return None, "MEMORY_STATUS_SCOPE_MISMATCH"
863
+ return dict(item), ""
864
+ if total is not None and len(seen) >= total:
865
+ return None, "" if len(seen) == total else "MEMORY_STATUS_DIRECTORY_CHANGED"
866
+ if len(items) < page_size:
867
+ return None, "" if total is None else "MEMORY_STATUS_DIRECTORY_INCOMPLETE"
868
+ return None, "MEMORY_STATUS_PAGE_BUDGET_EXHAUSTED"
869
+ except Exception:
870
+ logger.warning("ListSessions status query failed")
871
+ return None, "MEMORY_STATUS_QUERY_FAILED"
752
872
 
753
873
  def _parse_query_response(self, response: str) -> list[str]:
754
874
  """解析 QueryMemorySdk 响应
@@ -38,11 +38,11 @@ class ResilientADKSessionService(BaseSessionService):
38
38
  return
39
39
  self._primary_enabled = False
40
40
  logger.error(
41
- "ADK session persistence degraded; using in-memory live session: %s",
42
- exc,
41
+ "ADK session persistence degraded; using in-memory live session",
43
42
  extra={
44
43
  "session_backend_state": "degraded",
45
44
  "session_backend": type(self.primary).__name__,
45
+ "session_backend_reason_code": "SESSION_STORE_UNREACHABLE",
46
46
  },
47
47
  )
48
48
  self._start_probe()
@@ -63,22 +63,30 @@ class ResilientADKSessionService(BaseSessionService):
63
63
  await asyncio.sleep(self._probe_interval_seconds)
64
64
  if self._primary_enabled:
65
65
  break
66
- try:
67
- await self.primary.get_session(
68
- app_name="__ksadk_probe__",
69
- user_id="__ksadk_probe__",
70
- session_id="__ksadk_probe__",
71
- )
72
- except Exception:
73
- continue
74
- self._primary_enabled = True
75
- logger.info(
76
- "ADK session persistence recovered; durable backend re-enabled",
77
- extra={
78
- "session_backend_state": "recovered",
79
- "session_backend": type(self.primary).__name__,
80
- },
66
+ await self.refresh_persistence_capability()
67
+
68
+ async def refresh_persistence_capability(self) -> bool:
69
+ """Probe a degraded ADK database service without rebuilding the runner."""
70
+ if self._primary_enabled:
71
+ return True
72
+ try:
73
+ await self.primary.get_session(
74
+ app_name="__ksadk_probe__",
75
+ user_id="__ksadk_probe__",
76
+ session_id="__ksadk_probe__",
81
77
  )
78
+ except Exception:
79
+ return False
80
+ self._primary_enabled = True
81
+ logger.info(
82
+ "ADK session persistence recovered; durable backend re-enabled",
83
+ extra={
84
+ "session_backend_state": "recovered",
85
+ "session_backend": type(self.primary).__name__,
86
+ "session_backend_reason_code": "READY",
87
+ },
88
+ )
89
+ return True
82
90
 
83
91
  @staticmethod
84
92
  def _key(app_name: str, user_id: str, session_id: str) -> tuple[str, str, str]:
@@ -33,6 +33,7 @@ from ksadk.compat.adk_compat import (
33
33
  InMemorySessionService,
34
34
  Session,
35
35
  )
36
+ from ksadk.sessions.topology import StorageTarget, resolve_persistence_topology
36
37
 
37
38
  logger = logging.getLogger(__name__)
38
39
 
@@ -55,14 +56,20 @@ def _normalize_backend_name(backend: str) -> str:
55
56
 
56
57
 
57
58
  def _normalize_database_url(db_url: str) -> str:
58
- """Normalize sqlite URLs for google.adk DatabaseSessionService.
59
+ """Normalize database URLs for google.adk DatabaseSessionService.
59
60
 
60
- ADK uses SQLAlchemy async engines underneath, so plain `sqlite:///...`
61
- URLs fail while `sqlite+aiosqlite:///...` works.
61
+ ADK uses SQLAlchemy async engines underneath, so plain PostgreSQL and
62
+ SQLite URLs need their corresponding async driver schemes.
62
63
  """
63
64
  normalized = str(db_url or "").strip()
64
65
  if not normalized:
65
66
  return ""
67
+ if normalized.startswith("postgresql+asyncpg:"):
68
+ return normalized
69
+ if normalized.startswith("postgresql:"):
70
+ return "postgresql+asyncpg:" + normalized[len("postgresql:") :]
71
+ if normalized.startswith("postgres:"):
72
+ return "postgresql+asyncpg:" + normalized[len("postgres:") :]
66
73
  if normalized.startswith("sqlite+aiosqlite:"):
67
74
  return normalized
68
75
  if normalized.startswith("sqlite:"):
@@ -159,9 +166,7 @@ class ShortTermMemory(BaseModel):
159
166
  self._session_service = ResilientADKSessionService(
160
167
  DatabaseSessionService(db_url=normalized_db_url, **service_kwargs)
161
168
  )
162
- logger.info(
163
- f"ShortTermMemory: using DatabaseSessionService " f"({normalized_db_url[:30]}...)"
164
- )
169
+ logger.info("ShortTermMemory: using DatabaseSessionService")
165
170
  except ImportError:
166
171
  logger.warning(
167
172
  "DatabaseSessionService not available. "
@@ -170,10 +175,11 @@ class ShortTermMemory(BaseModel):
170
175
  )
171
176
  self._session_service = InMemorySessionService()
172
177
  self.backend = "local"
173
- except Exception as e:
178
+ except Exception as exc:
174
179
  logger.error(
175
- f"Failed to create DatabaseSessionService: {e}. "
176
- f"Falling back to InMemorySessionService."
180
+ "Failed to create DatabaseSessionService (%s); "
181
+ "falling back to InMemorySessionService.",
182
+ type(exc).__name__,
177
183
  )
178
184
  self._session_service = InMemorySessionService()
179
185
  self.backend = "local"
@@ -237,6 +243,13 @@ class ShortTermMemory(BaseModel):
237
243
  logger.error(f"Failed to create session: {e}")
238
244
  return None
239
245
 
246
+ @classmethod
247
+ def from_persistence_target(cls, target: StorageTarget) -> "ShortTermMemory":
248
+ """Build ADK-native state from an effective Checkpoint storage target."""
249
+ if target.backend == "postgres" and target.dsn:
250
+ return cls(backend="database", db_url=_normalize_database_url(target.dsn))
251
+ return cls(backend="local")
252
+
240
253
  @classmethod
241
254
  def from_env(cls) -> "ShortTermMemory":
242
255
  """从环境变量创建 ShortTermMemory
@@ -251,6 +264,10 @@ class ShortTermMemory(BaseModel):
251
264
  KSADK_SESSION_BACKEND: 统一 session backend fallback
252
265
  KSADK_SESSION_DSN: 统一 session DSN fallback
253
266
  """
267
+ topology = resolve_persistence_topology(framework="adk")
268
+ if topology.checkpoint.backend == "postgres" and topology.checkpoint.dsn:
269
+ return cls.from_persistence_target(topology.checkpoint)
270
+
254
271
  explicit_backend = _normalize_backend_name(
255
272
  _env_first(
256
273
  "KSADK_ADK_SESSION_BACKEND",
ksadk/memory/models.py CHANGED
@@ -127,6 +127,8 @@ class MemoryExtractionStatus:
127
127
  status: str
128
128
  searchable: bool = False
129
129
  message: str = ""
130
+ # Query failure does not prove that the previously submitted write failed.
131
+ error_code: str = ""
130
132
 
131
133
 
132
134
  def map_session_state(state: int | None) -> str:
@@ -176,7 +178,7 @@ class MemoryConflictError(MemoryOperationError):
176
178
  MEMORY_MODEL_VERSION = "v1"
177
179
 
178
180
  MemoryScope = Literal["user", "agent", "workspace", "org"]
179
- MemoryType = Literal["profile", "fact", "episode"]
181
+ MemoryType = Literal["profile", "fact", "episode", "unknown"]
180
182
  MemoryStatus = Literal["active", "superseded", "deleted", "expired"]
181
183
  MemoryOperation = Literal["add", "update", "delete", "ignore"]
182
184
  MemorySearchStatus = Literal["ok", "not_configured", "timeout", "unauthorized", "failed"]
@@ -206,8 +208,8 @@ class MemoryRecord:
206
208
  content: str
207
209
  summary: str
208
210
  status: MemoryStatus
209
- confidence: float
210
- importance: float
211
+ confidence: float | None
212
+ importance: float | None
211
213
  valid_from: str
212
214
  valid_to: str
213
215
  expires_at: str
@@ -215,7 +217,8 @@ class MemoryRecord:
215
217
  source_event_ids: list[str]
216
218
  source_seq_range: tuple[int, int] | None
217
219
  content_hash: str
218
- version: int
220
+ # None means the provider has no record revision/CAS contract.
221
+ version: int | None
219
222
  metadata: dict[str, Any] = field(default_factory=dict)
220
223
  created_at: str = ""
221
224
  updated_at: str = ""
@@ -32,6 +32,9 @@ def resolve_memory_provider(provider_ref: str) -> MemoryProviderLike:
32
32
  """
33
33
  ref = str(provider_ref or "").strip().lower()
34
34
 
35
+ if ref.startswith("binding://"):
36
+ raise ValueError("RESOURCE_MEMORY_BINDING_REQUIRES_ACTIVATION")
37
+
35
38
  if ref in ("local-inmemory", "inmemory"):
36
39
  from ksadk.memory.adk.backends.inmemory_ltm_backend import (
37
40
  InMemoryLTMBackend,
@@ -141,6 +141,13 @@ class SqliteMemoryProvider:
141
141
  workspace_id: str = "local",
142
142
  ) -> None:
143
143
  self._db_path = str(db_path)
144
+ if self._db_path != ":memory:":
145
+ # A fresh local Studio has not created its session directory yet.
146
+ # SQLite creates the database file, but not missing parents.
147
+ Path(self._db_path).expanduser().resolve().parent.mkdir(
148
+ parents=True,
149
+ exist_ok=True,
150
+ )
144
151
  self._tenant_id = tenant_id
145
152
  self._workspace_id = workspace_id
146
153
  self._lock = threading.Lock()
@@ -444,13 +444,18 @@ class ProxyServer:
444
444
  # 应用层取消信号:让活动 SSE 的 _stream_gen 主动 break
445
445
  self._app.state.cancel_event.set()
446
446
  if self._server is not None:
447
- # should_exit 触发主循环进入 shutdown;force_exit 让 shutdown 跳过等待
448
- # connections/tasks 完成(活动 SSE 下不再无限等)。两者缺一:只 should_exit
449
- # 会被活动连接卡死,只 force_exit 主循环根本不进 shutdown。
447
+ # Enter Uvicorn's normal shutdown so its lifespan task receives a
448
+ # shutdown event. Setting force_exit here skips that event and
449
+ # makes every completed Studio turn print a CancelledError.
450
450
  self._server.should_exit = True
451
- self._server.force_exit = True
452
451
  if self._thread is not None:
453
- self._thread.join(timeout=5)
452
+ self._thread.join(timeout=3)
453
+ if self._thread.is_alive() and self._server is not None:
454
+ # The application cancel signal normally drains active SSE
455
+ # generators. Keep a bounded last resort for a broken client
456
+ # or upstream that ignores cancellation.
457
+ self._server.force_exit = True
458
+ self._thread.join(timeout=2)
454
459
  if self._sock is not None:
455
460
  try:
456
461
  self._sock.close()