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
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import asyncio
5
6
  import base64
6
7
  import binascii
7
8
  import errno
@@ -9,6 +10,7 @@ import json
9
10
  import os
10
11
  import stat
11
12
  import time
13
+ import uuid
12
14
  from abc import ABC, abstractmethod
13
15
  from dataclasses import dataclass, field
14
16
  from pathlib import Path
@@ -19,6 +21,7 @@ from a2a.types import AgentCard
19
21
  from google.protobuf.json_format import ParseDict, ParseError
20
22
 
21
23
  from ksadk.a2a.ids import require_a2a_resource_id
24
+ from ksadk.common.kop_client import KOPClient, KOPError
22
25
 
23
26
  ENV_A2A_CONTROL_PLANE_URL = "KSADK_A2A_CONTROL_PLANE_URL"
24
27
  ENV_A2A_TOKEN_DIR = "KSADK_A2A_TOKEN_DIR"
@@ -581,6 +584,232 @@ class InternalA2AControlPlaneClient(A2AControlPlane):
581
584
  return self._token_provider.get_token(AUDIENCE_GATEWAY)
582
585
 
583
586
 
587
+ class A2AAgentCardClient(A2AControlPlane):
588
+ """Card-driven control-plane client for hosted/external A2A discovery.
589
+
590
+ 发现面通过 KOP 调 server 对外 Action (ListAToASpaceAgents) 拿到 space 内
591
+ 每个 agent 的完整投影后 AgentCard(含 callable url);调用面直接用
592
+ card.url 发 A2A 请求,不回连 server 做 permit/credential。
593
+ runtime 只需一个 service_url(KOP 对外 API,默认 aicp.api.ksyun.com),
594
+ 与 ksadk/skills 同款;card.url 由 server 投影,runtime 不需要知道 gateway 域名。
595
+
596
+ KOP 鉴权(AICP AK/SK 签名)复用 ksadk.common.kop_client.KOPClient,
597
+ 和 skill/mcp 共用同一公共层。
598
+ """
599
+
600
+ def __init__(
601
+ self,
602
+ service_url: str,
603
+ *,
604
+ service_token: str = "",
605
+ httpx_client: httpx.AsyncClient | None = None,
606
+ timeout: float = 15.0,
607
+ ) -> None:
608
+ if not service_url:
609
+ raise ValueError("A2AAgentCardClient requires a non-empty service_url")
610
+ self._service_url = service_url.rstrip("/")
611
+ self._service_token = service_token
612
+ self._client = httpx_client
613
+ self._timeout = timeout
614
+ self._cards_by_agent: dict[str, tuple[AgentCard, str, str]] = {}
615
+ self._kop = KOPClient(base_url=service_url, service_token=service_token, timeout=timeout)
616
+
617
+ async def _post_action(self, action: str, payload: dict[str, Any]) -> dict[str, Any]:
618
+ try:
619
+ return await asyncio.to_thread(self._kop.post_action, action, payload)
620
+ except KOPError as exc:
621
+ raise A2AControlPlaneError(
622
+ code=exc.code,
623
+ message=exc.message,
624
+ error_code=f"KOP_{exc.code}",
625
+ retryable=exc.code >= 500,
626
+ action=action, # type: ignore[arg-type]
627
+ ) from exc
628
+
629
+ async def list_space_agents(
630
+ self,
631
+ space_id: str,
632
+ *,
633
+ prompt: str | None = None,
634
+ skill_id: str | None = None,
635
+ include_blocked: bool = False,
636
+ if_none_match: str | None = None,
637
+ cursor: str | None = None,
638
+ page_size: int = 50,
639
+ ) -> SpaceAgentPage:
640
+ _ = (prompt, skill_id, if_none_match)
641
+ payload: dict[str, Any] = {
642
+ "A2ASpaceId": space_id,
643
+ "Status": "available" if not include_blocked else "",
644
+ "PageSize": page_size,
645
+ }
646
+ if cursor:
647
+ payload["PageNumber"] = int(cursor) if str(cursor).isdigit() else 1
648
+ data = await self._post_action("ListAToASpaceAgents", payload)
649
+ agents: list[DiscoveredAgent] = []
650
+ for item in data.get("Agents") or []:
651
+ if not isinstance(item, dict):
652
+ continue
653
+ a2a_agent_id = str(item.get("A2AAgentId") or "").strip()
654
+ if not a2a_agent_id:
655
+ continue
656
+ # server 用纯 uuid,ksadk 内部要求 a2a-agent- 前缀;补前缀适配契约。
657
+ if not a2a_agent_id.startswith("a2a-agent-"):
658
+ a2a_agent_id = f"a2a-agent-{a2a_agent_id}"
659
+ invocation_status = str(item.get("InvocationStatus") or "")
660
+ if invocation_status and invocation_status != "available":
661
+ continue
662
+ card_payload = item.get("AgentCard")
663
+ if not isinstance(card_payload, dict):
664
+ continue
665
+ try:
666
+ card = _agent_card_from_wire(card_payload)
667
+ except A2AControlPlaneError:
668
+ continue
669
+ sha = str(item.get("CardSha256") or "")
670
+ version_id = str(item.get("VersionId") or "") or sha
671
+ if version_id and not version_id.startswith("a2a-version-"):
672
+ version_id = f"a2a-version-{version_id}"
673
+ source = str(item.get("Source") or "hosted")
674
+ self._cards_by_agent[a2a_agent_id] = (card, sha, version_id)
675
+ agents.append(
676
+ DiscoveredAgent(
677
+ agent_id=a2a_agent_id,
678
+ version_id=version_id,
679
+ source=source if source in {"hosted", "external"} else "hosted",
680
+ agent_card=card,
681
+ card_sha256=sha,
682
+ callable=True,
683
+ route_kind="hosted_gateway" if source == "hosted" else "external_public",
684
+ )
685
+ )
686
+ return SpaceAgentPage(agents=agents)
687
+
688
+ async def _resolve_card(self, target_agent_id: str) -> tuple[AgentCard, str, str]:
689
+ cached = self._cards_by_agent.get(target_agent_id)
690
+ if cached is not None:
691
+ return cached
692
+ await self.list_space_agents(os.getenv("KSADK_A2A_SPACE_ID", ""), page_size=100)
693
+ cached = self._cards_by_agent.get(target_agent_id)
694
+ if cached is None:
695
+ raise A2AControlPlaneError(
696
+ code=404,
697
+ message=f"A2A agent {target_agent_id} not discoverable",
698
+ error_code="A2A_AGENT_NOT_FOUND",
699
+ action="PrepareA2ACall", # type: ignore[arg-type]
700
+ )
701
+ return cached
702
+
703
+ async def _direct_prepared(
704
+ self,
705
+ *,
706
+ target_agent_id: str,
707
+ version_id: str,
708
+ card: AgentCard,
709
+ card_sha256: str,
710
+ ) -> PreparedA2AOperation:
711
+ interfaces = list(card.supported_interfaces or [])
712
+ interface = interfaces[0] if interfaces else None
713
+ if interface is None or not interface.url:
714
+ raise A2AControlPlaneError(
715
+ code=502,
716
+ message="discovered agent card has no callable interface url",
717
+ error_code="A2A_CONTROL_PLANE_INVALID_RESPONSE",
718
+ action="PrepareA2ACall", # type: ignore[arg-type]
719
+ )
720
+ route = A2ARoute(
721
+ kind="hosted_gateway",
722
+ interface=A2ARouteInterface(
723
+ url=str(interface.url),
724
+ protocol_binding=str(interface.protocol_binding or "JSONRPC"),
725
+ protocol_version=str(interface.protocol_version or "1.0"),
726
+ ),
727
+ )
728
+ return PreparedA2AOperation(
729
+ platform_task_id=f"a2a-task-{uuid.uuid4().hex}",
730
+ target=A2ATarget(
731
+ agent_id=target_agent_id,
732
+ version_id=version_id,
733
+ card_sha256=card_sha256,
734
+ ),
735
+ route=route,
736
+ call_permit="",
737
+ call_permit_expires_at="",
738
+ )
739
+
740
+ async def prepare_call(
741
+ self,
742
+ *,
743
+ space_id: str,
744
+ target_agent_id: str,
745
+ expected_version_id: str | None,
746
+ message_id: str,
747
+ message_sha256: str,
748
+ idempotency_token: str,
749
+ ) -> PreparedA2AOperation:
750
+ _ = (space_id, expected_version_id, message_id, message_sha256, idempotency_token)
751
+ card, sha, version_id = await self._resolve_card(target_agent_id)
752
+ return await self._direct_prepared(
753
+ target_agent_id=target_agent_id,
754
+ version_id=version_id,
755
+ card=card,
756
+ card_sha256=sha,
757
+ )
758
+
759
+ async def prepare_task_operation(
760
+ self,
761
+ *,
762
+ platform_task_id: str,
763
+ operation: A2AOperation,
764
+ message_id: str | None = None,
765
+ message_sha256: str | None = None,
766
+ idempotency_token: str | None = None,
767
+ agent_id: str | None = None,
768
+ ) -> PreparedA2AOperation:
769
+ _ = (operation, message_id, message_sha256, idempotency_token)
770
+ target_id = agent_id or platform_task_id
771
+ card, sha, version_id = await self._resolve_card(target_id)
772
+ return await self._direct_prepared(
773
+ target_agent_id=target_id,
774
+ version_id=version_id,
775
+ card=card,
776
+ card_sha256=sha,
777
+ )
778
+
779
+ async def bind_remote_task(
780
+ self,
781
+ *,
782
+ platform_task_id: str,
783
+ remote_task_id: str,
784
+ remote_context_id: str | None,
785
+ observed_at: str,
786
+ ) -> dict[str, Any]:
787
+ _ = (platform_task_id, remote_context_id, observed_at)
788
+ return {"RemoteTaskId": remote_task_id, "Bound": True}
789
+
790
+ async def append_task_events(
791
+ self,
792
+ *,
793
+ platform_task_id: str,
794
+ events: list[dict[str, Any]],
795
+ ) -> dict[str, Any]:
796
+ _ = (platform_task_id, events)
797
+ return {"Appended": len(events)}
798
+
799
+ async def resolve_credential(
800
+ self,
801
+ *,
802
+ platform_task_id: str,
803
+ credential_handle: str | None,
804
+ call_permit: str,
805
+ ) -> CredentialInjection:
806
+ _ = (platform_task_id, credential_handle, call_permit)
807
+ return CredentialInjection()
808
+
809
+ def gateway_token(self) -> str:
810
+ return self._service_token
811
+
812
+
584
813
  def _credential_string_map(value: Any, *, field_name: str) -> dict[str, str]:
585
814
  if value is None:
586
815
  return {}
@@ -654,8 +883,16 @@ def _agent_card_from_wire(payload: Any) -> AgentCard:
654
883
  message="AgentCard must be an object",
655
884
  error_code="A2A_CONTROL_PLANE_INVALID_RESPONSE",
656
885
  )
886
+ # 兼容 0.3 card:顶层 url/preferredTransport 折叠进 supportedInterfaces[0]。
887
+ if not payload.get("supportedInterfaces") and payload.get("url"):
888
+ payload = dict(payload)
889
+ payload["supportedInterfaces"] = [{
890
+ "url": payload["url"],
891
+ "protocolBinding": payload.get("preferredTransport", "JSONRPC"),
892
+ "protocolVersion": payload.get("protocolVersion", "0.3"),
893
+ }]
657
894
  try:
658
- return ParseDict(payload, AgentCard())
895
+ return ParseDict(payload, AgentCard(), ignore_unknown_fields=True)
659
896
  except (ParseError, TypeError, ValueError) as exc:
660
897
  raise A2AControlPlaneError(
661
898
  code=502,
@@ -798,6 +1035,7 @@ __all__ = [
798
1035
  "A2AInternalAction",
799
1036
  "A2A_INTERNAL_ACTIONS",
800
1037
  "A2A_INTERNAL_PATH_PREFIX",
1038
+ "A2AAgentCardClient",
801
1039
  "A2AControlPlane",
802
1040
  "A2AControlPlaneError",
803
1041
  "A2AOperation",
@@ -5,31 +5,37 @@
5
5
 
6
6
  方向:
7
7
  - ``task_status_to_event``:A2A TaskStatus/TaskState → RuntimeEvent(run.*)。
8
- - ``artifact_to_event``:A2A Artifact → RuntimeEvent(artifact.*)。
9
- - ``message_to_event``:A2A Message → RuntimeEvent(text.*)。
10
- - ``event_to_text_part``:RuntimeEvent(text.*)→ A2A ``Part``(用于出站)。
8
+ - ``artifact_to_event``:A2A Artifact → RuntimeEvent(item.*,item_kind="artifact")。
9
+ - ``message_to_event``:A2A Message → RuntimeEvent(item.*,item_kind="message")。
10
+ - ``event_to_text_part``:RuntimeEvent(item.*,item_kind="message")→ A2A ``Part``(用于出站)。
11
11
 
12
12
  wire 对象是 protobuf(``a2a_pb2``);文本用 ``Part(text=...)``。
13
13
  """
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
+ import time
17
18
  from typing import Any, Optional
18
19
 
19
20
  from a2a.types import Part, TaskState, TaskStatus
20
21
 
21
- from ksadk.events.runtime_event import EventType, RuntimeEvent
22
-
23
- #: A2A TaskState → RuntimeEvent run.* 事件类型映射。
24
- _TASK_STATE_TO_RUN_EVENT = {
25
- TaskState.TASK_STATE_SUBMITTED: EventType.RUN_STARTED,
26
- TaskState.TASK_STATE_WORKING: EventType.RUN_PROGRESS,
27
- TaskState.TASK_STATE_COMPLETED: EventType.RUN_COMPLETED,
28
- TaskState.TASK_STATE_FAILED: EventType.RUN_FAILED,
29
- TaskState.TASK_STATE_CANCELED: EventType.RUN_CANCELED,
30
- TaskState.TASK_STATE_INPUT_REQUIRED: EventType.RUN_INTERRUPTED,
31
- TaskState.TASK_STATE_REJECTED: EventType.RUN_FAILED,
32
- }
22
+ from ksadk.events.canonical import (
23
+ ContentSnapshot,
24
+ ErrorInfo,
25
+ ItemCompleted,
26
+ ItemStarted,
27
+ ItemUpdated,
28
+ RunCanceled,
29
+ RunCompleted,
30
+ RunFailed,
31
+ RunInterrupted,
32
+ RunProgress,
33
+ RunStarted,
34
+ RuntimeEvent,
35
+ SourceRef,
36
+ )
37
+ from ksadk.events.content import TextContent
38
+ from ksadk.events.identity import stable_event_id, stable_item_id, stable_scope_id
33
39
 
34
40
 
35
41
  class A2AEventAdapter:
@@ -48,25 +54,57 @@ class A2AEventAdapter:
48
54
  seq_id: int,
49
55
  event_id: Optional[str] = None,
50
56
  ) -> RuntimeEvent:
51
- """A2A TaskStatus → RuntimeEvent(run.*)。"""
52
- event_type = _TASK_STATE_TO_RUN_EVENT.get(status.state, EventType.RUN_PROGRESS)
53
- state_name = TaskState.Name(status.state) if status.state is not None else "unknown"
54
- payload: dict[str, Any] = {"status": state_name}
55
- if event_type == EventType.RUN_CANCELED:
56
- payload["cancel_result"] = "interrupted_active_turn"
57
- elif event_type == EventType.RUN_FAILED:
58
- message = getattr(status, "message", None)
59
- payload["error"] = self._parts_text(getattr(message, "parts", None)) or state_name
60
- return RuntimeEvent.create(
61
- event_type,
62
- agent_id=agent_id,
63
- user_id=user_id,
64
- session_id=session_id,
65
- invocation_id=invocation_id,
66
- seq_id=seq_id,
67
- payload=payload,
68
- event_id=event_id,
57
+ """A2A TaskStatus → canonical RuntimeEvent(run.*)。"""
58
+ state = status.state
59
+ state_name = TaskState.Name(state) if state is not None else "unknown"
60
+ scope_id = stable_scope_id("a2a", session_id, invocation_id)
61
+ run_id = invocation_id
62
+ source = SourceRef(
63
+ framework="a2a",
64
+ native_run_id=invocation_id,
65
+ metadata={"agent_id": agent_id, "user_id": user_id, "status": state_name},
66
+ )
67
+ timestamp = time.time()
68
+ eid = event_id or stable_event_id(
69
+ "a2a", scope_id, run_id, "run", "run", invocation_id, seq_id
69
70
  )
71
+ common: dict[str, Any] = {
72
+ "schema_version": 2,
73
+ "event_id": eid,
74
+ "seq": seq_id,
75
+ "timestamp": timestamp,
76
+ "run_id": run_id,
77
+ "scope_id": scope_id,
78
+ "source": source,
79
+ }
80
+ if state == TaskState.TASK_STATE_SUBMITTED:
81
+ return RunStarted(**common, status="running")
82
+ if state == TaskState.TASK_STATE_WORKING:
83
+ return RunProgress(**common, status="running", message=state_name)
84
+ if state == TaskState.TASK_STATE_COMPLETED:
85
+ return RunCompleted(**common, status="completed", output_refs=())
86
+ if state in {TaskState.TASK_STATE_FAILED, TaskState.TASK_STATE_REJECTED}:
87
+ message = getattr(status, "message", None)
88
+ error_text = self._parts_text(getattr(message, "parts", None)) or state_name
89
+ return RunFailed(
90
+ **common,
91
+ status="failed",
92
+ error=ErrorInfo(
93
+ code=(
94
+ "a2a_task_rejected"
95
+ if state == TaskState.TASK_STATE_REJECTED
96
+ else "a2a_task_failed"
97
+ ),
98
+ message=error_text,
99
+ source="a2a",
100
+ scope_id=scope_id,
101
+ ),
102
+ )
103
+ if state == TaskState.TASK_STATE_CANCELED:
104
+ return RunCanceled(**common, status="canceled", reason="interrupted_active_turn")
105
+ if state == TaskState.TASK_STATE_INPUT_REQUIRED:
106
+ return RunInterrupted(**common, status="interrupted", reason=state_name)
107
+ return RunProgress(**common, status="running", message=state_name)
70
108
 
71
109
  def artifact_to_event(
72
110
  self,
@@ -79,23 +117,40 @@ class A2AEventAdapter:
79
117
  seq_id: int,
80
118
  event_id: Optional[str] = None,
81
119
  ) -> RuntimeEvent:
82
- """A2A Artifact → RuntimeEvent(artifact.*)。"""
120
+ """A2A Artifact → canonical RuntimeEvent(item.started,item_kind="artifact")。"""
121
+ artifact_id = str(getattr(artifact, "artifact_id", None) or "")
83
122
  name = getattr(artifact, "name", None) or "artifact"
84
123
  text = self._parts_text(getattr(artifact, "parts", None))
85
- return RuntimeEvent.create(
86
- EventType.ARTIFACT_CREATED,
87
- agent_id=agent_id,
88
- user_id=user_id,
89
- session_id=session_id,
90
- invocation_id=invocation_id,
91
- seq_id=seq_id,
92
- payload={
93
- "artifact_id": str(getattr(artifact, "artifact_id", None) or ""),
94
- "name": name,
95
- "version": 1,
96
- "text": text,
97
- },
98
- event_id=event_id,
124
+ scope_id = stable_scope_id("a2a", session_id, invocation_id)
125
+ item_id = stable_item_id(
126
+ "a2a", session_id, invocation_id, "artifact", artifact_id or name
127
+ )
128
+ source = SourceRef(
129
+ framework="a2a",
130
+ native_run_id=invocation_id,
131
+ native_item_id=artifact_id or None,
132
+ metadata={"agent_id": agent_id, "user_id": user_id, "artifact_name": name},
133
+ )
134
+ eid = event_id or stable_event_id(
135
+ "a2a", scope_id, item_id, "item.started", "artifact", invocation_id, seq_id
136
+ )
137
+ initial = (
138
+ ContentSnapshot(parts=(TextContent(part_id="text", text=text),))
139
+ if text
140
+ else None
141
+ )
142
+ return ItemStarted(
143
+ schema_version=2,
144
+ event_id=eid,
145
+ seq=seq_id,
146
+ timestamp=time.time(),
147
+ run_id=invocation_id,
148
+ scope_id=scope_id,
149
+ source=source,
150
+ item_id=item_id,
151
+ item_kind="artifact",
152
+ phase="final_answer",
153
+ initial=initial,
99
154
  )
100
155
 
101
156
  def message_to_event(
@@ -110,29 +165,66 @@ class A2AEventAdapter:
110
165
  seq_id: int,
111
166
  event_id: Optional[str] = None,
112
167
  ) -> RuntimeEvent:
113
- """A2A Message 文本 → RuntimeEvent(text.*,带相位)。"""
114
- return RuntimeEvent.create(
115
- EventType.TEXT_COMPLETED if final else EventType.TEXT_DELTA,
116
- agent_id=agent_id,
117
- user_id=user_id,
118
- session_id=session_id,
119
- invocation_id=invocation_id,
120
- seq_id=seq_id,
121
- phase="final_answer" if final else "commentary",
122
- payload={"text": text},
123
- event_id=event_id,
168
+ """A2A Message 文本 → canonical RuntimeEvent(item.*,item_kind="message")。"""
169
+ scope_id = stable_scope_id("a2a", session_id, invocation_id)
170
+ item_id = stable_item_id("a2a", session_id, invocation_id, "message", "response")
171
+ source = SourceRef(
172
+ framework="a2a",
173
+ native_run_id=invocation_id,
174
+ metadata={"agent_id": agent_id, "user_id": user_id},
175
+ )
176
+ timestamp = time.time()
177
+ if final:
178
+ eid = event_id or stable_event_id(
179
+ "a2a", scope_id, item_id, "item.completed", "snapshot", invocation_id, seq_id
180
+ )
181
+ return ItemCompleted(
182
+ schema_version=2,
183
+ event_id=eid,
184
+ seq=seq_id,
185
+ timestamp=timestamp,
186
+ run_id=invocation_id,
187
+ scope_id=scope_id,
188
+ source=source,
189
+ item_id=item_id,
190
+ item_kind="message",
191
+ snapshot=ContentSnapshot(
192
+ parts=(TextContent(part_id="text-0", text=text),)
193
+ ),
194
+ )
195
+ eid = event_id or stable_event_id(
196
+ "a2a", scope_id, item_id, "item.updated", "text-0", invocation_id, seq_id
197
+ )
198
+ return ItemUpdated(
199
+ schema_version=2,
200
+ event_id=eid,
201
+ seq=seq_id,
202
+ timestamp=timestamp,
203
+ run_id=invocation_id,
204
+ scope_id=scope_id,
205
+ source=source,
206
+ item_id=item_id,
207
+ item_kind="message",
208
+ op="append",
209
+ update=TextContent(part_id="text-0", text=text),
124
210
  )
125
211
 
126
212
  # ---- RuntimeEvent → A2A ----
127
213
 
128
214
  @staticmethod
129
215
  def event_to_text_part(event: RuntimeEvent) -> Optional[Part]:
130
- """RuntimeEvent(text.*)→ A2A ``Part``(用于出站 message/artifact)。"""
131
- event.validate_conformance()
132
- if event.event_type not in (EventType.TEXT_DELTA, EventType.TEXT_COMPLETED):
216
+ """RuntimeEvent(item.*,item_kind="message")→ A2A ``Part``(用于出站 message/artifact)。"""
217
+ if isinstance(event, ItemUpdated) and event.item_kind == "message":
218
+ if isinstance(event.update, TextContent):
219
+ text = event.update.text
220
+ return Part(text=text) if text else None
221
+ return None
222
+ if isinstance(event, ItemCompleted) and event.item_kind == "message":
223
+ if event.snapshot.parts and isinstance(event.snapshot.parts[0], TextContent):
224
+ text = event.snapshot.parts[0].text
225
+ return Part(text=text) if text else None
133
226
  return None
134
- text = str(event.payload.get("text") or "")
135
- return Part(text=text) if text else None
227
+ return None
136
228
 
137
229
  @staticmethod
138
230
  def _parts_text(parts: Any) -> str: