agentengine-sdk-python 0.8.1__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 (411) hide show
  1. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +22 -2
  2. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/RECORD +356 -222
  3. ksadk/a2a/_space_client_events.py +381 -0
  4. ksadk/a2a/event_adapter.py +156 -64
  5. ksadk/a2a/executor.py +179 -63
  6. ksadk/a2a/space_client.py +6 -333
  7. ksadk/a2ui/core.py +222 -53
  8. ksadk/agui/_agent_helpers.py +243 -0
  9. ksadk/agui/a2ui_projection.py +12 -5
  10. ksadk/agui/agent.py +443 -259
  11. ksadk/api/client.py +525 -27
  12. ksadk/builders/code_builder.py +284 -8
  13. ksadk/builders/container_builder.py +8 -1
  14. ksadk/builders/managed_runtime_builder.py +39 -35
  15. ksadk/cli/__init__.py +17 -0
  16. ksadk/cli/cmd_dashboard.py +15 -1
  17. ksadk/cli/cmd_deploy.py +10 -2
  18. ksadk/cli/cmd_eval.py +66 -9
  19. ksadk/cli/cmd_evalset.py +284 -0
  20. ksadk/cli/cmd_files.py +5 -1
  21. ksadk/cli/cmd_hermes.py +1 -126
  22. ksadk/cli/cmd_invoke.py +28 -38
  23. ksadk/cli/cmd_managed_runtime.py +95 -0
  24. ksadk/cli/cmd_observe.py +85 -0
  25. ksadk/cli/cmd_openclaw.py +1 -435
  26. ksadk/cli/cmd_replay.py +28 -4
  27. ksadk/cli/cmd_studio.py +99 -8
  28. ksadk/cli/cmd_web.py +10 -2
  29. ksadk/cli/hermes_env.py +151 -0
  30. ksadk/cli/invoke_payload.py +49 -0
  31. ksadk/cli/openclaw_env.py +458 -0
  32. ksadk/codex/client.py +180 -30
  33. ksadk/codex/runtime.py +428 -326
  34. ksadk/configs/env_registry.py +66 -12
  35. ksadk/configs/env_registry_pcm.py +181 -0
  36. ksadk/configs/env_var_spec.py +18 -0
  37. ksadk/configs/global_config.py +5 -0
  38. ksadk/context_engine/__init__.py +98 -0
  39. ksadk/context_engine/assembler.py +176 -0
  40. ksadk/context_engine/baseline.py +419 -0
  41. ksadk/context_engine/cache_observability.py +228 -0
  42. ksadk/context_engine/capabilities.py +443 -0
  43. ksadk/context_engine/contributors.py +344 -0
  44. ksadk/context_engine/hosted_pipeline.py +417 -0
  45. ksadk/context_engine/models.py +117 -0
  46. ksadk/context_engine/planner.py +698 -0
  47. ksadk/context_engine/policies.py +319 -0
  48. ksadk/context_engine/projection.py +31 -0
  49. ksadk/context_engine/shadow_plan.py +266 -0
  50. ksadk/context_engine/tokenizer.py +164 -0
  51. ksadk/conversations/context.py +126 -6
  52. ksadk/conversations/message_projection.py +292 -28
  53. ksadk/conversations/model_context.py +49 -3
  54. ksadk/conversations/runtime_compaction.py +207 -5
  55. ksadk/conversations/runtime_input.py +184 -2
  56. ksadk/conversations/runtime_invocation.py +81 -3
  57. ksadk/conversations/runtime_observability.py +141 -0
  58. ksadk/conversations/runtime_payloads.py +42 -0
  59. ksadk/conversations/runtime_preparation.py +272 -2
  60. ksadk/conversations/runtime_resume.py +20 -1
  61. ksadk/conversations/runtime_stream_events.py +94 -9
  62. ksadk/conversations/semantic_summary.py +311 -1
  63. ksadk/conversations/session_lock.py +51 -0
  64. ksadk/deployment/env_forward.py +72 -0
  65. ksadk/deployment/managed_runtime.py +5 -0
  66. ksadk/deployment/providers/serverless.py +143 -69
  67. ksadk/evaluation/__init__.py +32 -0
  68. ksadk/evaluation/a2a_adapter.py +9 -1
  69. ksadk/evaluation/adapters.py +18 -5
  70. ksadk/evaluation/agent_eval_client.py +395 -0
  71. ksadk/evaluation/cloud_binding.py +80 -0
  72. ksadk/evaluation/cloud_converter.py +194 -0
  73. ksadk/evaluation/cloud_service.py +199 -0
  74. ksadk/evaluation/contracts.py +73 -4
  75. ksadk/evaluation/evaluators.py +183 -17
  76. ksadk/evaluation/evidence.py +258 -0
  77. ksadk/evaluation/executor.py +31 -6
  78. ksadk/evaluation/local_adapter.py +550 -0
  79. ksadk/evaluation/service_env.py +27 -0
  80. ksadk/evaluation/studio_build_adapter.py +253 -0
  81. ksadk/evaluation/target.py +15 -6
  82. ksadk/events/__init__.py +13 -13
  83. ksadk/events/_v1_compat/__init__.py +1 -0
  84. ksadk/events/_v1_compat/models.py +299 -0
  85. ksadk/events/_v1_compat/parser.py +247 -0
  86. ksadk/events/_v1_compat/projection.py +753 -0
  87. ksadk/events/adapters/__init__.py +34 -0
  88. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  89. ksadk/events/adapters/_a2a_support.py +275 -0
  90. ksadk/events/adapters/_codex_interactions.py +375 -0
  91. ksadk/events/adapters/_codex_items.py +801 -0
  92. ksadk/events/adapters/_codex_validators.py +311 -0
  93. ksadk/events/adapters/_langgraph_support.py +785 -0
  94. ksadk/events/adapters/a2a.py +841 -0
  95. ksadk/events/adapters/adk.py +503 -0
  96. ksadk/events/adapters/codex.py +717 -0
  97. ksadk/events/adapters/langgraph.py +745 -0
  98. ksadk/events/canonical.py +440 -0
  99. ksadk/events/canonical_replay.py +497 -0
  100. ksadk/events/canonical_store.py +468 -0
  101. ksadk/events/cold_recovery.py +257 -0
  102. ksadk/events/content.py +89 -0
  103. ksadk/events/identity.py +86 -0
  104. ksadk/events/pipeline.py +455 -0
  105. ksadk/events/projections.py +66 -0
  106. ksadk/events/reducer.py +661 -0
  107. ksadk/events/replay.py +3 -36
  108. ksadk/events/runtime_event.py +20 -265
  109. ksadk/events/session_event.py +324 -0
  110. ksadk/events/store.py +3 -316
  111. ksadk/events/v1_compat.py +41 -0
  112. ksadk/harness/runtime.py +160 -57
  113. ksadk/identity/resolver.py +4 -3
  114. ksadk/interaction/__init__.py +28 -0
  115. ksadk/interaction/contracts.py +136 -0
  116. ksadk/interaction/ledger.py +189 -0
  117. ksadk/interaction/provider.py +122 -0
  118. ksadk/interaction/providers/__init__.py +52 -0
  119. ksadk/interaction/providers/adk.py +40 -0
  120. ksadk/interaction/providers/codex.py +94 -0
  121. ksadk/interaction/providers/langgraph.py +58 -0
  122. ksadk/kernel/__init__.py +117 -0
  123. ksadk/kernel/authorization.py +258 -0
  124. ksadk/kernel/bootstrap.py +1074 -0
  125. ksadk/kernel/contract_fingerprints.py +61 -0
  126. ksadk/kernel/contracts.py +362 -0
  127. ksadk/kernel/control.py +219 -0
  128. ksadk/kernel/errors.py +79 -0
  129. ksadk/kernel/ingress.py +1102 -0
  130. ksadk/kernel/mapping.py +111 -0
  131. ksadk/kernel/memory_store.py +1133 -0
  132. ksadk/kernel/postgres_store.py +1756 -0
  133. ksadk/kernel/recovery.py +452 -0
  134. ksadk/kernel/runtime_identity.py +103 -0
  135. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  136. ksadk/kernel/sqlite_store.py +1410 -0
  137. ksadk/kernel/state.py +145 -0
  138. ksadk/kernel/store.py +232 -0
  139. ksadk/kernel/worker.py +953 -0
  140. ksadk/knowledge_base/client.py +7 -0
  141. ksadk/knowledge_base/service.py +32 -5
  142. ksadk/memory/__init__.py +61 -0
  143. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  144. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  145. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  146. ksadk/memory/adk/backends/sdk_ltm_backend.py +384 -2
  147. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  148. ksadk/memory/coordinator.py +461 -0
  149. ksadk/memory/events.py +202 -0
  150. ksadk/memory/extraction.py +228 -0
  151. ksadk/memory/ltm_backend_factory.py +16 -3
  152. ksadk/memory/models.py +316 -0
  153. ksadk/memory/policy.py +215 -0
  154. ksadk/memory/provider.py +47 -0
  155. ksadk/memory/provider_adapter.py +159 -0
  156. ksadk/memory/provider_resolver.py +71 -0
  157. ksadk/memory/providers/__init__.py +5 -0
  158. ksadk/memory/providers/local_sqlite.py +490 -0
  159. ksadk/memory/resolved_policy.py +145 -0
  160. ksadk/memory/service.py +188 -6
  161. ksadk/model_proxy/bootstrap.py +16 -9
  162. ksadk/model_proxy/detect.py +202 -9
  163. ksadk/model_proxy/namespace.py +39 -15
  164. ksadk/model_proxy/server.py +24 -5
  165. ksadk/model_proxy/transform.py +60 -2
  166. ksadk/observability/__init__.py +25 -0
  167. ksadk/observability/session_log.py +420 -0
  168. ksadk/observability/trajectory.py +105 -0
  169. ksadk/prompts/__init__.py +71 -0
  170. ksadk/prompts/compiler.py +215 -0
  171. ksadk/prompts/models.py +82 -0
  172. ksadk/prompts/projection.py +89 -0
  173. ksadk/prompts/resolved.py +137 -0
  174. ksadk/prompts/sources.py +233 -0
  175. ksadk/runners/_langgraph_runner_streams.py +822 -0
  176. ksadk/runners/adk_runner.py +5 -5
  177. ksadk/runners/base_runner.py +16 -0
  178. ksadk/runners/factory.py +1 -2
  179. ksadk/runners/langgraph_runner.py +198 -437
  180. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  181. ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
  182. ksadk/runtime/adapter.py +118 -2
  183. ksadk/runtime/conversation_execution.py +316 -182
  184. ksadk/runtime/executor.py +144 -3
  185. ksadk/runtime/factory.py +193 -7
  186. ksadk/runtime/hosted_finalizer.py +268 -0
  187. ksadk/runtime/launch.py +14 -1
  188. ksadk/runtime/preprocessing.py +25 -3
  189. ksadk/runtime/runner_adapter.py +288 -508
  190. ksadk/runtime/usage.py +33 -0
  191. ksadk/sandbox/backends/e2b.py +35 -2
  192. ksadk/server/composition.py +8 -0
  193. ksadk/server/factory.py +69 -6
  194. ksadk/server/routes/kernel_ingress.py +258 -0
  195. ksadk/server/routes/openai_compat.py +88 -8
  196. ksadk/server/routes/projection.py +35 -20
  197. ksadk/server/routes/run.py +94 -0
  198. ksadk/server/routes/sessions.py +2 -0
  199. ksadk/server/routes/streaming.py +5 -2
  200. ksadk/server/static/assets/{ArtifactsPanel-CakCqxEN.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
  201. ksadk/server/static/assets/{CodeBlock-CynLknyO.js → CodeBlock-DOH6MVcn.js} +4 -4
  202. ksadk/server/static/assets/{MathMessageMarkdown-3sQdOysS.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
  203. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  204. ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
  205. ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
  206. ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
  207. ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
  208. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
  209. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
  210. ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
  211. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
  212. ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
  213. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
  214. ksadk/server/static/assets/{chunk-FMBD7UC4-B_fH2YuH.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
  215. ksadk/server/static/assets/{chunk-ND2GUHAM-D6rFLaVV.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
  216. ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
  217. ksadk/server/static/assets/{chunk-4BX2VUAB-B9drTgOW.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
  218. ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
  219. ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
  220. ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
  221. ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
  222. ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
  223. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
  224. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
  225. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-ChNs_Mdk.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
  226. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
  227. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
  228. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  229. ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
  230. ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
  231. ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
  232. ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
  233. ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
  234. ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
  235. ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
  236. ksadk/server/static/assets/{dist-Dli7qW-B.js → dist-8hqcx0sU.js} +1 -1
  237. ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
  238. ksadk/server/static/assets/{dist-C1sz5Eo3.js → dist-BE7bu-DL.js} +1 -1
  239. ksadk/server/static/assets/{dist-fhOuWds5.js → dist-BVDffZ0U.js} +1 -1
  240. ksadk/server/static/assets/{dist-BjOdlDjj.js → dist-BX8z72IC.js} +1 -1
  241. ksadk/server/static/assets/{dist-DsHPdk3W.js → dist-Bf2M8m3N.js} +1 -1
  242. ksadk/server/static/assets/{dist-o2OVmKvt.js → dist-BjU6y-A2.js} +1 -1
  243. ksadk/server/static/assets/{dist-DWKByxWV.js → dist-BytlxIDT.js} +1 -1
  244. ksadk/server/static/assets/{dist-DJN_6Y39.js → dist-CSh_DE14.js} +1 -1
  245. ksadk/server/static/assets/{dist-DQU9EWw-.js → dist-CXYYBw3_.js} +1 -1
  246. ksadk/server/static/assets/{dist-4N2NMVYg.js → dist-C_wsv-Qd.js} +1 -1
  247. ksadk/server/static/assets/{dist-gLnrGsoU.js → dist-ClxGviKw.js} +1 -1
  248. ksadk/server/static/assets/{dist-j6Dxmf_j.js → dist-CttYUqzS.js} +1 -1
  249. ksadk/server/static/assets/{dist-D6MpCZtz.js → dist-DNp6rLRA.js} +1 -1
  250. ksadk/server/static/assets/{dist-BB3-OwTQ.js → dist-DUX-id_F.js} +1 -1
  251. ksadk/server/static/assets/{dist-_pHPTyZ-.js → dist-DmldrHd_.js} +1 -1
  252. ksadk/server/static/assets/{dist-CWV4lDr1.js → dist-DnfXs8Vn.js} +2 -2
  253. ksadk/server/static/assets/{dist-B5oS1zcj.js → dist-Dq9gLD7L.js} +1 -1
  254. ksadk/server/static/assets/{dist-B-jNR6Vn.js → dist-W-TIVntx.js} +1 -1
  255. ksadk/server/static/assets/{dist-BIlKoW0k.js → dist-dDdADKFA.js} +1 -1
  256. ksadk/server/static/assets/{dist-X4TnqwOK.js → dist-dydu68Fl.js} +1 -1
  257. ksadk/server/static/assets/{dist-CmZHzlwZ.js → dist-ngtN0DJB.js} +1 -1
  258. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
  259. ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
  260. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
  261. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
  262. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
  263. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
  264. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
  265. ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
  266. ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
  267. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
  268. ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
  269. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-K0OOfVna.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
  270. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-8LeOJaZp.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
  271. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-C6uCgZrW.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
  272. ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
  273. ksadk/server/static/assets/{linear-hdBcYzM8.js → linear-BHjG8b-J.js} +1 -1
  274. ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
  275. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-Bjy_2v4_.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
  276. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
  277. ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
  278. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
  279. ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
  280. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-BmkRbwCg.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
  281. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
  282. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
  283. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
  284. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
  285. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
  286. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
  287. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
  288. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-l6iXmU65.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
  289. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-Cq6UBeQB.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
  290. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
  291. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
  292. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
  293. ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
  294. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
  295. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-DEz24vV0.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
  296. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
  297. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
  298. ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
  299. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
  300. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
  301. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
  302. ksadk/server/static/index.html +2 -2
  303. ksadk/sessions/__init__.py +26 -9
  304. ksadk/sessions/_local_service_sync.py +688 -0
  305. ksadk/sessions/_local_tables.py +21 -0
  306. ksadk/sessions/_postgres_schema.py +305 -0
  307. ksadk/sessions/_postgres_tables.py +15 -0
  308. ksadk/sessions/base.py +80 -1
  309. ksadk/sessions/in_memory.py +53 -2
  310. ksadk/sessions/local_service.py +63 -604
  311. ksadk/sessions/postgres_service.py +58 -148
  312. ksadk/sessions/resilient.py +35 -1
  313. ksadk/studio/api.py +577 -25
  314. ksadk/studio/api_contracts.py +114 -5
  315. ksadk/studio/api_memory_routes.py +82 -0
  316. ksadk/studio/authoring.py +252 -27
  317. ksadk/studio/authoring_coordinator.py +799 -67
  318. ksadk/studio/builder.py +88 -11
  319. ksadk/studio/capabilities.py +17 -0
  320. ksadk/studio/cloud.py +1916 -95
  321. ksadk/studio/codex_agent_service.py +125 -14
  322. ksadk/studio/codex_authoring.py +469 -0
  323. ksadk/studio/codex_builder.py +138 -25
  324. ksadk/studio/codex_manifest.py +51 -22
  325. ksadk/studio/codex_run.py +46 -3
  326. ksadk/studio/compiler.py +1 -0
  327. ksadk/studio/contracts.py +114 -3
  328. ksadk/studio/event_store.py +25 -95
  329. ksadk/studio/framework_run.py +231 -3
  330. ksadk/studio/hosted_kernel.py +317 -0
  331. ksadk/studio/manifest_resolver.py +131 -0
  332. ksadk/studio/model_client.py +95 -9
  333. ksadk/studio/model_profile_service.py +1 -1
  334. ksadk/studio/operations.py +37 -5
  335. ksadk/studio/otel_trace.py +348 -42
  336. ksadk/studio/pcm_memory.py +85 -0
  337. ksadk/studio/repository.py +23 -2
  338. ksadk/studio/resource_catalog.py +43 -0
  339. ksadk/studio/run_service.py +563 -137
  340. ksadk/studio/runtime_source.py +42 -16
  341. ksadk/studio/service.py +1180 -72
  342. ksadk/studio/shared_web.py +32 -22
  343. ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
  344. ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
  345. ksadk/studio/static/index.html +2 -2
  346. ksadk/studio/templates.py +100 -8
  347. ksadk/studio/validator.py +19 -0
  348. ksadk/studio/workspace.py +30 -32
  349. ksadk/tracing/setup.py +304 -3
  350. ksadk/version.py +1 -1
  351. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  352. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  353. ksadk/events/parser.py +0 -191
  354. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  355. ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +0 -303
  356. ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +0 -1
  357. ksadk/server/static/assets/arc-DrgjcKhl.js +0 -1
  358. ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +0 -1
  359. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-BXoVRbQ6.js +0 -36
  360. ksadk/server/static/assets/blockDiagram-GPEHLZMM-BnaB3Ywv.js +0 -132
  361. ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dw4weZcp.js +0 -10
  362. ksadk/server/static/assets/channel-Dt3rQTFI.js +0 -1
  363. ksadk/server/static/assets/chunk-2J33WTMH-ChjpLK7j.js +0 -1
  364. ksadk/server/static/assets/chunk-55IACEB6-CK4ROATy.js +0 -1
  365. ksadk/server/static/assets/chunk-727SXJPM-B9KtTTgw.js +0 -206
  366. ksadk/server/static/assets/chunk-AQP2D5EJ-1O1mki3m.js +0 -231
  367. ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +0 -1
  368. ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +0 -1
  369. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +0 -1
  370. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  371. ksadk/server/static/assets/dagre-BM42HDAG-D0QXg_MQ.js +0 -4
  372. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  373. ksadk/server/static/assets/diagram-2AECGRRQ-DBDDKwBQ.js +0 -43
  374. ksadk/server/static/assets/diagram-5GNKFQAL-BkwDOxmO.js +0 -10
  375. ksadk/server/static/assets/diagram-KO2AKTUF-Bv8waYvY.js +0 -3
  376. ksadk/server/static/assets/diagram-LMA3HP47-e1VECDdu.js +0 -24
  377. ksadk/server/static/assets/diagram-OG6HWLK6-Ds9adfRl.js +0 -24
  378. ksadk/server/static/assets/dist-B5J2uhNk.js +0 -1
  379. ksadk/server/static/assets/erDiagram-TEJ5UH35-BPItFKH6.js +0 -85
  380. ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +0 -1
  381. ksadk/server/static/assets/flowDiagram-I6XJVG4X-BbYB9w5Y.js +0 -162
  382. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-TQXa0KXv.js +0 -292
  383. ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +0 -1
  384. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-bKblCnpa.js +0 -106
  385. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  386. ksadk/server/static/assets/index-R52pJJvg.js +0 -177
  387. ksadk/server/static/assets/index-jJr3_955.css +0 -2
  388. ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +0 -1
  389. ksadk/server/static/assets/infoDiagram-5YYISTIA-BGVT7J_i.js +0 -2
  390. ksadk/server/static/assets/katex-CYWseY5E.js +0 -265
  391. ksadk/server/static/assets/mermaid-parser.core-BWrDjSZM.js +0 -161
  392. ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +0 -1
  393. ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +0 -1
  394. ksadk/server/static/assets/pieDiagram-4H26LBE5-GmmqNiVH.js +0 -30
  395. ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +0 -1
  396. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DSWFqL7c.js +0 -84
  397. ksadk/server/static/assets/stateDiagram-AJRCARHV-qzTQpg3Y.js +0 -1
  398. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +0 -1
  399. ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +0 -1
  400. ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +0 -1
  401. ksadk/server/static/assets/vennDiagram-CIIHVFJN-CMCixki2.js +0 -34
  402. ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +0 -1
  403. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-CVzB8F9K.js +0 -78
  404. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-BFBqBLc1.js +0 -7
  405. ksadk/studio/evaluation.py +0 -192
  406. ksadk/studio/static/assets/index-CaEN0eTR.css +0 -1
  407. ksadk/studio/static/assets/index-DI2eY_NH.js +0 -252
  408. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +0 -0
  409. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
  410. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
  411. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
@@ -9,6 +9,7 @@ Code Builder - zip 打包模式构建
9
9
 
10
10
  import ast
11
11
  import hashlib
12
+ import importlib.metadata as importlib_metadata
12
13
  import json
13
14
  import os
14
15
  import re
@@ -19,8 +20,9 @@ import threading
19
20
  import time
20
21
  import zipfile
21
22
  from concurrent.futures import ThreadPoolExecutor, as_completed
23
+ from datetime import datetime, timezone
22
24
  from pathlib import Path
23
- from typing import List, Optional, Set
25
+ from typing import Any, List, Optional, Set
24
26
  from urllib.parse import urlparse
25
27
  from urllib.request import Request, urlopen
26
28
 
@@ -39,6 +41,154 @@ from ksadk.builders.requirements_utils import (
39
41
  parse_requirements_text,
40
42
  )
41
43
 
44
+ BUILD_INFO_SCHEMA = "ksadk-build-info/v1"
45
+ BUILD_INFO_ARCNAME = "ksadk/BUILD-INFO.json"
46
+
47
+
48
+ def _sha256_file(path: Path) -> str:
49
+ digest = hashlib.sha256()
50
+ with open(path, "rb") as f:
51
+ for chunk in iter(lambda: f.read(1024 * 1024), b""):
52
+ digest.update(chunk)
53
+ return digest.hexdigest()
54
+
55
+
56
+ def _bundled_content_fingerprint(files: List[Any]) -> str:
57
+ """对 (relative, file_path) 列表计算确定性内容指纹。
58
+
59
+ 指纹只依赖相对路径与逐文件 sha256,同一来源目录重复打包结果一致,
60
+ 可用于在线上快速判断 zip 里的源码快照是否与某次构建/提交一致。
61
+ """
62
+
63
+ digest = hashlib.sha256()
64
+ digest.update(f"fingerprint:{BUILD_INFO_SCHEMA}\n".encode("utf-8"))
65
+ for relative, file_path in sorted(files, key=lambda item: item[0]):
66
+ digest.update(relative.encode("utf-8"))
67
+ digest.update(b"\0")
68
+ digest.update(_sha256_file(file_path).encode("ascii"))
69
+ digest.update(b"\n")
70
+ return digest.hexdigest()
71
+
72
+
73
+ def _git_provenance(start: Path) -> Optional[dict]:
74
+ """返回 start 所在 git 仓库的提交信息;非 git 目录返回 None。"""
75
+
76
+ def _git(*args: str) -> Optional[str]:
77
+ try:
78
+ proc = subprocess.run(
79
+ ["git", "-C", str(start), *args],
80
+ capture_output=True,
81
+ text=True,
82
+ timeout=10,
83
+ )
84
+ except Exception:
85
+ return None
86
+ if proc.returncode != 0:
87
+ return None
88
+ return proc.stdout.strip()
89
+
90
+ toplevel = _git("rev-parse", "--show-toplevel")
91
+ if not toplevel:
92
+ return None
93
+ commit = _git("rev-parse", "HEAD")
94
+ branch = _git("rev-parse", "--abbrev-ref", "HEAD")
95
+ status = _git("status", "--porcelain")
96
+ return {
97
+ "repo_root": toplevel,
98
+ "commit": commit,
99
+ "branch": branch or None,
100
+ "dirty": bool(status),
101
+ }
102
+
103
+
104
+ def _package_provenance(package_name: str, package_root: Path) -> dict:
105
+ """采集被 vendored 包的安装来源:dist 元信息 / 本地路径 / git 提交。"""
106
+
107
+ info: dict[str, Any] = {
108
+ "source_dir": str(package_root),
109
+ "dist_version": None,
110
+ "installer": None,
111
+ "direct_url": None,
112
+ "source_type": "unknown",
113
+ "git": None,
114
+ }
115
+ try:
116
+ dist = importlib_metadata.distribution(package_name)
117
+ except Exception:
118
+ dist = None
119
+ if dist is not None:
120
+ info["dist_version"] = dist.version
121
+ installer = (dist.read_text("INSTALLER") or "").strip()
122
+ info["installer"] = installer or None
123
+ raw_direct_url = dist.read_text("direct_url.json")
124
+ if raw_direct_url:
125
+ try:
126
+ direct_url = json.loads(raw_direct_url)
127
+ except ValueError:
128
+ direct_url = None
129
+ if isinstance(direct_url, dict):
130
+ info["direct_url"] = direct_url.get("url")
131
+ url = str(direct_url.get("url") or "")
132
+ dir_info = direct_url.get("dir_info") or {}
133
+ archive_info = direct_url.get("archive_info") or {}
134
+ if url.startswith("file://"):
135
+ if dir_info.get("editable"):
136
+ info["source_type"] = "editable-install"
137
+ elif url.endswith(".whl"):
138
+ info["source_type"] = "local-wheel"
139
+ else:
140
+ info["source_type"] = "local-path"
141
+ elif archive_info:
142
+ info["source_type"] = "remote-dist"
143
+ if info["direct_url"] is None and info["dist_version"] is not None:
144
+ # pip 从 index 安装的常规 dist 通常不写 direct_url.json
145
+ info["source_type"] = "installed-dist"
146
+ if info["source_type"] in {"editable-install", "local-path", "unknown"}:
147
+ info["git"] = _git_provenance(package_root)
148
+ return info
149
+
150
+
151
+ def build_bundled_source_manifest(
152
+ package_roots: dict,
153
+ bundled_files: List[Any],
154
+ ) -> dict:
155
+ """生成随 zip 下发的 BUILD-INFO 内容。
156
+
157
+ - ``package_roots``: {package_name: 源码目录}
158
+ - ``bundled_files``: _iter_bundled_source_files() 的 (name, relative, path) 三元组
159
+ """
160
+
161
+ grouped: dict[str, List[Any]] = {}
162
+ for package_name, relative, file_path in bundled_files:
163
+ grouped.setdefault(package_name, []).append((relative, file_path))
164
+
165
+ packages: dict[str, Any] = {}
166
+ for package_name, files in sorted(grouped.items()):
167
+ package_root = package_roots.get(package_name)
168
+ provenance = (
169
+ _package_provenance(package_name, package_root)
170
+ if package_root is not None
171
+ else {"source_dir": None, "source_type": "unknown"}
172
+ )
173
+ packages[package_name] = {
174
+ **provenance,
175
+ "file_count": len(files),
176
+ "content_fingerprint_sha256": _bundled_content_fingerprint(files),
177
+ }
178
+
179
+ return {
180
+ "schema": BUILD_INFO_SCHEMA,
181
+ "built_at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
182
+ "packages": packages,
183
+ }
184
+
185
+
186
+ _NONRELEASE_SOURCE_TYPES = {"editable-install", "local-path", "local-wheel", "unknown"}
187
+
188
+
189
+ def _is_release_like_source(provenance: dict) -> bool:
190
+ return provenance.get("source_type") in {"installed-dist", "remote-dist"}
191
+
42
192
 
43
193
  class CodeBuilder(BaseBuilder):
44
194
  """Code 模式构建器 - 打包 zip + 依赖"""
@@ -229,6 +379,7 @@ class CodeBuilder(BaseBuilder):
229
379
  self._save_input_fingerprint(zip_path, detection_result)
230
380
  zip_size = zip_path.stat().st_size / (1024 * 1024)
231
381
  click.secho(f"\n✅ 使用已有构建: {zip_path.name} ({zip_size:.2f} MB)", fg="green")
382
+ self._emit_bundled_ksadk_identity(zip_path)
232
383
  click.echo(
233
384
  " (如需只重新打包当前代码/runtime,请使用 --repackage;"
234
385
  "如需重装依赖,请使用 --no-cache)"
@@ -275,6 +426,7 @@ class CodeBuilder(BaseBuilder):
275
426
  package_started_at = time.monotonic()
276
427
  self._package_zip(zip_path, detection_result)
277
428
  click.echo(f" ✓ 打包耗时: {self._format_elapsed(package_started_at)}")
429
+ self._emit_bundled_ksadk_identity(zip_path)
278
430
  self._save_input_fingerprint(zip_path, detection_result)
279
431
 
280
432
  zip_size = zip_path.stat().st_size
@@ -657,15 +809,18 @@ class CodeBuilder(BaseBuilder):
657
809
  "file_digests": file_digests,
658
810
  }
659
811
 
660
- def _iter_bundled_source_files(self):
812
+ def _bundled_source_package_roots(self) -> dict:
661
813
  import ksadk
662
814
  import ksadk_runtime_common
663
815
 
664
- yield from self._iter_bundled_source_package("ksadk", Path(ksadk.__file__).resolve().parent)
665
- yield from self._iter_bundled_source_package(
666
- "ksadk_runtime_common",
667
- Path(ksadk_runtime_common.__file__).resolve().parent,
668
- )
816
+ return {
817
+ "ksadk": Path(ksadk.__file__).resolve().parent,
818
+ "ksadk_runtime_common": Path(ksadk_runtime_common.__file__).resolve().parent,
819
+ }
820
+
821
+ def _iter_bundled_source_files(self):
822
+ for package_name, package_root in self._bundled_source_package_roots().items():
823
+ yield from self._iter_bundled_source_package(package_name, package_root)
669
824
 
670
825
  def _iter_bundled_source_package(self, package_name: str, package_root: Path):
671
826
  for file_path in sorted(package_root.rglob("*")):
@@ -685,6 +840,32 @@ class CodeBuilder(BaseBuilder):
685
840
  parts = relative_path.parts
686
841
  return len(parts) >= 2 and parts[0] == "server" and parts[1] == "web-ui"
687
842
 
843
+ def _warn_on_nonrelease_bundled_source(self, build_info: dict) -> None:
844
+ """vendored ksadk 源码来自本地路径/editable/来源不明时给出醒目提示。
845
+
846
+ 历史事故:打包机 environment 里的 ksadk 是正式 release 之前的 dev 快照,
847
+ vendored 进 zip 上线后 runtime 行为与正式版不一致且无从追溯。
848
+ """
849
+
850
+ for package_name, package_info in (build_info.get("packages") or {}).items():
851
+ if _is_release_like_source(package_info):
852
+ continue
853
+ source_desc = (
854
+ f"type={package_info.get('source_type')} " f"dir={package_info.get('source_dir')}"
855
+ )
856
+ git_info = package_info.get("git") or {}
857
+ if git_info.get("commit"):
858
+ dirty = " (有未提交改动)" if git_info.get("dirty") else ""
859
+ source_desc += (
860
+ f" git={git_info.get('branch') or '?'}@{str(git_info['commit'])[:12]}{dirty}"
861
+ )
862
+ click.secho(
863
+ f" ⚠ 打包进 zip 的 {package_name} 不是正式发行版来源 ({source_desc})。"
864
+ "若这不是有意为之,请先用官方渠道的正式版本重装后再打包; "
865
+ f"解压 zip 后查看 {BUILD_INFO_ARCNAME} 可核对来源与内容指纹。",
866
+ fg="yellow",
867
+ )
868
+
688
869
  def _iter_project_files(self):
689
870
  for item in sorted(self.project_dir.iterdir(), key=lambda p: p.name):
690
871
  if self._should_skip_root_path(item):
@@ -1617,6 +1798,26 @@ class CodeBuilder(BaseBuilder):
1617
1798
  )
1618
1799
  self._finish_package_progress()
1619
1800
 
1801
+ # This provenance module is written after the bundled source so a
1802
+ # Code archive can attest to the KsADK source it actually imports.
1803
+ # It deliberately comes from local package bytes / Git only; no
1804
+ # environment value is copied into the archive.
1805
+ zf.writestr(
1806
+ "ksadk/_bundle_identity.py",
1807
+ self._bundle_runtime_identity_source(bundled_source_files),
1808
+ )
1809
+ # 写入 runtime 来源清单:排查"zip 里 vendored 的 ksadk 到底是什么快照"时,
1810
+ # 解压 ksadk/BUILD-INFO.json 即可看到来源/版本/commit/内容指纹,不用进 pod 翻文件。
1811
+ build_info = build_bundled_source_manifest(
1812
+ self._bundled_source_package_roots(),
1813
+ bundled_source_files,
1814
+ )
1815
+ zf.writestr(
1816
+ BUILD_INFO_ARCNAME,
1817
+ json.dumps(build_info, ensure_ascii=False, indent=2, sort_keys=True) + "\n",
1818
+ )
1819
+ self._warn_on_nonrelease_bundled_source(build_info)
1820
+
1620
1821
  click.echo(f" ✓ 打包运行时源码: {bundled_source_count} 个文件")
1621
1822
 
1622
1823
  # 添加 entrypoint
@@ -1626,6 +1827,75 @@ class CodeBuilder(BaseBuilder):
1626
1827
  click.echo(f" ✓ 打包完成: {len(project_files)} 个项目文件 + {deps_count} 个依赖文件")
1627
1828
  self._emit_package_size_report(zip_path)
1628
1829
 
1830
+ def _bundle_runtime_identity_source(self, bundled_source_files) -> str:
1831
+ """Generate package-local provenance for a Code archive."""
1832
+
1833
+ digest = hashlib.sha256()
1834
+ for package_name, relative, file_path in bundled_source_files:
1835
+ if package_name != "ksadk":
1836
+ continue
1837
+ digest.update(relative.encode("utf-8"))
1838
+ digest.update(b"\0")
1839
+ digest.update(file_path.read_bytes())
1840
+ digest.update(b"\0")
1841
+
1842
+ import ksadk
1843
+ from ksadk.version import VERSION
1844
+
1845
+ source_root = Path(ksadk.__file__).resolve().parent
1846
+ commit = ""
1847
+ try:
1848
+ result = subprocess.run(
1849
+ ["git", "-C", str(source_root.parent), "rev-parse", "HEAD"],
1850
+ capture_output=True,
1851
+ check=True,
1852
+ text=True,
1853
+ timeout=3,
1854
+ )
1855
+ candidate = result.stdout.strip().lower()
1856
+ if re.fullmatch(r"[0-9a-f]{40,64}", candidate):
1857
+ commit = candidate
1858
+ except (OSError, subprocess.SubprocessError):
1859
+ pass
1860
+
1861
+ payload = {
1862
+ "ksadk_version": VERSION,
1863
+ "ksadk_commit": commit,
1864
+ "ksadk_source_digest": digest.hexdigest(),
1865
+ }
1866
+ return (
1867
+ "# Generated by KsADK CodeBuilder; do not edit.\n"
1868
+ f"BUNDLE_IDENTITY = {payload!r}\n"
1869
+ )
1870
+
1871
+ def _emit_bundled_ksadk_identity(self, zip_path: Path) -> None:
1872
+ """Print the KsADK provenance embedded in *this exact* Code archive.
1873
+
1874
+ The code archive shadows packages from the base image. Reading the
1875
+ generated archive back here prevents a build log from accidentally
1876
+ describing the local CLI environment instead of what will run in the
1877
+ workload.
1878
+ """
1879
+
1880
+ try:
1881
+ with zipfile.ZipFile(zip_path) as zf:
1882
+ source = zf.read("ksadk/_bundle_identity.py").decode("utf-8")
1883
+ _prefix, raw_payload = source.split("=", 1)
1884
+ identity = ast.literal_eval(raw_payload.strip())
1885
+ except (OSError, KeyError, UnicodeDecodeError, ValueError, SyntaxError):
1886
+ click.secho(" ⚠ 未能读取 ZIP 内的 KsADK 来源信息", fg="yellow")
1887
+ return
1888
+
1889
+ if not isinstance(identity, dict):
1890
+ click.secho(" ⚠ ZIP 内的 KsADK 来源信息格式无效", fg="yellow")
1891
+ return
1892
+ version = str(identity.get("ksadk_version") or "unknown")
1893
+ commit = str(identity.get("ksadk_commit") or "unavailable")
1894
+ source_digest = str(identity.get("ksadk_source_digest") or "unavailable")
1895
+ click.echo(f" KsADK: version={version}")
1896
+ click.echo(f" KsADK source: commit={commit}")
1897
+ click.echo(f" KsADK source digest: sha256={source_digest}")
1898
+
1629
1899
  def _emit_package_size_report(self, zip_path: Path, *, limit: int = 8) -> None:
1630
1900
  try:
1631
1901
  with zipfile.ZipFile(zip_path, "r") as zf:
@@ -1741,6 +2011,9 @@ class CodeBuilder(BaseBuilder):
1741
2011
  def _generate_entrypoint(self, detection_result) -> str:
1742
2012
  """生成 entrypoint.py"""
1743
2013
  package_name = Path(detection_result.package_path).name
2014
+ runtime_config_json = json.dumps(
2015
+ self._load_config(), ensure_ascii=False, separators=(",", ":"), default=str
2016
+ )
1744
2017
  return f'''"""
1745
2018
  AgentEngine Code 模式入口
1746
2019
 
@@ -1754,6 +2027,7 @@ zip 包结构:
1754
2027
  import sys
1755
2028
  import os
1756
2029
  import logging
2030
+ import json
1757
2031
  from pathlib import Path
1758
2032
 
1759
2033
  # ========== 日志配置 ==========
@@ -1878,13 +2152,15 @@ if has_otlp or has_cloud_monitor_otlp:
1878
2152
  logger.warning(f"Tracing 初始化失败: {{e}}")
1879
2153
 
1880
2154
  # 只装配统一 RuntimeAdapter 执行链;具体 Adapter 在请求开始时由 Registry 创建。
2155
+ runtime_build_config = json.loads({runtime_config_json!r})
1881
2156
  runtime_context = RuntimeLaunchContext(
1882
2157
  runtime_type=detection_result.type.value,
1883
2158
  project_dir=Path(CODE_ROOT),
1884
2159
  detection=detection_result,
1885
- config=dict(getattr(detection_result, "raw_config", None) or {{}}),
2160
+ config=dict(runtime_build_config),
1886
2161
  )
1887
2162
  # managed A2A:KSADK_A2A_RUNTIME_ID 非空时挂 discovery card + 完整数据面 route。
2163
+ _managed_a2a_card = None
1888
2164
  _a2a_config = None
1889
2165
  _a2a_adapter = None
1890
2166
  if os.environ.get("KSADK_A2A_RUNTIME_ID", "").strip():
@@ -2,6 +2,7 @@
2
2
  Container Builder - Docker 镜像构建
3
3
  """
4
4
 
5
+ import json
5
6
  import os
6
7
  import platform
7
8
  import shutil
@@ -441,6 +442,9 @@ CMD ["python", "entrypoint.py"]
441
442
 
442
443
  def _generate_entrypoint(self, detection_result, package_name: str) -> str:
443
444
  """生成 entrypoint.py"""
445
+ runtime_config_json = json.dumps(
446
+ self._load_config(), ensure_ascii=False, separators=(",", ":"), default=str
447
+ )
444
448
  return f'''"""
445
449
  AgentEngine Container 模式入口
446
450
  """
@@ -448,6 +452,7 @@ AgentEngine Container 模式入口
448
452
  import sys
449
453
  import os
450
454
  import logging
455
+ import json
451
456
  from pathlib import Path
452
457
 
453
458
  # ========== 日志配置 ==========
@@ -549,15 +554,17 @@ if has_otlp or has_cloud_monitor_otlp:
549
554
  logger.warning(f"Tracing 初始化失败: {{e}}")
550
555
 
551
556
  # 只装配统一 RuntimeAdapter 执行链;具体 Adapter 在请求开始时由 Registry 创建。
557
+ runtime_build_config = json.loads({runtime_config_json!r})
552
558
  runtime_context = RuntimeLaunchContext(
553
559
  runtime_type=detection_result.type.value,
554
560
  project_dir=Path("/app"),
555
561
  detection=detection_result,
556
- config=dict(getattr(detection_result, "raw_config", None) or {{}}),
562
+ config=dict(runtime_build_config),
557
563
  )
558
564
  # managed A2A:KSADK_A2A_RUNTIME_ID 非空时挂 discovery card + 完整数据面 route。
559
565
  # discovery card 让 server 探测;数据面 route 让 gateway 转发的 JSON-RPC/REST
560
566
  # 能真正落到本 runtime 的 A2A 协议端点(路线 C 直连)。
567
+ _managed_a2a_card = None
561
568
  _a2a_config = None
562
569
  _a2a_adapter = None
563
570
  if os.environ.get("KSADK_A2A_RUNTIME_ID", "").strip():
@@ -4,7 +4,6 @@ from __future__ import annotations
4
4
 
5
5
  import hashlib
6
6
  import json
7
- import zipfile
8
7
  from pathlib import Path
9
8
  from typing import Any
10
9
 
@@ -22,35 +21,47 @@ _MANIFEST_KEYS = (
22
21
  "model",
23
22
  "models",
24
23
  "prompt",
24
+ "task_prompt",
25
25
  "skills",
26
26
  "mcp_servers",
27
27
  "sandbox",
28
28
  "approval_mode",
29
+ "context",
30
+ "memory",
29
31
  )
30
32
 
31
33
 
32
- class _RuntimeManifestDumper(yaml.SafeDumper):
33
- """Keep multi-line prompts readable while preserving deterministic bytes."""
34
-
35
-
36
- def _represent_manifest_string(dumper: yaml.SafeDumper, value: str):
37
- style = "|" if "\n" in value else None
38
- return dumper.represent_scalar("tag:yaml.org,2002:str", value, style=style)
34
+ def managed_runtime_lock_path(manifest_path: Path) -> Path:
35
+ """Return the immutable lock that accompanies a YAML-only declaration.
39
36
 
37
+ ``ManagedRuntime`` is not a user-code artifact. Keeping its two small
38
+ declaration files next to one another makes that visible in both the
39
+ workspace and the build receipt, while still preserving a historical
40
+ manifest for rollback.
41
+ """
40
42
 
41
- _RuntimeManifestDumper.add_representer(str, _represent_manifest_string)
43
+ return manifest_path.with_suffix(".lock.json")
42
44
 
43
45
 
44
46
  def serialize_managed_runtime_manifest(manifest: dict[str, Any]) -> bytes:
45
- """Serialize the canonical ManagedRuntime manifest used by every client."""
47
+ """Serialize the Server-canonical ManagedRuntime declaration.
48
+
49
+ The Server validates ``ManifestSHA256`` after parsing and re-dumping YAML
50
+ with sorted keys. Clients must hash those exact canonical bytes instead
51
+ of the editable source formatting, otherwise a valid Studio/CLI build is
52
+ rejected during ``CreateAgent``/``UpdateAgent`` admission.
53
+ """
46
54
 
47
- return yaml.dump(
55
+ canonical = yaml.safe_dump(
48
56
  manifest,
49
- Dumper=_RuntimeManifestDumper,
50
57
  allow_unicode=True,
51
- sort_keys=False,
58
+ sort_keys=True,
52
59
  default_flow_style=False,
53
- ).encode("utf-8")
60
+ width=10_000,
61
+ )
62
+ if not canonical.endswith("\n"):
63
+ canonical += "\n"
64
+ return canonical.encode("utf-8")
54
65
 
55
66
 
56
67
  class ManagedRuntimeBuilder(BaseBuilder):
@@ -102,25 +113,28 @@ class ManagedRuntimeBuilder(BaseBuilder):
102
113
  "runtime": runtime,
103
114
  "manifest_sha256": manifest_sha256,
104
115
  }
105
- lock_bytes = (
106
- json.dumps(lock, ensure_ascii=False, indent=2, sort_keys=True) + "\n"
107
- ).encode("utf-8")
116
+ lock_bytes = (json.dumps(lock, ensure_ascii=False, indent=2, sort_keys=True) + "\n").encode(
117
+ "utf-8"
118
+ )
108
119
 
109
120
  self.build_dir.mkdir(parents=True, exist_ok=True)
110
121
  name = str(config.get("name") or self.project_dir.name).strip() or self.project_dir.name
111
122
  project_version = str(config.get("version") or "1.0.0").strip() or "1.0.0"
112
- artifact_path = self.build_dir / f"{name}-{project_version}-runtime.zip"
113
- self._write_bundle(
114
- artifact_path,
115
- {
116
- "agentengine.yaml": manifest_bytes,
117
- "runtime-lock.json": lock_bytes,
118
- },
123
+ # This local declaration receipt is retained for Studio rollback.
124
+ # It is deliberately *not* a ZIP: YAML agents have no user code, no
125
+ # KS3 artifact and no code-downloader path. Version alone is mutable
126
+ # in an editable Agent, so retain the exact canonical YAML plus its
127
+ # lock under the content digest.
128
+ artifact_path = self.build_dir / (
129
+ f"{name}-{project_version}-{manifest_sha256[:16]}-runtime.yaml"
119
130
  )
131
+ lock_path = managed_runtime_lock_path(artifact_path)
132
+ artifact_path.write_bytes(manifest_bytes)
133
+ lock_path.write_bytes(lock_bytes)
120
134
  return BuildResult(
121
135
  success=True,
122
136
  artifact_path=artifact_path,
123
- artifact_size=artifact_path.stat().st_size,
137
+ artifact_size=artifact_path.stat().st_size + lock_path.stat().st_size,
124
138
  metadata={
125
139
  "agent_name": name,
126
140
  "framework": str(config.get("framework") or ""),
@@ -161,13 +175,3 @@ class ManagedRuntimeBuilder(BaseBuilder):
161
175
  elif key in config:
162
176
  normalized[key] = config[key]
163
177
  return normalized
164
-
165
- @staticmethod
166
- def _write_bundle(path: Path, files: dict[str, bytes]) -> None:
167
- with zipfile.ZipFile(path, "w", compression=zipfile.ZIP_DEFLATED) as archive:
168
- for name in sorted(files):
169
- info = zipfile.ZipInfo(name)
170
- info.date_time = (1980, 1, 1, 0, 0, 0)
171
- info.compress_type = zipfile.ZIP_DEFLATED
172
- info.external_attr = 0o100644 << 16
173
- archive.writestr(info, files[name])
ksadk/cli/__init__.py CHANGED
@@ -68,11 +68,14 @@ ROOT_HELP_COMMANDS = {
68
68
  "dashboard",
69
69
  "deploy",
70
70
  "eval",
71
+ "evalset",
71
72
  "files",
72
73
  "init",
73
74
  "hermes",
74
75
  "launch",
76
+ "managed-runtime",
75
77
  "mcp",
78
+ "observe",
76
79
  "openclaw",
77
80
  "run",
78
81
  "studio",
@@ -90,11 +93,14 @@ SHORT_HELP_MAP = {
90
93
  "dashboard": "打开云端 Agent Dashboard",
91
94
  "deploy": "部署到云端",
92
95
  "eval": "评测本地、A2A 或 Codex Agent",
96
+ "evalset": "预览或上传 EvalSet 云端快照",
93
97
  "files": "管理 workspace 文件",
94
98
  "hermes": "Hermes Agent 资源管理",
95
99
  "init": "创建新项目",
96
100
  "launch": "一键构建+部署",
101
+ "managed-runtime": "启动平台托管的 YAML Agent",
97
102
  "mcp": "MCP 资源管理",
103
+ "observe": "导出本地 Agent 观测数据",
98
104
  "openclaw": "OpenClaw 资源管理",
99
105
  "run": "运行 Agent",
100
106
  "studio": "启动本地 Agent 构建控制台",
@@ -179,12 +185,19 @@ class ColoredHelpGroup(click.Group):
179
185
  _write_colored_help_row(formatter, "agentengine web", "本地调试 Agent Invoke UI")
180
186
  _write_colored_help_row(formatter, "agentengine studio", "本地 Agent 构建控制台")
181
187
  _write_colored_help_row(formatter, "agentengine eval", "评测本地、A2A 或 Codex Agent")
188
+ _write_colored_help_row(formatter, "agentengine evalset", "预览或上传 EvalSet 云端快照")
189
+ _write_colored_help_row(formatter, "agentengine observe", "导出本地 Agent 观测数据")
182
190
 
183
191
  # 云端部署
184
192
  formatter.write(click.style(" 🚀 云端部署:\n\n", fg="blue", bold=True))
185
193
  _write_colored_help_row(formatter, "agentengine build", "构建部署制品")
186
194
  _write_colored_help_row(formatter, "agentengine deploy", "部署到云端")
187
195
  _write_colored_help_row(formatter, "agentengine launch", "一键构建+部署")
196
+ _write_colored_help_row(
197
+ formatter,
198
+ "agentengine managed-runtime",
199
+ "启动平台托管的 YAML Agent",
200
+ )
188
201
  _write_colored_help_row(formatter, "agentengine agent", "Agent 资源管理")
189
202
  _write_colored_help_row(formatter, "agentengine version", "Agent 版本管理")
190
203
  _write_colored_help_row(formatter, "agentengine mcp", "MCP 资源管理")
@@ -325,6 +338,7 @@ def _register_optional_command(cli: click.Group, module_path: str, *cmd_names: s
325
338
  def _register_commands():
326
339
  from ksadk.cli.cmd_create import create
327
340
  from ksadk.cli.cmd_deploy import deploy
341
+ from ksadk.cli.cmd_managed_runtime import managed_runtime
328
342
  from ksadk.cli.cmd_run import run
329
343
  from ksadk.cli.cmd_web import web
330
344
 
@@ -332,6 +346,7 @@ def _register_commands():
332
346
  _add_command_once(cli, run)
333
347
  _add_command_once(cli, deploy)
334
348
  _add_command_once(cli, web)
349
+ _add_command_once(cli, managed_runtime)
335
350
 
336
351
  # init 作为主命令 (PRD 规范)
337
352
  _add_command_once(cli, create, name="init")
@@ -344,6 +359,8 @@ def _register_commands():
344
359
  _register_optional_command(cli, "ksadk.cli.cmd_build", "build")
345
360
  _register_optional_command(cli, "ksadk.cli.cmd_studio", "studio")
346
361
  _register_optional_command(cli, "ksadk.cli.cmd_eval", "eval")
362
+ _register_optional_command(cli, "ksadk.cli.cmd_evalset", "evalset")
363
+ _register_optional_command(cli, "ksadk.cli.cmd_observe", "observe")
347
364
  _register_optional_command(cli, "ksadk.cli.cmd_launch", "launch")
348
365
  _register_optional_command(cli, "ksadk.cli.cmd_agent", "agent")
349
366
  _register_optional_command(cli, "ksadk.cli.cmd_status", "status")
@@ -64,6 +64,10 @@ _PATH_EMBEDDED_OPTION_HINTS = (
64
64
  DEFAULT_PRIVATE_LINK_EXPIRES_SECONDS = 24 * 60 * 60
65
65
  MAX_PRIVATE_LINK_EXPIRES_SECONDS = 365 * 24 * 60 * 60
66
66
  DEFAULT_REGION = "cn-beijing-6"
67
+ # Hosted UI is the shared interaction surface for platform-managed Agents.
68
+ # The access link keeps the user/session/Agent binding while this path keeps
69
+ # the Web release independent from the Agent runtime image.
70
+ HOSTED_INTERACTION_UI_PATH = "/hosted-ui/chat"
67
71
 
68
72
  DASHBOARD_RESOURCE = ResourceDescriptor(
69
73
  name="Dashboard",
@@ -528,7 +532,17 @@ def _open_dashboard(
528
532
  )
529
533
  normalized_path = _normalize_ui_path(resolved_ui.path or "/")
530
534
  custom_ui_enabled = str(resolved_ui.profile or "").strip().lower() == "custom"
531
- link_path = normalized_path if ui_path is not None or custom_ui_enabled else None
535
+ # Hermes owns its own dashboard surface and OpenClaw takes its gateway
536
+ # branch below. The shared Hosted UI is the default only for the generic
537
+ # ADK/LangChain-compatible profiles; an explicit/custom path always wins.
538
+ use_hosted_interaction_ui = resolved_ui.profile in {"adk", "langchain"}
539
+ link_path = (
540
+ normalized_path
541
+ if ui_path is not None or custom_ui_enabled
542
+ else HOSTED_INTERACTION_UI_PATH
543
+ if use_hosted_interaction_ui
544
+ else None
545
+ )
532
546
  base_url = _build_base_ui_url(endpoint, normalized_path)
533
547
 
534
548
  if direct:
ksadk/cli/cmd_deploy.py CHANGED
@@ -328,7 +328,7 @@ async def _deploy_async(
328
328
  agent_id: str | None = None,
329
329
  ):
330
330
  """异步部署流程"""
331
- from ksadk.deployment import DeploymentManager, DeployTarget
331
+ from ksadk.deployment import DeploymentManager, DeployStatus, DeployTarget
332
332
  from ksadk.detection import FrameworkDetector
333
333
 
334
334
  agent_path = Path(agent_dir).resolve()
@@ -606,7 +606,15 @@ async def _deploy_async(
606
606
  result = await provider.deploy(package_info, deploy_target)
607
607
 
608
608
  if result.is_success():
609
- print_success("部署成功")
609
+ # ``DEPLOYING`` only acknowledges that the control plane accepted
610
+ # the request. Runtime creation and the asynchronous
611
+ # CreateAgent callback may still be pending, so presenting it as a
612
+ # completed deployment is misleading (and hides a broken
613
+ # callback/data-plane handoff).
614
+ if result.status == DeployStatus.RUNNING:
615
+ print_success("部署成功")
616
+ else:
617
+ print_info("部署请求已提交,等待实例就绪")
610
618
  print_rule()
611
619
  print_kv("名称", result.agent_name or deploy_name)
612
620
  if result.agent_id: