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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (673) hide show
  1. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/METADATA +6 -3
  2. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/RECORD +591 -365
  3. ksadk/_build_provenance.json +1 -1
  4. ksadk/_process.py +83 -0
  5. ksadk/_str_enum.py +17 -0
  6. ksadk/a2ui/core.py +3 -3
  7. ksadk/api/client.py +6 -0
  8. ksadk/builders/code_builder.py +38 -12
  9. ksadk/builders/framework_requirements.py +20 -2
  10. ksadk/cli/__init__.py +36 -0
  11. ksadk/cli/cmd_config.py +4 -4
  12. ksadk/cli/cmd_create.py +12 -12
  13. ksadk/cli/cmd_hermes.py +24 -2
  14. ksadk/cli/cmd_invoke.py +28 -5
  15. ksadk/cli/cmd_openclaw.py +26 -1
  16. ksadk/cli/cmd_plugin.py +70 -12
  17. ksadk/cli/cmd_studio.py +64 -16
  18. ksadk/cli/openclaw_env.py +1 -1
  19. ksadk/cli/resource_common.py +26 -0
  20. ksadk/codex/client.py +3 -2
  21. ksadk/configs/__init__.py +1 -1
  22. ksadk/configs/env_registry.py +125 -31
  23. ksadk/configs/env_registry_studio.py +86 -0
  24. ksadk/configs/global_config.py +1 -1
  25. ksadk/configs/settings.py +3 -3
  26. ksadk/connector/__init__.py +17 -0
  27. ksadk/connector/channel.py +477 -0
  28. ksadk/context_engine/capabilities.py +52 -4
  29. ksadk/conversations/attachment_storage.py +10 -3
  30. ksadk/conversations/attachments.py +16 -5
  31. ksadk/conversations/message_projection.py +23 -32
  32. ksadk/conversations/normalize.py +28 -10
  33. ksadk/conversations/runtime_baseline.py +37 -0
  34. ksadk/conversations/runtime_invocation.py +17 -4
  35. ksadk/conversations/runtime_observability.py +39 -10
  36. ksadk/conversations/runtime_payloads.py +8 -0
  37. ksadk/conversations/runtime_persistence.py +105 -9
  38. ksadk/conversations/runtime_preparation.py +13 -7
  39. ksadk/conversations/runtime_stream_events.py +29 -35
  40. ksadk/conversations/runtime_streaming.py +8 -0
  41. ksadk/events/adapters/_codex_items.py +16 -8
  42. ksadk/events/adapters/_langgraph_support.py +34 -0
  43. ksadk/events/session_event.py +2 -2
  44. ksadk/harness/__init__.py +14 -0
  45. ksadk/harness/app.py +11 -0
  46. ksadk/harness/artifact_store.py +213 -0
  47. ksadk/harness/capabilities.py +115 -0
  48. ksadk/harness/capability_runtime.py +237 -0
  49. ksadk/harness/closure_contract.py +92 -0
  50. ksadk/harness/compaction_record.py +122 -0
  51. ksadk/harness/compiler.py +284 -0
  52. ksadk/harness/conformance/__init__.py +33 -0
  53. ksadk/harness/conformance/contract.py +506 -0
  54. ksadk/harness/conformance/fixtures.py +102 -0
  55. ksadk/harness/context_engine.py +403 -0
  56. ksadk/harness/context_maintenance.py +259 -0
  57. ksadk/harness/context_manifest.py +188 -0
  58. ksadk/harness/context_tuning.py +168 -0
  59. ksadk/harness/draft_runtime.py +322 -0
  60. ksadk/harness/engine/__init__.py +40 -0
  61. ksadk/harness/engine/base.py +122 -0
  62. ksadk/harness/engine/budgets.py +108 -0
  63. ksadk/harness/engine/capability_declarations.py +59 -0
  64. ksadk/harness/engine/completion_guard.py +42 -0
  65. ksadk/harness/engine/context_pipeline.py +579 -0
  66. ksadk/harness/engine/graph_builder.py +859 -0
  67. ksadk/harness/engine/langgraph.py +931 -0
  68. ksadk/harness/engine/mcp_disclosure.py +750 -0
  69. ksadk/harness/engine/policy_runtime.py +70 -0
  70. ksadk/harness/engine/postgres_checkpointer.py +63 -0
  71. ksadk/harness/engine/run_control_bridge.py +80 -0
  72. ksadk/harness/engine/run_types.py +88 -0
  73. ksadk/harness/engine/skill_disclosure.py +189 -0
  74. ksadk/harness/engine/spans.py +41 -0
  75. ksadk/harness/engine/subagents.py +343 -0
  76. ksadk/harness/engine/thread_ids.py +112 -0
  77. ksadk/harness/engine/tool_dispatch.py +144 -0
  78. ksadk/harness/event_tree.py +212 -0
  79. ksadk/harness/events.py +461 -0
  80. ksadk/harness/execution_policy.py +94 -0
  81. ksadk/harness/insights.py +210 -0
  82. ksadk/harness/lifecycle.py +578 -0
  83. ksadk/harness/lifecycle_conformance.py +233 -0
  84. ksadk/harness/lifecycle_local_plane.py +104 -0
  85. ksadk/harness/loop/__init__.py +44 -0
  86. ksadk/harness/loop/reason.py +454 -0
  87. ksadk/harness/loop/tools.py +762 -0
  88. ksadk/harness/managed_runtime.py +884 -0
  89. ksadk/harness/mcp_matrix.py +474 -0
  90. ksadk/harness/mcp_runtime.py +471 -0
  91. ksadk/harness/memory_consolidation.py +157 -0
  92. ksadk/harness/memory_loop.py +156 -0
  93. ksadk/harness/memory_runtime.py +541 -0
  94. ksadk/harness/metrics.py +90 -0
  95. ksadk/harness/model_capability.py +253 -0
  96. ksadk/harness/model_provider.py +220 -0
  97. ksadk/harness/observability/__init__.py +29 -0
  98. ksadk/harness/observability/inspection.py +528 -0
  99. ksadk/harness/observability/metrics.py +167 -0
  100. ksadk/harness/observability/otel_exporter.py +218 -0
  101. ksadk/harness/prompt_cache.py +70 -0
  102. ksadk/harness/public_activity.py +154 -0
  103. ksadk/harness/readiness.py +249 -0
  104. ksadk/harness/reasoner.py +466 -13
  105. ksadk/harness/release_readiness.py +140 -0
  106. ksadk/harness/resource_ref.py +69 -0
  107. ksadk/harness/run_control.py +668 -0
  108. ksadk/harness/runtime.py +146 -111
  109. ksadk/harness/runtime_capabilities.py +158 -0
  110. ksadk/harness/runtime_server.py +514 -0
  111. ksadk/harness/sandbox_adapters.py +739 -0
  112. ksadk/harness/sandbox_backend.py +530 -0
  113. ksadk/harness/sandbox_conformance.py +288 -0
  114. ksadk/harness/sandbox_lease.py +77 -0
  115. ksadk/harness/sandbox_lease_conformance.py +259 -0
  116. ksadk/harness/sandbox_matrix.py +170 -0
  117. ksadk/harness/sandbox_reconciliation.py +140 -0
  118. ksadk/harness/sandbox_recovery.py +586 -0
  119. ksadk/harness/sandbox_recovery_conformance.py +246 -0
  120. ksadk/harness/session_store.py +243 -0
  121. ksadk/harness/skill_composition.py +212 -0
  122. ksadk/harness/skill_feedback.py +123 -0
  123. ksadk/harness/skill_matrix.py +233 -0
  124. ksadk/harness/skill_runtime.py +259 -0
  125. ksadk/harness/spec.py +332 -0
  126. ksadk/harness/state.py +153 -0
  127. ksadk/harness/strategies.py +149 -0
  128. ksadk/harness/subagent.py +253 -0
  129. ksadk/harness/tool_policy.py +131 -0
  130. ksadk/harness/tool_receipts.py +96 -0
  131. ksadk/harness/tool_reliability.py +81 -0
  132. ksadk/harness/user_errors.py +69 -0
  133. ksadk/harness/working_context.py +81 -0
  134. ksadk/harness/working_context_patch.py +99 -0
  135. ksadk/identity/resolver.py +18 -0
  136. ksadk/interaction/__init__.py +1 -1
  137. ksadk/interaction/ledger.py +1 -1
  138. ksadk/interaction/provider.py +1 -1
  139. ksadk/interaction/providers/__init__.py +3 -1
  140. ksadk/interaction/providers/adk.py +1 -1
  141. ksadk/interaction/providers/codex.py +1 -1
  142. ksadk/interaction/providers/harness.py +50 -0
  143. ksadk/interaction/providers/langgraph.py +1 -1
  144. ksadk/kernel/__init__.py +10 -0
  145. ksadk/kernel/approval_presentation.py +91 -0
  146. ksadk/kernel/authorization.py +1 -1
  147. ksadk/kernel/bootstrap.py +86 -102
  148. ksadk/kernel/contract_fingerprints.py +1 -1
  149. ksadk/kernel/contracts.py +5 -0
  150. ksadk/kernel/control.py +32 -1
  151. ksadk/kernel/execution_grants.py +221 -0
  152. ksadk/kernel/execution_grants_memory.py +133 -0
  153. ksadk/kernel/execution_grants_postgres.py +217 -0
  154. ksadk/kernel/execution_grants_sqlite.py +209 -0
  155. ksadk/kernel/ingress.py +27 -27
  156. ksadk/kernel/mapping.py +1 -1
  157. ksadk/kernel/memory_store.py +24 -11
  158. ksadk/kernel/postgres_store.py +63 -33
  159. ksadk/kernel/recovery.py +78 -14
  160. ksadk/kernel/sql/001_agent_kernel.sql +23 -0
  161. ksadk/kernel/sqlite_store.py +304 -25
  162. ksadk/kernel/state.py +2 -3
  163. ksadk/kernel/store.py +69 -2
  164. ksadk/kernel/worker.py +79 -41
  165. ksadk/kernel/worker_history.py +72 -0
  166. ksadk/kernel/worker_identity.py +47 -0
  167. ksadk/memory/coordinator.py +22 -6
  168. ksadk/memory/extraction.py +40 -1
  169. ksadk/memory/models.py +77 -1
  170. ksadk/memory/provider_resolver.py +5 -0
  171. ksadk/memory/providers/local_postgres.py +200 -0
  172. ksadk/memory/providers/local_sqlite.py +42 -3
  173. ksadk/memory/retrieval.py +189 -0
  174. ksadk/memory/store_adapter.py +150 -0
  175. ksadk/model_policy.py +2 -2
  176. ksadk/model_proxy/detect.py +254 -0
  177. ksadk/model_proxy/server.py +4 -2
  178. ksadk/model_proxy/transform.py +40 -2
  179. ksadk/plugins/__init__.py +1 -1
  180. ksadk/plugins/bridges/dsh.py +11 -0
  181. ksadk/plugins/builtins.py +40 -2
  182. ksadk/plugins/companion_artifacts.py +83 -0
  183. ksadk/plugins/companions.py +368 -0
  184. ksadk/plugins/contracts.py +1 -1
  185. ksadk/plugins/dsh_channels.py +156 -0
  186. ksadk/plugins/dsh_home.py +140 -0
  187. ksadk/plugins/dsh_teams.py +105 -0
  188. ksadk/plugins/dsh_toolchain.py +101 -19
  189. ksadk/plugins/execution_host.py +99 -0
  190. ksadk/plugins/providers/bundles/dsh-channels-client/client.js +19 -0
  191. ksadk/plugins/providers/bundles/dsh-channels-client/cordis.patch.yml +3 -0
  192. ksadk/plugins/providers/bundles/dsh-channels-client/index.mjs +7 -0
  193. ksadk/plugins/providers/bundles/dsh-channels-client/package.json +12 -0
  194. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +1 -1
  195. ksadk/plugins/providers/bundles/dsh-memory/package.json +1 -1
  196. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +1 -1
  197. ksadk/plugins/providers/bundles/dsh-teams-client/client.js +29 -0
  198. ksadk/plugins/providers/bundles/dsh-teams-client/cordis.patch.yml +3 -0
  199. ksadk/plugins/providers/bundles/dsh-teams-client/index.mjs +11 -0
  200. ksadk/plugins/providers/bundles/dsh-teams-client/package.json +35 -0
  201. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/cordis.patch.yml +3 -0
  202. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/index.mjs +13 -0
  203. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/package.json +27 -0
  204. ksadk/plugins/providers/bundles/dsh-teams-profile/cordis.patch.yml +3 -0
  205. ksadk/plugins/providers/bundles/dsh-teams-profile/index.mjs +12 -0
  206. ksadk/plugins/providers/bundles/dsh-teams-profile/package.json +26 -0
  207. ksadk/plugins/providers/bundles/dsh-teams-router/cordis.patch.yml +3 -0
  208. ksadk/plugins/providers/bundles/dsh-teams-router/index.mjs +16 -0
  209. ksadk/plugins/providers/bundles/dsh-teams-router/package.json +27 -0
  210. ksadk/plugins/providers/bundles/dsh-teams-tasks/cordis.patch.yml +3 -0
  211. ksadk/plugins/providers/bundles/dsh-teams-tasks/index.mjs +16 -0
  212. ksadk/plugins/providers/bundles/dsh-teams-tasks/package.json +27 -0
  213. ksadk/plugins/providers/bundles/dsh-teams-tools/cordis.patch.yml +3 -0
  214. ksadk/plugins/providers/bundles/dsh-teams-tools/index.mjs +25 -0
  215. ksadk/plugins/providers/bundles/dsh-teams-tools/package.json +29 -0
  216. ksadk/plugins/providers/bundles/dsh-teams-tools/tools.json +235 -0
  217. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +1 -1
  218. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +51 -1
  219. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +2 -2
  220. ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/client.mjs +133 -0
  221. ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/index.mjs +14 -0
  222. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +27 -4
  223. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +9 -5
  224. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +1 -1
  225. ksadk/plugins/providers/codex.py +10 -2
  226. ksadk/plugins/providers/dsh_capabilities.py +61 -0
  227. ksadk/plugins/providers/harness.py +181 -33
  228. ksadk/plugins/providers/harness_delegation.py +593 -0
  229. ksadk/plugins/providers/harness_managed.py +456 -0
  230. ksadk/plugins/providers/harness_tools.py +326 -0
  231. ksadk/plugins/providers/shipped_dsh.py +4 -1
  232. ksadk/plugins/subagent_providers/codex.py +28 -6
  233. ksadk/plugins/teams/__init__.py +5 -0
  234. ksadk/plugins/teams/api.py +405 -0
  235. ksadk/plugins/teams/application.py +680 -0
  236. ksadk/plugins/teams/artifacts.py +60 -0
  237. ksadk/plugins/teams/context.py +96 -0
  238. ksadk/plugins/teams/contracts.py +136 -0
  239. ksadk/plugins/teams/domain.py +1427 -0
  240. ksadk/plugins/teams/domain_values.py +24 -0
  241. ksadk/plugins/teams/errors.py +13 -0
  242. ksadk/plugins/teams/migration.py +311 -0
  243. ksadk/plugins/teams/migration_cli.py +322 -0
  244. ksadk/plugins/teams/postgres_store.py +138 -0
  245. ksadk/plugins/teams/runtime.py +777 -0
  246. ksadk/plugins/teams/source_projection.py +84 -0
  247. ksadk/plugins/teams/store.py +311 -0
  248. ksadk/plugins/teams/task_decisions.py +423 -0
  249. ksadk/plugins/teams/transport.py +91 -0
  250. ksadk/plugins/teams/workspaces.py +255 -0
  251. ksadk/runners/_langgraph_runner_streams.py +121 -45
  252. ksadk/runners/_langgraph_state_reader.py +106 -0
  253. ksadk/runners/_session_identity.py +285 -0
  254. ksadk/runners/adk_runner.py +25 -60
  255. ksadk/runners/langgraph_runner.py +128 -111
  256. ksadk/runners/patch_langchain.py +47 -0
  257. ksadk/runners/usage_accumulator.py +11 -3
  258. ksadk/runtime/_runner_adapter/stream_mapping.py +52 -2
  259. ksadk/runtime/conversation_execution.py +25 -1
  260. ksadk/runtime/executor.py +9 -1
  261. ksadk/runtime/factory.py +36 -1
  262. ksadk/runtime/preprocessing.py +11 -3
  263. ksadk/runtime/runner_adapter.py +38 -9
  264. ksadk/runtime/skill_eval_result.py +36 -0
  265. ksadk/runtime/timing.py +46 -0
  266. ksadk/runtime/usage.py +49 -18
  267. ksadk/runtime_context.py +103 -1
  268. ksadk/sandbox/backends/e2b.py +245 -23
  269. ksadk/sandbox/backends/local_process.py +63 -39
  270. ksadk/sandbox/base.py +62 -1
  271. ksadk/sandbox/diagnostics.py +82 -0
  272. ksadk/sandbox/local_controls.py +746 -0
  273. ksadk/sandbox/local_launcher.py +90 -0
  274. ksadk/scheduler/dispatcher.py +1 -1
  275. ksadk/server/invocation_identity.py +118 -0
  276. ksadk/server/routes/common.py +32 -3
  277. ksadk/server/routes/control.py +64 -9
  278. ksadk/server/routes/dependencies.py +2 -1
  279. ksadk/server/routes/kernel_ingress.py +9 -1
  280. ksadk/server/routes/misc.py +233 -25
  281. ksadk/server/routes/models.py +3 -3
  282. ksadk/server/routes/openai_compat.py +76 -13
  283. ksadk/server/routes/run.py +106 -35
  284. ksadk/server/routes/sessions.py +244 -68
  285. ksadk/server/routes/workspace.py +130 -21
  286. ksadk/server/static/assets/{ArtifactsPanel-CGbWlMNh.js → ArtifactsPanel-C1YoaKhx.js} +1 -1
  287. ksadk/server/static/assets/{CodeBlock-b4C7upmO.js → CodeBlock-DHuAWfr5.js} +10 -7
  288. ksadk/server/static/assets/MathMessageMarkdown-cvdrBwYr.js +8 -0
  289. ksadk/server/static/assets/{MermaidBlock-BEBN4Ksz.js → MermaidBlock-DeBkbJvI.js} +9 -9
  290. ksadk/server/static/assets/{NativeTerminalPanel-zvL-WpAn.js → NativeTerminalPanel-oJj44_sV.js} +1 -1
  291. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-BYafW7Za.js → abnfDiagram-VCTEODGH-Dhfv25o2.js} +1 -1
  292. ksadk/server/static/assets/{arc-bTohInsS.js → arc-C35w-pn1.js} +1 -1
  293. ksadk/server/static/assets/architecture-7GRP2DOG-BCsa26zi.js +1 -0
  294. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-Ch5Lbzsi.js → architectureDiagram-5GKGNRK7-FoMY_u6D.js} +1 -1
  295. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-kqF4MDOG.js → blockDiagram-NRAW4CY4-zD4Rt7oE.js} +1 -1
  296. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-8uSRIODv.js → c4Diagram-UCG6FXSJ-BCtGGkhN.js} +1 -1
  297. ksadk/server/static/assets/channel-_KDifNys.js +1 -0
  298. ksadk/server/static/assets/chunk-2Q5K7J3B-HdVkJ9F0.js +1 -0
  299. ksadk/server/static/assets/{chunk-5VM5RSS4-DkhehZDr.js → chunk-5VM5RSS4-C2Ms13_k.js} +1 -1
  300. ksadk/server/static/assets/{chunk-F27PBJKO-BdXhtPe9.js → chunk-F27PBJKO-BoTj-qgx.js} +1 -1
  301. ksadk/server/static/assets/{chunk-G27WJ6UU-DPTpvpwi.js → chunk-G27WJ6UU-DOMyyjHH.js} +1 -1
  302. ksadk/server/static/assets/{chunk-JWPE2WC7-Pqoh38el.js → chunk-JWPE2WC7-DbJJqDli.js} +1 -1
  303. ksadk/server/static/assets/{chunk-LCL6LL3I-DeU00qC-.js → chunk-LCL6LL3I-CLuRCt_W.js} +1 -1
  304. ksadk/server/static/assets/{chunk-POPQ4Y6H-CzxScFkr.js → chunk-POPQ4Y6H-D0Dz847e.js} +1 -1
  305. ksadk/server/static/assets/{chunk-RHFEMEQ7-DpqMx-ux.js → chunk-RHFEMEQ7-BWSRzEcd.js} +1 -1
  306. ksadk/server/static/assets/{chunk-SVP7TREG-C6t0SypQ.js → chunk-SVP7TREG-CPoHqkCY.js} +1 -1
  307. ksadk/server/static/assets/{chunk-XXDRQBXY-DVaeafZk.js → chunk-XXDRQBXY-Bx1jS-X-.js} +1 -1
  308. ksadk/server/static/assets/classDiagram-DTDB5LWJ-BVCW3ZqZ.js +1 -0
  309. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-BVCW3ZqZ.js +1 -0
  310. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-Bf9D3tzJ.js → cose-bilkent-JH36ORCC-LzyWm4m0.js} +1 -1
  311. ksadk/server/static/assets/cynefin-OW5HDTMX-CNXjFctL.js +1 -0
  312. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-B9cY3iTz.js → cynefinDiagram-5FMLGOSQ-BlW_bHED.js} +1 -1
  313. ksadk/server/static/assets/{dagre-3AP2YEHR-CSwlx3CB.js → dagre-3AP2YEHR-Bu_S86_i.js} +1 -1
  314. ksadk/server/static/assets/{dagre-UBpgon5q.js → dagre-B7nCawed.js} +1 -1
  315. ksadk/server/static/assets/{diagram-S7CK7UJ4-C9akhN9a.js → diagram-S7CK7UJ4-W_Zow2Km.js} +1 -1
  316. ksadk/server/static/assets/{diagram-UQ7AKVKN-CgedhTPI.js → diagram-UQ7AKVKN-CLIKAHON.js} +1 -1
  317. ksadk/server/static/assets/{diagram-VSXAHHWV-Cjucz5BY.js → diagram-VSXAHHWV-Dv6_QAlN.js} +1 -1
  318. ksadk/server/static/assets/{diagram-VX7I27RA-Dd4Vleyn.js → diagram-VX7I27RA-BWAWRDtZ.js} +1 -1
  319. ksadk/server/static/assets/{diagram-Z3DM3KII-CZ2jGtYW.js → diagram-Z3DM3KII-XA_rWMss.js} +1 -1
  320. ksadk/server/static/assets/dist-0X_j2Rcc.js +1 -0
  321. ksadk/server/static/assets/{dist-DiixqL0J.js → dist-1nXCdsej.js} +1 -1
  322. ksadk/server/static/assets/{dist-BIr4DSRq.js → dist-2vL2sAdF.js} +1 -1
  323. ksadk/server/static/assets/{dist-D_ctSS2i.js → dist-B3bA05-e.js} +1 -1
  324. ksadk/server/static/assets/{dist-ClYUxfeK.js → dist-BLpRy_Yx.js} +1 -1
  325. ksadk/server/static/assets/{dist-QfkEHOlb.js → dist-BO_UwatH.js} +1 -1
  326. ksadk/server/static/assets/{dist-B3FR1SKK.js → dist-BdNFAney.js} +1 -1
  327. ksadk/server/static/assets/{dist-BnaTiyzN.js → dist-C0J5_3qM.js} +1 -1
  328. ksadk/server/static/assets/{dist-Bj730Ib4.js → dist-CGt_UGeO.js} +1 -1
  329. ksadk/server/static/assets/{dist-CFzsn6BG.js → dist-CIRMvUM4.js} +1 -1
  330. ksadk/server/static/assets/{dist-BgV_owcB.js → dist-CIpWk_5f.js} +1 -1
  331. ksadk/server/static/assets/{dist-C5_ZAZsG.js → dist-CPyieXEf.js} +1 -1
  332. ksadk/server/static/assets/{dist-btbmmX5O.js → dist-D-92S-Fd.js} +1 -1
  333. ksadk/server/static/assets/{dist-fBO2v5Kt.js → dist-DNKuMzWc.js} +1 -1
  334. ksadk/server/static/assets/{dist-ufY3F5p6.js → dist-DWfdmz9s.js} +2 -2
  335. ksadk/server/static/assets/{dist-DVCOWtha.js → dist-DppE_r-D.js} +1 -1
  336. ksadk/server/static/assets/{dist-C1NMAY5a.js → dist-DyG6Ya-z.js} +1 -1
  337. ksadk/server/static/assets/{dist-CB9iJrvg.js → dist-M-SrdhhZ.js} +1 -1
  338. ksadk/server/static/assets/{dist-DvFK7p5S.js → dist-mqD5TZup.js} +1 -1
  339. ksadk/server/static/assets/{dist-Cf125P_m.js → dist-n3n6t_FO.js} +1 -1
  340. ksadk/server/static/assets/{dist-DFD6Qa6T.js → dist-qe8xjesy.js} +1 -1
  341. ksadk/server/static/assets/{dist-DoVSwoDb.js → dist-t6MzE0jU.js} +1 -1
  342. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Ci8NqqZu.js → ebnfDiagram-PWID7BFC-BfCzF1Xi.js} +1 -1
  343. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CCIOhLZG.js → erDiagram-SSCWMZ5O-Dpz9_0zn.js} +1 -1
  344. ksadk/server/static/assets/eventmodeling-NTZA5JFV-B5-8RH9c.js +1 -0
  345. ksadk/server/static/assets/flowDiagram-A5DVABFB-BppFxEKw.js +1 -0
  346. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js → ganttDiagram-EL5Y4UJY-DDaG1f4_.js} +1 -1
  347. ksadk/server/static/assets/gitGraph-4MIJSDKK-B-AhYj4C.js +1 -0
  348. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js → gitGraphDiagram-WWUBYQGX-DcxzRwYC.js} +1 -1
  349. ksadk/server/static/assets/index-BMd2mucF.css +2 -0
  350. ksadk/server/static/assets/index-D5qyyhTH.js +244 -0
  351. ksadk/server/static/assets/info-A6RAGUB7-0uiKrC35.js +1 -0
  352. ksadk/server/static/assets/{infoDiagram-RXCK75RN-CO0rRTRA.js → infoDiagram-RXCK75RN-CYMdn6lQ.js} +1 -1
  353. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CHiaedSS.js → ishikawaDiagram-5VMMS53U-CLHFAD6c.js} +1 -1
  354. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-CHcCIB09.js → journeyDiagram-EYS64GPL-BHSKQGAl.js} +1 -1
  355. ksadk/server/static/assets/{kanban-definition-3QL26DDD-CJ_ebBZf.js → kanban-definition-3QL26DDD-D5W3tjTT.js} +1 -1
  356. ksadk/server/static/assets/{katex-B4weu383.js → katex-mtjOi4KM.js} +1 -1
  357. ksadk/server/static/assets/{linear-V-MgYHW1.js → linear-BETqsxE_.js} +1 -1
  358. ksadk/server/static/assets/{mermaid-parser.core-CBijEX_c.js → mermaid-parser.core-DPWrvs90.js} +2 -2
  359. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-Bc-pQvpp.js → mindmap-definition-FBJOCRG2-CJG2mfBP.js} +1 -1
  360. ksadk/server/static/assets/packet-AYTQ26CC-BVTmZ_cw.js +1 -0
  361. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-D7genGLl.js → pegDiagram-XKGWAZYB-GjAPNaqn.js} +1 -1
  362. ksadk/server/static/assets/pie-WAS4IAKB-DyfxBU7V.js +1 -0
  363. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-Bxj32zwD.js → pieDiagram-E7YTZNPT-ToIewrqr.js} +1 -1
  364. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BURv2mGh.js → quadrantDiagram-AXDQQJYC-4d78KiEY.js} +1 -1
  365. ksadk/server/static/assets/radar-RG4KPBEZ-FFontjL2.js +1 -0
  366. ksadk/server/static/assets/railroad-74A4TZTK-D0Uidzen.js +1 -0
  367. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BOo_9T2h.js +1 -0
  368. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-D6-BjW7Z.js +1 -0
  369. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CXx__yMm.js +1 -0
  370. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-CCsh3avW.js → railroadDiagram-O6MQD6OU-DKzx4xfv.js} +1 -1
  371. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-_FRRBKEd.js → requirementDiagram-EFPCY7ZU-CJYljxQS.js} +1 -1
  372. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-C-gr2o9M.js → sankeyDiagram-P5KCCOFB-DLU2fV1w.js} +1 -1
  373. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-D97NmfKg.js → sequenceDiagram-WJ2MYXX4-CVqysrA9.js} +1 -1
  374. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DjrPC5FX.js → sizeCapture-X5ZJPWSS-BUxfmTHc.js} +1 -1
  375. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DzMNg1hh.js → stateDiagram-HBIQ2CUA-CNFgYI9E.js} +1 -1
  376. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BXAFScz8.js +1 -0
  377. ksadk/server/static/assets/{swimlanes-XN3QIQJK-Cssf_CsU.js → swimlanes-XN3QIQJK-B6qCMe8N.js} +1 -1
  378. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uIQ2lJKH.js +8 -0
  379. ksadk/server/static/assets/{timeline-definition-24CTP7MA-BWTHzyS1.js → timeline-definition-24CTP7MA-CMD3x_U_.js} +1 -1
  380. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5GgucZ.js +1 -0
  381. ksadk/server/static/assets/treemap-WGGIJYW6-Bq1u1SpG.js +1 -0
  382. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-BSKgJsmR.js → vennDiagram-4TSXK5OY-BqtUqvXM.js} +1 -1
  383. ksadk/server/static/assets/wardley-WFR3VGLG-QAt06uEz.js +1 -0
  384. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-eflHNoaZ.js → wardleyDiagram-VM6X3IG4-B5KfDjI-.js} +1 -1
  385. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-eYqrQ-v4.js → xychartDiagram-S5SC5T6Z-BaUlSZrn.js} +1 -1
  386. ksadk/server/static/index.html +2 -2
  387. ksadk/server/terminal_sessions.py +34 -2
  388. ksadk/sessions/invocation_identity.py +235 -0
  389. ksadk/skills/__init__.py +26 -0
  390. ksadk/skills/events.py +464 -0
  391. ksadk/skills/manifest_cache.py +263 -0
  392. ksadk/skills/mcp_server/__init__.py +0 -0
  393. ksadk/skills/mcp_server/_registry.py +33 -0
  394. ksadk/skills/mcp_server/_routing.py +26 -0
  395. ksadk/skills/mcp_server/_workspace_files.py +160 -0
  396. ksadk/skills/mcp_server/register.py +415 -0
  397. ksadk/skills/mcp_server/server.py +218 -0
  398. ksadk/skills/models.py +11 -0
  399. ksadk/skills/observability.py +132 -0
  400. ksadk/skills/package_store.py +75 -2
  401. ksadk/skills/runtime/agent.py +38 -5
  402. ksadk/skills/runtime/artifacts.py +87 -0
  403. ksadk/skills/runtime/backends/e2b.py +393 -52
  404. ksadk/skills/runtime/backends/local.py +621 -119
  405. ksadk/skills/runtime/base.py +78 -7
  406. ksadk/skills/runtime/executor.py +266 -1
  407. ksadk/skills/runtime/loader.py +108 -3
  408. ksadk/skills/runtime/request.py +18 -0
  409. ksadk/skills/tool_defs.py +108 -3
  410. ksadk/studio/api.py +592 -57
  411. ksadk/studio/api_contracts.py +8 -2
  412. ksadk/studio/api_plugin_routes.py +39 -12
  413. ksadk/studio/api_resource_connections.py +79 -41
  414. ksadk/studio/authoring.py +12 -6
  415. ksadk/studio/authoring_coordinator.py +4 -2
  416. ksadk/studio/builder.py +12 -0
  417. ksadk/studio/capabilities.py +23 -6
  418. ksadk/studio/channel_connections.py +333 -0
  419. ksadk/studio/cloud.py +30 -10
  420. ksadk/studio/cloud_shared_web.py +75 -2
  421. ksadk/studio/codex_agent_service.py +2 -2
  422. ksadk/studio/codex_builder.py +1 -1
  423. ksadk/studio/codex_run.py +6 -1
  424. ksadk/studio/compiler.py +10 -0
  425. ksadk/studio/configuration.py +182 -0
  426. ksadk/studio/contracts.py +33 -5
  427. ksadk/studio/dsh_application.py +135 -25
  428. ksadk/studio/dsh_capability_service.py +287 -20
  429. ksadk/studio/dsh_lifecycle.py +58 -0
  430. ksadk/studio/dsh_provider_registration.py +55 -16
  431. ksadk/studio/entry.py +53 -0
  432. ksadk/studio/event_store.py +36 -5
  433. ksadk/studio/execution_host.py +525 -0
  434. ksadk/studio/framework_run.py +32 -10
  435. ksadk/studio/hosted_kernel.py +1 -1
  436. ksadk/studio/kernel_registry.py +418 -0
  437. ksadk/studio/kernel_sqlite_migration.py +181 -0
  438. ksadk/studio/model_client.py +1178 -64
  439. ksadk/studio/model_profile_service.py +26 -11
  440. ksadk/studio/native_documents.py +172 -0
  441. ksadk/studio/plugin_composition.py +13 -2
  442. ksadk/studio/plugin_kernel_adapter.py +15 -0
  443. ksadk/studio/plugin_lifecycle.py +80 -0
  444. ksadk/studio/plugin_runtime.py +230 -17
  445. ksadk/studio/provider_recovery.py +59 -0
  446. ksadk/studio/recovery_page.py +70 -0
  447. ksadk/studio/resource_authority.py +59 -32
  448. ksadk/studio/resource_catalog.py +6 -0
  449. ksadk/studio/run_activity.py +895 -0
  450. ksadk/studio/run_documents.py +127 -0
  451. ksadk/studio/run_service.py +329 -33
  452. ksadk/studio/runtime_catalog.py +53 -10
  453. ksadk/studio/runtime_source.py +1 -1
  454. ksadk/studio/scheduler_runtime.py +32 -289
  455. ksadk/studio/service.py +398 -103
  456. ksadk/studio/shared_web.py +149 -36
  457. ksadk/studio/static/assets/ChannelsPage-D_PGmKVq.js +8 -0
  458. ksadk/studio/static/assets/CodeBlock-DMIf4h33-UIqo-BPW.js +44 -0
  459. ksadk/studio/static/assets/ExecutionTree-v3HexvPo-Bk8wzGSy.js +1 -0
  460. ksadk/studio/static/assets/MathMessageMarkdown-BesSeCYl-OhNwH4K9.js +8 -0
  461. ksadk/studio/static/assets/MermaidBlock-H_0qzQDf-BdXtxug_.js +11 -0
  462. ksadk/studio/static/assets/MessageMarkdown-CwMTvgFj-g0I-I4dD.js +59 -0
  463. ksadk/studio/static/assets/PrismRenderer-5pK6tUdb.js +3 -0
  464. ksadk/studio/static/assets/TeamsPage-DqX4HWKQ.js +3 -0
  465. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-Bnb1O3tA.js +1 -0
  466. ksadk/studio/static/assets/architecture-7GRP2DOG-BMOPAkUC.js +1 -0
  467. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-5Zn1gqJv.js +36 -0
  468. ksadk/studio/static/assets/{blockDiagram-I7D4REHJ-CFmPl1de.js → blockDiagram-I7D4REHJ-CLB4L11u.js} +6 -6
  469. ksadk/studio/static/assets/{c4Diagram-7LVT6UL2-BRrGu8qt.js → c4Diagram-7LVT6UL2-BOma_Z_F.js} +7 -7
  470. ksadk/studio/static/assets/channel-r8itPEik.js +1 -0
  471. ksadk/studio/static/assets/chunk-2E4U76K2-BFf_huql.js +2 -0
  472. ksadk/studio/static/assets/chunk-2ZTRR5NV-C2qZJila.js +2 -0
  473. ksadk/studio/static/assets/chunk-3Z5EZCMW-DMniOlPd.js +1 -0
  474. ksadk/studio/static/assets/{chunk-4HAMMTFA-D220vUtq.js → chunk-4HAMMTFA-DVtDP4rm.js} +7 -7
  475. ksadk/studio/static/assets/chunk-5V3GS4D5-i-ZDOEnP.js +1 -0
  476. ksadk/studio/static/assets/chunk-6AZGARVD-BB6FqMl-.js +1 -0
  477. ksadk/studio/static/assets/chunk-6EIED4P4-DdUJkP0f.js +1 -0
  478. ksadk/studio/static/assets/chunk-6K3QC6MW-CqVsVn-y.js +1 -0
  479. ksadk/studio/static/assets/chunk-6TQVIW2G-DKlLbNIP.js +1 -0
  480. ksadk/studio/static/assets/chunk-747NJXEK-BFkZPlab.js +2 -0
  481. ksadk/studio/static/assets/chunk-75Z2AOVW-BZNhM4vB.js +2 -0
  482. ksadk/studio/static/assets/chunk-CLGD4ZFX-D-GTtyKs.js +1 -0
  483. ksadk/studio/static/assets/{chunk-DU6HZSFF-C4DtVpCu.js → chunk-DU6HZSFF-CpEZCUgg.js} +1 -1
  484. ksadk/studio/static/assets/chunk-F27PBJKO-D7pvKf0C.js +1 -0
  485. ksadk/studio/static/assets/{chunk-GMAD6QVW-DiQA-u2N.js → chunk-GMAD6QVW-DE_8H717.js} +6 -6
  486. ksadk/studio/static/assets/chunk-GVQU2GXP-BfEB0lNv.js +1 -0
  487. ksadk/studio/static/assets/chunk-I5DQTOEV-Hm2LfiYI.js +1 -0
  488. ksadk/studio/static/assets/chunk-ICYGCRZG-749o-pGJ.js +1 -0
  489. ksadk/studio/static/assets/chunk-IH6LHLGP-CC6I9F3i.js +1 -0
  490. ksadk/studio/static/assets/{chunk-IMKFNOWR-BSlbjT_b.js → chunk-IMKFNOWR-D38axYOR.js} +5 -5
  491. ksadk/studio/static/assets/chunk-KI3K4JFJ-Rma-0k_M.js +1 -0
  492. ksadk/studio/static/assets/chunk-L3NEJ4N5-Dq5xn7aL.js +1 -0
  493. ksadk/studio/static/assets/chunk-LNGE3PJU-DWpGwHrW.js +34 -0
  494. ksadk/studio/static/assets/{chunk-OSK3NFVY-M2m6G3j4.js → chunk-OSK3NFVY-DiCQjx9b.js} +5 -5
  495. ksadk/studio/static/assets/chunk-OUJLGHUK-D0j2JRSg.js +2 -0
  496. ksadk/studio/static/assets/{chunk-P2QGCYS3-DezaQxiK.js → chunk-P2QGCYS3-VdhKmfYq.js} +1 -1
  497. ksadk/studio/static/assets/chunk-POPQ4Y6H-C1_rzO5M.js +1 -0
  498. ksadk/studio/static/assets/chunk-PWAF6VOD-B45HvflI.js +1 -0
  499. ksadk/studio/static/assets/{chunk-SHT3W25Y-DAyIVp5H.js → chunk-SHT3W25Y-DsCFnRVE.js} +9 -9
  500. ksadk/studio/static/assets/{chunk-SVP7TREG-DulomOrS.js → chunk-SVP7TREG-DljApgRX.js} +1 -1
  501. ksadk/studio/static/assets/{chunk-TICWLB2K-bHJYoflj.js → chunk-TICWLB2K-DWqRtyqa.js} +6 -6
  502. ksadk/studio/static/assets/chunk-TLUHSLCS-DUeGgnD5.js +2 -0
  503. ksadk/studio/static/assets/chunk-UY3FDG6J-CnmaAkG5.js +1 -0
  504. ksadk/studio/static/assets/chunk-XHIXRSVI-BFQ6B8BE.js +1 -0
  505. ksadk/studio/static/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
  506. ksadk/studio/static/assets/classDiagram-ZZMXUADV-DjeMNJmu.js +1 -0
  507. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-DjeMNJmu.js +1 -0
  508. ksadk/studio/static/assets/clsx-DB0hHKMi.js +1 -0
  509. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-om8AY0Mc.js +1 -0
  510. ksadk/studio/static/assets/createLucideIcon-DR0LGTP5.js +1 -0
  511. ksadk/studio/static/assets/cynefin-OW5HDTMX-7tP7QfM3.js +1 -0
  512. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-6BrmK52S.js +62 -0
  513. ksadk/studio/static/assets/dagre-GXQ25YYZ-buZBRlwz.js +4 -0
  514. ksadk/studio/static/assets/{diagram-S7CK7UJ4-0BZ98mya.js → diagram-S7CK7UJ4-C6aH78c4.js} +3 -3
  515. ksadk/studio/static/assets/diagram-UQ7AKVKN-DY_tQ6C_.js +41 -0
  516. ksadk/studio/static/assets/diagram-VSXAHHWV-DX9p5cQT.js +3 -0
  517. ksadk/studio/static/assets/diagram-VX7I27RA-DB2WSH8X.js +24 -0
  518. ksadk/studio/static/assets/diagram-Z3DM3KII-Ce1BJwHE.js +24 -0
  519. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-Daukxwqf.js +1 -0
  520. ksadk/studio/static/assets/{erDiagram-RLTQ6QDP-DLGry2Ap.js → erDiagram-RLTQ6QDP-CGthTMmJ.js} +6 -6
  521. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-BR2FzK4R.js +1 -0
  522. ksadk/studio/static/assets/flowDiagram-HODETNUW-CZ1tEenp.js +1 -0
  523. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BfoAZW9X.js +292 -0
  524. ksadk/studio/static/assets/gitGraph-4MIJSDKK-DYlXv_yJ.js +1 -0
  525. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-S985OIJF.js +106 -0
  526. ksadk/studio/static/assets/iconfont-4HN3C9Pg.woff2 +0 -0
  527. ksadk/studio/static/assets/index-CfEnms6Y.css +2 -0
  528. ksadk/studio/static/assets/index-Dp61rOWZ.js +0 -0
  529. ksadk/studio/static/assets/index.dom-BQenBtFm.js +1 -0
  530. ksadk/studio/static/assets/info-A6RAGUB7-BlU-8_xu.js +1 -0
  531. ksadk/studio/static/assets/infoDiagram-27XIBGKW-CO3W8tFn.js +2 -0
  532. ksadk/studio/static/assets/{ishikawaDiagram-5VMMS53U-CljI2wyf.js → ishikawaDiagram-5VMMS53U-BUGEl8cO.js} +2 -2
  533. ksadk/studio/static/assets/{journeyDiagram-3NMN7TZE-D50Fo2sL.js → journeyDiagram-3NMN7TZE-Ch2ZYxvr.js} +6 -6
  534. ksadk/studio/static/assets/{kanban-definition-UXKFOSKX-DimfOTam.js → kanban-definition-UXKFOSKX-Da-Fp4vC.js} +3 -3
  535. ksadk/studio/static/assets/kingsoft-cloud-BOcLiQ3e.ico +0 -0
  536. ksadk/studio/static/assets/{line-CX5BOOUP.js → line-BDaeq300.js} +1 -1
  537. ksadk/studio/static/assets/linear-DmucvK78.js +1 -0
  538. ksadk/studio/static/assets/mermaid-parser.core-Cj5mYdBi.js +4 -0
  539. ksadk/studio/static/assets/{mindmap-definition-YA3MSWOX-Bizzqy5R.js → mindmap-definition-YA3MSWOX-CvlsVQ38.js} +1 -1
  540. ksadk/studio/static/assets/packet-AYTQ26CC-BSJEH9Lb.js +1 -0
  541. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-BuHuNgT5.js +1 -0
  542. ksadk/studio/static/assets/pie-WAS4IAKB-qxv01Y8W.js +1 -0
  543. ksadk/studio/static/assets/{pieDiagram-E7YTZNPT-B9mrFSDF.js → pieDiagram-E7YTZNPT-DlrWiSOv.js} +1 -1
  544. ksadk/studio/static/assets/preload-helper-CO68xz6u.js +1 -0
  545. ksadk/studio/static/assets/presentation-yYw7xK60-BmcZriri.js +1 -0
  546. ksadk/studio/static/assets/{quadrantDiagram-AXDQQJYC-NzUfCbMR.js → quadrantDiagram-AXDQQJYC-BA3hpUZM.js} +6 -6
  547. ksadk/studio/static/assets/radar-RG4KPBEZ-B6h6pWOs.js +1 -0
  548. ksadk/studio/static/assets/railroad-74A4TZTK-CGtTWdGc.js +1 -0
  549. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-Cq7y22IA.js +1 -0
  550. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-V0aQVv9m.js +1 -0
  551. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-BQiIsX_p.js +1 -0
  552. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-BxpAazym.js +1 -0
  553. ksadk/studio/static/assets/{requirementDiagram-BXWQKSXE-BF3d103U.js → requirementDiagram-BXWQKSXE-E-Ge0FcV.js} +1 -1
  554. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-CA6YKhQ3.js +40 -0
  555. ksadk/studio/static/assets/{sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js → sequenceDiagram-WJ2MYXX4-CcElXGg4.js} +9 -9
  556. ksadk/studio/static/assets/src-B6xuSHsQ.js +1 -0
  557. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DdXZOFqY.js +1 -0
  558. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-CJbOM-QK.js +1 -0
  559. ksadk/studio/static/assets/swimlanes-42K2YHIH-NtgEEHLY.js +1 -0
  560. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-D-AVlW8B.js +8 -0
  561. ksadk/studio/static/assets/{timeline-definition-24CTP7MA-DxmSSjRB.js → timeline-definition-24CTP7MA-CIuYhNy3.js} +7 -7
  562. ksadk/studio/static/assets/treeView-Q6P3EWNA-BTTYcvrF.js +1 -0
  563. ksadk/studio/static/assets/treemap-WGGIJYW6-Cg7tyfH8.js +1 -0
  564. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-7HbApbrv.js +34 -0
  565. ksadk/studio/static/assets/wardley-WFR3VGLG-C6N1rULY.js +1 -0
  566. ksadk/studio/static/assets/{wardleyDiagram-VM6X3IG4-Ba1AOWoe.js → wardleyDiagram-VM6X3IG4-CMJiaedy.js} +1 -1
  567. ksadk/studio/static/assets/{xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js → xychartDiagram-S5SC5T6Z-BdgtMvW2.js} +6 -6
  568. ksadk/studio/static/index.html +8 -2
  569. ksadk/studio/teams_catalog.py +133 -0
  570. ksadk/studio/teams_installation.py +214 -0
  571. ksadk/studio/teams_node.py +545 -0
  572. ksadk/studio/teams_node_runner.py +69 -0
  573. ksadk/studio/teams_remote.py +274 -0
  574. ksadk/studio/templates.py +40 -19
  575. ksadk/studio/validator.py +13 -0
  576. ksadk/studio/workspace.py +19 -4
  577. ksadk/studio/workspace_plugins.py +136 -0
  578. ksadk/studio/workspace_registry.py +286 -0
  579. ksadk/toolsets/__init__.py +11 -0
  580. ksadk/toolsets/skills.py +446 -378
  581. ksadk/toolsets/workspace.py +3 -3
  582. ksadk/toolsets/workspace_identity.py +15 -0
  583. ksadk/version.py +1 -1
  584. ksadk_runtime_common/memory_backend/providers/lancedb.py +56 -2
  585. ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -148
  586. ksadk_runtime_common/workspace_files/router.py +26 -13
  587. ksadk/server/static/assets/MathMessageMarkdown-DbdW5A4_.js +0 -8
  588. ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +0 -1
  589. ksadk/server/static/assets/channel-CF5Up3hQ.js +0 -1
  590. ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +0 -1
  591. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +0 -1
  592. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +0 -1
  593. ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +0 -1
  594. ksadk/server/static/assets/dist-B2_CVgKv.js +0 -1
  595. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +0 -1
  596. ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +0 -1
  597. ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +0 -1
  598. ksadk/server/static/assets/index-DcTML1Up.css +0 -2
  599. ksadk/server/static/assets/index-Dh2XHqPK.js +0 -244
  600. ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +0 -1
  601. ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +0 -1
  602. ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +0 -1
  603. ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +0 -1
  604. ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +0 -1
  605. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +0 -1
  606. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +0 -1
  607. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +0 -1
  608. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +0 -1
  609. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +0 -8
  610. ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +0 -1
  611. ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +0 -1
  612. ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +0 -1
  613. ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +0 -41
  614. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +0 -8
  615. ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +0 -44
  616. ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +0 -3
  617. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +0 -1
  618. ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +0 -1
  619. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +0 -36
  620. ksadk/studio/static/assets/channel-BqO-gtEw.js +0 -1
  621. ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +0 -2
  622. ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +0 -1
  623. ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +0 -1
  624. ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +0 -1
  625. ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +0 -1
  626. ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +0 -1
  627. ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +0 -1
  628. ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +0 -1
  629. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +0 -1
  630. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +0 -1
  631. ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +0 -1
  632. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +0 -62
  633. ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +0 -4
  634. ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +0 -41
  635. ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +0 -3
  636. ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +0 -24
  637. ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +0 -24
  638. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +0 -1
  639. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +0 -1
  640. ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +0 -1
  641. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +0 -292
  642. ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +0 -1
  643. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +0 -106
  644. ksadk/studio/static/assets/index-CeHL9ARV.css +0 -2
  645. ksadk/studio/static/assets/index-D9QEcVpL.js +0 -320
  646. ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +0 -1
  647. ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +0 -2
  648. ksadk/studio/static/assets/linear-BCxN9JLv.js +0 -1
  649. ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +0 -7
  650. ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +0 -1
  651. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +0 -1
  652. ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +0 -1
  653. ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +0 -1
  654. ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +0 -1
  655. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +0 -1
  656. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +0 -1
  657. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +0 -1
  658. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +0 -1
  659. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +0 -40
  660. ksadk/studio/static/assets/src-SFn9St9H.js +0 -1
  661. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +0 -1
  662. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +0 -1
  663. ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +0 -1
  664. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +0 -8
  665. ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +0 -1
  666. ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +0 -1
  667. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +0 -34
  668. ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +0 -1
  669. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/WHEEL +0 -0
  670. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/entry_points.txt +0 -0
  671. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/licenses/LICENSE +0 -0
  672. {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/top_level.txt +0 -0
  673. /ksadk/studio/static/assets/{MathMessageMarkdown-CBcDrAw--BEOyPC3w.css → MathMessageMarkdown-BesSeCYl-BEOyPC3w.css} +0 -0
@@ -0,0 +1,739 @@
1
+ """Adapters from the SDK sandbox sessions to the Harness async contract.
2
+
3
+ ``ksadk.sandbox`` deliberately exposes a small synchronous session API used by
4
+ the SDK and Skill Runtime. The Harness owns a different, asynchronous
5
+ lifecycle contract. This module bridges the two without claiming guarantees
6
+ that the wrapped backend cannot provide.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import asyncio
12
+ import math
13
+ import shlex
14
+ import time
15
+ from collections.abc import Callable, Iterable
16
+ from typing import cast
17
+ from uuid import uuid4
18
+
19
+ from ksadk.harness.sandbox_backend import (
20
+ ExecuteRequest,
21
+ ExecuteResult,
22
+ FilesystemIsolation,
23
+ NetworkControl,
24
+ SandboxAuditLog,
25
+ SandboxBackendCapabilities,
26
+ SandboxClosedError,
27
+ SandboxCommandResumeToken,
28
+ SandboxHandle,
29
+ SandboxPolicyViolation,
30
+ SandboxResumeToken,
31
+ SandboxSpec,
32
+ )
33
+ from ksadk.harness.sandbox_lease import (
34
+ SandboxLeaseConflict,
35
+ SandboxLeaseGrant,
36
+ SandboxLeaseProvider,
37
+ SandboxLeaseScope,
38
+ )
39
+ from ksadk.sandbox.backends.e2b import E2BSandboxBackend
40
+ from ksadk.sandbox.backends.local_process import LocalProcessSandboxBackend
41
+ from ksadk.sandbox.base import (
42
+ ArtifactListingSandboxSession,
43
+ BackgroundCommandSandboxSession,
44
+ ReconnectableCommandSandboxSession,
45
+ ReconnectableSandboxCommandHandle,
46
+ SandboxCommandHandle,
47
+ SandboxCommandResult,
48
+ SandboxSession,
49
+ )
50
+ from ksadk.sandbox.base import (
51
+ ReconnectableSandboxBackend as SdkReconnectableSandboxBackend,
52
+ )
53
+ from ksadk.sandbox.base import SandboxBackend as SdkSandboxBackend
54
+
55
+ ArtifactCollector = Callable[[SandboxSession], Iterable[str]]
56
+
57
+
58
+ class SessionSandboxHandle(SandboxHandle):
59
+ """Harness handle backed by one SDK ``SandboxSession``."""
60
+
61
+ def __init__(
62
+ self,
63
+ spec: SandboxSpec,
64
+ session: SandboxSession,
65
+ *,
66
+ lease: SandboxLeaseGrant | None = None,
67
+ ) -> None:
68
+ super().__init__(spec)
69
+ self.session = session
70
+ self.lease = lease
71
+
72
+
73
+ class SessionSandboxCommand:
74
+ """One background command owned by a ``SessionSandboxBackendAdapter``."""
75
+
76
+ def __init__(
77
+ self,
78
+ *,
79
+ adapter: SessionSandboxBackendAdapter,
80
+ sandbox: SessionSandboxHandle,
81
+ request: ExecuteRequest,
82
+ command_handle: SandboxCommandHandle,
83
+ ) -> None:
84
+ self._adapter = adapter
85
+ self.sandbox = sandbox
86
+ self.request = request
87
+ self.command_handle = command_handle
88
+ self.started_at = time.monotonic()
89
+ self.completed = False
90
+
91
+
92
+ class SessionSandboxBackendAdapter:
93
+ """Run a synchronous SDK sandbox backend behind the Harness contract.
94
+
95
+ Optional session protocols provide cancellation and Artifact enumeration.
96
+ A backend may only advertise those capabilities when each created session
97
+ implements the corresponding protocol; otherwise execution fails loudly
98
+ instead of silently degrading its isolation claim.
99
+ """
100
+
101
+ def __init__(
102
+ self,
103
+ backend: SdkSandboxBackend,
104
+ *,
105
+ capabilities: SandboxBackendCapabilities,
106
+ artifact_collector: ArtifactCollector | None = None,
107
+ audit_log: SandboxAuditLog | None = None,
108
+ lease_provider: SandboxLeaseProvider | None = None,
109
+ lease_scope: SandboxLeaseScope | None = None,
110
+ lease_owner_id: str | None = None,
111
+ lease_ttl_seconds: float = 120.0,
112
+ configured_workspace_root: str | None = None,
113
+ prepare_workspace: bool = False,
114
+ ) -> None:
115
+ if artifact_collector is not None and not capabilities.artifact_collection:
116
+ raise ValueError("提供 artifact_collector 时必须声明 artifact_collection")
117
+ if capabilities.execution_audit != (audit_log is not None):
118
+ raise ValueError("execution_audit 能力声明必须与 audit_log 装配一致")
119
+ if capabilities.reconnect and not isinstance(backend, SdkReconnectableSandboxBackend):
120
+ raise ValueError("后端声明 reconnect 但未实现 reconnect_session")
121
+ if capabilities.ownership_fencing != (lease_provider is not None):
122
+ raise ValueError("ownership_fencing 能力声明必须与 lease_provider 装配一致")
123
+ if (lease_provider is not None) != (lease_scope is not None):
124
+ raise ValueError("lease_provider 与 lease_scope 必须同时装配")
125
+ if capabilities.command_reconnect and not (
126
+ capabilities.reconnect
127
+ and capabilities.ownership_fencing
128
+ and capabilities.cooperative_cancellation
129
+ ):
130
+ raise ValueError(
131
+ "command_reconnect 依赖 reconnect、ownership_fencing 和 cooperative_cancellation"
132
+ )
133
+ if lease_provider is not None and not capabilities.reconnect:
134
+ raise ValueError("Sandbox 租约 fencing 只适用于支持 reconnect 的后端")
135
+ if lease_ttl_seconds <= 0:
136
+ raise ValueError("lease_ttl_seconds 必须大于 0")
137
+ self._backend = backend
138
+ self._capabilities = capabilities
139
+ self._artifact_collector = artifact_collector
140
+ self._audit = audit_log
141
+ self._lease_provider = lease_provider
142
+ self._lease_scope = lease_scope
143
+ self._lease_owner_id = (lease_owner_id or f"harness-{uuid4().hex}").strip()
144
+ if lease_provider is not None and not self._lease_owner_id:
145
+ raise ValueError("lease_owner_id 不能为空")
146
+ self._lease_ttl_seconds = lease_ttl_seconds
147
+ self._configured_workspace_root = configured_workspace_root
148
+ self._prepare_workspace = prepare_workspace
149
+ self._handles: dict[int, SessionSandboxHandle] = {}
150
+
151
+ @property
152
+ def capabilities(self) -> SandboxBackendCapabilities:
153
+ return self._capabilities
154
+
155
+ async def create(self, spec: SandboxSpec) -> SessionSandboxHandle:
156
+ self._validate_spec(spec)
157
+ provisional = SandboxHandle(spec)
158
+ session = await asyncio.to_thread(
159
+ self._backend.create_session,
160
+ session_id=provisional.handle_id,
161
+ env=dict(spec.env),
162
+ )
163
+ if self._prepare_workspace and spec.workspace_root:
164
+ try:
165
+ result = await asyncio.to_thread(
166
+ session.run_command,
167
+ f"mkdir -p -- {shlex.quote(spec.workspace_root)}",
168
+ timeout=10,
169
+ )
170
+ except Exception:
171
+ await asyncio.to_thread(session.kill)
172
+ raise
173
+ if result.exit_code != 0:
174
+ await asyncio.to_thread(session.kill)
175
+ raise SandboxPolicyViolation(f"无法初始化 Sandbox workspace_root: {result.stderr}")
176
+ handle = SessionSandboxHandle(spec, session)
177
+ # Keep the id generated before the potentially remote create call as
178
+ # the stable correlation id passed to the SDK backend.
179
+ handle.handle_id = provisional.handle_id
180
+ try:
181
+ handle.lease = await self._acquire_lease(handle.handle_id)
182
+ except Exception:
183
+ await asyncio.to_thread(session.kill)
184
+ raise
185
+ self._handles[id(handle)] = handle
186
+ return handle
187
+
188
+ def export_resume_token(self, handle: SandboxHandle) -> SandboxResumeToken:
189
+ if not self._capabilities.reconnect:
190
+ raise SandboxPolicyViolation("当前 Sandbox 后端未声明跨进程重连")
191
+ owned = self._require_open_handle(handle)
192
+ locator = str(owned.session.sandbox_id or "").strip()
193
+ if not locator:
194
+ raise RuntimeError("Sandbox Session 未提供可持久化的 session locator")
195
+ return SandboxResumeToken(
196
+ backend_id=self._capabilities.backend_id,
197
+ handle_id=owned.handle_id,
198
+ session_locator=locator,
199
+ )
200
+
201
+ async def reconnect(
202
+ self,
203
+ token: SandboxResumeToken,
204
+ *,
205
+ spec: SandboxSpec,
206
+ ) -> SessionSandboxHandle:
207
+ if not self._capabilities.reconnect:
208
+ raise SandboxPolicyViolation("当前 Sandbox 后端未声明跨进程重连")
209
+ if token.backend_id != self._capabilities.backend_id:
210
+ raise SandboxPolicyViolation("Sandbox Resume Token 与当前后端不匹配")
211
+ self._validate_spec(spec)
212
+ if any(
213
+ item.handle_id == token.handle_id and not item.closed for item in self._handles.values()
214
+ ):
215
+ raise SandboxPolicyViolation("Sandbox Handle 已在当前进程连接")
216
+ lease = await self._acquire_lease(token.handle_id)
217
+ backend = cast(SdkReconnectableSandboxBackend, self._backend)
218
+ try:
219
+ session = await asyncio.to_thread(
220
+ backend.reconnect_session,
221
+ session_locator=token.session_locator,
222
+ )
223
+ except Exception:
224
+ await self._release_lease(lease)
225
+ raise
226
+ locator = str(session.sandbox_id or "").strip()
227
+ if locator != token.session_locator:
228
+ await asyncio.to_thread(session.kill)
229
+ await self._release_lease(lease)
230
+ raise SandboxPolicyViolation("Sandbox 重连返回了不同的 session locator")
231
+ handle = SessionSandboxHandle(spec, session, lease=lease)
232
+ handle.handle_id = token.handle_id
233
+ self._handles[id(handle)] = handle
234
+ return handle
235
+
236
+ async def execute(self, handle: SandboxHandle, request: ExecuteRequest) -> ExecuteResult:
237
+ owned = self._require_open_handle(handle)
238
+ timeout = max(1, math.ceil(request.timeout_seconds))
239
+ await self._renew_lease(owned, ttl_seconds=max(self._lease_ttl_seconds, timeout + 30.0))
240
+ started = time.monotonic()
241
+ try:
242
+ if self._capabilities.cooperative_cancellation:
243
+ result = await self._execute_cancellable(owned, request, timeout)
244
+ else:
245
+ result = await asyncio.to_thread(
246
+ owned.session.run_command,
247
+ request.command,
248
+ timeout=timeout,
249
+ env=dict(owned.spec.env),
250
+ cwd=owned.spec.workspace_root or None,
251
+ )
252
+ except asyncio.CancelledError:
253
+ self._append_audit(
254
+ owned,
255
+ request,
256
+ ExecuteResult(ok=False, output="", exit_code=130, error="sandbox 命令已取消"),
257
+ started,
258
+ )
259
+ raise
260
+ except Exception as exc: # noqa: BLE001 - translate vendor SDK failures
261
+ translated = self._translate_command_error(exc)
262
+ self._append_audit(owned, request, translated, started)
263
+ return translated
264
+
265
+ translated = self._translate_command_result(result)
266
+ self._append_audit(owned, request, translated, started)
267
+ return translated
268
+
269
+ async def start_execute(
270
+ self,
271
+ handle: SandboxHandle,
272
+ request: ExecuteRequest,
273
+ ) -> SessionSandboxCommand:
274
+ """Start a recoverable command without waiting for its result.
275
+
276
+ The caller must persist ``export_command_resume_token`` before treating
277
+ the command as recoverable. KsADK deliberately leaves that durable
278
+ journal to the platform control plane.
279
+ """
280
+
281
+ if not self._capabilities.command_reconnect:
282
+ raise SandboxPolicyViolation("当前 Sandbox 后端未声明运行中命令重连")
283
+ owned = self._require_open_handle(handle)
284
+ timeout = max(1, math.ceil(request.timeout_seconds))
285
+ await self._renew_lease(owned, ttl_seconds=max(self._lease_ttl_seconds, timeout + 30.0))
286
+ session = owned.session
287
+ if not isinstance(session, ReconnectableCommandSandboxSession):
288
+ raise RuntimeError("后端声明 command_reconnect,但 Session 未实现命令重连协议")
289
+ command_handle = await asyncio.to_thread(
290
+ session.start_command,
291
+ request.command,
292
+ timeout=timeout,
293
+ env=dict(owned.spec.env),
294
+ cwd=owned.spec.workspace_root or None,
295
+ )
296
+ if not isinstance(command_handle, ReconnectableSandboxCommandHandle):
297
+ raise RuntimeError("后端声明 command_reconnect,但命令句柄未提供 process_id")
298
+ # Read once now so a malformed vendor handle fails before the platform
299
+ # records a resume token.
300
+ _ = command_handle.process_id
301
+ return SessionSandboxCommand(
302
+ adapter=self,
303
+ sandbox=owned,
304
+ request=request,
305
+ command_handle=command_handle,
306
+ )
307
+
308
+ def export_command_resume_token(
309
+ self,
310
+ command: SessionSandboxCommand,
311
+ ) -> SandboxCommandResumeToken:
312
+ owned = self._require_owned_command(command)
313
+ command_handle = command.command_handle
314
+ if not isinstance(command_handle, ReconnectableSandboxCommandHandle):
315
+ raise RuntimeError("Sandbox 命令句柄未提供 process_id")
316
+ locator = str(owned.session.sandbox_id or "").strip()
317
+ if not locator:
318
+ raise RuntimeError("Sandbox Session 未提供可持久化的 session locator")
319
+ return SandboxCommandResumeToken(
320
+ backend_id=self._capabilities.backend_id,
321
+ handle_id=owned.handle_id,
322
+ session_locator=locator,
323
+ process_id=command_handle.process_id,
324
+ )
325
+
326
+ async def reconnect_command(
327
+ self,
328
+ handle: SandboxHandle,
329
+ token: SandboxCommandResumeToken,
330
+ *,
331
+ request: ExecuteRequest,
332
+ ) -> SessionSandboxCommand:
333
+ """Reconnect a command after the Sandbox itself has been reconnected."""
334
+
335
+ if not self._capabilities.command_reconnect:
336
+ raise SandboxPolicyViolation("当前 Sandbox 后端未声明运行中命令重连")
337
+ owned = self._require_open_handle(handle)
338
+ locator = str(owned.session.sandbox_id or "").strip()
339
+ if (
340
+ token.backend_id != self._capabilities.backend_id
341
+ or token.handle_id != owned.handle_id
342
+ or token.session_locator != locator
343
+ ):
344
+ raise SandboxPolicyViolation("Sandbox Command Resume Token 与当前会话不匹配")
345
+ timeout = max(1, math.ceil(request.timeout_seconds))
346
+ await self._renew_lease(owned, ttl_seconds=max(self._lease_ttl_seconds, timeout + 30.0))
347
+ session = owned.session
348
+ if not isinstance(session, ReconnectableCommandSandboxSession):
349
+ raise RuntimeError("后端声明 command_reconnect,但 Session 未实现命令重连协议")
350
+ command_handle = await asyncio.to_thread(
351
+ session.connect_command,
352
+ token.process_id,
353
+ timeout=timeout,
354
+ )
355
+ if command_handle.process_id != token.process_id:
356
+ raise SandboxPolicyViolation("Sandbox 命令重连返回了不同的 process_id")
357
+ return SessionSandboxCommand(
358
+ adapter=self,
359
+ sandbox=owned,
360
+ request=request,
361
+ command_handle=command_handle,
362
+ )
363
+
364
+ async def wait_command(self, command: SessionSandboxCommand) -> ExecuteResult:
365
+ """Wait for a started or reconnected command with normal audit semantics."""
366
+
367
+ owned = self._require_owned_command(command)
368
+ if command.completed:
369
+ raise SandboxPolicyViolation("Sandbox 命令结果已经被消费")
370
+ timeout = max(1, math.ceil(command.request.timeout_seconds))
371
+ await self._renew_lease(owned, ttl_seconds=max(self._lease_ttl_seconds, timeout + 30.0))
372
+ try:
373
+ result = await asyncio.to_thread(command.command_handle.wait)
374
+ except asyncio.CancelledError:
375
+ await self.cancel_command(command)
376
+ raise
377
+ except Exception as exc: # noqa: BLE001 - translate vendor SDK failures
378
+ translated = self._translate_command_error(exc)
379
+ else:
380
+ translated = self._translate_command_result(result)
381
+ self._append_audit(owned, command.request, translated, command.started_at)
382
+ command.completed = True
383
+ return translated
384
+
385
+ async def cancel_command(self, command: SessionSandboxCommand) -> ExecuteResult:
386
+ """Terminate one recoverable command and close its audit lifecycle.
387
+
388
+ This is also the fail-closed escape hatch used when a control-plane
389
+ journal cannot durably persist the resume token. A command that has
390
+ no recovery record must not be allowed to continue as an orphan.
391
+ """
392
+
393
+ owned = self._require_owned_command(command)
394
+ if command.completed:
395
+ raise SandboxPolicyViolation("Sandbox 命令结果已经被消费")
396
+ await asyncio.to_thread(command.command_handle.kill)
397
+ translated = ExecuteResult(
398
+ ok=False,
399
+ output="",
400
+ exit_code=130,
401
+ error="sandbox 命令已取消",
402
+ )
403
+ self._append_audit(owned, command.request, translated, command.started_at)
404
+ command.completed = True
405
+ return translated
406
+
407
+ @staticmethod
408
+ def _translate_command_error(exc: Exception) -> ExecuteResult:
409
+ if "timeout" in type(exc).__name__.lower():
410
+ return ExecuteResult(
411
+ ok=False,
412
+ output="",
413
+ exit_code=124,
414
+ error=f"sandbox 命令超时: {exc}",
415
+ )
416
+ return ExecuteResult(ok=False, output="", exit_code=1, error=str(exc))
417
+
418
+ @staticmethod
419
+ def _translate_command_result(result: SandboxCommandResult) -> ExecuteResult:
420
+ exit_code = int(result.exit_code) if result.exit_code is not None else 1
421
+ error = str(result.stderr or "")
422
+ if exit_code == 124 and "超时" not in error:
423
+ error = f"sandbox 命令超时: {error}".rstrip()
424
+ return ExecuteResult(
425
+ ok=exit_code == 0,
426
+ output=str(result.stdout or ""),
427
+ exit_code=exit_code,
428
+ error=error,
429
+ )
430
+
431
+ def _append_audit(
432
+ self,
433
+ handle: SessionSandboxHandle,
434
+ request: ExecuteRequest,
435
+ result: ExecuteResult,
436
+ started: float,
437
+ ) -> None:
438
+ if self._audit is None:
439
+ return
440
+ self._audit.append(
441
+ handle_id=handle.handle_id,
442
+ command=request.command,
443
+ ok=result.ok,
444
+ exit_code=result.exit_code,
445
+ duration_ms=max(0, int((time.monotonic() - started) * 1000)),
446
+ output_bytes=len(result.output.encode("utf-8")),
447
+ error=result.error,
448
+ run_id=request.run_id,
449
+ )
450
+
451
+ async def _execute_cancellable(
452
+ self,
453
+ owned: SessionSandboxHandle,
454
+ request: ExecuteRequest,
455
+ timeout: int,
456
+ ) -> SandboxCommandResult:
457
+ session = owned.session
458
+ if not isinstance(session, BackgroundCommandSandboxSession):
459
+ raise RuntimeError("后端声明协作取消,但 Session 未实现 start_command")
460
+ command_handle = await asyncio.to_thread(
461
+ session.start_command,
462
+ request.command,
463
+ timeout=timeout,
464
+ env=dict(owned.spec.env),
465
+ cwd=owned.spec.workspace_root or None,
466
+ )
467
+ try:
468
+ return await asyncio.to_thread(command_handle.wait)
469
+ except asyncio.CancelledError:
470
+ # Cancellation is not considered complete until the remote process
471
+ # has received a kill request.
472
+ await asyncio.to_thread(command_handle.kill)
473
+ raise
474
+
475
+ async def collect_artifacts(self, handle: SandboxHandle) -> list[str]:
476
+ owned = self._require_open_handle(handle)
477
+ await self._renew_lease(owned)
478
+ if self._artifact_collector is None:
479
+ if not self._capabilities.artifact_collection:
480
+ return list(owned.artifacts)
481
+ session = owned.session
482
+ if not isinstance(session, ArtifactListingSandboxSession):
483
+ raise RuntimeError("后端声明 Artifact 收集,但 Session 未实现 list_files")
484
+ if not owned.spec.workspace_root:
485
+ return []
486
+ artifacts = await asyncio.to_thread(
487
+ session.list_files,
488
+ owned.spec.workspace_root,
489
+ recursive=True,
490
+ )
491
+ owned.artifacts = sorted(str(item) for item in artifacts)
492
+ return list(owned.artifacts)
493
+ artifacts = await asyncio.to_thread(self._artifact_collector, owned.session)
494
+ return sorted(str(item) for item in artifacts)
495
+
496
+ async def close(self, handle: SandboxHandle) -> None:
497
+ owned = self._handles.get(id(handle))
498
+ if owned is None:
499
+ handle.closed = True
500
+ return
501
+ try:
502
+ await self._renew_lease(owned)
503
+ except SandboxLeaseConflict:
504
+ self._handles.pop(id(handle), None)
505
+ owned.closed = True
506
+ raise
507
+ self._handles.pop(id(handle), None)
508
+ try:
509
+ await asyncio.to_thread(owned.session.kill)
510
+ finally:
511
+ await self._release_lease(owned.lease)
512
+ owned.closed = True
513
+
514
+ async def detach(self, handle: SandboxHandle) -> None:
515
+ """Release this process' lease without terminating the Sandbox.
516
+
517
+ This is only for recoverable remote sessions. It lets a failed
518
+ recovery attempt relinquish fencing ownership so another worker can
519
+ retry without destroying the still-running remote command.
520
+ """
521
+
522
+ if not self._capabilities.reconnect or self._lease_provider is None:
523
+ raise SandboxPolicyViolation("detach 需要 reconnect 和 ownership_fencing")
524
+ owned = self._require_open_handle(handle)
525
+ self._handles.pop(id(owned), None)
526
+ try:
527
+ await self._release_lease(owned.lease)
528
+ finally:
529
+ owned.closed = True
530
+
531
+ async def _acquire_lease(self, handle_id: str) -> SandboxLeaseGrant | None:
532
+ if self._lease_provider is None:
533
+ return None
534
+ grant = await self._lease_provider.acquire(
535
+ backend_id=self._capabilities.backend_id,
536
+ handle_id=handle_id,
537
+ scope=cast(SandboxLeaseScope, self._lease_scope),
538
+ owner_id=self._lease_owner_id,
539
+ ttl_seconds=self._lease_ttl_seconds,
540
+ )
541
+ self._validate_lease_grant(grant, handle_id=handle_id)
542
+ return grant
543
+
544
+ async def _renew_lease(
545
+ self,
546
+ handle: SessionSandboxHandle,
547
+ *,
548
+ ttl_seconds: float | None = None,
549
+ ) -> None:
550
+ if self._lease_provider is None:
551
+ return
552
+ if handle.lease is None:
553
+ raise SandboxLeaseConflict("Sandbox Handle 缺少所有权租约")
554
+ renewed = await self._lease_provider.renew(
555
+ handle.lease,
556
+ ttl_seconds=ttl_seconds or self._lease_ttl_seconds,
557
+ )
558
+ self._validate_lease_grant(
559
+ renewed,
560
+ handle_id=handle.handle_id,
561
+ fencing_token=handle.lease.fencing_token,
562
+ )
563
+ handle.lease = renewed
564
+
565
+ async def _release_lease(self, lease: SandboxLeaseGrant | None) -> None:
566
+ if self._lease_provider is not None and lease is not None:
567
+ await self._lease_provider.release(lease)
568
+
569
+ def _validate_lease_grant(
570
+ self,
571
+ grant: SandboxLeaseGrant,
572
+ *,
573
+ handle_id: str,
574
+ fencing_token: int | None = None,
575
+ ) -> None:
576
+ if (
577
+ grant.backend_id != self._capabilities.backend_id
578
+ or grant.handle_id != handle_id
579
+ or grant.scope != self._lease_scope
580
+ or grant.owner_id != self._lease_owner_id
581
+ or grant.fencing_token <= 0
582
+ or (fencing_token is not None and grant.fencing_token != fencing_token)
583
+ ):
584
+ raise SandboxLeaseConflict("Sandbox Lease Provider 返回了不匹配的租约")
585
+
586
+ def _require_open_handle(self, handle: SandboxHandle) -> SessionSandboxHandle:
587
+ owned = self._handles.get(id(handle))
588
+ if owned is None or owned.closed:
589
+ raise SandboxClosedError("Sandbox Handle 已关闭或不属于当前后端")
590
+ return owned
591
+
592
+ def _require_owned_command(
593
+ self,
594
+ command: SessionSandboxCommand,
595
+ ) -> SessionSandboxHandle:
596
+ if command._adapter is not self:
597
+ raise SandboxClosedError("Sandbox 命令不属于当前后端 Adapter")
598
+ return self._require_open_handle(command.sandbox)
599
+
600
+ def _validate_spec(self, spec: SandboxSpec) -> None:
601
+ if spec.read_only:
602
+ raise SandboxPolicyViolation("通用 SandboxSession 不提供只读挂载保证")
603
+ if spec.network_egress:
604
+ raise SandboxPolicyViolation(
605
+ "通用 SandboxSession 不支持按域名 network_egress allowlist"
606
+ )
607
+ if self._configured_workspace_root and spec.workspace_root:
608
+ if spec.workspace_root != self._configured_workspace_root:
609
+ raise SandboxPolicyViolation("Harness workspace_root 与 SDK Sandbox 后端配置不一致")
610
+
611
+
612
+ def adapt_local_process_backend(
613
+ backend: LocalProcessSandboxBackend,
614
+ ) -> SessionSandboxBackendAdapter:
615
+ """Adapt the SDK local-process fallback without overclaiming isolation."""
616
+
617
+ return SessionSandboxBackendAdapter(
618
+ cast(SdkSandboxBackend, backend),
619
+ capabilities=SandboxBackendCapabilities(
620
+ backend_id=f"sdk-{backend.backend_name}",
621
+ filesystem_isolation=FilesystemIsolation.SCOPED_WORKSPACE,
622
+ # The adapter rejects requested egress, but the host process is
623
+ # not protected by an OS network namespace.
624
+ network_control=NetworkControl.ADMISSION_ONLY,
625
+ process_boundary=True,
626
+ request_timeout=True,
627
+ cooperative_cancellation=False,
628
+ artifact_collection=False,
629
+ # LocalProcessSandboxSession.kill is a no-op and its shared
630
+ # workspace survives close, so cleanup must not be advertised.
631
+ deterministic_cleanup=False,
632
+ execution_audit=False,
633
+ reconnect=False,
634
+ ),
635
+ configured_workspace_root=str(backend.workspace_root),
636
+ )
637
+
638
+
639
+ def adapt_e2b_backend(
640
+ backend: E2BSandboxBackend,
641
+ *,
642
+ audit_log: SandboxAuditLog | None = None,
643
+ lease_provider: SandboxLeaseProvider | None = None,
644
+ lease_scope: SandboxLeaseScope | None = None,
645
+ lease_owner_id: str | None = None,
646
+ lease_ttl_seconds: float = 120.0,
647
+ ) -> SessionSandboxBackendAdapter:
648
+ """Adapt the current synchronous E2B backend.
649
+
650
+ E2B enforces the backend's boolean internet policy, but the current SDK
651
+ contract cannot express a per-domain allowlist. An internet-enabled
652
+ backend therefore declares ``NONE`` rather than pretending to provide
653
+ fine-grained network control.
654
+ """
655
+
656
+ network_control = (
657
+ NetworkControl.NONE if backend.spec.allow_internet_access else NetworkControl.ENFORCED
658
+ )
659
+ return SessionSandboxBackendAdapter(
660
+ cast(SdkSandboxBackend, backend),
661
+ capabilities=SandboxBackendCapabilities(
662
+ backend_id="sdk-e2b",
663
+ filesystem_isolation=FilesystemIsolation.REMOTE_SANDBOX,
664
+ network_control=network_control,
665
+ process_boundary=True,
666
+ request_timeout=True,
667
+ cooperative_cancellation=True,
668
+ artifact_collection=True,
669
+ deterministic_cleanup=True,
670
+ execution_audit=audit_log is not None,
671
+ reconnect=True,
672
+ ownership_fencing=lease_provider is not None,
673
+ command_reconnect=lease_provider is not None,
674
+ ),
675
+ audit_log=audit_log,
676
+ lease_provider=lease_provider,
677
+ lease_scope=lease_scope,
678
+ lease_owner_id=lease_owner_id,
679
+ lease_ttl_seconds=lease_ttl_seconds,
680
+ prepare_workspace=True,
681
+ )
682
+
683
+
684
+ def adapt_sdk_sandbox_backend(
685
+ backend: SdkSandboxBackend,
686
+ *,
687
+ capabilities: SandboxBackendCapabilities | None = None,
688
+ artifact_collector: ArtifactCollector | None = None,
689
+ audit_log: SandboxAuditLog | None = None,
690
+ lease_provider: SandboxLeaseProvider | None = None,
691
+ lease_scope: SandboxLeaseScope | None = None,
692
+ lease_owner_id: str | None = None,
693
+ lease_ttl_seconds: float = 120.0,
694
+ ) -> SessionSandboxBackendAdapter:
695
+ """Select a truthful built-in profile or require one for custom backends."""
696
+
697
+ if isinstance(backend, LocalProcessSandboxBackend):
698
+ if (
699
+ capabilities is not None
700
+ or artifact_collector is not None
701
+ or audit_log is not None
702
+ or lease_provider is not None
703
+ ):
704
+ raise ValueError("内置 local_process profile 不接受能力覆盖")
705
+ return adapt_local_process_backend(backend)
706
+ if isinstance(backend, E2BSandboxBackend):
707
+ if capabilities is not None or artifact_collector is not None:
708
+ raise ValueError("内置 E2B profile 不接受能力覆盖")
709
+ return adapt_e2b_backend(
710
+ backend,
711
+ audit_log=audit_log,
712
+ lease_provider=lease_provider,
713
+ lease_scope=lease_scope,
714
+ lease_owner_id=lease_owner_id,
715
+ lease_ttl_seconds=lease_ttl_seconds,
716
+ )
717
+ if capabilities is None:
718
+ raise ValueError("自定义 SDK SandboxBackend 必须显式提供 capabilities")
719
+ return SessionSandboxBackendAdapter(
720
+ backend,
721
+ capabilities=capabilities,
722
+ artifact_collector=artifact_collector,
723
+ audit_log=audit_log,
724
+ lease_provider=lease_provider,
725
+ lease_scope=lease_scope,
726
+ lease_owner_id=lease_owner_id,
727
+ lease_ttl_seconds=lease_ttl_seconds,
728
+ )
729
+
730
+
731
+ __all__ = [
732
+ "ArtifactCollector",
733
+ "SessionSandboxBackendAdapter",
734
+ "SessionSandboxCommand",
735
+ "SessionSandboxHandle",
736
+ "adapt_e2b_backend",
737
+ "adapt_local_process_backend",
738
+ "adapt_sdk_sandbox_backend",
739
+ ]