agentengine-sdk-python 0.8.1__py3-none-any.whl → 0.8.3__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 (476) hide show
  1. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/METADATA +25 -12
  2. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/RECORD +421 -232
  3. ksadk/_build_provenance.json +1 -0
  4. ksadk/a2a/_space_client_events.py +381 -0
  5. ksadk/a2a/event_adapter.py +156 -64
  6. ksadk/a2a/executor.py +179 -63
  7. ksadk/a2a/space_client.py +6 -333
  8. ksadk/a2ui/core.py +222 -53
  9. ksadk/agui/_agent_helpers.py +247 -0
  10. ksadk/agui/a2ui_projection.py +12 -5
  11. ksadk/agui/agent.py +443 -259
  12. ksadk/api/client.py +528 -27
  13. ksadk/builders/code_builder.py +284 -8
  14. ksadk/builders/container_builder.py +8 -1
  15. ksadk/builders/managed_runtime_builder.py +42 -35
  16. ksadk/cli/__init__.py +23 -0
  17. ksadk/cli/cmd_dashboard.py +15 -1
  18. ksadk/cli/cmd_deploy.py +10 -2
  19. ksadk/cli/cmd_eval.py +66 -9
  20. ksadk/cli/cmd_evalset.py +284 -0
  21. ksadk/cli/cmd_files.py +5 -1
  22. ksadk/cli/cmd_hermes.py +1 -126
  23. ksadk/cli/cmd_invoke.py +28 -38
  24. ksadk/cli/cmd_managed_runtime.py +95 -0
  25. ksadk/cli/cmd_observe.py +85 -0
  26. ksadk/cli/cmd_openclaw.py +1 -435
  27. ksadk/cli/cmd_plugin.py +657 -0
  28. ksadk/cli/cmd_replay.py +28 -4
  29. ksadk/cli/cmd_studio.py +99 -8
  30. ksadk/cli/cmd_web.py +10 -2
  31. ksadk/cli/hermes_env.py +151 -0
  32. ksadk/cli/invoke_payload.py +49 -0
  33. ksadk/cli/openclaw_env.py +458 -0
  34. ksadk/codex/client.py +180 -30
  35. ksadk/codex/runtime.py +475 -331
  36. ksadk/configs/env_registry.py +94 -12
  37. ksadk/configs/env_registry_pcm.py +181 -0
  38. ksadk/configs/env_var_spec.py +18 -0
  39. ksadk/configs/global_config.py +5 -0
  40. ksadk/configs/settings.py +9 -0
  41. ksadk/context_engine/__init__.py +98 -0
  42. ksadk/context_engine/assembler.py +176 -0
  43. ksadk/context_engine/baseline.py +419 -0
  44. ksadk/context_engine/cache_observability.py +228 -0
  45. ksadk/context_engine/capabilities.py +443 -0
  46. ksadk/context_engine/contributors.py +409 -0
  47. ksadk/context_engine/hosted_pipeline.py +417 -0
  48. ksadk/context_engine/models.py +117 -0
  49. ksadk/context_engine/planner.py +698 -0
  50. ksadk/context_engine/policies.py +319 -0
  51. ksadk/context_engine/projection.py +31 -0
  52. ksadk/context_engine/shadow_plan.py +266 -0
  53. ksadk/context_engine/tokenizer.py +164 -0
  54. ksadk/conversations/__init__.py +19 -0
  55. ksadk/conversations/context.py +230 -30
  56. ksadk/conversations/contracts.py +266 -0
  57. ksadk/conversations/message_projection.py +308 -26
  58. ksadk/conversations/model_context.py +49 -3
  59. ksadk/conversations/projector.py +616 -0
  60. ksadk/conversations/reducer.py +98 -0
  61. ksadk/conversations/runtime_compaction.py +207 -5
  62. ksadk/conversations/runtime_input.py +184 -2
  63. ksadk/conversations/runtime_invocation.py +81 -3
  64. ksadk/conversations/runtime_observability.py +141 -0
  65. ksadk/conversations/runtime_payloads.py +42 -0
  66. ksadk/conversations/runtime_preparation.py +272 -2
  67. ksadk/conversations/runtime_resume.py +20 -1
  68. ksadk/conversations/runtime_stream_events.py +94 -9
  69. ksadk/conversations/semantic_summary.py +311 -1
  70. ksadk/conversations/session_lock.py +51 -0
  71. ksadk/deployment/env_forward.py +72 -0
  72. ksadk/deployment/managed_runtime.py +5 -0
  73. ksadk/deployment/providers/serverless.py +143 -69
  74. ksadk/evaluation/__init__.py +32 -0
  75. ksadk/evaluation/a2a_adapter.py +9 -1
  76. ksadk/evaluation/adapters.py +18 -5
  77. ksadk/evaluation/agent_eval_client.py +395 -0
  78. ksadk/evaluation/cloud_binding.py +80 -0
  79. ksadk/evaluation/cloud_converter.py +194 -0
  80. ksadk/evaluation/cloud_service.py +199 -0
  81. ksadk/evaluation/contracts.py +73 -4
  82. ksadk/evaluation/evaluators.py +183 -17
  83. ksadk/evaluation/evidence.py +258 -0
  84. ksadk/evaluation/executor.py +31 -6
  85. ksadk/evaluation/local_adapter.py +550 -0
  86. ksadk/evaluation/service_env.py +27 -0
  87. ksadk/evaluation/studio_build_adapter.py +253 -0
  88. ksadk/evaluation/target.py +15 -6
  89. ksadk/events/__init__.py +13 -13
  90. ksadk/events/_v1_compat/__init__.py +1 -0
  91. ksadk/events/_v1_compat/models.py +299 -0
  92. ksadk/events/_v1_compat/parser.py +247 -0
  93. ksadk/events/_v1_compat/projection.py +755 -0
  94. ksadk/events/adapters/__init__.py +34 -0
  95. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  96. ksadk/events/adapters/_a2a_support.py +275 -0
  97. ksadk/events/adapters/_codex_interactions.py +375 -0
  98. ksadk/events/adapters/_codex_items.py +801 -0
  99. ksadk/events/adapters/_codex_validators.py +311 -0
  100. ksadk/events/adapters/_langgraph_support.py +785 -0
  101. ksadk/events/adapters/a2a.py +841 -0
  102. ksadk/events/adapters/adk.py +503 -0
  103. ksadk/events/adapters/codex.py +907 -0
  104. ksadk/events/adapters/langgraph.py +745 -0
  105. ksadk/events/canonical.py +440 -0
  106. ksadk/events/canonical_replay.py +497 -0
  107. ksadk/events/canonical_store.py +468 -0
  108. ksadk/events/cold_recovery.py +257 -0
  109. ksadk/events/content.py +89 -0
  110. ksadk/events/identity.py +86 -0
  111. ksadk/events/pipeline.py +455 -0
  112. ksadk/events/projections.py +66 -0
  113. ksadk/events/reducer.py +661 -0
  114. ksadk/events/replay.py +3 -36
  115. ksadk/events/runtime_event.py +20 -265
  116. ksadk/events/session_event.py +324 -0
  117. ksadk/events/store.py +3 -316
  118. ksadk/events/v1_compat.py +41 -0
  119. ksadk/harness/__init__.py +45 -35
  120. ksadk/harness/runtime.py +220 -58
  121. ksadk/identity/resolver.py +4 -3
  122. ksadk/interaction/__init__.py +28 -0
  123. ksadk/interaction/contracts.py +136 -0
  124. ksadk/interaction/ledger.py +189 -0
  125. ksadk/interaction/provider.py +122 -0
  126. ksadk/interaction/providers/__init__.py +52 -0
  127. ksadk/interaction/providers/adk.py +40 -0
  128. ksadk/interaction/providers/codex.py +94 -0
  129. ksadk/interaction/providers/langgraph.py +58 -0
  130. ksadk/kernel/__init__.py +117 -0
  131. ksadk/kernel/authorization.py +258 -0
  132. ksadk/kernel/bootstrap.py +1074 -0
  133. ksadk/kernel/contract_fingerprints.py +62 -0
  134. ksadk/kernel/contracts.py +370 -0
  135. ksadk/kernel/control.py +220 -0
  136. ksadk/kernel/errors.py +79 -0
  137. ksadk/kernel/ingress.py +1123 -0
  138. ksadk/kernel/mapping.py +111 -0
  139. ksadk/kernel/memory_store.py +1134 -0
  140. ksadk/kernel/postgres_store.py +1757 -0
  141. ksadk/kernel/recovery.py +452 -0
  142. ksadk/kernel/runtime_identity.py +103 -0
  143. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  144. ksadk/kernel/sqlite_store.py +1411 -0
  145. ksadk/kernel/state.py +145 -0
  146. ksadk/kernel/store.py +232 -0
  147. ksadk/kernel/worker.py +964 -0
  148. ksadk/knowledge_base/client.py +7 -0
  149. ksadk/knowledge_base/service.py +32 -5
  150. ksadk/memory/__init__.py +61 -0
  151. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  152. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  153. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  154. ksadk/memory/adk/backends/sdk_ltm_backend.py +384 -2
  155. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  156. ksadk/memory/coordinator.py +461 -0
  157. ksadk/memory/events.py +202 -0
  158. ksadk/memory/extraction.py +228 -0
  159. ksadk/memory/ltm_backend_factory.py +16 -3
  160. ksadk/memory/models.py +316 -0
  161. ksadk/memory/policy.py +215 -0
  162. ksadk/memory/provider.py +47 -0
  163. ksadk/memory/provider_adapter.py +159 -0
  164. ksadk/memory/provider_resolver.py +71 -0
  165. ksadk/memory/providers/__init__.py +5 -0
  166. ksadk/memory/providers/local_sqlite.py +497 -0
  167. ksadk/memory/resolved_policy.py +145 -0
  168. ksadk/memory/service.py +188 -6
  169. ksadk/model_proxy/bootstrap.py +16 -9
  170. ksadk/model_proxy/detect.py +202 -9
  171. ksadk/model_proxy/namespace.py +39 -15
  172. ksadk/model_proxy/server.py +24 -5
  173. ksadk/model_proxy/transform.py +60 -2
  174. ksadk/observability/__init__.py +25 -0
  175. ksadk/observability/session_log.py +420 -0
  176. ksadk/observability/trajectory.py +105 -0
  177. ksadk/plugins/__init__.py +167 -0
  178. ksadk/plugins/bridges/__init__.py +45 -0
  179. ksadk/plugins/bridges/codex.py +552 -0
  180. ksadk/plugins/bridges/dsh.py +1116 -0
  181. ksadk/plugins/builtins.py +747 -0
  182. ksadk/plugins/bundle.py +246 -0
  183. ksadk/plugins/bundle_security.py +167 -0
  184. ksadk/plugins/composition.py +529 -0
  185. ksadk/plugins/context_contributor.py +437 -0
  186. ksadk/plugins/contracts.py +451 -0
  187. ksadk/plugins/dsh_toolchain.py +935 -0
  188. ksadk/plugins/ecosystem_bridge.py +1105 -0
  189. ksadk/plugins/ecosystem_probe.py +191 -0
  190. ksadk/plugins/host.py +724 -0
  191. ksadk/plugins/providers/__init__.py +85 -0
  192. ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
  193. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
  194. ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
  195. ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
  196. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
  197. ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
  198. ksadk/plugins/providers/codex.py +722 -0
  199. ksadk/plugins/providers/codex_dsh.py +83 -0
  200. ksadk/plugins/providers/dsh.py +951 -0
  201. ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
  202. ksadk/plugins/providers/harness.py +627 -0
  203. ksadk/plugins/providers/harness_dsh.py +91 -0
  204. ksadk/plugins/providers/legacy.py +215 -0
  205. ksadk/plugins/providers/legacy_catalog.py +100 -0
  206. ksadk/plugins/providers/shipped_dsh.py +370 -0
  207. ksadk/plugins/resolver.py +331 -0
  208. ksadk/plugins/subagent_providers/__init__.py +12 -0
  209. ksadk/plugins/subagent_providers/codex.py +443 -0
  210. ksadk/plugins/subagents.py +333 -0
  211. ksadk/prompts/__init__.py +71 -0
  212. ksadk/prompts/compiler.py +215 -0
  213. ksadk/prompts/models.py +82 -0
  214. ksadk/prompts/projection.py +89 -0
  215. ksadk/prompts/resolved.py +137 -0
  216. ksadk/prompts/sources.py +233 -0
  217. ksadk/runners/_langgraph_runner_streams.py +822 -0
  218. ksadk/runners/adk_runner.py +5 -5
  219. ksadk/runners/base_runner.py +16 -0
  220. ksadk/runners/factory.py +1 -2
  221. ksadk/runners/langgraph_runner.py +198 -437
  222. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  223. ksadk/runtime/_runner_adapter/stream_mapping.py +797 -0
  224. ksadk/runtime/adapter.py +119 -2
  225. ksadk/runtime/conversation_execution.py +316 -182
  226. ksadk/runtime/executor.py +144 -3
  227. ksadk/runtime/factory.py +268 -8
  228. ksadk/runtime/framework_adapters.py +18 -0
  229. ksadk/runtime/hosted_finalizer.py +268 -0
  230. ksadk/runtime/launch.py +14 -1
  231. ksadk/runtime/preprocessing.py +25 -3
  232. ksadk/runtime/runner_adapter.py +293 -508
  233. ksadk/runtime/usage.py +33 -0
  234. ksadk/sandbox/__init__.py +2 -1
  235. ksadk/sandbox/backends/e2b.py +35 -2
  236. ksadk/sandbox/factory.py +72 -0
  237. ksadk/scheduler/__init__.py +18 -0
  238. ksadk/scheduler/calendar.py +102 -0
  239. ksadk/scheduler/contracts.py +254 -0
  240. ksadk/scheduler/dispatcher.py +129 -0
  241. ksadk/scheduler/engine.py +416 -0
  242. ksadk/scheduler/sqlite_store.py +563 -0
  243. ksadk/server/composition.py +8 -0
  244. ksadk/server/factory.py +69 -6
  245. ksadk/server/routes/kernel_ingress.py +258 -0
  246. ksadk/server/routes/openai_compat.py +88 -8
  247. ksadk/server/routes/projection.py +35 -20
  248. ksadk/server/routes/run.py +94 -0
  249. ksadk/server/routes/sessions.py +2 -0
  250. ksadk/server/routes/streaming.py +5 -2
  251. ksadk/server/static/assets/{ArtifactsPanel-CakCqxEN.js → ArtifactsPanel-10GPXIJ6.js} +1 -1
  252. ksadk/server/static/assets/{CodeBlock-CynLknyO.js → CodeBlock-BXk1l-G1.js} +4 -4
  253. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  254. ksadk/server/static/assets/{MathMessageMarkdown-3sQdOysS.js → MathMessageMarkdown-D9uB55Oh.js} +4 -4
  255. ksadk/server/static/assets/MermaidBlock--OEYoXIJ.js +312 -0
  256. ksadk/server/static/assets/NativeTerminalPanel-DrEe1syq.js +1 -0
  257. ksadk/server/static/assets/abnfDiagram-VCTEODGH-eeTFJLvo.js +1 -0
  258. ksadk/server/static/assets/arc-S3ZNbIAd.js +1 -0
  259. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +1 -0
  260. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-CRjgEJDX.js +36 -0
  261. ksadk/server/static/assets/blockDiagram-NRAW4CY4-C7bsBoNH.js +129 -0
  262. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-BX3c33Ob.js +38 -0
  263. ksadk/server/static/assets/channel-s354Yo6o.js +1 -0
  264. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +1 -0
  265. ksadk/server/static/assets/{chunk-FMBD7UC4-B_fH2YuH.js → chunk-5VM5RSS4-bZ7ws-8m.js} +1 -1
  266. ksadk/server/static/assets/{chunk-ND2GUHAM-D6rFLaVV.js → chunk-F27PBJKO-D2r0pvhY.js} +1 -1
  267. ksadk/server/static/assets/chunk-G27WJ6UU-CZwF3oUP.js +231 -0
  268. ksadk/server/static/assets/{chunk-4BX2VUAB-B9drTgOW.js → chunk-JWPE2WC7-DigFYCML.js} +1 -1
  269. ksadk/server/static/assets/chunk-LCL6LL3I-CnorGV5q.js +206 -0
  270. ksadk/server/static/assets/chunk-POPQ4Y6H-CexntQA-.js +1 -0
  271. ksadk/server/static/assets/chunk-RHFEMEQ7-CHTC7UxA.js +168 -0
  272. ksadk/server/static/assets/chunk-SVP7TREG-BC1EWt_-.js +88 -0
  273. ksadk/server/static/assets/chunk-XXDRQBXY-BTG24xN0.js +1 -0
  274. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +1 -0
  275. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +1 -0
  276. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-ChNs_Mdk.js → cose-bilkent-JH36ORCC-CkonRdAS.js} +1 -1
  277. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +1 -0
  278. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-DEOCBe15.js +62 -0
  279. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  280. ksadk/server/static/assets/dagre-3AP2YEHR-DBThPuLa.js +4 -0
  281. ksadk/server/static/assets/dagre-ClTPrTht.js +1 -0
  282. ksadk/server/static/assets/diagram-S7CK7UJ4-DsZHrnpJ.js +30 -0
  283. ksadk/server/static/assets/diagram-UQ7AKVKN-BJR4nhVr.js +41 -0
  284. ksadk/server/static/assets/diagram-VSXAHHWV-xzcERX0a.js +3 -0
  285. ksadk/server/static/assets/diagram-VX7I27RA-tn2xM1xu.js +24 -0
  286. ksadk/server/static/assets/diagram-Z3DM3KII-BZPGBkw5.js +24 -0
  287. ksadk/server/static/assets/{dist-gLnrGsoU.js → dist-4zN1_tq5.js} +1 -1
  288. ksadk/server/static/assets/{dist-C1sz5Eo3.js → dist-8VWI-2bZ.js} +1 -1
  289. ksadk/server/static/assets/{dist-BjOdlDjj.js → dist-B-46q3Hk.js} +1 -1
  290. ksadk/server/static/assets/{dist-o2OVmKvt.js → dist-B0gdk4rl.js} +1 -1
  291. ksadk/server/static/assets/{dist-4N2NMVYg.js → dist-B1oWRmrH.js} +1 -1
  292. ksadk/server/static/assets/{dist-CmZHzlwZ.js → dist-BI1qQH4n.js} +1 -1
  293. ksadk/server/static/assets/{dist-X4TnqwOK.js → dist-BJLUwH6W.js} +1 -1
  294. ksadk/server/static/assets/{dist-B5oS1zcj.js → dist-Bbwqa8TG.js} +1 -1
  295. ksadk/server/static/assets/{dist-j6Dxmf_j.js → dist-Btyo4vX4.js} +1 -1
  296. ksadk/server/static/assets/{dist-DQU9EWw-.js → dist-C71CsujO.js} +1 -1
  297. ksadk/server/static/assets/{dist-BIlKoW0k.js → dist-CXpH_Rdd.js} +1 -1
  298. ksadk/server/static/assets/{dist-DJN_6Y39.js → dist-Cq4OL6nO.js} +1 -1
  299. ksadk/server/static/assets/{dist-Dli7qW-B.js → dist-D1V3f1B4.js} +1 -1
  300. ksadk/server/static/assets/{dist-fhOuWds5.js → dist-DJmCPRVB.js} +1 -1
  301. ksadk/server/static/assets/{dist-CWV4lDr1.js → dist-DQAB0qn_.js} +2 -2
  302. ksadk/server/static/assets/{dist-D6MpCZtz.js → dist-DUwKa_l6.js} +1 -1
  303. ksadk/server/static/assets/dist-DdRBIceA.js +1 -0
  304. ksadk/server/static/assets/{dist-DWKByxWV.js → dist-DfGFrb0v.js} +1 -1
  305. ksadk/server/static/assets/{dist-DsHPdk3W.js → dist-DjhwGUgZ.js} +1 -1
  306. ksadk/server/static/assets/{dist-B-jNR6Vn.js → dist-DyqV4fL4.js} +1 -1
  307. ksadk/server/static/assets/{dist-BB3-OwTQ.js → dist-M67Hwu0n.js} +1 -1
  308. ksadk/server/static/assets/{dist-_pHPTyZ-.js → dist-u8tVH5Ak.js} +1 -1
  309. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-DVfMsLge.js +1 -0
  310. ksadk/server/static/assets/erDiagram-SSCWMZ5O-CWEZSYaw.js +99 -0
  311. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +1 -0
  312. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +1 -0
  313. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-TWIxoyYL.js +292 -0
  314. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +1 -0
  315. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-DDh2hd2S.js +106 -0
  316. ksadk/server/static/assets/index-B2k_urY8.js +241 -0
  317. ksadk/server/static/assets/index-ILPt6IWF.css +2 -0
  318. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +1 -0
  319. ksadk/server/static/assets/infoDiagram-RXCK75RN-CgoyWiDR.js +2 -0
  320. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-K0OOfVna.js → ishikawaDiagram-5VMMS53U-CyRIu_om.js} +6 -6
  321. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-8LeOJaZp.js → journeyDiagram-EYS64GPL-DN5JXHzN.js} +6 -6
  322. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-C6uCgZrW.js → kanban-definition-3QL26DDD-CNP3ui66.js} +10 -10
  323. ksadk/server/static/assets/katex-DWEzQy1d.js +257 -0
  324. ksadk/server/static/assets/{linear-hdBcYzM8.js → linear-C-qHp7d2.js} +1 -1
  325. ksadk/server/static/assets/mermaid-parser.core-Cl-K943T.js +166 -0
  326. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-Bjy_2v4_.js → mindmap-definition-FBJOCRG2-D5DB5mYm.js} +29 -29
  327. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +1 -0
  328. ksadk/server/static/assets/pegDiagram-XKGWAZYB-BQVc9ia_.js +1 -0
  329. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +1 -0
  330. ksadk/server/static/assets/pieDiagram-E7YTZNPT-B6UCAvtY.js +39 -0
  331. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-BmkRbwCg.js → quadrantDiagram-AXDQQJYC-mIr2d3eb.js} +6 -6
  332. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +1 -0
  333. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +1 -0
  334. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +1 -0
  335. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +1 -0
  336. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +1 -0
  337. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-Dt3FFDmK.js +1 -0
  338. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-Cz_vQtgF.js +84 -0
  339. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-l6iXmU65.js → sankeyDiagram-P5KCCOFB-wlO1TsH5.js} +7 -7
  340. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-Cq6UBeQB.js → sequenceDiagram-WJ2MYXX4-CHRbElYq.js} +10 -10
  341. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-DXX54iyO.js +1 -0
  342. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-Dp_lw9II.js +1 -0
  343. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +1 -0
  344. ksadk/server/static/assets/swimlanes-XN3QIQJK-D8O5UlLG.js +1 -0
  345. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +8 -0
  346. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-DEz24vV0.js → timeline-definition-24CTP7MA-8mfKcxvG.js} +7 -7
  347. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +1 -0
  348. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +1 -0
  349. ksadk/server/static/assets/vennDiagram-4TSXK5OY-EnNl0DE7.js +34 -0
  350. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +1 -0
  351. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DBu5fbYr.js +78 -0
  352. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-BSVXs4IY.js +7 -0
  353. ksadk/server/static/index.html +2 -2
  354. ksadk/sessions/__init__.py +26 -9
  355. ksadk/sessions/_local_service_sync.py +688 -0
  356. ksadk/sessions/_local_tables.py +21 -0
  357. ksadk/sessions/_postgres_schema.py +305 -0
  358. ksadk/sessions/_postgres_tables.py +15 -0
  359. ksadk/sessions/base.py +80 -1
  360. ksadk/sessions/in_memory.py +53 -2
  361. ksadk/sessions/local_service.py +63 -604
  362. ksadk/sessions/postgres_service.py +58 -148
  363. ksadk/sessions/resilient.py +35 -1
  364. ksadk/skills/service_client.py +48 -0
  365. ksadk/studio/agent_lifecycle.py +26 -20
  366. ksadk/studio/api.py +1063 -69
  367. ksadk/studio/api_catalog_routes.py +5 -0
  368. ksadk/studio/api_contracts.py +148 -6
  369. ksadk/studio/api_memory_routes.py +82 -0
  370. ksadk/studio/api_plugin_routes.py +480 -0
  371. ksadk/studio/attachment_store.py +187 -0
  372. ksadk/studio/authoring.py +259 -28
  373. ksadk/studio/authoring_coordinator.py +809 -67
  374. ksadk/studio/builder.py +197 -40
  375. ksadk/studio/capabilities.py +17 -0
  376. ksadk/studio/cloud.py +1920 -95
  377. ksadk/studio/codex_agent_service.py +137 -15
  378. ksadk/studio/codex_authoring.py +469 -0
  379. ksadk/studio/codex_builder.py +177 -25
  380. ksadk/studio/codex_manifest.py +71 -22
  381. ksadk/studio/codex_run.py +59 -4
  382. ksadk/studio/compatibility_report.py +445 -0
  383. ksadk/studio/compiler.py +7 -1
  384. ksadk/studio/contracts.py +234 -4
  385. ksadk/studio/dsh_provider_registration.py +768 -0
  386. ksadk/studio/event_store.py +79 -101
  387. ksadk/studio/framework_run.py +264 -3
  388. ksadk/studio/hosted_kernel.py +317 -0
  389. ksadk/studio/manifest_resolver.py +131 -0
  390. ksadk/studio/model_client.py +95 -9
  391. ksadk/studio/model_profile_service.py +1 -1
  392. ksadk/studio/operations.py +47 -5
  393. ksadk/studio/otel_trace.py +348 -42
  394. ksadk/studio/pcm_memory.py +85 -0
  395. ksadk/studio/plugin_composition.py +301 -0
  396. ksadk/studio/plugin_kernel_adapter.py +128 -0
  397. ksadk/studio/plugin_runtime.py +652 -0
  398. ksadk/studio/repository.py +23 -2
  399. ksadk/studio/resource_catalog.py +49 -1
  400. ksadk/studio/run_service.py +1266 -202
  401. ksadk/studio/runtime_source.py +51 -17
  402. ksadk/studio/scheduler_runtime.py +374 -0
  403. ksadk/studio/scheduler_service.py +211 -0
  404. ksadk/studio/service.py +1815 -117
  405. ksadk/studio/shared_web.py +199 -50
  406. ksadk/studio/soul.py +52 -0
  407. ksadk/studio/static/assets/index-DXs1Eq4M.css +1 -0
  408. ksadk/studio/static/assets/index-DeDqwTsD.js +283 -0
  409. ksadk/studio/static/index.html +2 -2
  410. ksadk/studio/templates.py +100 -8
  411. ksadk/studio/validator.py +20 -1
  412. ksadk/studio/workspace.py +31 -32
  413. ksadk/tracing/setup.py +304 -3
  414. ksadk/version.py +1 -1
  415. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  416. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  417. ksadk_runtime_common/workspace_files/path_utils.py +41 -0
  418. ksadk/events/parser.py +0 -191
  419. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  420. ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +0 -303
  421. ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +0 -1
  422. ksadk/server/static/assets/arc-DrgjcKhl.js +0 -1
  423. ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +0 -1
  424. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-BXoVRbQ6.js +0 -36
  425. ksadk/server/static/assets/blockDiagram-GPEHLZMM-BnaB3Ywv.js +0 -132
  426. ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dw4weZcp.js +0 -10
  427. ksadk/server/static/assets/channel-Dt3rQTFI.js +0 -1
  428. ksadk/server/static/assets/chunk-2J33WTMH-ChjpLK7j.js +0 -1
  429. ksadk/server/static/assets/chunk-55IACEB6-CK4ROATy.js +0 -1
  430. ksadk/server/static/assets/chunk-727SXJPM-B9KtTTgw.js +0 -206
  431. ksadk/server/static/assets/chunk-AQP2D5EJ-1O1mki3m.js +0 -231
  432. ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +0 -1
  433. ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +0 -1
  434. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +0 -1
  435. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  436. ksadk/server/static/assets/dagre-BM42HDAG-D0QXg_MQ.js +0 -4
  437. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  438. ksadk/server/static/assets/diagram-2AECGRRQ-DBDDKwBQ.js +0 -43
  439. ksadk/server/static/assets/diagram-5GNKFQAL-BkwDOxmO.js +0 -10
  440. ksadk/server/static/assets/diagram-KO2AKTUF-Bv8waYvY.js +0 -3
  441. ksadk/server/static/assets/diagram-LMA3HP47-e1VECDdu.js +0 -24
  442. ksadk/server/static/assets/diagram-OG6HWLK6-Ds9adfRl.js +0 -24
  443. ksadk/server/static/assets/dist-B5J2uhNk.js +0 -1
  444. ksadk/server/static/assets/erDiagram-TEJ5UH35-BPItFKH6.js +0 -85
  445. ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +0 -1
  446. ksadk/server/static/assets/flowDiagram-I6XJVG4X-BbYB9w5Y.js +0 -162
  447. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-TQXa0KXv.js +0 -292
  448. ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +0 -1
  449. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-bKblCnpa.js +0 -106
  450. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  451. ksadk/server/static/assets/index-R52pJJvg.js +0 -177
  452. ksadk/server/static/assets/index-jJr3_955.css +0 -2
  453. ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +0 -1
  454. ksadk/server/static/assets/infoDiagram-5YYISTIA-BGVT7J_i.js +0 -2
  455. ksadk/server/static/assets/katex-CYWseY5E.js +0 -265
  456. ksadk/server/static/assets/mermaid-parser.core-BWrDjSZM.js +0 -161
  457. ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +0 -1
  458. ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +0 -1
  459. ksadk/server/static/assets/pieDiagram-4H26LBE5-GmmqNiVH.js +0 -30
  460. ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +0 -1
  461. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DSWFqL7c.js +0 -84
  462. ksadk/server/static/assets/stateDiagram-AJRCARHV-qzTQpg3Y.js +0 -1
  463. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +0 -1
  464. ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +0 -1
  465. ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +0 -1
  466. ksadk/server/static/assets/vennDiagram-CIIHVFJN-CMCixki2.js +0 -34
  467. ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +0 -1
  468. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-CVzB8F9K.js +0 -78
  469. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-BFBqBLc1.js +0 -7
  470. ksadk/studio/evaluation.py +0 -192
  471. ksadk/studio/static/assets/index-CaEN0eTR.css +0 -1
  472. ksadk/studio/static/assets/index-DI2eY_NH.js +0 -252
  473. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/WHEEL +0 -0
  474. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/entry_points.txt +0 -0
  475. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/licenses/LICENSE +0 -0
  476. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,34 @@
1
+ """Framework-native adapters for canonical RuntimeEvent schema v2.
2
+
3
+ ADK adapter 依赖可选 extra ``ksadk[adk]``(google-adk)。托管 Codex 镜像只装
4
+ 默认依赖,这里必须惰性导出,否则 ``ksadk.events.adapters`` 的传递 import 会
5
+ 让 codex-only 环境在启动期直接崩溃。
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import TYPE_CHECKING, Any
11
+
12
+ if TYPE_CHECKING: # pragma: no cover - typing only
13
+ from ksadk.events.adapters.adk import ADKAdapterContext, ADKEventAdapter
14
+
15
+ __all__ = ["ADKAdapterContext", "ADKEventAdapter"]
16
+
17
+ _LAZY_ATTRS = {"ADKAdapterContext", "ADKEventAdapter"}
18
+
19
+
20
+ def __getattr__(name: str) -> Any:
21
+ if name in _LAZY_ATTRS:
22
+ try:
23
+ from ksadk.events.adapters import adk as _adk
24
+ except ModuleNotFoundError as exc: # google.adk missing -> optional extra
25
+ raise ImportError(
26
+ "ADK event adapter requires the optional 'adk' extra "
27
+ "(pip install ksadk[adk])"
28
+ ) from exc
29
+ return getattr(_adk, name)
30
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
31
+
32
+
33
+ def __dir__() -> list[str]:
34
+ return sorted(__all__)
@@ -0,0 +1,622 @@
1
+ """A2AEventAdapter 的 task 快照映射方法(纯移动自 adapters.a2a,行为不变)。
2
+
3
+ 以 mixin 形式被 :class:`A2AEventAdapter` 继承。
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import base64
9
+ from collections.abc import Mapping
10
+ from typing import Literal, cast
11
+
12
+ from a2a.types import (
13
+ Artifact,
14
+ Message,
15
+ Part,
16
+ Role,
17
+ Task,
18
+ TaskState,
19
+ )
20
+ from google.protobuf.json_format import MessageToDict
21
+ from pydantic import JsonValue
22
+
23
+ from ksadk.events.adapters._a2a_support import (
24
+ A2AAdapterContext,
25
+ _ArtifactState,
26
+ _fail,
27
+ _MessageState,
28
+ _metadata,
29
+ _Occurrence,
30
+ _optional_metadata_string,
31
+ _parts_text,
32
+ _proto_fingerprint,
33
+ _required_metadata_string,
34
+ _required_string,
35
+ _SnapshotScope,
36
+ _validate_unique_parts,
37
+ )
38
+ from ksadk.events.canonical import (
39
+ ErrorInfo,
40
+ InteractionResolved,
41
+ ItemCompleted,
42
+ ItemFailed,
43
+ ItemSnapshotReplaced,
44
+ ItemStarted,
45
+ ItemUpdated,
46
+ OutputRef,
47
+ RunCanceled,
48
+ RunCompleted,
49
+ RunFailed,
50
+ RuntimeEvent,
51
+ StructuredInputResponse,
52
+ )
53
+ from ksadk.events.content import (
54
+ ArtifactContent,
55
+ ContentSnapshot,
56
+ ContentValue,
57
+ DataContent,
58
+ TextContent,
59
+ ToolCallContent,
60
+ ToolResultContent,
61
+ )
62
+ from ksadk.events.identity import (
63
+ stable_item_id,
64
+ stable_part_id,
65
+ )
66
+
67
+ ReconciliationReason = Literal["terminal", "reconnect", "subscription_rebuild"]
68
+
69
+ _ACTIVE_STATES = frozenset({TaskState.TASK_STATE_SUBMITTED, TaskState.TASK_STATE_WORKING})
70
+ _INTERACTION_STATES = frozenset(
71
+ {TaskState.TASK_STATE_INPUT_REQUIRED, TaskState.TASK_STATE_AUTH_REQUIRED}
72
+ )
73
+ _TERMINAL_STATES = frozenset(
74
+ {
75
+ TaskState.TASK_STATE_COMPLETED,
76
+ TaskState.TASK_STATE_FAILED,
77
+ TaskState.TASK_STATE_CANCELED,
78
+ TaskState.TASK_STATE_REJECTED,
79
+ }
80
+ )
81
+
82
+
83
+ class _A2ATaskSnapshotMixin:
84
+ def _map_task_snapshot(
85
+ self,
86
+ task: Task,
87
+ context: A2AAdapterContext,
88
+ reason: ReconciliationReason,
89
+ attempt_id: str,
90
+ timestamp: float,
91
+ ) -> tuple[RuntimeEvent, ...]:
92
+ state = task.status.state
93
+ occurrence = _Occurrence(
94
+ native_event_id=None,
95
+ native_cursor=None,
96
+ identity=(
97
+ f"get-task:{reason}:{attempt_id}:"
98
+ f"{TaskState.Name(state)}:{_proto_fingerprint(task)}"
99
+ ),
100
+ provisional=False,
101
+ )
102
+ scope = _SnapshotScope(
103
+ task=task,
104
+ context=context,
105
+ source=self._source(
106
+ context,
107
+ occurrence,
108
+ native_item_id=task.id,
109
+ metadata={
110
+ "provisional": False,
111
+ "consistent": True,
112
+ "reconciliation_reason": reason,
113
+ "reconciliation_attempt_id": attempt_id,
114
+ "terminal": state in _TERMINAL_STATES,
115
+ },
116
+ ),
117
+ timestamp=timestamp,
118
+ occurrence=occurrence,
119
+ terminal=state in _TERMINAL_STATES,
120
+ reason=reason,
121
+ attempt_id=attempt_id,
122
+ )
123
+ self._ensure_run_started(scope.events, context, scope.source, timestamp, occurrence)
124
+ self._snapshot_artifacts(scope)
125
+ interaction_state = state in _INTERACTION_STATES
126
+ status_message_id = (
127
+ task.status.message.message_id if task.status.HasField("message") else ""
128
+ )
129
+ self._snapshot_messages(scope, interaction_state, status_message_id)
130
+ if interaction_state:
131
+ interaction_events = self._map_status(
132
+ task.status,
133
+ {"event_id": occurrence.identity},
134
+ context,
135
+ timestamp,
136
+ native_item_id=status_message_id or None,
137
+ occurrence_payload=task,
138
+ )
139
+ scope.events.extend(
140
+ event.model_copy(update={"source": scope.source}) for event in interaction_events
141
+ )
142
+ return tuple(scope.events)
143
+ self._snapshot_terminal_run(scope, state)
144
+ if scope.terminal:
145
+ self._run_interrupted = False
146
+ self._terminal_snapshot_fingerprint = _proto_fingerprint(task)
147
+ return tuple(scope.events)
148
+
149
+ def _snapshot_artifacts(self, scope: _SnapshotScope) -> None:
150
+ task, context, source, occurrence = (
151
+ scope.task,
152
+ scope.context,
153
+ scope.source,
154
+ scope.occurrence,
155
+ )
156
+ env = self._env_builder(context, source, scope.timestamp, occurrence)
157
+ snapshot_artifact_ids: set[str] = set()
158
+
159
+ for artifact in task.artifacts:
160
+ artifact_id = _required_string(artifact.artifact_id, "task.artifacts.artifact_id")
161
+ snapshot_artifact_ids.add(artifact_id)
162
+ item_id = stable_item_id(
163
+ "a2a", context.context_id, context.task_id, "artifact", artifact_id
164
+ )
165
+ parts = self._convert_parts(artifact, item_id, start_index=0)
166
+ if not parts:
167
+ _fail(
168
+ "empty_artifact_snapshot",
169
+ "task.artifacts.parts",
170
+ "A2A GetTask artifact snapshot requires supported parts",
171
+ )
172
+ _validate_unique_parts(parts, "task.artifacts.parts")
173
+ snapshot = ContentSnapshot(parts=parts)
174
+ artifact_state = self._artifacts.get(artifact_id)
175
+ artifact_source = source.model_copy(update={"native_item_id": artifact_id})
176
+ if artifact_state is None:
177
+ artifact_state = _ArtifactState(artifact_id=artifact_id, item_id=item_id)
178
+ self._artifacts[artifact_id] = artifact_state
179
+ scope.events.append(
180
+ ItemStarted(
181
+ **env(
182
+ item_id, "item.started", "artifact", len(scope.events), artifact_source
183
+ ),
184
+ item_id=item_id,
185
+ item_kind="artifact",
186
+ phase="final_answer",
187
+ )
188
+ )
189
+ elif artifact_state.closed:
190
+ if artifact_state.snapshot() != snapshot:
191
+ _fail(
192
+ "trusted_snapshot_collision",
193
+ "task.artifacts",
194
+ f"GetTask changed already completed artifact {artifact_id!r}",
195
+ )
196
+ if scope.terminal:
197
+ scope.add_output_ref(item_id)
198
+ continue
199
+ artifact_state.parts = {part.part_id: part for part in parts}
200
+ artifact_state.part_order = [part.part_id for part in parts]
201
+ artifact_state.present = True
202
+ if scope.terminal:
203
+ artifact_state.closed = True
204
+ scope.events.append(
205
+ ItemCompleted(
206
+ **env(
207
+ item_id,
208
+ "item.completed",
209
+ "snapshot",
210
+ len(scope.events),
211
+ artifact_source,
212
+ ),
213
+ item_id=item_id,
214
+ item_kind="artifact",
215
+ snapshot=snapshot,
216
+ )
217
+ )
218
+ scope.add_output_ref(item_id)
219
+ else:
220
+ scope.events.append(
221
+ ItemSnapshotReplaced(
222
+ **env(
223
+ item_id,
224
+ "item.snapshot_replaced",
225
+ "snapshot",
226
+ len(scope.events),
227
+ artifact_source,
228
+ ),
229
+ item_id=item_id,
230
+ item_kind="artifact",
231
+ snapshot=snapshot,
232
+ )
233
+ )
234
+
235
+ for artifact_id, artifact_state in self._artifacts.items():
236
+ if artifact_id in snapshot_artifact_ids or artifact_state.closed:
237
+ continue
238
+ removed_source = source.model_copy(update={"native_item_id": artifact_id})
239
+ artifact_state.present = False
240
+ artifact_state.parts = {}
241
+ artifact_state.part_order = []
242
+ if scope.terminal:
243
+ artifact_state.closed = True
244
+ scope.events.append(
245
+ ItemFailed(
246
+ **env(
247
+ artifact_state.item_id,
248
+ "item.failed",
249
+ "artifact",
250
+ len(scope.events),
251
+ removed_source,
252
+ ),
253
+ item_id=artifact_state.item_id,
254
+ item_kind="artifact",
255
+ error=ErrorInfo(
256
+ code="a2a_artifact_removed_by_snapshot",
257
+ message=(
258
+ "provisional artifact absent from authoritative GetTask snapshot"
259
+ ),
260
+ source="a2a",
261
+ scope_id=context.scope_id,
262
+ item_id=artifact_state.item_id,
263
+ source_ref=removed_source,
264
+ ),
265
+ )
266
+ )
267
+ else:
268
+ scope.events.append(
269
+ ItemSnapshotReplaced(
270
+ **env(
271
+ artifact_state.item_id,
272
+ "item.snapshot_replaced",
273
+ "snapshot",
274
+ len(scope.events),
275
+ removed_source,
276
+ ),
277
+ item_id=artifact_state.item_id,
278
+ item_kind="artifact",
279
+ snapshot=ContentSnapshot(parts=()),
280
+ )
281
+ )
282
+
283
+ def _snapshot_messages(
284
+ self,
285
+ scope: _SnapshotScope,
286
+ interaction_state: bool,
287
+ status_message_id: str,
288
+ ) -> None:
289
+ task = scope.task
290
+ snapshot_messages = [
291
+ message
292
+ for message in task.history
293
+ if not (interaction_state and message.message_id == status_message_id)
294
+ ]
295
+ if (
296
+ not interaction_state
297
+ and task.status.HasField("message")
298
+ and all(
299
+ message.message_id != task.status.message.message_id
300
+ for message in snapshot_messages
301
+ )
302
+ ):
303
+ snapshot_messages.append(task.status.message)
304
+ for nested_message in snapshot_messages:
305
+ message = self._normalize_nested_message(nested_message, scope.context)
306
+ if message.role != Role.ROLE_AGENT:
307
+ continue
308
+ scope.events.extend(
309
+ self._map_message(
310
+ message,
311
+ scope.context,
312
+ scope.timestamp,
313
+ consistent=True,
314
+ occurrence_identity=(
315
+ f"get-task:{scope.reason}:{scope.attempt_id}:message:{message.message_id}"
316
+ ),
317
+ )
318
+ )
319
+ message_id = self._message_item_id(
320
+ scope.context, _required_string(message.message_id, "message.message_id")
321
+ )
322
+ if scope.terminal:
323
+ scope.add_output_ref(message_id)
324
+
325
+ def _snapshot_terminal_run(self, scope: _SnapshotScope, state: TaskState) -> None:
326
+ context, events = scope.context, scope.events
327
+ terminal_source = scope.source.model_copy(update={"native_item_id": scope.task.id})
328
+ env = self._env_builder(context, terminal_source, scope.timestamp, scope.occurrence)
329
+
330
+ if state in _TERMINAL_STATES and self._active_interaction is not None:
331
+ interaction_id, _ = self._active_interaction
332
+ events.append(
333
+ InteractionResolved(
334
+ **env(interaction_id, "interaction.resolved", "interaction", len(events)),
335
+ interaction_id=interaction_id,
336
+ interaction_kind="structured_input",
337
+ response=StructuredInputResponse(data={"state": TaskState.Name(state)}),
338
+ )
339
+ )
340
+ self._active_interaction = None
341
+
342
+ def status_text() -> str | None:
343
+ if not scope.task.status.HasField("message"):
344
+ return None
345
+ return _parts_text(
346
+ self._normalize_nested_message(scope.task.status.message, context).parts
347
+ )
348
+
349
+ if state == TaskState.TASK_STATE_COMPLETED:
350
+ events.append(
351
+ RunCompleted(
352
+ **env(context.run_id, "run.completed", "run", len(events)),
353
+ status="completed",
354
+ output_refs=tuple(scope._output_refs),
355
+ )
356
+ )
357
+ elif state in {TaskState.TASK_STATE_FAILED, TaskState.TASK_STATE_REJECTED}:
358
+ events.append(
359
+ RunFailed(
360
+ **env(context.run_id, "run.failed", "run", len(events)),
361
+ status="failed",
362
+ error=ErrorInfo(
363
+ code=(
364
+ "a2a_task_rejected"
365
+ if state == TaskState.TASK_STATE_REJECTED
366
+ else "a2a_task_failed"
367
+ ),
368
+ message=status_text(),
369
+ source="a2a",
370
+ scope_id=context.scope_id,
371
+ source_ref=terminal_source,
372
+ ),
373
+ )
374
+ )
375
+ elif state == TaskState.TASK_STATE_CANCELED:
376
+ events.append(
377
+ RunCanceled(
378
+ **env(context.run_id, "run.canceled", "run", len(events)),
379
+ status="canceled",
380
+ reason=status_text(),
381
+ )
382
+ )
383
+ else:
384
+ events.append(
385
+ self._run_progress_event(
386
+ context,
387
+ terminal_source,
388
+ scope.timestamp,
389
+ scope.occurrence,
390
+ len(events),
391
+ message=f"authoritative {TaskState.Name(state)} snapshot",
392
+ )
393
+ )
394
+
395
+ def _map_message(
396
+ self,
397
+ message: Message,
398
+ context: A2AAdapterContext,
399
+ timestamp: float,
400
+ *,
401
+ consistent: bool,
402
+ occurrence_identity: str | None = None,
403
+ direct_response: bool = False,
404
+ ) -> tuple[RuntimeEvent, ...]:
405
+ message_id = _required_string(message.message_id, "message.message_id")
406
+ message_metadata = _metadata(message.metadata)
407
+ producer_event_id = _optional_metadata_string(
408
+ message_metadata, "event_id", "ksadk_event_id"
409
+ )
410
+ if producer_event_id is not None:
411
+ occurrence = self._occurrence(
412
+ message_metadata, provisional_key=f"message:{message_id}", payload=message
413
+ )
414
+ if occurrence.duplicate:
415
+ return ()
416
+ else:
417
+ cursor = _optional_metadata_string(message_metadata, "seq", "ksadk_seq")
418
+ occurrence = _Occurrence(
419
+ native_event_id=message_id,
420
+ native_cursor=cursor,
421
+ identity=occurrence_identity or message_id,
422
+ provisional=False,
423
+ )
424
+ signature = message.SerializeToString(deterministic=True)
425
+ existing = self._messages.get(message_id)
426
+ if existing is not None:
427
+ if existing.signature != signature:
428
+ _fail(
429
+ "message_identity_collision",
430
+ "message.message_id",
431
+ f"A2A message {message_id!r} changed after completion",
432
+ )
433
+ return ()
434
+ if producer_event_id is not None and occurrence_identity is not None:
435
+ occurrence = _Occurrence(
436
+ native_event_id=occurrence.native_event_id,
437
+ native_cursor=occurrence.native_cursor,
438
+ identity=occurrence_identity,
439
+ provisional=False,
440
+ )
441
+ item_id = self._message_item_id(context, message_id)
442
+ parts = self._convert_parts(message, item_id)
443
+ if not parts:
444
+ _fail(
445
+ "empty_message", "message.parts", "A2A message requires at least one supported part"
446
+ )
447
+ _validate_unique_parts(parts, "message.parts")
448
+ source = self._source(
449
+ context,
450
+ occurrence,
451
+ native_item_id=message_id,
452
+ metadata={
453
+ "provisional": False,
454
+ "consistent": consistent,
455
+ "role": Role.Name(message.role),
456
+ },
457
+ )
458
+
459
+ env = self._env_builder(context, source, timestamp, occurrence)
460
+ events: list[RuntimeEvent] = []
461
+ if direct_response:
462
+ self._ensure_run_started(events, context, source, timestamp, occurrence)
463
+ events.append(
464
+ ItemStarted(
465
+ **env(item_id, "item.started", "message", 0),
466
+ item_id=item_id,
467
+ item_kind="message",
468
+ phase="final_answer",
469
+ )
470
+ )
471
+ for index, part in enumerate(parts, start=1):
472
+ events.append(
473
+ ItemUpdated(
474
+ **env(item_id, "item.updated", part.part_id, index),
475
+ item_id=item_id,
476
+ item_kind="message",
477
+ op="replace",
478
+ update=part,
479
+ )
480
+ )
481
+ events.append(
482
+ ItemCompleted(
483
+ **env(item_id, "item.completed", "snapshot", len(parts) + 1),
484
+ item_id=item_id,
485
+ item_kind="message",
486
+ snapshot=ContentSnapshot(parts=parts),
487
+ )
488
+ )
489
+ self._messages[message_id] = _MessageState(signature=signature)
490
+ if direct_response:
491
+ events.append(
492
+ RunCompleted(
493
+ **env(context.run_id, "run.completed", "run", len(parts) + 2),
494
+ status="completed",
495
+ output_refs=(OutputRef(scope_id=context.scope_id, item_id=item_id),),
496
+ )
497
+ )
498
+ return tuple(events)
499
+
500
+ def _convert_parts(
501
+ self,
502
+ owner: Artifact | Message,
503
+ item_id: str,
504
+ *,
505
+ start_index: int = 0,
506
+ ) -> tuple[ContentValue, ...]:
507
+ converted: list[ContentValue] = []
508
+ for index, part in enumerate(owner.parts, start=start_index):
509
+ converted.append(self._convert_part(owner, part, item_id, index))
510
+ return tuple(converted)
511
+
512
+ def _convert_part(
513
+ self,
514
+ owner: Artifact | Message,
515
+ part: Part,
516
+ item_id: str,
517
+ index: int,
518
+ ) -> ContentValue:
519
+ metadata = _metadata(part.metadata)
520
+ content_kind = part.WhichOneof("content")
521
+ kind = _optional_metadata_string(metadata, "kind", "ksadk_kind")
522
+ if content_kind == "text":
523
+ native_part = _optional_metadata_string(metadata, "part_id") or f"text:{index}"
524
+ return TextContent(
525
+ part_id=stable_part_id("a2a", item_id, native_part),
526
+ text=part.text,
527
+ )
528
+ if content_kind == "data":
529
+ native_kind = kind or "data"
530
+ native_part = _optional_metadata_string(metadata, "part_id") or f"{native_kind}:{index}"
531
+ part_id = stable_part_id("a2a", item_id, native_part)
532
+ value = cast(JsonValue, MessageToDict(part.data))
533
+ if native_kind == "tool_call":
534
+ return ToolCallContent(
535
+ part_id=part_id,
536
+ call_id=_required_metadata_string(metadata, "call_id"),
537
+ name=_required_metadata_string(metadata, "name"),
538
+ arguments=value,
539
+ )
540
+ if native_kind == "tool_result":
541
+ return ToolResultContent(
542
+ part_id=part_id,
543
+ call_id=_required_metadata_string(metadata, "call_id"),
544
+ result=value,
545
+ is_error=bool(metadata.get("is_error", False)),
546
+ )
547
+ if native_kind != "data":
548
+ _fail(
549
+ "unknown_part_kind",
550
+ "part.metadata.kind",
551
+ f"unsupported A2A data part kind {native_kind!r}",
552
+ )
553
+ return DataContent(part_id=part_id, data=value)
554
+ if content_kind in {"url", "raw"}:
555
+ native_part = _optional_metadata_string(metadata, "part_id") or f"file:{index}"
556
+ artifact_id = (
557
+ owner.artifact_id
558
+ if isinstance(owner, Artifact)
559
+ else f"message:{owner.message_id}:part:{index}"
560
+ )
561
+ name = part.filename or (owner.name if isinstance(owner, Artifact) else "attachment")
562
+ data: JsonValue = None
563
+ if content_kind == "raw":
564
+ data = {"base64": base64.b64encode(part.raw).decode("ascii")}
565
+ return ArtifactContent(
566
+ part_id=stable_part_id("a2a", item_id, native_part),
567
+ artifact_id=artifact_id,
568
+ name=name,
569
+ mime_type=part.media_type or None,
570
+ uri=part.url if content_kind == "url" else None,
571
+ data=data,
572
+ )
573
+ _fail(
574
+ "empty_part",
575
+ "parts",
576
+ f"A2A part at index {index} has no supported payload",
577
+ )
578
+
579
+ def _occurrence(
580
+ self,
581
+ metadata: Mapping[str, JsonValue],
582
+ *,
583
+ provisional_key: str,
584
+ payload: object,
585
+ ) -> _Occurrence:
586
+ native_event_id = _optional_metadata_string(metadata, "event_id", "ksadk_event_id")
587
+ native_cursor = _optional_metadata_string(metadata, "seq", "ksadk_seq")
588
+ if native_event_id is not None:
589
+ fingerprint = _proto_fingerprint(payload)
590
+ previous = self._seen_occurrences.get(native_event_id)
591
+ if previous is not None:
592
+ if previous != fingerprint:
593
+ _fail(
594
+ "producer_event_id_collision",
595
+ "metadata.event_id",
596
+ f"A2A producer event_id {native_event_id!r} changed payload",
597
+ )
598
+ self._seen_occurrences.move_to_end(native_event_id)
599
+ return _Occurrence(
600
+ native_event_id=native_event_id,
601
+ native_cursor=native_cursor,
602
+ identity=native_event_id,
603
+ provisional=False,
604
+ duplicate=True,
605
+ )
606
+ self._seen_occurrences[native_event_id] = fingerprint
607
+ while len(self._seen_occurrences) > self.OCCURRENCE_CACHE_LIMIT:
608
+ self._seen_occurrences.popitem(last=False)
609
+ return _Occurrence(
610
+ native_event_id=native_event_id,
611
+ native_cursor=native_cursor,
612
+ identity=native_event_id,
613
+ provisional=False,
614
+ )
615
+ ordinal = self._provisional_ordinals.get(provisional_key, 0)
616
+ self._provisional_ordinals[provisional_key] = ordinal + 1
617
+ return _Occurrence(
618
+ native_event_id=None,
619
+ native_cursor=native_cursor,
620
+ identity=f"provisional:{provisional_key}:{ordinal}",
621
+ provisional=True,
622
+ )