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
ksadk/cli/cmd_eval.py CHANGED
@@ -31,6 +31,11 @@ from ksadk.evaluation import (
31
31
  execute_evaluation,
32
32
  load_evalset,
33
33
  )
34
+ from ksadk.evaluation.agent_eval_client import (
35
+ AgentEvalCloudClientError,
36
+ AgentEvalCloudDatasetClient,
37
+ )
38
+ from ksadk.evaluation.cloud_service import CloudEvalSetPreviewError, CloudEvalSetService
34
39
  from ksadk.evaluation.contracts import (
35
40
  DataPolicy,
36
41
  EvalRunReport,
@@ -42,10 +47,9 @@ from ksadk.evaluation.contracts import (
42
47
  TargetRunStatus,
43
48
  )
44
49
  from ksadk.evaluation.evalset import EvalSetParseError
45
- from ksadk.evaluation.evaluators import DEFAULT_EVALUATORS, SUPPORTED_EVALUATORS
50
+ from ksadk.evaluation.evaluators import SUPPORTED_EVALUATORS, resolve_evaluator_plan
46
51
  from ksadk.evaluation.storage import EvaluationStorage
47
52
 
48
- _DEFAULT_EVALUATORS = tuple(DEFAULT_EVALUATORS)
49
53
  _DATA_POLICIES = tuple(policy.value for policy in DataPolicy)
50
54
 
51
55
 
@@ -56,10 +60,13 @@ class EvaluationCliError(click.ClickException):
56
60
  @click.command(context_settings=dict(help_option_names=["-h", "--help"]))
57
61
  @click.option(
58
62
  "--evalset-file",
59
- required=True,
63
+ required=False,
60
64
  type=click.Path(exists=True, dir_okay=False, path_type=Path),
61
65
  help="本地 EvalSet YAML/JSON 文件",
62
66
  )
67
+ @click.option("--dataset-id", type=str, help="云端 Dataset ID;必须配合固定版本使用")
68
+ @click.option("--dataset-version", type=click.IntRange(1), help="云端 Dataset immutable version")
69
+ @click.option("--dataset-project-id", type=str, help="云端 Dataset 所属项目 ID")
63
70
  @click.option(
64
71
  "--agent-dir",
65
72
  type=click.Path(exists=True, file_okay=False, path_type=Path),
@@ -119,6 +126,9 @@ class EvaluationCliError(click.ClickException):
119
126
  )
120
127
  def eval(
121
128
  evalset_file: Path,
129
+ dataset_id: str | None,
130
+ dataset_version: int | None,
131
+ dataset_project_id: str | None,
122
132
  agent_dir: Path | None,
123
133
  a2a_url: str | None,
124
134
  codex_worktree: Path | None,
@@ -150,6 +160,9 @@ def eval(
150
160
  )
151
161
  request = _build_request(
152
162
  evalset_file=evalset_file,
163
+ dataset_id=dataset_id,
164
+ dataset_version=dataset_version,
165
+ dataset_project_id=dataset_project_id,
153
166
  target=target,
154
167
  evaluators=evaluators,
155
168
  judge_model=judge_model,
@@ -173,7 +186,10 @@ def eval(
173
186
 
174
187
  def _build_request(
175
188
  *,
176
- evalset_file: Path,
189
+ evalset_file: Path | None,
190
+ dataset_id: str | None,
191
+ dataset_version: int | None,
192
+ dataset_project_id: str | None,
177
193
  target: TargetRef,
178
194
  evaluators: tuple[str, ...],
179
195
  judge_model: str | None,
@@ -184,10 +200,37 @@ def _build_request(
184
200
  data_policy: str,
185
201
  report_dir: Path | None,
186
202
  ) -> EvaluationRequest:
187
- try:
188
- evalset = load_evalset(evalset_file)
189
- except EvalSetParseError as exc:
190
- raise click.UsageError(f"{exc.code}: {exc}") from exc
203
+ cloud_dataset = None
204
+ if dataset_id:
205
+ if evalset_file is not None:
206
+ raise click.UsageError("--evalset-file 与 --dataset-id 不能同时使用")
207
+ if dataset_version is None:
208
+ raise click.UsageError("--dataset-id 必须同时指定 --dataset-version")
209
+ try:
210
+ service = CloudEvalSetService(
211
+ Path.cwd(),
212
+ AgentEvalCloudDatasetClient(),
213
+ )
214
+ pulled = asyncio.run(
215
+ service.pull(
216
+ dataset_id=dataset_id,
217
+ version=dataset_version,
218
+ project_id=dataset_project_id,
219
+ )
220
+ )
221
+ except (AgentEvalCloudClientError, CloudEvalSetPreviewError, ValueError) as exc:
222
+ raise click.UsageError(str(exc)) from exc
223
+ evalset = pulled.evalset
224
+ cloud_dataset = pulled.cloud_dataset
225
+ else:
226
+ if evalset_file is None:
227
+ raise click.UsageError("必须指定 --evalset-file 或 --dataset-id")
228
+ if dataset_version is not None or dataset_project_id:
229
+ raise click.UsageError("云端 Dataset 参数必须与 --dataset-id 一起使用")
230
+ try:
231
+ evalset = load_evalset(evalset_file)
232
+ except EvalSetParseError as exc:
233
+ raise click.UsageError(f"{exc.code}: {exc}") from exc
191
234
 
192
235
  return EvaluationRequest(
193
236
  evalset=evalset,
@@ -195,13 +238,14 @@ def _build_request(
195
238
  config=EvaluationConfig(
196
239
  timeout_seconds=timeout_seconds,
197
240
  fail_fast=fail_fast,
198
- evaluators=list(evaluators) or list(_DEFAULT_EVALUATORS),
241
+ evaluators=list(evaluators),
199
242
  data_policy=data_policy,
200
243
  judge_model=judge_model,
201
244
  judge_api_base=judge_api_base,
202
245
  judge_api_key_env=judge_api_key_env,
203
246
  ),
204
247
  report_dir=str((report_dir or Path.cwd() / ".agentkit/evaluations").resolve()),
248
+ cloud_dataset=cloud_dataset,
205
249
  )
206
250
 
207
251
 
@@ -358,6 +402,14 @@ def _target_ref(
358
402
 
359
403
 
360
404
  def _render_validation(request: EvaluationRequest) -> None:
405
+ try:
406
+ evaluation_plan = resolve_evaluator_plan(
407
+ request.evalset.cases,
408
+ request.config.evaluators,
409
+ request.config,
410
+ )
411
+ except ValueError as exc:
412
+ raise click.UsageError(str(exc)) from exc
361
413
  payload = {
362
414
  "valid": True,
363
415
  "evalset": {
@@ -368,8 +420,13 @@ def _render_validation(request: EvaluationRequest) -> None:
368
420
  },
369
421
  "target": request.target.model_dump(mode="json", by_alias=True, exclude_none=True),
370
422
  "config": request.config.model_dump(mode="json", by_alias=True),
423
+ "evaluationPlan": evaluation_plan,
371
424
  "reportDir": request.report_dir,
372
425
  }
426
+ if request.cloud_dataset is not None:
427
+ payload["cloudDataset"] = request.cloud_dataset.model_dump(
428
+ mode="json", by_alias=True, exclude_none=True
429
+ )
373
430
  if is_json_output():
374
431
  emit_json(payload)
375
432
  return
@@ -0,0 +1,284 @@
1
+ """Commands for inspecting and publishing immutable cloud EvalSet snapshots."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import json
7
+ from pathlib import Path
8
+
9
+ import click
10
+ import yaml
11
+
12
+ from ksadk.evaluation.agent_eval_client import (
13
+ AgentEvalCloudClientError,
14
+ AgentEvalCloudDatasetClient,
15
+ )
16
+ from ksadk.evaluation.cloud_service import CloudEvalSetPreviewError, CloudEvalSetService
17
+ from ksadk.evaluation.contracts import DataPolicy
18
+ from ksadk.evaluation.evalset import EvalSetParseError, load_evalset, parse_evalset
19
+
20
+ _DATA_POLICIES = tuple(policy.value for policy in DataPolicy)
21
+ _TEMPLATE_NAMES = ("knowledge-qa", "structured-output", "tool-routing", "service-sla")
22
+ _TEMPLATES: dict[str, dict] = {
23
+ "knowledge-qa": {
24
+ "schemaVersion": "ksadk.eval/v1",
25
+ "name": "knowledge-qa",
26
+ "cases": [
27
+ {
28
+ "id": "capital",
29
+ "input": "中国的首都是哪里?",
30
+ "reference_output": "北京",
31
+ }
32
+ ],
33
+ },
34
+ "structured-output": {
35
+ "schemaVersion": "ksadk.eval/v1",
36
+ "name": "structured-output",
37
+ "cases": [
38
+ {
39
+ "id": "extract-order",
40
+ "input": "从‘订单 A123,金额 99 元’提取订单信息,并只返回 JSON。",
41
+ "assertions": [
42
+ {
43
+ "type": "response.jsonSchema",
44
+ "value": {
45
+ "type": "object",
46
+ "required": ["orderId", "amount"],
47
+ "properties": {
48
+ "orderId": {"type": "string"},
49
+ "amount": {"type": "number"},
50
+ },
51
+ },
52
+ }
53
+ ],
54
+ }
55
+ ],
56
+ },
57
+ "tool-routing": {
58
+ "schemaVersion": "ksadk.eval/v1",
59
+ "name": "tool-routing",
60
+ "cases": [
61
+ {
62
+ "id": "weather-lookup",
63
+ "input": "查询北京明天的天气,并给出出行建议。",
64
+ "reference_output": "根据天气查询结果回答北京明天的天气,并给出出行建议。",
65
+ "expectedTools": [{"name": "weather_lookup"}],
66
+ "assertions": [
67
+ {"type": "tool.succeeded", "value": "weather_lookup"},
68
+ {"type": "tool.sequence", "value": ["weather_lookup"]},
69
+ ],
70
+ }
71
+ ],
72
+ },
73
+ "service-sla": {
74
+ "schemaVersion": "ksadk.eval/v1",
75
+ "name": "service-sla",
76
+ "cases": [
77
+ {
78
+ "id": "password-reset",
79
+ "input": "如何重置密码?",
80
+ "reference_output": "可通过登录页的忘记密码入口重置密码。",
81
+ "assertions": [
82
+ {"type": "runtime.maxLatencyMs", "value": 3000},
83
+ {"type": "runtime.maxTotalTokens", "value": 300},
84
+ ],
85
+ }
86
+ ],
87
+ },
88
+ }
89
+
90
+
91
+ def _render(value: dict, output_format: str) -> None:
92
+ if output_format == "json":
93
+ click.echo(json.dumps(value, ensure_ascii=False, sort_keys=True))
94
+ return
95
+ for key, item in value.items():
96
+ click.echo(f"{key}: {item}")
97
+
98
+
99
+ def _load_snapshot(evalset_file: Path, data_policy: str):
100
+ try:
101
+ evalset = load_evalset(evalset_file)
102
+ except EvalSetParseError as exc:
103
+ raise click.UsageError(f"{exc.code}: {exc}") from exc
104
+ service = CloudEvalSetService(Path.cwd(), client=_PreviewOnlyCloudClient())
105
+ try:
106
+ return evalset, service.preview(evalset, data_policy=DataPolicy(data_policy))
107
+ except CloudEvalSetPreviewError as exc:
108
+ raise click.UsageError(str(exc)) from exc
109
+
110
+
111
+ class _PreviewOnlyCloudClient:
112
+ async def publish_snapshot(self, *args, **kwargs): # pragma: no cover - preview never publishes
113
+ raise RuntimeError("preview does not publish")
114
+
115
+
116
+ @click.group()
117
+ def evalset() -> None:
118
+ """Inspect or publish versioned cloud EvalSet snapshots."""
119
+
120
+
121
+ @evalset.command("init")
122
+ @click.option("--template", "template_name", type=click.Choice(_TEMPLATE_NAMES), required=True)
123
+ @click.option("--output-file", required=True, type=click.Path(dir_okay=False, path_type=Path))
124
+ @click.option("--force", is_flag=True, help="覆盖已有文件")
125
+ @click.option("--format", "output_format", type=click.Choice(["pretty", "json"]), default="pretty")
126
+ def init(template_name: str, output_file: Path, force: bool, output_format: str) -> None:
127
+ """Create a native EvalSet template without accessing cloud services."""
128
+
129
+ template = _TEMPLATES[template_name]
130
+ try:
131
+ parse_evalset(template)
132
+ except EvalSetParseError as exc: # pragma: no cover - protects static templates
133
+ raise click.ClickException(f"内置模板无效: {exc}") from exc
134
+
135
+ output = output_file.expanduser().resolve()
136
+ if output.exists() and not force:
137
+ raise click.UsageError("输出文件已存在;如需覆盖请指定 --force")
138
+ if output.exists() and output.is_dir():
139
+ raise click.UsageError("--output-file 必须是文件路径")
140
+ output.parent.mkdir(parents=True, exist_ok=True)
141
+ output.write_text(
142
+ yaml.safe_dump(template, allow_unicode=True, sort_keys=False),
143
+ encoding="utf-8",
144
+ )
145
+ _render({"template": template_name, "outputFile": str(output)}, output_format)
146
+
147
+
148
+ @evalset.command("preview")
149
+ @click.option(
150
+ "--evalset-file",
151
+ required=True,
152
+ type=click.Path(exists=True, dir_okay=False, path_type=Path),
153
+ )
154
+ @click.option(
155
+ "--data-policy",
156
+ type=click.Choice(_DATA_POLICIES),
157
+ default="full_trace",
158
+ show_default=True,
159
+ )
160
+ @click.option("--format", "output_format", type=click.Choice(["pretty", "json"]), default="pretty")
161
+ def preview(evalset_file: Path, data_policy: str, output_format: str) -> None:
162
+ """Show the exact fixed-schema payload that a push would publish."""
163
+ _evalset, snapshot = _load_snapshot(evalset_file, data_policy)
164
+ _render(snapshot.model_dump(mode="json", by_alias=True, exclude_none=True), output_format)
165
+
166
+
167
+ @evalset.command("push")
168
+ @click.option(
169
+ "--file",
170
+ "--evalset-file",
171
+ "evalset_file",
172
+ required=True,
173
+ type=click.Path(exists=True, dir_okay=False, path_type=Path),
174
+ )
175
+ @click.option("--dataset-id")
176
+ @click.option("--account-id", envvar="AGENT_EVAL_ACCOUNT_ID", hidden=True)
177
+ @click.option("--idempotency-key", hidden=True)
178
+ @click.option(
179
+ "--data-policy",
180
+ type=click.Choice(_DATA_POLICIES),
181
+ default="full_trace",
182
+ hidden=True,
183
+ )
184
+ @click.option("--format", "output_format", type=click.Choice(["pretty", "json"]), default="pretty")
185
+ def push(
186
+ evalset_file: Path,
187
+ dataset_id: str | None,
188
+ account_id: str | None,
189
+ idempotency_key: str | None,
190
+ data_policy: str,
191
+ output_format: str,
192
+ ) -> None:
193
+ """Publish a full EvalSet snapshot to the EvalSmith-backed agent-eval API."""
194
+ workspace = Path.cwd().resolve()
195
+ try:
196
+ evalset_path = evalset_file.resolve().relative_to(workspace).as_posix()
197
+ except ValueError as exc:
198
+ raise click.UsageError("--file must be inside the current workspace") from exc
199
+ evalset, _snapshot = _load_snapshot(evalset_file, data_policy)
200
+ client = AgentEvalCloudDatasetClient(
201
+ account_id=account_id,
202
+ )
203
+ service = CloudEvalSetService(workspace, client)
204
+ try:
205
+ result = asyncio.run(
206
+ service.publish(
207
+ evalset,
208
+ evalset_path=evalset_path,
209
+ dataset_id=dataset_id,
210
+ data_policy=DataPolicy(data_policy),
211
+ idempotency_key=idempotency_key,
212
+ )
213
+ )
214
+ except (AgentEvalCloudClientError, CloudEvalSetPreviewError, ValueError) as exc:
215
+ raise click.ClickException(str(exc)) from exc
216
+ _render(
217
+ {
218
+ "datasetId": result.dataset_id,
219
+ "datasetVersion": result.dataset_version,
220
+ "projectId": result.project_id,
221
+ "schemaHash": result.schema_hash,
222
+ "contentDigest": result.content_digest,
223
+ "rowCount": result.row_count,
224
+ },
225
+ output_format,
226
+ )
227
+
228
+
229
+ @evalset.command("pull")
230
+ @click.option("--dataset-id", required=True)
231
+ @click.option("--dataset-version", required=True, type=click.IntRange(1))
232
+ @click.option("--project-id")
233
+ @click.option("--output-file", required=True, type=click.Path(dir_okay=False, path_type=Path))
234
+ @click.option("--format", "output_format", type=click.Choice(["pretty", "json"]), default="pretty")
235
+ def pull(
236
+ dataset_id: str,
237
+ dataset_version: int,
238
+ project_id: str | None,
239
+ output_file: Path,
240
+ output_format: str,
241
+ ) -> None:
242
+ """Read one immutable cloud Dataset version into a local EvalSet file."""
243
+ workspace = Path.cwd().resolve()
244
+ target = output_file.resolve()
245
+ try:
246
+ target.relative_to(workspace)
247
+ except ValueError as exc:
248
+ raise click.UsageError("--output-file must be inside the current workspace") from exc
249
+
250
+ service = CloudEvalSetService(
251
+ workspace,
252
+ AgentEvalCloudDatasetClient(),
253
+ )
254
+ try:
255
+ result = asyncio.run(
256
+ service.pull(
257
+ dataset_id=dataset_id,
258
+ version=dataset_version,
259
+ project_id=project_id,
260
+ )
261
+ )
262
+ except (AgentEvalCloudClientError, CloudEvalSetPreviewError, ValueError) as exc:
263
+ raise click.ClickException(str(exc)) from exc
264
+
265
+ target.parent.mkdir(parents=True, exist_ok=True)
266
+ target.write_text(
267
+ yaml.safe_dump(
268
+ result.evalset.model_dump(mode="json", by_alias=True, exclude_none=True),
269
+ allow_unicode=True,
270
+ sort_keys=False,
271
+ ),
272
+ encoding="utf-8",
273
+ )
274
+ _render(
275
+ {
276
+ "outputFile": target.relative_to(workspace).as_posix(),
277
+ "datasetId": result.cloud_dataset.dataset_id,
278
+ "datasetVersion": result.cloud_dataset.version,
279
+ "schemaHash": result.cloud_dataset.schema_hash,
280
+ "contentDigest": result.cloud_dataset.content_digest,
281
+ "rowCount": result.cloud_dataset.row_count,
282
+ },
283
+ output_format,
284
+ )
ksadk/cli/cmd_files.py CHANGED
@@ -607,7 +607,11 @@ def _resolve_workspace_command_context(
607
607
  cwd = Path(".").resolve()
608
608
  state = load_state(cwd)
609
609
  resolved_region = _resolve_workspace_region(region, state)
610
- target_agent = _resolve_workspace_agent_ref(agent_input, cwd)
610
+ # An explicit runtime endpoint is authoritative. Do not leak an unrelated
611
+ # Agent id from the current workspace state into direct-runtime requests.
612
+ target_agent = (
613
+ None if endpoint and not agent_input else _resolve_workspace_agent_ref(agent_input, cwd)
614
+ )
611
615
  resolved_endpoint, resolved_api_key = _resolve_workspace_runtime_access(
612
616
  state=state,
613
617
  target_agent=target_agent,
ksadk/cli/cmd_hermes.py CHANGED
@@ -16,7 +16,6 @@ from ksadk.cli.agent_ref import merge_agent_inputs, resolve_agent_ref
16
16
  from ksadk.cli.cmd_dashboard import _open_dashboard
17
17
  from ksadk.cli.dry_run import dry_run_option, effective_dry_run, run_async_with_dry_run
18
18
  from ksadk.cli.env_options import (
19
- apply_explicit_env_with_shell_priority,
20
19
  env_options,
21
20
  inject_env_to_environ,
22
21
  resolve_runtime_env_overrides,
@@ -53,18 +52,17 @@ from ksadk.cli.ui import (
53
52
  from ksadk.cli.ui import (
54
53
  output_option as cli_output_option,
55
54
  )
56
- from ksadk.configs.env_registry import is_sensitive_env_var
57
55
  from ksadk.deployment.agent_access import (
58
56
  get_latest_agent_access,
59
57
  is_agent_not_found_error,
60
58
  normalize_deployment_status,
61
59
  )
62
60
  from ksadk.deployment.state import clear_state, load_state, save_state
61
+ from ksadk.cli.hermes_env import _build_hermes_env_vars
63
62
  from ksadk.hermes_terminal import (
64
63
  run_hermes_terminal_session,
65
64
  validate_hermes_pairing_argv,
66
65
  )
67
- from ksadk.model_policy import build_runtime_model_policy_env
68
66
 
69
67
  DEFAULT_HERMES_IMAGE = "ghcr.io/kingsoftcloud/hermes-agent:v2026.7.7.2-ksadk-v070"
70
68
  DEFAULT_HERMES_CONTEXT_LENGTHS = (("glm-5.1", "200000"),)
@@ -203,22 +201,6 @@ def _env_value(*names: str) -> str:
203
201
  return ""
204
202
 
205
203
 
206
- def _normalize_hermes_ui_locale(raw: Optional[str]) -> str:
207
- """标准化 Hermes UI 语言代码,当前 upstream 只支持 en / zh。"""
208
- text = str(raw or "").strip()
209
- if not text:
210
- return "zh"
211
-
212
- base = text.split(".", 1)[0].replace("_", "-").strip().lower()
213
- if base in {"c", "c-utf-8", "c.utf-8", "posix"}:
214
- return "zh"
215
- if base.startswith("en"):
216
- return "en"
217
- if base.startswith("zh"):
218
- return "zh"
219
- return "zh"
220
-
221
-
222
204
  async def _fetch_hermes_bootstrap_config(region: str) -> dict[str, Any] | None:
223
205
  """从服务端获取 Hermes 客户端启动配置。失败时返回 None。"""
224
206
  from ksadk.version import VERSION as CLI_VERSION
@@ -252,108 +234,6 @@ def _extract_hermes_bootstrap_image(bootstrap_cfg: dict[str, Any] | None) -> str
252
234
  return str(value or "").strip()
253
235
 
254
236
 
255
- def _default_context_length_for_model(model: str | None) -> str:
256
- normalized = str(model or "").strip().lower()
257
- if not normalized:
258
- return ""
259
- for model_fragment, context_length in DEFAULT_HERMES_CONTEXT_LENGTHS:
260
- if model_fragment in normalized:
261
- return context_length
262
- return ""
263
-
264
-
265
- def _build_hermes_env_vars(
266
- *,
267
- model_base_url: str | None = None,
268
- model_api_key: str | None = None,
269
- default_model: str | None = None,
270
- model_metadata: dict[str, Any] | None = None,
271
- cli_env: dict[str, str] | None = None,
272
- auto_dotenv: dict[str, str] | None = None,
273
- shell_keys: set[str] | None = None,
274
- ) -> list[dict[str, Any]]:
275
- raw_model_base_url = model_base_url or _env_value("OPENAI_BASE_URL")
276
- resolved_model_base_url = (
277
- _normalize_hermes_runtime_base_url(raw_model_base_url)
278
- if raw_model_base_url
279
- else DEFAULT_HERMES_RUNTIME_BASE_URL
280
- )
281
- resolved_default_model = (
282
- default_model or _env_value("OPENAI_MODEL_NAME") or DEFAULT_HERMES_MODEL_NAME
283
- )
284
- metadata_context_length = ""
285
- if isinstance(model_metadata, dict):
286
- metadata_context_length = str(model_metadata.get("context_window_tokens") or "").strip()
287
- context_length = (
288
- _env_value("HERMES_CONTEXT_LENGTH", "OPENAI_CONTEXT_LENGTH", "MODEL_CONTEXT_LENGTH")
289
- or metadata_context_length
290
- or _default_context_length_for_model(resolved_default_model)
291
- )
292
- ui_locale = _normalize_hermes_ui_locale(_env_value("HERMES_UI_LOCALE", "LANG", "LC_ALL"))
293
- raw = {
294
- "OPENAI_API_KEY": model_api_key or _env_value("OPENAI_API_KEY"),
295
- "OPENAI_BASE_URL": resolved_model_base_url,
296
- "OPENAI_MODEL_NAME": resolved_default_model,
297
- "API_SERVER_ENABLED": "true",
298
- "API_SERVER_HOST": "127.0.0.1",
299
- "API_SERVER_PORT": "8642",
300
- "HERMES_DASHBOARD_HOST": "127.0.0.1",
301
- "HERMES_DASHBOARD_PORT": "9119",
302
- "KSADK_RUNTIME_PORT": _env_value("PORT") or "8080",
303
- "HERMES_UI_LOCALE": ui_locale,
304
- }
305
- if context_length:
306
- raw["HERMES_CONTEXT_LENGTH"] = context_length
307
- fallback_model = _env_value("HERMES_FALLBACK_MODEL", "OPENAI_FALLBACK_MODEL_NAME")
308
- if fallback_model:
309
- raw["HERMES_FALLBACK_PROVIDER"] = _env_value("HERMES_FALLBACK_PROVIDER") or "custom"
310
- raw["HERMES_FALLBACK_MODEL"] = fallback_model
311
- raw["HERMES_FALLBACK_BASE_URL"] = (
312
- _env_value("HERMES_FALLBACK_BASE_URL") or resolved_model_base_url
313
- )
314
- api_server_key = _env_value("API_SERVER_KEY", "HERMES_API_SERVER_KEY")
315
- if api_server_key:
316
- raw["API_SERVER_KEY"] = api_server_key
317
- # Observability routes and credentials are platform-managed. The Hermes
318
- # deploy CLI must not translate or forward legacy Langfuse SDK variables;
319
- # server/runtime inject the standard OTLP primary and CloudMonitor secondary.
320
- for key in (
321
- "WPSXIEZUO_APP_ID",
322
- "WPSXIEZUO_APP_KEY",
323
- "WPSXIEZUO_API_BASE",
324
- "WPSXIEZUO_WS_ENDPOINT",
325
- "WPSXIEZUO_GROUP_AT_ONLY",
326
- "WPSXIEZUO_ALLOWED_USERS",
327
- "WPSXIEZUO_ALLOW_ALL_USERS",
328
- "WPSXIEZUO_HOME_CHANNEL",
329
- ):
330
- value = _env_value(key)
331
- if value:
332
- raw[key] = value
333
- raw = build_runtime_model_policy_env(raw, runtime="hermes")
334
- if raw.get("HERMES_FALLBACK_MODEL"):
335
- raw.setdefault(
336
- "HERMES_FALLBACK_PROVIDER", _env_value("HERMES_FALLBACK_PROVIDER") or "custom"
337
- )
338
- raw.setdefault(
339
- "HERMES_FALLBACK_BASE_URL",
340
- _env_value("HERMES_FALLBACK_BASE_URL") or resolved_model_base_url,
341
- )
342
- if cli_env or auto_dotenv:
343
- apply_explicit_env_with_shell_priority(
344
- raw, cli_env or {}, auto_dotenv or {}, shell_keys or set(os.environ)
345
- )
346
- return [
347
- {
348
- "Key": key,
349
- "Value": str(value),
350
- "IsSensitive": is_sensitive_env_var(key),
351
- }
352
- for key, value in raw.items()
353
- if value is not None and str(value).strip() != ""
354
- ]
355
-
356
-
357
237
  def _validate_hermes_model_config(
358
238
  *,
359
239
  model_base_url: str | None = None,
@@ -371,11 +251,6 @@ def _validate_hermes_model_config(
371
251
  print_info("未配置 OPENAI_API_KEY,将由服务端在需要时自动创建。")
372
252
 
373
253
 
374
- def _normalize_hermes_runtime_base_url(base_url: str | None) -> str:
375
- normalized = str(base_url or "").strip()
376
- return normalized
377
-
378
-
379
254
  _FAILURE_STATUSES = {"FAILED", "ERROR", "TERMINATED"}
380
255
 
381
256