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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +43 -7
  2. agentengine_sdk_python-0.8.2.dist-info/RECORD +778 -0
  3. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +1 -1
  4. ksadk/a2a/__init__.py +2 -0
  5. ksadk/a2a/_space_client_events.py +381 -0
  6. ksadk/a2a/bootstrap.py +0 -2
  7. ksadk/a2a/card.py +6 -111
  8. ksadk/a2a/control_plane.py +239 -1
  9. ksadk/a2a/event_adapter.py +156 -64
  10. ksadk/a2a/executor.py +195 -172
  11. ksadk/a2a/routes.py +12 -5
  12. ksadk/a2a/server.py +1 -8
  13. ksadk/a2a/service_env.py +33 -0
  14. ksadk/a2a/space_client.py +43 -349
  15. ksadk/a2a_card.py +101 -0
  16. ksadk/a2ui/core.py +222 -53
  17. ksadk/agui/_agent_helpers.py +243 -0
  18. ksadk/agui/a2ui_projection.py +12 -5
  19. ksadk/agui/agent.py +474 -275
  20. ksadk/agui/config.py +11 -5
  21. ksadk/agui/routes.py +7 -15
  22. ksadk/api/client.py +530 -40
  23. ksadk/api/environment.py +27 -0
  24. ksadk/builders/code_builder.py +352 -53
  25. ksadk/builders/container_builder.py +71 -44
  26. ksadk/builders/framework_requirements.py +2 -1
  27. ksadk/builders/ks3_uploader.py +2 -2
  28. ksadk/builders/managed_runtime_builder.py +60 -28
  29. ksadk/cli/__init__.py +25 -0
  30. ksadk/cli/cmd_a2a.py +18 -31
  31. ksadk/cli/cmd_create.py +13 -26
  32. ksadk/cli/cmd_dashboard.py +15 -1
  33. ksadk/cli/cmd_deploy.py +28 -3
  34. ksadk/cli/cmd_eval.py +443 -0
  35. ksadk/cli/cmd_evalset.py +284 -0
  36. ksadk/cli/cmd_files.py +5 -1
  37. ksadk/cli/cmd_hermes.py +137 -163
  38. ksadk/cli/cmd_invoke.py +28 -38
  39. ksadk/cli/cmd_launch.py +12 -0
  40. ksadk/cli/cmd_managed_runtime.py +95 -0
  41. ksadk/cli/cmd_observe.py +85 -0
  42. ksadk/cli/cmd_openclaw.py +85 -479
  43. ksadk/cli/cmd_replay.py +28 -4
  44. ksadk/cli/cmd_run.py +29 -67
  45. ksadk/cli/cmd_studio.py +201 -0
  46. ksadk/cli/cmd_web.py +15 -6
  47. ksadk/cli/dry_run.py +2 -1
  48. ksadk/cli/env_options.py +83 -0
  49. ksadk/cli/global_options.py +3 -1
  50. ksadk/cli/hermes_env.py +151 -0
  51. ksadk/cli/invoke_payload.py +49 -0
  52. ksadk/cli/network_options.py +7 -5
  53. ksadk/cli/openclaw_env.py +458 -0
  54. ksadk/cli/runtime_bootstrap.py +51 -0
  55. ksadk/cli/ui.py +6 -0
  56. ksadk/cli/workflow_common.py +5 -5
  57. ksadk/codex/__init__.py +3 -3
  58. ksadk/codex/client.py +833 -49
  59. ksadk/codex/phase.py +1 -1
  60. ksadk/codex/runtime.py +720 -127
  61. ksadk/common/kop_client.py +232 -0
  62. ksadk/configs/__init__.py +1 -3
  63. ksadk/configs/env_registry.py +244 -45
  64. ksadk/configs/env_registry_pcm.py +181 -0
  65. ksadk/configs/env_var_spec.py +18 -0
  66. ksadk/configs/global_config.py +6 -1
  67. ksadk/configs/settings.py +5 -108
  68. ksadk/context_engine/__init__.py +98 -0
  69. ksadk/context_engine/assembler.py +176 -0
  70. ksadk/context_engine/baseline.py +419 -0
  71. ksadk/context_engine/cache_observability.py +228 -0
  72. ksadk/context_engine/capabilities.py +443 -0
  73. ksadk/context_engine/contributors.py +344 -0
  74. ksadk/context_engine/hosted_pipeline.py +417 -0
  75. ksadk/context_engine/models.py +117 -0
  76. ksadk/context_engine/planner.py +698 -0
  77. ksadk/context_engine/policies.py +319 -0
  78. ksadk/context_engine/projection.py +31 -0
  79. ksadk/context_engine/shadow_plan.py +266 -0
  80. ksadk/context_engine/tokenizer.py +164 -0
  81. ksadk/conversations/__init__.py +85 -94
  82. ksadk/conversations/context.py +126 -6
  83. ksadk/conversations/message_projection.py +292 -28
  84. ksadk/conversations/model_context.py +49 -3
  85. ksadk/conversations/runtime_compaction.py +207 -5
  86. ksadk/conversations/runtime_input.py +193 -3
  87. ksadk/conversations/runtime_invocation.py +81 -3
  88. ksadk/conversations/runtime_observability.py +157 -4
  89. ksadk/conversations/runtime_payloads.py +42 -0
  90. ksadk/conversations/runtime_preparation.py +280 -2
  91. ksadk/conversations/runtime_resume.py +71 -32
  92. ksadk/conversations/runtime_stream_events.py +94 -9
  93. ksadk/conversations/runtime_streaming.py +175 -22
  94. ksadk/conversations/semantic_summary.py +311 -1
  95. ksadk/conversations/session_lock.py +51 -0
  96. ksadk/deployment/env_forward.py +72 -0
  97. ksadk/deployment/managed_runtime.py +38 -0
  98. ksadk/deployment/manager.py +24 -8
  99. ksadk/deployment/providers/serverless.py +228 -92
  100. ksadk/evaluation/__init__.py +116 -0
  101. ksadk/evaluation/a2a_adapter.py +452 -0
  102. ksadk/evaluation/adapters.py +67 -0
  103. ksadk/evaluation/agent_eval_client.py +395 -0
  104. ksadk/evaluation/cloud_binding.py +80 -0
  105. ksadk/evaluation/cloud_converter.py +194 -0
  106. ksadk/evaluation/cloud_service.py +199 -0
  107. ksadk/evaluation/contracts.py +478 -0
  108. ksadk/evaluation/evalset.py +351 -0
  109. ksadk/evaluation/evaluators.py +627 -0
  110. ksadk/evaluation/evidence.py +258 -0
  111. ksadk/evaluation/executor.py +143 -0
  112. ksadk/evaluation/local_adapter.py +550 -0
  113. ksadk/evaluation/service_env.py +27 -0
  114. ksadk/evaluation/storage.py +68 -0
  115. ksadk/evaluation/studio_build_adapter.py +253 -0
  116. ksadk/evaluation/target.py +82 -0
  117. ksadk/events/__init__.py +13 -13
  118. ksadk/events/_v1_compat/__init__.py +1 -0
  119. ksadk/events/_v1_compat/models.py +299 -0
  120. ksadk/events/_v1_compat/parser.py +247 -0
  121. ksadk/events/_v1_compat/projection.py +753 -0
  122. ksadk/events/adapters/__init__.py +34 -0
  123. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  124. ksadk/events/adapters/_a2a_support.py +275 -0
  125. ksadk/events/adapters/_codex_interactions.py +375 -0
  126. ksadk/events/adapters/_codex_items.py +801 -0
  127. ksadk/events/adapters/_codex_validators.py +311 -0
  128. ksadk/events/adapters/_langgraph_support.py +785 -0
  129. ksadk/events/adapters/a2a.py +841 -0
  130. ksadk/events/adapters/adk.py +503 -0
  131. ksadk/events/adapters/codex.py +717 -0
  132. ksadk/events/adapters/langgraph.py +745 -0
  133. ksadk/events/canonical.py +440 -0
  134. ksadk/events/canonical_replay.py +497 -0
  135. ksadk/events/canonical_store.py +468 -0
  136. ksadk/events/cold_recovery.py +257 -0
  137. ksadk/events/content.py +89 -0
  138. ksadk/events/identity.py +86 -0
  139. ksadk/events/pipeline.py +455 -0
  140. ksadk/events/projections.py +66 -0
  141. ksadk/events/reducer.py +661 -0
  142. ksadk/events/replay.py +3 -36
  143. ksadk/events/runtime_event.py +20 -256
  144. ksadk/events/session_event.py +324 -0
  145. ksadk/events/store.py +3 -316
  146. ksadk/events/v1_compat.py +41 -0
  147. ksadk/harness/__init__.py +3 -2
  148. ksadk/harness/app.py +114 -123
  149. ksadk/harness/config.py +1 -1
  150. ksadk/harness/runtime.py +467 -0
  151. ksadk/hermes_terminal.py +5 -0
  152. ksadk/identity/resolver.py +4 -3
  153. ksadk/interaction/__init__.py +28 -0
  154. ksadk/interaction/contracts.py +136 -0
  155. ksadk/interaction/ledger.py +189 -0
  156. ksadk/interaction/provider.py +122 -0
  157. ksadk/interaction/providers/__init__.py +52 -0
  158. ksadk/interaction/providers/adk.py +40 -0
  159. ksadk/interaction/providers/codex.py +94 -0
  160. ksadk/interaction/providers/langgraph.py +58 -0
  161. ksadk/kernel/__init__.py +117 -0
  162. ksadk/kernel/authorization.py +258 -0
  163. ksadk/kernel/bootstrap.py +1074 -0
  164. ksadk/kernel/contract_fingerprints.py +61 -0
  165. ksadk/kernel/contracts.py +362 -0
  166. ksadk/kernel/control.py +219 -0
  167. ksadk/kernel/errors.py +79 -0
  168. ksadk/kernel/ingress.py +1102 -0
  169. ksadk/kernel/mapping.py +111 -0
  170. ksadk/kernel/memory_store.py +1133 -0
  171. ksadk/kernel/postgres_store.py +1756 -0
  172. ksadk/kernel/recovery.py +452 -0
  173. ksadk/kernel/runtime_identity.py +103 -0
  174. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  175. ksadk/kernel/sqlite_store.py +1410 -0
  176. ksadk/kernel/state.py +145 -0
  177. ksadk/kernel/store.py +232 -0
  178. ksadk/kernel/worker.py +953 -0
  179. ksadk/knowledge_base/client.py +22 -4
  180. ksadk/knowledge_base/service.py +32 -5
  181. ksadk/managed_a2a_card.py +160 -0
  182. ksadk/managed_runtime.py +16 -9
  183. ksadk/memory/__init__.py +61 -0
  184. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  185. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  186. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  187. ksadk/memory/adk/backends/sdk_ltm_backend.py +394 -5
  188. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  189. ksadk/memory/adk/long_term_memory.py +3 -2
  190. ksadk/memory/coordinator.py +461 -0
  191. ksadk/memory/events.py +202 -0
  192. ksadk/memory/extraction.py +228 -0
  193. ksadk/memory/ltm_backend_factory.py +16 -3
  194. ksadk/memory/models.py +316 -0
  195. ksadk/memory/policy.py +215 -0
  196. ksadk/memory/provider.py +47 -0
  197. ksadk/memory/provider_adapter.py +159 -0
  198. ksadk/memory/provider_resolver.py +71 -0
  199. ksadk/memory/providers/__init__.py +5 -0
  200. ksadk/memory/providers/local_sqlite.py +490 -0
  201. ksadk/memory/resolved_policy.py +145 -0
  202. ksadk/memory/service.py +198 -8
  203. ksadk/memory/tool.py +4 -0
  204. ksadk/model_proxy/bootstrap.py +16 -9
  205. ksadk/model_proxy/config.py +22 -1
  206. ksadk/model_proxy/detect.py +202 -9
  207. ksadk/model_proxy/namespace.py +67 -15
  208. ksadk/model_proxy/server.py +168 -6
  209. ksadk/model_proxy/transform.py +105 -3
  210. ksadk/observability/__init__.py +25 -0
  211. ksadk/observability/session_log.py +420 -0
  212. ksadk/observability/trajectory.py +105 -0
  213. ksadk/prompts/__init__.py +71 -0
  214. ksadk/prompts/compiler.py +215 -0
  215. ksadk/prompts/models.py +82 -0
  216. ksadk/prompts/projection.py +89 -0
  217. ksadk/prompts/resolved.py +137 -0
  218. ksadk/prompts/sources.py +233 -0
  219. ksadk/runners/_langgraph_runner_streams.py +822 -0
  220. ksadk/runners/adk_runner.py +14 -31
  221. ksadk/runners/base_runner.py +44 -3
  222. ksadk/runners/factory.py +3 -3
  223. ksadk/runners/langgraph_runner.py +252 -433
  224. ksadk/runners/utils/__init__.py +0 -10
  225. ksadk/runners/utils/loader.py +16 -0
  226. ksadk/runtime/__init__.py +67 -41
  227. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  228. ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
  229. ksadk/runtime/adapter.py +199 -16
  230. ksadk/runtime/conversation_execution.py +687 -0
  231. ksadk/runtime/executor.py +392 -0
  232. ksadk/runtime/factory.py +342 -0
  233. ksadk/runtime/framework_adapters.py +6 -12
  234. ksadk/runtime/hosted_finalizer.py +268 -0
  235. ksadk/runtime/launch.py +61 -0
  236. ksadk/runtime/preprocessing.py +49 -14
  237. ksadk/runtime/runner_adapter.py +330 -391
  238. ksadk/runtime/runner_loading.py +36 -0
  239. ksadk/runtime/usage.py +33 -0
  240. ksadk/sandbox/backends/e2b.py +36 -3
  241. ksadk/server/__init__.py +39 -4
  242. ksadk/server/app.py +18 -492
  243. ksadk/server/composition.py +36 -2
  244. ksadk/server/factory.py +210 -149
  245. ksadk/server/routes/common.py +15 -46
  246. ksadk/server/routes/control.py +13 -9
  247. ksadk/server/routes/kernel_ingress.py +258 -0
  248. ksadk/server/routes/misc.py +10 -33
  249. ksadk/server/routes/models.py +14 -6
  250. ksadk/server/routes/openai_compat.py +129 -27
  251. ksadk/server/routes/projection.py +84 -16
  252. ksadk/server/routes/run.py +347 -460
  253. ksadk/server/routes/sessions.py +37 -40
  254. ksadk/server/routes/streaming.py +52 -7
  255. ksadk/server/routes/workspace.py +54 -21
  256. ksadk/server/static/assets/{ArtifactsPanel-Cjnqt-8W.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
  257. ksadk/server/static/assets/{CodeBlock-BqyqZfuB.js → CodeBlock-DOH6MVcn.js} +4 -4
  258. ksadk/server/static/assets/{MathMessageMarkdown-BpH7jiFM.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
  259. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  260. ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
  261. ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
  262. ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
  263. ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
  264. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
  265. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
  266. ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
  267. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
  268. ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
  269. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
  270. ksadk/server/static/assets/{chunk-FMBD7UC4-BGhvzDYt.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
  271. ksadk/server/static/assets/{chunk-ND2GUHAM-D98vPd-E.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
  272. ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
  273. ksadk/server/static/assets/{chunk-4BX2VUAB-CsWIQRhc.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
  274. ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
  275. ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
  276. ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
  277. ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
  278. ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
  279. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
  280. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
  281. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-CX3yotHq.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
  282. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
  283. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
  284. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  285. ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
  286. ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
  287. ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
  288. ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
  289. ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
  290. ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
  291. ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
  292. ksadk/server/static/assets/{dist-D82mtD2s.js → dist-8hqcx0sU.js} +1 -1
  293. ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
  294. ksadk/server/static/assets/{dist-DHn6nBzr.js → dist-BE7bu-DL.js} +1 -1
  295. ksadk/server/static/assets/{dist-eoW6tZXA.js → dist-BVDffZ0U.js} +1 -1
  296. ksadk/server/static/assets/{dist-C2xjE7cO.js → dist-BX8z72IC.js} +1 -1
  297. ksadk/server/static/assets/{dist-CgF3fj15.js → dist-Bf2M8m3N.js} +1 -1
  298. ksadk/server/static/assets/{dist-Bs-jQcRX.js → dist-BjU6y-A2.js} +1 -1
  299. ksadk/server/static/assets/{dist-Djgl2wVZ.js → dist-BytlxIDT.js} +1 -1
  300. ksadk/server/static/assets/{dist-CVQRZjPu.js → dist-CSh_DE14.js} +1 -1
  301. ksadk/server/static/assets/{dist-6CVKuTAe.js → dist-CXYYBw3_.js} +1 -1
  302. ksadk/server/static/assets/{dist-DlzCRy0S.js → dist-C_wsv-Qd.js} +1 -1
  303. ksadk/server/static/assets/{dist-DF06ORQo.js → dist-ClxGviKw.js} +1 -1
  304. ksadk/server/static/assets/{dist-Cf23NY4L.js → dist-CttYUqzS.js} +1 -1
  305. ksadk/server/static/assets/{dist-ivOya1LD.js → dist-DNp6rLRA.js} +1 -1
  306. ksadk/server/static/assets/{dist-BibcG1V9.js → dist-DUX-id_F.js} +1 -1
  307. ksadk/server/static/assets/{dist-BUHRxvDG.js → dist-DmldrHd_.js} +1 -1
  308. ksadk/server/static/assets/{dist-BZ9n9AjO.js → dist-DnfXs8Vn.js} +2 -2
  309. ksadk/server/static/assets/{dist-DqNnNFrw.js → dist-Dq9gLD7L.js} +1 -1
  310. ksadk/server/static/assets/{dist-CGcp2ex8.js → dist-W-TIVntx.js} +1 -1
  311. ksadk/server/static/assets/{dist-Cwt7koer.js → dist-dDdADKFA.js} +1 -1
  312. ksadk/server/static/assets/{dist-C7-3jInC.js → dist-dydu68Fl.js} +1 -1
  313. ksadk/server/static/assets/{dist-C99THtIA.js → dist-ngtN0DJB.js} +1 -1
  314. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
  315. ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
  316. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
  317. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
  318. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
  319. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
  320. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
  321. ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
  322. ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
  323. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
  324. ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
  325. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-DLOHGvWw.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
  326. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-BIzKeejT.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
  327. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-BWHoFSw2.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
  328. ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
  329. ksadk/server/static/assets/{linear-CvMBw9cA.js → linear-BHjG8b-J.js} +1 -1
  330. ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
  331. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-CSAQxEAe.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
  332. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
  333. ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
  334. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
  335. ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
  336. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-CxIR4JXI.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
  337. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
  338. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
  339. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
  340. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
  341. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
  342. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
  343. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
  344. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-DpGa6EAV.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
  345. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-NTKNGGe5.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
  346. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
  347. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
  348. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
  349. ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
  350. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
  351. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-jqoYs3jQ.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
  352. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
  353. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
  354. ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
  355. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
  356. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
  357. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
  358. ksadk/server/static/index.html +2 -2
  359. ksadk/sessions/__init__.py +26 -9
  360. ksadk/sessions/_local_service_sync.py +688 -0
  361. ksadk/sessions/_local_tables.py +21 -0
  362. ksadk/sessions/_postgres_schema.py +305 -0
  363. ksadk/sessions/_postgres_tables.py +15 -0
  364. ksadk/sessions/base.py +80 -1
  365. ksadk/sessions/in_memory.py +53 -2
  366. ksadk/sessions/local_service.py +63 -604
  367. ksadk/sessions/postgres_service.py +58 -148
  368. ksadk/sessions/resilient.py +35 -1
  369. ksadk/skills/runtime/backends/e2b.py +1 -1
  370. ksadk/skills/service_client.py +13 -3
  371. ksadk/studio/__init__.py +5 -0
  372. ksadk/studio/agent_avatar_assets.py +120 -0
  373. ksadk/studio/agent_lifecycle.py +51 -0
  374. ksadk/studio/api.py +1598 -0
  375. ksadk/studio/api_catalog_routes.py +324 -0
  376. ksadk/studio/api_contracts.py +286 -0
  377. ksadk/studio/api_helpers.py +132 -0
  378. ksadk/studio/api_memory_routes.py +82 -0
  379. ksadk/studio/authoring.py +749 -0
  380. ksadk/studio/authoring_coordinator.py +1017 -0
  381. ksadk/studio/builder.py +397 -0
  382. ksadk/studio/capabilities.py +368 -0
  383. ksadk/studio/cloud.py +2099 -0
  384. ksadk/studio/codex_agent_service.py +694 -0
  385. ksadk/studio/codex_authoring.py +469 -0
  386. ksadk/studio/codex_builder.py +437 -0
  387. ksadk/studio/codex_manifest.py +307 -0
  388. ksadk/studio/codex_run.py +395 -0
  389. ksadk/studio/compiler.py +190 -0
  390. ksadk/studio/contracts.py +755 -0
  391. ksadk/studio/errors.py +47 -0
  392. ksadk/studio/event_store.py +214 -0
  393. ksadk/studio/framework_run.py +342 -0
  394. ksadk/studio/hosted_kernel.py +317 -0
  395. ksadk/studio/identifiers.py +33 -0
  396. ksadk/studio/manifest_resolver.py +131 -0
  397. ksadk/studio/mcp_runtime.py +229 -0
  398. ksadk/studio/model_client.py +629 -0
  399. ksadk/studio/model_profile_service.py +214 -0
  400. ksadk/studio/operations.py +275 -0
  401. ksadk/studio/otel_trace.py +1060 -0
  402. ksadk/studio/pagination.py +182 -0
  403. ksadk/studio/pcm_memory.py +85 -0
  404. ksadk/studio/python_tool_inspection.py +183 -0
  405. ksadk/studio/repository.py +327 -0
  406. ksadk/studio/resource_catalog.py +1260 -0
  407. ksadk/studio/run_service.py +1133 -0
  408. ksadk/studio/runtime_catalog.py +74 -0
  409. ksadk/studio/runtime_source.py +365 -0
  410. ksadk/studio/service.py +2249 -0
  411. ksadk/studio/shared_web.py +1004 -0
  412. ksadk/studio/skill_discovery.py +628 -0
  413. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
  414. ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
  415. ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
  416. ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
  417. ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
  418. ksadk/studio/static/index.html +15 -0
  419. ksadk/studio/templates.py +722 -0
  420. ksadk/studio/validator.py +265 -0
  421. ksadk/studio/workspace.py +135 -0
  422. ksadk/tools/gateway.py +9 -0
  423. ksadk/toolsets/__init__.py +27 -1
  424. ksadk/toolsets/a2a.py +426 -0
  425. ksadk/tracing/__init__.py +19 -21
  426. ksadk/tracing/setup.py +317 -403
  427. ksadk/tracing/span_utils.py +0 -44
  428. ksadk/version.py +1 -1
  429. ksadk_runtime_common/memory_backend/registry.py +56 -56
  430. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  431. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  432. ksadk_runtime_common/workspace_files/router.py +8 -2
  433. agentengine_sdk_python-0.8.0.dist-info/RECORD +0 -578
  434. ksadk/a2a/card_builder.py +0 -64
  435. ksadk/a2a/client.py +0 -309
  436. ksadk/events/parser.py +0 -191
  437. ksadk/harness/runner.py +0 -211
  438. ksadk/runners/codex_runner.py +0 -132
  439. ksadk/runners/utils/langfuse.py +0 -230
  440. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  441. ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +0 -303
  442. ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +0 -1
  443. ksadk/server/static/assets/arc-CFKwSk_B.js +0 -1
  444. ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +0 -1
  445. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-Dej8jX8c.js +0 -36
  446. ksadk/server/static/assets/blockDiagram-GPEHLZMM-1F64jqvy.js +0 -132
  447. ksadk/server/static/assets/c4Diagram-AAUBKEIU-9q7AUAKb.js +0 -10
  448. ksadk/server/static/assets/channel-iUGv2N24.js +0 -1
  449. ksadk/server/static/assets/chunk-2J33WTMH-6qgwJm7Q.js +0 -1
  450. ksadk/server/static/assets/chunk-55IACEB6-BK8paA20.js +0 -1
  451. ksadk/server/static/assets/chunk-727SXJPM-B-JEhy7h.js +0 -206
  452. ksadk/server/static/assets/chunk-AQP2D5EJ-DYBvMHAa.js +0 -231
  453. ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +0 -1
  454. ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +0 -1
  455. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +0 -1
  456. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  457. ksadk/server/static/assets/dagre-BM42HDAG-C7TguAWo.js +0 -4
  458. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  459. ksadk/server/static/assets/diagram-2AECGRRQ-Dd17_kws.js +0 -43
  460. ksadk/server/static/assets/diagram-5GNKFQAL-DVIClIil.js +0 -10
  461. ksadk/server/static/assets/diagram-KO2AKTUF-Df_3gYQa.js +0 -3
  462. ksadk/server/static/assets/diagram-LMA3HP47-BhLk6ZtA.js +0 -24
  463. ksadk/server/static/assets/diagram-OG6HWLK6-D4GNGvuu.js +0 -24
  464. ksadk/server/static/assets/dist-DyvYLMW9.js +0 -1
  465. ksadk/server/static/assets/erDiagram-TEJ5UH35-CnfRcY2M.js +0 -85
  466. ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +0 -1
  467. ksadk/server/static/assets/flowDiagram-I6XJVG4X-DGaJjGNJ.js +0 -162
  468. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-DpCoB2g9.js +0 -292
  469. ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +0 -1
  470. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-9IKVFBVT.js +0 -106
  471. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  472. ksadk/server/static/assets/index-QSwCHuB8.js +0 -177
  473. ksadk/server/static/assets/index-jOPmTOZH.css +0 -2
  474. ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +0 -1
  475. ksadk/server/static/assets/infoDiagram-5YYISTIA-CYIIsb8y.js +0 -2
  476. ksadk/server/static/assets/katex-DATssjp1.js +0 -265
  477. ksadk/server/static/assets/mermaid-parser.core-mGAcEwcq.js +0 -161
  478. ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +0 -1
  479. ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +0 -1
  480. ksadk/server/static/assets/pieDiagram-4H26LBE5-By-ra07M.js +0 -30
  481. ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +0 -1
  482. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DpW90iu3.js +0 -84
  483. ksadk/server/static/assets/stateDiagram-AJRCARHV-DGpd9yFG.js +0 -1
  484. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +0 -1
  485. ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +0 -1
  486. ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +0 -1
  487. ksadk/server/static/assets/vennDiagram-CIIHVFJN-l3Z7-wbP.js +0 -34
  488. ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +0 -1
  489. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-BR54GPmr.js +0 -78
  490. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-SkiH8GsK.js +0 -7
  491. ksadk/tracing/exporters/langfuse_exporter.py +0 -460
  492. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
  493. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
  494. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,452 @@
1
+ """A2A protocol adapter for evaluation targets."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import hashlib
7
+ import json
8
+ import os
9
+ import time
10
+ from contextlib import suppress
11
+ from dataclasses import dataclass, field
12
+ from urllib.parse import urlsplit, urlunsplit
13
+ from uuid import uuid4
14
+
15
+ import httpx
16
+ from a2a.client import A2ACardResolver, ClientConfig, create_client
17
+ from a2a.client.errors import A2AClientError, A2AClientTimeoutError, AgentCardResolutionError
18
+ from a2a.types import (
19
+ AgentCard,
20
+ CancelTaskRequest,
21
+ Message,
22
+ Part,
23
+ Role,
24
+ SendMessageConfiguration,
25
+ SendMessageRequest,
26
+ StreamResponse,
27
+ TaskState,
28
+ )
29
+ from google.protobuf.json_format import MessageToDict
30
+
31
+ from .adapters import TargetAdapterError
32
+ from .contracts import (
33
+ EvalCase,
34
+ EvalRunSpec,
35
+ TargetKind,
36
+ TargetRef,
37
+ TargetRun,
38
+ TargetRunStatus,
39
+ TargetSnapshot,
40
+ )
41
+
42
+ _SUPPORTED_BINDINGS = ["JSONRPC", "HTTP+JSON"]
43
+ _TERMINAL_FAILURES = {
44
+ TaskState.TASK_STATE_FAILED: ("A2A_TASK_FAILED", "远端 A2A Task 执行失败"),
45
+ TaskState.TASK_STATE_REJECTED: ("A2A_TASK_REJECTED", "远端 A2A Task 被拒绝"),
46
+ TaskState.TASK_STATE_AUTH_REQUIRED: ("A2A_AUTH_REQUIRED", "远端 A2A Task 需要鉴权"),
47
+ TaskState.TASK_STATE_INPUT_REQUIRED: ("A2A_INPUT_REQUIRED", "远端 A2A Task 需要额外输入"),
48
+ }
49
+
50
+
51
+ class A2ATargetError(TargetAdapterError):
52
+ """Safe, classified failure while resolving an A2A target."""
53
+
54
+
55
+ @dataclass(frozen=True)
56
+ class _CardLocation:
57
+ base_url: str
58
+ relative_path: str | None
59
+
60
+
61
+ @dataclass
62
+ class _ResponseCollector:
63
+ state: int = TaskState.TASK_STATE_UNSPECIFIED
64
+ task_id: str | None = None
65
+ context_id: str | None = None
66
+ task_output: str = ""
67
+ status_output: str = ""
68
+ direct_output: str = ""
69
+ artifact_chunks: list[str] = field(default_factory=list)
70
+
71
+ def observe(self, response: StreamResponse) -> None:
72
+ if response.task:
73
+ self.task_id = response.task.id or self.task_id
74
+ self.context_id = response.task.context_id or self.context_id
75
+ self.state = int(response.task.status.state)
76
+ self.task_output = _parts_text(
77
+ part
78
+ for artifact in response.task.artifacts
79
+ for part in artifact.parts
80
+ )
81
+ self.status_output = _message_text(response.task.status.message)
82
+
83
+ if response.status_update:
84
+ update = response.status_update
85
+ self.task_id = update.task_id or self.task_id
86
+ self.context_id = update.context_id or self.context_id
87
+ self.state = int(update.status.state)
88
+ self.status_output = _message_text(update.status.message) or self.status_output
89
+
90
+ if response.artifact_update:
91
+ update = response.artifact_update
92
+ self.task_id = update.task_id or self.task_id
93
+ self.context_id = update.context_id or self.context_id
94
+ text = _parts_text(update.artifact.parts)
95
+ if text:
96
+ # canonical executor 的 replace 快照带 ksadk_output_snapshot 标记,
97
+ # 是权威全文;命中时重置而非继续拼接,避免 delta+快照翻倍。
98
+ if any(
99
+ dict(part.metadata or {}).get("ksadk_output_snapshot")
100
+ for part in update.artifact.parts
101
+ ):
102
+ self.artifact_chunks = [text]
103
+ else:
104
+ self.artifact_chunks.append(text)
105
+
106
+ if response.message:
107
+ self.task_id = response.message.task_id or self.task_id
108
+ self.context_id = response.message.context_id or self.context_id
109
+ self.direct_output = _message_text(response.message) or self.direct_output
110
+
111
+ @property
112
+ def output(self) -> str:
113
+ return (
114
+ self.task_output
115
+ or "".join(self.artifact_chunks)
116
+ or self.status_output
117
+ or self.direct_output
118
+ )
119
+
120
+
121
+ @dataclass(frozen=True)
122
+ class _TurnResult:
123
+ status: TargetRunStatus
124
+ output: str
125
+ task_id: str | None
126
+ context_id: str | None
127
+ task_state: int
128
+ error_code: str | None = None
129
+ error_message: str | None = None
130
+
131
+
132
+ def _new_http_client(*, headers: dict[str, str], timeout_seconds: int) -> httpx.AsyncClient:
133
+ return httpx.AsyncClient(
134
+ headers=headers,
135
+ timeout=httpx.Timeout(timeout_seconds),
136
+ follow_redirects=False,
137
+ )
138
+
139
+
140
+ class A2ATargetAdapter:
141
+ """Execute evaluation cases through the official A2A 1.0 client."""
142
+
143
+ kind = TargetKind.A2A
144
+
145
+ def __init__(self, *, timeout_seconds: int) -> None:
146
+ self._timeout_seconds = timeout_seconds
147
+ self._card: AgentCard | None = None
148
+ self._headers: dict[str, str] = {}
149
+
150
+ async def snapshot(self, target: TargetRef) -> TargetSnapshot:
151
+ if target.kind is not self.kind:
152
+ raise A2ATargetError("A2A_TARGET_KIND_INVALID", "A2A adapter 收到非 A2A target")
153
+
154
+ location = _card_location(target.locator)
155
+ headers = _credential_headers(target.credential_ref)
156
+ try:
157
+ async with _new_http_client(
158
+ headers=headers,
159
+ timeout_seconds=self._timeout_seconds,
160
+ ) as http_client:
161
+ resolver = A2ACardResolver(
162
+ httpx_client=http_client,
163
+ base_url=location.base_url,
164
+ )
165
+ card = await resolver.get_agent_card(
166
+ relative_card_path=location.relative_path,
167
+ )
168
+ client = await create_client(
169
+ agent=card,
170
+ client_config=ClientConfig(
171
+ httpx_client=http_client,
172
+ streaming=True,
173
+ supported_protocol_bindings=_SUPPORTED_BINDINGS,
174
+ ),
175
+ )
176
+ await client.close()
177
+ except AgentCardResolutionError as exc:
178
+ raise A2ATargetError(
179
+ "A2A_CARD_UNAVAILABLE",
180
+ "无法读取或校验 A2A Agent Card",
181
+ ) from exc
182
+ except (A2AClientError, httpx.HTTPError, ValueError) as exc:
183
+ raise A2ATargetError(
184
+ "A2A_PROTOCOL_UNAVAILABLE",
185
+ "A2A Agent Card 没有可用的协议接口",
186
+ ) from exc
187
+
188
+ digest = _agent_card_digest(card)
189
+ self._card = card
190
+ self._headers = headers
191
+ return TargetSnapshot(
192
+ kind=self.kind,
193
+ entrypoint=target.locator,
194
+ revision_digest=f"sha256:{digest}",
195
+ runtime="a2a/1.0",
196
+ metadata={
197
+ "agentName": card.name,
198
+ "agentVersion": card.version,
199
+ "credentialRef": target.credential_ref,
200
+ "supportedInterfaces": [
201
+ {
202
+ "protocolBinding": interface.protocol_binding,
203
+ "protocolVersion": interface.protocol_version,
204
+ }
205
+ for interface in card.supported_interfaces
206
+ ],
207
+ },
208
+ )
209
+
210
+ async def run_case(
211
+ self,
212
+ spec: EvalRunSpec,
213
+ case: EvalCase,
214
+ *,
215
+ attempt: int,
216
+ ) -> TargetRun:
217
+ del spec, attempt
218
+ if self._card is None:
219
+ raise RuntimeError("A2A target must be snapshotted before execution")
220
+
221
+ started_at = time.perf_counter()
222
+ task_ids: list[str] = []
223
+ context_id: str | None = None
224
+ final_output = ""
225
+ last_state = TaskState.TASK_STATE_UNSPECIFIED
226
+
227
+ try:
228
+ async with _new_http_client(
229
+ headers=self._headers,
230
+ timeout_seconds=self._timeout_seconds,
231
+ ) as http_client:
232
+ client = await create_client(
233
+ agent=self._card,
234
+ client_config=ClientConfig(
235
+ httpx_client=http_client,
236
+ streaming=True,
237
+ supported_protocol_bindings=_SUPPORTED_BINDINGS,
238
+ ),
239
+ )
240
+ try:
241
+ for turn in case.turns:
242
+ result = await self._run_turn(client, turn.input, context_id)
243
+ context_id = result.context_id or context_id
244
+ last_state = result.task_state
245
+ if result.task_id:
246
+ task_ids.append(result.task_id)
247
+ if result.output:
248
+ final_output = result.output
249
+ if result.status != TargetRunStatus.PASSED:
250
+ return _target_run(
251
+ result.status,
252
+ started_at=started_at,
253
+ output=final_output,
254
+ task_ids=task_ids,
255
+ context_id=context_id,
256
+ task_state=last_state,
257
+ error_code=result.error_code,
258
+ error_message=result.error_message,
259
+ )
260
+ finally:
261
+ await client.close()
262
+ except A2AClientTimeoutError:
263
+ return _target_run(
264
+ TargetRunStatus.ERROR,
265
+ started_at=started_at,
266
+ task_ids=task_ids,
267
+ context_id=context_id,
268
+ task_state=last_state,
269
+ error_code="A2A_NETWORK_TIMEOUT",
270
+ error_message="A2A 请求超时",
271
+ )
272
+ except (A2AClientError, httpx.HTTPError, ValueError):
273
+ return _target_run(
274
+ TargetRunStatus.ERROR,
275
+ started_at=started_at,
276
+ task_ids=task_ids,
277
+ context_id=context_id,
278
+ task_state=last_state,
279
+ error_code="A2A_PROTOCOL_ERROR",
280
+ error_message="A2A 请求或响应不符合协议",
281
+ )
282
+
283
+ return _target_run(
284
+ TargetRunStatus.PASSED,
285
+ started_at=started_at,
286
+ output=final_output,
287
+ task_ids=task_ids,
288
+ context_id=context_id,
289
+ task_state=last_state,
290
+ )
291
+
292
+ async def _run_turn(self, client: object, text: str, context_id: str | None) -> _TurnResult:
293
+ collector = _ResponseCollector(context_id=context_id)
294
+ request = _build_send_request(text, context_id)
295
+ try:
296
+ async for response in client.send_message(request): # type: ignore[attr-defined]
297
+ collector.observe(response)
298
+ except asyncio.CancelledError:
299
+ if collector.task_id:
300
+ with suppress(Exception):
301
+ await client.cancel_task( # type: ignore[attr-defined]
302
+ CancelTaskRequest(id=collector.task_id)
303
+ )
304
+ raise
305
+
306
+ status, error_code, error_message = _task_result(collector)
307
+ return _TurnResult(
308
+ status=status,
309
+ output=collector.output,
310
+ task_id=collector.task_id,
311
+ context_id=collector.context_id,
312
+ task_state=collector.state,
313
+ error_code=error_code,
314
+ error_message=error_message,
315
+ )
316
+
317
+
318
+ def _build_send_request(
319
+ text: str,
320
+ context_id: str | None,
321
+ ) -> SendMessageRequest:
322
+ return SendMessageRequest(
323
+ message=Message(
324
+ role=Role.ROLE_USER,
325
+ parts=[Part(text=text)],
326
+ message_id=f"eval-message-{uuid4().hex}",
327
+ context_id=context_id or "",
328
+ ),
329
+ configuration=SendMessageConfiguration(return_immediately=False),
330
+ )
331
+
332
+ def _card_location(locator: str) -> _CardLocation:
333
+ parsed = urlsplit(locator)
334
+ if parsed.scheme not in {"http", "https"} or not parsed.hostname:
335
+ raise A2ATargetError(
336
+ "A2A_URL_INVALID",
337
+ "A2A target 必须是有效的 http 或 https URL",
338
+ )
339
+ if parsed.username or parsed.password or parsed.fragment:
340
+ raise A2ATargetError(
341
+ "A2A_URL_INVALID",
342
+ "A2A target URL 不能包含用户凭据或 fragment",
343
+ )
344
+
345
+ marker = "/.well-known/"
346
+ if marker not in parsed.path:
347
+ return _CardLocation(locator.rstrip("/"), None)
348
+
349
+ base_path, card_name = parsed.path.split(marker, 1)
350
+ base_url = urlunsplit((parsed.scheme, parsed.netloc, base_path.rstrip("/"), "", ""))
351
+ relative_path = f".well-known/{card_name}"
352
+ if parsed.query:
353
+ relative_path = f"{relative_path}?{parsed.query}"
354
+ return _CardLocation(base_url, relative_path)
355
+
356
+
357
+ def _credential_headers(reference: str | None) -> dict[str, str]:
358
+ if not reference:
359
+ return {}
360
+ if not reference.startswith("env://"):
361
+ raise A2ATargetError(
362
+ "A2A_CREDENTIAL_REF_UNSUPPORTED",
363
+ "本地 A2A 评测当前只支持 env:// 鉴权引用",
364
+ )
365
+
366
+ name = reference.removeprefix("env://")
367
+ if not name or any(char not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" for char in name):
368
+ raise A2ATargetError(
369
+ "A2A_CREDENTIAL_REF_INVALID",
370
+ "A2A env:// 鉴权引用格式无效",
371
+ )
372
+ token = os.environ.get(name)
373
+ if not token:
374
+ raise A2ATargetError(
375
+ "A2A_CREDENTIAL_NOT_FOUND",
376
+ "A2A 鉴权引用尚未配置",
377
+ )
378
+ if len(token) > 16_384 or token != token.strip() or any(ord(char) < 32 for char in token):
379
+ raise A2ATargetError(
380
+ "A2A_CREDENTIAL_INVALID",
381
+ "A2A 鉴权值格式无效",
382
+ )
383
+ return {"Authorization": f"Bearer {token}"}
384
+
385
+
386
+ def _agent_card_digest(card: AgentCard) -> str:
387
+ payload = MessageToDict(card, preserving_proto_field_name=False)
388
+ encoded = json.dumps(payload, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
389
+ return hashlib.sha256(encoded.encode("utf-8")).hexdigest()
390
+
391
+
392
+ def _message_text(message: Message) -> str:
393
+ return _parts_text(message.parts) if message else ""
394
+
395
+
396
+ def _parts_text(parts: object) -> str:
397
+ return "".join(part.text for part in parts if part.text) # type: ignore[attr-defined]
398
+
399
+
400
+ def _task_result(
401
+ collector: _ResponseCollector,
402
+ ) -> tuple[TargetRunStatus, str | None, str | None]:
403
+ if collector.state == TaskState.TASK_STATE_CANCELED:
404
+ return TargetRunStatus.CANCELLED, "A2A_TASK_CANCELLED", "远端 A2A Task 已取消"
405
+ if collector.state in _TERMINAL_FAILURES:
406
+ code, message = _TERMINAL_FAILURES[collector.state]
407
+ return TargetRunStatus.FAILED, code, message
408
+ if collector.state in {
409
+ TaskState.TASK_STATE_SUBMITTED,
410
+ TaskState.TASK_STATE_WORKING,
411
+ }:
412
+ return (
413
+ TargetRunStatus.ERROR,
414
+ "A2A_TASK_INCOMPLETE",
415
+ "A2A 响应结束时 Task 尚未进入终态",
416
+ )
417
+ if collector.state == TaskState.TASK_STATE_COMPLETED or collector.output:
418
+ return TargetRunStatus.PASSED, None, None
419
+ return TargetRunStatus.UNAVAILABLE, "A2A_OUTPUT_UNAVAILABLE", "A2A 响应未提供文本结果"
420
+
421
+
422
+ def _target_run(
423
+ status: TargetRunStatus,
424
+ *,
425
+ started_at: float,
426
+ output: str = "",
427
+ task_ids: list[str],
428
+ context_id: str | None,
429
+ task_state: int,
430
+ error_code: str | None = None,
431
+ error_message: str | None = None,
432
+ ) -> TargetRun:
433
+ metadata: dict[str, object] = {"remoteTaskIds": task_ids}
434
+ if context_id:
435
+ metadata["remoteContextId"] = context_id
436
+ if task_state != TaskState.TASK_STATE_UNSPECIFIED:
437
+ metadata["taskState"] = _task_state_name(task_state)
438
+ return TargetRun(
439
+ status=status,
440
+ output=output,
441
+ duration_ms=max(0, round((time.perf_counter() - started_at) * 1000)),
442
+ error_code=error_code,
443
+ error_message=error_message,
444
+ metadata=metadata,
445
+ )
446
+
447
+
448
+ def _task_state_name(state: int) -> str:
449
+ try:
450
+ return TaskState.Name(state)
451
+ except ValueError:
452
+ return str(state)
@@ -0,0 +1,67 @@
1
+ """Target-kind routing for evaluation adapters."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Protocol
6
+
7
+ from .contracts import EvalCase, EvalRunSpec, TargetKind, TargetRef, TargetRun, TargetSnapshot
8
+
9
+ if TYPE_CHECKING:
10
+ from .evidence import EvidenceStore
11
+
12
+
13
+ class TargetAdapterError(RuntimeError):
14
+ """Classified failure raised by a protocol adapter."""
15
+
16
+ def __init__(self, code: str, message: str) -> None:
17
+ self.code = code
18
+ super().__init__(message)
19
+
20
+
21
+ class EvaluationNotImplementedError(NotImplementedError):
22
+ """Raised when a target kind has no evaluation adapter yet."""
23
+
24
+
25
+ class TargetAdapter(Protocol):
26
+ """Protocol-specific execution behind the common target lifecycle."""
27
+
28
+ kind: TargetKind
29
+
30
+ async def snapshot(self, target: TargetRef) -> TargetSnapshot:
31
+ """Resolve a target into an immutable snapshot."""
32
+
33
+ async def run_case(self, spec: EvalRunSpec, case: EvalCase, *, attempt: int) -> TargetRun:
34
+ """Execute one case and return its normalized result."""
35
+
36
+
37
+ def create_target_adapter(
38
+ target: TargetRef,
39
+ *,
40
+ timeout_seconds: int,
41
+ evidence_store: EvidenceStore | None = None,
42
+ ) -> TargetAdapter:
43
+ """Route a target reference to its protocol adapter."""
44
+
45
+ if target.kind is TargetKind.A2A:
46
+ from .a2a_adapter import A2ATargetAdapter
47
+
48
+ return A2ATargetAdapter(timeout_seconds=timeout_seconds)
49
+ if target.kind is TargetKind.LOCAL_SOURCE:
50
+ from .local_adapter import LocalSourceTargetAdapter
51
+
52
+ return LocalSourceTargetAdapter(
53
+ timeout_seconds=timeout_seconds,
54
+ evidence_store=evidence_store,
55
+ )
56
+ raise EvaluationNotImplementedError(
57
+ f"{target.kind.value} target 的评测执行尚未实现;"
58
+ "当前可使用 --validate-only 校验评测集和参数"
59
+ )
60
+
61
+
62
+ __all__ = [
63
+ "EvaluationNotImplementedError",
64
+ "TargetAdapterError",
65
+ "TargetAdapter",
66
+ "create_target_adapter",
67
+ ]