agentengine-sdk-python 0.8.4__py3-none-any.whl → 0.8.6__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 (1221) hide show
  1. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/METADATA +17 -10
  2. agentengine_sdk_python-0.8.6.dist-info/RECORD +1731 -0
  3. ksadk/_async_iterators.py +79 -0
  4. ksadk/_build_provenance.json +1 -1
  5. ksadk/_model_anthropic.py +49 -0
  6. ksadk/_model_input.py +86 -0
  7. ksadk/_model_json.py +40 -0
  8. ksadk/_model_reasoning.py +17 -0
  9. ksadk/_model_refusal.py +20 -0
  10. ksadk/_model_sse.py +163 -0
  11. ksadk/_process.py +83 -0
  12. ksadk/_str_enum.py +17 -0
  13. ksadk/a2a/__init__.py +157 -167
  14. ksadk/a2a/_invocation_state.py +86 -0
  15. ksadk/a2a/_space_client_events.py +33 -22
  16. ksadk/a2a/adk.py +194 -0
  17. ksadk/a2a/adk_invocation_context.py +242 -0
  18. ksadk/a2a/adk_runtime.py +126 -0
  19. ksadk/a2a/adk_tools.py +319 -0
  20. ksadk/a2a/bootstrap.py +149 -23
  21. ksadk/a2a/build_validation.py +147 -0
  22. ksadk/a2a/card.py +23 -15
  23. ksadk/a2a/codex.py +160 -0
  24. ksadk/a2a/codex_checkpoint.py +111 -0
  25. ksadk/a2a/codex_recovery.py +96 -0
  26. ksadk/a2a/codex_recovery_events.py +123 -0
  27. ksadk/a2a/codex_runtime.py +198 -0
  28. ksadk/a2a/codex_session_checkpoint.py +162 -0
  29. ksadk/a2a/composition.py +88 -0
  30. ksadk/a2a/context_store.py +118 -19
  31. ksadk/a2a/control_plane.py +108 -106
  32. ksadk/a2a/event_adapter.py +92 -193
  33. ksadk/a2a/executor.py +257 -85
  34. ksadk/a2a/exposure.py +106 -0
  35. ksadk/a2a/external_transport.py +3 -4
  36. ksadk/a2a/identity.py +106 -12
  37. ksadk/a2a/ids.py +14 -3
  38. ksadk/a2a/inbound_kernel.py +133 -0
  39. ksadk/a2a/interaction_wire.py +76 -0
  40. ksadk/a2a/invocation_checkpoint.py +274 -0
  41. ksadk/a2a/invocation_policy.py +87 -0
  42. ksadk/a2a/invocation_publication.py +210 -0
  43. ksadk/a2a/invocation_service.py +972 -0
  44. ksadk/a2a/invocation_types.py +459 -0
  45. ksadk/a2a/kernel_task_adapter.py +259 -0
  46. ksadk/a2a/langgraph.py +20 -7
  47. ksadk/a2a/langgraph_invocation_context.py +136 -0
  48. ksadk/a2a/langgraph_managed.py +150 -0
  49. ksadk/a2a/langgraph_recovery.py +32 -0
  50. ksadk/a2a/langgraph_runtime.py +89 -0
  51. ksadk/a2a/langgraph_tool_runtime.py +132 -0
  52. ksadk/a2a/langgraph_tools.py +63 -0
  53. ksadk/a2a/message_digest.py +40 -0
  54. ksadk/a2a/platform.py +389 -0
  55. ksadk/a2a/policy_refs.py +13 -0
  56. ksadk/a2a/presentation.py +402 -0
  57. ksadk/a2a/product_kernel_facts.py +177 -0
  58. ksadk/a2a/product_key.py +99 -0
  59. ksadk/a2a/protocol_errors.py +116 -0
  60. ksadk/a2a/result_text.py +49 -0
  61. ksadk/a2a/resume_store.py +93 -3
  62. ksadk/a2a/routes.py +6 -1
  63. ksadk/a2a/runtime_approval.py +198 -0
  64. ksadk/a2a/runtime_input.py +151 -0
  65. ksadk/a2a/server.py +16 -7
  66. ksadk/a2a/space_client.py +101 -16
  67. ksadk/a2a/task_adapter.py +19 -5
  68. ksadk/a2a/task_event_dispatcher.py +39 -2
  69. ksadk/a2a/task_event_outbox.py +215 -0
  70. ksadk/a2a/task_event_outbox_owned.py +130 -0
  71. ksadk/a2a/task_store.py +37 -0
  72. ksadk/a2a/tool_activity.py +176 -0
  73. ksadk/a2a/workload_tokens.py +134 -0
  74. ksadk/a2ui/core.py +3 -3
  75. ksadk/api/client.py +38 -79
  76. ksadk/api/sse_stream.py +96 -0
  77. ksadk/builders/code_builder.py +121 -118
  78. ksadk/builders/container_builder.py +11 -29
  79. ksadk/builders/framework_requirements.py +22 -2
  80. ksadk/builders/managed_runtime_builder.py +12 -0
  81. ksadk/builders/source_provenance.py +87 -0
  82. ksadk/cli/__init__.py +36 -0
  83. ksadk/cli/cmd_a2a.py +43 -0
  84. ksadk/cli/cmd_build.py +9 -0
  85. ksadk/cli/cmd_config.py +4 -4
  86. ksadk/cli/cmd_create.py +12 -12
  87. ksadk/cli/cmd_deploy.py +27 -2
  88. ksadk/cli/cmd_hermes.py +24 -2
  89. ksadk/cli/cmd_invoke.py +64 -88
  90. ksadk/cli/cmd_openclaw.py +26 -1
  91. ksadk/cli/cmd_plugin.py +70 -12
  92. ksadk/cli/cmd_studio.py +69 -17
  93. ksadk/cli/cmd_web.py +2 -0
  94. ksadk/cli/hosted_invoke.py +206 -0
  95. ksadk/cli/invoke_content.py +60 -0
  96. ksadk/cli/openclaw_env.py +1 -1
  97. ksadk/cli/resource_common.py +26 -0
  98. ksadk/cli/runtime_bootstrap.py +27 -5
  99. ksadk/codex/_expert_request_reader.py +48 -0
  100. ksadk/codex/a2a_tools.py +140 -0
  101. ksadk/codex/async_approval.py +169 -0
  102. ksadk/codex/async_client.py +938 -0
  103. ksadk/codex/async_proxy.py +216 -0
  104. ksadk/codex/base_runtime.py +25 -0
  105. ksadk/codex/client.py +3 -1047
  106. ksadk/codex/client_payloads.py +85 -0
  107. ksadk/codex/rollout_checkpoint.py +264 -0
  108. ksadk/codex/runtime.py +290 -54
  109. ksadk/common/auth.py +2 -2
  110. ksadk/common/cloud_headers.py +36 -0
  111. ksadk/common/diagnostics.py +34 -0
  112. ksadk/common/kop_client.py +2 -1
  113. ksadk/configs/__init__.py +1 -1
  114. ksadk/configs/env_registry.py +216 -143
  115. ksadk/configs/env_registry_a2a.py +173 -0
  116. ksadk/configs/env_registry_studio.py +134 -0
  117. ksadk/configs/global_config.py +2 -1
  118. ksadk/configs/settings.py +9 -3
  119. ksadk/connector/__init__.py +17 -0
  120. ksadk/connector/channel.py +477 -0
  121. ksadk/context_engine/assembler.py +9 -0
  122. ksadk/context_engine/capabilities.py +52 -4
  123. ksadk/context_engine/contributors.py +80 -17
  124. ksadk/context_engine/instruction_authority.py +18 -0
  125. ksadk/conversations/attachment_storage.py +10 -3
  126. ksadk/conversations/attachments.py +69 -20
  127. ksadk/conversations/contracts.py +28 -9
  128. ksadk/conversations/message_projection.py +51 -155
  129. ksadk/conversations/message_projection_blocks.py +137 -0
  130. ksadk/conversations/model_context.py +11 -3
  131. ksadk/conversations/normalize.py +28 -10
  132. ksadk/conversations/projector.py +63 -0
  133. ksadk/conversations/runtime_baseline.py +37 -0
  134. ksadk/conversations/runtime_compaction.py +7 -2
  135. ksadk/conversations/runtime_input.py +16 -4
  136. ksadk/conversations/runtime_invocation.py +17 -4
  137. ksadk/conversations/runtime_observability.py +39 -10
  138. ksadk/conversations/runtime_payloads.py +12 -0
  139. ksadk/conversations/runtime_persistence.py +296 -32
  140. ksadk/conversations/runtime_preparation.py +98 -13
  141. ksadk/conversations/runtime_projection.py +217 -0
  142. ksadk/conversations/runtime_resume.py +141 -70
  143. ksadk/conversations/runtime_stream_events.py +29 -35
  144. ksadk/conversations/runtime_streaming.py +8 -0
  145. ksadk/conversations/tool_receipt_resume.py +387 -0
  146. ksadk/conversations/tool_receipts.py +32 -0
  147. ksadk/deployment/env_forward.py +5 -0
  148. ksadk/deployment/manager.py +15 -6
  149. ksadk/deployment/providers/serverless.py +76 -136
  150. ksadk/deployment/providers/serverless_payloads.py +122 -0
  151. ksadk/evaluation/agent_eval_client.py +2 -1
  152. ksadk/evaluation/contracts.py +78 -3
  153. ksadk/evaluation/evaluators.py +166 -1
  154. ksadk/evaluation/evidence.py +271 -4
  155. ksadk/evaluation/local_adapter.py +76 -12
  156. ksadk/evaluation/studio_build_adapter.py +73 -9
  157. ksadk/events/adapters/_a2a_checkpoint.py +151 -0
  158. ksadk/events/adapters/_a2a_snapshot.py +18 -14
  159. ksadk/events/adapters/_a2a_support.py +15 -3
  160. ksadk/events/adapters/_a2a_tool_activity.py +123 -0
  161. ksadk/events/adapters/_codex_errors.py +49 -0
  162. ksadk/events/adapters/_codex_items.py +16 -8
  163. ksadk/events/adapters/_langgraph_support.py +46 -1
  164. ksadk/events/adapters/a2a.py +54 -26
  165. ksadk/events/adapters/adk.py +188 -30
  166. ksadk/events/adapters/codex.py +33 -7
  167. ksadk/events/adapters/langgraph.py +16 -6
  168. ksadk/events/canonical.py +5 -0
  169. ksadk/events/canonical_store.py +200 -4
  170. ksadk/events/reducer.py +82 -0
  171. ksadk/events/run_authority.py +176 -0
  172. ksadk/events/session_event.py +2 -2
  173. ksadk/harness/__init__.py +18 -0
  174. ksadk/harness/app.py +11 -0
  175. ksadk/harness/artifact_adapters/__init__.py +1 -0
  176. ksadk/harness/artifact_adapters/native_page_budget.py +172 -0
  177. ksadk/harness/artifact_adapters/native_search.py +249 -0
  178. ksadk/harness/artifact_adapters/native_search_budget.py +134 -0
  179. ksadk/harness/artifact_adapters/native_store.py +115 -0
  180. ksadk/harness/artifact_adapters/native_tool.py +222 -0
  181. ksadk/harness/artifact_store.py +230 -0
  182. ksadk/harness/browser_adapters/__init__.py +6 -0
  183. ksadk/harness/browser_adapters/native_browser_tool.py +92 -0
  184. ksadk/harness/browser_adapters/native_dom_snapshot.py +187 -0
  185. ksadk/harness/browser_adapters/native_playwright.py +953 -0
  186. ksadk/harness/browser_adapters/native_vision.py +295 -0
  187. ksadk/harness/capabilities.py +115 -0
  188. ksadk/harness/capability_adapters/__init__.py +1 -0
  189. ksadk/harness/capability_adapters/native_dsh.py +289 -0
  190. ksadk/harness/capability_runtime.py +332 -0
  191. ksadk/harness/closure_contract.py +92 -0
  192. ksadk/harness/compaction_record.py +153 -0
  193. ksadk/harness/compiler.py +284 -0
  194. ksadk/harness/config.py +28 -5
  195. ksadk/harness/conformance/__init__.py +33 -0
  196. ksadk/harness/conformance/contract.py +504 -0
  197. ksadk/harness/conformance/fixtures.py +102 -0
  198. ksadk/harness/context_engine.py +388 -0
  199. ksadk/harness/context_maintenance.py +259 -0
  200. ksadk/harness/context_manifest.py +188 -0
  201. ksadk/harness/context_sections.py +397 -0
  202. ksadk/harness/context_tuning.py +168 -0
  203. ksadk/harness/diagnostic_adapters/__init__.py +1 -0
  204. ksadk/harness/diagnostic_adapters/contracts.py +70 -0
  205. ksadk/harness/diagnostic_adapters/lsp_rpc.py +210 -0
  206. ksadk/harness/diagnostic_adapters/native_lsp.py +286 -0
  207. ksadk/harness/draft_runtime.py +322 -0
  208. ksadk/harness/engine/__init__.py +40 -0
  209. ksadk/harness/engine/base.py +122 -0
  210. ksadk/harness/engine/budgets.py +108 -0
  211. ksadk/harness/engine/capability_declarations.py +59 -0
  212. ksadk/harness/engine/completion_guard.py +57 -0
  213. ksadk/harness/engine/context_pipeline.py +1351 -0
  214. ksadk/harness/engine/graph_builder.py +352 -0
  215. ksadk/harness/engine/hooked_reasoner.py +380 -0
  216. ksadk/harness/engine/langgraph.py +1049 -0
  217. ksadk/harness/engine/mcp_disclosure.py +701 -0
  218. ksadk/harness/engine/phases/__init__.py +6 -0
  219. ksadk/harness/engine/phases/context.py +48 -0
  220. ksadk/harness/engine/phases/interaction.py +31 -0
  221. ksadk/harness/engine/phases/reason.py +552 -0
  222. ksadk/harness/engine/phases/tools.py +638 -0
  223. ksadk/harness/engine/policy_runtime.py +81 -0
  224. ksadk/harness/engine/postgres_checkpointer.py +386 -0
  225. ksadk/harness/engine/run_control_bridge.py +100 -0
  226. ksadk/harness/engine/run_types.py +98 -0
  227. ksadk/harness/engine/skill_disclosure.py +275 -0
  228. ksadk/harness/engine/spans.py +41 -0
  229. ksadk/harness/engine/steering.py +177 -0
  230. ksadk/harness/engine/subagents.py +360 -0
  231. ksadk/harness/engine/thread_ids.py +112 -0
  232. ksadk/harness/engine/tool_dispatch.py +249 -0
  233. ksadk/harness/event_tree.py +212 -0
  234. ksadk/harness/events.py +498 -0
  235. ksadk/harness/execution_policy.py +104 -0
  236. ksadk/harness/hooks.py +259 -0
  237. ksadk/harness/insights.py +210 -0
  238. ksadk/harness/lifecycle.py +578 -0
  239. ksadk/harness/lifecycle_conformance.py +233 -0
  240. ksadk/harness/lifecycle_local_plane.py +104 -0
  241. ksadk/harness/loop/__init__.py +44 -0
  242. ksadk/harness/loop/reason.py +699 -0
  243. ksadk/harness/loop/tools.py +907 -0
  244. ksadk/harness/managed_runtime.py +1044 -0
  245. ksadk/harness/mcp_disclosure_contract.py +85 -0
  246. ksadk/harness/mcp_matrix.py +474 -0
  247. ksadk/harness/mcp_result_policy.py +44 -0
  248. ksadk/harness/mcp_runtime.py +504 -0
  249. ksadk/harness/memory_consolidation.py +157 -0
  250. ksadk/harness/memory_loop.py +156 -0
  251. ksadk/harness/memory_runtime.py +541 -0
  252. ksadk/harness/metrics.py +90 -0
  253. ksadk/harness/micro_compact.py +69 -0
  254. ksadk/harness/model_adapters/__init__.py +1 -0
  255. ksadk/harness/model_adapters/native_mcp_media.py +100 -0
  256. ksadk/harness/model_adapters/native_mcp_result.py +36 -0
  257. ksadk/harness/model_adapters/native_openai.py +703 -0
  258. ksadk/harness/model_capability.py +468 -0
  259. ksadk/harness/model_provider.py +430 -0
  260. ksadk/harness/multimodal.py +57 -0
  261. ksadk/harness/native/__init__.py +1 -0
  262. ksadk/harness/native/activation_contract.py +25 -0
  263. ksadk/harness/native/activation_recovery.py +29 -0
  264. ksadk/harness/native/adapters.py +291 -0
  265. ksadk/harness/native/artifact_contract.py +14 -0
  266. ksadk/harness/native/artifact_partial_read_capacity.py +171 -0
  267. ksadk/harness/native/artifact_read_capacity.py +182 -0
  268. ksadk/harness/native/artifact_read_contract.py +27 -0
  269. ksadk/harness/native/artifact_runtime.py +408 -0
  270. ksadk/harness/native/artifact_search_capacity.py +206 -0
  271. ksadk/harness/native/artifact_search_contract.py +40 -0
  272. ksadk/harness/native/artifact_single_read_capacity.py +170 -0
  273. ksadk/harness/native/browser_contract.py +229 -0
  274. ksadk/harness/native/browser_recovery.py +183 -0
  275. ksadk/harness/native/capabilities.py +204 -0
  276. ksadk/harness/native/child_approval.py +60 -0
  277. ksadk/harness/native/child_budget.py +136 -0
  278. ksadk/harness/native/child_cancellation.py +80 -0
  279. ksadk/harness/native/child_input.py +98 -0
  280. ksadk/harness/native/child_input_runtime.py +59 -0
  281. ksadk/harness/native/child_interruption.py +81 -0
  282. ksadk/harness/native/child_lifecycle.py +246 -0
  283. ksadk/harness/native/child_lifecycle_contract.py +91 -0
  284. ksadk/harness/native/child_notifications.py +75 -0
  285. ksadk/harness/native/child_promotion.py +66 -0
  286. ksadk/harness/native/command_runtime.py +99 -0
  287. ksadk/harness/native/completion.py +302 -0
  288. ksadk/harness/native/completion_text.py +116 -0
  289. ksadk/harness/native/context.py +358 -0
  290. ksadk/harness/native/context_artifact_page.py +75 -0
  291. ksadk/harness/native/context_compaction_projection.py +131 -0
  292. ksadk/harness/native/context_contributions.py +320 -0
  293. ksadk/harness/native/context_contributor_contract.py +133 -0
  294. ksadk/harness/native/context_driver.py +820 -0
  295. ksadk/harness/native/context_fresh_tools.py +49 -0
  296. ksadk/harness/native/context_history.py +272 -0
  297. ksadk/harness/native/context_microcompact.py +61 -0
  298. ksadk/harness/native/context_partial_summary.py +58 -0
  299. ksadk/harness/native/context_partition.py +492 -0
  300. ksadk/harness/native/context_pruning.py +275 -0
  301. ksadk/harness/native/context_reduction.py +60 -0
  302. ksadk/harness/native/context_replay.py +148 -0
  303. ksadk/harness/native/context_request_projection.py +526 -0
  304. ksadk/harness/native/context_runtime.py +976 -0
  305. ksadk/harness/native/context_runtime_contracts.py +409 -0
  306. ksadk/harness/native/context_search.py +112 -0
  307. ksadk/harness/native/context_source_fragments.py +188 -0
  308. ksadk/harness/native/context_source_progress.py +119 -0
  309. ksadk/harness/native/context_summary_planning.py +788 -0
  310. ksadk/harness/native/context_summary_recovery.py +105 -0
  311. ksadk/harness/native/delivery_review.py +331 -0
  312. ksadk/harness/native/delivery_review_contract.py +54 -0
  313. ksadk/harness/native/effect_admission.py +82 -0
  314. ksadk/harness/native/effect_control.py +318 -0
  315. ksadk/harness/native/effect_receipts.py +729 -0
  316. ksadk/harness/native/effect_runtime.py +303 -0
  317. ksadk/harness/native/effective_configuration.py +28 -0
  318. ksadk/harness/native/engine.py +945 -0
  319. ksadk/harness/native/final_output.py +34 -0
  320. ksadk/harness/native/final_submission.py +58 -0
  321. ksadk/harness/native/finalization_workspace.py +96 -0
  322. ksadk/harness/native/fork.py +151 -0
  323. ksadk/harness/native/guidance.py +91 -0
  324. ksadk/harness/native/history.py +381 -0
  325. ksadk/harness/native/hook_executor.py +205 -0
  326. ksadk/harness/native/hook_runtime_contract.py +282 -0
  327. ksadk/harness/native/interaction_observation.py +117 -0
  328. ksadk/harness/native/lease.py +103 -0
  329. ksadk/harness/native/machine.py +974 -0
  330. ksadk/harness/native/mcp_result_governance.py +156 -0
  331. ksadk/harness/native/model.py +570 -0
  332. ksadk/harness/native/model_feedback.py +63 -0
  333. ksadk/harness/native/model_input.py +30 -0
  334. ksadk/harness/native/model_recovery_contract.py +35 -0
  335. ksadk/harness/native/model_replay.py +128 -0
  336. ksadk/harness/native/model_request.py +133 -0
  337. ksadk/harness/native/model_runtime.py +196 -0
  338. ksadk/harness/native/model_takeover.py +419 -0
  339. ksadk/harness/native/model_tool_batch.py +40 -0
  340. ksadk/harness/native/observed_progress.py +46 -0
  341. ksadk/harness/native/operator_guidance.py +201 -0
  342. ksadk/harness/native/output_contract.py +80 -0
  343. ksadk/harness/native/output_recovery.py +24 -0
  344. ksadk/harness/native/ports.py +749 -0
  345. ksadk/harness/native/precompact_hook_runtime.py +171 -0
  346. ksadk/harness/native/replay_context.py +149 -0
  347. ksadk/harness/native/request_media.py +112 -0
  348. ksadk/harness/native/restore_contract.py +16 -0
  349. ksadk/harness/native/run_clock.py +120 -0
  350. ksadk/harness/native/state.py +436 -0
  351. ksadk/harness/native/steering.py +170 -0
  352. ksadk/harness/native/stop_hook_runtime.py +151 -0
  353. ksadk/harness/native/studio_admission.py +29 -0
  354. ksadk/harness/native/subagents.py +86 -0
  355. ksadk/harness/native/task_policy.py +99 -0
  356. ksadk/harness/native/task_progress.py +86 -0
  357. ksadk/harness/native/terminal_verification.py +43 -0
  358. ksadk/harness/native/tool_argument_feedback.py +178 -0
  359. ksadk/harness/native/tool_budget.py +253 -0
  360. ksadk/harness/native/tool_error_streak.py +89 -0
  361. ksadk/harness/native/tool_hook_runtime.py +343 -0
  362. ksadk/harness/native/tool_input_validation.py +58 -0
  363. ksadk/harness/native/tool_interruption.py +96 -0
  364. ksadk/harness/native/tool_observation.py +259 -0
  365. ksadk/harness/native/tool_progress.py +223 -0
  366. ksadk/harness/native/tool_recovery.py +25 -0
  367. ksadk/harness/native/tool_scheduling.py +33 -0
  368. ksadk/harness/native/tool_schema.py +126 -0
  369. ksadk/harness/native/transitions.py +151 -0
  370. ksadk/harness/native/turn_control.py +98 -0
  371. ksadk/harness/native/user_document.py +98 -0
  372. ksadk/harness/native/user_document_capture.py +49 -0
  373. ksadk/harness/native/user_input.py +87 -0
  374. ksadk/harness/native/verification.py +432 -0
  375. ksadk/harness/native/verification_binding.py +40 -0
  376. ksadk/harness/native/verification_runtime.py +233 -0
  377. ksadk/harness/native/verification_workspace.py +67 -0
  378. ksadk/harness/native_driver_failure.py +123 -0
  379. ksadk/harness/native_facade.py +977 -0
  380. ksadk/harness/native_factory.py +244 -0
  381. ksadk/harness/native_projection.py +503 -0
  382. ksadk/harness/native_runtime.py +621 -0
  383. ksadk/harness/native_shadow.py +250 -0
  384. ksadk/harness/native_shadow_inputs.py +146 -0
  385. ksadk/harness/observability/__init__.py +29 -0
  386. ksadk/harness/observability/inspection.py +528 -0
  387. ksadk/harness/observability/metrics.py +167 -0
  388. ksadk/harness/observability/otel_exporter.py +218 -0
  389. ksadk/harness/progress_adapters/__init__.py +5 -0
  390. ksadk/harness/progress_adapters/native_todo.py +75 -0
  391. ksadk/harness/prompt_cache.py +132 -0
  392. ksadk/harness/public_activity.py +213 -0
  393. ksadk/harness/public_output.py +30 -0
  394. ksadk/harness/public_summary.py +36 -0
  395. ksadk/harness/readiness.py +249 -0
  396. ksadk/harness/reasoner.py +779 -17
  397. ksadk/harness/release_readiness.py +140 -0
  398. ksadk/harness/resource_ref.py +69 -0
  399. ksadk/harness/rpc.py +200 -0
  400. ksadk/harness/run_control.py +773 -0
  401. ksadk/harness/runtime.py +157 -113
  402. ksadk/harness/runtime_capabilities.py +228 -0
  403. ksadk/harness/runtime_server.py +514 -0
  404. ksadk/harness/sandbox_adapters.py +739 -0
  405. ksadk/harness/sandbox_backend.py +733 -0
  406. ksadk/harness/sandbox_conformance.py +288 -0
  407. ksadk/harness/sandbox_lease.py +77 -0
  408. ksadk/harness/sandbox_lease_conformance.py +259 -0
  409. ksadk/harness/sandbox_matrix.py +170 -0
  410. ksadk/harness/sandbox_reconciliation.py +140 -0
  411. ksadk/harness/sandbox_recovery.py +586 -0
  412. ksadk/harness/sandbox_recovery_conformance.py +246 -0
  413. ksadk/harness/sdk.py +153 -0
  414. ksadk/harness/session_store.py +589 -0
  415. ksadk/harness/skill_adapters/__init__.py +1 -0
  416. ksadk/harness/skill_adapters/native_bundle.py +148 -0
  417. ksadk/harness/skill_adapters/native_disclosure.py +306 -0
  418. ksadk/harness/skill_composition.py +212 -0
  419. ksadk/harness/skill_feedback.py +123 -0
  420. ksadk/harness/skill_intent.py +47 -0
  421. ksadk/harness/skill_matrix.py +233 -0
  422. ksadk/harness/skill_runtime.py +317 -0
  423. ksadk/harness/spec.py +342 -0
  424. ksadk/harness/state.py +155 -0
  425. ksadk/harness/stores/__init__.py +14 -0
  426. ksadk/harness/stores/native_command_settlement.py +65 -0
  427. ksadk/harness/stores/native_contract.py +311 -0
  428. ksadk/harness/stores/native_memory.py +326 -0
  429. ksadk/harness/stores/native_memory_archive.py +70 -0
  430. ksadk/harness/stores/native_migration_cli.py +91 -0
  431. ksadk/harness/stores/native_outbox.py +56 -0
  432. ksadk/harness/stores/native_sqlite.py +782 -0
  433. ksadk/harness/stores/native_sqlite_audit.py +29 -0
  434. ksadk/harness/stores/native_sqlite_migration.py +252 -0
  435. ksadk/harness/strategies.py +149 -0
  436. ksadk/harness/subagent.py +263 -0
  437. ksadk/harness/subagent_adapters/checkpoint_recovery.py +120 -0
  438. ksadk/harness/subagent_adapters/native_background_child.py +803 -0
  439. ksadk/harness/subagent_adapters/native_child.py +819 -0
  440. ksadk/harness/subagent_adapters/native_child_approval.py +128 -0
  441. ksadk/harness/subagent_adapters/native_child_continuation.py +51 -0
  442. ksadk/harness/subagent_adapters/native_child_result.py +392 -0
  443. ksadk/harness/subagent_adapters/prepared_recovery.py +120 -0
  444. ksadk/harness/tool_display.py +75 -0
  445. ksadk/harness/tool_display_contract.py +134 -0
  446. ksadk/harness/tool_output.py +141 -0
  447. ksadk/harness/tool_policy.py +134 -0
  448. ksadk/harness/tool_receipts.py +96 -0
  449. ksadk/harness/tool_reliability.py +81 -0
  450. ksadk/harness/tool_result_policy.py +216 -0
  451. ksadk/harness/tools.py +52 -0
  452. ksadk/harness/user_errors.py +69 -0
  453. ksadk/harness/working_context.py +81 -0
  454. ksadk/harness/working_context_patch.py +99 -0
  455. ksadk/harness/workspace_adapters/__init__.py +6 -0
  456. ksadk/harness/workspace_adapters/native_directory.py +180 -0
  457. ksadk/harness/workspace_adapters/native_git.py +208 -0
  458. ksadk/harness/workspace_adapters/native_isolation.py +350 -0
  459. ksadk/identity/resolver.py +18 -0
  460. ksadk/interaction/__init__.py +1 -1
  461. ksadk/interaction/ledger.py +1 -1
  462. ksadk/interaction/provider.py +1 -1
  463. ksadk/interaction/providers/__init__.py +3 -1
  464. ksadk/interaction/providers/adk.py +1 -1
  465. ksadk/interaction/providers/codex.py +1 -1
  466. ksadk/interaction/providers/harness.py +50 -0
  467. ksadk/interaction/providers/langgraph.py +9 -2
  468. ksadk/kernel/__init__.py +10 -0
  469. ksadk/kernel/approval_presentation.py +91 -0
  470. ksadk/kernel/authorization.py +1 -1
  471. ksadk/kernel/bootstrap.py +220 -252
  472. ksadk/kernel/contract_fingerprints.py +45 -1
  473. ksadk/kernel/contracts.py +30 -0
  474. ksadk/kernel/control.py +180 -29
  475. ksadk/kernel/execution_grants.py +428 -0
  476. ksadk/kernel/execution_grants_memory.py +252 -0
  477. ksadk/kernel/execution_grants_postgres.py +395 -0
  478. ksadk/kernel/execution_grants_sqlite.py +435 -0
  479. ksadk/kernel/execution_host_ingress.py +1071 -0
  480. ksadk/kernel/history_projection.py +120 -0
  481. ksadk/kernel/ingress.py +139 -226
  482. ksadk/kernel/ingress_bootstrap.py +268 -0
  483. ksadk/kernel/legacy_history.py +179 -0
  484. ksadk/kernel/mapping.py +1 -1
  485. ksadk/kernel/memory_store.py +61 -58
  486. ksadk/kernel/memory_store_projection.py +63 -0
  487. ksadk/kernel/postgres_event_log.py +181 -0
  488. ksadk/kernel/postgres_store.py +230 -231
  489. ksadk/kernel/readiness.py +125 -0
  490. ksadk/kernel/recovery.py +166 -16
  491. ksadk/kernel/recovery_projection.py +124 -0
  492. ksadk/kernel/runtime_checkpoint.py +34 -0
  493. ksadk/kernel/sql/001_agent_kernel.sql +28 -0
  494. ksadk/kernel/sqlite_schema.py +100 -0
  495. ksadk/kernel/sqlite_store.py +410 -200
  496. ksadk/kernel/state.py +2 -3
  497. ksadk/kernel/store.py +104 -5
  498. ksadk/kernel/teams_artifact_tools.py +392 -0
  499. ksadk/kernel/teams_effects.py +851 -0
  500. ksadk/kernel/teams_execution_context.py +408 -0
  501. ksadk/kernel/teams_host_http.py +237 -0
  502. ksadk/kernel/teams_material_transport.py +245 -0
  503. ksadk/kernel/teams_materials.py +318 -0
  504. ksadk/kernel/teams_runtime_bootstrap.py +604 -0
  505. ksadk/kernel/teams_tool_runtime.py +273 -0
  506. ksadk/kernel/teams_workspace.py +259 -0
  507. ksadk/kernel/worker.py +369 -340
  508. ksadk/kernel/worker_controls.py +454 -0
  509. ksadk/kernel/worker_history.py +72 -0
  510. ksadk/kernel/worker_identity.py +74 -0
  511. ksadk/kernel/worker_interactions.py +197 -0
  512. ksadk/knowledge_base/client.py +15 -1
  513. ksadk/managed_runtime.py +29 -2
  514. ksadk/memory/adk/backends/http_ltm_backend.py +2 -1
  515. ksadk/memory/adk/backends/sdk_ltm_backend.py +15 -1
  516. ksadk/memory/adk/bounded_database_session_service.py +232 -0
  517. ksadk/memory/adk/resilient_session_service.py +115 -15
  518. ksadk/memory/adk/short_term_memory.py +8 -9
  519. ksadk/memory/coordinator.py +22 -6
  520. ksadk/memory/extraction.py +159 -7
  521. ksadk/memory/models.py +77 -1
  522. ksadk/memory/provider_resolver.py +5 -0
  523. ksadk/memory/providers/local_candidates.py +183 -0
  524. ksadk/memory/providers/local_postgres.py +200 -0
  525. ksadk/memory/providers/local_sqlite.py +280 -67
  526. ksadk/memory/resolved_policy.py +12 -7
  527. ksadk/memory/retrieval.py +189 -0
  528. ksadk/memory/store_adapter.py +150 -0
  529. ksadk/model_gateway/__init__.py +29 -0
  530. ksadk/model_gateway/client.py +253 -0
  531. ksadk/model_gateway/events.py +113 -0
  532. ksadk/model_gateway/matrix.py +297 -0
  533. ksadk/model_policy.py +2 -2
  534. ksadk/model_proxy/compat.py +670 -0
  535. ksadk/model_proxy/detect.py +254 -0
  536. ksadk/model_proxy/server.py +14 -9
  537. ksadk/model_proxy/transform.py +72 -6
  538. ksadk/plugins/__init__.py +1 -1
  539. ksadk/plugins/bridges/dsh.py +29 -20
  540. ksadk/plugins/bridges/dsh_profile_manifest.py +36 -0
  541. ksadk/plugins/builtin_resources.py +199 -0
  542. ksadk/plugins/builtins.py +417 -185
  543. ksadk/plugins/companion_artifacts.py +83 -0
  544. ksadk/plugins/companions.py +368 -0
  545. ksadk/plugins/context_contributor.py +15 -4
  546. ksadk/plugins/contracts.py +1 -1
  547. ksadk/plugins/dsh_channels.py +156 -0
  548. ksadk/plugins/dsh_dependency_policy.py +41 -0
  549. ksadk/plugins/dsh_home.py +140 -0
  550. ksadk/plugins/dsh_teams.py +105 -0
  551. ksadk/plugins/dsh_toolchain.py +92 -21
  552. ksadk/plugins/execution_host.py +107 -0
  553. ksadk/plugins/host.py +73 -5
  554. ksadk/plugins/kernel_adapter.py +44 -1
  555. ksadk/plugins/memory_provider.py +180 -0
  556. ksadk/plugins/providers/_process_group.py +50 -0
  557. ksadk/plugins/providers/bundles/dsh-channels-client/client.js +19 -0
  558. ksadk/plugins/providers/bundles/dsh-channels-client/cordis.patch.yml +3 -0
  559. ksadk/plugins/providers/bundles/dsh-channels-client/index.mjs +7 -0
  560. ksadk/plugins/providers/bundles/dsh-channels-client/package.json +12 -0
  561. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +24 -2
  562. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +1 -1
  563. ksadk/plugins/providers/bundles/dsh-memory/package.json +1 -1
  564. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +1 -1
  565. ksadk/plugins/providers/bundles/dsh-teams-client/client.js +29 -0
  566. ksadk/plugins/providers/bundles/dsh-teams-client/cordis.patch.yml +3 -0
  567. ksadk/plugins/providers/bundles/dsh-teams-client/index.mjs +11 -0
  568. ksadk/plugins/providers/bundles/dsh-teams-client/package.json +35 -0
  569. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/cordis.patch.yml +3 -0
  570. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/index.mjs +13 -0
  571. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/package.json +27 -0
  572. ksadk/plugins/providers/bundles/dsh-teams-profile/cordis.patch.yml +3 -0
  573. ksadk/plugins/providers/bundles/dsh-teams-profile/index.mjs +12 -0
  574. ksadk/plugins/providers/bundles/dsh-teams-profile/package.json +26 -0
  575. ksadk/plugins/providers/bundles/dsh-teams-router/cordis.patch.yml +3 -0
  576. ksadk/plugins/providers/bundles/dsh-teams-router/index.mjs +16 -0
  577. ksadk/plugins/providers/bundles/dsh-teams-router/package.json +27 -0
  578. ksadk/plugins/providers/bundles/dsh-teams-tasks/cordis.patch.yml +3 -0
  579. ksadk/plugins/providers/bundles/dsh-teams-tasks/index.mjs +16 -0
  580. ksadk/plugins/providers/bundles/dsh-teams-tasks/package.json +27 -0
  581. ksadk/plugins/providers/bundles/dsh-teams-tools/cordis.patch.yml +3 -0
  582. ksadk/plugins/providers/bundles/dsh-teams-tools/index.mjs +25 -0
  583. ksadk/plugins/providers/bundles/dsh-teams-tools/package.json +29 -0
  584. ksadk/plugins/providers/bundles/dsh-teams-tools/tools.json +235 -0
  585. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +1 -1
  586. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +51 -1
  587. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +2 -2
  588. ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/client.mjs +133 -0
  589. ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/index.mjs +14 -0
  590. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +27 -4
  591. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +9 -5
  592. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +1 -1
  593. ksadk/plugins/providers/codex.py +52 -40
  594. ksadk/plugins/providers/codex_native.py +20 -0
  595. ksadk/plugins/providers/codex_skills.py +46 -0
  596. ksadk/plugins/providers/dsh_capabilities.py +49 -143
  597. ksadk/plugins/providers/dsh_connector_lease.py +225 -0
  598. ksadk/plugins/providers/dsh_mcp.py +163 -1
  599. ksadk/plugins/providers/harness.py +413 -52
  600. ksadk/plugins/providers/harness_context.py +61 -0
  601. ksadk/plugins/providers/harness_contributions.py +241 -0
  602. ksadk/plugins/providers/harness_delegation.py +670 -0
  603. ksadk/plugins/providers/harness_hooks.py +121 -0
  604. ksadk/plugins/providers/harness_managed.py +550 -0
  605. ksadk/plugins/providers/harness_tools.py +455 -0
  606. ksadk/plugins/providers/legacy_catalog.py +1 -1
  607. ksadk/plugins/providers/mcp_projection.py +100 -3
  608. ksadk/plugins/providers/platform_resources.py +16 -6
  609. ksadk/plugins/providers/shipped_dsh.py +4 -1
  610. ksadk/plugins/subagent_providers/codex.py +28 -6
  611. ksadk/plugins/teams/__init__.py +5 -0
  612. ksadk/plugins/teams/api.py +405 -0
  613. ksadk/plugins/teams/application.py +540 -0
  614. ksadk/plugins/teams/artifacts.py +60 -0
  615. ksadk/plugins/teams/build_artifacts.py +460 -0
  616. ksadk/plugins/teams/cloud_contract_fingerprints.py +22 -0
  617. ksadk/plugins/teams/cloud_contracts.py +928 -0
  618. ksadk/plugins/teams/cloud_permits.py +250 -0
  619. ksadk/plugins/teams/context.py +96 -0
  620. ksadk/plugins/teams/contracts.py +136 -0
  621. ksadk/plugins/teams/domain.py +1480 -0
  622. ksadk/plugins/teams/domain_values.py +24 -0
  623. ksadk/plugins/teams/effect_contracts.py +255 -0
  624. ksadk/plugins/teams/errors.py +13 -0
  625. ksadk/plugins/teams/execution_projection.py +255 -0
  626. ksadk/plugins/teams/leader_decisions.py +106 -0
  627. ksadk/plugins/teams/migration.py +311 -0
  628. ksadk/plugins/teams/migration_cli.py +322 -0
  629. ksadk/plugins/teams/postgres_store.py +352 -0
  630. ksadk/plugins/teams/release_contracts.py +60 -0
  631. ksadk/plugins/teams/runtime.py +853 -0
  632. ksadk/plugins/teams/source_projection.py +84 -0
  633. ksadk/plugins/teams/store.py +519 -0
  634. ksadk/plugins/teams/task_decisions.py +436 -0
  635. ksadk/plugins/teams/tool_service.py +152 -0
  636. ksadk/plugins/teams/transport.py +96 -0
  637. ksadk/plugins/teams/workspaces.py +255 -0
  638. ksadk/resource_runtime/skill_runtime.py +3 -0
  639. ksadk/resource_runtime/socket_server.py +11 -0
  640. ksadk/resource_runtime/worker.py +28 -4
  641. ksadk/runners/_adk_a2a_stream.py +122 -0
  642. ksadk/runners/_adk_canonical_stream.py +474 -0
  643. ksadk/runners/_langgraph_canonical_streams.py +527 -0
  644. ksadk/runners/_langgraph_runner_streams.py +83 -401
  645. ksadk/runners/_langgraph_state_reader.py +106 -0
  646. ksadk/runners/_langgraph_tool_projection.py +86 -0
  647. ksadk/runners/_langgraph_tools_transformer.py +27 -0
  648. ksadk/runners/_session_identity.py +285 -0
  649. ksadk/runners/adk_runner.py +220 -350
  650. ksadk/runners/base_runner.py +6 -5
  651. ksadk/runners/langgraph_runner.py +208 -195
  652. ksadk/runners/patch_langchain.py +47 -0
  653. ksadk/runners/usage_accumulator.py +11 -3
  654. ksadk/runners/utils/loader.py +28 -14
  655. ksadk/runtime/_runner_adapter/a2ui_surface.py +145 -0
  656. ksadk/runtime/_runner_adapter/gateway_approvals.py +93 -0
  657. ksadk/runtime/_runner_adapter/stream_mapping.py +134 -129
  658. ksadk/runtime/adapter.py +40 -3
  659. ksadk/runtime/conversation_execution.py +29 -3
  660. ksadk/runtime/executor.py +105 -7
  661. ksadk/runtime/factory.py +45 -3
  662. ksadk/runtime/framework_adapters.py +184 -10
  663. ksadk/runtime/hosted_finalizer.py +4 -6
  664. ksadk/runtime/launch.py +2 -0
  665. ksadk/runtime/preprocessing.py +11 -3
  666. ksadk/runtime/runner_adapter.py +160 -21
  667. ksadk/runtime/skill_eval_result.py +36 -0
  668. ksadk/runtime/timing.py +46 -0
  669. ksadk/runtime/usage.py +49 -18
  670. ksadk/runtime_context.py +105 -1
  671. ksadk/sandbox/backends/e2b.py +272 -24
  672. ksadk/sandbox/backends/local_process.py +73 -39
  673. ksadk/sandbox/base.py +62 -1
  674. ksadk/sandbox/diagnostics.py +82 -0
  675. ksadk/sandbox/e2b_connection.py +9 -1
  676. ksadk/sandbox/local_controls.py +776 -0
  677. ksadk/sandbox/local_launcher.py +124 -0
  678. ksadk/scheduler/dispatcher.py +1 -1
  679. ksadk/server/factory.py +178 -25
  680. ksadk/server/history_deadline.py +158 -0
  681. ksadk/server/history_page_cache.py +129 -0
  682. ksadk/server/invocation_identity.py +118 -0
  683. ksadk/server/routes/checkpoint_audit.py +88 -0
  684. ksadk/server/routes/checkpoint_listing.py +294 -0
  685. ksadk/server/routes/checkpoint_resolution.py +73 -20
  686. ksadk/server/routes/common.py +32 -3
  687. ksadk/server/routes/control.py +112 -9
  688. ksadk/server/routes/dependencies.py +2 -1
  689. ksadk/server/routes/display_projection.py +154 -0
  690. ksadk/server/routes/kernel_ingress.py +26 -3
  691. ksadk/server/routes/misc.py +331 -33
  692. ksadk/server/routes/models.py +28 -4
  693. ksadk/server/routes/openai_compat.py +82 -13
  694. ksadk/server/routes/projection.py +159 -216
  695. ksadk/server/routes/run.py +112 -37
  696. ksadk/server/routes/sessions.py +493 -358
  697. ksadk/server/routes/streaming.py +68 -15
  698. ksadk/server/routes/tool_receipt_claim_routes.py +107 -0
  699. ksadk/server/routes/workspace.py +135 -23
  700. ksadk/server/static/assets/{ArtifactsPanel-CGbWlMNh.js → ArtifactsPanel-CILaW-fC.js} +1 -1
  701. ksadk/server/static/assets/{CodeBlock-b4C7upmO.js → CodeBlock-BVrNVtJC.js} +10 -7
  702. ksadk/server/static/assets/MathMessageMarkdown-Dp7c4wWD.js +8 -0
  703. ksadk/server/static/assets/{MermaidBlock-BEBN4Ksz.js → MermaidBlock-Dxop8Rd7.js} +9 -9
  704. ksadk/server/static/assets/{NativeTerminalPanel-zvL-WpAn.js → NativeTerminalPanel-Cjjz8B30.js} +1 -1
  705. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-BYafW7Za.js → abnfDiagram-VCTEODGH-ckWDmOzw.js} +1 -1
  706. ksadk/server/static/assets/{arc-bTohInsS.js → arc-DqxJede-.js} +1 -1
  707. ksadk/server/static/assets/architecture-7GRP2DOG-pn_DuLy6.js +1 -0
  708. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-Ch5Lbzsi.js → architectureDiagram-5GKGNRK7-SEQA4bVi.js} +1 -1
  709. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-kqF4MDOG.js → blockDiagram-NRAW4CY4-pM0B-6NJ.js} +1 -1
  710. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-8uSRIODv.js → c4Diagram-UCG6FXSJ-m2tuCNVq.js} +1 -1
  711. ksadk/server/static/assets/channel-fySsnkft.js +1 -0
  712. ksadk/server/static/assets/chunk-2Q5K7J3B-BheGxKRQ.js +1 -0
  713. ksadk/server/static/assets/{chunk-5VM5RSS4-DkhehZDr.js → chunk-5VM5RSS4-GJHDr9Ww.js} +1 -1
  714. ksadk/server/static/assets/{chunk-F27PBJKO-BdXhtPe9.js → chunk-F27PBJKO-CbAN45AV.js} +1 -1
  715. ksadk/server/static/assets/{chunk-G27WJ6UU-DPTpvpwi.js → chunk-G27WJ6UU-D5ngbbzF.js} +1 -1
  716. ksadk/server/static/assets/{chunk-JWPE2WC7-Pqoh38el.js → chunk-JWPE2WC7-Cc5IwuYC.js} +1 -1
  717. ksadk/server/static/assets/{chunk-LCL6LL3I-DeU00qC-.js → chunk-LCL6LL3I-CprgDDdJ.js} +1 -1
  718. ksadk/server/static/assets/{chunk-POPQ4Y6H-CzxScFkr.js → chunk-POPQ4Y6H-CDZhSy82.js} +1 -1
  719. ksadk/server/static/assets/{chunk-RHFEMEQ7-DpqMx-ux.js → chunk-RHFEMEQ7-CZchUNro.js} +1 -1
  720. ksadk/server/static/assets/{chunk-SVP7TREG-C6t0SypQ.js → chunk-SVP7TREG-BVruqk6T.js} +1 -1
  721. ksadk/server/static/assets/{chunk-XXDRQBXY-DVaeafZk.js → chunk-XXDRQBXY-4ld9SxPN.js} +1 -1
  722. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DSfLtNYm.js +1 -0
  723. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DSfLtNYm.js +1 -0
  724. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-Bf9D3tzJ.js → cose-bilkent-JH36ORCC-Dmyyk_Vp.js} +1 -1
  725. ksadk/server/static/assets/cynefin-OW5HDTMX-PFWIGtvA.js +1 -0
  726. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-B9cY3iTz.js → cynefinDiagram-5FMLGOSQ-BIyq3EJb.js} +1 -1
  727. ksadk/server/static/assets/{dagre-3AP2YEHR-CSwlx3CB.js → dagre-3AP2YEHR-eBw08Qdk.js} +1 -1
  728. ksadk/server/static/assets/{dagre-UBpgon5q.js → dagre-DfvnEf45.js} +1 -1
  729. ksadk/server/static/assets/{diagram-S7CK7UJ4-C9akhN9a.js → diagram-S7CK7UJ4-CUSrE3Mg.js} +1 -1
  730. ksadk/server/static/assets/{diagram-UQ7AKVKN-CgedhTPI.js → diagram-UQ7AKVKN-Dq5Zw2gy.js} +1 -1
  731. ksadk/server/static/assets/{diagram-VSXAHHWV-Cjucz5BY.js → diagram-VSXAHHWV-DyUHfNwT.js} +1 -1
  732. ksadk/server/static/assets/{diagram-VX7I27RA-Dd4Vleyn.js → diagram-VX7I27RA-CREmM89O.js} +1 -1
  733. ksadk/server/static/assets/{diagram-Z3DM3KII-CZ2jGtYW.js → diagram-Z3DM3KII-Dw9zhHUK.js} +1 -1
  734. ksadk/server/static/assets/{dist-Bj730Ib4.js → dist-0uJ4tdx6.js} +1 -1
  735. ksadk/server/static/assets/{dist-BnaTiyzN.js → dist-AEv-vXf-.js} +1 -1
  736. ksadk/server/static/assets/{dist-BgV_owcB.js → dist-B49GzZDb.js} +1 -1
  737. ksadk/server/static/assets/{dist-D_ctSS2i.js → dist-B8Myiet9.js} +1 -1
  738. ksadk/server/static/assets/{dist-ufY3F5p6.js → dist-BBsYarrI.js} +2 -2
  739. ksadk/server/static/assets/{dist-ClYUxfeK.js → dist-BQMrUwdI.js} +1 -1
  740. ksadk/server/static/assets/{dist-CFzsn6BG.js → dist-BX_-FENW.js} +1 -1
  741. ksadk/server/static/assets/{dist-B3FR1SKK.js → dist-CD4L6ymH.js} +1 -1
  742. ksadk/server/static/assets/{dist-Cf125P_m.js → dist-CHpW1BHj.js} +1 -1
  743. ksadk/server/static/assets/{dist-DVCOWtha.js → dist-CVPau3tn.js} +1 -1
  744. ksadk/server/static/assets/{dist-DFD6Qa6T.js → dist-C_qdxcSH.js} +1 -1
  745. ksadk/server/static/assets/{dist-BIr4DSRq.js → dist-Co68Apq4.js} +1 -1
  746. ksadk/server/static/assets/{dist-DiixqL0J.js → dist-Cp2PaOMY.js} +1 -1
  747. ksadk/server/static/assets/{dist-fBO2v5Kt.js → dist-CuR5Bgme.js} +1 -1
  748. ksadk/server/static/assets/{dist-DoVSwoDb.js → dist-DDSyLEOX.js} +1 -1
  749. ksadk/server/static/assets/{dist-C5_ZAZsG.js → dist-DUxO0R99.js} +1 -1
  750. ksadk/server/static/assets/{dist-C1NMAY5a.js → dist-QzbGrED_.js} +1 -1
  751. ksadk/server/static/assets/dist-bupkyEBZ.js +1 -0
  752. ksadk/server/static/assets/{dist-DvFK7p5S.js → dist-cxTGfdqx.js} +1 -1
  753. ksadk/server/static/assets/{dist-CB9iJrvg.js → dist-hL5p1til.js} +1 -1
  754. ksadk/server/static/assets/{dist-btbmmX5O.js → dist-lOy23y43.js} +1 -1
  755. ksadk/server/static/assets/{dist-QfkEHOlb.js → dist-pq-nD33R.js} +1 -1
  756. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Ci8NqqZu.js → ebnfDiagram-PWID7BFC-BS5LdNoR.js} +1 -1
  757. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CCIOhLZG.js → erDiagram-SSCWMZ5O-Bv1QtiY-.js} +1 -1
  758. ksadk/server/static/assets/eventmodeling-NTZA5JFV-DsM4upQX.js +1 -0
  759. ksadk/server/static/assets/flowDiagram-A5DVABFB-D5NA16k9.js +1 -0
  760. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js → ganttDiagram-EL5Y4UJY-musi-e0G.js} +1 -1
  761. ksadk/server/static/assets/gitGraph-4MIJSDKK-DUCVz-ih.js +1 -0
  762. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js → gitGraphDiagram-WWUBYQGX-DH37EGkG.js} +1 -1
  763. ksadk/server/static/assets/index-CZdkAvsv.js +244 -0
  764. ksadk/server/static/assets/index-CvXdHgF3.css +2 -0
  765. ksadk/server/static/assets/info-A6RAGUB7-rw0ZNHZp.js +1 -0
  766. ksadk/server/static/assets/{infoDiagram-RXCK75RN-CO0rRTRA.js → infoDiagram-RXCK75RN-C1kEtv2y.js} +1 -1
  767. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CHiaedSS.js → ishikawaDiagram-5VMMS53U-BCNPyMka.js} +1 -1
  768. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-CHcCIB09.js → journeyDiagram-EYS64GPL--cDbKnjP.js} +1 -1
  769. ksadk/server/static/assets/{kanban-definition-3QL26DDD-CJ_ebBZf.js → kanban-definition-3QL26DDD-R1rAVw2f.js} +1 -1
  770. ksadk/server/static/assets/{katex-B4weu383.js → katex-BT-X-V7U.js} +1 -1
  771. ksadk/server/static/assets/{linear-V-MgYHW1.js → linear-DTR631iG.js} +1 -1
  772. ksadk/server/static/assets/{mermaid-parser.core-CBijEX_c.js → mermaid-parser.core-DfFzJhX8.js} +2 -2
  773. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-Bc-pQvpp.js → mindmap-definition-FBJOCRG2-D4by_rmk.js} +1 -1
  774. ksadk/server/static/assets/packet-AYTQ26CC-Ca4Hvki9.js +1 -0
  775. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-D7genGLl.js → pegDiagram-XKGWAZYB-xWXPEh0c.js} +1 -1
  776. ksadk/server/static/assets/pie-WAS4IAKB-hwiz6fbw.js +1 -0
  777. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-Bxj32zwD.js → pieDiagram-E7YTZNPT-BudBDlCI.js} +1 -1
  778. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BURv2mGh.js → quadrantDiagram-AXDQQJYC-DXZ0PCJF.js} +1 -1
  779. ksadk/server/static/assets/radar-RG4KPBEZ-BR1oZXLM.js +1 -0
  780. ksadk/server/static/assets/railroad-74A4TZTK-DfgEISfX.js +1 -0
  781. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-CWOC3rdk.js +1 -0
  782. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CiRvHCLY.js +1 -0
  783. ksadk/server/static/assets/railroad-peg-WCYAUIDC-DSDDyJ2f.js +1 -0
  784. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-CCsh3avW.js → railroadDiagram-O6MQD6OU-BdAYRYB8.js} +1 -1
  785. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-_FRRBKEd.js → requirementDiagram-EFPCY7ZU-CBBmaL70.js} +1 -1
  786. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-C-gr2o9M.js → sankeyDiagram-P5KCCOFB-Doc3rdwp.js} +1 -1
  787. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-D97NmfKg.js → sequenceDiagram-WJ2MYXX4-0J8R8hWW.js} +1 -1
  788. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DjrPC5FX.js → sizeCapture-X5ZJPWSS-CfFLlWsK.js} +1 -1
  789. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DzMNg1hh.js → stateDiagram-HBIQ2CUA-jBwkjtTy.js} +1 -1
  790. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-Cw1fPb5w.js +1 -0
  791. ksadk/server/static/assets/{swimlanes-XN3QIQJK-Cssf_CsU.js → swimlanes-XN3QIQJK-B0WxTQf8.js} +1 -1
  792. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-Cc3JMBAF.js +8 -0
  793. ksadk/server/static/assets/{timeline-definition-24CTP7MA-BWTHzyS1.js → timeline-definition-24CTP7MA-BfCT_75A.js} +1 -1
  794. ksadk/server/static/assets/treeView-Q6P3EWNA-C05SJHxo.js +1 -0
  795. ksadk/server/static/assets/treemap-WGGIJYW6-BqNLAhc3.js +1 -0
  796. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-BSKgJsmR.js → vennDiagram-4TSXK5OY-9gX1VMDC.js} +1 -1
  797. ksadk/server/static/assets/wardley-WFR3VGLG-DokNktqB.js +1 -0
  798. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-eflHNoaZ.js → wardleyDiagram-VM6X3IG4-sEs_BP6O.js} +1 -1
  799. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-eYqrQ-v4.js → xychartDiagram-S5SC5T6Z-Ll4jvUN9.js} +1 -1
  800. ksadk/server/static/index.html +2 -2
  801. ksadk/server/terminal_sessions.py +34 -2
  802. ksadk/sessions/__init__.py +8 -1
  803. ksadk/sessions/_checkpoint_resume_audit.py +44 -0
  804. ksadk/sessions/_in_memory_query.py +112 -0
  805. ksadk/sessions/_local_service_sync.py +157 -156
  806. ksadk/sessions/_local_state_sync.py +152 -0
  807. ksadk/sessions/_local_tables.py +2 -0
  808. ksadk/sessions/_postgres_checkpoint_read.py +323 -0
  809. ksadk/sessions/_postgres_checkpoint_stats.py +330 -0
  810. ksadk/sessions/_postgres_history_read.py +678 -0
  811. ksadk/sessions/_postgres_schema.py +44 -2
  812. ksadk/sessions/_postgres_tables.py +2 -0
  813. ksadk/sessions/_postgres_tool_receipts.py +169 -0
  814. ksadk/sessions/_resilient_read.py +630 -0
  815. ksadk/sessions/_tool_receipt_sync.py +119 -0
  816. ksadk/sessions/agent_identity.py +16 -0
  817. ksadk/sessions/base.py +278 -0
  818. ksadk/sessions/db_budget.py +332 -0
  819. ksadk/sessions/errors.py +12 -0
  820. ksadk/sessions/history_budget.py +36 -0
  821. ksadk/sessions/history_identity.py +27 -0
  822. ksadk/sessions/in_memory.py +376 -113
  823. ksadk/sessions/invocation_identity.py +235 -0
  824. ksadk/sessions/local_service.py +345 -0
  825. ksadk/sessions/postgres_service.py +515 -549
  826. ksadk/sessions/resilience.py +21 -14
  827. ksadk/sessions/resilient.py +611 -504
  828. ksadk/skills/__init__.py +26 -0
  829. ksadk/skills/events.py +464 -0
  830. ksadk/skills/loader.py +44 -2
  831. ksadk/skills/manifest_cache.py +263 -0
  832. ksadk/skills/mcp_server/__init__.py +0 -0
  833. ksadk/skills/mcp_server/_registry.py +33 -0
  834. ksadk/skills/mcp_server/_routing.py +26 -0
  835. ksadk/skills/mcp_server/_workspace_files.py +160 -0
  836. ksadk/skills/mcp_server/register.py +415 -0
  837. ksadk/skills/mcp_server/server.py +218 -0
  838. ksadk/skills/models.py +11 -0
  839. ksadk/skills/observability.py +132 -0
  840. ksadk/skills/package_store.py +75 -2
  841. ksadk/skills/runtime/agent.py +38 -5
  842. ksadk/skills/runtime/artifacts.py +87 -0
  843. ksadk/skills/runtime/backends/e2b.py +400 -56
  844. ksadk/skills/runtime/backends/local.py +621 -119
  845. ksadk/skills/runtime/base.py +78 -7
  846. ksadk/skills/runtime/executor.py +266 -1
  847. ksadk/skills/runtime/loader.py +108 -3
  848. ksadk/skills/runtime/request.py +18 -0
  849. ksadk/skills/service_client.py +6 -1
  850. ksadk/skills/tool_defs.py +108 -3
  851. ksadk/studio/a2a_bindings.py +407 -0
  852. ksadk/studio/a2a_orchestration.py +178 -0
  853. ksadk/studio/active_run_output.py +92 -0
  854. ksadk/studio/activity_records.py +542 -0
  855. ksadk/studio/agent_configuration.py +173 -0
  856. ksadk/studio/api.py +784 -419
  857. ksadk/studio/api_a2a_routes.py +93 -0
  858. ksadk/studio/api_catalog_routes.py +13 -0
  859. ksadk/studio/api_cloud_chat_routes.py +382 -0
  860. ksadk/studio/api_contracts.py +31 -2
  861. ksadk/studio/api_plugin_routes.py +39 -12
  862. ksadk/studio/api_resource_connections.py +79 -41
  863. ksadk/studio/attachment_store.py +14 -2
  864. ksadk/studio/authoring.py +12 -6
  865. ksadk/studio/authoring_coordinator.py +4 -2
  866. ksadk/studio/build_resolution.py +117 -0
  867. ksadk/studio/build_singleflight.py +37 -0
  868. ksadk/studio/builder.py +32 -2
  869. ksadk/studio/capabilities.py +31 -9
  870. ksadk/studio/channel_connections.py +333 -0
  871. ksadk/studio/cloud.py +113 -387
  872. ksadk/studio/cloud_gateways.py +424 -0
  873. ksadk/studio/cloud_shared_web.py +82 -2
  874. ksadk/studio/codex_agent_service.py +19 -2
  875. ksadk/studio/codex_builder.py +1 -1
  876. ksadk/studio/codex_manifest.py +5 -1
  877. ksadk/studio/codex_provider_build.py +65 -0
  878. ksadk/studio/codex_run.py +6 -1
  879. ksadk/studio/compiler.py +112 -6
  880. ksadk/studio/configuration.py +182 -0
  881. ksadk/studio/contract_base.py +19 -0
  882. ksadk/studio/contracts.py +260 -202
  883. ksadk/studio/dsh_application.py +183 -27
  884. ksadk/studio/dsh_capability_service.py +302 -189
  885. ksadk/studio/dsh_lifecycle.py +58 -0
  886. ksadk/studio/dsh_mcp_transport.py +191 -0
  887. ksadk/studio/dsh_provider_registration.py +55 -16
  888. ksadk/studio/entry.py +53 -0
  889. ksadk/studio/event_store.py +53 -5
  890. ksadk/studio/execution_host.py +598 -0
  891. ksadk/studio/framework_run.py +50 -10
  892. ksadk/studio/hosted_kernel.py +1 -1
  893. ksadk/studio/interaction_submission.py +265 -0
  894. ksadk/studio/kernel_registry.py +429 -0
  895. ksadk/studio/kernel_sqlite_migration.py +181 -0
  896. ksadk/studio/lifecycle_status.py +43 -0
  897. ksadk/studio/model_buffered_wire.py +227 -0
  898. ksadk/studio/model_chat_tools.py +143 -0
  899. ksadk/studio/model_client.py +1939 -345
  900. ksadk/studio/model_content_stream.py +129 -0
  901. ksadk/studio/model_credentials.py +196 -0
  902. ksadk/studio/model_profile_service.py +89 -40
  903. ksadk/studio/model_request_projection.py +284 -0
  904. ksadk/studio/model_responses_content.py +296 -0
  905. ksadk/studio/model_usage.py +109 -0
  906. ksadk/studio/model_wire_failure.py +110 -0
  907. ksadk/studio/model_wire_identity.py +138 -0
  908. ksadk/studio/model_wire_snapshot.py +45 -0
  909. ksadk/studio/model_wire_tools.py +283 -0
  910. ksadk/studio/native_acceptance.py +68 -0
  911. ksadk/studio/native_approval.py +111 -0
  912. ksadk/studio/native_browser_port.py +861 -0
  913. ksadk/studio/native_child_mcp.py +87 -0
  914. ksadk/studio/native_child_publication.py +68 -0
  915. ksadk/studio/native_child_skills.py +72 -0
  916. ksadk/studio/native_child_workspace.py +176 -0
  917. ksadk/studio/native_command_policy.py +53 -0
  918. ksadk/studio/native_context_port.py +326 -0
  919. ksadk/studio/native_context_registration.py +54 -0
  920. ksadk/studio/native_document_input.py +88 -0
  921. ksadk/studio/native_documents.py +172 -0
  922. ksadk/studio/native_final_shape.py +852 -0
  923. ksadk/studio/native_gateway_stream.py +69 -0
  924. ksadk/studio/native_hook_port.py +145 -0
  925. ksadk/studio/native_hook_registration.py +70 -0
  926. ksadk/studio/native_inventory_disclosure.py +223 -0
  927. ksadk/studio/native_kernel_admission.py +84 -0
  928. ksadk/studio/native_language_diagnostics.py +320 -0
  929. ksadk/studio/native_mcp_disclosure.py +198 -0
  930. ksadk/studio/native_mcp_tool_port.py +219 -0
  931. ksadk/studio/native_memory_acceptance.py +362 -0
  932. ksadk/studio/native_memory_context.py +266 -0
  933. ksadk/studio/native_memory_flush.py +174 -0
  934. ksadk/studio/native_memory_sources.py +80 -0
  935. ksadk/studio/native_memory_tool_port.py +360 -0
  936. ksadk/studio/native_memory_turn.py +183 -0
  937. ksadk/studio/native_model_port.py +765 -0
  938. ksadk/studio/native_model_recovery.py +126 -0
  939. ksadk/studio/native_options.py +75 -0
  940. ksadk/studio/native_output_fields.py +58 -0
  941. ksadk/studio/native_planning.py +156 -0
  942. ksadk/studio/native_product.py +988 -0
  943. ksadk/studio/native_read_budget.py +426 -0
  944. ksadk/studio/native_recovery.py +171 -0
  945. ksadk/studio/native_scope.py +35 -0
  946. ksadk/studio/native_session_context_port.py +141 -0
  947. ksadk/studio/native_session_engine.py +14 -0
  948. ksadk/studio/native_skill_source.py +74 -0
  949. ksadk/studio/native_subagent_port.py +700 -0
  950. ksadk/studio/native_terminal_recovery.py +95 -0
  951. ksadk/studio/native_test_action.py +610 -0
  952. ksadk/studio/native_tool_port.py +477 -0
  953. ksadk/studio/native_user_input.py +60 -0
  954. ksadk/studio/native_verification_presentation.py +65 -0
  955. ksadk/studio/native_workspace_diagnostics.py +183 -0
  956. ksadk/studio/native_workspace_port.py +43 -0
  957. ksadk/studio/operations.py +34 -9
  958. ksadk/studio/plugin_composition.py +39 -12
  959. ksadk/studio/plugin_kernel_adapter.py +89 -0
  960. ksadk/studio/plugin_lifecycle.py +80 -0
  961. ksadk/studio/plugin_native_activation.py +163 -0
  962. ksadk/studio/plugin_runtime.py +832 -99
  963. ksadk/studio/plugin_runtime_admission.py +57 -0
  964. ksadk/studio/presentation.py +92 -0
  965. ksadk/studio/provider_recovery.py +59 -0
  966. ksadk/studio/public_output_store.py +69 -0
  967. ksadk/studio/recovery_page.py +70 -0
  968. ksadk/studio/resource_authority.py +69 -34
  969. ksadk/studio/resource_catalog.py +14 -12
  970. ksadk/studio/run_activity.py +848 -0
  971. ksadk/studio/run_controls.py +185 -0
  972. ksadk/studio/run_documents.py +127 -0
  973. ksadk/studio/run_service.py +1220 -335
  974. ksadk/studio/run_submission_receipts.py +68 -0
  975. ksadk/studio/runtime_catalog.py +73 -11
  976. ksadk/studio/runtime_prewarm.py +22 -0
  977. ksadk/studio/runtime_source.py +1 -1
  978. ksadk/studio/scheduler_assistant.py +4 -1
  979. ksadk/studio/scheduler_runtime.py +32 -289
  980. ksadk/studio/service.py +615 -246
  981. ksadk/studio/service_settings.py +229 -0
  982. ksadk/studio/shared_web.py +518 -181
  983. ksadk/studio/shared_web_response_events.py +180 -0
  984. ksadk/studio/shared_web_run_state.py +133 -0
  985. ksadk/studio/skill_discovery.py +305 -3
  986. ksadk/studio/static/assets/ChannelsPage-xX5HlMId.js +8 -0
  987. ksadk/studio/static/assets/CodeBlock-DMIf4h33-CkufcPYo.js +44 -0
  988. ksadk/studio/static/assets/ExecutionTree-v3HexvPo-Bk8wzGSy.js +1 -0
  989. ksadk/studio/static/assets/MathMessageMarkdown-BesSeCYl-DYG1Wzbx.js +8 -0
  990. ksadk/studio/static/assets/MermaidBlock-H_0qzQDf-BdXtxug_.js +11 -0
  991. ksadk/studio/static/assets/MessageMarkdown-CwMTvgFj-BeyLyQHu.js +59 -0
  992. ksadk/studio/static/assets/PrismRenderer-5pK6tUdb.js +3 -0
  993. ksadk/studio/static/assets/TeamsPage-CCaaGaVp.js +3 -0
  994. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-Bnb1O3tA.js +1 -0
  995. ksadk/studio/static/assets/architecture-7GRP2DOG-BMOPAkUC.js +1 -0
  996. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-5Zn1gqJv.js +36 -0
  997. ksadk/studio/static/assets/{blockDiagram-I7D4REHJ-CFmPl1de.js → blockDiagram-I7D4REHJ-CLB4L11u.js} +6 -6
  998. ksadk/studio/static/assets/{c4Diagram-7LVT6UL2-BRrGu8qt.js → c4Diagram-7LVT6UL2-BOma_Z_F.js} +7 -7
  999. ksadk/studio/static/assets/channel-r8itPEik.js +1 -0
  1000. ksadk/studio/static/assets/chunk-2E4U76K2-BFf_huql.js +2 -0
  1001. ksadk/studio/static/assets/chunk-2ZTRR5NV-C2qZJila.js +2 -0
  1002. ksadk/studio/static/assets/chunk-3Z5EZCMW-DMniOlPd.js +1 -0
  1003. ksadk/studio/static/assets/{chunk-4HAMMTFA-D220vUtq.js → chunk-4HAMMTFA-DVtDP4rm.js} +7 -7
  1004. ksadk/studio/static/assets/chunk-5V3GS4D5-i-ZDOEnP.js +1 -0
  1005. ksadk/studio/static/assets/chunk-6AZGARVD-BB6FqMl-.js +1 -0
  1006. ksadk/studio/static/assets/chunk-6EIED4P4-DdUJkP0f.js +1 -0
  1007. ksadk/studio/static/assets/chunk-6K3QC6MW-CqVsVn-y.js +1 -0
  1008. ksadk/studio/static/assets/chunk-6TQVIW2G-DKlLbNIP.js +1 -0
  1009. ksadk/studio/static/assets/chunk-747NJXEK-BFkZPlab.js +2 -0
  1010. ksadk/studio/static/assets/chunk-75Z2AOVW-BZNhM4vB.js +2 -0
  1011. ksadk/studio/static/assets/chunk-CLGD4ZFX-D-GTtyKs.js +1 -0
  1012. ksadk/studio/static/assets/{chunk-DU6HZSFF-C4DtVpCu.js → chunk-DU6HZSFF-CpEZCUgg.js} +1 -1
  1013. ksadk/studio/static/assets/chunk-F27PBJKO-D7pvKf0C.js +1 -0
  1014. ksadk/studio/static/assets/{chunk-GMAD6QVW-DiQA-u2N.js → chunk-GMAD6QVW-DE_8H717.js} +6 -6
  1015. ksadk/studio/static/assets/chunk-GVQU2GXP-BfEB0lNv.js +1 -0
  1016. ksadk/studio/static/assets/chunk-I5DQTOEV-Hm2LfiYI.js +1 -0
  1017. ksadk/studio/static/assets/chunk-ICYGCRZG-749o-pGJ.js +1 -0
  1018. ksadk/studio/static/assets/chunk-IH6LHLGP-CC6I9F3i.js +1 -0
  1019. ksadk/studio/static/assets/{chunk-IMKFNOWR-BSlbjT_b.js → chunk-IMKFNOWR-D38axYOR.js} +5 -5
  1020. ksadk/studio/static/assets/chunk-KI3K4JFJ-Rma-0k_M.js +1 -0
  1021. ksadk/studio/static/assets/chunk-L3NEJ4N5-Dq5xn7aL.js +1 -0
  1022. ksadk/studio/static/assets/chunk-LNGE3PJU-DWpGwHrW.js +34 -0
  1023. ksadk/studio/static/assets/{chunk-OSK3NFVY-M2m6G3j4.js → chunk-OSK3NFVY-DiCQjx9b.js} +5 -5
  1024. ksadk/studio/static/assets/chunk-OUJLGHUK-D0j2JRSg.js +2 -0
  1025. ksadk/studio/static/assets/{chunk-P2QGCYS3-DezaQxiK.js → chunk-P2QGCYS3-VdhKmfYq.js} +1 -1
  1026. ksadk/studio/static/assets/chunk-POPQ4Y6H-C1_rzO5M.js +1 -0
  1027. ksadk/studio/static/assets/chunk-PWAF6VOD-B45HvflI.js +1 -0
  1028. ksadk/studio/static/assets/{chunk-SHT3W25Y-DAyIVp5H.js → chunk-SHT3W25Y-DsCFnRVE.js} +9 -9
  1029. ksadk/studio/static/assets/{chunk-SVP7TREG-DulomOrS.js → chunk-SVP7TREG-DljApgRX.js} +1 -1
  1030. ksadk/studio/static/assets/{chunk-TICWLB2K-bHJYoflj.js → chunk-TICWLB2K-DWqRtyqa.js} +6 -6
  1031. ksadk/studio/static/assets/chunk-TLUHSLCS-DUeGgnD5.js +2 -0
  1032. ksadk/studio/static/assets/chunk-UY3FDG6J-CnmaAkG5.js +1 -0
  1033. ksadk/studio/static/assets/chunk-XHIXRSVI-BFQ6B8BE.js +1 -0
  1034. ksadk/studio/static/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
  1035. ksadk/studio/static/assets/classDiagram-ZZMXUADV-DjeMNJmu.js +1 -0
  1036. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-DjeMNJmu.js +1 -0
  1037. ksadk/studio/static/assets/clsx-DB0hHKMi.js +1 -0
  1038. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-om8AY0Mc.js +1 -0
  1039. ksadk/studio/static/assets/createLucideIcon-DR0LGTP5.js +1 -0
  1040. ksadk/studio/static/assets/cynefin-OW5HDTMX-7tP7QfM3.js +1 -0
  1041. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-6BrmK52S.js +62 -0
  1042. ksadk/studio/static/assets/dagre-GXQ25YYZ-buZBRlwz.js +4 -0
  1043. ksadk/studio/static/assets/{diagram-S7CK7UJ4-0BZ98mya.js → diagram-S7CK7UJ4-C6aH78c4.js} +3 -3
  1044. ksadk/studio/static/assets/diagram-UQ7AKVKN-DY_tQ6C_.js +41 -0
  1045. ksadk/studio/static/assets/diagram-VSXAHHWV-DX9p5cQT.js +3 -0
  1046. ksadk/studio/static/assets/diagram-VX7I27RA-DB2WSH8X.js +24 -0
  1047. ksadk/studio/static/assets/diagram-Z3DM3KII-Ce1BJwHE.js +24 -0
  1048. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-Daukxwqf.js +1 -0
  1049. ksadk/studio/static/assets/{erDiagram-RLTQ6QDP-DLGry2Ap.js → erDiagram-RLTQ6QDP-CGthTMmJ.js} +6 -6
  1050. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-BR2FzK4R.js +1 -0
  1051. ksadk/studio/static/assets/flowDiagram-HODETNUW-CZ1tEenp.js +1 -0
  1052. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BfoAZW9X.js +292 -0
  1053. ksadk/studio/static/assets/gitGraph-4MIJSDKK-DYlXv_yJ.js +1 -0
  1054. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-S985OIJF.js +106 -0
  1055. ksadk/studio/static/assets/iconfont-4HN3C9Pg.woff2 +0 -0
  1056. ksadk/studio/static/assets/index-C7DNDik2.css +2 -0
  1057. ksadk/studio/static/assets/index-Cy68gTlH.js +265 -0
  1058. ksadk/studio/static/assets/index.dom-BQenBtFm.js +1 -0
  1059. ksadk/studio/static/assets/info-A6RAGUB7-BlU-8_xu.js +1 -0
  1060. ksadk/studio/static/assets/infoDiagram-27XIBGKW-CO3W8tFn.js +2 -0
  1061. ksadk/studio/static/assets/{ishikawaDiagram-5VMMS53U-CljI2wyf.js → ishikawaDiagram-5VMMS53U-BUGEl8cO.js} +2 -2
  1062. ksadk/studio/static/assets/{journeyDiagram-3NMN7TZE-D50Fo2sL.js → journeyDiagram-3NMN7TZE-Ch2ZYxvr.js} +6 -6
  1063. ksadk/studio/static/assets/{kanban-definition-UXKFOSKX-DimfOTam.js → kanban-definition-UXKFOSKX-Da-Fp4vC.js} +3 -3
  1064. ksadk/studio/static/assets/kingsoft-cloud-BOcLiQ3e.ico +0 -0
  1065. ksadk/studio/static/assets/{line-CX5BOOUP.js → line-BDaeq300.js} +1 -1
  1066. ksadk/studio/static/assets/linear-DmucvK78.js +1 -0
  1067. ksadk/studio/static/assets/mermaid-parser.core-Cj5mYdBi.js +4 -0
  1068. ksadk/studio/static/assets/{mindmap-definition-YA3MSWOX-Bizzqy5R.js → mindmap-definition-YA3MSWOX-CvlsVQ38.js} +1 -1
  1069. ksadk/studio/static/assets/packet-AYTQ26CC-BSJEH9Lb.js +1 -0
  1070. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-BuHuNgT5.js +1 -0
  1071. ksadk/studio/static/assets/pie-WAS4IAKB-qxv01Y8W.js +1 -0
  1072. ksadk/studio/static/assets/{pieDiagram-E7YTZNPT-B9mrFSDF.js → pieDiagram-E7YTZNPT-DlrWiSOv.js} +1 -1
  1073. ksadk/studio/static/assets/preload-helper-CO68xz6u.js +1 -0
  1074. ksadk/studio/static/assets/presentation-yYw7xK60-BmcZriri.js +1 -0
  1075. ksadk/studio/static/assets/{quadrantDiagram-AXDQQJYC-NzUfCbMR.js → quadrantDiagram-AXDQQJYC-BA3hpUZM.js} +6 -6
  1076. ksadk/studio/static/assets/radar-RG4KPBEZ-B6h6pWOs.js +1 -0
  1077. ksadk/studio/static/assets/railroad-74A4TZTK-CGtTWdGc.js +1 -0
  1078. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-Cq7y22IA.js +1 -0
  1079. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-V0aQVv9m.js +1 -0
  1080. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-BQiIsX_p.js +1 -0
  1081. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-BxpAazym.js +1 -0
  1082. ksadk/studio/static/assets/{requirementDiagram-BXWQKSXE-BF3d103U.js → requirementDiagram-BXWQKSXE-E-Ge0FcV.js} +1 -1
  1083. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-CA6YKhQ3.js +40 -0
  1084. ksadk/studio/static/assets/{sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js → sequenceDiagram-WJ2MYXX4-CcElXGg4.js} +9 -9
  1085. ksadk/studio/static/assets/src-B6xuSHsQ.js +1 -0
  1086. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DdXZOFqY.js +1 -0
  1087. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-CJbOM-QK.js +1 -0
  1088. ksadk/studio/static/assets/swimlanes-42K2YHIH-NtgEEHLY.js +1 -0
  1089. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-D-AVlW8B.js +8 -0
  1090. ksadk/studio/static/assets/{timeline-definition-24CTP7MA-DxmSSjRB.js → timeline-definition-24CTP7MA-CIuYhNy3.js} +7 -7
  1091. ksadk/studio/static/assets/treeView-Q6P3EWNA-BTTYcvrF.js +1 -0
  1092. ksadk/studio/static/assets/treemap-WGGIJYW6-Cg7tyfH8.js +1 -0
  1093. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-7HbApbrv.js +34 -0
  1094. ksadk/studio/static/assets/wardley-WFR3VGLG-C6N1rULY.js +1 -0
  1095. ksadk/studio/static/assets/{wardleyDiagram-VM6X3IG4-Ba1AOWoe.js → wardleyDiagram-VM6X3IG4-CMJiaedy.js} +1 -1
  1096. ksadk/studio/static/assets/{xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js → xychartDiagram-S5SC5T6Z-BdgtMvW2.js} +6 -6
  1097. ksadk/studio/static/index.html +8 -2
  1098. ksadk/studio/teams_catalog.py +166 -0
  1099. ksadk/studio/teams_installation.py +217 -0
  1100. ksadk/studio/teams_node.py +549 -0
  1101. ksadk/studio/teams_node_factory.py +558 -0
  1102. ksadk/studio/teams_node_runner.py +72 -0
  1103. ksadk/studio/teams_node_v1.py +935 -0
  1104. ksadk/studio/teams_remote.py +496 -0
  1105. ksadk/studio/templates.py +41 -19
  1106. ksadk/studio/validator.py +13 -0
  1107. ksadk/studio/workspace.py +19 -4
  1108. ksadk/studio/workspace_plugins.py +138 -0
  1109. ksadk/studio/workspace_registry.py +286 -0
  1110. ksadk/tools/a2a_policy.py +5 -0
  1111. ksadk/tools/artifact_observation.py +53 -0
  1112. ksadk/tools/captured_source_artifact.py +68 -0
  1113. ksadk/tools/schema.py +34 -0
  1114. ksadk/toolsets/__init__.py +93 -88
  1115. ksadk/toolsets/a2a.py +89 -89
  1116. ksadk/toolsets/sandbox.py +377 -6
  1117. ksadk/toolsets/skill_management.py +315 -0
  1118. ksadk/toolsets/skills.py +446 -378
  1119. ksadk/toolsets/tool_selection.py +94 -0
  1120. ksadk/toolsets/workspace.py +344 -326
  1121. ksadk/toolsets/workspace_editing.py +291 -0
  1122. ksadk/toolsets/workspace_identity.py +15 -0
  1123. ksadk/toolsets/workspace_model_observation.py +104 -0
  1124. ksadk/toolsets/workspace_mutation.py +75 -0
  1125. ksadk/toolsets/workspace_read_budget.py +216 -0
  1126. ksadk/toolsets/workspace_search.py +192 -0
  1127. ksadk/toolsets/workspace_search_process.py +129 -0
  1128. ksadk/toolsets/workspace_state.py +6 -0
  1129. ksadk/version.py +1 -1
  1130. ksadk_runtime_common/http_headers.py +18 -0
  1131. ksadk_runtime_common/memory_backend/providers/lancedb.py +56 -2
  1132. ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -148
  1133. ksadk_runtime_common/workspace_files/router.py +28 -14
  1134. agentengine_sdk_python-0.8.4.dist-info/RECORD +0 -1070
  1135. ksadk/server/static/assets/MathMessageMarkdown-DbdW5A4_.js +0 -8
  1136. ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +0 -1
  1137. ksadk/server/static/assets/channel-CF5Up3hQ.js +0 -1
  1138. ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +0 -1
  1139. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +0 -1
  1140. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +0 -1
  1141. ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +0 -1
  1142. ksadk/server/static/assets/dist-B2_CVgKv.js +0 -1
  1143. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +0 -1
  1144. ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +0 -1
  1145. ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +0 -1
  1146. ksadk/server/static/assets/index-DcTML1Up.css +0 -2
  1147. ksadk/server/static/assets/index-Dh2XHqPK.js +0 -244
  1148. ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +0 -1
  1149. ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +0 -1
  1150. ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +0 -1
  1151. ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +0 -1
  1152. ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +0 -1
  1153. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +0 -1
  1154. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +0 -1
  1155. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +0 -1
  1156. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +0 -1
  1157. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +0 -8
  1158. ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +0 -1
  1159. ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +0 -1
  1160. ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +0 -1
  1161. ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +0 -41
  1162. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +0 -8
  1163. ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +0 -44
  1164. ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +0 -3
  1165. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +0 -1
  1166. ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +0 -1
  1167. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +0 -36
  1168. ksadk/studio/static/assets/channel-BqO-gtEw.js +0 -1
  1169. ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +0 -2
  1170. ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +0 -1
  1171. ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +0 -1
  1172. ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +0 -1
  1173. ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +0 -1
  1174. ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +0 -1
  1175. ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +0 -1
  1176. ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +0 -1
  1177. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +0 -1
  1178. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +0 -1
  1179. ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +0 -1
  1180. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +0 -62
  1181. ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +0 -4
  1182. ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +0 -41
  1183. ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +0 -3
  1184. ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +0 -24
  1185. ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +0 -24
  1186. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +0 -1
  1187. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +0 -1
  1188. ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +0 -1
  1189. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +0 -292
  1190. ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +0 -1
  1191. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +0 -106
  1192. ksadk/studio/static/assets/index-CeHL9ARV.css +0 -2
  1193. ksadk/studio/static/assets/index-D9QEcVpL.js +0 -320
  1194. ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +0 -1
  1195. ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +0 -2
  1196. ksadk/studio/static/assets/linear-BCxN9JLv.js +0 -1
  1197. ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +0 -7
  1198. ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +0 -1
  1199. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +0 -1
  1200. ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +0 -1
  1201. ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +0 -1
  1202. ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +0 -1
  1203. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +0 -1
  1204. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +0 -1
  1205. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +0 -1
  1206. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +0 -1
  1207. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +0 -40
  1208. ksadk/studio/static/assets/src-SFn9St9H.js +0 -1
  1209. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +0 -1
  1210. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +0 -1
  1211. ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +0 -1
  1212. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +0 -8
  1213. ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +0 -1
  1214. ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +0 -1
  1215. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +0 -34
  1216. ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +0 -1
  1217. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/WHEEL +0 -0
  1218. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/entry_points.txt +0 -0
  1219. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/licenses/LICENSE +0 -0
  1220. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/top_level.txt +0 -0
  1221. /ksadk/studio/static/assets/{MathMessageMarkdown-CBcDrAw--BEOyPC3w.css → MathMessageMarkdown-BesSeCYl-BEOyPC3w.css} +0 -0
@@ -1,18 +1,30 @@
1
1
  """Session, UI bootstrap, checkpoint-list, and tool-receipt routes."""
2
-
2
+ # ruff: noqa: I001
3
3
  from __future__ import annotations
4
4
 
5
+ import heapq
5
6
  import os
6
7
  from collections.abc import Mapping
7
8
  from typing import Any
8
9
 
9
- from fastapi import HTTPException
10
+ from fastapi import Depends, HTTPException
10
11
 
12
+ from ksadk.conversations.runtime_persistence import (
13
+ ensure_conversation_session,
14
+ require_conversation_session,
15
+ )
11
16
  from ksadk.runtime.executor import project_legacy_runtime_capabilities
17
+ from ksadk.runtime_context import PlatformIdentityContext
12
18
  from ksadk.server.factory import get_runtime_execution, get_state
13
19
  from ksadk.sessions import SessionEvent
14
20
  from ksadk.sessions.base import CheckpointEventQuery, SessionEventQuery
15
21
  from ksadk.sessions.errors import CheckpointScanRestartRequired, SessionBackendUnavailable
22
+ from ksadk.sessions.in_memory import InMemorySessionService
23
+ from ksadk.sessions.invocation_identity import (
24
+ bind_or_validate_session_identity,
25
+ identity_can_adopt_any_legacy_user,
26
+ session_identity_binding_matches,
27
+ )
16
28
  from ksadk.tools.gateway import tool_approval_capability
17
29
  from ksadk.toolsets import describe_agentengine_tools
18
30
  from ksadk_runtime_common.workspace_files import (
@@ -20,13 +32,13 @@ from ksadk_runtime_common.workspace_files import (
20
32
  workspace_files_enabled,
21
33
  )
22
34
 
35
+ from ..invocation_identity import resolve_trusted_invocation_identity
23
36
  from . import dependencies as deps
24
37
  from .common import (
25
38
  _action_response,
26
39
  _build_bootstrap_model_payload,
27
40
  _build_native_terminal_capability,
28
41
  _ensure_session,
29
- _hydrate_session,
30
42
  _resolve_agent_ui_spec,
31
43
  )
32
44
  from .models import (
@@ -41,6 +53,7 @@ from .models import (
41
53
  _runtime_agent_id,
42
54
  )
43
55
  from .projection import (
56
+ _HISTORY_INITIAL_EVENTS,
44
57
  _apply_adk_only_latest_resumable,
45
58
  _apply_checkpoint_resume_audit,
46
59
  _apply_latest_checkpoint_policy,
@@ -49,18 +62,130 @@ from .projection import (
49
62
  _event_to_action_payload,
50
63
  _extend_invocation_after_window,
51
64
  _extend_invocation_before_window,
52
- _iter_session_event_pages,
65
+ _history_identity,
66
+ _HistoryProjectionBudget,
53
67
  _require_action_session,
54
68
  _resume_audit_by_checkpoint,
55
69
  _session_to_action_payload,
56
70
  _tool_receipt_event_to_action_payload,
71
+ _validate_history_cursor,
57
72
  )
58
73
  from .routers import sessions_router, tools_router, ui_bootstrap_router
59
74
  from .streaming import _cancel_detached_streams_for_session
75
+ from .tool_receipt_claim_routes import get_tool_receipt_claim_action, reconcile_tool_receipt_claim_action # noqa: E501,F401,I001
76
+
77
+ from ksadk.server.routes.checkpoint_listing import _count_resumable_checkpoints, _normalize_action_id_list, _is_checkpoint_resumable, _list_checkpoints_payload_legacy_filtered, _list_checkpoints_payload as _checkpoint_listing_payload
78
+
79
+
80
+ async def _require_identity_action_session(
81
+ service: Any,
82
+ *,
83
+ session_id: str,
84
+ agent_id: str | None,
85
+ user_id: str | None,
86
+ invocation_identity: PlatformIdentityContext,
87
+ history_only: bool = False,
88
+ history_header_loader: Any = None,
89
+ ):
90
+ if history_only:
91
+ loader = history_header_loader or getattr(service, "get_session_header", service.get_session_metadata)
92
+ session = await loader(session_id)
93
+ from ksadk.sessions.agent_identity import session_agent_ids
94
+ if (session is None or (agent_id is not None and session.agent_id not in session_agent_ids(agent_id))
95
+ or (user_id is not None and invocation_identity.is_empty and session.user_id != user_id)):
96
+ raise HTTPException(status_code=404, detail="Session not found")
97
+ if invocation_identity.is_empty:
98
+ return session
99
+ if not agent_id:
100
+ raise HTTPException(status_code=400, detail="AgentId is required")
101
+ from ksadk.sessions.invocation_identity import bind_or_validate_session_identity
102
+ return await bind_or_validate_session_identity(
103
+ service=service, session=session, identity=invocation_identity,
104
+ requested_user_id=str(user_id or ""),
105
+ )
106
+ if invocation_identity.is_empty:
107
+ return await _require_action_session(
108
+ service,
109
+ session_id=session_id,
110
+ agent_id=agent_id,
111
+ user_id=user_id,
112
+ )
113
+ if not agent_id:
114
+ raise HTTPException(status_code=400, detail="AgentId is required")
115
+ return await require_conversation_session(
116
+ agent_id=agent_id,
117
+ user_id=str(user_id or ""),
118
+ session_id=session_id,
119
+ session_service_provider=lambda: service,
120
+ invocation_identity=invocation_identity,
121
+ )
122
+
123
+
124
+ async def _list_identity_session_metadata(
125
+ service: Any,
126
+ *,
127
+ agent_id: str,
128
+ user_id: str | None,
129
+ invocation_identity: PlatformIdentityContext,
130
+ ) -> list[Any]:
131
+ """List bound sessions; only the verified IAM account may adopt legacy rows."""
132
+
133
+ if invocation_identity.is_empty:
134
+ return await service.list_session_metadata(agent_id, user_id)
135
+ from ksadk.sessions.agent_identity import session_agent_ids
136
+ from ksadk.sessions.invocation_identity import identity_native_user_id
137
+
138
+ candidate_users: set[str | None] = {identity_native_user_id(invocation_identity)}
139
+ if identity_can_adopt_any_legacy_user(invocation_identity):
140
+ candidate_users.add(None)
141
+ elif (
142
+ invocation_identity.identity_namespace == "kscloud-iam"
143
+ and invocation_identity.subject_type == "user"
144
+ ):
145
+ candidate_users.add(invocation_identity.subject_id)
146
+ sessions: list[Any] = []
147
+ seen: set[str] = set()
148
+ for candidate_user in candidate_users:
149
+ candidates = [
150
+ session
151
+ for owner_id in session_agent_ids(agent_id)
152
+ for session in await service.list_session_metadata(owner_id, candidate_user)
153
+ ]
154
+ for session in candidates:
155
+ if session.id in seen:
156
+ continue
157
+ matches = await session_identity_binding_matches(
158
+ service=service,
159
+ session=session,
160
+ identity=invocation_identity,
161
+ )
162
+ if not matches:
163
+ try:
164
+ await bind_or_validate_session_identity(
165
+ service=service,
166
+ session=session,
167
+ identity=invocation_identity,
168
+ requested_user_id=session.user_id,
169
+ )
170
+ except HTTPException:
171
+ matches = False
172
+ else:
173
+ matches = True
174
+ if matches:
175
+ sessions.append(session)
176
+ seen.add(session.id)
177
+ sessions.sort(
178
+ key=lambda item: (item.updated_at, item.created_at, item.id),
179
+ reverse=True,
180
+ )
181
+ return sessions
60
182
 
61
183
 
62
184
  @ui_bootstrap_router.post("/agentengine/api/v1/GetAgentUiBootstrap")
63
- async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
185
+ async def get_agent_ui_bootstrap(
186
+ request: UiBootstrapRequest,
187
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
188
+ ):
64
189
  state = get_state()
65
190
  executor, launch_context = get_runtime_execution()
66
191
  detection = launch_context.detection
@@ -71,9 +196,7 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
71
196
  ui_spec = _resolve_agent_ui_spec()
72
197
  capability_subject = executor.capability_subject(launch_context)
73
198
  if capability_subject is not None:
74
- wait_timeout = max(
75
- 0.1, float(os.getenv("KSADK_PERSISTENCE_PROBE_TIMEOUT") or "2")
76
- )
199
+ wait_timeout = max(0.1, float(os.getenv("KSADK_PERSISTENCE_PROBE_TIMEOUT") or "2"))
77
200
  capability_snapshot = await state.persistence_capability.get_snapshot(
78
201
  runner=capability_subject,
79
202
  framework=framework,
@@ -87,14 +210,10 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
87
210
  runtime_capability_matrix = executor.capability_matrix(launch_context)
88
211
  else:
89
212
  runtime_capability_matrix = executor.capability_matrix(launch_context)
90
- persistence_status = dict(
91
- await deps.get_persistence_status(framework=framework)
92
- )
213
+ persistence_status = dict(await deps.get_persistence_status(framework=framework))
93
214
  if isinstance(persistence_status.get("Session"), Mapping):
94
215
  persistence = dict(persistence_status["Session"])
95
- checkpoint_persistence = dict(
96
- persistence_status.get("Checkpoint") or {}
97
- )
216
+ checkpoint_persistence = dict(persistence_status.get("Checkpoint") or {})
98
217
  else:
99
218
  persistence = persistence_status
100
219
  checkpoint_persistence = dict(persistence_status)
@@ -102,9 +221,7 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
102
221
  executor.native_capabilities(launch_context), runtime_capability_matrix
103
222
  )
104
223
  resume_capability = (
105
- runtime_capabilities.get("ResumeRun")
106
- if isinstance(runtime_capabilities, Mapping)
107
- else None
224
+ runtime_capabilities.get("ResumeRun") if isinstance(runtime_capabilities, Mapping) else None
108
225
  )
109
226
  resume_capability = resume_capability if isinstance(resume_capability, Mapping) else {}
110
227
  checkpoint_capability = (
@@ -116,9 +233,7 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
116
233
  checkpoint_capability if isinstance(checkpoint_capability, Mapping) else {}
117
234
  )
118
235
  cancel_capability = (
119
- runtime_capabilities.get("CancelRun")
120
- if isinstance(runtime_capabilities, Mapping)
121
- else None
236
+ runtime_capabilities.get("CancelRun") if isinstance(runtime_capabilities, Mapping) else None
122
237
  )
123
238
  cancel_capability = cancel_capability if isinstance(cancel_capability, Mapping) else {}
124
239
  checkpoint_resume_capability = {
@@ -163,6 +278,29 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
163
278
  and bool(getattr(state.agui_config, "preferred", False))
164
279
  else "responses"
165
280
  )
281
+ # Producer declaration is separate from transport availability. Consumers
282
+ # intersect this surface with their renderer catalogue before selecting a
283
+ # presentation profile; an older runtime has no such declaration.
284
+ presentation_capabilities: dict[str, Any] = {}
285
+ managed_remote_surface = (
286
+ framework in {"codex", "langgraph"}
287
+ and bool(getattr(state.a2a_bootstrap, "outbound_enabled", False))
288
+ )
289
+ if framework == "adk" or managed_remote_surface:
290
+ from ksadk.conversations.contracts import ConversationCapability, ConversationSurface
291
+
292
+ presentation_capabilities["ConversationSurface"] = ConversationSurface(
293
+ surface_id=f"runtime:{agent_id}",
294
+ session_id=request.SessionId or "new-session",
295
+ provider_ref=framework,
296
+ inputs=(ConversationCapability(name="ksadk.presentation", mode="native"),),
297
+ outputs=(
298
+ ConversationCapability(
299
+ name="agent.block",
300
+ mode="native" if framework == "adk" else "translated",
301
+ ),
302
+ ),
303
+ ).model_dump(mode="json", by_alias=True)
166
304
  return _action_response(
167
305
  "GetAgentUiBootstrap",
168
306
  {
@@ -174,6 +312,15 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
174
312
  },
175
313
  "Modules": ["Chat", "Build", "Deploy"],
176
314
  "Capabilities": {
315
+ # Lightweight protocol negotiation; it does not hydrate a
316
+ # session or require historical Agent packages to be patched.
317
+ "HistoryRead": {
318
+ "Protocol": "ksadk.history/v2",
319
+ "SessionContractVersion": 2,
320
+ "SupportsEpoch": True,
321
+ "SupportsSnapshot": True,
322
+ },
323
+ **presentation_capabilities,
177
324
  "Attachments": True,
178
325
  "WorkspaceFiles": workspace_enabled,
179
326
  "Approval": True,
@@ -196,7 +343,7 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
196
343
  },
197
344
  "MCP": False,
198
345
  "HostedRuntime": False,
199
- "NativeTerminal": _build_native_terminal_capability(framework),
346
+ "NativeTerminal": _build_native_terminal_capability(framework, invocation_identity),
200
347
  "BuiltinTools": describe_agentengine_tools(),
201
348
  },
202
349
  "WorkspaceFiles": build_workspace_files_bootstrap(enabled=workspace_enabled),
@@ -228,23 +375,52 @@ async def get_agent_ui_bootstrap(request: UiBootstrapRequest):
228
375
 
229
376
 
230
377
  @sessions_router.post("/agentengine/api/v1/CreateSession")
231
- async def create_session_action(request: CreateSessionActionRequest):
232
- session = await _ensure_session(request.AgentId, request.UserId or "user", request.SessionId)
233
- return _action_response("CreateSession", {"Session": await _session_to_action_payload(session)})
378
+ async def create_session_action(
379
+ request: CreateSessionActionRequest,
380
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
381
+ ):
382
+ service = deps.resolve_session_service()
383
+ if invocation_identity.is_empty:
384
+ session = await _ensure_session(
385
+ request.AgentId, request.UserId or "user", request.SessionId
386
+ )
387
+ else:
388
+ session = await ensure_conversation_session(
389
+ agent_id=request.AgentId,
390
+ user_id=request.UserId or "user",
391
+ session_id=request.SessionId,
392
+ session_service_provider=deps.resolve_session_service,
393
+ invocation_identity=invocation_identity,
394
+ )
395
+ return _action_response("CreateSession", {"Session": await _session_to_action_payload(session, service)})
234
396
 
235
397
 
236
398
  @sessions_router.post("/agentengine/api/v1/ListSessions")
237
- async def list_sessions_action(request: ListSessionsActionRequest):
399
+ async def list_sessions_action(
400
+ request: ListSessionsActionRequest,
401
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
402
+ ):
238
403
  service = deps.resolve_session_service()
239
404
  offset = (request.Page - 1) * request.PageSize
240
- sessions = await service.list_sessions(
241
- request.AgentId,
242
- request.UserId,
243
- offset=offset,
244
- limit=request.PageSize,
245
- )
246
- total = await service.count_sessions(request.AgentId, request.UserId)
247
- session_payloads = [await _session_to_action_payload(session) for session in sessions]
405
+ if invocation_identity.is_empty:
406
+ if isinstance(service, InMemorySessionService):
407
+ all_metadata = await service.list_session_metadata(request.AgentId, request.UserId)
408
+ sessions = all_metadata[offset:offset + request.PageSize]
409
+ else:
410
+ sessions = await service.list_sessions(
411
+ request.AgentId, request.UserId, offset=offset, limit=request.PageSize,
412
+ )
413
+ total = await service.count_sessions(request.AgentId, request.UserId)
414
+ else:
415
+ all_sessions = await _list_identity_session_metadata(
416
+ service,
417
+ agent_id=request.AgentId,
418
+ user_id=request.UserId,
419
+ invocation_identity=invocation_identity,
420
+ )
421
+ total = len(all_sessions)
422
+ sessions = all_sessions[offset : offset + request.PageSize]
423
+ session_payloads = [await _session_to_action_payload(session, service) for session in sessions]
248
424
  return _action_response(
249
425
  "ListSessions",
250
426
  {
@@ -260,28 +436,33 @@ async def list_sessions_action(request: ListSessionsActionRequest):
260
436
 
261
437
 
262
438
  @sessions_router.post("/agentengine/api/v1/GetSession")
263
- async def get_session_action(request: SessionIdRequest):
439
+ async def get_session_action(
440
+ request: SessionIdRequest,
441
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
442
+ ):
264
443
  service = deps.resolve_session_service()
265
- session = await _require_action_session(
444
+ session = await _require_identity_action_session(
266
445
  service,
267
446
  session_id=request.SessionId,
268
447
  agent_id=request.AgentId,
269
448
  user_id=request.UserId,
449
+ invocation_identity=invocation_identity,
270
450
  )
271
- hydrated = await _hydrate_session(session)
272
- if hydrated is None:
273
- raise HTTPException(status_code=404, detail="Session not found")
274
- return _action_response("GetSession", {"Session": await _session_to_action_payload(hydrated)})
451
+ return _action_response("GetSession", {"Session": await _session_to_action_payload(session, service)})
275
452
 
276
453
 
277
454
  @sessions_router.post("/agentengine/api/v1/DeleteSession")
278
- async def delete_session_action(request: SessionIdRequest):
455
+ async def delete_session_action(
456
+ request: SessionIdRequest,
457
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
458
+ ):
279
459
  service = deps.resolve_session_service()
280
- await _require_action_session(
460
+ await _require_identity_action_session(
281
461
  service,
282
462
  session_id=request.SessionId,
283
463
  agent_id=request.AgentId,
284
464
  user_id=request.UserId,
465
+ invocation_identity=invocation_identity,
285
466
  )
286
467
  await _cancel_detached_streams_for_session(request.SessionId)
287
468
  deleted = await service.delete_session(request.SessionId)
@@ -291,7 +472,10 @@ async def delete_session_action(request: SessionIdRequest):
291
472
 
292
473
 
293
474
  @sessions_router.post("/agentengine/api/v1/ListSessionEvents")
294
- async def list_session_events_action(request: ListSessionEventsActionRequest):
475
+ async def list_session_events_action(
476
+ request: ListSessionEventsActionRequest,
477
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
478
+ ):
295
479
  _executor, launch_context = get_runtime_execution()
296
480
  service = deps.resolve_session_service()
297
481
  session_id = str(request.SessionId or "").strip()
@@ -302,11 +486,31 @@ async def list_session_events_action(request: ListSessionEventsActionRequest):
302
486
  # seq 游标是会话内序号,跨会话模式下不适用,直接忽略)
303
487
  agent_id = str(request.AgentId or "").strip() or _runtime_agent_id(launch_context)
304
488
  session_ids = None
305
- if request.UserId is not None:
489
+ if request.UserId is not None or not invocation_identity.is_empty:
306
490
  session_ids = [
307
491
  session.id
308
- for session in await service.list_session_metadata(agent_id, request.UserId)
492
+ for session in await _list_identity_session_metadata(
493
+ service,
494
+ agent_id=agent_id,
495
+ user_id=request.UserId,
496
+ invocation_identity=invocation_identity,
497
+ )
309
498
  ]
499
+ if not invocation_identity.is_empty and not session_ids:
500
+ return _action_response(
501
+ "ListSessionEvents",
502
+ {
503
+ "Events": [],
504
+ "Total": 0,
505
+ "Offset": request.Offset or 0,
506
+ "Limit": request.Limit or 0,
507
+ "AfterSeqId": request.AfterSeqId,
508
+ "BeforeSeqId": request.BeforeSeqId,
509
+ "CheckpointIds": request.CheckpointIds,
510
+ "EventTypes": request.EventTypes,
511
+ "ScopedAllSessions": True,
512
+ },
513
+ )
310
514
  query = SessionEventQuery(
311
515
  session_ids=session_ids,
312
516
  agent_id=agent_id,
@@ -342,37 +546,66 @@ async def list_session_events_action(request: ListSessionEventsActionRequest):
342
546
  "ScopedAllSessions": True,
343
547
  },
344
548
  )
345
- await _require_action_session(
549
+ session = await _require_identity_action_session(
346
550
  service,
347
551
  session_id=session_id,
348
552
  agent_id=request.AgentId,
349
553
  user_id=request.UserId,
554
+ invocation_identity=invocation_identity,
555
+ history_only=True,
556
+ )
557
+ epoch, is_live = _history_identity(service, session)
558
+ _validate_history_cursor(
559
+ epoch=epoch, is_live=is_live, requested_epoch=request.HistoryEpoch,
560
+ cursor_source=request.CursorSource,
561
+ has_cursor=(request.AfterSeqId or 0) > 0 or (request.BeforeSeqId or 0) > 0,
562
+ )
563
+ forward = request.EventOrder == "session_seq"
564
+ seq_page = forward or (request.BeforeSeqId is not None and not request.Offset)
565
+ max_seq = getattr(service, "get_max_seq_id", None)
566
+ newest_seq = (await max_seq(session_id) if callable(max_seq)
567
+ else max((event.seq_id for event in await service.get_events(
568
+ session_id, limit=1)), default=0))
569
+ snapshot_seq = (request.SnapshotSeqId if request.SnapshotSeqId is not None
570
+ else newest_seq)
571
+ snapshot_upper = min(
572
+ value for value in (request.BeforeSeqId, snapshot_seq + 1) if value is not None
350
573
  )
351
574
  query = SessionEventQuery(
352
575
  session_ids=[session_id],
353
- agent_id=request.AgentId,
576
+ agent_id=session.agent_id,
354
577
  offset=request.Offset or 0,
355
- limit=request.Limit,
578
+ limit=request.Limit + 1 if seq_page else request.Limit,
356
579
  after_seq_id=request.AfterSeqId,
357
- before_seq_id=request.BeforeSeqId,
580
+ before_seq_id=snapshot_upper,
358
581
  event_types=event_types,
359
582
  checkpoint_ids=checkpoint_ids,
583
+ from_start=forward,
584
+ order_by_seq=seq_page,
360
585
  )
361
586
  events = await service.query_events(query)
587
+ has_more = seq_page and len(events) > request.Limit
588
+ if seq_page:
589
+ events = events[:request.Limit] if forward else events[-request.Limit:]
362
590
  total = await service.count_event_query(
363
591
  SessionEventQuery(
364
592
  session_ids=[session_id],
365
- agent_id=request.AgentId,
593
+ agent_id=session.agent_id,
366
594
  after_seq_id=request.AfterSeqId,
367
- before_seq_id=request.BeforeSeqId,
595
+ before_seq_id=snapshot_upper,
368
596
  event_types=event_types,
369
597
  checkpoint_ids=checkpoint_ids,
370
598
  )
371
599
  )
372
- events.sort(
373
- key=lambda event: (event.timestamp, event.session_id, event.seq_id, event.id),
374
- reverse=True,
375
- )
600
+ if forward:
601
+ events.sort(key=lambda event: (event.seq_id, event.id))
602
+ elif seq_page:
603
+ events.sort(key=lambda event: (event.seq_id, event.id), reverse=True)
604
+ elif not seq_page:
605
+ events.sort(
606
+ key=lambda event: (event.timestamp, event.session_id, event.seq_id, event.id),
607
+ reverse=True,
608
+ )
376
609
  return _action_response(
377
610
  "ListSessionEvents",
378
611
  {
@@ -384,62 +617,184 @@ async def list_session_events_action(request: ListSessionEventsActionRequest):
384
617
  "BeforeSeqId": request.BeforeSeqId,
385
618
  "CheckpointIds": request.CheckpointIds,
386
619
  "EventTypes": request.EventTypes,
620
+ "HistoryEpoch": epoch,
621
+ "SnapshotSeqId": snapshot_seq,
622
+ "PersistenceDegraded": is_live,
623
+ "DataSource": "runtime",
624
+ "Degraded": False,
625
+ "CursorSource": "runtime",
626
+ "CursorCompatibleWithRuntime": True,
627
+ "SessionContractVersion": 2,
628
+ **({
629
+ "NextCursor": events[-1].seq_id if events else (request.AfterSeqId or 0) if forward else None,
630
+ "HasMore": has_more,
631
+ } if seq_page else {}),
632
+ **({
633
+ "EventOrder": "session_seq",
634
+ } if forward else {}),
387
635
  },
388
636
  )
389
637
 
390
638
 
391
639
  @sessions_router.post("/agentengine/api/v1/ListSessionMessages")
392
- async def list_session_messages_action(request: ListSessionMessagesActionRequest):
393
- from ksadk.conversations.message_projection import project_session_messages
394
-
640
+ async def list_session_messages_action(
641
+ request: ListSessionMessagesActionRequest,
642
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
643
+ ):
395
644
  service = deps.resolve_session_service()
396
- await _require_action_session(
397
- service,
398
- session_id=request.SessionId,
399
- agent_id=request.AgentId,
400
- user_id=request.UserId,
401
- )
402
- total_events = await service.count_events(
403
- request.SessionId,
404
- after_seq_id=request.AfterSeqId,
405
- before_seq_id=request.BeforeSeqId,
645
+ from ksadk.server.history_page_cache import cache_for, eligible, bounded_pg_read
646
+
647
+ async def load_scope():
648
+ newest_seq = None
649
+ combined = getattr(service, 'get_session_header_with_watermark', None)
650
+
651
+ async def header_with_watermark(session_id):
652
+ nonlocal newest_seq
653
+ header, newest_seq = await combined(session_id)
654
+ return header
655
+
656
+ session = await _require_identity_action_session(
657
+ service,
658
+ session_id=request.SessionId,
659
+ agent_id=request.AgentId,
660
+ user_id=request.UserId,
661
+ invocation_identity=invocation_identity,
662
+ history_only=True,
663
+ history_header_loader=(header_with_watermark
664
+ if callable(combined) and bounded_pg_read(service, False) else None),
665
+ )
666
+ epoch, is_live = _history_identity(service, session)
667
+ max_seq = getattr(service, "get_max_seq_id", None)
668
+ if newest_seq is None:
669
+ newest_seq = (await max_seq(request.SessionId) if callable(max_seq)
670
+ else max((event.seq_id for event in await service.get_events(
671
+ request.SessionId, limit=1)), default=0))
672
+ return session, epoch, is_live, newest_seq
673
+
674
+ if eligible(service, False):
675
+ # Includes the full verified principal (including actor), Agent and
676
+ # legacy UserId hint. Never reuse authorization after the SQL finishes.
677
+ scope_key = (request.SessionId, request.AgentId, request.UserId, invocation_identity)
678
+ session, epoch, is_live, newest_seq = await cache_for(service).lookup(scope_key, load_scope)
679
+ else:
680
+ session, epoch, is_live, newest_seq = await load_scope()
681
+ _validate_history_cursor(
682
+ epoch=epoch, is_live=is_live, requested_epoch=request.HistoryEpoch,
683
+ cursor_source=request.CursorSource,
684
+ has_cursor=(request.AfterSeqId or 0) > 0 or (request.BeforeSeqId or 0) > 0,
406
685
  )
407
- event_offset = 0
408
- if request.AfterSeqId is not None and total_events > 2000:
409
- # Storage pagination is tail-based. Offset past the newest surplus so
410
- # reconnect starts with the oldest unseen window and cannot skip gaps.
411
- event_offset = total_events - 2000
412
- events = await service.get_events(
413
- request.SessionId,
414
- offset=event_offset,
415
- limit=2000,
416
- after_seq_id=request.AfterSeqId,
417
- before_seq_id=request.BeforeSeqId,
686
+ snapshot_seq = (request.SnapshotSeqId if request.SnapshotSeqId is not None
687
+ else newest_seq)
688
+ if eligible(service, is_live):
689
+ import json
690
+ from starlette.responses import Response
691
+
692
+ key = (epoch, newest_seq, snapshot_seq, invocation_identity.user_scope,
693
+ request.model_dump_json())
694
+
695
+ async def produce():
696
+ # Eligible clean PostgreSQL reads complete several adjacent event
697
+ # windows serially. Avoid a pool reset/network round trip between
698
+ # every window; retain normal cleanup once the projection ends.
699
+ primary = getattr(service, 'primary', service)
700
+ async with primary.history_read_scope():
701
+ result = await _project_session_message_page(
702
+ request, service, invocation_identity, epoch, is_live, snapshot_seq)
703
+ if _history_identity(service, session) != (epoch, is_live):
704
+ from ksadk.sessions.errors import HistoryReloadRequired
705
+ raise HistoryReloadRequired("History source changed during projection")
706
+ return result["Data"]
707
+
708
+ body = await cache_for(service).read(key, produce)
709
+ if _history_identity(service, session) != (epoch, is_live):
710
+ from ksadk.sessions.errors import HistoryReloadRequired
711
+ raise HistoryReloadRequired("History source changed during read")
712
+ # Each request keeps its own envelope/request id. The immutable Data
713
+ # bytes are serialized once, rather than encoding the same MiB of
714
+ # tools independently for every concurrent reader.
715
+ envelope = _action_response("ListSessionMessages", None)
716
+ del envelope["Data"]
717
+ prefix = json.dumps(envelope, separators=(",", ":"))[:-1].encode()
718
+ return Response(prefix + b',"Data":' + body + b'}', media_type="application/json")
719
+ return await _project_session_message_page(
720
+ request, service, invocation_identity, epoch, is_live, snapshot_seq)
721
+
722
+
723
+ async def _project_session_message_page(request, service, invocation_identity, epoch, is_live, snapshot_seq):
724
+ from ksadk.conversations.message_projection import project_session_messages
725
+ from ksadk.server.history_page_cache import bounded_pg_read
726
+ snapshot_upper = min(
727
+ value for value in (request.BeforeSeqId, snapshot_seq + 1) if value is not None
418
728
  )
729
+ message_window = getattr(service, 'get_message_event_window', None)
730
+ if callable(message_window) and bounded_pg_read(service, is_live):
731
+ events = await message_window(
732
+ request.SessionId, limit=_HISTORY_INITIAL_EVENTS,
733
+ from_start=request.AfterSeqId is not None,
734
+ after_seq_id=request.AfterSeqId, before_seq_id=snapshot_upper,
735
+ )
736
+ elif request.AfterSeqId is not None:
737
+ events = await service.query_events(SessionEventQuery(
738
+ session_ids=[request.SessionId], from_start=True, order_by_seq=True,
739
+ limit=_HISTORY_INITIAL_EVENTS, after_seq_id=request.AfterSeqId,
740
+ before_seq_id=snapshot_upper,
741
+ ))
742
+ else:
743
+ events = await service.get_events(
744
+ request.SessionId, limit=_HISTORY_INITIAL_EVENTS,
745
+ before_seq_id=snapshot_upper,
746
+ )
747
+ budget = _HistoryProjectionBudget()
748
+ budget.account(events)
749
+ boundary_hint: dict[str, bool] = {}
750
+ projection_cache: dict[str, dict[str, Any]] = {}
419
751
 
420
- def project(
752
+ async def project(
421
753
  events_to_project: list[SessionEvent],
422
754
  ) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:
423
755
  serialized = [_event_to_action_payload(event) for event in events_to_project]
756
+ from ksadk.kernel.bootstrap import get_agent_kernel_runtime
757
+ from ksadk.kernel.history_projection import project_inbox_inputs
758
+
759
+ message_events = await project_inbox_inputs(
760
+ serialized, runtime=get_agent_kernel_runtime(), session_id=request.SessionId,
761
+ tenant_id=invocation_identity.tenant_id,
762
+ request_cache=projection_cache,
763
+ )
764
+ budget.account_enrichment(serialized, message_events)
424
765
  return serialized, project_session_messages(
425
- serialized,
766
+ message_events,
426
767
  include_reasoning=request.IncludeReasoning,
427
768
  include_tool_events=request.IncludeToolEvents,
428
769
  include_attachments=request.IncludeAttachments,
770
+ session_id=request.SessionId,
429
771
  )
430
772
 
431
- serialized_events, messages = project(events)
773
+ serialized_events, messages = await project(events)
432
774
  if request.AfterSeqId is not None:
433
- if total_events > len(events):
775
+ if events:
434
776
  events = await _extend_invocation_after_window(
435
777
  service,
436
778
  request.SessionId,
437
779
  events,
438
- before_seq_id=request.BeforeSeqId,
780
+ before_seq_id=snapshot_upper,
781
+ budget=budget,
439
782
  )
440
- serialized_events, messages = project(events)
783
+ serialized_events, messages = await project(events)
441
784
  page = messages
442
- has_more = total_events > len(serialized_events)
785
+ # Keep complete invocation groups, including a first group larger than
786
+ # the requested message limit.
787
+ if len(page) > request.Limit:
788
+ end = request.Limit
789
+ boundary = int(page[end - 1].get("StartSeqId") or 0)
790
+ while end < len(page) and int(page[end].get("StartSeqId") or 0) == boundary:
791
+ end += 1
792
+ page = page[:end]
793
+ last_seq = events[-1].seq_id if events else request.AfterSeqId
794
+ has_more = len(page) < len(messages) or bool(await service.query_events(SessionEventQuery(
795
+ session_ids=[request.SessionId], from_start=True, order_by_seq=True,
796
+ limit=1, after_seq_id=last_seq, before_seq_id=snapshot_upper,
797
+ )))
443
798
  next_cursor = None
444
799
  else:
445
800
  page_start = len(messages)
@@ -464,7 +819,6 @@ async def list_session_messages_action(request: ListSessionMessagesActionRequest
464
819
  if (
465
820
  page
466
821
  and events
467
- and total_events > len(events)
468
822
  and _event_invocation_id(events[0])
469
823
  and any(
470
824
  str(message.get("InvocationId") or "") == _event_invocation_id(events[0])
@@ -476,8 +830,10 @@ async def list_session_messages_action(request: ListSessionMessagesActionRequest
476
830
  request.SessionId,
477
831
  events,
478
832
  after_seq_id=request.AfterSeqId,
833
+ budget=budget,
834
+ boundary_hint=boundary_hint,
479
835
  )
480
- serialized_events, messages = project(events)
836
+ serialized_events, messages = await project(events)
481
837
  page_start = len(messages)
482
838
  while page_start > 0:
483
839
  group_start_seq_id = int(messages[page_start - 1].get("StartSeqId") or 0)
@@ -498,10 +854,17 @@ async def list_session_messages_action(request: ListSessionMessagesActionRequest
498
854
  break
499
855
  page = messages[page_start:]
500
856
  minimum_start_seq_id = int(page[0].get("StartSeqId") or 0) if page else 0
501
- has_more = page_start > 0 or total_events > len(serialized_events)
857
+ has_more = page_start > 0
858
+ if not has_more and 'has_more' in boundary_hint:
859
+ has_more = boundary_hint['has_more']
860
+ elif not has_more and events:
861
+ probe = getattr(service, "has_events", None)
862
+ bounds = dict(after_seq_id=request.AfterSeqId, before_seq_id=events[0].seq_id)
863
+ has_more = (await probe(request.SessionId, **bounds) if callable(probe)
864
+ else bool(await service.get_events(request.SessionId, limit=1, **bounds)))
502
865
  # BeforeSeqId is exclusive. Use the invocation group boundary so the
503
866
  # next page cannot duplicate reasoning/tools or skip its user message.
504
- next_cursor = minimum_start_seq_id if has_more else None
867
+ next_cursor = (minimum_start_seq_id or (events[0].seq_id if events else 0)) if has_more else None
505
868
  latest_seq_id = (
506
869
  int(page[-1].get("SeqId") or 0)
507
870
  if page
@@ -518,299 +881,71 @@ async def list_session_messages_action(request: ListSessionMessagesActionRequest
518
881
  "LatestSeqId": latest_seq_id,
519
882
  "HasMore": has_more,
520
883
  "NextCursor": next_cursor,
884
+ "DataSource": "runtime",
885
+ "CursorSource": "runtime",
886
+ "HistoryEpoch": epoch,
887
+ "SnapshotSeqId": snapshot_seq,
888
+ "PersistenceDegraded": is_live,
889
+ "Degraded": False,
890
+ "CursorCompatibleWithRuntime": True,
891
+ "SessionContractVersion": 2,
521
892
  },
522
893
  )
523
894
 
524
895
 
525
- def _count_resumable_checkpoints(checkpoints: list[dict[str, Any]]) -> int:
526
- """统计可恢复 checkpoint 数量。
527
-
528
- 规则:IsResumable=True AND ReplayAllowed!=False AND IsTerminal!=True
529
- AND CheckpointStatus not in {expired, disabled}。
530
- 不排除 resumed(已恢复过的仍计入,符合存档点可反复读的回档语义)。
531
- """
532
- resumable = 0
533
- for cp in checkpoints:
534
- if cp.get("IsResumable") is not True:
535
- continue
536
- if cp.get("ReplayAllowed") is False:
537
- continue
538
- if cp.get("IsTerminal") is True:
539
- continue
540
- status = str(cp.get("CheckpointStatus") or "").strip().lower()
541
- if status in {"expired", "disabled"}:
542
- continue
543
- resumable += 1
544
- return resumable
545
-
546
-
547
- def _normalize_action_id_list(value: list[str] | str | None) -> list[str]:
548
- values = [value] if isinstance(value, str) else list(value or [])
549
- return list(dict.fromkeys(str(item).strip() for item in values if str(item).strip()))
550
-
551
-
552
- def _is_checkpoint_resumable(checkpoint: Mapping[str, Any]) -> bool:
553
- if checkpoint.get("IsResumable") is not True or checkpoint.get("IsTerminal") is True:
554
- return False
555
- if checkpoint.get("ReplayAllowed") is False:
556
- return False
557
- checkpoint_status = str(checkpoint.get("CheckpointStatus") or "").strip().lower()
558
- resume_status = str(checkpoint.get("ResumeStatus") or "").strip().lower()
559
- return (
560
- checkpoint_status not in {"expired", "disabled", "terminal"}
561
- and resume_status != "disabled"
562
- )
563
-
564
-
565
- async def _list_checkpoints_payload_legacy_filtered(
896
+ async def _list_checkpoints_payload(
566
897
  request: ListSessionCheckpointsActionRequest,
567
- session_ids: list[str],
568
- checkpoint_ids: list[str],
898
+ invocation_identity: PlatformIdentityContext,
569
899
  ) -> dict[str, Any]:
570
- if len(session_ids) != 1:
571
- raise HTTPException(
572
- status_code=501, detail="Backend does not support multi-session checkpoints"
573
- )
574
- service = deps.resolve_session_service()
575
- events = await service.get_events(session_ids[0])
576
- audit = _resume_audit_by_checkpoint(events)
577
- latest_by_session_run: dict[tuple[str, str], int] = {}
578
- for event in events:
579
- checkpoint = _checkpoint_event_to_action_payload(event)
580
- if checkpoint is not None and (checkpoint.get("Metadata") or {}).get(
581
- "only_latest_resumable"
582
- ):
583
- key = (event.session_id, str(checkpoint.get("RunId") or ""))
584
- latest_by_session_run[key] = max(
585
- latest_by_session_run.get(key, 0), int(checkpoint.get("SeqId") or 0)
586
- )
587
- checkpoints: list[dict[str, Any]] = []
588
- resume_status_filter = set(request.ResumeStatus)
589
- resume_type_filter = set(request.ResumeTypes)
590
- for event in events:
591
- checkpoint = _checkpoint_event_to_action_payload(event)
592
- if checkpoint is None:
593
- continue
594
- checkpoint = _apply_checkpoint_resume_audit(checkpoint, audit)
595
- checkpoint = _apply_latest_checkpoint_policy(
596
- checkpoint, latest_by_session_run, session_id=event.session_id
597
- )
598
- if request.RunId and checkpoint["RunId"] != str(request.RunId):
599
- continue
600
- if checkpoint_ids and checkpoint["CheckpointId"] not in checkpoint_ids:
601
- continue
602
- if request.Framework and str(checkpoint["Framework"]).lower() != str(
603
- request.Framework
604
- ).lower():
605
- continue
606
- if (
607
- resume_status_filter
608
- and str(checkpoint.get("ResumeStatus") or "").lower()
609
- not in resume_status_filter
610
- ):
611
- continue
612
- if (
613
- resume_type_filter
614
- and str(checkpoint.get("Scope") or "unknown").lower()
615
- not in resume_type_filter
616
- ):
617
- continue
618
- checkpoints.append(checkpoint)
619
- checkpoints = _apply_adk_only_latest_resumable(checkpoints)
620
- resumable_total = sum(_is_checkpoint_resumable(item) for item in checkpoints)
621
- if request.OnlyResumable:
622
- checkpoints = [item for item in checkpoints if _is_checkpoint_resumable(item)]
623
- offset = int(request.Offset or 0)
624
- checkpoints.sort(
625
- key=lambda item: (item["Timestamp"], item["SessionId"], item["SeqId"]),
626
- reverse=True,
900
+ return await _checkpoint_listing_payload(
901
+ request, invocation_identity,
902
+ require_session=_require_identity_action_session,
903
+ list_sessions=_list_identity_session_metadata,
627
904
  )
628
- checkpoints = checkpoints[offset: offset + request.Limit]
629
- return {
630
- "Checkpoints": checkpoints,
631
- "Total": len(checkpoints),
632
- "ResumableTotal": resumable_total,
633
- "HasResumableCheckpoint": resumable_total > 0,
634
- "SessionId": session_ids,
635
- "CheckpointId": checkpoint_ids,
636
- "ResumeStatus": request.ResumeStatus,
637
- "ResumeTypes": request.ResumeTypes,
638
- "Offset": offset,
639
- "Limit": request.Limit,
640
- }
641
-
642
-
643
- async def _list_checkpoints_payload(request: ListSessionCheckpointsActionRequest) -> dict[str, Any]:
644
- service = deps.resolve_session_service()
645
- session_ids = _normalize_action_id_list(request.SessionId)
646
- checkpoint_ids = _normalize_action_id_list(request.CheckpointId)
647
- if session_ids:
648
- for session_id in session_ids:
649
- await _require_action_session(
650
- service,
651
- session_id=session_id,
652
- agent_id=request.AgentId,
653
- user_id=request.UserId,
654
- )
655
- elif request.UserId is not None:
656
- session_ids = [
657
- session.id
658
- for session in await service.list_session_metadata(
659
- request.AgentId, request.UserId
660
- )
661
- ]
662
- query = CheckpointEventQuery(
663
- session_ids=session_ids or None,
664
- agent_id=request.AgentId,
665
- checkpoint_ids=checkpoint_ids or None,
666
- run_id=str(request.RunId or "").strip() or None,
667
- framework=str(request.Framework or "").strip().lower() or None,
668
- limit=50,
669
- )
670
- resume_status_filter = set(request.ResumeStatus)
671
- resume_type_filter = set(request.ResumeTypes)
672
- offset = int(request.Offset or 0)
673
- for attempt in range(2):
674
- total = 0
675
- resumable_total = 0
676
- checkpoints: list[dict[str, Any]] = []
677
- batches = service.iter_checkpoint_event_chunks(query)
678
- try:
679
- async for batch in batches:
680
- chunk = [
681
- checkpoint
682
- for event in batch
683
- if (checkpoint := _checkpoint_event_to_action_payload(event)) is not None
684
- and (
685
- not checkpoint_ids
686
- or str(checkpoint.get("CheckpointId") or "") in checkpoint_ids
687
- )
688
- and (
689
- query.run_id is None
690
- or str(checkpoint.get("RunId") or "") == query.run_id
691
- )
692
- and (
693
- query.framework is None
694
- or str(checkpoint.get("Framework") or "").lower()
695
- == query.framework
696
- )
697
- ]
698
- keys = [
699
- (
700
- str(checkpoint["SessionId"]),
701
- str(checkpoint["RunId"]),
702
- str(checkpoint["CheckpointId"]),
703
- )
704
- for checkpoint in chunk
705
- ]
706
- stats = await service.get_checkpoint_stats(keys)
707
- for checkpoint in chunk:
708
- checkpoint = _apply_checkpoint_resume_audit(
709
- checkpoint, stats.get("audits") or {}
710
- )
711
- checkpoint = _apply_latest_checkpoint_policy(
712
- checkpoint,
713
- stats.get("latest_seq_ids") or {},
714
- session_id=str(checkpoint.get("SessionId") or ""),
715
- )
716
- if resume_status_filter and str(
717
- checkpoint.get("ResumeStatus") or ""
718
- ).strip().lower() not in resume_status_filter:
719
- continue
720
- if resume_type_filter and str(
721
- checkpoint.get("Scope") or "unknown"
722
- ).strip().lower() not in resume_type_filter:
723
- continue
724
- resumable_total += int(_is_checkpoint_resumable(checkpoint))
725
- if request.OnlyResumable and not _is_checkpoint_resumable(checkpoint):
726
- continue
727
- checkpoints.append(checkpoint)
728
- total += 1
729
- except CheckpointScanRestartRequired as exc:
730
- if attempt == 0:
731
- continue
732
- raise SessionBackendUnavailable(
733
- "Checkpoint backend changed repeatedly during one request"
734
- ) from exc
735
- except NotImplementedError:
736
- return await _list_checkpoints_payload_legacy_filtered(
737
- request, session_ids, checkpoint_ids
738
- )
739
- finally:
740
- close = getattr(batches, "aclose", None)
741
- if callable(close):
742
- await close()
743
- break
744
- checkpoints.sort(
745
- key=lambda item: (item["Timestamp"], item["SessionId"], item["SeqId"]),
746
- reverse=True,
747
- )
748
- checkpoints = checkpoints[offset : offset + int(request.Limit)]
749
- return {
750
- "Checkpoints": checkpoints,
751
- "Total": total,
752
- "ResumableTotal": resumable_total,
753
- "HasResumableCheckpoint": resumable_total > 0,
754
- "SessionId": session_ids,
755
- "CheckpointId": checkpoint_ids,
756
- "ResumeStatus": request.ResumeStatus,
757
- "ResumeTypes": request.ResumeTypes,
758
- "Offset": offset,
759
- "Limit": request.Limit,
760
- }
761
905
 
762
906
 
763
907
  @sessions_router.post("/agentengine/api/v1/ListSessionCheckpoints")
764
- async def list_session_checkpoints_action(request: ListSessionCheckpointsActionRequest):
765
- return _action_response("ListSessionCheckpoints", await _list_checkpoints_payload(request))
908
+ async def list_session_checkpoints_action(
909
+ request: ListSessionCheckpointsActionRequest,
910
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
911
+ ):
912
+ return _action_response(
913
+ "ListSessionCheckpoints",
914
+ await _list_checkpoints_payload(request, invocation_identity),
915
+ )
766
916
 
767
917
 
768
918
  @tools_router.post("/agentengine/api/v1/ListToolReceipts")
769
- async def list_tool_receipts_action(request: ListToolReceiptsActionRequest):
919
+ async def list_tool_receipts_action(
920
+ request: ListToolReceiptsActionRequest,
921
+ invocation_identity: PlatformIdentityContext = Depends(resolve_trusted_invocation_identity),
922
+ ):
770
923
  service = deps.resolve_session_service()
771
- await _require_action_session(
924
+ await _require_identity_action_session(
772
925
  service,
773
926
  session_id=request.SessionId,
774
927
  agent_id=request.AgentId,
775
928
  user_id=request.UserId,
929
+ invocation_identity=invocation_identity,
930
+ history_only=True,
776
931
  )
777
932
 
778
933
  run_id_filter = str(request.RunId or "").strip()
779
934
  checkpoint_id_filter = str(request.CheckpointId or "").strip()
780
- total = 0
781
- async for page in _iter_session_event_pages(service, request.SessionId):
782
- for event in page:
783
- receipt = _tool_receipt_event_to_action_payload(event)
784
- if receipt is None:
785
- continue
786
- if run_id_filter and receipt["RunId"] != run_id_filter:
787
- continue
788
- if checkpoint_id_filter and receipt["CheckpointId"] != checkpoint_id_filter:
789
- continue
790
- total += 1
791
-
792
935
  offset = int(request.Offset)
793
936
  limit = int(request.Limit)
794
- window_end = max(total - offset, 0)
795
- window_start = max(window_end - limit, 0)
796
- receipts: list[dict[str, Any]] = []
797
- filtered_index = 0
798
- async for page in _iter_session_event_pages(service, request.SessionId):
799
- for event in page:
800
- receipt = _tool_receipt_event_to_action_payload(event)
801
- if receipt is None:
802
- continue
803
- if run_id_filter and receipt["RunId"] != run_id_filter:
804
- continue
805
- if checkpoint_id_filter and receipt["CheckpointId"] != checkpoint_id_filter:
806
- continue
807
- if window_start <= filtered_index < window_end:
808
- receipts.append(receipt)
809
- filtered_index += 1
810
- if filtered_index >= window_end:
811
- break
812
- if filtered_index >= window_end:
813
- break
937
+ filtered_query = SessionEventQuery(
938
+ session_ids=[request.SessionId], receipt_only=True,
939
+ run_id=run_id_filter or None,
940
+ checkpoint_id=checkpoint_id_filter or None,
941
+ )
942
+ total = await service.count_event_query(filtered_query)
943
+ events = await service.query_events(SessionEventQuery(
944
+ **{**filtered_query.__dict__, "offset": offset, "limit": limit}
945
+ ))
946
+ receipts = [receipt for event in events
947
+ if (receipt := _tool_receipt_event_to_action_payload(event)) is not None]
948
+ receipts.reverse()
814
949
 
815
950
  return _action_response(
816
951
  "ListToolReceipts",