agentengine-sdk-python 0.8.0__py3-none-any.whl → 0.8.2__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 (494) hide show
  1. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +43 -7
  2. agentengine_sdk_python-0.8.2.dist-info/RECORD +778 -0
  3. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +1 -1
  4. ksadk/a2a/__init__.py +2 -0
  5. ksadk/a2a/_space_client_events.py +381 -0
  6. ksadk/a2a/bootstrap.py +0 -2
  7. ksadk/a2a/card.py +6 -111
  8. ksadk/a2a/control_plane.py +239 -1
  9. ksadk/a2a/event_adapter.py +156 -64
  10. ksadk/a2a/executor.py +195 -172
  11. ksadk/a2a/routes.py +12 -5
  12. ksadk/a2a/server.py +1 -8
  13. ksadk/a2a/service_env.py +33 -0
  14. ksadk/a2a/space_client.py +43 -349
  15. ksadk/a2a_card.py +101 -0
  16. ksadk/a2ui/core.py +222 -53
  17. ksadk/agui/_agent_helpers.py +243 -0
  18. ksadk/agui/a2ui_projection.py +12 -5
  19. ksadk/agui/agent.py +474 -275
  20. ksadk/agui/config.py +11 -5
  21. ksadk/agui/routes.py +7 -15
  22. ksadk/api/client.py +530 -40
  23. ksadk/api/environment.py +27 -0
  24. ksadk/builders/code_builder.py +352 -53
  25. ksadk/builders/container_builder.py +71 -44
  26. ksadk/builders/framework_requirements.py +2 -1
  27. ksadk/builders/ks3_uploader.py +2 -2
  28. ksadk/builders/managed_runtime_builder.py +60 -28
  29. ksadk/cli/__init__.py +25 -0
  30. ksadk/cli/cmd_a2a.py +18 -31
  31. ksadk/cli/cmd_create.py +13 -26
  32. ksadk/cli/cmd_dashboard.py +15 -1
  33. ksadk/cli/cmd_deploy.py +28 -3
  34. ksadk/cli/cmd_eval.py +443 -0
  35. ksadk/cli/cmd_evalset.py +284 -0
  36. ksadk/cli/cmd_files.py +5 -1
  37. ksadk/cli/cmd_hermes.py +137 -163
  38. ksadk/cli/cmd_invoke.py +28 -38
  39. ksadk/cli/cmd_launch.py +12 -0
  40. ksadk/cli/cmd_managed_runtime.py +95 -0
  41. ksadk/cli/cmd_observe.py +85 -0
  42. ksadk/cli/cmd_openclaw.py +85 -479
  43. ksadk/cli/cmd_replay.py +28 -4
  44. ksadk/cli/cmd_run.py +29 -67
  45. ksadk/cli/cmd_studio.py +201 -0
  46. ksadk/cli/cmd_web.py +15 -6
  47. ksadk/cli/dry_run.py +2 -1
  48. ksadk/cli/env_options.py +83 -0
  49. ksadk/cli/global_options.py +3 -1
  50. ksadk/cli/hermes_env.py +151 -0
  51. ksadk/cli/invoke_payload.py +49 -0
  52. ksadk/cli/network_options.py +7 -5
  53. ksadk/cli/openclaw_env.py +458 -0
  54. ksadk/cli/runtime_bootstrap.py +51 -0
  55. ksadk/cli/ui.py +6 -0
  56. ksadk/cli/workflow_common.py +5 -5
  57. ksadk/codex/__init__.py +3 -3
  58. ksadk/codex/client.py +833 -49
  59. ksadk/codex/phase.py +1 -1
  60. ksadk/codex/runtime.py +720 -127
  61. ksadk/common/kop_client.py +232 -0
  62. ksadk/configs/__init__.py +1 -3
  63. ksadk/configs/env_registry.py +244 -45
  64. ksadk/configs/env_registry_pcm.py +181 -0
  65. ksadk/configs/env_var_spec.py +18 -0
  66. ksadk/configs/global_config.py +6 -1
  67. ksadk/configs/settings.py +5 -108
  68. ksadk/context_engine/__init__.py +98 -0
  69. ksadk/context_engine/assembler.py +176 -0
  70. ksadk/context_engine/baseline.py +419 -0
  71. ksadk/context_engine/cache_observability.py +228 -0
  72. ksadk/context_engine/capabilities.py +443 -0
  73. ksadk/context_engine/contributors.py +344 -0
  74. ksadk/context_engine/hosted_pipeline.py +417 -0
  75. ksadk/context_engine/models.py +117 -0
  76. ksadk/context_engine/planner.py +698 -0
  77. ksadk/context_engine/policies.py +319 -0
  78. ksadk/context_engine/projection.py +31 -0
  79. ksadk/context_engine/shadow_plan.py +266 -0
  80. ksadk/context_engine/tokenizer.py +164 -0
  81. ksadk/conversations/__init__.py +85 -94
  82. ksadk/conversations/context.py +126 -6
  83. ksadk/conversations/message_projection.py +292 -28
  84. ksadk/conversations/model_context.py +49 -3
  85. ksadk/conversations/runtime_compaction.py +207 -5
  86. ksadk/conversations/runtime_input.py +193 -3
  87. ksadk/conversations/runtime_invocation.py +81 -3
  88. ksadk/conversations/runtime_observability.py +157 -4
  89. ksadk/conversations/runtime_payloads.py +42 -0
  90. ksadk/conversations/runtime_preparation.py +280 -2
  91. ksadk/conversations/runtime_resume.py +71 -32
  92. ksadk/conversations/runtime_stream_events.py +94 -9
  93. ksadk/conversations/runtime_streaming.py +175 -22
  94. ksadk/conversations/semantic_summary.py +311 -1
  95. ksadk/conversations/session_lock.py +51 -0
  96. ksadk/deployment/env_forward.py +72 -0
  97. ksadk/deployment/managed_runtime.py +38 -0
  98. ksadk/deployment/manager.py +24 -8
  99. ksadk/deployment/providers/serverless.py +228 -92
  100. ksadk/evaluation/__init__.py +116 -0
  101. ksadk/evaluation/a2a_adapter.py +452 -0
  102. ksadk/evaluation/adapters.py +67 -0
  103. ksadk/evaluation/agent_eval_client.py +395 -0
  104. ksadk/evaluation/cloud_binding.py +80 -0
  105. ksadk/evaluation/cloud_converter.py +194 -0
  106. ksadk/evaluation/cloud_service.py +199 -0
  107. ksadk/evaluation/contracts.py +478 -0
  108. ksadk/evaluation/evalset.py +351 -0
  109. ksadk/evaluation/evaluators.py +627 -0
  110. ksadk/evaluation/evidence.py +258 -0
  111. ksadk/evaluation/executor.py +143 -0
  112. ksadk/evaluation/local_adapter.py +550 -0
  113. ksadk/evaluation/service_env.py +27 -0
  114. ksadk/evaluation/storage.py +68 -0
  115. ksadk/evaluation/studio_build_adapter.py +253 -0
  116. ksadk/evaluation/target.py +82 -0
  117. ksadk/events/__init__.py +13 -13
  118. ksadk/events/_v1_compat/__init__.py +1 -0
  119. ksadk/events/_v1_compat/models.py +299 -0
  120. ksadk/events/_v1_compat/parser.py +247 -0
  121. ksadk/events/_v1_compat/projection.py +753 -0
  122. ksadk/events/adapters/__init__.py +34 -0
  123. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  124. ksadk/events/adapters/_a2a_support.py +275 -0
  125. ksadk/events/adapters/_codex_interactions.py +375 -0
  126. ksadk/events/adapters/_codex_items.py +801 -0
  127. ksadk/events/adapters/_codex_validators.py +311 -0
  128. ksadk/events/adapters/_langgraph_support.py +785 -0
  129. ksadk/events/adapters/a2a.py +841 -0
  130. ksadk/events/adapters/adk.py +503 -0
  131. ksadk/events/adapters/codex.py +717 -0
  132. ksadk/events/adapters/langgraph.py +745 -0
  133. ksadk/events/canonical.py +440 -0
  134. ksadk/events/canonical_replay.py +497 -0
  135. ksadk/events/canonical_store.py +468 -0
  136. ksadk/events/cold_recovery.py +257 -0
  137. ksadk/events/content.py +89 -0
  138. ksadk/events/identity.py +86 -0
  139. ksadk/events/pipeline.py +455 -0
  140. ksadk/events/projections.py +66 -0
  141. ksadk/events/reducer.py +661 -0
  142. ksadk/events/replay.py +3 -36
  143. ksadk/events/runtime_event.py +20 -256
  144. ksadk/events/session_event.py +324 -0
  145. ksadk/events/store.py +3 -316
  146. ksadk/events/v1_compat.py +41 -0
  147. ksadk/harness/__init__.py +3 -2
  148. ksadk/harness/app.py +114 -123
  149. ksadk/harness/config.py +1 -1
  150. ksadk/harness/runtime.py +467 -0
  151. ksadk/hermes_terminal.py +5 -0
  152. ksadk/identity/resolver.py +4 -3
  153. ksadk/interaction/__init__.py +28 -0
  154. ksadk/interaction/contracts.py +136 -0
  155. ksadk/interaction/ledger.py +189 -0
  156. ksadk/interaction/provider.py +122 -0
  157. ksadk/interaction/providers/__init__.py +52 -0
  158. ksadk/interaction/providers/adk.py +40 -0
  159. ksadk/interaction/providers/codex.py +94 -0
  160. ksadk/interaction/providers/langgraph.py +58 -0
  161. ksadk/kernel/__init__.py +117 -0
  162. ksadk/kernel/authorization.py +258 -0
  163. ksadk/kernel/bootstrap.py +1074 -0
  164. ksadk/kernel/contract_fingerprints.py +61 -0
  165. ksadk/kernel/contracts.py +362 -0
  166. ksadk/kernel/control.py +219 -0
  167. ksadk/kernel/errors.py +79 -0
  168. ksadk/kernel/ingress.py +1102 -0
  169. ksadk/kernel/mapping.py +111 -0
  170. ksadk/kernel/memory_store.py +1133 -0
  171. ksadk/kernel/postgres_store.py +1756 -0
  172. ksadk/kernel/recovery.py +452 -0
  173. ksadk/kernel/runtime_identity.py +103 -0
  174. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  175. ksadk/kernel/sqlite_store.py +1410 -0
  176. ksadk/kernel/state.py +145 -0
  177. ksadk/kernel/store.py +232 -0
  178. ksadk/kernel/worker.py +953 -0
  179. ksadk/knowledge_base/client.py +22 -4
  180. ksadk/knowledge_base/service.py +32 -5
  181. ksadk/managed_a2a_card.py +160 -0
  182. ksadk/managed_runtime.py +16 -9
  183. ksadk/memory/__init__.py +61 -0
  184. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  185. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  186. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  187. ksadk/memory/adk/backends/sdk_ltm_backend.py +394 -5
  188. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  189. ksadk/memory/adk/long_term_memory.py +3 -2
  190. ksadk/memory/coordinator.py +461 -0
  191. ksadk/memory/events.py +202 -0
  192. ksadk/memory/extraction.py +228 -0
  193. ksadk/memory/ltm_backend_factory.py +16 -3
  194. ksadk/memory/models.py +316 -0
  195. ksadk/memory/policy.py +215 -0
  196. ksadk/memory/provider.py +47 -0
  197. ksadk/memory/provider_adapter.py +159 -0
  198. ksadk/memory/provider_resolver.py +71 -0
  199. ksadk/memory/providers/__init__.py +5 -0
  200. ksadk/memory/providers/local_sqlite.py +490 -0
  201. ksadk/memory/resolved_policy.py +145 -0
  202. ksadk/memory/service.py +198 -8
  203. ksadk/memory/tool.py +4 -0
  204. ksadk/model_proxy/bootstrap.py +16 -9
  205. ksadk/model_proxy/config.py +22 -1
  206. ksadk/model_proxy/detect.py +202 -9
  207. ksadk/model_proxy/namespace.py +67 -15
  208. ksadk/model_proxy/server.py +168 -6
  209. ksadk/model_proxy/transform.py +105 -3
  210. ksadk/observability/__init__.py +25 -0
  211. ksadk/observability/session_log.py +420 -0
  212. ksadk/observability/trajectory.py +105 -0
  213. ksadk/prompts/__init__.py +71 -0
  214. ksadk/prompts/compiler.py +215 -0
  215. ksadk/prompts/models.py +82 -0
  216. ksadk/prompts/projection.py +89 -0
  217. ksadk/prompts/resolved.py +137 -0
  218. ksadk/prompts/sources.py +233 -0
  219. ksadk/runners/_langgraph_runner_streams.py +822 -0
  220. ksadk/runners/adk_runner.py +14 -31
  221. ksadk/runners/base_runner.py +44 -3
  222. ksadk/runners/factory.py +3 -3
  223. ksadk/runners/langgraph_runner.py +252 -433
  224. ksadk/runners/utils/__init__.py +0 -10
  225. ksadk/runners/utils/loader.py +16 -0
  226. ksadk/runtime/__init__.py +67 -41
  227. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  228. ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
  229. ksadk/runtime/adapter.py +199 -16
  230. ksadk/runtime/conversation_execution.py +687 -0
  231. ksadk/runtime/executor.py +392 -0
  232. ksadk/runtime/factory.py +342 -0
  233. ksadk/runtime/framework_adapters.py +6 -12
  234. ksadk/runtime/hosted_finalizer.py +268 -0
  235. ksadk/runtime/launch.py +61 -0
  236. ksadk/runtime/preprocessing.py +49 -14
  237. ksadk/runtime/runner_adapter.py +330 -391
  238. ksadk/runtime/runner_loading.py +36 -0
  239. ksadk/runtime/usage.py +33 -0
  240. ksadk/sandbox/backends/e2b.py +36 -3
  241. ksadk/server/__init__.py +39 -4
  242. ksadk/server/app.py +18 -492
  243. ksadk/server/composition.py +36 -2
  244. ksadk/server/factory.py +210 -149
  245. ksadk/server/routes/common.py +15 -46
  246. ksadk/server/routes/control.py +13 -9
  247. ksadk/server/routes/kernel_ingress.py +258 -0
  248. ksadk/server/routes/misc.py +10 -33
  249. ksadk/server/routes/models.py +14 -6
  250. ksadk/server/routes/openai_compat.py +129 -27
  251. ksadk/server/routes/projection.py +84 -16
  252. ksadk/server/routes/run.py +347 -460
  253. ksadk/server/routes/sessions.py +37 -40
  254. ksadk/server/routes/streaming.py +52 -7
  255. ksadk/server/routes/workspace.py +54 -21
  256. ksadk/server/static/assets/{ArtifactsPanel-Cjnqt-8W.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
  257. ksadk/server/static/assets/{CodeBlock-BqyqZfuB.js → CodeBlock-DOH6MVcn.js} +4 -4
  258. ksadk/server/static/assets/{MathMessageMarkdown-BpH7jiFM.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
  259. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  260. ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
  261. ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
  262. ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
  263. ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
  264. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
  265. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
  266. ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
  267. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
  268. ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
  269. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
  270. ksadk/server/static/assets/{chunk-FMBD7UC4-BGhvzDYt.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
  271. ksadk/server/static/assets/{chunk-ND2GUHAM-D98vPd-E.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
  272. ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
  273. ksadk/server/static/assets/{chunk-4BX2VUAB-CsWIQRhc.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
  274. ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
  275. ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
  276. ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
  277. ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
  278. ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
  279. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
  280. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
  281. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-CX3yotHq.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
  282. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
  283. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
  284. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  285. ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
  286. ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
  287. ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
  288. ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
  289. ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
  290. ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
  291. ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
  292. ksadk/server/static/assets/{dist-D82mtD2s.js → dist-8hqcx0sU.js} +1 -1
  293. ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
  294. ksadk/server/static/assets/{dist-DHn6nBzr.js → dist-BE7bu-DL.js} +1 -1
  295. ksadk/server/static/assets/{dist-eoW6tZXA.js → dist-BVDffZ0U.js} +1 -1
  296. ksadk/server/static/assets/{dist-C2xjE7cO.js → dist-BX8z72IC.js} +1 -1
  297. ksadk/server/static/assets/{dist-CgF3fj15.js → dist-Bf2M8m3N.js} +1 -1
  298. ksadk/server/static/assets/{dist-Bs-jQcRX.js → dist-BjU6y-A2.js} +1 -1
  299. ksadk/server/static/assets/{dist-Djgl2wVZ.js → dist-BytlxIDT.js} +1 -1
  300. ksadk/server/static/assets/{dist-CVQRZjPu.js → dist-CSh_DE14.js} +1 -1
  301. ksadk/server/static/assets/{dist-6CVKuTAe.js → dist-CXYYBw3_.js} +1 -1
  302. ksadk/server/static/assets/{dist-DlzCRy0S.js → dist-C_wsv-Qd.js} +1 -1
  303. ksadk/server/static/assets/{dist-DF06ORQo.js → dist-ClxGviKw.js} +1 -1
  304. ksadk/server/static/assets/{dist-Cf23NY4L.js → dist-CttYUqzS.js} +1 -1
  305. ksadk/server/static/assets/{dist-ivOya1LD.js → dist-DNp6rLRA.js} +1 -1
  306. ksadk/server/static/assets/{dist-BibcG1V9.js → dist-DUX-id_F.js} +1 -1
  307. ksadk/server/static/assets/{dist-BUHRxvDG.js → dist-DmldrHd_.js} +1 -1
  308. ksadk/server/static/assets/{dist-BZ9n9AjO.js → dist-DnfXs8Vn.js} +2 -2
  309. ksadk/server/static/assets/{dist-DqNnNFrw.js → dist-Dq9gLD7L.js} +1 -1
  310. ksadk/server/static/assets/{dist-CGcp2ex8.js → dist-W-TIVntx.js} +1 -1
  311. ksadk/server/static/assets/{dist-Cwt7koer.js → dist-dDdADKFA.js} +1 -1
  312. ksadk/server/static/assets/{dist-C7-3jInC.js → dist-dydu68Fl.js} +1 -1
  313. ksadk/server/static/assets/{dist-C99THtIA.js → dist-ngtN0DJB.js} +1 -1
  314. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
  315. ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
  316. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
  317. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
  318. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
  319. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
  320. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
  321. ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
  322. ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
  323. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
  324. ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
  325. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-DLOHGvWw.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
  326. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-BIzKeejT.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
  327. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-BWHoFSw2.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
  328. ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
  329. ksadk/server/static/assets/{linear-CvMBw9cA.js → linear-BHjG8b-J.js} +1 -1
  330. ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
  331. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-CSAQxEAe.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
  332. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
  333. ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
  334. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
  335. ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
  336. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-CxIR4JXI.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
  337. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
  338. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
  339. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
  340. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
  341. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
  342. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
  343. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
  344. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-DpGa6EAV.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
  345. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-NTKNGGe5.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
  346. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
  347. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
  348. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
  349. ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
  350. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
  351. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-jqoYs3jQ.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
  352. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
  353. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
  354. ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
  355. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
  356. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
  357. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
  358. ksadk/server/static/index.html +2 -2
  359. ksadk/sessions/__init__.py +26 -9
  360. ksadk/sessions/_local_service_sync.py +688 -0
  361. ksadk/sessions/_local_tables.py +21 -0
  362. ksadk/sessions/_postgres_schema.py +305 -0
  363. ksadk/sessions/_postgres_tables.py +15 -0
  364. ksadk/sessions/base.py +80 -1
  365. ksadk/sessions/in_memory.py +53 -2
  366. ksadk/sessions/local_service.py +63 -604
  367. ksadk/sessions/postgres_service.py +58 -148
  368. ksadk/sessions/resilient.py +35 -1
  369. ksadk/skills/runtime/backends/e2b.py +1 -1
  370. ksadk/skills/service_client.py +13 -3
  371. ksadk/studio/__init__.py +5 -0
  372. ksadk/studio/agent_avatar_assets.py +120 -0
  373. ksadk/studio/agent_lifecycle.py +51 -0
  374. ksadk/studio/api.py +1598 -0
  375. ksadk/studio/api_catalog_routes.py +324 -0
  376. ksadk/studio/api_contracts.py +286 -0
  377. ksadk/studio/api_helpers.py +132 -0
  378. ksadk/studio/api_memory_routes.py +82 -0
  379. ksadk/studio/authoring.py +749 -0
  380. ksadk/studio/authoring_coordinator.py +1017 -0
  381. ksadk/studio/builder.py +397 -0
  382. ksadk/studio/capabilities.py +368 -0
  383. ksadk/studio/cloud.py +2099 -0
  384. ksadk/studio/codex_agent_service.py +694 -0
  385. ksadk/studio/codex_authoring.py +469 -0
  386. ksadk/studio/codex_builder.py +437 -0
  387. ksadk/studio/codex_manifest.py +307 -0
  388. ksadk/studio/codex_run.py +395 -0
  389. ksadk/studio/compiler.py +190 -0
  390. ksadk/studio/contracts.py +755 -0
  391. ksadk/studio/errors.py +47 -0
  392. ksadk/studio/event_store.py +214 -0
  393. ksadk/studio/framework_run.py +342 -0
  394. ksadk/studio/hosted_kernel.py +317 -0
  395. ksadk/studio/identifiers.py +33 -0
  396. ksadk/studio/manifest_resolver.py +131 -0
  397. ksadk/studio/mcp_runtime.py +229 -0
  398. ksadk/studio/model_client.py +629 -0
  399. ksadk/studio/model_profile_service.py +214 -0
  400. ksadk/studio/operations.py +275 -0
  401. ksadk/studio/otel_trace.py +1060 -0
  402. ksadk/studio/pagination.py +182 -0
  403. ksadk/studio/pcm_memory.py +85 -0
  404. ksadk/studio/python_tool_inspection.py +183 -0
  405. ksadk/studio/repository.py +327 -0
  406. ksadk/studio/resource_catalog.py +1260 -0
  407. ksadk/studio/run_service.py +1133 -0
  408. ksadk/studio/runtime_catalog.py +74 -0
  409. ksadk/studio/runtime_source.py +365 -0
  410. ksadk/studio/service.py +2249 -0
  411. ksadk/studio/shared_web.py +1004 -0
  412. ksadk/studio/skill_discovery.py +628 -0
  413. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
  414. ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
  415. ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
  416. ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
  417. ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
  418. ksadk/studio/static/index.html +15 -0
  419. ksadk/studio/templates.py +722 -0
  420. ksadk/studio/validator.py +265 -0
  421. ksadk/studio/workspace.py +135 -0
  422. ksadk/tools/gateway.py +9 -0
  423. ksadk/toolsets/__init__.py +27 -1
  424. ksadk/toolsets/a2a.py +426 -0
  425. ksadk/tracing/__init__.py +19 -21
  426. ksadk/tracing/setup.py +317 -403
  427. ksadk/tracing/span_utils.py +0 -44
  428. ksadk/version.py +1 -1
  429. ksadk_runtime_common/memory_backend/registry.py +56 -56
  430. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  431. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  432. ksadk_runtime_common/workspace_files/router.py +8 -2
  433. agentengine_sdk_python-0.8.0.dist-info/RECORD +0 -578
  434. ksadk/a2a/card_builder.py +0 -64
  435. ksadk/a2a/client.py +0 -309
  436. ksadk/events/parser.py +0 -191
  437. ksadk/harness/runner.py +0 -211
  438. ksadk/runners/codex_runner.py +0 -132
  439. ksadk/runners/utils/langfuse.py +0 -230
  440. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  441. ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +0 -303
  442. ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +0 -1
  443. ksadk/server/static/assets/arc-CFKwSk_B.js +0 -1
  444. ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +0 -1
  445. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-Dej8jX8c.js +0 -36
  446. ksadk/server/static/assets/blockDiagram-GPEHLZMM-1F64jqvy.js +0 -132
  447. ksadk/server/static/assets/c4Diagram-AAUBKEIU-9q7AUAKb.js +0 -10
  448. ksadk/server/static/assets/channel-iUGv2N24.js +0 -1
  449. ksadk/server/static/assets/chunk-2J33WTMH-6qgwJm7Q.js +0 -1
  450. ksadk/server/static/assets/chunk-55IACEB6-BK8paA20.js +0 -1
  451. ksadk/server/static/assets/chunk-727SXJPM-B-JEhy7h.js +0 -206
  452. ksadk/server/static/assets/chunk-AQP2D5EJ-DYBvMHAa.js +0 -231
  453. ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +0 -1
  454. ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +0 -1
  455. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +0 -1
  456. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  457. ksadk/server/static/assets/dagre-BM42HDAG-C7TguAWo.js +0 -4
  458. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  459. ksadk/server/static/assets/diagram-2AECGRRQ-Dd17_kws.js +0 -43
  460. ksadk/server/static/assets/diagram-5GNKFQAL-DVIClIil.js +0 -10
  461. ksadk/server/static/assets/diagram-KO2AKTUF-Df_3gYQa.js +0 -3
  462. ksadk/server/static/assets/diagram-LMA3HP47-BhLk6ZtA.js +0 -24
  463. ksadk/server/static/assets/diagram-OG6HWLK6-D4GNGvuu.js +0 -24
  464. ksadk/server/static/assets/dist-DyvYLMW9.js +0 -1
  465. ksadk/server/static/assets/erDiagram-TEJ5UH35-CnfRcY2M.js +0 -85
  466. ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +0 -1
  467. ksadk/server/static/assets/flowDiagram-I6XJVG4X-DGaJjGNJ.js +0 -162
  468. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-DpCoB2g9.js +0 -292
  469. ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +0 -1
  470. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-9IKVFBVT.js +0 -106
  471. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  472. ksadk/server/static/assets/index-QSwCHuB8.js +0 -177
  473. ksadk/server/static/assets/index-jOPmTOZH.css +0 -2
  474. ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +0 -1
  475. ksadk/server/static/assets/infoDiagram-5YYISTIA-CYIIsb8y.js +0 -2
  476. ksadk/server/static/assets/katex-DATssjp1.js +0 -265
  477. ksadk/server/static/assets/mermaid-parser.core-mGAcEwcq.js +0 -161
  478. ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +0 -1
  479. ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +0 -1
  480. ksadk/server/static/assets/pieDiagram-4H26LBE5-By-ra07M.js +0 -30
  481. ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +0 -1
  482. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DpW90iu3.js +0 -84
  483. ksadk/server/static/assets/stateDiagram-AJRCARHV-DGpd9yFG.js +0 -1
  484. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +0 -1
  485. ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +0 -1
  486. ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +0 -1
  487. ksadk/server/static/assets/vennDiagram-CIIHVFJN-l3Z7-wbP.js +0 -34
  488. ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +0 -1
  489. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-BR54GPmr.js +0 -78
  490. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-SkiH8GsK.js +0 -7
  491. ksadk/tracing/exporters/langfuse_exporter.py +0 -460
  492. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
  493. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
  494. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,694 @@
1
+ """Codex Agent lifecycle behind the common Studio Agent contract.
2
+
3
+ The deployable ``agentengine.yaml`` deliberately remains a narrow platform
4
+ contract. Studio-only display metadata and bindings live in a sidecar draft so
5
+ editing a Codex Agent behaves like every other Runtime without polluting the
6
+ ManagedRuntime manifest.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import asyncio
12
+ import builtins
13
+ import json
14
+ import os
15
+ import shutil
16
+ from datetime import datetime, timezone
17
+ from pathlib import Path
18
+ from typing import Any, Callable, cast
19
+
20
+ from pydantic import ValidationError
21
+
22
+ from ksadk.managed_runtime import installed_runtime_version
23
+ from ksadk.studio.codex_builder import CodexBuildRecord
24
+ from ksadk.studio.codex_manifest import (
25
+ CodexAgentManifest,
26
+ CodexManifestSnapshot,
27
+ CodexRuntimeRef,
28
+ )
29
+ from ksadk.studio.contracts import (
30
+ AgentAppearance,
31
+ AgentBindings,
32
+ AgentDraft,
33
+ AgentMetadata,
34
+ AgentSpec,
35
+ CapabilityBinding,
36
+ Instructions,
37
+ ModelSpec,
38
+ Operation,
39
+ OperationKind,
40
+ RunEvent,
41
+ RunStatus,
42
+ RuntimeRef,
43
+ )
44
+ from ksadk.studio.errors import StudioError
45
+ from ksadk.studio.templates import default_agent_spec
46
+ from ksadk.studio.workspace import Workspace
47
+
48
+
49
+ class CodexDraftRepository:
50
+ """Persist Studio-only Codex metadata separately from deployment YAML."""
51
+
52
+ def __init__(self, workspace: Workspace) -> None:
53
+ self.workspace = workspace
54
+
55
+ def _path(self, agent_id: str) -> Path:
56
+ return self.workspace.resolve(Path(".agentkit/codex-drafts") / f"{agent_id}.json")
57
+
58
+ def get(self, agent_id: str) -> AgentDraft | None:
59
+ path = self._path(agent_id)
60
+ if not path.is_file():
61
+ return None
62
+ try:
63
+ return cast(
64
+ AgentDraft,
65
+ AgentDraft.model_validate_json(path.read_text(encoding="utf-8")),
66
+ )
67
+ except (OSError, ValidationError) as exc:
68
+ raise StudioError(
69
+ "CODEX_DRAFT_INVALID",
70
+ "Codex Agent 的 Studio 元数据损坏",
71
+ status_code=500,
72
+ details={"agentId": agent_id},
73
+ ) from exc
74
+
75
+ def save(self, draft: AgentDraft) -> AgentDraft:
76
+ payload = draft.model_dump(
77
+ by_alias=True,
78
+ exclude_none=True,
79
+ mode="json",
80
+ )
81
+ self.workspace.atomic_write_text(
82
+ self._path(draft.metadata.id),
83
+ json.dumps(payload, ensure_ascii=False, sort_keys=True, indent=2) + "\n",
84
+ )
85
+ return draft
86
+
87
+ def delete(
88
+ self,
89
+ agent_id: str,
90
+ *,
91
+ purge: bool,
92
+ trash_directory: Path | None,
93
+ ) -> None:
94
+ path = self._path(agent_id)
95
+ if not path.is_file():
96
+ return
97
+ if purge:
98
+ path.unlink()
99
+ return
100
+ if trash_directory is None:
101
+ raise ValueError("recoverable deletion requires a trash directory")
102
+ target = self.workspace.resolve(trash_directory / "metadata" / path.name)
103
+ target.parent.mkdir(parents=True, exist_ok=True)
104
+ shutil.move(str(path), str(target))
105
+
106
+
107
+ class CodexAgentService:
108
+ """Own Codex definition projection, metadata and operation dispatch."""
109
+
110
+ def __init__(self, studio: Any) -> None:
111
+ self.studio = studio
112
+ self.drafts = getattr(studio, "codex_drafts", None) or CodexDraftRepository(
113
+ studio.workspace
114
+ )
115
+
116
+ def manifest_state(self, agent_id: str | None = None) -> dict:
117
+ snapshot = self.studio.codex_manifests.load(agent_id)
118
+ builds = self._builds(snapshot.manifest.name)
119
+ latest = builds[0] if builds else None
120
+ return {
121
+ "manifest": snapshot.manifest,
122
+ "manifestSha256": snapshot.manifest_sha256,
123
+ "sourcePath": self.studio.workspace.relative(snapshot.source_path),
124
+ "sourceYaml": snapshot.source_bytes.decode("utf-8"),
125
+ "buildCurrent": bool(latest and self.studio.codex_builder.is_current(latest)),
126
+ "latestBuild": latest,
127
+ }
128
+
129
+ def save_manifest(self, manifest: CodexAgentManifest) -> dict:
130
+ snapshot = self.studio.codex_manifests.save(manifest)
131
+ current = self.drafts.get(manifest.name)
132
+ if current is not None:
133
+ projected = self._project(snapshot, current=current)
134
+ projected.metadata.revision = current.metadata.revision + 1
135
+ self.drafts.save(projected)
136
+ return self.manifest_state(manifest.name)
137
+
138
+ def list(self, *, query: str = "", limit: int = 50) -> list[AgentDraft]:
139
+ if limit < 1:
140
+ return []
141
+ normalized = query.strip().lower()
142
+ results: list[AgentDraft] = []
143
+ for snapshot in self.studio.codex_manifests.list():
144
+ draft = self._project(snapshot)
145
+ if (
146
+ normalized
147
+ and normalized not in draft.metadata.id.lower()
148
+ and (normalized not in draft.metadata.name.lower())
149
+ ):
150
+ continue
151
+ results.append(draft)
152
+ return results[:limit]
153
+
154
+ def create(
155
+ self,
156
+ *,
157
+ agent_id: str,
158
+ spec: AgentSpec | None,
159
+ name: str | None = None,
160
+ labels: dict[str, str] | None = None,
161
+ ) -> AgentDraft:
162
+ if self.studio.codex_manifests.exists(agent_id) or self.studio._draft_exists(agent_id):
163
+ raise StudioError(
164
+ "AGENT_ALREADY_EXISTS",
165
+ "本地 Agent 已存在",
166
+ status_code=409,
167
+ details={"agentId": agent_id},
168
+ )
169
+ resolved = (spec or default_agent_spec("blank")).model_copy(deep=True)
170
+ resolved.runtime = RuntimeRef(type="codex", version=self._runtime_version(resolved))
171
+ self.ensure_bindings_supported(resolved)
172
+ manifest = self._manifest(agent_id, resolved)
173
+ snapshot = self.studio.codex_manifests.save(manifest)
174
+ draft = AgentDraft(
175
+ metadata=AgentMetadata(
176
+ id=agent_id,
177
+ name=str(name or agent_id).strip() or agent_id,
178
+ labels={**self._labels(manifest), **dict(labels or {})},
179
+ ),
180
+ spec=resolved,
181
+ )
182
+ self.drafts.save(draft)
183
+ return self._project(snapshot)
184
+
185
+ def update(
186
+ self,
187
+ agent_id: str,
188
+ spec: AgentSpec,
189
+ *,
190
+ expected_revision: int,
191
+ name: str | None = None,
192
+ ) -> AgentDraft:
193
+ snapshot = self.studio.codex_manifests.load(agent_id)
194
+ current = self._project(snapshot)
195
+ if current.metadata.revision != expected_revision:
196
+ raise StudioError(
197
+ "AGENT_REVISION_CONFLICT",
198
+ "Agent 已被其他操作更新",
199
+ status_code=409,
200
+ details={
201
+ "expected": expected_revision,
202
+ "actual": current.metadata.revision,
203
+ },
204
+ )
205
+ resolved = spec.model_copy(deep=True)
206
+ resolved.runtime = current.spec.runtime
207
+ # 早期 Studio 曾把 ksadk Tool 写进 Codex 草稿,尽管 Codex Runtime
208
+ # 从未执行这些绑定。允许原样保存这类 dormant 历史数据,避免用户只改
209
+ # Prompt/Model 时被迫丢绑定;新增、删除或修改仍按当前能力矩阵拒绝。
210
+ if (
211
+ resolved.bindings.tools != current.spec.bindings.tools
212
+ or resolved.capabilities.tools != current.spec.capabilities.tools
213
+ ):
214
+ self.ensure_bindings_supported(resolved)
215
+ manifest = self._manifest(agent_id, resolved, current=snapshot.manifest)
216
+ updated_snapshot = self.studio.codex_manifests.save(manifest)
217
+ updated = AgentDraft(
218
+ metadata=current.metadata.model_copy(
219
+ deep=True,
220
+ update={
221
+ "revision": current.metadata.revision + 1,
222
+ **({"name": name} if name is not None else {}),
223
+ },
224
+ ),
225
+ spec=resolved,
226
+ )
227
+ updated.metadata.labels.update(self._labels(manifest))
228
+ self.drafts.save(updated)
229
+ return self._project(updated_snapshot)
230
+
231
+ def update_appearance(
232
+ self,
233
+ agent_id: str,
234
+ appearance: AgentAppearance,
235
+ *,
236
+ expected_revision: int,
237
+ ) -> AgentDraft:
238
+ snapshot = self.studio.codex_manifests.load(agent_id)
239
+ current = self._project(snapshot)
240
+ if current.metadata.revision != expected_revision:
241
+ raise StudioError(
242
+ "AGENT_REVISION_CONFLICT",
243
+ "Agent 已被其他操作更新",
244
+ status_code=409,
245
+ field="metadata.revision",
246
+ details={"expected": expected_revision, "actual": current.metadata.revision},
247
+ )
248
+ updated = current.model_copy(deep=True)
249
+ updated.metadata.revision += 1
250
+ updated.metadata.appearance = appearance
251
+ self.drafts.save(updated)
252
+ return self._project(snapshot, current=updated)
253
+
254
+ @staticmethod
255
+ def ensure_bindings_supported(spec: AgentSpec) -> None:
256
+ bindings = spec.bindings
257
+ if bindings.tools or spec.capabilities.tools:
258
+ raise StudioError(
259
+ "TOOL_RUNTIME_INCOMPATIBLE",
260
+ "Codex Runtime 当前只使用其原生工具,不能绑定 ksadk Tool",
261
+ status_code=422,
262
+ field="spec.bindings.tools",
263
+ details={"runtimeType": "codex"},
264
+ )
265
+ # codex 支持 streamable-http MCP(通过 config_overrides 注入 mcp_servers)。
266
+
267
+ def _skill_resource_ids(self, spec: AgentSpec) -> list[str]:
268
+ bindings = spec.bindings
269
+ ids = [b.resource_id for b in bindings.skills]
270
+ ids.extend(spec.capabilities.skills or [])
271
+ seen: set[str] = set()
272
+ ordered: list[str] = []
273
+ for sid in ids:
274
+ if sid and sid not in seen:
275
+ seen.add(sid)
276
+ ordered.append(sid)
277
+ return ordered
278
+
279
+ def _mcp_server_configs(self, spec: AgentSpec) -> list[dict[str, Any]]:
280
+ """Resolve bound MCP resource ids to codex streamable-http MCP configs."""
281
+ bindings = spec.bindings
282
+ ids = [b.resource_id for b in bindings.mcp_servers]
283
+ ids.extend(spec.capabilities.mcp_servers or [])
284
+ seen: set[str] = set()
285
+ ordered: list[dict[str, Any]] = []
286
+ catalog = getattr(self.studio, "catalog", None)
287
+ if catalog is None:
288
+ return ordered
289
+ try:
290
+ resources = catalog.list(limit=200)
291
+ except Exception:
292
+ return ordered
293
+ mcp_by_id = {item.resource_id: item for item in resources if item.kind == "mcp"}
294
+ for rid in ids:
295
+ if rid in seen:
296
+ continue
297
+ seen.add(rid)
298
+ descriptor = mcp_by_id.get(rid)
299
+ if descriptor is None:
300
+ continue
301
+ contract = descriptor.contract or {}
302
+ url = str(
303
+ contract.get("endpointUrl")
304
+ or contract.get("endpoint_url")
305
+ or contract.get("url")
306
+ or ""
307
+ ).strip()
308
+ if not url:
309
+ continue
310
+ env_refs = contract.get("envRefs") or {}
311
+ env_key = ""
312
+ for ref in env_refs.values():
313
+ if isinstance(ref, str) and ref.startswith("env://"):
314
+ env_key = ref.removeprefix("env://")
315
+ break
316
+ entry: dict[str, Any] = {
317
+ "name": descriptor.name,
318
+ "url": url,
319
+ }
320
+ if env_key:
321
+ entry["env_key"] = env_key
322
+ ordered.append(entry)
323
+ return ordered
324
+
325
+ def delete(self, agent_id: str, *, purge: bool = False) -> None:
326
+ self.studio.codex_manifests.load(agent_id)
327
+ running = [
328
+ run.id
329
+ for run in self.studio.event_store.list_runs(agent_id=agent_id)
330
+ if run.status in {RunStatus.CREATED, RunStatus.RUNNING}
331
+ ]
332
+ if running:
333
+ raise StudioError(
334
+ "AGENT_RUN_ACTIVE",
335
+ "Agent 仍有运行中的任务,请等待运行结束后再删除",
336
+ status_code=409,
337
+ details={"agentId": agent_id, "runIds": running},
338
+ )
339
+ trash_directory = None
340
+ if not purge:
341
+ timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S%fZ")
342
+ trash_directory = self.studio.workspace.resolve(
343
+ Path(".agentkit/trash/agents") / f"{agent_id}-{timestamp}"
344
+ )
345
+ trash_directory.mkdir(parents=True, exist_ok=False)
346
+ self.studio.event_store.delete_agent(
347
+ agent_id,
348
+ purge=purge,
349
+ trash_directory=trash_directory,
350
+ )
351
+ self.studio.codex_builds.delete_for_agent(
352
+ agent_id,
353
+ purge=purge,
354
+ trash_directory=trash_directory,
355
+ )
356
+ self.drafts.delete(
357
+ agent_id,
358
+ purge=purge,
359
+ trash_directory=trash_directory,
360
+ )
361
+ # 早期 Studio 会把首个 Codex Agent 同时保存在根 agentengine.yaml 与
362
+ # agents/<id>/agentengine.yaml。Repository.load() 会优先返回根文件;只删
363
+ # 一次会让同一个 Agent 在刷新列表后从副本“复活”。最多消费这两个兼容
364
+ # 位置,且始终使用同一 recoverable trash 目录。
365
+ for _ in range(2):
366
+ try:
367
+ self.studio.codex_manifests.delete(
368
+ agent_id,
369
+ purge=purge,
370
+ trash_directory=trash_directory,
371
+ )
372
+ except StudioError as exc:
373
+ if exc.status_code == 404:
374
+ break
375
+ raise
376
+
377
+ def detail(self, agent_id: str | None = None) -> dict:
378
+ snapshot = self.studio.codex_manifests.load(agent_id)
379
+ _mcp_bindings, unresolved_mcp = self._mcp_bindings(snapshot.manifest)
380
+ return {
381
+ "draft": self._project(snapshot),
382
+ "builds": [self.build_view(item) for item in self._builds(snapshot.manifest.name)],
383
+ "validation": {"valid": True, "level": "build", "diagnostics": []},
384
+ "manifestSha256": snapshot.manifest_sha256,
385
+ "sourcePath": self.studio.workspace.relative(snapshot.source_path),
386
+ "bindingProjection": {
387
+ "unresolvedMcpServers": unresolved_mcp,
388
+ },
389
+ }
390
+
391
+ @staticmethod
392
+ def build_view(record: CodexBuildRecord) -> dict:
393
+ return {
394
+ "id": record.id,
395
+ "agentId": record.agent_name,
396
+ "sourceRevision": record.source_revision,
397
+ "status": record.status,
398
+ "resolvedDigest": record.manifest_sha256,
399
+ "bundleDigest": f"sha256:{record.manifest_sha256}",
400
+ "artifactPath": record.artifact_path,
401
+ "diagnostics": [],
402
+ "createdAt": record.created_at,
403
+ "completedAt": record.created_at,
404
+ "manifestSha256": record.manifest_sha256,
405
+ "runtimeLock": record.runtime_lock,
406
+ "runtimeName": record.runtime_name,
407
+ "runtimeVersion": record.runtime_version,
408
+ "proxyMode": record.proxy_mode,
409
+ }
410
+
411
+ def submit_build(
412
+ self,
413
+ *,
414
+ idempotency_key: str,
415
+ agent_id: str | None = None,
416
+ ) -> Operation:
417
+ resolved_id = self.studio.codex_manifests.load(agent_id).manifest.name
418
+ revision = self._project(self.studio.codex_manifests.load(resolved_id)).metadata.revision
419
+
420
+ async def runner(_operation_id: str):
421
+ return await asyncio.to_thread(
422
+ self.studio.codex_builder.build,
423
+ resolved_id,
424
+ source_revision=revision,
425
+ )
426
+
427
+ return cast(
428
+ Operation,
429
+ self.studio.operations.submit(
430
+ kind=OperationKind.BUILD,
431
+ resource_id=resolved_id,
432
+ idempotency_key=idempotency_key,
433
+ runner=runner,
434
+ ),
435
+ )
436
+
437
+ def submit_run(
438
+ self,
439
+ build_id: str,
440
+ user_input: str,
441
+ *,
442
+ session_id: str | None,
443
+ model: str | None,
444
+ idempotency_key: str,
445
+ on_event: Callable[[RunEvent], None] | None,
446
+ sandbox: str | None = None,
447
+ approval_mode: str | None = None,
448
+ collaboration_mode: str | None = None,
449
+ goal_objective: str | None = None,
450
+ reasoning_effort: str | None = None,
451
+ runtime_input: Any = None,
452
+ ) -> Operation:
453
+ async def runner(_operation_id: str):
454
+ return await self.studio.run_build(
455
+ build_id,
456
+ user_input,
457
+ session_id,
458
+ model=model,
459
+ sandbox=sandbox,
460
+ approval_mode=approval_mode,
461
+ collaboration_mode=collaboration_mode,
462
+ goal_objective=goal_objective,
463
+ reasoning_effort=reasoning_effort,
464
+ runtime_input=runtime_input,
465
+ on_event=on_event,
466
+ )
467
+
468
+ return cast(
469
+ Operation,
470
+ self.studio.operations.submit(
471
+ kind=OperationKind.RUN,
472
+ resource_id=build_id,
473
+ idempotency_key=idempotency_key,
474
+ runner=runner,
475
+ ),
476
+ )
477
+
478
+ def _project(
479
+ self,
480
+ snapshot: CodexManifestSnapshot,
481
+ *,
482
+ current: AgentDraft | None = None,
483
+ ) -> AgentDraft:
484
+ manifest = snapshot.manifest
485
+ saved = current or self.drafts.get(manifest.name)
486
+ bindings = self._model_bindings(manifest)
487
+ mcp_bindings, _unresolved_mcp = self._mcp_bindings(manifest)
488
+ skill_bindings = [
489
+ CapabilityBinding(resource_id=resource_id)
490
+ for resource_id in (manifest.skills or [])
491
+ ]
492
+ # 从 Manifest 恢复 PCM context/memory(方案 §5.1:Build 不可变)
493
+ # Manifest 已在 model_validate 时严格校验;这里直接恢复
494
+ from ksadk.studio.contracts import ContextSpec, MemorySpec
495
+
496
+ context_spec = manifest.context or ContextSpec()
497
+ memory_spec = manifest.memory or MemorySpec()
498
+ if saved is not None:
499
+ draft = saved.model_copy(deep=True)
500
+ draft.spec.runtime = RuntimeRef(
501
+ type="codex",
502
+ version=manifest.runtime.version,
503
+ )
504
+ draft.spec.instructions = Instructions(
505
+ system=manifest.prompt,
506
+ task=manifest.task_prompt or "",
507
+ )
508
+ draft.spec.bindings.model_profile_id = bindings[0]
509
+ draft.spec.bindings.model_profile_ids = bindings[1]
510
+ draft.spec.bindings.skills = skill_bindings
511
+ draft.spec.bindings.mcp_servers = mcp_bindings
512
+ draft.spec.context = context_spec
513
+ draft.spec.memory = memory_spec
514
+ draft.metadata.labels.update(self._labels(manifest))
515
+ return draft
516
+ default_profile, profiles = bindings
517
+ return AgentDraft(
518
+ metadata=AgentMetadata(
519
+ id=manifest.name,
520
+ name=manifest.name,
521
+ labels=self._labels(manifest),
522
+ ),
523
+ spec=AgentSpec(
524
+ description="由 agentengine.yaml 管理的 Codex Agent",
525
+ runtime=RuntimeRef(type="codex", version=manifest.runtime.version),
526
+ instructions=Instructions(
527
+ system=manifest.prompt,
528
+ task=manifest.task_prompt or "",
529
+ ),
530
+ bindings=AgentBindings(
531
+ model_profile_id=default_profile,
532
+ model_profile_ids=profiles,
533
+ skills=skill_bindings,
534
+ mcp_servers=mcp_bindings,
535
+ ),
536
+ context=context_spec,
537
+ memory=memory_spec,
538
+ ),
539
+ )
540
+
541
+ def _manifest(
542
+ self,
543
+ agent_id: str,
544
+ spec: AgentSpec,
545
+ *,
546
+ current: CodexAgentManifest | None = None,
547
+ ) -> CodexAgentManifest:
548
+ model = self._model_name(spec, agent_id=agent_id)
549
+ models = self._model_names(spec, default_model=model, agent_id=agent_id)
550
+ prompt = spec.instructions.system.strip()
551
+ task_prompt = spec.instructions.task.strip() or None
552
+ skill_ids = self._skill_resource_ids(spec)
553
+ mcp_servers = self._mcp_server_configs(spec)
554
+ if current is not None:
555
+ _current_bindings, unresolved_current = self._mcp_bindings(current)
556
+ unresolved_names = {item["name"] for item in unresolved_current}
557
+ mcp_servers.extend(
558
+ dict(item)
559
+ for item in (current.mcp_servers or [])
560
+ if str(item.get("name") or "").strip() in unresolved_names
561
+ and str(item.get("name") or "").strip()
562
+ not in {str(server.get("name") or "").strip() for server in mcp_servers}
563
+ )
564
+ # PCM 策略写入 Manifest(随 Build 锁定,不可变)
565
+ context_payload = (
566
+ spec.context.model_dump(by_alias=True, exclude_none=True, mode="json") or None
567
+ )
568
+ memory_payload = (
569
+ spec.memory.model_dump(by_alias=True, exclude_none=True, mode="json") or None
570
+ )
571
+ return CodexAgentManifest(
572
+ name=agent_id,
573
+ version=current.version if current is not None else "1.0.0",
574
+ runtime=CodexRuntimeRef(version=self._runtime_version(spec, current=current)),
575
+ model=model,
576
+ models=models if len(models) > 1 else None,
577
+ prompt=prompt,
578
+ task_prompt=task_prompt,
579
+ skills=skill_ids or None,
580
+ mcp_servers=mcp_servers or None,
581
+ sandbox=spec.execution.sandbox,
582
+ approval_mode=spec.execution.approval_mode,
583
+ context=context_payload,
584
+ memory=memory_payload,
585
+ )
586
+
587
+ @staticmethod
588
+ def _runtime_version(
589
+ spec: AgentSpec,
590
+ *,
591
+ current: CodexAgentManifest | None = None,
592
+ ) -> str:
593
+ if spec.runtime is not None and spec.runtime.version:
594
+ return spec.runtime.version
595
+ return (
596
+ current.runtime.version
597
+ if current is not None
598
+ else (installed_runtime_version("codex") or "0.144.4")
599
+ )
600
+
601
+ def _model_name(self, spec: AgentSpec, *, agent_id: str | None = None) -> str:
602
+ resolved = self.studio.catalog.resolve_model(spec.bindings)
603
+ if resolved is not None:
604
+ return str(resolved.model)
605
+ if spec.model is not None:
606
+ return spec.model.model
607
+ if agent_id and self.studio.codex_manifests.exists(agent_id):
608
+ return str(self.studio.codex_manifests.load(agent_id).manifest.model)
609
+ configured = os.environ.get("OPENAI_MODEL_NAME", "").strip()
610
+ return configured or "glm-5.1"
611
+
612
+ def _model_names(
613
+ self,
614
+ spec: AgentSpec,
615
+ *,
616
+ default_model: str,
617
+ agent_id: str | None,
618
+ ) -> builtins.list[str]:
619
+ names = [item.model for item in self.studio.catalog.resolve_models(spec.bindings)]
620
+ if not names and agent_id and self.studio.codex_manifests.exists(agent_id):
621
+ names = builtins.list(
622
+ self.studio.codex_manifests.load(agent_id).manifest.allowed_models
623
+ )
624
+ if not names and spec.model is not None:
625
+ names = [spec.model.model]
626
+ names = [default_model, *[name for name in names if name != default_model]]
627
+ return builtins.list(dict.fromkeys(names))
628
+
629
+ def _model_bindings(
630
+ self,
631
+ manifest: CodexAgentManifest,
632
+ ) -> tuple[str | None, builtins.list[str]]:
633
+ resources: dict[str, str] = {}
634
+ for descriptor in self.studio.catalog.list(kind="model", limit=500):
635
+ try:
636
+ model_spec = ModelSpec.model_validate(descriptor.contract)
637
+ except ValueError:
638
+ continue
639
+ resources.setdefault(model_spec.model, descriptor.resource_id)
640
+ default = resources.get(manifest.model)
641
+ profiles = [resources[model] for model in manifest.allowed_models if model in resources]
642
+ return default, profiles if default in profiles else []
643
+
644
+ def _mcp_bindings(
645
+ self,
646
+ manifest: CodexAgentManifest,
647
+ ) -> tuple[builtins.list[CapabilityBinding], builtins.list[dict[str, str]]]:
648
+ """Project YAML MCP configs to real catalog bindings without inventing ids."""
649
+
650
+ resources: dict[tuple[str, str], str] = {}
651
+ for descriptor in self.studio.catalog.list(kind="mcp", limit=500):
652
+ contract = descriptor.contract or {}
653
+ name = str(contract.get("name") or descriptor.name or "").strip()
654
+ url = str(
655
+ contract.get("endpointUrl")
656
+ or contract.get("endpoint_url")
657
+ or contract.get("url")
658
+ or ""
659
+ ).strip()
660
+ if name and url:
661
+ resources.setdefault((name, url), descriptor.resource_id)
662
+
663
+ bindings: builtins.list[CapabilityBinding] = []
664
+ unresolved: builtins.list[dict[str, str]] = []
665
+ for entry in manifest.mcp_servers or []:
666
+ name = str(entry.get("name") or "").strip()
667
+ url = str(entry.get("url") or "").strip()
668
+ resource_id = resources.get((name, url))
669
+ if resource_id:
670
+ bindings.append(CapabilityBinding(resource_id=resource_id))
671
+ else:
672
+ unresolved.append({
673
+ "name": name or "未命名 MCP",
674
+ "reason": "not-in-resource-catalog",
675
+ })
676
+ return bindings, unresolved
677
+
678
+ @staticmethod
679
+ def _labels(manifest: CodexAgentManifest) -> dict[str, str]:
680
+ return {
681
+ "agentkit.ksyun.com/template": "blank",
682
+ "agentkit.ksyun.com/framework": "codex",
683
+ "agentkit.ksyun.com/artifact-type": "ManagedRuntime",
684
+ "agentkit.ksyun.com/model": manifest.model,
685
+ "agentkit.ksyun.com/models": ",".join(manifest.allowed_models),
686
+ "agentkit.ksyun.com/runtime-version": manifest.runtime.version,
687
+ "agentkit.ksyun.com/manifest-version": manifest.version,
688
+ }
689
+
690
+ def _builds(self, agent_id: str) -> builtins.list[CodexBuildRecord]:
691
+ return [item for item in self.studio.codex_builds.list() if item.agent_name == agent_id]
692
+
693
+
694
+ __all__ = ["CodexAgentService", "CodexDraftRepository"]