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,443 @@
1
+ """A streaming fuzzy matcher.
2
+
3
+ It that can process text chunks incrementally
4
+ and return the best match found so far at each step.
5
+
6
+ This is a Python port of Zed's streaming fuzzy matcher, designed for
7
+ real-time code editing and location resolution.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from dataclasses import dataclass, field
13
+ from typing import Literal
14
+
15
+
16
+ REPLACEMENT_COST = 1
17
+ INSERTION_COST = 3
18
+ DELETION_COST = 10
19
+
20
+ LINE_HINT_TOLERANCE = 200
21
+ THRESHOLD = 0.8
22
+ SearchDirection = Literal["up", "left", "diagonal"]
23
+
24
+
25
+ @dataclass(frozen=True, slots=True)
26
+ class Range:
27
+ """Represents a text range with start and end byte offsets."""
28
+
29
+ start: int
30
+ end: int
31
+
32
+
33
+ @dataclass(slots=True)
34
+ class SearchState:
35
+ """State for a cell in the dynamic programming matrix."""
36
+
37
+ cost: int
38
+ direction: SearchDirection
39
+
40
+ def __post_init__(self) -> None:
41
+ self.cost = max(self.cost, 0)
42
+
43
+
44
+ @dataclass
45
+ class SearchMatrix:
46
+ """Dynamic programming matrix for edit distance computation."""
47
+
48
+ cols: int
49
+ rows: int = 0
50
+ data: list[SearchState] = field(default_factory=list)
51
+
52
+ def resize_rows(self, new_rows: int) -> None:
53
+ """Resize matrix to accommodate more query lines."""
54
+ if new_rows <= self.rows:
55
+ return
56
+
57
+ old_size = self.rows * self.cols
58
+ new_size = new_rows * self.cols
59
+ self.data.extend([SearchState(0, "diagonal") for _ in range(new_size - old_size)])
60
+ self.rows = new_rows
61
+
62
+ def get(self, row: int, col: int) -> SearchState:
63
+ """Get state at matrix position."""
64
+ if row >= self.rows or col >= self.cols or row < 0 or col < 0:
65
+ return SearchState(999999, "diagonal")
66
+ return self.data[row * self.cols + col]
67
+
68
+ def set(self, row: int, col: int, state: SearchState) -> None:
69
+ """Set state at matrix position."""
70
+ if row < self.rows and col < self.cols and row >= 0 and col >= 0:
71
+ self.data[row * self.cols + col] = state
72
+
73
+
74
+ class StreamingFuzzyMatcher:
75
+ """A streaming fuzzy matcher that processes text chunks incrementally.
76
+
77
+ This matcher accumulates text chunks and performs fuzzy matching against
78
+ a source buffer, returning the best matches found so far.
79
+ """
80
+
81
+ def __init__(self, source_text: str) -> None:
82
+ """Initialize matcher with source text to search against.
83
+
84
+ Args:
85
+ source_text: The text buffer to search within
86
+ """
87
+ self.source_lines: list[str] = source_text.splitlines()
88
+ self.query_lines: list[str] = []
89
+ self.line_hint: int | None = None
90
+ self.incomplete_line: str = ""
91
+ self.matches: list[Range] = []
92
+
93
+ # Initialize matrix with buffer line count + 1
94
+ buffer_line_count = len(self.source_lines)
95
+ self.matrix: SearchMatrix = SearchMatrix(buffer_line_count + 1)
96
+
97
+ @property
98
+ def query_lines_list(self) -> list[str]:
99
+ """Returns the accumulated query lines."""
100
+ return self.query_lines.copy()
101
+
102
+ def push(self, chunk: str, line_hint: int | None = None) -> Range | None:
103
+ """Push a new chunk of text and get the best match found so far.
104
+
105
+ This method accumulates text chunks and processes complete lines.
106
+ Partial lines are buffered internally until a newline is received.
107
+
108
+ Args:
109
+ chunk: Text chunk to add to the query
110
+ line_hint: Optional line number hint for match selection
111
+
112
+ Returns:
113
+ Range if a match has been found, None otherwise
114
+ """
115
+ if line_hint is not None:
116
+ self.line_hint = line_hint
117
+
118
+ # Add chunk to incomplete line buffer
119
+ self.incomplete_line += chunk
120
+
121
+ # Process complete lines (everything up to the last newline)
122
+ if "\n" in self.incomplete_line:
123
+ # Find last newline position
124
+ last_newline = self.incomplete_line.rfind("\n")
125
+ complete_part = self.incomplete_line[: last_newline + 1]
126
+
127
+ # Split into lines and add to query_lines
128
+ new_lines = complete_part.splitlines()
129
+ self.query_lines.extend(new_lines)
130
+
131
+ # Keep remaining incomplete part
132
+ self.incomplete_line = self.incomplete_line[last_newline + 1 :]
133
+
134
+ # Update matches with new query lines
135
+ self.matches = self._resolve_location_fuzzy()
136
+
137
+ # Return best match
138
+ best_match = self.select_best_match()
139
+ return best_match or (self.matches[0] if self.matches else None)
140
+
141
+ def finish(self) -> list[Range]:
142
+ """Finish processing and return all final matches.
143
+
144
+ This processes any remaining incomplete line before returning
145
+ the final match results.
146
+
147
+ Returns:
148
+ List of all found matches
149
+ """
150
+ # Process any remaining incomplete line
151
+ if self.incomplete_line.strip():
152
+ self.query_lines.append(self.incomplete_line)
153
+ self.incomplete_line = ""
154
+ self.matches = self._resolve_location_fuzzy()
155
+
156
+ return self.matches.copy()
157
+
158
+ def select_best_match(self) -> Range | None:
159
+ """Return the best match considering line hints.
160
+
161
+ Returns:
162
+ Best match range, or None if no suitable match found
163
+ """
164
+ if not self.matches:
165
+ return None
166
+
167
+ if len(self.matches) == 1:
168
+ return self.matches[0]
169
+
170
+ if self.line_hint is None:
171
+ # Multiple ambiguous matches without hint
172
+ return None
173
+
174
+ best_match = None
175
+ best_distance = float("inf")
176
+
177
+ for match_range in self.matches:
178
+ # Convert byte offset to approximate line number
179
+ start_line = self._offset_to_line(match_range.start)
180
+ distance = abs(start_line - self.line_hint)
181
+
182
+ if distance <= LINE_HINT_TOLERANCE and distance < best_distance:
183
+ best_distance = distance
184
+ best_match = match_range
185
+
186
+ return best_match
187
+
188
+ def _resolve_location_fuzzy(self) -> list[Range]:
189
+ """Perform fuzzy matching using dynamic programming.
190
+
191
+ Returns:
192
+ List of match ranges found in the source text
193
+ """
194
+ new_query_line_count = len(self.query_lines)
195
+ old_query_line_count = max(0, self.matrix.rows - 1)
196
+
197
+ if new_query_line_count == old_query_line_count:
198
+ return []
199
+
200
+ self.matrix.resize_rows(new_query_line_count + 1)
201
+
202
+ # Process only the new query lines
203
+ for row in range(old_query_line_count, new_query_line_count):
204
+ query_line = self.query_lines[row].strip()
205
+ leading_deletion_cost = (row + 1) * DELETION_COST
206
+
207
+ # Initialize first column
208
+ self.matrix.set(row + 1, 0, SearchState(leading_deletion_cost, "up"))
209
+
210
+ # Process each source line
211
+ for col, source_line in enumerate(self.source_lines):
212
+ line = source_line.strip()
213
+
214
+ # Calculate costs for each direction
215
+ up_cost = self.matrix.get(row, col + 1).cost + DELETION_COST
216
+ left_cost = self.matrix.get(row + 1, col).cost + INSERTION_COST
217
+
218
+ # Diagonal cost depends on character match
219
+ diagonal_cost = self.matrix.get(row, col).cost
220
+ if not _fuzzy_eq(query_line, line):
221
+ diagonal_cost += REPLACEMENT_COST
222
+
223
+ # Choose minimum cost direction
224
+ if diagonal_cost <= up_cost and diagonal_cost <= left_cost:
225
+ best_state = SearchState(diagonal_cost, "diagonal")
226
+ elif up_cost <= left_cost:
227
+ best_state = SearchState(up_cost, "up")
228
+ else:
229
+ best_state = SearchState(left_cost, "left")
230
+
231
+ self.matrix.set(row + 1, col + 1, best_state)
232
+
233
+ # Extract matches by backtracking through matrix
234
+ return self._extract_matches()
235
+
236
+ def _extract_matches(self) -> list[Range]:
237
+ """Extract match ranges by backtracking through the DP matrix."""
238
+ if not self.query_lines:
239
+ return []
240
+
241
+ query_len = len(self.query_lines)
242
+
243
+ # Find all reasonable endpoints and score them
244
+ min_cost = float("inf")
245
+
246
+ for col in range(len(self.source_lines) + 1):
247
+ state = self.matrix.get(query_len, col)
248
+ min_cost = min(min_cost, state.cost)
249
+
250
+ # Accept costs within reasonable range of minimum
251
+ max_acceptable_cost = min(min_cost * 2, query_len * REPLACEMENT_COST * 4)
252
+
253
+ candidates: list[tuple[float, Range]] = []
254
+ for col in range(len(self.source_lines) + 1):
255
+ state = self.matrix.get(query_len, col)
256
+ if state.cost <= max_acceptable_cost:
257
+ match_range = self._backtrack_match(query_len, col)
258
+ if match_range:
259
+ # Score based on cost and match quality
260
+ quality_score = self._calculate_match_quality(match_range)
261
+ candidates.append((
262
+ float(state.cost) - quality_score * 10,
263
+ match_range,
264
+ ))
265
+
266
+ # Sort by score and return best matches
267
+ candidates.sort(key=lambda x: x[0])
268
+ return [match for _, match in candidates[:5]] # Limit to top 5 matches
269
+
270
+ def _backtrack_match(self, end_row: int, end_col: int) -> Range | None:
271
+ """Backtrack through matrix to find match boundaries."""
272
+ if end_row == 0 or end_col == 0:
273
+ return None
274
+
275
+ # Track which source lines were matched
276
+ matched_lines: set[int] = set()
277
+ row, col = end_row, end_col
278
+
279
+ # Backtrack to collect matched source lines
280
+ while row > 0 and col > 0:
281
+ state = self.matrix.get(row, col)
282
+ if state.direction == "diagonal":
283
+ # represents a match between query line (row-1) and source line (col-1)
284
+ matched_lines.add(col - 1)
285
+ row -= 1
286
+ col -= 1
287
+ elif state.direction == "up":
288
+ row -= 1
289
+ else: # LEFT
290
+ col -= 1
291
+
292
+ if not matched_lines:
293
+ return None
294
+
295
+ # Find contiguous range of matched lines
296
+ matched_list = sorted(matched_lines)
297
+ start_line: int = matched_list[0]
298
+ end_line: int = matched_list[-1]
299
+
300
+ # Extend range to include some context for better matches
301
+ context_lines = min(2, len(self.query_lines))
302
+ start_line = max(0, start_line - context_lines // 2)
303
+ end_line = min(len(self.source_lines) - 1, end_line + context_lines // 2)
304
+
305
+ start_offset = self._line_to_offset(start_line)
306
+ end_offset = self._line_to_offset(end_line + 1)
307
+
308
+ return Range(start_offset, end_offset)
309
+
310
+ def _calculate_match_quality(self, match_range: Range) -> float:
311
+ """Calculate quality score for a match (higher is better)."""
312
+ if not self.query_lines:
313
+ return 0.0
314
+
315
+ source_text = "\n".join(self.source_lines)
316
+ matched_text = source_text[match_range.start : match_range.end]
317
+ matched_lines = matched_text.split("\n")
318
+
319
+ score = 0.0
320
+ query_words: set[str] = set()
321
+ for line in self.query_lines:
322
+ query_words.update(line.strip().split())
323
+
324
+ # Score based on word overlap
325
+ for line in matched_lines:
326
+ line_words = set(line.strip().split())
327
+ overlap = len(query_words & line_words)
328
+ if len(query_words) > 0:
329
+ score += overlap / len(query_words)
330
+
331
+ # Bonus for exact line matches
332
+ for query_line in self.query_lines:
333
+ normalized_query = " ".join(query_line.strip().split())
334
+ for matched_line in matched_lines:
335
+ normalized_matched = " ".join(matched_line.strip().split())
336
+ if normalized_query == normalized_matched:
337
+ score += 2.0
338
+
339
+ return score
340
+
341
+ def _line_to_offset(self, line_num: int) -> int:
342
+ """Convert line number to byte offset."""
343
+ if line_num <= 0:
344
+ return 0
345
+
346
+ # Calculate offset by summing lengths of previous lines
347
+ offset = 0
348
+ for i in range(min(line_num, len(self.source_lines))):
349
+ offset += len(self.source_lines[i]) + 1 # +1 for newline
350
+
351
+ if line_num >= len(self.source_lines):
352
+ return offset
353
+
354
+ return max(0, offset - 1) if offset > 0 else 0
355
+
356
+ def _offset_to_line(self, offset: int) -> int:
357
+ """Convert byte offset to approximate line number."""
358
+ if offset <= 0:
359
+ return 0
360
+
361
+ current_offset = 0
362
+ for i, line in enumerate(self.source_lines):
363
+ if current_offset + len(line) + 1 > offset:
364
+ return i
365
+ current_offset += len(line) + 1
366
+
367
+ return len(self.source_lines) - 1
368
+
369
+
370
+ def _fuzzy_eq(left: str, right: str) -> bool:
371
+ """Check if two strings are fuzzy equal using normalized Levenshtein distance.
372
+
373
+ Args:
374
+ left: First string to compare
375
+ right: Second string to compare
376
+
377
+ Returns:
378
+ True if strings are similar enough (>= 0.8 similarity)
379
+ """
380
+ if not left and not right:
381
+ return True
382
+ if not left or not right:
383
+ return False
384
+
385
+ # Normalize whitespace for better matching
386
+ left_normalized = " ".join(left.split())
387
+ right_normalized = " ".join(right.split())
388
+
389
+ # Quick exact match after normalization
390
+ if left_normalized == right_normalized:
391
+ return True
392
+
393
+ # Quick check: if length difference is too large, they can't be similar enough
394
+ max_len = max(len(left_normalized), len(right_normalized))
395
+ if max_len == 0:
396
+ return True
397
+
398
+ min_levenshtein = abs(len(left_normalized) - len(right_normalized))
399
+ min_normalized_similarity = 1.0 - (min_levenshtein / max_len)
400
+
401
+ if min_normalized_similarity < THRESHOLD:
402
+ return False
403
+
404
+ # Calculate actual Levenshtein distance
405
+ distance = _levenshtein_distance(left_normalized, right_normalized)
406
+ normalized_similarity = 1.0 - (distance / max_len)
407
+
408
+ return normalized_similarity >= THRESHOLD
409
+
410
+
411
+ def _levenshtein_distance(s1: str, s2: str) -> int:
412
+ """Calculate Levenshtein distance between two strings.
413
+
414
+ Args:
415
+ s1: First string
416
+ s2: Second string
417
+
418
+ Returns:
419
+ Edit distance between the strings
420
+ """
421
+ if len(s1) < len(s2):
422
+ return _levenshtein_distance(s2, s1)
423
+
424
+ if len(s2) == 0:
425
+ return len(s1)
426
+
427
+ # Create matrix
428
+ previous_row = list(range(len(s2) + 1))
429
+
430
+ for i, c1 in enumerate(s1):
431
+ current_row = [i + 1]
432
+
433
+ for j, c2 in enumerate(s2):
434
+ # Cost of insertions, deletions, substitutions
435
+ insertions = previous_row[j + 1] + 1
436
+ deletions = current_row[j] + 1
437
+ substitutions = previous_row[j] + (0 if c1 == c2 else 1)
438
+
439
+ current_row.append(min(insertions, deletions, substitutions))
440
+
441
+ previous_row = current_row
442
+
443
+ return previous_row[-1]
@@ -0,0 +1,36 @@
1
+ """Provider for history tools."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from agentpool.agents.context import AgentContext # noqa: TC001
6
+ from agentpool.resource_providers import StaticResourceProvider
7
+
8
+
9
+ async def search_history(
10
+ ctx: AgentContext,
11
+ query: str | None = None,
12
+ hours: int = 24,
13
+ limit: int = 5,
14
+ ) -> str:
15
+ """Search conversation history."""
16
+ from agentpool_storage.formatters import format_output
17
+
18
+ if not ctx.pool:
19
+ return "No agent pool available for history search"
20
+ provider = ctx.pool.storage.get_history_provider()
21
+ results = await provider.get_filtered_conversations(
22
+ query=query,
23
+ period=f"{hours}h",
24
+ limit=limit,
25
+ )
26
+ return format_output(results)
27
+
28
+
29
+ class HistoryTools(StaticResourceProvider):
30
+ """Provider for history tools."""
31
+
32
+ def __init__(self, name: str = "history") -> None:
33
+ super().__init__(name=name)
34
+ self._tools = [
35
+ self.create_tool(search_history, category="search", read_only=True, idempotent=True),
36
+ ]
@@ -0,0 +1,85 @@
1
+ """Provider for integration tools."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Literal
6
+
7
+ from pydantic import HttpUrl
8
+
9
+ from agentpool.agents.context import AgentContext # noqa: TC001
10
+ from agentpool.resource_providers import ResourceProvider
11
+
12
+
13
+ if TYPE_CHECKING:
14
+ from agentpool.tools.base import Tool
15
+ from agentpool_config.mcp_server import MCPServerConfig
16
+
17
+
18
+ async def add_local_mcp_server( # noqa: D417
19
+ ctx: AgentContext,
20
+ name: str,
21
+ command: str,
22
+ args: list[str] | None = None,
23
+ env_vars: dict[str, str] | None = None,
24
+ ) -> str:
25
+ """Add a local MCP server via stdio transport.
26
+
27
+ Args:
28
+ name: Unique name for the MCP server
29
+ command: Command to execute for the server
30
+ args: Command arguments
31
+ env_vars: Environment variables to pass to the server
32
+
33
+ Returns:
34
+ Confirmation message about the added server
35
+ """
36
+ from agentpool_config.mcp_server import StdioMCPServerConfig
37
+
38
+ env = env_vars or {}
39
+ config = StdioMCPServerConfig(name=name, command=command, args=args or [], env=env)
40
+ await ctx.agent.mcp.setup_server_runtime(config)
41
+ # New provider automatically available via aggregating provider
42
+ return f"Added local MCP server **{name}** with command: **{command}**"
43
+
44
+
45
+ async def add_remote_mcp_server( # noqa: D417
46
+ ctx: AgentContext,
47
+ name: str,
48
+ url: str,
49
+ transport: Literal["sse", "streamable-http"] = "streamable-http",
50
+ ) -> str:
51
+ """Add a remote MCP server via HTTP-based transport.
52
+
53
+ Args:
54
+ name: Unique name for the MCP server
55
+ url: Server URL endpoint
56
+ transport: HTTP transport type to use (http is preferred)
57
+
58
+ Returns:
59
+ Confirmation message about the added server
60
+ """
61
+ from agentpool_config.mcp_server import SSEMCPServerConfig, StreamableHTTPMCPServerConfig
62
+
63
+ match transport:
64
+ case "sse":
65
+ config: MCPServerConfig = SSEMCPServerConfig(name=name, url=HttpUrl(url))
66
+ case "streamable-http":
67
+ config = StreamableHTTPMCPServerConfig(name=name, url=HttpUrl(url))
68
+
69
+ await ctx.agent.mcp.setup_server_runtime(config)
70
+ # New provider automatically available via aggregating provider
71
+ return f"Added remote MCP server **{name}** at *{url}* using {transport} transport"
72
+
73
+
74
+ class IntegrationTools(ResourceProvider):
75
+ """Provider for integration tools."""
76
+
77
+ def __init__(self, name: str = "integrations") -> None:
78
+ super().__init__(name)
79
+
80
+ async def get_tools(self) -> list[Tool]:
81
+ """Get integration tools."""
82
+ return [
83
+ self.create_tool(add_local_mcp_server, category="other"),
84
+ self.create_tool(add_remote_mcp_server, category="other", open_world=True),
85
+ ]
@@ -0,0 +1,77 @@
1
+ """Provider for skills tools."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from agentpool.agents.context import AgentContext # noqa: TC001
6
+ from agentpool.resource_providers import StaticResourceProvider
7
+
8
+
9
+ BASE_DESC = """Load a Claude Code Skill and return its instructions.
10
+
11
+ This tool provides access to Claude Code Skills - specialized workflows and techniques
12
+ for handling specific types of tasks. When you need to use a skill, call this tool
13
+ with the skill name.
14
+
15
+ Available skills:"""
16
+
17
+
18
+ async def load_skill(ctx: AgentContext, skill_name: str) -> str:
19
+ """Load a Claude Code Skill and return its instructions.
20
+
21
+ Args:
22
+ ctx: Agent context providing access to pool and skills
23
+ skill_name: Name of the skill to load
24
+
25
+ Returns:
26
+ The full skill instructions for execution
27
+ """
28
+ if not ctx.pool:
29
+ return "No agent pool available - skills require pool context"
30
+
31
+ skills = ctx.pool.skills.list_skills()
32
+ if not skills:
33
+ return "No skills available."
34
+ skill = next((s for s in skills if s.name == skill_name), None)
35
+ if not skill:
36
+ available = ", ".join(s.name for s in skills)
37
+ return f"Skill {skill_name!r} not found. Available skills: {available}"
38
+
39
+ try:
40
+ instructions = ctx.pool.skills.get_skill_instructions(skill_name)
41
+ except Exception as e: # noqa: BLE001
42
+ return f"Failed to load skill {skill_name!r}: {e}"
43
+ return f"# {skill.name}\n{instructions}\nSkill directory: {skill.skill_path}"
44
+
45
+
46
+ async def list_skills(ctx: AgentContext) -> str:
47
+ """List all available skills.
48
+
49
+ Returns:
50
+ Formatted list of available skills with descriptions
51
+ """
52
+ if not ctx.pool:
53
+ return "No agent pool available - skills require pool context"
54
+ skills = ctx.pool.skills.list_skills()
55
+ if not skills:
56
+ return "No skills available"
57
+ lines = ["Available skills:", ""]
58
+ lines.extend(f"- **{skill.name}**: {skill.description}" for skill in skills)
59
+ return "\n".join(lines)
60
+
61
+
62
+ class SkillsTools(StaticResourceProvider):
63
+ """Provider for Claude Code Skills tools.
64
+
65
+ Provides tools to discover and load skills from the pool's skills registry.
66
+ Skills are discovered from configured directories (e.g., ~/.claude/skills/,
67
+ .claude/skills/).
68
+
69
+ The pool manages skill discovery; this toolset just provides access to them.
70
+ """
71
+
72
+ def __init__(self, name: str = "skills") -> None:
73
+ super().__init__(name=name)
74
+ self._tools = [
75
+ self.create_tool(load_skill, category="read", read_only=True, idempotent=True),
76
+ self.create_tool(list_skills, category="read", read_only=True, idempotent=True),
77
+ ]