agentpool 2.2.3__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 (250) hide show
  1. acp/__init__.py +0 -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/client/connection.py +38 -29
  7. acp/client/implementations/default_client.py +3 -2
  8. acp/client/implementations/headless_client.py +2 -2
  9. acp/connection.py +2 -2
  10. acp/notifications.py +18 -49
  11. acp/schema/__init__.py +2 -0
  12. acp/schema/agent_responses.py +21 -0
  13. acp/schema/client_requests.py +3 -3
  14. acp/schema/session_state.py +63 -29
  15. acp/task/supervisor.py +2 -2
  16. acp/utils.py +2 -2
  17. agentpool/__init__.py +2 -0
  18. agentpool/agents/acp_agent/acp_agent.py +278 -263
  19. agentpool/agents/acp_agent/acp_converters.py +150 -17
  20. agentpool/agents/acp_agent/client_handler.py +35 -24
  21. agentpool/agents/acp_agent/session_state.py +14 -6
  22. agentpool/agents/agent.py +471 -643
  23. agentpool/agents/agui_agent/agui_agent.py +104 -107
  24. agentpool/agents/agui_agent/helpers.py +3 -4
  25. agentpool/agents/base_agent.py +485 -32
  26. agentpool/agents/claude_code_agent/FORKING.md +191 -0
  27. agentpool/agents/claude_code_agent/__init__.py +13 -1
  28. agentpool/agents/claude_code_agent/claude_code_agent.py +654 -334
  29. agentpool/agents/claude_code_agent/converters.py +4 -141
  30. agentpool/agents/claude_code_agent/models.py +77 -0
  31. agentpool/agents/claude_code_agent/static_info.py +100 -0
  32. agentpool/agents/claude_code_agent/usage.py +242 -0
  33. agentpool/agents/events/__init__.py +22 -0
  34. agentpool/agents/events/builtin_handlers.py +65 -0
  35. agentpool/agents/events/event_emitter.py +3 -0
  36. agentpool/agents/events/events.py +84 -3
  37. agentpool/agents/events/infer_info.py +145 -0
  38. agentpool/agents/events/processors.py +254 -0
  39. agentpool/agents/interactions.py +41 -6
  40. agentpool/agents/modes.py +13 -0
  41. agentpool/agents/slashed_agent.py +5 -4
  42. agentpool/agents/tool_wrapping.py +18 -6
  43. agentpool/common_types.py +35 -21
  44. agentpool/config_resources/acp_assistant.yml +2 -2
  45. agentpool/config_resources/agents.yml +3 -0
  46. agentpool/config_resources/agents_template.yml +1 -0
  47. agentpool/config_resources/claude_code_agent.yml +9 -8
  48. agentpool/config_resources/external_acp_agents.yml +2 -1
  49. agentpool/delegation/base_team.py +4 -30
  50. agentpool/delegation/pool.py +104 -265
  51. agentpool/delegation/team.py +57 -57
  52. agentpool/delegation/teamrun.py +50 -55
  53. agentpool/functional/run.py +10 -4
  54. agentpool/mcp_server/client.py +73 -38
  55. agentpool/mcp_server/conversions.py +54 -13
  56. agentpool/mcp_server/manager.py +9 -23
  57. agentpool/mcp_server/registries/official_registry_client.py +10 -1
  58. agentpool/mcp_server/tool_bridge.py +114 -79
  59. agentpool/messaging/connection_manager.py +11 -10
  60. agentpool/messaging/event_manager.py +5 -5
  61. agentpool/messaging/message_container.py +6 -30
  62. agentpool/messaging/message_history.py +87 -8
  63. agentpool/messaging/messagenode.py +52 -14
  64. agentpool/messaging/messages.py +2 -26
  65. agentpool/messaging/processing.py +10 -22
  66. agentpool/models/__init__.py +1 -1
  67. agentpool/models/acp_agents/base.py +6 -2
  68. agentpool/models/acp_agents/mcp_capable.py +124 -15
  69. agentpool/models/acp_agents/non_mcp.py +0 -23
  70. agentpool/models/agents.py +66 -66
  71. agentpool/models/agui_agents.py +1 -1
  72. agentpool/models/claude_code_agents.py +111 -17
  73. agentpool/models/file_parsing.py +0 -1
  74. agentpool/models/manifest.py +70 -50
  75. agentpool/prompts/conversion_manager.py +1 -1
  76. agentpool/prompts/prompts.py +5 -2
  77. agentpool/resource_providers/__init__.py +2 -0
  78. agentpool/resource_providers/aggregating.py +4 -2
  79. agentpool/resource_providers/base.py +13 -3
  80. agentpool/resource_providers/codemode/code_executor.py +72 -5
  81. agentpool/resource_providers/codemode/helpers.py +2 -2
  82. agentpool/resource_providers/codemode/provider.py +64 -12
  83. agentpool/resource_providers/codemode/remote_mcp_execution.py +2 -2
  84. agentpool/resource_providers/codemode/remote_provider.py +9 -12
  85. agentpool/resource_providers/filtering.py +3 -1
  86. agentpool/resource_providers/mcp_provider.py +66 -12
  87. agentpool/resource_providers/plan_provider.py +111 -18
  88. agentpool/resource_providers/pool.py +5 -3
  89. agentpool/resource_providers/resource_info.py +111 -0
  90. agentpool/resource_providers/static.py +2 -2
  91. agentpool/sessions/__init__.py +2 -0
  92. agentpool/sessions/manager.py +2 -3
  93. agentpool/sessions/models.py +9 -6
  94. agentpool/sessions/protocol.py +28 -0
  95. agentpool/sessions/session.py +11 -55
  96. agentpool/storage/manager.py +361 -54
  97. agentpool/talk/registry.py +4 -4
  98. agentpool/talk/talk.py +9 -10
  99. agentpool/testing.py +1 -1
  100. agentpool/tool_impls/__init__.py +6 -0
  101. agentpool/tool_impls/agent_cli/__init__.py +42 -0
  102. agentpool/tool_impls/agent_cli/tool.py +95 -0
  103. agentpool/tool_impls/bash/__init__.py +64 -0
  104. agentpool/tool_impls/bash/helpers.py +35 -0
  105. agentpool/tool_impls/bash/tool.py +171 -0
  106. agentpool/tool_impls/delete_path/__init__.py +70 -0
  107. agentpool/tool_impls/delete_path/tool.py +142 -0
  108. agentpool/tool_impls/download_file/__init__.py +80 -0
  109. agentpool/tool_impls/download_file/tool.py +183 -0
  110. agentpool/tool_impls/execute_code/__init__.py +55 -0
  111. agentpool/tool_impls/execute_code/tool.py +163 -0
  112. agentpool/tool_impls/grep/__init__.py +80 -0
  113. agentpool/tool_impls/grep/tool.py +200 -0
  114. agentpool/tool_impls/list_directory/__init__.py +73 -0
  115. agentpool/tool_impls/list_directory/tool.py +197 -0
  116. agentpool/tool_impls/question/__init__.py +42 -0
  117. agentpool/tool_impls/question/tool.py +127 -0
  118. agentpool/tool_impls/read/__init__.py +104 -0
  119. agentpool/tool_impls/read/tool.py +305 -0
  120. agentpool/tools/__init__.py +2 -1
  121. agentpool/tools/base.py +114 -34
  122. agentpool/tools/manager.py +57 -1
  123. agentpool/ui/base.py +2 -2
  124. agentpool/ui/mock_provider.py +2 -2
  125. agentpool/ui/stdlib_provider.py +2 -2
  126. agentpool/utils/streams.py +21 -96
  127. agentpool/vfs_registry.py +7 -2
  128. {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/METADATA +16 -22
  129. {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/RECORD +242 -195
  130. {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/WHEEL +1 -1
  131. agentpool_cli/__main__.py +20 -0
  132. agentpool_cli/create.py +1 -1
  133. agentpool_cli/serve_acp.py +59 -1
  134. agentpool_cli/serve_opencode.py +1 -1
  135. agentpool_cli/ui.py +557 -0
  136. agentpool_commands/__init__.py +12 -5
  137. agentpool_commands/agents.py +1 -1
  138. agentpool_commands/pool.py +260 -0
  139. agentpool_commands/session.py +1 -1
  140. agentpool_commands/text_sharing/__init__.py +119 -0
  141. agentpool_commands/text_sharing/base.py +123 -0
  142. agentpool_commands/text_sharing/github_gist.py +80 -0
  143. agentpool_commands/text_sharing/opencode.py +462 -0
  144. agentpool_commands/text_sharing/paste_rs.py +59 -0
  145. agentpool_commands/text_sharing/pastebin.py +116 -0
  146. agentpool_commands/text_sharing/shittycodingagent.py +112 -0
  147. agentpool_commands/utils.py +31 -32
  148. agentpool_config/__init__.py +30 -2
  149. agentpool_config/agentpool_tools.py +498 -0
  150. agentpool_config/converters.py +1 -1
  151. agentpool_config/event_handlers.py +42 -0
  152. agentpool_config/events.py +1 -1
  153. agentpool_config/forward_targets.py +1 -4
  154. agentpool_config/jinja.py +3 -3
  155. agentpool_config/mcp_server.py +1 -5
  156. agentpool_config/nodes.py +1 -1
  157. agentpool_config/observability.py +44 -0
  158. agentpool_config/session.py +0 -3
  159. agentpool_config/storage.py +38 -39
  160. agentpool_config/task.py +3 -3
  161. agentpool_config/tools.py +11 -28
  162. agentpool_config/toolsets.py +22 -90
  163. agentpool_server/a2a_server/agent_worker.py +307 -0
  164. agentpool_server/a2a_server/server.py +23 -18
  165. agentpool_server/acp_server/acp_agent.py +125 -56
  166. agentpool_server/acp_server/commands/acp_commands.py +46 -216
  167. agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +8 -7
  168. agentpool_server/acp_server/event_converter.py +651 -0
  169. agentpool_server/acp_server/input_provider.py +53 -10
  170. agentpool_server/acp_server/server.py +1 -11
  171. agentpool_server/acp_server/session.py +90 -410
  172. agentpool_server/acp_server/session_manager.py +8 -34
  173. agentpool_server/agui_server/server.py +3 -1
  174. agentpool_server/mcp_server/server.py +5 -2
  175. agentpool_server/opencode_server/ENDPOINTS.md +53 -14
  176. agentpool_server/opencode_server/OPENCODE_UI_TOOLS_COMPLETE.md +202 -0
  177. agentpool_server/opencode_server/__init__.py +0 -8
  178. agentpool_server/opencode_server/converters.py +132 -26
  179. agentpool_server/opencode_server/input_provider.py +160 -8
  180. agentpool_server/opencode_server/models/__init__.py +42 -20
  181. agentpool_server/opencode_server/models/app.py +12 -0
  182. agentpool_server/opencode_server/models/events.py +203 -29
  183. agentpool_server/opencode_server/models/mcp.py +19 -0
  184. agentpool_server/opencode_server/models/message.py +18 -1
  185. agentpool_server/opencode_server/models/parts.py +134 -1
  186. agentpool_server/opencode_server/models/question.py +56 -0
  187. agentpool_server/opencode_server/models/session.py +13 -1
  188. agentpool_server/opencode_server/routes/__init__.py +4 -0
  189. agentpool_server/opencode_server/routes/agent_routes.py +33 -2
  190. agentpool_server/opencode_server/routes/app_routes.py +66 -3
  191. agentpool_server/opencode_server/routes/config_routes.py +66 -5
  192. agentpool_server/opencode_server/routes/file_routes.py +184 -5
  193. agentpool_server/opencode_server/routes/global_routes.py +1 -1
  194. agentpool_server/opencode_server/routes/lsp_routes.py +1 -1
  195. agentpool_server/opencode_server/routes/message_routes.py +122 -66
  196. agentpool_server/opencode_server/routes/permission_routes.py +63 -0
  197. agentpool_server/opencode_server/routes/pty_routes.py +23 -22
  198. agentpool_server/opencode_server/routes/question_routes.py +128 -0
  199. agentpool_server/opencode_server/routes/session_routes.py +139 -68
  200. agentpool_server/opencode_server/routes/tui_routes.py +1 -1
  201. agentpool_server/opencode_server/server.py +47 -2
  202. agentpool_server/opencode_server/state.py +30 -0
  203. agentpool_storage/__init__.py +0 -4
  204. agentpool_storage/base.py +81 -2
  205. agentpool_storage/claude_provider/ARCHITECTURE.md +433 -0
  206. agentpool_storage/claude_provider/__init__.py +42 -0
  207. agentpool_storage/{claude_provider.py → claude_provider/provider.py} +190 -8
  208. agentpool_storage/file_provider.py +149 -15
  209. agentpool_storage/memory_provider.py +132 -12
  210. agentpool_storage/opencode_provider/ARCHITECTURE.md +386 -0
  211. agentpool_storage/opencode_provider/__init__.py +16 -0
  212. agentpool_storage/opencode_provider/helpers.py +414 -0
  213. agentpool_storage/opencode_provider/provider.py +895 -0
  214. agentpool_storage/session_store.py +20 -6
  215. agentpool_storage/sql_provider/sql_provider.py +135 -2
  216. agentpool_storage/sql_provider/utils.py +2 -12
  217. agentpool_storage/zed_provider/__init__.py +16 -0
  218. agentpool_storage/zed_provider/helpers.py +281 -0
  219. agentpool_storage/zed_provider/models.py +130 -0
  220. agentpool_storage/zed_provider/provider.py +442 -0
  221. agentpool_storage/zed_provider.py +803 -0
  222. agentpool_toolsets/__init__.py +0 -2
  223. agentpool_toolsets/builtin/__init__.py +2 -4
  224. agentpool_toolsets/builtin/code.py +4 -4
  225. agentpool_toolsets/builtin/debug.py +115 -40
  226. agentpool_toolsets/builtin/execution_environment.py +54 -165
  227. agentpool_toolsets/builtin/skills.py +0 -77
  228. agentpool_toolsets/builtin/subagent_tools.py +64 -51
  229. agentpool_toolsets/builtin/workers.py +4 -2
  230. agentpool_toolsets/composio_toolset.py +2 -2
  231. agentpool_toolsets/entry_points.py +3 -1
  232. agentpool_toolsets/fsspec_toolset/grep.py +25 -5
  233. agentpool_toolsets/fsspec_toolset/helpers.py +3 -2
  234. agentpool_toolsets/fsspec_toolset/toolset.py +350 -66
  235. agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
  236. agentpool_toolsets/mcp_discovery/toolset.py +74 -17
  237. agentpool_toolsets/mcp_run_toolset.py +8 -11
  238. agentpool_toolsets/notifications.py +33 -33
  239. agentpool_toolsets/openapi.py +3 -1
  240. agentpool_toolsets/search_toolset.py +3 -1
  241. agentpool_config/resources.py +0 -33
  242. agentpool_server/acp_server/acp_tools.py +0 -43
  243. agentpool_server/acp_server/commands/spawn.py +0 -210
  244. agentpool_storage/opencode_provider.py +0 -730
  245. agentpool_storage/text_log_provider.py +0 -276
  246. agentpool_toolsets/builtin/chain.py +0 -288
  247. agentpool_toolsets/builtin/user_interaction.py +0 -52
  248. agentpool_toolsets/semantic_memory_toolset.py +0 -536
  249. {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/entry_points.txt +0 -0
  250. {agentpool-2.2.3.dist-info → agentpool-2.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -7,11 +7,10 @@ from asyncio import Lock
7
7
  from contextlib import AsyncExitStack, asynccontextmanager, suppress
8
8
  import os
9
9
  from pathlib import Path
10
- from typing import TYPE_CHECKING, Any, Literal, Self, Unpack, overload
10
+ from typing import TYPE_CHECKING, Any, Self, Unpack, overload
11
11
 
12
12
  from anyenv import ProcessManager
13
13
  import anyio
14
- from llmling_models.configs.model_configs import BaseModelConfig
15
14
  from upathtools import UPath
16
15
 
17
16
  from agentpool.agents import Agent
@@ -51,21 +50,14 @@ if TYPE_CHECKING:
51
50
  AgentName,
52
51
  BuiltinEventHandlerType,
53
52
  IndividualEventHandler,
54
- SessionIdType,
55
- SupportsStructuredOutput,
56
53
  )
57
54
  from agentpool.delegation.base_team import BaseTeam
58
55
  from agentpool.mcp_server.tool_bridge import ToolManagerBridge
56
+ from agentpool.messaging import ChatMessage
59
57
  from agentpool.messaging.compaction import CompactionPipeline
60
- from agentpool.models import (
61
- AGUIAgentConfig,
62
- AnyAgentConfig,
63
- BaseACPAgentConfig,
64
- ClaudeCodeAgentConfig,
65
- )
58
+ from agentpool.models import AnyAgentConfig
66
59
  from agentpool.models.manifest import AgentsManifest
67
60
  from agentpool.ui.base import InputProvider
68
- from agentpool_config.session import SessionQuery
69
61
  from agentpool_config.task import Job
70
62
 
71
63
 
@@ -111,7 +103,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
111
103
  ValueError: If manifest contains invalid node configurations
112
104
  RuntimeError: If node initialization fails
113
105
  """
114
- super().__init__()
115
106
  from agentpool.mcp_server.manager import MCPManager
116
107
  from agentpool.models.manifest import AgentsManifest
117
108
  from agentpool.observability import registry
@@ -119,6 +110,9 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
119
110
  from agentpool.skills.manager import SkillsManager
120
111
  from agentpool.storage import StorageManager
121
112
  from agentpool.utils.streams import FileOpsTracker, TodoTracker
113
+ from agentpool_toolsets.builtin.debug import install_memory_handler
114
+
115
+ super().__init__()
122
116
 
123
117
  match manifest:
124
118
  case None:
@@ -132,12 +126,7 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
132
126
  raise ValueError(msg)
133
127
 
134
128
  registry.configure_observability(self.manifest.observability)
135
-
136
- # Install memory log handler early so all logs are captured
137
- from agentpool_toolsets.builtin.debug import install_memory_handler
138
-
139
129
  self._memory_log_handler = install_memory_handler()
140
-
141
130
  self.shared_deps_type = shared_deps_type
142
131
  self._input_provider = input_provider
143
132
  self.exit_stack = AsyncExitStack()
@@ -156,7 +145,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
156
145
  for name, task in self.manifest.jobs.items():
157
146
  self._tasks.register(name, task)
158
147
  self.process_manager = ProcessManager()
159
- self.pool_talk = TeamTalk[Any].from_nodes(list(self.nodes.values()))
160
148
  self.file_ops = FileOpsTracker()
161
149
  # Todo/plan tracker for task management
162
150
  self.todos = TodoTracker()
@@ -169,7 +157,7 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
169
157
  self._create_teams()
170
158
  if connect_nodes:
171
159
  self._connect_nodes()
172
-
160
+ self.pool_talk = TeamTalk[Any].from_nodes(list(self.nodes.values()))
173
161
  self._enter_lock = Lock() # Initialize async safety fields
174
162
  self._running_count = 0
175
163
 
@@ -236,7 +224,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
236
224
  name: str = "pool_tools",
237
225
  host: str = "127.0.0.1",
238
226
  port: int = 0,
239
- transport: Literal["sse", "streamable-http"] = "sse",
240
227
  ) -> ToolManagerBridge:
241
228
  """Create and start a tool bridge for exposing tools to external agents.
242
229
 
@@ -249,7 +236,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
249
236
  name: Unique name for this bridge
250
237
  host: Host to bind the HTTP server to
251
238
  port: Port to bind to (0 = auto-select)
252
- transport: Transport protocol ('sse' or 'streamable-http')
253
239
 
254
240
  Returns:
255
241
  Started ToolManagerBridge instance
@@ -277,7 +263,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
277
263
  config = BridgeConfig(
278
264
  host=host,
279
265
  port=port,
280
- transport=transport,
281
266
  server_name=f"agentpool-{name}",
282
267
  )
283
268
  bridge = ToolManagerBridge(node=node, config=config)
@@ -323,9 +308,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
323
308
  name: str | None = None,
324
309
  description: str | None = None,
325
310
  shared_prompt: str | None = None,
326
- picker: SupportsStructuredOutput | None = None,
327
- num_picks: int | None = None,
328
- pick_prompt: str | None = None,
329
311
  ) -> TeamRun[TPoolDeps, TResult]: ...
330
312
 
331
313
  @overload
@@ -337,9 +319,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
337
319
  name: str | None = None,
338
320
  description: str | None = None,
339
321
  shared_prompt: str | None = None,
340
- picker: SupportsStructuredOutput | None = None,
341
- num_picks: int | None = None,
342
- pick_prompt: str | None = None,
343
322
  ) -> TeamRun[TDeps, TResult]: ...
344
323
 
345
324
  @overload
@@ -351,9 +330,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
351
330
  name: str | None = None,
352
331
  description: str | None = None,
353
332
  shared_prompt: str | None = None,
354
- picker: SupportsStructuredOutput | None = None,
355
- num_picks: int | None = None,
356
- pick_prompt: str | None = None,
357
333
  ) -> TeamRun[Any, TResult]: ...
358
334
 
359
335
  def create_team_run[TResult](
@@ -364,9 +340,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
364
340
  name: str | None = None,
365
341
  description: str | None = None,
366
342
  shared_prompt: str | None = None,
367
- picker: SupportsStructuredOutput | None = None,
368
- num_picks: int | None = None,
369
- pick_prompt: str | None = None,
370
343
  ) -> TeamRun[Any, TResult]:
371
344
  """Create a a sequential TeamRun from a list of Agents.
372
345
 
@@ -376,9 +349,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
376
349
  name: Optional name for the team
377
350
  description: Optional description for the team
378
351
  shared_prompt: Optional prompt for all agents
379
- picker: Agent to use for picking agents
380
- num_picks: Number of agents to pick
381
- pick_prompt: Prompt to use for picking agents
382
352
  """
383
353
  from agentpool.delegation.teamrun import TeamRun
384
354
 
@@ -390,9 +360,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
390
360
  description=description,
391
361
  validator=validator,
392
362
  shared_prompt=shared_prompt,
393
- picker=picker,
394
- num_picks=num_picks,
395
- pick_prompt=pick_prompt,
396
363
  )
397
364
  if name:
398
365
  self[name] = team
@@ -409,9 +376,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
409
376
  name: str | None = None,
410
377
  description: str | None = None,
411
378
  shared_prompt: str | None = None,
412
- picker: SupportsStructuredOutput | None = None,
413
- num_picks: int | None = None,
414
- pick_prompt: str | None = None,
415
379
  ) -> Team[TDeps]: ...
416
380
 
417
381
  @overload
@@ -422,9 +386,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
422
386
  name: str | None = None,
423
387
  description: str | None = None,
424
388
  shared_prompt: str | None = None,
425
- picker: SupportsStructuredOutput | None = None,
426
- num_picks: int | None = None,
427
- pick_prompt: str | None = None,
428
389
  ) -> Team[Any]: ...
429
390
 
430
391
  def create_team(
@@ -434,9 +395,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
434
395
  name: str | None = None,
435
396
  description: str | None = None,
436
397
  shared_prompt: str | None = None,
437
- picker: SupportsStructuredOutput | None = None,
438
- num_picks: int | None = None,
439
- pick_prompt: str | None = None,
440
398
  ) -> Team[Any]:
441
399
  """Create a group from agent names or instances.
442
400
 
@@ -445,9 +403,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
445
403
  name: Optional name for the team
446
404
  description: Optional description for the team
447
405
  shared_prompt: Optional prompt for all agents
448
- picker: Agent to use for picking agents
449
- num_picks: Number of agents to pick
450
- pick_prompt: Prompt to use for picking agents
451
406
  """
452
407
  from agentpool.delegation.team import Team
453
408
 
@@ -459,9 +414,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
459
414
  description=description,
460
415
  agents=[self.get_agent(i) if isinstance(i, str) else i for i in agents],
461
416
  shared_prompt=shared_prompt,
462
- picker=picker,
463
- num_picks=num_picks,
464
- pick_prompt=pick_prompt,
465
417
  )
466
418
  if name:
467
419
  self[name] = team
@@ -633,18 +585,14 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
633
585
  stop_condition=target.stop_condition.check if target.stop_condition else None,
634
586
  exit_condition=target.exit_condition.check if target.exit_condition else None,
635
587
  )
636
- source.connections.set_wait_state(
637
- target_node,
638
- wait=target.wait_for_completion,
639
- )
588
+ source.connections.set_wait_state(target_node, wait=target.wait_for_completion)
640
589
 
641
590
  @overload
642
591
  def get_agent[TResult = str](
643
592
  self,
644
593
  agent: AgentName | Agent[Any, str],
645
594
  *,
646
- return_type: type[TResult] = str, # type: ignore
647
- session: SessionIdType | SessionQuery = None,
595
+ output_type: type[TResult] = str, # type: ignore
648
596
  ) -> Agent[TPoolDeps, TResult]: ...
649
597
 
650
598
  @overload
@@ -653,8 +601,7 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
653
601
  agent: AgentName | Agent[Any, str],
654
602
  *,
655
603
  deps_type: type[TCustomDeps],
656
- return_type: type[TResult] = str, # type: ignore
657
- session: SessionIdType | SessionQuery = None,
604
+ output_type: type[TResult] = str, # type: ignore
658
605
  ) -> Agent[TCustomDeps, TResult]: ...
659
606
 
660
607
  def get_agent(
@@ -662,8 +609,7 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
662
609
  agent: AgentName | Agent[Any, str],
663
610
  *,
664
611
  deps_type: Any | None = None,
665
- return_type: Any = str,
666
- session: SessionIdType | SessionQuery = None,
612
+ output_type: Any = str,
667
613
  ) -> Agent[Any, Any]:
668
614
  """Get or configure an agent from the pool.
669
615
 
@@ -674,8 +620,7 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
674
620
  Args:
675
621
  agent: Either agent name or instance
676
622
  deps_type: Optional custom dependencies type (overrides shared deps)
677
- return_type: Optional type for structured responses
678
- session: Optional session ID or query to recover conversation
623
+ output_type: Optional type for structured responses
679
624
 
680
625
  Returns:
681
626
  Either:
@@ -697,11 +642,8 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
697
642
  # base.context.data = deps if deps is not None else self.shared_deps
698
643
  base.deps_type = deps_type
699
644
  base.agent_pool = self
700
- if session:
701
- base.conversation.load_history_from_database(session=session)
702
- if return_type not in {str, None}:
703
- base.to_structured(return_type)
704
-
645
+ if output_type not in {str, None}:
646
+ base.to_structured(output_type)
705
647
  return base
706
648
 
707
649
  def get_job(self, name: str) -> Job[Any, Any]:
@@ -780,6 +722,55 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
780
722
 
781
723
  return "\n".join(lines)
782
724
 
725
+ def get_message_chain(self, message: ChatMessage[Any]) -> list[str]:
726
+ """Get the chain of agent names that processed a message.
727
+
728
+ Reconstructs the forwarding chain by walking parent_id references
729
+ across all agents' conversations in the pool.
730
+
731
+ Args:
732
+ message: The message to trace back
733
+
734
+ Returns:
735
+ List of agent names in order from origin to current message's agent.
736
+ Empty list if message has no parent or parent not found.
737
+ """
738
+ # Build index of all messages by ID across all agents
739
+ message_index: dict[str, tuple[ChatMessage[Any], str]] = {}
740
+ for agent in self.agents.values():
741
+ for msg in agent.conversation.chat_messages:
742
+ message_index[msg.message_id] = (msg, agent.name)
743
+
744
+ # Walk back through parent_id chain
745
+ chain: list[str] = []
746
+ current_id = message.parent_id
747
+
748
+ while current_id and current_id in message_index:
749
+ parent_msg, agent_name = message_index[current_id]
750
+ # Only add agent name if it's different from previous (avoid duplicates)
751
+ if not chain or chain[-1] != agent_name:
752
+ chain.append(agent_name)
753
+ current_id = parent_msg.parent_id
754
+
755
+ # Reverse to get origin -> current order
756
+ chain.reverse()
757
+ return chain
758
+
759
+ def find_message_by_id(self, message_id: str) -> ChatMessage[Any] | None:
760
+ """Find a message by ID across all agents in the pool.
761
+
762
+ Args:
763
+ message_id: The message ID to search for
764
+
765
+ Returns:
766
+ The ChatMessage if found, None otherwise
767
+ """
768
+ for agent in self.agents.values():
769
+ for msg in agent.conversation.chat_messages:
770
+ if msg.message_id == message_id:
771
+ return msg
772
+ return None
773
+
783
774
  def _create_agent_from_config[TAgentDeps](
784
775
  self,
785
776
  name: str,
@@ -807,99 +798,56 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
807
798
 
808
799
  match config:
809
800
  case NativeAgentConfig():
810
- return self.create_agent(
811
- name,
812
- deps_type=deps_type,
813
- input_provider=self._input_provider,
814
- pool=self,
801
+ from agentpool import Agent
802
+
803
+ return Agent.from_config(
804
+ config,
805
+ name=name, # Pass dict key for manifest lookups
806
+ manifest=self.manifest,
815
807
  event_handlers=self.event_handlers,
808
+ input_provider=self._input_provider,
809
+ agent_pool=self,
810
+ deps_type=deps_type,
816
811
  )
817
812
  case AGUIAgentConfig():
818
- return self._create_agui_agent_from_config(config, deps_type)
813
+ from agentpool.agents.agui_agent import AGUIAgent
814
+
815
+ return AGUIAgent.from_config(
816
+ config,
817
+ event_handlers=self.event_handlers,
818
+ agent_pool=self,
819
+ )
819
820
  case ClaudeCodeAgentConfig():
820
- return self._create_claude_code_agent_from_config(config, deps_type)
821
+ from agentpool.agents.claude_code_agent import ClaudeCodeAgent
822
+ from agentpool.utils.result_utils import to_type
823
+
824
+ output_type: type | None = None
825
+ if config.output_type:
826
+ output_type = to_type(config.output_type, self.manifest.responses)
827
+ return ClaudeCodeAgent.from_config(
828
+ config,
829
+ event_handlers=self.event_handlers,
830
+ input_provider=self._input_provider,
831
+ agent_pool=self,
832
+ output_type=output_type,
833
+ )
821
834
  case BaseACPAgentConfig():
822
- return self._create_acp_agent_from_config(config, deps_type)
835
+ from agentpool.agents.acp_agent import ACPAgent
836
+
837
+ return ACPAgent.from_config(
838
+ config,
839
+ event_handlers=self.event_handlers,
840
+ agent_pool=self,
841
+ )
823
842
  case _:
824
843
  msg = f"Unknown agent config type: {type(config)}"
825
844
  raise TypeError(msg)
826
845
 
827
- def _create_acp_agent_from_config[TDeps](
828
- self,
829
- config: BaseACPAgentConfig,
830
- deps_type: type[TDeps] | None = None,
831
- ) -> ACPAgent[TDeps]:
832
- """Create an ACPAgent from config object."""
833
- from agentpool.agents.acp_agent import ACPAgent
834
-
835
- config_handlers = config.get_event_handlers()
836
- merged_handlers: list[IndividualEventHandler | BuiltinEventHandlerType] = [
837
- *config_handlers,
838
- *self.event_handlers,
839
- ]
840
- return ACPAgent(config=config, event_handlers=merged_handlers or None)
841
-
842
- def _create_agui_agent_from_config[TDeps](
843
- self,
844
- config: AGUIAgentConfig,
845
- deps_type: type[TDeps] | None = None,
846
- ) -> AGUIAgent[TDeps]:
847
- """Create an AGUIAgent from config object."""
848
- from agentpool.agents.agui_agent import AGUIAgent
849
-
850
- config_handlers = config.get_event_handlers()
851
- merged_handlers: list[IndividualEventHandler | BuiltinEventHandlerType] = [
852
- *config_handlers,
853
- *self.event_handlers,
854
- ]
855
- return AGUIAgent(
856
- endpoint=config.endpoint,
857
- name=config.name or "agui-agent",
858
- description=config.description,
859
- display_name=config.display_name,
860
- event_handlers=merged_handlers or None,
861
- timeout=config.timeout,
862
- headers=config.headers,
863
- startup_command=config.startup_command,
864
- startup_delay=config.startup_delay,
865
- tools=[tool_config.get_tool() for tool_config in config.tools],
866
- mcp_servers=config.mcp_servers,
867
- tool_confirmation_mode=config.requires_tool_confirmation,
868
- )
869
-
870
- def _create_claude_code_agent_from_config[TDeps, TResult](
871
- self,
872
- config: ClaudeCodeAgentConfig,
873
- deps_type: type[TDeps] | None = None,
874
- ) -> ClaudeCodeAgent[TDeps, TResult]:
875
- """Create a ClaudeCodeAgent from config object."""
876
- from agentpool.agents.claude_code_agent import ClaudeCodeAgent
877
- from agentpool.utils.result_utils import to_type
878
-
879
- config_handlers = config.get_event_handlers()
880
- merged_handlers: list[IndividualEventHandler | BuiltinEventHandlerType] = [
881
- *config_handlers,
882
- *self.event_handlers,
883
- ]
884
- # Resolve output type if configured
885
- output_type: type | None = None
886
- if config.output_type:
887
- output_type = to_type(config.output_type, self.manifest.responses)
888
- return ClaudeCodeAgent(
889
- config=config,
890
- event_handlers=merged_handlers or None,
891
- input_provider=self._input_provider,
892
- tool_confirmation_mode=config.requires_tool_confirmation,
893
- output_type=output_type,
894
- agent_pool=self,
895
- )
896
-
897
846
  def create_agent[TAgentDeps]( # noqa: PLR0915
898
847
  self,
899
848
  name: str,
900
849
  deps_type: type[TAgentDeps] | None = None,
901
850
  input_provider: InputProvider | None = None,
902
- pool: AgentPool[Any] | None = None,
903
851
  event_handlers: list[IndividualEventHandler | BuiltinEventHandlerType] | None = None,
904
852
  ) -> Agent[TAgentDeps, Any]:
905
853
  from agentpool import Agent
@@ -980,16 +928,10 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
980
928
  *config_handlers,
981
929
  *(event_handlers or []),
982
930
  ]
983
- match config.model:
984
- case str():
985
- model: Model | str | None = config.model
986
- model_settings: ModelSettings | None = None
987
- case BaseModelConfig():
988
- model = config.model.get_model()
989
- model_settings = config.model.get_model_settings()
990
- case _:
991
- model = None
992
- model_settings = None
931
+ # Resolve model (handles variants and wraps strings)
932
+ resolved_model = self.manifest.resolve_model(config.model)
933
+ model: Model | str = resolved_model.get_model()
934
+ model_settings: ModelSettings | None = resolved_model.get_model_settings()
993
935
  # Extract pydantic-ai builtin tools from config
994
936
  builtin_tools = config.get_builtin_tools()
995
937
 
@@ -1011,7 +953,7 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
1011
953
  input_provider=input_provider,
1012
954
  output_type=resolved_output_type,
1013
955
  event_handlers=merged_handlers or None,
1014
- agent_pool=pool,
956
+ agent_pool=self,
1015
957
  tool_mode=config.tool_mode,
1016
958
  knowledge=config.knowledge,
1017
959
  toolsets=toolsets_list,
@@ -1022,109 +964,6 @@ class AgentPool[TPoolDeps = None](BaseRegistry[NodeName, MessageNode[Any, Any]])
1022
964
  providers=config.model_providers,
1023
965
  )
1024
966
 
1025
- def create_acp_agent[TDeps](
1026
- self,
1027
- name: str,
1028
- deps_type: type[TDeps] | None = None,
1029
- ) -> ACPAgent[TDeps]:
1030
- """Create an ACPAgent from configuration.
1031
-
1032
- Args:
1033
- name: Name of the ACP agent in the manifest
1034
- deps_type: Optional dependency type (not used by ACP agents currently)
1035
-
1036
- Returns:
1037
- Configured ACPAgent instance
1038
- """
1039
- from agentpool.agents.acp_agent import ACPAgent
1040
-
1041
- config = self.manifest.acp_agents[name]
1042
- # Ensure name is set on config
1043
- if config.name is None:
1044
- config = config.model_copy(update={"name": name})
1045
- # Merge pool-level handlers with config-level handlers
1046
- config_handlers = config.get_event_handlers()
1047
- merged_handlers: list[IndividualEventHandler | BuiltinEventHandlerType] = [
1048
- *config_handlers,
1049
- *self.event_handlers,
1050
- ]
1051
- return ACPAgent(config=config, event_handlers=merged_handlers or None)
1052
-
1053
- def create_agui_agent[TDeps](
1054
- self,
1055
- name: str,
1056
- deps_type: type[TDeps] | None = None,
1057
- ) -> AGUIAgent[TDeps]:
1058
- """Create an AGUIAgent from configuration.
1059
-
1060
- Args:
1061
- name: Name of the AG-UI agent in the manifest
1062
- deps_type: Optional dependency type (not used by AG-UI agents currently)
1063
-
1064
- Returns:
1065
- Configured AGUIAgent instance
1066
- """
1067
- from agentpool.agents.agui_agent import AGUIAgent
1068
-
1069
- config = self.manifest.agui_agents[name]
1070
- # Ensure name is set on config
1071
- if config.name is None:
1072
- config = config.model_copy(update={"name": name})
1073
- # Merge pool-level handlers with config-level handlers
1074
- config_handlers = config.get_event_handlers()
1075
- merged_handlers: list[IndividualEventHandler | BuiltinEventHandlerType] = [
1076
- *config_handlers,
1077
- *self.event_handlers,
1078
- ]
1079
- return AGUIAgent(
1080
- endpoint=config.endpoint,
1081
- name=config.name or "agui-agent",
1082
- description=config.description,
1083
- display_name=config.display_name,
1084
- event_handlers=merged_handlers or None,
1085
- timeout=config.timeout,
1086
- headers=config.headers,
1087
- startup_command=config.startup_command,
1088
- startup_delay=config.startup_delay,
1089
- tools=[tool_config.get_tool() for tool_config in config.tools],
1090
- mcp_servers=config.mcp_servers,
1091
- tool_confirmation_mode=config.requires_tool_confirmation,
1092
- )
1093
-
1094
- def create_claude_code_agent[TDeps](
1095
- self,
1096
- name: str,
1097
- deps_type: type[TDeps] | None = None,
1098
- ) -> ClaudeCodeAgent[TDeps, str]:
1099
- """Create a ClaudeCodeAgent from configuration.
1100
-
1101
- Args:
1102
- name: Name of the Claude Code agent in the manifest
1103
- deps_type: Optional dependency type (not used by Claude Code agents currently)
1104
-
1105
- Returns:
1106
- Configured ClaudeCodeAgent instance
1107
- """
1108
- from agentpool.agents.claude_code_agent import ClaudeCodeAgent
1109
-
1110
- config = self.manifest.claude_code_agents[name]
1111
- # Ensure name is set on config
1112
- if config.name is None:
1113
- config = config.model_copy(update={"name": name})
1114
- # Merge pool-level handlers with config-level handlers
1115
- config_handlers = config.get_event_handlers()
1116
- merged_handlers: list[IndividualEventHandler | BuiltinEventHandlerType] = [
1117
- *config_handlers,
1118
- *self.event_handlers,
1119
- ]
1120
- return ClaudeCodeAgent(
1121
- config=config,
1122
- event_handlers=merged_handlers or None,
1123
- input_provider=self._input_provider,
1124
- tool_confirmation_mode=config.requires_tool_confirmation,
1125
- agent_pool=self,
1126
- )
1127
-
1128
967
 
1129
968
  if __name__ == "__main__":
1130
969