agentengine-sdk-python 0.8.1__py3-none-any.whl → 0.8.3__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 (476) hide show
  1. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/METADATA +25 -12
  2. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/RECORD +421 -232
  3. ksadk/_build_provenance.json +1 -0
  4. ksadk/a2a/_space_client_events.py +381 -0
  5. ksadk/a2a/event_adapter.py +156 -64
  6. ksadk/a2a/executor.py +179 -63
  7. ksadk/a2a/space_client.py +6 -333
  8. ksadk/a2ui/core.py +222 -53
  9. ksadk/agui/_agent_helpers.py +247 -0
  10. ksadk/agui/a2ui_projection.py +12 -5
  11. ksadk/agui/agent.py +443 -259
  12. ksadk/api/client.py +528 -27
  13. ksadk/builders/code_builder.py +284 -8
  14. ksadk/builders/container_builder.py +8 -1
  15. ksadk/builders/managed_runtime_builder.py +42 -35
  16. ksadk/cli/__init__.py +23 -0
  17. ksadk/cli/cmd_dashboard.py +15 -1
  18. ksadk/cli/cmd_deploy.py +10 -2
  19. ksadk/cli/cmd_eval.py +66 -9
  20. ksadk/cli/cmd_evalset.py +284 -0
  21. ksadk/cli/cmd_files.py +5 -1
  22. ksadk/cli/cmd_hermes.py +1 -126
  23. ksadk/cli/cmd_invoke.py +28 -38
  24. ksadk/cli/cmd_managed_runtime.py +95 -0
  25. ksadk/cli/cmd_observe.py +85 -0
  26. ksadk/cli/cmd_openclaw.py +1 -435
  27. ksadk/cli/cmd_plugin.py +657 -0
  28. ksadk/cli/cmd_replay.py +28 -4
  29. ksadk/cli/cmd_studio.py +99 -8
  30. ksadk/cli/cmd_web.py +10 -2
  31. ksadk/cli/hermes_env.py +151 -0
  32. ksadk/cli/invoke_payload.py +49 -0
  33. ksadk/cli/openclaw_env.py +458 -0
  34. ksadk/codex/client.py +180 -30
  35. ksadk/codex/runtime.py +475 -331
  36. ksadk/configs/env_registry.py +94 -12
  37. ksadk/configs/env_registry_pcm.py +181 -0
  38. ksadk/configs/env_var_spec.py +18 -0
  39. ksadk/configs/global_config.py +5 -0
  40. ksadk/configs/settings.py +9 -0
  41. ksadk/context_engine/__init__.py +98 -0
  42. ksadk/context_engine/assembler.py +176 -0
  43. ksadk/context_engine/baseline.py +419 -0
  44. ksadk/context_engine/cache_observability.py +228 -0
  45. ksadk/context_engine/capabilities.py +443 -0
  46. ksadk/context_engine/contributors.py +409 -0
  47. ksadk/context_engine/hosted_pipeline.py +417 -0
  48. ksadk/context_engine/models.py +117 -0
  49. ksadk/context_engine/planner.py +698 -0
  50. ksadk/context_engine/policies.py +319 -0
  51. ksadk/context_engine/projection.py +31 -0
  52. ksadk/context_engine/shadow_plan.py +266 -0
  53. ksadk/context_engine/tokenizer.py +164 -0
  54. ksadk/conversations/__init__.py +19 -0
  55. ksadk/conversations/context.py +230 -30
  56. ksadk/conversations/contracts.py +266 -0
  57. ksadk/conversations/message_projection.py +308 -26
  58. ksadk/conversations/model_context.py +49 -3
  59. ksadk/conversations/projector.py +616 -0
  60. ksadk/conversations/reducer.py +98 -0
  61. ksadk/conversations/runtime_compaction.py +207 -5
  62. ksadk/conversations/runtime_input.py +184 -2
  63. ksadk/conversations/runtime_invocation.py +81 -3
  64. ksadk/conversations/runtime_observability.py +141 -0
  65. ksadk/conversations/runtime_payloads.py +42 -0
  66. ksadk/conversations/runtime_preparation.py +272 -2
  67. ksadk/conversations/runtime_resume.py +20 -1
  68. ksadk/conversations/runtime_stream_events.py +94 -9
  69. ksadk/conversations/semantic_summary.py +311 -1
  70. ksadk/conversations/session_lock.py +51 -0
  71. ksadk/deployment/env_forward.py +72 -0
  72. ksadk/deployment/managed_runtime.py +5 -0
  73. ksadk/deployment/providers/serverless.py +143 -69
  74. ksadk/evaluation/__init__.py +32 -0
  75. ksadk/evaluation/a2a_adapter.py +9 -1
  76. ksadk/evaluation/adapters.py +18 -5
  77. ksadk/evaluation/agent_eval_client.py +395 -0
  78. ksadk/evaluation/cloud_binding.py +80 -0
  79. ksadk/evaluation/cloud_converter.py +194 -0
  80. ksadk/evaluation/cloud_service.py +199 -0
  81. ksadk/evaluation/contracts.py +73 -4
  82. ksadk/evaluation/evaluators.py +183 -17
  83. ksadk/evaluation/evidence.py +258 -0
  84. ksadk/evaluation/executor.py +31 -6
  85. ksadk/evaluation/local_adapter.py +550 -0
  86. ksadk/evaluation/service_env.py +27 -0
  87. ksadk/evaluation/studio_build_adapter.py +253 -0
  88. ksadk/evaluation/target.py +15 -6
  89. ksadk/events/__init__.py +13 -13
  90. ksadk/events/_v1_compat/__init__.py +1 -0
  91. ksadk/events/_v1_compat/models.py +299 -0
  92. ksadk/events/_v1_compat/parser.py +247 -0
  93. ksadk/events/_v1_compat/projection.py +755 -0
  94. ksadk/events/adapters/__init__.py +34 -0
  95. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  96. ksadk/events/adapters/_a2a_support.py +275 -0
  97. ksadk/events/adapters/_codex_interactions.py +375 -0
  98. ksadk/events/adapters/_codex_items.py +801 -0
  99. ksadk/events/adapters/_codex_validators.py +311 -0
  100. ksadk/events/adapters/_langgraph_support.py +785 -0
  101. ksadk/events/adapters/a2a.py +841 -0
  102. ksadk/events/adapters/adk.py +503 -0
  103. ksadk/events/adapters/codex.py +907 -0
  104. ksadk/events/adapters/langgraph.py +745 -0
  105. ksadk/events/canonical.py +440 -0
  106. ksadk/events/canonical_replay.py +497 -0
  107. ksadk/events/canonical_store.py +468 -0
  108. ksadk/events/cold_recovery.py +257 -0
  109. ksadk/events/content.py +89 -0
  110. ksadk/events/identity.py +86 -0
  111. ksadk/events/pipeline.py +455 -0
  112. ksadk/events/projections.py +66 -0
  113. ksadk/events/reducer.py +661 -0
  114. ksadk/events/replay.py +3 -36
  115. ksadk/events/runtime_event.py +20 -265
  116. ksadk/events/session_event.py +324 -0
  117. ksadk/events/store.py +3 -316
  118. ksadk/events/v1_compat.py +41 -0
  119. ksadk/harness/__init__.py +45 -35
  120. ksadk/harness/runtime.py +220 -58
  121. ksadk/identity/resolver.py +4 -3
  122. ksadk/interaction/__init__.py +28 -0
  123. ksadk/interaction/contracts.py +136 -0
  124. ksadk/interaction/ledger.py +189 -0
  125. ksadk/interaction/provider.py +122 -0
  126. ksadk/interaction/providers/__init__.py +52 -0
  127. ksadk/interaction/providers/adk.py +40 -0
  128. ksadk/interaction/providers/codex.py +94 -0
  129. ksadk/interaction/providers/langgraph.py +58 -0
  130. ksadk/kernel/__init__.py +117 -0
  131. ksadk/kernel/authorization.py +258 -0
  132. ksadk/kernel/bootstrap.py +1074 -0
  133. ksadk/kernel/contract_fingerprints.py +62 -0
  134. ksadk/kernel/contracts.py +370 -0
  135. ksadk/kernel/control.py +220 -0
  136. ksadk/kernel/errors.py +79 -0
  137. ksadk/kernel/ingress.py +1123 -0
  138. ksadk/kernel/mapping.py +111 -0
  139. ksadk/kernel/memory_store.py +1134 -0
  140. ksadk/kernel/postgres_store.py +1757 -0
  141. ksadk/kernel/recovery.py +452 -0
  142. ksadk/kernel/runtime_identity.py +103 -0
  143. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  144. ksadk/kernel/sqlite_store.py +1411 -0
  145. ksadk/kernel/state.py +145 -0
  146. ksadk/kernel/store.py +232 -0
  147. ksadk/kernel/worker.py +964 -0
  148. ksadk/knowledge_base/client.py +7 -0
  149. ksadk/knowledge_base/service.py +32 -5
  150. ksadk/memory/__init__.py +61 -0
  151. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  152. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  153. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  154. ksadk/memory/adk/backends/sdk_ltm_backend.py +384 -2
  155. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  156. ksadk/memory/coordinator.py +461 -0
  157. ksadk/memory/events.py +202 -0
  158. ksadk/memory/extraction.py +228 -0
  159. ksadk/memory/ltm_backend_factory.py +16 -3
  160. ksadk/memory/models.py +316 -0
  161. ksadk/memory/policy.py +215 -0
  162. ksadk/memory/provider.py +47 -0
  163. ksadk/memory/provider_adapter.py +159 -0
  164. ksadk/memory/provider_resolver.py +71 -0
  165. ksadk/memory/providers/__init__.py +5 -0
  166. ksadk/memory/providers/local_sqlite.py +497 -0
  167. ksadk/memory/resolved_policy.py +145 -0
  168. ksadk/memory/service.py +188 -6
  169. ksadk/model_proxy/bootstrap.py +16 -9
  170. ksadk/model_proxy/detect.py +202 -9
  171. ksadk/model_proxy/namespace.py +39 -15
  172. ksadk/model_proxy/server.py +24 -5
  173. ksadk/model_proxy/transform.py +60 -2
  174. ksadk/observability/__init__.py +25 -0
  175. ksadk/observability/session_log.py +420 -0
  176. ksadk/observability/trajectory.py +105 -0
  177. ksadk/plugins/__init__.py +167 -0
  178. ksadk/plugins/bridges/__init__.py +45 -0
  179. ksadk/plugins/bridges/codex.py +552 -0
  180. ksadk/plugins/bridges/dsh.py +1116 -0
  181. ksadk/plugins/builtins.py +747 -0
  182. ksadk/plugins/bundle.py +246 -0
  183. ksadk/plugins/bundle_security.py +167 -0
  184. ksadk/plugins/composition.py +529 -0
  185. ksadk/plugins/context_contributor.py +437 -0
  186. ksadk/plugins/contracts.py +451 -0
  187. ksadk/plugins/dsh_toolchain.py +935 -0
  188. ksadk/plugins/ecosystem_bridge.py +1105 -0
  189. ksadk/plugins/ecosystem_probe.py +191 -0
  190. ksadk/plugins/host.py +724 -0
  191. ksadk/plugins/providers/__init__.py +85 -0
  192. ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
  193. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
  194. ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
  195. ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
  196. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
  197. ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
  198. ksadk/plugins/providers/codex.py +722 -0
  199. ksadk/plugins/providers/codex_dsh.py +83 -0
  200. ksadk/plugins/providers/dsh.py +951 -0
  201. ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
  202. ksadk/plugins/providers/harness.py +627 -0
  203. ksadk/plugins/providers/harness_dsh.py +91 -0
  204. ksadk/plugins/providers/legacy.py +215 -0
  205. ksadk/plugins/providers/legacy_catalog.py +100 -0
  206. ksadk/plugins/providers/shipped_dsh.py +370 -0
  207. ksadk/plugins/resolver.py +331 -0
  208. ksadk/plugins/subagent_providers/__init__.py +12 -0
  209. ksadk/plugins/subagent_providers/codex.py +443 -0
  210. ksadk/plugins/subagents.py +333 -0
  211. ksadk/prompts/__init__.py +71 -0
  212. ksadk/prompts/compiler.py +215 -0
  213. ksadk/prompts/models.py +82 -0
  214. ksadk/prompts/projection.py +89 -0
  215. ksadk/prompts/resolved.py +137 -0
  216. ksadk/prompts/sources.py +233 -0
  217. ksadk/runners/_langgraph_runner_streams.py +822 -0
  218. ksadk/runners/adk_runner.py +5 -5
  219. ksadk/runners/base_runner.py +16 -0
  220. ksadk/runners/factory.py +1 -2
  221. ksadk/runners/langgraph_runner.py +198 -437
  222. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  223. ksadk/runtime/_runner_adapter/stream_mapping.py +797 -0
  224. ksadk/runtime/adapter.py +119 -2
  225. ksadk/runtime/conversation_execution.py +316 -182
  226. ksadk/runtime/executor.py +144 -3
  227. ksadk/runtime/factory.py +268 -8
  228. ksadk/runtime/framework_adapters.py +18 -0
  229. ksadk/runtime/hosted_finalizer.py +268 -0
  230. ksadk/runtime/launch.py +14 -1
  231. ksadk/runtime/preprocessing.py +25 -3
  232. ksadk/runtime/runner_adapter.py +293 -508
  233. ksadk/runtime/usage.py +33 -0
  234. ksadk/sandbox/__init__.py +2 -1
  235. ksadk/sandbox/backends/e2b.py +35 -2
  236. ksadk/sandbox/factory.py +72 -0
  237. ksadk/scheduler/__init__.py +18 -0
  238. ksadk/scheduler/calendar.py +102 -0
  239. ksadk/scheduler/contracts.py +254 -0
  240. ksadk/scheduler/dispatcher.py +129 -0
  241. ksadk/scheduler/engine.py +416 -0
  242. ksadk/scheduler/sqlite_store.py +563 -0
  243. ksadk/server/composition.py +8 -0
  244. ksadk/server/factory.py +69 -6
  245. ksadk/server/routes/kernel_ingress.py +258 -0
  246. ksadk/server/routes/openai_compat.py +88 -8
  247. ksadk/server/routes/projection.py +35 -20
  248. ksadk/server/routes/run.py +94 -0
  249. ksadk/server/routes/sessions.py +2 -0
  250. ksadk/server/routes/streaming.py +5 -2
  251. ksadk/server/static/assets/{ArtifactsPanel-CakCqxEN.js → ArtifactsPanel-10GPXIJ6.js} +1 -1
  252. ksadk/server/static/assets/{CodeBlock-CynLknyO.js → CodeBlock-BXk1l-G1.js} +4 -4
  253. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  254. ksadk/server/static/assets/{MathMessageMarkdown-3sQdOysS.js → MathMessageMarkdown-D9uB55Oh.js} +4 -4
  255. ksadk/server/static/assets/MermaidBlock--OEYoXIJ.js +312 -0
  256. ksadk/server/static/assets/NativeTerminalPanel-DrEe1syq.js +1 -0
  257. ksadk/server/static/assets/abnfDiagram-VCTEODGH-eeTFJLvo.js +1 -0
  258. ksadk/server/static/assets/arc-S3ZNbIAd.js +1 -0
  259. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +1 -0
  260. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-CRjgEJDX.js +36 -0
  261. ksadk/server/static/assets/blockDiagram-NRAW4CY4-C7bsBoNH.js +129 -0
  262. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-BX3c33Ob.js +38 -0
  263. ksadk/server/static/assets/channel-s354Yo6o.js +1 -0
  264. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +1 -0
  265. ksadk/server/static/assets/{chunk-FMBD7UC4-B_fH2YuH.js → chunk-5VM5RSS4-bZ7ws-8m.js} +1 -1
  266. ksadk/server/static/assets/{chunk-ND2GUHAM-D6rFLaVV.js → chunk-F27PBJKO-D2r0pvhY.js} +1 -1
  267. ksadk/server/static/assets/chunk-G27WJ6UU-CZwF3oUP.js +231 -0
  268. ksadk/server/static/assets/{chunk-4BX2VUAB-B9drTgOW.js → chunk-JWPE2WC7-DigFYCML.js} +1 -1
  269. ksadk/server/static/assets/chunk-LCL6LL3I-CnorGV5q.js +206 -0
  270. ksadk/server/static/assets/chunk-POPQ4Y6H-CexntQA-.js +1 -0
  271. ksadk/server/static/assets/chunk-RHFEMEQ7-CHTC7UxA.js +168 -0
  272. ksadk/server/static/assets/chunk-SVP7TREG-BC1EWt_-.js +88 -0
  273. ksadk/server/static/assets/chunk-XXDRQBXY-BTG24xN0.js +1 -0
  274. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +1 -0
  275. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +1 -0
  276. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-ChNs_Mdk.js → cose-bilkent-JH36ORCC-CkonRdAS.js} +1 -1
  277. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +1 -0
  278. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-DEOCBe15.js +62 -0
  279. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  280. ksadk/server/static/assets/dagre-3AP2YEHR-DBThPuLa.js +4 -0
  281. ksadk/server/static/assets/dagre-ClTPrTht.js +1 -0
  282. ksadk/server/static/assets/diagram-S7CK7UJ4-DsZHrnpJ.js +30 -0
  283. ksadk/server/static/assets/diagram-UQ7AKVKN-BJR4nhVr.js +41 -0
  284. ksadk/server/static/assets/diagram-VSXAHHWV-xzcERX0a.js +3 -0
  285. ksadk/server/static/assets/diagram-VX7I27RA-tn2xM1xu.js +24 -0
  286. ksadk/server/static/assets/diagram-Z3DM3KII-BZPGBkw5.js +24 -0
  287. ksadk/server/static/assets/{dist-gLnrGsoU.js → dist-4zN1_tq5.js} +1 -1
  288. ksadk/server/static/assets/{dist-C1sz5Eo3.js → dist-8VWI-2bZ.js} +1 -1
  289. ksadk/server/static/assets/{dist-BjOdlDjj.js → dist-B-46q3Hk.js} +1 -1
  290. ksadk/server/static/assets/{dist-o2OVmKvt.js → dist-B0gdk4rl.js} +1 -1
  291. ksadk/server/static/assets/{dist-4N2NMVYg.js → dist-B1oWRmrH.js} +1 -1
  292. ksadk/server/static/assets/{dist-CmZHzlwZ.js → dist-BI1qQH4n.js} +1 -1
  293. ksadk/server/static/assets/{dist-X4TnqwOK.js → dist-BJLUwH6W.js} +1 -1
  294. ksadk/server/static/assets/{dist-B5oS1zcj.js → dist-Bbwqa8TG.js} +1 -1
  295. ksadk/server/static/assets/{dist-j6Dxmf_j.js → dist-Btyo4vX4.js} +1 -1
  296. ksadk/server/static/assets/{dist-DQU9EWw-.js → dist-C71CsujO.js} +1 -1
  297. ksadk/server/static/assets/{dist-BIlKoW0k.js → dist-CXpH_Rdd.js} +1 -1
  298. ksadk/server/static/assets/{dist-DJN_6Y39.js → dist-Cq4OL6nO.js} +1 -1
  299. ksadk/server/static/assets/{dist-Dli7qW-B.js → dist-D1V3f1B4.js} +1 -1
  300. ksadk/server/static/assets/{dist-fhOuWds5.js → dist-DJmCPRVB.js} +1 -1
  301. ksadk/server/static/assets/{dist-CWV4lDr1.js → dist-DQAB0qn_.js} +2 -2
  302. ksadk/server/static/assets/{dist-D6MpCZtz.js → dist-DUwKa_l6.js} +1 -1
  303. ksadk/server/static/assets/dist-DdRBIceA.js +1 -0
  304. ksadk/server/static/assets/{dist-DWKByxWV.js → dist-DfGFrb0v.js} +1 -1
  305. ksadk/server/static/assets/{dist-DsHPdk3W.js → dist-DjhwGUgZ.js} +1 -1
  306. ksadk/server/static/assets/{dist-B-jNR6Vn.js → dist-DyqV4fL4.js} +1 -1
  307. ksadk/server/static/assets/{dist-BB3-OwTQ.js → dist-M67Hwu0n.js} +1 -1
  308. ksadk/server/static/assets/{dist-_pHPTyZ-.js → dist-u8tVH5Ak.js} +1 -1
  309. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-DVfMsLge.js +1 -0
  310. ksadk/server/static/assets/erDiagram-SSCWMZ5O-CWEZSYaw.js +99 -0
  311. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +1 -0
  312. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +1 -0
  313. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-TWIxoyYL.js +292 -0
  314. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +1 -0
  315. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-DDh2hd2S.js +106 -0
  316. ksadk/server/static/assets/index-B2k_urY8.js +241 -0
  317. ksadk/server/static/assets/index-ILPt6IWF.css +2 -0
  318. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +1 -0
  319. ksadk/server/static/assets/infoDiagram-RXCK75RN-CgoyWiDR.js +2 -0
  320. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-K0OOfVna.js → ishikawaDiagram-5VMMS53U-CyRIu_om.js} +6 -6
  321. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-8LeOJaZp.js → journeyDiagram-EYS64GPL-DN5JXHzN.js} +6 -6
  322. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-C6uCgZrW.js → kanban-definition-3QL26DDD-CNP3ui66.js} +10 -10
  323. ksadk/server/static/assets/katex-DWEzQy1d.js +257 -0
  324. ksadk/server/static/assets/{linear-hdBcYzM8.js → linear-C-qHp7d2.js} +1 -1
  325. ksadk/server/static/assets/mermaid-parser.core-Cl-K943T.js +166 -0
  326. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-Bjy_2v4_.js → mindmap-definition-FBJOCRG2-D5DB5mYm.js} +29 -29
  327. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +1 -0
  328. ksadk/server/static/assets/pegDiagram-XKGWAZYB-BQVc9ia_.js +1 -0
  329. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +1 -0
  330. ksadk/server/static/assets/pieDiagram-E7YTZNPT-B6UCAvtY.js +39 -0
  331. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-BmkRbwCg.js → quadrantDiagram-AXDQQJYC-mIr2d3eb.js} +6 -6
  332. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +1 -0
  333. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +1 -0
  334. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +1 -0
  335. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +1 -0
  336. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +1 -0
  337. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-Dt3FFDmK.js +1 -0
  338. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-Cz_vQtgF.js +84 -0
  339. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-l6iXmU65.js → sankeyDiagram-P5KCCOFB-wlO1TsH5.js} +7 -7
  340. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-Cq6UBeQB.js → sequenceDiagram-WJ2MYXX4-CHRbElYq.js} +10 -10
  341. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-DXX54iyO.js +1 -0
  342. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-Dp_lw9II.js +1 -0
  343. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +1 -0
  344. ksadk/server/static/assets/swimlanes-XN3QIQJK-D8O5UlLG.js +1 -0
  345. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +8 -0
  346. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-DEz24vV0.js → timeline-definition-24CTP7MA-8mfKcxvG.js} +7 -7
  347. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +1 -0
  348. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +1 -0
  349. ksadk/server/static/assets/vennDiagram-4TSXK5OY-EnNl0DE7.js +34 -0
  350. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +1 -0
  351. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DBu5fbYr.js +78 -0
  352. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-BSVXs4IY.js +7 -0
  353. ksadk/server/static/index.html +2 -2
  354. ksadk/sessions/__init__.py +26 -9
  355. ksadk/sessions/_local_service_sync.py +688 -0
  356. ksadk/sessions/_local_tables.py +21 -0
  357. ksadk/sessions/_postgres_schema.py +305 -0
  358. ksadk/sessions/_postgres_tables.py +15 -0
  359. ksadk/sessions/base.py +80 -1
  360. ksadk/sessions/in_memory.py +53 -2
  361. ksadk/sessions/local_service.py +63 -604
  362. ksadk/sessions/postgres_service.py +58 -148
  363. ksadk/sessions/resilient.py +35 -1
  364. ksadk/skills/service_client.py +48 -0
  365. ksadk/studio/agent_lifecycle.py +26 -20
  366. ksadk/studio/api.py +1063 -69
  367. ksadk/studio/api_catalog_routes.py +5 -0
  368. ksadk/studio/api_contracts.py +148 -6
  369. ksadk/studio/api_memory_routes.py +82 -0
  370. ksadk/studio/api_plugin_routes.py +480 -0
  371. ksadk/studio/attachment_store.py +187 -0
  372. ksadk/studio/authoring.py +259 -28
  373. ksadk/studio/authoring_coordinator.py +809 -67
  374. ksadk/studio/builder.py +197 -40
  375. ksadk/studio/capabilities.py +17 -0
  376. ksadk/studio/cloud.py +1920 -95
  377. ksadk/studio/codex_agent_service.py +137 -15
  378. ksadk/studio/codex_authoring.py +469 -0
  379. ksadk/studio/codex_builder.py +177 -25
  380. ksadk/studio/codex_manifest.py +71 -22
  381. ksadk/studio/codex_run.py +59 -4
  382. ksadk/studio/compatibility_report.py +445 -0
  383. ksadk/studio/compiler.py +7 -1
  384. ksadk/studio/contracts.py +234 -4
  385. ksadk/studio/dsh_provider_registration.py +768 -0
  386. ksadk/studio/event_store.py +79 -101
  387. ksadk/studio/framework_run.py +264 -3
  388. ksadk/studio/hosted_kernel.py +317 -0
  389. ksadk/studio/manifest_resolver.py +131 -0
  390. ksadk/studio/model_client.py +95 -9
  391. ksadk/studio/model_profile_service.py +1 -1
  392. ksadk/studio/operations.py +47 -5
  393. ksadk/studio/otel_trace.py +348 -42
  394. ksadk/studio/pcm_memory.py +85 -0
  395. ksadk/studio/plugin_composition.py +301 -0
  396. ksadk/studio/plugin_kernel_adapter.py +128 -0
  397. ksadk/studio/plugin_runtime.py +652 -0
  398. ksadk/studio/repository.py +23 -2
  399. ksadk/studio/resource_catalog.py +49 -1
  400. ksadk/studio/run_service.py +1266 -202
  401. ksadk/studio/runtime_source.py +51 -17
  402. ksadk/studio/scheduler_runtime.py +374 -0
  403. ksadk/studio/scheduler_service.py +211 -0
  404. ksadk/studio/service.py +1815 -117
  405. ksadk/studio/shared_web.py +199 -50
  406. ksadk/studio/soul.py +52 -0
  407. ksadk/studio/static/assets/index-DXs1Eq4M.css +1 -0
  408. ksadk/studio/static/assets/index-DeDqwTsD.js +283 -0
  409. ksadk/studio/static/index.html +2 -2
  410. ksadk/studio/templates.py +100 -8
  411. ksadk/studio/validator.py +20 -1
  412. ksadk/studio/workspace.py +31 -32
  413. ksadk/tracing/setup.py +304 -3
  414. ksadk/version.py +1 -1
  415. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  416. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  417. ksadk_runtime_common/workspace_files/path_utils.py +41 -0
  418. ksadk/events/parser.py +0 -191
  419. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  420. ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +0 -303
  421. ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +0 -1
  422. ksadk/server/static/assets/arc-DrgjcKhl.js +0 -1
  423. ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +0 -1
  424. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-BXoVRbQ6.js +0 -36
  425. ksadk/server/static/assets/blockDiagram-GPEHLZMM-BnaB3Ywv.js +0 -132
  426. ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dw4weZcp.js +0 -10
  427. ksadk/server/static/assets/channel-Dt3rQTFI.js +0 -1
  428. ksadk/server/static/assets/chunk-2J33WTMH-ChjpLK7j.js +0 -1
  429. ksadk/server/static/assets/chunk-55IACEB6-CK4ROATy.js +0 -1
  430. ksadk/server/static/assets/chunk-727SXJPM-B9KtTTgw.js +0 -206
  431. ksadk/server/static/assets/chunk-AQP2D5EJ-1O1mki3m.js +0 -231
  432. ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +0 -1
  433. ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +0 -1
  434. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +0 -1
  435. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  436. ksadk/server/static/assets/dagre-BM42HDAG-D0QXg_MQ.js +0 -4
  437. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  438. ksadk/server/static/assets/diagram-2AECGRRQ-DBDDKwBQ.js +0 -43
  439. ksadk/server/static/assets/diagram-5GNKFQAL-BkwDOxmO.js +0 -10
  440. ksadk/server/static/assets/diagram-KO2AKTUF-Bv8waYvY.js +0 -3
  441. ksadk/server/static/assets/diagram-LMA3HP47-e1VECDdu.js +0 -24
  442. ksadk/server/static/assets/diagram-OG6HWLK6-Ds9adfRl.js +0 -24
  443. ksadk/server/static/assets/dist-B5J2uhNk.js +0 -1
  444. ksadk/server/static/assets/erDiagram-TEJ5UH35-BPItFKH6.js +0 -85
  445. ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +0 -1
  446. ksadk/server/static/assets/flowDiagram-I6XJVG4X-BbYB9w5Y.js +0 -162
  447. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-TQXa0KXv.js +0 -292
  448. ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +0 -1
  449. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-bKblCnpa.js +0 -106
  450. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  451. ksadk/server/static/assets/index-R52pJJvg.js +0 -177
  452. ksadk/server/static/assets/index-jJr3_955.css +0 -2
  453. ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +0 -1
  454. ksadk/server/static/assets/infoDiagram-5YYISTIA-BGVT7J_i.js +0 -2
  455. ksadk/server/static/assets/katex-CYWseY5E.js +0 -265
  456. ksadk/server/static/assets/mermaid-parser.core-BWrDjSZM.js +0 -161
  457. ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +0 -1
  458. ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +0 -1
  459. ksadk/server/static/assets/pieDiagram-4H26LBE5-GmmqNiVH.js +0 -30
  460. ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +0 -1
  461. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DSWFqL7c.js +0 -84
  462. ksadk/server/static/assets/stateDiagram-AJRCARHV-qzTQpg3Y.js +0 -1
  463. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +0 -1
  464. ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +0 -1
  465. ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +0 -1
  466. ksadk/server/static/assets/vennDiagram-CIIHVFJN-CMCixki2.js +0 -34
  467. ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +0 -1
  468. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-CVzB8F9K.js +0 -78
  469. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-BFBqBLc1.js +0 -7
  470. ksadk/studio/evaluation.py +0 -192
  471. ksadk/studio/static/assets/index-CaEN0eTR.css +0 -1
  472. ksadk/studio/static/assets/index-DI2eY_NH.js +0 -252
  473. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/WHEEL +0 -0
  474. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/entry_points.txt +0 -0
  475. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/licenses/LICENSE +0 -0
  476. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/top_level.txt +0 -0
ksadk/runtime/executor.py CHANGED
@@ -1,9 +1,17 @@
1
- """RuntimeAdapter 的统一生命周期路由与 Handle 所有权。"""
1
+ """RuntimeAdapter 的统一生命周期路由与 Handle 所有权。
2
+
3
+ ``_runs`` 只是当前进程的 handle cache:status、幂等、恢复资格和 owner 判断的
4
+ 真相在 ``AgentKernelStore`` 的 durable Run 行;cache miss 不能等价于 Run 不
5
+ 存在(见 :meth:`RuntimeExecutor.resolve_run`)。
6
+ """
2
7
 
3
8
  from __future__ import annotations
4
9
 
10
+ import hashlib
11
+ import json
5
12
  from contextlib import suppress
6
13
  from dataclasses import dataclass
14
+ from typing import TYPE_CHECKING
7
15
 
8
16
  from ksadk.runtime.adapter import (
9
17
  CancelResult,
@@ -18,9 +26,28 @@ from ksadk.runtime.adapter import (
18
26
  )
19
27
  from ksadk.runtime.launch import RuntimeLaunchContext
20
28
 
29
+ if TYPE_CHECKING: # pragma: no cover - import cycle guard
30
+ from ksadk.kernel.store import AgentKernelStore, RunRecord
31
+
21
32
  _HandleKey = tuple[str, str, str]
22
33
 
23
34
 
35
+ class RunNotFoundError(LookupError):
36
+ """durable Store 中不存在该 Run;cache miss 不是证据,必须查 Store。"""
37
+
38
+ def __init__(self, run_id: str) -> None:
39
+ super().__init__(f"durable run not found: {run_id!r}")
40
+ self.run_id = run_id
41
+
42
+
43
+ @dataclass
44
+ class DurableRun:
45
+ """Store 中的 Run 真相 + 本进程 live handle(可能未 attach)。"""
46
+
47
+ run: "RunRecord"
48
+ live_handle: RunHandle | None = None
49
+
50
+
24
51
  @dataclass
25
52
  class _OwnedRun:
26
53
  adapter: RuntimeAdapter
@@ -39,10 +66,58 @@ class RuntimeStartPreparation:
39
66
  class RuntimeExecutor:
40
67
  """让每个 Handle 始终回到创建或恢复它的 Adapter 实例。"""
41
68
 
42
- def __init__(self, registry: RuntimeRegistry) -> None:
69
+ def __init__(
70
+ self,
71
+ registry: RuntimeRegistry,
72
+ *,
73
+ kernel_store: "AgentKernelStore | None" = None,
74
+ ) -> None:
43
75
  self._registry = registry
76
+ self._kernel_store = kernel_store
44
77
  self._runs: dict[_HandleKey, _OwnedRun] = {}
45
78
 
79
+ def create_adapter(self, context: RuntimeLaunchContext) -> RuntimeAdapter:
80
+ """从本 executor 的 registry 创建一个 adapter。
81
+
82
+ 生产 composition root 需要为 AgentKernelWorker 提供 adapter factory。
83
+ 暴露这个窄入口可避免其绕过当前 RuntimeExecutor、另建默认 registry,
84
+ 从而让普通执行、worker 与恢复走同一套 runtime-type 注册表。
85
+ """
86
+
87
+ return self._registry.create(context)
88
+
89
+ async def resolve_run(self, run_id: str) -> DurableRun:
90
+ """以 durable Store 为真相解析 Run;cache 只是 live handle 提示。"""
91
+
92
+ durable = None
93
+ if self._kernel_store is not None:
94
+ durable = await self._kernel_store.load_run(run_id)
95
+ if durable is None:
96
+ # 没有 Store 时只能退回 cache;cache miss 不等价于 Run 不存在,
97
+ # 因此未配置 kernel_store 的旧调用方仍需显式处理缺失。
98
+ if self._kernel_store is not None:
99
+ raise RunNotFoundError(run_id)
100
+ cached = next(
101
+ (
102
+ owned.handle
103
+ for (_, rid, _), owned in self._runs.items()
104
+ if rid == run_id
105
+ ),
106
+ None,
107
+ )
108
+ if cached is None:
109
+ raise RunNotFoundError(run_id)
110
+ return DurableRun(run=_cache_only_record(cached), live_handle=cached)
111
+ live = next(
112
+ (
113
+ owned.handle
114
+ for (_, rid, _), owned in self._runs.items()
115
+ if rid == run_id
116
+ ),
117
+ None,
118
+ )
119
+ return DurableRun(run=durable, live_handle=live)
120
+
46
121
  async def prepare_start(self, context: RuntimeLaunchContext) -> RuntimeStartPreparation:
47
122
  """Preflight a fresh adapter and retain it for the matching ``start``.
48
123
 
@@ -173,6 +248,29 @@ class RuntimeExecutor:
173
248
  self._record_owner(adapter, restored)
174
249
  return restored
175
250
 
251
+ async def attach_record(
252
+ self,
253
+ run: "RunRecord",
254
+ context: RuntimeLaunchContext,
255
+ ) -> RunHandle:
256
+ """Attach a run from its durable record (cross-process recovery path).
257
+
258
+ 一个新进程没有任何 ``_runs`` 缓存;durable Run 行的 ``handle`` +
259
+ ``handle_digest`` 是唯一恢复线索。digest 不匹配即拒绝——被篡改或
260
+ 版本漂移的 handle 绝不能接回 live 执行。
261
+ """
262
+
263
+ handle_dump = run.metadata.get("handle")
264
+ digest = run.metadata.get("handle_digest")
265
+ if not isinstance(handle_dump, dict) or not isinstance(digest, str):
266
+ raise ValueError(
267
+ f"durable run {run.run_id!r} has no durably attachable handle"
268
+ )
269
+ handle = RunHandle.model_validate(handle_dump)
270
+ if handle_digest(handle) != digest:
271
+ raise ValueError(f"handle digest mismatch for run {run.run_id!r}")
272
+ return await self.attach(context, handle)
273
+
176
274
  def is_attached(self, handle: RunHandle) -> bool:
177
275
  owned = self._runs.get(_handle_key(handle))
178
276
  return owned is not None and owned.handle == handle
@@ -200,6 +298,17 @@ class RuntimeExecutor:
200
298
  adapter = self._registry.create(context)
201
299
  return dict(adapter.runtime.native_capabilities())
202
300
 
301
+ def capability_matrix(self, context: RuntimeLaunchContext) -> dict[str, object]:
302
+ """Return the canonical typed RuntimeCapabilityMatrix/v1 projection.
303
+
304
+ ``native_capabilities`` is a compatibility view whose shape varies by
305
+ framework. UI clients need the versioned matrix so optional execution
306
+ modes can be exposed only when the selected runtime declares support.
307
+ """
308
+
309
+ adapter = self._registry.create(context)
310
+ return adapter.capabilities().model_dump(mode="json")
311
+
203
312
  def registered_runtime_types(self) -> list[str]:
204
313
  """Expose Registry membership without leaking or duplicating the Registry."""
205
314
 
@@ -236,6 +345,32 @@ class RuntimeExecutor:
236
345
  return preparation.adapter
237
346
 
238
347
 
348
+ def handle_digest(handle: RunHandle) -> str:
349
+ """Stable digest of one durable handle (cross-process recovery evidence)."""
350
+
351
+ payload = json.dumps(
352
+ handle.model_dump(mode="json"),
353
+ sort_keys=True,
354
+ separators=(",", ":"),
355
+ ensure_ascii=False,
356
+ ).encode("utf-8")
357
+ return hashlib.sha256(payload).hexdigest()
358
+
359
+
360
+ def _cache_only_record(handle: RunHandle) -> "RunRecord":
361
+ from ksadk.kernel.state import RunState
362
+ from ksadk.kernel.store import RunRecord
363
+
364
+ # 无 kernel_store 的旧调用方路径:state 只能标记 pending,真相以 Store 为准。
365
+ return RunRecord(
366
+ run_id=handle.run_id,
367
+ agent_instance_id="",
368
+ session_id=handle.session_id,
369
+ state=RunState.PENDING,
370
+ metadata={"source": "process_cache", "runtime_type": handle.runtime_type},
371
+ )
372
+
373
+
239
374
  def _normalize_runtime_type(runtime_type: str) -> str:
240
375
  return runtime_type.strip().lower()
241
376
 
@@ -248,4 +383,10 @@ def _handle_key(handle: RunHandle) -> _HandleKey:
248
383
  )
249
384
 
250
385
 
251
- __all__ = ["RuntimeExecutor", "RuntimeStartPreparation"]
386
+ __all__ = [
387
+ "RuntimeExecutor",
388
+ "RuntimeStartPreparation",
389
+ "DurableRun",
390
+ "RunNotFoundError",
391
+ "handle_digest",
392
+ ]
ksadk/runtime/factory.py CHANGED
@@ -3,21 +3,185 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import dataclasses
6
+ import hashlib
6
7
  import os
8
+ import re
9
+ import shutil
10
+ import tempfile
7
11
  from pathlib import Path
8
12
  from typing import Any
9
13
 
10
14
  from ksadk.codex.client import AsyncCodexClient
11
15
  from ksadk.codex.runtime import CodexRuntimeAdapter
12
16
  from ksadk.runners.base_runner import BaseRunner
13
- from ksadk.runtime.adapter import RuntimeAdapter, RuntimeRegistry
17
+ from ksadk.runtime.adapter import RuntimeAdapter, RuntimeRegistry, StartRequest
14
18
  from ksadk.runtime.framework_adapters import ADKRuntimeAdapter, LangGraphRuntimeAdapter
15
19
  from ksadk.runtime.launch import RuntimeLaunchContext
16
20
 
17
21
 
22
+ def kernel_start_request_defaults(context: RuntimeLaunchContext) -> dict[str, Any]:
23
+ """Project an admitted launch manifest into immutable Kernel turn defaults.
24
+
25
+ The durable Kernel owns enqueue ordering, while the deployment manifest
26
+ owns model, instructions, sandbox and approval policy. Keeping this
27
+ projection beside the RuntimeAdapter factory prevents the Kernel ingress
28
+ from trusting caller-supplied execution policy.
29
+ """
30
+
31
+ config = dict(context.config)
32
+ defaults: dict[str, Any] = {}
33
+ detection_name = str(getattr(context.detection, "name", "") or "").strip()
34
+ if detection_name:
35
+ defaults["agent_id"] = detection_name
36
+ model = str(config.get("model") or "").strip()
37
+ if model:
38
+ defaults["model"] = model
39
+ raw_allowed_models = (
40
+ config.get("models") or config.get("allowed_models") or config.get("allowedModels") or []
41
+ )
42
+ allowed_models = (
43
+ {str(item).strip() for item in raw_allowed_models if str(item).strip()}
44
+ if isinstance(raw_allowed_models, (list, tuple, set))
45
+ else set()
46
+ )
47
+ # 不把默认 model 自动加进白名单:白名单只在显式声明 models/allowedModels
48
+ # 时才存在(显式声明 = 收紧;只配默认 = 不限制 run 级覆盖)。
49
+ if allowed_models:
50
+ defaults["allowed_models"] = sorted(allowed_models)
51
+ if context.runtime_type != "codex":
52
+ return defaults
53
+
54
+ prompt = str(config.get("prompt") or "").strip()
55
+ task_prompt = str(config.get("task_prompt") or "").strip()
56
+ base_instructions = prompt
57
+ if task_prompt:
58
+ base_instructions = f"{prompt}\n\n{task_prompt}" if prompt else task_prompt
59
+
60
+ raw_sandbox = str(config.get("sandbox") or "read_only").strip().lower()
61
+ raw_approval = str(config.get("approval_mode") or "").strip().lower()
62
+ approval_profiles = {
63
+ "ask": ("workspace-write", "manual"),
64
+ "risk": ("workspace-write", "auto_review"),
65
+ "full": ("full-access", "deny_all"),
66
+ }
67
+ sandbox_profiles = {
68
+ "read_only": ("read-only", "deny_all"),
69
+ "read-only": ("read-only", "deny_all"),
70
+ "workspace_write": ("workspace-write", "deny_all"),
71
+ "workspace-write": ("workspace-write", "deny_all"),
72
+ "workspace_write_auto": ("workspace-write", "auto_review"),
73
+ "workspace-write-auto": ("workspace-write", "auto_review"),
74
+ "full_access": ("full-access", "deny_all"),
75
+ "full-access": ("full-access", "deny_all"),
76
+ }
77
+ if raw_approval in approval_profiles:
78
+ sandbox, approval = approval_profiles[raw_approval]
79
+ else:
80
+ sandbox, default_approval = sandbox_profiles.get(raw_sandbox, ("read-only", "deny_all"))
81
+ approval = raw_approval or default_approval
82
+
83
+ request_config: dict[str, Any] = {
84
+ "sandbox_read_only": sandbox == "read-only",
85
+ "sandbox": sandbox,
86
+ "approval_mode": approval,
87
+ "cwd": str(context.project_dir),
88
+ "summary": "auto",
89
+ "ephemeral": False,
90
+ }
91
+ if base_instructions:
92
+ request_config["base_instructions"] = base_instructions
93
+ collaboration_mode = str(config.get("collaboration_mode") or "").strip().lower()
94
+ if collaboration_mode:
95
+ if collaboration_mode not in {"default", "plan"}:
96
+ raise ValueError("Codex collaboration_mode must be default or plan")
97
+ request_config["collaboration_mode"] = collaboration_mode
98
+ goal_objective = str(config.get("goal_objective") or "").strip()
99
+ if goal_objective:
100
+ request_config["goal_objective"] = goal_objective
101
+ raw_skills = config.get("skills")
102
+ if isinstance(raw_skills, (list, tuple)):
103
+ request_config["skills"] = [
104
+ dict(item) for item in raw_skills if isinstance(item, dict)
105
+ ]
106
+ defaults["config"] = request_config
107
+ return defaults
108
+
109
+
110
+ def apply_runtime_start_request_defaults(
111
+ context: RuntimeLaunchContext,
112
+ request: StartRequest,
113
+ ) -> StartRequest:
114
+ """Apply deployment-owned launch policy to a direct runtime start.
115
+
116
+ AgentKernelWorker already projects these defaults before ``adapter.start``.
117
+ Foreground RunAgent, ``/run_sse`` and OpenAI-compatible routes also create
118
+ ``StartRequest`` objects directly, so they must use the same projection or
119
+ a deployed Codex agent silently falls back to the generic Codex role.
120
+
121
+ Request-local config is internal runtime state, not caller-owned policy;
122
+ retain it for local Studio builds while using the manifest model as the
123
+ fallback (and as the fail-closed fallback for an explicit allow-list).
124
+ """
125
+
126
+ defaults = kernel_start_request_defaults(context)
127
+ default_model = str(defaults.get("model") or "").strip() or None
128
+ requested_model = str(request.model or "").strip()
129
+ allowed_models = {
130
+ str(item).strip()
131
+ for item in (defaults.get("allowed_models") or [])
132
+ if str(item).strip()
133
+ }
134
+ selected_model = (
135
+ requested_model
136
+ if requested_model and (not allowed_models or requested_model in allowed_models)
137
+ else default_model
138
+ )
139
+ config = {
140
+ **dict(defaults.get("config") or {}),
141
+ **dict(request.config or {}),
142
+ }
143
+ return request.model_copy(
144
+ update={
145
+ "agent_id": request.agent_id or defaults.get("agent_id"),
146
+ "model": selected_model,
147
+ "config": config,
148
+ }
149
+ )
150
+
151
+
152
+ def _manifest_mcp_overrides(config: dict[str, Any]) -> list[str]:
153
+ """Translate declarative MCP bindings into native Codex config keys."""
154
+
155
+ overrides: list[str] = []
156
+ servers = config.get("mcp_servers") or []
157
+ if not isinstance(servers, (list, tuple)):
158
+ return overrides
159
+ for server in servers:
160
+ if not isinstance(server, dict):
161
+ continue
162
+ name = str(server.get("name") or "").strip()
163
+ url = str(server.get("url") or "").strip()
164
+ if not name or not url:
165
+ continue
166
+ overrides.append(f"mcp_servers.{name}.url={url}")
167
+ env_key = str(server.get("env_key") or "").strip()
168
+ if env_key:
169
+ overrides.append(f"mcp_servers.{name}.bearer_token_env_var={env_key}")
170
+ return overrides
171
+
172
+
18
173
  def _create_codex(context: RuntimeLaunchContext) -> RuntimeAdapter:
19
174
  client_factory = context.services.codex_client_factory or AsyncCodexClient
20
- overrides = list(context.config.get("codex_overrides") or [])
175
+ config = dict(context.config)
176
+ bound_skill_paths: dict[str, str] = {}
177
+ overrides = list(config.get("codex_overrides") or [])
178
+ manifest_mcp_overrides = _manifest_mcp_overrides(config)
179
+ overrides.extend(item for item in manifest_mcp_overrides if item not in overrides)
180
+ projected_config = kernel_start_request_defaults(context).get("config") or {}
181
+ if manifest_mcp_overrides and projected_config.get("sandbox") == "workspace-write":
182
+ network_override = "sandbox_workspace_write.network_access=true"
183
+ if network_override not in overrides:
184
+ overrides.append(network_override)
21
185
  # Studio's default collaboration mode must expose Codex's structured
22
186
  # request_user_input tool; the upstream feature is intentionally off by
23
187
  # default outside Plan mode. This stays process-local to the isolated
@@ -37,6 +201,9 @@ def _create_codex(context: RuntimeLaunchContext) -> RuntimeAdapter:
37
201
  )
38
202
  env = dict(getattr(base_cfg, "env", None) or {})
39
203
  isolated_home = _isolated_codex_home(context.project_dir)
204
+ bound_skill_paths = _materialize_bound_codex_skills(
205
+ isolated_home, config.get("skills")
206
+ )
40
207
  env.setdefault("CODEX_HOME", str(isolated_home))
41
208
  # HOME 级隔离:codex app-server 还会按约定扫 ~/.agents/skills、
42
209
  # ~/.claude/skills 等宿主目录,仅设 CODEX_HOME 挡不住。隔离 HOME 后这些
@@ -60,10 +227,18 @@ def _create_codex(context: RuntimeLaunchContext) -> RuntimeAdapter:
60
227
  if overrides:
61
228
  _apply_codex_overrides(client, overrides)
62
229
  timeout = context.config.get("turn_timeout_seconds")
230
+ request_defaults = kernel_start_request_defaults(context)
231
+ request_config = request_defaults.get("config") or {}
232
+ sandbox_read_only = (
233
+ bool(context.config["sandbox_read_only"])
234
+ if "sandbox_read_only" in context.config
235
+ else bool(request_config.get("sandbox_read_only", True))
236
+ )
63
237
  return CodexRuntimeAdapter(
64
238
  client,
65
- sandbox_read_only=bool(context.config.get("sandbox_read_only", True)),
239
+ sandbox_read_only=sandbox_read_only,
66
240
  turn_timeout_seconds=float(timeout) if timeout is not None else None,
241
+ bound_skill_paths=bound_skill_paths,
67
242
  )
68
243
 
69
244
 
@@ -76,10 +251,90 @@ def _isolated_codex_home(project_dir: Any) -> Path:
76
251
  """
77
252
  override = os.environ.get("KSADK_CODEX_HOME")
78
253
  if override:
79
- return Path(override).expanduser()
80
- home = Path(str(project_dir)) / ".agentkit" / "codex-home"
81
- home.mkdir(parents=True, exist_ok=True)
82
- return home
254
+ home = Path(override).expanduser()
255
+ home.mkdir(parents=True, exist_ok=True)
256
+ return home
257
+
258
+ # Source bundles are deliberately mounted read-only in managed runtimes.
259
+ # Keep the preferred workspace-local isolation for local development, but
260
+ # never make a Codex turn depend on being able to mutate that bundle.
261
+ workspace_home = Path(str(project_dir)) / ".agentkit" / "codex-home"
262
+ try:
263
+ workspace_home.mkdir(parents=True, exist_ok=True)
264
+ return workspace_home
265
+ except OSError:
266
+ pass
267
+
268
+ # The managed runtime already provides a per-workload writable state
269
+ # volume. Derive from its explicit directory first, then from the
270
+ # session-store path for backward-compatible images. /tmp is a final
271
+ # process-local fallback for custom read-only launchers.
272
+ state_dir = os.environ.get("KSADK_RUNTIME_STATE_DIR")
273
+ session_path = os.environ.get("KSADK_SESSION_PATH")
274
+ fallback_root = (
275
+ Path(state_dir)
276
+ if state_dir
277
+ else Path(session_path).expanduser().parent
278
+ if session_path
279
+ else Path(tempfile.gettempdir()) / "ksadk-runtime-state"
280
+ )
281
+ fallback_home = fallback_root / "codex-home"
282
+ fallback_home.mkdir(parents=True, exist_ok=True)
283
+ return fallback_home
284
+
285
+
286
+ def _materialize_bound_codex_skills(
287
+ codex_home: Path, value: Any
288
+ ) -> dict[str, str]:
289
+ """Expose immutable Bundle Skills through Codex's native skill catalog.
290
+
291
+ Passing an arbitrary ``SkillInput`` path is accepted by the Python SDK but
292
+ ignored by the real App Server unless the Skill is discoverable by the
293
+ native host. Copy each content-addressed Bundle Skill into the isolated
294
+ CODEX_HOME so the host owns discovery while the Bundle remains read-only.
295
+ Content-addressed directory names avoid overwriting user-managed Skills
296
+ when an explicit KSADK_CODEX_HOME is used.
297
+ """
298
+
299
+ if not isinstance(value, (list, tuple)):
300
+ return {}
301
+ skills_root = codex_home / "skills"
302
+ skills_root.mkdir(parents=True, exist_ok=True)
303
+ installed: dict[str, str] = {}
304
+ for item in value:
305
+ if not isinstance(item, dict):
306
+ continue
307
+ name = str(item.get("name") or "").strip()
308
+ raw_path = str(item.get("path") or "").strip()
309
+ if not name or not raw_path:
310
+ continue
311
+ skill_file = Path(raw_path).resolve()
312
+ if skill_file.name != "SKILL.md" or not skill_file.is_file():
313
+ continue
314
+ source_dir = skill_file.parent
315
+ digest = hashlib.sha256()
316
+ for source in sorted(path for path in source_dir.rglob("*") if path.is_file()):
317
+ digest.update(source.relative_to(source_dir).as_posix().encode("utf-8"))
318
+ digest.update(b"\0")
319
+ digest.update(source.read_bytes())
320
+ digest.update(b"\0")
321
+ safe_name = re.sub(r"[^A-Za-z0-9._-]+", "-", name).strip(".-") or "skill"
322
+ target = skills_root / f"ksadk-{digest.hexdigest()[:16]}-{safe_name}"
323
+ if target.is_dir():
324
+ installed[name] = str(target / "SKILL.md")
325
+ continue
326
+ staging = Path(tempfile.mkdtemp(prefix=".ksadk-skill-", dir=skills_root))
327
+ try:
328
+ shutil.copytree(source_dir, staging, dirs_exist_ok=True)
329
+ try:
330
+ staging.replace(target)
331
+ except FileExistsError:
332
+ pass
333
+ finally:
334
+ if staging.exists():
335
+ shutil.rmtree(staging)
336
+ installed[name] = str(target / "SKILL.md")
337
+ return installed
83
338
 
84
339
 
85
340
  def _apply_codex_overrides(client: Any, overrides: Any) -> None:
@@ -153,4 +408,9 @@ def create_runtime_adapter(context: RuntimeLaunchContext) -> RuntimeAdapter:
153
408
  return build_default_runtime_registry().create(context)
154
409
 
155
410
 
156
- __all__ = ["build_default_runtime_registry", "create_runtime_adapter"]
411
+ __all__ = [
412
+ "apply_runtime_start_request_defaults",
413
+ "build_default_runtime_registry",
414
+ "create_runtime_adapter",
415
+ "kernel_start_request_defaults",
416
+ ]
@@ -63,6 +63,24 @@ class LangGraphRuntimeAdapter(RunnerRuntimeAdapter):
63
63
  def __init__(self, runner: BaseRunner) -> None:
64
64
  super().__init__(runner, runtime_type="langgraph")
65
65
 
66
+ def capabilities(self): # noqa: ANN201
67
+ """Advertise checkpoint interaction only when LangGraph can resume it.
68
+
69
+ ``RunnerRuntimeAdapter`` is intentionally conservative because a
70
+ generic checkpoint is not proof of original-interrupt delivery. The
71
+ LangGraph adapter owns that mapping, so it is the only runner-family
72
+ adapter that may publish ``durable_resume``.
73
+ """
74
+
75
+ matrix = super().capabilities()
76
+ return matrix.model_copy(
77
+ update={
78
+ "interaction_mode": (
79
+ "durable_resume" if matrix.resume.supported else "unavailable"
80
+ )
81
+ }
82
+ )
83
+
66
84
  async def _resume_native(
67
85
  self,
68
86
  handle: RunHandle,