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
agentpool/talk/talk.py ADDED
@@ -0,0 +1,604 @@
1
+ """Manages message flow between agents/groups."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections import defaultdict
6
+ from collections.abc import Callable, Sequence
7
+ from contextlib import asynccontextmanager
8
+ from dataclasses import dataclass, field, replace
9
+ from typing import TYPE_CHECKING, Any, Self, overload
10
+
11
+ from psygnal import Signal
12
+
13
+ from agentpool.log import get_logger
14
+ from agentpool.messaging import ChatMessage
15
+ from agentpool.talk.stats import AggregatedTalkStats, TalkStats
16
+ from agentpool.utils.inspection import execute
17
+ from agentpool.utils.now import get_now
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from collections.abc import AsyncIterator, Awaitable, Iterator
22
+ from datetime import datetime, timedelta
23
+
24
+ from evented.event_data import EventData
25
+
26
+ from agentpool.common_types import (
27
+ AnyFilterFn,
28
+ AnyTransformFn,
29
+ ProcessorCallback,
30
+ PromptCompatible,
31
+ QueueStrategy,
32
+ )
33
+ from agentpool.messaging import MessageNode
34
+ from agentpool.messaging.events import ConnectionEventData
35
+ from agentpool_config.events import ConnectionEventType
36
+ from agentpool_config.forward_targets import ConnectionType
37
+
38
+ logger = get_logger(__name__)
39
+
40
+
41
+ class Talk[TTransmittedData = Any]:
42
+ """Manages message flow between agents/groups."""
43
+
44
+ @dataclass(frozen=True)
45
+ class ConnectionProcessed:
46
+ """Event emitted when a message flows through a connection."""
47
+
48
+ message: ChatMessage[Any]
49
+ source: MessageNode[Any, Any]
50
+ targets: list[MessageNode[Any, Any]]
51
+ queued: bool
52
+ connection_type: ConnectionType
53
+ timestamp: datetime = field(default_factory=get_now)
54
+
55
+ # Original message "coming in"
56
+ message_received = Signal(ChatMessage)
57
+ # After any transformation (one for each message, not per target)
58
+ message_forwarded = Signal(ChatMessage)
59
+ # Comprehensive signal capturing all information about one "message handling process"
60
+ connection_processed = Signal(ConnectionProcessed)
61
+
62
+ def __init__(
63
+ self,
64
+ source: MessageNode[Any, Any],
65
+ targets: Sequence[MessageNode[Any, Any]],
66
+ group: TeamTalk | None = None,
67
+ *,
68
+ name: str | None = None,
69
+ connection_type: ConnectionType = "run",
70
+ wait_for_connections: bool = False,
71
+ priority: int = 0,
72
+ delay: timedelta | None = None,
73
+ queued: bool = False,
74
+ queue_strategy: QueueStrategy = "latest",
75
+ transform: AnyTransformFn[ChatMessage[TTransmittedData]] | None = None,
76
+ filter_condition: AnyFilterFn | None = None,
77
+ stop_condition: AnyFilterFn | None = None,
78
+ exit_condition: AnyFilterFn | None = None,
79
+ ) -> None:
80
+ """Initialize talk connection.
81
+
82
+ Args:
83
+ source: Agent sending messages
84
+ targets: Agents receiving messages
85
+ group: Optional group this talk belongs to
86
+ name: Optional name for this talk
87
+ connection_type: How to handle messages:
88
+ - "run": Execute message as a new run in target
89
+ - "context": Add message as context to target
90
+ - "forward": Forward message to target's outbox
91
+ wait_for_connections: Whether to wait for all targets to complete
92
+ priority: Task priority (lower = higher priority)
93
+ delay: Optional delay before processing
94
+ queued: Whether messages should be queued for manual processing
95
+ queue_strategy: How to process queued messages:
96
+ - "concat": Combine all messages with newlines
97
+ - "latest": Use only the most recent message
98
+ - "buffer": Process all messages individually
99
+ transform: Optional function to transform messages
100
+ filter_condition: Optional condition for filtering messages
101
+ stop_condition: Optional condition for disconnecting
102
+ exit_condition: Optional condition for stopping the event loop
103
+ """
104
+ self.source = source
105
+ self.targets = list(targets)
106
+ # Could perhaps better be an auto-inferring property
107
+ self.name = name or f"{source.name}->{[t.name for t in targets]}"
108
+ self.group = group
109
+ self.priority = priority
110
+ self.delay = delay
111
+ self.active = True
112
+ self.connection_type: ConnectionType = connection_type
113
+ self.wait_for_connections = wait_for_connections
114
+ self.queued = queued
115
+ self.queue_strategy = queue_strategy
116
+ self._pending_messages = defaultdict[str, list[ChatMessage[TTransmittedData]]](list)
117
+ names = {t.name for t in targets}
118
+ self._stats = TalkStats(source_name=source.name, target_names=names)
119
+ self.transform_fn = transform
120
+ self.filter_condition = filter_condition
121
+ self.stop_condition = stop_condition
122
+ self.exit_condition = exit_condition
123
+
124
+ def __repr__(self) -> str:
125
+ targets = [t.name for t in self.targets]
126
+ return f"<Talk({self.connection_type}) {self.source.name} -> {targets}>"
127
+
128
+ @overload
129
+ def __rshift__(
130
+ self,
131
+ other: MessageNode[Any, str]
132
+ | ProcessorCallback[str]
133
+ | Sequence[MessageNode[Any, str] | ProcessorCallback[str]],
134
+ ) -> TeamTalk[str]: ...
135
+
136
+ @overload
137
+ def __rshift__(
138
+ self,
139
+ other: MessageNode[Any, Any]
140
+ | ProcessorCallback[Any]
141
+ | Sequence[MessageNode[Any, Any] | ProcessorCallback[Any]],
142
+ ) -> TeamTalk[Any]: ...
143
+
144
+ def __rshift__(
145
+ self,
146
+ other: MessageNode[Any, Any]
147
+ | ProcessorCallback[Any]
148
+ | Sequence[MessageNode[Any, Any] | ProcessorCallback[Any]],
149
+ ) -> TeamTalk[Any]:
150
+ """Add another node as target to the connection or group.
151
+
152
+ Example:
153
+ connection >> other_agent # Connect to single agent
154
+ connection >> (agent2 & agent3) # Connect to group
155
+ """
156
+ from agentpool import Agent, MessageNode
157
+ from agentpool.talk import TeamTalk
158
+
159
+ match other:
160
+ case Callable():
161
+ other = Agent.from_callback(other)
162
+ if pool := self.source.agent_pool:
163
+ other.agent_pool = pool
164
+ pool.register(other.name, other)
165
+ return self.__rshift__(other)
166
+ case Sequence():
167
+ team_talks = [self.__rshift__(o) for o in other]
168
+ return TeamTalk([self, *team_talks])
169
+ case MessageNode():
170
+ talks = [t.__rshift__(other) for t in self.targets]
171
+ return TeamTalk([self, *talks])
172
+ case _:
173
+ msg = f"Invalid agent type: {type(other)}"
174
+ raise TypeError(msg)
175
+
176
+ async def _evaluate_condition(
177
+ self,
178
+ condition: Callable[..., bool | Awaitable[bool]] | None,
179
+ message: ChatMessage[Any],
180
+ target: MessageNode[Any, Any],
181
+ *,
182
+ default_return: bool = False,
183
+ ) -> bool:
184
+ """Evaluate a condition with flexible parameter handling."""
185
+ from agentpool.talk.registry import EventContext
186
+
187
+ if not condition:
188
+ return default_return
189
+ registry = pool.connection_registry if (pool := self.source.agent_pool) else None
190
+ ctx = EventContext(
191
+ message=message,
192
+ target=target,
193
+ stats=self.stats,
194
+ registry=registry,
195
+ talk=self,
196
+ )
197
+ return await execute(condition, ctx)
198
+
199
+ def on_event(
200
+ self,
201
+ event_type: ConnectionEventType,
202
+ callback: Callable[[ConnectionEventData[TTransmittedData]], None | Awaitable[None]],
203
+ ) -> Self:
204
+ """Register callback for connection events."""
205
+ from agentpool.messaging.events import ConnectionEventData
206
+
207
+ async def wrapped_callback(event: EventData) -> None:
208
+ if isinstance(event, ConnectionEventData) and event.event_type == event_type:
209
+ await execute(callback, event)
210
+
211
+ self.source._events.add_callback(wrapped_callback)
212
+ return self
213
+
214
+ async def _emit_connection_event(
215
+ self,
216
+ event_type: ConnectionEventType,
217
+ message: ChatMessage[TTransmittedData] | None,
218
+ ) -> None:
219
+ from agentpool.messaging.events import ConnectionEventData
220
+
221
+ event = ConnectionEventData[Any](
222
+ connection=self,
223
+ source="connection",
224
+ connection_name=self.name,
225
+ event_type=event_type,
226
+ message=message,
227
+ timestamp=get_now(),
228
+ )
229
+ # Propagate to all event managers through registry
230
+ if pool := self.source.agent_pool:
231
+ for connection in pool.connection_registry.values():
232
+ await connection.source._events.emit_event(event)
233
+
234
+ async def _handle_message(
235
+ self,
236
+ message: ChatMessage[TTransmittedData],
237
+ prompt: str | None = None,
238
+ ) -> list[ChatMessage[Any]]:
239
+ """Handle message forwarding based on connection configuration."""
240
+ # 2. Early exit checks
241
+ if not (self.active and (not self.group or self.group.active)):
242
+ return []
243
+
244
+ # 3. Check exit condition for any target
245
+ for target in self.targets:
246
+ # Exit if condition returns True
247
+ if await self._evaluate_condition(self.exit_condition, message, target):
248
+ raise SystemExit
249
+
250
+ # 4. Check stop condition for any target
251
+ for target in self.targets:
252
+ # Stop if condition returns True
253
+ if await self._evaluate_condition(self.stop_condition, message, target):
254
+ self.disconnect()
255
+ return []
256
+
257
+ # 5. Transform if configured
258
+ processed_message = message
259
+ if self.transform_fn:
260
+ processed_message = await execute(self.transform_fn, message)
261
+ # 6. First pass: Determine target list
262
+ target_list: list[MessageNode[Any, Any]] = [
263
+ target
264
+ for target in self.targets
265
+ if await self._evaluate_condition(
266
+ self.filter_condition,
267
+ processed_message,
268
+ target,
269
+ default_return=True,
270
+ )
271
+ ]
272
+ # 7. emit connection processed event
273
+ self.connection_processed.emit(
274
+ self.ConnectionProcessed(
275
+ message=processed_message,
276
+ source=self.source,
277
+ targets=target_list,
278
+ queued=self.queued,
279
+ connection_type=self.connection_type, # pyright: ignore
280
+ )
281
+ )
282
+ # 8. if we have targets, update stats and emit message forwarded
283
+ if target_list:
284
+ messages = [*self._stats.messages, processed_message]
285
+ self._stats = replace(self._stats, messages=messages)
286
+ self.message_forwarded.emit(processed_message)
287
+
288
+ # 9. Second pass: Actually process for each target
289
+ responses: list[ChatMessage[Any]] = []
290
+ for target in target_list:
291
+ if self.queued:
292
+ self._pending_messages[target.name].append(processed_message)
293
+ continue
294
+ if response := await self._process_for_target(processed_message, target, prompt):
295
+ responses.append(response)
296
+
297
+ return responses
298
+
299
+ async def _process_for_target(
300
+ self,
301
+ message: ChatMessage[Any],
302
+ target: MessageNode[Any, Any],
303
+ prompt: PromptCompatible | None = None,
304
+ ) -> ChatMessage[Any] | None:
305
+ """Process message for a single target."""
306
+ from agentpool.agents import Agent
307
+ from agentpool.delegation.base_team import BaseTeam
308
+
309
+ match self.connection_type:
310
+ case "run":
311
+ prompts: list[PromptCompatible] = [message]
312
+ if prompt:
313
+ prompts.append(prompt)
314
+ return await target.run(*prompts)
315
+
316
+ case "context":
317
+ meta = {
318
+ "type": "forwarded_message",
319
+ "role": message.role,
320
+ "model": message.model_name,
321
+ "cost_info": message.cost_info,
322
+ "timestamp": message.timestamp.isoformat(),
323
+ "prompt": prompt,
324
+ }
325
+
326
+ async def add_context() -> None:
327
+ match target:
328
+ case BaseTeam():
329
+ # Use distribute for teams
330
+ await target.distribute(str(message.content), metadata=meta)
331
+ case Agent(): # Agent case
332
+ # Use existing context message approach
333
+ target.conversation.add_context_message(
334
+ str(message.content),
335
+ source=message.name,
336
+ metadata=meta,
337
+ )
338
+
339
+ if self.delay is not None or self.priority != 0:
340
+ coro = add_context()
341
+ target.task_manager.run_background(
342
+ coro, priority=self.priority, delay=self.delay
343
+ )
344
+ else:
345
+ await add_context()
346
+ return None
347
+
348
+ case "forward":
349
+ if self.delay is not None or self.priority != 0:
350
+
351
+ async def delayed_emit() -> None:
352
+ await target.connections.route_message(message)
353
+
354
+ coro = delayed_emit()
355
+ target.task_manager.run_background(
356
+ coro, priority=self.priority, delay=self.delay
357
+ )
358
+ else:
359
+ await target.connections.route_message(message)
360
+ return None
361
+
362
+ async def trigger(
363
+ self, prompt: PromptCompatible | None = None
364
+ ) -> list[ChatMessage[TTransmittedData]]:
365
+ """Process queued messages."""
366
+ if not self._pending_messages:
367
+ return []
368
+ match self.queue_strategy:
369
+ case "buffer":
370
+ results: list[ChatMessage[TTransmittedData]] = []
371
+ # Process each agent's queue
372
+ for target in self.targets:
373
+ queue = self._pending_messages[target.name]
374
+ for msg in queue:
375
+ if resp := await self._process_for_target(msg, target, prompt):
376
+ results.append(resp) # noqa: PERF401
377
+ queue.clear()
378
+ return results
379
+
380
+ case "latest":
381
+ results = []
382
+ # Get latest message for each agent
383
+ for target in self.targets:
384
+ queue = self._pending_messages[target.name]
385
+ if queue:
386
+ latest = queue[-1]
387
+ if resp := await self._process_for_target(latest, target, prompt):
388
+ results.append(resp)
389
+ queue.clear()
390
+ return results
391
+
392
+ case "concat":
393
+ results = []
394
+ # Concat messages per agent
395
+ for target in self.targets:
396
+ queue = self._pending_messages[target.name]
397
+ if not queue:
398
+ continue
399
+
400
+ base = queue[-1]
401
+ contents = [str(m.content) for m in queue]
402
+ meta = {
403
+ **base.metadata,
404
+ "merged_count": len(queue),
405
+ "queue_strategy": self.queue_strategy,
406
+ }
407
+ content = "\n\n".join(contents)
408
+ merged = replace(base, content=content, metadata=meta) # type: ignore
409
+
410
+ if response := await self._process_for_target(merged, target, prompt):
411
+ results.append(response)
412
+ queue.clear()
413
+
414
+ return results
415
+ case _:
416
+ msg = f"Invalid queue strategy: {self.queue_strategy}"
417
+ raise ValueError(msg)
418
+
419
+ def when(self, condition: AnyFilterFn) -> Self:
420
+ """Add condition for message forwarding."""
421
+ self.filter_condition = condition
422
+ return self
423
+
424
+ def transform[TNewData](
425
+ self,
426
+ transformer: Callable[
427
+ [ChatMessage[TTransmittedData]],
428
+ ChatMessage[TNewData] | Awaitable[ChatMessage[TNewData]],
429
+ ],
430
+ *,
431
+ name: str | None = None,
432
+ description: str | None = None,
433
+ ) -> Talk[TNewData]:
434
+ """Chain a new transformation after existing ones.
435
+
436
+ Args:
437
+ transformer: Function to transform messages
438
+ name: Optional name for debugging
439
+ description: Optional description
440
+
441
+ Returns:
442
+ New Talk instance with chained transformation
443
+
444
+ Example:
445
+ ```python
446
+ talk = (agent1 >> agent2)
447
+ .transform(parse_json) # str -> dict
448
+ .transform(extract_values) # dict -> list
449
+ ```
450
+ """
451
+ new_talk = Talk[TNewData](
452
+ source=self.source,
453
+ targets=self.targets,
454
+ connection_type=self.connection_type,
455
+ )
456
+
457
+ if self.transform_fn is not None:
458
+ oldtransform_fn = self.transform_fn
459
+
460
+ async def chainedtransform_fn(
461
+ data: ChatMessage[TTransmittedData],
462
+ ) -> ChatMessage[TNewData]:
463
+ intermediate = await execute(oldtransform_fn, data)
464
+ return await execute(transformer, intermediate)
465
+
466
+ new_talk.transform_fn = chainedtransform_fn # type: ignore
467
+ else:
468
+ new_talk.transform_fn = transformer # type: ignore
469
+
470
+ return new_talk
471
+
472
+ @asynccontextmanager
473
+ async def paused(self) -> AsyncIterator[Self]:
474
+ """Temporarily set inactive."""
475
+ previous = self.active
476
+ self.active = False
477
+ try:
478
+ yield self
479
+ finally:
480
+ self.active = previous
481
+
482
+ def disconnect(self) -> None:
483
+ """Permanently disconnect the connection."""
484
+ self.active = False
485
+
486
+ @property
487
+ def stats(self) -> TalkStats:
488
+ """Get current connection statistics."""
489
+ return self._stats
490
+
491
+
492
+ class TeamTalk[TTransmittedData = Any](list["Talk | TeamTalk"]):
493
+ """Group of connections with aggregate operations."""
494
+
495
+ def __init__(
496
+ self, talks: Sequence[Talk[TTransmittedData] | TeamTalk[TTransmittedData]]
497
+ ) -> None:
498
+ super().__init__(talks)
499
+ self.filter_condition: AnyFilterFn | None = None
500
+ self.active = True
501
+
502
+ def __repr__(self) -> str:
503
+ return f"TeamTalk({list(self)})"
504
+
505
+ def __rshift__(
506
+ self,
507
+ other: MessageNode[Any, Any]
508
+ | ProcessorCallback[Any]
509
+ | Sequence[MessageNode[Any, Any] | ProcessorCallback[Any]],
510
+ ) -> TeamTalk[Any]:
511
+ """Add another node as target to the connection or group.
512
+
513
+ Example:
514
+ connection >> other_agent # Connect to single agent
515
+ connection >> (agent2 & agent3) # Connect to group
516
+ """
517
+ from agentpool import Agent, MessageNode
518
+ from agentpool.talk import TeamTalk
519
+
520
+ match other:
521
+ case Callable():
522
+ other = Agent.from_callback(other)
523
+ for talk_ in self.iter_talks():
524
+ if pool := talk_.source.agent_pool:
525
+ other.agent_pool = pool
526
+ pool.register(other.name, other)
527
+ break
528
+ return self.__rshift__(other)
529
+ case Sequence():
530
+ team_talks = [self.__rshift__(o) for o in other]
531
+ return TeamTalk([self, *team_talks])
532
+ case MessageNode():
533
+ talks = [t.connect_to(other) for t in self.targets]
534
+ return TeamTalk([self, *talks])
535
+ case _:
536
+ msg = f"Invalid agent type: {type(other)}"
537
+ raise TypeError(msg)
538
+
539
+ @property
540
+ def targets(self) -> list[MessageNode[Any, Any]]:
541
+ """Get all targets from all connections."""
542
+ return [t for talk in self for t in talk.targets]
543
+
544
+ def iter_talks(self) -> Iterator[Talk]:
545
+ """Get all contained talks."""
546
+ for t in self:
547
+ match t:
548
+ case Talk():
549
+ yield t
550
+ case TeamTalk():
551
+ yield from t.iter_talks()
552
+
553
+ async def _handle_message(self, message: ChatMessage[Any], prompt: str | None = None) -> None:
554
+ for talk in self:
555
+ await talk._handle_message(message, prompt)
556
+
557
+ async def trigger(self, prompt: PromptCompatible | None = None) -> list[ChatMessage[Any]]:
558
+ messages = []
559
+ for talk in self:
560
+ messages.extend(await talk.trigger(prompt))
561
+ return messages
562
+
563
+ @classmethod
564
+ def from_nodes(
565
+ cls,
566
+ agents: Sequence[MessageNode[Any, Any]],
567
+ targets: list[MessageNode[Any, Any]] | None = None,
568
+ ) -> Self:
569
+ """Create TeamTalk from a collection of agents."""
570
+ return cls([Talk(agent, targets or []) for agent in agents])
571
+
572
+ @asynccontextmanager
573
+ async def paused(self) -> AsyncIterator[Self]:
574
+ """Temporarily set inactive."""
575
+ previous = self.active
576
+ self.active = False
577
+ try:
578
+ yield self
579
+ finally:
580
+ self.active = previous
581
+
582
+ def has_active_talks(self) -> bool:
583
+ """Check if any contained talks are active."""
584
+ return any(talk.active for talk in self)
585
+
586
+ def get_active_talks(self) -> list[Talk | TeamTalk]:
587
+ """Get list of currently active talks."""
588
+ return [talk for talk in self if talk.active]
589
+
590
+ @property
591
+ def stats(self) -> AggregatedTalkStats:
592
+ """Get aggregated statistics for all connections."""
593
+ return AggregatedTalkStats(stats=[talk.stats for talk in self])
594
+
595
+ def when(self, condition: AnyFilterFn) -> Self:
596
+ """Add condition to all connections in group."""
597
+ for talk in self:
598
+ talk.when(condition)
599
+ return self
600
+
601
+ def disconnect(self) -> None:
602
+ """Disconnect all connections in group."""
603
+ for talk in self:
604
+ talk.disconnect()
@@ -0,0 +1,20 @@
1
+ """Task management."""
2
+
3
+ from agentpool.tasks.exceptions import (
4
+ JobError,
5
+ ToolSkippedError,
6
+ RunAbortedError,
7
+ ChainAbortedError,
8
+ JobRegistrationError,
9
+ )
10
+
11
+ from agentpool.tasks.registry import TaskRegistry
12
+
13
+ __all__ = [
14
+ "ChainAbortedError",
15
+ "JobError",
16
+ "JobRegistrationError",
17
+ "RunAbortedError",
18
+ "TaskRegistry",
19
+ "ToolSkippedError",
20
+ ]
@@ -0,0 +1,25 @@
1
+ """Task-related exceptions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from agentpool.utils.baseregistry import AgentPoolError
6
+
7
+
8
+ class JobError(AgentPoolError):
9
+ """General task-related exception."""
10
+
11
+
12
+ class ToolSkippedError(JobError):
13
+ """Tool execution was skipped by user."""
14
+
15
+
16
+ class RunAbortedError(JobError):
17
+ """Run was aborted by user."""
18
+
19
+
20
+ class ChainAbortedError(JobError):
21
+ """Agent chain was aborted by user."""
22
+
23
+
24
+ class JobRegistrationError(JobError):
25
+ """Task could not get registered."""
@@ -0,0 +1,33 @@
1
+ """Task definition and registry for agents."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from agentpool.tasks.exceptions import JobRegistrationError
8
+ from agentpool.utils.baseregistry import BaseRegistry
9
+ from agentpool_config.task import Job
10
+
11
+
12
+ class TaskRegistry(BaseRegistry[str, Job[Any, Any]]):
13
+ """Registry for managing tasks."""
14
+
15
+ @property
16
+ def _error_class(self) -> type[JobRegistrationError]:
17
+ return JobRegistrationError
18
+
19
+ def _validate_item(self, item: Any) -> Job[Any, Any]:
20
+ from agentpool_config.task import Job
21
+
22
+ if not isinstance(item, Job):
23
+ msg = f"Expected Job, got {type(item)}"
24
+ raise self._error_class(msg)
25
+ return item
26
+
27
+ def register(self, name: str, task: Job[Any, Any], replace: bool = False) -> None:
28
+ """Register a task with name.
29
+
30
+ Creates a copy of the task with the name set.
31
+ """
32
+ task_copy = task.model_copy(update={"name": name})
33
+ super().register(name, task_copy, replace)