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,49 @@
1
+ """Public Codex retry diagnostics without persisting provider response bodies."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from collections.abc import Mapping
7
+ from typing import Any
8
+
9
+ from ._codex_validators import _safe_codex_error_info_kind
10
+
11
+
12
+ def codex_http_status(error: Mapping[str, Any]) -> int | None:
13
+ info = error.get("codexErrorInfo")
14
+ kind = _safe_codex_error_info_kind(info)
15
+ detail = info.get(kind) if isinstance(info, Mapping) and kind else None
16
+ value = detail.get("httpStatusCode") if isinstance(detail, Mapping) else None
17
+ if isinstance(value, int) and not isinstance(value, bool) and 400 <= value <= 599:
18
+ return value
19
+ # Older App Servers put the HTTP status only in the diagnostic string.
20
+ # Extract the bounded numeric field; never copy that free text into progress.
21
+ for key in ("message", "additionalDetails"):
22
+ text = error.get(key)
23
+ match = (
24
+ re.search(r"\b(?:HTTP(?: status)?|status code)[:\s]+([45]\d{2})\b", text, re.I)
25
+ if isinstance(text, str)
26
+ else None
27
+ )
28
+ if match:
29
+ return int(match.group(1))
30
+ return None
31
+
32
+
33
+ def codex_retry_numbers(message: str, observed: int) -> tuple[int, int | None]:
34
+ # This exact counter is emitted by Codex itself. It counts retries, not
35
+ # initial requests, and may reset for the next sampling step in a turn.
36
+ match = re.fullmatch(r"Reconnecting\.\.\. (\d+)/(\d+)", message)
37
+ if match:
38
+ count, maximum = (int(value) for value in match.groups())
39
+ if 0 < count <= maximum <= 100:
40
+ return count, maximum
41
+ return observed, None
42
+
43
+
44
+ def codex_error_label(status: int | None) -> str:
45
+ if status == 429:
46
+ return "模型限流(HTTP 429)"
47
+ if status is not None:
48
+ return f"模型请求失败(HTTP {status})"
49
+ return "模型连接中断"
@@ -75,6 +75,7 @@ class LangGraphAdapterContext:
75
75
  graph_run_id: str
76
76
  initial_seq: int = 0
77
77
  checkpoint_ref: Mapping[str, str] | None = None
78
+ publication_epoch: str | None = None
78
79
  _next_seq: int = field(init=False, repr=False)
79
80
 
80
81
  def __post_init__(self) -> None:
@@ -153,7 +154,10 @@ def _map_data_channel(
153
154
  value: Any,
154
155
  ) -> tuple[RuntimeEvent, ...]:
155
156
  env = _envelope(context, frame.occurrence_key, frame.timestamp)
156
- item_id = stable_item_id("langgraph", frame.scope_id, "channel", method, frame.source_seq)
157
+ item_id = stable_item_id(
158
+ "langgraph", frame.scope_id, "channel", method, frame.source_seq,
159
+ *([context.publication_epoch] if context.publication_epoch else []),
160
+ )
157
161
  part_id = _part_id(item_id, "channel", method)
158
162
  content = DataContent(part_id=part_id, data=_json_value(value))
159
163
  envelope = lambda event_type: env( # noqa: E731
@@ -465,6 +469,9 @@ def _envelope(
465
469
  occurrence_key: str,
466
470
  timestamp: float,
467
471
  ) -> Callable[..., dict[str, Any]]:
472
+ if context.publication_epoch:
473
+ occurrence_key = f"{context.publication_epoch}:{occurrence_key}"
474
+
468
475
  def env(
469
476
  scope_id: str,
470
477
  parent_scope_id: str | None,
@@ -474,6 +481,10 @@ def _envelope(
474
481
  source: SourceRef,
475
482
  ordinal: int = 0,
476
483
  ) -> dict[str, Any]:
484
+ if context.publication_epoch:
485
+ source = source.model_copy(update={"metadata": {
486
+ **source.metadata, "publication_epoch": context.publication_epoch,
487
+ }})
477
488
  return {
478
489
  "schema_version": 2,
479
490
  "event_id": stable_event_id(
@@ -89,6 +89,8 @@ class A2AEventAdapter(_A2ATaskSnapshotMixin):
89
89
  OCCURRENCE_CACHE_LIMIT = 1024
90
90
 
91
91
  def __init__(self) -> None:
92
+ self._tool_activities = {}
93
+ self._tool_activity_bytes = 0
92
94
  self._artifacts: dict[str, _ArtifactState] = {}
93
95
  self._messages: dict[str, _MessageState] = {}
94
96
  self._seen_occurrences: OrderedDict[str, str] = OrderedDict()
@@ -97,8 +99,20 @@ class A2AEventAdapter(_A2ATaskSnapshotMixin):
97
99
  self._run_started = False
98
100
  self._run_interrupted = False
99
101
  self._active_interaction: tuple[str, str] | None = None
102
+ self._active_interaction_kind = "structured_input"
100
103
  self._terminal_snapshot_fingerprint: str | None = None
101
104
 
105
+ def checkpoint(self, context: A2AAdapterContext):
106
+ from ksadk.events.adapters._a2a_checkpoint import export_checkpoint
107
+
108
+ return export_checkpoint(self, context)
109
+
110
+ @classmethod
111
+ def restore_checkpoint(cls, payload):
112
+ from ksadk.events.adapters._a2a_checkpoint import restore_checkpoint
113
+
114
+ return restore_checkpoint(cls, payload)
115
+
102
116
  def map_event(
103
117
  self,
104
118
  native_event: object,
@@ -134,6 +148,12 @@ class A2AEventAdapter(_A2ATaskSnapshotMixin):
134
148
  getattr(native_event, payload_name), context, timestamp=timestamp
135
149
  )
136
150
  if isinstance(native_event, TaskArtifactUpdateEvent):
151
+ from ksadk.events.adapters._a2a_tool_activity import map_tool_artifact
152
+
153
+ self._validate_identity(native_event.context_id, native_event.task_id, context)
154
+ public = map_tool_artifact(self, native_event.artifact, context, timestamp)
155
+ if public is not None:
156
+ return public
137
157
  return self._map_artifact_update(native_event, context, timestamp)
138
158
  if isinstance(native_event, TaskStatusUpdateEvent):
139
159
  return self._map_status_update(native_event, context, timestamp)
@@ -317,9 +337,7 @@ class A2AEventAdapter(_A2ATaskSnapshotMixin):
317
337
  "artifact.artifact_id",
318
338
  f"A2A artifact {artifact_id!r} is already closed",
319
339
  )
320
- item_id = stable_item_id(
321
- "a2a", context.context_id, context.task_id, "artifact", artifact_id
322
- )
340
+ item_id = stable_item_id("a2a", *context.item_identity, "artifact", artifact_id)
323
341
  source = self._source(
324
342
  context,
325
343
  occurrence,
@@ -460,14 +478,17 @@ class A2AEventAdapter(_A2ATaskSnapshotMixin):
460
478
  events: list[RuntimeEvent] = []
461
479
  if self._active_interaction is not None:
462
480
  interaction_id, continuation_id = self._active_interaction
463
- events.append(
464
- InteractionResolved(
465
- **env(interaction_id, "interaction.resolved", "interaction", len(events)),
466
- interaction_id=interaction_id,
467
- interaction_kind="structured_input",
468
- response=StructuredInputResponse(data={"state": TaskState.Name(state)}),
481
+ # Remote progress is not evidence of a user's approval decision.
482
+ # The caller's durable interaction ledger owns that resolution.
483
+ if self._active_interaction_kind == "structured_input":
484
+ events.append(
485
+ InteractionResolved(
486
+ **env(interaction_id, "interaction.resolved", "interaction", len(events)),
487
+ interaction_id=interaction_id,
488
+ interaction_kind="structured_input",
489
+ response=StructuredInputResponse(data={"state": TaskState.Name(state)}),
490
+ )
469
491
  )
470
- )
471
492
  events.append(
472
493
  ContinuationResumed(
473
494
  **env(continuation_id, "continuation.resumed", "continuation", len(events)),
@@ -528,18 +549,19 @@ class A2AEventAdapter(_A2ATaskSnapshotMixin):
528
549
  events: list[RuntimeEvent] = []
529
550
  if self._active_interaction is not None:
530
551
  previous_interaction_id, _ = self._active_interaction
531
- events.append(
532
- InteractionResolved(
533
- **env(
534
- previous_interaction_id, "interaction.resolved", "interaction", len(events)
535
- ),
536
- interaction_id=previous_interaction_id,
537
- interaction_kind="structured_input",
538
- response=StructuredInputResponse(
539
- data={"state": "SUPERSEDED_BY_NEW_A2A_INTERACTION"}
540
- ),
552
+ if self._active_interaction_kind == "structured_input":
553
+ events.append(
554
+ InteractionResolved(
555
+ **env(
556
+ previous_interaction_id, "interaction.resolved", "interaction", len(events)
557
+ ),
558
+ interaction_id=previous_interaction_id,
559
+ interaction_kind="structured_input",
560
+ response=StructuredInputResponse(
561
+ data={"state": "SUPERSEDED_BY_NEW_A2A_INTERACTION"}
562
+ ),
563
+ )
541
564
  )
542
- )
543
565
  self._active_interaction = None
544
566
  self._ensure_run_started(events, context, source, timestamp, occurrence)
545
567
  interaction_id = stable_item_id(
@@ -553,12 +575,18 @@ class A2AEventAdapter(_A2ATaskSnapshotMixin):
553
575
  schema = message_metadata.get("input_schema")
554
576
  if not isinstance(schema, dict):
555
577
  schema = {"type": "object" if state == TaskState.TASK_STATE_AUTH_REQUIRED else "string"}
578
+ from ksadk.a2a.interaction_wire import parse_approval_metadata
579
+
580
+ approval = parse_approval_metadata(message_metadata, call_id=interaction_id)
581
+ if approval is not None and state != TaskState.TASK_STATE_INPUT_REQUIRED:
582
+ raise ValueError("A2A_INTERACTION_DECLARATION_INVALID")
583
+ kind = "approval" if approval is not None else "structured_input"
556
584
  events.append(
557
585
  InteractionRequested(
558
586
  **env(interaction_id, "interaction.requested", "interaction", len(events)),
559
587
  interaction_id=interaction_id,
560
- interaction_kind="structured_input",
561
- request=StructuredInputRequest(prompt=prompt, schema=schema),
588
+ interaction_kind=kind,
589
+ request=approval or StructuredInputRequest(prompt=prompt, schema=schema),
562
590
  )
563
591
  )
564
592
  events.append(
@@ -582,6 +610,7 @@ class A2AEventAdapter(_A2ATaskSnapshotMixin):
582
610
  )
583
611
  self._run_interrupted = True
584
612
  self._active_interaction = (interaction_id, continuation_id)
613
+ self._active_interaction_kind = kind
585
614
  return tuple(events)
586
615
 
587
616
  def _map_awaiting_terminal_status(
@@ -684,9 +713,7 @@ class A2AEventAdapter(_A2ATaskSnapshotMixin):
684
713
 
685
714
  @staticmethod
686
715
  def _message_item_id(context: A2AAdapterContext, message_id: str) -> str:
687
- if context.task_id is not None:
688
- return stable_item_id("a2a", context.context_id, context.task_id, "message", message_id)
689
- return stable_item_id("a2a", context.context_id, "message", message_id)
716
+ return stable_item_id("a2a", *context.item_identity, "message", message_id)
690
717
 
691
718
  @staticmethod
692
719
  def _require_task_status(task: Task) -> None:
@@ -752,6 +779,7 @@ class A2AEventAdapter(_A2ATaskSnapshotMixin):
752
779
  "timestamp": timestamp,
753
780
  "run_id": context.run_id,
754
781
  "scope_id": context.scope_id,
782
+ "parent_scope_id": context.parent_scope_id,
755
783
  "source": source,
756
784
  }
757
785
 
@@ -1,9 +1,10 @@
1
- """Google ADK 2.6.3+ events to canonical RuntimeEvent schema v2."""
1
+ """Google ADK events to canonical RuntimeEvent schema v2."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
5
  from collections import defaultdict
6
6
  from dataclasses import dataclass, field
7
+ from importlib.metadata import version
7
8
  from typing import Any, TypeAlias, cast
8
9
 
9
10
  from google.adk.events import Event
@@ -37,6 +38,7 @@ class ADKAdapterContext:
37
38
 
38
39
  run_id: str
39
40
  initial_seq: int = 1
41
+ max_native_events: int = 32768
40
42
  _next_seq: int = field(init=False, repr=False)
41
43
  _ordinals: dict[_OrdinalKey, int] = field(
42
44
  default_factory=lambda: defaultdict(int), init=False, repr=False
@@ -44,14 +46,29 @@ class ADKAdapterContext:
44
46
  _open_items: set[_ItemKey] = field(default_factory=set, init=False, repr=False)
45
47
  _open_item_kinds: dict[_ItemKey, ItemKind] = field(default_factory=dict, init=False, repr=False)
46
48
  _completed_items: set[_ItemKey] = field(default_factory=set, init=False, repr=False)
49
+ _remote_completed_text: dict[_ItemKey, str] = field(
50
+ default_factory=dict, init=False, repr=False
51
+ )
47
52
  _output_refs: list[OutputRef] = field(default_factory=list, init=False, repr=False)
48
53
  _output_replacement_items: set[_ItemKey] = field(default_factory=set, init=False, repr=False)
54
+ _active_text_items: dict[tuple[str, str], str] = field(
55
+ default_factory=dict, init=False, repr=False
56
+ )
57
+ _pending_text: dict[_ItemKey, tuple[dict[str, Any], str]] = field(
58
+ default_factory=dict, init=False, repr=False
59
+ )
60
+ _partial_deliveries: int = field(default=0, init=False, repr=False)
61
+ _seen_native_events: set[tuple[str, str, str]] = field(
62
+ default_factory=set, init=False, repr=False
63
+ )
49
64
 
50
65
  def __post_init__(self) -> None:
51
66
  if not self.run_id.strip():
52
67
  raise ValueError("ADK adapter run_id must not be empty")
53
68
  if self.initial_seq < 0:
54
69
  raise ValueError("ADK adapter initial_seq must be non-negative")
70
+ if self.max_native_events <= 0:
71
+ raise ValueError("ADK adapter max_native_events must be positive")
55
72
  self._next_seq = self.initial_seq
56
73
 
57
74
  def allocate_seq(self) -> int:
@@ -96,6 +113,7 @@ class ADKAdapterContext:
96
113
  def mark_completed(self, key: _ItemKey, *, output: bool) -> None:
97
114
  self._open_items.discard(key)
98
115
  self._open_item_kinds.pop(key, None)
116
+ self._pending_text.pop(key, None)
99
117
  self._completed_items.add(key)
100
118
  if output:
101
119
  if key in self._output_replacement_items:
@@ -106,21 +124,88 @@ class ADKAdapterContext:
106
124
  def mark_output_replacement(self, key: _ItemKey) -> None:
107
125
  self._output_replacement_items.add(key)
108
126
 
127
+ def accept_native_event(
128
+ self, native_run_id: str, path_key: str, native_event_id: str, *, deduplicate: bool = True
129
+ ) -> bool:
130
+ key = (native_run_id, path_key, native_event_id)
131
+ if deduplicate and key in self._seen_native_events:
132
+ return False
133
+ if len(self._seen_native_events) + self._partial_deliveries >= self.max_native_events:
134
+ raise ValueError("ADK native event budget exceeded")
135
+ if deduplicate:
136
+ self._seen_native_events.add(key)
137
+ else:
138
+ self._partial_deliveries += 1
139
+ return True
140
+
141
+ def resolve_text_item(self, scope_id: str, lane: str, candidate_item_id: str) -> str:
142
+ """Reuse the open ADK response lane across per-chunk native Event IDs."""
143
+
144
+ return self._active_text_items.get((scope_id, lane), candidate_item_id)
145
+
146
+ def mark_text_started(self, key: _ItemKey, lane: str, item_kind: ItemKind) -> None:
147
+ self.mark_started(key, item_kind)
148
+ self._active_text_items[(key[0], lane)] = key[1]
149
+
150
+ def mark_text_completed(self, key: _ItemKey, lane: str, *, output: bool) -> None:
151
+ active_key = (key[0], lane)
152
+ if self._active_text_items.get(active_key) == key[1]:
153
+ self._active_text_items.pop(active_key, None)
154
+ self.mark_completed(key, output=output)
155
+
109
156
  def mark_failed(self, key: _ItemKey) -> None:
110
157
  self._open_items.discard(key)
111
158
  self._open_item_kinds.pop(key, None)
159
+ self._pending_text.pop(key, None)
112
160
  self._output_replacement_items.discard(key)
161
+ for active_key, active_item_id in tuple(self._active_text_items.items()):
162
+ if active_key[0] == key[0] and active_item_id == key[1]:
163
+ self._active_text_items.pop(active_key, None)
113
164
 
114
165
 
115
166
  class ADKEventAdapter:
116
167
  """Map ADK native response identities without author/text inference."""
117
168
 
169
+ def __init__(self, *, partial_ids_identify_response: bool | None = None):
170
+ if partial_ids_identify_response is None:
171
+ release = tuple(int(part) for part in version("google-adk").split(".")[:2])
172
+ partial_ids_identify_response = release >= (2, 6)
173
+ self._partial_ids_identify_response = partial_ids_identify_response
174
+
118
175
  def map(self, event: Event, context: ADKAdapterContext) -> tuple[RuntimeEvent, ...]:
176
+ if getattr(event, "_canonical", None) is not None:
177
+ # Only our in-process event type can carry an already persisted
178
+ # fact. Public custom_metadata cannot opt into this bypass.
179
+ from ksadk.a2a.adk import canonical_event_from_adk
180
+
181
+ canonical = canonical_event_from_adk(event)
182
+ if canonical is not None:
183
+ if canonical.run_id != context.run_id or canonical.event_type.startswith("run."):
184
+ raise ValueError("A2A_CANONICAL_REFERENCE_CONFLICT")
185
+ if not context.accept_native_event(
186
+ canonical.run_id, canonical.scope_id, canonical.event_id
187
+ ):
188
+ return ()
189
+ context._next_seq = max(context.next_seq, canonical.seq + 1)
190
+ return (canonical,)
119
191
  native_event_id = _required_string(getattr(event, "id", None), "event id")
120
192
  native_run_id = _required_string(getattr(event, "invocation_id", None), "invocation id")
121
193
  path = str(getattr(getattr(event, "node_info", None), "path", "") or "")
122
194
  branch = str(getattr(event, "branch", "") or "")
123
195
  path_key = path or branch or "$root"
196
+ # ADK >= 2.6 reuses one response ID for every transient partial and
197
+ # its aggregate. These partials are not persisted by native sessions;
198
+ # their ordered deliveries, including equal text, must remain distinct.
199
+ # Canonical references and A2A artifact observations keep their own IDs.
200
+ shared_partial = (
201
+ self._partial_ids_identify_response
202
+ and bool(getattr(event, "partial", False))
203
+ and not (getattr(event, "custom_metadata", None) or {}).get("ksadk_a2a_stream")
204
+ )
205
+ if not context.accept_native_event(
206
+ native_run_id, path_key, native_event_id, deduplicate=not shared_partial
207
+ ):
208
+ return ()
124
209
  scope_id = stable_scope_id("adk", native_run_id, path_key)
125
210
  source_metadata: dict[str, JsonValue] = {"path": path, "path_key": path_key}
126
211
  author = str(getattr(event, "author", "") or "")
@@ -144,30 +229,49 @@ class ADKEventAdapter:
144
229
  ),
145
230
  }
146
231
  is_partial = bool(getattr(event, "partial", False))
147
- for lane in ("reasoning", "message"):
148
- text = text_by_lane[lane]
149
- if not text:
150
- continue
151
- mapped.extend(
152
- self._map_text_lane(
153
- event=event,
154
- context=context,
155
- native_event_id=native_event_id,
156
- native_run_id=native_run_id,
157
- path_key=path_key,
158
- scope_id=scope_id,
159
- source_metadata=source_metadata,
160
- lane=cast("_TextLane", lane),
161
- text=text,
162
- partial=is_partial,
163
- replace=any(
164
- getattr(part, "text", None)
165
- and bool(getattr(part, "thought", False)) == (lane == "reasoning")
166
- and _metadata_flag(part, "ksadk_output_snapshot")
167
- for part in parts
232
+ observations = (getattr(event, "custom_metadata", None) or {}).get("ksadk_a2a_stream") or [
233
+ None
234
+ ]
235
+ for remote in observations:
236
+ remote_item_id = None
237
+ if remote is not None:
238
+ remote_item_id = stable_item_id(
239
+ "a2a", str(remote["task_id"]), str(remote["artifact_id"])
240
+ )
241
+ for lane in ("reasoning", "message"):
242
+ text = remote["text"][lane] if remote else text_by_lane[lane]
243
+ candidate_key = (
244
+ scope_id,
245
+ stable_item_id(
246
+ "adk", native_run_id, path_key, remote_item_id or native_event_id, lane
168
247
  ),
169
248
  )
170
- )
249
+ if not text and not (remote and context.is_open(candidate_key)):
250
+ continue
251
+ mapped.extend(
252
+ self._map_text_lane(
253
+ event=event,
254
+ context=context,
255
+ native_event_id=native_event_id,
256
+ native_run_id=native_run_id,
257
+ path_key=path_key,
258
+ scope_id=scope_id,
259
+ source_metadata=source_metadata,
260
+ lane=cast("_TextLane", lane),
261
+ text=text,
262
+ partial=(not remote["snapshot"]) if remote else is_partial,
263
+ native_item_id=remote_item_id,
264
+ close_at_end=bool(remote["last_chunk"]) if remote else False,
265
+ replace=(not remote["append"])
266
+ if remote
267
+ else any(
268
+ getattr(part, "text", None)
269
+ and bool(getattr(part, "thought", False)) == (lane == "reasoning")
270
+ and _metadata_flag(part, "ksadk_output_snapshot")
271
+ for part in parts
272
+ ),
273
+ )
274
+ )
171
275
 
172
276
  if not is_partial:
173
277
  for part in parts:
@@ -207,6 +311,24 @@ class ADKEventAdapter:
207
311
  )
208
312
  return tuple(mapped)
209
313
 
314
+ def finish(self, context: ADKAdapterContext) -> tuple[RuntimeEvent, ...]:
315
+ """Close a partial reasoning lane omitted from the terminal response."""
316
+
317
+ mapped: list[RuntimeEvent] = []
318
+ for _key, (kwargs, text) in list(context._pending_text.items()):
319
+ if (kwargs["lane"] == "reasoning" and not kwargs.get("native_item_id")) or kwargs.get(
320
+ "close_at_end", False
321
+ ):
322
+ mapped.extend(
323
+ self._map_text_lane(
324
+ **kwargs,
325
+ text=text,
326
+ partial=False,
327
+ replace=False,
328
+ )
329
+ )
330
+ return tuple(mapped)
331
+
210
332
  def _map_text_lane(
211
333
  self,
212
334
  *,
@@ -221,10 +343,21 @@ class ADKEventAdapter:
221
343
  text: str,
222
344
  partial: bool,
223
345
  replace: bool,
346
+ native_item_id: str | None = None,
347
+ close_at_end: bool = False,
224
348
  ) -> list[RuntimeEvent]:
225
- item_id = stable_item_id("adk", native_run_id, path_key, native_event_id, lane)
349
+ candidate_item_id = stable_item_id(
350
+ "adk", native_run_id, path_key, native_item_id or native_event_id, lane
351
+ )
352
+ item_id = (
353
+ candidate_item_id
354
+ if native_item_id
355
+ else context.resolve_text_item(scope_id, lane, candidate_item_id)
356
+ )
226
357
  key = (scope_id, item_id)
227
358
  if context.is_completed(key):
359
+ if native_item_id and context._remote_completed_text.get(key) != text:
360
+ raise ValueError("A2A_TERMINAL_CONTENT_CONFLICT")
228
361
  return []
229
362
  part_id = f"{lane}.text"
230
363
  item_kind: ItemKind = "reasoning" if lane == "reasoning" else "message"
@@ -232,8 +365,11 @@ class ADKEventAdapter:
232
365
  source = _source(
233
366
  native_event_id=native_event_id,
234
367
  native_run_id=native_run_id,
235
- native_item_id=native_event_id,
236
- metadata=source_metadata,
368
+ native_item_id=native_item_id or native_event_id,
369
+ metadata={
370
+ **source_metadata,
371
+ **({"ksadk_output_snapshot": True} if replace and not native_item_id else {}),
372
+ },
237
373
  )
238
374
  mapped: list[RuntimeEvent] = []
239
375
  if not context.is_open(key):
@@ -254,11 +390,30 @@ class ADKEventAdapter:
254
390
  phase=phase,
255
391
  )
256
392
  )
257
- context.mark_started(key, item_kind)
393
+ if native_item_id:
394
+ context.mark_started(key, item_kind)
395
+ else:
396
+ context.mark_text_started(key, lane, item_kind)
258
397
  content = TextContent(part_id=part_id, text=text)
259
- if replace and lane == "message":
398
+ if replace and lane == "message" and not native_item_id:
260
399
  context.mark_output_replacement(key)
261
400
  if partial:
401
+ previous = context._pending_text.get(key, ({}, ""))[1]
402
+ context._pending_text[key] = (
403
+ {
404
+ "event": event,
405
+ "context": context,
406
+ "native_event_id": native_event_id,
407
+ "native_run_id": native_run_id,
408
+ "path_key": path_key,
409
+ "scope_id": scope_id,
410
+ "source_metadata": source_metadata,
411
+ "lane": lane,
412
+ "native_item_id": native_item_id,
413
+ "close_at_end": close_at_end,
414
+ },
415
+ ("" if replace else previous) + text,
416
+ )
262
417
  mapped.append(
263
418
  ItemUpdated(
264
419
  **_envelope(
@@ -295,9 +450,12 @@ class ADKEventAdapter:
295
450
  snapshot=ContentSnapshot(parts=(content,)),
296
451
  )
297
452
  )
298
- context.mark_completed(
453
+ if native_item_id:
454
+ context._remote_completed_text[key] = text
455
+ context.mark_text_completed(
299
456
  key,
300
- output=lane == "message" and event.is_final_response(),
457
+ lane,
458
+ output=lane == "message" and (bool(native_item_id) or event.is_final_response()),
301
459
  )
302
460
  return mapped
303
461
 
@@ -9,6 +9,11 @@ from collections import OrderedDict
9
9
  from collections.abc import Iterable, Mapping, Sequence
10
10
  from typing import Any, Callable
11
11
 
12
+ from ksadk.events.adapters._codex_errors import (
13
+ codex_error_label,
14
+ codex_http_status,
15
+ codex_retry_numbers,
16
+ )
12
17
  from ksadk.events.adapters._codex_interactions import _CodexInteractionMixin
13
18
  from ksadk.events.adapters._codex_items import (
14
19
  _CODEX_0_147_0_NOTIFICATION_METHODS,
@@ -80,6 +85,7 @@ class CodexEventAdapter(_CodexInteractionMixin):
80
85
  def __init__(self, *, known_thread_ids: Iterable[str] = ()) -> None:
81
86
  self._items: dict[tuple[str, str], _ItemState] = {}
82
87
  self._active_turns: set[str] = set()
88
+ self._retry_counts: dict[str, int] = {}
83
89
  self._completed_items: dict[str, list[OutputRef]] = {}
84
90
  self._interactions: dict[str, _InteractionState] = {}
85
91
  self._thread_continuations: dict[str, str] = {
@@ -632,11 +638,19 @@ class CodexEventAdapter(_CodexInteractionMixin):
632
638
  elif status == "failed":
633
639
  error = _mapping(turn.get("error"), "params.turn.error")
634
640
  message = _required_text(error.get("message"), "params.turn.error.message")
641
+ http_status = codex_http_status(error)
642
+ retry_count = self._retry_counts.get(scope_id, 0)
643
+ if http_status is not None:
644
+ outcome = f"自动重试 {retry_count} 次后仍失败" if retry_count else "本次请求失败"
645
+ message = f"{codex_error_label(http_status)},{outcome},请稍后重试。"
646
+ source = source.model_copy(update={"metadata": {
647
+ **source.metadata, "status_code": http_status, "retry_count": retry_count,
648
+ }})
635
649
  terminal = RunFailed(
636
650
  **env(scope_id, turn_id, "run.failed", "run", source),
637
651
  status="failed",
638
652
  error=ErrorInfo(
639
- code="codex_turn_failed",
653
+ code="MODEL_RATE_LIMITED" if http_status == 429 else "codex_turn_failed",
640
654
  message=message,
641
655
  source="codex",
642
656
  scope_id=scope_id,
@@ -656,6 +670,7 @@ class CodexEventAdapter(_CodexInteractionMixin):
656
670
  f"Unsupported terminal Codex turn status: {status}",
657
671
  )
658
672
  self._active_turns.remove(scope_id)
673
+ self._retry_counts.pop(scope_id, None)
659
674
  self._completed_items.pop(scope_id, None)
660
675
  return (terminal,)
661
676
 
@@ -735,7 +750,7 @@ class CodexEventAdapter(_CodexInteractionMixin):
735
750
  cursor: str,
736
751
  ) -> tuple[RuntimeEvent, ...]:
737
752
  error = _mapping(params.get("error"), "params.error")
738
- _required_text(error.get("message"), "params.error.message")
753
+ native_message = _required_text(error.get("message"), "params.error.message")
739
754
  will_retry = params.get("willRetry")
740
755
  if not isinstance(will_retry, bool):
741
756
  _fail(
@@ -750,11 +765,26 @@ class CodexEventAdapter(_CodexInteractionMixin):
750
765
  turn_id=turn_id,
751
766
  native_item_id=None,
752
767
  )
768
+ http_status = codex_http_status(error)
769
+ observed = self._retry_counts.get(scope_id, 0)
770
+ if will_retry:
771
+ observed += 1
772
+ self._retry_counts[scope_id] = observed
773
+ count, maximum = codex_retry_numbers(native_message, observed)
774
+ counter = f"{count}/{maximum}" if maximum else str(count)
775
+ public_message = (
776
+ f"{codex_error_label(http_status)},正在自动重试(第 {counter} 次)"
777
+ if will_retry
778
+ else f"{codex_error_label(http_status)},自动重试已停止"
779
+ )
753
780
  source = base.model_copy(
754
781
  update={
755
782
  "metadata": {
756
783
  **base.metadata,
757
784
  "will_retry": will_retry,
785
+ "status_code": http_status,
786
+ "retry_count": count,
787
+ "max_retries": maximum,
758
788
  "error_message_present": True,
759
789
  "additional_details_present": error.get("additionalDetails") is not None,
760
790
  "codex_error_info_present": error.get("codexErrorInfo") is not None,
@@ -774,11 +804,7 @@ class CodexEventAdapter(_CodexInteractionMixin):
774
804
  source,
775
805
  ),
776
806
  status="running",
777
- message=(
778
- "Codex reported a retryable turn error"
779
- if will_retry
780
- else "Codex reported a non-retryable turn error"
781
- ),
807
+ message=public_message,
782
808
  ),
783
809
  )
784
810