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,317 @@
1
+ """Content-addressed preflight for Studio Code bundles hosted by Agent Kernel.
2
+
3
+ This module deliberately proves only properties available in the local bundle:
4
+ the frozen Agent Kernel wire-contract digest and the launch layout generated by
5
+ Studio. Whether the target Server-selected image implements that digest remains
6
+ a separate control-plane/readiness check.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import io
12
+ import json
13
+ import zipfile
14
+ from dataclasses import dataclass
15
+ from pathlib import PurePosixPath
16
+ from typing import Any
17
+
18
+ from ksadk.studio.capabilities import canonical_json, sha256_digest
19
+ from ksadk.studio.errors import StudioError
20
+
21
+ AGENT_KERNEL_V1_CONTRACT_SET = "agent-kernel/v1"
22
+ # This mirrors contracts/agent-kernel/v1/manifest.json. A Studio test compares
23
+ # the two, so a frozen-contract update cannot leave packaged preflight stale.
24
+ AGENT_KERNEL_V1_CONTRACT_DIGEST = "47e1003e03d97abeba232cc3e03a14b9cbcf78b1109870ccd2ce371f073b6211"
25
+ HOSTED_KERNEL_REQUIREMENTS_PATH = "hosted-kernel-requirements.json"
26
+ HOSTED_KERNEL_REQUIREMENTS_FORMAT = "agentkit.hosted-kernel-requirements/v1"
27
+ HOSTED_KERNEL_RUNTIME_CONTRACT = "agentkit.runtime/v1"
28
+ HOSTED_KERNEL_BUNDLE_FORMAT = "agentkit.bundle/v2"
29
+ _RUNTIME_TYPES = frozenset({"adk", "codex", "langgraph"})
30
+
31
+
32
+ @dataclass(frozen=True)
33
+ class HostedKernelBundle:
34
+ """Facts proved from the exact ZIP bytes that will be uploaded."""
35
+
36
+ manifest: dict[str, Any]
37
+ provenance: dict[str, Any]
38
+ requirement: dict[str, Any]
39
+ requirement_digest: str
40
+
41
+
42
+ def build_hosted_kernel_requirement(
43
+ *,
44
+ runtime_type: str,
45
+ entry_point: str | None,
46
+ agent_variable: str | None,
47
+ launch_config: bytes | None,
48
+ ) -> dict[str, Any]:
49
+ """Build the immutable local requirement embedded into every Studio ZIP."""
50
+
51
+ return {
52
+ "format": HOSTED_KERNEL_REQUIREMENTS_FORMAT,
53
+ "kernelContract": {
54
+ "set": AGENT_KERNEL_V1_CONTRACT_SET,
55
+ "digest": AGENT_KERNEL_V1_CONTRACT_DIGEST,
56
+ },
57
+ "bundleLayout": HOSTED_KERNEL_BUNDLE_FORMAT,
58
+ "runtimeContract": HOSTED_KERNEL_RUNTIME_CONTRACT,
59
+ "runtime": {
60
+ "type": runtime_type,
61
+ "entryPoint": entry_point or "",
62
+ "agentVariable": agent_variable or "",
63
+ "launchConfig": "runtime/agentengine.yaml" if launch_config is not None else "",
64
+ "launchConfigSha256": sha256_digest(launch_config) if launch_config is not None else "",
65
+ },
66
+ }
67
+
68
+
69
+ def hosted_kernel_requirement_digest(requirement: dict[str, Any]) -> str:
70
+ return sha256_digest(canonical_json(requirement))
71
+
72
+
73
+ def preflight_hosted_kernel_bundle(bundle: bytes) -> HostedKernelBundle:
74
+ """Reject a ZIP that cannot be proved compatible before CreateAgent.
75
+
76
+ This validates the uploaded bytes, including their file manifest, instead
77
+ of trusting a writable sibling directory from a local Build.
78
+ """
79
+
80
+ try:
81
+ with zipfile.ZipFile(io.BytesIO(bundle)) as archive:
82
+ names = _validated_zip_names(archive)
83
+ entries = {name: archive.read(name) for name in names}
84
+ except (OSError, zipfile.BadZipFile, zipfile.LargeZipFile) as error:
85
+ raise _integrity_error("Bundle 不是可验证的 ZIP 文件", reason="invalid_zip") from error
86
+
87
+ manifest = _json_object(entries, "manifest.json")
88
+ provenance = _json_object(entries, "provenance.json")
89
+ requirement = _json_object(entries, HOSTED_KERNEL_REQUIREMENTS_PATH)
90
+ requirement_digest = hosted_kernel_requirement_digest(requirement)
91
+
92
+ _validate_requirement(manifest, provenance, requirement, requirement_digest, entries)
93
+ _validate_content_manifest(manifest, entries)
94
+ _validate_declared_bundle_digest(manifest)
95
+ return HostedKernelBundle(
96
+ manifest=manifest,
97
+ provenance=provenance,
98
+ requirement=requirement,
99
+ requirement_digest=requirement_digest,
100
+ )
101
+
102
+
103
+ def _validated_zip_names(archive: zipfile.ZipFile) -> list[str]:
104
+ names = archive.namelist()
105
+ if not names:
106
+ raise _integrity_error("Bundle 为空", reason="empty_zip")
107
+ if len(names) != len(set(names)):
108
+ raise _integrity_error("Bundle 含有重复文件名", reason="duplicate_path")
109
+ for name in names:
110
+ path = PurePosixPath(name)
111
+ if (
112
+ not name
113
+ or "\\" in name
114
+ or name.endswith("/")
115
+ or path.is_absolute()
116
+ or any(part in {"", ".", ".."} for part in path.parts)
117
+ ):
118
+ raise _integrity_error("Bundle 含有不安全文件路径", reason="unsafe_path")
119
+ return names
120
+
121
+
122
+ def _json_object(entries: dict[str, bytes], path: str) -> dict[str, Any]:
123
+ raw = entries.get(path)
124
+ if raw is None:
125
+ raise _incompatible_error(f"Bundle 缺少 {path}", reason="missing_required_file")
126
+ try:
127
+ parsed = json.loads(raw.decode("utf-8"))
128
+ except (UnicodeDecodeError, json.JSONDecodeError) as error:
129
+ raise _incompatible_error(
130
+ f"Bundle 中的 {path} 不是 JSON 对象", reason="invalid_json"
131
+ ) from error
132
+ if not isinstance(parsed, dict):
133
+ raise _incompatible_error(f"Bundle 中的 {path} 不是 JSON 对象", reason="invalid_json")
134
+ return parsed
135
+
136
+
137
+ def _validate_requirement(
138
+ manifest: dict[str, Any],
139
+ provenance: dict[str, Any],
140
+ requirement: dict[str, Any],
141
+ requirement_digest: str,
142
+ entries: dict[str, bytes],
143
+ ) -> None:
144
+ if manifest.get("bundleFormat") != HOSTED_KERNEL_BUNDLE_FORMAT:
145
+ raise _incompatible_error(
146
+ "Bundle 不是受支持的 Studio Code bundle 格式", reason="bundle_format"
147
+ )
148
+ if manifest.get("runtimeContract") != HOSTED_KERNEL_RUNTIME_CONTRACT:
149
+ raise _incompatible_error(
150
+ "Bundle runtime contract 不受 Hosted Agent Kernel 支持", reason="runtime_contract"
151
+ )
152
+ if requirement.get("format") != HOSTED_KERNEL_REQUIREMENTS_FORMAT:
153
+ raise _incompatible_error(
154
+ "Bundle 缺少 Hosted Agent Kernel requirement 格式声明", reason="requirement_format"
155
+ )
156
+ if requirement.get("bundleLayout") != manifest.get("bundleFormat"):
157
+ raise _incompatible_error(
158
+ "Bundle requirement 与 bundle layout 不一致", reason="bundle_layout"
159
+ )
160
+ if requirement.get("runtimeContract") != manifest.get("runtimeContract"):
161
+ raise _incompatible_error(
162
+ "Bundle requirement 与 runtime contract 不一致", reason="runtime_contract"
163
+ )
164
+
165
+ contract = requirement.get("kernelContract")
166
+ if not isinstance(contract, dict):
167
+ raise _incompatible_error(
168
+ "Bundle 缺少 Agent Kernel contract requirement", reason="missing_contract"
169
+ )
170
+ if contract.get("set") != AGENT_KERNEL_V1_CONTRACT_SET:
171
+ raise _incompatible_error(
172
+ "Bundle Agent Kernel contract set 不受支持", reason="contract_set"
173
+ )
174
+ if contract.get("digest") != AGENT_KERNEL_V1_CONTRACT_DIGEST:
175
+ raise _incompatible_error(
176
+ "Bundle Agent Kernel contract digest 与当前 KsADK 不一致,请重新 Build 后部署",
177
+ reason="contract_digest",
178
+ )
179
+
180
+ hosted = provenance.get("hostedKernel")
181
+ if not isinstance(hosted, dict):
182
+ raise _incompatible_error(
183
+ "Bundle provenance 缺少 Hosted Agent Kernel requirement", reason="missing_provenance"
184
+ )
185
+ if hosted.get("requirementsPath") != HOSTED_KERNEL_REQUIREMENTS_PATH:
186
+ raise _incompatible_error(
187
+ "Bundle provenance 的 requirement 路径不一致", reason="provenance_path"
188
+ )
189
+ if hosted.get("requirementDigest") != requirement_digest:
190
+ raise _incompatible_error(
191
+ "Bundle provenance 的 requirement digest 不一致", reason="provenance_digest"
192
+ )
193
+ if hosted.get("contractSet") != contract.get("set") or hosted.get(
194
+ "contractDigest"
195
+ ) != contract.get("digest"):
196
+ raise _incompatible_error(
197
+ "Bundle provenance 的 Agent Kernel contract 不一致", reason="provenance_contract"
198
+ )
199
+ if manifest.get("hostedKernelRequirementDigest") != requirement_digest:
200
+ raise _incompatible_error(
201
+ "Bundle manifest 的 requirement digest 不一致", reason="manifest_digest"
202
+ )
203
+
204
+ runtime = requirement.get("runtime")
205
+ if not isinstance(runtime, dict):
206
+ raise _incompatible_error(
207
+ "Bundle 缺少受支持的 runtime 启动 requirement", reason="missing_runtime"
208
+ )
209
+ runtime_type = str(runtime.get("type") or "").strip().lower()
210
+ entry_point = str(runtime.get("entryPoint") or "").strip()
211
+ agent_variable = str(runtime.get("agentVariable") or "").strip()
212
+ launch_path = str(runtime.get("launchConfig") or "").strip()
213
+ launch_digest = str(runtime.get("launchConfigSha256") or "").strip()
214
+ if runtime_type not in _RUNTIME_TYPES:
215
+ raise _incompatible_error(
216
+ "Bundle runtime 类型不受 Hosted Agent Kernel 支持", reason="runtime_type"
217
+ )
218
+ if (
219
+ runtime_type != str(manifest.get("runtimeType") or "").strip().lower()
220
+ or not entry_point
221
+ or not agent_variable
222
+ or launch_path != "runtime/agentengine.yaml"
223
+ or not launch_digest
224
+ ):
225
+ raise _incompatible_error("Bundle 缺少可验证的 runtime 启动配置", reason="runtime_launch")
226
+ if not _safe_relative_file(entry_point) or f"runtime/{entry_point}" not in entries:
227
+ raise _incompatible_error("Bundle runtime entryPoint 不存在或不安全", reason="entry_point")
228
+ launch_bytes = entries.get(launch_path)
229
+ if launch_bytes is None or sha256_digest(launch_bytes) != launch_digest:
230
+ raise _incompatible_error("Bundle runtime 启动配置 digest 不一致", reason="launch_digest")
231
+ launch = _json_object(entries, launch_path)
232
+ if (
233
+ str(launch.get("framework") or "").strip().lower() != runtime_type
234
+ or launch.get("entry_point") != entry_point
235
+ or launch.get("agent_variable") != agent_variable
236
+ or launch.get("package") != "."
237
+ ):
238
+ raise _incompatible_error(
239
+ "Bundle runtime 启动配置与 requirement 不一致", reason="launch_config"
240
+ )
241
+ runtime_lock = _json_object(entries, "runtime-lock.json")
242
+ if (
243
+ str(runtime_lock.get("type") or "").strip().lower() != runtime_type
244
+ or runtime_lock.get("entryPoint") != entry_point
245
+ or runtime_lock.get("agentVariable") != agent_variable
246
+ ):
247
+ raise _incompatible_error(
248
+ "Bundle runtime lock 与 requirement 不一致", reason="runtime_lock"
249
+ )
250
+
251
+
252
+ def _validate_content_manifest(manifest: dict[str, Any], entries: dict[str, bytes]) -> None:
253
+ files = manifest.get("files")
254
+ if not isinstance(files, list):
255
+ raise _integrity_error("Bundle manifest 缺少文件清单", reason="missing_file_manifest")
256
+ recorded: dict[str, dict[str, Any]] = {}
257
+ for item in files:
258
+ if not isinstance(item, dict) or not isinstance(item.get("path"), str):
259
+ raise _integrity_error("Bundle manifest 的文件清单无效", reason="invalid_file_manifest")
260
+ path = item["path"]
261
+ if path in recorded or not _safe_relative_file(path) or path == "manifest.json":
262
+ raise _integrity_error("Bundle manifest 的文件路径无效", reason="invalid_file_manifest")
263
+ recorded[path] = item
264
+ if set(entries) != set(recorded) | {"manifest.json"}:
265
+ raise _integrity_error("Bundle ZIP 与 manifest 文件清单不一致", reason="file_membership")
266
+ for path, item in recorded.items():
267
+ content = entries[path]
268
+ if item.get("sha256") != sha256_digest(content) or item.get("size") != len(content):
269
+ raise _integrity_error("Bundle 文件摘要与 manifest 不一致", reason="file_digest")
270
+
271
+
272
+ def _validate_declared_bundle_digest(manifest: dict[str, Any]) -> None:
273
+ declared = manifest.get("bundleDigest")
274
+ digest_payload = dict(manifest)
275
+ digest_payload.pop("bundleDigest", None)
276
+ if declared != sha256_digest(canonical_json(digest_payload)):
277
+ raise _integrity_error("Bundle manifest 的 bundle digest 不一致", reason="bundle_digest")
278
+
279
+
280
+ def _safe_relative_file(value: str) -> bool:
281
+ path = PurePosixPath(value)
282
+ return (
283
+ bool(value)
284
+ and "\\" not in value
285
+ and not path.is_absolute()
286
+ and all(part not in {"", ".", ".."} for part in path.parts)
287
+ )
288
+
289
+
290
+ def _incompatible_error(message: str, *, reason: str) -> StudioError:
291
+ return StudioError(
292
+ "HOSTED_KERNEL_BUNDLE_INCOMPATIBLE",
293
+ message,
294
+ status_code=422,
295
+ details={"reason": reason},
296
+ )
297
+
298
+
299
+ def _integrity_error(message: str, *, reason: str) -> StudioError:
300
+ return StudioError(
301
+ "HOSTED_KERNEL_BUNDLE_INTEGRITY_INVALID",
302
+ message,
303
+ status_code=422,
304
+ details={"reason": reason},
305
+ )
306
+
307
+
308
+ __all__ = [
309
+ "AGENT_KERNEL_V1_CONTRACT_DIGEST",
310
+ "AGENT_KERNEL_V1_CONTRACT_SET",
311
+ "HOSTED_KERNEL_REQUIREMENTS_FORMAT",
312
+ "HOSTED_KERNEL_REQUIREMENTS_PATH",
313
+ "HostedKernelBundle",
314
+ "build_hosted_kernel_requirement",
315
+ "hosted_kernel_requirement_digest",
316
+ "preflight_hosted_kernel_bundle",
317
+ ]
@@ -0,0 +1,33 @@
1
+ """Server-owned local identifiers for Studio resources."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ import secrets
7
+ from collections.abc import Callable
8
+
9
+ from ksadk.studio.errors import StudioError
10
+
11
+ _GENERATED_AGENT_SLUG = re.compile(r"^agentkit-[0-9a-f]{8}$")
12
+
13
+
14
+ def generate_agent_slug(exists: Callable[[str], bool]) -> str:
15
+ """Allocate a short opaque Agent ID without trusting a client-side default."""
16
+
17
+ for _attempt in range(32):
18
+ candidate = f"agentkit-{secrets.token_hex(4)}"
19
+ if not exists(candidate):
20
+ return candidate
21
+ raise StudioError(
22
+ "AGENT_ID_EXHAUSTED",
23
+ "无法分配唯一的本地标识",
24
+ status_code=503,
25
+ field="slug",
26
+ )
27
+
28
+
29
+ def is_generated_agent_slug(value: str) -> bool:
30
+ return bool(_GENERATED_AGENT_SLUG.fullmatch(str(value or "").strip()))
31
+
32
+
33
+ __all__ = ["generate_agent_slug", "is_generated_agent_slug"]
@@ -0,0 +1,131 @@
1
+ """ManifestResolver —— 统一识别工作区根 Manifest 的种类(方案 §6.1)。
2
+
3
+ 当前问题(方案 §2.4 第 1 点):标准 LangGraph/ADK 项目作为 Studio workspace 启动后,根
4
+ ``agentengine.yaml`` 可能先进入 Codex Manifest 解析,导致 ``CODEX_MANIFEST_INVALID``。
5
+
6
+ 本模块提供统一入口:根 manifest 存在时先读 ``framework`` / ``runtime.type`` 字段决定 kind,
7
+ 只有明确 ``framework: codex`` 才走 ``CodexAgentManifest`` 解析;明确为 ADK/LangGraph 等框架时
8
+ 返回 framework kind(交给 ``FrameworkDetector`` 与标准 Code 项目导入);无法判定时返回
9
+ ``MANIFEST_KIND_AMBIGUOUS``,列出候选,不猜测为 Codex。
10
+
11
+ 解析顺序(方案 §6.1):
12
+ 1. 根 manifest 不存在 → ``none``
13
+ 2. 显式 ``framework: codex`` 或 ``runtime.name: codex`` → ``codex``
14
+ 3. 显式 ``framework: adk|langgraph|...`` 或 ``runtime.type: adk|langgraph|...`` → ``framework``
15
+ 4. 仍无法判定 → ``ambiguous``(列出已读到的关键字段,便于诊断)
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from dataclasses import dataclass, field
21
+ from pathlib import Path
22
+ from typing import Any, Literal
23
+
24
+ import yaml
25
+
26
+ ManifestKind = Literal["none", "codex", "framework", "ambiguous"]
27
+
28
+ # framework/runtime 字段的已知 codex / framework 取值。
29
+ _CODEX_FRAMEWORK_VALUES = frozenset({"codex"})
30
+ _CODEX_RUNTIME_VALUES = frozenset({"codex"})
31
+ _FRAMEWORK_VALUES = frozenset({"adk", "langgraph", "langchain", "deepagents", "hermes", "openclaw"})
32
+
33
+
34
+ @dataclass(frozen=True)
35
+ class ManifestKindResult:
36
+ """根 manifest 识别结果。"""
37
+
38
+ kind: ManifestKind
39
+ path: Path
40
+ framework: str = ""
41
+ runtime_type: str = ""
42
+ artifact_type: str = ""
43
+ # ambiguous 时列出已读字段,供诊断与错误返回。
44
+ detected_fields: dict[str, Any] = field(default_factory=dict)
45
+
46
+ @property
47
+ def is_codex(self) -> bool:
48
+ return self.kind == "codex"
49
+
50
+
51
+ def _safe_yaml(path: Path) -> dict[str, Any]:
52
+ try:
53
+ with open(path, "r", encoding="utf-8-sig") as f:
54
+ payload = yaml.safe_load(f)
55
+ except (OSError, yaml.YAMLError):
56
+ return {}
57
+ if not isinstance(payload, dict):
58
+ return {}
59
+ return payload
60
+
61
+
62
+ def detect_manifest_kind(workspace_root: Path | str) -> ManifestKindResult:
63
+ """识别工作区根 manifest 的种类(方案 §6.1)。
64
+
65
+ ``workspace_root`` 指工作区目录;本函数查其下的 ``agentengine.yaml``(不存在时返回 ``none``)。
66
+ """
67
+ root = Path(workspace_root)
68
+ path = root / "agentengine.yaml"
69
+ if not path.is_file():
70
+ return ManifestKindResult(kind="none", path=path)
71
+
72
+ payload = _safe_yaml(path)
73
+ if not payload:
74
+ # 文件存在但无法解析为 dict → ambiguous(不猜测为 codex)
75
+ return ManifestKindResult(kind="ambiguous", path=path, detected_fields={"unparsable": True})
76
+
77
+ framework = str(payload.get("framework") or "").strip().lower()
78
+ runtime = payload.get("runtime") or {}
79
+ runtime_type = (
80
+ str(runtime.get("type") or runtime.get("name") or "").strip().lower()
81
+ if isinstance(runtime, dict)
82
+ else ""
83
+ )
84
+ artifact_type = str(payload.get("artifact_type") or "").strip().lower()
85
+ detected = {
86
+ "framework": framework,
87
+ "runtimeType": runtime_type,
88
+ "artifactType": artifact_type,
89
+ "topLevelKeys": sorted(payload.keys()),
90
+ }
91
+
92
+ # 2. 显式 codex
93
+ if framework in _CODEX_FRAMEWORK_VALUES or runtime_type in _CODEX_RUNTIME_VALUES:
94
+ return ManifestKindResult(
95
+ kind="codex",
96
+ path=path,
97
+ framework=framework,
98
+ runtime_type=runtime_type,
99
+ artifact_type=artifact_type,
100
+ )
101
+ # 3. 显式 framework
102
+ if framework in _FRAMEWORK_VALUES or runtime_type in _FRAMEWORK_VALUES:
103
+ return ManifestKindResult(
104
+ kind="framework",
105
+ path=path,
106
+ framework=framework or runtime_type,
107
+ runtime_type=runtime_type,
108
+ artifact_type=artifact_type,
109
+ )
110
+ # 4. 无法判定(例如只有 name/version 但无 framework/runtime)
111
+ return ManifestKindResult(
112
+ kind="ambiguous",
113
+ path=path,
114
+ framework=framework,
115
+ runtime_type=runtime_type,
116
+ artifact_type=artifact_type,
117
+ detected_fields=detected,
118
+ )
119
+
120
+
121
+ def root_manifest_is_codex(workspace_root: Path | str) -> bool:
122
+ """便捷判定:根 manifest 是否应走 Codex 解析(方案 §6.1)。"""
123
+ return detect_manifest_kind(workspace_root).is_codex
124
+
125
+
126
+ __all__ = [
127
+ "ManifestKind",
128
+ "ManifestKindResult",
129
+ "detect_manifest_kind",
130
+ "root_manifest_is_codex",
131
+ ]