agentpool 2.1.9__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.

Potentially problematic release.


This version of agentpool might be problematic. Click here for more details.

Files changed (474) hide show
  1. acp/README.md +64 -0
  2. acp/__init__.py +172 -0
  3. acp/__main__.py +10 -0
  4. acp/acp_requests.py +285 -0
  5. acp/agent/__init__.py +6 -0
  6. acp/agent/connection.py +256 -0
  7. acp/agent/implementations/__init__.py +6 -0
  8. acp/agent/implementations/debug_server/__init__.py +1 -0
  9. acp/agent/implementations/debug_server/cli.py +79 -0
  10. acp/agent/implementations/debug_server/debug.html +234 -0
  11. acp/agent/implementations/debug_server/debug_server.py +496 -0
  12. acp/agent/implementations/testing.py +91 -0
  13. acp/agent/protocol.py +65 -0
  14. acp/bridge/README.md +162 -0
  15. acp/bridge/__init__.py +6 -0
  16. acp/bridge/__main__.py +91 -0
  17. acp/bridge/bridge.py +246 -0
  18. acp/bridge/py.typed +0 -0
  19. acp/bridge/settings.py +15 -0
  20. acp/client/__init__.py +7 -0
  21. acp/client/connection.py +251 -0
  22. acp/client/implementations/__init__.py +7 -0
  23. acp/client/implementations/default_client.py +185 -0
  24. acp/client/implementations/headless_client.py +266 -0
  25. acp/client/implementations/noop_client.py +110 -0
  26. acp/client/protocol.py +61 -0
  27. acp/connection.py +280 -0
  28. acp/exceptions.py +46 -0
  29. acp/filesystem.py +524 -0
  30. acp/notifications.py +832 -0
  31. acp/py.typed +0 -0
  32. acp/schema/__init__.py +265 -0
  33. acp/schema/agent_plan.py +30 -0
  34. acp/schema/agent_requests.py +126 -0
  35. acp/schema/agent_responses.py +256 -0
  36. acp/schema/base.py +39 -0
  37. acp/schema/capabilities.py +230 -0
  38. acp/schema/client_requests.py +247 -0
  39. acp/schema/client_responses.py +96 -0
  40. acp/schema/common.py +81 -0
  41. acp/schema/content_blocks.py +188 -0
  42. acp/schema/mcp.py +82 -0
  43. acp/schema/messages.py +171 -0
  44. acp/schema/notifications.py +82 -0
  45. acp/schema/protocol_stuff.md +3 -0
  46. acp/schema/session_state.py +160 -0
  47. acp/schema/session_updates.py +419 -0
  48. acp/schema/slash_commands.py +51 -0
  49. acp/schema/terminal.py +15 -0
  50. acp/schema/tool_call.py +347 -0
  51. acp/stdio.py +250 -0
  52. acp/task/__init__.py +53 -0
  53. acp/task/debug.py +197 -0
  54. acp/task/dispatcher.py +93 -0
  55. acp/task/queue.py +69 -0
  56. acp/task/sender.py +82 -0
  57. acp/task/state.py +87 -0
  58. acp/task/supervisor.py +93 -0
  59. acp/terminal_handle.py +30 -0
  60. acp/tool_call_reporter.py +199 -0
  61. acp/tool_call_state.py +178 -0
  62. acp/transports.py +104 -0
  63. acp/utils.py +240 -0
  64. agentpool/__init__.py +63 -0
  65. agentpool/__main__.py +7 -0
  66. agentpool/agents/__init__.py +30 -0
  67. agentpool/agents/acp_agent/__init__.py +5 -0
  68. agentpool/agents/acp_agent/acp_agent.py +837 -0
  69. agentpool/agents/acp_agent/acp_converters.py +294 -0
  70. agentpool/agents/acp_agent/client_handler.py +317 -0
  71. agentpool/agents/acp_agent/session_state.py +44 -0
  72. agentpool/agents/agent.py +1264 -0
  73. agentpool/agents/agui_agent/__init__.py +19 -0
  74. agentpool/agents/agui_agent/agui_agent.py +677 -0
  75. agentpool/agents/agui_agent/agui_converters.py +423 -0
  76. agentpool/agents/agui_agent/chunk_transformer.py +204 -0
  77. agentpool/agents/agui_agent/event_types.py +83 -0
  78. agentpool/agents/agui_agent/helpers.py +192 -0
  79. agentpool/agents/architect.py +71 -0
  80. agentpool/agents/base_agent.py +177 -0
  81. agentpool/agents/claude_code_agent/__init__.py +11 -0
  82. agentpool/agents/claude_code_agent/claude_code_agent.py +1021 -0
  83. agentpool/agents/claude_code_agent/converters.py +243 -0
  84. agentpool/agents/context.py +105 -0
  85. agentpool/agents/events/__init__.py +61 -0
  86. agentpool/agents/events/builtin_handlers.py +129 -0
  87. agentpool/agents/events/event_emitter.py +320 -0
  88. agentpool/agents/events/events.py +561 -0
  89. agentpool/agents/events/tts_handlers.py +186 -0
  90. agentpool/agents/interactions.py +419 -0
  91. agentpool/agents/slashed_agent.py +244 -0
  92. agentpool/agents/sys_prompts.py +178 -0
  93. agentpool/agents/tool_wrapping.py +184 -0
  94. agentpool/base_provider.py +28 -0
  95. agentpool/common_types.py +226 -0
  96. agentpool/config_resources/__init__.py +16 -0
  97. agentpool/config_resources/acp_assistant.yml +24 -0
  98. agentpool/config_resources/agents.yml +109 -0
  99. agentpool/config_resources/agents_template.yml +18 -0
  100. agentpool/config_resources/agui_test.yml +18 -0
  101. agentpool/config_resources/claude_code_agent.yml +16 -0
  102. agentpool/config_resources/claude_style_subagent.md +30 -0
  103. agentpool/config_resources/external_acp_agents.yml +77 -0
  104. agentpool/config_resources/opencode_style_subagent.md +19 -0
  105. agentpool/config_resources/tts_test_agents.yml +78 -0
  106. agentpool/delegation/__init__.py +8 -0
  107. agentpool/delegation/base_team.py +504 -0
  108. agentpool/delegation/message_flow_tracker.py +39 -0
  109. agentpool/delegation/pool.py +1129 -0
  110. agentpool/delegation/team.py +325 -0
  111. agentpool/delegation/teamrun.py +343 -0
  112. agentpool/docs/__init__.py +5 -0
  113. agentpool/docs/gen_examples.py +42 -0
  114. agentpool/docs/utils.py +370 -0
  115. agentpool/functional/__init__.py +20 -0
  116. agentpool/functional/py.typed +0 -0
  117. agentpool/functional/run.py +80 -0
  118. agentpool/functional/structure.py +136 -0
  119. agentpool/hooks/__init__.py +20 -0
  120. agentpool/hooks/agent_hooks.py +247 -0
  121. agentpool/hooks/base.py +119 -0
  122. agentpool/hooks/callable.py +140 -0
  123. agentpool/hooks/command.py +180 -0
  124. agentpool/hooks/prompt.py +122 -0
  125. agentpool/jinja_filters.py +132 -0
  126. agentpool/log.py +224 -0
  127. agentpool/mcp_server/__init__.py +17 -0
  128. agentpool/mcp_server/client.py +429 -0
  129. agentpool/mcp_server/constants.py +32 -0
  130. agentpool/mcp_server/conversions.py +172 -0
  131. agentpool/mcp_server/helpers.py +47 -0
  132. agentpool/mcp_server/manager.py +232 -0
  133. agentpool/mcp_server/message_handler.py +164 -0
  134. agentpool/mcp_server/registries/__init__.py +1 -0
  135. agentpool/mcp_server/registries/official_registry_client.py +345 -0
  136. agentpool/mcp_server/registries/pulsemcp_client.py +88 -0
  137. agentpool/mcp_server/tool_bridge.py +548 -0
  138. agentpool/messaging/__init__.py +58 -0
  139. agentpool/messaging/compaction.py +928 -0
  140. agentpool/messaging/connection_manager.py +319 -0
  141. agentpool/messaging/context.py +66 -0
  142. agentpool/messaging/event_manager.py +426 -0
  143. agentpool/messaging/events.py +39 -0
  144. agentpool/messaging/message_container.py +209 -0
  145. agentpool/messaging/message_history.py +491 -0
  146. agentpool/messaging/messagenode.py +377 -0
  147. agentpool/messaging/messages.py +655 -0
  148. agentpool/messaging/processing.py +76 -0
  149. agentpool/mime_utils.py +95 -0
  150. agentpool/models/__init__.py +21 -0
  151. agentpool/models/acp_agents/__init__.py +22 -0
  152. agentpool/models/acp_agents/base.py +308 -0
  153. agentpool/models/acp_agents/mcp_capable.py +790 -0
  154. agentpool/models/acp_agents/non_mcp.py +842 -0
  155. agentpool/models/agents.py +450 -0
  156. agentpool/models/agui_agents.py +89 -0
  157. agentpool/models/claude_code_agents.py +238 -0
  158. agentpool/models/file_agents.py +116 -0
  159. agentpool/models/file_parsing.py +367 -0
  160. agentpool/models/manifest.py +658 -0
  161. agentpool/observability/__init__.py +9 -0
  162. agentpool/observability/observability_registry.py +97 -0
  163. agentpool/prompts/__init__.py +1 -0
  164. agentpool/prompts/base.py +27 -0
  165. agentpool/prompts/builtin_provider.py +75 -0
  166. agentpool/prompts/conversion_manager.py +95 -0
  167. agentpool/prompts/convert.py +96 -0
  168. agentpool/prompts/manager.py +204 -0
  169. agentpool/prompts/parts/zed.md +33 -0
  170. agentpool/prompts/prompts.py +581 -0
  171. agentpool/py.typed +0 -0
  172. agentpool/queries/tree-sitter-language-pack/README.md +7 -0
  173. agentpool/queries/tree-sitter-language-pack/arduino-tags.scm +5 -0
  174. agentpool/queries/tree-sitter-language-pack/c-tags.scm +9 -0
  175. agentpool/queries/tree-sitter-language-pack/chatito-tags.scm +16 -0
  176. agentpool/queries/tree-sitter-language-pack/clojure-tags.scm +7 -0
  177. agentpool/queries/tree-sitter-language-pack/commonlisp-tags.scm +122 -0
  178. agentpool/queries/tree-sitter-language-pack/cpp-tags.scm +15 -0
  179. agentpool/queries/tree-sitter-language-pack/csharp-tags.scm +26 -0
  180. agentpool/queries/tree-sitter-language-pack/d-tags.scm +26 -0
  181. agentpool/queries/tree-sitter-language-pack/dart-tags.scm +92 -0
  182. agentpool/queries/tree-sitter-language-pack/elisp-tags.scm +5 -0
  183. agentpool/queries/tree-sitter-language-pack/elixir-tags.scm +54 -0
  184. agentpool/queries/tree-sitter-language-pack/elm-tags.scm +19 -0
  185. agentpool/queries/tree-sitter-language-pack/gleam-tags.scm +41 -0
  186. agentpool/queries/tree-sitter-language-pack/go-tags.scm +42 -0
  187. agentpool/queries/tree-sitter-language-pack/java-tags.scm +20 -0
  188. agentpool/queries/tree-sitter-language-pack/javascript-tags.scm +88 -0
  189. agentpool/queries/tree-sitter-language-pack/lua-tags.scm +34 -0
  190. agentpool/queries/tree-sitter-language-pack/matlab-tags.scm +10 -0
  191. agentpool/queries/tree-sitter-language-pack/ocaml-tags.scm +115 -0
  192. agentpool/queries/tree-sitter-language-pack/ocaml_interface-tags.scm +98 -0
  193. agentpool/queries/tree-sitter-language-pack/pony-tags.scm +39 -0
  194. agentpool/queries/tree-sitter-language-pack/properties-tags.scm +5 -0
  195. agentpool/queries/tree-sitter-language-pack/python-tags.scm +14 -0
  196. agentpool/queries/tree-sitter-language-pack/r-tags.scm +21 -0
  197. agentpool/queries/tree-sitter-language-pack/racket-tags.scm +12 -0
  198. agentpool/queries/tree-sitter-language-pack/ruby-tags.scm +64 -0
  199. agentpool/queries/tree-sitter-language-pack/rust-tags.scm +60 -0
  200. agentpool/queries/tree-sitter-language-pack/solidity-tags.scm +43 -0
  201. agentpool/queries/tree-sitter-language-pack/swift-tags.scm +51 -0
  202. agentpool/queries/tree-sitter-language-pack/udev-tags.scm +20 -0
  203. agentpool/queries/tree-sitter-languages/README.md +24 -0
  204. agentpool/queries/tree-sitter-languages/c-tags.scm +9 -0
  205. agentpool/queries/tree-sitter-languages/c_sharp-tags.scm +46 -0
  206. agentpool/queries/tree-sitter-languages/cpp-tags.scm +15 -0
  207. agentpool/queries/tree-sitter-languages/dart-tags.scm +91 -0
  208. agentpool/queries/tree-sitter-languages/elisp-tags.scm +8 -0
  209. agentpool/queries/tree-sitter-languages/elixir-tags.scm +54 -0
  210. agentpool/queries/tree-sitter-languages/elm-tags.scm +19 -0
  211. agentpool/queries/tree-sitter-languages/fortran-tags.scm +15 -0
  212. agentpool/queries/tree-sitter-languages/go-tags.scm +30 -0
  213. agentpool/queries/tree-sitter-languages/haskell-tags.scm +3 -0
  214. agentpool/queries/tree-sitter-languages/hcl-tags.scm +77 -0
  215. agentpool/queries/tree-sitter-languages/java-tags.scm +20 -0
  216. agentpool/queries/tree-sitter-languages/javascript-tags.scm +88 -0
  217. agentpool/queries/tree-sitter-languages/julia-tags.scm +60 -0
  218. agentpool/queries/tree-sitter-languages/kotlin-tags.scm +27 -0
  219. agentpool/queries/tree-sitter-languages/matlab-tags.scm +10 -0
  220. agentpool/queries/tree-sitter-languages/ocaml-tags.scm +115 -0
  221. agentpool/queries/tree-sitter-languages/ocaml_interface-tags.scm +98 -0
  222. agentpool/queries/tree-sitter-languages/php-tags.scm +26 -0
  223. agentpool/queries/tree-sitter-languages/python-tags.scm +12 -0
  224. agentpool/queries/tree-sitter-languages/ql-tags.scm +26 -0
  225. agentpool/queries/tree-sitter-languages/ruby-tags.scm +64 -0
  226. agentpool/queries/tree-sitter-languages/rust-tags.scm +60 -0
  227. agentpool/queries/tree-sitter-languages/scala-tags.scm +65 -0
  228. agentpool/queries/tree-sitter-languages/typescript-tags.scm +41 -0
  229. agentpool/queries/tree-sitter-languages/zig-tags.scm +3 -0
  230. agentpool/repomap.py +1231 -0
  231. agentpool/resource_providers/__init__.py +17 -0
  232. agentpool/resource_providers/aggregating.py +54 -0
  233. agentpool/resource_providers/base.py +172 -0
  234. agentpool/resource_providers/codemode/__init__.py +9 -0
  235. agentpool/resource_providers/codemode/code_executor.py +215 -0
  236. agentpool/resource_providers/codemode/default_prompt.py +19 -0
  237. agentpool/resource_providers/codemode/helpers.py +83 -0
  238. agentpool/resource_providers/codemode/progress_executor.py +212 -0
  239. agentpool/resource_providers/codemode/provider.py +150 -0
  240. agentpool/resource_providers/codemode/remote_mcp_execution.py +143 -0
  241. agentpool/resource_providers/codemode/remote_provider.py +171 -0
  242. agentpool/resource_providers/filtering.py +42 -0
  243. agentpool/resource_providers/mcp_provider.py +246 -0
  244. agentpool/resource_providers/plan_provider.py +196 -0
  245. agentpool/resource_providers/pool.py +69 -0
  246. agentpool/resource_providers/static.py +289 -0
  247. agentpool/running/__init__.py +20 -0
  248. agentpool/running/decorators.py +56 -0
  249. agentpool/running/discovery.py +101 -0
  250. agentpool/running/executor.py +284 -0
  251. agentpool/running/injection.py +111 -0
  252. agentpool/running/py.typed +0 -0
  253. agentpool/running/run_nodes.py +87 -0
  254. agentpool/server.py +122 -0
  255. agentpool/sessions/__init__.py +13 -0
  256. agentpool/sessions/manager.py +302 -0
  257. agentpool/sessions/models.py +71 -0
  258. agentpool/sessions/session.py +239 -0
  259. agentpool/sessions/store.py +163 -0
  260. agentpool/skills/__init__.py +5 -0
  261. agentpool/skills/manager.py +120 -0
  262. agentpool/skills/registry.py +210 -0
  263. agentpool/skills/skill.py +36 -0
  264. agentpool/storage/__init__.py +17 -0
  265. agentpool/storage/manager.py +419 -0
  266. agentpool/storage/serialization.py +136 -0
  267. agentpool/talk/__init__.py +13 -0
  268. agentpool/talk/registry.py +128 -0
  269. agentpool/talk/stats.py +159 -0
  270. agentpool/talk/talk.py +604 -0
  271. agentpool/tasks/__init__.py +20 -0
  272. agentpool/tasks/exceptions.py +25 -0
  273. agentpool/tasks/registry.py +33 -0
  274. agentpool/testing.py +129 -0
  275. agentpool/text_templates/__init__.py +39 -0
  276. agentpool/text_templates/system_prompt.jinja +30 -0
  277. agentpool/text_templates/tool_call_default.jinja +13 -0
  278. agentpool/text_templates/tool_call_markdown.jinja +25 -0
  279. agentpool/text_templates/tool_call_simple.jinja +5 -0
  280. agentpool/tools/__init__.py +16 -0
  281. agentpool/tools/base.py +269 -0
  282. agentpool/tools/exceptions.py +9 -0
  283. agentpool/tools/manager.py +255 -0
  284. agentpool/tools/tool_call_info.py +87 -0
  285. agentpool/ui/__init__.py +2 -0
  286. agentpool/ui/base.py +89 -0
  287. agentpool/ui/mock_provider.py +81 -0
  288. agentpool/ui/stdlib_provider.py +150 -0
  289. agentpool/utils/__init__.py +44 -0
  290. agentpool/utils/baseregistry.py +185 -0
  291. agentpool/utils/count_tokens.py +62 -0
  292. agentpool/utils/dag.py +184 -0
  293. agentpool/utils/importing.py +206 -0
  294. agentpool/utils/inspection.py +334 -0
  295. agentpool/utils/model_capabilities.py +25 -0
  296. agentpool/utils/network.py +28 -0
  297. agentpool/utils/now.py +22 -0
  298. agentpool/utils/parse_time.py +87 -0
  299. agentpool/utils/result_utils.py +35 -0
  300. agentpool/utils/signatures.py +305 -0
  301. agentpool/utils/streams.py +112 -0
  302. agentpool/utils/tasks.py +186 -0
  303. agentpool/vfs_registry.py +250 -0
  304. agentpool-2.1.9.dist-info/METADATA +336 -0
  305. agentpool-2.1.9.dist-info/RECORD +474 -0
  306. agentpool-2.1.9.dist-info/WHEEL +4 -0
  307. agentpool-2.1.9.dist-info/entry_points.txt +14 -0
  308. agentpool-2.1.9.dist-info/licenses/LICENSE +22 -0
  309. agentpool_cli/__init__.py +34 -0
  310. agentpool_cli/__main__.py +66 -0
  311. agentpool_cli/agent.py +175 -0
  312. agentpool_cli/cli_types.py +23 -0
  313. agentpool_cli/common.py +163 -0
  314. agentpool_cli/create.py +175 -0
  315. agentpool_cli/history.py +217 -0
  316. agentpool_cli/log.py +78 -0
  317. agentpool_cli/py.typed +0 -0
  318. agentpool_cli/run.py +84 -0
  319. agentpool_cli/serve_acp.py +177 -0
  320. agentpool_cli/serve_api.py +69 -0
  321. agentpool_cli/serve_mcp.py +74 -0
  322. agentpool_cli/serve_vercel.py +233 -0
  323. agentpool_cli/store.py +171 -0
  324. agentpool_cli/task.py +84 -0
  325. agentpool_cli/utils.py +104 -0
  326. agentpool_cli/watch.py +54 -0
  327. agentpool_commands/__init__.py +180 -0
  328. agentpool_commands/agents.py +199 -0
  329. agentpool_commands/base.py +45 -0
  330. agentpool_commands/commands.py +58 -0
  331. agentpool_commands/completers.py +110 -0
  332. agentpool_commands/connections.py +175 -0
  333. agentpool_commands/markdown_utils.py +31 -0
  334. agentpool_commands/models.py +62 -0
  335. agentpool_commands/prompts.py +78 -0
  336. agentpool_commands/py.typed +0 -0
  337. agentpool_commands/read.py +77 -0
  338. agentpool_commands/resources.py +210 -0
  339. agentpool_commands/session.py +48 -0
  340. agentpool_commands/tools.py +269 -0
  341. agentpool_commands/utils.py +189 -0
  342. agentpool_commands/workers.py +163 -0
  343. agentpool_config/__init__.py +53 -0
  344. agentpool_config/builtin_tools.py +265 -0
  345. agentpool_config/commands.py +237 -0
  346. agentpool_config/conditions.py +301 -0
  347. agentpool_config/converters.py +30 -0
  348. agentpool_config/durable.py +331 -0
  349. agentpool_config/event_handlers.py +600 -0
  350. agentpool_config/events.py +153 -0
  351. agentpool_config/forward_targets.py +251 -0
  352. agentpool_config/hook_conditions.py +331 -0
  353. agentpool_config/hooks.py +241 -0
  354. agentpool_config/jinja.py +206 -0
  355. agentpool_config/knowledge.py +41 -0
  356. agentpool_config/loaders.py +350 -0
  357. agentpool_config/mcp_server.py +243 -0
  358. agentpool_config/nodes.py +202 -0
  359. agentpool_config/observability.py +191 -0
  360. agentpool_config/output_types.py +55 -0
  361. agentpool_config/pool_server.py +267 -0
  362. agentpool_config/prompt_hubs.py +105 -0
  363. agentpool_config/prompts.py +185 -0
  364. agentpool_config/py.typed +0 -0
  365. agentpool_config/resources.py +33 -0
  366. agentpool_config/session.py +119 -0
  367. agentpool_config/skills.py +17 -0
  368. agentpool_config/storage.py +288 -0
  369. agentpool_config/system_prompts.py +190 -0
  370. agentpool_config/task.py +162 -0
  371. agentpool_config/teams.py +52 -0
  372. agentpool_config/tools.py +112 -0
  373. agentpool_config/toolsets.py +1033 -0
  374. agentpool_config/workers.py +86 -0
  375. agentpool_prompts/__init__.py +1 -0
  376. agentpool_prompts/braintrust_hub.py +235 -0
  377. agentpool_prompts/fabric.py +75 -0
  378. agentpool_prompts/langfuse_hub.py +79 -0
  379. agentpool_prompts/promptlayer_provider.py +59 -0
  380. agentpool_prompts/py.typed +0 -0
  381. agentpool_server/__init__.py +9 -0
  382. agentpool_server/a2a_server/__init__.py +5 -0
  383. agentpool_server/a2a_server/a2a_types.py +41 -0
  384. agentpool_server/a2a_server/server.py +190 -0
  385. agentpool_server/a2a_server/storage.py +81 -0
  386. agentpool_server/acp_server/__init__.py +22 -0
  387. agentpool_server/acp_server/acp_agent.py +786 -0
  388. agentpool_server/acp_server/acp_tools.py +43 -0
  389. agentpool_server/acp_server/commands/__init__.py +18 -0
  390. agentpool_server/acp_server/commands/acp_commands.py +594 -0
  391. agentpool_server/acp_server/commands/debug_commands.py +376 -0
  392. agentpool_server/acp_server/commands/docs_commands/__init__.py +39 -0
  393. agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +169 -0
  394. agentpool_server/acp_server/commands/docs_commands/get_schema.py +176 -0
  395. agentpool_server/acp_server/commands/docs_commands/get_source.py +110 -0
  396. agentpool_server/acp_server/commands/docs_commands/git_diff.py +111 -0
  397. agentpool_server/acp_server/commands/docs_commands/helpers.py +33 -0
  398. agentpool_server/acp_server/commands/docs_commands/url_to_markdown.py +90 -0
  399. agentpool_server/acp_server/commands/spawn.py +210 -0
  400. agentpool_server/acp_server/converters.py +235 -0
  401. agentpool_server/acp_server/input_provider.py +338 -0
  402. agentpool_server/acp_server/server.py +288 -0
  403. agentpool_server/acp_server/session.py +969 -0
  404. agentpool_server/acp_server/session_manager.py +313 -0
  405. agentpool_server/acp_server/syntax_detection.py +250 -0
  406. agentpool_server/acp_server/zed_tools.md +90 -0
  407. agentpool_server/aggregating_server.py +309 -0
  408. agentpool_server/agui_server/__init__.py +11 -0
  409. agentpool_server/agui_server/server.py +128 -0
  410. agentpool_server/base.py +189 -0
  411. agentpool_server/http_server.py +164 -0
  412. agentpool_server/mcp_server/__init__.py +6 -0
  413. agentpool_server/mcp_server/server.py +314 -0
  414. agentpool_server/mcp_server/zed_wrapper.py +110 -0
  415. agentpool_server/openai_api_server/__init__.py +5 -0
  416. agentpool_server/openai_api_server/completions/__init__.py +1 -0
  417. agentpool_server/openai_api_server/completions/helpers.py +81 -0
  418. agentpool_server/openai_api_server/completions/models.py +98 -0
  419. agentpool_server/openai_api_server/responses/__init__.py +1 -0
  420. agentpool_server/openai_api_server/responses/helpers.py +74 -0
  421. agentpool_server/openai_api_server/responses/models.py +96 -0
  422. agentpool_server/openai_api_server/server.py +242 -0
  423. agentpool_server/py.typed +0 -0
  424. agentpool_storage/__init__.py +9 -0
  425. agentpool_storage/base.py +310 -0
  426. agentpool_storage/file_provider.py +378 -0
  427. agentpool_storage/formatters.py +129 -0
  428. agentpool_storage/memory_provider.py +396 -0
  429. agentpool_storage/models.py +108 -0
  430. agentpool_storage/py.typed +0 -0
  431. agentpool_storage/session_store.py +262 -0
  432. agentpool_storage/sql_provider/__init__.py +21 -0
  433. agentpool_storage/sql_provider/cli.py +146 -0
  434. agentpool_storage/sql_provider/models.py +249 -0
  435. agentpool_storage/sql_provider/queries.py +15 -0
  436. agentpool_storage/sql_provider/sql_provider.py +444 -0
  437. agentpool_storage/sql_provider/utils.py +234 -0
  438. agentpool_storage/text_log_provider.py +275 -0
  439. agentpool_toolsets/__init__.py +15 -0
  440. agentpool_toolsets/builtin/__init__.py +33 -0
  441. agentpool_toolsets/builtin/agent_management.py +239 -0
  442. agentpool_toolsets/builtin/chain.py +288 -0
  443. agentpool_toolsets/builtin/code.py +398 -0
  444. agentpool_toolsets/builtin/debug.py +291 -0
  445. agentpool_toolsets/builtin/execution_environment.py +381 -0
  446. agentpool_toolsets/builtin/file_edit/__init__.py +11 -0
  447. agentpool_toolsets/builtin/file_edit/file_edit.py +747 -0
  448. agentpool_toolsets/builtin/file_edit/fuzzy_matcher/__init__.py +5 -0
  449. agentpool_toolsets/builtin/file_edit/fuzzy_matcher/example_usage.py +311 -0
  450. agentpool_toolsets/builtin/file_edit/fuzzy_matcher/streaming_fuzzy_matcher.py +443 -0
  451. agentpool_toolsets/builtin/history.py +36 -0
  452. agentpool_toolsets/builtin/integration.py +85 -0
  453. agentpool_toolsets/builtin/skills.py +77 -0
  454. agentpool_toolsets/builtin/subagent_tools.py +324 -0
  455. agentpool_toolsets/builtin/tool_management.py +90 -0
  456. agentpool_toolsets/builtin/user_interaction.py +52 -0
  457. agentpool_toolsets/builtin/workers.py +128 -0
  458. agentpool_toolsets/composio_toolset.py +96 -0
  459. agentpool_toolsets/config_creation.py +192 -0
  460. agentpool_toolsets/entry_points.py +47 -0
  461. agentpool_toolsets/fsspec_toolset/__init__.py +7 -0
  462. agentpool_toolsets/fsspec_toolset/diagnostics.py +115 -0
  463. agentpool_toolsets/fsspec_toolset/grep.py +450 -0
  464. agentpool_toolsets/fsspec_toolset/helpers.py +631 -0
  465. agentpool_toolsets/fsspec_toolset/streaming_diff_parser.py +249 -0
  466. agentpool_toolsets/fsspec_toolset/toolset.py +1384 -0
  467. agentpool_toolsets/mcp_run_toolset.py +61 -0
  468. agentpool_toolsets/notifications.py +146 -0
  469. agentpool_toolsets/openapi.py +118 -0
  470. agentpool_toolsets/py.typed +0 -0
  471. agentpool_toolsets/search_toolset.py +202 -0
  472. agentpool_toolsets/semantic_memory_toolset.py +536 -0
  473. agentpool_toolsets/streaming_tools.py +265 -0
  474. agentpool_toolsets/vfs_toolset.py +124 -0
@@ -0,0 +1,423 @@
1
+ """AG-UI to native event converters.
2
+
3
+ This module provides conversion from AG-UI protocol events to native agentpool
4
+ streaming events, enabling AGUIAgent to yield the same event types as native agents.
5
+
6
+ Also provides conversion of native Tool objects to AG-UI Tool format for
7
+ client-side tool execution.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import base64
13
+ from typing import TYPE_CHECKING, Any
14
+
15
+ import anyenv
16
+ from pydantic_ai import (
17
+ AudioUrl,
18
+ BinaryContent,
19
+ BinaryImage,
20
+ CachePoint,
21
+ DocumentUrl,
22
+ FileUrl,
23
+ ImageUrl,
24
+ PartDeltaEvent,
25
+ TextPartDelta,
26
+ ThinkingPartDelta,
27
+ VideoUrl,
28
+ )
29
+
30
+ from agentpool.agents.events import (
31
+ CustomEvent,
32
+ PlanUpdateEvent,
33
+ RunErrorEvent,
34
+ RunStartedEvent,
35
+ ToolCallProgressEvent,
36
+ ToolCallStartEvent as NativeToolCallStartEvent,
37
+ )
38
+ from agentpool.resource_providers.plan_provider import PlanEntry
39
+
40
+
41
+ if TYPE_CHECKING:
42
+ from collections.abc import Sequence
43
+
44
+ from ag_ui.core import BaseEvent, InputContent, Tool as AGUITool
45
+ from pydantic_ai import UserContent
46
+
47
+ from agentpool.agents.events import RichAgentStreamEvent
48
+ from agentpool.tools.base import Tool
49
+
50
+
51
+ def agui_to_native_event(event: BaseEvent) -> RichAgentStreamEvent[Any] | None: # noqa: PLR0911
52
+ """Convert AG-UI event to native streaming event.
53
+
54
+ Args:
55
+ event: AG-UI Event from SSE stream
56
+
57
+ Returns:
58
+ Corresponding native event, or None if no mapping exists
59
+ """
60
+ from ag_ui.core import (
61
+ ActivityDeltaEvent,
62
+ ActivitySnapshotEvent,
63
+ CustomEvent as AGUICustomEvent,
64
+ MessagesSnapshotEvent,
65
+ RawEvent,
66
+ RunErrorEvent as AGUIRunErrorEvent,
67
+ RunStartedEvent as AGUIRunStartedEvent,
68
+ StateDeltaEvent,
69
+ StateSnapshotEvent,
70
+ TextMessageChunkEvent,
71
+ TextMessageContentEvent,
72
+ TextMessageEndEvent,
73
+ TextMessageStartEvent,
74
+ ThinkingEndEvent,
75
+ ThinkingStartEvent,
76
+ ThinkingTextMessageContentEvent,
77
+ ThinkingTextMessageEndEvent,
78
+ ThinkingTextMessageStartEvent,
79
+ ToolCallArgsEvent,
80
+ ToolCallChunkEvent,
81
+ ToolCallEndEvent,
82
+ ToolCallResultEvent,
83
+ ToolCallStartEvent,
84
+ )
85
+
86
+ match event:
87
+ # === Lifecycle Events ===
88
+
89
+ case AGUIRunStartedEvent(thread_id=thread_id, run_id=run_id):
90
+ return RunStartedEvent(thread_id=thread_id, run_id=run_id)
91
+
92
+ case AGUIRunErrorEvent(message=message, code=code):
93
+ return RunErrorEvent(message=message, code=code)
94
+
95
+ # === Text Message Events ===
96
+
97
+ case TextMessageContentEvent(delta=delta):
98
+ return PartDeltaEvent(index=0, delta=TextPartDelta(content_delta=delta))
99
+
100
+ case TextMessageChunkEvent(delta=delta) if delta:
101
+ return PartDeltaEvent(index=0, delta=TextPartDelta(content_delta=delta))
102
+
103
+ case TextMessageStartEvent() | TextMessageEndEvent():
104
+ return None
105
+
106
+ # === Thinking/Reasoning Events ===
107
+
108
+ case ThinkingTextMessageContentEvent(delta=delta):
109
+ return PartDeltaEvent(index=0, delta=ThinkingPartDelta(content_delta=delta))
110
+
111
+ case ThinkingStartEvent() | ThinkingEndEvent():
112
+ # These mark thinking blocks but don't carry content
113
+ return None
114
+
115
+ case ThinkingTextMessageStartEvent() | ThinkingTextMessageEndEvent():
116
+ return None
117
+
118
+ # === Tool Call Events ===
119
+
120
+ case ToolCallStartEvent(tool_call_id=str() as tc_id, tool_call_name=name):
121
+ return NativeToolCallStartEvent(tool_call_id=tc_id, tool_name=name, title=name)
122
+
123
+ case ToolCallChunkEvent(tool_call_id=str() as tc_id, tool_call_name=str() as name):
124
+ return NativeToolCallStartEvent(tool_call_id=tc_id, tool_name=name, title=name)
125
+
126
+ case ToolCallArgsEvent(tool_call_id=tool_call_id, delta=_):
127
+ return ToolCallProgressEvent(tool_call_id=tool_call_id, status="in_progress")
128
+
129
+ case ToolCallResultEvent(tool_call_id=tc_id, content=content, message_id=_):
130
+ return ToolCallProgressEvent(tool_call_id=tc_id, status="completed", message=content)
131
+
132
+ case ToolCallEndEvent(tool_call_id=tool_call_id):
133
+ return ToolCallProgressEvent(tool_call_id=tool_call_id, status="completed")
134
+
135
+ # === Activity Events -> PlanUpdateEvent ===
136
+
137
+ case ActivitySnapshotEvent(
138
+ message_id=_, activity_type=activity_type, content=content, replace=_
139
+ ):
140
+ # Map activity content to plan entries if it looks like a plan
141
+ if activity_type.upper() == "PLAN" and isinstance(content, list):
142
+ entries = _content_to_plan_entries(content)
143
+ if entries:
144
+ return PlanUpdateEvent(entries=entries)
145
+ # For other activity types, wrap as custom event
146
+ return CustomEvent(
147
+ event_data={"activity_type": activity_type, "content": content},
148
+ event_type=f"activity_{activity_type.lower()}",
149
+ source="ag-ui",
150
+ )
151
+
152
+ case ActivityDeltaEvent(message_id=_, activity_type=activity_type, patch=patch):
153
+ return CustomEvent(
154
+ event_data={"activity_type": activity_type, "patch": patch},
155
+ event_type=f"activity_delta_{activity_type.lower()}",
156
+ source="ag-ui",
157
+ )
158
+
159
+ # === State Management Events ===
160
+
161
+ case StateSnapshotEvent(snapshot=snapshot):
162
+ return CustomEvent(event_data=snapshot, event_type="state_snapshot", source="ag-ui")
163
+
164
+ case StateDeltaEvent(delta=delta):
165
+ return CustomEvent(event_data=delta, event_type="state_delta", source="ag-ui")
166
+
167
+ case MessagesSnapshotEvent(messages=messages):
168
+ data = [m.model_dump() if hasattr(m, "model_dump") else m for m in messages]
169
+ return CustomEvent(event_data=data, event_type="messages_snapshot", source="ag-ui")
170
+
171
+ # === Special Events ===
172
+
173
+ case RawEvent(event=raw_event, source=source):
174
+ return CustomEvent(event_data=raw_event, event_type="raw", source=source or "ag-ui")
175
+
176
+ case AGUICustomEvent(name=name, value=value):
177
+ return CustomEvent(event_data=value, event_type=name, source="ag-ui")
178
+
179
+ case _:
180
+ return None
181
+
182
+
183
+ def _content_to_plan_entries(content: list[Any]) -> list[PlanEntry]:
184
+ """Convert AG-UI activity content to PlanEntry list.
185
+
186
+ Args:
187
+ content: List of plan items from ActivitySnapshotEvent
188
+
189
+ Returns:
190
+ List of PlanEntry objects
191
+ """
192
+ entries: list[PlanEntry] = []
193
+ for item in content:
194
+ if isinstance(item, dict):
195
+ # Try to extract plan entry fields
196
+ entry_content = item.get("content") or item.get("text") or item.get("description", "")
197
+ priority = item.get("priority", "medium")
198
+ status = item.get("status", "pending")
199
+
200
+ # Normalize values
201
+ if priority not in ("high", "medium", "low"):
202
+ priority = "medium"
203
+ if status not in ("pending", "in_progress", "completed"):
204
+ status = "pending"
205
+
206
+ if entry_content:
207
+ entry = PlanEntry(content=str(entry_content), priority=priority, status=status)
208
+ entries.append(entry)
209
+ elif isinstance(item, str):
210
+ entries.append(PlanEntry(content=item, priority="medium", status="pending"))
211
+ return entries
212
+
213
+
214
+ def to_agui_input_content(
215
+ parts: UserContent | Sequence[UserContent] | None,
216
+ ) -> list[InputContent]:
217
+ """Convert pydantic-ai UserContent parts to AG-UI InputContent format.
218
+
219
+ Args:
220
+ parts: UserContent part(s) to convert (str, ImageUrl, BinaryContent, etc.)
221
+
222
+ Returns:
223
+ List of AG-UI InputContent items
224
+ """
225
+ from ag_ui.core import BinaryInputContent, TextInputContent
226
+
227
+ if parts is None:
228
+ return []
229
+
230
+ # Normalize to list
231
+ part_list = (
232
+ [parts] if isinstance(parts, str | FileUrl | BinaryContent | CachePoint) else list(parts)
233
+ )
234
+
235
+ result: list[InputContent] = []
236
+ for part in part_list:
237
+ match part:
238
+ case str() as text:
239
+ result.append(TextInputContent(text=text))
240
+
241
+ case ImageUrl(url=url, media_type=media_type):
242
+ result.append(BinaryInputContent(url=str(url), mime_type=media_type))
243
+
244
+ case AudioUrl(url=url, media_type=media_type):
245
+ result.append(BinaryInputContent(url=str(url), mime_type=media_type))
246
+
247
+ case DocumentUrl(url=url, media_type=media_type):
248
+ result.append(BinaryInputContent(url=str(url), mime_type=media_type))
249
+
250
+ case VideoUrl(url=url, media_type=media_type):
251
+ result.append(BinaryInputContent(url=str(url), mime_type=media_type))
252
+
253
+ case FileUrl(url=url, media_type=media_type):
254
+ # Generic FileUrl fallback
255
+ result.append(BinaryInputContent(url=str(url), mime_type=media_type))
256
+
257
+ case BinaryImage(data=data, media_type=media_type):
258
+ encoded = base64.b64encode(data).decode("utf-8")
259
+ result.append(BinaryInputContent(data=encoded, mime_type=media_type))
260
+
261
+ case BinaryContent(data=data, media_type=media_type):
262
+ encoded = base64.b64encode(data).decode("utf-8")
263
+ result.append(BinaryInputContent(data=encoded, mime_type=media_type))
264
+
265
+ case CachePoint():
266
+ # Cache points are markers, not actual content - skip
267
+ pass
268
+
269
+ case _:
270
+ # Fallback: convert to string
271
+ result.append(TextInputContent(text=str(part)))
272
+
273
+ return result
274
+
275
+
276
+ def to_agui_tool(tool: Tool) -> AGUITool:
277
+ """Convert native Tool to AG-UI Tool format.
278
+
279
+ Args:
280
+ tool: native Tool instance
281
+
282
+ Returns:
283
+ AG-UI Tool with JSON Schema parameters
284
+ """
285
+ from ag_ui.core import Tool as AGUITool
286
+
287
+ schema = tool.schema
288
+ func_schema = schema["function"]
289
+ return AGUITool(
290
+ name=func_schema["name"],
291
+ description=func_schema.get("description", ""),
292
+ parameters=func_schema.get("parameters", {"type": "object", "properties": {}}),
293
+ )
294
+
295
+
296
+ def _repair_partial_json(buffer: str) -> str:
297
+ """Attempt to repair truncated JSON for preview purposes.
298
+
299
+ Handles common truncation cases:
300
+ - Unclosed strings
301
+ - Missing closing braces/brackets
302
+ - Trailing commas
303
+
304
+ Args:
305
+ buffer: Potentially incomplete JSON string
306
+
307
+ Returns:
308
+ Repaired JSON string (may still be invalid in edge cases)
309
+ """
310
+ if not buffer:
311
+ return "{}"
312
+
313
+ result = buffer.rstrip()
314
+
315
+ # Check if we're in the middle of a string by counting unescaped quotes
316
+ in_string = False
317
+ i = 0
318
+ while i < len(result):
319
+ char = result[i]
320
+ if char == "\\" and i + 1 < len(result):
321
+ i += 2 # Skip escaped character
322
+ continue
323
+ if char == '"':
324
+ in_string = not in_string
325
+ i += 1
326
+
327
+ # Close unclosed string
328
+ if in_string:
329
+ result += '"'
330
+
331
+ # Remove trailing comma (invalid JSON)
332
+ result = result.rstrip()
333
+ if result.endswith(","):
334
+ result = result[:-1]
335
+
336
+ # Balance braces and brackets
337
+ open_braces = result.count("{") - result.count("}")
338
+ open_brackets = result.count("[") - result.count("]")
339
+
340
+ result += "]" * max(0, open_brackets)
341
+ result += "}" * max(0, open_braces)
342
+
343
+ return result
344
+
345
+
346
+ class ToolCallAccumulator:
347
+ """Accumulates streamed tool call arguments.
348
+
349
+ AG-UI streams tool call arguments as deltas, this class accumulates them
350
+ and provides the complete arguments when the tool call ends.
351
+ """
352
+
353
+ def __init__(self) -> None:
354
+ self._calls: dict[str, dict[str, Any]] = {}
355
+
356
+ def start(self, tool_call_id: str, tool_name: str) -> None:
357
+ """Start tracking a new tool call."""
358
+ self._calls[tool_call_id] = {"name": tool_name, "args_buffer": ""}
359
+
360
+ def add_args(self, tool_call_id: str, delta: str) -> None:
361
+ """Add argument delta to a tool call."""
362
+ if tool_call_id in self._calls:
363
+ self._calls[tool_call_id]["args_buffer"] += delta
364
+
365
+ def complete(self, tool_call_id: str) -> tuple[str, dict[str, Any]] | None:
366
+ """Complete a tool call and return (tool_name, parsed_args).
367
+
368
+ Returns:
369
+ Tuple of (tool_name, args_dict) or None if call not found
370
+ """
371
+ if tool_call_id not in self._calls:
372
+ return None
373
+
374
+ call_data = self._calls.pop(tool_call_id)
375
+ args_str = call_data["args_buffer"]
376
+ try:
377
+ args = anyenv.load_json(args_str) if args_str else {}
378
+ except anyenv.JsonLoadError:
379
+ args = {"raw": args_str}
380
+ return call_data["name"], args
381
+
382
+ def get_pending(self, tool_call_id: str) -> tuple[str, str] | None:
383
+ """Get pending call data (tool_name, args_buffer) without completing."""
384
+ if tool_call_id not in self._calls:
385
+ return None
386
+ data = self._calls[tool_call_id]
387
+ return data["name"], data["args_buffer"]
388
+
389
+ def get_partial_args(self, tool_call_id: str) -> dict[str, Any]:
390
+ """Get best-effort parsed args from incomplete JSON stream.
391
+
392
+ Uses heuristics to complete truncated JSON for preview purposes.
393
+ Handles unclosed strings, missing braces/brackets, and trailing commas.
394
+
395
+ Args:
396
+ tool_call_id: Tool call ID
397
+
398
+ Returns:
399
+ Partially parsed arguments or empty dict
400
+ """
401
+ if tool_call_id not in self._calls:
402
+ return {}
403
+
404
+ buffer = self._calls[tool_call_id]["args_buffer"]
405
+ if not buffer:
406
+ return {}
407
+
408
+ # Try direct parse first
409
+ try:
410
+ return anyenv.load_json(buffer)
411
+ except anyenv.JsonLoadError:
412
+ pass
413
+
414
+ # Try to repair truncated JSON
415
+ try:
416
+ repaired = _repair_partial_json(buffer)
417
+ return anyenv.load_json(repaired)
418
+ except anyenv.JsonLoadError:
419
+ return {}
420
+
421
+ def clear(self) -> None:
422
+ """Clear all pending tool calls."""
423
+ self._calls.clear()
@@ -0,0 +1,204 @@
1
+ """Chunk transformer for AG-UI events.
2
+
3
+ Transforms TEXT_MESSAGE_CHUNK and TOOL_CALL_CHUNK events into proper
4
+ START/CONTENT/END sequences for easier downstream processing.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import TYPE_CHECKING
10
+
11
+ from agentpool.log import get_logger
12
+
13
+
14
+ if TYPE_CHECKING:
15
+ from ag_ui.core import BaseEvent, TextMessageChunkEvent, ToolCallChunkEvent
16
+
17
+
18
+ logger = get_logger(__name__)
19
+
20
+
21
+ class ChunkTransformer:
22
+ """Transforms CHUNK events into proper START/CONTENT/END sequences.
23
+
24
+ AG-UI supports two streaming modes:
25
+ 1. Explicit: TEXT_MESSAGE_START -> TEXT_MESSAGE_CONTENT* -> TEXT_MESSAGE_END
26
+ 2. Chunk: TEXT_MESSAGE_CHUNK* (implicit start/end based on message_id changes)
27
+
28
+ This transformer normalizes chunk mode into explicit mode for consistent handling.
29
+ Same applies for TOOL_CALL_CHUNK events.
30
+ """
31
+
32
+ def __init__(self) -> None:
33
+ """Initialize transformer."""
34
+ # Track active text message: message_id -> role
35
+ self._active_text: dict[str, str] | None = None
36
+ # Track active tool call: tool_call_id -> (name, parent_message_id)
37
+ self._active_tool: dict[str, tuple[str, str | None]] | None = None
38
+
39
+ def transform(self, event: BaseEvent) -> list[BaseEvent]:
40
+ """Transform a single event, potentially expanding chunks.
41
+
42
+ Args:
43
+ event: Input event
44
+
45
+ Returns:
46
+ List of output events (may be empty, single, or multiple)
47
+ """
48
+ from ag_ui.core import EventType
49
+
50
+ match event.type:
51
+ case EventType.TEXT_MESSAGE_CHUNK:
52
+ return self._handle_text_chunk(event) # type: ignore[arg-type]
53
+
54
+ case EventType.TOOL_CALL_CHUNK:
55
+ return self._handle_tool_chunk(event) # type: ignore[arg-type]
56
+
57
+ # These events close any pending chunks
58
+ case (
59
+ EventType.TEXT_MESSAGE_START
60
+ | EventType.TEXT_MESSAGE_END
61
+ | EventType.TOOL_CALL_START
62
+ | EventType.TOOL_CALL_END
63
+ | EventType.RUN_FINISHED
64
+ | EventType.RUN_ERROR
65
+ ):
66
+ close_events = self._close_all_pending()
67
+ return [*close_events, event]
68
+
69
+ case _:
70
+ # Pass through other events unchanged
71
+ return [event]
72
+
73
+ def _handle_text_chunk(self, event: TextMessageChunkEvent) -> list[BaseEvent]:
74
+ """Handle TEXT_MESSAGE_CHUNK event."""
75
+ from ag_ui.core import EventType, TextMessageContentEvent, TextMessageStartEvent
76
+
77
+ result: list[BaseEvent] = []
78
+ message_id = event.message_id
79
+ role = event.role or "assistant"
80
+ delta = event.delta
81
+
82
+ # Check if we need to close current text message (different ID)
83
+ if self._active_text is not None:
84
+ current_id = next(iter(self._active_text.keys()))
85
+ if message_id and message_id != current_id:
86
+ result.extend(self._close_text_message())
87
+
88
+ # Start new message if needed
89
+ if self._active_text is None and message_id:
90
+ self._active_text = {message_id: role}
91
+ start_event = TextMessageStartEvent(
92
+ type=EventType.TEXT_MESSAGE_START,
93
+ message_id=message_id,
94
+ role=role,
95
+ )
96
+ result.append(start_event)
97
+
98
+ # Emit content if we have delta and active message
99
+ if delta and self._active_text:
100
+ current_id = next(iter(self._active_text.keys()))
101
+ content_event = TextMessageContentEvent(
102
+ type=EventType.TEXT_MESSAGE_CONTENT,
103
+ message_id=current_id,
104
+ delta=delta,
105
+ )
106
+ result.append(content_event)
107
+
108
+ return result
109
+
110
+ def _handle_tool_chunk(self, event: ToolCallChunkEvent) -> list[BaseEvent]:
111
+ """Handle TOOL_CALL_CHUNK event."""
112
+ from ag_ui.core import EventType, ToolCallArgsEvent, ToolCallStartEvent
113
+
114
+ result: list[BaseEvent] = []
115
+ tool_call_id = event.tool_call_id
116
+ tool_name = event.tool_call_name
117
+ parent_id = event.parent_message_id
118
+ delta = event.delta
119
+
120
+ # Check if we need to close current tool call (different ID)
121
+ if self._active_tool is not None:
122
+ current_id = next(iter(self._active_tool.keys()))
123
+ if tool_call_id and tool_call_id != current_id:
124
+ result.extend(self._close_tool_call())
125
+
126
+ # Start new tool call if needed
127
+ if self._active_tool is None and tool_call_id and tool_name:
128
+ self._active_tool = {tool_call_id: (tool_name, parent_id)}
129
+ start_event = ToolCallStartEvent(
130
+ type=EventType.TOOL_CALL_START,
131
+ tool_call_id=tool_call_id,
132
+ tool_call_name=tool_name,
133
+ parent_message_id=parent_id,
134
+ )
135
+ result.append(start_event)
136
+
137
+ # Emit args if we have delta and active tool call
138
+ if delta and self._active_tool:
139
+ current_id = next(iter(self._active_tool.keys()))
140
+ args_event = ToolCallArgsEvent(
141
+ type=EventType.TOOL_CALL_ARGS,
142
+ tool_call_id=current_id,
143
+ delta=delta,
144
+ )
145
+ result.append(args_event)
146
+
147
+ return result
148
+
149
+ def _close_text_message(self) -> list[BaseEvent]:
150
+ """Close active text message."""
151
+ from ag_ui.core import EventType, TextMessageEndEvent
152
+
153
+ if self._active_text is None:
154
+ return []
155
+
156
+ message_id = next(iter(self._active_text.keys()))
157
+ self._active_text = None
158
+
159
+ end_event = TextMessageEndEvent(
160
+ type=EventType.TEXT_MESSAGE_END,
161
+ message_id=message_id,
162
+ )
163
+ logger.debug("Chunk transformer: TEXT_MESSAGE_END", message_id=message_id)
164
+ return [end_event]
165
+
166
+ def _close_tool_call(self) -> list[BaseEvent]:
167
+ """Close active tool call."""
168
+ from ag_ui.core import EventType, ToolCallEndEvent
169
+
170
+ if self._active_tool is None:
171
+ return []
172
+
173
+ tool_call_id = next(iter(self._active_tool.keys()))
174
+ self._active_tool = None
175
+
176
+ end_event = ToolCallEndEvent(
177
+ type=EventType.TOOL_CALL_END,
178
+ tool_call_id=tool_call_id,
179
+ )
180
+ logger.debug("Chunk transformer: TOOL_CALL_END", tool_call_id=tool_call_id)
181
+ return [end_event]
182
+
183
+ def _close_all_pending(self) -> list[BaseEvent]:
184
+ """Close all pending chunks (text and tool)."""
185
+ result: list[BaseEvent] = []
186
+ result.extend(self._close_text_message())
187
+ result.extend(self._close_tool_call())
188
+ return result
189
+
190
+ def flush(self) -> list[BaseEvent]:
191
+ """Flush any pending events at end of stream.
192
+
193
+ Call this when the stream ends to ensure all pending
194
+ messages/tool calls are properly closed.
195
+
196
+ Returns:
197
+ List of closing events
198
+ """
199
+ return self._close_all_pending()
200
+
201
+ def reset(self) -> None:
202
+ """Reset transformer state."""
203
+ self._active_text = None
204
+ self._active_tool = None
@@ -0,0 +1,83 @@
1
+ """Extended AG-UI event types.
2
+
3
+ The upstream ag_ui.core.Event union is missing thinking events.
4
+ This module provides a complete Event type until the SDK is fixed.
5
+
6
+ TODO: Remove this workaround once upstream SDK is fixed.
7
+ See: https://github.com/ag-ui-protocol/ag-ui/pull/753
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import Annotated
13
+
14
+ from ag_ui.core import (
15
+ ActivityDeltaEvent,
16
+ ActivitySnapshotEvent,
17
+ CustomEvent,
18
+ MessagesSnapshotEvent,
19
+ RawEvent,
20
+ RunErrorEvent,
21
+ RunFinishedEvent,
22
+ RunStartedEvent,
23
+ StateDeltaEvent,
24
+ StateSnapshotEvent,
25
+ StepFinishedEvent,
26
+ StepStartedEvent,
27
+ TextMessageChunkEvent,
28
+ TextMessageContentEvent,
29
+ TextMessageEndEvent,
30
+ TextMessageStartEvent,
31
+ ThinkingEndEvent,
32
+ ThinkingStartEvent,
33
+ ThinkingTextMessageContentEvent,
34
+ ThinkingTextMessageEndEvent,
35
+ ThinkingTextMessageStartEvent,
36
+ ToolCallArgsEvent,
37
+ ToolCallChunkEvent,
38
+ ToolCallEndEvent,
39
+ ToolCallResultEvent,
40
+ ToolCallStartEvent,
41
+ )
42
+ from pydantic import Field
43
+
44
+
45
+ # Complete Event union including thinking events (missing from upstream SDK)
46
+ Event = Annotated[
47
+ # Text message events
48
+ TextMessageStartEvent
49
+ | TextMessageContentEvent
50
+ | TextMessageEndEvent
51
+ | TextMessageChunkEvent
52
+ # Thinking events (missing from upstream Event union)
53
+ | ThinkingStartEvent
54
+ | ThinkingEndEvent
55
+ | ThinkingTextMessageStartEvent
56
+ | ThinkingTextMessageContentEvent
57
+ | ThinkingTextMessageEndEvent
58
+ # Tool call events
59
+ | ToolCallStartEvent
60
+ | ToolCallArgsEvent
61
+ | ToolCallEndEvent
62
+ | ToolCallChunkEvent
63
+ | ToolCallResultEvent
64
+ # State events
65
+ | StateSnapshotEvent
66
+ | StateDeltaEvent
67
+ | MessagesSnapshotEvent
68
+ # Activity events
69
+ | ActivitySnapshotEvent
70
+ | ActivityDeltaEvent
71
+ # Lifecycle events
72
+ | RunStartedEvent
73
+ | RunFinishedEvent
74
+ | RunErrorEvent
75
+ | StepStartedEvent
76
+ | StepFinishedEvent
77
+ # Special events
78
+ | RawEvent
79
+ | CustomEvent,
80
+ Field(discriminator="type"),
81
+ ]
82
+
83
+ __all__ = ["Event"]