agentengine-sdk-python 0.8.0__py3-none-any.whl → 0.8.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +43 -7
  2. agentengine_sdk_python-0.8.2.dist-info/RECORD +778 -0
  3. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +1 -1
  4. ksadk/a2a/__init__.py +2 -0
  5. ksadk/a2a/_space_client_events.py +381 -0
  6. ksadk/a2a/bootstrap.py +0 -2
  7. ksadk/a2a/card.py +6 -111
  8. ksadk/a2a/control_plane.py +239 -1
  9. ksadk/a2a/event_adapter.py +156 -64
  10. ksadk/a2a/executor.py +195 -172
  11. ksadk/a2a/routes.py +12 -5
  12. ksadk/a2a/server.py +1 -8
  13. ksadk/a2a/service_env.py +33 -0
  14. ksadk/a2a/space_client.py +43 -349
  15. ksadk/a2a_card.py +101 -0
  16. ksadk/a2ui/core.py +222 -53
  17. ksadk/agui/_agent_helpers.py +243 -0
  18. ksadk/agui/a2ui_projection.py +12 -5
  19. ksadk/agui/agent.py +474 -275
  20. ksadk/agui/config.py +11 -5
  21. ksadk/agui/routes.py +7 -15
  22. ksadk/api/client.py +530 -40
  23. ksadk/api/environment.py +27 -0
  24. ksadk/builders/code_builder.py +352 -53
  25. ksadk/builders/container_builder.py +71 -44
  26. ksadk/builders/framework_requirements.py +2 -1
  27. ksadk/builders/ks3_uploader.py +2 -2
  28. ksadk/builders/managed_runtime_builder.py +60 -28
  29. ksadk/cli/__init__.py +25 -0
  30. ksadk/cli/cmd_a2a.py +18 -31
  31. ksadk/cli/cmd_create.py +13 -26
  32. ksadk/cli/cmd_dashboard.py +15 -1
  33. ksadk/cli/cmd_deploy.py +28 -3
  34. ksadk/cli/cmd_eval.py +443 -0
  35. ksadk/cli/cmd_evalset.py +284 -0
  36. ksadk/cli/cmd_files.py +5 -1
  37. ksadk/cli/cmd_hermes.py +137 -163
  38. ksadk/cli/cmd_invoke.py +28 -38
  39. ksadk/cli/cmd_launch.py +12 -0
  40. ksadk/cli/cmd_managed_runtime.py +95 -0
  41. ksadk/cli/cmd_observe.py +85 -0
  42. ksadk/cli/cmd_openclaw.py +85 -479
  43. ksadk/cli/cmd_replay.py +28 -4
  44. ksadk/cli/cmd_run.py +29 -67
  45. ksadk/cli/cmd_studio.py +201 -0
  46. ksadk/cli/cmd_web.py +15 -6
  47. ksadk/cli/dry_run.py +2 -1
  48. ksadk/cli/env_options.py +83 -0
  49. ksadk/cli/global_options.py +3 -1
  50. ksadk/cli/hermes_env.py +151 -0
  51. ksadk/cli/invoke_payload.py +49 -0
  52. ksadk/cli/network_options.py +7 -5
  53. ksadk/cli/openclaw_env.py +458 -0
  54. ksadk/cli/runtime_bootstrap.py +51 -0
  55. ksadk/cli/ui.py +6 -0
  56. ksadk/cli/workflow_common.py +5 -5
  57. ksadk/codex/__init__.py +3 -3
  58. ksadk/codex/client.py +833 -49
  59. ksadk/codex/phase.py +1 -1
  60. ksadk/codex/runtime.py +720 -127
  61. ksadk/common/kop_client.py +232 -0
  62. ksadk/configs/__init__.py +1 -3
  63. ksadk/configs/env_registry.py +244 -45
  64. ksadk/configs/env_registry_pcm.py +181 -0
  65. ksadk/configs/env_var_spec.py +18 -0
  66. ksadk/configs/global_config.py +6 -1
  67. ksadk/configs/settings.py +5 -108
  68. ksadk/context_engine/__init__.py +98 -0
  69. ksadk/context_engine/assembler.py +176 -0
  70. ksadk/context_engine/baseline.py +419 -0
  71. ksadk/context_engine/cache_observability.py +228 -0
  72. ksadk/context_engine/capabilities.py +443 -0
  73. ksadk/context_engine/contributors.py +344 -0
  74. ksadk/context_engine/hosted_pipeline.py +417 -0
  75. ksadk/context_engine/models.py +117 -0
  76. ksadk/context_engine/planner.py +698 -0
  77. ksadk/context_engine/policies.py +319 -0
  78. ksadk/context_engine/projection.py +31 -0
  79. ksadk/context_engine/shadow_plan.py +266 -0
  80. ksadk/context_engine/tokenizer.py +164 -0
  81. ksadk/conversations/__init__.py +85 -94
  82. ksadk/conversations/context.py +126 -6
  83. ksadk/conversations/message_projection.py +292 -28
  84. ksadk/conversations/model_context.py +49 -3
  85. ksadk/conversations/runtime_compaction.py +207 -5
  86. ksadk/conversations/runtime_input.py +193 -3
  87. ksadk/conversations/runtime_invocation.py +81 -3
  88. ksadk/conversations/runtime_observability.py +157 -4
  89. ksadk/conversations/runtime_payloads.py +42 -0
  90. ksadk/conversations/runtime_preparation.py +280 -2
  91. ksadk/conversations/runtime_resume.py +71 -32
  92. ksadk/conversations/runtime_stream_events.py +94 -9
  93. ksadk/conversations/runtime_streaming.py +175 -22
  94. ksadk/conversations/semantic_summary.py +311 -1
  95. ksadk/conversations/session_lock.py +51 -0
  96. ksadk/deployment/env_forward.py +72 -0
  97. ksadk/deployment/managed_runtime.py +38 -0
  98. ksadk/deployment/manager.py +24 -8
  99. ksadk/deployment/providers/serverless.py +228 -92
  100. ksadk/evaluation/__init__.py +116 -0
  101. ksadk/evaluation/a2a_adapter.py +452 -0
  102. ksadk/evaluation/adapters.py +67 -0
  103. ksadk/evaluation/agent_eval_client.py +395 -0
  104. ksadk/evaluation/cloud_binding.py +80 -0
  105. ksadk/evaluation/cloud_converter.py +194 -0
  106. ksadk/evaluation/cloud_service.py +199 -0
  107. ksadk/evaluation/contracts.py +478 -0
  108. ksadk/evaluation/evalset.py +351 -0
  109. ksadk/evaluation/evaluators.py +627 -0
  110. ksadk/evaluation/evidence.py +258 -0
  111. ksadk/evaluation/executor.py +143 -0
  112. ksadk/evaluation/local_adapter.py +550 -0
  113. ksadk/evaluation/service_env.py +27 -0
  114. ksadk/evaluation/storage.py +68 -0
  115. ksadk/evaluation/studio_build_adapter.py +253 -0
  116. ksadk/evaluation/target.py +82 -0
  117. ksadk/events/__init__.py +13 -13
  118. ksadk/events/_v1_compat/__init__.py +1 -0
  119. ksadk/events/_v1_compat/models.py +299 -0
  120. ksadk/events/_v1_compat/parser.py +247 -0
  121. ksadk/events/_v1_compat/projection.py +753 -0
  122. ksadk/events/adapters/__init__.py +34 -0
  123. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  124. ksadk/events/adapters/_a2a_support.py +275 -0
  125. ksadk/events/adapters/_codex_interactions.py +375 -0
  126. ksadk/events/adapters/_codex_items.py +801 -0
  127. ksadk/events/adapters/_codex_validators.py +311 -0
  128. ksadk/events/adapters/_langgraph_support.py +785 -0
  129. ksadk/events/adapters/a2a.py +841 -0
  130. ksadk/events/adapters/adk.py +503 -0
  131. ksadk/events/adapters/codex.py +717 -0
  132. ksadk/events/adapters/langgraph.py +745 -0
  133. ksadk/events/canonical.py +440 -0
  134. ksadk/events/canonical_replay.py +497 -0
  135. ksadk/events/canonical_store.py +468 -0
  136. ksadk/events/cold_recovery.py +257 -0
  137. ksadk/events/content.py +89 -0
  138. ksadk/events/identity.py +86 -0
  139. ksadk/events/pipeline.py +455 -0
  140. ksadk/events/projections.py +66 -0
  141. ksadk/events/reducer.py +661 -0
  142. ksadk/events/replay.py +3 -36
  143. ksadk/events/runtime_event.py +20 -256
  144. ksadk/events/session_event.py +324 -0
  145. ksadk/events/store.py +3 -316
  146. ksadk/events/v1_compat.py +41 -0
  147. ksadk/harness/__init__.py +3 -2
  148. ksadk/harness/app.py +114 -123
  149. ksadk/harness/config.py +1 -1
  150. ksadk/harness/runtime.py +467 -0
  151. ksadk/hermes_terminal.py +5 -0
  152. ksadk/identity/resolver.py +4 -3
  153. ksadk/interaction/__init__.py +28 -0
  154. ksadk/interaction/contracts.py +136 -0
  155. ksadk/interaction/ledger.py +189 -0
  156. ksadk/interaction/provider.py +122 -0
  157. ksadk/interaction/providers/__init__.py +52 -0
  158. ksadk/interaction/providers/adk.py +40 -0
  159. ksadk/interaction/providers/codex.py +94 -0
  160. ksadk/interaction/providers/langgraph.py +58 -0
  161. ksadk/kernel/__init__.py +117 -0
  162. ksadk/kernel/authorization.py +258 -0
  163. ksadk/kernel/bootstrap.py +1074 -0
  164. ksadk/kernel/contract_fingerprints.py +61 -0
  165. ksadk/kernel/contracts.py +362 -0
  166. ksadk/kernel/control.py +219 -0
  167. ksadk/kernel/errors.py +79 -0
  168. ksadk/kernel/ingress.py +1102 -0
  169. ksadk/kernel/mapping.py +111 -0
  170. ksadk/kernel/memory_store.py +1133 -0
  171. ksadk/kernel/postgres_store.py +1756 -0
  172. ksadk/kernel/recovery.py +452 -0
  173. ksadk/kernel/runtime_identity.py +103 -0
  174. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  175. ksadk/kernel/sqlite_store.py +1410 -0
  176. ksadk/kernel/state.py +145 -0
  177. ksadk/kernel/store.py +232 -0
  178. ksadk/kernel/worker.py +953 -0
  179. ksadk/knowledge_base/client.py +22 -4
  180. ksadk/knowledge_base/service.py +32 -5
  181. ksadk/managed_a2a_card.py +160 -0
  182. ksadk/managed_runtime.py +16 -9
  183. ksadk/memory/__init__.py +61 -0
  184. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  185. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  186. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  187. ksadk/memory/adk/backends/sdk_ltm_backend.py +394 -5
  188. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  189. ksadk/memory/adk/long_term_memory.py +3 -2
  190. ksadk/memory/coordinator.py +461 -0
  191. ksadk/memory/events.py +202 -0
  192. ksadk/memory/extraction.py +228 -0
  193. ksadk/memory/ltm_backend_factory.py +16 -3
  194. ksadk/memory/models.py +316 -0
  195. ksadk/memory/policy.py +215 -0
  196. ksadk/memory/provider.py +47 -0
  197. ksadk/memory/provider_adapter.py +159 -0
  198. ksadk/memory/provider_resolver.py +71 -0
  199. ksadk/memory/providers/__init__.py +5 -0
  200. ksadk/memory/providers/local_sqlite.py +490 -0
  201. ksadk/memory/resolved_policy.py +145 -0
  202. ksadk/memory/service.py +198 -8
  203. ksadk/memory/tool.py +4 -0
  204. ksadk/model_proxy/bootstrap.py +16 -9
  205. ksadk/model_proxy/config.py +22 -1
  206. ksadk/model_proxy/detect.py +202 -9
  207. ksadk/model_proxy/namespace.py +67 -15
  208. ksadk/model_proxy/server.py +168 -6
  209. ksadk/model_proxy/transform.py +105 -3
  210. ksadk/observability/__init__.py +25 -0
  211. ksadk/observability/session_log.py +420 -0
  212. ksadk/observability/trajectory.py +105 -0
  213. ksadk/prompts/__init__.py +71 -0
  214. ksadk/prompts/compiler.py +215 -0
  215. ksadk/prompts/models.py +82 -0
  216. ksadk/prompts/projection.py +89 -0
  217. ksadk/prompts/resolved.py +137 -0
  218. ksadk/prompts/sources.py +233 -0
  219. ksadk/runners/_langgraph_runner_streams.py +822 -0
  220. ksadk/runners/adk_runner.py +14 -31
  221. ksadk/runners/base_runner.py +44 -3
  222. ksadk/runners/factory.py +3 -3
  223. ksadk/runners/langgraph_runner.py +252 -433
  224. ksadk/runners/utils/__init__.py +0 -10
  225. ksadk/runners/utils/loader.py +16 -0
  226. ksadk/runtime/__init__.py +67 -41
  227. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  228. ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
  229. ksadk/runtime/adapter.py +199 -16
  230. ksadk/runtime/conversation_execution.py +687 -0
  231. ksadk/runtime/executor.py +392 -0
  232. ksadk/runtime/factory.py +342 -0
  233. ksadk/runtime/framework_adapters.py +6 -12
  234. ksadk/runtime/hosted_finalizer.py +268 -0
  235. ksadk/runtime/launch.py +61 -0
  236. ksadk/runtime/preprocessing.py +49 -14
  237. ksadk/runtime/runner_adapter.py +330 -391
  238. ksadk/runtime/runner_loading.py +36 -0
  239. ksadk/runtime/usage.py +33 -0
  240. ksadk/sandbox/backends/e2b.py +36 -3
  241. ksadk/server/__init__.py +39 -4
  242. ksadk/server/app.py +18 -492
  243. ksadk/server/composition.py +36 -2
  244. ksadk/server/factory.py +210 -149
  245. ksadk/server/routes/common.py +15 -46
  246. ksadk/server/routes/control.py +13 -9
  247. ksadk/server/routes/kernel_ingress.py +258 -0
  248. ksadk/server/routes/misc.py +10 -33
  249. ksadk/server/routes/models.py +14 -6
  250. ksadk/server/routes/openai_compat.py +129 -27
  251. ksadk/server/routes/projection.py +84 -16
  252. ksadk/server/routes/run.py +347 -460
  253. ksadk/server/routes/sessions.py +37 -40
  254. ksadk/server/routes/streaming.py +52 -7
  255. ksadk/server/routes/workspace.py +54 -21
  256. ksadk/server/static/assets/{ArtifactsPanel-Cjnqt-8W.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
  257. ksadk/server/static/assets/{CodeBlock-BqyqZfuB.js → CodeBlock-DOH6MVcn.js} +4 -4
  258. ksadk/server/static/assets/{MathMessageMarkdown-BpH7jiFM.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
  259. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  260. ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
  261. ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
  262. ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
  263. ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
  264. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
  265. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
  266. ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
  267. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
  268. ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
  269. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
  270. ksadk/server/static/assets/{chunk-FMBD7UC4-BGhvzDYt.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
  271. ksadk/server/static/assets/{chunk-ND2GUHAM-D98vPd-E.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
  272. ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
  273. ksadk/server/static/assets/{chunk-4BX2VUAB-CsWIQRhc.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
  274. ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
  275. ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
  276. ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
  277. ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
  278. ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
  279. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
  280. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
  281. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-CX3yotHq.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
  282. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
  283. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
  284. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  285. ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
  286. ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
  287. ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
  288. ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
  289. ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
  290. ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
  291. ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
  292. ksadk/server/static/assets/{dist-D82mtD2s.js → dist-8hqcx0sU.js} +1 -1
  293. ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
  294. ksadk/server/static/assets/{dist-DHn6nBzr.js → dist-BE7bu-DL.js} +1 -1
  295. ksadk/server/static/assets/{dist-eoW6tZXA.js → dist-BVDffZ0U.js} +1 -1
  296. ksadk/server/static/assets/{dist-C2xjE7cO.js → dist-BX8z72IC.js} +1 -1
  297. ksadk/server/static/assets/{dist-CgF3fj15.js → dist-Bf2M8m3N.js} +1 -1
  298. ksadk/server/static/assets/{dist-Bs-jQcRX.js → dist-BjU6y-A2.js} +1 -1
  299. ksadk/server/static/assets/{dist-Djgl2wVZ.js → dist-BytlxIDT.js} +1 -1
  300. ksadk/server/static/assets/{dist-CVQRZjPu.js → dist-CSh_DE14.js} +1 -1
  301. ksadk/server/static/assets/{dist-6CVKuTAe.js → dist-CXYYBw3_.js} +1 -1
  302. ksadk/server/static/assets/{dist-DlzCRy0S.js → dist-C_wsv-Qd.js} +1 -1
  303. ksadk/server/static/assets/{dist-DF06ORQo.js → dist-ClxGviKw.js} +1 -1
  304. ksadk/server/static/assets/{dist-Cf23NY4L.js → dist-CttYUqzS.js} +1 -1
  305. ksadk/server/static/assets/{dist-ivOya1LD.js → dist-DNp6rLRA.js} +1 -1
  306. ksadk/server/static/assets/{dist-BibcG1V9.js → dist-DUX-id_F.js} +1 -1
  307. ksadk/server/static/assets/{dist-BUHRxvDG.js → dist-DmldrHd_.js} +1 -1
  308. ksadk/server/static/assets/{dist-BZ9n9AjO.js → dist-DnfXs8Vn.js} +2 -2
  309. ksadk/server/static/assets/{dist-DqNnNFrw.js → dist-Dq9gLD7L.js} +1 -1
  310. ksadk/server/static/assets/{dist-CGcp2ex8.js → dist-W-TIVntx.js} +1 -1
  311. ksadk/server/static/assets/{dist-Cwt7koer.js → dist-dDdADKFA.js} +1 -1
  312. ksadk/server/static/assets/{dist-C7-3jInC.js → dist-dydu68Fl.js} +1 -1
  313. ksadk/server/static/assets/{dist-C99THtIA.js → dist-ngtN0DJB.js} +1 -1
  314. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
  315. ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
  316. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
  317. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
  318. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
  319. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
  320. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
  321. ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
  322. ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
  323. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
  324. ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
  325. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-DLOHGvWw.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
  326. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-BIzKeejT.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
  327. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-BWHoFSw2.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
  328. ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
  329. ksadk/server/static/assets/{linear-CvMBw9cA.js → linear-BHjG8b-J.js} +1 -1
  330. ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
  331. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-CSAQxEAe.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
  332. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
  333. ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
  334. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
  335. ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
  336. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-CxIR4JXI.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
  337. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
  338. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
  339. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
  340. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
  341. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
  342. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
  343. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
  344. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-DpGa6EAV.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
  345. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-NTKNGGe5.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
  346. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
  347. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
  348. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
  349. ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
  350. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
  351. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-jqoYs3jQ.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
  352. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
  353. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
  354. ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
  355. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
  356. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
  357. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
  358. ksadk/server/static/index.html +2 -2
  359. ksadk/sessions/__init__.py +26 -9
  360. ksadk/sessions/_local_service_sync.py +688 -0
  361. ksadk/sessions/_local_tables.py +21 -0
  362. ksadk/sessions/_postgres_schema.py +305 -0
  363. ksadk/sessions/_postgres_tables.py +15 -0
  364. ksadk/sessions/base.py +80 -1
  365. ksadk/sessions/in_memory.py +53 -2
  366. ksadk/sessions/local_service.py +63 -604
  367. ksadk/sessions/postgres_service.py +58 -148
  368. ksadk/sessions/resilient.py +35 -1
  369. ksadk/skills/runtime/backends/e2b.py +1 -1
  370. ksadk/skills/service_client.py +13 -3
  371. ksadk/studio/__init__.py +5 -0
  372. ksadk/studio/agent_avatar_assets.py +120 -0
  373. ksadk/studio/agent_lifecycle.py +51 -0
  374. ksadk/studio/api.py +1598 -0
  375. ksadk/studio/api_catalog_routes.py +324 -0
  376. ksadk/studio/api_contracts.py +286 -0
  377. ksadk/studio/api_helpers.py +132 -0
  378. ksadk/studio/api_memory_routes.py +82 -0
  379. ksadk/studio/authoring.py +749 -0
  380. ksadk/studio/authoring_coordinator.py +1017 -0
  381. ksadk/studio/builder.py +397 -0
  382. ksadk/studio/capabilities.py +368 -0
  383. ksadk/studio/cloud.py +2099 -0
  384. ksadk/studio/codex_agent_service.py +694 -0
  385. ksadk/studio/codex_authoring.py +469 -0
  386. ksadk/studio/codex_builder.py +437 -0
  387. ksadk/studio/codex_manifest.py +307 -0
  388. ksadk/studio/codex_run.py +395 -0
  389. ksadk/studio/compiler.py +190 -0
  390. ksadk/studio/contracts.py +755 -0
  391. ksadk/studio/errors.py +47 -0
  392. ksadk/studio/event_store.py +214 -0
  393. ksadk/studio/framework_run.py +342 -0
  394. ksadk/studio/hosted_kernel.py +317 -0
  395. ksadk/studio/identifiers.py +33 -0
  396. ksadk/studio/manifest_resolver.py +131 -0
  397. ksadk/studio/mcp_runtime.py +229 -0
  398. ksadk/studio/model_client.py +629 -0
  399. ksadk/studio/model_profile_service.py +214 -0
  400. ksadk/studio/operations.py +275 -0
  401. ksadk/studio/otel_trace.py +1060 -0
  402. ksadk/studio/pagination.py +182 -0
  403. ksadk/studio/pcm_memory.py +85 -0
  404. ksadk/studio/python_tool_inspection.py +183 -0
  405. ksadk/studio/repository.py +327 -0
  406. ksadk/studio/resource_catalog.py +1260 -0
  407. ksadk/studio/run_service.py +1133 -0
  408. ksadk/studio/runtime_catalog.py +74 -0
  409. ksadk/studio/runtime_source.py +365 -0
  410. ksadk/studio/service.py +2249 -0
  411. ksadk/studio/shared_web.py +1004 -0
  412. ksadk/studio/skill_discovery.py +628 -0
  413. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
  414. ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
  415. ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
  416. ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
  417. ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
  418. ksadk/studio/static/index.html +15 -0
  419. ksadk/studio/templates.py +722 -0
  420. ksadk/studio/validator.py +265 -0
  421. ksadk/studio/workspace.py +135 -0
  422. ksadk/tools/gateway.py +9 -0
  423. ksadk/toolsets/__init__.py +27 -1
  424. ksadk/toolsets/a2a.py +426 -0
  425. ksadk/tracing/__init__.py +19 -21
  426. ksadk/tracing/setup.py +317 -403
  427. ksadk/tracing/span_utils.py +0 -44
  428. ksadk/version.py +1 -1
  429. ksadk_runtime_common/memory_backend/registry.py +56 -56
  430. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  431. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  432. ksadk_runtime_common/workspace_files/router.py +8 -2
  433. agentengine_sdk_python-0.8.0.dist-info/RECORD +0 -578
  434. ksadk/a2a/card_builder.py +0 -64
  435. ksadk/a2a/client.py +0 -309
  436. ksadk/events/parser.py +0 -191
  437. ksadk/harness/runner.py +0 -211
  438. ksadk/runners/codex_runner.py +0 -132
  439. ksadk/runners/utils/langfuse.py +0 -230
  440. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  441. ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +0 -303
  442. ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +0 -1
  443. ksadk/server/static/assets/arc-CFKwSk_B.js +0 -1
  444. ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +0 -1
  445. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-Dej8jX8c.js +0 -36
  446. ksadk/server/static/assets/blockDiagram-GPEHLZMM-1F64jqvy.js +0 -132
  447. ksadk/server/static/assets/c4Diagram-AAUBKEIU-9q7AUAKb.js +0 -10
  448. ksadk/server/static/assets/channel-iUGv2N24.js +0 -1
  449. ksadk/server/static/assets/chunk-2J33WTMH-6qgwJm7Q.js +0 -1
  450. ksadk/server/static/assets/chunk-55IACEB6-BK8paA20.js +0 -1
  451. ksadk/server/static/assets/chunk-727SXJPM-B-JEhy7h.js +0 -206
  452. ksadk/server/static/assets/chunk-AQP2D5EJ-DYBvMHAa.js +0 -231
  453. ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +0 -1
  454. ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +0 -1
  455. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +0 -1
  456. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  457. ksadk/server/static/assets/dagre-BM42HDAG-C7TguAWo.js +0 -4
  458. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  459. ksadk/server/static/assets/diagram-2AECGRRQ-Dd17_kws.js +0 -43
  460. ksadk/server/static/assets/diagram-5GNKFQAL-DVIClIil.js +0 -10
  461. ksadk/server/static/assets/diagram-KO2AKTUF-Df_3gYQa.js +0 -3
  462. ksadk/server/static/assets/diagram-LMA3HP47-BhLk6ZtA.js +0 -24
  463. ksadk/server/static/assets/diagram-OG6HWLK6-D4GNGvuu.js +0 -24
  464. ksadk/server/static/assets/dist-DyvYLMW9.js +0 -1
  465. ksadk/server/static/assets/erDiagram-TEJ5UH35-CnfRcY2M.js +0 -85
  466. ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +0 -1
  467. ksadk/server/static/assets/flowDiagram-I6XJVG4X-DGaJjGNJ.js +0 -162
  468. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-DpCoB2g9.js +0 -292
  469. ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +0 -1
  470. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-9IKVFBVT.js +0 -106
  471. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  472. ksadk/server/static/assets/index-QSwCHuB8.js +0 -177
  473. ksadk/server/static/assets/index-jOPmTOZH.css +0 -2
  474. ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +0 -1
  475. ksadk/server/static/assets/infoDiagram-5YYISTIA-CYIIsb8y.js +0 -2
  476. ksadk/server/static/assets/katex-DATssjp1.js +0 -265
  477. ksadk/server/static/assets/mermaid-parser.core-mGAcEwcq.js +0 -161
  478. ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +0 -1
  479. ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +0 -1
  480. ksadk/server/static/assets/pieDiagram-4H26LBE5-By-ra07M.js +0 -30
  481. ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +0 -1
  482. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DpW90iu3.js +0 -84
  483. ksadk/server/static/assets/stateDiagram-AJRCARHV-DGpd9yFG.js +0 -1
  484. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +0 -1
  485. ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +0 -1
  486. ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +0 -1
  487. ksadk/server/static/assets/vennDiagram-CIIHVFJN-l3Z7-wbP.js +0 -34
  488. ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +0 -1
  489. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-BR54GPmr.js +0 -78
  490. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-SkiH8GsK.js +0 -7
  491. ksadk/tracing/exporters/langfuse_exporter.py +0 -460
  492. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
  493. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
  494. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
ksadk/cli/cmd_hermes.py CHANGED
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  import os
7
+ from datetime import datetime, timezone
7
8
  from pathlib import Path
8
9
  from typing import Any, Callable, Optional, cast
9
10
 
@@ -14,6 +15,11 @@ from ksadk.api import AgentEngineClient
14
15
  from ksadk.cli.agent_ref import merge_agent_inputs, resolve_agent_ref
15
16
  from ksadk.cli.cmd_dashboard import _open_dashboard
16
17
  from ksadk.cli.dry_run import dry_run_option, effective_dry_run, run_async_with_dry_run
18
+ from ksadk.cli.env_options import (
19
+ env_options,
20
+ inject_env_to_environ,
21
+ resolve_runtime_env_overrides,
22
+ )
17
23
  from ksadk.cli.error_utils import remote_error, resolution_error
18
24
  from ksadk.cli.model_catalog import fetch_provider_model_metadata
19
25
  from ksadk.cli.network_options import build_network_payload, network_cli_kwargs, network_options
@@ -52,12 +58,11 @@ from ksadk.deployment.agent_access import (
52
58
  normalize_deployment_status,
53
59
  )
54
60
  from ksadk.deployment.state import clear_state, load_state, save_state
61
+ from ksadk.cli.hermes_env import _build_hermes_env_vars
55
62
  from ksadk.hermes_terminal import (
56
63
  run_hermes_terminal_session,
57
- validate_hermes_exec_argv,
58
64
  validate_hermes_pairing_argv,
59
65
  )
60
- from ksadk.model_policy import build_runtime_model_policy_env
61
66
 
62
67
  DEFAULT_HERMES_IMAGE = "ghcr.io/kingsoftcloud/hermes-agent:v2026.7.7.2-ksadk-v070"
63
68
  DEFAULT_HERMES_CONTEXT_LENGTHS = (("glm-5.1", "200000"),)
@@ -150,6 +155,7 @@ def _build_hermes_update_payload(
150
155
  "resources": payload["resources"],
151
156
  "scaling": payload["scaling"],
152
157
  "ui_config": payload["ui_config"],
158
+ "enable_observability": payload["enable_observability"],
153
159
  }
154
160
  if include_env:
155
161
  update_payload["env_vars"] = payload["env_vars"]
@@ -165,19 +171,6 @@ def hermes():
165
171
  """Hermes Agent 资源管理。"""
166
172
 
167
173
 
168
- def _load_dotenv_into_env(project_dir: Path) -> None:
169
- env_path = project_dir / ".env"
170
- if not env_path.exists():
171
- return
172
- try:
173
- from dotenv import dotenv_values
174
- except ImportError:
175
- return
176
- for key, value in dotenv_values(env_path).items():
177
- if key and value is not None and os.getenv(key) is None:
178
- os.environ[key] = str(value)
179
-
180
-
181
174
  def _get_hermes_global_env() -> dict[str, str]:
182
175
  global _HERMES_GLOBAL_ENV_CACHE
183
176
  if _HERMES_GLOBAL_ENV_CACHE is not None:
@@ -208,22 +201,6 @@ def _env_value(*names: str) -> str:
208
201
  return ""
209
202
 
210
203
 
211
- def _normalize_hermes_ui_locale(raw: Optional[str]) -> str:
212
- """标准化 Hermes UI 语言代码,当前 upstream 只支持 en / zh。"""
213
- text = str(raw or "").strip()
214
- if not text:
215
- return "zh"
216
-
217
- base = text.split(".", 1)[0].replace("_", "-").strip().lower()
218
- if base in {"c", "c-utf-8", "c.utf-8", "posix"}:
219
- return "zh"
220
- if base.startswith("en"):
221
- return "en"
222
- if base.startswith("zh"):
223
- return "zh"
224
- return "zh"
225
-
226
-
227
204
  async def _fetch_hermes_bootstrap_config(region: str) -> dict[str, Any] | None:
228
205
  """从服务端获取 Hermes 客户端启动配置。失败时返回 None。"""
229
206
  from ksadk.version import VERSION as CLI_VERSION
@@ -257,118 +234,6 @@ def _extract_hermes_bootstrap_image(bootstrap_cfg: dict[str, Any] | None) -> str
257
234
  return str(value or "").strip()
258
235
 
259
236
 
260
- def _default_context_length_for_model(model: str | None) -> str:
261
- normalized = str(model or "").strip().lower()
262
- if not normalized:
263
- return ""
264
- for model_fragment, context_length in DEFAULT_HERMES_CONTEXT_LENGTHS:
265
- if model_fragment in normalized:
266
- return context_length
267
- return ""
268
-
269
-
270
- def _build_hermes_env_vars(
271
- *,
272
- model_base_url: str | None = None,
273
- model_api_key: str | None = None,
274
- default_model: str | None = None,
275
- model_metadata: dict[str, Any] | None = None,
276
- ) -> list[dict[str, Any]]:
277
- raw_model_base_url = model_base_url or _env_value("OPENAI_BASE_URL")
278
- resolved_model_base_url = (
279
- _normalize_hermes_runtime_base_url(raw_model_base_url)
280
- if raw_model_base_url
281
- else DEFAULT_HERMES_RUNTIME_BASE_URL
282
- )
283
- resolved_default_model = (
284
- default_model or _env_value("OPENAI_MODEL_NAME") or DEFAULT_HERMES_MODEL_NAME
285
- )
286
- metadata_context_length = ""
287
- if isinstance(model_metadata, dict):
288
- metadata_context_length = str(model_metadata.get("context_window_tokens") or "").strip()
289
- context_length = (
290
- _env_value("HERMES_CONTEXT_LENGTH", "OPENAI_CONTEXT_LENGTH", "MODEL_CONTEXT_LENGTH")
291
- or metadata_context_length
292
- or _default_context_length_for_model(resolved_default_model)
293
- )
294
- ui_locale = _normalize_hermes_ui_locale(_env_value("HERMES_UI_LOCALE", "LANG", "LC_ALL"))
295
- raw = {
296
- "OPENAI_API_KEY": model_api_key or _env_value("OPENAI_API_KEY"),
297
- "OPENAI_BASE_URL": resolved_model_base_url,
298
- "OPENAI_MODEL_NAME": resolved_default_model,
299
- "API_SERVER_ENABLED": "true",
300
- "API_SERVER_HOST": "127.0.0.1",
301
- "API_SERVER_PORT": "8642",
302
- "HERMES_DASHBOARD_HOST": "127.0.0.1",
303
- "HERMES_DASHBOARD_PORT": "9119",
304
- "KSADK_RUNTIME_PORT": _env_value("PORT") or "8080",
305
- "HERMES_UI_LOCALE": ui_locale,
306
- }
307
- if context_length:
308
- raw["HERMES_CONTEXT_LENGTH"] = context_length
309
- fallback_model = _env_value("HERMES_FALLBACK_MODEL", "OPENAI_FALLBACK_MODEL_NAME")
310
- if fallback_model:
311
- raw["HERMES_FALLBACK_PROVIDER"] = _env_value("HERMES_FALLBACK_PROVIDER") or "custom"
312
- raw["HERMES_FALLBACK_MODEL"] = fallback_model
313
- raw["HERMES_FALLBACK_BASE_URL"] = (
314
- _env_value("HERMES_FALLBACK_BASE_URL") or resolved_model_base_url
315
- )
316
- api_server_key = _env_value("API_SERVER_KEY", "HERMES_API_SERVER_KEY")
317
- if api_server_key:
318
- raw["API_SERVER_KEY"] = api_server_key
319
- langfuse_public_key = _env_value("HERMES_LANGFUSE_PUBLIC_KEY", "LANGFUSE_PUBLIC_KEY")
320
- langfuse_secret_key = _env_value("HERMES_LANGFUSE_SECRET_KEY", "LANGFUSE_SECRET_KEY")
321
- if langfuse_public_key and langfuse_secret_key:
322
- raw["HERMES_LANGFUSE_PUBLIC_KEY"] = langfuse_public_key
323
- raw["HERMES_LANGFUSE_SECRET_KEY"] = langfuse_secret_key
324
- langfuse_base_url = _env_value(
325
- "HERMES_LANGFUSE_BASE_URL", "LANGFUSE_BASE_URL", "LANGFUSE_HOST"
326
- )
327
- if langfuse_base_url:
328
- raw["HERMES_LANGFUSE_BASE_URL"] = langfuse_base_url
329
- for target_key, source_keys in {
330
- "HERMES_LANGFUSE_ENV": ("HERMES_LANGFUSE_ENV", "LANGFUSE_ENV"),
331
- "HERMES_LANGFUSE_RELEASE": ("HERMES_LANGFUSE_RELEASE", "LANGFUSE_RELEASE"),
332
- "HERMES_LANGFUSE_SAMPLE_RATE": ("HERMES_LANGFUSE_SAMPLE_RATE",),
333
- "HERMES_LANGFUSE_MAX_CHARS": ("HERMES_LANGFUSE_MAX_CHARS",),
334
- "HERMES_LANGFUSE_DEBUG": ("HERMES_LANGFUSE_DEBUG",),
335
- }.items():
336
- value = _env_value(*source_keys)
337
- if value:
338
- raw[target_key] = value
339
- for key in (
340
- "WPSXIEZUO_APP_ID",
341
- "WPSXIEZUO_APP_KEY",
342
- "WPSXIEZUO_API_BASE",
343
- "WPSXIEZUO_WS_ENDPOINT",
344
- "WPSXIEZUO_GROUP_AT_ONLY",
345
- "WPSXIEZUO_ALLOWED_USERS",
346
- "WPSXIEZUO_ALLOW_ALL_USERS",
347
- "WPSXIEZUO_HOME_CHANNEL",
348
- ):
349
- value = _env_value(key)
350
- if value:
351
- raw[key] = value
352
- raw = build_runtime_model_policy_env(raw, runtime="hermes")
353
- if raw.get("HERMES_FALLBACK_MODEL"):
354
- raw.setdefault(
355
- "HERMES_FALLBACK_PROVIDER", _env_value("HERMES_FALLBACK_PROVIDER") or "custom"
356
- )
357
- raw.setdefault(
358
- "HERMES_FALLBACK_BASE_URL",
359
- _env_value("HERMES_FALLBACK_BASE_URL") or resolved_model_base_url,
360
- )
361
- return [
362
- {
363
- "Key": key,
364
- "Value": str(value),
365
- "IsSensitive": any(token in key for token in ("KEY", "TOKEN", "SECRET")),
366
- }
367
- for key, value in raw.items()
368
- if value is not None and str(value).strip() != ""
369
- ]
370
-
371
-
372
237
  def _validate_hermes_model_config(
373
238
  *,
374
239
  model_base_url: str | None = None,
@@ -386,11 +251,6 @@ def _validate_hermes_model_config(
386
251
  print_info("未配置 OPENAI_API_KEY,将由服务端在需要时自动创建。")
387
252
 
388
253
 
389
- def _normalize_hermes_runtime_base_url(base_url: str | None) -> str:
390
- normalized = str(base_url or "").strip()
391
- return normalized
392
-
393
-
394
254
  _FAILURE_STATUSES = {"FAILED", "ERROR", "TERMINATED"}
395
255
 
396
256
 
@@ -500,6 +360,13 @@ def _split_terminal_agent_ref_and_argv(
500
360
  *,
501
361
  validator: Callable[[tuple[str, ...] | list[str]], list[str]],
502
362
  ) -> tuple[str | None, list[str]]:
363
+ """Split argv into (agent_ref, exec_argv).
364
+
365
+ The first token is treated as agent_ref when the validator rejects the
366
+ full argv (whitelist validators raise ValueError), or when the validator
367
+ is the passthrough one and the first token looks like an agent id
368
+ (``ar-`` prefix) with remaining tokens.
369
+ """
503
370
  raw = [str(item) for item in argv]
504
371
  try:
505
372
  return None, validator(raw)
@@ -512,6 +379,19 @@ def _split_terminal_agent_ref_and_argv(
512
379
  raise direct_error
513
380
 
514
381
 
382
+ def _passthrough_exec_argv(argv: tuple[str, ...] | list[str]) -> list[str]:
383
+ """Local exec passes argv through unchanged; the pod enforces allowlists.
384
+
385
+ Raises ValueError when the first token looks like an agent id (``ar-``
386
+ prefix) and there are remaining tokens, so ``_split_terminal_agent_ref_and_argv``
387
+ falls back to splitting the first token as agent_ref.
388
+ """
389
+ items = [str(item) for item in argv]
390
+ if len(items) >= 2 and items[0].startswith("ar-"):
391
+ raise ValueError("first token looks like an agent ref")
392
+ return items
393
+
394
+
515
395
  def _render_hermes_dry_run(
516
396
  action: str, request: dict[str, Any], hints: tuple[str, ...] = ()
517
397
  ) -> None:
@@ -548,6 +428,21 @@ def _render_hermes_dry_run(
548
428
  @click.option("--storage-size-gi", type=int, default=20, show_default=True, help="PVC 容量(Gi)")
549
429
  @click.option("--storage-mount-path", default=None, help="PVC 挂载目录(默认: /home/node/.hermes)")
550
430
  @click.option("--no-storage", is_flag=True, help="禁用默认 PVC 挂载")
431
+ @env_options
432
+ @click.option(
433
+ "--observability/--no-observability",
434
+ default=True,
435
+ help="是否启用可观测性 (默认开启)",
436
+ )
437
+ @click.option(
438
+ "--agent-id",
439
+ "agent_id_opt",
440
+ default=None,
441
+ help=(
442
+ "指定要更新的已有 Agent ID;当前凭证有权限时会自动回填 "
443
+ ".agentengine.state 并走热更新(用于本地状态丢失后重新关联)"
444
+ ),
445
+ )
551
446
  @network_options
552
447
  @dry_run_option()
553
448
  @cli_output_option()
@@ -563,6 +458,10 @@ def deploy(
563
458
  storage_size_gi: int,
564
459
  storage_mount_path: Optional[str],
565
460
  no_storage: bool,
461
+ extra_env: tuple[str, ...],
462
+ env_file: Optional[str],
463
+ observability: bool,
464
+ agent_id_opt: Optional[str],
566
465
  enable_public_access: Optional[bool],
567
466
  enable_vpc_access: bool,
568
467
  vpc_id: Optional[str],
@@ -578,6 +477,8 @@ def deploy(
578
477
  ctx = click.get_current_context(silent=True)
579
478
  include_env_on_update = any(
580
479
  (
480
+ bool(extra_env),
481
+ _option_was_explicit(ctx, "env_file"),
581
482
  _option_was_explicit(ctx, "model_base_url"),
582
483
  _option_was_explicit(ctx, "model_api_key"),
583
484
  _option_was_explicit(ctx, "default_model"),
@@ -603,8 +504,12 @@ def deploy(
603
504
  storage_size_gi=storage_size_gi,
604
505
  storage_mount_path=storage_mount_path,
605
506
  no_storage=no_storage,
507
+ observability=observability,
508
+ agent_id=agent_id_opt,
606
509
  include_env_on_update=include_env_on_update,
607
510
  include_storage_on_update=include_storage_on_update,
511
+ extra_env=extra_env,
512
+ env_file=env_file,
608
513
  **network_cli_kwargs(
609
514
  enable_public_access=enable_public_access,
610
515
  enable_vpc_access=enable_vpc_access,
@@ -634,22 +539,43 @@ async def _deploy_hermes(
634
539
  storage_size_gi: int,
635
540
  storage_mount_path: str | None,
636
541
  no_storage: bool,
542
+ observability: bool,
543
+ agent_id: str | None = None,
637
544
  include_env_on_update: bool,
638
545
  include_storage_on_update: bool,
639
- enable_public_access: bool | None,
640
- enable_vpc_access: bool,
641
- vpc_id: str | None,
642
- subnet_id: str | None,
643
- security_group_id: str | None,
644
- availability_zone: str | None,
645
- dry_run: bool,
546
+ extra_env: tuple[str, ...] = (),
547
+ env_file: str | None = None,
548
+ enable_public_access: bool | None = None,
549
+ enable_vpc_access: bool = False,
550
+ vpc_id: str | None = None,
551
+ subnet_id: str | None = None,
552
+ security_group_id: str | None = None,
553
+ availability_zone: str | None = None,
554
+ dry_run: bool = False,
646
555
  ) -> None:
647
556
  project_dir = Path(".").resolve()
648
- _load_dotenv_into_env(project_dir)
557
+ cli_env, auto_dotenv, shell_keys, env_source = resolve_runtime_env_overrides(
558
+ env_file=env_file,
559
+ extra_env=extra_env,
560
+ base_dir=project_dir,
561
+ )
562
+ loaded = inject_env_to_environ(cli_env, auto_dotenv, shell_keys)
563
+ if loaded:
564
+ print_info(f"已从 {env_source or '--env'} 注入环境变量: {loaded} 项")
565
+ if cli_env or auto_dotenv:
566
+ include_env_on_update = True
649
567
  state = load_state(project_dir)
650
568
  existing_agent_id = None
651
569
  if str(state.get("type") or state.get("framework") or "").strip().lower() == "hermes":
652
570
  existing_agent_id = str(state.get("agent_id") or "").strip() or None
571
+ explicit_agent_id = (agent_id or "").strip() or None
572
+ if explicit_agent_id:
573
+ if existing_agent_id and existing_agent_id != explicit_agent_id:
574
+ print_warn(
575
+ f"--agent-id ({explicit_agent_id}) 与本地状态 "
576
+ f"({existing_agent_id}) 不一致,以 --agent-id 为准"
577
+ )
578
+ existing_agent_id = explicit_agent_id
653
579
  agent_name = name or state.get("name") or project_dir.name.replace("-", "_")
654
580
  image_ref = image or _env_value("HERMES_IMAGE", "HERMES_DOCKER_IMAGE")
655
581
  if not image_ref:
@@ -676,6 +602,9 @@ async def _deploy_hermes(
676
602
  model_api_key=model_api_key,
677
603
  default_model=default_model,
678
604
  model_metadata=model_metadata,
605
+ cli_env=cli_env,
606
+ auto_dotenv=auto_dotenv,
607
+ shell_keys=shell_keys,
679
608
  )
680
609
  payload = {
681
610
  "name": agent_name,
@@ -686,6 +615,7 @@ async def _deploy_hermes(
686
615
  "region": region,
687
616
  "resources": {"cpu": cpu, "memory": memory},
688
617
  "scaling": {"min_replicas": 1, "max_replicas": 1, "concurrency": 1000},
618
+ "enable_observability": observability,
689
619
  "env_vars": env_vars,
690
620
  "ui_config": {"profile": "hermes", "path": "/", "url": None},
691
621
  }
@@ -723,6 +653,38 @@ async def _deploy_hermes(
723
653
  print_kv("镜像", image_ref)
724
654
 
725
655
  async with AgentEngineClient(region=region, dry_run=dry_run) as client:
656
+ if explicit_agent_id and not dry_run:
657
+ try:
658
+ detail = await client.get_agent(
659
+ explicit_agent_id, include_api_key=True
660
+ )
661
+ except Exception as e:
662
+ raise click.ClickException(
663
+ f"指定的 Agent ID '{explicit_agent_id}' 不存在,或当前凭证无权限访问。\n"
664
+ f" 详情: {e}\n"
665
+ " 👉 请确认 agent_id 正确,且当前 AK/SK / 账号有该 Agent 的权限。"
666
+ ) from e
667
+ qa = detail.get("quick_access", {}) or {}
668
+ basic = detail.get("basic", {}) or {}
669
+ recovered_state = state.copy()
670
+ recovered_state.update(
671
+ {
672
+ "agent_id": explicit_agent_id,
673
+ "name": basic.get("name") or agent_name,
674
+ "type": "hermes",
675
+ "region": region,
676
+ "endpoint": qa.get("public_endpoint"),
677
+ "updated_at": datetime.now(timezone.utc).isoformat(),
678
+ }
679
+ )
680
+ if qa.get("api_key"):
681
+ recovered_state["api_key"] = qa["api_key"]
682
+ recovered_state = {
683
+ k: v for k, v in recovered_state.items() if v is not None
684
+ }
685
+ save_state(project_dir, recovered_state)
686
+ state = recovered_state
687
+ print_info(f"已通过 --agent-id 关联已有 Agent: {explicit_agent_id}")
726
688
  if existing_agent_id:
727
689
  update_payload = _build_hermes_update_payload(
728
690
  payload=payload,
@@ -815,7 +777,7 @@ async def _deploy_hermes(
815
777
  if dry_run:
816
778
  return
817
779
 
818
- agent_id = res.get("agent_id")
780
+ final_agent_id = res.get("agent_id")
819
781
  endpoint = res.get("endpoint")
820
782
  api_key = res.get("api_key")
821
783
  deployment_status = normalize_deployment_status(res.get("status") or res.get("phase"))
@@ -824,7 +786,7 @@ async def _deploy_hermes(
824
786
  {
825
787
  "type": "hermes",
826
788
  "framework": "hermes",
827
- "agent_id": agent_id,
789
+ "agent_id": final_agent_id,
828
790
  "name": res.get("name") or agent_name,
829
791
  "region": region,
830
792
  "endpoint": endpoint,
@@ -841,8 +803,8 @@ async def _deploy_hermes(
841
803
  resource="hermes",
842
804
  action="deploy",
843
805
  result={
844
- "id": str(agent_id or ""),
845
- "agent_id": str(agent_id or ""),
806
+ "id": str(final_agent_id or ""),
807
+ "agent_id": str(final_agent_id or ""),
846
808
  "name": str(res.get("name") or agent_name),
847
809
  "status": deployment_status,
848
810
  "framework": "hermes",
@@ -857,7 +819,7 @@ async def _deploy_hermes(
857
819
  )
858
820
  return
859
821
  print_success("Hermes 已提交部署")
860
- print_kv("Agent ID", str(agent_id or "(创建中)"))
822
+ print_kv("Agent ID", str(final_agent_id or "(创建中)"))
861
823
  print_kv("当前状态", deployment_status, value_style=status_rich_style(deployment_status))
862
824
  if endpoint:
863
825
  print_kv("Endpoint", str(endpoint), value_style="#58a6ff")
@@ -1072,6 +1034,7 @@ def open_hermes(
1072
1034
 
1073
1035
  @hermes.command("exec", context_settings=CONTEXT_SETTINGS)
1074
1036
  @click.argument("argv", nargs=-1, required=True)
1037
+ @click.option("--agent", "agent_option", default=None, help="Hermes Agent 名称(显式指定)")
1075
1038
  @click.option("--region", "-r", default="cn-beijing-6", envvar="KSYUN_REGION", help="区域")
1076
1039
  @click.option("--endpoint", "-e", default=None, help="Agent Endpoint URL (覆盖自动获取)")
1077
1040
  @click.option("--api-key", default=None, help="AgentEngine API Key (覆盖自动获取)")
@@ -1081,6 +1044,7 @@ def open_hermes(
1081
1044
  @cli_output_option()
1082
1045
  def exec_hermes(
1083
1046
  argv: tuple[str, ...],
1047
+ agent_option: Optional[str],
1084
1048
  region: str,
1085
1049
  endpoint: Optional[str],
1086
1050
  api_key: Optional[str],
@@ -1092,10 +1056,19 @@ def exec_hermes(
1092
1056
  """透传受限 Hermes 只读运维子命令。"""
1093
1057
  _ = output_mode
1094
1058
  try:
1095
- agent_ref, validated_argv = _split_terminal_agent_ref_and_argv(
1059
+ if agent_option is not None:
1060
+ agent_option = agent_option.strip()
1061
+ if not agent_option:
1062
+ raise click.ClickException("--agent 必须指定非空的 Hermes Agent 名称")
1063
+ positional_agent_ref, validated_argv = _split_terminal_agent_ref_and_argv(
1096
1064
  argv,
1097
- validator=validate_hermes_exec_argv,
1065
+ validator=_passthrough_exec_argv,
1098
1066
  )
1067
+ if agent_option is not None and positional_agent_ref:
1068
+ raise click.ClickException(
1069
+ "--agent 不能与位置参数 Agent ID 同时使用: " f"{positional_agent_ref}"
1070
+ )
1071
+ agent_ref = agent_option if agent_option is not None else positional_agent_ref
1099
1072
  dry_run = effective_dry_run(dry_run)
1100
1073
  if dry_run:
1101
1074
  _render_hermes_dry_run(
@@ -1122,6 +1095,7 @@ def exec_hermes(
1122
1095
  insecure=insecure,
1123
1096
  mode="exec",
1124
1097
  argv=validated_argv,
1098
+ exec_argv_validator=_passthrough_exec_argv,
1125
1099
  )
1126
1100
  )
1127
1101
  except (KeyboardInterrupt, asyncio.CancelledError):
ksadk/cli/cmd_invoke.py CHANGED
@@ -18,6 +18,7 @@ import click
18
18
 
19
19
  from ksadk.api import AgentEngineAPIError, AgentEngineClient
20
20
  from ksadk.cli.agent_ref import merge_agent_inputs, resolve_agent_ref, resolve_openclaw_ref
21
+ from ksadk.cli.invoke_payload import build_chat_request
21
22
  from ksadk.cli.cmd_files import (
22
23
  _build_sync_payload,
23
24
  _collect_local_files_report,
@@ -603,6 +604,9 @@ def run_invoke_command(
603
604
  insecure,
604
605
  model,
605
606
  api_format_resolved,
607
+ default_model=(
608
+ "openclaw" if _is_openclaw_target(next_state, latest_access) else None
609
+ ),
606
610
  )
607
611
  )
608
612
  else:
@@ -1286,6 +1290,7 @@ async def _invoke_once(
1286
1290
  insecure: bool = False,
1287
1291
  model: Optional[str] = None,
1288
1292
  api_format: str = "chat_completions",
1293
+ default_model: Optional[str] = None,
1289
1294
  ):
1290
1295
  """单次调用"""
1291
1296
  click.echo(f"\n👤 你: {message}")
@@ -1306,7 +1311,7 @@ async def _invoke_once(
1306
1311
  last_refresh_time = 0.0
1307
1312
  full_reasoning = ""
1308
1313
  async for chunk in _stream_chat(
1309
- endpoint, message, api_key, session_id, True, insecure, model, api_format
1314
+ endpoint, message, api_key, session_id, True, insecure, model, api_format, default_model
1310
1315
  ):
1311
1316
  content, reasoning = _extract_content(chunk)
1312
1317
 
@@ -1336,7 +1341,7 @@ async def _invoke_once(
1336
1341
  live.refresh() # 确保最后一次刷新
1337
1342
  else:
1338
1343
  async for chunk in _stream_chat(
1339
- endpoint, message, api_key, session_id, True, insecure, model, api_format
1344
+ endpoint, message, api_key, session_id, True, insecure, model, api_format, default_model
1340
1345
  ):
1341
1346
  content, reasoning = _extract_content(chunk)
1342
1347
  if reasoning:
@@ -1346,7 +1351,7 @@ async def _invoke_once(
1346
1351
  click.echo() # 换行
1347
1352
  else:
1348
1353
  response = await _chat(
1349
- endpoint, message, api_key, session_id, insecure, model, api_format
1354
+ endpoint, message, api_key, session_id, insecure, model, api_format, default_model
1350
1355
  )
1351
1356
  content = _extract_response_content(response)
1352
1357
  if console and Markdown:
@@ -1365,6 +1370,7 @@ async def _chat(
1365
1370
  insecure: bool = False,
1366
1371
  model: Optional[str] = None,
1367
1372
  api_format: str = "chat_completions",
1373
+ default_model: Optional[str] = None,
1368
1374
  ) -> dict[str, Any]:
1369
1375
  """非流式调用 (OpenAI 兼容格式)"""
1370
1376
  try:
@@ -1373,25 +1379,15 @@ async def _chat(
1373
1379
  click.secho("❌ 请安装 httpx: pip install httpx", fg="red")
1374
1380
  raise SystemExit(1)
1375
1381
 
1376
- normalized_api_format = str(api_format or "chat_completions").strip().lower()
1377
- if normalized_api_format == "responses":
1378
- url = f"{endpoint.rstrip('/')}/v1/responses"
1379
- payload: dict[str, Any] = {
1380
- "input": [{"role": "user", "content": message}],
1381
- "stream": False,
1382
- }
1383
- else:
1384
- url = f"{endpoint.rstrip('/')}/v1/chat/completions"
1385
- payload = {
1386
- "messages": [{"role": "user", "content": message}],
1387
- "stream": False,
1388
- }
1389
-
1390
- if session_id:
1391
- payload["session_id"] = session_id
1392
-
1393
- if model:
1394
- payload["model"] = model
1382
+ url, payload = build_chat_request(
1383
+ endpoint,
1384
+ message,
1385
+ session_id=session_id,
1386
+ model=model,
1387
+ api_format=api_format,
1388
+ default_model=default_model,
1389
+ stream=False,
1390
+ )
1395
1391
 
1396
1392
  # 本地请求禁用系统代理 (ClashX 等会导致本地请求 502 错误)
1397
1393
  # trust_env=False 会禁用: 代理设置、SSL 证书环境变量、.netrc 文件
@@ -1431,6 +1427,7 @@ async def _stream_chat(
1431
1427
  insecure: bool = False,
1432
1428
  model: Optional[str] = None,
1433
1429
  api_format: str = "chat_completions",
1430
+ default_model: Optional[str] = None,
1434
1431
  ):
1435
1432
  """流式调用 (SSE)"""
1436
1433
  try:
@@ -1439,22 +1436,15 @@ async def _stream_chat(
1439
1436
  click.secho("❌ 请安装 httpx: pip install httpx", fg="red")
1440
1437
  raise SystemExit(1)
1441
1438
 
1442
- normalized_api_format = str(api_format or "chat_completions").strip().lower()
1443
- if normalized_api_format == "responses":
1444
- url = f"{endpoint.rstrip('/')}/v1/responses"
1445
- payload: dict[str, Any] = {
1446
- "input": [{"role": "user", "content": message}],
1447
- "stream": True,
1448
- }
1449
- else:
1450
- url = f"{endpoint.rstrip('/')}/v1/chat/completions"
1451
- payload = {"messages": [{"role": "user", "content": message}], "stream": True}
1452
-
1453
- if session_id:
1454
- payload["session_id"] = session_id
1455
-
1456
- if model:
1457
- payload["model"] = model
1439
+ url, payload = build_chat_request(
1440
+ endpoint,
1441
+ message,
1442
+ session_id=session_id,
1443
+ model=model,
1444
+ api_format=api_format,
1445
+ default_model=default_model,
1446
+ stream=True,
1447
+ )
1458
1448
 
1459
1449
  # 本地请求禁用系统代理 (ClashX 等会导致本地请求 502 错误)
1460
1450
  # trust_env=False 会禁用: 代理设置、SSL 证书环境变量、.netrc 文件
ksadk/cli/cmd_launch.py CHANGED
@@ -71,6 +71,14 @@ def _dict_or_none(value: object) -> dict[str, Any] | None:
71
71
  help="部署目标 (default: serverless)",
72
72
  )
73
73
  @click.option("--name", "-n", help="部署名称")
74
+ @click.option(
75
+ "--agent-id",
76
+ default=None,
77
+ help=(
78
+ "指定要更新的已有 Agent ID;当前凭证有权限时会自动回填 "
79
+ ".agentengine.state 并走热更新(用于本地状态丢失后重新关联)"
80
+ ),
81
+ )
74
82
  @click.option(
75
83
  "--region", "-r", default="cn-beijing-6", envvar="KSYUN_REGION", help="区域 (serverless)"
76
84
  )
@@ -142,6 +150,7 @@ def launch(
142
150
  no_version: bool,
143
151
  auto_rollback: bool,
144
152
  output_mode: str | None,
153
+ agent_id: str | None,
145
154
  ):
146
155
  """一键完成构建和部署 (Build + Deploy)
147
156
 
@@ -199,6 +208,7 @@ def launch(
199
208
  extra_env=extra_env,
200
209
  env_file=env_file,
201
210
  dry_run_context=dry_run_context,
211
+ agent_id=agent_id,
202
212
  ),
203
213
  dry_run=dry_run,
204
214
  on_dry_run=(
@@ -246,6 +256,7 @@ async def _launch_async(
246
256
  extra_env: tuple[str, ...] = (),
247
257
  env_file: str | None = None,
248
258
  dry_run_context: dict[str, object] | None = None,
259
+ agent_id: str | None = None,
249
260
  ):
250
261
  from ksadk.deployment import DeploymentManager, DeployTarget
251
262
  from ksadk.detection import FrameworkDetector
@@ -322,6 +333,7 @@ async def _launch_async(
322
333
  "ui_url": resolved_ui_url,
323
334
  "dry_run": dry_run,
324
335
  "env_vars": explicit_env_vars,
336
+ "agent_id": agent_id,
325
337
  },
326
338
  )
327
339