agentengine-sdk-python 0.8.3__py3-none-any.whl → 0.8.5__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 (819) hide show
  1. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.5.dist-info}/METADATA +13 -9
  2. agentengine_sdk_python-0.8.5.dist-info/RECORD +1296 -0
  3. ksadk/_build_provenance.json +1 -1
  4. ksadk/_process.py +83 -0
  5. ksadk/_str_enum.py +17 -0
  6. ksadk/a2ui/core.py +3 -3
  7. ksadk/api/client.py +111 -91
  8. ksadk/builders/code_builder.py +74 -21
  9. ksadk/builders/framework_requirements.py +22 -3
  10. ksadk/builders/ks3_uploader.py +36 -7
  11. ksadk/builders/managed_runtime_builder.py +1 -0
  12. ksadk/cli/__init__.py +68 -3
  13. ksadk/cli/cmd_config.py +4 -4
  14. ksadk/cli/cmd_create.py +12 -12
  15. ksadk/cli/cmd_hermes.py +24 -2
  16. ksadk/cli/cmd_invoke.py +28 -5
  17. ksadk/cli/cmd_managed_runtime.py +13 -1
  18. ksadk/cli/cmd_openclaw.py +26 -1
  19. ksadk/cli/cmd_plugin.py +76 -13
  20. ksadk/cli/cmd_studio.py +64 -16
  21. ksadk/cli/cmd_web.py +2 -5
  22. ksadk/cli/openclaw_env.py +1 -1
  23. ksadk/cli/resource_common.py +26 -0
  24. ksadk/cli/runtime_bootstrap.py +23 -1
  25. ksadk/codex/client.py +425 -96
  26. ksadk/codex/projection.py +24 -0
  27. ksadk/codex/runtime.py +56 -298
  28. ksadk/common/auth.py +16 -10
  29. ksadk/configs/__init__.py +1 -1
  30. ksadk/configs/env_registry.py +153 -31
  31. ksadk/configs/env_registry_studio.py +86 -0
  32. ksadk/configs/global_config.py +1 -1
  33. ksadk/configs/settings.py +3 -3
  34. ksadk/connector/__init__.py +17 -0
  35. ksadk/connector/channel.py +477 -0
  36. ksadk/context_engine/capabilities.py +52 -4
  37. ksadk/conversations/attachment_storage.py +10 -3
  38. ksadk/conversations/attachments.py +16 -5
  39. ksadk/conversations/message_projection.py +133 -21
  40. ksadk/conversations/normalize.py +28 -10
  41. ksadk/conversations/projector.py +4 -6
  42. ksadk/conversations/runtime_baseline.py +37 -0
  43. ksadk/conversations/runtime_invocation.py +22 -4
  44. ksadk/conversations/runtime_observability.py +39 -10
  45. ksadk/conversations/runtime_payloads.py +9 -0
  46. ksadk/conversations/runtime_persistence.py +105 -9
  47. ksadk/conversations/runtime_preparation.py +42 -33
  48. ksadk/conversations/runtime_resume.py +50 -2
  49. ksadk/conversations/runtime_stream_events.py +34 -35
  50. ksadk/conversations/runtime_streaming.py +33 -7
  51. ksadk/deployment/env_forward.py +2 -2
  52. ksadk/deployment/providers/serverless.py +1 -1
  53. ksadk/events/adapters/_codex_items.py +16 -8
  54. ksadk/events/adapters/_codex_validators.py +18 -7
  55. ksadk/events/adapters/_langgraph_support.py +34 -0
  56. ksadk/events/adapters/langgraph.py +15 -1
  57. ksadk/events/canonical_store.py +3 -1
  58. ksadk/events/projections.py +1 -1
  59. ksadk/events/session_event.py +2 -2
  60. ksadk/harness/__init__.py +14 -0
  61. ksadk/harness/app.py +11 -0
  62. ksadk/harness/artifact_store.py +213 -0
  63. ksadk/harness/capabilities.py +115 -0
  64. ksadk/harness/capability_runtime.py +237 -0
  65. ksadk/harness/closure_contract.py +92 -0
  66. ksadk/harness/compaction_record.py +122 -0
  67. ksadk/harness/compiler.py +284 -0
  68. ksadk/harness/config.py +2 -2
  69. ksadk/harness/conformance/__init__.py +33 -0
  70. ksadk/harness/conformance/contract.py +506 -0
  71. ksadk/harness/conformance/fixtures.py +102 -0
  72. ksadk/harness/context_engine.py +403 -0
  73. ksadk/harness/context_maintenance.py +259 -0
  74. ksadk/harness/context_manifest.py +188 -0
  75. ksadk/harness/context_tuning.py +168 -0
  76. ksadk/harness/draft_runtime.py +322 -0
  77. ksadk/harness/engine/__init__.py +40 -0
  78. ksadk/harness/engine/base.py +122 -0
  79. ksadk/harness/engine/budgets.py +108 -0
  80. ksadk/harness/engine/capability_declarations.py +59 -0
  81. ksadk/harness/engine/completion_guard.py +42 -0
  82. ksadk/harness/engine/context_pipeline.py +579 -0
  83. ksadk/harness/engine/graph_builder.py +859 -0
  84. ksadk/harness/engine/langgraph.py +931 -0
  85. ksadk/harness/engine/mcp_disclosure.py +750 -0
  86. ksadk/harness/engine/policy_runtime.py +70 -0
  87. ksadk/harness/engine/postgres_checkpointer.py +63 -0
  88. ksadk/harness/engine/run_control_bridge.py +80 -0
  89. ksadk/harness/engine/run_types.py +88 -0
  90. ksadk/harness/engine/skill_disclosure.py +189 -0
  91. ksadk/harness/engine/spans.py +41 -0
  92. ksadk/harness/engine/subagents.py +343 -0
  93. ksadk/harness/engine/thread_ids.py +112 -0
  94. ksadk/harness/engine/tool_dispatch.py +144 -0
  95. ksadk/harness/event_tree.py +212 -0
  96. ksadk/harness/events.py +461 -0
  97. ksadk/harness/execution_policy.py +94 -0
  98. ksadk/harness/insights.py +210 -0
  99. ksadk/harness/lifecycle.py +578 -0
  100. ksadk/harness/lifecycle_conformance.py +233 -0
  101. ksadk/harness/lifecycle_local_plane.py +104 -0
  102. ksadk/harness/loop/__init__.py +44 -0
  103. ksadk/harness/loop/reason.py +454 -0
  104. ksadk/harness/loop/tools.py +762 -0
  105. ksadk/harness/managed_runtime.py +884 -0
  106. ksadk/harness/mcp_matrix.py +474 -0
  107. ksadk/harness/mcp_runtime.py +471 -0
  108. ksadk/harness/memory_consolidation.py +157 -0
  109. ksadk/harness/memory_loop.py +156 -0
  110. ksadk/harness/memory_runtime.py +541 -0
  111. ksadk/harness/metrics.py +90 -0
  112. ksadk/harness/model_capability.py +253 -0
  113. ksadk/harness/model_provider.py +220 -0
  114. ksadk/harness/observability/__init__.py +29 -0
  115. ksadk/harness/observability/inspection.py +528 -0
  116. ksadk/harness/observability/metrics.py +167 -0
  117. ksadk/harness/observability/otel_exporter.py +218 -0
  118. ksadk/harness/prompt_cache.py +70 -0
  119. ksadk/harness/public_activity.py +154 -0
  120. ksadk/harness/readiness.py +249 -0
  121. ksadk/harness/reasoner.py +466 -13
  122. ksadk/harness/release_readiness.py +140 -0
  123. ksadk/harness/resource_ref.py +69 -0
  124. ksadk/harness/run_control.py +668 -0
  125. ksadk/harness/runtime.py +171 -136
  126. ksadk/harness/runtime_capabilities.py +158 -0
  127. ksadk/harness/runtime_server.py +514 -0
  128. ksadk/harness/sandbox_adapters.py +739 -0
  129. ksadk/harness/sandbox_backend.py +530 -0
  130. ksadk/harness/sandbox_conformance.py +288 -0
  131. ksadk/harness/sandbox_lease.py +77 -0
  132. ksadk/harness/sandbox_lease_conformance.py +259 -0
  133. ksadk/harness/sandbox_matrix.py +170 -0
  134. ksadk/harness/sandbox_reconciliation.py +140 -0
  135. ksadk/harness/sandbox_recovery.py +586 -0
  136. ksadk/harness/sandbox_recovery_conformance.py +246 -0
  137. ksadk/harness/session_store.py +243 -0
  138. ksadk/harness/skill_composition.py +212 -0
  139. ksadk/harness/skill_feedback.py +123 -0
  140. ksadk/harness/skill_matrix.py +233 -0
  141. ksadk/harness/skill_runtime.py +259 -0
  142. ksadk/harness/spec.py +332 -0
  143. ksadk/harness/state.py +153 -0
  144. ksadk/harness/strategies.py +149 -0
  145. ksadk/harness/subagent.py +253 -0
  146. ksadk/harness/tool_policy.py +131 -0
  147. ksadk/harness/tool_receipts.py +96 -0
  148. ksadk/harness/tool_reliability.py +81 -0
  149. ksadk/harness/tools.py +38 -13
  150. ksadk/harness/user_errors.py +69 -0
  151. ksadk/harness/working_context.py +81 -0
  152. ksadk/harness/working_context_patch.py +99 -0
  153. ksadk/identity/resolver.py +18 -0
  154. ksadk/interaction/__init__.py +1 -1
  155. ksadk/interaction/ledger.py +1 -1
  156. ksadk/interaction/provider.py +2 -1
  157. ksadk/interaction/providers/__init__.py +3 -1
  158. ksadk/interaction/providers/adk.py +1 -1
  159. ksadk/interaction/providers/codex.py +1 -1
  160. ksadk/interaction/providers/harness.py +50 -0
  161. ksadk/interaction/providers/langgraph.py +2 -1
  162. ksadk/kernel/__init__.py +10 -0
  163. ksadk/kernel/approval_presentation.py +91 -0
  164. ksadk/kernel/authorization.py +1 -1
  165. ksadk/kernel/bootstrap.py +114 -106
  166. ksadk/kernel/contract_fingerprints.py +1 -1
  167. ksadk/kernel/contracts.py +5 -0
  168. ksadk/kernel/control.py +32 -1
  169. ksadk/kernel/execution_grants.py +221 -0
  170. ksadk/kernel/execution_grants_memory.py +133 -0
  171. ksadk/kernel/execution_grants_postgres.py +217 -0
  172. ksadk/kernel/execution_grants_sqlite.py +209 -0
  173. ksadk/kernel/ingress.py +42 -29
  174. ksadk/kernel/mapping.py +1 -1
  175. ksadk/kernel/memory_store.py +24 -11
  176. ksadk/kernel/postgres_store.py +63 -33
  177. ksadk/kernel/recovery.py +78 -14
  178. ksadk/kernel/sql/001_agent_kernel.sql +23 -0
  179. ksadk/kernel/sqlite_store.py +331 -25
  180. ksadk/kernel/state.py +2 -3
  181. ksadk/kernel/store.py +72 -2
  182. ksadk/kernel/worker.py +144 -51
  183. ksadk/kernel/worker_history.py +72 -0
  184. ksadk/kernel/worker_identity.py +47 -0
  185. ksadk/knowledge_base/client.py +57 -27
  186. ksadk/mcp_runtime/__init__.py +12 -4
  187. ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
  188. ksadk/memory/adk/resilient_session_service.py +25 -17
  189. ksadk/memory/adk/short_term_memory.py +26 -9
  190. ksadk/memory/coordinator.py +22 -6
  191. ksadk/memory/extraction.py +40 -1
  192. ksadk/memory/models.py +84 -5
  193. ksadk/memory/provider_resolver.py +8 -0
  194. ksadk/memory/providers/local_postgres.py +200 -0
  195. ksadk/memory/providers/local_sqlite.py +42 -3
  196. ksadk/memory/retrieval.py +189 -0
  197. ksadk/memory/store_adapter.py +150 -0
  198. ksadk/model_policy.py +2 -2
  199. ksadk/model_proxy/detect.py +254 -0
  200. ksadk/model_proxy/server.py +14 -7
  201. ksadk/model_proxy/transform.py +40 -2
  202. ksadk/plugins/__init__.py +5 -1
  203. ksadk/plugins/artifacts.py +275 -0
  204. ksadk/plugins/bridges/__init__.py +4 -2
  205. ksadk/plugins/bridges/codex.py +120 -13
  206. ksadk/plugins/bridges/dsh.py +351 -156
  207. ksadk/plugins/builtins.py +72 -35
  208. ksadk/plugins/bundle_security.py +28 -4
  209. ksadk/plugins/codex_manifest.py +983 -0
  210. ksadk/plugins/companion_artifacts.py +83 -0
  211. ksadk/plugins/companions.py +368 -0
  212. ksadk/plugins/composition.py +8 -0
  213. ksadk/plugins/contracts.py +119 -1
  214. ksadk/plugins/delivery.py +153 -0
  215. ksadk/plugins/dsh_channels.py +156 -0
  216. ksadk/plugins/dsh_home.py +140 -0
  217. ksadk/plugins/dsh_installation_digest.py +71 -0
  218. ksadk/plugins/dsh_teams.py +105 -0
  219. ksadk/plugins/dsh_toolchain.py +203 -32
  220. ksadk/plugins/ecosystem_probe.py +6 -6
  221. ksadk/plugins/execution_host.py +99 -0
  222. ksadk/plugins/host.py +102 -39
  223. ksadk/plugins/kernel_adapter.py +205 -0
  224. ksadk/plugins/providers/__init__.py +23 -0
  225. ksadk/plugins/providers/bundles/dsh-channels-client/client.js +19 -0
  226. ksadk/plugins/providers/bundles/dsh-channels-client/cordis.patch.yml +3 -0
  227. ksadk/plugins/providers/bundles/dsh-channels-client/index.mjs +7 -0
  228. ksadk/plugins/providers/bundles/dsh-channels-client/package.json +12 -0
  229. ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
  230. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
  231. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
  232. ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
  233. ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
  234. ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
  235. ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
  236. ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
  237. ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
  238. ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
  239. ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
  240. ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
  241. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -0
  242. ksadk/plugins/providers/bundles/dsh-teams-client/client.js +29 -0
  243. ksadk/plugins/providers/bundles/dsh-teams-client/cordis.patch.yml +3 -0
  244. ksadk/plugins/providers/bundles/dsh-teams-client/index.mjs +11 -0
  245. ksadk/plugins/providers/bundles/dsh-teams-client/package.json +35 -0
  246. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/cordis.patch.yml +3 -0
  247. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/index.mjs +13 -0
  248. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/package.json +27 -0
  249. ksadk/plugins/providers/bundles/dsh-teams-profile/cordis.patch.yml +3 -0
  250. ksadk/plugins/providers/bundles/dsh-teams-profile/index.mjs +12 -0
  251. ksadk/plugins/providers/bundles/dsh-teams-profile/package.json +26 -0
  252. ksadk/plugins/providers/bundles/dsh-teams-router/cordis.patch.yml +3 -0
  253. ksadk/plugins/providers/bundles/dsh-teams-router/index.mjs +16 -0
  254. ksadk/plugins/providers/bundles/dsh-teams-router/package.json +27 -0
  255. ksadk/plugins/providers/bundles/dsh-teams-tasks/cordis.patch.yml +3 -0
  256. ksadk/plugins/providers/bundles/dsh-teams-tasks/index.mjs +16 -0
  257. ksadk/plugins/providers/bundles/dsh-teams-tasks/package.json +27 -0
  258. ksadk/plugins/providers/bundles/dsh-teams-tools/cordis.patch.yml +3 -0
  259. ksadk/plugins/providers/bundles/dsh-teams-tools/index.mjs +25 -0
  260. ksadk/plugins/providers/bundles/dsh-teams-tools/package.json +29 -0
  261. ksadk/plugins/providers/bundles/dsh-teams-tools/tools.json +235 -0
  262. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +1 -1
  263. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/cordis.patch.yml +3 -0
  264. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +920 -0
  265. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
  266. ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/client.mjs +133 -0
  267. ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/index.mjs +14 -0
  268. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +115 -0
  269. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +19 -0
  270. ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -0
  271. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +1 -1
  272. ksadk/plugins/providers/codex.py +344 -70
  273. ksadk/plugins/providers/codex_native.py +368 -0
  274. ksadk/plugins/providers/codex_turn.py +301 -0
  275. ksadk/plugins/providers/dsh_capabilities.py +1450 -0
  276. ksadk/plugins/providers/dsh_mcp.py +467 -0
  277. ksadk/plugins/providers/harness.py +294 -141
  278. ksadk/plugins/providers/harness_delegation.py +593 -0
  279. ksadk/plugins/providers/harness_managed.py +456 -0
  280. ksadk/plugins/providers/harness_tools.py +326 -0
  281. ksadk/plugins/providers/mcp_projection.py +150 -0
  282. ksadk/plugins/providers/platform_resources.py +657 -0
  283. ksadk/plugins/providers/shipped_dsh.py +4 -1
  284. ksadk/plugins/resolver.py +8 -1
  285. ksadk/plugins/subagent_providers/codex.py +28 -6
  286. ksadk/plugins/teams/__init__.py +5 -0
  287. ksadk/plugins/teams/api.py +405 -0
  288. ksadk/plugins/teams/application.py +680 -0
  289. ksadk/plugins/teams/artifacts.py +60 -0
  290. ksadk/plugins/teams/context.py +96 -0
  291. ksadk/plugins/teams/contracts.py +136 -0
  292. ksadk/plugins/teams/domain.py +1427 -0
  293. ksadk/plugins/teams/domain_values.py +24 -0
  294. ksadk/plugins/teams/errors.py +13 -0
  295. ksadk/plugins/teams/migration.py +311 -0
  296. ksadk/plugins/teams/migration_cli.py +322 -0
  297. ksadk/plugins/teams/postgres_store.py +138 -0
  298. ksadk/plugins/teams/runtime.py +777 -0
  299. ksadk/plugins/teams/source_projection.py +84 -0
  300. ksadk/plugins/teams/store.py +311 -0
  301. ksadk/plugins/teams/task_decisions.py +423 -0
  302. ksadk/plugins/teams/transport.py +91 -0
  303. ksadk/plugins/teams/workspaces.py +255 -0
  304. ksadk/resource_runtime/__init__.py +4 -0
  305. ksadk/resource_runtime/broker.py +616 -0
  306. ksadk/resource_runtime/build_artifacts.py +165 -0
  307. ksadk/resource_runtime/contracts.py +138 -0
  308. ksadk/resource_runtime/discovery_receipts.py +100 -0
  309. ksadk/resource_runtime/discovery_skills.py +172 -0
  310. ksadk/resource_runtime/errors.py +6 -0
  311. ksadk/resource_runtime/ipc.py +142 -0
  312. ksadk/resource_runtime/kernel_approval.py +165 -0
  313. ksadk/resource_runtime/knowledge.py +114 -0
  314. ksadk/resource_runtime/langgraph.py +94 -0
  315. ksadk/resource_runtime/leases.py +191 -0
  316. ksadk/resource_runtime/managed_projection.py +186 -0
  317. ksadk/resource_runtime/mcp_server.py +138 -0
  318. ksadk/resource_runtime/memory_provider.py +318 -0
  319. ksadk/resource_runtime/memory_receipts.py +34 -0
  320. ksadk/resource_runtime/operation_ledger.py +211 -0
  321. ksadk/resource_runtime/plugin_config.py +48 -0
  322. ksadk/resource_runtime/policy_authorization.py +54 -0
  323. ksadk/resource_runtime/process.py +110 -0
  324. ksadk/resource_runtime/skill_artifacts.py +153 -0
  325. ksadk/resource_runtime/skill_runtime.py +42 -0
  326. ksadk/resource_runtime/skill_workspace.py +118 -0
  327. ksadk/resource_runtime/skills.py +215 -0
  328. ksadk/resource_runtime/snapshots.py +180 -0
  329. ksadk/resource_runtime/socket_server.py +103 -0
  330. ksadk/resource_runtime/supervisor.py +380 -0
  331. ksadk/resource_runtime/worker.py +504 -0
  332. ksadk/runners/_langgraph_runner_streams.py +182 -38
  333. ksadk/runners/_langgraph_state_reader.py +106 -0
  334. ksadk/runners/_session_identity.py +285 -0
  335. ksadk/runners/adk_runner.py +166 -63
  336. ksadk/runners/base_runner.py +29 -1
  337. ksadk/runners/langgraph_runner.py +542 -195
  338. ksadk/runners/patch_langchain.py +47 -0
  339. ksadk/runners/usage_accumulator.py +11 -3
  340. ksadk/runtime/_runner_adapter/stream_mapping.py +194 -20
  341. ksadk/runtime/adapter.py +2 -0
  342. ksadk/runtime/conversation_execution.py +117 -17
  343. ksadk/runtime/executor.py +87 -3
  344. ksadk/runtime/factory.py +65 -274
  345. ksadk/runtime/framework_adapters.py +23 -0
  346. ksadk/runtime/preprocessing.py +21 -5
  347. ksadk/runtime/runner_adapter.py +106 -18
  348. ksadk/runtime/skill_eval_result.py +36 -0
  349. ksadk/runtime/timing.py +46 -0
  350. ksadk/runtime/usage.py +49 -18
  351. ksadk/runtime_context.py +142 -2
  352. ksadk/sandbox/backends/e2b.py +288 -25
  353. ksadk/sandbox/backends/local_process.py +72 -39
  354. ksadk/sandbox/base.py +64 -1
  355. ksadk/sandbox/diagnostics.py +82 -0
  356. ksadk/sandbox/e2b_connection.py +66 -0
  357. ksadk/sandbox/local_controls.py +746 -0
  358. ksadk/sandbox/local_launcher.py +90 -0
  359. ksadk/scheduler/dispatcher.py +1 -1
  360. ksadk/scheduler/sqlite_store.py +18 -0
  361. ksadk/server/composition.py +2 -0
  362. ksadk/server/factory.py +5 -0
  363. ksadk/server/invocation_identity.py +118 -0
  364. ksadk/server/persistence_capability.py +516 -0
  365. ksadk/server/routes/common.py +32 -3
  366. ksadk/server/routes/control.py +271 -52
  367. ksadk/server/routes/dependencies.py +16 -0
  368. ksadk/server/routes/kernel_ingress.py +9 -1
  369. ksadk/server/routes/misc.py +233 -25
  370. ksadk/server/routes/models.py +47 -4
  371. ksadk/server/routes/openai_compat.py +76 -13
  372. ksadk/server/routes/projection.py +252 -12
  373. ksadk/server/routes/run.py +106 -35
  374. ksadk/server/routes/sessions.py +491 -138
  375. ksadk/server/routes/streaming.py +43 -9
  376. ksadk/server/routes/workspace.py +130 -21
  377. ksadk/server/static/assets/{ArtifactsPanel-10GPXIJ6.js → ArtifactsPanel-C1YoaKhx.js} +1 -1
  378. ksadk/server/static/assets/{CodeBlock-BXk1l-G1.js → CodeBlock-DHuAWfr5.js} +10 -7
  379. ksadk/server/static/assets/MathMessageMarkdown-cvdrBwYr.js +8 -0
  380. ksadk/server/static/assets/{MermaidBlock--OEYoXIJ.js → MermaidBlock-DeBkbJvI.js} +9 -9
  381. ksadk/server/static/assets/{NativeTerminalPanel-DrEe1syq.js → NativeTerminalPanel-oJj44_sV.js} +1 -1
  382. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-eeTFJLvo.js → abnfDiagram-VCTEODGH-Dhfv25o2.js} +1 -1
  383. ksadk/server/static/assets/{arc-S3ZNbIAd.js → arc-C35w-pn1.js} +1 -1
  384. ksadk/server/static/assets/architecture-7GRP2DOG-BCsa26zi.js +1 -0
  385. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-CRjgEJDX.js → architectureDiagram-5GKGNRK7-FoMY_u6D.js} +1 -1
  386. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-C7bsBoNH.js → blockDiagram-NRAW4CY4-zD4Rt7oE.js} +1 -1
  387. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-BX3c33Ob.js → c4Diagram-UCG6FXSJ-BCtGGkhN.js} +1 -1
  388. ksadk/server/static/assets/channel-_KDifNys.js +1 -0
  389. ksadk/server/static/assets/chunk-2Q5K7J3B-HdVkJ9F0.js +1 -0
  390. ksadk/server/static/assets/{chunk-5VM5RSS4-bZ7ws-8m.js → chunk-5VM5RSS4-C2Ms13_k.js} +1 -1
  391. ksadk/server/static/assets/{chunk-F27PBJKO-D2r0pvhY.js → chunk-F27PBJKO-BoTj-qgx.js} +1 -1
  392. ksadk/server/static/assets/{chunk-G27WJ6UU-CZwF3oUP.js → chunk-G27WJ6UU-DOMyyjHH.js} +1 -1
  393. ksadk/server/static/assets/{chunk-JWPE2WC7-DigFYCML.js → chunk-JWPE2WC7-DbJJqDli.js} +1 -1
  394. ksadk/server/static/assets/{chunk-LCL6LL3I-CnorGV5q.js → chunk-LCL6LL3I-CLuRCt_W.js} +1 -1
  395. ksadk/server/static/assets/{chunk-POPQ4Y6H-CexntQA-.js → chunk-POPQ4Y6H-D0Dz847e.js} +1 -1
  396. ksadk/server/static/assets/{chunk-RHFEMEQ7-CHTC7UxA.js → chunk-RHFEMEQ7-BWSRzEcd.js} +1 -1
  397. ksadk/server/static/assets/{chunk-SVP7TREG-BC1EWt_-.js → chunk-SVP7TREG-CPoHqkCY.js} +1 -1
  398. ksadk/server/static/assets/{chunk-XXDRQBXY-BTG24xN0.js → chunk-XXDRQBXY-Bx1jS-X-.js} +1 -1
  399. ksadk/server/static/assets/classDiagram-DTDB5LWJ-BVCW3ZqZ.js +1 -0
  400. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-BVCW3ZqZ.js +1 -0
  401. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-CkonRdAS.js → cose-bilkent-JH36ORCC-LzyWm4m0.js} +1 -1
  402. ksadk/server/static/assets/cynefin-OW5HDTMX-CNXjFctL.js +1 -0
  403. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-DEOCBe15.js → cynefinDiagram-5FMLGOSQ-BlW_bHED.js} +1 -1
  404. ksadk/server/static/assets/{dagre-3AP2YEHR-DBThPuLa.js → dagre-3AP2YEHR-Bu_S86_i.js} +1 -1
  405. ksadk/server/static/assets/{dagre-ClTPrTht.js → dagre-B7nCawed.js} +1 -1
  406. ksadk/server/static/assets/{diagram-S7CK7UJ4-DsZHrnpJ.js → diagram-S7CK7UJ4-W_Zow2Km.js} +1 -1
  407. ksadk/server/static/assets/{diagram-UQ7AKVKN-BJR4nhVr.js → diagram-UQ7AKVKN-CLIKAHON.js} +1 -1
  408. ksadk/server/static/assets/{diagram-VSXAHHWV-xzcERX0a.js → diagram-VSXAHHWV-Dv6_QAlN.js} +1 -1
  409. ksadk/server/static/assets/{diagram-VX7I27RA-tn2xM1xu.js → diagram-VX7I27RA-BWAWRDtZ.js} +1 -1
  410. ksadk/server/static/assets/{diagram-Z3DM3KII-BZPGBkw5.js → diagram-Z3DM3KII-XA_rWMss.js} +1 -1
  411. ksadk/server/static/assets/dist-0X_j2Rcc.js +1 -0
  412. ksadk/server/static/assets/{dist-4zN1_tq5.js → dist-1nXCdsej.js} +1 -1
  413. ksadk/server/static/assets/{dist-M67Hwu0n.js → dist-2vL2sAdF.js} +1 -1
  414. ksadk/server/static/assets/{dist-BJLUwH6W.js → dist-B3bA05-e.js} +1 -1
  415. ksadk/server/static/assets/{dist-8VWI-2bZ.js → dist-BLpRy_Yx.js} +1 -1
  416. ksadk/server/static/assets/{dist-D1V3f1B4.js → dist-BO_UwatH.js} +1 -1
  417. ksadk/server/static/assets/{dist-Cq4OL6nO.js → dist-BdNFAney.js} +1 -1
  418. ksadk/server/static/assets/{dist-DfGFrb0v.js → dist-C0J5_3qM.js} +1 -1
  419. ksadk/server/static/assets/{dist-DyqV4fL4.js → dist-CGt_UGeO.js} +1 -1
  420. ksadk/server/static/assets/{dist-DjhwGUgZ.js → dist-CIRMvUM4.js} +1 -1
  421. ksadk/server/static/assets/{dist-B1oWRmrH.js → dist-CIpWk_5f.js} +1 -1
  422. ksadk/server/static/assets/{dist-CXpH_Rdd.js → dist-CPyieXEf.js} +1 -1
  423. ksadk/server/static/assets/{dist-Btyo4vX4.js → dist-D-92S-Fd.js} +1 -1
  424. ksadk/server/static/assets/{dist-u8tVH5Ak.js → dist-DNKuMzWc.js} +1 -1
  425. ksadk/server/static/assets/{dist-DQAB0qn_.js → dist-DWfdmz9s.js} +2 -2
  426. ksadk/server/static/assets/{dist-B-46q3Hk.js → dist-DppE_r-D.js} +1 -1
  427. ksadk/server/static/assets/{dist-C71CsujO.js → dist-DyG6Ya-z.js} +1 -1
  428. ksadk/server/static/assets/{dist-DJmCPRVB.js → dist-M-SrdhhZ.js} +1 -1
  429. ksadk/server/static/assets/{dist-Bbwqa8TG.js → dist-mqD5TZup.js} +1 -1
  430. ksadk/server/static/assets/{dist-BI1qQH4n.js → dist-n3n6t_FO.js} +1 -1
  431. ksadk/server/static/assets/{dist-DUwKa_l6.js → dist-qe8xjesy.js} +1 -1
  432. ksadk/server/static/assets/{dist-B0gdk4rl.js → dist-t6MzE0jU.js} +1 -1
  433. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-DVfMsLge.js → ebnfDiagram-PWID7BFC-BfCzF1Xi.js} +1 -1
  434. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CWEZSYaw.js → erDiagram-SSCWMZ5O-Dpz9_0zn.js} +1 -1
  435. ksadk/server/static/assets/eventmodeling-NTZA5JFV-B5-8RH9c.js +1 -0
  436. ksadk/server/static/assets/flowDiagram-A5DVABFB-BppFxEKw.js +1 -0
  437. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-TWIxoyYL.js → ganttDiagram-EL5Y4UJY-DDaG1f4_.js} +1 -1
  438. ksadk/server/static/assets/gitGraph-4MIJSDKK-B-AhYj4C.js +1 -0
  439. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-DDh2hd2S.js → gitGraphDiagram-WWUBYQGX-DcxzRwYC.js} +1 -1
  440. ksadk/server/static/assets/index-BMd2mucF.css +2 -0
  441. ksadk/server/static/assets/index-D5qyyhTH.js +244 -0
  442. ksadk/server/static/assets/info-A6RAGUB7-0uiKrC35.js +1 -0
  443. ksadk/server/static/assets/{infoDiagram-RXCK75RN-CgoyWiDR.js → infoDiagram-RXCK75RN-CYMdn6lQ.js} +1 -1
  444. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CyRIu_om.js → ishikawaDiagram-5VMMS53U-CLHFAD6c.js} +1 -1
  445. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DN5JXHzN.js → journeyDiagram-EYS64GPL-BHSKQGAl.js} +1 -1
  446. ksadk/server/static/assets/{kanban-definition-3QL26DDD-CNP3ui66.js → kanban-definition-3QL26DDD-D5W3tjTT.js} +1 -1
  447. ksadk/server/static/assets/{katex-DWEzQy1d.js → katex-mtjOi4KM.js} +1 -1
  448. ksadk/server/static/assets/{linear-C-qHp7d2.js → linear-BETqsxE_.js} +1 -1
  449. ksadk/server/static/assets/{mermaid-parser.core-Cl-K943T.js → mermaid-parser.core-DPWrvs90.js} +2 -2
  450. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-D5DB5mYm.js → mindmap-definition-FBJOCRG2-CJG2mfBP.js} +1 -1
  451. ksadk/server/static/assets/packet-AYTQ26CC-BVTmZ_cw.js +1 -0
  452. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-BQVc9ia_.js → pegDiagram-XKGWAZYB-GjAPNaqn.js} +1 -1
  453. ksadk/server/static/assets/pie-WAS4IAKB-DyfxBU7V.js +1 -0
  454. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-B6UCAvtY.js → pieDiagram-E7YTZNPT-ToIewrqr.js} +1 -1
  455. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-mIr2d3eb.js → quadrantDiagram-AXDQQJYC-4d78KiEY.js} +1 -1
  456. ksadk/server/static/assets/radar-RG4KPBEZ-FFontjL2.js +1 -0
  457. ksadk/server/static/assets/railroad-74A4TZTK-D0Uidzen.js +1 -0
  458. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BOo_9T2h.js +1 -0
  459. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-D6-BjW7Z.js +1 -0
  460. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CXx__yMm.js +1 -0
  461. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-Dt3FFDmK.js → railroadDiagram-O6MQD6OU-DKzx4xfv.js} +1 -1
  462. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-Cz_vQtgF.js → requirementDiagram-EFPCY7ZU-CJYljxQS.js} +1 -1
  463. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-wlO1TsH5.js → sankeyDiagram-P5KCCOFB-DLU2fV1w.js} +1 -1
  464. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-CHRbElYq.js → sequenceDiagram-WJ2MYXX4-CVqysrA9.js} +1 -1
  465. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DXX54iyO.js → sizeCapture-X5ZJPWSS-BUxfmTHc.js} +1 -1
  466. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-Dp_lw9II.js → stateDiagram-HBIQ2CUA-CNFgYI9E.js} +1 -1
  467. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BXAFScz8.js +1 -0
  468. ksadk/server/static/assets/{swimlanes-XN3QIQJK-D8O5UlLG.js → swimlanes-XN3QIQJK-B6qCMe8N.js} +1 -1
  469. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uIQ2lJKH.js +8 -0
  470. ksadk/server/static/assets/{timeline-definition-24CTP7MA-8mfKcxvG.js → timeline-definition-24CTP7MA-CMD3x_U_.js} +1 -1
  471. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5GgucZ.js +1 -0
  472. ksadk/server/static/assets/treemap-WGGIJYW6-Bq1u1SpG.js +1 -0
  473. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-EnNl0DE7.js → vennDiagram-4TSXK5OY-BqtUqvXM.js} +1 -1
  474. ksadk/server/static/assets/wardley-WFR3VGLG-QAt06uEz.js +1 -0
  475. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DBu5fbYr.js → wardleyDiagram-VM6X3IG4-B5KfDjI-.js} +1 -1
  476. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-BSVXs4IY.js → xychartDiagram-S5SC5T6Z-BaUlSZrn.js} +1 -1
  477. ksadk/server/static/index.html +2 -2
  478. ksadk/server/terminal_sessions.py +34 -2
  479. ksadk/session_context.py +66 -0
  480. ksadk/sessions/__init__.py +11 -21
  481. ksadk/sessions/_local_service_sync.py +263 -1
  482. ksadk/sessions/base.py +176 -0
  483. ksadk/sessions/errors.py +4 -0
  484. ksadk/sessions/in_memory.py +309 -19
  485. ksadk/sessions/invocation_identity.py +235 -0
  486. ksadk/sessions/local_service.py +83 -1
  487. ksadk/sessions/persistence.py +275 -0
  488. ksadk/sessions/postgres_service.py +358 -0
  489. ksadk/sessions/resilience.py +8 -0
  490. ksadk/sessions/resilient.py +362 -4
  491. ksadk/sessions/topology.py +135 -0
  492. ksadk/skills/__init__.py +26 -0
  493. ksadk/skills/events.py +464 -0
  494. ksadk/skills/manifest_cache.py +263 -0
  495. ksadk/skills/mcp_server/__init__.py +0 -0
  496. ksadk/skills/mcp_server/_registry.py +33 -0
  497. ksadk/skills/mcp_server/_routing.py +26 -0
  498. ksadk/skills/mcp_server/_workspace_files.py +160 -0
  499. ksadk/skills/mcp_server/register.py +415 -0
  500. ksadk/skills/mcp_server/server.py +218 -0
  501. ksadk/skills/models.py +37 -4
  502. ksadk/skills/observability.py +132 -0
  503. ksadk/skills/package_store.py +261 -40
  504. ksadk/skills/runtime/agent.py +67 -9
  505. ksadk/skills/runtime/artifact_delivery.py +139 -0
  506. ksadk/skills/runtime/artifacts.py +87 -0
  507. ksadk/skills/runtime/backends/e2b.py +460 -27
  508. ksadk/skills/runtime/backends/local.py +629 -62
  509. ksadk/skills/runtime/base.py +81 -7
  510. ksadk/skills/runtime/executor.py +268 -1
  511. ksadk/skills/runtime/loader.py +118 -5
  512. ksadk/skills/runtime/pinned.py +114 -0
  513. ksadk/skills/runtime/request.py +49 -0
  514. ksadk/skills/service_client.py +167 -28
  515. ksadk/skills/tool_defs.py +108 -3
  516. ksadk/studio/api.py +810 -93
  517. ksadk/studio/api_catalog_routes.py +18 -0
  518. ksadk/studio/api_contracts.py +8 -2
  519. ksadk/studio/api_plugin_routes.py +562 -104
  520. ksadk/studio/api_resource_connections.py +221 -0
  521. ksadk/studio/authoring.py +12 -6
  522. ksadk/studio/authoring_coordinator.py +23 -16
  523. ksadk/studio/builder.py +88 -0
  524. ksadk/studio/capabilities.py +23 -6
  525. ksadk/studio/channel_connections.py +333 -0
  526. ksadk/studio/cloud.py +370 -112
  527. ksadk/studio/cloud_shared_web.py +638 -0
  528. ksadk/studio/codex_agent_service.py +130 -28
  529. ksadk/studio/codex_builder.py +242 -3
  530. ksadk/studio/codex_credentials.py +90 -0
  531. ksadk/studio/codex_manifest.py +31 -4
  532. ksadk/studio/codex_plugin_store.py +746 -0
  533. ksadk/studio/codex_provider_build.py +231 -0
  534. ksadk/studio/codex_run.py +190 -26
  535. ksadk/studio/compatibility_report.py +12 -1
  536. ksadk/studio/compiler.py +88 -14
  537. ksadk/studio/configuration.py +182 -0
  538. ksadk/studio/contracts.py +165 -11
  539. ksadk/studio/dsh_application.py +247 -0
  540. ksadk/studio/dsh_capability_service.py +1374 -0
  541. ksadk/studio/dsh_lifecycle.py +58 -0
  542. ksadk/studio/dsh_models.py +59 -0
  543. ksadk/studio/dsh_provider_registration.py +367 -21
  544. ksadk/studio/entry.py +53 -0
  545. ksadk/studio/event_store.py +36 -5
  546. ksadk/studio/execution_host.py +525 -0
  547. ksadk/studio/framework_run.py +32 -10
  548. ksadk/studio/hosted_kernel.py +89 -14
  549. ksadk/studio/kernel_registry.py +418 -0
  550. ksadk/studio/kernel_sqlite_migration.py +181 -0
  551. ksadk/studio/mcp_runtime.py +11 -3
  552. ksadk/studio/model_client.py +1180 -66
  553. ksadk/studio/model_profile_service.py +26 -11
  554. ksadk/studio/native_documents.py +172 -0
  555. ksadk/studio/plugin_composition.py +202 -24
  556. ksadk/studio/plugin_kernel_adapter.py +21 -106
  557. ksadk/studio/plugin_lifecycle.py +80 -0
  558. ksadk/studio/plugin_runtime.py +448 -56
  559. ksadk/studio/provider_recovery.py +59 -0
  560. ksadk/studio/recovery_page.py +70 -0
  561. ksadk/studio/resource_authority.py +664 -0
  562. ksadk/studio/resource_binding_validation.py +77 -0
  563. ksadk/studio/resource_build_admission.py +196 -0
  564. ksadk/studio/resource_build_materializer.py +149 -0
  565. ksadk/studio/resource_catalog.py +149 -2
  566. ksadk/studio/resource_connections.py +220 -0
  567. ksadk/studio/run_activity.py +895 -0
  568. ksadk/studio/run_documents.py +127 -0
  569. ksadk/studio/run_service.py +789 -83
  570. ksadk/studio/runtime_catalog.py +53 -10
  571. ksadk/studio/runtime_source.py +16 -8
  572. ksadk/studio/scheduler_assistant.py +317 -0
  573. ksadk/studio/scheduler_runtime.py +32 -280
  574. ksadk/studio/scheduler_service.py +3 -0
  575. ksadk/studio/service.py +861 -120
  576. ksadk/studio/shared_web.py +579 -82
  577. ksadk/studio/static/assets/ChannelsPage-D_PGmKVq.js +8 -0
  578. ksadk/studio/static/assets/CodeBlock-DMIf4h33-UIqo-BPW.js +44 -0
  579. ksadk/studio/static/assets/ExecutionTree-v3HexvPo-Bk8wzGSy.js +1 -0
  580. ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  581. ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  582. ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  583. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  584. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  585. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  586. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  587. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  588. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  589. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  590. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  591. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  592. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  593. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  594. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  595. ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  596. ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  597. ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  598. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  599. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  600. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  601. ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  602. ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  603. ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  604. ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  605. ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  606. ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  607. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  608. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  609. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  610. ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  611. ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  612. ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  613. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  614. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  615. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  616. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  617. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  618. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  619. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  620. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  621. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  622. ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  623. ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  624. ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  625. ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  626. ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  627. ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  628. ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  629. ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  630. ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  631. ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  632. ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  633. ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  634. ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  635. ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  636. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  637. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  638. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  639. ksadk/studio/static/assets/MathMessageMarkdown-BesSeCYl-BEOyPC3w.css +1 -0
  640. ksadk/studio/static/assets/MathMessageMarkdown-BesSeCYl-OhNwH4K9.js +8 -0
  641. ksadk/studio/static/assets/MermaidBlock-H_0qzQDf-BdXtxug_.js +11 -0
  642. ksadk/studio/static/assets/MessageMarkdown-CwMTvgFj-g0I-I4dD.js +59 -0
  643. ksadk/studio/static/assets/PrismRenderer-5pK6tUdb.js +3 -0
  644. ksadk/studio/static/assets/TeamsPage-DqX4HWKQ.js +3 -0
  645. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-Bnb1O3tA.js +1 -0
  646. ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
  647. ksadk/studio/static/assets/architecture-7GRP2DOG-BMOPAkUC.js +1 -0
  648. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-5Zn1gqJv.js +36 -0
  649. ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
  650. ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CLB4L11u.js +129 -0
  651. ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BOma_Z_F.js +38 -0
  652. ksadk/studio/static/assets/channel-r8itPEik.js +1 -0
  653. ksadk/studio/static/assets/chunk-2E4U76K2-BFf_huql.js +2 -0
  654. ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  655. ksadk/studio/static/assets/chunk-2ZTRR5NV-C2qZJila.js +2 -0
  656. ksadk/studio/static/assets/chunk-3Z5EZCMW-DMniOlPd.js +1 -0
  657. ksadk/studio/static/assets/chunk-4HAMMTFA-DVtDP4rm.js +62 -0
  658. ksadk/studio/static/assets/chunk-5V3GS4D5-i-ZDOEnP.js +1 -0
  659. ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  660. ksadk/studio/static/assets/chunk-6AZGARVD-BB6FqMl-.js +1 -0
  661. ksadk/studio/static/assets/chunk-6EIED4P4-DdUJkP0f.js +1 -0
  662. ksadk/studio/static/assets/chunk-6K3QC6MW-CqVsVn-y.js +1 -0
  663. ksadk/studio/static/assets/chunk-6TQVIW2G-DKlLbNIP.js +1 -0
  664. ksadk/studio/static/assets/chunk-747NJXEK-BFkZPlab.js +2 -0
  665. ksadk/studio/static/assets/chunk-75Z2AOVW-BZNhM4vB.js +2 -0
  666. ksadk/studio/static/assets/chunk-CLGD4ZFX-D-GTtyKs.js +1 -0
  667. ksadk/studio/static/assets/chunk-DU6HZSFF-CpEZCUgg.js +128 -0
  668. ksadk/studio/static/assets/chunk-F27PBJKO-D7pvKf0C.js +1 -0
  669. ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
  670. ksadk/studio/static/assets/chunk-GMAD6QVW-DE_8H717.js +72 -0
  671. ksadk/studio/static/assets/chunk-GVQU2GXP-BfEB0lNv.js +1 -0
  672. ksadk/studio/static/assets/chunk-I5DQTOEV-Hm2LfiYI.js +1 -0
  673. ksadk/studio/static/assets/chunk-ICYGCRZG-749o-pGJ.js +1 -0
  674. ksadk/studio/static/assets/chunk-IH6LHLGP-CC6I9F3i.js +1 -0
  675. ksadk/studio/static/assets/chunk-IMKFNOWR-D38axYOR.js +231 -0
  676. ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  677. ksadk/studio/static/assets/chunk-KI3K4JFJ-Rma-0k_M.js +1 -0
  678. ksadk/studio/static/assets/chunk-L3NEJ4N5-Dq5xn7aL.js +1 -0
  679. ksadk/studio/static/assets/chunk-LNGE3PJU-DWpGwHrW.js +34 -0
  680. ksadk/studio/static/assets/chunk-OSK3NFVY-DiCQjx9b.js +10 -0
  681. ksadk/studio/static/assets/chunk-OUJLGHUK-D0j2JRSg.js +2 -0
  682. ksadk/studio/static/assets/chunk-P2QGCYS3-VdhKmfYq.js +1 -0
  683. ksadk/studio/static/assets/chunk-POPQ4Y6H-C1_rzO5M.js +1 -0
  684. ksadk/studio/static/assets/chunk-PWAF6VOD-B45HvflI.js +1 -0
  685. ksadk/studio/static/assets/chunk-SHT3W25Y-DsCFnRVE.js +168 -0
  686. ksadk/studio/static/assets/chunk-SVP7TREG-DljApgRX.js +88 -0
  687. ksadk/studio/static/assets/chunk-TICWLB2K-DWqRtyqa.js +206 -0
  688. ksadk/studio/static/assets/chunk-TLUHSLCS-DUeGgnD5.js +2 -0
  689. ksadk/studio/static/assets/chunk-UY3FDG6J-CnmaAkG5.js +1 -0
  690. ksadk/studio/static/assets/chunk-XHIXRSVI-BFQ6B8BE.js +1 -0
  691. ksadk/studio/static/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
  692. ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  693. ksadk/studio/static/assets/classDiagram-ZZMXUADV-DjeMNJmu.js +1 -0
  694. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-DjeMNJmu.js +1 -0
  695. ksadk/studio/static/assets/clsx-DB0hHKMi.js +1 -0
  696. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-om8AY0Mc.js +1 -0
  697. ksadk/studio/static/assets/createLucideIcon-DR0LGTP5.js +1 -0
  698. ksadk/studio/static/assets/cynefin-OW5HDTMX-7tP7QfM3.js +1 -0
  699. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-6BrmK52S.js +62 -0
  700. ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
  701. ksadk/studio/static/assets/dagre-GXQ25YYZ-buZBRlwz.js +4 -0
  702. ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
  703. ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
  704. ksadk/studio/static/assets/diagram-S7CK7UJ4-C6aH78c4.js +30 -0
  705. ksadk/studio/static/assets/diagram-UQ7AKVKN-DY_tQ6C_.js +41 -0
  706. ksadk/studio/static/assets/diagram-VSXAHHWV-DX9p5cQT.js +3 -0
  707. ksadk/studio/static/assets/diagram-VX7I27RA-DB2WSH8X.js +24 -0
  708. ksadk/studio/static/assets/diagram-Z3DM3KII-Ce1BJwHE.js +24 -0
  709. ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
  710. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-Daukxwqf.js +1 -0
  711. ksadk/studio/static/assets/erDiagram-RLTQ6QDP-CGthTMmJ.js +99 -0
  712. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-BR2FzK4R.js +1 -0
  713. ksadk/studio/static/assets/flowDiagram-HODETNUW-CZ1tEenp.js +1 -0
  714. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BfoAZW9X.js +292 -0
  715. ksadk/studio/static/assets/gitGraph-4MIJSDKK-DYlXv_yJ.js +1 -0
  716. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-S985OIJF.js +106 -0
  717. ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
  718. ksadk/studio/static/assets/iconfont-4HN3C9Pg.woff2 +0 -0
  719. ksadk/studio/static/assets/index-CfEnms6Y.css +2 -0
  720. ksadk/studio/static/assets/index-Dp61rOWZ.js +0 -0
  721. ksadk/studio/static/assets/index.dom-BQenBtFm.js +1 -0
  722. ksadk/studio/static/assets/info-A6RAGUB7-BlU-8_xu.js +1 -0
  723. ksadk/studio/static/assets/infoDiagram-27XIBGKW-CO3W8tFn.js +2 -0
  724. ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
  725. ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-BUGEl8cO.js +70 -0
  726. ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-Ch2ZYxvr.js +139 -0
  727. ksadk/studio/static/assets/kanban-definition-UXKFOSKX-Da-Fp4vC.js +89 -0
  728. ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
  729. ksadk/studio/static/assets/kingsoft-cloud-BOcLiQ3e.ico +0 -0
  730. ksadk/studio/static/assets/line-BDaeq300.js +1 -0
  731. ksadk/studio/static/assets/linear-DmucvK78.js +1 -0
  732. ksadk/studio/static/assets/mermaid-parser.core-Cj5mYdBi.js +4 -0
  733. ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-CvlsVQ38.js +96 -0
  734. ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
  735. ksadk/studio/static/assets/packet-AYTQ26CC-BSJEH9Lb.js +1 -0
  736. ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
  737. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-BuHuNgT5.js +1 -0
  738. ksadk/studio/static/assets/pie-WAS4IAKB-qxv01Y8W.js +1 -0
  739. ksadk/studio/static/assets/pieDiagram-E7YTZNPT-DlrWiSOv.js +39 -0
  740. ksadk/studio/static/assets/preload-helper-CO68xz6u.js +1 -0
  741. ksadk/studio/static/assets/presentation-yYw7xK60-BmcZriri.js +1 -0
  742. ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-BA3hpUZM.js +7 -0
  743. ksadk/studio/static/assets/radar-RG4KPBEZ-B6h6pWOs.js +1 -0
  744. ksadk/studio/static/assets/railroad-74A4TZTK-CGtTWdGc.js +1 -0
  745. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-Cq7y22IA.js +1 -0
  746. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-V0aQVv9m.js +1 -0
  747. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-BQiIsX_p.js +1 -0
  748. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-BxpAazym.js +1 -0
  749. ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-E-Ge0FcV.js +84 -0
  750. ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
  751. ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
  752. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-CA6YKhQ3.js +40 -0
  753. ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-CcElXGg4.js +162 -0
  754. ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  755. ksadk/studio/static/assets/src-B6xuSHsQ.js +1 -0
  756. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DdXZOFqY.js +1 -0
  757. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-CJbOM-QK.js +1 -0
  758. ksadk/studio/static/assets/swimlanes-42K2YHIH-NtgEEHLY.js +1 -0
  759. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-D-AVlW8B.js +8 -0
  760. ksadk/studio/static/assets/timeline-definition-24CTP7MA-CIuYhNy3.js +120 -0
  761. ksadk/studio/static/assets/treeView-Q6P3EWNA-BTTYcvrF.js +1 -0
  762. ksadk/studio/static/assets/treemap-WGGIJYW6-Cg7tyfH8.js +1 -0
  763. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-7HbApbrv.js +34 -0
  764. ksadk/studio/static/assets/wardley-WFR3VGLG-C6N1rULY.js +1 -0
  765. ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-CMJiaedy.js +78 -0
  766. ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-BdgtMvW2.js +7 -0
  767. ksadk/studio/static/index.html +8 -2
  768. ksadk/studio/teams_catalog.py +133 -0
  769. ksadk/studio/teams_installation.py +214 -0
  770. ksadk/studio/teams_node.py +545 -0
  771. ksadk/studio/teams_node_runner.py +69 -0
  772. ksadk/studio/teams_remote.py +274 -0
  773. ksadk/studio/templates.py +40 -19
  774. ksadk/studio/validator.py +13 -0
  775. ksadk/studio/workspace.py +19 -4
  776. ksadk/studio/workspace_plugins.py +136 -0
  777. ksadk/studio/workspace_registry.py +286 -0
  778. ksadk/toolsets/__init__.py +11 -0
  779. ksadk/toolsets/skills.py +446 -378
  780. ksadk/toolsets/workspace.py +3 -3
  781. ksadk/toolsets/workspace_identity.py +15 -0
  782. ksadk/version.py +1 -1
  783. ksadk_runtime_common/memory_backend/providers/lancedb.py +56 -2
  784. ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -148
  785. ksadk_runtime_common/workspace_files/router.py +26 -13
  786. agentengine_sdk_python-0.8.3.dist-info/RECORD +0 -833
  787. ksadk/server/static/assets/MathMessageMarkdown-D9uB55Oh.js +0 -8
  788. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +0 -1
  789. ksadk/server/static/assets/channel-s354Yo6o.js +0 -1
  790. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +0 -1
  791. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +0 -1
  792. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +0 -1
  793. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +0 -1
  794. ksadk/server/static/assets/dist-DdRBIceA.js +0 -1
  795. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +0 -1
  796. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +0 -1
  797. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +0 -1
  798. ksadk/server/static/assets/index-B2k_urY8.js +0 -241
  799. ksadk/server/static/assets/index-ILPt6IWF.css +0 -2
  800. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +0 -1
  801. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +0 -1
  802. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +0 -1
  803. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +0 -1
  804. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +0 -1
  805. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +0 -1
  806. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +0 -1
  807. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +0 -1
  808. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +0 -1
  809. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +0 -8
  810. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +0 -1
  811. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +0 -1
  812. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +0 -1
  813. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
  814. ksadk/studio/static/assets/index-DXs1Eq4M.css +0 -1
  815. ksadk/studio/static/assets/index-DeDqwTsD.js +0 -283
  816. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.5.dist-info}/WHEEL +0 -0
  817. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.5.dist-info}/entry_points.txt +0 -0
  818. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.5.dist-info}/licenses/LICENSE +0 -0
  819. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.5.dist-info}/top_level.txt +0 -0
@@ -2,13 +2,27 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import os
5
6
  from collections.abc import Mapping
6
7
  from typing import Any
7
8
 
8
- from fastapi import HTTPException
9
+ from fastapi import Depends, HTTPException
9
10
 
11
+ from ksadk.conversations.runtime_persistence import (
12
+ ensure_conversation_session,
13
+ require_conversation_session,
14
+ )
15
+ from ksadk.runtime.executor import project_legacy_runtime_capabilities
16
+ from ksadk.runtime_context import PlatformIdentityContext
10
17
  from ksadk.server.factory import get_runtime_execution, get_state
11
18
  from ksadk.sessions import SessionEvent
19
+ from ksadk.sessions.base import CheckpointEventQuery, SessionEventQuery
20
+ from ksadk.sessions.errors import CheckpointScanRestartRequired, SessionBackendUnavailable
21
+ from ksadk.sessions.invocation_identity import (
22
+ bind_or_validate_session_identity,
23
+ identity_can_adopt_any_legacy_user,
24
+ session_identity_binding_matches,
25
+ )
12
26
  from ksadk.tools.gateway import tool_approval_capability
13
27
  from ksadk.toolsets import describe_agentengine_tools
14
28
  from ksadk_runtime_common.workspace_files import (
@@ -16,6 +30,7 @@ from ksadk_runtime_common.workspace_files import (
16
30
  workspace_files_enabled,
17
31
  )
18
32
 
33
+ from ..invocation_identity import resolve_trusted_invocation_identity
19
34
  from . import dependencies as deps
20
35
  from .common import (
21
36
  _action_response,
@@ -34,10 +49,10 @@ from .models import (
34
49
  ListToolReceiptsActionRequest,
35
50
  SessionIdRequest,
36
51
  UiBootstrapRequest,
37
- _event_run_id,
38
52
  _runtime_agent_id,
39
53
  )
40
54
  from .projection import (
55
+ _apply_adk_only_latest_resumable,
41
56
  _apply_checkpoint_resume_audit,
42
57
  _apply_latest_checkpoint_policy,
43
58
  _checkpoint_event_to_action_payload,
@@ -45,10 +60,9 @@ from .projection import (
45
60
  _event_to_action_payload,
46
61
  _extend_invocation_after_window,
47
62
  _extend_invocation_before_window,
48
- _iter_scoped_event_pages,
49
63
  _iter_session_event_pages,
50
- _record_resume_audit,
51
64
  _require_action_session,
65
+ _resume_audit_by_checkpoint,
52
66
  _session_to_action_payload,
53
67
  _tool_receipt_event_to_action_payload,
54
68
  )
@@ -56,8 +70,91 @@ from .routers import sessions_router, tools_router, ui_bootstrap_router
56
70
  from .streaming import _cancel_detached_streams_for_session
57
71
 
58
72
 
73
+ async def _require_identity_action_session(
74
+ service: Any,
75
+ *,
76
+ session_id: str,
77
+ agent_id: str | None,
78
+ user_id: str | None,
79
+ invocation_identity: PlatformIdentityContext,
80
+ ):
81
+ if invocation_identity.is_empty:
82
+ return await _require_action_session(
83
+ service,
84
+ session_id=session_id,
85
+ agent_id=agent_id,
86
+ user_id=user_id,
87
+ )
88
+ if not agent_id:
89
+ raise HTTPException(status_code=400, detail="AgentId is required")
90
+ return await require_conversation_session(
91
+ agent_id=agent_id,
92
+ user_id=str(user_id or ""),
93
+ session_id=session_id,
94
+ session_service_provider=lambda: service,
95
+ invocation_identity=invocation_identity,
96
+ )
97
+
98
+
99
+ async def _list_identity_session_metadata(
100
+ service: Any,
101
+ *,
102
+ agent_id: str,
103
+ user_id: str | None,
104
+ invocation_identity: PlatformIdentityContext,
105
+ ) -> list[Any]:
106
+ """List bound sessions; only the verified IAM account may adopt legacy rows."""
107
+
108
+ if invocation_identity.is_empty:
109
+ return await service.list_session_metadata(agent_id, user_id)
110
+ from ksadk.sessions.invocation_identity import identity_native_user_id
111
+
112
+ candidate_users: set[str | None] = {identity_native_user_id(invocation_identity)}
113
+ if identity_can_adopt_any_legacy_user(invocation_identity):
114
+ candidate_users.add(None)
115
+ elif (
116
+ invocation_identity.identity_namespace == "kscloud-iam"
117
+ and invocation_identity.subject_type == "user"
118
+ ):
119
+ candidate_users.add(invocation_identity.subject_id)
120
+ sessions: list[Any] = []
121
+ seen: set[str] = set()
122
+ for candidate_user in candidate_users:
123
+ for session in await service.list_session_metadata(agent_id, candidate_user):
124
+ if session.id in seen:
125
+ continue
126
+ matches = await session_identity_binding_matches(
127
+ service=service,
128
+ session=session,
129
+ identity=invocation_identity,
130
+ )
131
+ if not matches:
132
+ try:
133
+ await bind_or_validate_session_identity(
134
+ service=service,
135
+ session=session,
136
+ identity=invocation_identity,
137
+ requested_user_id=session.user_id,
138
+ )
139
+ except HTTPException:
140
+ matches = False
141
+ else:
142
+ matches = True
143
+ if matches:
144
+ sessions.append(session)
145
+ seen.add(session.id)
146
+ sessions.sort(
147
+ key=lambda item: (item.updated_at, item.created_at, item.id),
148
+ reverse=True,
149
+ )
150
+ return sessions
151
+
152
+
59
153
  @ui_bootstrap_router.post("/agentengine/api/v1/GetAgentUiBootstrap")
60
- async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
154
+ async def get_agent_ui_bootstrap(
155
+ request: UiBootstrapRequest,
156
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
157
+ ):
61
158
  state = get_state()
62
159
  executor, launch_context = get_runtime_execution()
63
160
  detection = launch_context.detection
@@ -66,12 +163,34 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
66
163
  framework = launch_context.runtime_type.strip().lower()
67
164
  workspace_enabled = workspace_files_enabled(default=True)
68
165
  ui_spec = _resolve_agent_ui_spec()
69
- runtime_capabilities = executor.native_capabilities(launch_context)
70
- runtime_capability_matrix = executor.capability_matrix(launch_context)
166
+ capability_subject = executor.capability_subject(launch_context)
167
+ if capability_subject is not None:
168
+ wait_timeout = max(0.1, float(os.getenv("KSADK_PERSISTENCE_PROBE_TIMEOUT") or "2"))
169
+ capability_snapshot = await state.persistence_capability.get_snapshot(
170
+ runner=capability_subject,
171
+ framework=framework,
172
+ status_provider=deps.get_persistence_status,
173
+ session_service_provider=deps.resolve_session_service,
174
+ wait_timeout=wait_timeout,
175
+ )
176
+ persistence = dict(capability_snapshot.session_persistence)
177
+ checkpoint_persistence = dict(capability_snapshot.checkpoint_persistence)
178
+ runtime_capabilities = dict(capability_snapshot.runtime_capabilities)
179
+ runtime_capability_matrix = executor.capability_matrix(launch_context)
180
+ else:
181
+ runtime_capability_matrix = executor.capability_matrix(launch_context)
182
+ persistence_status = dict(await deps.get_persistence_status(framework=framework))
183
+ if isinstance(persistence_status.get("Session"), Mapping):
184
+ persistence = dict(persistence_status["Session"])
185
+ checkpoint_persistence = dict(persistence_status.get("Checkpoint") or {})
186
+ else:
187
+ persistence = persistence_status
188
+ checkpoint_persistence = dict(persistence_status)
189
+ runtime_capabilities = project_legacy_runtime_capabilities(
190
+ executor.native_capabilities(launch_context), runtime_capability_matrix
191
+ )
71
192
  resume_capability = (
72
- runtime_capabilities.get("ResumeRun")
73
- if isinstance(runtime_capabilities, Mapping)
74
- else None
193
+ runtime_capabilities.get("ResumeRun") if isinstance(runtime_capabilities, Mapping) else None
75
194
  )
76
195
  resume_capability = resume_capability if isinstance(resume_capability, Mapping) else {}
77
196
  checkpoint_capability = (
@@ -83,9 +202,7 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
83
202
  checkpoint_capability if isinstance(checkpoint_capability, Mapping) else {}
84
203
  )
85
204
  cancel_capability = (
86
- runtime_capabilities.get("CancelRun")
87
- if isinstance(runtime_capabilities, Mapping)
88
- else None
205
+ runtime_capabilities.get("CancelRun") if isinstance(runtime_capabilities, Mapping) else None
89
206
  )
90
207
  cancel_capability = cancel_capability if isinstance(cancel_capability, Mapping) else {}
91
208
  checkpoint_resume_capability = {
@@ -148,6 +265,8 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
148
265
  "Thinking": True,
149
266
  "StopRun": cancel_run_supported,
150
267
  "ResumeRun": checkpoint_resume_supported,
268
+ "Persistence": persistence,
269
+ "CheckpointPersistence": checkpoint_persistence,
151
270
  "RuntimeCapabilities": runtime_capabilities,
152
271
  "RuntimeCapabilityMatrix": runtime_capability_matrix,
153
272
  "CheckpointResumeCapability": checkpoint_resume_capability,
@@ -161,7 +280,7 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
161
280
  },
162
281
  "MCP": False,
163
282
  "HostedRuntime": False,
164
- "NativeTerminal": _build_native_terminal_capability(framework),
283
+ "NativeTerminal": _build_native_terminal_capability(framework, invocation_identity),
165
284
  "BuiltinTools": describe_agentengine_tools(),
166
285
  },
167
286
  "WorkspaceFiles": build_workspace_files_bootstrap(enabled=workspace_enabled),
@@ -193,22 +312,49 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
193
312
 
194
313
 
195
314
  @sessions_router.post("/agentengine/api/v1/CreateSession")
196
- async def create_session_action(request: CreateSessionActionRequest):
197
- session = await _ensure_session(request.AgentId, request.UserId or "user", request.SessionId)
315
+ async def create_session_action(
316
+ request: CreateSessionActionRequest,
317
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
318
+ ):
319
+ if invocation_identity.is_empty:
320
+ session = await _ensure_session(
321
+ request.AgentId, request.UserId or "user", request.SessionId
322
+ )
323
+ else:
324
+ session = await ensure_conversation_session(
325
+ agent_id=request.AgentId,
326
+ user_id=request.UserId or "user",
327
+ session_id=request.SessionId,
328
+ session_service_provider=deps.resolve_session_service,
329
+ invocation_identity=invocation_identity,
330
+ )
198
331
  return _action_response("CreateSession", {"Session": await _session_to_action_payload(session)})
199
332
 
200
333
 
201
334
  @sessions_router.post("/agentengine/api/v1/ListSessions")
202
- async def list_sessions_action(request: ListSessionsActionRequest):
335
+ async def list_sessions_action(
336
+ request: ListSessionsActionRequest,
337
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
338
+ ):
203
339
  service = deps.resolve_session_service()
204
340
  offset = (request.Page - 1) * request.PageSize
205
- sessions = await service.list_sessions(
206
- request.AgentId,
207
- request.UserId,
208
- offset=offset,
209
- limit=request.PageSize,
210
- )
211
- total = await service.count_sessions(request.AgentId, request.UserId)
341
+ if invocation_identity.is_empty:
342
+ sessions = await service.list_sessions(
343
+ request.AgentId,
344
+ request.UserId,
345
+ offset=offset,
346
+ limit=request.PageSize,
347
+ )
348
+ total = await service.count_sessions(request.AgentId, request.UserId)
349
+ else:
350
+ all_sessions = await _list_identity_session_metadata(
351
+ service,
352
+ agent_id=request.AgentId,
353
+ user_id=request.UserId,
354
+ invocation_identity=invocation_identity,
355
+ )
356
+ total = len(all_sessions)
357
+ sessions = all_sessions[offset : offset + request.PageSize]
212
358
  session_payloads = [await _session_to_action_payload(session) for session in sessions]
213
359
  return _action_response(
214
360
  "ListSessions",
@@ -225,13 +371,17 @@ async def list_sessions_action(request: ListSessionsActionRequest):
225
371
 
226
372
 
227
373
  @sessions_router.post("/agentengine/api/v1/GetSession")
228
- async def get_session_action(request: SessionIdRequest):
374
+ async def get_session_action(
375
+ request: SessionIdRequest,
376
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
377
+ ):
229
378
  service = deps.resolve_session_service()
230
- session = await _require_action_session(
379
+ session = await _require_identity_action_session(
231
380
  service,
232
381
  session_id=request.SessionId,
233
382
  agent_id=request.AgentId,
234
383
  user_id=request.UserId,
384
+ invocation_identity=invocation_identity,
235
385
  )
236
386
  hydrated = await _hydrate_session(session)
237
387
  if hydrated is None:
@@ -240,13 +390,17 @@ async def get_session_action(request: SessionIdRequest):
240
390
 
241
391
 
242
392
  @sessions_router.post("/agentengine/api/v1/DeleteSession")
243
- async def delete_session_action(request: SessionIdRequest):
393
+ async def delete_session_action(
394
+ request: SessionIdRequest,
395
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
396
+ ):
244
397
  service = deps.resolve_session_service()
245
- await _require_action_session(
398
+ await _require_identity_action_session(
246
399
  service,
247
400
  session_id=request.SessionId,
248
401
  agent_id=request.AgentId,
249
402
  user_id=request.UserId,
403
+ invocation_identity=invocation_identity,
250
404
  )
251
405
  await _cancel_detached_streams_for_session(request.SessionId)
252
406
  deleted = await service.delete_session(request.SessionId)
@@ -256,21 +410,66 @@ async def delete_session_action(request: SessionIdRequest):
256
410
 
257
411
 
258
412
  @sessions_router.post("/agentengine/api/v1/ListSessionEvents")
259
- async def list_session_events_action(request: ListSessionEventsActionRequest):
413
+ async def list_session_events_action(
414
+ request: ListSessionEventsActionRequest,
415
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
416
+ ):
260
417
  _executor, launch_context = get_runtime_execution()
261
418
  service = deps.resolve_session_service()
262
419
  session_id = str(request.SessionId or "").strip()
420
+ event_types = request.EventTypes or None
421
+ checkpoint_ids = request.CheckpointIds or None
263
422
  if not session_id:
264
423
  # 未传 SessionId:返回该 agent 全部会话的事件(存储层跨会话查询,真分页无截断;
265
424
  # seq 游标是会话内序号,跨会话模式下不适用,直接忽略)
266
425
  agent_id = str(request.AgentId or "").strip() or _runtime_agent_id(launch_context)
267
- events = await service.get_events_for_agent(
268
- agent_id,
269
- user_id=request.UserId,
270
- offset=request.Offset,
426
+ session_ids = None
427
+ if request.UserId is not None or not invocation_identity.is_empty:
428
+ session_ids = [
429
+ session.id
430
+ for session in await _list_identity_session_metadata(
431
+ service,
432
+ agent_id=agent_id,
433
+ user_id=request.UserId,
434
+ invocation_identity=invocation_identity,
435
+ )
436
+ ]
437
+ if not invocation_identity.is_empty and not session_ids:
438
+ return _action_response(
439
+ "ListSessionEvents",
440
+ {
441
+ "Events": [],
442
+ "Total": 0,
443
+ "Offset": request.Offset or 0,
444
+ "Limit": request.Limit or 0,
445
+ "AfterSeqId": request.AfterSeqId,
446
+ "BeforeSeqId": request.BeforeSeqId,
447
+ "CheckpointIds": request.CheckpointIds,
448
+ "EventTypes": request.EventTypes,
449
+ "ScopedAllSessions": True,
450
+ },
451
+ )
452
+ query = SessionEventQuery(
453
+ session_ids=session_ids,
454
+ agent_id=agent_id,
455
+ offset=request.Offset or 0,
271
456
  limit=request.Limit,
457
+ event_types=event_types,
458
+ checkpoint_ids=checkpoint_ids,
459
+ )
460
+ events = await service.query_events(query)
461
+ total = await service.count_event_query(
462
+ SessionEventQuery(
463
+ session_ids=session_ids,
464
+ agent_id=agent_id,
465
+ event_types=event_types,
466
+ checkpoint_ids=checkpoint_ids,
467
+ )
468
+ )
469
+ events.sort(
470
+ key=lambda event: (event.timestamp, event.session_id, event.seq_id, event.id),
471
+ reverse=True,
272
472
  )
273
- total = await service.count_events_for_agent(agent_id, user_id=request.UserId)
274
473
  return _action_response(
275
474
  "ListSessionEvents",
276
475
  {
@@ -280,26 +479,42 @@ async def list_session_events_action(request: ListSessionEventsActionRequest):
280
479
  "Limit": request.Limit if request.Limit is not None else len(events),
281
480
  "AfterSeqId": request.AfterSeqId,
282
481
  "BeforeSeqId": request.BeforeSeqId,
482
+ "CheckpointIds": request.CheckpointIds,
483
+ "EventTypes": request.EventTypes,
283
484
  "ScopedAllSessions": True,
284
485
  },
285
486
  )
286
- await _require_action_session(
487
+ await _require_identity_action_session(
287
488
  service,
288
489
  session_id=session_id,
289
490
  agent_id=request.AgentId,
290
491
  user_id=request.UserId,
492
+ invocation_identity=invocation_identity,
291
493
  )
292
- events = await service.get_events(
293
- session_id,
294
- offset=request.Offset,
494
+ query = SessionEventQuery(
495
+ session_ids=[session_id],
496
+ agent_id=request.AgentId,
497
+ offset=request.Offset or 0,
295
498
  limit=request.Limit,
296
499
  after_seq_id=request.AfterSeqId,
297
500
  before_seq_id=request.BeforeSeqId,
501
+ event_types=event_types,
502
+ checkpoint_ids=checkpoint_ids,
298
503
  )
299
- total = await service.count_events(
300
- session_id,
301
- after_seq_id=request.AfterSeqId,
302
- before_seq_id=request.BeforeSeqId,
504
+ events = await service.query_events(query)
505
+ total = await service.count_event_query(
506
+ SessionEventQuery(
507
+ session_ids=[session_id],
508
+ agent_id=request.AgentId,
509
+ after_seq_id=request.AfterSeqId,
510
+ before_seq_id=request.BeforeSeqId,
511
+ event_types=event_types,
512
+ checkpoint_ids=checkpoint_ids,
513
+ )
514
+ )
515
+ events.sort(
516
+ key=lambda event: (event.timestamp, event.session_id, event.seq_id, event.id),
517
+ reverse=True,
303
518
  )
304
519
  return _action_response(
305
520
  "ListSessionEvents",
@@ -310,20 +525,26 @@ async def list_session_events_action(request: ListSessionEventsActionRequest):
310
525
  "Limit": request.Limit if request.Limit is not None else len(events),
311
526
  "AfterSeqId": request.AfterSeqId,
312
527
  "BeforeSeqId": request.BeforeSeqId,
528
+ "CheckpointIds": request.CheckpointIds,
529
+ "EventTypes": request.EventTypes,
313
530
  },
314
531
  )
315
532
 
316
533
 
317
534
  @sessions_router.post("/agentengine/api/v1/ListSessionMessages")
318
- async def list_session_messages_action(request: ListSessionMessagesActionRequest):
535
+ async def list_session_messages_action(
536
+ request: ListSessionMessagesActionRequest,
537
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
538
+ ):
319
539
  from ksadk.conversations.message_projection import project_session_messages
320
540
 
321
541
  service = deps.resolve_session_service()
322
- await _require_action_session(
542
+ await _require_identity_action_session(
323
543
  service,
324
544
  session_id=request.SessionId,
325
545
  agent_id=request.AgentId,
326
546
  user_id=request.UserId,
547
+ invocation_identity=invocation_identity,
327
548
  )
328
549
  total_events = await service.count_events(
329
550
  request.SessionId,
@@ -352,6 +573,7 @@ async def list_session_messages_action(request: ListSessionMessagesActionRequest
352
573
  include_reasoning=request.IncludeReasoning,
353
574
  include_tool_events=request.IncludeToolEvents,
354
575
  include_attachments=request.IncludeAttachments,
576
+ session_id=request.SessionId,
355
577
  )
356
578
 
357
579
  serialized_events, messages = project(events)
@@ -470,132 +692,263 @@ def _count_resumable_checkpoints(checkpoints: list[dict[str, Any]]) -> int:
470
692
  return resumable
471
693
 
472
694
 
473
- async def _list_checkpoints_payload(request: ListSessionCheckpointsActionRequest) -> dict[str, Any]:
474
- service = deps.resolve_session_service()
475
- run_id_filter = str(request.RunId or "").strip()
476
- framework_filter = str(request.Framework or "").strip().lower()
695
+ def _normalize_action_id_list(value: list[str] | str | None) -> list[str]:
696
+ values = [value] if isinstance(value, str) else list(value or [])
697
+ return list(dict.fromkeys(str(item).strip() for item in values if str(item).strip()))
477
698
 
478
- session_id = str(request.SessionId or "").strip()
479
- if session_id:
480
- await _require_action_session(
481
- service,
482
- session_id=session_id,
483
- agent_id=request.AgentId,
484
- user_id=request.UserId,
485
- )
486
699
 
487
- audit_by_session: dict[str, dict[tuple[str, str], dict[str, Any]]] = {}
700
+ def _is_checkpoint_resumable(checkpoint: Mapping[str, Any]) -> bool:
701
+ if checkpoint.get("IsResumable") is not True or checkpoint.get("IsTerminal") is True:
702
+ return False
703
+ if checkpoint.get("ReplayAllowed") is False:
704
+ return False
705
+ checkpoint_status = str(checkpoint.get("CheckpointStatus") or "").strip().lower()
706
+ resume_status = str(checkpoint.get("ResumeStatus") or "").strip().lower()
707
+ return (
708
+ checkpoint_status not in {"expired", "disabled", "terminal"} and resume_status != "disabled"
709
+ )
710
+
711
+
712
+ async def _list_checkpoints_payload_legacy_filtered(
713
+ request: ListSessionCheckpointsActionRequest,
714
+ session_ids: list[str],
715
+ checkpoint_ids: list[str],
716
+ ) -> dict[str, Any]:
717
+ if len(session_ids) != 1:
718
+ raise HTTPException(
719
+ status_code=501, detail="Backend does not support multi-session checkpoints"
720
+ )
721
+ service = deps.resolve_session_service()
722
+ events = await service.get_events(session_ids[0])
723
+ audit = _resume_audit_by_checkpoint(events)
488
724
  latest_by_session_run: dict[tuple[str, str], int] = {}
489
- run_seen = not run_id_filter
490
- async for page in _iter_scoped_event_pages(
491
- service,
492
- session_id=session_id or None,
493
- agent_id=request.AgentId,
494
- user_id=request.UserId,
495
- ):
496
- for event in page:
497
- if run_id_filter and _event_run_id(event) == run_id_filter:
498
- run_seen = True
499
- _record_resume_audit(audit_by_session, event)
500
- checkpoint = _checkpoint_event_to_action_payload(event)
501
- if checkpoint is None or not (checkpoint.get("Metadata") or {}).get(
502
- "only_latest_resumable"
503
- ):
504
- continue
725
+ for event in events:
726
+ checkpoint = _checkpoint_event_to_action_payload(event)
727
+ if checkpoint is not None and (checkpoint.get("Metadata") or {}).get(
728
+ "only_latest_resumable"
729
+ ):
505
730
  key = (event.session_id, str(checkpoint.get("RunId") or ""))
506
731
  latest_by_session_run[key] = max(
507
- latest_by_session_run.get(key, 0),
508
- int(checkpoint.get("SeqId") or 0),
732
+ latest_by_session_run.get(key, 0), int(checkpoint.get("SeqId") or 0)
509
733
  )
510
- if session_id and not run_seen:
511
- raise HTTPException(status_code=409, detail="RunId does not belong to SessionId")
512
-
513
- def project_checkpoint(event: SessionEvent) -> dict[str, Any] | None:
734
+ checkpoints: list[dict[str, Any]] = []
735
+ resume_status_filter = set(request.ResumeStatus)
736
+ resume_type_filter = set(request.ResumeTypes)
737
+ for event in events:
514
738
  checkpoint = _checkpoint_event_to_action_payload(event)
515
739
  if checkpoint is None:
516
- return None
517
- checkpoint = _apply_checkpoint_resume_audit(
518
- checkpoint,
519
- audit_by_session.get(event.session_id, {}),
520
- )
740
+ continue
741
+ checkpoint = _apply_checkpoint_resume_audit(checkpoint, audit)
521
742
  checkpoint = _apply_latest_checkpoint_policy(
522
- checkpoint,
523
- latest_by_session_run,
524
- session_id=event.session_id,
743
+ checkpoint, latest_by_session_run, session_id=event.session_id
525
744
  )
526
- if run_id_filter and checkpoint["RunId"] != run_id_filter:
527
- return None
528
- if framework_filter and str(checkpoint["Framework"]).lower() != framework_filter:
529
- return None
530
- return checkpoint
745
+ if request.RunId and checkpoint["RunId"] != str(request.RunId):
746
+ continue
747
+ if checkpoint_ids and checkpoint["CheckpointId"] not in checkpoint_ids:
748
+ continue
749
+ if (
750
+ request.Framework
751
+ and str(checkpoint["Framework"]).lower() != str(request.Framework).lower()
752
+ ):
753
+ continue
754
+ if (
755
+ resume_status_filter
756
+ and str(checkpoint.get("ResumeStatus") or "").lower() not in resume_status_filter
757
+ ):
758
+ continue
759
+ if (
760
+ resume_type_filter
761
+ and str(checkpoint.get("Scope") or "unknown").lower() not in resume_type_filter
762
+ ):
763
+ continue
764
+ checkpoints.append(checkpoint)
765
+ checkpoints = _apply_adk_only_latest_resumable(checkpoints)
766
+ resumable_total = sum(_is_checkpoint_resumable(item) for item in checkpoints)
767
+ if request.OnlyResumable:
768
+ checkpoints = [item for item in checkpoints if _is_checkpoint_resumable(item)]
769
+ offset = int(request.Offset or 0)
770
+ checkpoints.sort(
771
+ key=lambda item: (item["Timestamp"], item["SessionId"], item["SeqId"]),
772
+ reverse=True,
773
+ )
774
+ checkpoints = checkpoints[offset : offset + request.Limit]
775
+ return {
776
+ "Checkpoints": checkpoints,
777
+ "Total": len(checkpoints),
778
+ "ResumableTotal": resumable_total,
779
+ "HasResumableCheckpoint": resumable_total > 0,
780
+ "SessionId": session_ids,
781
+ "CheckpointId": checkpoint_ids,
782
+ "ResumeStatus": request.ResumeStatus,
783
+ "ResumeTypes": request.ResumeTypes,
784
+ "Offset": offset,
785
+ "Limit": request.Limit,
786
+ }
531
787
 
532
- total = 0
533
- resumable_total = 0
534
- async for page in _iter_scoped_event_pages(
535
- service,
536
- session_id=session_id or None,
537
- agent_id=request.AgentId,
538
- user_id=request.UserId,
539
- ):
540
- for event in page:
541
- checkpoint = project_checkpoint(event)
542
- if checkpoint is None:
543
- continue
544
- if checkpoint.get("IsResumable") is True:
545
- resumable_total += 1
546
- if request.OnlyResumable and checkpoint.get("IsResumable") is not True:
547
- continue
548
- total += 1
549
788
 
550
- offset = int(request.Offset or 0)
551
- limit = int(request.Limit)
552
- window_end = max(total - offset, 0)
553
- window_start = max(window_end - limit, 0)
554
- checkpoints: list[dict[str, Any]] = []
555
- filtered_index = 0
556
- async for page in _iter_scoped_event_pages(
557
- service,
558
- session_id=session_id or None,
789
+ async def _list_checkpoints_payload(
790
+ request: ListSessionCheckpointsActionRequest,
791
+ invocation_identity: PlatformIdentityContext,
792
+ ) -> dict[str, Any]:
793
+ service = deps.resolve_session_service()
794
+ session_ids = _normalize_action_id_list(request.SessionId)
795
+ checkpoint_ids = _normalize_action_id_list(request.CheckpointId)
796
+ if session_ids:
797
+ for session_id in session_ids:
798
+ await _require_identity_action_session(
799
+ service,
800
+ session_id=session_id,
801
+ agent_id=request.AgentId,
802
+ user_id=request.UserId,
803
+ invocation_identity=invocation_identity,
804
+ )
805
+ elif request.UserId is not None or not invocation_identity.is_empty:
806
+ session_ids = [
807
+ session.id
808
+ for session in await _list_identity_session_metadata(
809
+ service,
810
+ agent_id=request.AgentId,
811
+ user_id=request.UserId,
812
+ invocation_identity=invocation_identity,
813
+ )
814
+ ]
815
+ if not invocation_identity.is_empty and not session_ids:
816
+ return {
817
+ "Checkpoints": [],
818
+ "Total": 0,
819
+ "ResumableTotal": 0,
820
+ "HasResumableCheckpoint": False,
821
+ "SessionId": [],
822
+ "CheckpointId": checkpoint_ids,
823
+ "ResumeStatus": request.ResumeStatus,
824
+ "ResumeTypes": request.ResumeTypes,
825
+ "Offset": int(request.Offset or 0),
826
+ "Limit": request.Limit,
827
+ }
828
+ query = CheckpointEventQuery(
829
+ session_ids=session_ids or None,
559
830
  agent_id=request.AgentId,
560
- user_id=request.UserId,
561
- ):
562
- for event in page:
563
- checkpoint = project_checkpoint(event)
564
- if checkpoint is None:
565
- continue
566
- if request.OnlyResumable and checkpoint.get("IsResumable") is not True:
831
+ checkpoint_ids=checkpoint_ids or None,
832
+ run_id=str(request.RunId or "").strip() or None,
833
+ framework=str(request.Framework or "").strip().lower() or None,
834
+ limit=50,
835
+ )
836
+ resume_status_filter = set(request.ResumeStatus)
837
+ resume_type_filter = set(request.ResumeTypes)
838
+ offset = int(request.Offset or 0)
839
+ for attempt in range(2):
840
+ total = 0
841
+ resumable_total = 0
842
+ checkpoints: list[dict[str, Any]] = []
843
+ batches = service.iter_checkpoint_event_chunks(query)
844
+ try:
845
+ async for batch in batches:
846
+ chunk = [
847
+ checkpoint
848
+ for event in batch
849
+ if (checkpoint := _checkpoint_event_to_action_payload(event)) is not None
850
+ and (
851
+ not checkpoint_ids
852
+ or str(checkpoint.get("CheckpointId") or "") in checkpoint_ids
853
+ )
854
+ and (query.run_id is None or str(checkpoint.get("RunId") or "") == query.run_id)
855
+ and (
856
+ query.framework is None
857
+ or str(checkpoint.get("Framework") or "").lower() == query.framework
858
+ )
859
+ ]
860
+ keys = [
861
+ (
862
+ str(checkpoint["SessionId"]),
863
+ str(checkpoint["RunId"]),
864
+ str(checkpoint["CheckpointId"]),
865
+ )
866
+ for checkpoint in chunk
867
+ ]
868
+ stats = await service.get_checkpoint_stats(keys)
869
+ for checkpoint in chunk:
870
+ checkpoint = _apply_checkpoint_resume_audit(
871
+ checkpoint, stats.get("audits") or {}
872
+ )
873
+ checkpoint = _apply_latest_checkpoint_policy(
874
+ checkpoint,
875
+ stats.get("latest_seq_ids") or {},
876
+ session_id=str(checkpoint.get("SessionId") or ""),
877
+ )
878
+ if (
879
+ resume_status_filter
880
+ and str(checkpoint.get("ResumeStatus") or "").strip().lower()
881
+ not in resume_status_filter
882
+ ):
883
+ continue
884
+ if (
885
+ resume_type_filter
886
+ and str(checkpoint.get("Scope") or "unknown").strip().lower()
887
+ not in resume_type_filter
888
+ ):
889
+ continue
890
+ resumable_total += int(_is_checkpoint_resumable(checkpoint))
891
+ if request.OnlyResumable and not _is_checkpoint_resumable(checkpoint):
892
+ continue
893
+ checkpoints.append(checkpoint)
894
+ total += 1
895
+ except CheckpointScanRestartRequired as exc:
896
+ if attempt == 0:
567
897
  continue
568
- if window_start <= filtered_index < window_end:
569
- checkpoints.append(checkpoint)
570
- filtered_index += 1
571
- if filtered_index >= window_end:
572
- break
573
- if filtered_index >= window_end:
574
- break
575
-
898
+ raise SessionBackendUnavailable(
899
+ "Checkpoint backend changed repeatedly during one request"
900
+ ) from exc
901
+ except NotImplementedError:
902
+ return await _list_checkpoints_payload_legacy_filtered(
903
+ request, session_ids, checkpoint_ids
904
+ )
905
+ finally:
906
+ close = getattr(batches, "aclose", None)
907
+ if callable(close):
908
+ await close()
909
+ break
910
+ checkpoints.sort(
911
+ key=lambda item: (item["Timestamp"], item["SessionId"], item["SeqId"]),
912
+ reverse=True,
913
+ )
914
+ checkpoints = checkpoints[offset : offset + int(request.Limit)]
576
915
  return {
577
916
  "Checkpoints": checkpoints,
578
917
  "Total": total,
579
918
  "ResumableTotal": resumable_total,
580
919
  "HasResumableCheckpoint": resumable_total > 0,
920
+ "SessionId": session_ids,
921
+ "CheckpointId": checkpoint_ids,
922
+ "ResumeStatus": request.ResumeStatus,
923
+ "ResumeTypes": request.ResumeTypes,
581
924
  "Offset": offset,
582
- "Limit": limit,
925
+ "Limit": request.Limit,
583
926
  }
584
927
 
585
928
 
586
929
  @sessions_router.post("/agentengine/api/v1/ListSessionCheckpoints")
587
- async def list_session_checkpoints_action(request: ListSessionCheckpointsActionRequest):
588
- return _action_response("ListSessionCheckpoints", await _list_checkpoints_payload(request))
930
+ async def list_session_checkpoints_action(
931
+ request: ListSessionCheckpointsActionRequest,
932
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
933
+ ):
934
+ return _action_response(
935
+ "ListSessionCheckpoints",
936
+ await _list_checkpoints_payload(request, invocation_identity),
937
+ )
589
938
 
590
939
 
591
940
  @tools_router.post("/agentengine/api/v1/ListToolReceipts")
592
- async def list_tool_receipts_action(request: ListToolReceiptsActionRequest):
941
+ async def list_tool_receipts_action(
942
+ request: ListToolReceiptsActionRequest,
943
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
944
+ ):
593
945
  service = deps.resolve_session_service()
594
- await _require_action_session(
946
+ await _require_identity_action_session(
595
947
  service,
596
948
  session_id=request.SessionId,
597
949
  agent_id=request.AgentId,
598
950
  user_id=request.UserId,
951
+ invocation_identity=invocation_identity,
599
952
  )
600
953
 
601
954
  run_id_filter = str(request.RunId or "").strip()