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,42 @@
1
+ """Utils for documentation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ast
6
+ from pathlib import Path
7
+ from typing import Literal
8
+
9
+ import mknodes as mk
10
+
11
+
12
+ DocStyle = Literal["simple", "full"]
13
+ EXAMPLES_DIR = Path("src/agentpool_docs/examples")
14
+
15
+ def create_example_doc(name: str, *, style: DocStyle = "full") -> mk.MkContainer:
16
+ """Create documentation for an example file.
17
+
18
+ Args:
19
+ name: Name of example file (e.g. "download_agents.py")
20
+ examples_dir: Directory containing examples (default: examples/)
21
+ style: Documentation style:
22
+ - simple: Just the code
23
+ - full: Title, description from docstring, code, etc.
24
+
25
+ Returns:
26
+ Container with all documentation elements
27
+ """
28
+ path = EXAMPLES_DIR / name
29
+ if not path.exists():
30
+ raise FileNotFoundError(f"Example {name} not found")
31
+
32
+ container = mk.MkContainer()
33
+ if style == "full":
34
+ # Extract title/description from example's docstring
35
+ title = path.stem.replace("_", " ").title()
36
+ container += mk.MkHeader(title, level=2)
37
+ # Add description from docstring if available
38
+ if docstring := ast.get_docstring(ast.parse(path.read_text(encoding="utf-8"))):
39
+ container += docstring
40
+ # Add the code itself
41
+ container += mk.MkCode(path.read_text(encoding="utf-8"), language="python")
42
+ return container
@@ -0,0 +1,370 @@
1
+ """Helper functions for running examples in different environments."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import types
7
+ from dataclasses import dataclass
8
+ from pathlib import Path
9
+ from typing import TYPE_CHECKING, Annotated, Any, Self, Union, get_args, get_origin
10
+
11
+
12
+ if TYPE_CHECKING:
13
+ from collections.abc import Awaitable, Iterator
14
+
15
+ from agentpool.resource_providers import ResourceProvider
16
+ from agentpool.tools.base import Tool
17
+
18
+
19
+ EXAMPLES_DIR = Path("src/agentpool_docs/examples")
20
+
21
+
22
+ def is_pyodide() -> bool:
23
+ """Check if code is running in a Pyodide environment."""
24
+ try:
25
+ from js import Object # type: ignore[import-not-found] # noqa: F401
26
+
27
+ return True # noqa: TRY300
28
+ except ImportError:
29
+ return False
30
+
31
+
32
+ def get_config_path(module_path: str | None = None, filename: str = "config.yml") -> Path:
33
+ """Get the configuration file path based on environment.
34
+
35
+ Args:
36
+ module_path: Optional __file__ from the calling module (ignored in Pyodide)
37
+ filename: Name of the config file (default: config.yml)
38
+
39
+ Returns:
40
+ Path to the configuration file
41
+ """
42
+ if is_pyodide():
43
+ return Path(filename)
44
+ if module_path is None:
45
+ raise ValueError("module_path is required in non-Pyodide environment")
46
+ return Path(module_path).parent / filename
47
+
48
+
49
+ def run[T](coro: Awaitable[T]) -> T:
50
+ """Run a coroutine in both normal Python and Pyodide environments."""
51
+ try:
52
+ # Check if we're in an event loop
53
+ asyncio.get_running_loop()
54
+ # If we are, run until complete
55
+ return asyncio.get_event_loop().run_until_complete(coro)
56
+ except RuntimeError:
57
+ # No running event loop, create one
58
+ return asyncio.run(coro) # type: ignore
59
+
60
+
61
+ @dataclass
62
+ class Example:
63
+ """Represents a AgentPool example with its metadata."""
64
+
65
+ name: str
66
+ path: Path
67
+ title: str
68
+ description: str
69
+ icon: str = "octicon:code-16"
70
+
71
+ @property
72
+ def files(self) -> list[Path]:
73
+ """Get all Python and YAML files (excluding __init__.py)."""
74
+ return [
75
+ f
76
+ for f in self.path.glob("**/*.*")
77
+ if f.suffix in {".py", ".yml"} and not f.name.startswith("__")
78
+ ]
79
+
80
+ @property
81
+ def docs(self) -> Path | None:
82
+ """Get docs.md file if it exists."""
83
+ docs = self.path / "docs.md"
84
+ return docs if docs.exists() else None
85
+
86
+ @classmethod
87
+ def from_directory(cls, path: Path) -> Self | None:
88
+ """Create Example from directory if it's a valid example."""
89
+ if not path.is_dir() or path.name.startswith("__"):
90
+ return None
91
+
92
+ init_file = path / "__init__.py"
93
+ if not init_file.exists():
94
+ return None
95
+
96
+ # Load the module to get variables
97
+ namespace: dict[str, str] = {}
98
+ with init_file.open() as f:
99
+ exec(f.read(), namespace)
100
+
101
+ # Get metadata with defaults
102
+ title = namespace.get("TITLE", path.name.replace("_", " ").title())
103
+ icon = namespace.get("ICON", "octicon:code-16")
104
+ description = namespace.get("__doc__", "")
105
+
106
+ return cls(
107
+ name=path.name,
108
+ path=path,
109
+ title=title,
110
+ description=description,
111
+ icon=icon,
112
+ )
113
+
114
+
115
+ def iter_examples(root: Path | str | None = None) -> Iterator[Example]:
116
+ """Iterate over all available examples.
117
+
118
+ Args:
119
+ root: Optional root directory (defaults to agentpool_docs/examples)
120
+ """
121
+ root = Path(root) if root else EXAMPLES_DIR
122
+
123
+ for path in sorted(root.iterdir()):
124
+ if example := Example.from_directory(path):
125
+ yield example
126
+
127
+
128
+ def get_example(name: str, root: Path | str | None = None) -> Example:
129
+ """Get a specific example by name."""
130
+ for example in iter_examples(root):
131
+ if example.name == name:
132
+ return example
133
+ raise KeyError(f"Example {name!r} not found")
134
+
135
+
136
+ def get_discriminator_values(union_type: Any) -> dict[str, type]:
137
+ """Extract discriminator values from a discriminated union.
138
+
139
+ Args:
140
+ union_type: A Union type (possibly wrapped in Annotated)
141
+
142
+ Returns:
143
+ Dict mapping discriminator values to their model classes
144
+ """
145
+ # Unwrap Annotated if present
146
+ origin = get_origin(union_type)
147
+ if origin is Annotated:
148
+ union_type = get_args(union_type)[0]
149
+ origin = get_origin(union_type)
150
+
151
+ # Verify it's a Union
152
+ if origin not in (Union, types.UnionType):
153
+ msg = f"Expected Union type, got: {union_type}"
154
+ raise TypeError(msg)
155
+
156
+ # Get all types in the union
157
+ union_args = get_args(union_type)
158
+
159
+ # Extract discriminator values from each model
160
+ result: dict[str, type] = {}
161
+ for model_cls in union_args:
162
+ if model_cls is type(None):
163
+ continue
164
+
165
+ # Get the 'type' field which serves as discriminator
166
+ if hasattr(model_cls, "model_fields") and "type" in model_cls.model_fields:
167
+ field = model_cls.model_fields["type"]
168
+ if field.default is not None:
169
+ result[field.default] = model_cls
170
+
171
+ return result
172
+
173
+
174
+ def discriminator_to_filename(discriminator: str) -> str:
175
+ """Convert discriminator value to expected doc filename.
176
+
177
+ Examples:
178
+ "file_access" -> "file-access"
179
+ "vfs" -> "vfs"
180
+ "agent_management" -> "agent-management"
181
+ """
182
+ return discriminator.replace("_", "-")
183
+
184
+
185
+ def check_docs_for_union(
186
+ union_type: Any,
187
+ docs_dir: Path | str,
188
+ *,
189
+ index_filename: str = "index",
190
+ ) -> tuple[dict[str, type], set[str]]:
191
+ """Check that all union members have corresponding doc files.
192
+
193
+ Args:
194
+ union_type: A discriminated Union type
195
+ docs_dir: Directory containing the doc files
196
+ index_filename: Filename to ignore (default: "index")
197
+
198
+ Returns:
199
+ Tuple of (missing_docs, extra_docs) where:
200
+ - missing_docs: Dict of discriminator -> model class for undocumented types
201
+ - extra_docs: Set of doc filenames without corresponding union member
202
+
203
+ Example:
204
+ ```python
205
+ from agentpool_config.toolsets import ToolsetConfig
206
+ missing, extra = check_docs_for_union(
207
+ ToolsetConfig,
208
+ Path("docs/configuration/toolsets"),
209
+ )
210
+ ```
211
+ """
212
+ docs_dir = Path(docs_dir)
213
+
214
+ # Get discriminator values from union
215
+ discriminators = get_discriminator_values(union_type)
216
+
217
+ # Get doc files (filename without .md, excluding index)
218
+ doc_files = {f.stem for f in docs_dir.glob("*.md") if f.stem != index_filename}
219
+
220
+ # Convert discriminators to expected filenames
221
+ expected_files = {discriminator_to_filename(d): d for d in discriminators}
222
+
223
+ # Find mismatches
224
+ missing_docs = {
225
+ orig_discriminator: discriminators[orig_discriminator]
226
+ for filename, orig_discriminator in expected_files.items()
227
+ if filename not in doc_files
228
+ }
229
+
230
+ extra_docs = doc_files - set(expected_files.keys())
231
+
232
+ return missing_docs, extra_docs
233
+
234
+
235
+ def _strip_docstring_sections(description: str) -> str:
236
+ """Strip Args/Returns/Raises sections from a docstring, keeping only the summary.
237
+
238
+ Args:
239
+ description: The full docstring
240
+
241
+ Returns:
242
+ Just the summary/description part without parameter documentation
243
+ """
244
+ lines = description.split("\n")
245
+ result = []
246
+ in_section = False
247
+
248
+ for line in lines:
249
+ stripped = line.strip()
250
+ # Check if we're entering a standard docstring section
251
+ if stripped in ("Args:", "Arguments:", "Returns:", "Raises:", "Yields:", "Note:"):
252
+ in_section = True
253
+ continue
254
+ # Check if we're in a section (indented content after section header)
255
+ if in_section:
256
+ # If line is empty or still indented, skip it
257
+ if not stripped or line.startswith(" ") or line.startswith("\t"):
258
+ continue
259
+ # Non-indented non-empty line means new content
260
+ in_section = False
261
+ result.append(line)
262
+
263
+ # Clean up trailing empty lines
264
+ while result and not result[-1].strip():
265
+ result.pop()
266
+
267
+ return "\n".join(result)
268
+
269
+
270
+ def tool_to_markdown(tool: Tool) -> str:
271
+ """Generate markdown documentation for a single tool.
272
+
273
+ Args:
274
+ tool: The tool to document
275
+
276
+ Returns:
277
+ Markdown formatted documentation string
278
+ """
279
+ lines = [f"### `{tool.name}`", ""]
280
+
281
+ if tool.description:
282
+ # Strip Args/Returns sections since we have a parameters table
283
+ desc = _strip_docstring_sections(tool.description)
284
+ if desc:
285
+ lines.append(desc)
286
+ lines.append("")
287
+
288
+ # Get parameters from schema
289
+ schema = tool.schema["function"]
290
+ params_schema = schema.get("parameters", {})
291
+ properties = params_schema.get("properties", {})
292
+ required = params_schema.get("required", [])
293
+
294
+ if properties:
295
+ lines.append("**Parameters:**")
296
+ lines.append("")
297
+ lines.append("| Name | Type | Required | Description |")
298
+ lines.append("|------|------|----------|-------------|")
299
+ for name, details in properties.items():
300
+ req = "✓" if name in required else ""
301
+ type_info = details.get("type", "-")
302
+ desc = details.get("description", "-")
303
+ # Escape pipe characters in description
304
+ desc = desc.replace("|", "\\|").replace("\n", " ")
305
+ lines.append(f"| `{name}` | {type_info} | {req} | {desc} |")
306
+ lines.append("")
307
+
308
+ # Add hints if any are set
309
+ hints = []
310
+ if tool.hints.read_only:
311
+ hints.append("read-only")
312
+ if tool.hints.destructive:
313
+ hints.append("destructive")
314
+ if tool.hints.idempotent:
315
+ hints.append("idempotent")
316
+ if tool.hints.open_world:
317
+ hints.append("open-world")
318
+
319
+ if hints:
320
+ lines.append(f"**Hints:** {', '.join(hints)}")
321
+ lines.append("")
322
+
323
+ if tool.category:
324
+ lines.append(f"**Category:** {tool.category}")
325
+ lines.append("")
326
+
327
+ return "\n".join(lines)
328
+
329
+
330
+ def generate_tool_docs(toolset: ResourceProvider) -> str:
331
+ """Generate markdown documentation for all tools in a toolset.
332
+
333
+ Args:
334
+ toolset: A ResourceProvider that provides tools
335
+
336
+ Returns:
337
+ Markdown formatted documentation for all tools
338
+
339
+ Example:
340
+ ```python exec="true"
341
+ from agentpool_toolsets.builtin.code import CodeTools
342
+ from agentpool.docs.utils import generate_tool_docs
343
+
344
+ toolset = CodeTools()
345
+ print(generate_tool_docs(toolset))
346
+ ```
347
+ """
348
+ # Get tools (handle async)
349
+ tools = run(toolset.get_tools())
350
+
351
+ if not tools:
352
+ return "*No tools available.*"
353
+
354
+ lines = [f"## {toolset.name.replace('_', ' ').title()} Tools", ""]
355
+
356
+ for tool in tools:
357
+ lines.append(tool_to_markdown(tool))
358
+
359
+ return "\n".join(lines)
360
+
361
+
362
+ if __name__ == "__main__":
363
+ # Example usage:
364
+ for ex in iter_examples():
365
+ print(f"\n{ex.title} ({ex.name})")
366
+ print(f"Icon: {ex.icon}")
367
+ print(f"Files: {len(ex.files)}")
368
+ if ex.docs:
369
+ print("Has docs.md")
370
+ print(f"Description: {ex.description.splitlines()[0]}")
@@ -0,0 +1,20 @@
1
+ """High-level functional interfaces for AgentPool."""
2
+
3
+ from agentpool.functional.run import (
4
+ run_agent,
5
+ run_agent_sync,
6
+ )
7
+ from agentpool.functional.structure import (
8
+ get_structured,
9
+ get_structured_multiple,
10
+ pick_one,
11
+ )
12
+
13
+ __all__ = [
14
+ "auto_callable",
15
+ "get_structured",
16
+ "get_structured_multiple",
17
+ "pick_one",
18
+ "run_agent",
19
+ "run_agent_sync",
20
+ ]
File without changes
@@ -0,0 +1,80 @@
1
+ """Functional wrappers for Agent usage."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any, Unpack, overload
6
+
7
+ from anyenv import run_sync
8
+ from pydantic_ai import ImageUrl
9
+
10
+ from agentpool import Agent
11
+
12
+
13
+ if TYPE_CHECKING:
14
+ from agentpool.agents.agent import AgentKwargs
15
+ from agentpool.common_types import PromptCompatible
16
+
17
+
18
+ @overload
19
+ async def run_agent[TResult](
20
+ prompt: PromptCompatible,
21
+ image_url: str | None = None,
22
+ *,
23
+ output_type: type[TResult],
24
+ **kwargs: Unpack[AgentKwargs],
25
+ ) -> TResult: ...
26
+
27
+
28
+ @overload
29
+ async def run_agent(
30
+ prompt: PromptCompatible,
31
+ image_url: str | None = None,
32
+ **kwargs: Unpack[AgentKwargs],
33
+ ) -> str: ...
34
+
35
+
36
+ async def run_agent(
37
+ prompt: PromptCompatible,
38
+ image_url: str | None = None,
39
+ *,
40
+ output_type: type[Any] | None = None,
41
+ **kwargs: Unpack[AgentKwargs],
42
+ ) -> Any:
43
+ """Run prompt through agent and return result."""
44
+ async with Agent[Any, str](**kwargs) as agent:
45
+ if image_url:
46
+ image = ImageUrl(url=image_url)
47
+ result = await agent.run(prompt, image, output_type=output_type)
48
+ else:
49
+ result = await agent.run(prompt, output_type=output_type)
50
+ return result.content
51
+
52
+
53
+ @overload
54
+ def run_agent_sync[TResult](
55
+ prompt: PromptCompatible,
56
+ image_url: str | None = None,
57
+ *,
58
+ output_type: type[TResult],
59
+ **kwargs: Unpack[AgentKwargs],
60
+ ) -> TResult: ...
61
+
62
+
63
+ @overload
64
+ def run_agent_sync(
65
+ prompt: PromptCompatible,
66
+ image_url: str | None = None,
67
+ **kwargs: Unpack[AgentKwargs],
68
+ ) -> str: ...
69
+
70
+
71
+ def run_agent_sync(
72
+ prompt: PromptCompatible,
73
+ image_url: str | None = None,
74
+ *,
75
+ output_type: type[Any] | None = None,
76
+ **kwargs: Unpack[AgentKwargs],
77
+ ) -> Any:
78
+ """Sync wrapper for run_agent."""
79
+ coro = run_agent(prompt, image_url, output_type=output_type, **kwargs) # type: ignore
80
+ return run_sync(coro)
@@ -0,0 +1,136 @@
1
+ """High-level pipeline functions for agent execution."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from enum import Enum
6
+ from typing import TYPE_CHECKING, Literal, get_args
7
+
8
+ from agentpool.agents.agent import Agent
9
+ from agentpool.log import get_logger
10
+
11
+
12
+ if TYPE_CHECKING:
13
+ from collections.abc import Callable
14
+
15
+ from agentpool.common_types import ModelType
16
+
17
+
18
+ logger = get_logger(__name__)
19
+
20
+
21
+ async def get_structured[T](
22
+ prompt: str,
23
+ response_type: type[T],
24
+ model: ModelType,
25
+ *,
26
+ system_prompt: str | None = None,
27
+ max_retries: int = 3,
28
+ error_handler: Callable[[Exception], T | None] | None = None,
29
+ ) -> T:
30
+ """Get structured output from LLM using function calling.
31
+
32
+ This function creates a temporary agent that uses the class constructor
33
+ as a tool to generate structured output. It handles:
34
+ - Type conversion from Python types to JSON schema
35
+ - Constructor parameter validation
36
+ - Error handling with optional recovery
37
+
38
+ Args:
39
+ prompt: The prompt to send to the LLM
40
+ response_type: The type to create (class with typed constructor)
41
+ model: model to use
42
+ system_prompt: Optional system instructions
43
+ max_retries: Max attempts for parsing (default: 3)
44
+ error_handler: Optional error handler for recovery
45
+
46
+ Returns:
47
+ Instance of response_type
48
+
49
+ Example:
50
+ ```python
51
+ class TaskResult:
52
+ '''Analysis result for a task.'''
53
+ def __init__(
54
+ self,
55
+ success: bool,
56
+ message: str,
57
+ due_date: datetime | None = None
58
+ ):
59
+ self.success = success
60
+ self.message = message
61
+ self.due_date = due_date
62
+
63
+ result = await get_structured(
64
+ "Analyze task: Deploy monitoring",
65
+ TaskResult,
66
+ system_prompt="You analyze task success"
67
+ )
68
+ print(f"Success: {result.success}")
69
+ ```
70
+
71
+ Raises:
72
+ TypeError: If response_type is not a valid type
73
+ ValueError: If constructor schema cannot be created
74
+ Exception: If LLM call fails and no error_handler recovers
75
+ """
76
+ """Get structured output from LLM using function calling."""
77
+ async with Agent(
78
+ model=model,
79
+ system_prompt=system_prompt or [],
80
+ name="structured",
81
+ retries=max_retries,
82
+ ) as agent:
83
+ try:
84
+ return await agent.talk.extract(prompt, response_type)
85
+ except Exception as e:
86
+ if error_handler and (err_result := error_handler(e)):
87
+ return err_result
88
+ raise
89
+
90
+
91
+ async def get_structured_multiple[T](
92
+ prompt: str,
93
+ target: type[T],
94
+ model: ModelType,
95
+ ) -> list[T]:
96
+ """Extract multiple structured instances from text."""
97
+ async with Agent(model=model, name="structured") as agent:
98
+ return await agent.talk.extract_multiple(prompt, target)
99
+
100
+
101
+ async def pick_one[T](
102
+ prompt: str,
103
+ options: type[T | Enum] | list[T],
104
+ model: ModelType,
105
+ ) -> T:
106
+ """Pick one option from a list of choices."""
107
+ instances: dict[str, T] = {}
108
+
109
+ # Create mapping and descriptions
110
+ if isinstance(options, type):
111
+ if issubclass(options, Enum):
112
+ choices = {e.name: (e.value, str(e.value)) for e in options}
113
+ else:
114
+ literal_opts = get_args(options)
115
+ choices = {str(opt): (opt, str(opt)) for opt in literal_opts}
116
+ else: # List
117
+ choices = {str(i): (opt, repr(opt)) for i, opt in enumerate(options)}
118
+
119
+ async def select_option(option: Literal[tuple(choices.keys())]) -> str: # type: ignore
120
+ """Pick one of the available options.
121
+
122
+ Args:
123
+ option: Which option to pick
124
+ """
125
+ instances["selected"] = choices[option][0]
126
+ return f"Selected: {option}"
127
+
128
+ # Add options to docstring
129
+ docs = "\n".join(f"- {k}: {desc}" for k, (_, desc) in choices.items())
130
+ assert select_option.__doc__
131
+ select_option.__doc__ += f"\nOptions:\n{docs}"
132
+ sys_prompt = "Select the most appropriate option based on the context."
133
+ async with Agent(model=model, system_prompt=sys_prompt) as agent:
134
+ agent.tools.register_tool(select_option, enabled=True)
135
+ await agent.run(prompt)
136
+ return instances["selected"]
@@ -0,0 +1,20 @@
1
+ """Runtime hook classes for agent lifecycle events."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from agentpool.hooks.agent_hooks import AgentHooks
6
+ from agentpool.hooks.base import Hook, HookEvent, HookInput, HookResult
7
+ from agentpool.hooks.callable import CallableHook
8
+ from agentpool.hooks.command import CommandHook
9
+ from agentpool.hooks.prompt import PromptHook
10
+
11
+ __all__ = [
12
+ "AgentHooks",
13
+ "CallableHook",
14
+ "CommandHook",
15
+ "Hook",
16
+ "HookEvent",
17
+ "HookInput",
18
+ "HookResult",
19
+ "PromptHook",
20
+ ]