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,243 @@
1
+ """Claude Agent SDK to native event converters.
2
+
3
+ This module provides conversion from Claude Agent SDK message types to native
4
+ agentpool streaming events, enabling ClaudeCodeAgent to yield the same
5
+ event types as native agents.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass, field
11
+ from typing import TYPE_CHECKING, Any
12
+
13
+ from pydantic_ai import PartDeltaEvent, TextPartDelta, ThinkingPartDelta
14
+
15
+ from agentpool.agents.events import (
16
+ DiffContentItem,
17
+ LocationContentItem,
18
+ ToolCallCompleteEvent,
19
+ ToolCallStartEvent,
20
+ )
21
+
22
+
23
+ if TYPE_CHECKING:
24
+ from claude_agent_sdk import ContentBlock, Message, ToolUseBlock
25
+
26
+ from agentpool.agents.events import RichAgentStreamEvent, ToolCallContentItem
27
+ from agentpool.tools.base import ToolKind
28
+
29
+
30
+ @dataclass
31
+ class RichToolInfo:
32
+ """Rich display information derived from tool name and input."""
33
+
34
+ title: str
35
+ """Human-readable title for the tool call."""
36
+ kind: ToolKind = "other"
37
+ """Category of tool operation."""
38
+ locations: list[LocationContentItem] = field(default_factory=list)
39
+ """File locations involved in the operation."""
40
+ content: list[ToolCallContentItem] = field(default_factory=list)
41
+ """Rich content items (diffs, text, etc.)."""
42
+
43
+
44
+ def derive_rich_tool_info(name: str, input_data: dict[str, Any]) -> RichToolInfo: # noqa: PLR0911, PLR0915
45
+ """Derive rich display info from tool name and input arguments.
46
+
47
+ Maps MCP tool names and their inputs to human-readable titles, kinds,
48
+ and location information for rich UI display. Handles both Claude Code
49
+ built-in tools and MCP bridge tools.
50
+
51
+ Args:
52
+ name: The tool name (e.g., "Read", "mcp__server__read_file")
53
+ input_data: The tool input arguments
54
+
55
+ Returns:
56
+ RichToolInfo with derived display information
57
+ """
58
+ # Extract the actual tool name if it's an MCP bridge tool
59
+ # Format: mcp__{server_name}__{tool_name}
60
+ actual_name = name
61
+ if name.startswith("mcp__") and "__" in name[5:]:
62
+ parts = name.split("__")
63
+ if len(parts) >= 3: # noqa: PLR2004
64
+ actual_name = parts[-1] # Get the last part (actual tool name)
65
+
66
+ # Normalize to lowercase for matching
67
+ tool_lower = actual_name.lower()
68
+ # Read operations
69
+ if tool_lower in ("read", "read_file"):
70
+ path = input_data.get("file_path") or input_data.get("path", "")
71
+ offset = input_data.get("offset") or input_data.get("line")
72
+ limit = input_data.get("limit")
73
+
74
+ suffix = ""
75
+ if limit:
76
+ start = (offset or 0) + 1
77
+ end = (offset or 0) + limit
78
+ suffix = f" ({start}-{end})"
79
+ elif offset:
80
+ suffix = f" (from line {offset + 1})"
81
+ title = f"Read {path}{suffix}" if path else "Read File"
82
+ locations = [LocationContentItem(path=path, line=offset or 0)] if path else []
83
+ return RichToolInfo(title=title, kind="read", locations=locations)
84
+
85
+ # Write operations
86
+ if tool_lower in ("write", "write_file"):
87
+ path = input_data.get("file_path") or input_data.get("path", "")
88
+ content = input_data.get("content", "")
89
+ return RichToolInfo(
90
+ title=f"Write {path}" if path else "Write File",
91
+ kind="edit",
92
+ locations=[LocationContentItem(path=path)] if path else [],
93
+ content=[DiffContentItem(path=path, old_text=None, new_text=content)] if path else [],
94
+ )
95
+ # Edit operations
96
+ if tool_lower in ("edit", "edit_file"):
97
+ path = input_data.get("file_path") or input_data.get("path", "")
98
+ old_string = input_data.get("old_string") or input_data.get("old_text", "")
99
+ new_string = input_data.get("new_string") or input_data.get("new_text", "")
100
+ return RichToolInfo(
101
+ title=f"Edit {path}" if path else "Edit File",
102
+ kind="edit",
103
+ locations=[LocationContentItem(path=path)] if path else [],
104
+ content=[DiffContentItem(path=path, old_text=old_string, new_text=new_string)]
105
+ if path
106
+ else [],
107
+ )
108
+ # Delete operations
109
+ if tool_lower in ("delete", "delete_path", "delete_file"):
110
+ path = input_data.get("file_path") or input_data.get("path", "")
111
+ locations = [LocationContentItem(path=path)] if path else []
112
+ title = f"Delete {path}" if path else "Delete"
113
+ return RichToolInfo(title=title, kind="delete", locations=locations)
114
+ # Bash/terminal operations
115
+ if tool_lower in ("bash", "execute", "run_command", "execute_command", "execute_code"):
116
+ command = input_data.get("command") or input_data.get("code", "")
117
+ # Escape backticks in command
118
+ escaped_cmd = command.replace("`", "\\`") if command else ""
119
+ title = f"`{escaped_cmd}`" if escaped_cmd else "Terminal"
120
+ return RichToolInfo(title=title, kind="execute")
121
+ # Search operations
122
+ if tool_lower in ("grep", "search", "glob", "find"):
123
+ pattern = input_data.get("pattern") or input_data.get("query", "")
124
+ path = input_data.get("path", "")
125
+ title = f"Search for '{pattern}'" if pattern else "Search"
126
+ if path:
127
+ title += f" in {path}"
128
+ locations = [LocationContentItem(path=path)] if path else []
129
+ return RichToolInfo(title=title, kind="search", locations=locations)
130
+ # List directory
131
+ if tool_lower in ("ls", "list", "list_directory"):
132
+ path = input_data.get("path", ".")
133
+ title = f"List {path}" if path != "." else "List current directory"
134
+ locations = [LocationContentItem(path=path)] if path else []
135
+ return RichToolInfo(title=title, kind="search", locations=locations)
136
+ # Web operations
137
+ if tool_lower in ("webfetch", "web_fetch", "fetch"):
138
+ url = input_data.get("url", "")
139
+ return RichToolInfo(title=f"Fetch {url}" if url else "Web Fetch", kind="fetch")
140
+ if tool_lower in ("websearch", "web_search", "search_web"):
141
+ query = input_data.get("query", "")
142
+ return RichToolInfo(title=f"Search: {query}" if query else "Web Search", kind="fetch")
143
+ # Task/subagent operations
144
+ if tool_lower == "task":
145
+ description = input_data.get("description", "")
146
+ return RichToolInfo(title=description if description else "Task", kind="think")
147
+ # Notebook operations
148
+ if tool_lower in ("notebookread", "notebook_read"):
149
+ path = input_data.get("notebook_path", "")
150
+ title = f"Read Notebook {path}" if path else "Read Notebook"
151
+ locations = [LocationContentItem(path=path)] if path else []
152
+ return RichToolInfo(title=title, kind="read", locations=locations)
153
+ if tool_lower in ("notebookedit", "notebook_edit"):
154
+ path = input_data.get("notebook_path", "")
155
+ title = f"Edit Notebook {path}" if path else "Edit Notebook"
156
+ locations = [LocationContentItem(path=path)] if path else []
157
+ return RichToolInfo(title=title, kind="edit", locations=locations)
158
+ # Default: use the tool name as title
159
+ return RichToolInfo(title=actual_name, kind="other")
160
+
161
+
162
+ def content_block_to_event(block: ContentBlock, index: int = 0) -> RichAgentStreamEvent[Any] | None:
163
+ """Convert a Claude SDK ContentBlock to a streaming event.
164
+
165
+ Args:
166
+ block: Claude SDK content block
167
+ index: Part index for the event
168
+
169
+ Returns:
170
+ Corresponding streaming event, or None if not mappable
171
+ """
172
+ from claude_agent_sdk import TextBlock, ThinkingBlock, ToolUseBlock
173
+
174
+ match block:
175
+ case TextBlock(text=text):
176
+ return PartDeltaEvent(index=index, delta=TextPartDelta(content_delta=text))
177
+ case ThinkingBlock(thinking=thinking):
178
+ return PartDeltaEvent(index=index, delta=ThinkingPartDelta(content_delta=thinking))
179
+ case ToolUseBlock(id=tool_id, name=name, input=input_data):
180
+ rich_info = derive_rich_tool_info(name, input_data)
181
+ return ToolCallStartEvent(
182
+ tool_call_id=tool_id,
183
+ tool_name=name,
184
+ title=rich_info.title,
185
+ kind=rich_info.kind,
186
+ locations=rich_info.locations,
187
+ content=rich_info.content,
188
+ raw_input=input_data,
189
+ )
190
+ case _:
191
+ return None
192
+
193
+
194
+ def claude_message_to_events(
195
+ message: Message,
196
+ agent_name: str = "",
197
+ pending_tool_calls: dict[str, ToolUseBlock] | None = None,
198
+ ) -> list[RichAgentStreamEvent[Any]]:
199
+ """Convert a Claude SDK Message to a list of streaming events.
200
+
201
+ Args:
202
+ message: Claude SDK message (UserMessage, AssistantMessage, etc.)
203
+ agent_name: Name of the agent for event attribution
204
+ pending_tool_calls: Dict to track tool calls awaiting results
205
+
206
+ Returns:
207
+ List of corresponding streaming events
208
+ """
209
+ from claude_agent_sdk import AssistantMessage, ToolResultBlock, ToolUseBlock
210
+
211
+ events: list[RichAgentStreamEvent[Any]] = []
212
+
213
+ match message:
214
+ case AssistantMessage(content=content):
215
+ for idx, block in enumerate(content):
216
+ # Track tool use blocks for later pairing with results
217
+ if isinstance(block, ToolUseBlock) and pending_tool_calls is not None:
218
+ pending_tool_calls[block.id] = block
219
+
220
+ # Handle tool results - pair with pending tool call
221
+ if isinstance(block, ToolResultBlock) and pending_tool_calls is not None:
222
+ tool_use = pending_tool_calls.pop(block.tool_use_id, None)
223
+ if tool_use:
224
+ complete_event = ToolCallCompleteEvent(
225
+ tool_name=tool_use.name,
226
+ tool_call_id=block.tool_use_id,
227
+ tool_input=tool_use.input,
228
+ tool_result=block.content,
229
+ agent_name=agent_name,
230
+ message_id="",
231
+ )
232
+ events.append(complete_event)
233
+ continue
234
+
235
+ # Convert other blocks to events
236
+ if event := content_block_to_event(block, index=idx):
237
+ events.append(event)
238
+
239
+ case _:
240
+ # UserMessage, SystemMessage, ResultMessage - no events to emit
241
+ pass
242
+
243
+ return events
@@ -0,0 +1,105 @@
1
+ """Runtime context models for Agents."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import TYPE_CHECKING, Any, Literal
7
+
8
+ from agentpool.log import get_logger
9
+ from agentpool.messaging.context import NodeContext
10
+
11
+
12
+ if TYPE_CHECKING:
13
+ from mcp import types
14
+
15
+ from agentpool import Agent
16
+ from agentpool.agents.events import StreamEventEmitter
17
+ from agentpool.models.acp_agents.base import BaseACPAgentConfig
18
+ from agentpool.models.agents import NativeAgentConfig
19
+ from agentpool.models.agui_agents import AGUIAgentConfig
20
+ from agentpool.models.claude_code_agents import ClaudeCodeAgentConfig
21
+ from agentpool.tools.base import Tool
22
+
23
+
24
+ ConfirmationResult = Literal["allow", "skip", "abort_run", "abort_chain"]
25
+
26
+ logger = get_logger(__name__)
27
+
28
+
29
+ @dataclass(kw_only=True)
30
+ class AgentContext[TDeps = Any](NodeContext[TDeps]):
31
+ """Runtime context for agent execution.
32
+
33
+ Generically typed with AgentContext[Type of Dependencies]
34
+ """
35
+
36
+ config: NativeAgentConfig | BaseACPAgentConfig | AGUIAgentConfig | ClaudeCodeAgentConfig
37
+ """Current agent's specific configuration."""
38
+
39
+ tool_name: str | None = None
40
+ """Name of the currently executing tool."""
41
+
42
+ tool_call_id: str | None = None
43
+ """ID of the current tool call."""
44
+
45
+ tool_input: dict[str, Any] = field(default_factory=dict)
46
+ """Input arguments for the current tool call."""
47
+
48
+ @property
49
+ def native_agent(self) -> Agent[TDeps, Any]:
50
+ """Current agent, type-narrowed to native pydantic-ai Agent."""
51
+ from agentpool import Agent
52
+
53
+ assert isinstance(self.node, Agent)
54
+ return self.node
55
+
56
+ async def handle_elicitation(
57
+ self,
58
+ params: types.ElicitRequestParams,
59
+ ) -> types.ElicitResult | types.ErrorData:
60
+ """Handle elicitation request for additional information."""
61
+ provider = self.get_input_provider()
62
+ return await provider.get_elicitation(params)
63
+
64
+ async def report_progress(self, progress: float, total: float | None, message: str) -> None:
65
+ """Report progress by emitting event into the agent's stream."""
66
+ from agentpool.agents.events import ToolCallProgressEvent
67
+
68
+ logger.info("Reporting tool call progress", progress=progress, total=total, message=message)
69
+ progress_event = ToolCallProgressEvent(
70
+ progress=int(progress),
71
+ total=int(total) if total is not None else 100,
72
+ message=message,
73
+ tool_name=self.tool_name or "",
74
+ tool_call_id=self.tool_call_id or "",
75
+ tool_input=self.tool_input,
76
+ )
77
+ await self.agent._event_queue.put(progress_event)
78
+
79
+ @property
80
+ def events(self) -> StreamEventEmitter:
81
+ """Get event emitter with context automatically injected."""
82
+ from agentpool.agents.events import StreamEventEmitter
83
+
84
+ return StreamEventEmitter(self)
85
+
86
+ async def handle_confirmation(self, tool: Tool, args: dict[str, Any]) -> ConfirmationResult:
87
+ """Handle tool execution confirmation.
88
+
89
+ Returns "allow" if:
90
+ - No confirmation handler is set
91
+ - Handler confirms the execution
92
+
93
+ Args:
94
+ tool: The tool being executed
95
+ args: Arguments passed to the tool
96
+
97
+ Returns:
98
+ Confirmation result indicating how to proceed
99
+ """
100
+ provider = self.get_input_provider()
101
+ mode = self.agent.tool_confirmation_mode
102
+ if (mode == "per_tool" and not tool.requires_confirmation) or mode == "never":
103
+ return "allow"
104
+ history = self.agent.conversation.get_history() if self.pool else []
105
+ return await provider.get_tool_confirmation(self, tool, args, history)
@@ -0,0 +1,61 @@
1
+ """Agent events."""
2
+
3
+ from .events import (
4
+ CommandCompleteEvent,
5
+ CommandOutputEvent,
6
+ CustomEvent,
7
+ DiffContentItem,
8
+ FileContentItem,
9
+ LocationContentItem,
10
+ PlanUpdateEvent,
11
+ RichAgentStreamEvent,
12
+ RunErrorEvent,
13
+ RunStartedEvent,
14
+ SlashedAgentStreamEvent,
15
+ StreamCompleteEvent,
16
+ TerminalContentItem,
17
+ TextContentItem,
18
+ ToolCallCompleteEvent,
19
+ ToolCallContentItem,
20
+ ToolCallProgressEvent,
21
+ ToolCallStartEvent,
22
+ )
23
+ from .event_emitter import StreamEventEmitter
24
+ from .builtin_handlers import (
25
+ detailed_print_handler,
26
+ simple_print_handler,
27
+ resolve_event_handlers,
28
+ )
29
+ from .tts_handlers import (
30
+ BaseTTSEventHandler,
31
+ EdgeTTSEventHandler,
32
+ OpenAITTSEventHandler,
33
+ )
34
+
35
+ __all__ = [
36
+ "BaseTTSEventHandler",
37
+ "CommandCompleteEvent",
38
+ "CommandOutputEvent",
39
+ "CustomEvent",
40
+ "DiffContentItem",
41
+ "EdgeTTSEventHandler",
42
+ "FileContentItem",
43
+ "LocationContentItem",
44
+ "OpenAITTSEventHandler",
45
+ "PlanUpdateEvent",
46
+ "RichAgentStreamEvent",
47
+ "RunErrorEvent",
48
+ "RunStartedEvent",
49
+ "SlashedAgentStreamEvent",
50
+ "StreamCompleteEvent",
51
+ "StreamEventEmitter",
52
+ "TerminalContentItem",
53
+ "TextContentItem",
54
+ "ToolCallCompleteEvent",
55
+ "ToolCallContentItem",
56
+ "ToolCallProgressEvent",
57
+ "ToolCallStartEvent",
58
+ "detailed_print_handler",
59
+ "resolve_event_handlers",
60
+ "simple_print_handler",
61
+ ]
@@ -0,0 +1,129 @@
1
+ """Built-in event handlers for simple console output."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from typing import TYPE_CHECKING, Any
7
+
8
+ from pydantic_ai import (
9
+ FunctionToolCallEvent,
10
+ FunctionToolResultEvent,
11
+ PartDeltaEvent,
12
+ PartStartEvent,
13
+ TextPart,
14
+ TextPartDelta,
15
+ ThinkingPart,
16
+ ThinkingPartDelta,
17
+ ToolCallPart,
18
+ ToolReturnPart,
19
+ )
20
+
21
+ from agentpool.agents.events import (
22
+ RunErrorEvent,
23
+ StreamCompleteEvent,
24
+ ToolCallProgressEvent,
25
+ ToolCallStartEvent,
26
+ )
27
+
28
+
29
+ if TYPE_CHECKING:
30
+ from collections.abc import Sequence
31
+
32
+ from pydantic_ai import RunContext
33
+
34
+ from agentpool.agents.events import RichAgentStreamEvent
35
+ from agentpool.common_types import BuiltinEventHandlerType, IndividualEventHandler
36
+
37
+
38
+ async def simple_print_handler(ctx: RunContext, event: RichAgentStreamEvent[Any]) -> None:
39
+ """Simple event handler that prints text and basic tool information.
40
+
41
+ Focus: Core text output and minimal tool notifications.
42
+ Prints:
43
+ - Text content (streaming)
44
+ - Tool calls (name only)
45
+ - Errors
46
+ """
47
+ match event:
48
+ case (
49
+ PartStartEvent(part=TextPart(content=delta))
50
+ | PartDeltaEvent(delta=TextPartDelta(content_delta=delta))
51
+ ):
52
+ print(delta, end="", flush=True, file=sys.stderr)
53
+
54
+ case FunctionToolCallEvent(part=ToolCallPart() as part):
55
+ kwargs_str = ", ".join(f"{k}={v!r}" for k, v in part.args_as_dict().items())
56
+ print(f"\nšŸ”§ {part.tool_name}({kwargs_str})", flush=True, file=sys.stderr)
57
+
58
+ case FunctionToolResultEvent(result=ToolReturnPart() as return_part):
59
+ print(f"Result: {return_part.content}", file=sys.stderr)
60
+
61
+ case RunErrorEvent(message=message):
62
+ print(f"\nāŒ Error: {message}", flush=True, file=sys.stderr)
63
+
64
+ case StreamCompleteEvent():
65
+ print(file=sys.stderr) # Final newline
66
+
67
+
68
+ async def detailed_print_handler(ctx: RunContext, event: RichAgentStreamEvent[Any]) -> None:
69
+ """Detailed event handler with rich tool execution information.
70
+
71
+ Focus: Comprehensive execution visibility.
72
+ Prints:
73
+ - Text content (streaming)
74
+ - Thinking content
75
+ - Tool calls with inputs
76
+ - Tool results
77
+ - Tool progress with title
78
+ - Errors
79
+ """
80
+ match event:
81
+ case (
82
+ PartStartEvent(part=TextPart(content=delta))
83
+ | PartDeltaEvent(delta=TextPartDelta(content_delta=delta))
84
+ ):
85
+ print(delta, end="", flush=True, file=sys.stderr)
86
+
87
+ case (
88
+ PartStartEvent(part=ThinkingPart(content=delta))
89
+ | PartDeltaEvent(delta=ThinkingPartDelta(content_delta=delta))
90
+ ):
91
+ if delta:
92
+ print(f"\nšŸ’­ {delta}", end="", flush=True, file=sys.stderr)
93
+
94
+ case ToolCallStartEvent(tool_name=tool_name, title=title, tool_call_id=call_id):
95
+ print(f"\nšŸ”§ {tool_name}: {title} (#{call_id[:8]})", flush=True, file=sys.stderr)
96
+
97
+ case FunctionToolCallEvent(part=ToolCallPart(tool_name=tool_name, args=args)):
98
+ args_str = str(args)
99
+ if len(args_str) > 100: # noqa: PLR2004
100
+ args_str = args_str[:97] + "..."
101
+ print(f" šŸ“ Input: {args_str}", flush=True, file=sys.stderr)
102
+
103
+ case FunctionToolResultEvent(result=ToolReturnPart(content=content, tool_name=tool_name)):
104
+ result_str = str(content)
105
+ if len(result_str) > 150: # noqa: PLR2004
106
+ result_str = result_str[:147] + "..."
107
+ print(f" āœ… {tool_name}: {result_str}", flush=True, file=sys.stderr)
108
+
109
+ case ToolCallProgressEvent(title=title, status=status):
110
+ if title:
111
+ emoji = {"completed": "āœ…", "failed": "āŒ"}.get(status, "ā³")
112
+ print(f" {emoji} {title}", flush=True, file=sys.stderr)
113
+
114
+ case RunErrorEvent(message=message, code=code):
115
+ error_info = f" [{code}]" if code else ""
116
+ print(f"\nāŒ Error{error_info}: {message}", flush=True, file=sys.stderr)
117
+
118
+ case StreamCompleteEvent():
119
+ print(file=sys.stderr) # Final newline
120
+
121
+
122
+ def resolve_event_handlers(
123
+ event_handlers: Sequence[IndividualEventHandler | BuiltinEventHandlerType] | None,
124
+ ) -> list[IndividualEventHandler]:
125
+ """Resolve event handlers, converting builtin handler names to actual handlers."""
126
+ if not event_handlers:
127
+ return []
128
+ builtin_map = {"simple": simple_print_handler, "detailed": detailed_print_handler}
129
+ return [builtin_map[h] if isinstance(h, str) else h for h in event_handlers]