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
@@ -4,12 +4,11 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  from time import perf_counter
7
- from typing import TYPE_CHECKING, Any
7
+ from typing import TYPE_CHECKING, Any, Literal
8
8
  from uuid import uuid4
9
9
 
10
10
  from anyenv.async_run import as_generated
11
11
  import anyio
12
- from toprompt import to_prompt
13
12
 
14
13
  from agentpool.common_types import SupportsRunStream
15
14
  from agentpool.delegation.base_team import BaseTeam
@@ -33,36 +32,6 @@ if TYPE_CHECKING:
33
32
  from agentpool_config.task import Job
34
33
 
35
34
 
36
- async def normalize_stream_for_teams(
37
- node: MessageNode[Any, Any],
38
- *args: Any,
39
- **kwargs: Any,
40
- ) -> AsyncIterator[tuple[MessageNode[Any, Any], RichAgentStreamEvent[Any]]]:
41
- """Normalize any streaming node to yield (node, event) tuples for team composition.
42
-
43
- Args:
44
- node: The streaming node (Agent, Team, etc.)
45
- *args: Arguments to pass to run_stream
46
- **kwargs: Keyword arguments to pass to run_stream
47
-
48
- Yields:
49
- Tuples of (node, event) where node is the MessageNode instance
50
- and event is the streaming event from that node.
51
- """
52
- if not isinstance(node, SupportsRunStream):
53
- msg = f"Node {node.name} does not support streaming"
54
- raise TypeError(msg)
55
-
56
- stream = node.run_stream(*args, **kwargs)
57
- async for item in stream:
58
- if isinstance(item, tuple):
59
- # Already normalized (from Team or other composite node)
60
- yield item
61
- else:
62
- # Raw event (from Agent) - wrap it with the source node
63
- yield (node, item)
64
-
65
-
66
35
  class Team[TDeps = None](BaseTeam[TDeps, Any]):
67
36
  """Group of agents that can execute together."""
68
37
 
@@ -77,8 +46,7 @@ class Team[TDeps = None](BaseTeam[TDeps, Any]):
77
46
  final_prompt = list(prompts)
78
47
  if self.shared_prompt:
79
48
  final_prompt.insert(0, self.shared_prompt)
80
- combined_prompt = "\n".join([await to_prompt(p) for p in final_prompt])
81
- all_nodes = list(await self.pick_agents(combined_prompt))
49
+ all_nodes = list(self.nodes)
82
50
  # Create Talk connections for monitoring this execution
83
51
  execution_talks: list[Talk[Any]] = []
84
52
  for node in all_nodes:
@@ -130,8 +98,7 @@ class Team[TDeps = None](BaseTeam[TDeps, Any]):
130
98
  await queue.put(None)
131
99
 
132
100
  # Get nodes to run
133
- combined_prompt = "\n".join([await to_prompt(p) for p in prompts])
134
- all_nodes = list(await self.pick_agents(combined_prompt))
101
+ all_nodes = list(self.nodes)
135
102
 
136
103
  # Start all agents
137
104
  tasks = [asyncio.create_task(_run(n), name=f"run_{n.name}") for n in all_nodes]
@@ -163,8 +130,8 @@ class Team[TDeps = None](BaseTeam[TDeps, Any]):
163
130
  ) -> ChatMessage[list[Any]]:
164
131
  """Run all agents in parallel and return combined message."""
165
132
  # Prepare prompts and create user message
166
- user_msg, processed_prompts, original_message = await prepare_prompts(*prompts)
167
- self.message_received.emit(user_msg)
133
+ user_msg, processed_prompts = await prepare_prompts(*prompts)
134
+ await self.message_received.emit(user_msg)
168
135
 
169
136
  # Execute team logic
170
137
  result = await self.execute(*processed_prompts, **kwargs)
@@ -176,6 +143,7 @@ class Team[TDeps = None](BaseTeam[TDeps, Any]):
176
143
  name=self.name,
177
144
  message_id=message_id,
178
145
  conversation_id=user_msg.conversation_id,
146
+ parent_id=user_msg.message_id,
179
147
  metadata={
180
148
  "agent_names": [r.agent_name for r in result],
181
149
  "errors": {name: str(error) for name, error in result.errors.items()},
@@ -194,7 +162,6 @@ class Team[TDeps = None](BaseTeam[TDeps, Any]):
194
162
  user_msg,
195
163
  self,
196
164
  self.connections,
197
- original_message,
198
165
  wait_for_connections,
199
166
  )
200
167
 
@@ -202,7 +169,7 @@ class Team[TDeps = None](BaseTeam[TDeps, Any]):
202
169
  self,
203
170
  *prompts: PromptCompatible,
204
171
  **kwargs: Any,
205
- ) -> AsyncIterator[tuple[MessageNode[Any, Any], RichAgentStreamEvent[Any]]]:
172
+ ) -> AsyncIterator[RichAgentStreamEvent[Any]]:
206
173
  """Stream responses from all team members in parallel.
207
174
 
208
175
  Args:
@@ -210,23 +177,53 @@ class Team[TDeps = None](BaseTeam[TDeps, Any]):
210
177
  kwargs: Additional arguments passed to each agent
211
178
 
212
179
  Yields:
213
- Tuples of (agent, event) where agent is the Agent instance
214
- and event is the streaming event from that agent.
180
+ RichAgentStreamEvent, with member events wrapped in SubAgentEvent
215
181
  """
216
- # Get nodes to run
217
- combined_prompt = "\n".join([await to_prompt(p) for p in prompts])
218
- all_nodes = list(await self.pick_agents(combined_prompt))
182
+ from agentpool.agents.events import SubAgentEvent
219
183
 
220
- # Create list of streams that yield (agent, event) tuples
221
- agent_streams = [
222
- normalize_stream_for_teams(agent, *prompts, **kwargs)
223
- for agent in all_nodes
224
- if isinstance(agent, SupportsRunStream)
225
- ]
226
-
227
- # Merge all agent streams
228
- async for agent_event_tuple in as_generated(agent_streams):
229
- yield agent_event_tuple
184
+ # Get nodes to run
185
+ all_nodes = list(self.nodes)
186
+
187
+ # Create list of streams
188
+ async def wrap_stream(
189
+ node: MessageNode[Any, Any],
190
+ ) -> AsyncIterator[RichAgentStreamEvent[Any]]:
191
+ """Wrap a node's stream events in SubAgentEvent."""
192
+ if not isinstance(node, SupportsRunStream):
193
+ return
194
+ async for event in node.run_stream(*prompts, **kwargs):
195
+ # Handle already-wrapped SubAgentEvents (nested teams)
196
+ if isinstance(event, SubAgentEvent):
197
+ yield SubAgentEvent(
198
+ source_name=event.source_name,
199
+ source_type=event.source_type,
200
+ event=event.event,
201
+ depth=event.depth + 1,
202
+ )
203
+ else:
204
+ # Determine source type based on node type
205
+ from agentpool.delegation.teamrun import TeamRun
206
+
207
+ if isinstance(node, TeamRun):
208
+ source_type: Literal["team_parallel", "team_sequential", "agent"] = (
209
+ "team_sequential"
210
+ )
211
+ elif isinstance(node, BaseTeam):
212
+ source_type = "team_parallel"
213
+ else:
214
+ source_type = "agent"
215
+
216
+ yield SubAgentEvent(
217
+ source_name=node.name,
218
+ source_type=source_type,
219
+ event=event,
220
+ depth=1,
221
+ )
222
+
223
+ streams = [wrap_stream(node) for node in all_nodes]
224
+ # Merge all streams
225
+ async for event in as_generated(streams):
226
+ yield event
230
227
 
231
228
  async def run_job[TJobResult](
232
229
  self,
@@ -310,6 +307,7 @@ if __name__ == "__main__":
310
307
 
311
308
  async def main() -> None:
312
309
  from agentpool import Agent, TeamRun
310
+ from agentpool.agents.events import SubAgentEvent
313
311
 
314
312
  agent_a = Agent(name="A", model="test")
315
313
  agent_b = Agent(name="B", model="test")
@@ -319,7 +317,10 @@ if __name__ == "__main__":
319
317
  outer_team = Team([inner_run, agent_c], name="Parallel")
320
318
 
321
319
  print("Testing Team containing TeamRun...")
322
- async for node, event in outer_team.run_stream("test"):
323
- print(f"{node.name}: {type(event).__name__}")
320
+ async for event in outer_team.run_stream("test"):
321
+ if isinstance(event, SubAgentEvent):
322
+ print(f"[depth={event.depth}] {event.source_name}: {type(event.event).__name__}")
323
+ else:
324
+ print(f"Event: {type(event).__name__}")
324
325
 
325
326
  anyio.run(main)
@@ -9,11 +9,9 @@ from typing import TYPE_CHECKING, Any, Literal, overload
9
9
  from uuid import uuid4
10
10
 
11
11
  import anyio
12
- from pydantic_ai import PartDeltaEvent, TextPartDelta
13
12
 
14
13
  from agentpool.common_types import SupportsRunStream
15
14
  from agentpool.delegation.base_team import BaseTeam
16
- from agentpool.delegation.team import normalize_stream_for_teams
17
15
  from agentpool.log import get_logger
18
16
  from agentpool.messaging import AgentResponse, ChatMessage, TeamResponse
19
17
  from agentpool.messaging.processing import finalize_message, prepare_prompts
@@ -27,7 +25,7 @@ if TYPE_CHECKING:
27
25
 
28
26
  from agentpool import MessageNode
29
27
  from agentpool.agents.events import RichAgentStreamEvent
30
- from agentpool.common_types import PromptCompatible, SupportsStructuredOutput
28
+ from agentpool.common_types import PromptCompatible
31
29
  from agentpool.delegation import AgentPool
32
30
 
33
31
 
@@ -65,9 +63,6 @@ class TeamRun[TDeps, TResult](BaseTeam[TDeps, TResult]):
65
63
  display_name: str | None = None,
66
64
  shared_prompt: str | None = None,
67
65
  validator: MessageNode[Any, TResult],
68
- picker: SupportsStructuredOutput | None = None,
69
- num_picks: int | None = None,
70
- pick_prompt: str | None = None,
71
66
  agent_pool: AgentPool | None = None,
72
67
  ) -> None: ...
73
68
 
@@ -81,9 +76,6 @@ class TeamRun[TDeps, TResult](BaseTeam[TDeps, TResult]):
81
76
  display_name: str | None = None,
82
77
  shared_prompt: str | None = None,
83
78
  validator: None = None,
84
- picker: SupportsStructuredOutput | None = None,
85
- num_picks: int | None = None,
86
- pick_prompt: str | None = None,
87
79
  agent_pool: AgentPool | None = None,
88
80
  ) -> None: ...
89
81
 
@@ -97,9 +89,6 @@ class TeamRun[TDeps, TResult](BaseTeam[TDeps, TResult]):
97
89
  display_name: str | None = None,
98
90
  shared_prompt: str | None = None,
99
91
  validator: MessageNode[Any, TResult] | None = None,
100
- picker: SupportsStructuredOutput | None = None,
101
- num_picks: int | None = None,
102
- pick_prompt: str | None = None,
103
92
  agent_pool: AgentPool | None = None,
104
93
  ) -> None: ...
105
94
 
@@ -112,9 +101,6 @@ class TeamRun[TDeps, TResult](BaseTeam[TDeps, TResult]):
112
101
  display_name: str | None = None,
113
102
  shared_prompt: str | None = None,
114
103
  validator: MessageNode[Any, TResult] | None = None,
115
- picker: SupportsStructuredOutput | None = None,
116
- num_picks: int | None = None,
117
- pick_prompt: str | None = None,
118
104
  agent_pool: AgentPool | None = None,
119
105
  # result_mode: ResultMode = "last",
120
106
  ) -> None:
@@ -124,9 +110,6 @@ class TeamRun[TDeps, TResult](BaseTeam[TDeps, TResult]):
124
110
  description=description,
125
111
  display_name=display_name,
126
112
  shared_prompt=shared_prompt,
127
- picker=picker,
128
- num_picks=num_picks,
129
- pick_prompt=pick_prompt,
130
113
  agent_pool=agent_pool,
131
114
  )
132
115
  self.validator = validator
@@ -147,8 +130,8 @@ class TeamRun[TDeps, TResult](BaseTeam[TDeps, TResult]):
147
130
  ) -> ChatMessage[TResult]:
148
131
  """Run agents sequentially and return combined message."""
149
132
  # Prepare prompts and create user message
150
- user_msg, processed_prompts, original_message = await prepare_prompts(*prompts)
151
- self.message_received.emit(user_msg)
133
+ user_msg, processed_prompts = await prepare_prompts(*prompts)
134
+ await self.message_received.emit(user_msg)
152
135
  # Execute sequential logic
153
136
  message_id = str(uuid4()) # Always generate unique response ID
154
137
  result = await self.execute(*processed_prompts, **kwargs)
@@ -172,6 +155,7 @@ class TeamRun[TDeps, TResult](BaseTeam[TDeps, TResult]):
172
155
  associated_messages=all_messages,
173
156
  message_id=message_id,
174
157
  conversation_id=user_msg.conversation_id,
158
+ parent_id=user_msg.message_id,
175
159
  metadata={
176
160
  "execution_order": [r.agent_name for r in result],
177
161
  "start_time": result.start_time.isoformat(),
@@ -186,7 +170,6 @@ class TeamRun[TDeps, TResult](BaseTeam[TDeps, TResult]):
186
170
  user_msg,
187
171
  self,
188
172
  self.connections,
189
- original_message,
190
173
  wait_for_connections,
191
174
  )
192
175
 
@@ -223,12 +206,9 @@ class TeamRun[TDeps, TResult](BaseTeam[TDeps, TResult]):
223
206
  *prompt: PromptCompatible,
224
207
  **kwargs: Any,
225
208
  ) -> AsyncIterator[Talk[Any] | AgentResponse[Any]]:
226
- from toprompt import to_prompt
227
-
228
209
  connections: list[Talk[Any]] = []
229
210
  try:
230
- combined_prompt = "\n".join([await to_prompt(p) for p in prompt])
231
- all_nodes = list(await self.pick_agents(combined_prompt))
211
+ all_nodes = list(self.nodes)
232
212
  if self.validator:
233
213
  all_nodes.append(self.validator)
234
214
  first = all_nodes[0]
@@ -273,7 +253,7 @@ class TeamRun[TDeps, TResult](BaseTeam[TDeps, TResult]):
273
253
  *prompts: PromptCompatible,
274
254
  require_all: bool = True,
275
255
  **kwargs: Any,
276
- ) -> AsyncIterator[tuple[MessageNode[Any, Any], RichAgentStreamEvent[Any]]]:
256
+ ) -> AsyncIterator[RichAgentStreamEvent[Any]]:
277
257
  """Stream responses through the chain of team members.
278
258
 
279
259
  Args:
@@ -283,50 +263,61 @@ class TeamRun[TDeps, TResult](BaseTeam[TDeps, TResult]):
283
263
  kwargs: Additional arguments passed to each agent
284
264
 
285
265
  Yields:
286
- Tuples of (agent, event) where agent is the Agent instance
287
- and event is the streaming event.
266
+ RichAgentStreamEvent, with member events wrapped in SubAgentEvent
288
267
  """
289
- from agentpool.agents.events import StreamCompleteEvent
268
+ from agentpool.agents.events import StreamCompleteEvent, SubAgentEvent
269
+ from agentpool.delegation.team import Team
290
270
 
291
271
  current_message = prompts
292
- collected_content = []
293
- for agent in self.nodes:
272
+ for node in self.nodes:
294
273
  try:
295
- agent_content = []
296
-
297
- # Use wrapper to normalize all streaming nodes to (agent, event) tuples
298
- if not isinstance(agent, SupportsRunStream):
299
- msg = f"Agent {agent.name} does not support streaming"
274
+ if not isinstance(node, SupportsRunStream):
275
+ msg = f"Node {node.name} does not support streaming"
300
276
  raise TypeError(msg) # noqa: TRY301
301
277
 
302
- stream = normalize_stream_for_teams(agent, *current_message, **kwargs)
303
-
304
- async for agent_event_tuple in stream:
305
- actual_agent, event = agent_event_tuple
306
- match event:
307
- case PartDeltaEvent(delta=TextPartDelta(content_delta=delta)):
308
- agent_content.append(delta)
309
- collected_content.append(delta)
310
- yield (actual_agent, event) # Yield tuple with agent context
311
- case StreamCompleteEvent(message=message):
312
- # Use complete response as input for next agent
313
- current_message = (message.content,)
314
- yield (actual_agent, event) # Yield tuple with agent context
315
- case _:
316
- yield (actual_agent, event) # Yield tuple with agent context
278
+ async for event in node.run_stream(*current_message, **kwargs):
279
+ # Handle already-wrapped SubAgentEvents (nested teams)
280
+ if isinstance(event, SubAgentEvent):
281
+ yield SubAgentEvent(
282
+ source_name=event.source_name,
283
+ source_type=event.source_type,
284
+ event=event.event,
285
+ depth=event.depth + 1,
286
+ )
287
+ else:
288
+ # Determine source type based on node type
289
+ if isinstance(node, Team):
290
+ source_type: Literal["team_parallel", "team_sequential", "agent"] = (
291
+ "team_parallel"
292
+ )
293
+ elif isinstance(node, BaseTeam):
294
+ source_type = "team_sequential"
295
+ else:
296
+ source_type = "agent"
297
+
298
+ yield SubAgentEvent(
299
+ source_name=node.name,
300
+ source_type=source_type,
301
+ event=event,
302
+ )
303
+
304
+ # Extract content for next agent in chain
305
+ if isinstance(event, StreamCompleteEvent):
306
+ current_message = (event.message.content,)
317
307
 
318
308
  except Exception as e:
319
309
  if require_all:
320
- msg = f"Chain broken at {agent.name}: {e}"
310
+ msg = f"Chain broken at {node.name}: {e}"
321
311
  logger.exception(msg)
322
312
  raise ValueError(msg) from e
323
- logger.warning("Chain handler failed", name=agent.name, error=e)
313
+ logger.warning("Chain handler failed", name=node.name, error=e)
324
314
 
325
315
 
326
316
  if __name__ == "__main__":
327
317
 
328
318
  async def main() -> None:
329
319
  from agentpool import Agent, Team
320
+ from agentpool.agents.events import SubAgentEvent
330
321
 
331
322
  agent1 = Agent(name="Agent1", model="test")
332
323
  agent2 = Agent(name="Agent2", model="test")
@@ -335,8 +326,13 @@ if __name__ == "__main__":
335
326
  outer_run = TeamRun([inner_team, agent3], name="Sequential")
336
327
  print("Testing TeamRun containing Team...")
337
328
  try:
338
- async for node, event in outer_run.run_stream("test"):
339
- print(f"{node.name}: {type(event).__name__}")
329
+ async for event in outer_run.run_stream("test"):
330
+ if isinstance(event, SubAgentEvent):
331
+ print(
332
+ f"[depth={event.depth}] {event.source_name}: {type(event.event).__name__}"
333
+ )
334
+ else:
335
+ print(f"Event: {type(event).__name__}")
340
336
  except Exception as e: # noqa: BLE001
341
337
  print(f"Error: {e}")
342
338
 
@@ -0,0 +1,53 @@
1
+ """Diagnostics module for code analysis via LSP and CLI tools.
2
+
3
+ This module provides:
4
+ - LSP server lifecycle management via LSPManager
5
+ - LSP proxy for stdio-based servers exposed via Unix socket
6
+ - Integration with execution environments (local, remote, sandboxed)
7
+ """
8
+
9
+ from agentpool.diagnostics.lsp_manager import LSPManager
10
+ from agentpool.diagnostics.lsp_proxy import LSPProxy
11
+ from agentpool.diagnostics.models import (
12
+ COMPLETION_KIND_MAP,
13
+ CODE_ACTION_KIND_MAP,
14
+ SYMBOL_KIND_MAP,
15
+ CallHierarchyCall,
16
+ CallHierarchyItem,
17
+ CodeAction,
18
+ CompletionItem,
19
+ Diagnostic,
20
+ DiagnosticsResult,
21
+ HoverInfo,
22
+ Location,
23
+ LSPServerState,
24
+ Position,
25
+ Range,
26
+ RenameResult,
27
+ SignatureInfo,
28
+ SymbolInfo,
29
+ TypeHierarchyItem,
30
+ )
31
+
32
+ __all__ = [
33
+ "CODE_ACTION_KIND_MAP",
34
+ "COMPLETION_KIND_MAP",
35
+ "SYMBOL_KIND_MAP",
36
+ "CallHierarchyCall",
37
+ "CallHierarchyItem",
38
+ "CodeAction",
39
+ "CompletionItem",
40
+ "Diagnostic",
41
+ "DiagnosticsResult",
42
+ "HoverInfo",
43
+ "LSPManager",
44
+ "LSPProxy",
45
+ "LSPServerState",
46
+ "Location",
47
+ "Position",
48
+ "Range",
49
+ "RenameResult",
50
+ "SignatureInfo",
51
+ "SymbolInfo",
52
+ "TypeHierarchyItem",
53
+ ]