agentengine-sdk-python 0.8.3__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 (819) hide show
  1. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.5.dist-info}/METADATA +13 -9
  2. agentengine_sdk_python-0.8.5.dist-info/RECORD +1296 -0
  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 +111 -91
  8. ksadk/builders/code_builder.py +74 -21
  9. ksadk/builders/framework_requirements.py +22 -3
  10. ksadk/builders/ks3_uploader.py +36 -7
  11. ksadk/builders/managed_runtime_builder.py +1 -0
  12. ksadk/cli/__init__.py +68 -3
  13. ksadk/cli/cmd_config.py +4 -4
  14. ksadk/cli/cmd_create.py +12 -12
  15. ksadk/cli/cmd_hermes.py +24 -2
  16. ksadk/cli/cmd_invoke.py +28 -5
  17. ksadk/cli/cmd_managed_runtime.py +13 -1
  18. ksadk/cli/cmd_openclaw.py +26 -1
  19. ksadk/cli/cmd_plugin.py +76 -13
  20. ksadk/cli/cmd_studio.py +64 -16
  21. ksadk/cli/cmd_web.py +2 -5
  22. ksadk/cli/openclaw_env.py +1 -1
  23. ksadk/cli/resource_common.py +26 -0
  24. ksadk/cli/runtime_bootstrap.py +23 -1
  25. ksadk/codex/client.py +425 -96
  26. ksadk/codex/projection.py +24 -0
  27. ksadk/codex/runtime.py +56 -298
  28. ksadk/common/auth.py +16 -10
  29. ksadk/configs/__init__.py +1 -1
  30. ksadk/configs/env_registry.py +153 -31
  31. ksadk/configs/env_registry_studio.py +86 -0
  32. ksadk/configs/global_config.py +1 -1
  33. ksadk/configs/settings.py +3 -3
  34. ksadk/connector/__init__.py +17 -0
  35. ksadk/connector/channel.py +477 -0
  36. ksadk/context_engine/capabilities.py +52 -4
  37. ksadk/conversations/attachment_storage.py +10 -3
  38. ksadk/conversations/attachments.py +16 -5
  39. ksadk/conversations/message_projection.py +133 -21
  40. ksadk/conversations/normalize.py +28 -10
  41. ksadk/conversations/projector.py +4 -6
  42. ksadk/conversations/runtime_baseline.py +37 -0
  43. ksadk/conversations/runtime_invocation.py +22 -4
  44. ksadk/conversations/runtime_observability.py +39 -10
  45. ksadk/conversations/runtime_payloads.py +9 -0
  46. ksadk/conversations/runtime_persistence.py +105 -9
  47. ksadk/conversations/runtime_preparation.py +42 -33
  48. ksadk/conversations/runtime_resume.py +50 -2
  49. ksadk/conversations/runtime_stream_events.py +34 -35
  50. ksadk/conversations/runtime_streaming.py +33 -7
  51. ksadk/deployment/env_forward.py +2 -2
  52. ksadk/deployment/providers/serverless.py +1 -1
  53. ksadk/events/adapters/_codex_items.py +16 -8
  54. ksadk/events/adapters/_codex_validators.py +18 -7
  55. ksadk/events/adapters/_langgraph_support.py +34 -0
  56. ksadk/events/adapters/langgraph.py +15 -1
  57. ksadk/events/canonical_store.py +3 -1
  58. ksadk/events/projections.py +1 -1
  59. ksadk/events/session_event.py +2 -2
  60. ksadk/harness/__init__.py +14 -0
  61. ksadk/harness/app.py +11 -0
  62. ksadk/harness/artifact_store.py +213 -0
  63. ksadk/harness/capabilities.py +115 -0
  64. ksadk/harness/capability_runtime.py +237 -0
  65. ksadk/harness/closure_contract.py +92 -0
  66. ksadk/harness/compaction_record.py +122 -0
  67. ksadk/harness/compiler.py +284 -0
  68. ksadk/harness/config.py +2 -2
  69. ksadk/harness/conformance/__init__.py +33 -0
  70. ksadk/harness/conformance/contract.py +506 -0
  71. ksadk/harness/conformance/fixtures.py +102 -0
  72. ksadk/harness/context_engine.py +403 -0
  73. ksadk/harness/context_maintenance.py +259 -0
  74. ksadk/harness/context_manifest.py +188 -0
  75. ksadk/harness/context_tuning.py +168 -0
  76. ksadk/harness/draft_runtime.py +322 -0
  77. ksadk/harness/engine/__init__.py +40 -0
  78. ksadk/harness/engine/base.py +122 -0
  79. ksadk/harness/engine/budgets.py +108 -0
  80. ksadk/harness/engine/capability_declarations.py +59 -0
  81. ksadk/harness/engine/completion_guard.py +42 -0
  82. ksadk/harness/engine/context_pipeline.py +579 -0
  83. ksadk/harness/engine/graph_builder.py +859 -0
  84. ksadk/harness/engine/langgraph.py +931 -0
  85. ksadk/harness/engine/mcp_disclosure.py +750 -0
  86. ksadk/harness/engine/policy_runtime.py +70 -0
  87. ksadk/harness/engine/postgres_checkpointer.py +63 -0
  88. ksadk/harness/engine/run_control_bridge.py +80 -0
  89. ksadk/harness/engine/run_types.py +88 -0
  90. ksadk/harness/engine/skill_disclosure.py +189 -0
  91. ksadk/harness/engine/spans.py +41 -0
  92. ksadk/harness/engine/subagents.py +343 -0
  93. ksadk/harness/engine/thread_ids.py +112 -0
  94. ksadk/harness/engine/tool_dispatch.py +144 -0
  95. ksadk/harness/event_tree.py +212 -0
  96. ksadk/harness/events.py +461 -0
  97. ksadk/harness/execution_policy.py +94 -0
  98. ksadk/harness/insights.py +210 -0
  99. ksadk/harness/lifecycle.py +578 -0
  100. ksadk/harness/lifecycle_conformance.py +233 -0
  101. ksadk/harness/lifecycle_local_plane.py +104 -0
  102. ksadk/harness/loop/__init__.py +44 -0
  103. ksadk/harness/loop/reason.py +454 -0
  104. ksadk/harness/loop/tools.py +762 -0
  105. ksadk/harness/managed_runtime.py +884 -0
  106. ksadk/harness/mcp_matrix.py +474 -0
  107. ksadk/harness/mcp_runtime.py +471 -0
  108. ksadk/harness/memory_consolidation.py +157 -0
  109. ksadk/harness/memory_loop.py +156 -0
  110. ksadk/harness/memory_runtime.py +541 -0
  111. ksadk/harness/metrics.py +90 -0
  112. ksadk/harness/model_capability.py +253 -0
  113. ksadk/harness/model_provider.py +220 -0
  114. ksadk/harness/observability/__init__.py +29 -0
  115. ksadk/harness/observability/inspection.py +528 -0
  116. ksadk/harness/observability/metrics.py +167 -0
  117. ksadk/harness/observability/otel_exporter.py +218 -0
  118. ksadk/harness/prompt_cache.py +70 -0
  119. ksadk/harness/public_activity.py +154 -0
  120. ksadk/harness/readiness.py +249 -0
  121. ksadk/harness/reasoner.py +466 -13
  122. ksadk/harness/release_readiness.py +140 -0
  123. ksadk/harness/resource_ref.py +69 -0
  124. ksadk/harness/run_control.py +668 -0
  125. ksadk/harness/runtime.py +171 -136
  126. ksadk/harness/runtime_capabilities.py +158 -0
  127. ksadk/harness/runtime_server.py +514 -0
  128. ksadk/harness/sandbox_adapters.py +739 -0
  129. ksadk/harness/sandbox_backend.py +530 -0
  130. ksadk/harness/sandbox_conformance.py +288 -0
  131. ksadk/harness/sandbox_lease.py +77 -0
  132. ksadk/harness/sandbox_lease_conformance.py +259 -0
  133. ksadk/harness/sandbox_matrix.py +170 -0
  134. ksadk/harness/sandbox_reconciliation.py +140 -0
  135. ksadk/harness/sandbox_recovery.py +586 -0
  136. ksadk/harness/sandbox_recovery_conformance.py +246 -0
  137. ksadk/harness/session_store.py +243 -0
  138. ksadk/harness/skill_composition.py +212 -0
  139. ksadk/harness/skill_feedback.py +123 -0
  140. ksadk/harness/skill_matrix.py +233 -0
  141. ksadk/harness/skill_runtime.py +259 -0
  142. ksadk/harness/spec.py +332 -0
  143. ksadk/harness/state.py +153 -0
  144. ksadk/harness/strategies.py +149 -0
  145. ksadk/harness/subagent.py +253 -0
  146. ksadk/harness/tool_policy.py +131 -0
  147. ksadk/harness/tool_receipts.py +96 -0
  148. ksadk/harness/tool_reliability.py +81 -0
  149. ksadk/harness/tools.py +38 -13
  150. ksadk/harness/user_errors.py +69 -0
  151. ksadk/harness/working_context.py +81 -0
  152. ksadk/harness/working_context_patch.py +99 -0
  153. ksadk/identity/resolver.py +18 -0
  154. ksadk/interaction/__init__.py +1 -1
  155. ksadk/interaction/ledger.py +1 -1
  156. ksadk/interaction/provider.py +2 -1
  157. ksadk/interaction/providers/__init__.py +3 -1
  158. ksadk/interaction/providers/adk.py +1 -1
  159. ksadk/interaction/providers/codex.py +1 -1
  160. ksadk/interaction/providers/harness.py +50 -0
  161. ksadk/interaction/providers/langgraph.py +2 -1
  162. ksadk/kernel/__init__.py +10 -0
  163. ksadk/kernel/approval_presentation.py +91 -0
  164. ksadk/kernel/authorization.py +1 -1
  165. ksadk/kernel/bootstrap.py +114 -106
  166. ksadk/kernel/contract_fingerprints.py +1 -1
  167. ksadk/kernel/contracts.py +5 -0
  168. ksadk/kernel/control.py +32 -1
  169. ksadk/kernel/execution_grants.py +221 -0
  170. ksadk/kernel/execution_grants_memory.py +133 -0
  171. ksadk/kernel/execution_grants_postgres.py +217 -0
  172. ksadk/kernel/execution_grants_sqlite.py +209 -0
  173. ksadk/kernel/ingress.py +42 -29
  174. ksadk/kernel/mapping.py +1 -1
  175. ksadk/kernel/memory_store.py +24 -11
  176. ksadk/kernel/postgres_store.py +63 -33
  177. ksadk/kernel/recovery.py +78 -14
  178. ksadk/kernel/sql/001_agent_kernel.sql +23 -0
  179. ksadk/kernel/sqlite_store.py +331 -25
  180. ksadk/kernel/state.py +2 -3
  181. ksadk/kernel/store.py +72 -2
  182. ksadk/kernel/worker.py +144 -51
  183. ksadk/kernel/worker_history.py +72 -0
  184. ksadk/kernel/worker_identity.py +47 -0
  185. ksadk/knowledge_base/client.py +57 -27
  186. ksadk/mcp_runtime/__init__.py +12 -4
  187. ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
  188. ksadk/memory/adk/resilient_session_service.py +25 -17
  189. ksadk/memory/adk/short_term_memory.py +26 -9
  190. ksadk/memory/coordinator.py +22 -6
  191. ksadk/memory/extraction.py +40 -1
  192. ksadk/memory/models.py +84 -5
  193. ksadk/memory/provider_resolver.py +8 -0
  194. ksadk/memory/providers/local_postgres.py +200 -0
  195. ksadk/memory/providers/local_sqlite.py +42 -3
  196. ksadk/memory/retrieval.py +189 -0
  197. ksadk/memory/store_adapter.py +150 -0
  198. ksadk/model_policy.py +2 -2
  199. ksadk/model_proxy/detect.py +254 -0
  200. ksadk/model_proxy/server.py +14 -7
  201. ksadk/model_proxy/transform.py +40 -2
  202. ksadk/plugins/__init__.py +5 -1
  203. ksadk/plugins/artifacts.py +275 -0
  204. ksadk/plugins/bridges/__init__.py +4 -2
  205. ksadk/plugins/bridges/codex.py +120 -13
  206. ksadk/plugins/bridges/dsh.py +351 -156
  207. ksadk/plugins/builtins.py +72 -35
  208. ksadk/plugins/bundle_security.py +28 -4
  209. ksadk/plugins/codex_manifest.py +983 -0
  210. ksadk/plugins/companion_artifacts.py +83 -0
  211. ksadk/plugins/companions.py +368 -0
  212. ksadk/plugins/composition.py +8 -0
  213. ksadk/plugins/contracts.py +119 -1
  214. ksadk/plugins/delivery.py +153 -0
  215. ksadk/plugins/dsh_channels.py +156 -0
  216. ksadk/plugins/dsh_home.py +140 -0
  217. ksadk/plugins/dsh_installation_digest.py +71 -0
  218. ksadk/plugins/dsh_teams.py +105 -0
  219. ksadk/plugins/dsh_toolchain.py +203 -32
  220. ksadk/plugins/ecosystem_probe.py +6 -6
  221. ksadk/plugins/execution_host.py +99 -0
  222. ksadk/plugins/host.py +102 -39
  223. ksadk/plugins/kernel_adapter.py +205 -0
  224. ksadk/plugins/providers/__init__.py +23 -0
  225. ksadk/plugins/providers/bundles/dsh-channels-client/client.js +19 -0
  226. ksadk/plugins/providers/bundles/dsh-channels-client/cordis.patch.yml +3 -0
  227. ksadk/plugins/providers/bundles/dsh-channels-client/index.mjs +7 -0
  228. ksadk/plugins/providers/bundles/dsh-channels-client/package.json +12 -0
  229. ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
  230. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
  231. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
  232. ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
  233. ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
  234. ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
  235. ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
  236. ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
  237. ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
  238. ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
  239. ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
  240. ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
  241. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -0
  242. ksadk/plugins/providers/bundles/dsh-teams-client/client.js +29 -0
  243. ksadk/plugins/providers/bundles/dsh-teams-client/cordis.patch.yml +3 -0
  244. ksadk/plugins/providers/bundles/dsh-teams-client/index.mjs +11 -0
  245. ksadk/plugins/providers/bundles/dsh-teams-client/package.json +35 -0
  246. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/cordis.patch.yml +3 -0
  247. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/index.mjs +13 -0
  248. ksadk/plugins/providers/bundles/dsh-teams-leader-policy/package.json +27 -0
  249. ksadk/plugins/providers/bundles/dsh-teams-profile/cordis.patch.yml +3 -0
  250. ksadk/plugins/providers/bundles/dsh-teams-profile/index.mjs +12 -0
  251. ksadk/plugins/providers/bundles/dsh-teams-profile/package.json +26 -0
  252. ksadk/plugins/providers/bundles/dsh-teams-router/cordis.patch.yml +3 -0
  253. ksadk/plugins/providers/bundles/dsh-teams-router/index.mjs +16 -0
  254. ksadk/plugins/providers/bundles/dsh-teams-router/package.json +27 -0
  255. ksadk/plugins/providers/bundles/dsh-teams-tasks/cordis.patch.yml +3 -0
  256. ksadk/plugins/providers/bundles/dsh-teams-tasks/index.mjs +16 -0
  257. ksadk/plugins/providers/bundles/dsh-teams-tasks/package.json +27 -0
  258. ksadk/plugins/providers/bundles/dsh-teams-tools/cordis.patch.yml +3 -0
  259. ksadk/plugins/providers/bundles/dsh-teams-tools/index.mjs +25 -0
  260. ksadk/plugins/providers/bundles/dsh-teams-tools/package.json +29 -0
  261. ksadk/plugins/providers/bundles/dsh-teams-tools/tools.json +235 -0
  262. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +1 -1
  263. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/cordis.patch.yml +3 -0
  264. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +920 -0
  265. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
  266. ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/client.mjs +133 -0
  267. ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/index.mjs +14 -0
  268. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +115 -0
  269. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +19 -0
  270. ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -0
  271. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +1 -1
  272. ksadk/plugins/providers/codex.py +344 -70
  273. ksadk/plugins/providers/codex_native.py +368 -0
  274. ksadk/plugins/providers/codex_turn.py +301 -0
  275. ksadk/plugins/providers/dsh_capabilities.py +1450 -0
  276. ksadk/plugins/providers/dsh_mcp.py +467 -0
  277. ksadk/plugins/providers/harness.py +294 -141
  278. ksadk/plugins/providers/harness_delegation.py +593 -0
  279. ksadk/plugins/providers/harness_managed.py +456 -0
  280. ksadk/plugins/providers/harness_tools.py +326 -0
  281. ksadk/plugins/providers/mcp_projection.py +150 -0
  282. ksadk/plugins/providers/platform_resources.py +657 -0
  283. ksadk/plugins/providers/shipped_dsh.py +4 -1
  284. ksadk/plugins/resolver.py +8 -1
  285. ksadk/plugins/subagent_providers/codex.py +28 -6
  286. ksadk/plugins/teams/__init__.py +5 -0
  287. ksadk/plugins/teams/api.py +405 -0
  288. ksadk/plugins/teams/application.py +680 -0
  289. ksadk/plugins/teams/artifacts.py +60 -0
  290. ksadk/plugins/teams/context.py +96 -0
  291. ksadk/plugins/teams/contracts.py +136 -0
  292. ksadk/plugins/teams/domain.py +1427 -0
  293. ksadk/plugins/teams/domain_values.py +24 -0
  294. ksadk/plugins/teams/errors.py +13 -0
  295. ksadk/plugins/teams/migration.py +311 -0
  296. ksadk/plugins/teams/migration_cli.py +322 -0
  297. ksadk/plugins/teams/postgres_store.py +138 -0
  298. ksadk/plugins/teams/runtime.py +777 -0
  299. ksadk/plugins/teams/source_projection.py +84 -0
  300. ksadk/plugins/teams/store.py +311 -0
  301. ksadk/plugins/teams/task_decisions.py +423 -0
  302. ksadk/plugins/teams/transport.py +91 -0
  303. ksadk/plugins/teams/workspaces.py +255 -0
  304. ksadk/resource_runtime/__init__.py +4 -0
  305. ksadk/resource_runtime/broker.py +616 -0
  306. ksadk/resource_runtime/build_artifacts.py +165 -0
  307. ksadk/resource_runtime/contracts.py +138 -0
  308. ksadk/resource_runtime/discovery_receipts.py +100 -0
  309. ksadk/resource_runtime/discovery_skills.py +172 -0
  310. ksadk/resource_runtime/errors.py +6 -0
  311. ksadk/resource_runtime/ipc.py +142 -0
  312. ksadk/resource_runtime/kernel_approval.py +165 -0
  313. ksadk/resource_runtime/knowledge.py +114 -0
  314. ksadk/resource_runtime/langgraph.py +94 -0
  315. ksadk/resource_runtime/leases.py +191 -0
  316. ksadk/resource_runtime/managed_projection.py +186 -0
  317. ksadk/resource_runtime/mcp_server.py +138 -0
  318. ksadk/resource_runtime/memory_provider.py +318 -0
  319. ksadk/resource_runtime/memory_receipts.py +34 -0
  320. ksadk/resource_runtime/operation_ledger.py +211 -0
  321. ksadk/resource_runtime/plugin_config.py +48 -0
  322. ksadk/resource_runtime/policy_authorization.py +54 -0
  323. ksadk/resource_runtime/process.py +110 -0
  324. ksadk/resource_runtime/skill_artifacts.py +153 -0
  325. ksadk/resource_runtime/skill_runtime.py +42 -0
  326. ksadk/resource_runtime/skill_workspace.py +118 -0
  327. ksadk/resource_runtime/skills.py +215 -0
  328. ksadk/resource_runtime/snapshots.py +180 -0
  329. ksadk/resource_runtime/socket_server.py +103 -0
  330. ksadk/resource_runtime/supervisor.py +380 -0
  331. ksadk/resource_runtime/worker.py +504 -0
  332. ksadk/runners/_langgraph_runner_streams.py +182 -38
  333. ksadk/runners/_langgraph_state_reader.py +106 -0
  334. ksadk/runners/_session_identity.py +285 -0
  335. ksadk/runners/adk_runner.py +166 -63
  336. ksadk/runners/base_runner.py +29 -1
  337. ksadk/runners/langgraph_runner.py +542 -195
  338. ksadk/runners/patch_langchain.py +47 -0
  339. ksadk/runners/usage_accumulator.py +11 -3
  340. ksadk/runtime/_runner_adapter/stream_mapping.py +194 -20
  341. ksadk/runtime/adapter.py +2 -0
  342. ksadk/runtime/conversation_execution.py +117 -17
  343. ksadk/runtime/executor.py +87 -3
  344. ksadk/runtime/factory.py +65 -274
  345. ksadk/runtime/framework_adapters.py +23 -0
  346. ksadk/runtime/preprocessing.py +21 -5
  347. ksadk/runtime/runner_adapter.py +106 -18
  348. ksadk/runtime/skill_eval_result.py +36 -0
  349. ksadk/runtime/timing.py +46 -0
  350. ksadk/runtime/usage.py +49 -18
  351. ksadk/runtime_context.py +142 -2
  352. ksadk/sandbox/backends/e2b.py +288 -25
  353. ksadk/sandbox/backends/local_process.py +72 -39
  354. ksadk/sandbox/base.py +64 -1
  355. ksadk/sandbox/diagnostics.py +82 -0
  356. ksadk/sandbox/e2b_connection.py +66 -0
  357. ksadk/sandbox/local_controls.py +746 -0
  358. ksadk/sandbox/local_launcher.py +90 -0
  359. ksadk/scheduler/dispatcher.py +1 -1
  360. ksadk/scheduler/sqlite_store.py +18 -0
  361. ksadk/server/composition.py +2 -0
  362. ksadk/server/factory.py +5 -0
  363. ksadk/server/invocation_identity.py +118 -0
  364. ksadk/server/persistence_capability.py +516 -0
  365. ksadk/server/routes/common.py +32 -3
  366. ksadk/server/routes/control.py +271 -52
  367. ksadk/server/routes/dependencies.py +16 -0
  368. ksadk/server/routes/kernel_ingress.py +9 -1
  369. ksadk/server/routes/misc.py +233 -25
  370. ksadk/server/routes/models.py +47 -4
  371. ksadk/server/routes/openai_compat.py +76 -13
  372. ksadk/server/routes/projection.py +252 -12
  373. ksadk/server/routes/run.py +106 -35
  374. ksadk/server/routes/sessions.py +491 -138
  375. ksadk/server/routes/streaming.py +43 -9
  376. ksadk/server/routes/workspace.py +130 -21
  377. ksadk/server/static/assets/{ArtifactsPanel-10GPXIJ6.js → ArtifactsPanel-C1YoaKhx.js} +1 -1
  378. ksadk/server/static/assets/{CodeBlock-BXk1l-G1.js → CodeBlock-DHuAWfr5.js} +10 -7
  379. ksadk/server/static/assets/MathMessageMarkdown-cvdrBwYr.js +8 -0
  380. ksadk/server/static/assets/{MermaidBlock--OEYoXIJ.js → MermaidBlock-DeBkbJvI.js} +9 -9
  381. ksadk/server/static/assets/{NativeTerminalPanel-DrEe1syq.js → NativeTerminalPanel-oJj44_sV.js} +1 -1
  382. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-eeTFJLvo.js → abnfDiagram-VCTEODGH-Dhfv25o2.js} +1 -1
  383. ksadk/server/static/assets/{arc-S3ZNbIAd.js → arc-C35w-pn1.js} +1 -1
  384. ksadk/server/static/assets/architecture-7GRP2DOG-BCsa26zi.js +1 -0
  385. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-CRjgEJDX.js → architectureDiagram-5GKGNRK7-FoMY_u6D.js} +1 -1
  386. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-C7bsBoNH.js → blockDiagram-NRAW4CY4-zD4Rt7oE.js} +1 -1
  387. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-BX3c33Ob.js → c4Diagram-UCG6FXSJ-BCtGGkhN.js} +1 -1
  388. ksadk/server/static/assets/channel-_KDifNys.js +1 -0
  389. ksadk/server/static/assets/chunk-2Q5K7J3B-HdVkJ9F0.js +1 -0
  390. ksadk/server/static/assets/{chunk-5VM5RSS4-bZ7ws-8m.js → chunk-5VM5RSS4-C2Ms13_k.js} +1 -1
  391. ksadk/server/static/assets/{chunk-F27PBJKO-D2r0pvhY.js → chunk-F27PBJKO-BoTj-qgx.js} +1 -1
  392. ksadk/server/static/assets/{chunk-G27WJ6UU-CZwF3oUP.js → chunk-G27WJ6UU-DOMyyjHH.js} +1 -1
  393. ksadk/server/static/assets/{chunk-JWPE2WC7-DigFYCML.js → chunk-JWPE2WC7-DbJJqDli.js} +1 -1
  394. ksadk/server/static/assets/{chunk-LCL6LL3I-CnorGV5q.js → chunk-LCL6LL3I-CLuRCt_W.js} +1 -1
  395. ksadk/server/static/assets/{chunk-POPQ4Y6H-CexntQA-.js → chunk-POPQ4Y6H-D0Dz847e.js} +1 -1
  396. ksadk/server/static/assets/{chunk-RHFEMEQ7-CHTC7UxA.js → chunk-RHFEMEQ7-BWSRzEcd.js} +1 -1
  397. ksadk/server/static/assets/{chunk-SVP7TREG-BC1EWt_-.js → chunk-SVP7TREG-CPoHqkCY.js} +1 -1
  398. ksadk/server/static/assets/{chunk-XXDRQBXY-BTG24xN0.js → chunk-XXDRQBXY-Bx1jS-X-.js} +1 -1
  399. ksadk/server/static/assets/classDiagram-DTDB5LWJ-BVCW3ZqZ.js +1 -0
  400. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-BVCW3ZqZ.js +1 -0
  401. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-CkonRdAS.js → cose-bilkent-JH36ORCC-LzyWm4m0.js} +1 -1
  402. ksadk/server/static/assets/cynefin-OW5HDTMX-CNXjFctL.js +1 -0
  403. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-DEOCBe15.js → cynefinDiagram-5FMLGOSQ-BlW_bHED.js} +1 -1
  404. ksadk/server/static/assets/{dagre-3AP2YEHR-DBThPuLa.js → dagre-3AP2YEHR-Bu_S86_i.js} +1 -1
  405. ksadk/server/static/assets/{dagre-ClTPrTht.js → dagre-B7nCawed.js} +1 -1
  406. ksadk/server/static/assets/{diagram-S7CK7UJ4-DsZHrnpJ.js → diagram-S7CK7UJ4-W_Zow2Km.js} +1 -1
  407. ksadk/server/static/assets/{diagram-UQ7AKVKN-BJR4nhVr.js → diagram-UQ7AKVKN-CLIKAHON.js} +1 -1
  408. ksadk/server/static/assets/{diagram-VSXAHHWV-xzcERX0a.js → diagram-VSXAHHWV-Dv6_QAlN.js} +1 -1
  409. ksadk/server/static/assets/{diagram-VX7I27RA-tn2xM1xu.js → diagram-VX7I27RA-BWAWRDtZ.js} +1 -1
  410. ksadk/server/static/assets/{diagram-Z3DM3KII-BZPGBkw5.js → diagram-Z3DM3KII-XA_rWMss.js} +1 -1
  411. ksadk/server/static/assets/dist-0X_j2Rcc.js +1 -0
  412. ksadk/server/static/assets/{dist-4zN1_tq5.js → dist-1nXCdsej.js} +1 -1
  413. ksadk/server/static/assets/{dist-M67Hwu0n.js → dist-2vL2sAdF.js} +1 -1
  414. ksadk/server/static/assets/{dist-BJLUwH6W.js → dist-B3bA05-e.js} +1 -1
  415. ksadk/server/static/assets/{dist-8VWI-2bZ.js → dist-BLpRy_Yx.js} +1 -1
  416. ksadk/server/static/assets/{dist-D1V3f1B4.js → dist-BO_UwatH.js} +1 -1
  417. ksadk/server/static/assets/{dist-Cq4OL6nO.js → dist-BdNFAney.js} +1 -1
  418. ksadk/server/static/assets/{dist-DfGFrb0v.js → dist-C0J5_3qM.js} +1 -1
  419. ksadk/server/static/assets/{dist-DyqV4fL4.js → dist-CGt_UGeO.js} +1 -1
  420. ksadk/server/static/assets/{dist-DjhwGUgZ.js → dist-CIRMvUM4.js} +1 -1
  421. ksadk/server/static/assets/{dist-B1oWRmrH.js → dist-CIpWk_5f.js} +1 -1
  422. ksadk/server/static/assets/{dist-CXpH_Rdd.js → dist-CPyieXEf.js} +1 -1
  423. ksadk/server/static/assets/{dist-Btyo4vX4.js → dist-D-92S-Fd.js} +1 -1
  424. ksadk/server/static/assets/{dist-u8tVH5Ak.js → dist-DNKuMzWc.js} +1 -1
  425. ksadk/server/static/assets/{dist-DQAB0qn_.js → dist-DWfdmz9s.js} +2 -2
  426. ksadk/server/static/assets/{dist-B-46q3Hk.js → dist-DppE_r-D.js} +1 -1
  427. ksadk/server/static/assets/{dist-C71CsujO.js → dist-DyG6Ya-z.js} +1 -1
  428. ksadk/server/static/assets/{dist-DJmCPRVB.js → dist-M-SrdhhZ.js} +1 -1
  429. ksadk/server/static/assets/{dist-Bbwqa8TG.js → dist-mqD5TZup.js} +1 -1
  430. ksadk/server/static/assets/{dist-BI1qQH4n.js → dist-n3n6t_FO.js} +1 -1
  431. ksadk/server/static/assets/{dist-DUwKa_l6.js → dist-qe8xjesy.js} +1 -1
  432. ksadk/server/static/assets/{dist-B0gdk4rl.js → dist-t6MzE0jU.js} +1 -1
  433. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-DVfMsLge.js → ebnfDiagram-PWID7BFC-BfCzF1Xi.js} +1 -1
  434. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CWEZSYaw.js → erDiagram-SSCWMZ5O-Dpz9_0zn.js} +1 -1
  435. ksadk/server/static/assets/eventmodeling-NTZA5JFV-B5-8RH9c.js +1 -0
  436. ksadk/server/static/assets/flowDiagram-A5DVABFB-BppFxEKw.js +1 -0
  437. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-TWIxoyYL.js → ganttDiagram-EL5Y4UJY-DDaG1f4_.js} +1 -1
  438. ksadk/server/static/assets/gitGraph-4MIJSDKK-B-AhYj4C.js +1 -0
  439. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-DDh2hd2S.js → gitGraphDiagram-WWUBYQGX-DcxzRwYC.js} +1 -1
  440. ksadk/server/static/assets/index-BMd2mucF.css +2 -0
  441. ksadk/server/static/assets/index-D5qyyhTH.js +244 -0
  442. ksadk/server/static/assets/info-A6RAGUB7-0uiKrC35.js +1 -0
  443. ksadk/server/static/assets/{infoDiagram-RXCK75RN-CgoyWiDR.js → infoDiagram-RXCK75RN-CYMdn6lQ.js} +1 -1
  444. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CyRIu_om.js → ishikawaDiagram-5VMMS53U-CLHFAD6c.js} +1 -1
  445. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DN5JXHzN.js → journeyDiagram-EYS64GPL-BHSKQGAl.js} +1 -1
  446. ksadk/server/static/assets/{kanban-definition-3QL26DDD-CNP3ui66.js → kanban-definition-3QL26DDD-D5W3tjTT.js} +1 -1
  447. ksadk/server/static/assets/{katex-DWEzQy1d.js → katex-mtjOi4KM.js} +1 -1
  448. ksadk/server/static/assets/{linear-C-qHp7d2.js → linear-BETqsxE_.js} +1 -1
  449. ksadk/server/static/assets/{mermaid-parser.core-Cl-K943T.js → mermaid-parser.core-DPWrvs90.js} +2 -2
  450. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-D5DB5mYm.js → mindmap-definition-FBJOCRG2-CJG2mfBP.js} +1 -1
  451. ksadk/server/static/assets/packet-AYTQ26CC-BVTmZ_cw.js +1 -0
  452. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-BQVc9ia_.js → pegDiagram-XKGWAZYB-GjAPNaqn.js} +1 -1
  453. ksadk/server/static/assets/pie-WAS4IAKB-DyfxBU7V.js +1 -0
  454. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-B6UCAvtY.js → pieDiagram-E7YTZNPT-ToIewrqr.js} +1 -1
  455. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-mIr2d3eb.js → quadrantDiagram-AXDQQJYC-4d78KiEY.js} +1 -1
  456. ksadk/server/static/assets/radar-RG4KPBEZ-FFontjL2.js +1 -0
  457. ksadk/server/static/assets/railroad-74A4TZTK-D0Uidzen.js +1 -0
  458. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BOo_9T2h.js +1 -0
  459. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-D6-BjW7Z.js +1 -0
  460. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CXx__yMm.js +1 -0
  461. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-Dt3FFDmK.js → railroadDiagram-O6MQD6OU-DKzx4xfv.js} +1 -1
  462. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-Cz_vQtgF.js → requirementDiagram-EFPCY7ZU-CJYljxQS.js} +1 -1
  463. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-wlO1TsH5.js → sankeyDiagram-P5KCCOFB-DLU2fV1w.js} +1 -1
  464. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-CHRbElYq.js → sequenceDiagram-WJ2MYXX4-CVqysrA9.js} +1 -1
  465. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DXX54iyO.js → sizeCapture-X5ZJPWSS-BUxfmTHc.js} +1 -1
  466. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-Dp_lw9II.js → stateDiagram-HBIQ2CUA-CNFgYI9E.js} +1 -1
  467. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BXAFScz8.js +1 -0
  468. ksadk/server/static/assets/{swimlanes-XN3QIQJK-D8O5UlLG.js → swimlanes-XN3QIQJK-B6qCMe8N.js} +1 -1
  469. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uIQ2lJKH.js +8 -0
  470. ksadk/server/static/assets/{timeline-definition-24CTP7MA-8mfKcxvG.js → timeline-definition-24CTP7MA-CMD3x_U_.js} +1 -1
  471. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5GgucZ.js +1 -0
  472. ksadk/server/static/assets/treemap-WGGIJYW6-Bq1u1SpG.js +1 -0
  473. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-EnNl0DE7.js → vennDiagram-4TSXK5OY-BqtUqvXM.js} +1 -1
  474. ksadk/server/static/assets/wardley-WFR3VGLG-QAt06uEz.js +1 -0
  475. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DBu5fbYr.js → wardleyDiagram-VM6X3IG4-B5KfDjI-.js} +1 -1
  476. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-BSVXs4IY.js → xychartDiagram-S5SC5T6Z-BaUlSZrn.js} +1 -1
  477. ksadk/server/static/index.html +2 -2
  478. ksadk/server/terminal_sessions.py +34 -2
  479. ksadk/session_context.py +66 -0
  480. ksadk/sessions/__init__.py +11 -21
  481. ksadk/sessions/_local_service_sync.py +263 -1
  482. ksadk/sessions/base.py +176 -0
  483. ksadk/sessions/errors.py +4 -0
  484. ksadk/sessions/in_memory.py +309 -19
  485. ksadk/sessions/invocation_identity.py +235 -0
  486. ksadk/sessions/local_service.py +83 -1
  487. ksadk/sessions/persistence.py +275 -0
  488. ksadk/sessions/postgres_service.py +358 -0
  489. ksadk/sessions/resilience.py +8 -0
  490. ksadk/sessions/resilient.py +362 -4
  491. ksadk/sessions/topology.py +135 -0
  492. ksadk/skills/__init__.py +26 -0
  493. ksadk/skills/events.py +464 -0
  494. ksadk/skills/manifest_cache.py +263 -0
  495. ksadk/skills/mcp_server/__init__.py +0 -0
  496. ksadk/skills/mcp_server/_registry.py +33 -0
  497. ksadk/skills/mcp_server/_routing.py +26 -0
  498. ksadk/skills/mcp_server/_workspace_files.py +160 -0
  499. ksadk/skills/mcp_server/register.py +415 -0
  500. ksadk/skills/mcp_server/server.py +218 -0
  501. ksadk/skills/models.py +37 -4
  502. ksadk/skills/observability.py +132 -0
  503. ksadk/skills/package_store.py +261 -40
  504. ksadk/skills/runtime/agent.py +67 -9
  505. ksadk/skills/runtime/artifact_delivery.py +139 -0
  506. ksadk/skills/runtime/artifacts.py +87 -0
  507. ksadk/skills/runtime/backends/e2b.py +460 -27
  508. ksadk/skills/runtime/backends/local.py +629 -62
  509. ksadk/skills/runtime/base.py +81 -7
  510. ksadk/skills/runtime/executor.py +268 -1
  511. ksadk/skills/runtime/loader.py +118 -5
  512. ksadk/skills/runtime/pinned.py +114 -0
  513. ksadk/skills/runtime/request.py +49 -0
  514. ksadk/skills/service_client.py +167 -28
  515. ksadk/skills/tool_defs.py +108 -3
  516. ksadk/studio/api.py +810 -93
  517. ksadk/studio/api_catalog_routes.py +18 -0
  518. ksadk/studio/api_contracts.py +8 -2
  519. ksadk/studio/api_plugin_routes.py +562 -104
  520. ksadk/studio/api_resource_connections.py +221 -0
  521. ksadk/studio/authoring.py +12 -6
  522. ksadk/studio/authoring_coordinator.py +23 -16
  523. ksadk/studio/builder.py +88 -0
  524. ksadk/studio/capabilities.py +23 -6
  525. ksadk/studio/channel_connections.py +333 -0
  526. ksadk/studio/cloud.py +370 -112
  527. ksadk/studio/cloud_shared_web.py +638 -0
  528. ksadk/studio/codex_agent_service.py +130 -28
  529. ksadk/studio/codex_builder.py +242 -3
  530. ksadk/studio/codex_credentials.py +90 -0
  531. ksadk/studio/codex_manifest.py +31 -4
  532. ksadk/studio/codex_plugin_store.py +746 -0
  533. ksadk/studio/codex_provider_build.py +231 -0
  534. ksadk/studio/codex_run.py +190 -26
  535. ksadk/studio/compatibility_report.py +12 -1
  536. ksadk/studio/compiler.py +88 -14
  537. ksadk/studio/configuration.py +182 -0
  538. ksadk/studio/contracts.py +165 -11
  539. ksadk/studio/dsh_application.py +247 -0
  540. ksadk/studio/dsh_capability_service.py +1374 -0
  541. ksadk/studio/dsh_lifecycle.py +58 -0
  542. ksadk/studio/dsh_models.py +59 -0
  543. ksadk/studio/dsh_provider_registration.py +367 -21
  544. ksadk/studio/entry.py +53 -0
  545. ksadk/studio/event_store.py +36 -5
  546. ksadk/studio/execution_host.py +525 -0
  547. ksadk/studio/framework_run.py +32 -10
  548. ksadk/studio/hosted_kernel.py +89 -14
  549. ksadk/studio/kernel_registry.py +418 -0
  550. ksadk/studio/kernel_sqlite_migration.py +181 -0
  551. ksadk/studio/mcp_runtime.py +11 -3
  552. ksadk/studio/model_client.py +1180 -66
  553. ksadk/studio/model_profile_service.py +26 -11
  554. ksadk/studio/native_documents.py +172 -0
  555. ksadk/studio/plugin_composition.py +202 -24
  556. ksadk/studio/plugin_kernel_adapter.py +21 -106
  557. ksadk/studio/plugin_lifecycle.py +80 -0
  558. ksadk/studio/plugin_runtime.py +448 -56
  559. ksadk/studio/provider_recovery.py +59 -0
  560. ksadk/studio/recovery_page.py +70 -0
  561. ksadk/studio/resource_authority.py +664 -0
  562. ksadk/studio/resource_binding_validation.py +77 -0
  563. ksadk/studio/resource_build_admission.py +196 -0
  564. ksadk/studio/resource_build_materializer.py +149 -0
  565. ksadk/studio/resource_catalog.py +149 -2
  566. ksadk/studio/resource_connections.py +220 -0
  567. ksadk/studio/run_activity.py +895 -0
  568. ksadk/studio/run_documents.py +127 -0
  569. ksadk/studio/run_service.py +789 -83
  570. ksadk/studio/runtime_catalog.py +53 -10
  571. ksadk/studio/runtime_source.py +16 -8
  572. ksadk/studio/scheduler_assistant.py +317 -0
  573. ksadk/studio/scheduler_runtime.py +32 -280
  574. ksadk/studio/scheduler_service.py +3 -0
  575. ksadk/studio/service.py +861 -120
  576. ksadk/studio/shared_web.py +579 -82
  577. ksadk/studio/static/assets/ChannelsPage-D_PGmKVq.js +8 -0
  578. ksadk/studio/static/assets/CodeBlock-DMIf4h33-UIqo-BPW.js +44 -0
  579. ksadk/studio/static/assets/ExecutionTree-v3HexvPo-Bk8wzGSy.js +1 -0
  580. ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  581. ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  582. ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  583. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  584. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  585. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  586. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  587. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  588. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  589. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  590. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  591. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  592. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  593. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  594. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  595. ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  596. ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  597. ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  598. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  599. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  600. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  601. ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  602. ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  603. ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  604. ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  605. ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  606. ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  607. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  608. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  609. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  610. ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  611. ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  612. ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  613. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  614. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  615. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  616. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  617. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  618. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  619. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  620. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  621. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  622. ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  623. ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  624. ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  625. ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  626. ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  627. ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  628. ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  629. ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  630. ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  631. ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  632. ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  633. ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  634. ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  635. ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  636. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  637. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  638. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  639. ksadk/studio/static/assets/MathMessageMarkdown-BesSeCYl-BEOyPC3w.css +1 -0
  640. ksadk/studio/static/assets/MathMessageMarkdown-BesSeCYl-OhNwH4K9.js +8 -0
  641. ksadk/studio/static/assets/MermaidBlock-H_0qzQDf-BdXtxug_.js +11 -0
  642. ksadk/studio/static/assets/MessageMarkdown-CwMTvgFj-g0I-I4dD.js +59 -0
  643. ksadk/studio/static/assets/PrismRenderer-5pK6tUdb.js +3 -0
  644. ksadk/studio/static/assets/TeamsPage-DqX4HWKQ.js +3 -0
  645. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-Bnb1O3tA.js +1 -0
  646. ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
  647. ksadk/studio/static/assets/architecture-7GRP2DOG-BMOPAkUC.js +1 -0
  648. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-5Zn1gqJv.js +36 -0
  649. ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
  650. ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CLB4L11u.js +129 -0
  651. ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BOma_Z_F.js +38 -0
  652. ksadk/studio/static/assets/channel-r8itPEik.js +1 -0
  653. ksadk/studio/static/assets/chunk-2E4U76K2-BFf_huql.js +2 -0
  654. ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  655. ksadk/studio/static/assets/chunk-2ZTRR5NV-C2qZJila.js +2 -0
  656. ksadk/studio/static/assets/chunk-3Z5EZCMW-DMniOlPd.js +1 -0
  657. ksadk/studio/static/assets/chunk-4HAMMTFA-DVtDP4rm.js +62 -0
  658. ksadk/studio/static/assets/chunk-5V3GS4D5-i-ZDOEnP.js +1 -0
  659. ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  660. ksadk/studio/static/assets/chunk-6AZGARVD-BB6FqMl-.js +1 -0
  661. ksadk/studio/static/assets/chunk-6EIED4P4-DdUJkP0f.js +1 -0
  662. ksadk/studio/static/assets/chunk-6K3QC6MW-CqVsVn-y.js +1 -0
  663. ksadk/studio/static/assets/chunk-6TQVIW2G-DKlLbNIP.js +1 -0
  664. ksadk/studio/static/assets/chunk-747NJXEK-BFkZPlab.js +2 -0
  665. ksadk/studio/static/assets/chunk-75Z2AOVW-BZNhM4vB.js +2 -0
  666. ksadk/studio/static/assets/chunk-CLGD4ZFX-D-GTtyKs.js +1 -0
  667. ksadk/studio/static/assets/chunk-DU6HZSFF-CpEZCUgg.js +128 -0
  668. ksadk/studio/static/assets/chunk-F27PBJKO-D7pvKf0C.js +1 -0
  669. ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
  670. ksadk/studio/static/assets/chunk-GMAD6QVW-DE_8H717.js +72 -0
  671. ksadk/studio/static/assets/chunk-GVQU2GXP-BfEB0lNv.js +1 -0
  672. ksadk/studio/static/assets/chunk-I5DQTOEV-Hm2LfiYI.js +1 -0
  673. ksadk/studio/static/assets/chunk-ICYGCRZG-749o-pGJ.js +1 -0
  674. ksadk/studio/static/assets/chunk-IH6LHLGP-CC6I9F3i.js +1 -0
  675. ksadk/studio/static/assets/chunk-IMKFNOWR-D38axYOR.js +231 -0
  676. ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  677. ksadk/studio/static/assets/chunk-KI3K4JFJ-Rma-0k_M.js +1 -0
  678. ksadk/studio/static/assets/chunk-L3NEJ4N5-Dq5xn7aL.js +1 -0
  679. ksadk/studio/static/assets/chunk-LNGE3PJU-DWpGwHrW.js +34 -0
  680. ksadk/studio/static/assets/chunk-OSK3NFVY-DiCQjx9b.js +10 -0
  681. ksadk/studio/static/assets/chunk-OUJLGHUK-D0j2JRSg.js +2 -0
  682. ksadk/studio/static/assets/chunk-P2QGCYS3-VdhKmfYq.js +1 -0
  683. ksadk/studio/static/assets/chunk-POPQ4Y6H-C1_rzO5M.js +1 -0
  684. ksadk/studio/static/assets/chunk-PWAF6VOD-B45HvflI.js +1 -0
  685. ksadk/studio/static/assets/chunk-SHT3W25Y-DsCFnRVE.js +168 -0
  686. ksadk/studio/static/assets/chunk-SVP7TREG-DljApgRX.js +88 -0
  687. ksadk/studio/static/assets/chunk-TICWLB2K-DWqRtyqa.js +206 -0
  688. ksadk/studio/static/assets/chunk-TLUHSLCS-DUeGgnD5.js +2 -0
  689. ksadk/studio/static/assets/chunk-UY3FDG6J-CnmaAkG5.js +1 -0
  690. ksadk/studio/static/assets/chunk-XHIXRSVI-BFQ6B8BE.js +1 -0
  691. ksadk/studio/static/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
  692. ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  693. ksadk/studio/static/assets/classDiagram-ZZMXUADV-DjeMNJmu.js +1 -0
  694. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-DjeMNJmu.js +1 -0
  695. ksadk/studio/static/assets/clsx-DB0hHKMi.js +1 -0
  696. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-om8AY0Mc.js +1 -0
  697. ksadk/studio/static/assets/createLucideIcon-DR0LGTP5.js +1 -0
  698. ksadk/studio/static/assets/cynefin-OW5HDTMX-7tP7QfM3.js +1 -0
  699. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-6BrmK52S.js +62 -0
  700. ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
  701. ksadk/studio/static/assets/dagre-GXQ25YYZ-buZBRlwz.js +4 -0
  702. ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
  703. ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
  704. ksadk/studio/static/assets/diagram-S7CK7UJ4-C6aH78c4.js +30 -0
  705. ksadk/studio/static/assets/diagram-UQ7AKVKN-DY_tQ6C_.js +41 -0
  706. ksadk/studio/static/assets/diagram-VSXAHHWV-DX9p5cQT.js +3 -0
  707. ksadk/studio/static/assets/diagram-VX7I27RA-DB2WSH8X.js +24 -0
  708. ksadk/studio/static/assets/diagram-Z3DM3KII-Ce1BJwHE.js +24 -0
  709. ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
  710. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-Daukxwqf.js +1 -0
  711. ksadk/studio/static/assets/erDiagram-RLTQ6QDP-CGthTMmJ.js +99 -0
  712. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-BR2FzK4R.js +1 -0
  713. ksadk/studio/static/assets/flowDiagram-HODETNUW-CZ1tEenp.js +1 -0
  714. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BfoAZW9X.js +292 -0
  715. ksadk/studio/static/assets/gitGraph-4MIJSDKK-DYlXv_yJ.js +1 -0
  716. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-S985OIJF.js +106 -0
  717. ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
  718. ksadk/studio/static/assets/iconfont-4HN3C9Pg.woff2 +0 -0
  719. ksadk/studio/static/assets/index-CfEnms6Y.css +2 -0
  720. ksadk/studio/static/assets/index-Dp61rOWZ.js +0 -0
  721. ksadk/studio/static/assets/index.dom-BQenBtFm.js +1 -0
  722. ksadk/studio/static/assets/info-A6RAGUB7-BlU-8_xu.js +1 -0
  723. ksadk/studio/static/assets/infoDiagram-27XIBGKW-CO3W8tFn.js +2 -0
  724. ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
  725. ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-BUGEl8cO.js +70 -0
  726. ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-Ch2ZYxvr.js +139 -0
  727. ksadk/studio/static/assets/kanban-definition-UXKFOSKX-Da-Fp4vC.js +89 -0
  728. ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
  729. ksadk/studio/static/assets/kingsoft-cloud-BOcLiQ3e.ico +0 -0
  730. ksadk/studio/static/assets/line-BDaeq300.js +1 -0
  731. ksadk/studio/static/assets/linear-DmucvK78.js +1 -0
  732. ksadk/studio/static/assets/mermaid-parser.core-Cj5mYdBi.js +4 -0
  733. ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-CvlsVQ38.js +96 -0
  734. ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
  735. ksadk/studio/static/assets/packet-AYTQ26CC-BSJEH9Lb.js +1 -0
  736. ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
  737. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-BuHuNgT5.js +1 -0
  738. ksadk/studio/static/assets/pie-WAS4IAKB-qxv01Y8W.js +1 -0
  739. ksadk/studio/static/assets/pieDiagram-E7YTZNPT-DlrWiSOv.js +39 -0
  740. ksadk/studio/static/assets/preload-helper-CO68xz6u.js +1 -0
  741. ksadk/studio/static/assets/presentation-yYw7xK60-BmcZriri.js +1 -0
  742. ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-BA3hpUZM.js +7 -0
  743. ksadk/studio/static/assets/radar-RG4KPBEZ-B6h6pWOs.js +1 -0
  744. ksadk/studio/static/assets/railroad-74A4TZTK-CGtTWdGc.js +1 -0
  745. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-Cq7y22IA.js +1 -0
  746. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-V0aQVv9m.js +1 -0
  747. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-BQiIsX_p.js +1 -0
  748. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-BxpAazym.js +1 -0
  749. ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-E-Ge0FcV.js +84 -0
  750. ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
  751. ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
  752. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-CA6YKhQ3.js +40 -0
  753. ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-CcElXGg4.js +162 -0
  754. ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  755. ksadk/studio/static/assets/src-B6xuSHsQ.js +1 -0
  756. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DdXZOFqY.js +1 -0
  757. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-CJbOM-QK.js +1 -0
  758. ksadk/studio/static/assets/swimlanes-42K2YHIH-NtgEEHLY.js +1 -0
  759. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-D-AVlW8B.js +8 -0
  760. ksadk/studio/static/assets/timeline-definition-24CTP7MA-CIuYhNy3.js +120 -0
  761. ksadk/studio/static/assets/treeView-Q6P3EWNA-BTTYcvrF.js +1 -0
  762. ksadk/studio/static/assets/treemap-WGGIJYW6-Cg7tyfH8.js +1 -0
  763. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-7HbApbrv.js +34 -0
  764. ksadk/studio/static/assets/wardley-WFR3VGLG-C6N1rULY.js +1 -0
  765. ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-CMJiaedy.js +78 -0
  766. ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-BdgtMvW2.js +7 -0
  767. ksadk/studio/static/index.html +8 -2
  768. ksadk/studio/teams_catalog.py +133 -0
  769. ksadk/studio/teams_installation.py +214 -0
  770. ksadk/studio/teams_node.py +545 -0
  771. ksadk/studio/teams_node_runner.py +69 -0
  772. ksadk/studio/teams_remote.py +274 -0
  773. ksadk/studio/templates.py +40 -19
  774. ksadk/studio/validator.py +13 -0
  775. ksadk/studio/workspace.py +19 -4
  776. ksadk/studio/workspace_plugins.py +136 -0
  777. ksadk/studio/workspace_registry.py +286 -0
  778. ksadk/toolsets/__init__.py +11 -0
  779. ksadk/toolsets/skills.py +446 -378
  780. ksadk/toolsets/workspace.py +3 -3
  781. ksadk/toolsets/workspace_identity.py +15 -0
  782. ksadk/version.py +1 -1
  783. ksadk_runtime_common/memory_backend/providers/lancedb.py +56 -2
  784. ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -148
  785. ksadk_runtime_common/workspace_files/router.py +26 -13
  786. agentengine_sdk_python-0.8.3.dist-info/RECORD +0 -833
  787. ksadk/server/static/assets/MathMessageMarkdown-D9uB55Oh.js +0 -8
  788. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +0 -1
  789. ksadk/server/static/assets/channel-s354Yo6o.js +0 -1
  790. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +0 -1
  791. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +0 -1
  792. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +0 -1
  793. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +0 -1
  794. ksadk/server/static/assets/dist-DdRBIceA.js +0 -1
  795. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +0 -1
  796. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +0 -1
  797. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +0 -1
  798. ksadk/server/static/assets/index-B2k_urY8.js +0 -241
  799. ksadk/server/static/assets/index-ILPt6IWF.css +0 -2
  800. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +0 -1
  801. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +0 -1
  802. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +0 -1
  803. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +0 -1
  804. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +0 -1
  805. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +0 -1
  806. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +0 -1
  807. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +0 -1
  808. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +0 -1
  809. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +0 -8
  810. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +0 -1
  811. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +0 -1
  812. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +0 -1
  813. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
  814. ksadk/studio/static/assets/index-DXs1Eq4M.css +0 -1
  815. ksadk/studio/static/assets/index-DeDqwTsD.js +0 -283
  816. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.5.dist-info}/WHEEL +0 -0
  817. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.5.dist-info}/entry_points.txt +0 -0
  818. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.5.dist-info}/licenses/LICENSE +0 -0
  819. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.5.dist-info}/top_level.txt +0 -0
ksadk/studio/entry.py ADDED
@@ -0,0 +1,53 @@
1
+ """Studio entry selection and local-session bootstrap responses."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import os
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ from fastapi import Request
11
+ from fastapi.responses import RedirectResponse, Response
12
+
13
+ from ksadk.studio.errors import StudioError
14
+
15
+
16
+ async def studio_entry_response(
17
+ studio: Any, request: Request, static_root: Path,
18
+ ) -> Response:
19
+ # Workspace navigation is contributed by the official Core client.
20
+ # Opening the standalone React shell with enabled plugins silently
21
+ # hides those pages. Select the host from Profile metadata, without
22
+ # starting Core just to decide which entry to serve.
23
+ use_core = False
24
+ if request.url.path == "/" and os.environ.get("KSADK_STUDIO_LAZY_START") != "1":
25
+ try:
26
+ # 有界等待:探测可能触发 Node bridge 冷启动(可达数十秒),
27
+ # 超时则先回 React shell,避免首屏长时间白屏;
28
+ # 预热完成后真实 Core 用户下次导航仍会拿到正确重定向。
29
+ use_core = await asyncio.wait_for(
30
+ studio.dsh_capabilities.has_enabled_profile_plugins(), timeout=2.0
31
+ )
32
+ except (asyncio.TimeoutError, StudioError, OSError, RuntimeError):
33
+ # The optional toolchain may be absent in a plain SDK workspace.
34
+ pass
35
+ if request.url.path == "/studio-recovery/":
36
+ from ksadk.studio.recovery_page import RECOVERY_HTML
37
+
38
+ response = Response(content=RECOVERY_HTML, media_type="text/html")
39
+ # Desktop startup keeps the shell available while Core starts.
40
+ elif use_core and os.environ.get("KSADK_STUDIO_LAZY_START") != "1":
41
+ target = "/studio-core/"
42
+ if request.url.query:
43
+ target += "?" + request.url.query
44
+ # Browsers inherit the original fragment across this redirect,
45
+ # preserving Agent/session/group deep links and CLI bootstrap.
46
+ response = RedirectResponse(target, status_code=307)
47
+ else:
48
+ path = static_root / "index.html"
49
+ html = path.read_text(encoding="utf-8")
50
+ # Keep hashed module URLs identical to internal lazy imports.
51
+ response = Response(content=html, media_type="text/html")
52
+ response.headers["Cache-Control"] = "no-store"
53
+ return response
@@ -20,6 +20,11 @@ class RunEventStore:
20
20
  def __init__(self, workspace: Workspace) -> None:
21
21
  self.workspace = workspace
22
22
  self.trace_store = OtlpTraceStore(workspace)
23
+ # (mtime, size, inode) → 已解析 (record, events)。流式期间 SSE 投影
24
+ # 每 50ms 调 events()/list_runs(),全量 JSON 解析 + Pydantic 验证会
25
+ # 随事件数线性放大(实测把事件循环拖到整段卡死)。同进程内写读方
26
+ # 在 _write/_read 之间共享此缓存;外部改动通过 stat 元数据失效。
27
+ self._cache: dict[str, tuple[tuple[float, int, int], tuple[Any, list[RunEvent]]]] = {}
23
28
 
24
29
  def _path(self, run_id: str) -> Path:
25
30
  return self.workspace.resolve(Path(".agentkit/runs") / f"{run_id}.json")
@@ -120,9 +125,13 @@ class RunEventStore:
120
125
  directory = self.workspace.resolve(".agentkit/runs")
121
126
  for path in sorted(directory.glob("run_*.json")):
122
127
  try:
123
- payload = json.loads(path.read_text(encoding="utf-8"))
124
- record = RunRecord.model_validate(payload["record"])
125
- except (OSError, ValueError, KeyError, ValidationError):
128
+ # ``list_runs`` is polled while a chat is running. Parsing every
129
+ # growing run file on every poll turns a streamed response into
130
+ # an O(polls * events) JSON workload and can consume an entire
131
+ # CPU core. Route the read through the stat-aware cache used by
132
+ # ``get``/``events``; external edits still invalidate it.
133
+ record, _events = self._read(path.stem)
134
+ except (OSError, ValueError, KeyError, ValidationError, StudioError):
126
135
  continue
127
136
  if session_id and record.session_id != session_id:
128
137
  continue
@@ -146,6 +155,7 @@ class RunEventStore:
146
155
  if path.is_file():
147
156
  self.trace_store.delete(record.trace_id, purge=True)
148
157
  path.unlink()
158
+ self._cache.pop(record.id, None)
149
159
  deleted += 1
150
160
  return deleted
151
161
 
@@ -231,15 +241,31 @@ class RunEventStore:
231
241
  status=status,
232
242
  )
233
243
 
244
+ @staticmethod
245
+ def _stat_key(path: Path) -> tuple[float, int, int]:
246
+ info = path.stat()
247
+ return (info.st_mtime, info.st_size, info.st_ino)
248
+
234
249
  def _read(self, run_id: str) -> tuple[RunRecord, list[RunEvent]]:
235
250
  path = self._path(run_id)
236
251
  if not path.is_file():
252
+ self._cache.pop(run_id, None)
237
253
  raise not_found("run", run_id)
254
+ try:
255
+ key = self._stat_key(path)
256
+ except OSError:
257
+ key = None
258
+ cached = self._cache.get(run_id)
259
+ if cached is not None and key is not None and cached[0] == key:
260
+ return cached[1]
238
261
  try:
239
262
  payload = json.loads(path.read_text(encoding="utf-8"))
240
263
  record = RunRecord.model_validate(payload["record"])
241
264
  events = [RunEvent.model_validate(item) for item in payload.get("events", [])]
242
- return record, events
265
+ parsed = (record, events)
266
+ if key is not None:
267
+ self._cache[run_id] = (key, parsed)
268
+ return parsed
243
269
  except (OSError, ValueError, KeyError, ValidationError) as exc:
244
270
  raise StudioError(
245
271
  "RUN_RECORD_INVALID",
@@ -256,7 +282,12 @@ class RunEventStore:
256
282
  payload["events"] = [
257
283
  event.model_dump(by_alias=True, exclude_none=True, mode="json") for event in events
258
284
  ]
285
+ path = self._path(record.id)
259
286
  self.workspace.atomic_write_text(
260
- self._path(record.id),
287
+ path,
261
288
  json.dumps(payload, ensure_ascii=False, sort_keys=True, indent=2) + "\n",
262
289
  )
290
+ try:
291
+ self._cache[record.id] = (self._stat_key(path), (record, list(events or [])))
292
+ except OSError:
293
+ self._cache.pop(record.id, None)
@@ -0,0 +1,525 @@
1
+ """Authorized plugin execution services over Studio's shared Build registry.
2
+
3
+ This module owns transport authorization and immutable execution references.
4
+ It has no group/task/leader policy. Installed plugins register their own
5
+ authorization and policy resolvers; all commands still enter AgentKernel.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import asyncio
11
+ import hashlib
12
+ import json
13
+ import sqlite3
14
+ from collections.abc import Awaitable, Callable
15
+ from dataclasses import asdict
16
+ from pathlib import Path
17
+ from typing import Any
18
+ from uuid import NAMESPACE_URL, uuid5
19
+
20
+ from ksadk.conversations.projector import (
21
+ project_conversation_item,
22
+ project_interaction_conversation_item,
23
+ )
24
+ from ksadk.events.canonical import parse_runtime_event
25
+ from ksadk.kernel.contracts import AgentControlCommand
26
+ from ksadk.kernel.execution_grants import ExecutionGrantSpec, execution_grant_run_id
27
+ from ksadk.kernel.ingress import trusted_context
28
+ from ksadk.plugins.execution_host import (
29
+ ExecutionBarrier,
30
+ ExecutionReceipt,
31
+ PluginExecutionScope,
32
+ )
33
+ from ksadk.studio.kernel_registry import StudioBuildKernelRegistry
34
+
35
+ Authorize = Callable[[PluginExecutionScope, str], None]
36
+ ResolvePolicy = Callable[..., Awaitable[Any]]
37
+
38
+
39
+ class ExecutionHostError(ValueError):
40
+ def __init__(self, code: str, message: str, *, status: int = 403) -> None:
41
+ super().__init__(message)
42
+ self.code, self.status = code, status
43
+
44
+
45
+ def _json(value: Any) -> str:
46
+ return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
47
+
48
+
49
+ def _hash(value: Any) -> str:
50
+ return hashlib.sha256(_json(value).encode()).hexdigest()
51
+
52
+
53
+ class StudioExecutionHost:
54
+ def __init__(self, registry: StudioBuildKernelRegistry, *, state_path: Path) -> None:
55
+ self.registry = registry
56
+ state_path.parent.mkdir(parents=True, exist_ok=True)
57
+ self._db = sqlite3.connect(state_path, isolation_level=None, check_same_thread=False)
58
+ self._db.execute("PRAGMA journal_mode=WAL")
59
+ self._db.execute("PRAGMA synchronous=FULL")
60
+ self._db.executescript("""
61
+ CREATE TABLE IF NOT EXISTS plugin_session_scopes (
62
+ session_id TEXT PRIMARY KEY, scope TEXT NOT NULL);
63
+ CREATE TABLE IF NOT EXISTS execution_policy_refs (
64
+ ref TEXT PRIMARY KEY, scope TEXT NOT NULL, context TEXT NOT NULL,
65
+ command_id TEXT NOT NULL, run_id TEXT NOT NULL);
66
+ CREATE TABLE IF NOT EXISTS plugin_grant_operations (
67
+ operation_id TEXT PRIMARY KEY, digest TEXT NOT NULL,
68
+ expected_revision INTEGER NOT NULL);
69
+ """)
70
+ self._plugins: dict[str, tuple[str, Authorize, ResolvePolicy]] = {}
71
+ self._grant_lock = asyncio.Lock()
72
+ self._dispatch_lock = asyncio.Lock()
73
+ self._admission_open = True
74
+
75
+ def register_plugin(
76
+ self, plugin_id: str, digest: str, *, authorize: Authorize, resolve_policy: ResolvePolicy
77
+ ) -> Callable[[], None]:
78
+ if plugin_id in self._plugins:
79
+ raise ExecutionHostError("plugin_already_registered", "插件已注册")
80
+ registration = (digest, authorize, resolve_policy)
81
+ self._plugins[plugin_id] = registration
82
+
83
+ def dispose() -> None:
84
+ if self._plugins.get(plugin_id) is registration:
85
+ self._plugins.pop(plugin_id)
86
+
87
+ return dispose
88
+
89
+ def _authorize(self, scope: PluginExecutionScope, operation: str) -> None:
90
+ registered = self._plugins.get(scope.plugin_id)
91
+ if registered is None or registered[0] != scope.plugin_digest:
92
+ raise ExecutionHostError("plugin_grant_unavailable", "插件执行授权不可用")
93
+ registered[1](scope, operation)
94
+ row = self._db.execute(
95
+ "SELECT scope FROM plugin_session_scopes WHERE session_id=?", (scope.session_id,)
96
+ ).fetchone()
97
+ if row and row[0] != _json(asdict(scope)):
98
+ raise ExecutionHostError("execution_scope_mismatch", "会话绑定与执行授权不一致")
99
+
100
+ @staticmethod
101
+ def build_id(binding_ref: str) -> str:
102
+ prefix = "local-build:"
103
+ if not binding_ref.startswith(prefix) or not binding_ref[len(prefix) :]:
104
+ raise ExecutionHostError("binding_unsupported", "当前宿主不支持该执行绑定", status=422)
105
+ return binding_ref[len(prefix) :]
106
+
107
+ async def _target(self, scope: PluginExecutionScope, operation: str):
108
+ self._authorize(scope, operation)
109
+ target = await self.registry.ensure_build(self.build_id(scope.binding_ref))
110
+ if target.tenant_id != scope.tenant_id:
111
+ raise ExecutionHostError("execution_tenant_mismatch", "执行绑定不属于当前授权域")
112
+ return target, self.registry.runtime_for_build(target.build_id)
113
+
114
+ async def describe(self, scope: PluginExecutionScope) -> dict[str, Any]:
115
+ target, runtime = await self._target(scope, "describe")
116
+ spec = self.registry.spec_for_build(target.build_id)
117
+ matrix = runtime.kernel.capabilities()
118
+ policy_capability = getattr(matrix, "execution_policy", None)
119
+ policy_supported = bool(policy_capability and policy_capability.supported)
120
+ return {
121
+ "bindingRef": scope.binding_ref,
122
+ "providerRef": spec.request_config.get(
123
+ "provider_ref", spec.launch_context.runtime_type
124
+ ),
125
+ "kind": "local_build",
126
+ "agentId": target.agent_id,
127
+ "buildId": target.build_id,
128
+ "authorityRef": scope.authority_ref,
129
+ "tenantId": target.tenant_id,
130
+ "pluginLockDigest": spec.request_config.get(
131
+ "plugin_bundle_digest", spec.manifest_sha256
132
+ ),
133
+ "capabilities": {
134
+ "enqueue": policy_supported,
135
+ "leader": policy_supported,
136
+ "cancel": matrix.cancel.supported,
137
+ "restore": matrix.durable_restore.supported,
138
+ "steer": matrix.steer.supported,
139
+ "interaction": matrix.submit_interaction.supported,
140
+ },
141
+ "capabilitySnapshot": matrix.model_dump(mode="json"),
142
+ }
143
+
144
+ async def ensure_session(self, scope: PluginExecutionScope) -> None:
145
+ target, _ = await self._target(scope, "ensure_session")
146
+ await self.registry.ensure_session(target.build_id, scope.session_id, scope.owner_subject)
147
+ self._db.execute(
148
+ "INSERT OR IGNORE INTO plugin_session_scopes VALUES(?,?)",
149
+ (scope.session_id, _json(asdict(scope))),
150
+ )
151
+ self._authorize(scope, "ensure_session")
152
+
153
+ def require_unreserved_session(self, session_id: str) -> None:
154
+ if self.is_reserved_session(session_id):
155
+ raise ExecutionHostError(
156
+ "plugin_session_control_required", "该会话由插件管理,请从插件页面操作"
157
+ )
158
+
159
+ def is_reserved_session(self, session_id: str) -> bool:
160
+ return bool(
161
+ self._db.execute(
162
+ "SELECT 1 FROM plugin_session_scopes WHERE session_id=?", (session_id,)
163
+ ).fetchone()
164
+ )
165
+
166
+ def require_unreserved_run(self, run_id: str) -> None:
167
+ if self.is_reserved_run(run_id):
168
+ raise ExecutionHostError(
169
+ "plugin_run_control_required", "该执行由插件管理,请从插件页面操作"
170
+ )
171
+
172
+ def is_reserved_run(self, run_id: str) -> bool:
173
+ return bool(self._db.execute(
174
+ "SELECT 1 FROM execution_policy_refs WHERE run_id=?", (run_id,)
175
+ ).fetchone())
176
+
177
+ @staticmethod
178
+ def _grant(scope: PluginExecutionScope, target: Any, grant_id: str) -> ExecutionGrantSpec:
179
+ return ExecutionGrantSpec(
180
+ grant_id=grant_id,
181
+ tenant_id=scope.tenant_id,
182
+ agent_instance_id=target.agent_instance_id,
183
+ session_id=scope.session_id,
184
+ owner_ref="plugin:"
185
+ + _hash(
186
+ [scope.plugin_id, scope.plugin_digest, scope.authority_ref, scope.owner_subject]
187
+ ),
188
+ )
189
+
190
+ def _command(self, scope, target, verb, key, payload, causation=None):
191
+ trusted = trusted_context(
192
+ source_kind="system",
193
+ source_ref=scope.plugin_id,
194
+ tenant_id=scope.tenant_id,
195
+ agent_instance_id=target.agent_instance_id,
196
+ session_id=scope.session_id,
197
+ operations=(verb,),
198
+ )
199
+ command = AgentControlCommand(
200
+ command_id=uuid5(NAMESPACE_URL, _json([scope.plugin_id, scope.session_id, verb, key])),
201
+ idempotency_key=key,
202
+ tenant_id=scope.tenant_id,
203
+ agent_instance_id=target.agent_instance_id,
204
+ session_id=scope.session_id,
205
+ command_type=verb,
206
+ payload=payload,
207
+ source=trusted.source,
208
+ authorization_ref=trusted.permit.permit_id,
209
+ submitted_at=trusted.received_at,
210
+ causation_id=causation,
211
+ )
212
+ return command, trusted.permit
213
+
214
+ async def set_admission_open(self, enabled: bool) -> None:
215
+ async with self._dispatch_lock:
216
+ self._admission_open = enabled
217
+
218
+ async def submit(self, scope, **arguments):
219
+ async with self._dispatch_lock:
220
+ if not self._admission_open:
221
+ raise ExecutionHostError("host_maintenance", "插件宿主正在维护", status=503)
222
+ return await self._submit_authorized(scope, **arguments)
223
+
224
+ async def _submit_authorized(
225
+ self, scope, *, content, idempotency_key, grant_id, causation, policy_context
226
+ ):
227
+ target, runtime = await self._target(scope, "submit")
228
+ grant = self._grant(scope, target, grant_id)
229
+ await runtime.kernel.ensure_execution_grant(grant)
230
+ ref = "policy_" + _hash([asdict(scope), idempotency_key])
231
+ command, permit = self._command(
232
+ scope,
233
+ target,
234
+ "enqueue",
235
+ idempotency_key,
236
+ {
237
+ "content": content,
238
+ "execution_grant_id": grant_id,
239
+ "execution_policy_ref": ref,
240
+ },
241
+ causation,
242
+ )
243
+ expected = (
244
+ _json(asdict(scope)),
245
+ _json(policy_context),
246
+ str(command.command_id),
247
+ execution_grant_run_id(command),
248
+ )
249
+ self._db.execute(
250
+ "INSERT OR IGNORE INTO execution_policy_refs VALUES(?,?,?,?,?)", (ref, *expected)
251
+ )
252
+ stored = self._db.execute(
253
+ "SELECT scope,context,command_id,run_id FROM execution_policy_refs WHERE ref=?", (ref,)
254
+ ).fetchone()
255
+ if stored != expected:
256
+ raise ExecutionHostError(
257
+ "policy_idempotency_conflict", "原执行授权内容已改变", status=409
258
+ )
259
+ receipt = await self.registry.submit_control(command, permit)
260
+ if receipt.status not in {"accepted", "duplicate"}:
261
+ return ExecutionReceipt(
262
+ "uncertain" if receipt.status == "persistence_uncertain" else "rejected",
263
+ command_id=str(command.command_id),
264
+ message_id=str(receipt.message_id) if receipt.message_id else None,
265
+ reason=receipt.error.code if receipt.error else receipt.status,
266
+ )
267
+ return await self.lookup(scope, idempotency_key)
268
+
269
+ async def lookup(self, scope, idempotency_key):
270
+ target, runtime = await self._target(scope, "lookup")
271
+ message = await runtime.kernel_store.load_by_idempotency(scope.session_id, idempotency_key)
272
+ if message is None:
273
+ return ExecutionReceipt("missing")
274
+ command = message.command
275
+ if command is None or message.agent_instance_id != target.agent_instance_id:
276
+ raise ExecutionHostError("command_scope_mismatch", "命令作用域不一致")
277
+ run_id = execution_grant_run_id(command)
278
+ run = await runtime.kernel_store.load_run(run_id)
279
+ if run is None:
280
+ return ExecutionReceipt(
281
+ "rejected" if message.status == "discarded" else "accepted",
282
+ command_id=str(command.command_id),
283
+ message_id=message.message_id,
284
+ reason="execution_admission_revoked" if message.status == "discarded" else None,
285
+ )
286
+ status = {
287
+ "completed": "succeeded",
288
+ "paused": "awaiting_approval",
289
+ "waiting": "awaiting_approval",
290
+ "pending": None,
291
+ }.get(run.state.value, run.state.value)
292
+ output, tokens, source_id = "", 0, None
293
+ if run.state in {"completed", "failed", "cancelled", "interrupted"}:
294
+ # Terminal-only scan; streaming observation uses its own cursor.
295
+ # Stable completed item identities avoid duplicate final chunks.
296
+ messages = {}
297
+ cursor = 0
298
+ while True:
299
+ events = await runtime.session_events.read(scope.session_id, cursor, 500)
300
+ if not events:
301
+ break
302
+ cursor = events[-1].seq
303
+ for envelope in events:
304
+ if envelope.run_id != run_id or envelope.family != "runtime":
305
+ continue
306
+ payload = envelope.payload
307
+ if envelope.event_type == "usage.reported":
308
+ tokens += int(
309
+ payload.get("total_tokens")
310
+ or int(payload.get("input_tokens") or 0)
311
+ + int(payload.get("output_tokens") or 0)
312
+ )
313
+ source_metadata = (payload.get("source") or {}).get("metadata") or {}
314
+ if envelope.family_version == 2 and not source_metadata.get("parent_run_id"):
315
+ item = project_conversation_item(
316
+ parse_runtime_event(payload), session_id=scope.session_id
317
+ )
318
+ if item.kind == "assistant_text" and item.lifecycle == "completed":
319
+ messages[item.item_id] = str(item.payload.get("text") or "")
320
+ source_id = str(envelope.event_id)
321
+ output = "\n\n".join(messages.values())
322
+ return ExecutionReceipt(
323
+ "accepted",
324
+ command_id=str(command.command_id),
325
+ message_id=message.message_id,
326
+ run_id=run_id,
327
+ run_status=status,
328
+ reason="provider_restore_required" if status == "interrupted" else None,
329
+ output=output,
330
+ tokens=tokens,
331
+ source_event_id=source_id,
332
+ )
333
+
334
+ async def set_grant(self, scope, grant_id, state, idempotency_key):
335
+ target, runtime = await self._target(scope, "set_grant")
336
+ spec = self._grant(scope, target, grant_id)
337
+ async with self._grant_lock:
338
+ record = await runtime.kernel.ensure_execution_grant(spec)
339
+ operation_id = _hash([asdict(scope), idempotency_key])
340
+ operation_digest = _hash([spec.model_dump(), state])
341
+ self._db.execute(
342
+ "INSERT OR IGNORE INTO plugin_grant_operations VALUES(?,?,?)",
343
+ (operation_id, operation_digest, record.revision),
344
+ )
345
+ row = self._db.execute(
346
+ "SELECT digest,expected_revision FROM plugin_grant_operations WHERE operation_id=?",
347
+ (operation_id,),
348
+ ).fetchone()
349
+ if row[0] != operation_digest:
350
+ raise ExecutionHostError(
351
+ "grant_idempotency_conflict", "原授权变更内容已改变", status=409
352
+ )
353
+ barrier = await runtime.kernel.set_execution_grant_state(
354
+ spec, state, expected_revision=row[1], idempotency_key=operation_id
355
+ )
356
+ return ExecutionBarrier(
357
+ barrier.grant.state,
358
+ barrier.grant.revision,
359
+ in_flight=barrier.in_flight_message_ids,
360
+ queued=barrier.queued_message_ids,
361
+ discarded=barrier.discarded_message_ids,
362
+ details={"commands": [item.model_dump() for item in barrier.commands]},
363
+ )
364
+
365
+ async def cancel(self, scope, run_id, idempotency_key):
366
+ target, runtime = await self._target(scope, "cancel")
367
+ await self._require_run(scope, runtime, target, run_id)
368
+ command, permit = self._command(
369
+ scope, target, "interrupt", idempotency_key, {"run_id": run_id}
370
+ )
371
+ receipt = await self.registry.submit_control(command, permit)
372
+ return ExecutionReceipt(
373
+ "accepted" if receipt.status in {"accepted", "duplicate"} else "rejected",
374
+ command_id=str(command.command_id),
375
+ message_id=str(receipt.message_id) if receipt.message_id else None,
376
+ run_id=run_id,
377
+ )
378
+
379
+ @staticmethod
380
+ async def _require_run(scope, runtime, target, run_id):
381
+ run = await runtime.kernel_store.load_run(run_id)
382
+ if (
383
+ not run
384
+ or run.session_id != scope.session_id
385
+ or run.agent_instance_id != target.agent_instance_id
386
+ ):
387
+ raise ExecutionHostError("run_scope_mismatch", "执行不属于此会话", status=404)
388
+ return run
389
+
390
+ async def interactions(self, scope):
391
+ _, runtime = await self._target(scope, "interactions")
392
+ records = await runtime.kernel_store.list_pending_interactions(
393
+ scope.tenant_id, scope.session_id
394
+ )
395
+ return [{**record.public_request(), "status": record.status} for record in records]
396
+
397
+ async def submit_interaction(
398
+ self,
399
+ scope,
400
+ *,
401
+ run_id,
402
+ interaction_id,
403
+ expected_revision,
404
+ action,
405
+ response,
406
+ idempotency_key,
407
+ actor_subject,
408
+ ):
409
+ target, runtime = await self._target(scope, "submit_interaction")
410
+ if actor_subject != scope.owner_subject:
411
+ raise ExecutionHostError("interaction_actor_forbidden", "只有授权人类主体可以回复审批")
412
+ await self._require_run(scope, runtime, target, run_id)
413
+ record = await runtime.kernel_store.get(
414
+ interaction_id,
415
+ tenant_id=scope.tenant_id,
416
+ agent_instance_id=target.agent_instance_id,
417
+ session_id=scope.session_id,
418
+ run_id=run_id,
419
+ )
420
+ if not record:
421
+ raise ExecutionHostError(
422
+ "interaction_not_found", "审批不存在或不属于此执行", status=404
423
+ )
424
+ previous = await runtime.kernel_store.load_by_idempotency(scope.session_id, idempotency_key)
425
+ if previous is None:
426
+ if record.revision != expected_revision:
427
+ raise ExecutionHostError(
428
+ "interaction_revision_conflict", "审批状态已更新,请刷新后重试", status=409
429
+ )
430
+ if record.status not in {"pending", "resolving"}:
431
+ raise ExecutionHostError("interaction_already_resolved", "审批已经处理", status=409)
432
+ if record.kind != "approval" and action in {"approve", "reject"}:
433
+ raise ExecutionHostError(
434
+ "interaction_action_invalid", "此请求需要提交表单", status=422
435
+ )
436
+ command, permit = self._command(
437
+ scope,
438
+ target,
439
+ "submit_interaction",
440
+ idempotency_key,
441
+ {
442
+ "run_id": run_id,
443
+ "interaction_id": interaction_id,
444
+ "expected_revision": expected_revision,
445
+ "action": action,
446
+ "response": response,
447
+ "token_ref": "host:" + _hash([asdict(scope), interaction_id]),
448
+ "idempotency_key": idempotency_key,
449
+ },
450
+ )
451
+ receipt = await self.registry.submit_control(command, permit)
452
+ if receipt.status not in {"accepted", "duplicate"}:
453
+ raise ExecutionHostError(
454
+ receipt.error.code if receipt.error else "interaction_" + receipt.status,
455
+ "审批命令尚未获准执行,请刷新状态后使用原幂等标识重试",
456
+ status=503
457
+ if receipt.status == "persistence_uncertain"
458
+ else 422
459
+ if receipt.status == "unsupported"
460
+ else 409,
461
+ )
462
+ return {
463
+ "status": receipt.status,
464
+ "interactionId": interaction_id,
465
+ "revision": record.revision,
466
+ "commandId": str(command.command_id),
467
+ }
468
+
469
+ async def get_interaction(self, scope, *, run_id, interaction_id):
470
+ target, runtime = await self._target(scope, "interactions")
471
+ record = await runtime.kernel_store.get(
472
+ interaction_id,
473
+ tenant_id=scope.tenant_id,
474
+ agent_instance_id=target.agent_instance_id,
475
+ session_id=scope.session_id,
476
+ run_id=run_id,
477
+ )
478
+ return {**record.public_request(), "status": record.status} if record else None
479
+
480
+ async def conversation_events(self, scope, *, run_id: str, after: int = 0, limit: int = 200):
481
+ target, runtime = await self._target(scope, "observe")
482
+ await self._require_run(scope, runtime, target, run_id)
483
+ envelopes = await runtime.session_events.read(scope.session_id, after, min(limit, 1000))
484
+ items = []
485
+ for envelope in envelopes:
486
+ if envelope.run_id != run_id:
487
+ continue
488
+ item = None
489
+ if envelope.family == "runtime" and envelope.family_version == 2:
490
+ item = project_conversation_item(
491
+ parse_runtime_event(envelope.payload), session_id=scope.session_id
492
+ )
493
+ elif envelope.family == "interaction":
494
+ item = project_interaction_conversation_item(envelope)
495
+ if item:
496
+ items.append(
497
+ {"item": item.model_dump(mode="json", by_alias=True), "cursor": envelope.seq}
498
+ )
499
+ return {"items": items, "cursor": envelopes[-1].seq if envelopes else after}
500
+
501
+ async def source_events(self, scope, *, after: int = 0, limit: int = 200):
502
+ _, runtime = await self._target(scope, "observe")
503
+ envelopes = await runtime.session_events.read(scope.session_id, after, min(limit, 1000))
504
+ return {
505
+ "items": [item.model_dump(mode="json") for item in envelopes],
506
+ "cursor": envelopes[-1].seq if envelopes else after,
507
+ }
508
+
509
+ async def resolve(self, ref: str, *, request: Any):
510
+ row = self._db.execute(
511
+ "SELECT scope,context,command_id,run_id FROM execution_policy_refs WHERE ref=?", (ref,)
512
+ ).fetchone()
513
+ if not row:
514
+ raise ExecutionHostError("execution_policy_unavailable", "执行策略授权不存在")
515
+ scope = PluginExecutionScope(**json.loads(row[0]))
516
+ self._authorize(scope, "resolve_policy")
517
+ if request.session_id != scope.session_id or request.metadata.get("run_id") != row[3]:
518
+ raise ExecutionHostError(
519
+ "execution_policy_scope_mismatch", "执行策略不能用于其他会话或执行"
520
+ )
521
+ return await self._plugins[scope.plugin_id][2](scope, json.loads(row[1]), request=request)
522
+
523
+ async def close(self) -> None:
524
+ self._plugins.clear()
525
+ self._db.close()