agentpool 2.1.9__py3-none-any.whl → 2.5.0__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.
Files changed (311) hide show
  1. acp/__init__.py +13 -4
  2. acp/acp_requests.py +20 -77
  3. acp/agent/connection.py +8 -0
  4. acp/agent/implementations/debug_server/debug_server.py +6 -2
  5. acp/agent/protocol.py +6 -0
  6. acp/bridge/README.md +15 -2
  7. acp/bridge/__init__.py +3 -2
  8. acp/bridge/__main__.py +60 -19
  9. acp/bridge/ws_server.py +173 -0
  10. acp/bridge/ws_server_cli.py +89 -0
  11. acp/client/connection.py +38 -29
  12. acp/client/implementations/default_client.py +3 -2
  13. acp/client/implementations/headless_client.py +2 -2
  14. acp/connection.py +2 -2
  15. acp/notifications.py +20 -50
  16. acp/schema/__init__.py +2 -0
  17. acp/schema/agent_responses.py +21 -0
  18. acp/schema/client_requests.py +3 -3
  19. acp/schema/session_state.py +63 -29
  20. acp/stdio.py +39 -9
  21. acp/task/supervisor.py +2 -2
  22. acp/transports.py +362 -2
  23. acp/utils.py +17 -4
  24. agentpool/__init__.py +6 -1
  25. agentpool/agents/__init__.py +2 -0
  26. agentpool/agents/acp_agent/acp_agent.py +407 -277
  27. agentpool/agents/acp_agent/acp_converters.py +196 -38
  28. agentpool/agents/acp_agent/client_handler.py +191 -26
  29. agentpool/agents/acp_agent/session_state.py +17 -6
  30. agentpool/agents/agent.py +607 -572
  31. agentpool/agents/agui_agent/__init__.py +0 -2
  32. agentpool/agents/agui_agent/agui_agent.py +176 -110
  33. agentpool/agents/agui_agent/agui_converters.py +0 -131
  34. agentpool/agents/agui_agent/helpers.py +3 -4
  35. agentpool/agents/base_agent.py +632 -17
  36. agentpool/agents/claude_code_agent/FORKING.md +191 -0
  37. agentpool/agents/claude_code_agent/__init__.py +13 -1
  38. agentpool/agents/claude_code_agent/claude_code_agent.py +1058 -291
  39. agentpool/agents/claude_code_agent/converters.py +74 -143
  40. agentpool/agents/claude_code_agent/history.py +474 -0
  41. agentpool/agents/claude_code_agent/models.py +77 -0
  42. agentpool/agents/claude_code_agent/static_info.py +100 -0
  43. agentpool/agents/claude_code_agent/usage.py +242 -0
  44. agentpool/agents/context.py +40 -0
  45. agentpool/agents/events/__init__.py +24 -0
  46. agentpool/agents/events/builtin_handlers.py +67 -1
  47. agentpool/agents/events/event_emitter.py +32 -2
  48. agentpool/agents/events/events.py +104 -3
  49. agentpool/agents/events/infer_info.py +145 -0
  50. agentpool/agents/events/processors.py +254 -0
  51. agentpool/agents/interactions.py +41 -6
  52. agentpool/agents/modes.py +67 -0
  53. agentpool/agents/slashed_agent.py +5 -4
  54. agentpool/agents/tool_call_accumulator.py +213 -0
  55. agentpool/agents/tool_wrapping.py +18 -6
  56. agentpool/common_types.py +56 -21
  57. agentpool/config_resources/__init__.py +38 -1
  58. agentpool/config_resources/acp_assistant.yml +2 -2
  59. agentpool/config_resources/agents.yml +3 -0
  60. agentpool/config_resources/agents_template.yml +1 -0
  61. agentpool/config_resources/claude_code_agent.yml +10 -6
  62. agentpool/config_resources/external_acp_agents.yml +2 -1
  63. agentpool/delegation/base_team.py +4 -30
  64. agentpool/delegation/pool.py +136 -289
  65. agentpool/delegation/team.py +58 -57
  66. agentpool/delegation/teamrun.py +51 -55
  67. agentpool/diagnostics/__init__.py +53 -0
  68. agentpool/diagnostics/lsp_manager.py +1593 -0
  69. agentpool/diagnostics/lsp_proxy.py +41 -0
  70. agentpool/diagnostics/lsp_proxy_script.py +229 -0
  71. agentpool/diagnostics/models.py +398 -0
  72. agentpool/functional/run.py +10 -4
  73. agentpool/mcp_server/__init__.py +0 -2
  74. agentpool/mcp_server/client.py +76 -32
  75. agentpool/mcp_server/conversions.py +54 -13
  76. agentpool/mcp_server/manager.py +34 -54
  77. agentpool/mcp_server/registries/official_registry_client.py +35 -1
  78. agentpool/mcp_server/tool_bridge.py +186 -139
  79. agentpool/messaging/__init__.py +0 -2
  80. agentpool/messaging/compaction.py +72 -197
  81. agentpool/messaging/connection_manager.py +11 -10
  82. agentpool/messaging/event_manager.py +5 -5
  83. agentpool/messaging/message_container.py +6 -30
  84. agentpool/messaging/message_history.py +99 -8
  85. agentpool/messaging/messagenode.py +52 -14
  86. agentpool/messaging/messages.py +54 -35
  87. agentpool/messaging/processing.py +12 -22
  88. agentpool/models/__init__.py +1 -1
  89. agentpool/models/acp_agents/base.py +6 -24
  90. agentpool/models/acp_agents/mcp_capable.py +126 -157
  91. agentpool/models/acp_agents/non_mcp.py +129 -95
  92. agentpool/models/agents.py +98 -76
  93. agentpool/models/agui_agents.py +1 -1
  94. agentpool/models/claude_code_agents.py +144 -19
  95. agentpool/models/file_parsing.py +0 -1
  96. agentpool/models/manifest.py +113 -50
  97. agentpool/prompts/conversion_manager.py +1 -1
  98. agentpool/prompts/prompts.py +5 -2
  99. agentpool/repomap.py +1 -1
  100. agentpool/resource_providers/__init__.py +11 -1
  101. agentpool/resource_providers/aggregating.py +56 -5
  102. agentpool/resource_providers/base.py +70 -4
  103. agentpool/resource_providers/codemode/code_executor.py +72 -5
  104. agentpool/resource_providers/codemode/helpers.py +2 -2
  105. agentpool/resource_providers/codemode/provider.py +64 -12
  106. agentpool/resource_providers/codemode/remote_mcp_execution.py +2 -2
  107. agentpool/resource_providers/codemode/remote_provider.py +9 -12
  108. agentpool/resource_providers/filtering.py +3 -1
  109. agentpool/resource_providers/mcp_provider.py +89 -12
  110. agentpool/resource_providers/plan_provider.py +228 -46
  111. agentpool/resource_providers/pool.py +7 -3
  112. agentpool/resource_providers/resource_info.py +111 -0
  113. agentpool/resource_providers/static.py +4 -2
  114. agentpool/sessions/__init__.py +4 -1
  115. agentpool/sessions/manager.py +33 -5
  116. agentpool/sessions/models.py +59 -6
  117. agentpool/sessions/protocol.py +28 -0
  118. agentpool/sessions/session.py +11 -55
  119. agentpool/skills/registry.py +13 -8
  120. agentpool/storage/manager.py +572 -49
  121. agentpool/talk/registry.py +4 -4
  122. agentpool/talk/talk.py +9 -10
  123. agentpool/testing.py +538 -20
  124. agentpool/tool_impls/__init__.py +6 -0
  125. agentpool/tool_impls/agent_cli/__init__.py +42 -0
  126. agentpool/tool_impls/agent_cli/tool.py +95 -0
  127. agentpool/tool_impls/bash/__init__.py +64 -0
  128. agentpool/tool_impls/bash/helpers.py +35 -0
  129. agentpool/tool_impls/bash/tool.py +171 -0
  130. agentpool/tool_impls/delete_path/__init__.py +70 -0
  131. agentpool/tool_impls/delete_path/tool.py +142 -0
  132. agentpool/tool_impls/download_file/__init__.py +80 -0
  133. agentpool/tool_impls/download_file/tool.py +183 -0
  134. agentpool/tool_impls/execute_code/__init__.py +55 -0
  135. agentpool/tool_impls/execute_code/tool.py +163 -0
  136. agentpool/tool_impls/grep/__init__.py +80 -0
  137. agentpool/tool_impls/grep/tool.py +200 -0
  138. agentpool/tool_impls/list_directory/__init__.py +73 -0
  139. agentpool/tool_impls/list_directory/tool.py +197 -0
  140. agentpool/tool_impls/question/__init__.py +42 -0
  141. agentpool/tool_impls/question/tool.py +127 -0
  142. agentpool/tool_impls/read/__init__.py +104 -0
  143. agentpool/tool_impls/read/tool.py +305 -0
  144. agentpool/tools/__init__.py +2 -1
  145. agentpool/tools/base.py +114 -34
  146. agentpool/tools/manager.py +57 -1
  147. agentpool/ui/base.py +2 -2
  148. agentpool/ui/mock_provider.py +2 -2
  149. agentpool/ui/stdlib_provider.py +2 -2
  150. agentpool/utils/file_watcher.py +269 -0
  151. agentpool/utils/identifiers.py +121 -0
  152. agentpool/utils/pydantic_ai_helpers.py +46 -0
  153. agentpool/utils/streams.py +616 -2
  154. agentpool/utils/subprocess_utils.py +155 -0
  155. agentpool/utils/token_breakdown.py +461 -0
  156. agentpool/vfs_registry.py +7 -2
  157. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/METADATA +41 -27
  158. agentpool-2.5.0.dist-info/RECORD +579 -0
  159. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/WHEEL +1 -1
  160. agentpool_cli/__main__.py +24 -0
  161. agentpool_cli/create.py +1 -1
  162. agentpool_cli/serve_acp.py +100 -21
  163. agentpool_cli/serve_agui.py +87 -0
  164. agentpool_cli/serve_opencode.py +119 -0
  165. agentpool_cli/ui.py +557 -0
  166. agentpool_commands/__init__.py +42 -5
  167. agentpool_commands/agents.py +75 -2
  168. agentpool_commands/history.py +62 -0
  169. agentpool_commands/mcp.py +176 -0
  170. agentpool_commands/models.py +56 -3
  171. agentpool_commands/pool.py +260 -0
  172. agentpool_commands/session.py +1 -1
  173. agentpool_commands/text_sharing/__init__.py +119 -0
  174. agentpool_commands/text_sharing/base.py +123 -0
  175. agentpool_commands/text_sharing/github_gist.py +80 -0
  176. agentpool_commands/text_sharing/opencode.py +462 -0
  177. agentpool_commands/text_sharing/paste_rs.py +59 -0
  178. agentpool_commands/text_sharing/pastebin.py +116 -0
  179. agentpool_commands/text_sharing/shittycodingagent.py +112 -0
  180. agentpool_commands/tools.py +57 -0
  181. agentpool_commands/utils.py +80 -30
  182. agentpool_config/__init__.py +30 -2
  183. agentpool_config/agentpool_tools.py +498 -0
  184. agentpool_config/builtin_tools.py +77 -22
  185. agentpool_config/commands.py +24 -1
  186. agentpool_config/compaction.py +258 -0
  187. agentpool_config/converters.py +1 -1
  188. agentpool_config/event_handlers.py +42 -0
  189. agentpool_config/events.py +1 -1
  190. agentpool_config/forward_targets.py +1 -4
  191. agentpool_config/jinja.py +3 -3
  192. agentpool_config/mcp_server.py +132 -6
  193. agentpool_config/nodes.py +1 -1
  194. agentpool_config/observability.py +44 -0
  195. agentpool_config/session.py +0 -3
  196. agentpool_config/storage.py +82 -38
  197. agentpool_config/task.py +3 -3
  198. agentpool_config/tools.py +11 -22
  199. agentpool_config/toolsets.py +109 -233
  200. agentpool_server/a2a_server/agent_worker.py +307 -0
  201. agentpool_server/a2a_server/server.py +23 -18
  202. agentpool_server/acp_server/acp_agent.py +234 -181
  203. agentpool_server/acp_server/commands/acp_commands.py +151 -156
  204. agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +18 -17
  205. agentpool_server/acp_server/event_converter.py +651 -0
  206. agentpool_server/acp_server/input_provider.py +53 -10
  207. agentpool_server/acp_server/server.py +24 -90
  208. agentpool_server/acp_server/session.py +173 -331
  209. agentpool_server/acp_server/session_manager.py +8 -34
  210. agentpool_server/agui_server/server.py +3 -1
  211. agentpool_server/mcp_server/server.py +5 -2
  212. agentpool_server/opencode_server/.rules +95 -0
  213. agentpool_server/opencode_server/ENDPOINTS.md +401 -0
  214. agentpool_server/opencode_server/OPENCODE_UI_TOOLS_COMPLETE.md +202 -0
  215. agentpool_server/opencode_server/__init__.py +19 -0
  216. agentpool_server/opencode_server/command_validation.py +172 -0
  217. agentpool_server/opencode_server/converters.py +975 -0
  218. agentpool_server/opencode_server/dependencies.py +24 -0
  219. agentpool_server/opencode_server/input_provider.py +421 -0
  220. agentpool_server/opencode_server/models/__init__.py +250 -0
  221. agentpool_server/opencode_server/models/agent.py +53 -0
  222. agentpool_server/opencode_server/models/app.py +72 -0
  223. agentpool_server/opencode_server/models/base.py +26 -0
  224. agentpool_server/opencode_server/models/common.py +23 -0
  225. agentpool_server/opencode_server/models/config.py +37 -0
  226. agentpool_server/opencode_server/models/events.py +821 -0
  227. agentpool_server/opencode_server/models/file.py +88 -0
  228. agentpool_server/opencode_server/models/mcp.py +44 -0
  229. agentpool_server/opencode_server/models/message.py +179 -0
  230. agentpool_server/opencode_server/models/parts.py +323 -0
  231. agentpool_server/opencode_server/models/provider.py +81 -0
  232. agentpool_server/opencode_server/models/pty.py +43 -0
  233. agentpool_server/opencode_server/models/question.py +56 -0
  234. agentpool_server/opencode_server/models/session.py +111 -0
  235. agentpool_server/opencode_server/routes/__init__.py +29 -0
  236. agentpool_server/opencode_server/routes/agent_routes.py +473 -0
  237. agentpool_server/opencode_server/routes/app_routes.py +202 -0
  238. agentpool_server/opencode_server/routes/config_routes.py +302 -0
  239. agentpool_server/opencode_server/routes/file_routes.py +571 -0
  240. agentpool_server/opencode_server/routes/global_routes.py +94 -0
  241. agentpool_server/opencode_server/routes/lsp_routes.py +319 -0
  242. agentpool_server/opencode_server/routes/message_routes.py +761 -0
  243. agentpool_server/opencode_server/routes/permission_routes.py +63 -0
  244. agentpool_server/opencode_server/routes/pty_routes.py +300 -0
  245. agentpool_server/opencode_server/routes/question_routes.py +128 -0
  246. agentpool_server/opencode_server/routes/session_routes.py +1276 -0
  247. agentpool_server/opencode_server/routes/tui_routes.py +139 -0
  248. agentpool_server/opencode_server/server.py +475 -0
  249. agentpool_server/opencode_server/state.py +151 -0
  250. agentpool_server/opencode_server/time_utils.py +8 -0
  251. agentpool_storage/__init__.py +12 -0
  252. agentpool_storage/base.py +184 -2
  253. agentpool_storage/claude_provider/ARCHITECTURE.md +433 -0
  254. agentpool_storage/claude_provider/__init__.py +42 -0
  255. agentpool_storage/claude_provider/provider.py +1089 -0
  256. agentpool_storage/file_provider.py +278 -15
  257. agentpool_storage/memory_provider.py +193 -12
  258. agentpool_storage/models.py +3 -0
  259. agentpool_storage/opencode_provider/ARCHITECTURE.md +386 -0
  260. agentpool_storage/opencode_provider/__init__.py +16 -0
  261. agentpool_storage/opencode_provider/helpers.py +414 -0
  262. agentpool_storage/opencode_provider/provider.py +895 -0
  263. agentpool_storage/project_store.py +325 -0
  264. agentpool_storage/session_store.py +26 -6
  265. agentpool_storage/sql_provider/__init__.py +4 -2
  266. agentpool_storage/sql_provider/models.py +48 -0
  267. agentpool_storage/sql_provider/sql_provider.py +269 -3
  268. agentpool_storage/sql_provider/utils.py +12 -13
  269. agentpool_storage/zed_provider/__init__.py +16 -0
  270. agentpool_storage/zed_provider/helpers.py +281 -0
  271. agentpool_storage/zed_provider/models.py +130 -0
  272. agentpool_storage/zed_provider/provider.py +442 -0
  273. agentpool_storage/zed_provider.py +803 -0
  274. agentpool_toolsets/__init__.py +0 -2
  275. agentpool_toolsets/builtin/__init__.py +2 -12
  276. agentpool_toolsets/builtin/code.py +96 -57
  277. agentpool_toolsets/builtin/debug.py +118 -48
  278. agentpool_toolsets/builtin/execution_environment.py +115 -230
  279. agentpool_toolsets/builtin/file_edit/file_edit.py +115 -7
  280. agentpool_toolsets/builtin/skills.py +9 -4
  281. agentpool_toolsets/builtin/subagent_tools.py +64 -51
  282. agentpool_toolsets/builtin/workers.py +4 -2
  283. agentpool_toolsets/composio_toolset.py +2 -2
  284. agentpool_toolsets/entry_points.py +3 -1
  285. agentpool_toolsets/fsspec_toolset/__init__.py +13 -1
  286. agentpool_toolsets/fsspec_toolset/diagnostics.py +860 -73
  287. agentpool_toolsets/fsspec_toolset/grep.py +99 -7
  288. agentpool_toolsets/fsspec_toolset/helpers.py +3 -2
  289. agentpool_toolsets/fsspec_toolset/image_utils.py +161 -0
  290. agentpool_toolsets/fsspec_toolset/toolset.py +500 -95
  291. agentpool_toolsets/mcp_discovery/__init__.py +5 -0
  292. agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
  293. agentpool_toolsets/mcp_discovery/toolset.py +511 -0
  294. agentpool_toolsets/mcp_run_toolset.py +87 -12
  295. agentpool_toolsets/notifications.py +33 -33
  296. agentpool_toolsets/openapi.py +3 -1
  297. agentpool_toolsets/search_toolset.py +3 -1
  298. agentpool-2.1.9.dist-info/RECORD +0 -474
  299. agentpool_config/resources.py +0 -33
  300. agentpool_server/acp_server/acp_tools.py +0 -43
  301. agentpool_server/acp_server/commands/spawn.py +0 -210
  302. agentpool_storage/text_log_provider.py +0 -275
  303. agentpool_toolsets/builtin/agent_management.py +0 -239
  304. agentpool_toolsets/builtin/chain.py +0 -288
  305. agentpool_toolsets/builtin/history.py +0 -36
  306. agentpool_toolsets/builtin/integration.py +0 -85
  307. agentpool_toolsets/builtin/tool_management.py +0 -90
  308. agentpool_toolsets/builtin/user_interaction.py +0 -52
  309. agentpool_toolsets/semantic_memory_toolset.py +0 -536
  310. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/entry_points.txt +0 -0
  311. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/licenses/LICENSE +0 -0
agentpool_cli/__main__.py CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from importlib import metadata
6
+
5
7
  import typer as t
6
8
 
7
9
  from agentpool_cli import log
@@ -10,11 +12,14 @@ from agentpool_cli.cli_types import LogLevel # noqa: TC001
10
12
  from agentpool_cli.history import history_cli
11
13
  from agentpool_cli.run import run_command
12
14
  from agentpool_cli.serve_acp import acp_command
15
+ from agentpool_cli.serve_agui import agui_command
13
16
  from agentpool_cli.serve_api import api_command
14
17
  from agentpool_cli.serve_mcp import serve_command
18
+ from agentpool_cli.serve_opencode import opencode_command
15
19
  from agentpool_cli.serve_vercel import vercel_command
16
20
  from agentpool_cli.store import ConfigStore
17
21
  from agentpool_cli.task import task_command
22
+ from agentpool_cli.ui import ui_app
18
23
  from agentpool_cli.watch import watch_command
19
24
 
20
25
 
@@ -30,8 +35,24 @@ def get_command_help(base_help: str) -> str:
30
35
  return f"{base_help}\n\n(No active config set)"
31
36
 
32
37
 
38
+ def version_callback(value: bool) -> None:
39
+ """Print version and exit."""
40
+ if value:
41
+ version = metadata.version("agentpool")
42
+ t.echo(f"agentpool version {version}")
43
+ raise t.Exit
44
+
45
+
33
46
  def main(
34
47
  ctx: t.Context,
48
+ version: bool = t.Option(
49
+ False,
50
+ "--version",
51
+ "-v",
52
+ help="Show version and exit",
53
+ callback=version_callback,
54
+ is_eager=True,
55
+ ),
35
56
  log_level: LogLevel = t.Option("info", "--log-level", "-l", help="Log level"), # noqa: B008
36
57
  ) -> None:
37
58
  """🤖 AgentPool CLI - Run and manage LLM agents."""
@@ -54,12 +75,15 @@ cli.command(name="list-configs")(list_configs)
54
75
  cli.command(name="set")(set_active_file)
55
76
  cli.command(name="watch")(watch_command)
56
77
  cli.command(name="serve-acp")(acp_command)
78
+ cli.command(name="serve-agui")(agui_command)
57
79
  cli.command(name="serve-mcp")(serve_command)
58
80
  cli.command(name="serve-api")(api_command)
81
+ cli.command(name="serve-opencode")(opencode_command)
59
82
  cli.command(name="serve-vercel")(vercel_command)
60
83
  cli.command(name="task")(task_command)
61
84
 
62
85
  cli.add_typer(history_cli, name="history")
86
+ cli.add_typer(ui_app, name="ui")
63
87
 
64
88
 
65
89
  if __name__ == "__main__":
agentpool_cli/create.py CHANGED
@@ -115,7 +115,7 @@ def create(
115
115
  from upathtools import to_upath
116
116
 
117
117
  super().__init__()
118
- agent = Agent(output_type=YAMLCode)
118
+ agent = Agent(output_type=YAMLCode, model="openai:gpt-5-nano")
119
119
  self.agent = agent
120
120
  self.current_config: str | None = None
121
121
  self.output_path = to_upath(output_path) if output_path else None
@@ -8,8 +8,9 @@ integration with file system access, permission handling, and terminal support.
8
8
  from __future__ import annotations
9
9
 
10
10
  import asyncio
11
+ import json
11
12
  import os
12
- from typing import Annotated
13
+ from typing import TYPE_CHECKING, Annotated, Literal
13
14
 
14
15
  from platformdirs import user_log_path
15
16
  import typer as t
@@ -17,10 +18,16 @@ import typer as t
17
18
  from agentpool_cli import log, resolve_agent_config
18
19
 
19
20
 
21
+ if TYPE_CHECKING:
22
+ from acp import Transport
23
+ from agentpool_config.mcp_server import MCPServerConfig
24
+
25
+
20
26
  logger = log.get_logger(__name__)
21
27
 
22
28
 
23
- def acp_command(
29
+ def acp_command( # noqa: PLR0915
30
+ # Too many statements - complex CLI command with many options
24
31
  config: Annotated[str | None, t.Argument(help="Path to agent configuration (optional)")] = None,
25
32
  file_access: Annotated[
26
33
  bool,
@@ -49,13 +56,6 @@ def acp_command(
49
56
  help="File to save JSON-RPC debug messages (default: acp-debug.jsonl)",
50
57
  ),
51
58
  ] = None,
52
- providers: Annotated[
53
- list[str] | None,
54
- t.Option(
55
- "--model-provider",
56
- help="Providers to search for models (can be specified multiple times)",
57
- ),
58
- ] = None,
59
59
  debug_commands: Annotated[
60
60
  bool,
61
61
  t.Option(
@@ -77,6 +77,35 @@ def acp_command(
77
77
  help="Load client-side skills from .claude/skills directory",
78
78
  ),
79
79
  ] = True,
80
+ transport: Annotated[
81
+ Literal["stdio", "websocket"],
82
+ t.Option(
83
+ "--transport",
84
+ "-t",
85
+ help="Transport type: stdio (default) or websocket",
86
+ ),
87
+ ] = "stdio",
88
+ ws_host: Annotated[
89
+ str,
90
+ t.Option(
91
+ "--ws-host",
92
+ help="WebSocket host (only used with --transport websocket)",
93
+ ),
94
+ ] = "localhost",
95
+ ws_port: Annotated[
96
+ int,
97
+ t.Option(
98
+ "--ws-port",
99
+ help="WebSocket port (only used with --transport websocket)",
100
+ ),
101
+ ] = 8765,
102
+ mcp_config: Annotated[
103
+ str | None,
104
+ t.Option(
105
+ "--mcp-config",
106
+ help='MCP servers configuration as JSON (format: {"mcpServers": {...}})',
107
+ ),
108
+ ] = None,
80
109
  ) -> None:
81
110
  r"""Run agents as an ACP (Agent Client Protocol) server.
82
111
 
@@ -99,9 +128,19 @@ def acp_command(
99
128
  allowing users to switch between agents mid-conversation. Each agent appears
100
129
  as a different "mode" with its own name and capabilities.
101
130
  """
131
+ from acp import StdioTransport, WebSocketTransport
102
132
  from agentpool import log
133
+ from agentpool.config_resources import ACP_ASSISTANT
103
134
  from agentpool_server.acp_server import ACPServer
104
135
 
136
+ # Build transport config
137
+ if transport == "websocket":
138
+ transport_config: Transport = WebSocketTransport(host=ws_host, port=ws_port)
139
+ elif transport == "stdio":
140
+ transport_config = StdioTransport()
141
+ else:
142
+ raise t.BadParameter(f"Unknown transport: {transport}. Use 'stdio' or 'websocket'.")
143
+
105
144
  # Always log to file with rollover
106
145
  log_dir = user_log_path("agentpool", appauthor=False)
107
146
  log_dir.mkdir(parents=True, exist_ok=True)
@@ -117,40 +156,80 @@ def acp_command(
117
156
  msg = str(e)
118
157
  raise t.BadParameter(msg) from e
119
158
 
120
- logger.info("Starting ACP server", config_path=config_path)
159
+ logger.info("Starting ACP server", config_path=config_path, transport=transport)
121
160
  acp_server = ACPServer.from_config(
122
161
  config_path,
123
162
  file_access=file_access,
124
163
  terminal_access=terminal_access,
125
- providers=providers, # type: ignore[arg-type]
126
164
  debug_messages=debug_messages,
127
165
  debug_file=debug_file or "acp-debug.jsonl" if debug_messages else None,
128
166
  debug_commands=debug_commands,
129
167
  agent=agent,
130
168
  load_skills=load_skills,
169
+ transport=transport_config,
131
170
  )
132
171
  else:
133
172
  # Use default ACP assistant config
134
- from agentpool.config_resources import ACP_ASSISTANT
135
-
136
- logger.info("Starting ACP server with default configuration")
173
+ logger.info("Starting ACP server with default configuration", transport=transport)
137
174
  acp_server = ACPServer.from_config(
138
175
  ACP_ASSISTANT,
139
176
  file_access=file_access,
140
177
  terminal_access=terminal_access,
141
- providers=providers, # type: ignore[arg-type]
142
178
  debug_messages=debug_messages,
143
179
  debug_file=debug_file or "acp-debug.jsonl" if debug_messages else None,
144
180
  debug_commands=debug_commands,
145
181
  agent=agent,
146
182
  load_skills=load_skills,
183
+ transport=transport_config,
147
184
  )
148
- # Configure agent capabilities
149
- agent_count = len(acp_server.pool.all_agents)
150
- if agent_count == 0:
151
- logger.error("No agents found in configuration")
152
- raise t.Exit(1)
153
- logger.info("Configured agents for ACP protocol", count=agent_count)
185
+
186
+ # Inject MCP servers from --mcp-config if provided
187
+ # TODO: Consider adding to specific agent's MCP manager instead of pool-level
188
+ # for better isolation (currently all agents in pool share these servers)
189
+ if mcp_config:
190
+ try:
191
+ mcp_data = json.loads(mcp_config)
192
+ if "mcpServers" not in mcp_data:
193
+ raise t.BadParameter("MCP config must contain 'mcpServers' key")
194
+
195
+ from agentpool_config.mcp_server import (
196
+ SSEMCPServerConfig,
197
+ StreamableHTTPMCPServerConfig,
198
+ )
199
+
200
+ for server_name, server_cfg in mcp_data["mcpServers"].items():
201
+ # Parse server config based on transport type
202
+ if "transport" in server_cfg:
203
+ if server_cfg["transport"] == "sse":
204
+ server: MCPServerConfig = SSEMCPServerConfig(
205
+ name=server_name,
206
+ url=server_cfg["url"],
207
+ )
208
+ elif server_cfg["transport"] == "http":
209
+ server = StreamableHTTPMCPServerConfig(
210
+ name=server_name,
211
+ url=server_cfg["url"],
212
+ )
213
+ else:
214
+ msg = f"Unsupported transport type: {server_cfg['transport']}"
215
+ raise t.BadParameter(msg)
216
+ else:
217
+ # Default to HTTP if no transport specified
218
+ server = StreamableHTTPMCPServerConfig(
219
+ name=server_name,
220
+ url=server_cfg["url"],
221
+ )
222
+
223
+ acp_server.pool.mcp.add_server_config(server)
224
+ logger.info(
225
+ "Added MCP server from --mcp-config",
226
+ server_name=server_name,
227
+ url=server_cfg.get("url"),
228
+ )
229
+ except json.JSONDecodeError as e:
230
+ msg = f"Invalid JSON in --mcp-config: {e}"
231
+ raise t.BadParameter(msg) from e
232
+
154
233
  if show_messages:
155
234
  logger.info("Message activity logging enabled")
156
235
  if debug_messages:
@@ -0,0 +1,87 @@
1
+ """Command for running agents as an AG-UI server."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import TYPE_CHECKING, Annotated, Any
7
+
8
+ import typer as t
9
+
10
+ from agentpool_cli import resolve_agent_config
11
+ from agentpool_cli.log import get_logger
12
+
13
+
14
+ if TYPE_CHECKING:
15
+ from agentpool import ChatMessage
16
+
17
+
18
+ logger = get_logger(__name__)
19
+
20
+
21
+ def agui_command(
22
+ ctx: t.Context,
23
+ config: Annotated[str | None, t.Argument(help="Path to agent configuration")] = None,
24
+ host: Annotated[str, t.Option(help="Host to bind server to")] = "localhost",
25
+ port: Annotated[int, t.Option(help="Port to listen on")] = 8002,
26
+ show_messages: Annotated[
27
+ bool, t.Option("--show-messages", help="Show message activity")
28
+ ] = False,
29
+ ) -> None:
30
+ """Run agents as an AG-UI server.
31
+
32
+ This creates an AG-UI protocol server that makes your agents available
33
+ through the AG-UI interface, compatible with AG-UI clients like Toad.
34
+
35
+ Each agent is accessible at /{agent_name} route.
36
+ """
37
+ import anyio
38
+
39
+ from agentpool import AgentPool, AgentsManifest
40
+ from agentpool_server.agui_server import AGUIServer
41
+
42
+ logger.info("Server PID", pid=os.getpid())
43
+
44
+ def on_message(message: ChatMessage[Any]) -> None:
45
+ print(message.format(style="simple"))
46
+
47
+ try:
48
+ config_path = resolve_agent_config(config)
49
+ except ValueError as e:
50
+ msg = str(e)
51
+ raise t.BadParameter(msg) from e
52
+
53
+ manifest = AgentsManifest.from_file(config_path)
54
+
55
+ async def run_server() -> None:
56
+ async with AgentPool(manifest) as pool:
57
+ if show_messages:
58
+ for agent in pool.agents.values():
59
+ agent.message_sent.connect(on_message)
60
+
61
+ server = AGUIServer(pool, host=host, port=port)
62
+ async with server:
63
+ logger.info(
64
+ "AG-UI server started",
65
+ host=host,
66
+ port=port,
67
+ agents=list(pool.agents.keys()),
68
+ )
69
+ # List agent routes
70
+ for name, url in server.list_agent_routes().items():
71
+ logger.info("Agent route", agent=name, url=url)
72
+
73
+ async with server.run_context():
74
+ # Keep running until interrupted
75
+ try:
76
+ while True:
77
+ await anyio.sleep(1)
78
+ except KeyboardInterrupt:
79
+ logger.info("Shutting down AG-UI server")
80
+
81
+ anyio.run(run_server)
82
+
83
+
84
+ if __name__ == "__main__":
85
+ import typer
86
+
87
+ typer.run(agui_command)
@@ -0,0 +1,119 @@
1
+ """Command for running agents as an OpenCode-compatible server.
2
+
3
+ This creates an HTTP server that implements the OpenCode API protocol,
4
+ allowing OpenCode TUI and SDK clients to interact with AgentPool agents.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Annotated
10
+
11
+ from platformdirs import user_log_path
12
+ import typer as t
13
+
14
+ from agentpool_cli import log, resolve_agent_config
15
+
16
+
17
+ logger = log.get_logger(__name__)
18
+
19
+
20
+ def opencode_command(
21
+ config: Annotated[str | None, t.Argument(help="Path to agent configuration (optional)")] = None,
22
+ host: Annotated[
23
+ str,
24
+ t.Option("--host", "-h", help="Host to bind to"),
25
+ ] = "127.0.0.1",
26
+ port: Annotated[
27
+ int,
28
+ t.Option("--port", "-p", help="Port to listen on"),
29
+ ] = 4096,
30
+ agent: Annotated[
31
+ str | None,
32
+ t.Option(
33
+ "--agent",
34
+ help="Name of specific agent to use (defaults to first agent in config)",
35
+ ),
36
+ ] = None,
37
+ working_dir: Annotated[
38
+ str | None,
39
+ t.Option(
40
+ "--working-dir",
41
+ "-w",
42
+ help="Working directory for file operations (defaults to current directory)",
43
+ ),
44
+ ] = None,
45
+ ) -> None:
46
+ """Run agents as an OpenCode-compatible HTTP server.
47
+
48
+ This creates an HTTP server implementing the OpenCode API protocol,
49
+ enabling your AgentPool agents to work with OpenCode TUI and SDK clients.
50
+
51
+ Configuration:
52
+ Config file is optional. Without a config file, creates a general-purpose
53
+ agent with default settings similar to the ACP server.
54
+
55
+ Agent Selection:
56
+ Use --agent to specify which agent to use by name. Without this option,
57
+ the first agent in your config is used as the default (or "assistant"
58
+ if no config provided).
59
+
60
+ Examples:
61
+ # Start with default agent
62
+ agentpool serve-opencode
63
+
64
+ # Start with specific config
65
+ agentpool serve-opencode agents.yml
66
+
67
+ # Start on custom port with specific agent
68
+ agentpool serve-opencode --port 8080 --agent myagent agents.yml
69
+ """
70
+ from agentpool import AgentPool, log as ap_log
71
+ from agentpool.config_resources import CLAUDE_CODE_ASSISTANT
72
+ from agentpool_server.opencode_server.server import OpenCodeServer
73
+
74
+ # Always log to file with rollover
75
+ log_dir = user_log_path("agentpool", appauthor=False)
76
+ log_dir.mkdir(parents=True, exist_ok=True)
77
+ log_file = log_dir / "opencode.log"
78
+ ap_log.configure_logging(force=True, log_file=str(log_file))
79
+ logger.info("Configured file logging with rollover", log_file=str(log_file))
80
+
81
+ # Resolve config path (use default if not provided)
82
+ if config:
83
+ try:
84
+ config_path = resolve_agent_config(config)
85
+ except ValueError as e:
86
+ raise t.BadParameter(str(e)) from e
87
+ else:
88
+ config_path = CLAUDE_CODE_ASSISTANT
89
+
90
+ logger.info("Starting OpenCode server", config_path=config_path, host=host, port=port)
91
+
92
+ # Load agent from config
93
+ pool = AgentPool(config_path)
94
+
95
+ async def run_server() -> None:
96
+ async with pool:
97
+ server = OpenCodeServer(
98
+ pool,
99
+ host=host,
100
+ port=port,
101
+ working_dir=working_dir,
102
+ agent_name=agent,
103
+ )
104
+ logger.info("Server starting", url=f"http://{host}:{port}")
105
+ await server.run_async()
106
+
107
+ import asyncio
108
+
109
+ try:
110
+ asyncio.run(run_server())
111
+ except KeyboardInterrupt:
112
+ logger.info("OpenCode server shutdown requested")
113
+ except Exception as e:
114
+ logger.exception("OpenCode server error")
115
+ raise t.Exit(1) from e
116
+
117
+
118
+ if __name__ == "__main__":
119
+ t.run(opencode_command)