agentengine-sdk-python 0.8.4__py3-none-any.whl → 0.8.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1221) hide show
  1. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/METADATA +17 -10
  2. agentengine_sdk_python-0.8.6.dist-info/RECORD +1731 -0
  3. ksadk/_async_iterators.py +79 -0
  4. ksadk/_build_provenance.json +1 -1
  5. ksadk/_model_anthropic.py +49 -0
  6. ksadk/_model_input.py +86 -0
  7. ksadk/_model_json.py +40 -0
  8. ksadk/_model_reasoning.py +17 -0
  9. ksadk/_model_refusal.py +20 -0
  10. ksadk/_model_sse.py +163 -0
  11. ksadk/_process.py +83 -0
  12. ksadk/_str_enum.py +17 -0
  13. ksadk/a2a/__init__.py +157 -167
  14. ksadk/a2a/_invocation_state.py +86 -0
  15. ksadk/a2a/_space_client_events.py +33 -22
  16. ksadk/a2a/adk.py +194 -0
  17. ksadk/a2a/adk_invocation_context.py +242 -0
  18. ksadk/a2a/adk_runtime.py +126 -0
  19. ksadk/a2a/adk_tools.py +319 -0
  20. ksadk/a2a/bootstrap.py +149 -23
  21. ksadk/a2a/build_validation.py +147 -0
  22. ksadk/a2a/card.py +23 -15
  23. ksadk/a2a/codex.py +160 -0
  24. ksadk/a2a/codex_checkpoint.py +111 -0
  25. ksadk/a2a/codex_recovery.py +96 -0
  26. ksadk/a2a/codex_recovery_events.py +123 -0
  27. ksadk/a2a/codex_runtime.py +198 -0
  28. ksadk/a2a/codex_session_checkpoint.py +162 -0
  29. ksadk/a2a/composition.py +88 -0
  30. ksadk/a2a/context_store.py +118 -19
  31. ksadk/a2a/control_plane.py +108 -106
  32. ksadk/a2a/event_adapter.py +92 -193
  33. ksadk/a2a/executor.py +257 -85
  34. ksadk/a2a/exposure.py +106 -0
  35. ksadk/a2a/external_transport.py +3 -4
  36. ksadk/a2a/identity.py +106 -12
  37. ksadk/a2a/ids.py +14 -3
  38. ksadk/a2a/inbound_kernel.py +133 -0
  39. ksadk/a2a/interaction_wire.py +76 -0
  40. ksadk/a2a/invocation_checkpoint.py +274 -0
  41. ksadk/a2a/invocation_policy.py +87 -0
  42. ksadk/a2a/invocation_publication.py +210 -0
  43. ksadk/a2a/invocation_service.py +972 -0
  44. ksadk/a2a/invocation_types.py +459 -0
  45. ksadk/a2a/kernel_task_adapter.py +259 -0
  46. ksadk/a2a/langgraph.py +20 -7
  47. ksadk/a2a/langgraph_invocation_context.py +136 -0
  48. ksadk/a2a/langgraph_managed.py +150 -0
  49. ksadk/a2a/langgraph_recovery.py +32 -0
  50. ksadk/a2a/langgraph_runtime.py +89 -0
  51. ksadk/a2a/langgraph_tool_runtime.py +132 -0
  52. ksadk/a2a/langgraph_tools.py +63 -0
  53. ksadk/a2a/message_digest.py +40 -0
  54. ksadk/a2a/platform.py +389 -0
  55. ksadk/a2a/policy_refs.py +13 -0
  56. ksadk/a2a/presentation.py +402 -0
  57. ksadk/a2a/product_kernel_facts.py +177 -0
  58. ksadk/a2a/product_key.py +99 -0
  59. ksadk/a2a/protocol_errors.py +116 -0
  60. ksadk/a2a/result_text.py +49 -0
  61. ksadk/a2a/resume_store.py +93 -3
  62. ksadk/a2a/routes.py +6 -1
  63. ksadk/a2a/runtime_approval.py +198 -0
  64. ksadk/a2a/runtime_input.py +151 -0
  65. ksadk/a2a/server.py +16 -7
  66. ksadk/a2a/space_client.py +101 -16
  67. ksadk/a2a/task_adapter.py +19 -5
  68. ksadk/a2a/task_event_dispatcher.py +39 -2
  69. ksadk/a2a/task_event_outbox.py +215 -0
  70. ksadk/a2a/task_event_outbox_owned.py +130 -0
  71. ksadk/a2a/task_store.py +37 -0
  72. ksadk/a2a/tool_activity.py +176 -0
  73. ksadk/a2a/workload_tokens.py +134 -0
  74. ksadk/a2ui/core.py +3 -3
  75. ksadk/api/client.py +38 -79
  76. ksadk/api/sse_stream.py +96 -0
  77. ksadk/builders/code_builder.py +121 -118
  78. ksadk/builders/container_builder.py +11 -29
  79. ksadk/builders/framework_requirements.py +22 -2
  80. ksadk/builders/managed_runtime_builder.py +12 -0
  81. ksadk/builders/source_provenance.py +87 -0
  82. ksadk/cli/__init__.py +36 -0
  83. ksadk/cli/cmd_a2a.py +43 -0
  84. ksadk/cli/cmd_build.py +9 -0
  85. ksadk/cli/cmd_config.py +4 -4
  86. ksadk/cli/cmd_create.py +12 -12
  87. ksadk/cli/cmd_deploy.py +27 -2
  88. ksadk/cli/cmd_hermes.py +24 -2
  89. ksadk/cli/cmd_invoke.py +64 -88
  90. ksadk/cli/cmd_openclaw.py +26 -1
  91. ksadk/cli/cmd_plugin.py +70 -12
  92. ksadk/cli/cmd_studio.py +69 -17
  93. ksadk/cli/cmd_web.py +2 -0
  94. ksadk/cli/hosted_invoke.py +206 -0
  95. ksadk/cli/invoke_content.py +60 -0
  96. ksadk/cli/openclaw_env.py +1 -1
  97. ksadk/cli/resource_common.py +26 -0
  98. ksadk/cli/runtime_bootstrap.py +27 -5
  99. ksadk/codex/_expert_request_reader.py +48 -0
  100. ksadk/codex/a2a_tools.py +140 -0
  101. ksadk/codex/async_approval.py +169 -0
  102. ksadk/codex/async_client.py +938 -0
  103. ksadk/codex/async_proxy.py +216 -0
  104. ksadk/codex/base_runtime.py +25 -0
  105. ksadk/codex/client.py +3 -1047
  106. ksadk/codex/client_payloads.py +85 -0
  107. ksadk/codex/rollout_checkpoint.py +264 -0
  108. ksadk/codex/runtime.py +290 -54
  109. ksadk/common/auth.py +2 -2
  110. ksadk/common/cloud_headers.py +36 -0
  111. ksadk/common/diagnostics.py +34 -0
  112. ksadk/common/kop_client.py +2 -1
  113. ksadk/configs/__init__.py +1 -1
  114. ksadk/configs/env_registry.py +216 -143
  115. ksadk/configs/env_registry_a2a.py +173 -0
  116. ksadk/configs/env_registry_studio.py +134 -0
  117. ksadk/configs/global_config.py +2 -1
  118. ksadk/configs/settings.py +9 -3
  119. ksadk/connector/__init__.py +17 -0
  120. ksadk/connector/channel.py +477 -0
  121. ksadk/context_engine/assembler.py +9 -0
  122. ksadk/context_engine/capabilities.py +52 -4
  123. ksadk/context_engine/contributors.py +80 -17
  124. ksadk/context_engine/instruction_authority.py +18 -0
  125. ksadk/conversations/attachment_storage.py +10 -3
  126. ksadk/conversations/attachments.py +69 -20
  127. ksadk/conversations/contracts.py +28 -9
  128. ksadk/conversations/message_projection.py +51 -155
  129. ksadk/conversations/message_projection_blocks.py +137 -0
  130. ksadk/conversations/model_context.py +11 -3
  131. ksadk/conversations/normalize.py +28 -10
  132. ksadk/conversations/projector.py +63 -0
  133. ksadk/conversations/runtime_baseline.py +37 -0
  134. ksadk/conversations/runtime_compaction.py +7 -2
  135. ksadk/conversations/runtime_input.py +16 -4
  136. ksadk/conversations/runtime_invocation.py +17 -4
  137. ksadk/conversations/runtime_observability.py +39 -10
  138. ksadk/conversations/runtime_payloads.py +12 -0
  139. ksadk/conversations/runtime_persistence.py +296 -32
  140. ksadk/conversations/runtime_preparation.py +98 -13
  141. ksadk/conversations/runtime_projection.py +217 -0
  142. ksadk/conversations/runtime_resume.py +141 -70
  143. ksadk/conversations/runtime_stream_events.py +29 -35
  144. ksadk/conversations/runtime_streaming.py +8 -0
  145. ksadk/conversations/tool_receipt_resume.py +387 -0
  146. ksadk/conversations/tool_receipts.py +32 -0
  147. ksadk/deployment/env_forward.py +5 -0
  148. ksadk/deployment/manager.py +15 -6
  149. ksadk/deployment/providers/serverless.py +76 -136
  150. ksadk/deployment/providers/serverless_payloads.py +122 -0
  151. ksadk/evaluation/agent_eval_client.py +2 -1
  152. ksadk/evaluation/contracts.py +78 -3
  153. ksadk/evaluation/evaluators.py +166 -1
  154. ksadk/evaluation/evidence.py +271 -4
  155. ksadk/evaluation/local_adapter.py +76 -12
  156. ksadk/evaluation/studio_build_adapter.py +73 -9
  157. ksadk/events/adapters/_a2a_checkpoint.py +151 -0
  158. ksadk/events/adapters/_a2a_snapshot.py +18 -14
  159. ksadk/events/adapters/_a2a_support.py +15 -3
  160. ksadk/events/adapters/_a2a_tool_activity.py +123 -0
  161. ksadk/events/adapters/_codex_errors.py +49 -0
  162. ksadk/events/adapters/_codex_items.py +16 -8
  163. ksadk/events/adapters/_langgraph_support.py +46 -1
  164. ksadk/events/adapters/a2a.py +54 -26
  165. ksadk/events/adapters/adk.py +188 -30
  166. ksadk/events/adapters/codex.py +33 -7
  167. ksadk/events/adapters/langgraph.py +16 -6
  168. ksadk/events/canonical.py +5 -0
  169. ksadk/events/canonical_store.py +200 -4
  170. ksadk/events/reducer.py +82 -0
  171. ksadk/events/run_authority.py +176 -0
  172. ksadk/events/session_event.py +2 -2
  173. ksadk/harness/__init__.py +18 -0
  174. ksadk/harness/app.py +11 -0
  175. ksadk/harness/artifact_adapters/__init__.py +1 -0
  176. ksadk/harness/artifact_adapters/native_page_budget.py +172 -0
  177. ksadk/harness/artifact_adapters/native_search.py +249 -0
  178. ksadk/harness/artifact_adapters/native_search_budget.py +134 -0
  179. ksadk/harness/artifact_adapters/native_store.py +115 -0
  180. ksadk/harness/artifact_adapters/native_tool.py +222 -0
  181. ksadk/harness/artifact_store.py +230 -0
  182. ksadk/harness/browser_adapters/__init__.py +6 -0
  183. ksadk/harness/browser_adapters/native_browser_tool.py +92 -0
  184. ksadk/harness/browser_adapters/native_dom_snapshot.py +187 -0
  185. ksadk/harness/browser_adapters/native_playwright.py +953 -0
  186. ksadk/harness/browser_adapters/native_vision.py +295 -0
  187. ksadk/harness/capabilities.py +115 -0
  188. ksadk/harness/capability_adapters/__init__.py +1 -0
  189. ksadk/harness/capability_adapters/native_dsh.py +289 -0
  190. ksadk/harness/capability_runtime.py +332 -0
  191. ksadk/harness/closure_contract.py +92 -0
  192. ksadk/harness/compaction_record.py +153 -0
  193. ksadk/harness/compiler.py +284 -0
  194. ksadk/harness/config.py +28 -5
  195. ksadk/harness/conformance/__init__.py +33 -0
  196. ksadk/harness/conformance/contract.py +504 -0
  197. ksadk/harness/conformance/fixtures.py +102 -0
  198. ksadk/harness/context_engine.py +388 -0
  199. ksadk/harness/context_maintenance.py +259 -0
  200. ksadk/harness/context_manifest.py +188 -0
  201. ksadk/harness/context_sections.py +397 -0
  202. ksadk/harness/context_tuning.py +168 -0
  203. ksadk/harness/diagnostic_adapters/__init__.py +1 -0
  204. ksadk/harness/diagnostic_adapters/contracts.py +70 -0
  205. ksadk/harness/diagnostic_adapters/lsp_rpc.py +210 -0
  206. ksadk/harness/diagnostic_adapters/native_lsp.py +286 -0
  207. ksadk/harness/draft_runtime.py +322 -0
  208. ksadk/harness/engine/__init__.py +40 -0
  209. ksadk/harness/engine/base.py +122 -0
  210. ksadk/harness/engine/budgets.py +108 -0
  211. ksadk/harness/engine/capability_declarations.py +59 -0
  212. ksadk/harness/engine/completion_guard.py +57 -0
  213. ksadk/harness/engine/context_pipeline.py +1351 -0
  214. ksadk/harness/engine/graph_builder.py +352 -0
  215. ksadk/harness/engine/hooked_reasoner.py +380 -0
  216. ksadk/harness/engine/langgraph.py +1049 -0
  217. ksadk/harness/engine/mcp_disclosure.py +701 -0
  218. ksadk/harness/engine/phases/__init__.py +6 -0
  219. ksadk/harness/engine/phases/context.py +48 -0
  220. ksadk/harness/engine/phases/interaction.py +31 -0
  221. ksadk/harness/engine/phases/reason.py +552 -0
  222. ksadk/harness/engine/phases/tools.py +638 -0
  223. ksadk/harness/engine/policy_runtime.py +81 -0
  224. ksadk/harness/engine/postgres_checkpointer.py +386 -0
  225. ksadk/harness/engine/run_control_bridge.py +100 -0
  226. ksadk/harness/engine/run_types.py +98 -0
  227. ksadk/harness/engine/skill_disclosure.py +275 -0
  228. ksadk/harness/engine/spans.py +41 -0
  229. ksadk/harness/engine/steering.py +177 -0
  230. ksadk/harness/engine/subagents.py +360 -0
  231. ksadk/harness/engine/thread_ids.py +112 -0
  232. ksadk/harness/engine/tool_dispatch.py +249 -0
  233. ksadk/harness/event_tree.py +212 -0
  234. ksadk/harness/events.py +498 -0
  235. ksadk/harness/execution_policy.py +104 -0
  236. ksadk/harness/hooks.py +259 -0
  237. ksadk/harness/insights.py +210 -0
  238. ksadk/harness/lifecycle.py +578 -0
  239. ksadk/harness/lifecycle_conformance.py +233 -0
  240. ksadk/harness/lifecycle_local_plane.py +104 -0
  241. ksadk/harness/loop/__init__.py +44 -0
  242. ksadk/harness/loop/reason.py +699 -0
  243. ksadk/harness/loop/tools.py +907 -0
  244. ksadk/harness/managed_runtime.py +1044 -0
  245. ksadk/harness/mcp_disclosure_contract.py +85 -0
  246. ksadk/harness/mcp_matrix.py +474 -0
  247. ksadk/harness/mcp_result_policy.py +44 -0
  248. ksadk/harness/mcp_runtime.py +504 -0
  249. ksadk/harness/memory_consolidation.py +157 -0
  250. ksadk/harness/memory_loop.py +156 -0
  251. ksadk/harness/memory_runtime.py +541 -0
  252. ksadk/harness/metrics.py +90 -0
  253. ksadk/harness/micro_compact.py +69 -0
  254. ksadk/harness/model_adapters/__init__.py +1 -0
  255. ksadk/harness/model_adapters/native_mcp_media.py +100 -0
  256. ksadk/harness/model_adapters/native_mcp_result.py +36 -0
  257. ksadk/harness/model_adapters/native_openai.py +703 -0
  258. ksadk/harness/model_capability.py +468 -0
  259. ksadk/harness/model_provider.py +430 -0
  260. ksadk/harness/multimodal.py +57 -0
  261. ksadk/harness/native/__init__.py +1 -0
  262. ksadk/harness/native/activation_contract.py +25 -0
  263. ksadk/harness/native/activation_recovery.py +29 -0
  264. ksadk/harness/native/adapters.py +291 -0
  265. ksadk/harness/native/artifact_contract.py +14 -0
  266. ksadk/harness/native/artifact_partial_read_capacity.py +171 -0
  267. ksadk/harness/native/artifact_read_capacity.py +182 -0
  268. ksadk/harness/native/artifact_read_contract.py +27 -0
  269. ksadk/harness/native/artifact_runtime.py +408 -0
  270. ksadk/harness/native/artifact_search_capacity.py +206 -0
  271. ksadk/harness/native/artifact_search_contract.py +40 -0
  272. ksadk/harness/native/artifact_single_read_capacity.py +170 -0
  273. ksadk/harness/native/browser_contract.py +229 -0
  274. ksadk/harness/native/browser_recovery.py +183 -0
  275. ksadk/harness/native/capabilities.py +204 -0
  276. ksadk/harness/native/child_approval.py +60 -0
  277. ksadk/harness/native/child_budget.py +136 -0
  278. ksadk/harness/native/child_cancellation.py +80 -0
  279. ksadk/harness/native/child_input.py +98 -0
  280. ksadk/harness/native/child_input_runtime.py +59 -0
  281. ksadk/harness/native/child_interruption.py +81 -0
  282. ksadk/harness/native/child_lifecycle.py +246 -0
  283. ksadk/harness/native/child_lifecycle_contract.py +91 -0
  284. ksadk/harness/native/child_notifications.py +75 -0
  285. ksadk/harness/native/child_promotion.py +66 -0
  286. ksadk/harness/native/command_runtime.py +99 -0
  287. ksadk/harness/native/completion.py +302 -0
  288. ksadk/harness/native/completion_text.py +116 -0
  289. ksadk/harness/native/context.py +358 -0
  290. ksadk/harness/native/context_artifact_page.py +75 -0
  291. ksadk/harness/native/context_compaction_projection.py +131 -0
  292. ksadk/harness/native/context_contributions.py +320 -0
  293. ksadk/harness/native/context_contributor_contract.py +133 -0
  294. ksadk/harness/native/context_driver.py +820 -0
  295. ksadk/harness/native/context_fresh_tools.py +49 -0
  296. ksadk/harness/native/context_history.py +272 -0
  297. ksadk/harness/native/context_microcompact.py +61 -0
  298. ksadk/harness/native/context_partial_summary.py +58 -0
  299. ksadk/harness/native/context_partition.py +492 -0
  300. ksadk/harness/native/context_pruning.py +275 -0
  301. ksadk/harness/native/context_reduction.py +60 -0
  302. ksadk/harness/native/context_replay.py +148 -0
  303. ksadk/harness/native/context_request_projection.py +526 -0
  304. ksadk/harness/native/context_runtime.py +976 -0
  305. ksadk/harness/native/context_runtime_contracts.py +409 -0
  306. ksadk/harness/native/context_search.py +112 -0
  307. ksadk/harness/native/context_source_fragments.py +188 -0
  308. ksadk/harness/native/context_source_progress.py +119 -0
  309. ksadk/harness/native/context_summary_planning.py +788 -0
  310. ksadk/harness/native/context_summary_recovery.py +105 -0
  311. ksadk/harness/native/delivery_review.py +331 -0
  312. ksadk/harness/native/delivery_review_contract.py +54 -0
  313. ksadk/harness/native/effect_admission.py +82 -0
  314. ksadk/harness/native/effect_control.py +318 -0
  315. ksadk/harness/native/effect_receipts.py +729 -0
  316. ksadk/harness/native/effect_runtime.py +303 -0
  317. ksadk/harness/native/effective_configuration.py +28 -0
  318. ksadk/harness/native/engine.py +945 -0
  319. ksadk/harness/native/final_output.py +34 -0
  320. ksadk/harness/native/final_submission.py +58 -0
  321. ksadk/harness/native/finalization_workspace.py +96 -0
  322. ksadk/harness/native/fork.py +151 -0
  323. ksadk/harness/native/guidance.py +91 -0
  324. ksadk/harness/native/history.py +381 -0
  325. ksadk/harness/native/hook_executor.py +205 -0
  326. ksadk/harness/native/hook_runtime_contract.py +282 -0
  327. ksadk/harness/native/interaction_observation.py +117 -0
  328. ksadk/harness/native/lease.py +103 -0
  329. ksadk/harness/native/machine.py +974 -0
  330. ksadk/harness/native/mcp_result_governance.py +156 -0
  331. ksadk/harness/native/model.py +570 -0
  332. ksadk/harness/native/model_feedback.py +63 -0
  333. ksadk/harness/native/model_input.py +30 -0
  334. ksadk/harness/native/model_recovery_contract.py +35 -0
  335. ksadk/harness/native/model_replay.py +128 -0
  336. ksadk/harness/native/model_request.py +133 -0
  337. ksadk/harness/native/model_runtime.py +196 -0
  338. ksadk/harness/native/model_takeover.py +419 -0
  339. ksadk/harness/native/model_tool_batch.py +40 -0
  340. ksadk/harness/native/observed_progress.py +46 -0
  341. ksadk/harness/native/operator_guidance.py +201 -0
  342. ksadk/harness/native/output_contract.py +80 -0
  343. ksadk/harness/native/output_recovery.py +24 -0
  344. ksadk/harness/native/ports.py +749 -0
  345. ksadk/harness/native/precompact_hook_runtime.py +171 -0
  346. ksadk/harness/native/replay_context.py +149 -0
  347. ksadk/harness/native/request_media.py +112 -0
  348. ksadk/harness/native/restore_contract.py +16 -0
  349. ksadk/harness/native/run_clock.py +120 -0
  350. ksadk/harness/native/state.py +436 -0
  351. ksadk/harness/native/steering.py +170 -0
  352. ksadk/harness/native/stop_hook_runtime.py +151 -0
  353. ksadk/harness/native/studio_admission.py +29 -0
  354. ksadk/harness/native/subagents.py +86 -0
  355. ksadk/harness/native/task_policy.py +99 -0
  356. ksadk/harness/native/task_progress.py +86 -0
  357. ksadk/harness/native/terminal_verification.py +43 -0
  358. ksadk/harness/native/tool_argument_feedback.py +178 -0
  359. ksadk/harness/native/tool_budget.py +253 -0
  360. ksadk/harness/native/tool_error_streak.py +89 -0
  361. ksadk/harness/native/tool_hook_runtime.py +343 -0
  362. ksadk/harness/native/tool_input_validation.py +58 -0
  363. ksadk/harness/native/tool_interruption.py +96 -0
  364. ksadk/harness/native/tool_observation.py +259 -0
  365. ksadk/harness/native/tool_progress.py +223 -0
  366. ksadk/harness/native/tool_recovery.py +25 -0
  367. ksadk/harness/native/tool_scheduling.py +33 -0
  368. ksadk/harness/native/tool_schema.py +126 -0
  369. ksadk/harness/native/transitions.py +151 -0
  370. ksadk/harness/native/turn_control.py +98 -0
  371. ksadk/harness/native/user_document.py +98 -0
  372. ksadk/harness/native/user_document_capture.py +49 -0
  373. ksadk/harness/native/user_input.py +87 -0
  374. ksadk/harness/native/verification.py +432 -0
  375. ksadk/harness/native/verification_binding.py +40 -0
  376. ksadk/harness/native/verification_runtime.py +233 -0
  377. ksadk/harness/native/verification_workspace.py +67 -0
  378. ksadk/harness/native_driver_failure.py +123 -0
  379. ksadk/harness/native_facade.py +977 -0
  380. ksadk/harness/native_factory.py +244 -0
  381. ksadk/harness/native_projection.py +503 -0
  382. ksadk/harness/native_runtime.py +621 -0
  383. ksadk/harness/native_shadow.py +250 -0
  384. ksadk/harness/native_shadow_inputs.py +146 -0
  385. ksadk/harness/observability/__init__.py +29 -0
  386. ksadk/harness/observability/inspection.py +528 -0
  387. ksadk/harness/observability/metrics.py +167 -0
  388. ksadk/harness/observability/otel_exporter.py +218 -0
  389. ksadk/harness/progress_adapters/__init__.py +5 -0
  390. ksadk/harness/progress_adapters/native_todo.py +75 -0
  391. ksadk/harness/prompt_cache.py +132 -0
  392. ksadk/harness/public_activity.py +213 -0
  393. ksadk/harness/public_output.py +30 -0
  394. ksadk/harness/public_summary.py +36 -0
  395. ksadk/harness/readiness.py +249 -0
  396. ksadk/harness/reasoner.py +779 -17
  397. ksadk/harness/release_readiness.py +140 -0
  398. ksadk/harness/resource_ref.py +69 -0
  399. ksadk/harness/rpc.py +200 -0
  400. ksadk/harness/run_control.py +773 -0
  401. ksadk/harness/runtime.py +157 -113
  402. ksadk/harness/runtime_capabilities.py +228 -0
  403. ksadk/harness/runtime_server.py +514 -0
  404. ksadk/harness/sandbox_adapters.py +739 -0
  405. ksadk/harness/sandbox_backend.py +733 -0
  406. ksadk/harness/sandbox_conformance.py +288 -0
  407. ksadk/harness/sandbox_lease.py +77 -0
  408. ksadk/harness/sandbox_lease_conformance.py +259 -0
  409. ksadk/harness/sandbox_matrix.py +170 -0
  410. ksadk/harness/sandbox_reconciliation.py +140 -0
  411. ksadk/harness/sandbox_recovery.py +586 -0
  412. ksadk/harness/sandbox_recovery_conformance.py +246 -0
  413. ksadk/harness/sdk.py +153 -0
  414. ksadk/harness/session_store.py +589 -0
  415. ksadk/harness/skill_adapters/__init__.py +1 -0
  416. ksadk/harness/skill_adapters/native_bundle.py +148 -0
  417. ksadk/harness/skill_adapters/native_disclosure.py +306 -0
  418. ksadk/harness/skill_composition.py +212 -0
  419. ksadk/harness/skill_feedback.py +123 -0
  420. ksadk/harness/skill_intent.py +47 -0
  421. ksadk/harness/skill_matrix.py +233 -0
  422. ksadk/harness/skill_runtime.py +317 -0
  423. ksadk/harness/spec.py +342 -0
  424. ksadk/harness/state.py +155 -0
  425. ksadk/harness/stores/__init__.py +14 -0
  426. ksadk/harness/stores/native_command_settlement.py +65 -0
  427. ksadk/harness/stores/native_contract.py +311 -0
  428. ksadk/harness/stores/native_memory.py +326 -0
  429. ksadk/harness/stores/native_memory_archive.py +70 -0
  430. ksadk/harness/stores/native_migration_cli.py +91 -0
  431. ksadk/harness/stores/native_outbox.py +56 -0
  432. ksadk/harness/stores/native_sqlite.py +782 -0
  433. ksadk/harness/stores/native_sqlite_audit.py +29 -0
  434. ksadk/harness/stores/native_sqlite_migration.py +252 -0
  435. ksadk/harness/strategies.py +149 -0
  436. ksadk/harness/subagent.py +263 -0
  437. ksadk/harness/subagent_adapters/checkpoint_recovery.py +120 -0
  438. ksadk/harness/subagent_adapters/native_background_child.py +803 -0
  439. ksadk/harness/subagent_adapters/native_child.py +819 -0
  440. ksadk/harness/subagent_adapters/native_child_approval.py +128 -0
  441. ksadk/harness/subagent_adapters/native_child_continuation.py +51 -0
  442. ksadk/harness/subagent_adapters/native_child_result.py +392 -0
  443. ksadk/harness/subagent_adapters/prepared_recovery.py +120 -0
  444. ksadk/harness/tool_display.py +75 -0
  445. ksadk/harness/tool_display_contract.py +134 -0
  446. ksadk/harness/tool_output.py +141 -0
  447. ksadk/harness/tool_policy.py +134 -0
  448. ksadk/harness/tool_receipts.py +96 -0
  449. ksadk/harness/tool_reliability.py +81 -0
  450. ksadk/harness/tool_result_policy.py +216 -0
  451. ksadk/harness/tools.py +52 -0
  452. ksadk/harness/user_errors.py +69 -0
  453. ksadk/harness/working_context.py +81 -0
  454. ksadk/harness/working_context_patch.py +99 -0
  455. ksadk/harness/workspace_adapters/__init__.py +6 -0
  456. ksadk/harness/workspace_adapters/native_directory.py +180 -0
  457. ksadk/harness/workspace_adapters/native_git.py +208 -0
  458. ksadk/harness/workspace_adapters/native_isolation.py +350 -0
  459. ksadk/identity/resolver.py +18 -0
  460. ksadk/interaction/__init__.py +1 -1
  461. ksadk/interaction/ledger.py +1 -1
  462. ksadk/interaction/provider.py +1 -1
  463. ksadk/interaction/providers/__init__.py +3 -1
  464. ksadk/interaction/providers/adk.py +1 -1
  465. ksadk/interaction/providers/codex.py +1 -1
  466. ksadk/interaction/providers/harness.py +50 -0
  467. ksadk/interaction/providers/langgraph.py +9 -2
  468. ksadk/kernel/__init__.py +10 -0
  469. ksadk/kernel/approval_presentation.py +91 -0
  470. ksadk/kernel/authorization.py +1 -1
  471. ksadk/kernel/bootstrap.py +220 -252
  472. ksadk/kernel/contract_fingerprints.py +45 -1
  473. ksadk/kernel/contracts.py +30 -0
  474. ksadk/kernel/control.py +180 -29
  475. ksadk/kernel/execution_grants.py +428 -0
  476. ksadk/kernel/execution_grants_memory.py +252 -0
  477. ksadk/kernel/execution_grants_postgres.py +395 -0
  478. ksadk/kernel/execution_grants_sqlite.py +435 -0
  479. ksadk/kernel/execution_host_ingress.py +1071 -0
  480. ksadk/kernel/history_projection.py +120 -0
  481. ksadk/kernel/ingress.py +139 -226
  482. ksadk/kernel/ingress_bootstrap.py +268 -0
  483. ksadk/kernel/legacy_history.py +179 -0
  484. ksadk/kernel/mapping.py +1 -1
  485. ksadk/kernel/memory_store.py +61 -58
  486. ksadk/kernel/memory_store_projection.py +63 -0
  487. ksadk/kernel/postgres_event_log.py +181 -0
  488. ksadk/kernel/postgres_store.py +230 -231
  489. ksadk/kernel/readiness.py +125 -0
  490. ksadk/kernel/recovery.py +166 -16
  491. ksadk/kernel/recovery_projection.py +124 -0
  492. ksadk/kernel/runtime_checkpoint.py +34 -0
  493. ksadk/kernel/sql/001_agent_kernel.sql +28 -0
  494. ksadk/kernel/sqlite_schema.py +100 -0
  495. ksadk/kernel/sqlite_store.py +410 -200
  496. ksadk/kernel/state.py +2 -3
  497. ksadk/kernel/store.py +104 -5
  498. ksadk/kernel/teams_artifact_tools.py +392 -0
  499. ksadk/kernel/teams_effects.py +851 -0
  500. ksadk/kernel/teams_execution_context.py +408 -0
  501. ksadk/kernel/teams_host_http.py +237 -0
  502. ksadk/kernel/teams_material_transport.py +245 -0
  503. ksadk/kernel/teams_materials.py +318 -0
  504. ksadk/kernel/teams_runtime_bootstrap.py +604 -0
  505. ksadk/kernel/teams_tool_runtime.py +273 -0
  506. ksadk/kernel/teams_workspace.py +259 -0
  507. ksadk/kernel/worker.py +369 -340
  508. ksadk/kernel/worker_controls.py +454 -0
  509. ksadk/kernel/worker_history.py +72 -0
  510. ksadk/kernel/worker_identity.py +74 -0
  511. ksadk/kernel/worker_interactions.py +197 -0
  512. ksadk/knowledge_base/client.py +15 -1
  513. ksadk/managed_runtime.py +29 -2
  514. ksadk/memory/adk/backends/http_ltm_backend.py +2 -1
  515. ksadk/memory/adk/backends/sdk_ltm_backend.py +15 -1
  516. ksadk/memory/adk/bounded_database_session_service.py +232 -0
  517. ksadk/memory/adk/resilient_session_service.py +115 -15
  518. ksadk/memory/adk/short_term_memory.py +8 -9
  519. ksadk/memory/coordinator.py +22 -6
  520. ksadk/memory/extraction.py +159 -7
  521. ksadk/memory/models.py +77 -1
  522. ksadk/memory/provider_resolver.py +5 -0
  523. ksadk/memory/providers/local_candidates.py +183 -0
  524. ksadk/memory/providers/local_postgres.py +200 -0
  525. ksadk/memory/providers/local_sqlite.py +280 -67
  526. ksadk/memory/resolved_policy.py +12 -7
  527. ksadk/memory/retrieval.py +189 -0
  528. ksadk/memory/store_adapter.py +150 -0
  529. ksadk/model_gateway/__init__.py +29 -0
  530. ksadk/model_gateway/client.py +253 -0
  531. ksadk/model_gateway/events.py +113 -0
  532. ksadk/model_gateway/matrix.py +297 -0
  533. ksadk/model_policy.py +2 -2
  534. ksadk/model_proxy/compat.py +670 -0
  535. ksadk/model_proxy/detect.py +254 -0
  536. ksadk/model_proxy/server.py +14 -9
  537. ksadk/model_proxy/transform.py +72 -6
  538. ksadk/plugins/__init__.py +1 -1
  539. ksadk/plugins/bridges/dsh.py +29 -20
  540. ksadk/plugins/bridges/dsh_profile_manifest.py +36 -0
  541. ksadk/plugins/builtin_resources.py +199 -0
  542. ksadk/plugins/builtins.py +417 -185
  543. ksadk/plugins/companion_artifacts.py +83 -0
  544. ksadk/plugins/companions.py +368 -0
  545. ksadk/plugins/context_contributor.py +15 -4
  546. ksadk/plugins/contracts.py +1 -1
  547. ksadk/plugins/dsh_channels.py +156 -0
  548. ksadk/plugins/dsh_dependency_policy.py +41 -0
  549. ksadk/plugins/dsh_home.py +140 -0
  550. ksadk/plugins/dsh_teams.py +105 -0
  551. ksadk/plugins/dsh_toolchain.py +92 -21
  552. ksadk/plugins/execution_host.py +107 -0
  553. ksadk/plugins/host.py +73 -5
  554. ksadk/plugins/kernel_adapter.py +44 -1
  555. ksadk/plugins/memory_provider.py +180 -0
  556. ksadk/plugins/providers/_process_group.py +50 -0
  557. ksadk/plugins/providers/bundles/dsh-channels-client/client.js +19 -0
  558. ksadk/plugins/providers/bundles/dsh-channels-client/cordis.patch.yml +3 -0
  559. ksadk/plugins/providers/bundles/dsh-channels-client/index.mjs +7 -0
  560. ksadk/plugins/providers/bundles/dsh-channels-client/package.json +12 -0
  561. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +24 -2
  562. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +1 -1
  563. ksadk/plugins/providers/bundles/dsh-memory/package.json +1 -1
  564. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +1 -1
  565. ksadk/plugins/providers/bundles/dsh-teams-client/client.js +29 -0
  566. ksadk/plugins/providers/bundles/dsh-teams-client/cordis.patch.yml +3 -0
  567. ksadk/plugins/providers/bundles/dsh-teams-client/index.mjs +11 -0
  568. ksadk/plugins/providers/bundles/dsh-teams-client/package.json +35 -0
  569. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/cordis.patch.yml +3 -0
  570. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/index.mjs +13 -0
  571. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/package.json +27 -0
  572. ksadk/plugins/providers/bundles/dsh-teams-profile/cordis.patch.yml +3 -0
  573. ksadk/plugins/providers/bundles/dsh-teams-profile/index.mjs +12 -0
  574. ksadk/plugins/providers/bundles/dsh-teams-profile/package.json +26 -0
  575. ksadk/plugins/providers/bundles/dsh-teams-router/cordis.patch.yml +3 -0
  576. ksadk/plugins/providers/bundles/dsh-teams-router/index.mjs +16 -0
  577. ksadk/plugins/providers/bundles/dsh-teams-router/package.json +27 -0
  578. ksadk/plugins/providers/bundles/dsh-teams-tasks/cordis.patch.yml +3 -0
  579. ksadk/plugins/providers/bundles/dsh-teams-tasks/index.mjs +16 -0
  580. ksadk/plugins/providers/bundles/dsh-teams-tasks/package.json +27 -0
  581. ksadk/plugins/providers/bundles/dsh-teams-tools/cordis.patch.yml +3 -0
  582. ksadk/plugins/providers/bundles/dsh-teams-tools/index.mjs +25 -0
  583. ksadk/plugins/providers/bundles/dsh-teams-tools/package.json +29 -0
  584. ksadk/plugins/providers/bundles/dsh-teams-tools/tools.json +235 -0
  585. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +1 -1
  586. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +51 -1
  587. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +2 -2
  588. ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/client.mjs +133 -0
  589. ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/index.mjs +14 -0
  590. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +27 -4
  591. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +9 -5
  592. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +1 -1
  593. ksadk/plugins/providers/codex.py +52 -40
  594. ksadk/plugins/providers/codex_native.py +20 -0
  595. ksadk/plugins/providers/codex_skills.py +46 -0
  596. ksadk/plugins/providers/dsh_capabilities.py +49 -143
  597. ksadk/plugins/providers/dsh_connector_lease.py +225 -0
  598. ksadk/plugins/providers/dsh_mcp.py +163 -1
  599. ksadk/plugins/providers/harness.py +413 -52
  600. ksadk/plugins/providers/harness_context.py +61 -0
  601. ksadk/plugins/providers/harness_contributions.py +241 -0
  602. ksadk/plugins/providers/harness_delegation.py +670 -0
  603. ksadk/plugins/providers/harness_hooks.py +121 -0
  604. ksadk/plugins/providers/harness_managed.py +550 -0
  605. ksadk/plugins/providers/harness_tools.py +455 -0
  606. ksadk/plugins/providers/legacy_catalog.py +1 -1
  607. ksadk/plugins/providers/mcp_projection.py +100 -3
  608. ksadk/plugins/providers/platform_resources.py +16 -6
  609. ksadk/plugins/providers/shipped_dsh.py +4 -1
  610. ksadk/plugins/subagent_providers/codex.py +28 -6
  611. ksadk/plugins/teams/__init__.py +5 -0
  612. ksadk/plugins/teams/api.py +405 -0
  613. ksadk/plugins/teams/application.py +540 -0
  614. ksadk/plugins/teams/artifacts.py +60 -0
  615. ksadk/plugins/teams/build_artifacts.py +460 -0
  616. ksadk/plugins/teams/cloud_contract_fingerprints.py +22 -0
  617. ksadk/plugins/teams/cloud_contracts.py +928 -0
  618. ksadk/plugins/teams/cloud_permits.py +250 -0
  619. ksadk/plugins/teams/context.py +96 -0
  620. ksadk/plugins/teams/contracts.py +136 -0
  621. ksadk/plugins/teams/domain.py +1480 -0
  622. ksadk/plugins/teams/domain_values.py +24 -0
  623. ksadk/plugins/teams/effect_contracts.py +255 -0
  624. ksadk/plugins/teams/errors.py +13 -0
  625. ksadk/plugins/teams/execution_projection.py +255 -0
  626. ksadk/plugins/teams/leader_decisions.py +106 -0
  627. ksadk/plugins/teams/migration.py +311 -0
  628. ksadk/plugins/teams/migration_cli.py +322 -0
  629. ksadk/plugins/teams/postgres_store.py +352 -0
  630. ksadk/plugins/teams/release_contracts.py +60 -0
  631. ksadk/plugins/teams/runtime.py +853 -0
  632. ksadk/plugins/teams/source_projection.py +84 -0
  633. ksadk/plugins/teams/store.py +519 -0
  634. ksadk/plugins/teams/task_decisions.py +436 -0
  635. ksadk/plugins/teams/tool_service.py +152 -0
  636. ksadk/plugins/teams/transport.py +96 -0
  637. ksadk/plugins/teams/workspaces.py +255 -0
  638. ksadk/resource_runtime/skill_runtime.py +3 -0
  639. ksadk/resource_runtime/socket_server.py +11 -0
  640. ksadk/resource_runtime/worker.py +28 -4
  641. ksadk/runners/_adk_a2a_stream.py +122 -0
  642. ksadk/runners/_adk_canonical_stream.py +474 -0
  643. ksadk/runners/_langgraph_canonical_streams.py +527 -0
  644. ksadk/runners/_langgraph_runner_streams.py +83 -401
  645. ksadk/runners/_langgraph_state_reader.py +106 -0
  646. ksadk/runners/_langgraph_tool_projection.py +86 -0
  647. ksadk/runners/_langgraph_tools_transformer.py +27 -0
  648. ksadk/runners/_session_identity.py +285 -0
  649. ksadk/runners/adk_runner.py +220 -350
  650. ksadk/runners/base_runner.py +6 -5
  651. ksadk/runners/langgraph_runner.py +208 -195
  652. ksadk/runners/patch_langchain.py +47 -0
  653. ksadk/runners/usage_accumulator.py +11 -3
  654. ksadk/runners/utils/loader.py +28 -14
  655. ksadk/runtime/_runner_adapter/a2ui_surface.py +145 -0
  656. ksadk/runtime/_runner_adapter/gateway_approvals.py +93 -0
  657. ksadk/runtime/_runner_adapter/stream_mapping.py +134 -129
  658. ksadk/runtime/adapter.py +40 -3
  659. ksadk/runtime/conversation_execution.py +29 -3
  660. ksadk/runtime/executor.py +105 -7
  661. ksadk/runtime/factory.py +45 -3
  662. ksadk/runtime/framework_adapters.py +184 -10
  663. ksadk/runtime/hosted_finalizer.py +4 -6
  664. ksadk/runtime/launch.py +2 -0
  665. ksadk/runtime/preprocessing.py +11 -3
  666. ksadk/runtime/runner_adapter.py +160 -21
  667. ksadk/runtime/skill_eval_result.py +36 -0
  668. ksadk/runtime/timing.py +46 -0
  669. ksadk/runtime/usage.py +49 -18
  670. ksadk/runtime_context.py +105 -1
  671. ksadk/sandbox/backends/e2b.py +272 -24
  672. ksadk/sandbox/backends/local_process.py +73 -39
  673. ksadk/sandbox/base.py +62 -1
  674. ksadk/sandbox/diagnostics.py +82 -0
  675. ksadk/sandbox/e2b_connection.py +9 -1
  676. ksadk/sandbox/local_controls.py +776 -0
  677. ksadk/sandbox/local_launcher.py +124 -0
  678. ksadk/scheduler/dispatcher.py +1 -1
  679. ksadk/server/factory.py +178 -25
  680. ksadk/server/history_deadline.py +158 -0
  681. ksadk/server/history_page_cache.py +129 -0
  682. ksadk/server/invocation_identity.py +118 -0
  683. ksadk/server/routes/checkpoint_audit.py +88 -0
  684. ksadk/server/routes/checkpoint_listing.py +294 -0
  685. ksadk/server/routes/checkpoint_resolution.py +73 -20
  686. ksadk/server/routes/common.py +32 -3
  687. ksadk/server/routes/control.py +112 -9
  688. ksadk/server/routes/dependencies.py +2 -1
  689. ksadk/server/routes/display_projection.py +154 -0
  690. ksadk/server/routes/kernel_ingress.py +26 -3
  691. ksadk/server/routes/misc.py +331 -33
  692. ksadk/server/routes/models.py +28 -4
  693. ksadk/server/routes/openai_compat.py +82 -13
  694. ksadk/server/routes/projection.py +159 -216
  695. ksadk/server/routes/run.py +112 -37
  696. ksadk/server/routes/sessions.py +493 -358
  697. ksadk/server/routes/streaming.py +68 -15
  698. ksadk/server/routes/tool_receipt_claim_routes.py +107 -0
  699. ksadk/server/routes/workspace.py +135 -23
  700. ksadk/server/static/assets/{ArtifactsPanel-CGbWlMNh.js → ArtifactsPanel-CILaW-fC.js} +1 -1
  701. ksadk/server/static/assets/{CodeBlock-b4C7upmO.js → CodeBlock-BVrNVtJC.js} +10 -7
  702. ksadk/server/static/assets/MathMessageMarkdown-Dp7c4wWD.js +8 -0
  703. ksadk/server/static/assets/{MermaidBlock-BEBN4Ksz.js → MermaidBlock-Dxop8Rd7.js} +9 -9
  704. ksadk/server/static/assets/{NativeTerminalPanel-zvL-WpAn.js → NativeTerminalPanel-Cjjz8B30.js} +1 -1
  705. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-BYafW7Za.js → abnfDiagram-VCTEODGH-ckWDmOzw.js} +1 -1
  706. ksadk/server/static/assets/{arc-bTohInsS.js → arc-DqxJede-.js} +1 -1
  707. ksadk/server/static/assets/architecture-7GRP2DOG-pn_DuLy6.js +1 -0
  708. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-Ch5Lbzsi.js → architectureDiagram-5GKGNRK7-SEQA4bVi.js} +1 -1
  709. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-kqF4MDOG.js → blockDiagram-NRAW4CY4-pM0B-6NJ.js} +1 -1
  710. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-8uSRIODv.js → c4Diagram-UCG6FXSJ-m2tuCNVq.js} +1 -1
  711. ksadk/server/static/assets/channel-fySsnkft.js +1 -0
  712. ksadk/server/static/assets/chunk-2Q5K7J3B-BheGxKRQ.js +1 -0
  713. ksadk/server/static/assets/{chunk-5VM5RSS4-DkhehZDr.js → chunk-5VM5RSS4-GJHDr9Ww.js} +1 -1
  714. ksadk/server/static/assets/{chunk-F27PBJKO-BdXhtPe9.js → chunk-F27PBJKO-CbAN45AV.js} +1 -1
  715. ksadk/server/static/assets/{chunk-G27WJ6UU-DPTpvpwi.js → chunk-G27WJ6UU-D5ngbbzF.js} +1 -1
  716. ksadk/server/static/assets/{chunk-JWPE2WC7-Pqoh38el.js → chunk-JWPE2WC7-Cc5IwuYC.js} +1 -1
  717. ksadk/server/static/assets/{chunk-LCL6LL3I-DeU00qC-.js → chunk-LCL6LL3I-CprgDDdJ.js} +1 -1
  718. ksadk/server/static/assets/{chunk-POPQ4Y6H-CzxScFkr.js → chunk-POPQ4Y6H-CDZhSy82.js} +1 -1
  719. ksadk/server/static/assets/{chunk-RHFEMEQ7-DpqMx-ux.js → chunk-RHFEMEQ7-CZchUNro.js} +1 -1
  720. ksadk/server/static/assets/{chunk-SVP7TREG-C6t0SypQ.js → chunk-SVP7TREG-BVruqk6T.js} +1 -1
  721. ksadk/server/static/assets/{chunk-XXDRQBXY-DVaeafZk.js → chunk-XXDRQBXY-4ld9SxPN.js} +1 -1
  722. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DSfLtNYm.js +1 -0
  723. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DSfLtNYm.js +1 -0
  724. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-Bf9D3tzJ.js → cose-bilkent-JH36ORCC-Dmyyk_Vp.js} +1 -1
  725. ksadk/server/static/assets/cynefin-OW5HDTMX-PFWIGtvA.js +1 -0
  726. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-B9cY3iTz.js → cynefinDiagram-5FMLGOSQ-BIyq3EJb.js} +1 -1
  727. ksadk/server/static/assets/{dagre-3AP2YEHR-CSwlx3CB.js → dagre-3AP2YEHR-eBw08Qdk.js} +1 -1
  728. ksadk/server/static/assets/{dagre-UBpgon5q.js → dagre-DfvnEf45.js} +1 -1
  729. ksadk/server/static/assets/{diagram-S7CK7UJ4-C9akhN9a.js → diagram-S7CK7UJ4-CUSrE3Mg.js} +1 -1
  730. ksadk/server/static/assets/{diagram-UQ7AKVKN-CgedhTPI.js → diagram-UQ7AKVKN-Dq5Zw2gy.js} +1 -1
  731. ksadk/server/static/assets/{diagram-VSXAHHWV-Cjucz5BY.js → diagram-VSXAHHWV-DyUHfNwT.js} +1 -1
  732. ksadk/server/static/assets/{diagram-VX7I27RA-Dd4Vleyn.js → diagram-VX7I27RA-CREmM89O.js} +1 -1
  733. ksadk/server/static/assets/{diagram-Z3DM3KII-CZ2jGtYW.js → diagram-Z3DM3KII-Dw9zhHUK.js} +1 -1
  734. ksadk/server/static/assets/{dist-Bj730Ib4.js → dist-0uJ4tdx6.js} +1 -1
  735. ksadk/server/static/assets/{dist-BnaTiyzN.js → dist-AEv-vXf-.js} +1 -1
  736. ksadk/server/static/assets/{dist-BgV_owcB.js → dist-B49GzZDb.js} +1 -1
  737. ksadk/server/static/assets/{dist-D_ctSS2i.js → dist-B8Myiet9.js} +1 -1
  738. ksadk/server/static/assets/{dist-ufY3F5p6.js → dist-BBsYarrI.js} +2 -2
  739. ksadk/server/static/assets/{dist-ClYUxfeK.js → dist-BQMrUwdI.js} +1 -1
  740. ksadk/server/static/assets/{dist-CFzsn6BG.js → dist-BX_-FENW.js} +1 -1
  741. ksadk/server/static/assets/{dist-B3FR1SKK.js → dist-CD4L6ymH.js} +1 -1
  742. ksadk/server/static/assets/{dist-Cf125P_m.js → dist-CHpW1BHj.js} +1 -1
  743. ksadk/server/static/assets/{dist-DVCOWtha.js → dist-CVPau3tn.js} +1 -1
  744. ksadk/server/static/assets/{dist-DFD6Qa6T.js → dist-C_qdxcSH.js} +1 -1
  745. ksadk/server/static/assets/{dist-BIr4DSRq.js → dist-Co68Apq4.js} +1 -1
  746. ksadk/server/static/assets/{dist-DiixqL0J.js → dist-Cp2PaOMY.js} +1 -1
  747. ksadk/server/static/assets/{dist-fBO2v5Kt.js → dist-CuR5Bgme.js} +1 -1
  748. ksadk/server/static/assets/{dist-DoVSwoDb.js → dist-DDSyLEOX.js} +1 -1
  749. ksadk/server/static/assets/{dist-C5_ZAZsG.js → dist-DUxO0R99.js} +1 -1
  750. ksadk/server/static/assets/{dist-C1NMAY5a.js → dist-QzbGrED_.js} +1 -1
  751. ksadk/server/static/assets/dist-bupkyEBZ.js +1 -0
  752. ksadk/server/static/assets/{dist-DvFK7p5S.js → dist-cxTGfdqx.js} +1 -1
  753. ksadk/server/static/assets/{dist-CB9iJrvg.js → dist-hL5p1til.js} +1 -1
  754. ksadk/server/static/assets/{dist-btbmmX5O.js → dist-lOy23y43.js} +1 -1
  755. ksadk/server/static/assets/{dist-QfkEHOlb.js → dist-pq-nD33R.js} +1 -1
  756. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Ci8NqqZu.js → ebnfDiagram-PWID7BFC-BS5LdNoR.js} +1 -1
  757. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CCIOhLZG.js → erDiagram-SSCWMZ5O-Bv1QtiY-.js} +1 -1
  758. ksadk/server/static/assets/eventmodeling-NTZA5JFV-DsM4upQX.js +1 -0
  759. ksadk/server/static/assets/flowDiagram-A5DVABFB-D5NA16k9.js +1 -0
  760. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js → ganttDiagram-EL5Y4UJY-musi-e0G.js} +1 -1
  761. ksadk/server/static/assets/gitGraph-4MIJSDKK-DUCVz-ih.js +1 -0
  762. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js → gitGraphDiagram-WWUBYQGX-DH37EGkG.js} +1 -1
  763. ksadk/server/static/assets/index-CZdkAvsv.js +244 -0
  764. ksadk/server/static/assets/index-CvXdHgF3.css +2 -0
  765. ksadk/server/static/assets/info-A6RAGUB7-rw0ZNHZp.js +1 -0
  766. ksadk/server/static/assets/{infoDiagram-RXCK75RN-CO0rRTRA.js → infoDiagram-RXCK75RN-C1kEtv2y.js} +1 -1
  767. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CHiaedSS.js → ishikawaDiagram-5VMMS53U-BCNPyMka.js} +1 -1
  768. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-CHcCIB09.js → journeyDiagram-EYS64GPL--cDbKnjP.js} +1 -1
  769. ksadk/server/static/assets/{kanban-definition-3QL26DDD-CJ_ebBZf.js → kanban-definition-3QL26DDD-R1rAVw2f.js} +1 -1
  770. ksadk/server/static/assets/{katex-B4weu383.js → katex-BT-X-V7U.js} +1 -1
  771. ksadk/server/static/assets/{linear-V-MgYHW1.js → linear-DTR631iG.js} +1 -1
  772. ksadk/server/static/assets/{mermaid-parser.core-CBijEX_c.js → mermaid-parser.core-DfFzJhX8.js} +2 -2
  773. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-Bc-pQvpp.js → mindmap-definition-FBJOCRG2-D4by_rmk.js} +1 -1
  774. ksadk/server/static/assets/packet-AYTQ26CC-Ca4Hvki9.js +1 -0
  775. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-D7genGLl.js → pegDiagram-XKGWAZYB-xWXPEh0c.js} +1 -1
  776. ksadk/server/static/assets/pie-WAS4IAKB-hwiz6fbw.js +1 -0
  777. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-Bxj32zwD.js → pieDiagram-E7YTZNPT-BudBDlCI.js} +1 -1
  778. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BURv2mGh.js → quadrantDiagram-AXDQQJYC-DXZ0PCJF.js} +1 -1
  779. ksadk/server/static/assets/radar-RG4KPBEZ-BR1oZXLM.js +1 -0
  780. ksadk/server/static/assets/railroad-74A4TZTK-DfgEISfX.js +1 -0
  781. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-CWOC3rdk.js +1 -0
  782. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CiRvHCLY.js +1 -0
  783. ksadk/server/static/assets/railroad-peg-WCYAUIDC-DSDDyJ2f.js +1 -0
  784. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-CCsh3avW.js → railroadDiagram-O6MQD6OU-BdAYRYB8.js} +1 -1
  785. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-_FRRBKEd.js → requirementDiagram-EFPCY7ZU-CBBmaL70.js} +1 -1
  786. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-C-gr2o9M.js → sankeyDiagram-P5KCCOFB-Doc3rdwp.js} +1 -1
  787. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-D97NmfKg.js → sequenceDiagram-WJ2MYXX4-0J8R8hWW.js} +1 -1
  788. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DjrPC5FX.js → sizeCapture-X5ZJPWSS-CfFLlWsK.js} +1 -1
  789. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DzMNg1hh.js → stateDiagram-HBIQ2CUA-jBwkjtTy.js} +1 -1
  790. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-Cw1fPb5w.js +1 -0
  791. ksadk/server/static/assets/{swimlanes-XN3QIQJK-Cssf_CsU.js → swimlanes-XN3QIQJK-B0WxTQf8.js} +1 -1
  792. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-Cc3JMBAF.js +8 -0
  793. ksadk/server/static/assets/{timeline-definition-24CTP7MA-BWTHzyS1.js → timeline-definition-24CTP7MA-BfCT_75A.js} +1 -1
  794. ksadk/server/static/assets/treeView-Q6P3EWNA-C05SJHxo.js +1 -0
  795. ksadk/server/static/assets/treemap-WGGIJYW6-BqNLAhc3.js +1 -0
  796. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-BSKgJsmR.js → vennDiagram-4TSXK5OY-9gX1VMDC.js} +1 -1
  797. ksadk/server/static/assets/wardley-WFR3VGLG-DokNktqB.js +1 -0
  798. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-eflHNoaZ.js → wardleyDiagram-VM6X3IG4-sEs_BP6O.js} +1 -1
  799. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-eYqrQ-v4.js → xychartDiagram-S5SC5T6Z-Ll4jvUN9.js} +1 -1
  800. ksadk/server/static/index.html +2 -2
  801. ksadk/server/terminal_sessions.py +34 -2
  802. ksadk/sessions/__init__.py +8 -1
  803. ksadk/sessions/_checkpoint_resume_audit.py +44 -0
  804. ksadk/sessions/_in_memory_query.py +112 -0
  805. ksadk/sessions/_local_service_sync.py +157 -156
  806. ksadk/sessions/_local_state_sync.py +152 -0
  807. ksadk/sessions/_local_tables.py +2 -0
  808. ksadk/sessions/_postgres_checkpoint_read.py +323 -0
  809. ksadk/sessions/_postgres_checkpoint_stats.py +330 -0
  810. ksadk/sessions/_postgres_history_read.py +678 -0
  811. ksadk/sessions/_postgres_schema.py +44 -2
  812. ksadk/sessions/_postgres_tables.py +2 -0
  813. ksadk/sessions/_postgres_tool_receipts.py +169 -0
  814. ksadk/sessions/_resilient_read.py +630 -0
  815. ksadk/sessions/_tool_receipt_sync.py +119 -0
  816. ksadk/sessions/agent_identity.py +16 -0
  817. ksadk/sessions/base.py +278 -0
  818. ksadk/sessions/db_budget.py +332 -0
  819. ksadk/sessions/errors.py +12 -0
  820. ksadk/sessions/history_budget.py +36 -0
  821. ksadk/sessions/history_identity.py +27 -0
  822. ksadk/sessions/in_memory.py +376 -113
  823. ksadk/sessions/invocation_identity.py +235 -0
  824. ksadk/sessions/local_service.py +345 -0
  825. ksadk/sessions/postgres_service.py +515 -549
  826. ksadk/sessions/resilience.py +21 -14
  827. ksadk/sessions/resilient.py +611 -504
  828. ksadk/skills/__init__.py +26 -0
  829. ksadk/skills/events.py +464 -0
  830. ksadk/skills/loader.py +44 -2
  831. ksadk/skills/manifest_cache.py +263 -0
  832. ksadk/skills/mcp_server/__init__.py +0 -0
  833. ksadk/skills/mcp_server/_registry.py +33 -0
  834. ksadk/skills/mcp_server/_routing.py +26 -0
  835. ksadk/skills/mcp_server/_workspace_files.py +160 -0
  836. ksadk/skills/mcp_server/register.py +415 -0
  837. ksadk/skills/mcp_server/server.py +218 -0
  838. ksadk/skills/models.py +11 -0
  839. ksadk/skills/observability.py +132 -0
  840. ksadk/skills/package_store.py +75 -2
  841. ksadk/skills/runtime/agent.py +38 -5
  842. ksadk/skills/runtime/artifacts.py +87 -0
  843. ksadk/skills/runtime/backends/e2b.py +400 -56
  844. ksadk/skills/runtime/backends/local.py +621 -119
  845. ksadk/skills/runtime/base.py +78 -7
  846. ksadk/skills/runtime/executor.py +266 -1
  847. ksadk/skills/runtime/loader.py +108 -3
  848. ksadk/skills/runtime/request.py +18 -0
  849. ksadk/skills/service_client.py +6 -1
  850. ksadk/skills/tool_defs.py +108 -3
  851. ksadk/studio/a2a_bindings.py +407 -0
  852. ksadk/studio/a2a_orchestration.py +178 -0
  853. ksadk/studio/active_run_output.py +92 -0
  854. ksadk/studio/activity_records.py +542 -0
  855. ksadk/studio/agent_configuration.py +173 -0
  856. ksadk/studio/api.py +784 -419
  857. ksadk/studio/api_a2a_routes.py +93 -0
  858. ksadk/studio/api_catalog_routes.py +13 -0
  859. ksadk/studio/api_cloud_chat_routes.py +382 -0
  860. ksadk/studio/api_contracts.py +31 -2
  861. ksadk/studio/api_plugin_routes.py +39 -12
  862. ksadk/studio/api_resource_connections.py +79 -41
  863. ksadk/studio/attachment_store.py +14 -2
  864. ksadk/studio/authoring.py +12 -6
  865. ksadk/studio/authoring_coordinator.py +4 -2
  866. ksadk/studio/build_resolution.py +117 -0
  867. ksadk/studio/build_singleflight.py +37 -0
  868. ksadk/studio/builder.py +32 -2
  869. ksadk/studio/capabilities.py +31 -9
  870. ksadk/studio/channel_connections.py +333 -0
  871. ksadk/studio/cloud.py +113 -387
  872. ksadk/studio/cloud_gateways.py +424 -0
  873. ksadk/studio/cloud_shared_web.py +82 -2
  874. ksadk/studio/codex_agent_service.py +19 -2
  875. ksadk/studio/codex_builder.py +1 -1
  876. ksadk/studio/codex_manifest.py +5 -1
  877. ksadk/studio/codex_provider_build.py +65 -0
  878. ksadk/studio/codex_run.py +6 -1
  879. ksadk/studio/compiler.py +112 -6
  880. ksadk/studio/configuration.py +182 -0
  881. ksadk/studio/contract_base.py +19 -0
  882. ksadk/studio/contracts.py +260 -202
  883. ksadk/studio/dsh_application.py +183 -27
  884. ksadk/studio/dsh_capability_service.py +302 -189
  885. ksadk/studio/dsh_lifecycle.py +58 -0
  886. ksadk/studio/dsh_mcp_transport.py +191 -0
  887. ksadk/studio/dsh_provider_registration.py +55 -16
  888. ksadk/studio/entry.py +53 -0
  889. ksadk/studio/event_store.py +53 -5
  890. ksadk/studio/execution_host.py +598 -0
  891. ksadk/studio/framework_run.py +50 -10
  892. ksadk/studio/hosted_kernel.py +1 -1
  893. ksadk/studio/interaction_submission.py +265 -0
  894. ksadk/studio/kernel_registry.py +429 -0
  895. ksadk/studio/kernel_sqlite_migration.py +181 -0
  896. ksadk/studio/lifecycle_status.py +43 -0
  897. ksadk/studio/model_buffered_wire.py +227 -0
  898. ksadk/studio/model_chat_tools.py +143 -0
  899. ksadk/studio/model_client.py +1939 -345
  900. ksadk/studio/model_content_stream.py +129 -0
  901. ksadk/studio/model_credentials.py +196 -0
  902. ksadk/studio/model_profile_service.py +89 -40
  903. ksadk/studio/model_request_projection.py +284 -0
  904. ksadk/studio/model_responses_content.py +296 -0
  905. ksadk/studio/model_usage.py +109 -0
  906. ksadk/studio/model_wire_failure.py +110 -0
  907. ksadk/studio/model_wire_identity.py +138 -0
  908. ksadk/studio/model_wire_snapshot.py +45 -0
  909. ksadk/studio/model_wire_tools.py +283 -0
  910. ksadk/studio/native_acceptance.py +68 -0
  911. ksadk/studio/native_approval.py +111 -0
  912. ksadk/studio/native_browser_port.py +861 -0
  913. ksadk/studio/native_child_mcp.py +87 -0
  914. ksadk/studio/native_child_publication.py +68 -0
  915. ksadk/studio/native_child_skills.py +72 -0
  916. ksadk/studio/native_child_workspace.py +176 -0
  917. ksadk/studio/native_command_policy.py +53 -0
  918. ksadk/studio/native_context_port.py +326 -0
  919. ksadk/studio/native_context_registration.py +54 -0
  920. ksadk/studio/native_document_input.py +88 -0
  921. ksadk/studio/native_documents.py +172 -0
  922. ksadk/studio/native_final_shape.py +852 -0
  923. ksadk/studio/native_gateway_stream.py +69 -0
  924. ksadk/studio/native_hook_port.py +145 -0
  925. ksadk/studio/native_hook_registration.py +70 -0
  926. ksadk/studio/native_inventory_disclosure.py +223 -0
  927. ksadk/studio/native_kernel_admission.py +84 -0
  928. ksadk/studio/native_language_diagnostics.py +320 -0
  929. ksadk/studio/native_mcp_disclosure.py +198 -0
  930. ksadk/studio/native_mcp_tool_port.py +219 -0
  931. ksadk/studio/native_memory_acceptance.py +362 -0
  932. ksadk/studio/native_memory_context.py +266 -0
  933. ksadk/studio/native_memory_flush.py +174 -0
  934. ksadk/studio/native_memory_sources.py +80 -0
  935. ksadk/studio/native_memory_tool_port.py +360 -0
  936. ksadk/studio/native_memory_turn.py +183 -0
  937. ksadk/studio/native_model_port.py +765 -0
  938. ksadk/studio/native_model_recovery.py +126 -0
  939. ksadk/studio/native_options.py +75 -0
  940. ksadk/studio/native_output_fields.py +58 -0
  941. ksadk/studio/native_planning.py +156 -0
  942. ksadk/studio/native_product.py +988 -0
  943. ksadk/studio/native_read_budget.py +426 -0
  944. ksadk/studio/native_recovery.py +171 -0
  945. ksadk/studio/native_scope.py +35 -0
  946. ksadk/studio/native_session_context_port.py +141 -0
  947. ksadk/studio/native_session_engine.py +14 -0
  948. ksadk/studio/native_skill_source.py +74 -0
  949. ksadk/studio/native_subagent_port.py +700 -0
  950. ksadk/studio/native_terminal_recovery.py +95 -0
  951. ksadk/studio/native_test_action.py +610 -0
  952. ksadk/studio/native_tool_port.py +477 -0
  953. ksadk/studio/native_user_input.py +60 -0
  954. ksadk/studio/native_verification_presentation.py +65 -0
  955. ksadk/studio/native_workspace_diagnostics.py +183 -0
  956. ksadk/studio/native_workspace_port.py +43 -0
  957. ksadk/studio/operations.py +34 -9
  958. ksadk/studio/plugin_composition.py +39 -12
  959. ksadk/studio/plugin_kernel_adapter.py +89 -0
  960. ksadk/studio/plugin_lifecycle.py +80 -0
  961. ksadk/studio/plugin_native_activation.py +163 -0
  962. ksadk/studio/plugin_runtime.py +832 -99
  963. ksadk/studio/plugin_runtime_admission.py +57 -0
  964. ksadk/studio/presentation.py +92 -0
  965. ksadk/studio/provider_recovery.py +59 -0
  966. ksadk/studio/public_output_store.py +69 -0
  967. ksadk/studio/recovery_page.py +70 -0
  968. ksadk/studio/resource_authority.py +69 -34
  969. ksadk/studio/resource_catalog.py +14 -12
  970. ksadk/studio/run_activity.py +848 -0
  971. ksadk/studio/run_controls.py +185 -0
  972. ksadk/studio/run_documents.py +127 -0
  973. ksadk/studio/run_service.py +1220 -335
  974. ksadk/studio/run_submission_receipts.py +68 -0
  975. ksadk/studio/runtime_catalog.py +73 -11
  976. ksadk/studio/runtime_prewarm.py +22 -0
  977. ksadk/studio/runtime_source.py +1 -1
  978. ksadk/studio/scheduler_assistant.py +4 -1
  979. ksadk/studio/scheduler_runtime.py +32 -289
  980. ksadk/studio/service.py +615 -246
  981. ksadk/studio/service_settings.py +229 -0
  982. ksadk/studio/shared_web.py +518 -181
  983. ksadk/studio/shared_web_response_events.py +180 -0
  984. ksadk/studio/shared_web_run_state.py +133 -0
  985. ksadk/studio/skill_discovery.py +305 -3
  986. ksadk/studio/static/assets/ChannelsPage-xX5HlMId.js +8 -0
  987. ksadk/studio/static/assets/CodeBlock-DMIf4h33-CkufcPYo.js +44 -0
  988. ksadk/studio/static/assets/ExecutionTree-v3HexvPo-Bk8wzGSy.js +1 -0
  989. ksadk/studio/static/assets/MathMessageMarkdown-BesSeCYl-DYG1Wzbx.js +8 -0
  990. ksadk/studio/static/assets/MermaidBlock-H_0qzQDf-BdXtxug_.js +11 -0
  991. ksadk/studio/static/assets/MessageMarkdown-CwMTvgFj-BeyLyQHu.js +59 -0
  992. ksadk/studio/static/assets/PrismRenderer-5pK6tUdb.js +3 -0
  993. ksadk/studio/static/assets/TeamsPage-CCaaGaVp.js +3 -0
  994. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-Bnb1O3tA.js +1 -0
  995. ksadk/studio/static/assets/architecture-7GRP2DOG-BMOPAkUC.js +1 -0
  996. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-5Zn1gqJv.js +36 -0
  997. ksadk/studio/static/assets/{blockDiagram-I7D4REHJ-CFmPl1de.js → blockDiagram-I7D4REHJ-CLB4L11u.js} +6 -6
  998. ksadk/studio/static/assets/{c4Diagram-7LVT6UL2-BRrGu8qt.js → c4Diagram-7LVT6UL2-BOma_Z_F.js} +7 -7
  999. ksadk/studio/static/assets/channel-r8itPEik.js +1 -0
  1000. ksadk/studio/static/assets/chunk-2E4U76K2-BFf_huql.js +2 -0
  1001. ksadk/studio/static/assets/chunk-2ZTRR5NV-C2qZJila.js +2 -0
  1002. ksadk/studio/static/assets/chunk-3Z5EZCMW-DMniOlPd.js +1 -0
  1003. ksadk/studio/static/assets/{chunk-4HAMMTFA-D220vUtq.js → chunk-4HAMMTFA-DVtDP4rm.js} +7 -7
  1004. ksadk/studio/static/assets/chunk-5V3GS4D5-i-ZDOEnP.js +1 -0
  1005. ksadk/studio/static/assets/chunk-6AZGARVD-BB6FqMl-.js +1 -0
  1006. ksadk/studio/static/assets/chunk-6EIED4P4-DdUJkP0f.js +1 -0
  1007. ksadk/studio/static/assets/chunk-6K3QC6MW-CqVsVn-y.js +1 -0
  1008. ksadk/studio/static/assets/chunk-6TQVIW2G-DKlLbNIP.js +1 -0
  1009. ksadk/studio/static/assets/chunk-747NJXEK-BFkZPlab.js +2 -0
  1010. ksadk/studio/static/assets/chunk-75Z2AOVW-BZNhM4vB.js +2 -0
  1011. ksadk/studio/static/assets/chunk-CLGD4ZFX-D-GTtyKs.js +1 -0
  1012. ksadk/studio/static/assets/{chunk-DU6HZSFF-C4DtVpCu.js → chunk-DU6HZSFF-CpEZCUgg.js} +1 -1
  1013. ksadk/studio/static/assets/chunk-F27PBJKO-D7pvKf0C.js +1 -0
  1014. ksadk/studio/static/assets/{chunk-GMAD6QVW-DiQA-u2N.js → chunk-GMAD6QVW-DE_8H717.js} +6 -6
  1015. ksadk/studio/static/assets/chunk-GVQU2GXP-BfEB0lNv.js +1 -0
  1016. ksadk/studio/static/assets/chunk-I5DQTOEV-Hm2LfiYI.js +1 -0
  1017. ksadk/studio/static/assets/chunk-ICYGCRZG-749o-pGJ.js +1 -0
  1018. ksadk/studio/static/assets/chunk-IH6LHLGP-CC6I9F3i.js +1 -0
  1019. ksadk/studio/static/assets/{chunk-IMKFNOWR-BSlbjT_b.js → chunk-IMKFNOWR-D38axYOR.js} +5 -5
  1020. ksadk/studio/static/assets/chunk-KI3K4JFJ-Rma-0k_M.js +1 -0
  1021. ksadk/studio/static/assets/chunk-L3NEJ4N5-Dq5xn7aL.js +1 -0
  1022. ksadk/studio/static/assets/chunk-LNGE3PJU-DWpGwHrW.js +34 -0
  1023. ksadk/studio/static/assets/{chunk-OSK3NFVY-M2m6G3j4.js → chunk-OSK3NFVY-DiCQjx9b.js} +5 -5
  1024. ksadk/studio/static/assets/chunk-OUJLGHUK-D0j2JRSg.js +2 -0
  1025. ksadk/studio/static/assets/{chunk-P2QGCYS3-DezaQxiK.js → chunk-P2QGCYS3-VdhKmfYq.js} +1 -1
  1026. ksadk/studio/static/assets/chunk-POPQ4Y6H-C1_rzO5M.js +1 -0
  1027. ksadk/studio/static/assets/chunk-PWAF6VOD-B45HvflI.js +1 -0
  1028. ksadk/studio/static/assets/{chunk-SHT3W25Y-DAyIVp5H.js → chunk-SHT3W25Y-DsCFnRVE.js} +9 -9
  1029. ksadk/studio/static/assets/{chunk-SVP7TREG-DulomOrS.js → chunk-SVP7TREG-DljApgRX.js} +1 -1
  1030. ksadk/studio/static/assets/{chunk-TICWLB2K-bHJYoflj.js → chunk-TICWLB2K-DWqRtyqa.js} +6 -6
  1031. ksadk/studio/static/assets/chunk-TLUHSLCS-DUeGgnD5.js +2 -0
  1032. ksadk/studio/static/assets/chunk-UY3FDG6J-CnmaAkG5.js +1 -0
  1033. ksadk/studio/static/assets/chunk-XHIXRSVI-BFQ6B8BE.js +1 -0
  1034. ksadk/studio/static/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
  1035. ksadk/studio/static/assets/classDiagram-ZZMXUADV-DjeMNJmu.js +1 -0
  1036. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-DjeMNJmu.js +1 -0
  1037. ksadk/studio/static/assets/clsx-DB0hHKMi.js +1 -0
  1038. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-om8AY0Mc.js +1 -0
  1039. ksadk/studio/static/assets/createLucideIcon-DR0LGTP5.js +1 -0
  1040. ksadk/studio/static/assets/cynefin-OW5HDTMX-7tP7QfM3.js +1 -0
  1041. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-6BrmK52S.js +62 -0
  1042. ksadk/studio/static/assets/dagre-GXQ25YYZ-buZBRlwz.js +4 -0
  1043. ksadk/studio/static/assets/{diagram-S7CK7UJ4-0BZ98mya.js → diagram-S7CK7UJ4-C6aH78c4.js} +3 -3
  1044. ksadk/studio/static/assets/diagram-UQ7AKVKN-DY_tQ6C_.js +41 -0
  1045. ksadk/studio/static/assets/diagram-VSXAHHWV-DX9p5cQT.js +3 -0
  1046. ksadk/studio/static/assets/diagram-VX7I27RA-DB2WSH8X.js +24 -0
  1047. ksadk/studio/static/assets/diagram-Z3DM3KII-Ce1BJwHE.js +24 -0
  1048. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-Daukxwqf.js +1 -0
  1049. ksadk/studio/static/assets/{erDiagram-RLTQ6QDP-DLGry2Ap.js → erDiagram-RLTQ6QDP-CGthTMmJ.js} +6 -6
  1050. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-BR2FzK4R.js +1 -0
  1051. ksadk/studio/static/assets/flowDiagram-HODETNUW-CZ1tEenp.js +1 -0
  1052. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BfoAZW9X.js +292 -0
  1053. ksadk/studio/static/assets/gitGraph-4MIJSDKK-DYlXv_yJ.js +1 -0
  1054. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-S985OIJF.js +106 -0
  1055. ksadk/studio/static/assets/iconfont-4HN3C9Pg.woff2 +0 -0
  1056. ksadk/studio/static/assets/index-C7DNDik2.css +2 -0
  1057. ksadk/studio/static/assets/index-Cy68gTlH.js +265 -0
  1058. ksadk/studio/static/assets/index.dom-BQenBtFm.js +1 -0
  1059. ksadk/studio/static/assets/info-A6RAGUB7-BlU-8_xu.js +1 -0
  1060. ksadk/studio/static/assets/infoDiagram-27XIBGKW-CO3W8tFn.js +2 -0
  1061. ksadk/studio/static/assets/{ishikawaDiagram-5VMMS53U-CljI2wyf.js → ishikawaDiagram-5VMMS53U-BUGEl8cO.js} +2 -2
  1062. ksadk/studio/static/assets/{journeyDiagram-3NMN7TZE-D50Fo2sL.js → journeyDiagram-3NMN7TZE-Ch2ZYxvr.js} +6 -6
  1063. ksadk/studio/static/assets/{kanban-definition-UXKFOSKX-DimfOTam.js → kanban-definition-UXKFOSKX-Da-Fp4vC.js} +3 -3
  1064. ksadk/studio/static/assets/kingsoft-cloud-BOcLiQ3e.ico +0 -0
  1065. ksadk/studio/static/assets/{line-CX5BOOUP.js → line-BDaeq300.js} +1 -1
  1066. ksadk/studio/static/assets/linear-DmucvK78.js +1 -0
  1067. ksadk/studio/static/assets/mermaid-parser.core-Cj5mYdBi.js +4 -0
  1068. ksadk/studio/static/assets/{mindmap-definition-YA3MSWOX-Bizzqy5R.js → mindmap-definition-YA3MSWOX-CvlsVQ38.js} +1 -1
  1069. ksadk/studio/static/assets/packet-AYTQ26CC-BSJEH9Lb.js +1 -0
  1070. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-BuHuNgT5.js +1 -0
  1071. ksadk/studio/static/assets/pie-WAS4IAKB-qxv01Y8W.js +1 -0
  1072. ksadk/studio/static/assets/{pieDiagram-E7YTZNPT-B9mrFSDF.js → pieDiagram-E7YTZNPT-DlrWiSOv.js} +1 -1
  1073. ksadk/studio/static/assets/preload-helper-CO68xz6u.js +1 -0
  1074. ksadk/studio/static/assets/presentation-yYw7xK60-BmcZriri.js +1 -0
  1075. ksadk/studio/static/assets/{quadrantDiagram-AXDQQJYC-NzUfCbMR.js → quadrantDiagram-AXDQQJYC-BA3hpUZM.js} +6 -6
  1076. ksadk/studio/static/assets/radar-RG4KPBEZ-B6h6pWOs.js +1 -0
  1077. ksadk/studio/static/assets/railroad-74A4TZTK-CGtTWdGc.js +1 -0
  1078. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-Cq7y22IA.js +1 -0
  1079. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-V0aQVv9m.js +1 -0
  1080. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-BQiIsX_p.js +1 -0
  1081. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-BxpAazym.js +1 -0
  1082. ksadk/studio/static/assets/{requirementDiagram-BXWQKSXE-BF3d103U.js → requirementDiagram-BXWQKSXE-E-Ge0FcV.js} +1 -1
  1083. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-CA6YKhQ3.js +40 -0
  1084. ksadk/studio/static/assets/{sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js → sequenceDiagram-WJ2MYXX4-CcElXGg4.js} +9 -9
  1085. ksadk/studio/static/assets/src-B6xuSHsQ.js +1 -0
  1086. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DdXZOFqY.js +1 -0
  1087. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-CJbOM-QK.js +1 -0
  1088. ksadk/studio/static/assets/swimlanes-42K2YHIH-NtgEEHLY.js +1 -0
  1089. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-D-AVlW8B.js +8 -0
  1090. ksadk/studio/static/assets/{timeline-definition-24CTP7MA-DxmSSjRB.js → timeline-definition-24CTP7MA-CIuYhNy3.js} +7 -7
  1091. ksadk/studio/static/assets/treeView-Q6P3EWNA-BTTYcvrF.js +1 -0
  1092. ksadk/studio/static/assets/treemap-WGGIJYW6-Cg7tyfH8.js +1 -0
  1093. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-7HbApbrv.js +34 -0
  1094. ksadk/studio/static/assets/wardley-WFR3VGLG-C6N1rULY.js +1 -0
  1095. ksadk/studio/static/assets/{wardleyDiagram-VM6X3IG4-Ba1AOWoe.js → wardleyDiagram-VM6X3IG4-CMJiaedy.js} +1 -1
  1096. ksadk/studio/static/assets/{xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js → xychartDiagram-S5SC5T6Z-BdgtMvW2.js} +6 -6
  1097. ksadk/studio/static/index.html +8 -2
  1098. ksadk/studio/teams_catalog.py +166 -0
  1099. ksadk/studio/teams_installation.py +217 -0
  1100. ksadk/studio/teams_node.py +549 -0
  1101. ksadk/studio/teams_node_factory.py +558 -0
  1102. ksadk/studio/teams_node_runner.py +72 -0
  1103. ksadk/studio/teams_node_v1.py +935 -0
  1104. ksadk/studio/teams_remote.py +496 -0
  1105. ksadk/studio/templates.py +41 -19
  1106. ksadk/studio/validator.py +13 -0
  1107. ksadk/studio/workspace.py +19 -4
  1108. ksadk/studio/workspace_plugins.py +138 -0
  1109. ksadk/studio/workspace_registry.py +286 -0
  1110. ksadk/tools/a2a_policy.py +5 -0
  1111. ksadk/tools/artifact_observation.py +53 -0
  1112. ksadk/tools/captured_source_artifact.py +68 -0
  1113. ksadk/tools/schema.py +34 -0
  1114. ksadk/toolsets/__init__.py +93 -88
  1115. ksadk/toolsets/a2a.py +89 -89
  1116. ksadk/toolsets/sandbox.py +377 -6
  1117. ksadk/toolsets/skill_management.py +315 -0
  1118. ksadk/toolsets/skills.py +446 -378
  1119. ksadk/toolsets/tool_selection.py +94 -0
  1120. ksadk/toolsets/workspace.py +344 -326
  1121. ksadk/toolsets/workspace_editing.py +291 -0
  1122. ksadk/toolsets/workspace_identity.py +15 -0
  1123. ksadk/toolsets/workspace_model_observation.py +104 -0
  1124. ksadk/toolsets/workspace_mutation.py +75 -0
  1125. ksadk/toolsets/workspace_read_budget.py +216 -0
  1126. ksadk/toolsets/workspace_search.py +192 -0
  1127. ksadk/toolsets/workspace_search_process.py +129 -0
  1128. ksadk/toolsets/workspace_state.py +6 -0
  1129. ksadk/version.py +1 -1
  1130. ksadk_runtime_common/http_headers.py +18 -0
  1131. ksadk_runtime_common/memory_backend/providers/lancedb.py +56 -2
  1132. ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -148
  1133. ksadk_runtime_common/workspace_files/router.py +28 -14
  1134. agentengine_sdk_python-0.8.4.dist-info/RECORD +0 -1070
  1135. ksadk/server/static/assets/MathMessageMarkdown-DbdW5A4_.js +0 -8
  1136. ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +0 -1
  1137. ksadk/server/static/assets/channel-CF5Up3hQ.js +0 -1
  1138. ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +0 -1
  1139. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +0 -1
  1140. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +0 -1
  1141. ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +0 -1
  1142. ksadk/server/static/assets/dist-B2_CVgKv.js +0 -1
  1143. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +0 -1
  1144. ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +0 -1
  1145. ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +0 -1
  1146. ksadk/server/static/assets/index-DcTML1Up.css +0 -2
  1147. ksadk/server/static/assets/index-Dh2XHqPK.js +0 -244
  1148. ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +0 -1
  1149. ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +0 -1
  1150. ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +0 -1
  1151. ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +0 -1
  1152. ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +0 -1
  1153. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +0 -1
  1154. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +0 -1
  1155. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +0 -1
  1156. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +0 -1
  1157. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +0 -8
  1158. ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +0 -1
  1159. ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +0 -1
  1160. ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +0 -1
  1161. ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +0 -41
  1162. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +0 -8
  1163. ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +0 -44
  1164. ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +0 -3
  1165. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +0 -1
  1166. ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +0 -1
  1167. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +0 -36
  1168. ksadk/studio/static/assets/channel-BqO-gtEw.js +0 -1
  1169. ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +0 -2
  1170. ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +0 -1
  1171. ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +0 -1
  1172. ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +0 -1
  1173. ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +0 -1
  1174. ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +0 -1
  1175. ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +0 -1
  1176. ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +0 -1
  1177. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +0 -1
  1178. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +0 -1
  1179. ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +0 -1
  1180. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +0 -62
  1181. ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +0 -4
  1182. ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +0 -41
  1183. ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +0 -3
  1184. ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +0 -24
  1185. ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +0 -24
  1186. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +0 -1
  1187. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +0 -1
  1188. ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +0 -1
  1189. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +0 -292
  1190. ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +0 -1
  1191. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +0 -106
  1192. ksadk/studio/static/assets/index-CeHL9ARV.css +0 -2
  1193. ksadk/studio/static/assets/index-D9QEcVpL.js +0 -320
  1194. ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +0 -1
  1195. ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +0 -2
  1196. ksadk/studio/static/assets/linear-BCxN9JLv.js +0 -1
  1197. ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +0 -7
  1198. ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +0 -1
  1199. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +0 -1
  1200. ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +0 -1
  1201. ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +0 -1
  1202. ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +0 -1
  1203. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +0 -1
  1204. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +0 -1
  1205. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +0 -1
  1206. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +0 -1
  1207. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +0 -40
  1208. ksadk/studio/static/assets/src-SFn9St9H.js +0 -1
  1209. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +0 -1
  1210. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +0 -1
  1211. ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +0 -1
  1212. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +0 -8
  1213. ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +0 -1
  1214. ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +0 -1
  1215. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +0 -34
  1216. ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +0 -1
  1217. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/WHEEL +0 -0
  1218. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/entry_points.txt +0 -0
  1219. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/licenses/LICENSE +0 -0
  1220. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.6.dist-info}/top_level.txt +0 -0
  1221. /ksadk/studio/static/assets/{MathMessageMarkdown-CBcDrAw--BEOyPC3w.css → MathMessageMarkdown-BesSeCYl-BEOyPC3w.css} +0 -0
ksadk/studio/service.py CHANGED
@@ -3,10 +3,12 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import asyncio
6
+ import copy
6
7
  import hashlib
7
8
  import json
8
9
  import logging
9
10
  import os
11
+ import time
10
12
  import zipfile
11
13
  from collections.abc import AsyncIterator, Awaitable, Mapping, Sequence
12
14
  from contextlib import asynccontextmanager
@@ -18,6 +20,7 @@ from uuid import uuid4
18
20
 
19
21
  from ksadk.api import AgentEngineClient
20
22
  from ksadk.conversations.contracts import ConversationCapability, ConversationSurface
23
+ from ksadk.conversations.model_context import supports_native_image_input
21
24
  from ksadk.evaluation import (
22
25
  EvaluationConfig as PublicEvaluationConfig,
23
26
  )
@@ -42,15 +45,29 @@ from ksadk.evaluation.studio_build_adapter import (
42
45
  StudioBuildTargetError,
43
46
  )
44
47
  from ksadk.events.store import RuntimeEventStore
48
+ from ksadk.harness.diagnostic_adapters.contracts import LanguageServerProfile
49
+ from ksadk.harness.native.delivery_review_contract import DeliveryReviewPolicy
50
+ from ksadk.harness.native.hook_executor import HookAuthorizer
51
+ from ksadk.harness.native.ports import ChildRecoveryPolicy
52
+ from ksadk.model_gateway import ModelGatewayClient
45
53
  from ksadk.observability.session_log import SessionLogError, export_session_log
46
54
  from ksadk.observability.trajectory import encode_sse, project_trajectory_event
47
55
  from ksadk.plugins.bundle_security import BundleSecurityError
48
56
  from ksadk.plugins.contracts import PluginManifest
57
+ from ksadk.plugins.providers.harness import (
58
+ HarnessEngineSelector,
59
+ HarnessNativeAdapterBuilder,
60
+ )
49
61
  from ksadk.plugins.providers.legacy import LegacyHarnessSource
50
62
  from ksadk.plugins.providers.legacy_catalog import (
51
63
  KSADK_HARNESS_AGENT_PROVIDER_PLUGIN_ID,
52
64
  )
53
- from ksadk.runtime import RuntimeExecutor, build_default_runtime_registry
65
+ from ksadk.runtime import (
66
+ RuntimeAdapter,
67
+ RuntimeExecutor,
68
+ RuntimeLaunchContext,
69
+ build_default_runtime_registry,
70
+ )
54
71
  from ksadk.scheduler.contracts import (
55
72
  ScheduleCommandTemplate,
56
73
  ScheduledTask,
@@ -58,6 +75,7 @@ from ksadk.scheduler.contracts import (
58
75
  ScheduleSpec,
59
76
  )
60
77
  from ksadk.sessions.local_service import LocalSessionService
78
+ from ksadk.studio.a2a_bindings import A2ACatalogService
61
79
  from ksadk.studio.agent_avatar_assets import AgentAvatarAssetStore
62
80
  from ksadk.studio.agent_lifecycle import delete_framework_agent
63
81
  from ksadk.studio.attachment_store import ConversationAttachmentStore
@@ -76,9 +94,6 @@ from ksadk.studio.codex_builder import (
76
94
  CodexBuildRepository,
77
95
  CodexStudioBuilder,
78
96
  RuntimeInspector,
79
- current_proxy_mode,
80
- normalize_proxy_mode,
81
- proxy_mode_env_value,
82
97
  )
83
98
  from ksadk.studio.codex_manifest import (
84
99
  CodexAgentManifest,
@@ -88,6 +103,7 @@ from ksadk.studio.codex_plugin_store import CodexPluginSnapshotStore
88
103
  from ksadk.studio.codex_provider_build import CodexProviderBuildManager
89
104
  from ksadk.studio.codex_run import CodexRunSpecResolver
90
105
  from ksadk.studio.compiler import AgentCompiler
106
+ from ksadk.studio.configuration import WorkspaceConfiguration
91
107
  from ksadk.studio.contracts import (
92
108
  AgentAppearance,
93
109
  AgentBindings,
@@ -102,8 +118,11 @@ from ksadk.studio.contracts import (
102
118
  DiagnosticSeverity,
103
119
  Operation,
104
120
  OperationKind,
121
+ OperationStatus,
122
+ RemoteAgentBinding,
105
123
  RunEvent,
106
124
  RunStatus,
125
+ RunSubmissionRef,
107
126
  RuntimeRef,
108
127
  ToolContract,
109
128
  )
@@ -120,10 +139,18 @@ from ksadk.studio.framework_run import FrameworkRunSpecResolver
120
139
  from ksadk.studio.mcp_runtime import MCPRuntimeAdapter
121
140
  from ksadk.studio.model_client import CredentialResolver, OpenAICompatibleModelClient
122
141
  from ksadk.studio.model_profile_service import test_model_profile_connection
142
+ from ksadk.studio.native_acceptance import StudioNativeAcceptanceExtension
143
+ from ksadk.studio.native_context_registration import StudioNativeContextRegistration
144
+ from ksadk.studio.native_hook_registration import (
145
+ StudioNativeHookRegistration,
146
+ validate_hook_authorization_policy,
147
+ )
148
+ from ksadk.studio.native_model_recovery import StudioModelTakeoverDeclaration
149
+ from ksadk.studio.native_options import validate_native_options
123
150
  from ksadk.studio.operations import OperationManager
124
151
  from ksadk.studio.plugin_composition import StudioPluginCompositionCompiler
125
152
  from ksadk.studio.plugin_runtime import StudioPluginRuntime
126
- from ksadk.studio.repository import AgentDraftRepository, BuildRepository, load_yaml_file
153
+ from ksadk.studio.repository import AgentDraftRepository, BuildRepository
127
154
  from ksadk.studio.resource_authority import (
128
155
  ResourceAuthorityPolicy,
129
156
  SignedKnowledgeResourceAuthority,
@@ -143,15 +170,18 @@ from ksadk.studio.scheduler_runtime import (
143
170
  StudioSchedulerRuntimeError,
144
171
  )
145
172
  from ksadk.studio.scheduler_service import StudioSchedulerService
173
+ from ksadk.studio.service_settings import StudioSettingsMixin
146
174
  from ksadk.studio.soul import soul_digest
147
175
  from ksadk.studio.templates import (
148
176
  compose_blank_agent,
149
177
  compose_research_agent,
150
178
  default_agent_spec,
151
179
  list_agent_templates,
180
+ with_harness_provider_permissions,
152
181
  )
153
182
  from ksadk.studio.validator import AgentValidator
154
183
  from ksadk.studio.workspace import Workspace
184
+ from ksadk.studio.workspace_registry import WorkspaceRegistry
155
185
 
156
186
  _T = TypeVar("_T")
157
187
 
@@ -169,7 +199,7 @@ class _OperationResource:
169
199
  id: str
170
200
 
171
201
 
172
- class StudioService:
202
+ class StudioService(StudioSettingsMixin):
173
203
  def __init__(
174
204
  self,
175
205
  root: Path | str,
@@ -179,13 +209,36 @@ class StudioService:
179
209
  cloud_gateway: CloudDeploymentGateway | None = None,
180
210
  codex_runtime_inspector: RuntimeInspector | None = None,
181
211
  runtime_executor: RuntimeExecutor | None = None,
212
+ harness_runtime_factory: Callable[[RuntimeLaunchContext], RuntimeAdapter] | None = None,
182
213
  harness_reasoner: Any | None = None,
214
+ harness_engine_selector: HarnessEngineSelector | None = None,
215
+ harness_native_adapter_builder: HarnessNativeAdapterBuilder | None = None,
216
+ native_harness_agent_ids: Sequence[str] | None = None,
217
+ native_harness_default: bool | None = None,
218
+ native_harness_durable: bool | None = None,
219
+ native_harness_session_context_read: bool = False,
220
+ native_harness_browser_reobserve: bool = False,
221
+ native_harness_terminal_child_reconcile: bool = False,
222
+ native_harness_prepared_child_recovery: bool = False,
223
+ native_harness_child_recovery_policy: ChildRecoveryPolicy | None = None,
224
+ native_harness_model_recovery_policy: Literal["pure-inference-takeover/v1"] | None = None,
225
+ native_harness_model_recovery_host: StudioModelTakeoverDeclaration | None = None,
226
+ native_acceptance_extension: StudioNativeAcceptanceExtension | None = None,
227
+ native_delivery_review_policy: DeliveryReviewPolicy | None = None,
228
+ native_harness_hook_registrations: Sequence[StudioNativeHookRegistration] = (),
229
+ native_harness_context_registrations: Sequence[StudioNativeContextRegistration] = (),
230
+ native_harness_hook_authorizer: HookAuthorizer | None = None,
231
+ native_harness_hook_authorization_version: str | None = None,
232
+ native_harness_diagnostic_profiles: Mapping[
233
+ str, tuple[LanguageServerProfile, ...]
234
+ ] | None = None,
183
235
  plugin_provider_manifests: Mapping[str, PluginManifest] | None = None,
184
236
  plugin_provider_factories: Mapping[str, Any] | None = None,
185
237
  legacy_harness_sources: Sequence[LegacyHarnessSource] = (),
186
238
  dsh_provider_registration_manager: StudioDshProviderRegistrationManager | None = None,
187
239
  dsh_capability_service: StudioDshCapabilityService | None = None,
188
240
  resource_authority_policy: ResourceAuthorityPolicy | None = None,
241
+ configuration_overrides: dict[str, str] | None = None,
189
242
  ) -> None:
190
243
  provider_manifests = dict(plugin_provider_manifests or {})
191
244
  provider_factories = dict(plugin_provider_factories or {})
@@ -193,8 +246,105 @@ class StudioService:
193
246
  raise ValueError(
194
247
  "plugin provider manifests and factories must use the same exact references"
195
248
  )
249
+ if (harness_engine_selector is None) != (harness_native_adapter_builder is None) or (
250
+ harness_engine_selector is not None
251
+ and (
252
+ not callable(harness_engine_selector)
253
+ or not callable(harness_native_adapter_builder)
254
+ )
255
+ ):
256
+ raise ValueError("Native Harness requires a host selector and adapter builder")
257
+ selected_native_agents = tuple(
258
+ native_harness_agent_ids
259
+ if native_harness_agent_ids is not None
260
+ else os.environ.get("KSADK_STUDIO_NATIVE_AGENT_IDS", "").split(",")
261
+ )
262
+ selected_native_agents = tuple(
263
+ item.strip() for item in selected_native_agents if item.strip()
264
+ )
265
+ if native_harness_default is None:
266
+ default_flag = os.environ.get("KSADK_STUDIO_NATIVE_DEFAULT")
267
+ if default_flag is not None:
268
+ if default_flag not in {"0", "1"}:
269
+ raise ValueError("KSADK_STUDIO_NATIVE_DEFAULT must be 0 or 1")
270
+ native_harness_default = default_flag == "1"
271
+ else:
272
+ # Exact Agent selection and injected execution hosts remain
273
+ # explicit compatibility modes. Ordinary Studio uses Native.
274
+ native_harness_default = (
275
+ native_harness_agent_ids is None
276
+ and "KSADK_STUDIO_NATIVE_AGENT_IDS" not in os.environ
277
+ and harness_engine_selector is None
278
+ and harness_runtime_factory is None
279
+ and harness_reasoner is None
280
+ )
281
+ elif type(native_harness_default) is not bool:
282
+ raise ValueError("Native Studio default must be a boolean")
283
+ native_enabled = native_harness_default or bool(selected_native_agents)
284
+ self._native_harness_default = native_harness_default
285
+ self._native_harness_agent_ids = frozenset(selected_native_agents)
286
+ if native_harness_durable is None:
287
+ # A normal desktop conversation must retain its committed ledger
288
+ # across app restarts. Explicit compatibility hosts keep their
289
+ # opt-in storage policy; either setting can still select memory.
290
+ durable_flag = os.environ.get(
291
+ "KSADK_STUDIO_NATIVE_DURABLE", "1" if native_harness_default else "0",
292
+ )
293
+ if durable_flag not in {"0", "1"}:
294
+ raise ValueError("KSADK_STUDIO_NATIVE_DURABLE must be 0 or 1")
295
+ native_harness_durable = durable_flag == "1"
296
+ elif type(native_harness_durable) is not bool:
297
+ raise ValueError("Native Studio durability must be a boolean")
298
+ self._native_harness_durable = native_harness_durable
299
+ validate_native_options(
300
+ selected_native_agents=selected_native_agents,
301
+ native_harness_default=native_harness_default,
302
+ native_harness_durable=native_harness_durable,
303
+ native_harness_session_context_read=native_harness_session_context_read,
304
+ native_harness_browser_reobserve=native_harness_browser_reobserve,
305
+ native_harness_terminal_child_reconcile=native_harness_terminal_child_reconcile,
306
+ native_harness_prepared_child_recovery=native_harness_prepared_child_recovery,
307
+ native_harness_child_recovery_policy=native_harness_child_recovery_policy,
308
+ native_harness_model_recovery_policy=native_harness_model_recovery_policy,
309
+ native_harness_model_recovery_host=native_harness_model_recovery_host,
310
+ harness_engine_selector=harness_engine_selector,
311
+ native_acceptance_extension=native_acceptance_extension,
312
+ native_delivery_review_policy=native_delivery_review_policy,
313
+ )
314
+ diagnostic_profiles = native_harness_diagnostic_profiles or {}
315
+ if any(agent not in selected_native_agents for agent in diagnostic_profiles):
316
+ raise ValueError("Native diagnostics require explicitly selected Studio Agents")
317
+ hook_registrations = tuple(native_harness_hook_registrations)
318
+ if any(
319
+ not isinstance(item, StudioNativeHookRegistration)
320
+ or not item.agent_ids.issubset(selected_native_agents) for item in hook_registrations
321
+ ):
322
+ raise ValueError("Native Hooks require registered, explicitly selected Studio Agents")
323
+ hook_ids = [item.manifest.metadata.id for item in hook_registrations]
324
+ if len(set(hook_ids)) != len(hook_ids):
325
+ raise ValueError("Native Hook plugin IDs must be unique")
326
+ context_registrations = tuple(native_harness_context_registrations)
327
+ if any(not isinstance(item, StudioNativeContextRegistration)
328
+ or not item.agent_ids.issubset(selected_native_agents)
329
+ for item in context_registrations):
330
+ raise ValueError(
331
+ "Native Context requires registered, explicitly selected Studio Agents",
332
+ )
333
+ context_ids = [item.manifest.metadata.id for item in context_registrations]
334
+ if len(set(context_ids)) != len(context_ids) or set(context_ids) & set(hook_ids):
335
+ raise ValueError("Native Context plugin IDs must be unique across host capabilities")
336
+ validate_hook_authorization_policy(
337
+ native_harness_hook_authorizer, native_harness_hook_authorization_version,
338
+ )
339
+ if native_harness_hook_authorizer is not None and not hook_registrations:
340
+ raise ValueError(
341
+ "Native Hook authorization requires registrations and a policy version",
342
+ )
343
+ self._native_product_composer = None
196
344
  self.workspace = Workspace(root)
197
345
  self.workspace.initialize()
346
+ self.workspace_registry = WorkspaceRegistry()
347
+ self.workspace_record = self.workspace_registry.open(self.workspace.root)
198
348
  self._startup_provider_manifests = provider_manifests
199
349
  self._startup_provider_factories = provider_factories
200
350
  self._active_provider_manifests = dict(provider_manifests)
@@ -208,9 +358,11 @@ class StudioService:
208
358
  dsh_capability_service
209
359
  or StudioDshCapabilityService.discover_or_create_workspace_default(self.workspace.root)
210
360
  )
211
- if dsh_capability_service is not None or os.environ.get(
212
- "KSADK_DSH_HOME", ""
213
- ).strip() or os.environ.get("KSADK_DSH_PROFILE", "").strip():
361
+ if (
362
+ dsh_capability_service is not None
363
+ or os.environ.get("KSADK_DSH_HOME", "").strip()
364
+ or os.environ.get("KSADK_DSH_PROFILE", "").strip()
365
+ ):
214
366
  self._resource_dsh_provider_registration_manager = None
215
367
  self.resource_dsh_capabilities = self.dsh_capabilities
216
368
  else:
@@ -220,13 +372,19 @@ class StudioService:
220
372
  )
221
373
  )
222
374
  self.resource_dsh_capabilities = (
223
- StudioDshCapabilityService.create_workspace_resource_default(
224
- self.workspace.root
225
- )
375
+ StudioDshCapabilityService.create_workspace_resource_default(self.workspace.root)
226
376
  )
227
377
  self._start_lock = asyncio.Lock()
378
+ self._profile_maintenance = False
228
379
  self._started = False
380
+ self._dsh_startup_task: asyncio.Task[None] | None = None
381
+ self._dsh_ready = False
229
382
  self._closed = False
383
+ self._profile_maintenance = False
384
+ self.configuration = WorkspaceConfiguration(
385
+ self.workspace, overrides=configuration_overrides
386
+ )
387
+ self._resource_authority_policy_override = resource_authority_policy
230
388
  self._apply_persisted_settings()
231
389
  self.avatar_assets = AgentAvatarAssetStore(self.workspace)
232
390
  self.conversation_attachments = ConversationAttachmentStore(self.workspace)
@@ -236,18 +394,16 @@ class StudioService:
236
394
  self.credentials = (
237
395
  credential_resolver
238
396
  or getattr(model_client, "credential_resolver", None)
239
- or CredentialResolver(self.workspace)
397
+ or CredentialResolver(self.workspace, configuration=self.configuration)
240
398
  )
241
399
  self.resource_connections = ResourceConnectionRepository(self.workspace, self.credentials)
242
400
  effective_resource_policy = (
243
401
  resource_authority_policy
244
402
  if resource_authority_policy is not None
245
- else resource_authority_policy_from_environment()
403
+ else resource_authority_policy_from_environment(self.configuration.environment())
246
404
  )
247
405
  self.resource_authority = (
248
- SignedKnowledgeResourceAuthority(
249
- self.resource_connections, effective_resource_policy
250
- )
406
+ SignedKnowledgeResourceAuthority(self.resource_connections, effective_resource_policy)
251
407
  if effective_resource_policy is not None
252
408
  else None
253
409
  )
@@ -265,6 +421,8 @@ class StudioService:
265
421
  self.workspace,
266
422
  self.catalog,
267
423
  provider_manifests=provider_manifests,
424
+ hook_registrations=hook_registrations,
425
+ context_registrations=context_registrations,
268
426
  )
269
427
  self.event_store = RunEventStore(self.workspace)
270
428
  self.session_service = LocalSessionService(project_dir=str(self.workspace.root))
@@ -289,8 +447,10 @@ class StudioService:
289
447
  provider_validate=self.codex_provider_builds.bundle_root,
290
448
  **codex_builder_kwargs,
291
449
  )
450
+ if runtime_executor is not None and harness_runtime_factory is not None:
451
+ raise ValueError("provide either runtime_executor or harness_runtime_factory")
292
452
  self.runtime_executor = runtime_executor or RuntimeExecutor(
293
- build_default_runtime_registry()
453
+ build_default_runtime_registry(harness_factory=harness_runtime_factory)
294
454
  )
295
455
  self.run_service = StudioRunService(
296
456
  self.workspace,
@@ -298,6 +458,7 @@ class StudioService:
298
458
  event_store=self.event_store,
299
459
  session_service=self.session_service,
300
460
  runtime_events=self.runtime_events,
461
+ native_harness_ingress=harness_runtime_factory is not None,
301
462
  )
302
463
  self.codex_runs = CodexRunSpecResolver(
303
464
  self.workspace,
@@ -313,10 +474,37 @@ class StudioService:
313
474
  self.workspace,
314
475
  build_repository=self.builds,
315
476
  )
316
- runtime_model_client = model_client or OpenAICompatibleModelClient(
477
+ runtime_model_client = model_client or ModelGatewayClient(
317
478
  credential_resolver=self.credentials
318
479
  )
319
480
  self.model_client = runtime_model_client
481
+ if native_enabled:
482
+ from ksadk.studio.native_product import StudioNativeProductComposer
483
+
484
+ self._native_product_composer = StudioNativeProductComposer(
485
+ model_client=self.model_client,
486
+ workspace_root=self.workspace.root,
487
+ acceptance_extension=native_acceptance_extension,
488
+ delivery_review_policy=native_delivery_review_policy,
489
+ hook_authorizer=native_harness_hook_authorizer,
490
+ hook_authorization_version=native_harness_hook_authorization_version,
491
+ durable=native_harness_durable,
492
+ session_context_read=native_harness_session_context_read,
493
+ browser_reobserve=native_harness_browser_reobserve,
494
+ terminal_child_reconcile=native_harness_terminal_child_reconcile,
495
+ prepared_child_recovery=native_harness_prepared_child_recovery,
496
+ child_recovery_policy=native_harness_child_recovery_policy,
497
+ diagnostic_profiles=diagnostic_profiles,
498
+ model_recovery_policy=native_harness_model_recovery_policy,
499
+ model_recovery_host=native_harness_model_recovery_host,
500
+ )
501
+ def select_native_engine(context): # type: ignore[no-untyped-def]
502
+ if self._native_session_enabled(context.agent_name, context.activation_key):
503
+ return "native"
504
+ return "legacy"
505
+
506
+ harness_engine_selector = select_native_engine
507
+ harness_native_adapter_builder = self._native_product_composer
320
508
  self.plugin_runs = StudioPluginRuntime(
321
509
  self.workspace,
322
510
  build_repository=self.builds,
@@ -326,14 +514,22 @@ class StudioService:
326
514
  codex_local_launch_resolver=self.codex_provider_builds.native_launch,
327
515
  runtime_executor=self.runtime_executor,
328
516
  harness_reasoner=harness_reasoner,
517
+ harness_engine_selector=harness_engine_selector,
518
+ harness_native_session_enabled=(
519
+ self._native_session_enabled if native_enabled else None
520
+ ),
521
+ harness_native_adapter_builder=harness_native_adapter_builder,
329
522
  provider_manifests=provider_manifests,
330
523
  provider_factories=provider_factories,
524
+ hook_registrations=hook_registrations,
525
+ context_registrations=context_registrations,
331
526
  legacy_harness_sources=legacy_harness_sources,
332
527
  dsh_capability_service=self.dsh_capabilities,
333
528
  resource_dsh_capability_service=self.resource_dsh_capabilities,
334
529
  resource_authority=self.resource_authority,
335
530
  resource_connections=self.resource_connections,
336
531
  resource_actor_ref="local-user",
532
+ native_workspace_id=self.workspace_record.workspace_id,
337
533
  )
338
534
  self.run_service.plugin_runtime = self.plugin_runs
339
535
  self.scheduler_runtimes = StudioScheduledKernelRegistry(
@@ -341,32 +537,76 @@ class StudioService:
341
537
  resolve_adapter_provider=self._scheduler_adapter_provider,
342
538
  session_service=self.session_service,
343
539
  runtime_executor=self.runtime_executor,
540
+ state_dir=self.workspace.resolve(".agentkit/plugin-runtime/state"),
344
541
  )
345
542
  self.scheduler = StudioSchedulerService(
346
543
  self.workspace,
347
544
  runtime_registry=self.scheduler_runtimes,
348
545
  )
546
+ from ksadk.studio.execution_host import StudioExecutionHost
547
+ from ksadk.studio.teams_installation import create_teams_installation
548
+ from ksadk.studio.workspace_plugins import WorkspacePluginRegistry
549
+
550
+ self.workspace_plugins = WorkspacePluginRegistry()
551
+ self.execution_host = StudioExecutionHost(
552
+ self.scheduler_runtimes,
553
+ state_path=self.workspace.resolve(".agentkit/plugin-runtime/execution-host.sqlite"),
554
+ )
555
+ self.plugin_runs.execution_policy_resolver = self.execution_host
556
+ self.teams_installation = create_teams_installation(self)
557
+ from ksadk.studio.channel_connections import StudioChannelConnections
558
+
559
+ self.channel_connections = StudioChannelConnections(self)
349
560
  from ksadk.studio.scheduler_assistant import StudioScheduleAssistant
350
561
 
351
562
  self.run_service.schedule_assistant = StudioScheduleAssistant(self)
352
563
  self.mcp_runtime = MCPRuntimeAdapter(self.workspace, credentials=self.credentials)
353
564
  self._cloud_gateway_override = cloud_gateway
565
+ self._profile_maintenance = False
354
566
  self.cloud = CloudDeploymentService(
355
567
  self.workspace,
356
568
  gateway=cloud_gateway or self._configured_cloud_gateway(),
357
569
  build_repository=self.builds,
358
570
  )
571
+ self.a2a_catalog = A2ACatalogService(lambda: self.cloud.gateway)
359
572
  self.operations = OperationManager(self.workspace)
360
573
  self.evaluation_storage = EvaluationStorage(self.workspace.resolve(".agentkit/evaluations"))
361
574
  self.authoring = StudioAuthoringCoordinator(self)
362
575
  self.codex_agents = CodexAgentService(self)
363
-
364
- async def start(self) -> None:
365
- """Bind ready managed DSH registrations before build or execution."""
366
-
576
+ self._current_codex_builds: dict[str, CodexBuildRecord] = {}
577
+ from ksadk.studio.build_singleflight import BuildSingleFlight
578
+
579
+ self._build_singleflight = BuildSingleFlight()
580
+ # agent_detail 进程内 TTL 缓存:bootstrap/list_models/list_sessions 等
581
+ # 转发接口在会话切换时反复调用 agent_detail,每次都重做 builds 全扫 +
582
+ # validator.validate(100-300ms)。5s TTL 把切换/刷新的重复读折叠掉;
583
+ # create/update/delete agent 时主动失效。
584
+ self._agent_detail_cache: dict[str, tuple[float, dict[str, Any]]] = {}
585
+ self._agent_detail_ttl = 5.0
586
+
587
+ async def start(self, *, wait_for_dsh: bool = True) -> None:
588
+ """Start local state and optionally wait for the managed DSH profile."""
589
+ # Desktop workspace switching must not queue behind an in-flight DSH
590
+ # discovery task. The service is already usable while that optional
591
+ # task finishes in the background; callers that explicitly request
592
+ # readiness still await the task below.
593
+ if self._started and not wait_for_dsh:
594
+ return
367
595
  async with self._start_lock:
368
596
  self._ensure_open()
369
- if self._started:
597
+ if not self._started:
598
+ await self.scheduler_runtimes.start()
599
+ self._started = True
600
+ self._dsh_startup_task = asyncio.create_task(self._initialize_dsh())
601
+ self.channel_connections.start_background()
602
+ task = self._dsh_startup_task
603
+ if wait_for_dsh and task is not None:
604
+ await asyncio.shield(task)
605
+
606
+ async def _initialize_dsh(self) -> None:
607
+ async with self._start_lock:
608
+ self._ensure_open()
609
+ if self._dsh_ready:
370
610
  return
371
611
  await self._bootstrap_official_dsh_defaults()
372
612
  manifests, factories, manager_refs = await self._provider_snapshot(refresh=False)
@@ -376,21 +616,32 @@ class StudioService:
376
616
  manager = self._dsh_provider_registration_manager
377
617
  if manager is not None and manager_refs is not None:
378
618
  manager.mark_bound(manager_refs)
379
- self._started = True
619
+ self._dsh_ready = True
380
620
 
381
621
  async def refresh_dsh_provider_registrations(self) -> None:
382
622
  """Rebind the exact current DSH Profile and release stale activations."""
383
623
 
384
624
  async with self._start_lock:
385
625
  self._ensure_open()
386
- safe_to_resume = False
626
+ await self.execution_host.set_admission_open(False)
627
+ await self.scheduler_runtimes.set_admission_open(False)
628
+ self._profile_maintenance = True
629
+ safe_to_resume = True
387
630
  try:
631
+ await self._require_profile_idle()
632
+ safe_to_resume = False
388
633
  await self.plugin_runs.suspend_admission()
389
634
  await self.reset_dsh_capability_state()
390
635
  await self._bind_dsh_provider_registrations_locked(refresh=True)
391
636
  await self._refresh_dsh_catalog_resource(required=False)
392
637
  safe_to_resume = True
393
638
  finally:
639
+ # 维护窗标志是纯同步状态,无条件复位:任何异常/取消路径都不得
640
+ # 把整个会话面永久留在 503。admission 的恢复语义不变(恢复失败
641
+ # 仍按契约保持关闭,由测试 test_failed_profile_rebind_* 保障)。
642
+ self._profile_maintenance = False
643
+ await self.execution_host.set_admission_open(safe_to_resume)
644
+ await self.scheduler_runtimes.set_admission_open(safe_to_resume)
394
645
  if safe_to_resume:
395
646
  await self.plugin_runs.resume_admission()
396
647
 
@@ -402,12 +653,21 @@ class StudioService:
402
653
 
403
654
  async with self._start_lock:
404
655
  self._ensure_open()
405
- safe_to_resume = False
656
+ await self.execution_host.set_admission_open(False)
657
+ await self.scheduler_runtimes.set_admission_open(False)
658
+ self._profile_maintenance = True
659
+ safe_to_resume = True
406
660
  try:
661
+ await self._require_profile_idle()
662
+ safe_to_resume = False
407
663
  await self.plugin_runs.suspend_admission()
408
664
  await self.reset_dsh_capability_state()
409
665
  try:
410
666
  result = await operation()
667
+ except asyncio.CancelledError:
668
+ # 取消中的任务做不了 recovery;维护窗标志在 finally 无条件
669
+ # 复位,避免一次取消把会话面永久 503。
670
+ raise
411
671
  except BaseException as mutation_error:
412
672
  if (
413
673
  isinstance(mutation_error, StudioError)
@@ -429,9 +689,45 @@ class StudioService:
429
689
  safe_to_resume = True
430
690
  return result
431
691
  finally:
692
+ # 维护窗标志是纯同步状态,无条件复位:任何异常/取消路径都不得
693
+ # 把整个会话面永久留在 503。admission 的恢复语义不变(恢复失败
694
+ # 仍按契约保持关闭,由测试 test_failed_profile_rebind_* 保障)。
695
+ self._profile_maintenance = False
696
+ await self.execution_host.set_admission_open(safe_to_resume)
697
+ await self.scheduler_runtimes.set_admission_open(safe_to_resume)
432
698
  if safe_to_resume:
433
699
  await self.plugin_runs.resume_admission()
434
700
 
701
+ async def _require_profile_idle(self) -> None:
702
+ pending = await self.scheduler_runtimes.unsettled_sessions()
703
+ active_operations = [
704
+ operation for operation in self.operations.list()
705
+ if operation.status in {OperationStatus.QUEUED, OperationStatus.RUNNING}
706
+ ]
707
+ if pending or active_operations:
708
+ raise StudioError("DSH_PROFILE_IN_USE",
709
+ "仍有执行或审批正在进行,请结束执行后再变更插件 Profile", status_code=409)
710
+
711
+ def _require_direct_session(self, session_id: str | None) -> None:
712
+ if self._profile_maintenance:
713
+ raise StudioError("DSH_PROFILE_MAINTENANCE", "插件宿主正在维护", status_code=503)
714
+ if session_id:
715
+ from ksadk.studio.execution_host import ExecutionHostError
716
+
717
+ try:
718
+ self.execution_host.require_unreserved_session(session_id)
719
+ except ExecutionHostError as error:
720
+ raise StudioError(error.code, str(error), status_code=error.status) from error
721
+
722
+ def _require_direct_run(self, run_id: str) -> None:
723
+ from ksadk.studio.execution_host import ExecutionHostError
724
+
725
+ self._require_direct_session(None)
726
+ try:
727
+ self.execution_host.require_unreserved_run(run_id)
728
+ except ExecutionHostError as error:
729
+ raise StudioError(error.code, str(error), status_code=error.status) from error
730
+
435
731
  async def _bind_dsh_provider_registrations_locked(self, *, refresh: bool) -> None:
436
732
  if self._dsh_provider_registration_manager is None:
437
733
  self._dsh_provider_registration_manager = (
@@ -448,6 +744,7 @@ class StudioService:
448
744
  if manager is not None and manager_refs is not None:
449
745
  manager.mark_bound(manager_refs)
450
746
  self._started = True
747
+ self._dsh_ready = True
451
748
 
452
749
  async def reset_dsh_capability_state(self) -> None:
453
750
  """Drop the current DSH capability/Core generation."""
@@ -531,6 +828,17 @@ class StudioService:
531
828
  logging.getLogger(__name__).info(
532
829
  "official Codex DSH provider bootstrap: %s", result
533
830
  )
831
+ try:
832
+ harness_result = await manager.bootstrap_official_harness_provider()
833
+ except Exception as error:
834
+ logging.getLogger(__name__).warning(
835
+ "official Harness DSH provider bootstrap skipped: %s", error
836
+ )
837
+ else:
838
+ if harness_result in {"installed", "already_enabled"}:
839
+ logging.getLogger(__name__).info(
840
+ "official Harness DSH provider bootstrap: %s", harness_result
841
+ )
534
842
  try:
535
843
  resource_result = await manager.bootstrap_official_resource_plugins()
536
844
  except Exception as error: # optional DSH must fail closed to legacy paths
@@ -656,11 +964,32 @@ class StudioService:
656
964
  }
657
965
 
658
966
  def runtime_catalog(self) -> list[dict]:
659
- return inspect_runtime_catalog(self.runtime_executor)
967
+ return inspect_runtime_catalog(
968
+ self.runtime_executor,
969
+ native_harness_default=self._native_harness_default,
970
+ native_harness_durable=self._native_harness_durable,
971
+ )
660
972
 
661
973
  def _scheduler_adapter_provider(self, spec: StudioRunSpec): # type: ignore[no-untyped-def]
662
974
  if spec.plugin_bundle_root is not None:
663
- return self.plugin_runs.kernel_adapter_provider(spec)
975
+ provider = self.plugin_runs.kernel_adapter_provider(spec)
976
+
977
+ def create_adapter(): # type: ignore[no-untyped-def]
978
+ from ksadk.studio.native_kernel_admission import admit_native_kernel_start
979
+ from ksadk.studio.plugin_kernel_adapter import StudioPluginKernelAdapter
980
+
981
+ adapter = provider()
982
+ if isinstance(adapter, StudioPluginKernelAdapter):
983
+ adapter.bind_native_admission(
984
+ lambda native, request: admit_native_kernel_start(
985
+ spec=spec, request=request, native=native,
986
+ runtime=self.scheduler_runtimes.runtime_for_build(spec.build_id),
987
+ run_events=self.run_service.event_store,
988
+ )
989
+ )
990
+ return adapter
991
+
992
+ return create_adapter
664
993
  return lambda: self.runtime_executor.create_adapter(spec.launch_context)
665
994
 
666
995
  def resolve_run_spec(
@@ -768,6 +1097,7 @@ class StudioService:
768
1097
  sending provider-specific fields to every Runtime.
769
1098
  """
770
1099
 
1100
+ self._require_direct_session(session_id)
771
1101
  spec = self.resolve_run_spec(build_id)
772
1102
  runtime_type = spec.launch_context.runtime_type.strip().lower()
773
1103
  runtime_mode: Literal["native", "translated"] = (
@@ -777,6 +1107,16 @@ class StudioService:
777
1107
  if spec.model:
778
1108
  inputs.append(ConversationCapability(name="model.select", mode=runtime_mode))
779
1109
  inputs.append(ConversationCapability(name="approval", mode=runtime_mode))
1110
+ if runtime_type == "harness" and self._native_session_enabled(spec.agent_id, session_id):
1111
+ inputs.append(ConversationCapability(name="attachment.file", mode="translated"))
1112
+ if (
1113
+ runtime_type in {"harness", "adk", "langgraph"}
1114
+ and supports_native_image_input(spec.model_metadata)
1115
+ ):
1116
+ # Non-Codex runtimes receive the normalized Runtime image part.
1117
+ # The capability is taken from the immutable Build snapshot, so a
1118
+ # text-only model is never offered an image composer by name guess.
1119
+ inputs.append(ConversationCapability(name="attachment.image", mode="translated"))
780
1120
  if runtime_type == "codex":
781
1121
  inputs.extend(
782
1122
  (
@@ -784,7 +1124,7 @@ class StudioService:
784
1124
  ConversationCapability(name="attachment.image", mode="native"),
785
1125
  # Bounded UTF-8/code attachments are made model-visible as
786
1126
  # deterministic text parts by the Responses compatibility
787
- # adapter. Binary files remain unavailable in Phase 2.
1127
+ # adapter. Binary files remain unavailable in Release.
788
1128
  ConversationCapability(name="attachment.file", mode="translated"),
789
1129
  ConversationCapability(name="reasoning.effort", mode="native"),
790
1130
  ConversationCapability(name="goal", mode="native"),
@@ -796,6 +1136,9 @@ class StudioService:
796
1136
  ConversationCapability(name="text", mode="native"),
797
1137
  ConversationCapability(name="streaming", mode=runtime_mode),
798
1138
  ]
1139
+ if runtime_type == "adk":
1140
+ inputs.append(ConversationCapability(name="ksadk.presentation", mode="native"))
1141
+ outputs.append(ConversationCapability(name="agent.block", mode="native"))
799
1142
  if runtime_type == "codex":
800
1143
  outputs.extend(
801
1144
  (
@@ -816,58 +1159,24 @@ class StudioService:
816
1159
  )
817
1160
 
818
1161
  async def ensure_current_build(self, agent_id: str):
819
- """Return the Build that is eligible for a local Studio turn.
1162
+ from ksadk.studio.build_resolution import resolve_current_build
1163
+
1164
+ return await self._build_singleflight.run(
1165
+ agent_id, lambda: resolve_current_build(self, agent_id),
1166
+ identity=lambda: (
1167
+ ("codex", self.codex_manifests.load(agent_id).manifest_sha256)
1168
+ if self.is_codex_agent(agent_id)
1169
+ else ("draft", self.drafts.get(agent_id).metadata.revision)
1170
+ ),
1171
+ )
820
1172
 
821
- This is deliberately one shared resolver for Web chat and Scheduler
822
- authoring. A Scheduler must never select a mutable Draft or a stale
823
- Codex manifest merely because a UI happened to show it as an Agent.
824
- """
1173
+ def _native_session_enabled(self, agent_id: str, session_id: str) -> bool:
1174
+ from ksadk.studio.native_session_engine import native_session_enabled
825
1175
 
826
- await self.start()
827
- if self.is_codex_agent(agent_id):
828
- self.codex_agent_detail(agent_id)
829
- builds = [
830
- record
831
- for record in self.codex_builds.list()
832
- if record.agent_name == agent_id and self.codex_builder.is_current(record)
833
- ]
834
- if builds:
835
- return builds[0]
836
- return await asyncio.to_thread(self.codex_builder.build, agent_id)
837
- draft = self.drafts.get(agent_id)
838
- composition_required = self.plugin_compositions.required_for(draft)
839
- resources_required = resource_build_required(draft)
840
- for record in self.builds.list_for_agent(agent_id):
841
- if record.status == BuildStatus.SUCCEEDED:
842
- if (composition_required or resources_required) and (
843
- record.source_revision != draft.metadata.revision
844
- or (composition_required and not self._build_has_composition(record))
845
- or (resources_required and not self._build_has_resources(record))
846
- ):
847
- continue
848
- if composition_required:
849
- composition = self.plugin_compositions.compile_if_required(draft)
850
- if composition is None: # pragma: no cover - guarded by required_for
851
- raise StudioError(
852
- "PLUGIN_COMPOSITION_REQUIRED",
853
- "当前 Agent 需要插件组合,但无法生成 Composition",
854
- status_code=409,
855
- )
856
- self.plugin_compositions.bind_build(
857
- composition,
858
- agent_id=draft.metadata.id,
859
- build_id=record.id,
860
- )
861
- return record
862
- if draft.spec.model is None and not draft.spec.bindings.model_profile_id:
863
- raise StudioError(
864
- "AGENT_MODEL_REQUIRED",
865
- "当前 Agent 未绑定 Model Profile,请先在 Agent 配置中选择模型;"
866
- "API Key 只提供访问凭证,不会自动绑定模型。",
867
- status_code=422,
868
- field="spec.bindings.modelProfileId",
869
- )
870
- return await asyncio.to_thread(self._build_agent_bundle, draft)
1176
+ return native_session_enabled(
1177
+ self.event_store, agent_id, session_id,
1178
+ selected=self._native_harness_default or agent_id in self._native_harness_agent_ids,
1179
+ )
871
1180
 
872
1181
  def _build_agent_bundle(self, draft: AgentDraft):
873
1182
  composition = self.plugin_compositions.compile_if_required(draft)
@@ -917,7 +1226,7 @@ class StudioService:
917
1226
  )
918
1227
  return record
919
1228
 
920
- def _build_has_composition(self, record: Any) -> bool:
1229
+ def _build_has_composition(self, record: Any, *, composition: Any = None) -> bool:
921
1230
  """Reject stale pre-Phase-2 builds for a composed runtime.
922
1231
 
923
1232
  This check is intentionally scoped to Harness/plugin runtimes. Legacy
@@ -936,6 +1245,13 @@ class StudioService:
936
1245
  and manifest.get("compositionProfileDigest")
937
1246
  and "composition-profile.json" in names
938
1247
  and "plugin-lock.json" in names
1248
+ and (
1249
+ composition is None
1250
+ or (
1251
+ manifest.get("compositionProfileDigest") == composition.profile_digest
1252
+ and manifest.get("pluginLockDigest") == composition.plugin_lock_digest
1253
+ )
1254
+ )
939
1255
  )
940
1256
  except (KeyError, OSError, UnicodeError, ValueError, zipfile.BadZipFile):
941
1257
  return False
@@ -1140,12 +1456,15 @@ class StudioService:
1140
1456
  name: str | None = None,
1141
1457
  labels: dict[str, str] | None = None,
1142
1458
  ) -> AgentDraft:
1143
- return self.codex_agents.create(
1459
+ created = self.codex_agents.create(
1144
1460
  agent_id=agent_id,
1145
1461
  spec=spec,
1146
1462
  name=name,
1147
1463
  labels=labels,
1148
1464
  )
1465
+ self._current_codex_builds.pop(agent_id, None)
1466
+ self.invalidate_agent_detail(agent_id)
1467
+ return created
1149
1468
 
1150
1469
  def update_codex_agent(
1151
1470
  self,
@@ -1155,15 +1474,20 @@ class StudioService:
1155
1474
  expected_revision: int,
1156
1475
  name: str | None = None,
1157
1476
  ) -> AgentDraft:
1158
- return self.codex_agents.update(
1477
+ updated = self.codex_agents.update(
1159
1478
  agent_id,
1160
1479
  spec,
1161
1480
  expected_revision=expected_revision,
1162
1481
  name=name,
1163
1482
  )
1483
+ self._current_codex_builds.pop(agent_id, None)
1484
+ self.invalidate_agent_detail(agent_id)
1485
+ return updated
1164
1486
 
1165
1487
  def delete_codex_agent(self, agent_id: str, *, purge: bool = False) -> None:
1166
1488
  self.codex_agents.delete(agent_id, purge=purge)
1489
+ self._current_codex_builds.pop(agent_id, None)
1490
+ self.invalidate_agent_detail(agent_id)
1167
1491
 
1168
1492
  def codex_agent_detail(self, agent_id: str | None = None) -> dict:
1169
1493
  return self.codex_agents.detail(agent_id)
@@ -1198,7 +1522,9 @@ class StudioService:
1198
1522
  runtime_input: Any = None,
1199
1523
  idempotency_key: str,
1200
1524
  on_event: Callable[[RunEvent], None] | None = None,
1525
+ submission_ref: RunSubmissionRef | None = None,
1201
1526
  ) -> Operation:
1527
+ self._require_direct_session(session_id)
1202
1528
  return self.codex_agents.submit_run(
1203
1529
  build_id,
1204
1530
  user_input,
@@ -1212,22 +1538,36 @@ class StudioService:
1212
1538
  runtime_input=runtime_input,
1213
1539
  idempotency_key=idempotency_key,
1214
1540
  on_event=on_event,
1541
+ submission_ref=submission_ref,
1215
1542
  )
1216
1543
 
1217
1544
  async def delete_session(self, session_id: str) -> None:
1218
1545
  from ksadk.studio.errors import not_found
1219
1546
 
1547
+ self._require_direct_session(session_id)
1220
1548
  runs = self.event_store.list_runs(session_id=session_id)
1221
1549
  session = await self.session_service.get_session_metadata(session_id)
1222
1550
  if not runs and session is None:
1223
1551
  raise not_found("session", session_id)
1224
- if any(run.status == RunStatus.RUNNING for run in runs):
1552
+ if self.run_service.has_pending_session_turns(session_id):
1225
1553
  raise StudioError(
1226
1554
  "SESSION_RUN_ACTIVE",
1227
- "会话仍在运行,请先停止运行后再删除",
1555
+ "会话仍有运行或排队中的消息,请先停止或撤销后再删除",
1228
1556
  status_code=409,
1229
1557
  details={"sessionId": session_id},
1230
1558
  )
1559
+ # 磁盘停在 RUNNING 的 run 只有仍在本进程内执行时才阻止删除;
1560
+ # 崩溃/重启遗留的僵尸 RUNNING 一律回收为 canceled 后放行删除。
1561
+ for run in runs:
1562
+ if run.status == RunStatus.RUNNING:
1563
+ if self.run_service.is_run_executing(run.id):
1564
+ raise StudioError(
1565
+ "SESSION_RUN_ACTIVE",
1566
+ "会话仍在运行,请先停止运行后再删除",
1567
+ status_code=409,
1568
+ details={"sessionId": session_id},
1569
+ )
1570
+ await self.run_service.reap_stale_running_run(run.id)
1231
1571
  await self.plugin_runs.close_session(session_id)
1232
1572
  await self.session_service.delete_session(session_id)
1233
1573
  self.event_store.delete_session(session_id)
@@ -1238,6 +1578,8 @@ class StudioService:
1238
1578
  async with self._start_lock:
1239
1579
  if self._closed:
1240
1580
  return
1581
+ if self._dsh_startup_task is not None and not self._dsh_startup_task.done():
1582
+ self._dsh_startup_task.cancel()
1241
1583
  self._closed = True
1242
1584
  cleanup = asyncio.create_task(self._close_owned_plugin_services())
1243
1585
  interrupted = False
@@ -1251,10 +1593,24 @@ class StudioService:
1251
1593
  raise asyncio.CancelledError
1252
1594
 
1253
1595
  async def _close_owned_plugin_services(self) -> None:
1596
+ from ksadk.studio.provider_recovery import detach_recovered_runs
1597
+
1598
+ await detach_recovered_runs(self.run_service)
1254
1599
  first_error: BaseException | None = None
1255
- owned = [self.plugin_runs.aclose, self.dsh_capabilities.aclose]
1600
+ owned = [
1601
+ self.channel_connections.close,
1602
+ self.workspace_plugins.close, self.plugin_runs.aclose, self.dsh_capabilities.aclose,
1603
+ self.scheduler_runtimes.close, self.execution_host.close,
1604
+ ]
1605
+ # The model client owns a keep-alive connection pool shared by all
1606
+ # turns. Close it with the Studio service so shutdown remains clean.
1607
+ close_model_client = getattr(self.model_client, "aclose", None)
1608
+ if close_model_client is not None:
1609
+ owned.append(close_model_client)
1256
1610
  if self.resource_dsh_capabilities is not self.dsh_capabilities:
1257
1611
  owned.append(self.resource_dsh_capabilities.aclose)
1612
+ if self._native_product_composer is not None:
1613
+ owned.append(self._native_product_composer.aclose)
1258
1614
  if self._dsh_provider_registration_manager is not None:
1259
1615
  owned.append(self._dsh_provider_registration_manager.aclose)
1260
1616
  if self._resource_dsh_provider_registration_manager is not None:
@@ -1277,6 +1633,7 @@ class StudioService:
1277
1633
  )
1278
1634
 
1279
1635
  async def _require_runtime_session(self, session_id: str) -> None:
1636
+ self._require_direct_session(session_id)
1280
1637
  if await self.session_service.get_session_metadata(session_id) is None:
1281
1638
  raise StudioError(
1282
1639
  "SESSION_NOT_FOUND",
@@ -1799,17 +2156,29 @@ class StudioService:
1799
2156
  return values[:limit]
1800
2157
 
1801
2158
  def agent_detail(self, agent_id: str) -> dict:
2159
+ cached = self._agent_detail_cache.get(agent_id)
2160
+ if cached and cached[0] > time.monotonic():
2161
+ return cached[1]
1802
2162
  if self.is_codex_agent(agent_id):
1803
2163
  detail = self.codex_agent_detail(agent_id)
1804
2164
  detail["soulProjection"] = self._soul_projection(detail["draft"])
1805
- return detail
1806
- draft = self.drafts.get(agent_id)
1807
- return {
1808
- "draft": draft,
1809
- "builds": self.builds.list_for_agent(agent_id)[:10],
1810
- "validation": self.validator.validate(draft),
1811
- "soulProjection": self._soul_projection(draft),
1812
- }
2165
+ else:
2166
+ draft = self.drafts.get(agent_id)
2167
+ detail = {
2168
+ "draft": draft,
2169
+ "builds": self.builds.list_for_agent(agent_id)[:10],
2170
+ "validation": self.validator.validate(draft),
2171
+ "soulProjection": self._soul_projection(draft),
2172
+ }
2173
+ self._agent_detail_cache[agent_id] = (time.monotonic() + self._agent_detail_ttl, detail)
2174
+ return detail
2175
+
2176
+ def invalidate_agent_detail(self, agent_id: str | None = None) -> None:
2177
+ """Invalidate cached agent_detail after create/update/delete/build."""
2178
+ if agent_id is None:
2179
+ self._agent_detail_cache.clear()
2180
+ else:
2181
+ self._agent_detail_cache.pop(agent_id, None)
1813
2182
 
1814
2183
  @staticmethod
1815
2184
  def _soul_projection(draft: AgentDraft) -> dict[str, object]:
@@ -1850,6 +2219,8 @@ class StudioService:
1850
2219
  )
1851
2220
  selected = runtime or resolved_spec.runtime
1852
2221
  resolved_spec.runtime = selected
2222
+ if selected is not None and selected.type == "harness" and spec is None:
2223
+ resolved_spec = with_harness_provider_permissions(resolved_spec)
1853
2224
  if selected is not None and selected.type == "codex":
1854
2225
  return cast(
1855
2226
  AgentDraft,
@@ -1860,7 +2231,7 @@ class StudioService:
1860
2231
  labels=labels,
1861
2232
  ),
1862
2233
  )
1863
- return cast(
2234
+ created = cast(
1864
2235
  AgentDraft,
1865
2236
  self.create_agent(
1866
2237
  agent_id=agent_id,
@@ -1871,6 +2242,8 @@ class StudioService:
1871
2242
  labels=labels,
1872
2243
  ),
1873
2244
  )
2245
+ self.invalidate_agent_detail(agent_id)
2246
+ return created
1874
2247
 
1875
2248
  def update_studio_agent(
1876
2249
  self,
@@ -1942,17 +2315,21 @@ class StudioService:
1942
2315
  appearance,
1943
2316
  expected_revision=expected_revision,
1944
2317
  )
1945
- return self.drafts.update_appearance(
2318
+ updated = self.drafts.update_appearance(
1946
2319
  agent_id,
1947
2320
  appearance,
1948
2321
  expected_revision=expected_revision,
1949
2322
  )
2323
+ self.invalidate_agent_detail(agent_id)
2324
+ return updated
1950
2325
 
1951
2326
  def delete_studio_agent(self, agent_id: str, *, purge: bool = False) -> None:
1952
2327
  if self.is_codex_agent(agent_id):
1953
2328
  self.delete_codex_agent(agent_id, purge=purge)
2329
+ self.invalidate_agent_detail(agent_id)
1954
2330
  return
1955
2331
  delete_framework_agent(self, agent_id, purge=purge)
2332
+ self.invalidate_agent_detail(agent_id)
1956
2333
 
1957
2334
  def validate_studio_agent(
1958
2335
  self,
@@ -1979,11 +2356,13 @@ class StudioService:
1979
2356
  # Check workspace ownership, but never project the mutable draft as runtime state.
1980
2357
  await asyncio.to_thread(self.agent_detail, agent_id)
1981
2358
  status = await self.dsh_capabilities.resource_runtime_status(
1982
- agent_id=agent_id, activation_id=activation_id,
2359
+ agent_id=agent_id,
2360
+ activation_id=activation_id,
1983
2361
  )
1984
2362
  if status is None:
1985
2363
  raise StudioError(
1986
- "RESOURCE_ACTIVATION_NOT_FOUND", "未找到此 Agent 的资源运行实例",
2364
+ "RESOURCE_ACTIVATION_NOT_FOUND",
2365
+ "未找到此 Agent 的资源运行实例",
1987
2366
  status_code=404,
1988
2367
  )
1989
2368
  return status
@@ -1995,10 +2374,14 @@ class StudioService:
1995
2374
  draft = self.agent_detail(agent_id)["draft"]
1996
2375
  if draft.metadata.revision != expected_revision:
1997
2376
  raise StudioError(
1998
- "AGENT_REVISION_CONFLICT", "资源校验版本与当前 Agent 不一致", status_code=409,
2377
+ "AGENT_REVISION_CONFLICT",
2378
+ "资源校验版本与当前 Agent 不一致",
2379
+ status_code=409,
1999
2380
  )
2000
2381
  diagnostics = resource_binding_diagnostics(
2001
- draft.spec.bindings.plugins, draft.spec.memory, self.resource_connections,
2382
+ draft.spec.bindings.plugins,
2383
+ draft.spec.memory,
2384
+ self.resource_connections,
2002
2385
  )
2003
2386
  configs = [
2004
2387
  (index, config)
@@ -2029,8 +2412,7 @@ class StudioService:
2029
2412
  severity=DiagnosticSeverity.ERROR,
2030
2413
  code=error.code,
2031
2414
  message=error.message,
2032
- field=error.field
2033
- or f"spec.bindings.plugins[{index}].config.binding",
2415
+ field=error.field or f"spec.bindings.plugins[{index}].config.binding",
2034
2416
  )
2035
2417
  )
2036
2418
  current = self.agent_detail(agent_id)["draft"]
@@ -2112,8 +2494,11 @@ class StudioService:
2112
2494
  goal_objective: str | None = None,
2113
2495
  reasoning_effort: str | None = None,
2114
2496
  runtime_input: Any = None,
2497
+ presentation_profile: Literal["flat-v1", "agent-block-v1"] = "flat-v1",
2115
2498
  on_event: Callable[[RunEvent], None] | None = None,
2499
+ submission_ref: RunSubmissionRef | None = None,
2116
2500
  ) -> Operation:
2501
+ self._require_direct_session(session_id)
2117
2502
  try:
2118
2503
  self.codex_builds.get(build_id)
2119
2504
  except Exception as exc:
@@ -2133,6 +2518,7 @@ class StudioService:
2133
2518
  runtime_input=runtime_input,
2134
2519
  idempotency_key=idempotency_key,
2135
2520
  on_event=on_event,
2521
+ submission_ref=submission_ref,
2136
2522
  )
2137
2523
  return self.submit_run(
2138
2524
  build_id,
@@ -2145,8 +2531,10 @@ class StudioService:
2145
2531
  goal_objective=goal_objective,
2146
2532
  reasoning_effort=reasoning_effort,
2147
2533
  runtime_input=runtime_input,
2534
+ presentation_profile=presentation_profile,
2148
2535
  idempotency_key=idempotency_key,
2149
2536
  on_event=on_event,
2537
+ submission_ref=submission_ref,
2150
2538
  )
2151
2539
 
2152
2540
  def _draft_exists(self, agent_id: str) -> bool:
@@ -2230,12 +2618,14 @@ class StudioService:
2230
2618
  preview,
2231
2619
  catalog=self.catalog,
2232
2620
  )
2233
- return self.drafts.update(
2621
+ updated = self.drafts.update(
2234
2622
  agent_id,
2235
2623
  spec,
2236
2624
  expected_revision=expected_revision,
2237
2625
  name=name,
2238
2626
  )
2627
+ self.invalidate_agent_detail(agent_id)
2628
+ return updated
2239
2629
 
2240
2630
  def update_agent_bindings(
2241
2631
  self,
@@ -2399,6 +2789,7 @@ class StudioService:
2399
2789
  snapshot = draft.model_copy(deep=True)
2400
2790
 
2401
2791
  async def runner(_operation_id: str):
2792
+ await self.a2a_catalog.validate_bindings(snapshot.spec.bindings.remote_agents)
2402
2793
  return await asyncio.to_thread(self._build_agent_bundle, snapshot)
2403
2794
 
2404
2795
  return self.operations.submit(
@@ -2421,9 +2812,14 @@ class StudioService:
2421
2812
  goal_objective: str | None = None,
2422
2813
  reasoning_effort: str | None = None,
2423
2814
  runtime_input: Any = None,
2815
+ presentation_profile: Literal["flat-v1", "agent-block-v1"] = "flat-v1",
2424
2816
  idempotency_key: str,
2425
2817
  on_event: Callable[[RunEvent], None] | None = None,
2818
+ submission_ref: RunSubmissionRef | None = None,
2426
2819
  ) -> Operation:
2820
+ self._require_direct_session(session_id)
2821
+ runtime_input = copy.deepcopy(runtime_input)
2822
+ submission_ref = submission_ref.model_copy(deep=True) if submission_ref else None
2427
2823
  async def runner(_operation_id: str):
2428
2824
  return await self.run_build(
2429
2825
  build_id,
@@ -2436,14 +2832,22 @@ class StudioService:
2436
2832
  goal_objective=goal_objective,
2437
2833
  reasoning_effort=reasoning_effort,
2438
2834
  runtime_input=runtime_input,
2835
+ presentation_profile=presentation_profile,
2439
2836
  on_event=on_event,
2837
+ submission_ref=submission_ref,
2838
+ queue_if_active=True,
2839
+ on_admitted=lambda: self.operations.mark_started(_operation_id),
2440
2840
  )
2441
2841
 
2442
2842
  return self.operations.submit(
2443
2843
  kind=OperationKind.RUN,
2444
2844
  resource_id=build_id,
2445
2845
  idempotency_key=idempotency_key,
2846
+ metadata=(
2847
+ {"submission_ref": submission_ref.model_dump()} if submission_ref else None
2848
+ ),
2446
2849
  runner=runner,
2850
+ deferred_start=True,
2447
2851
  )
2448
2852
 
2449
2853
  async def run_build(
@@ -2459,18 +2863,29 @@ class StudioService:
2459
2863
  goal_objective: str | None = None,
2460
2864
  reasoning_effort: str | None = None,
2461
2865
  runtime_input: Any = None,
2866
+ presentation_profile: Literal["flat-v1", "agent-block-v1"] = "flat-v1",
2462
2867
  on_event: Callable[[RunEvent], None] | None = None,
2868
+ submission_ref: RunSubmissionRef | None = None,
2869
+ queue_if_active: bool = False,
2870
+ on_admitted: Callable[[], None] | None = None,
2463
2871
  ):
2464
2872
  """Execute any immutable Studio Build through the canonical executor."""
2465
2873
 
2466
2874
  await self.start()
2875
+ self._require_direct_session(session_id)
2876
+ await self.a2a_catalog.validate_bindings(self._remote_bindings_for_build(build_id))
2467
2877
  spec = self.resolve_run_spec(
2468
2878
  build_id,
2469
2879
  model=model,
2470
2880
  sandbox=sandbox,
2471
2881
  approval_mode=approval_mode,
2472
2882
  )
2473
- if collaboration_mode or goal_objective or reasoning_effort:
2883
+ if submission_ref is not None:
2884
+ from dataclasses import replace
2885
+
2886
+ spec = replace(spec, submission_ref=submission_ref)
2887
+ if (collaboration_mode or goal_objective or reasoning_effort
2888
+ or presentation_profile != "flat-v1"):
2474
2889
  from dataclasses import replace
2475
2890
 
2476
2891
  request_config = dict(spec.request_config)
@@ -2481,13 +2896,17 @@ class StudioService:
2481
2896
  request_config["ephemeral"] = False
2482
2897
  if reasoning_effort:
2483
2898
  request_config["effort"] = reasoning_effort
2484
- spec = replace(spec, request_config=request_config)
2899
+ spec = replace(
2900
+ spec, request_config=request_config, presentation_profile=presentation_profile
2901
+ )
2485
2902
  return await self.run_service.run(
2486
2903
  spec,
2487
2904
  user_input,
2488
2905
  runtime_input=runtime_input,
2489
2906
  session_id=session_id,
2490
2907
  on_event=on_event,
2908
+ queue_if_active=queue_if_active,
2909
+ on_admitted=on_admitted,
2491
2910
  )
2492
2911
 
2493
2912
  def submit_public_evaluation(
@@ -2667,7 +3086,7 @@ class StudioService:
2667
3086
  try:
2668
3087
  return self.drafts.get(agent_id).metadata.name
2669
3088
  except StudioError as exc:
2670
- if exc.status_code != 404:
3089
+ if exc.status_code not in {404, 422}:
2671
3090
  raise
2672
3091
  return agent_id
2673
3092
 
@@ -2779,12 +3198,16 @@ class StudioService:
2779
3198
  evidence_store = EvidenceStore(request.report_dir) if request.report_dir else None
2780
3199
  return StudioBuildTargetAdapter(
2781
3200
  timeout_seconds=request.config.timeout_seconds,
2782
- resolve_build=self._resolve_evaluation_build,
3201
+ resolve_build=lambda build_id: self._resolve_evaluation_build(
3202
+ build_id, request.config.tool_approval_mode
3203
+ ),
2783
3204
  run_service=self.run_service,
2784
3205
  evidence_store=evidence_store,
2785
3206
  )
2786
3207
 
2787
- def _resolve_evaluation_build(self, build_id: str) -> StudioBuildResolution:
3208
+ def _resolve_evaluation_build(
3209
+ self, build_id: str, approval_mode: str | None = None
3210
+ ) -> StudioBuildResolution:
2788
3211
  try:
2789
3212
  self.codex_builds.get(build_id)
2790
3213
  except Exception as exc:
@@ -2803,7 +3226,7 @@ class StudioService:
2803
3226
  "STUDIO_BUILD_NOT_READY",
2804
3227
  "Studio Build must be SUCCEEDED before evaluation",
2805
3228
  )
2806
- run_spec = self.framework_runs.resolve(build_id)
3229
+ run_spec = self.resolve_run_spec(build_id, approval_mode=approval_mode)
2807
3230
  revision_digest = str(build.bundle_digest or build.resolved_digest).strip()
2808
3231
  if not revision_digest:
2809
3232
  raise StudioBuildTargetError(
@@ -2823,6 +3246,15 @@ class StudioService:
2823
3246
  "sourceDigest": build.source_digest,
2824
3247
  "sourceRevision": build.source_revision,
2825
3248
  },
3249
+ # Artifact assertions follow the runtime's admitted workspace
3250
+ # tools, not the repository root. Harness runs use the isolated
3251
+ # tool workspace also exposed by run_documents; framework tools
3252
+ # use the local AgentEngine session workspace.
3253
+ verification_root=(
3254
+ self.workspace.root / ".harness-tools" / "workspace"
3255
+ if build.runtime_type in {"harness", "plugin"}
3256
+ else self.workspace.root / ".agentengine" / "ui" / "workspace"
3257
+ ),
2826
3258
  )
2827
3259
 
2828
3260
  def _validate_evaluation_build(self, build_id: str) -> None:
@@ -2908,6 +3340,7 @@ class StudioService:
2908
3340
  )
2909
3341
 
2910
3342
  async def managed_runtime_runner(_operation_id: str):
3343
+ await self.a2a_catalog.validate_bindings(self._remote_bindings_for_build(build_id))
2911
3344
  return await self.cloud.deploy_managed_runtime(
2912
3345
  build_id=build_id,
2913
3346
  agent_name=codex_build.agent_name,
@@ -2936,6 +3369,7 @@ class StudioService:
2936
3369
  self.builds.get(build_id)
2937
3370
 
2938
3371
  async def runner(_operation_id: str):
3372
+ await self.a2a_catalog.validate_bindings(self._remote_bindings_for_build(build_id))
2939
3373
  return await self.cloud.deploy(build_id, request)
2940
3374
 
2941
3375
  return self.operations.submit(
@@ -2970,6 +3404,9 @@ class StudioService:
2970
3404
  request = self.cloud.request_for(deployment_id)
2971
3405
 
2972
3406
  async def managed_runtime_runner(_operation_id: str):
3407
+ await self.a2a_catalog.validate_bindings(
3408
+ self._remote_bindings_for_build(target_build.id)
3409
+ )
2973
3410
  return await self.cloud.deploy_managed_runtime(
2974
3411
  build_id=target_build.id,
2975
3412
  agent_name=target_build.agent_name,
@@ -3002,6 +3439,9 @@ class StudioService:
3002
3439
  )
3003
3440
 
3004
3441
  async def runner(_operation_id: str):
3442
+ await self.a2a_catalog.validate_bindings(
3443
+ self._remote_bindings_for_build(target_build_id)
3444
+ )
3005
3445
  return await self.cloud.rollback(
3006
3446
  deployment_id,
3007
3447
  target_build_id=target_build_id,
@@ -3014,6 +3454,45 @@ class StudioService:
3014
3454
  runner=runner,
3015
3455
  )
3016
3456
 
3457
+ def _remote_bindings_for_build(
3458
+ self,
3459
+ build_id: str,
3460
+ ) -> list[RemoteAgentBinding]:
3461
+ try:
3462
+ codex_build = self.codex_builds.get(build_id)
3463
+ except StudioError as exc:
3464
+ if exc.status_code != 404:
3465
+ raise
3466
+ else:
3467
+ import yaml
3468
+
3469
+ from ksadk.studio.codex_manifest import CodexAgentManifest
3470
+
3471
+ # Read digest-verified immutable bytes, never today's editable YAML.
3472
+ text = self.codex_builds.manifest_text(codex_build)
3473
+ manifest = CodexAgentManifest.model_validate(yaml.safe_load(text))
3474
+ return list(manifest.remote_agents or [])
3475
+ build = self.builds.get(build_id)
3476
+ if not build.artifact_path:
3477
+ return []
3478
+ archive = self.workspace.resolve(build.artifact_path, must_exist=True)
3479
+ try:
3480
+ with zipfile.ZipFile(archive) as bundle:
3481
+ payload = json.loads(bundle.read("resolved-agent-spec.json"))
3482
+ if not isinstance(payload, dict):
3483
+ raise ValueError("resolved-agent-spec must be an object")
3484
+ raw_bindings = payload.get("remoteAgents", [])
3485
+ if not isinstance(raw_bindings, list):
3486
+ raise ValueError("remoteAgents must be a list")
3487
+ return [RemoteAgentBinding.model_validate(item) for item in raw_bindings]
3488
+ except (KeyError, OSError, UnicodeError, ValueError, zipfile.BadZipFile) as exc:
3489
+ raise StudioError(
3490
+ "A2A_BINDING_BUNDLE_INVALID",
3491
+ "Build 中的远端 Agent binding 无法验证",
3492
+ status_code=422,
3493
+ details={"buildId": build_id},
3494
+ ) from exc
3495
+
3017
3496
  def submit_account_agent_version_rollback(
3018
3497
  self,
3019
3498
  agent_id: str,
@@ -3081,161 +3560,51 @@ class StudioService:
3081
3560
  "cloudCredential": opaque(f"{region}\0{access_key}"),
3082
3561
  }
3083
3562
 
3084
- def get_settings(self) -> dict[str, Any]:
3085
- path = self.workspace.resolve(".agentkit/settings.yaml")
3086
- data: dict[str, Any] = {}
3087
- if path.is_file():
3088
- try:
3089
- data = load_yaml_file(path) or {}
3090
- except Exception:
3091
- data = {}
3092
- defaults = {
3093
- "sandbox": os.environ.get("KSADK_CODEX_SANDBOX", "workspace-write-auto"),
3094
- "buildAfterCreate": True,
3095
- "codexProxy": current_proxy_mode(),
3096
- "cloudRegion": os.environ.get(
3097
- "AGENTENGINE_REGION", os.environ.get("KSYUN_REGION", "cn-beijing-6")
3098
- ),
3099
- "cloudBucket": os.environ.get("KS3_BUCKET", ""),
3100
- "cloudAccountId": (os.environ.get("KSYUN_ACCOUNT_ID", "").strip()),
3101
- # AK/SK 不回显(避免本地 UI 回传 secret);只暴露配置状态。
3102
- # 已配置 = 启动环境或已持久化 settings 里 AK+SK 齐全。
3103
- "cloudAccountConfigured": bool(
3104
- (os.environ.get("KSYUN_ACCESS_KEY") or os.environ.get("KS3_ACCESS_KEY", "")).strip()
3105
- and (
3106
- os.environ.get("KSYUN_SECRET_KEY") or os.environ.get("KS3_SECRET_KEY", "")
3107
- ).strip()
3108
- ),
3109
- "cloudSignedAccountConfigured": bool(
3110
- (os.environ.get("KSYUN_ACCESS_KEY") or os.environ.get("KS3_ACCESS_KEY", "")).strip()
3111
- and (
3112
- os.environ.get("KSYUN_SECRET_KEY") or os.environ.get("KS3_SECRET_KEY", "")
3113
- ).strip()
3114
- ),
3115
- "traceContent": os.environ.get("KSADK_STUDIO_TRACE_CONTENT", "1") != "0",
3116
- }
3117
- defaults.update({k: v for k, v in data.items() if k in defaults and v is not None})
3118
- defaults["codexProxy"] = normalize_proxy_mode(defaults.get("codexProxy"))
3119
- return defaults
3120
-
3121
- def update_settings(self, payload: dict[str, Any]) -> dict[str, Any]:
3122
- allowed = {
3123
- "sandbox",
3124
- "buildAfterCreate",
3125
- "codexProxy",
3126
- "cloudRegion",
3127
- "cloudBucket",
3128
- "traceContent",
3129
- # 云账号:AK/SK 留空 = 不修改(保留已存值);AccountID 可单独更新。
3130
- "cloudAccessKey",
3131
- "cloudSecretKey",
3132
- "cloudAccountId",
3133
- }
3134
- data = {k: payload[k] for k in allowed if k in payload}
3135
- if "cloudAccessKey" in data and not str(data["cloudAccessKey"]).strip():
3136
- data.pop("cloudAccessKey")
3137
- if "cloudSecretKey" in data and not str(data["cloudSecretKey"]).strip():
3138
- data.pop("cloudSecretKey")
3139
- if "cloudAccountId" in data:
3140
- data["cloudAccountId"] = str(data["cloudAccountId"]).strip()
3141
- if not data["cloudAccountId"]:
3142
- data.pop("cloudAccountId")
3143
- if data.get("sandbox") and data["sandbox"] not in {
3144
- "read-only",
3145
- "workspace-write",
3146
- "workspace-write-auto",
3147
- "full-access",
3148
- "read_only",
3149
- "workspace_write",
3150
- "workspace_write_auto",
3151
- "full_access",
3152
- }:
3153
- raise StudioError("SETTINGS_INVALID", "sandbox 取值非法", status_code=422)
3154
- if "codexProxy" in data and data["codexProxy"] not in {"auto", "forced", "direct"}:
3155
- raise StudioError("SETTINGS_INVALID", "codexProxy 取值非法", status_code=422)
3156
- path = self.workspace.resolve(".agentkit/settings.yaml")
3157
- self.workspace.atomic_write_yaml(path, data)
3158
- # env 桥接用落盘后的全量数据:局部更新(只改 AccountID)时,
3159
- # 已持久化的 AK/SK 也要继续桥接,否则签名凭证丢失。
3160
- try:
3161
- persisted = load_yaml_file(path) or {}
3162
- except Exception:
3163
- persisted = data
3164
- self._apply_settings_to_env(persisted if isinstance(persisted, dict) else data)
3165
- if self._cloud_gateway_override is None:
3166
- self.cloud.gateway = self._configured_cloud_gateway()
3167
- return self.get_settings()
3168
-
3169
- def _apply_persisted_settings(self) -> None:
3170
- """启动时把 settings.yaml 回填到进程环境。
3171
-
3172
- update_settings 只在 PUT 时桥接 env;重启后 env 丢失,运行解析
3173
- (如 _resolve_sandbox 读 KSADK_CODEX_SANDBOX)会回落默认,表现为
3174
- 「设置页显示 workspace-write-auto,实际运行 read-only」。
3175
- """
3176
- path = self.workspace.resolve(".agentkit/settings.yaml")
3177
- if not path.is_file():
3178
- return
3179
- try:
3180
- data = load_yaml_file(path) or {}
3181
- except Exception:
3182
- return
3183
- if isinstance(data, dict):
3184
- self._apply_settings_to_env(data)
3185
-
3186
3563
  @staticmethod
3187
- def _apply_settings_to_env(data: dict[str, Any]) -> None:
3188
- if data.get("sandbox"):
3189
- os.environ["KSADK_CODEX_SANDBOX"] = data["sandbox"]
3190
- if "codexProxy" in data:
3191
- proxy_env = proxy_mode_env_value(data["codexProxy"])
3192
- if proxy_env is None:
3193
- os.environ.pop("KSADK_CODEX_USE_PROXY", None)
3194
- else:
3195
- os.environ["KSADK_CODEX_USE_PROXY"] = proxy_env
3196
- if data.get("cloudRegion"):
3197
- os.environ["AGENTENGINE_REGION"] = data["cloudRegion"]
3198
- if data.get("cloudBucket"):
3199
- os.environ["KS3_BUCKET"] = data["cloudBucket"]
3200
- if "traceContent" in data:
3201
- os.environ["KSADK_STUDIO_TRACE_CONTENT"] = "1" if data["traceContent"] else "0"
3202
- # 云账号凭证:桥接到 KSYUN_* env(AgentEngineClient 的 V4 签名与
3203
- # X-Ksc-Account-Id 注入都从这里取值)。
3204
- if data.get("cloudAccessKey"):
3205
- os.environ["KSYUN_ACCESS_KEY"] = str(data["cloudAccessKey"])
3206
- if data.get("cloudSecretKey"):
3207
- os.environ["KSYUN_SECRET_KEY"] = str(data["cloudSecretKey"])
3208
- if data.get("cloudAccountId"):
3209
- os.environ["KSYUN_ACCOUNT_ID"] = str(data["cloudAccountId"])
3564
+ def frontend_assets() -> dict[str, Any]:
3565
+ import re
3210
3566
 
3211
- @staticmethod
3212
- def _configured_cloud_gateway() -> CloudDeploymentGateway:
3567
+ entry = Path(__file__).with_name("static") / "index.html"
3568
+ if not entry.is_file():
3569
+ return {"entryAssets": []}
3570
+ assets = re.findall(
3571
+ r'(?:src|href)="(/static/assets/[^"<>]+\.(?:js|css))"',
3572
+ entry.read_text(encoding="utf-8"),
3573
+ )
3574
+ return {"entryAssets": [Path(asset).name for asset in assets]}
3575
+
3576
+
3577
+
3578
+
3579
+
3580
+
3581
+ def _configured_cloud_gateway(self) -> CloudDeploymentGateway:
3213
3582
  """Compose the existing signed Code deployment path from process-only credentials."""
3214
3583
 
3584
+ environment = self.configuration.environment()
3215
3585
  access_key = (
3216
- os.environ.get("KSYUN_ACCESS_KEY") or os.environ.get("KS3_ACCESS_KEY", "")
3586
+ environment.get("KSYUN_ACCESS_KEY") or environment.get("KS3_ACCESS_KEY", "")
3217
3587
  ).strip()
3218
3588
  secret_key = (
3219
- os.environ.get("KSYUN_SECRET_KEY") or os.environ.get("KS3_SECRET_KEY", "")
3589
+ environment.get("KSYUN_SECRET_KEY") or environment.get("KS3_SECRET_KEY", "")
3220
3590
  ).strip()
3221
- configured_region = os.environ.get(
3222
- "AGENTENGINE_REGION", os.environ.get("KSYUN_REGION", "")
3591
+ configured_region = environment.get(
3592
+ "AGENTENGINE_REGION", environment.get("KSYUN_REGION", "")
3223
3593
  ).strip()
3224
- environment_region = os.environ.get("KSYUN_REGION", "").strip()
3594
+ environment_region = environment.get("KSYUN_REGION", "").strip()
3225
3595
  logical_region = (
3226
- "pre-online"
3227
- if environment_region.lower() == "pre-online"
3228
- else configured_region
3596
+ "pre-online" if environment_region.lower() == "pre-online" else configured_region
3229
3597
  )
3230
3598
  if not all((access_key, secret_key, logical_region)):
3231
3599
  return UnavailableCloudGateway()
3232
3600
  control_client = AgentEngineClient(
3601
+ base_url=environment.get("AGENTENGINE_SERVER_URL") or None,
3233
3602
  region=logical_region,
3234
3603
  access_key=access_key,
3235
3604
  secret_key=secret_key,
3236
3605
  )
3237
3606
  is_preonline = logical_region.lower() == "pre-online"
3238
- stream_base_url = os.environ.get("AGENTENGINE_STREAM_SERVER_URL", "").strip()
3607
+ stream_base_url = environment.get("AGENTENGINE_STREAM_SERVER_URL", "").strip()
3239
3608
  if not stream_base_url and is_preonline:
3240
3609
  # The pre-online KOP response path currently buffers SSE until
3241
3610
  # EOF, and KOP may not yet publish newly deployed native Action
@@ -3257,7 +3626,7 @@ class StudioService:
3257
3626
  client=control_client,
3258
3627
  stream_client=stream_client,
3259
3628
  managed_runtime_client=stream_client if is_preonline else None,
3260
- bucket=os.environ.get("KS3_BUCKET", "").strip() or None,
3629
+ bucket=environment.get("KS3_BUCKET", "").strip() or None,
3261
3630
  ks3_credentials={
3262
3631
  "access_key": access_key,
3263
3632
  "secret_key": secret_key,