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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +43 -7
  2. agentengine_sdk_python-0.8.2.dist-info/RECORD +778 -0
  3. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +1 -1
  4. ksadk/a2a/__init__.py +2 -0
  5. ksadk/a2a/_space_client_events.py +381 -0
  6. ksadk/a2a/bootstrap.py +0 -2
  7. ksadk/a2a/card.py +6 -111
  8. ksadk/a2a/control_plane.py +239 -1
  9. ksadk/a2a/event_adapter.py +156 -64
  10. ksadk/a2a/executor.py +195 -172
  11. ksadk/a2a/routes.py +12 -5
  12. ksadk/a2a/server.py +1 -8
  13. ksadk/a2a/service_env.py +33 -0
  14. ksadk/a2a/space_client.py +43 -349
  15. ksadk/a2a_card.py +101 -0
  16. ksadk/a2ui/core.py +222 -53
  17. ksadk/agui/_agent_helpers.py +243 -0
  18. ksadk/agui/a2ui_projection.py +12 -5
  19. ksadk/agui/agent.py +474 -275
  20. ksadk/agui/config.py +11 -5
  21. ksadk/agui/routes.py +7 -15
  22. ksadk/api/client.py +530 -40
  23. ksadk/api/environment.py +27 -0
  24. ksadk/builders/code_builder.py +352 -53
  25. ksadk/builders/container_builder.py +71 -44
  26. ksadk/builders/framework_requirements.py +2 -1
  27. ksadk/builders/ks3_uploader.py +2 -2
  28. ksadk/builders/managed_runtime_builder.py +60 -28
  29. ksadk/cli/__init__.py +25 -0
  30. ksadk/cli/cmd_a2a.py +18 -31
  31. ksadk/cli/cmd_create.py +13 -26
  32. ksadk/cli/cmd_dashboard.py +15 -1
  33. ksadk/cli/cmd_deploy.py +28 -3
  34. ksadk/cli/cmd_eval.py +443 -0
  35. ksadk/cli/cmd_evalset.py +284 -0
  36. ksadk/cli/cmd_files.py +5 -1
  37. ksadk/cli/cmd_hermes.py +137 -163
  38. ksadk/cli/cmd_invoke.py +28 -38
  39. ksadk/cli/cmd_launch.py +12 -0
  40. ksadk/cli/cmd_managed_runtime.py +95 -0
  41. ksadk/cli/cmd_observe.py +85 -0
  42. ksadk/cli/cmd_openclaw.py +85 -479
  43. ksadk/cli/cmd_replay.py +28 -4
  44. ksadk/cli/cmd_run.py +29 -67
  45. ksadk/cli/cmd_studio.py +201 -0
  46. ksadk/cli/cmd_web.py +15 -6
  47. ksadk/cli/dry_run.py +2 -1
  48. ksadk/cli/env_options.py +83 -0
  49. ksadk/cli/global_options.py +3 -1
  50. ksadk/cli/hermes_env.py +151 -0
  51. ksadk/cli/invoke_payload.py +49 -0
  52. ksadk/cli/network_options.py +7 -5
  53. ksadk/cli/openclaw_env.py +458 -0
  54. ksadk/cli/runtime_bootstrap.py +51 -0
  55. ksadk/cli/ui.py +6 -0
  56. ksadk/cli/workflow_common.py +5 -5
  57. ksadk/codex/__init__.py +3 -3
  58. ksadk/codex/client.py +833 -49
  59. ksadk/codex/phase.py +1 -1
  60. ksadk/codex/runtime.py +720 -127
  61. ksadk/common/kop_client.py +232 -0
  62. ksadk/configs/__init__.py +1 -3
  63. ksadk/configs/env_registry.py +244 -45
  64. ksadk/configs/env_registry_pcm.py +181 -0
  65. ksadk/configs/env_var_spec.py +18 -0
  66. ksadk/configs/global_config.py +6 -1
  67. ksadk/configs/settings.py +5 -108
  68. ksadk/context_engine/__init__.py +98 -0
  69. ksadk/context_engine/assembler.py +176 -0
  70. ksadk/context_engine/baseline.py +419 -0
  71. ksadk/context_engine/cache_observability.py +228 -0
  72. ksadk/context_engine/capabilities.py +443 -0
  73. ksadk/context_engine/contributors.py +344 -0
  74. ksadk/context_engine/hosted_pipeline.py +417 -0
  75. ksadk/context_engine/models.py +117 -0
  76. ksadk/context_engine/planner.py +698 -0
  77. ksadk/context_engine/policies.py +319 -0
  78. ksadk/context_engine/projection.py +31 -0
  79. ksadk/context_engine/shadow_plan.py +266 -0
  80. ksadk/context_engine/tokenizer.py +164 -0
  81. ksadk/conversations/__init__.py +85 -94
  82. ksadk/conversations/context.py +126 -6
  83. ksadk/conversations/message_projection.py +292 -28
  84. ksadk/conversations/model_context.py +49 -3
  85. ksadk/conversations/runtime_compaction.py +207 -5
  86. ksadk/conversations/runtime_input.py +193 -3
  87. ksadk/conversations/runtime_invocation.py +81 -3
  88. ksadk/conversations/runtime_observability.py +157 -4
  89. ksadk/conversations/runtime_payloads.py +42 -0
  90. ksadk/conversations/runtime_preparation.py +280 -2
  91. ksadk/conversations/runtime_resume.py +71 -32
  92. ksadk/conversations/runtime_stream_events.py +94 -9
  93. ksadk/conversations/runtime_streaming.py +175 -22
  94. ksadk/conversations/semantic_summary.py +311 -1
  95. ksadk/conversations/session_lock.py +51 -0
  96. ksadk/deployment/env_forward.py +72 -0
  97. ksadk/deployment/managed_runtime.py +38 -0
  98. ksadk/deployment/manager.py +24 -8
  99. ksadk/deployment/providers/serverless.py +228 -92
  100. ksadk/evaluation/__init__.py +116 -0
  101. ksadk/evaluation/a2a_adapter.py +452 -0
  102. ksadk/evaluation/adapters.py +67 -0
  103. ksadk/evaluation/agent_eval_client.py +395 -0
  104. ksadk/evaluation/cloud_binding.py +80 -0
  105. ksadk/evaluation/cloud_converter.py +194 -0
  106. ksadk/evaluation/cloud_service.py +199 -0
  107. ksadk/evaluation/contracts.py +478 -0
  108. ksadk/evaluation/evalset.py +351 -0
  109. ksadk/evaluation/evaluators.py +627 -0
  110. ksadk/evaluation/evidence.py +258 -0
  111. ksadk/evaluation/executor.py +143 -0
  112. ksadk/evaluation/local_adapter.py +550 -0
  113. ksadk/evaluation/service_env.py +27 -0
  114. ksadk/evaluation/storage.py +68 -0
  115. ksadk/evaluation/studio_build_adapter.py +253 -0
  116. ksadk/evaluation/target.py +82 -0
  117. ksadk/events/__init__.py +13 -13
  118. ksadk/events/_v1_compat/__init__.py +1 -0
  119. ksadk/events/_v1_compat/models.py +299 -0
  120. ksadk/events/_v1_compat/parser.py +247 -0
  121. ksadk/events/_v1_compat/projection.py +753 -0
  122. ksadk/events/adapters/__init__.py +34 -0
  123. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  124. ksadk/events/adapters/_a2a_support.py +275 -0
  125. ksadk/events/adapters/_codex_interactions.py +375 -0
  126. ksadk/events/adapters/_codex_items.py +801 -0
  127. ksadk/events/adapters/_codex_validators.py +311 -0
  128. ksadk/events/adapters/_langgraph_support.py +785 -0
  129. ksadk/events/adapters/a2a.py +841 -0
  130. ksadk/events/adapters/adk.py +503 -0
  131. ksadk/events/adapters/codex.py +717 -0
  132. ksadk/events/adapters/langgraph.py +745 -0
  133. ksadk/events/canonical.py +440 -0
  134. ksadk/events/canonical_replay.py +497 -0
  135. ksadk/events/canonical_store.py +468 -0
  136. ksadk/events/cold_recovery.py +257 -0
  137. ksadk/events/content.py +89 -0
  138. ksadk/events/identity.py +86 -0
  139. ksadk/events/pipeline.py +455 -0
  140. ksadk/events/projections.py +66 -0
  141. ksadk/events/reducer.py +661 -0
  142. ksadk/events/replay.py +3 -36
  143. ksadk/events/runtime_event.py +20 -256
  144. ksadk/events/session_event.py +324 -0
  145. ksadk/events/store.py +3 -316
  146. ksadk/events/v1_compat.py +41 -0
  147. ksadk/harness/__init__.py +3 -2
  148. ksadk/harness/app.py +114 -123
  149. ksadk/harness/config.py +1 -1
  150. ksadk/harness/runtime.py +467 -0
  151. ksadk/hermes_terminal.py +5 -0
  152. ksadk/identity/resolver.py +4 -3
  153. ksadk/interaction/__init__.py +28 -0
  154. ksadk/interaction/contracts.py +136 -0
  155. ksadk/interaction/ledger.py +189 -0
  156. ksadk/interaction/provider.py +122 -0
  157. ksadk/interaction/providers/__init__.py +52 -0
  158. ksadk/interaction/providers/adk.py +40 -0
  159. ksadk/interaction/providers/codex.py +94 -0
  160. ksadk/interaction/providers/langgraph.py +58 -0
  161. ksadk/kernel/__init__.py +117 -0
  162. ksadk/kernel/authorization.py +258 -0
  163. ksadk/kernel/bootstrap.py +1074 -0
  164. ksadk/kernel/contract_fingerprints.py +61 -0
  165. ksadk/kernel/contracts.py +362 -0
  166. ksadk/kernel/control.py +219 -0
  167. ksadk/kernel/errors.py +79 -0
  168. ksadk/kernel/ingress.py +1102 -0
  169. ksadk/kernel/mapping.py +111 -0
  170. ksadk/kernel/memory_store.py +1133 -0
  171. ksadk/kernel/postgres_store.py +1756 -0
  172. ksadk/kernel/recovery.py +452 -0
  173. ksadk/kernel/runtime_identity.py +103 -0
  174. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  175. ksadk/kernel/sqlite_store.py +1410 -0
  176. ksadk/kernel/state.py +145 -0
  177. ksadk/kernel/store.py +232 -0
  178. ksadk/kernel/worker.py +953 -0
  179. ksadk/knowledge_base/client.py +22 -4
  180. ksadk/knowledge_base/service.py +32 -5
  181. ksadk/managed_a2a_card.py +160 -0
  182. ksadk/managed_runtime.py +16 -9
  183. ksadk/memory/__init__.py +61 -0
  184. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  185. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  186. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  187. ksadk/memory/adk/backends/sdk_ltm_backend.py +394 -5
  188. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  189. ksadk/memory/adk/long_term_memory.py +3 -2
  190. ksadk/memory/coordinator.py +461 -0
  191. ksadk/memory/events.py +202 -0
  192. ksadk/memory/extraction.py +228 -0
  193. ksadk/memory/ltm_backend_factory.py +16 -3
  194. ksadk/memory/models.py +316 -0
  195. ksadk/memory/policy.py +215 -0
  196. ksadk/memory/provider.py +47 -0
  197. ksadk/memory/provider_adapter.py +159 -0
  198. ksadk/memory/provider_resolver.py +71 -0
  199. ksadk/memory/providers/__init__.py +5 -0
  200. ksadk/memory/providers/local_sqlite.py +490 -0
  201. ksadk/memory/resolved_policy.py +145 -0
  202. ksadk/memory/service.py +198 -8
  203. ksadk/memory/tool.py +4 -0
  204. ksadk/model_proxy/bootstrap.py +16 -9
  205. ksadk/model_proxy/config.py +22 -1
  206. ksadk/model_proxy/detect.py +202 -9
  207. ksadk/model_proxy/namespace.py +67 -15
  208. ksadk/model_proxy/server.py +168 -6
  209. ksadk/model_proxy/transform.py +105 -3
  210. ksadk/observability/__init__.py +25 -0
  211. ksadk/observability/session_log.py +420 -0
  212. ksadk/observability/trajectory.py +105 -0
  213. ksadk/prompts/__init__.py +71 -0
  214. ksadk/prompts/compiler.py +215 -0
  215. ksadk/prompts/models.py +82 -0
  216. ksadk/prompts/projection.py +89 -0
  217. ksadk/prompts/resolved.py +137 -0
  218. ksadk/prompts/sources.py +233 -0
  219. ksadk/runners/_langgraph_runner_streams.py +822 -0
  220. ksadk/runners/adk_runner.py +14 -31
  221. ksadk/runners/base_runner.py +44 -3
  222. ksadk/runners/factory.py +3 -3
  223. ksadk/runners/langgraph_runner.py +252 -433
  224. ksadk/runners/utils/__init__.py +0 -10
  225. ksadk/runners/utils/loader.py +16 -0
  226. ksadk/runtime/__init__.py +67 -41
  227. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  228. ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
  229. ksadk/runtime/adapter.py +199 -16
  230. ksadk/runtime/conversation_execution.py +687 -0
  231. ksadk/runtime/executor.py +392 -0
  232. ksadk/runtime/factory.py +342 -0
  233. ksadk/runtime/framework_adapters.py +6 -12
  234. ksadk/runtime/hosted_finalizer.py +268 -0
  235. ksadk/runtime/launch.py +61 -0
  236. ksadk/runtime/preprocessing.py +49 -14
  237. ksadk/runtime/runner_adapter.py +330 -391
  238. ksadk/runtime/runner_loading.py +36 -0
  239. ksadk/runtime/usage.py +33 -0
  240. ksadk/sandbox/backends/e2b.py +36 -3
  241. ksadk/server/__init__.py +39 -4
  242. ksadk/server/app.py +18 -492
  243. ksadk/server/composition.py +36 -2
  244. ksadk/server/factory.py +210 -149
  245. ksadk/server/routes/common.py +15 -46
  246. ksadk/server/routes/control.py +13 -9
  247. ksadk/server/routes/kernel_ingress.py +258 -0
  248. ksadk/server/routes/misc.py +10 -33
  249. ksadk/server/routes/models.py +14 -6
  250. ksadk/server/routes/openai_compat.py +129 -27
  251. ksadk/server/routes/projection.py +84 -16
  252. ksadk/server/routes/run.py +347 -460
  253. ksadk/server/routes/sessions.py +37 -40
  254. ksadk/server/routes/streaming.py +52 -7
  255. ksadk/server/routes/workspace.py +54 -21
  256. ksadk/server/static/assets/{ArtifactsPanel-Cjnqt-8W.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
  257. ksadk/server/static/assets/{CodeBlock-BqyqZfuB.js → CodeBlock-DOH6MVcn.js} +4 -4
  258. ksadk/server/static/assets/{MathMessageMarkdown-BpH7jiFM.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
  259. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  260. ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
  261. ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
  262. ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
  263. ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
  264. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
  265. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
  266. ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
  267. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
  268. ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
  269. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
  270. ksadk/server/static/assets/{chunk-FMBD7UC4-BGhvzDYt.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
  271. ksadk/server/static/assets/{chunk-ND2GUHAM-D98vPd-E.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
  272. ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
  273. ksadk/server/static/assets/{chunk-4BX2VUAB-CsWIQRhc.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
  274. ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
  275. ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
  276. ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
  277. ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
  278. ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
  279. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
  280. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
  281. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-CX3yotHq.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
  282. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
  283. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
  284. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  285. ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
  286. ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
  287. ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
  288. ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
  289. ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
  290. ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
  291. ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
  292. ksadk/server/static/assets/{dist-D82mtD2s.js → dist-8hqcx0sU.js} +1 -1
  293. ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
  294. ksadk/server/static/assets/{dist-DHn6nBzr.js → dist-BE7bu-DL.js} +1 -1
  295. ksadk/server/static/assets/{dist-eoW6tZXA.js → dist-BVDffZ0U.js} +1 -1
  296. ksadk/server/static/assets/{dist-C2xjE7cO.js → dist-BX8z72IC.js} +1 -1
  297. ksadk/server/static/assets/{dist-CgF3fj15.js → dist-Bf2M8m3N.js} +1 -1
  298. ksadk/server/static/assets/{dist-Bs-jQcRX.js → dist-BjU6y-A2.js} +1 -1
  299. ksadk/server/static/assets/{dist-Djgl2wVZ.js → dist-BytlxIDT.js} +1 -1
  300. ksadk/server/static/assets/{dist-CVQRZjPu.js → dist-CSh_DE14.js} +1 -1
  301. ksadk/server/static/assets/{dist-6CVKuTAe.js → dist-CXYYBw3_.js} +1 -1
  302. ksadk/server/static/assets/{dist-DlzCRy0S.js → dist-C_wsv-Qd.js} +1 -1
  303. ksadk/server/static/assets/{dist-DF06ORQo.js → dist-ClxGviKw.js} +1 -1
  304. ksadk/server/static/assets/{dist-Cf23NY4L.js → dist-CttYUqzS.js} +1 -1
  305. ksadk/server/static/assets/{dist-ivOya1LD.js → dist-DNp6rLRA.js} +1 -1
  306. ksadk/server/static/assets/{dist-BibcG1V9.js → dist-DUX-id_F.js} +1 -1
  307. ksadk/server/static/assets/{dist-BUHRxvDG.js → dist-DmldrHd_.js} +1 -1
  308. ksadk/server/static/assets/{dist-BZ9n9AjO.js → dist-DnfXs8Vn.js} +2 -2
  309. ksadk/server/static/assets/{dist-DqNnNFrw.js → dist-Dq9gLD7L.js} +1 -1
  310. ksadk/server/static/assets/{dist-CGcp2ex8.js → dist-W-TIVntx.js} +1 -1
  311. ksadk/server/static/assets/{dist-Cwt7koer.js → dist-dDdADKFA.js} +1 -1
  312. ksadk/server/static/assets/{dist-C7-3jInC.js → dist-dydu68Fl.js} +1 -1
  313. ksadk/server/static/assets/{dist-C99THtIA.js → dist-ngtN0DJB.js} +1 -1
  314. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
  315. ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
  316. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
  317. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
  318. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
  319. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
  320. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
  321. ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
  322. ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
  323. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
  324. ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
  325. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-DLOHGvWw.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
  326. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-BIzKeejT.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
  327. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-BWHoFSw2.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
  328. ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
  329. ksadk/server/static/assets/{linear-CvMBw9cA.js → linear-BHjG8b-J.js} +1 -1
  330. ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
  331. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-CSAQxEAe.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
  332. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
  333. ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
  334. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
  335. ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
  336. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-CxIR4JXI.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
  337. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
  338. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
  339. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
  340. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
  341. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
  342. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
  343. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
  344. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-DpGa6EAV.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
  345. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-NTKNGGe5.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
  346. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
  347. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
  348. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
  349. ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
  350. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
  351. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-jqoYs3jQ.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
  352. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
  353. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
  354. ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
  355. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
  356. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
  357. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
  358. ksadk/server/static/index.html +2 -2
  359. ksadk/sessions/__init__.py +26 -9
  360. ksadk/sessions/_local_service_sync.py +688 -0
  361. ksadk/sessions/_local_tables.py +21 -0
  362. ksadk/sessions/_postgres_schema.py +305 -0
  363. ksadk/sessions/_postgres_tables.py +15 -0
  364. ksadk/sessions/base.py +80 -1
  365. ksadk/sessions/in_memory.py +53 -2
  366. ksadk/sessions/local_service.py +63 -604
  367. ksadk/sessions/postgres_service.py +58 -148
  368. ksadk/sessions/resilient.py +35 -1
  369. ksadk/skills/runtime/backends/e2b.py +1 -1
  370. ksadk/skills/service_client.py +13 -3
  371. ksadk/studio/__init__.py +5 -0
  372. ksadk/studio/agent_avatar_assets.py +120 -0
  373. ksadk/studio/agent_lifecycle.py +51 -0
  374. ksadk/studio/api.py +1598 -0
  375. ksadk/studio/api_catalog_routes.py +324 -0
  376. ksadk/studio/api_contracts.py +286 -0
  377. ksadk/studio/api_helpers.py +132 -0
  378. ksadk/studio/api_memory_routes.py +82 -0
  379. ksadk/studio/authoring.py +749 -0
  380. ksadk/studio/authoring_coordinator.py +1017 -0
  381. ksadk/studio/builder.py +397 -0
  382. ksadk/studio/capabilities.py +368 -0
  383. ksadk/studio/cloud.py +2099 -0
  384. ksadk/studio/codex_agent_service.py +694 -0
  385. ksadk/studio/codex_authoring.py +469 -0
  386. ksadk/studio/codex_builder.py +437 -0
  387. ksadk/studio/codex_manifest.py +307 -0
  388. ksadk/studio/codex_run.py +395 -0
  389. ksadk/studio/compiler.py +190 -0
  390. ksadk/studio/contracts.py +755 -0
  391. ksadk/studio/errors.py +47 -0
  392. ksadk/studio/event_store.py +214 -0
  393. ksadk/studio/framework_run.py +342 -0
  394. ksadk/studio/hosted_kernel.py +317 -0
  395. ksadk/studio/identifiers.py +33 -0
  396. ksadk/studio/manifest_resolver.py +131 -0
  397. ksadk/studio/mcp_runtime.py +229 -0
  398. ksadk/studio/model_client.py +629 -0
  399. ksadk/studio/model_profile_service.py +214 -0
  400. ksadk/studio/operations.py +275 -0
  401. ksadk/studio/otel_trace.py +1060 -0
  402. ksadk/studio/pagination.py +182 -0
  403. ksadk/studio/pcm_memory.py +85 -0
  404. ksadk/studio/python_tool_inspection.py +183 -0
  405. ksadk/studio/repository.py +327 -0
  406. ksadk/studio/resource_catalog.py +1260 -0
  407. ksadk/studio/run_service.py +1133 -0
  408. ksadk/studio/runtime_catalog.py +74 -0
  409. ksadk/studio/runtime_source.py +365 -0
  410. ksadk/studio/service.py +2249 -0
  411. ksadk/studio/shared_web.py +1004 -0
  412. ksadk/studio/skill_discovery.py +628 -0
  413. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
  414. ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
  415. ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
  416. ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
  417. ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
  418. ksadk/studio/static/index.html +15 -0
  419. ksadk/studio/templates.py +722 -0
  420. ksadk/studio/validator.py +265 -0
  421. ksadk/studio/workspace.py +135 -0
  422. ksadk/tools/gateway.py +9 -0
  423. ksadk/toolsets/__init__.py +27 -1
  424. ksadk/toolsets/a2a.py +426 -0
  425. ksadk/tracing/__init__.py +19 -21
  426. ksadk/tracing/setup.py +317 -403
  427. ksadk/tracing/span_utils.py +0 -44
  428. ksadk/version.py +1 -1
  429. ksadk_runtime_common/memory_backend/registry.py +56 -56
  430. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  431. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  432. ksadk_runtime_common/workspace_files/router.py +8 -2
  433. agentengine_sdk_python-0.8.0.dist-info/RECORD +0 -578
  434. ksadk/a2a/card_builder.py +0 -64
  435. ksadk/a2a/client.py +0 -309
  436. ksadk/events/parser.py +0 -191
  437. ksadk/harness/runner.py +0 -211
  438. ksadk/runners/codex_runner.py +0 -132
  439. ksadk/runners/utils/langfuse.py +0 -230
  440. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  441. ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +0 -303
  442. ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +0 -1
  443. ksadk/server/static/assets/arc-CFKwSk_B.js +0 -1
  444. ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +0 -1
  445. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-Dej8jX8c.js +0 -36
  446. ksadk/server/static/assets/blockDiagram-GPEHLZMM-1F64jqvy.js +0 -132
  447. ksadk/server/static/assets/c4Diagram-AAUBKEIU-9q7AUAKb.js +0 -10
  448. ksadk/server/static/assets/channel-iUGv2N24.js +0 -1
  449. ksadk/server/static/assets/chunk-2J33WTMH-6qgwJm7Q.js +0 -1
  450. ksadk/server/static/assets/chunk-55IACEB6-BK8paA20.js +0 -1
  451. ksadk/server/static/assets/chunk-727SXJPM-B-JEhy7h.js +0 -206
  452. ksadk/server/static/assets/chunk-AQP2D5EJ-DYBvMHAa.js +0 -231
  453. ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +0 -1
  454. ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +0 -1
  455. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +0 -1
  456. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  457. ksadk/server/static/assets/dagre-BM42HDAG-C7TguAWo.js +0 -4
  458. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  459. ksadk/server/static/assets/diagram-2AECGRRQ-Dd17_kws.js +0 -43
  460. ksadk/server/static/assets/diagram-5GNKFQAL-DVIClIil.js +0 -10
  461. ksadk/server/static/assets/diagram-KO2AKTUF-Df_3gYQa.js +0 -3
  462. ksadk/server/static/assets/diagram-LMA3HP47-BhLk6ZtA.js +0 -24
  463. ksadk/server/static/assets/diagram-OG6HWLK6-D4GNGvuu.js +0 -24
  464. ksadk/server/static/assets/dist-DyvYLMW9.js +0 -1
  465. ksadk/server/static/assets/erDiagram-TEJ5UH35-CnfRcY2M.js +0 -85
  466. ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +0 -1
  467. ksadk/server/static/assets/flowDiagram-I6XJVG4X-DGaJjGNJ.js +0 -162
  468. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-DpCoB2g9.js +0 -292
  469. ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +0 -1
  470. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-9IKVFBVT.js +0 -106
  471. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  472. ksadk/server/static/assets/index-QSwCHuB8.js +0 -177
  473. ksadk/server/static/assets/index-jOPmTOZH.css +0 -2
  474. ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +0 -1
  475. ksadk/server/static/assets/infoDiagram-5YYISTIA-CYIIsb8y.js +0 -2
  476. ksadk/server/static/assets/katex-DATssjp1.js +0 -265
  477. ksadk/server/static/assets/mermaid-parser.core-mGAcEwcq.js +0 -161
  478. ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +0 -1
  479. ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +0 -1
  480. ksadk/server/static/assets/pieDiagram-4H26LBE5-By-ra07M.js +0 -30
  481. ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +0 -1
  482. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DpW90iu3.js +0 -84
  483. ksadk/server/static/assets/stateDiagram-AJRCARHV-DGpd9yFG.js +0 -1
  484. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +0 -1
  485. ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +0 -1
  486. ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +0 -1
  487. ksadk/server/static/assets/vennDiagram-CIIHVFJN-l3Z7-wbP.js +0 -34
  488. ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +0 -1
  489. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-BR54GPmr.js +0 -78
  490. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-SkiH8GsK.js +0 -7
  491. ksadk/tracing/exporters/langfuse_exporter.py +0 -460
  492. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
  493. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
  494. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
ksadk/toolsets/a2a.py ADDED
@@ -0,0 +1,426 @@
1
+ """A2A toolset: 把 A2A Space 下的远程 agent 暴露为固定几个元 tool(对齐 skill 模式)。
2
+
3
+ 不随 agent 数量增长:固定 3 个 tool —— list_a2a_agents / get_a2a_agent_card /
4
+ call_a2a_agent。LLM 操作哪个远程 agent 通过参数动态指定。
5
+
6
+ 容错(参考 ksadk/toolsets/skills.py 并加强误传容错):
7
+ - agent 参数同时接受 A2AAgentId 或 AgentCard.name,内部归一化(strip/lower、
8
+ 容忍 a2a-agent- 前缀有无);
9
+ - 找不到时返回 available_agents + difflib 模糊建议;
10
+ - 统一 {ok, error_type, error_message} 信封,永不抛异常;
11
+ - 未绑 A2A Space 时挂载 0 个 tool(空值守卫)。
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import difflib
17
+ import ipaddress
18
+ import os
19
+ import socket
20
+ import uuid
21
+ from typing import Any
22
+ from urllib.parse import urlsplit
23
+
24
+ import httpcore
25
+ import httpx
26
+
27
+ from ksadk.tools.gateway import ToolPolicy
28
+ from ksadk.toolsets._langchain import as_tool
29
+
30
+ ENV_A2A_SPACE_ID = "KSADK_A2A_SPACE_ID"
31
+ ENV_A2A_SPACE_IDS = "KSADK_A2A_SPACE_IDS"
32
+
33
+
34
+ def _a2a_space_id() -> str:
35
+ explicit = (os.getenv(ENV_A2A_SPACE_ID) or "").strip()
36
+ if explicit:
37
+ return explicit
38
+ raw = (os.getenv(ENV_A2A_SPACE_IDS) or "").strip()
39
+ if not raw:
40
+ return ""
41
+ try:
42
+ import json
43
+
44
+ ids = json.loads(raw)
45
+ if isinstance(ids, list) and ids and isinstance(ids[0], str):
46
+ return ids[0].strip()
47
+ except (ValueError, IndexError):
48
+ pass
49
+ return ""
50
+
51
+
52
+ def _normalize_agent_ref(value: str) -> str:
53
+ return (value or "").strip().lower().removeprefix("a2a-agent-")
54
+
55
+
56
+ def _discover_agents() -> list[dict[str, Any]]:
57
+ """同步发现 space 下的可用 A2A agent(经 KOP ListAToASpaceAgents)。
58
+
59
+ 用同步 KOPClient,不用 async A2ASpaceClient——这样 tool 可在 langgraph 的
60
+ async node 里安全调用(避免 sync 工具内部 asyncio.run 与运行中 event loop 冲突,
61
+ 也保证 OTel traceparent contextvar 沿 event loop 传递不断链)。
62
+ """
63
+ from ksadk.common.kop_client import KOPClient
64
+
65
+ space_id = _a2a_space_id()
66
+ if not space_id:
67
+ return []
68
+ try:
69
+ kop = KOPClient()
70
+ data = kop.post_action(
71
+ "ListAToASpaceAgents",
72
+ {"A2ASpaceId": space_id, "Status": "available", "PageSize": 100},
73
+ )
74
+ except Exception:
75
+ return []
76
+ result = []
77
+ for item in data.get("Agents") or []:
78
+ if not isinstance(item, dict):
79
+ continue
80
+ if str(item.get("InvocationStatus") or "") not in {"", "available"}:
81
+ continue
82
+ card = item.get("AgentCard") if isinstance(item.get("AgentCard"), dict) else {}
83
+ ifaces = card.get("supportedInterfaces") or []
84
+ card_url = str(ifaces[0].get("url")) if ifaces and isinstance(ifaces[0], dict) else ""
85
+ result.append(
86
+ {
87
+ "agent_id": str(item.get("A2AAgentId") or ""),
88
+ "name": str(card.get("name") or item.get("Name") or ""),
89
+ "description": str(card.get("description") or item.get("Description") or ""),
90
+ "version_id": str(item.get("VersionId") or item.get("LatestVersionId") or ""),
91
+ "card_sha256": str(item.get("CardSha256") or ""),
92
+ "source": str(item.get("Source") or "hosted"),
93
+ "url": card_url,
94
+ }
95
+ )
96
+ return result
97
+
98
+
99
+ def _match_agent(agents: list[dict[str, Any]], ref: str) -> tuple[dict[str, Any] | None, list[str]]:
100
+ target = _normalize_agent_ref(ref)
101
+ if not target:
102
+ return None, [a["agent_id"] for a in agents]
103
+ for a in agents:
104
+ if _normalize_agent_ref(a["agent_id"]) == target or _normalize_agent_ref(
105
+ a["name"]
106
+ ) == target:
107
+ return a, []
108
+ available = [a["agent_id"] for a in agents]
109
+ names = [_normalize_agent_ref(a["agent_id"]) for a in agents] + [
110
+ _normalize_agent_ref(a["name"]) for a in agents if a["name"]
111
+ ]
112
+ suggestions = difflib.get_close_matches(target, names, n=1, cutoff=0.6)
113
+ return None, available + (suggestions or [])
114
+
115
+
116
+ def _task_state_name(remote_task: Any) -> str:
117
+ status = getattr(remote_task, "status", None)
118
+ state = getattr(status, "state", None)
119
+ return str(state) if state is not None else ""
120
+
121
+
122
+ def _extract_reply_text(remote_task: Any) -> str:
123
+ """从 task 的 status.message.parts 与 artifacts 提取回复文本。
124
+
125
+ 兼容 proto Task 对象(属性访问)与 JSON dict(键访问)。
126
+ """
127
+ if isinstance(remote_task, dict):
128
+ status = remote_task.get("status") or {}
129
+ message = status.get("message") or {}
130
+ parts: list[str] = []
131
+ # 优先 status.message.parts(终态回复);无则退到 artifacts 分片。
132
+ for part in (message.get("parts") or []):
133
+ if isinstance(part, dict) and part.get("text"):
134
+ parts.append(part["text"])
135
+ if parts:
136
+ return "".join(parts)
137
+ for artifact in (remote_task.get("artifacts") or []):
138
+ for part in (artifact.get("parts") or []):
139
+ if isinstance(part, dict) and part.get("text"):
140
+ parts.append(part["text"])
141
+ return "".join(parts)
142
+ parts_text: list[str] = []
143
+ status = getattr(remote_task, "status", None)
144
+ message = getattr(status, "message", None)
145
+ if message is not None:
146
+ for part in (getattr(message, "parts", None) or []):
147
+ text = getattr(part, "text", None)
148
+ if isinstance(text, str) and text:
149
+ parts_text.append(text)
150
+ for artifact in (getattr(remote_task, "artifacts", None) or []):
151
+ for part in (getattr(artifact, "parts", None) or []):
152
+ text = getattr(part, "text", None)
153
+ if isinstance(text, str) and text:
154
+ parts_text.append(text)
155
+ return "".join(parts_text)
156
+
157
+
158
+ class _PinnedDNSNetworkBackend(httpcore.NetworkBackend):
159
+ """Dial the address selected by the URL validator while preserving TLS SNI."""
160
+
161
+ def __init__(
162
+ self,
163
+ delegate: httpcore.NetworkBackend,
164
+ *,
165
+ expected_hostname: str,
166
+ expected_port: int,
167
+ pinned_ip: str,
168
+ ) -> None:
169
+ self._delegate = delegate
170
+ self._expected_hostname = expected_hostname
171
+ self._expected_port = expected_port
172
+ self._pinned_ip = pinned_ip
173
+
174
+ def connect_tcp(
175
+ self,
176
+ host: str,
177
+ port: int,
178
+ timeout: float | None = None,
179
+ local_address: str | None = None,
180
+ socket_options: Any = None,
181
+ ) -> httpcore.NetworkStream:
182
+ if host.lower() != self._expected_hostname or port != self._expected_port:
183
+ raise RuntimeError("A2A tool transport attempted to dial an unapproved origin")
184
+ return self._delegate.connect_tcp(
185
+ self._pinned_ip,
186
+ port,
187
+ timeout=timeout,
188
+ local_address=local_address,
189
+ socket_options=socket_options,
190
+ )
191
+
192
+ def connect_unix_socket(
193
+ self,
194
+ path: str,
195
+ timeout: float | None = None,
196
+ socket_options: Any = None,
197
+ ) -> httpcore.NetworkStream:
198
+ return self._delegate.connect_unix_socket(
199
+ path,
200
+ timeout=timeout,
201
+ socket_options=socket_options,
202
+ )
203
+
204
+ def sleep(self, seconds: float) -> None:
205
+ self._delegate.sleep(seconds)
206
+
207
+
208
+ def _validated_card_origin(url: str) -> tuple[str, int, str] | dict[str, Any]:
209
+ """Validate a card URL and pin one address from its all-public DNS result."""
210
+ parsed = urlsplit(url)
211
+ try:
212
+ port = parsed.port
213
+ except ValueError:
214
+ port = None
215
+ if (
216
+ parsed.scheme not in {"http", "https"}
217
+ or not parsed.hostname
218
+ or parsed.username is not None
219
+ or parsed.password is not None
220
+ or parsed.netloc.rsplit("@", 1)[-1].endswith(":")
221
+ or port is not None and not 1 <= port <= 65535
222
+ ):
223
+ return {
224
+ "ok": False,
225
+ "error_type": "invalid_card_url",
226
+ "error_message": "card url must be an HTTP(S) URL without userinfo",
227
+ }
228
+ try:
229
+ hostname = parsed.hostname.encode("idna").decode("ascii").lower()
230
+ effective_port = port or (443 if parsed.scheme == "https" else 80)
231
+ addresses = socket.getaddrinfo(
232
+ hostname,
233
+ effective_port,
234
+ type=socket.SOCK_STREAM,
235
+ )
236
+ except (UnicodeError, socket.gaierror) as exc:
237
+ return {
238
+ "ok": False,
239
+ "error_type": "dns_resolution_failed",
240
+ "error_message": str(exc),
241
+ }
242
+ public_addresses: list[str] = []
243
+ for address in addresses:
244
+ ip = ipaddress.ip_address(address[4][0])
245
+ if not ip.is_global:
246
+ return {
247
+ "ok": False,
248
+ "error_type": "blocked_by_ssrf_policy",
249
+ "error_message": f"blocked non-public card address: {ip}",
250
+ }
251
+ public_addresses.append(str(ip))
252
+ if not public_addresses:
253
+ return {
254
+ "ok": False,
255
+ "error_type": "dns_resolution_failed",
256
+ "error_message": "card hostname resolved to no addresses",
257
+ }
258
+ return hostname, effective_port, public_addresses[0]
259
+
260
+
261
+ def _validate_card_url(url: str) -> dict[str, Any] | None:
262
+ validated = _validated_card_origin(url)
263
+ return validated if isinstance(validated, dict) else None
264
+
265
+
266
+ def _pinned_http_client(*, hostname: str, port: int, pinned_ip: str) -> httpx.Client:
267
+ transport = httpx.HTTPTransport(
268
+ trust_env=False,
269
+ http1=True,
270
+ http2=False,
271
+ limits=httpx.Limits(max_connections=1, max_keepalive_connections=0),
272
+ )
273
+ pool = getattr(transport, "_pool", None)
274
+ if not isinstance(pool, httpcore.ConnectionPool):
275
+ transport.close()
276
+ raise RuntimeError("httpx direct sync transport is unavailable for A2A DNS pinning")
277
+ pool._network_backend = _PinnedDNSNetworkBackend( # type: ignore[attr-defined]
278
+ pool._network_backend,
279
+ expected_hostname=hostname,
280
+ expected_port=port,
281
+ pinned_ip=pinned_ip,
282
+ )
283
+ return httpx.Client(
284
+ transport=transport,
285
+ follow_redirects=False,
286
+ trust_env=False,
287
+ timeout=120,
288
+ )
289
+
290
+
291
+ def list_a2a_agents() -> dict[str, Any]:
292
+ """List remote A2A agents in the configured A2A Space.
293
+
294
+ Returns each agent's id, name, description and version. No remote calls
295
+ are made to the agents themselves — only discovery metadata.
296
+ """
297
+ space_id = _a2a_space_id()
298
+ if not space_id:
299
+ return {"ok": False, "error_message": "A2A Space not configured"}
300
+ try:
301
+ agents = _discover_agents()
302
+ except Exception as exc:
303
+ return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
304
+ return {"ok": True, "space_id": space_id, "agents": agents}
305
+
306
+
307
+ def get_a2a_agent_card(agent: str) -> dict[str, Any]:
308
+ """Get the AgentCard of a remote A2A agent by id or name.
309
+
310
+ ``agent`` accepts the A2AAgentId (a2a-agent-*) or the card name. When not
311
+ found, returns available_agents and a suggestion.
312
+ """
313
+ space_id = _a2a_space_id()
314
+ if not space_id:
315
+ return {"ok": False, "error_message": "A2A Space not configured"}
316
+ try:
317
+ agents = _discover_agents()
318
+ except Exception as exc:
319
+ return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
320
+ matched, hint = _match_agent(agents, agent)
321
+ if matched is None:
322
+ return {
323
+ "ok": False,
324
+ "error_message": f"Agent not found: {agent}",
325
+ "available_agents": hint,
326
+ }
327
+ return {"ok": True, "agent": matched}
328
+
329
+
330
+ def call_a2a_agent(agent: str, message: str) -> dict[str, Any]:
331
+ """Call a remote A2A agent by id or name with a text message.
332
+
333
+ ``agent`` accepts A2AAgentId (a2a-agent-*) or card name. Synchronously waits
334
+ for the remote task to complete and returns the agent's text reply. If the
335
+ task does not reach a terminal state within the poll budget, returns the
336
+ last known state and task_id for follow-up.
337
+ """
338
+ space_id = _a2a_space_id()
339
+ if not space_id:
340
+ return {"ok": False, "error_message": "A2A Space not configured"}
341
+ if not (message or "").strip():
342
+ return {"ok": False, "error_message": "message is required"}
343
+ try:
344
+ agents = _discover_agents()
345
+ except Exception as exc:
346
+ return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
347
+ matched, hint = _match_agent(agents, agent)
348
+ if matched is None:
349
+ return {
350
+ "ok": False,
351
+ "error_message": f"Agent not found: {agent}",
352
+ "available_agents": hint,
353
+ }
354
+ try:
355
+ card_url = str(matched.get("url") or "").strip()
356
+ if not card_url:
357
+ return {"ok": False, "error_message": f"agent {matched['agent_id']} card 无可用 url"}
358
+
359
+ def _send() -> dict[str, Any]:
360
+ # 直接对 card.url 发非流式 SendMessage(returnImmediately=false),同步拿终态回复。
361
+ # 不走 space_client 的流式 send_message/subscribe(其 task 状态跟踪在异步下不可靠)。
362
+ payload = {
363
+ "jsonrpc": "2.0",
364
+ "method": "SendMessage",
365
+ "id": "1",
366
+ "params": {
367
+ "message": {
368
+ "messageId": f"m-{uuid.uuid4().hex[:12]}",
369
+ "role": "ROLE_USER",
370
+ "parts": [{"text": message}],
371
+ },
372
+ "configuration": {"returnImmediately": False},
373
+ },
374
+ }
375
+ # 透传 OTel trace context:把当前 span 注入 traceparent header,
376
+ # 让被调 agent 的 span 挂到同一条分布式 trace 上。
377
+ headers = {"Content-Type": "application/json", "A2A-Version": "1.0"}
378
+ try:
379
+ from opentelemetry import propagate
380
+
381
+ propagate.inject(headers)
382
+ except Exception:
383
+ pass
384
+ validated = _validated_card_origin(card_url)
385
+ if isinstance(validated, dict):
386
+ return validated
387
+ hostname, port, pinned_ip = validated
388
+ with _pinned_http_client(
389
+ hostname=hostname,
390
+ port=port,
391
+ pinned_ip=pinned_ip,
392
+ ) as client:
393
+ resp = client.post(card_url, json=payload, headers=headers)
394
+ if resp.status_code != 200:
395
+ return {
396
+ "ok": False,
397
+ "error_type": "A2AClientError",
398
+ "error_message": f"HTTP {resp.status_code}: {resp.text[:200]}",
399
+ }
400
+ data = resp.json()
401
+ if "error" in data and data["error"]:
402
+ err = str(data["error"])[:300]
403
+ return {"ok": False, "error_type": "A2AError", "error_message": err}
404
+ task = (data.get("result") or {}).get("task") or {}
405
+ return {
406
+ "ok": True,
407
+ "agent": matched["agent_id"],
408
+ "task_id": task.get("id", ""),
409
+ "state": str((task.get("status") or {}).get("state", "")),
410
+ "reply": _extract_reply_text(task),
411
+ }
412
+
413
+ return _send()
414
+ except Exception as exc:
415
+ return {"ok": False, "error_type": type(exc).__name__, "error_message": str(exc)}
416
+
417
+
418
+ def get_a2a_tools() -> list:
419
+ return [as_tool(list_a2a_agents), as_tool(get_a2a_agent_card), as_tool(call_a2a_agent)]
420
+
421
+
422
+ _A2A_TOOL_POLICIES = {
423
+ "list_a2a_agents": ToolPolicy(risk_level="low"),
424
+ "get_a2a_agent_card": ToolPolicy(risk_level="low"),
425
+ "call_a2a_agent": ToolPolicy(risk_level="high", side_effects=("a2a_remote_call",)),
426
+ }
ksadk/tracing/__init__.py CHANGED
@@ -4,34 +4,32 @@ KsADK Tracing - 可观测性模块 (OpenTelemetry)
4
4
  使用方式:
5
5
  from ksadk.tracing import setup_tracing
6
6
 
7
- # 优先使用标准 OTel/OTLP 环境变量,后端可以是 Langfuse 或其他 Collector
7
+ # 使用标准 OTel/OTLP 环境变量,直接连接任意 OTLP 兼容后端
8
8
  # OTEL_EXPORTER_OTLP_ENDPOINT=https://collector.example.com/otel
9
9
  # OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf
10
10
  setup_tracing()
11
11
 
12
- # 兼容旧 Langfuse 环境变量,也可以显式启用
13
- setup_tracing(enable_langfuse=True)
14
-
15
12
  环境变量:
16
- OTEL_EXPORTER_OTLP_ENDPOINT - 通用 OTLP endpoint
17
- OTEL_EXPORTER_OTLP_TRACES_ENDPOINT - traces 专用 OTLP endpoint
18
- OTEL_EXPORTER_OTLP_TRACES_PROTOCOL - traces 专用 OTLP 协议
19
- OTEL_EXPORTER_OTLP_TRACES_HEADERS - traces 专用 OTLP headers
20
- CLOUD_MONITOR_APP_KEY - 云监控 OTLP AppKey,注入 Ksc-Appkey header
21
- CLOUD_MONITOR_OTLP_ENABLED - 云监控 OTLP 导出开关 (0.6.7 新增)
22
- CLOUD_MONITOR_OTLP_ENDPOINT - 云监控 OTLP endpoint
23
- CLOUD_MONITOR_OTLP_PROTOCOL - 云监控 OTLP 协议
24
- CLOUD_MONITOR_OTLP_HEADERS - 云监控 OTLP headers (0.6.7 新增)
25
- CLOUD_MONITOR_OTLP_TRACES_ENDPOINT - 云监控 traces 专用 endpoint
26
- CLOUD_MONITOR_OTLP_TRACES_PROTOCOL - 云监控 traces 专用协议
27
- LANGFUSE_PUBLIC_KEY - 存在即自动启用 Langfuse (无独立 LANGFUSE_ENABLED 开关)
28
- LANGFUSE_SECRET_KEY - Langfuse Secret
29
- LANGFUSE_BASE_URL - Langfuse 服务地址 (优先)
30
- LANGFUSE_HOST - Langfuse 服务地址 (LANGFUSE_BASE_URL 别名)
13
+ OTEL_EXPORTER_OTLP_ENDPOINT - 通用 OTLP endpoint (托管 Agent 的 Langfuse 主路)
14
+ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT - traces 专用 OTLP endpoint
15
+ OTEL_EXPORTER_OTLP_TRACES_PROTOCOL - traces 专用 OTLP 协议
16
+ OTEL_EXPORTER_OTLP_TRACES_HEADERS - traces 专用 OTLP headers
17
+ CLOUD_MONITOR_OTLP_ENDPOINT - 云监控 OTLP endpoint (次路)
18
+ CLOUD_MONITOR_OTLP_TRACES_ENDPOINT - 云监控 traces 专用 endpoint
19
+ CLOUD_MONITOR_OTLP_HEADERS - 云监控 OTLP headers (含 Ksc-Appkey)
20
+ CLOUD_MONITOR_OTLP_TRACES_HEADERS - 云监控 traces 专用 headers,优先于通用 headers
21
+ CLOUD_MONITOR_OTLP_PROTOCOL - 云监控 OTLP 协议
22
+ CLOUD_MONITOR_OTLP_TRACES_PROTOCOL - 云监控 traces 专用协议
23
+ CLOUD_MONITOR_APP_KEY - 已废弃:仅当两个 headers 变量整体缺失时回退
31
24
 
32
25
  Agent / session / user 等业务维度建议作为 span attributes 写入。
33
26
  """
34
27
 
35
- from ksadk.tracing.setup import get_memory_exporter, get_tracer, setup_tracing
28
+ from ksadk.tracing.setup import (
29
+ get_memory_exporter,
30
+ get_tracer,
31
+ setup_tracing,
32
+ shutdown_tracing,
33
+ )
36
34
 
37
- __all__ = ["setup_tracing", "get_memory_exporter", "get_tracer"]
35
+ __all__ = ["setup_tracing", "shutdown_tracing", "get_memory_exporter", "get_tracer"]