agentengine-sdk-python 0.8.5__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 (851) hide show
  1. {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/METADATA +12 -8
  2. {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/RECORD +823 -388
  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/a2a/__init__.py +157 -167
  12. ksadk/a2a/_invocation_state.py +86 -0
  13. ksadk/a2a/_space_client_events.py +33 -22
  14. ksadk/a2a/adk.py +194 -0
  15. ksadk/a2a/adk_invocation_context.py +242 -0
  16. ksadk/a2a/adk_runtime.py +126 -0
  17. ksadk/a2a/adk_tools.py +319 -0
  18. ksadk/a2a/bootstrap.py +149 -23
  19. ksadk/a2a/build_validation.py +147 -0
  20. ksadk/a2a/card.py +23 -15
  21. ksadk/a2a/codex.py +160 -0
  22. ksadk/a2a/codex_checkpoint.py +111 -0
  23. ksadk/a2a/codex_recovery.py +96 -0
  24. ksadk/a2a/codex_recovery_events.py +123 -0
  25. ksadk/a2a/codex_runtime.py +198 -0
  26. ksadk/a2a/codex_session_checkpoint.py +162 -0
  27. ksadk/a2a/composition.py +88 -0
  28. ksadk/a2a/context_store.py +118 -19
  29. ksadk/a2a/control_plane.py +108 -106
  30. ksadk/a2a/event_adapter.py +92 -193
  31. ksadk/a2a/executor.py +257 -85
  32. ksadk/a2a/exposure.py +106 -0
  33. ksadk/a2a/external_transport.py +3 -4
  34. ksadk/a2a/identity.py +106 -12
  35. ksadk/a2a/ids.py +14 -3
  36. ksadk/a2a/inbound_kernel.py +133 -0
  37. ksadk/a2a/interaction_wire.py +76 -0
  38. ksadk/a2a/invocation_checkpoint.py +274 -0
  39. ksadk/a2a/invocation_policy.py +87 -0
  40. ksadk/a2a/invocation_publication.py +210 -0
  41. ksadk/a2a/invocation_service.py +972 -0
  42. ksadk/a2a/invocation_types.py +459 -0
  43. ksadk/a2a/kernel_task_adapter.py +259 -0
  44. ksadk/a2a/langgraph.py +20 -7
  45. ksadk/a2a/langgraph_invocation_context.py +136 -0
  46. ksadk/a2a/langgraph_managed.py +150 -0
  47. ksadk/a2a/langgraph_recovery.py +32 -0
  48. ksadk/a2a/langgraph_runtime.py +89 -0
  49. ksadk/a2a/langgraph_tool_runtime.py +132 -0
  50. ksadk/a2a/langgraph_tools.py +63 -0
  51. ksadk/a2a/message_digest.py +40 -0
  52. ksadk/a2a/platform.py +389 -0
  53. ksadk/a2a/policy_refs.py +13 -0
  54. ksadk/a2a/presentation.py +402 -0
  55. ksadk/a2a/product_kernel_facts.py +177 -0
  56. ksadk/a2a/product_key.py +99 -0
  57. ksadk/a2a/protocol_errors.py +116 -0
  58. ksadk/a2a/result_text.py +49 -0
  59. ksadk/a2a/resume_store.py +93 -3
  60. ksadk/a2a/routes.py +6 -1
  61. ksadk/a2a/runtime_approval.py +198 -0
  62. ksadk/a2a/runtime_input.py +151 -0
  63. ksadk/a2a/server.py +16 -7
  64. ksadk/a2a/space_client.py +101 -16
  65. ksadk/a2a/task_adapter.py +19 -5
  66. ksadk/a2a/task_event_dispatcher.py +39 -2
  67. ksadk/a2a/task_event_outbox.py +215 -0
  68. ksadk/a2a/task_event_outbox_owned.py +130 -0
  69. ksadk/a2a/task_store.py +37 -0
  70. ksadk/a2a/tool_activity.py +176 -0
  71. ksadk/a2a/workload_tokens.py +134 -0
  72. ksadk/api/client.py +32 -79
  73. ksadk/api/sse_stream.py +96 -0
  74. ksadk/builders/code_builder.py +83 -106
  75. ksadk/builders/container_builder.py +11 -29
  76. ksadk/builders/framework_requirements.py +2 -0
  77. ksadk/builders/managed_runtime_builder.py +12 -0
  78. ksadk/builders/source_provenance.py +87 -0
  79. ksadk/cli/cmd_a2a.py +43 -0
  80. ksadk/cli/cmd_build.py +9 -0
  81. ksadk/cli/cmd_deploy.py +27 -2
  82. ksadk/cli/cmd_invoke.py +45 -92
  83. ksadk/cli/cmd_studio.py +5 -1
  84. ksadk/cli/cmd_web.py +2 -0
  85. ksadk/cli/hosted_invoke.py +206 -0
  86. ksadk/cli/invoke_content.py +60 -0
  87. ksadk/cli/runtime_bootstrap.py +27 -5
  88. ksadk/codex/_expert_request_reader.py +48 -0
  89. ksadk/codex/a2a_tools.py +140 -0
  90. ksadk/codex/async_approval.py +169 -0
  91. ksadk/codex/async_client.py +938 -0
  92. ksadk/codex/async_proxy.py +216 -0
  93. ksadk/codex/base_runtime.py +25 -0
  94. ksadk/codex/client.py +3 -1048
  95. ksadk/codex/client_payloads.py +85 -0
  96. ksadk/codex/rollout_checkpoint.py +264 -0
  97. ksadk/codex/runtime.py +290 -54
  98. ksadk/common/auth.py +2 -2
  99. ksadk/common/cloud_headers.py +36 -0
  100. ksadk/common/diagnostics.py +34 -0
  101. ksadk/common/kop_client.py +2 -1
  102. ksadk/configs/env_registry.py +106 -127
  103. ksadk/configs/env_registry_a2a.py +173 -0
  104. ksadk/configs/env_registry_studio.py +53 -5
  105. ksadk/configs/global_config.py +1 -0
  106. ksadk/configs/settings.py +6 -0
  107. ksadk/context_engine/assembler.py +9 -0
  108. ksadk/context_engine/contributors.py +80 -17
  109. ksadk/context_engine/instruction_authority.py +18 -0
  110. ksadk/conversations/attachments.py +53 -15
  111. ksadk/conversations/contracts.py +28 -9
  112. ksadk/conversations/message_projection.py +30 -125
  113. ksadk/conversations/message_projection_blocks.py +137 -0
  114. ksadk/conversations/model_context.py +11 -3
  115. ksadk/conversations/projector.py +63 -0
  116. ksadk/conversations/runtime_compaction.py +7 -2
  117. ksadk/conversations/runtime_input.py +16 -4
  118. ksadk/conversations/runtime_payloads.py +4 -0
  119. ksadk/conversations/runtime_persistence.py +192 -24
  120. ksadk/conversations/runtime_preparation.py +85 -6
  121. ksadk/conversations/runtime_projection.py +217 -0
  122. ksadk/conversations/runtime_resume.py +141 -70
  123. ksadk/conversations/tool_receipt_resume.py +387 -0
  124. ksadk/conversations/tool_receipts.py +32 -0
  125. ksadk/deployment/env_forward.py +5 -0
  126. ksadk/deployment/manager.py +15 -6
  127. ksadk/deployment/providers/serverless.py +76 -136
  128. ksadk/deployment/providers/serverless_payloads.py +122 -0
  129. ksadk/evaluation/agent_eval_client.py +2 -1
  130. ksadk/evaluation/contracts.py +78 -3
  131. ksadk/evaluation/evaluators.py +166 -1
  132. ksadk/evaluation/evidence.py +271 -4
  133. ksadk/evaluation/local_adapter.py +76 -12
  134. ksadk/evaluation/studio_build_adapter.py +73 -9
  135. ksadk/events/adapters/_a2a_checkpoint.py +151 -0
  136. ksadk/events/adapters/_a2a_snapshot.py +18 -14
  137. ksadk/events/adapters/_a2a_support.py +15 -3
  138. ksadk/events/adapters/_a2a_tool_activity.py +123 -0
  139. ksadk/events/adapters/_codex_errors.py +49 -0
  140. ksadk/events/adapters/_langgraph_support.py +12 -1
  141. ksadk/events/adapters/a2a.py +54 -26
  142. ksadk/events/adapters/adk.py +188 -30
  143. ksadk/events/adapters/codex.py +33 -7
  144. ksadk/events/adapters/langgraph.py +16 -6
  145. ksadk/events/canonical.py +5 -0
  146. ksadk/events/canonical_store.py +200 -4
  147. ksadk/events/reducer.py +82 -0
  148. ksadk/events/run_authority.py +176 -0
  149. ksadk/harness/__init__.py +4 -0
  150. ksadk/harness/artifact_adapters/__init__.py +1 -0
  151. ksadk/harness/artifact_adapters/native_page_budget.py +172 -0
  152. ksadk/harness/artifact_adapters/native_search.py +249 -0
  153. ksadk/harness/artifact_adapters/native_search_budget.py +134 -0
  154. ksadk/harness/artifact_adapters/native_store.py +115 -0
  155. ksadk/harness/artifact_adapters/native_tool.py +222 -0
  156. ksadk/harness/artifact_store.py +26 -9
  157. ksadk/harness/browser_adapters/__init__.py +6 -0
  158. ksadk/harness/browser_adapters/native_browser_tool.py +92 -0
  159. ksadk/harness/browser_adapters/native_dom_snapshot.py +187 -0
  160. ksadk/harness/browser_adapters/native_playwright.py +953 -0
  161. ksadk/harness/browser_adapters/native_vision.py +295 -0
  162. ksadk/harness/capability_adapters/__init__.py +1 -0
  163. ksadk/harness/capability_adapters/native_dsh.py +289 -0
  164. ksadk/harness/capability_runtime.py +104 -9
  165. ksadk/harness/compaction_record.py +31 -0
  166. ksadk/harness/compiler.py +3 -3
  167. ksadk/harness/config.py +28 -5
  168. ksadk/harness/conformance/contract.py +9 -11
  169. ksadk/harness/context_engine.py +18 -33
  170. ksadk/harness/context_sections.py +397 -0
  171. ksadk/harness/diagnostic_adapters/__init__.py +1 -0
  172. ksadk/harness/diagnostic_adapters/contracts.py +70 -0
  173. ksadk/harness/diagnostic_adapters/lsp_rpc.py +210 -0
  174. ksadk/harness/diagnostic_adapters/native_lsp.py +286 -0
  175. ksadk/harness/engine/completion_guard.py +16 -1
  176. ksadk/harness/engine/context_pipeline.py +864 -92
  177. ksadk/harness/engine/graph_builder.py +123 -630
  178. ksadk/harness/engine/hooked_reasoner.py +380 -0
  179. ksadk/harness/engine/langgraph.py +126 -8
  180. ksadk/harness/engine/mcp_disclosure.py +65 -114
  181. ksadk/harness/engine/phases/__init__.py +6 -0
  182. ksadk/harness/engine/phases/context.py +48 -0
  183. ksadk/harness/engine/phases/interaction.py +31 -0
  184. ksadk/harness/engine/phases/reason.py +552 -0
  185. ksadk/harness/engine/phases/tools.py +638 -0
  186. ksadk/harness/engine/policy_runtime.py +21 -10
  187. ksadk/harness/engine/postgres_checkpointer.py +325 -2
  188. ksadk/harness/engine/run_control_bridge.py +21 -1
  189. ksadk/harness/engine/run_types.py +10 -0
  190. ksadk/harness/engine/skill_disclosure.py +98 -12
  191. ksadk/harness/engine/steering.py +177 -0
  192. ksadk/harness/engine/subagents.py +18 -1
  193. ksadk/harness/engine/tool_dispatch.py +112 -7
  194. ksadk/harness/events.py +39 -2
  195. ksadk/harness/execution_policy.py +10 -0
  196. ksadk/harness/hooks.py +259 -0
  197. ksadk/harness/loop/reason.py +281 -36
  198. ksadk/harness/loop/tools.py +157 -12
  199. ksadk/harness/managed_runtime.py +254 -94
  200. ksadk/harness/mcp_disclosure_contract.py +85 -0
  201. ksadk/harness/mcp_result_policy.py +44 -0
  202. ksadk/harness/mcp_runtime.py +33 -0
  203. ksadk/harness/micro_compact.py +69 -0
  204. ksadk/harness/model_adapters/__init__.py +1 -0
  205. ksadk/harness/model_adapters/native_mcp_media.py +100 -0
  206. ksadk/harness/model_adapters/native_mcp_result.py +36 -0
  207. ksadk/harness/model_adapters/native_openai.py +703 -0
  208. ksadk/harness/model_capability.py +223 -8
  209. ksadk/harness/model_provider.py +214 -4
  210. ksadk/harness/multimodal.py +57 -0
  211. ksadk/harness/native/__init__.py +1 -0
  212. ksadk/harness/native/activation_contract.py +25 -0
  213. ksadk/harness/native/activation_recovery.py +29 -0
  214. ksadk/harness/native/adapters.py +291 -0
  215. ksadk/harness/native/artifact_contract.py +14 -0
  216. ksadk/harness/native/artifact_partial_read_capacity.py +171 -0
  217. ksadk/harness/native/artifact_read_capacity.py +182 -0
  218. ksadk/harness/native/artifact_read_contract.py +27 -0
  219. ksadk/harness/native/artifact_runtime.py +408 -0
  220. ksadk/harness/native/artifact_search_capacity.py +206 -0
  221. ksadk/harness/native/artifact_search_contract.py +40 -0
  222. ksadk/harness/native/artifact_single_read_capacity.py +170 -0
  223. ksadk/harness/native/browser_contract.py +229 -0
  224. ksadk/harness/native/browser_recovery.py +183 -0
  225. ksadk/harness/native/capabilities.py +204 -0
  226. ksadk/harness/native/child_approval.py +60 -0
  227. ksadk/harness/native/child_budget.py +136 -0
  228. ksadk/harness/native/child_cancellation.py +80 -0
  229. ksadk/harness/native/child_input.py +98 -0
  230. ksadk/harness/native/child_input_runtime.py +59 -0
  231. ksadk/harness/native/child_interruption.py +81 -0
  232. ksadk/harness/native/child_lifecycle.py +246 -0
  233. ksadk/harness/native/child_lifecycle_contract.py +91 -0
  234. ksadk/harness/native/child_notifications.py +75 -0
  235. ksadk/harness/native/child_promotion.py +66 -0
  236. ksadk/harness/native/command_runtime.py +99 -0
  237. ksadk/harness/native/completion.py +302 -0
  238. ksadk/harness/native/completion_text.py +116 -0
  239. ksadk/harness/native/context.py +358 -0
  240. ksadk/harness/native/context_artifact_page.py +75 -0
  241. ksadk/harness/native/context_compaction_projection.py +131 -0
  242. ksadk/harness/native/context_contributions.py +320 -0
  243. ksadk/harness/native/context_contributor_contract.py +133 -0
  244. ksadk/harness/native/context_driver.py +820 -0
  245. ksadk/harness/native/context_fresh_tools.py +49 -0
  246. ksadk/harness/native/context_history.py +272 -0
  247. ksadk/harness/native/context_microcompact.py +61 -0
  248. ksadk/harness/native/context_partial_summary.py +58 -0
  249. ksadk/harness/native/context_partition.py +492 -0
  250. ksadk/harness/native/context_pruning.py +275 -0
  251. ksadk/harness/native/context_reduction.py +60 -0
  252. ksadk/harness/native/context_replay.py +148 -0
  253. ksadk/harness/native/context_request_projection.py +526 -0
  254. ksadk/harness/native/context_runtime.py +976 -0
  255. ksadk/harness/native/context_runtime_contracts.py +409 -0
  256. ksadk/harness/native/context_search.py +112 -0
  257. ksadk/harness/native/context_source_fragments.py +188 -0
  258. ksadk/harness/native/context_source_progress.py +119 -0
  259. ksadk/harness/native/context_summary_planning.py +788 -0
  260. ksadk/harness/native/context_summary_recovery.py +105 -0
  261. ksadk/harness/native/delivery_review.py +331 -0
  262. ksadk/harness/native/delivery_review_contract.py +54 -0
  263. ksadk/harness/native/effect_admission.py +82 -0
  264. ksadk/harness/native/effect_control.py +318 -0
  265. ksadk/harness/native/effect_receipts.py +729 -0
  266. ksadk/harness/native/effect_runtime.py +303 -0
  267. ksadk/harness/native/effective_configuration.py +28 -0
  268. ksadk/harness/native/engine.py +945 -0
  269. ksadk/harness/native/final_output.py +34 -0
  270. ksadk/harness/native/final_submission.py +58 -0
  271. ksadk/harness/native/finalization_workspace.py +96 -0
  272. ksadk/harness/native/fork.py +151 -0
  273. ksadk/harness/native/guidance.py +91 -0
  274. ksadk/harness/native/history.py +381 -0
  275. ksadk/harness/native/hook_executor.py +205 -0
  276. ksadk/harness/native/hook_runtime_contract.py +282 -0
  277. ksadk/harness/native/interaction_observation.py +117 -0
  278. ksadk/harness/native/lease.py +103 -0
  279. ksadk/harness/native/machine.py +974 -0
  280. ksadk/harness/native/mcp_result_governance.py +156 -0
  281. ksadk/harness/native/model.py +570 -0
  282. ksadk/harness/native/model_feedback.py +63 -0
  283. ksadk/harness/native/model_input.py +30 -0
  284. ksadk/harness/native/model_recovery_contract.py +35 -0
  285. ksadk/harness/native/model_replay.py +128 -0
  286. ksadk/harness/native/model_request.py +133 -0
  287. ksadk/harness/native/model_runtime.py +196 -0
  288. ksadk/harness/native/model_takeover.py +419 -0
  289. ksadk/harness/native/model_tool_batch.py +40 -0
  290. ksadk/harness/native/observed_progress.py +46 -0
  291. ksadk/harness/native/operator_guidance.py +201 -0
  292. ksadk/harness/native/output_contract.py +80 -0
  293. ksadk/harness/native/output_recovery.py +24 -0
  294. ksadk/harness/native/ports.py +749 -0
  295. ksadk/harness/native/precompact_hook_runtime.py +171 -0
  296. ksadk/harness/native/replay_context.py +149 -0
  297. ksadk/harness/native/request_media.py +112 -0
  298. ksadk/harness/native/restore_contract.py +16 -0
  299. ksadk/harness/native/run_clock.py +120 -0
  300. ksadk/harness/native/state.py +436 -0
  301. ksadk/harness/native/steering.py +170 -0
  302. ksadk/harness/native/stop_hook_runtime.py +151 -0
  303. ksadk/harness/native/studio_admission.py +29 -0
  304. ksadk/harness/native/subagents.py +86 -0
  305. ksadk/harness/native/task_policy.py +99 -0
  306. ksadk/harness/native/task_progress.py +86 -0
  307. ksadk/harness/native/terminal_verification.py +43 -0
  308. ksadk/harness/native/tool_argument_feedback.py +178 -0
  309. ksadk/harness/native/tool_budget.py +253 -0
  310. ksadk/harness/native/tool_error_streak.py +89 -0
  311. ksadk/harness/native/tool_hook_runtime.py +343 -0
  312. ksadk/harness/native/tool_input_validation.py +58 -0
  313. ksadk/harness/native/tool_interruption.py +96 -0
  314. ksadk/harness/native/tool_observation.py +259 -0
  315. ksadk/harness/native/tool_progress.py +223 -0
  316. ksadk/harness/native/tool_recovery.py +25 -0
  317. ksadk/harness/native/tool_scheduling.py +33 -0
  318. ksadk/harness/native/tool_schema.py +126 -0
  319. ksadk/harness/native/transitions.py +151 -0
  320. ksadk/harness/native/turn_control.py +98 -0
  321. ksadk/harness/native/user_document.py +98 -0
  322. ksadk/harness/native/user_document_capture.py +49 -0
  323. ksadk/harness/native/user_input.py +87 -0
  324. ksadk/harness/native/verification.py +432 -0
  325. ksadk/harness/native/verification_binding.py +40 -0
  326. ksadk/harness/native/verification_runtime.py +233 -0
  327. ksadk/harness/native/verification_workspace.py +67 -0
  328. ksadk/harness/native_driver_failure.py +123 -0
  329. ksadk/harness/native_facade.py +977 -0
  330. ksadk/harness/native_factory.py +244 -0
  331. ksadk/harness/native_projection.py +503 -0
  332. ksadk/harness/native_runtime.py +621 -0
  333. ksadk/harness/native_shadow.py +250 -0
  334. ksadk/harness/native_shadow_inputs.py +146 -0
  335. ksadk/harness/progress_adapters/__init__.py +5 -0
  336. ksadk/harness/progress_adapters/native_todo.py +75 -0
  337. ksadk/harness/prompt_cache.py +65 -3
  338. ksadk/harness/public_activity.py +59 -0
  339. ksadk/harness/public_output.py +30 -0
  340. ksadk/harness/public_summary.py +36 -0
  341. ksadk/harness/reasoner.py +331 -22
  342. ksadk/harness/rpc.py +200 -0
  343. ksadk/harness/run_control.py +107 -2
  344. ksadk/harness/runtime.py +11 -2
  345. ksadk/harness/runtime_capabilities.py +71 -1
  346. ksadk/harness/sandbox_backend.py +203 -0
  347. ksadk/harness/sdk.py +153 -0
  348. ksadk/harness/session_store.py +370 -24
  349. ksadk/harness/skill_adapters/__init__.py +1 -0
  350. ksadk/harness/skill_adapters/native_bundle.py +148 -0
  351. ksadk/harness/skill_adapters/native_disclosure.py +306 -0
  352. ksadk/harness/skill_intent.py +47 -0
  353. ksadk/harness/skill_runtime.py +74 -16
  354. ksadk/harness/spec.py +20 -10
  355. ksadk/harness/state.py +2 -0
  356. ksadk/harness/stores/__init__.py +14 -0
  357. ksadk/harness/stores/native_command_settlement.py +65 -0
  358. ksadk/harness/stores/native_contract.py +311 -0
  359. ksadk/harness/stores/native_memory.py +326 -0
  360. ksadk/harness/stores/native_memory_archive.py +70 -0
  361. ksadk/harness/stores/native_migration_cli.py +91 -0
  362. ksadk/harness/stores/native_outbox.py +56 -0
  363. ksadk/harness/stores/native_sqlite.py +782 -0
  364. ksadk/harness/stores/native_sqlite_audit.py +29 -0
  365. ksadk/harness/stores/native_sqlite_migration.py +252 -0
  366. ksadk/harness/subagent.py +12 -2
  367. ksadk/harness/subagent_adapters/checkpoint_recovery.py +120 -0
  368. ksadk/harness/subagent_adapters/native_background_child.py +803 -0
  369. ksadk/harness/subagent_adapters/native_child.py +819 -0
  370. ksadk/harness/subagent_adapters/native_child_approval.py +128 -0
  371. ksadk/harness/subagent_adapters/native_child_continuation.py +51 -0
  372. ksadk/harness/subagent_adapters/native_child_result.py +392 -0
  373. ksadk/harness/subagent_adapters/prepared_recovery.py +120 -0
  374. ksadk/harness/tool_display.py +75 -0
  375. ksadk/harness/tool_display_contract.py +134 -0
  376. ksadk/harness/tool_output.py +141 -0
  377. ksadk/harness/tool_policy.py +3 -0
  378. ksadk/harness/tool_result_policy.py +216 -0
  379. ksadk/harness/tools.py +52 -0
  380. ksadk/harness/workspace_adapters/__init__.py +6 -0
  381. ksadk/harness/workspace_adapters/native_directory.py +180 -0
  382. ksadk/harness/workspace_adapters/native_git.py +208 -0
  383. ksadk/harness/workspace_adapters/native_isolation.py +350 -0
  384. ksadk/interaction/providers/langgraph.py +8 -1
  385. ksadk/kernel/bootstrap.py +144 -160
  386. ksadk/kernel/contract_fingerprints.py +45 -1
  387. ksadk/kernel/contracts.py +25 -0
  388. ksadk/kernel/control.py +153 -33
  389. ksadk/kernel/execution_grants.py +209 -2
  390. ksadk/kernel/execution_grants_memory.py +127 -8
  391. ksadk/kernel/execution_grants_postgres.py +188 -10
  392. ksadk/kernel/execution_grants_sqlite.py +235 -9
  393. ksadk/kernel/execution_host_ingress.py +1071 -0
  394. ksadk/kernel/history_projection.py +120 -0
  395. ksadk/kernel/ingress.py +117 -204
  396. ksadk/kernel/ingress_bootstrap.py +268 -0
  397. ksadk/kernel/legacy_history.py +179 -0
  398. ksadk/kernel/memory_store.py +38 -48
  399. ksadk/kernel/memory_store_projection.py +63 -0
  400. ksadk/kernel/postgres_event_log.py +181 -0
  401. ksadk/kernel/postgres_store.py +167 -198
  402. ksadk/kernel/readiness.py +125 -0
  403. ksadk/kernel/recovery.py +89 -3
  404. ksadk/kernel/recovery_projection.py +124 -0
  405. ksadk/kernel/runtime_checkpoint.py +34 -0
  406. ksadk/kernel/sql/001_agent_kernel.sql +5 -0
  407. ksadk/kernel/sqlite_schema.py +100 -0
  408. ksadk/kernel/sqlite_store.py +147 -216
  409. ksadk/kernel/store.py +47 -15
  410. ksadk/kernel/teams_artifact_tools.py +392 -0
  411. ksadk/kernel/teams_effects.py +851 -0
  412. ksadk/kernel/teams_execution_context.py +408 -0
  413. ksadk/kernel/teams_host_http.py +237 -0
  414. ksadk/kernel/teams_material_transport.py +245 -0
  415. ksadk/kernel/teams_materials.py +318 -0
  416. ksadk/kernel/teams_runtime_bootstrap.py +604 -0
  417. ksadk/kernel/teams_tool_runtime.py +273 -0
  418. ksadk/kernel/teams_workspace.py +259 -0
  419. ksadk/kernel/worker.py +323 -332
  420. ksadk/kernel/worker_controls.py +454 -0
  421. ksadk/kernel/worker_identity.py +27 -0
  422. ksadk/kernel/worker_interactions.py +197 -0
  423. ksadk/knowledge_base/client.py +15 -1
  424. ksadk/managed_runtime.py +29 -2
  425. ksadk/memory/adk/backends/http_ltm_backend.py +2 -1
  426. ksadk/memory/adk/backends/sdk_ltm_backend.py +15 -1
  427. ksadk/memory/adk/bounded_database_session_service.py +232 -0
  428. ksadk/memory/adk/resilient_session_service.py +115 -15
  429. ksadk/memory/adk/short_term_memory.py +8 -9
  430. ksadk/memory/extraction.py +120 -7
  431. ksadk/memory/providers/local_candidates.py +183 -0
  432. ksadk/memory/providers/local_sqlite.py +252 -78
  433. ksadk/memory/resolved_policy.py +12 -7
  434. ksadk/model_gateway/__init__.py +29 -0
  435. ksadk/model_gateway/client.py +253 -0
  436. ksadk/model_gateway/events.py +113 -0
  437. ksadk/model_gateway/matrix.py +297 -0
  438. ksadk/model_proxy/compat.py +670 -0
  439. ksadk/model_proxy/server.py +10 -7
  440. ksadk/model_proxy/transform.py +37 -9
  441. ksadk/plugins/bridges/dsh.py +18 -20
  442. ksadk/plugins/bridges/dsh_profile_manifest.py +36 -0
  443. ksadk/plugins/builtin_resources.py +199 -0
  444. ksadk/plugins/builtins.py +380 -186
  445. ksadk/plugins/context_contributor.py +15 -4
  446. ksadk/plugins/dsh_dependency_policy.py +41 -0
  447. ksadk/plugins/dsh_toolchain.py +24 -35
  448. ksadk/plugins/execution_host.py +8 -0
  449. ksadk/plugins/host.py +73 -5
  450. ksadk/plugins/kernel_adapter.py +44 -1
  451. ksadk/plugins/memory_provider.py +180 -0
  452. ksadk/plugins/providers/_process_group.py +50 -0
  453. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +24 -2
  454. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +1 -1
  455. ksadk/plugins/providers/bundles/dsh-memory/package.json +1 -1
  456. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +1 -1
  457. ksadk/plugins/providers/bundles/dsh-teams-tools/package.json +1 -1
  458. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +1 -1
  459. ksadk/plugins/providers/codex.py +42 -38
  460. ksadk/plugins/providers/codex_native.py +20 -0
  461. ksadk/plugins/providers/codex_skills.py +46 -0
  462. ksadk/plugins/providers/dsh_capabilities.py +16 -171
  463. ksadk/plugins/providers/dsh_connector_lease.py +225 -0
  464. ksadk/plugins/providers/dsh_mcp.py +163 -1
  465. ksadk/plugins/providers/harness.py +247 -34
  466. ksadk/plugins/providers/harness_context.py +61 -0
  467. ksadk/plugins/providers/harness_contributions.py +241 -0
  468. ksadk/plugins/providers/harness_delegation.py +91 -14
  469. ksadk/plugins/providers/harness_hooks.py +121 -0
  470. ksadk/plugins/providers/harness_managed.py +269 -175
  471. ksadk/plugins/providers/harness_tools.py +165 -36
  472. ksadk/plugins/providers/legacy_catalog.py +1 -1
  473. ksadk/plugins/providers/mcp_projection.py +100 -3
  474. ksadk/plugins/providers/platform_resources.py +16 -6
  475. ksadk/plugins/teams/application.py +3 -143
  476. ksadk/plugins/teams/build_artifacts.py +460 -0
  477. ksadk/plugins/teams/cloud_contract_fingerprints.py +22 -0
  478. ksadk/plugins/teams/cloud_contracts.py +928 -0
  479. ksadk/plugins/teams/cloud_permits.py +250 -0
  480. ksadk/plugins/teams/domain.py +201 -148
  481. ksadk/plugins/teams/effect_contracts.py +255 -0
  482. ksadk/plugins/teams/execution_projection.py +255 -0
  483. ksadk/plugins/teams/leader_decisions.py +106 -0
  484. ksadk/plugins/teams/postgres_store.py +299 -85
  485. ksadk/plugins/teams/release_contracts.py +60 -0
  486. ksadk/plugins/teams/runtime.py +116 -40
  487. ksadk/plugins/teams/store.py +214 -6
  488. ksadk/plugins/teams/task_decisions.py +21 -8
  489. ksadk/plugins/teams/tool_service.py +152 -0
  490. ksadk/plugins/teams/transport.py +8 -3
  491. ksadk/resource_runtime/skill_runtime.py +3 -0
  492. ksadk/resource_runtime/socket_server.py +11 -0
  493. ksadk/resource_runtime/worker.py +28 -4
  494. ksadk/runners/_adk_a2a_stream.py +122 -0
  495. ksadk/runners/_adk_canonical_stream.py +474 -0
  496. ksadk/runners/_langgraph_canonical_streams.py +527 -0
  497. ksadk/runners/_langgraph_runner_streams.py +6 -400
  498. ksadk/runners/_langgraph_tool_projection.py +86 -0
  499. ksadk/runners/_langgraph_tools_transformer.py +27 -0
  500. ksadk/runners/adk_runner.py +195 -290
  501. ksadk/runners/base_runner.py +6 -5
  502. ksadk/runners/langgraph_runner.py +82 -86
  503. ksadk/runners/utils/loader.py +28 -14
  504. ksadk/runtime/_runner_adapter/a2ui_surface.py +145 -0
  505. ksadk/runtime/_runner_adapter/gateway_approvals.py +93 -0
  506. ksadk/runtime/_runner_adapter/stream_mapping.py +83 -128
  507. ksadk/runtime/adapter.py +40 -3
  508. ksadk/runtime/conversation_execution.py +4 -2
  509. ksadk/runtime/executor.py +97 -7
  510. ksadk/runtime/factory.py +13 -6
  511. ksadk/runtime/framework_adapters.py +184 -10
  512. ksadk/runtime/hosted_finalizer.py +4 -6
  513. ksadk/runtime/launch.py +2 -0
  514. ksadk/runtime/runner_adapter.py +123 -13
  515. ksadk/runtime_context.py +2 -0
  516. ksadk/sandbox/backends/e2b.py +30 -4
  517. ksadk/sandbox/backends/local_process.py +10 -0
  518. ksadk/sandbox/e2b_connection.py +9 -1
  519. ksadk/sandbox/local_controls.py +32 -2
  520. ksadk/sandbox/local_launcher.py +34 -0
  521. ksadk/server/factory.py +178 -25
  522. ksadk/server/history_deadline.py +158 -0
  523. ksadk/server/history_page_cache.py +129 -0
  524. ksadk/server/routes/checkpoint_audit.py +88 -0
  525. ksadk/server/routes/checkpoint_listing.py +294 -0
  526. ksadk/server/routes/checkpoint_resolution.py +73 -20
  527. ksadk/server/routes/control.py +51 -3
  528. ksadk/server/routes/display_projection.py +154 -0
  529. ksadk/server/routes/kernel_ingress.py +17 -2
  530. ksadk/server/routes/misc.py +102 -12
  531. ksadk/server/routes/models.py +25 -1
  532. ksadk/server/routes/openai_compat.py +6 -0
  533. ksadk/server/routes/projection.py +159 -216
  534. ksadk/server/routes/run.py +6 -2
  535. ksadk/server/routes/sessions.py +301 -342
  536. ksadk/server/routes/streaming.py +68 -15
  537. ksadk/server/routes/tool_receipt_claim_routes.py +107 -0
  538. ksadk/server/routes/workspace.py +5 -2
  539. ksadk/server/static/assets/{ArtifactsPanel-C1YoaKhx.js → ArtifactsPanel-CILaW-fC.js} +1 -1
  540. ksadk/server/static/assets/{CodeBlock-DHuAWfr5.js → CodeBlock-BVrNVtJC.js} +1 -1
  541. ksadk/server/static/assets/{MathMessageMarkdown-cvdrBwYr.js → MathMessageMarkdown-Dp7c4wWD.js} +1 -1
  542. ksadk/server/static/assets/{MermaidBlock-DeBkbJvI.js → MermaidBlock-Dxop8Rd7.js} +6 -6
  543. ksadk/server/static/assets/{NativeTerminalPanel-oJj44_sV.js → NativeTerminalPanel-Cjjz8B30.js} +1 -1
  544. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-Dhfv25o2.js → abnfDiagram-VCTEODGH-ckWDmOzw.js} +1 -1
  545. ksadk/server/static/assets/{arc-C35w-pn1.js → arc-DqxJede-.js} +1 -1
  546. ksadk/server/static/assets/architecture-7GRP2DOG-pn_DuLy6.js +1 -0
  547. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-FoMY_u6D.js → architectureDiagram-5GKGNRK7-SEQA4bVi.js} +1 -1
  548. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-zD4Rt7oE.js → blockDiagram-NRAW4CY4-pM0B-6NJ.js} +1 -1
  549. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-BCtGGkhN.js → c4Diagram-UCG6FXSJ-m2tuCNVq.js} +1 -1
  550. ksadk/server/static/assets/channel-fySsnkft.js +1 -0
  551. ksadk/server/static/assets/chunk-2Q5K7J3B-BheGxKRQ.js +1 -0
  552. ksadk/server/static/assets/{chunk-5VM5RSS4-C2Ms13_k.js → chunk-5VM5RSS4-GJHDr9Ww.js} +1 -1
  553. ksadk/server/static/assets/{chunk-F27PBJKO-BoTj-qgx.js → chunk-F27PBJKO-CbAN45AV.js} +1 -1
  554. ksadk/server/static/assets/{chunk-G27WJ6UU-DOMyyjHH.js → chunk-G27WJ6UU-D5ngbbzF.js} +1 -1
  555. ksadk/server/static/assets/{chunk-JWPE2WC7-DbJJqDli.js → chunk-JWPE2WC7-Cc5IwuYC.js} +1 -1
  556. ksadk/server/static/assets/{chunk-LCL6LL3I-CLuRCt_W.js → chunk-LCL6LL3I-CprgDDdJ.js} +1 -1
  557. ksadk/server/static/assets/{chunk-POPQ4Y6H-D0Dz847e.js → chunk-POPQ4Y6H-CDZhSy82.js} +1 -1
  558. ksadk/server/static/assets/{chunk-RHFEMEQ7-BWSRzEcd.js → chunk-RHFEMEQ7-CZchUNro.js} +1 -1
  559. ksadk/server/static/assets/{chunk-SVP7TREG-CPoHqkCY.js → chunk-SVP7TREG-BVruqk6T.js} +1 -1
  560. ksadk/server/static/assets/{chunk-XXDRQBXY-Bx1jS-X-.js → chunk-XXDRQBXY-4ld9SxPN.js} +1 -1
  561. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DSfLtNYm.js +1 -0
  562. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DSfLtNYm.js +1 -0
  563. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-LzyWm4m0.js → cose-bilkent-JH36ORCC-Dmyyk_Vp.js} +1 -1
  564. ksadk/server/static/assets/cynefin-OW5HDTMX-PFWIGtvA.js +1 -0
  565. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-BlW_bHED.js → cynefinDiagram-5FMLGOSQ-BIyq3EJb.js} +1 -1
  566. ksadk/server/static/assets/{dagre-3AP2YEHR-Bu_S86_i.js → dagre-3AP2YEHR-eBw08Qdk.js} +1 -1
  567. ksadk/server/static/assets/{dagre-B7nCawed.js → dagre-DfvnEf45.js} +1 -1
  568. ksadk/server/static/assets/{diagram-S7CK7UJ4-W_Zow2Km.js → diagram-S7CK7UJ4-CUSrE3Mg.js} +1 -1
  569. ksadk/server/static/assets/{diagram-UQ7AKVKN-CLIKAHON.js → diagram-UQ7AKVKN-Dq5Zw2gy.js} +1 -1
  570. ksadk/server/static/assets/{diagram-VSXAHHWV-Dv6_QAlN.js → diagram-VSXAHHWV-DyUHfNwT.js} +1 -1
  571. ksadk/server/static/assets/{diagram-VX7I27RA-BWAWRDtZ.js → diagram-VX7I27RA-CREmM89O.js} +1 -1
  572. ksadk/server/static/assets/{diagram-Z3DM3KII-XA_rWMss.js → diagram-Z3DM3KII-Dw9zhHUK.js} +1 -1
  573. ksadk/server/static/assets/{dist-CGt_UGeO.js → dist-0uJ4tdx6.js} +1 -1
  574. ksadk/server/static/assets/{dist-C0J5_3qM.js → dist-AEv-vXf-.js} +1 -1
  575. ksadk/server/static/assets/{dist-CIpWk_5f.js → dist-B49GzZDb.js} +1 -1
  576. ksadk/server/static/assets/{dist-B3bA05-e.js → dist-B8Myiet9.js} +1 -1
  577. ksadk/server/static/assets/{dist-DWfdmz9s.js → dist-BBsYarrI.js} +1 -1
  578. ksadk/server/static/assets/{dist-BLpRy_Yx.js → dist-BQMrUwdI.js} +1 -1
  579. ksadk/server/static/assets/{dist-CIRMvUM4.js → dist-BX_-FENW.js} +1 -1
  580. ksadk/server/static/assets/{dist-BdNFAney.js → dist-CD4L6ymH.js} +1 -1
  581. ksadk/server/static/assets/{dist-n3n6t_FO.js → dist-CHpW1BHj.js} +1 -1
  582. ksadk/server/static/assets/{dist-DppE_r-D.js → dist-CVPau3tn.js} +1 -1
  583. ksadk/server/static/assets/{dist-qe8xjesy.js → dist-C_qdxcSH.js} +1 -1
  584. ksadk/server/static/assets/{dist-2vL2sAdF.js → dist-Co68Apq4.js} +1 -1
  585. ksadk/server/static/assets/{dist-1nXCdsej.js → dist-Cp2PaOMY.js} +1 -1
  586. ksadk/server/static/assets/{dist-DNKuMzWc.js → dist-CuR5Bgme.js} +1 -1
  587. ksadk/server/static/assets/{dist-t6MzE0jU.js → dist-DDSyLEOX.js} +1 -1
  588. ksadk/server/static/assets/{dist-CPyieXEf.js → dist-DUxO0R99.js} +1 -1
  589. ksadk/server/static/assets/{dist-DyG6Ya-z.js → dist-QzbGrED_.js} +1 -1
  590. ksadk/server/static/assets/{dist-0X_j2Rcc.js → dist-bupkyEBZ.js} +1 -1
  591. ksadk/server/static/assets/{dist-mqD5TZup.js → dist-cxTGfdqx.js} +1 -1
  592. ksadk/server/static/assets/{dist-M-SrdhhZ.js → dist-hL5p1til.js} +1 -1
  593. ksadk/server/static/assets/{dist-D-92S-Fd.js → dist-lOy23y43.js} +1 -1
  594. ksadk/server/static/assets/{dist-BO_UwatH.js → dist-pq-nD33R.js} +1 -1
  595. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-BfCzF1Xi.js → ebnfDiagram-PWID7BFC-BS5LdNoR.js} +1 -1
  596. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-Dpz9_0zn.js → erDiagram-SSCWMZ5O-Bv1QtiY-.js} +1 -1
  597. ksadk/server/static/assets/eventmodeling-NTZA5JFV-DsM4upQX.js +1 -0
  598. ksadk/server/static/assets/flowDiagram-A5DVABFB-D5NA16k9.js +1 -0
  599. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-DDaG1f4_.js → ganttDiagram-EL5Y4UJY-musi-e0G.js} +1 -1
  600. ksadk/server/static/assets/gitGraph-4MIJSDKK-DUCVz-ih.js +1 -0
  601. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-DcxzRwYC.js → gitGraphDiagram-WWUBYQGX-DH37EGkG.js} +1 -1
  602. ksadk/server/static/assets/index-CZdkAvsv.js +244 -0
  603. ksadk/server/static/assets/index-CvXdHgF3.css +2 -0
  604. ksadk/server/static/assets/info-A6RAGUB7-rw0ZNHZp.js +1 -0
  605. ksadk/server/static/assets/{infoDiagram-RXCK75RN-CYMdn6lQ.js → infoDiagram-RXCK75RN-C1kEtv2y.js} +1 -1
  606. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CLHFAD6c.js → ishikawaDiagram-5VMMS53U-BCNPyMka.js} +1 -1
  607. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-BHSKQGAl.js → journeyDiagram-EYS64GPL--cDbKnjP.js} +1 -1
  608. ksadk/server/static/assets/{kanban-definition-3QL26DDD-D5W3tjTT.js → kanban-definition-3QL26DDD-R1rAVw2f.js} +1 -1
  609. ksadk/server/static/assets/{katex-mtjOi4KM.js → katex-BT-X-V7U.js} +1 -1
  610. ksadk/server/static/assets/{linear-BETqsxE_.js → linear-DTR631iG.js} +1 -1
  611. ksadk/server/static/assets/{mermaid-parser.core-DPWrvs90.js → mermaid-parser.core-DfFzJhX8.js} +2 -2
  612. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-CJG2mfBP.js → mindmap-definition-FBJOCRG2-D4by_rmk.js} +1 -1
  613. ksadk/server/static/assets/packet-AYTQ26CC-Ca4Hvki9.js +1 -0
  614. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-GjAPNaqn.js → pegDiagram-XKGWAZYB-xWXPEh0c.js} +1 -1
  615. ksadk/server/static/assets/pie-WAS4IAKB-hwiz6fbw.js +1 -0
  616. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-ToIewrqr.js → pieDiagram-E7YTZNPT-BudBDlCI.js} +1 -1
  617. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-4d78KiEY.js → quadrantDiagram-AXDQQJYC-DXZ0PCJF.js} +1 -1
  618. ksadk/server/static/assets/radar-RG4KPBEZ-BR1oZXLM.js +1 -0
  619. ksadk/server/static/assets/railroad-74A4TZTK-DfgEISfX.js +1 -0
  620. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-CWOC3rdk.js +1 -0
  621. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CiRvHCLY.js +1 -0
  622. ksadk/server/static/assets/railroad-peg-WCYAUIDC-DSDDyJ2f.js +1 -0
  623. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-DKzx4xfv.js → railroadDiagram-O6MQD6OU-BdAYRYB8.js} +1 -1
  624. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-CJYljxQS.js → requirementDiagram-EFPCY7ZU-CBBmaL70.js} +1 -1
  625. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-DLU2fV1w.js → sankeyDiagram-P5KCCOFB-Doc3rdwp.js} +1 -1
  626. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-CVqysrA9.js → sequenceDiagram-WJ2MYXX4-0J8R8hWW.js} +1 -1
  627. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-BUxfmTHc.js → sizeCapture-X5ZJPWSS-CfFLlWsK.js} +1 -1
  628. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-CNFgYI9E.js → stateDiagram-HBIQ2CUA-jBwkjtTy.js} +1 -1
  629. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-Cw1fPb5w.js +1 -0
  630. ksadk/server/static/assets/{swimlanes-XN3QIQJK-B6qCMe8N.js → swimlanes-XN3QIQJK-B0WxTQf8.js} +1 -1
  631. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-Cc3JMBAF.js +8 -0
  632. ksadk/server/static/assets/{timeline-definition-24CTP7MA-CMD3x_U_.js → timeline-definition-24CTP7MA-BfCT_75A.js} +1 -1
  633. ksadk/server/static/assets/treeView-Q6P3EWNA-C05SJHxo.js +1 -0
  634. ksadk/server/static/assets/treemap-WGGIJYW6-BqNLAhc3.js +1 -0
  635. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-BqtUqvXM.js → vennDiagram-4TSXK5OY-9gX1VMDC.js} +1 -1
  636. ksadk/server/static/assets/wardley-WFR3VGLG-DokNktqB.js +1 -0
  637. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-B5KfDjI-.js → wardleyDiagram-VM6X3IG4-sEs_BP6O.js} +1 -1
  638. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-BaUlSZrn.js → xychartDiagram-S5SC5T6Z-Ll4jvUN9.js} +1 -1
  639. ksadk/server/static/index.html +2 -2
  640. ksadk/sessions/__init__.py +8 -1
  641. ksadk/sessions/_checkpoint_resume_audit.py +44 -0
  642. ksadk/sessions/_in_memory_query.py +112 -0
  643. ksadk/sessions/_local_service_sync.py +157 -156
  644. ksadk/sessions/_local_state_sync.py +152 -0
  645. ksadk/sessions/_local_tables.py +2 -0
  646. ksadk/sessions/_postgres_checkpoint_read.py +323 -0
  647. ksadk/sessions/_postgres_checkpoint_stats.py +330 -0
  648. ksadk/sessions/_postgres_history_read.py +678 -0
  649. ksadk/sessions/_postgres_schema.py +44 -2
  650. ksadk/sessions/_postgres_tables.py +2 -0
  651. ksadk/sessions/_postgres_tool_receipts.py +169 -0
  652. ksadk/sessions/_resilient_read.py +630 -0
  653. ksadk/sessions/_tool_receipt_sync.py +119 -0
  654. ksadk/sessions/agent_identity.py +16 -0
  655. ksadk/sessions/base.py +278 -0
  656. ksadk/sessions/db_budget.py +332 -0
  657. ksadk/sessions/errors.py +12 -0
  658. ksadk/sessions/history_budget.py +36 -0
  659. ksadk/sessions/history_identity.py +27 -0
  660. ksadk/sessions/in_memory.py +376 -113
  661. ksadk/sessions/local_service.py +345 -0
  662. ksadk/sessions/postgres_service.py +515 -549
  663. ksadk/sessions/resilience.py +21 -14
  664. ksadk/sessions/resilient.py +611 -504
  665. ksadk/skills/loader.py +44 -2
  666. ksadk/skills/runtime/backends/e2b.py +17 -14
  667. ksadk/skills/service_client.py +6 -1
  668. ksadk/studio/a2a_bindings.py +407 -0
  669. ksadk/studio/a2a_orchestration.py +178 -0
  670. ksadk/studio/active_run_output.py +92 -0
  671. ksadk/studio/activity_records.py +542 -0
  672. ksadk/studio/agent_configuration.py +173 -0
  673. ksadk/studio/api.py +219 -389
  674. ksadk/studio/api_a2a_routes.py +93 -0
  675. ksadk/studio/api_catalog_routes.py +13 -0
  676. ksadk/studio/api_cloud_chat_routes.py +382 -0
  677. ksadk/studio/api_contracts.py +23 -0
  678. ksadk/studio/attachment_store.py +14 -2
  679. ksadk/studio/build_resolution.py +117 -0
  680. ksadk/studio/build_singleflight.py +37 -0
  681. ksadk/studio/builder.py +20 -2
  682. ksadk/studio/capabilities.py +8 -3
  683. ksadk/studio/cloud.py +83 -377
  684. ksadk/studio/cloud_gateways.py +424 -0
  685. ksadk/studio/cloud_shared_web.py +7 -0
  686. ksadk/studio/codex_agent_service.py +17 -0
  687. ksadk/studio/codex_manifest.py +5 -1
  688. ksadk/studio/codex_provider_build.py +65 -0
  689. ksadk/studio/compiler.py +102 -6
  690. ksadk/studio/contract_base.py +19 -0
  691. ksadk/studio/contracts.py +231 -201
  692. ksadk/studio/dsh_application.py +58 -12
  693. ksadk/studio/dsh_capability_service.py +17 -171
  694. ksadk/studio/dsh_mcp_transport.py +191 -0
  695. ksadk/studio/event_store.py +17 -0
  696. ksadk/studio/execution_host.py +84 -11
  697. ksadk/studio/framework_run.py +18 -0
  698. ksadk/studio/interaction_submission.py +265 -0
  699. ksadk/studio/kernel_registry.py +12 -1
  700. ksadk/studio/lifecycle_status.py +43 -0
  701. ksadk/studio/model_buffered_wire.py +227 -0
  702. ksadk/studio/model_chat_tools.py +143 -0
  703. ksadk/studio/model_client.py +1241 -761
  704. ksadk/studio/model_content_stream.py +129 -0
  705. ksadk/studio/model_credentials.py +196 -0
  706. ksadk/studio/model_profile_service.py +65 -31
  707. ksadk/studio/model_request_projection.py +284 -0
  708. ksadk/studio/model_responses_content.py +296 -0
  709. ksadk/studio/model_usage.py +109 -0
  710. ksadk/studio/model_wire_failure.py +110 -0
  711. ksadk/studio/model_wire_identity.py +138 -0
  712. ksadk/studio/model_wire_snapshot.py +45 -0
  713. ksadk/studio/model_wire_tools.py +283 -0
  714. ksadk/studio/native_acceptance.py +68 -0
  715. ksadk/studio/native_approval.py +111 -0
  716. ksadk/studio/native_browser_port.py +861 -0
  717. ksadk/studio/native_child_mcp.py +87 -0
  718. ksadk/studio/native_child_publication.py +68 -0
  719. ksadk/studio/native_child_skills.py +72 -0
  720. ksadk/studio/native_child_workspace.py +176 -0
  721. ksadk/studio/native_command_policy.py +53 -0
  722. ksadk/studio/native_context_port.py +326 -0
  723. ksadk/studio/native_context_registration.py +54 -0
  724. ksadk/studio/native_document_input.py +88 -0
  725. ksadk/studio/native_final_shape.py +852 -0
  726. ksadk/studio/native_gateway_stream.py +69 -0
  727. ksadk/studio/native_hook_port.py +145 -0
  728. ksadk/studio/native_hook_registration.py +70 -0
  729. ksadk/studio/native_inventory_disclosure.py +223 -0
  730. ksadk/studio/native_kernel_admission.py +84 -0
  731. ksadk/studio/native_language_diagnostics.py +320 -0
  732. ksadk/studio/native_mcp_disclosure.py +198 -0
  733. ksadk/studio/native_mcp_tool_port.py +219 -0
  734. ksadk/studio/native_memory_acceptance.py +362 -0
  735. ksadk/studio/native_memory_context.py +266 -0
  736. ksadk/studio/native_memory_flush.py +174 -0
  737. ksadk/studio/native_memory_sources.py +80 -0
  738. ksadk/studio/native_memory_tool_port.py +360 -0
  739. ksadk/studio/native_memory_turn.py +183 -0
  740. ksadk/studio/native_model_port.py +765 -0
  741. ksadk/studio/native_model_recovery.py +126 -0
  742. ksadk/studio/native_options.py +75 -0
  743. ksadk/studio/native_output_fields.py +58 -0
  744. ksadk/studio/native_planning.py +156 -0
  745. ksadk/studio/native_product.py +988 -0
  746. ksadk/studio/native_read_budget.py +426 -0
  747. ksadk/studio/native_recovery.py +171 -0
  748. ksadk/studio/native_scope.py +35 -0
  749. ksadk/studio/native_session_context_port.py +141 -0
  750. ksadk/studio/native_session_engine.py +14 -0
  751. ksadk/studio/native_skill_source.py +74 -0
  752. ksadk/studio/native_subagent_port.py +700 -0
  753. ksadk/studio/native_terminal_recovery.py +95 -0
  754. ksadk/studio/native_test_action.py +610 -0
  755. ksadk/studio/native_tool_port.py +477 -0
  756. ksadk/studio/native_user_input.py +60 -0
  757. ksadk/studio/native_verification_presentation.py +65 -0
  758. ksadk/studio/native_workspace_diagnostics.py +183 -0
  759. ksadk/studio/native_workspace_port.py +43 -0
  760. ksadk/studio/operations.py +34 -9
  761. ksadk/studio/plugin_composition.py +26 -10
  762. ksadk/studio/plugin_kernel_adapter.py +75 -1
  763. ksadk/studio/plugin_native_activation.py +163 -0
  764. ksadk/studio/plugin_runtime.py +639 -119
  765. ksadk/studio/plugin_runtime_admission.py +57 -0
  766. ksadk/studio/presentation.py +92 -0
  767. ksadk/studio/public_output_store.py +69 -0
  768. ksadk/studio/resource_authority.py +11 -3
  769. ksadk/studio/resource_catalog.py +8 -12
  770. ksadk/studio/run_activity.py +338 -385
  771. ksadk/studio/run_controls.py +185 -0
  772. ksadk/studio/run_service.py +908 -319
  773. ksadk/studio/run_submission_receipts.py +68 -0
  774. ksadk/studio/runtime_catalog.py +23 -4
  775. ksadk/studio/runtime_prewarm.py +22 -0
  776. ksadk/studio/scheduler_assistant.py +4 -1
  777. ksadk/studio/service.py +356 -282
  778. ksadk/studio/service_settings.py +229 -0
  779. ksadk/studio/shared_web.py +393 -169
  780. ksadk/studio/shared_web_response_events.py +180 -0
  781. ksadk/studio/shared_web_run_state.py +133 -0
  782. ksadk/studio/skill_discovery.py +305 -3
  783. ksadk/studio/static/assets/ChannelsPage-xX5HlMId.js +8 -0
  784. ksadk/studio/static/assets/{CodeBlock-DMIf4h33-UIqo-BPW.js → CodeBlock-DMIf4h33-CkufcPYo.js} +3 -3
  785. ksadk/studio/static/assets/{MathMessageMarkdown-BesSeCYl-OhNwH4K9.js → MathMessageMarkdown-BesSeCYl-DYG1Wzbx.js} +1 -1
  786. ksadk/studio/static/assets/{MessageMarkdown-CwMTvgFj-g0I-I4dD.js → MessageMarkdown-CwMTvgFj-BeyLyQHu.js} +2 -2
  787. ksadk/studio/static/assets/TeamsPage-CCaaGaVp.js +3 -0
  788. ksadk/studio/static/assets/index-C7DNDik2.css +2 -0
  789. ksadk/studio/static/assets/index-Cy68gTlH.js +265 -0
  790. ksadk/studio/static/index.html +3 -3
  791. ksadk/studio/teams_catalog.py +33 -0
  792. ksadk/studio/teams_installation.py +4 -1
  793. ksadk/studio/teams_node.py +4 -0
  794. ksadk/studio/teams_node_factory.py +558 -0
  795. ksadk/studio/teams_node_runner.py +3 -0
  796. ksadk/studio/teams_node_v1.py +935 -0
  797. ksadk/studio/teams_remote.py +259 -37
  798. ksadk/studio/templates.py +1 -0
  799. ksadk/studio/workspace_plugins.py +3 -1
  800. ksadk/tools/a2a_policy.py +5 -0
  801. ksadk/tools/artifact_observation.py +53 -0
  802. ksadk/tools/captured_source_artifact.py +68 -0
  803. ksadk/tools/schema.py +34 -0
  804. ksadk/toolsets/__init__.py +82 -88
  805. ksadk/toolsets/a2a.py +89 -89
  806. ksadk/toolsets/sandbox.py +377 -6
  807. ksadk/toolsets/skill_management.py +315 -0
  808. ksadk/toolsets/tool_selection.py +94 -0
  809. ksadk/toolsets/workspace.py +342 -324
  810. ksadk/toolsets/workspace_editing.py +291 -0
  811. ksadk/toolsets/workspace_model_observation.py +104 -0
  812. ksadk/toolsets/workspace_mutation.py +75 -0
  813. ksadk/toolsets/workspace_read_budget.py +216 -0
  814. ksadk/toolsets/workspace_search.py +192 -0
  815. ksadk/toolsets/workspace_search_process.py +129 -0
  816. ksadk/toolsets/workspace_state.py +6 -0
  817. ksadk/version.py +1 -1
  818. ksadk_runtime_common/http_headers.py +18 -0
  819. ksadk_runtime_common/workspace_files/router.py +2 -1
  820. ksadk/server/static/assets/architecture-7GRP2DOG-BCsa26zi.js +0 -1
  821. ksadk/server/static/assets/channel-_KDifNys.js +0 -1
  822. ksadk/server/static/assets/chunk-2Q5K7J3B-HdVkJ9F0.js +0 -1
  823. ksadk/server/static/assets/classDiagram-DTDB5LWJ-BVCW3ZqZ.js +0 -1
  824. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-BVCW3ZqZ.js +0 -1
  825. ksadk/server/static/assets/cynefin-OW5HDTMX-CNXjFctL.js +0 -1
  826. ksadk/server/static/assets/eventmodeling-NTZA5JFV-B5-8RH9c.js +0 -1
  827. ksadk/server/static/assets/flowDiagram-A5DVABFB-BppFxEKw.js +0 -1
  828. ksadk/server/static/assets/gitGraph-4MIJSDKK-B-AhYj4C.js +0 -1
  829. ksadk/server/static/assets/index-BMd2mucF.css +0 -2
  830. ksadk/server/static/assets/index-D5qyyhTH.js +0 -244
  831. ksadk/server/static/assets/info-A6RAGUB7-0uiKrC35.js +0 -1
  832. ksadk/server/static/assets/packet-AYTQ26CC-BVTmZ_cw.js +0 -1
  833. ksadk/server/static/assets/pie-WAS4IAKB-DyfxBU7V.js +0 -1
  834. ksadk/server/static/assets/radar-RG4KPBEZ-FFontjL2.js +0 -1
  835. ksadk/server/static/assets/railroad-74A4TZTK-D0Uidzen.js +0 -1
  836. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BOo_9T2h.js +0 -1
  837. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-D6-BjW7Z.js +0 -1
  838. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CXx__yMm.js +0 -1
  839. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BXAFScz8.js +0 -1
  840. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uIQ2lJKH.js +0 -8
  841. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5GgucZ.js +0 -1
  842. ksadk/server/static/assets/treemap-WGGIJYW6-Bq1u1SpG.js +0 -1
  843. ksadk/server/static/assets/wardley-WFR3VGLG-QAt06uEz.js +0 -1
  844. ksadk/studio/static/assets/ChannelsPage-D_PGmKVq.js +0 -8
  845. ksadk/studio/static/assets/TeamsPage-DqX4HWKQ.js +0 -3
  846. ksadk/studio/static/assets/index-CfEnms6Y.css +0 -2
  847. ksadk/studio/static/assets/index-Dp61rOWZ.js +0 -0
  848. {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/WHEEL +0 -0
  849. {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/entry_points.txt +0 -0
  850. {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/licenses/LICENSE +0 -0
  851. {agentengine_sdk_python-0.8.5.dist-info → agentengine_sdk_python-0.8.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,282 @@
1
+ """Native Hook contracts. A Hook can propose data, never grant runtime authority.
2
+
3
+ This is a new native protocol, not an adapter for the legacy ProviderHook API.
4
+ Dispatch and durable lifecycle admission belong to the Kernel and host Ports.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import hashlib
10
+ import json
11
+ import math
12
+ from typing import Literal, Protocol
13
+
14
+ from pydantic import Field, JsonValue, model_validator
15
+
16
+ from .model import ModelToolCall
17
+ from .state import Contract, RunScope
18
+
19
+ HookEvent = Literal["PreToolUse", "PostToolUse", "Stop", "PreCompact"]
20
+ HookFailure = Literal[
21
+ "producer_failed", "producer_invalid", "input_budget_exceeded", "output_budget_exceeded",
22
+ "producer_timeout", "binding_unavailable", "policy_denied", "policy_error",
23
+ ]
24
+
25
+
26
+ def _json_bytes(value: object) -> bytes:
27
+ return json.dumps(
28
+ value, ensure_ascii=False, sort_keys=True, separators=(",", ":"), allow_nan=False,
29
+ ).encode("utf-8")
30
+
31
+
32
+ def hook_execution_policy_digest(*, cleanup_timeout_seconds: float) -> str:
33
+ if (type(cleanup_timeout_seconds) not in (int, float)
34
+ or not math.isfinite(cleanup_timeout_seconds) or cleanup_timeout_seconds <= 0):
35
+ raise ValueError("Hook cleanup wait must be explicit, finite and positive")
36
+ policy = {
37
+ "version": "ksadk.native-hook-callback-lifetime/v1",
38
+ "cleanup_timeout_seconds": float(cleanup_timeout_seconds),
39
+ }
40
+ return "sha256:" + hashlib.sha256(_json_bytes(policy)).hexdigest()
41
+
42
+
43
+ class HookDefinition(Contract):
44
+ hook_id: str = Field(min_length=1, max_length=128, pattern=r"^[a-z0-9._-]+$")
45
+ source_ref: str = Field(min_length=1, max_length=512)
46
+ binding_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
47
+ execution_policy_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
48
+ # Host authority for interpreting unknown callback outcomes. Never inferred
49
+ # from the Hook's event/name or from model-produced data.
50
+ read_only: bool = Field(strict=True)
51
+ events: tuple[HookEvent, ...] = Field(min_length=1, max_length=4)
52
+ tool_names: tuple[str, ...] | None = None
53
+ # All I/O limits are explicit host inputs. No invisible timeout or retry.
54
+ timeout_seconds: float = Field(strict=True, gt=0, allow_inf_nan=False)
55
+ max_input_bytes: int = Field(strict=True, ge=1)
56
+ max_output_bytes: int = Field(strict=True, ge=1)
57
+ failure_mode: Literal["warn", "block"]
58
+ compaction_source_projection: Literal["canonical_user"] | None = Field(
59
+ default=None, exclude_if=lambda value: value is None,
60
+ )
61
+
62
+ @model_validator(mode="after")
63
+ def valid_selection(self):
64
+ if len(set(self.events)) != len(self.events):
65
+ raise ValueError("duplicate Hook events")
66
+ if self.tool_names is not None and (
67
+ not self.tool_names or any(not name.strip() for name in self.tool_names)
68
+ or len(set(self.tool_names)) != len(self.tool_names)
69
+ ):
70
+ raise ValueError("invalid Hook tool selection")
71
+ if set(self.events) <= {"Stop", "PreCompact"} and self.tool_names is not None:
72
+ raise ValueError("lifecycle Hook cannot select tool names")
73
+ if self.compaction_source_projection is not None and "PreCompact" not in self.events:
74
+ raise ValueError("compaction projection requires PreCompact")
75
+ return self
76
+
77
+ def matches(self, event: HookEvent, tool_name: str | None = None) -> bool:
78
+ return event in self.events and (
79
+ event in {"Stop", "PreCompact"} or self.tool_names is None
80
+ or tool_name in self.tool_names
81
+ )
82
+
83
+
84
+ class PreCompactSubject(Contract):
85
+ """The admitted original prefix, before any summary or callback projection."""
86
+
87
+ source_revision: int = Field(strict=True, ge=0)
88
+ source_context_digest: str = Field(pattern=r"^[0-9a-f]{64}$")
89
+ source_message_count: int = Field(strict=True, ge=0)
90
+ message_refs: tuple[str, ...]
91
+ messages: tuple[dict[str, JsonValue], ...]
92
+ retained_message_refs: tuple[str, ...]
93
+ source_projection: Literal["canonical_user"] | None = Field(
94
+ default=None, exclude_if=lambda value: value is None,
95
+ )
96
+
97
+ @model_validator(mode="after")
98
+ def source_alignment(self):
99
+ if (len(self.message_refs) != len(self.messages)
100
+ or len(set(self.message_refs)) != len(self.message_refs)
101
+ or set(self.message_refs) & set(self.retained_message_refs)):
102
+ raise ValueError("PreCompact source references do not match its removed messages")
103
+ return self
104
+
105
+
106
+ class HookInvocationRequest(Contract):
107
+ schema_version: Literal["ksadk.native-hook-request/v1"] = "ksadk.native-hook-request/v1"
108
+ scope: RunScope
109
+ run_id: str = Field(min_length=1)
110
+ session_id: str = Field(min_length=1)
111
+ turn_id: str = Field(min_length=1)
112
+ operation_key: str = Field(min_length=1)
113
+ goal_revision: int = Field(strict=True, ge=0)
114
+ goal: str = Field(min_length=1)
115
+ tool_call_count: int = Field(strict=True, ge=0)
116
+ stop_continuation_count: int = Field(strict=True, ge=0)
117
+ event: HookEvent
118
+ definition: HookDefinition
119
+ call: ModelToolCall | None = None
120
+ tool_result: dict[str, JsonValue] | None = None
121
+ candidate_id: str | None = Field(default=None, min_length=1)
122
+ candidate_text: str | None = None
123
+ compaction: PreCompactSubject | None = Field(
124
+ default=None, exclude_if=lambda value: value is None,
125
+ )
126
+
127
+ @model_validator(mode="after")
128
+ def valid_subject(self):
129
+ if not self.definition.matches(self.event, self.call.name if self.call else None):
130
+ raise ValueError("Hook event or tool is outside its definition")
131
+ if self.event == "PreCompact":
132
+ if (self.compaction is None or self.call is not None or self.tool_result is not None
133
+ or self.candidate_id is not None or self.candidate_text is not None):
134
+ raise ValueError("PreCompact requires only an admitted compaction source")
135
+ if self.compaction.source_projection != self.definition.compaction_source_projection:
136
+ raise ValueError("PreCompact projection differs from its locked definition")
137
+ elif self.compaction is not None:
138
+ raise ValueError("only PreCompact may contain a compaction source")
139
+ elif self.event == "Stop":
140
+ if (self.call is not None or self.tool_result is not None
141
+ or self.candidate_id is None or self.candidate_text is None):
142
+ raise ValueError("Stop Hook requires only a completion candidate")
143
+ elif self.call is None or self.candidate_id is not None or self.candidate_text is not None:
144
+ raise ValueError("tool Hook requires only a tool subject")
145
+ elif self.event == "PreToolUse" and self.tool_result is not None:
146
+ raise ValueError("PreToolUse cannot contain an executed result")
147
+ elif self.event == "PostToolUse":
148
+ if self.tool_result is None:
149
+ raise ValueError("PostToolUse requires an executed result")
150
+ # Lazy import keeps HookDefinition usable by the Port contracts.
151
+ from .ports import ToolResult
152
+
153
+ ToolResult.model_validate(self.tool_result)
154
+ _json_bytes(self.input_payload())
155
+ return self
156
+
157
+ def input_payload(self) -> dict:
158
+ payload = {
159
+ "goal": self.goal,
160
+ "tool_call_count": self.tool_call_count,
161
+ "stop_continuation_count": self.stop_continuation_count,
162
+ "call": self.call.model_dump(mode="json") if self.call else None,
163
+ "tool_result": self.tool_result,
164
+ "candidate_id": self.candidate_id,
165
+ "candidate_text": self.candidate_text,
166
+ }
167
+ if self.compaction is not None:
168
+ payload["compaction"] = self.compaction.model_dump(mode="json")
169
+ return payload
170
+
171
+ @property
172
+ def input_digest(self) -> str:
173
+ payload = {
174
+ "definition": self.definition.model_dump(mode="json"),
175
+ "input": self.input_payload(),
176
+ }
177
+ return "sha256:" + hashlib.sha256(_json_bytes(payload)).hexdigest()
178
+
179
+ @property
180
+ def input_bytes(self) -> int:
181
+ return len(_json_bytes(self.input_payload()))
182
+
183
+ @property
184
+ def stop_hook_active(self) -> bool:
185
+ return self.event == "Stop" and self.stop_continuation_count > 0
186
+
187
+
188
+ class HookOutput(Contract):
189
+ action: Literal["continue", "deny", "repair"] = "continue"
190
+ additional_context: tuple[str, ...] = ()
191
+ updated_arguments: dict[str, JsonValue] | None = None
192
+
193
+ @model_validator(mode="after")
194
+ def valid_data(self):
195
+ _json_bytes(self.model_dump(mode="json"))
196
+ if self.action == "repair" and not any(text.strip() for text in self.additional_context):
197
+ raise ValueError("Stop repair requires actionable context")
198
+ return self
199
+
200
+
201
+ class HookInvocationResult(Contract):
202
+ schema_version: Literal["ksadk.native-hook-result/v1"] = "ksadk.native-hook-result/v1"
203
+ scope: RunScope
204
+ run_id: str
205
+ session_id: str
206
+ turn_id: str
207
+ operation_key: str
208
+ goal_revision: int = Field(strict=True, ge=0)
209
+ event: HookEvent
210
+ hook_id: str
211
+ source_ref: str
212
+ binding_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
213
+ input_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
214
+ status: Literal["ok", "failed", "uncertain"]
215
+ output: HookOutput | None = None
216
+ reason: HookFailure | None = None
217
+
218
+ @model_validator(mode="after")
219
+ def valid_outcome(self):
220
+ if self.status == "ok":
221
+ if self.output is None or self.reason is not None:
222
+ raise ValueError("successful Hook requires only a valid output")
223
+ elif self.output is not None or self.reason is None:
224
+ raise ValueError("failed Hook cannot supply an output")
225
+ if self.output is not None:
226
+ if self.output.updated_arguments is not None and (
227
+ self.event != "PreToolUse" or self.output.action != "continue"
228
+ ):
229
+ raise ValueError("only a continuing PreToolUse may propose new arguments")
230
+ if self.output.action == "repair" and self.event != "Stop":
231
+ raise ValueError("only Stop may request repair")
232
+ return self
233
+
234
+ @classmethod
235
+ def for_request(
236
+ cls, request: HookInvocationRequest, *, output: HookOutput | None = None,
237
+ reason: HookFailure | None = None, uncertain: bool = False,
238
+ ):
239
+ return cls(
240
+ **request.model_dump(include={
241
+ "scope", "run_id", "session_id", "turn_id", "operation_key",
242
+ "goal_revision", "event",
243
+ }),
244
+ hook_id=request.definition.hook_id, source_ref=request.definition.source_ref,
245
+ binding_digest=request.definition.binding_digest, input_digest=request.input_digest,
246
+ status="uncertain" if uncertain else "failed" if reason is not None else "ok",
247
+ output=output, reason=reason,
248
+ )
249
+
250
+
251
+ class HookPort(Protocol):
252
+ async def invoke(self, request: HookInvocationRequest) -> HookInvocationResult: ...
253
+
254
+
255
+ def validate_hook_result(
256
+ request: HookInvocationRequest, result: HookInvocationResult,
257
+ ) -> HookInvocationResult:
258
+ # Frozen Pydantic objects contain mutable JSON. Detach/revalidate both
259
+ # sides, including objects created by model_copy/model_construct.
260
+ request = HookInvocationRequest.model_validate_json(
261
+ _json_bytes(request.model_dump(mode="json"))
262
+ )
263
+ result = HookInvocationResult.model_validate_json(_json_bytes(result.model_dump(mode="json")))
264
+ identity = ("scope", "run_id", "session_id", "turn_id", "operation_key",
265
+ "goal_revision", "event")
266
+ if any(getattr(request, key) != getattr(result, key) for key in identity):
267
+ raise ValueError("Hook receipt identity mismatch")
268
+ if (result.hook_id, result.source_ref, result.binding_digest, result.input_digest) != (
269
+ request.definition.hook_id, request.definition.source_ref,
270
+ request.definition.binding_digest, request.input_digest,
271
+ ):
272
+ raise ValueError("Hook receipt binding or input mismatch")
273
+ if request.input_bytes > request.definition.max_input_bytes and not (
274
+ result.status == "failed" and result.reason == "input_budget_exceeded"
275
+ ):
276
+ raise ValueError("Hook input exceeded its declared budget")
277
+ if result.output is not None and (
278
+ len(_json_bytes(result.output.model_dump(mode="json")))
279
+ > request.definition.max_output_bytes
280
+ ):
281
+ raise ValueError("Hook output exceeded its declared budget")
282
+ return result
@@ -0,0 +1,117 @@
1
+ """Durable host evidence for browser observations and interaction failures."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+
8
+ from pydantic import JsonValue
9
+
10
+ from .ports import ToolResult
11
+
12
+ _INTERACTIVE_ACTIONS = frozenset({"click", "fill", "press", "reload"})
13
+
14
+
15
+ def advance_browser_observation(
16
+ previous: dict[str, JsonValue] | None,
17
+ *,
18
+ role: str,
19
+ tool_call: int,
20
+ result: ToolResult,
21
+ ) -> dict[str, JsonValue] | None:
22
+ """Remember only a successful screenshot from the host-bound browser port."""
23
+ if role != "browser" or result.status != "ok" or not isinstance(result.content, dict):
24
+ return previous
25
+ content = result.content
26
+ entry = content.get("entry_path")
27
+ screenshot = content.get("screenshot_path")
28
+ if (
29
+ content.get("ok") is not True
30
+ or not isinstance(entry, str)
31
+ or not entry
32
+ or not isinstance(screenshot, str)
33
+ or not screenshot
34
+ ):
35
+ return previous
36
+ receipt = json.dumps(
37
+ {
38
+ "entry_path": entry,
39
+ "screenshot_path": screenshot,
40
+ "browser_session_id": content.get("browser_session_id"),
41
+ "browser_action_seq": content.get("browser_action_seq"),
42
+ "tool_call": tool_call,
43
+ },
44
+ ensure_ascii=False,
45
+ sort_keys=True,
46
+ default=str,
47
+ ).encode("utf-8")
48
+ return {
49
+ "entry_path": entry,
50
+ "tool_call": tool_call,
51
+ "evidence_ref": "sha256:" + hashlib.sha256(receipt).hexdigest(),
52
+ "vision_description_status": str(content.get("vision_description_status") or "not_bound"),
53
+ }
54
+
55
+
56
+ def advance_interaction_observation(
57
+ previous: dict[str, JsonValue] | None,
58
+ *,
59
+ role: str,
60
+ tool_name: str,
61
+ tool_call: int,
62
+ result: ToolResult,
63
+ ) -> dict[str, JsonValue] | None:
64
+ """Clear a page failure only after a successful action on the same entry.
65
+
66
+ A later screenshot or host-only reload is insufficient: it can hide an
67
+ error triggered by the user's original click or key press. The receipt is
68
+ host supplied, and only a host-tagged browser port participates.
69
+ """
70
+ if role != "browser" or not isinstance(result.content, dict):
71
+ return previous
72
+ content = result.content
73
+ entry = content.get("entry_path")
74
+ if not isinstance(entry, str) or not entry:
75
+ return previous
76
+ errors = (
77
+ item[:300]
78
+ for key in ("page_errors", "console_errors", "request_failures")
79
+ for group in (content.get(key),)
80
+ if isinstance(group, list)
81
+ for item in group
82
+ if isinstance(item, str) and item
83
+ )
84
+ error = next(errors, None)
85
+ if result.status == "error" and error is not None:
86
+ receipt = json.dumps(
87
+ {"entry_path": entry, "tool_call": tool_call, "content": content},
88
+ ensure_ascii=False,
89
+ sort_keys=True,
90
+ default=str,
91
+ ).encode("utf-8")
92
+ return {
93
+ "tool_name": tool_name,
94
+ "entry_path": entry,
95
+ "tool_call": tool_call,
96
+ "error": error,
97
+ "evidence_ref": "sha256:" + hashlib.sha256(receipt).hexdigest(),
98
+ }
99
+ actions = content.get("actions")
100
+ interactive = isinstance(actions, list) and any(
101
+ isinstance(action, dict) and action.get("type") in _INTERACTIVE_ACTIONS
102
+ for action in actions
103
+ )
104
+ if (
105
+ previous is not None
106
+ and result.status == "ok"
107
+ and content.get("ok") is True
108
+ and content.get("actions_ok") is True
109
+ and interactive
110
+ and previous.get("tool_name") == tool_name
111
+ and previous.get("entry_path") == entry
112
+ ):
113
+ return None
114
+ return previous
115
+
116
+
117
+ __all__ = ["advance_browser_observation", "advance_interaction_observation"]
@@ -0,0 +1,103 @@
1
+ """Local worker ownership for a Native run, separate from loop decisions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ from typing import Awaitable, TypeVar
7
+ from uuid import uuid4
8
+
9
+ from ksadk.harness.stores.native_contract import LeasedRunStore, RunStore
10
+
11
+ from .state import RunScope
12
+
13
+ Result = TypeVar("Result")
14
+
15
+
16
+ class RunLeaseController:
17
+ def __init__(
18
+ self, store: RunStore, scope: RunScope, *, ttl_seconds: float | None = None
19
+ ) -> None:
20
+ if ttl_seconds is not None:
21
+ if not isinstance(store, LeasedRunStore):
22
+ raise ValueError("leased Native runs require a durable lease store")
23
+ if type(ttl_seconds) not in {int, float} or not 0 < ttl_seconds <= 3600:
24
+ raise ValueError("lease TTL must be positive and at most one hour")
25
+ self.store = store
26
+ self.scope = scope
27
+ self.ttl_seconds = ttl_seconds
28
+ self.owner_id = uuid4().hex if ttl_seconds is not None else None
29
+ self._fences: dict[str, int] = {}
30
+
31
+ def attached(self, run_id: str) -> bool:
32
+ return run_id in self._fences
33
+
34
+ def acquire(self, run_id: str) -> None:
35
+ if run_id in self._fences:
36
+ return
37
+ if self.ttl_seconds is None:
38
+ self._fences[run_id] = self.store.acquire(self.scope, run_id)
39
+ else:
40
+ self._fences[run_id] = self.store.acquire_lease(
41
+ self.scope, run_id, owner_id=self.owner_id, ttl_seconds=self.ttl_seconds
42
+ )
43
+
44
+ def token(self, run_id: str) -> int:
45
+ if run_id not in self._fences:
46
+ raise ValueError("attach the run before driving it")
47
+ token = self._fences[run_id]
48
+ if self.ttl_seconds is not None:
49
+ self.store.renew_lease(
50
+ self.scope, run_id, owner_id=self.owner_id,
51
+ fencing_token=token, ttl_seconds=self.ttl_seconds,
52
+ )
53
+ return token
54
+
55
+ def release(self, run_id: str) -> None:
56
+ token = self._fences.get(run_id)
57
+ if token is None:
58
+ return
59
+ if self.ttl_seconds is not None:
60
+ self.store.release_lease(
61
+ self.scope, run_id, owner_id=self.owner_id, fencing_token=token
62
+ )
63
+ self._fences.pop(run_id)
64
+
65
+ async def keep_alive(self, run_id: str, effect: Awaitable[Result]) -> Result:
66
+ """Renew during owned work or backoff; the Store fences late writes."""
67
+ if self.ttl_seconds is None:
68
+ return await effect
69
+ stopped = asyncio.Event()
70
+
71
+ async def heartbeat() -> None:
72
+ interval = min(10.0, max(0.01, self.ttl_seconds / 3))
73
+ while True:
74
+ try:
75
+ await asyncio.wait_for(stopped.wait(), timeout=interval)
76
+ return
77
+ except asyncio.TimeoutError:
78
+ self.token(run_id)
79
+
80
+ task = asyncio.create_task(heartbeat())
81
+ running = asyncio.ensure_future(effect)
82
+ # Observe any result after bounded cancellation, including a port that
83
+ # ignores cancellation. It cannot be returned to the old owner.
84
+ running.add_done_callback(
85
+ lambda finished: finished.exception() if not finished.cancelled() else None
86
+ )
87
+ try:
88
+ completed, _ = await asyncio.wait(
89
+ (running, task), return_when=asyncio.FIRST_COMPLETED
90
+ )
91
+ if task in completed:
92
+ # A renewal error revokes local execution ownership now,
93
+ # rather than after the external effect happens to return.
94
+ task.result()
95
+ return await running
96
+ finally:
97
+ stopped.set()
98
+ if not running.done():
99
+ running.cancel()
100
+ # The dispatcher also bounds its own port cancellation. Never
101
+ # make an uncooperative awaitable defeat lease-loss shutdown.
102
+ await asyncio.wait((running,), timeout=0.5)
103
+ await task