agentengine-sdk-python 0.7.0__py3-none-any.whl → 0.8.1__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 (450) hide show
  1. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/METADATA +52 -20
  2. agentengine_sdk_python-0.8.1.dist-info/RECORD +644 -0
  3. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/WHEEL +1 -1
  4. ksadk/a2a/__init__.py +180 -11
  5. ksadk/a2a/bootstrap.py +332 -0
  6. ksadk/a2a/card.py +15 -0
  7. ksadk/a2a/context_store.py +203 -0
  8. ksadk/a2a/control_plane.py +1056 -0
  9. ksadk/a2a/credential.py +99 -0
  10. ksadk/a2a/event_adapter.py +149 -0
  11. ksadk/a2a/executor.py +361 -137
  12. ksadk/a2a/external_transport.py +516 -0
  13. ksadk/a2a/identity.py +304 -0
  14. ksadk/a2a/ids.py +22 -0
  15. ksadk/a2a/langgraph.py +285 -0
  16. ksadk/a2a/resume_store.py +201 -0
  17. ksadk/a2a/routes.py +112 -0
  18. ksadk/a2a/server.py +102 -62
  19. ksadk/a2a/service_env.py +33 -0
  20. ksadk/a2a/space_client.py +1122 -0
  21. ksadk/a2a/task_adapter.py +423 -0
  22. ksadk/a2a/task_event_dispatcher.py +167 -0
  23. ksadk/a2a/task_event_outbox.py +326 -0
  24. ksadk/a2a/task_store.py +206 -0
  25. ksadk/a2a_card.py +101 -0
  26. ksadk/a2ui/__init__.py +27 -0
  27. ksadk/a2ui/core.py +186 -0
  28. ksadk/a2ui/models.py +166 -0
  29. ksadk/a2ui/renderer.py +198 -0
  30. ksadk/agui/__init__.py +9 -0
  31. ksadk/agui/a2ui_projection.py +92 -0
  32. ksadk/agui/agent.py +872 -0
  33. ksadk/agui/config.py +92 -0
  34. ksadk/agui/routes.py +47 -0
  35. ksadk/api/client.py +238 -204
  36. ksadk/api/environment.py +27 -0
  37. ksadk/builders/__init__.py +2 -0
  38. ksadk/builders/base.py +16 -14
  39. ksadk/builders/code_builder.py +375 -270
  40. ksadk/builders/container_builder.py +240 -200
  41. ksadk/builders/framework_requirements.py +31 -12
  42. ksadk/builders/ks3_uploader.py +60 -29
  43. ksadk/builders/managed_runtime_builder.py +173 -0
  44. ksadk/builders/mcp_builder.py +91 -92
  45. ksadk/builders/requirements_utils.py +1 -5
  46. ksadk/cli/__init__.py +97 -171
  47. ksadk/cli/cmd_a2a.py +255 -84
  48. ksadk/cli/cmd_agent.py +19 -5
  49. ksadk/cli/cmd_build.py +158 -29
  50. ksadk/cli/cmd_completion.py +47 -35
  51. ksadk/cli/cmd_config.py +267 -198
  52. ksadk/cli/cmd_create.py +507 -740
  53. ksadk/cli/cmd_dashboard.py +120 -45
  54. ksadk/cli/cmd_deploy.py +135 -59
  55. ksadk/cli/cmd_destroy.py +44 -14
  56. ksadk/cli/cmd_eval.py +386 -0
  57. ksadk/cli/cmd_files.py +63 -24
  58. ksadk/cli/cmd_hermes.py +313 -135
  59. ksadk/cli/cmd_invoke.py +184 -122
  60. ksadk/cli/cmd_launch.py +76 -28
  61. ksadk/cli/cmd_mcp.py +98 -64
  62. ksadk/cli/cmd_model.py +14 -5
  63. ksadk/cli/cmd_openclaw.py +564 -268
  64. ksadk/cli/cmd_replay.py +71 -0
  65. ksadk/cli/cmd_run.py +58 -73
  66. ksadk/cli/cmd_status.py +80 -31
  67. ksadk/cli/cmd_studio.py +110 -0
  68. ksadk/cli/cmd_version.py +20 -13
  69. ksadk/cli/cmd_web.py +95 -18
  70. ksadk/cli/deploy_utils.py +20 -20
  71. ksadk/cli/dry_run.py +7 -4
  72. ksadk/cli/env_options.py +83 -0
  73. ksadk/cli/error_utils.py +37 -12
  74. ksadk/cli/global_options.py +4 -3
  75. ksadk/cli/local_runtime.py +1 -2
  76. ksadk/cli/model_catalog.py +6 -2
  77. ksadk/cli/network_options.py +41 -19
  78. ksadk/cli/resource_common.py +6 -2
  79. ksadk/cli/runtime_bootstrap.py +51 -0
  80. ksadk/cli/storage.py +0 -1
  81. ksadk/cli/ui.py +11 -3
  82. ksadk/cli/workflow_common.py +52 -18
  83. ksadk/codex/__init__.py +12 -0
  84. ksadk/codex/client.py +1042 -0
  85. ksadk/codex/phase.py +143 -0
  86. ksadk/codex/runtime.py +940 -0
  87. ksadk/common/aicp_env.py +0 -1
  88. ksadk/common/auth.py +2 -2
  89. ksadk/common/constants.py +1 -3
  90. ksadk/common/kop_client.py +232 -0
  91. ksadk/common/llm_utils.py +17 -13
  92. ksadk/compat/__init__.py +5 -0
  93. ksadk/compat/adk_compat.py +200 -0
  94. ksadk/compat/copilotkit_a2ui.py +330 -0
  95. ksadk/configs/__init__.py +12 -14
  96. ksadk/configs/env_registry.py +661 -116
  97. ksadk/configs/global_config.py +3 -2
  98. ksadk/configs/settings.py +133 -209
  99. ksadk/conversations/__init__.py +85 -92
  100. ksadk/conversations/attachment_storage.py +16 -11
  101. ksadk/conversations/attachments.py +44 -36
  102. ksadk/conversations/compaction_pipeline.py +12 -12
  103. ksadk/conversations/compaction_prompt.py +9 -5
  104. ksadk/conversations/context.py +221 -6
  105. ksadk/conversations/message_projection.py +438 -51
  106. ksadk/conversations/model_context.py +12 -6
  107. ksadk/conversations/model_options.py +0 -1
  108. ksadk/conversations/normalize.py +20 -16
  109. ksadk/conversations/reasoning_markup.py +1 -1
  110. ksadk/conversations/runtime.py +339 -5255
  111. ksadk/conversations/runtime_compaction.py +333 -0
  112. ksadk/conversations/runtime_constants.py +27 -0
  113. ksadk/conversations/runtime_governance.py +185 -0
  114. ksadk/conversations/runtime_input.py +660 -0
  115. ksadk/conversations/runtime_invocation.py +395 -0
  116. ksadk/conversations/runtime_metadata.py +475 -0
  117. ksadk/conversations/runtime_observability.py +367 -0
  118. ksadk/conversations/runtime_payloads.py +272 -0
  119. ksadk/conversations/runtime_persistence.py +440 -0
  120. ksadk/conversations/runtime_preparation.py +426 -0
  121. ksadk/conversations/runtime_resume.py +836 -0
  122. ksadk/conversations/runtime_stream_events.py +902 -0
  123. ksadk/conversations/runtime_streaming.py +700 -0
  124. ksadk/conversations/semantic_summary.py +17 -5
  125. ksadk/conversations/session_title.py +6 -3
  126. ksadk/deployment/__init__.py +15 -16
  127. ksadk/deployment/agent_access.py +12 -23
  128. ksadk/deployment/base.py +51 -38
  129. ksadk/deployment/managed_runtime.py +33 -0
  130. ksadk/deployment/manager.py +85 -71
  131. ksadk/deployment/providers/serverless.py +379 -210
  132. ksadk/deployment/registry.py +38 -32
  133. ksadk/deployment/state.py +11 -11
  134. ksadk/deployment/ui_config.py +1 -1
  135. ksadk/detection/__init__.py +1 -1
  136. ksadk/detection/detector.py +146 -83
  137. ksadk/detection/mcp_detector.py +9 -6
  138. ksadk/evaluation/__init__.py +84 -0
  139. ksadk/evaluation/a2a_adapter.py +444 -0
  140. ksadk/evaluation/adapters.py +54 -0
  141. ksadk/evaluation/contracts.py +409 -0
  142. ksadk/evaluation/evalset.py +351 -0
  143. ksadk/evaluation/evaluators.py +461 -0
  144. ksadk/evaluation/executor.py +118 -0
  145. ksadk/evaluation/storage.py +68 -0
  146. ksadk/evaluation/target.py +73 -0
  147. ksadk/events/__init__.py +25 -0
  148. ksadk/events/parser.py +191 -0
  149. ksadk/events/replay.py +37 -0
  150. ksadk/events/runtime_event.py +273 -0
  151. ksadk/events/store.py +317 -0
  152. ksadk/harness/__init__.py +35 -0
  153. ksadk/harness/app.py +269 -0
  154. ksadk/harness/config.py +181 -0
  155. ksadk/harness/reasoner.py +105 -0
  156. ksadk/harness/runtime.py +364 -0
  157. ksadk/harness/sandbox.py +141 -0
  158. ksadk/harness/tools.py +222 -0
  159. ksadk/hermes_terminal.py +28 -12
  160. ksadk/identity/resolver.py +15 -9
  161. ksadk/ids.py +32 -0
  162. ksadk/knowledge_base/adk_tool.py +1 -1
  163. ksadk/knowledge_base/client.py +38 -33
  164. ksadk/managed_a2a_card.py +160 -0
  165. ksadk/managed_runtime.py +195 -0
  166. ksadk/markdown.py +5 -2
  167. ksadk/mcp_runtime/__init__.py +9 -6
  168. ksadk/memory/__init__.py +1 -1
  169. ksadk/memory/adk/__init__.py +2 -0
  170. ksadk/memory/adk/backends/base_ltm_backend.py +2 -6
  171. ksadk/memory/adk/backends/http_ltm_backend.py +13 -21
  172. ksadk/memory/adk/backends/inmemory_ltm_backend.py +7 -13
  173. ksadk/memory/adk/backends/sdk_ltm_backend.py +36 -36
  174. ksadk/memory/adk/long_term_memory.py +34 -37
  175. ksadk/memory/adk/resilient_session_service.py +4 -5
  176. ksadk/memory/adk/short_term_memory.py +12 -21
  177. ksadk/memory/adk_tool.py +3 -2
  178. ksadk/memory/backends/base.py +19 -19
  179. ksadk/memory/backends/memory.py +24 -25
  180. ksadk/memory/backends/redis.py +31 -30
  181. ksadk/memory/langchain_tool.py +2 -1
  182. ksadk/memory/manager.py +52 -47
  183. ksadk/memory/service.py +16 -6
  184. ksadk/memory/tool.py +4 -0
  185. ksadk/model_policy.py +15 -7
  186. ksadk/model_proxy/__init__.py +51 -0
  187. ksadk/model_proxy/bootstrap.py +80 -0
  188. ksadk/model_proxy/cache.py +165 -0
  189. ksadk/model_proxy/config.py +66 -0
  190. ksadk/model_proxy/demo_webui.py +115 -0
  191. ksadk/model_proxy/detect.py +145 -0
  192. ksadk/model_proxy/gate.py +68 -0
  193. ksadk/model_proxy/namespace.py +201 -0
  194. ksadk/model_proxy/protocol_proxy.py +22 -0
  195. ksadk/model_proxy/server.py +443 -0
  196. ksadk/model_proxy/transform.py +735 -0
  197. ksadk/openclaw_gateway.py +29 -14
  198. ksadk/runners/adk_runner.py +354 -146
  199. ksadk/runners/base_runner.py +71 -29
  200. ksadk/runners/deepagents_runner.py +0 -1
  201. ksadk/runners/factory.py +18 -5
  202. ksadk/runners/langchain_runner.py +29 -742
  203. ksadk/runners/langgraph_runner.py +417 -97
  204. ksadk/runners/patch_langchain.py +16 -16
  205. ksadk/runners/remote_runner.py +134 -33
  206. ksadk/runners/usage_accumulator.py +1 -0
  207. ksadk/runners/utils/__init__.py +0 -10
  208. ksadk/runners/utils/loader.py +23 -7
  209. ksadk/runtime/__init__.py +67 -0
  210. ksadk/runtime/adapter.py +412 -0
  211. ksadk/runtime/conversation_execution.py +553 -0
  212. ksadk/runtime/executor.py +251 -0
  213. ksadk/runtime/factory.py +156 -0
  214. ksadk/runtime/framework_adapters.py +118 -0
  215. ksadk/runtime/launch.py +48 -0
  216. ksadk/runtime/preprocessing.py +131 -0
  217. ksadk/runtime/runner_adapter.py +1032 -0
  218. ksadk/runtime/runner_loading.py +36 -0
  219. ksadk/runtime_context.py +18 -3
  220. ksadk/runtime_state.py +0 -1
  221. ksadk/sandbox/__init__.py +4 -1
  222. ksadk/sandbox/backends/__init__.py +4 -1
  223. ksadk/sandbox/backends/e2b.py +13 -5
  224. ksadk/sandbox/backends/local_process.py +11 -3
  225. ksadk/sandbox/base.py +10 -15
  226. ksadk/sandbox/factory.py +14 -4
  227. ksadk/sandbox/registry.py +57 -6
  228. ksadk/server/__init__.py +39 -4
  229. ksadk/server/api_models.py +15 -5
  230. ksadk/server/app.py +24 -3928
  231. ksadk/server/composition.py +47 -0
  232. ksadk/server/factory.py +622 -0
  233. ksadk/server/routes/__init__.py +1 -0
  234. ksadk/server/routes/checkpoint_resolution.py +116 -0
  235. ksadk/server/routes/common.py +682 -0
  236. ksadk/server/routes/control.py +331 -0
  237. ksadk/server/routes/dependencies.py +98 -0
  238. ksadk/server/routes/misc.py +425 -0
  239. ksadk/server/routes/models.py +451 -0
  240. ksadk/server/routes/openai_compat.py +229 -0
  241. ksadk/server/routes/projection.py +848 -0
  242. ksadk/server/routes/routers.py +52 -0
  243. ksadk/server/routes/run.py +519 -0
  244. ksadk/server/routes/sessions.py +644 -0
  245. ksadk/server/routes/streaming.py +265 -0
  246. ksadk/server/routes/workspace.py +414 -0
  247. ksadk/server/static/assets/{ArtifactsPanel-D-SSn2ee.js → ArtifactsPanel-CakCqxEN.js} +1 -1
  248. ksadk/server/static/assets/CodeBlock-CynLknyO.js +9 -0
  249. ksadk/server/static/assets/MathMessageMarkdown-3sQdOysS.js +8 -0
  250. ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +303 -0
  251. ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +1 -0
  252. ksadk/server/static/assets/{arc-BA13sHc9.js → arc-DrgjcKhl.js} +1 -1
  253. ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +1 -0
  254. ksadk/server/static/assets/{architectureDiagram-3BPJPVTR-DzJzgVoL.js → architectureDiagram-3BPJPVTR-BXoVRbQ6.js} +1 -1
  255. ksadk/server/static/assets/{blockDiagram-GPEHLZMM-UTdVcZhn.js → blockDiagram-GPEHLZMM-BnaB3Ywv.js} +1 -1
  256. ksadk/server/static/assets/{c4Diagram-AAUBKEIU-Dix0GD4m.js → c4Diagram-AAUBKEIU-Dw4weZcp.js} +1 -1
  257. ksadk/server/static/assets/channel-Dt3rQTFI.js +1 -0
  258. ksadk/server/static/assets/{chunk-2J33WTMH-C2JxuZ42.js → chunk-2J33WTMH-ChjpLK7j.js} +1 -1
  259. ksadk/server/static/assets/{chunk-4BX2VUAB-Be57QPgD.js → chunk-4BX2VUAB-B9drTgOW.js} +1 -1
  260. ksadk/server/static/assets/{chunk-55IACEB6-WjSuy4nv.js → chunk-55IACEB6-CK4ROATy.js} +1 -1
  261. ksadk/server/static/assets/{chunk-727SXJPM-BOovP-b5.js → chunk-727SXJPM-B9KtTTgw.js} +1 -1
  262. ksadk/server/static/assets/{chunk-AQP2D5EJ-DOmZNmWj.js → chunk-AQP2D5EJ-1O1mki3m.js} +1 -1
  263. ksadk/server/static/assets/{chunk-FMBD7UC4-DzwlodkU.js → chunk-FMBD7UC4-B_fH2YuH.js} +1 -1
  264. ksadk/server/static/assets/{chunk-ND2GUHAM-DMqAikEU.js → chunk-ND2GUHAM-D6rFLaVV.js} +1 -1
  265. ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +1 -0
  266. ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +1 -0
  267. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +1 -0
  268. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-Zhy2GBnP.js → cose-bilkent-S5V4N54A-ChNs_Mdk.js} +1 -1
  269. ksadk/server/static/assets/{dagre-BM42HDAG-CbKrtIUz.js → dagre-BM42HDAG-D0QXg_MQ.js} +1 -1
  270. ksadk/server/static/assets/{diagram-2AECGRRQ-BRApgQRK.js → diagram-2AECGRRQ-DBDDKwBQ.js} +1 -1
  271. ksadk/server/static/assets/{diagram-5GNKFQAL-D0xbnDiK.js → diagram-5GNKFQAL-BkwDOxmO.js} +1 -1
  272. ksadk/server/static/assets/{diagram-KO2AKTUF-CVugVI9L.js → diagram-KO2AKTUF-Bv8waYvY.js} +1 -1
  273. ksadk/server/static/assets/{diagram-LMA3HP47-DozUGgee.js → diagram-LMA3HP47-e1VECDdu.js} +1 -1
  274. ksadk/server/static/assets/{diagram-OG6HWLK6-ZOYsKlru.js → diagram-OG6HWLK6-Ds9adfRl.js} +1 -1
  275. ksadk/server/static/assets/{dist-DpKtt4Bo.js → dist-4N2NMVYg.js} +1 -1
  276. ksadk/server/static/assets/{dist-CkEKJFtk.js → dist-B-jNR6Vn.js} +1 -1
  277. ksadk/server/static/assets/{dist-D57wnGWd.js → dist-B5J2uhNk.js} +1 -1
  278. ksadk/server/static/assets/{dist-8_SfK1IP.js → dist-B5oS1zcj.js} +1 -1
  279. ksadk/server/static/assets/{dist-DMezvBGJ.js → dist-BB3-OwTQ.js} +1 -1
  280. ksadk/server/static/assets/{dist-2hInLS_J.js → dist-BIlKoW0k.js} +1 -1
  281. ksadk/server/static/assets/{dist-BrCcQ47T.js → dist-BjOdlDjj.js} +1 -1
  282. ksadk/server/static/assets/{dist-BmlMPsCc.js → dist-C1sz5Eo3.js} +1 -1
  283. ksadk/server/static/assets/{dist-B0NP_Z0z.js → dist-CWV4lDr1.js} +1 -1
  284. ksadk/server/static/assets/{dist-D-xOD048.js → dist-CmZHzlwZ.js} +1 -1
  285. ksadk/server/static/assets/{dist-DL_NKc_z.js → dist-D6MpCZtz.js} +1 -1
  286. ksadk/server/static/assets/{dist-DyOkZmze.js → dist-DJN_6Y39.js} +1 -1
  287. ksadk/server/static/assets/{dist-DmFaq_Iy.js → dist-DQU9EWw-.js} +1 -1
  288. ksadk/server/static/assets/{dist-gX6GOLKq.js → dist-DWKByxWV.js} +1 -1
  289. ksadk/server/static/assets/{dist-DyWsb78Q.js → dist-Dli7qW-B.js} +1 -1
  290. ksadk/server/static/assets/{dist-BIJVDMuB.js → dist-DsHPdk3W.js} +1 -1
  291. ksadk/server/static/assets/{dist-Dp0k7bWI.js → dist-X4TnqwOK.js} +1 -1
  292. ksadk/server/static/assets/{dist-8EEyGgDx.js → dist-_pHPTyZ-.js} +1 -1
  293. ksadk/server/static/assets/{dist-CPBtqRTW.js → dist-fhOuWds5.js} +1 -1
  294. ksadk/server/static/assets/{dist-D-JMdWPQ.js → dist-gLnrGsoU.js} +1 -1
  295. ksadk/server/static/assets/{dist-BssVmjIo.js → dist-j6Dxmf_j.js} +1 -1
  296. ksadk/server/static/assets/{dist-C3HIIaN5.js → dist-o2OVmKvt.js} +1 -1
  297. ksadk/server/static/assets/{erDiagram-TEJ5UH35-Bk-9bgE5.js → erDiagram-TEJ5UH35-BPItFKH6.js} +1 -1
  298. ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +1 -0
  299. ksadk/server/static/assets/{flowDiagram-I6XJVG4X-Dn9kZVuZ.js → flowDiagram-I6XJVG4X-BbYB9w5Y.js} +1 -1
  300. ksadk/server/static/assets/{ganttDiagram-6RSMTGT7-BGxXlJqm.js → ganttDiagram-6RSMTGT7-TQXa0KXv.js} +1 -1
  301. ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +1 -0
  302. ksadk/server/static/assets/{gitGraphDiagram-PVQCEYII-C7Q0X-wi.js → gitGraphDiagram-PVQCEYII-bKblCnpa.js} +1 -1
  303. ksadk/server/static/assets/index-R52pJJvg.js +177 -0
  304. ksadk/server/static/assets/index-jJr3_955.css +2 -0
  305. ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +1 -0
  306. ksadk/server/static/assets/{infoDiagram-5YYISTIA-BO_CSqq5.js → infoDiagram-5YYISTIA-BGVT7J_i.js} +1 -1
  307. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-eYLPLd46.js → ishikawaDiagram-YF4QCWOH-K0OOfVna.js} +1 -1
  308. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-De9geSb0.js → journeyDiagram-JHISSGLW-8LeOJaZp.js} +1 -1
  309. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-Cs80kQto.js → kanban-definition-UN3LZRKU-C6uCgZrW.js} +1 -1
  310. ksadk/server/static/assets/{katex-DSrCFD8n.js → katex-CYWseY5E.js} +1 -1
  311. ksadk/server/static/assets/{linear-CN9sbKTF.js → linear-hdBcYzM8.js} +1 -1
  312. ksadk/server/static/assets/{mermaid-parser.core-DlgSBU8l.js → mermaid-parser.core-BWrDjSZM.js} +2 -2
  313. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-9afz7Oug.js → mindmap-definition-RKZ34NQL-Bjy_2v4_.js} +1 -1
  314. ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +1 -0
  315. ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +1 -0
  316. ksadk/server/static/assets/{pieDiagram-4H26LBE5-DPv_VstN.js → pieDiagram-4H26LBE5-GmmqNiVH.js} +1 -1
  317. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-o77wZ1XK.js → quadrantDiagram-W4KKPZXB-BmkRbwCg.js} +1 -1
  318. ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +1 -0
  319. ksadk/server/static/assets/{requirementDiagram-4Y6WPE33-BYVw81VC.js → requirementDiagram-4Y6WPE33-DSWFqL7c.js} +1 -1
  320. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-B7nZFMKT.js → sankeyDiagram-5OEKKPKP-l6iXmU65.js} +1 -1
  321. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-BGRRrFw5.js → sequenceDiagram-3UESZ5HK-Cq6UBeQB.js} +1 -1
  322. ksadk/server/static/assets/{stateDiagram-AJRCARHV-BUfHCoPs.js → stateDiagram-AJRCARHV-qzTQpg3Y.js} +1 -1
  323. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +1 -0
  324. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-FbCTGrf9.js → timeline-definition-PNZ67QCA-DEz24vV0.js} +1 -1
  325. ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +1 -0
  326. ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +1 -0
  327. ksadk/server/static/assets/{vennDiagram-CIIHVFJN-DWgwtPsJ.js → vennDiagram-CIIHVFJN-CMCixki2.js} +1 -1
  328. ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +1 -0
  329. ksadk/server/static/assets/{wardleyDiagram-YWT4CUSO-2x8G-tTM.js → wardleyDiagram-YWT4CUSO-CVzB8F9K.js} +1 -1
  330. ksadk/server/static/assets/{xychartDiagram-2RQKCTM6-Drma3AYl.js → xychartDiagram-2RQKCTM6-BFBqBLc1.js} +1 -1
  331. ksadk/server/static/index.html +2 -2
  332. ksadk/server/terminal_sessions.py +111 -58
  333. ksadk/sessions/__init__.py +69 -19
  334. ksadk/sessions/base.py +31 -11
  335. ksadk/sessions/continuity.py +2 -3
  336. ksadk/sessions/in_memory.py +46 -2
  337. ksadk/sessions/local_service.py +148 -17
  338. ksadk/sessions/postgres_service.py +143 -25
  339. ksadk/sessions/resilient.py +36 -8
  340. ksadk/skills/models.py +17 -5
  341. ksadk/skills/package_store.py +5 -2
  342. ksadk/skills/runtime/agent.py +20 -5
  343. ksadk/skills/runtime/artifacts.py +1 -5
  344. ksadk/skills/runtime/backends/e2b.py +10 -4
  345. ksadk/skills/runtime/backends/local.py +15 -3
  346. ksadk/skills/runtime/base.py +1 -2
  347. ksadk/skills/runtime/executor.py +10 -3
  348. ksadk/skills/runtime/factory.py +4 -2
  349. ksadk/skills/runtime/loader.py +1 -2
  350. ksadk/skills/runtime/registry.py +15 -10
  351. ksadk/skills/runtime/request.py +3 -1
  352. ksadk/skills/service_client.py +47 -16
  353. ksadk/skills/tool_defs.py +15 -10
  354. ksadk/studio/__init__.py +5 -0
  355. ksadk/studio/agent_avatar_assets.py +120 -0
  356. ksadk/studio/agent_lifecycle.py +51 -0
  357. ksadk/studio/api.py +1046 -0
  358. ksadk/studio/api_catalog_routes.py +324 -0
  359. ksadk/studio/api_contracts.py +177 -0
  360. ksadk/studio/api_helpers.py +132 -0
  361. ksadk/studio/authoring.py +524 -0
  362. ksadk/studio/authoring_coordinator.py +285 -0
  363. ksadk/studio/builder.py +320 -0
  364. ksadk/studio/capabilities.py +351 -0
  365. ksadk/studio/cloud.py +278 -0
  366. ksadk/studio/codex_agent_service.py +583 -0
  367. ksadk/studio/codex_builder.py +324 -0
  368. ksadk/studio/codex_manifest.py +278 -0
  369. ksadk/studio/codex_run.py +352 -0
  370. ksadk/studio/compiler.py +189 -0
  371. ksadk/studio/contracts.py +644 -0
  372. ksadk/studio/errors.py +47 -0
  373. ksadk/studio/evaluation.py +192 -0
  374. ksadk/studio/event_store.py +284 -0
  375. ksadk/studio/framework_run.py +114 -0
  376. ksadk/studio/identifiers.py +33 -0
  377. ksadk/studio/mcp_runtime.py +229 -0
  378. ksadk/studio/model_client.py +543 -0
  379. ksadk/studio/model_profile_service.py +214 -0
  380. ksadk/studio/operations.py +243 -0
  381. ksadk/studio/otel_trace.py +754 -0
  382. ksadk/studio/pagination.py +182 -0
  383. ksadk/studio/python_tool_inspection.py +183 -0
  384. ksadk/studio/repository.py +306 -0
  385. ksadk/studio/resource_catalog.py +1217 -0
  386. ksadk/studio/run_service.py +707 -0
  387. ksadk/studio/runtime_catalog.py +74 -0
  388. ksadk/studio/runtime_source.py +339 -0
  389. ksadk/studio/service.py +1141 -0
  390. ksadk/studio/shared_web.py +994 -0
  391. ksadk/studio/skill_discovery.py +628 -0
  392. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
  393. ksadk/studio/static/assets/index-CaEN0eTR.css +1 -0
  394. ksadk/studio/static/assets/index-DI2eY_NH.js +252 -0
  395. ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
  396. ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
  397. ksadk/studio/static/index.html +15 -0
  398. ksadk/studio/templates.py +630 -0
  399. ksadk/studio/validator.py +246 -0
  400. ksadk/studio/workspace.py +137 -0
  401. ksadk/terminal_exec_policy.py +3 -4
  402. ksadk/tools/gateway.py +101 -15
  403. ksadk/tools/result_budget.py +12 -4
  404. ksadk/toolsets/__init__.py +161 -37
  405. ksadk/toolsets/a2a.py +426 -0
  406. ksadk/toolsets/platform.py +21 -5
  407. ksadk/toolsets/sandbox.py +82 -16
  408. ksadk/toolsets/skills.py +200 -39
  409. ksadk/toolsets/web.py +123 -26
  410. ksadk/toolsets/workspace.py +212 -101
  411. ksadk/tracing/__init__.py +19 -21
  412. ksadk/tracing/exporters/inmemory_exporter.py +62 -51
  413. ksadk/tracing/setup.py +135 -506
  414. ksadk/tracing/span_utils.py +0 -41
  415. ksadk/tui/loop.py +78 -30
  416. ksadk/tui/stream_render.py +1 -0
  417. ksadk/ui_config.py +5 -3
  418. ksadk/version.py +1 -1
  419. ksadk_runtime_common/memory_backend/registry.py +56 -56
  420. ksadk_runtime_common/schemas/runtime_event_v1.json +95 -0
  421. ksadk_runtime_common/workspace_files/router.py +8 -2
  422. agentengine_sdk_python-0.7.0.dist-info/RECORD +0 -482
  423. ksadk/a2a/card_builder.py +0 -64
  424. ksadk/a2a/client.py +0 -309
  425. ksadk/runners/utils/langfuse.py +0 -230
  426. ksadk/server/static/assets/CodeBlock-P16VOLYi.js +0 -9
  427. ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +0 -8
  428. ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +0 -303
  429. ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +0 -1
  430. ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +0 -1
  431. ksadk/server/static/assets/channel-CTuydARX.js +0 -1
  432. ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +0 -1
  433. ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +0 -1
  434. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +0 -1
  435. ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +0 -1
  436. ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +0 -1
  437. ksadk/server/static/assets/index-C00Lwg3L.js +0 -165
  438. ksadk/server/static/assets/index-DAURbCsP.css +0 -1
  439. ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +0 -1
  440. ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +0 -1
  441. ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +0 -1
  442. ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +0 -1
  443. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +0 -1
  444. ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +0 -1
  445. ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +0 -1
  446. ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +0 -1
  447. ksadk/tracing/exporters/langfuse_exporter.py +0 -445
  448. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/entry_points.txt +0 -0
  449. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/licenses/LICENSE +0 -0
  450. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,84 @@
1
+ """Public contracts and file loading for local Agent evaluation."""
2
+
3
+ from .a2a_adapter import A2ATargetAdapter, A2ATargetError
4
+ from .adapters import (
5
+ EvaluationNotImplementedError,
6
+ TargetAdapter,
7
+ TargetAdapterError,
8
+ create_target_adapter,
9
+ )
10
+ from .contracts import (
11
+ AssertionSpec,
12
+ AssertionType,
13
+ CaseRun,
14
+ DataPolicy,
15
+ EvalCase,
16
+ EvalRunReport,
17
+ EvalRunSpec,
18
+ EvalRunStatus,
19
+ EvalRunSummary,
20
+ EvalSetVersion,
21
+ EvalTurn,
22
+ EvaluationConfig,
23
+ EvaluationRequest,
24
+ MetricResult,
25
+ MetricStatus,
26
+ TargetKind,
27
+ TargetRef,
28
+ TargetRun,
29
+ TargetRunStatus,
30
+ TargetSnapshot,
31
+ TraceRef,
32
+ UsageSnapshot,
33
+ )
34
+ from .evalset import (
35
+ EvalSetFormat,
36
+ EvalSetParseError,
37
+ identify_evalset_format,
38
+ load_evalset,
39
+ parse_evalset,
40
+ )
41
+ from .executor import EvaluationExecutionError, execute_evaluation
42
+ from .storage import EvaluationStorage, EvaluationStorageError
43
+ from .target import EvaluationTarget
44
+
45
+ __all__ = [
46
+ "AssertionSpec",
47
+ "AssertionType",
48
+ "A2ATargetAdapter",
49
+ "A2ATargetError",
50
+ "CaseRun",
51
+ "DataPolicy",
52
+ "EvalCase",
53
+ "EvalRunReport",
54
+ "EvalRunSummary",
55
+ "EvalRunSpec",
56
+ "EvalRunStatus",
57
+ "EvalSetFormat",
58
+ "EvalSetParseError",
59
+ "EvalSetVersion",
60
+ "EvalTurn",
61
+ "EvaluationConfig",
62
+ "EvaluationExecutionError",
63
+ "EvaluationNotImplementedError",
64
+ "EvaluationRequest",
65
+ "EvaluationStorage",
66
+ "EvaluationStorageError",
67
+ "EvaluationTarget",
68
+ "MetricResult",
69
+ "MetricStatus",
70
+ "TargetKind",
71
+ "TargetAdapter",
72
+ "TargetAdapterError",
73
+ "TargetRun",
74
+ "TargetRunStatus",
75
+ "TargetSnapshot",
76
+ "TargetRef",
77
+ "TraceRef",
78
+ "UsageSnapshot",
79
+ "identify_evalset_format",
80
+ "load_evalset",
81
+ "parse_evalset",
82
+ "execute_evaluation",
83
+ "create_target_adapter",
84
+ ]
@@ -0,0 +1,444 @@
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
+ self.artifact_chunks.append(text)
97
+
98
+ if response.message:
99
+ self.task_id = response.message.task_id or self.task_id
100
+ self.context_id = response.message.context_id or self.context_id
101
+ self.direct_output = _message_text(response.message) or self.direct_output
102
+
103
+ @property
104
+ def output(self) -> str:
105
+ return (
106
+ self.task_output
107
+ or "".join(self.artifact_chunks)
108
+ or self.status_output
109
+ or self.direct_output
110
+ )
111
+
112
+
113
+ @dataclass(frozen=True)
114
+ class _TurnResult:
115
+ status: TargetRunStatus
116
+ output: str
117
+ task_id: str | None
118
+ context_id: str | None
119
+ task_state: int
120
+ error_code: str | None = None
121
+ error_message: str | None = None
122
+
123
+
124
+ def _new_http_client(*, headers: dict[str, str], timeout_seconds: int) -> httpx.AsyncClient:
125
+ return httpx.AsyncClient(
126
+ headers=headers,
127
+ timeout=httpx.Timeout(timeout_seconds),
128
+ follow_redirects=False,
129
+ )
130
+
131
+
132
+ class A2ATargetAdapter:
133
+ """Execute evaluation cases through the official A2A 1.0 client."""
134
+
135
+ kind = TargetKind.A2A
136
+
137
+ def __init__(self, *, timeout_seconds: int) -> None:
138
+ self._timeout_seconds = timeout_seconds
139
+ self._card: AgentCard | None = None
140
+ self._headers: dict[str, str] = {}
141
+
142
+ async def snapshot(self, target: TargetRef) -> TargetSnapshot:
143
+ if target.kind is not self.kind:
144
+ raise A2ATargetError("A2A_TARGET_KIND_INVALID", "A2A adapter 收到非 A2A target")
145
+
146
+ location = _card_location(target.locator)
147
+ headers = _credential_headers(target.credential_ref)
148
+ try:
149
+ async with _new_http_client(
150
+ headers=headers,
151
+ timeout_seconds=self._timeout_seconds,
152
+ ) as http_client:
153
+ resolver = A2ACardResolver(
154
+ httpx_client=http_client,
155
+ base_url=location.base_url,
156
+ )
157
+ card = await resolver.get_agent_card(
158
+ relative_card_path=location.relative_path,
159
+ )
160
+ client = await create_client(
161
+ agent=card,
162
+ client_config=ClientConfig(
163
+ httpx_client=http_client,
164
+ streaming=True,
165
+ supported_protocol_bindings=_SUPPORTED_BINDINGS,
166
+ ),
167
+ )
168
+ await client.close()
169
+ except AgentCardResolutionError as exc:
170
+ raise A2ATargetError(
171
+ "A2A_CARD_UNAVAILABLE",
172
+ "无法读取或校验 A2A Agent Card",
173
+ ) from exc
174
+ except (A2AClientError, httpx.HTTPError, ValueError) as exc:
175
+ raise A2ATargetError(
176
+ "A2A_PROTOCOL_UNAVAILABLE",
177
+ "A2A Agent Card 没有可用的协议接口",
178
+ ) from exc
179
+
180
+ digest = _agent_card_digest(card)
181
+ self._card = card
182
+ self._headers = headers
183
+ return TargetSnapshot(
184
+ kind=self.kind,
185
+ entrypoint=target.locator,
186
+ revision_digest=f"sha256:{digest}",
187
+ runtime="a2a/1.0",
188
+ metadata={
189
+ "agentName": card.name,
190
+ "agentVersion": card.version,
191
+ "credentialRef": target.credential_ref,
192
+ "supportedInterfaces": [
193
+ {
194
+ "protocolBinding": interface.protocol_binding,
195
+ "protocolVersion": interface.protocol_version,
196
+ }
197
+ for interface in card.supported_interfaces
198
+ ],
199
+ },
200
+ )
201
+
202
+ async def run_case(
203
+ self,
204
+ spec: EvalRunSpec,
205
+ case: EvalCase,
206
+ *,
207
+ attempt: int,
208
+ ) -> TargetRun:
209
+ del spec, attempt
210
+ if self._card is None:
211
+ raise RuntimeError("A2A target must be snapshotted before execution")
212
+
213
+ started_at = time.perf_counter()
214
+ task_ids: list[str] = []
215
+ context_id: str | None = None
216
+ final_output = ""
217
+ last_state = TaskState.TASK_STATE_UNSPECIFIED
218
+
219
+ try:
220
+ async with _new_http_client(
221
+ headers=self._headers,
222
+ timeout_seconds=self._timeout_seconds,
223
+ ) as http_client:
224
+ client = await create_client(
225
+ agent=self._card,
226
+ client_config=ClientConfig(
227
+ httpx_client=http_client,
228
+ streaming=True,
229
+ supported_protocol_bindings=_SUPPORTED_BINDINGS,
230
+ ),
231
+ )
232
+ try:
233
+ for turn in case.turns:
234
+ result = await self._run_turn(client, turn.input, context_id)
235
+ context_id = result.context_id or context_id
236
+ last_state = result.task_state
237
+ if result.task_id:
238
+ task_ids.append(result.task_id)
239
+ if result.output:
240
+ final_output = result.output
241
+ if result.status != TargetRunStatus.PASSED:
242
+ return _target_run(
243
+ result.status,
244
+ started_at=started_at,
245
+ output=final_output,
246
+ task_ids=task_ids,
247
+ context_id=context_id,
248
+ task_state=last_state,
249
+ error_code=result.error_code,
250
+ error_message=result.error_message,
251
+ )
252
+ finally:
253
+ await client.close()
254
+ except A2AClientTimeoutError:
255
+ return _target_run(
256
+ TargetRunStatus.ERROR,
257
+ started_at=started_at,
258
+ task_ids=task_ids,
259
+ context_id=context_id,
260
+ task_state=last_state,
261
+ error_code="A2A_NETWORK_TIMEOUT",
262
+ error_message="A2A 请求超时",
263
+ )
264
+ except (A2AClientError, httpx.HTTPError, ValueError):
265
+ return _target_run(
266
+ TargetRunStatus.ERROR,
267
+ started_at=started_at,
268
+ task_ids=task_ids,
269
+ context_id=context_id,
270
+ task_state=last_state,
271
+ error_code="A2A_PROTOCOL_ERROR",
272
+ error_message="A2A 请求或响应不符合协议",
273
+ )
274
+
275
+ return _target_run(
276
+ TargetRunStatus.PASSED,
277
+ started_at=started_at,
278
+ output=final_output,
279
+ task_ids=task_ids,
280
+ context_id=context_id,
281
+ task_state=last_state,
282
+ )
283
+
284
+ async def _run_turn(self, client: object, text: str, context_id: str | None) -> _TurnResult:
285
+ collector = _ResponseCollector(context_id=context_id)
286
+ request = _build_send_request(text, context_id)
287
+ try:
288
+ async for response in client.send_message(request): # type: ignore[attr-defined]
289
+ collector.observe(response)
290
+ except asyncio.CancelledError:
291
+ if collector.task_id:
292
+ with suppress(Exception):
293
+ await client.cancel_task( # type: ignore[attr-defined]
294
+ CancelTaskRequest(id=collector.task_id)
295
+ )
296
+ raise
297
+
298
+ status, error_code, error_message = _task_result(collector)
299
+ return _TurnResult(
300
+ status=status,
301
+ output=collector.output,
302
+ task_id=collector.task_id,
303
+ context_id=collector.context_id,
304
+ task_state=collector.state,
305
+ error_code=error_code,
306
+ error_message=error_message,
307
+ )
308
+
309
+
310
+ def _build_send_request(
311
+ text: str,
312
+ context_id: str | None,
313
+ ) -> SendMessageRequest:
314
+ return SendMessageRequest(
315
+ message=Message(
316
+ role=Role.ROLE_USER,
317
+ parts=[Part(text=text)],
318
+ message_id=f"eval-message-{uuid4().hex}",
319
+ context_id=context_id or "",
320
+ ),
321
+ configuration=SendMessageConfiguration(return_immediately=False),
322
+ )
323
+
324
+ def _card_location(locator: str) -> _CardLocation:
325
+ parsed = urlsplit(locator)
326
+ if parsed.scheme not in {"http", "https"} or not parsed.hostname:
327
+ raise A2ATargetError(
328
+ "A2A_URL_INVALID",
329
+ "A2A target 必须是有效的 http 或 https URL",
330
+ )
331
+ if parsed.username or parsed.password or parsed.fragment:
332
+ raise A2ATargetError(
333
+ "A2A_URL_INVALID",
334
+ "A2A target URL 不能包含用户凭据或 fragment",
335
+ )
336
+
337
+ marker = "/.well-known/"
338
+ if marker not in parsed.path:
339
+ return _CardLocation(locator.rstrip("/"), None)
340
+
341
+ base_path, card_name = parsed.path.split(marker, 1)
342
+ base_url = urlunsplit((parsed.scheme, parsed.netloc, base_path.rstrip("/"), "", ""))
343
+ relative_path = f".well-known/{card_name}"
344
+ if parsed.query:
345
+ relative_path = f"{relative_path}?{parsed.query}"
346
+ return _CardLocation(base_url, relative_path)
347
+
348
+
349
+ def _credential_headers(reference: str | None) -> dict[str, str]:
350
+ if not reference:
351
+ return {}
352
+ if not reference.startswith("env://"):
353
+ raise A2ATargetError(
354
+ "A2A_CREDENTIAL_REF_UNSUPPORTED",
355
+ "本地 A2A 评测当前只支持 env:// 鉴权引用",
356
+ )
357
+
358
+ name = reference.removeprefix("env://")
359
+ if not name or any(char not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" for char in name):
360
+ raise A2ATargetError(
361
+ "A2A_CREDENTIAL_REF_INVALID",
362
+ "A2A env:// 鉴权引用格式无效",
363
+ )
364
+ token = os.environ.get(name)
365
+ if not token:
366
+ raise A2ATargetError(
367
+ "A2A_CREDENTIAL_NOT_FOUND",
368
+ "A2A 鉴权引用尚未配置",
369
+ )
370
+ if len(token) > 16_384 or token != token.strip() or any(ord(char) < 32 for char in token):
371
+ raise A2ATargetError(
372
+ "A2A_CREDENTIAL_INVALID",
373
+ "A2A 鉴权值格式无效",
374
+ )
375
+ return {"Authorization": f"Bearer {token}"}
376
+
377
+
378
+ def _agent_card_digest(card: AgentCard) -> str:
379
+ payload = MessageToDict(card, preserving_proto_field_name=False)
380
+ encoded = json.dumps(payload, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
381
+ return hashlib.sha256(encoded.encode("utf-8")).hexdigest()
382
+
383
+
384
+ def _message_text(message: Message) -> str:
385
+ return _parts_text(message.parts) if message else ""
386
+
387
+
388
+ def _parts_text(parts: object) -> str:
389
+ return "".join(part.text for part in parts if part.text) # type: ignore[attr-defined]
390
+
391
+
392
+ def _task_result(
393
+ collector: _ResponseCollector,
394
+ ) -> tuple[TargetRunStatus, str | None, str | None]:
395
+ if collector.state == TaskState.TASK_STATE_CANCELED:
396
+ return TargetRunStatus.CANCELLED, "A2A_TASK_CANCELLED", "远端 A2A Task 已取消"
397
+ if collector.state in _TERMINAL_FAILURES:
398
+ code, message = _TERMINAL_FAILURES[collector.state]
399
+ return TargetRunStatus.FAILED, code, message
400
+ if collector.state in {
401
+ TaskState.TASK_STATE_SUBMITTED,
402
+ TaskState.TASK_STATE_WORKING,
403
+ }:
404
+ return (
405
+ TargetRunStatus.ERROR,
406
+ "A2A_TASK_INCOMPLETE",
407
+ "A2A 响应结束时 Task 尚未进入终态",
408
+ )
409
+ if collector.state == TaskState.TASK_STATE_COMPLETED or collector.output:
410
+ return TargetRunStatus.PASSED, None, None
411
+ return TargetRunStatus.UNAVAILABLE, "A2A_OUTPUT_UNAVAILABLE", "A2A 响应未提供文本结果"
412
+
413
+
414
+ def _target_run(
415
+ status: TargetRunStatus,
416
+ *,
417
+ started_at: float,
418
+ output: str = "",
419
+ task_ids: list[str],
420
+ context_id: str | None,
421
+ task_state: int,
422
+ error_code: str | None = None,
423
+ error_message: str | None = None,
424
+ ) -> TargetRun:
425
+ metadata: dict[str, object] = {"remoteTaskIds": task_ids}
426
+ if context_id:
427
+ metadata["remoteContextId"] = context_id
428
+ if task_state != TaskState.TASK_STATE_UNSPECIFIED:
429
+ metadata["taskState"] = _task_state_name(task_state)
430
+ return TargetRun(
431
+ status=status,
432
+ output=output,
433
+ duration_ms=max(0, round((time.perf_counter() - started_at) * 1000)),
434
+ error_code=error_code,
435
+ error_message=error_message,
436
+ metadata=metadata,
437
+ )
438
+
439
+
440
+ def _task_state_name(state: int) -> str:
441
+ try:
442
+ return TaskState.Name(state)
443
+ except ValueError:
444
+ return str(state)
@@ -0,0 +1,54 @@
1
+ """Target-kind routing for evaluation adapters."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Protocol
6
+
7
+ from .contracts import EvalCase, EvalRunSpec, TargetKind, TargetRef, TargetRun, TargetSnapshot
8
+
9
+
10
+ class TargetAdapterError(RuntimeError):
11
+ """Classified failure raised by a protocol adapter."""
12
+
13
+ def __init__(self, code: str, message: str) -> None:
14
+ self.code = code
15
+ super().__init__(message)
16
+
17
+
18
+ class EvaluationNotImplementedError(NotImplementedError):
19
+ """Raised when a target kind has no evaluation adapter yet."""
20
+
21
+
22
+ class TargetAdapter(Protocol):
23
+ """Protocol-specific execution behind the common target lifecycle."""
24
+
25
+ kind: TargetKind
26
+
27
+ async def snapshot(self, target: TargetRef) -> TargetSnapshot:
28
+ """Resolve a target into an immutable snapshot."""
29
+
30
+ async def run_case(
31
+ self, spec: EvalRunSpec, case: EvalCase, *, attempt: int
32
+ ) -> TargetRun:
33
+ """Execute one case and return its normalized result."""
34
+
35
+
36
+ def create_target_adapter(target: TargetRef, *, timeout_seconds: int) -> TargetAdapter:
37
+ """Route a target reference to its protocol adapter."""
38
+
39
+ if target.kind is TargetKind.A2A:
40
+ from .a2a_adapter import A2ATargetAdapter
41
+
42
+ return A2ATargetAdapter(timeout_seconds=timeout_seconds)
43
+ raise EvaluationNotImplementedError(
44
+ f"{target.kind.value} target 的评测执行尚未实现;"
45
+ "当前可使用 --validate-only 校验评测集和参数"
46
+ )
47
+
48
+
49
+ __all__ = [
50
+ "EvaluationNotImplementedError",
51
+ "TargetAdapterError",
52
+ "TargetAdapter",
53
+ "create_target_adapter",
54
+ ]