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
@@ -13,29 +13,6 @@ if TYPE_CHECKING:
13
13
  from agentpool.prompts.manager import PromptManager
14
14
 
15
15
 
16
- ClaudeCodeModelName = Literal["default", "sonnet", "opus", "haiku", "sonnet[1m]", "opusplan"]
17
- ClaudeCodeToolName = Literal[
18
- "AskUserQuestion",
19
- "Bash",
20
- "BashOutput",
21
- "Edit",
22
- "ExitPlanMode",
23
- "Glob",
24
- "Grep",
25
- "KillShell",
26
- "NotebookEdit",
27
- "Read",
28
- "Skill",
29
- "SlashCommand",
30
- "Task",
31
- "TodoWrite",
32
- "WebFetch",
33
- "WebSearch",
34
- "Write",
35
- ]
36
- ClaudeCodePermissionmode = Literal["default", "acceptEdits", "bypassPermissions", "dontAsk", "plan"]
37
-
38
-
39
16
  class CodexACPAgentConfig(BaseACPAgentConfig):
40
17
  """Configuration for Zed Codex via ACP.
41
18
 
@@ -4,11 +4,11 @@ from __future__ import annotations
4
4
 
5
5
  from collections.abc import Sequence # noqa: TC003
6
6
  from pathlib import Path
7
- from typing import TYPE_CHECKING, Any, Literal, assert_never
7
+ from typing import TYPE_CHECKING, Annotated, Any, Literal, assert_never
8
8
  from uuid import UUID
9
9
 
10
- from exxec.configs import ExecutionEnvironmentConfig # noqa: TC002
11
- from llmling_models.configs import AnyModelConfig # noqa: TC002
10
+ from exxec_config import ExecutionEnvironmentConfig # noqa: TC002
11
+ from llmling_models_config import AnyModelConfig # noqa: TC002
12
12
  from pydantic import ConfigDict, Field, model_validator
13
13
  from pydantic_ai import UsageLimits # noqa: TC002
14
14
  from schemez import InlineSchemaDef
@@ -20,6 +20,7 @@ from agentpool import log
20
20
  from agentpool.common_types import EndStrategy # noqa: TC001
21
21
  from agentpool.prompts.prompts import PromptMessage, StaticPrompt
22
22
  from agentpool.resource_providers import StaticResourceProvider
23
+ from agentpool_config import BaseToolConfig, NativeAgentToolConfig
23
24
  from agentpool_config.builtin_tools import BaseBuiltinToolConfig
24
25
  from agentpool_config.hooks import HooksConfig # noqa: TC001
25
26
  from agentpool_config.knowledge import Knowledge # noqa: TC001
@@ -27,8 +28,7 @@ from agentpool_config.nodes import BaseAgentConfig
27
28
  from agentpool_config.output_types import StructuredResponseConfig # noqa: TC001
28
29
  from agentpool_config.session import MemoryConfig, SessionQuery
29
30
  from agentpool_config.system_prompts import PromptConfig # noqa: TC001
30
- from agentpool_config.tools import BaseToolConfig, ToolConfig # noqa: TC001
31
- from agentpool_config.toolsets import ToolsetConfig # noqa: TC001
31
+ from agentpool_config.toolsets import BaseToolsetConfig, ToolsetConfig
32
32
  from agentpool_config.workers import WorkerConfig # noqa: TC001
33
33
 
34
34
 
@@ -42,6 +42,12 @@ ToolMode = Literal["codemode"]
42
42
 
43
43
  logger = log.get_logger(__name__)
44
44
 
45
+ # Unified type for all tool configurations (single tools + toolsets)
46
+ AnyToolConfig = Annotated[
47
+ NativeAgentToolConfig | ToolsetConfig,
48
+ Field(discriminator="type"),
49
+ ]
50
+
45
51
 
46
52
  class NativeAgentConfig(BaseAgentConfig):
47
53
  """Configuration for a single agent in the system.
@@ -62,11 +68,8 @@ class NativeAgentConfig(BaseAgentConfig):
62
68
  type: Literal["native"] = Field(default="native", init=False)
63
69
  """Top-level discriminator for agent type."""
64
70
 
65
- inherits: str | None = Field(default=None, title="Inheritance source")
66
- """Name of agent config to inherit from"""
67
-
68
- model: AnyModelConfig | ModelId | str | None = Field(
69
- default=None,
71
+ model: AnyModelConfig | ModelId | str = Field(
72
+ ...,
70
73
  examples=["openai:gpt-5-nano"],
71
74
  title="Model configuration or name",
72
75
  json_schema_extra={
@@ -79,7 +82,7 @@ class NativeAgentConfig(BaseAgentConfig):
79
82
  Docs: https://phil65.github.io/agentpool/YAML%20Configuration/model_configuration/
80
83
  """
81
84
 
82
- tools: list[ToolConfig | str] = Field(
85
+ tools: list[AnyToolConfig | str] = Field(
83
86
  default_factory=list,
84
87
  examples=[
85
88
  ["webbrowser:open", "builtins:print"],
@@ -88,46 +91,30 @@ class NativeAgentConfig(BaseAgentConfig):
88
91
  "type": "import",
89
92
  "import_path": "webbrowser:open",
90
93
  "name": "web_browser",
91
- }
92
- ],
93
- ],
94
- title="Tool configurations",
95
- json_schema_extra={
96
- "documentation_url": "https://phil65.github.io/agentpool/YAML%20Configuration/tool_configuration/"
97
- },
98
- )
99
- """A list of tools to register with this agent.
100
-
101
- Docs: https://phil65.github.io/agentpool/YAML%20Configuration/tool_configuration/
102
- """
103
-
104
- toolsets: list[ToolsetConfig] = Field(
105
- default_factory=list,
106
- examples=[
107
- [
94
+ },
108
95
  {
109
- "type": "openapi",
110
- "spec": "https://api.example.com/openapi.json",
111
- "namespace": "api",
96
+ "type": "bash",
97
+ "timeout": 30.0,
112
98
  },
113
99
  {
114
100
  "type": "file_access",
115
101
  },
116
102
  {
117
- "type": "composio",
118
- "user_id": "user123@example.com",
119
- "toolsets": ["github", "slack"],
103
+ "type": "process_management",
120
104
  },
121
105
  ],
122
106
  ],
123
- title="Toolset configurations",
107
+ title="Tool configurations",
124
108
  json_schema_extra={
125
- "documentation_url": "https://phil65.github.io/agentpool/YAML%20Configuration/toolset_configuration/"
109
+ "documentation_url": "https://phil65.github.io/agentpool/YAML%20Configuration/tool_configuration/"
126
110
  },
127
111
  )
128
- """Toolset configurations for extensible tool collections.
112
+ """A list of tools and toolsets to register with this agent.
129
113
 
130
- Docs: https://phil65.github.io/agentpool/YAML%20Configuration/toolset_configuration/
114
+ Supports both single tools (bash, import, web_search, etc.) and
115
+ toolsets (file_access, process_management, code, etc.).
116
+
117
+ Docs: https://phil65.github.io/agentpool/YAML%20Configuration/tool_configuration/
131
118
  """
132
119
 
133
120
  session: str | SessionQuery | MemoryConfig | None = Field(
@@ -297,48 +284,61 @@ class NativeAgentConfig(BaseAgentConfig):
297
284
  data["model"] = {"type": "string", "identifier": model}
298
285
  return data
299
286
 
300
- def get_toolsets(self) -> list[ResourceProvider]:
301
- """Get all resource providers for this agent."""
302
- providers: list[ResourceProvider] = []
303
-
304
- # Add providers from toolsets
305
- for toolset_config in self.toolsets:
306
- try:
307
- provider = toolset_config.get_provider()
308
- providers.append(provider)
309
- except Exception as e:
310
- msg = "Failed to create provider for toolset"
311
- logger.exception(msg, toolset_config)
312
- raise ValueError(msg) from e
287
+ def get_tool_providers(self) -> list[ResourceProvider]:
288
+ """Get all resource providers for this agent's tools.
313
289
 
314
- return providers
290
+ Processes the unified tools list, separating:
291
+ - Toolsets: Each becomes its own ResourceProvider
292
+ - Single tools: Aggregated into a single StaticResourceProvider
315
293
 
316
- def get_tool_provider(self) -> ResourceProvider | None:
317
- """Get tool provider for this agent (excludes builtin tools)."""
294
+ Returns:
295
+ List of ResourceProvider instances
296
+ """
318
297
  from agentpool.tools.base import Tool
319
298
 
320
- # Create provider for static tools
321
- if not self.tools:
322
- return None
299
+ providers: list[ResourceProvider] = []
323
300
  static_tools: list[Tool] = []
301
+
324
302
  for tool_config in self.tools:
325
303
  # Skip builtin tools - they're handled via get_builtin_tools()
326
304
  if isinstance(tool_config, BaseBuiltinToolConfig):
327
305
  continue
306
+
328
307
  try:
329
- match tool_config:
330
- case str():
331
- tool = Tool.from_callable(tool_config)
332
- static_tools.append(tool)
333
- case BaseToolConfig():
334
- static_tools.append(tool_config.get_tool())
308
+ if isinstance(tool_config, BaseToolsetConfig):
309
+ # Toolset -> get its provider directly
310
+ providers.append(tool_config.get_provider())
311
+ elif isinstance(tool_config, str):
312
+ # String import path -> single tool
313
+ static_tools.append(Tool.from_callable(tool_config))
314
+ elif isinstance(tool_config, BaseToolConfig):
315
+ # Single tool config -> single tool
316
+ static_tools.append(tool_config.get_tool())
335
317
  except Exception:
336
318
  logger.exception("Failed to load tool", config=tool_config)
337
319
  continue
338
320
 
339
- if not static_tools:
340
- return None
341
- return StaticResourceProvider(name="builtin", tools=static_tools)
321
+ # Wrap all single tools in one provider
322
+ if static_tools:
323
+ providers.append(StaticResourceProvider(name="tools", tools=static_tools))
324
+
325
+ return providers
326
+
327
+ # Keep old methods for backward compatibility during transition
328
+ def get_toolsets(self) -> list[ResourceProvider]:
329
+ """Get toolset providers. Deprecated: use get_tool_providers() instead."""
330
+ return [
331
+ p
332
+ for p in self.get_tool_providers()
333
+ if not isinstance(p, StaticResourceProvider) or p.name != "tools"
334
+ ]
335
+
336
+ def get_tool_provider(self) -> ResourceProvider | None:
337
+ """Get single tools provider. Deprecated: use get_tool_providers() instead."""
338
+ for p in self.get_tool_providers():
339
+ if isinstance(p, StaticResourceProvider) and p.name == "tools":
340
+ return p
341
+ return None
342
342
 
343
343
  def get_builtin_tools(self) -> list[Any]:
344
344
  """Get pydantic-ai builtin tools from config.
@@ -6,8 +6,8 @@ from typing import Literal
6
6
 
7
7
  from pydantic import ConfigDict, Field
8
8
 
9
+ from agentpool_config import ToolConfig # noqa: TC001
9
10
  from agentpool_config.nodes import BaseAgentConfig
10
- from agentpool_config.tools import ToolConfig # noqa: TC001
11
11
 
12
12
 
13
13
  class AGUIAgentConfig(BaseAgentConfig):
@@ -6,18 +6,26 @@ from collections.abc import Sequence # noqa: TC003
6
6
  from typing import TYPE_CHECKING, Literal
7
7
 
8
8
  from pydantic import ConfigDict, Field
9
-
9
+ from tokonomics.model_names import AnthropicMaxModelName # noqa: TC002
10
+
11
+ from agentpool import log
12
+ from agentpool.resource_providers import StaticResourceProvider
13
+ from agentpool_config import (
14
+ AnyToolConfig, # noqa: TC001
15
+ BaseToolConfig,
16
+ )
10
17
  from agentpool_config.nodes import BaseAgentConfig
11
18
  from agentpool_config.output_types import StructuredResponseConfig # noqa: TC001
12
19
  from agentpool_config.system_prompts import PromptConfig # noqa: TC001
13
- from agentpool_config.toolsets import ToolsetConfig # noqa: TC001
14
20
 
15
21
 
16
22
  if TYPE_CHECKING:
17
23
  from agentpool.resource_providers import ResourceProvider
18
24
 
25
+ logger = log.get_logger(__name__)
19
26
 
20
27
  PermissionMode = Literal["default", "acceptEdits", "plan", "bypassPermissions"]
28
+ SettingSource = Literal["user", "project", "local"]
21
29
  ToolName = Literal[
22
30
  "Task",
23
31
  "TaskOutput",
@@ -37,6 +45,7 @@ ToolName = Literal[
37
45
  "Skill",
38
46
  "EnterPlanMode",
39
47
  "LSP",
48
+ "Chrome",
40
49
  ]
41
50
 
42
51
 
@@ -87,7 +96,7 @@ class ClaudeCodeAgentConfig(BaseAgentConfig):
87
96
  )
88
97
  """Working directory for Claude Code operations."""
89
98
 
90
- model: str | None = Field(
99
+ model: AnthropicMaxModelName | str | None = Field(
91
100
  default=None,
92
101
  title="Model",
93
102
  examples=["claude-sonnet-4-5", "claude-opus-4", "claude-haiku-3-5"],
@@ -219,15 +228,23 @@ class ClaudeCodeAgentConfig(BaseAgentConfig):
219
228
  builtin_tools: list[str] | None = Field(
220
229
  default=None,
221
230
  title="Built-in Tools",
222
- examples=[["Bash", "Edit", "Read"], []],
231
+ examples=[["Bash", "Edit", "Read"], ["Read", "Write", "LSP"], ["Bash", "Chrome"]],
223
232
  )
224
233
  """Available tools from Claude Code's built-in set.
225
234
 
226
235
  Empty list disables all tools. If not specified, all tools are available.
227
236
  Different from allowed_tools which filters an already-available set.
237
+
238
+ Special tools:
239
+ - "LSP": Enable Language Server Protocol support for code intelligence
240
+ (go to definition, find references, symbol info, etc.)
241
+ - "Chrome": Enable Claude in Chrome integration for browser control
242
+ (opens, navigates, interacts with browser tabs)
243
+
244
+ Both LSP and Chrome require additional setup in your environment.
228
245
  """
229
246
 
230
- fallback_model: str | None = Field(
247
+ fallback_model: AnthropicMaxModelName | str | None = Field(
231
248
  default=None,
232
249
  title="Fallback Model",
233
250
  examples=["claude-sonnet-4-5", "claude-haiku-3-5"],
@@ -240,30 +257,107 @@ class ClaudeCodeAgentConfig(BaseAgentConfig):
240
257
  )
241
258
  """Bypass all permission checks. Only for sandboxed environments."""
242
259
 
243
- toolsets: list[ToolsetConfig] = Field(
260
+ setting_sources: list[SettingSource] | None = Field(
261
+ default=None,
262
+ title="Setting Sources",
263
+ examples=[["user", "project"], ["local"], ["user", "project", "local"]],
264
+ )
265
+ """Setting sources to load configuration from.
266
+
267
+ Controls which Claude Code settings files are loaded:
268
+ - "user": User-level settings (~/.config/claude/settings.json)
269
+ - "project": Project-level settings (.claude/settings.json in project root)
270
+ - "local": Local settings (.claude/settings.local.json, git-ignored)
271
+
272
+ If not specified, Claude Code will load all available settings.
273
+ """
274
+
275
+ use_subscription: bool = Field(
276
+ default=False,
277
+ title="Use Claude Subscription",
278
+ )
279
+ """Force usage of Claude subscription instead of API key.
280
+
281
+ When True, sets ANTHROPIC_API_KEY to empty string, forcing Claude Code
282
+ to use your Claude.ai subscription for authentication instead of an API key.
283
+
284
+ This is useful when:
285
+ - You have a Claude Pro/Team subscription with higher rate limits
286
+ - You want to use subscription credits instead of API credits
287
+ - You're using features only available to subscribers
288
+
289
+ Note: Requires an active Claude subscription and logged-in session.
290
+ """
291
+
292
+ tools: list[AnyToolConfig | str] = Field(
244
293
  default_factory=list,
245
- title="Toolsets",
294
+ title="Tools",
246
295
  examples=[
247
296
  [
248
297
  {"type": "subagent"},
249
298
  {"type": "agent_management"},
299
+ "webbrowser:open",
300
+ {
301
+ "type": "import",
302
+ "import_path": "webbrowser:open",
303
+ "name": "web_browser",
304
+ },
250
305
  ],
251
306
  ],
252
307
  )
253
- """Toolsets to expose to this Claude Code agent via MCP bridge.
308
+ """Tools and toolsets to expose to this Claude Code agent via MCP bridge.
254
309
 
255
- These toolsets will be started as an in-process MCP server and made
256
- available to Claude Code. This allows Claude Code to use internal
257
- agentpool toolsets like subagent delegation, agent management, etc.
310
+ Supports both single tools and toolsets. These will be started as an
311
+ in-process MCP server and made available to Claude Code.
258
312
 
259
- The toolsets are exposed using the Claude SDK's native MCP support,
260
- which passes the FastMCP server instance directly without HTTP overhead.
313
+ Docs: https://phil65.github.io/agentpool/YAML%20Configuration/tool_configuration/
261
314
  """
262
315
 
263
- def get_toolset_providers(self) -> list[ResourceProvider]:
264
- """Get resource providers for all configured toolsets.
316
+ def get_tool_providers(self) -> list[ResourceProvider]:
317
+ """Get all resource providers for this agent's tools.
318
+
319
+ Processes the unified tools list, separating:
320
+ - Toolsets: Each becomes its own ResourceProvider
321
+ - Single tools: Aggregated into a single StaticResourceProvider
265
322
 
266
323
  Returns:
267
- List of initialized ResourceProvider instances
324
+ List of ResourceProvider instances
268
325
  """
269
- return [toolset.get_provider() for toolset in self.toolsets]
326
+ from agentpool.tools.base import Tool
327
+ from agentpool_config.toolsets import BaseToolsetConfig
328
+
329
+ providers: list[ResourceProvider] = []
330
+ static_tools: list[Tool] = []
331
+
332
+ for tool_config in self.tools:
333
+ try:
334
+ if isinstance(tool_config, BaseToolsetConfig):
335
+ providers.append(tool_config.get_provider())
336
+ elif isinstance(tool_config, str):
337
+ static_tools.append(Tool.from_callable(tool_config))
338
+ elif isinstance(tool_config, BaseToolConfig):
339
+ static_tools.append(tool_config.get_tool())
340
+ except Exception:
341
+ logger.exception("Failed to load tool", config=tool_config)
342
+ continue
343
+
344
+ if static_tools:
345
+ providers.append(StaticResourceProvider(name="tools", tools=static_tools))
346
+
347
+ return providers
348
+
349
+ # Backward compatibility
350
+ def get_toolset_providers(self) -> list[ResourceProvider]:
351
+ """Deprecated: use get_tool_providers() instead."""
352
+ return [
353
+ p
354
+ for p in self.get_tool_providers()
355
+ if not isinstance(p, StaticResourceProvider) or p.name != "tools"
356
+ ]
357
+
358
+ def get_tool_provider(self) -> ResourceProvider | None:
359
+ """Deprecated: use get_tool_providers() instead."""
360
+ for p in self.get_tool_providers():
361
+ if isinstance(p, StaticResourceProvider) and p.name == "tools":
362
+ return p
363
+ return None
@@ -41,7 +41,6 @@ PERMISSION_MODE_MAP: dict[str, Literal["always", "never", "per_tool"]] = {
41
41
 
42
42
  # Fields that pass through directly to NativeAgentConfig
43
43
  PASSTHROUGH_FIELDS = {
44
- "inherits",
45
44
  "toolsets",
46
45
  "session",
47
46
  "output_type",
@@ -5,14 +5,15 @@ from __future__ import annotations
5
5
  from functools import cached_property
6
6
  from typing import TYPE_CHECKING, Annotated, Any, Self
7
7
 
8
+ from llmling_models_config import AnyModelConfig, StringModelConfig
8
9
  from pydantic import ConfigDict, Field, model_validator
9
10
  from schemez import Schema
10
- from upathtools.configs import FilesystemConfigType
11
- from upathtools.configs.base import URIFileSystemConfig
11
+ from upathtools_config import FilesystemConfigType
12
+ from upathtools_config.base import URIFileSystemConfig
12
13
 
13
14
  from agentpool import log
14
15
  from agentpool.models.acp_agents import ACPAgentConfigTypes
15
- from agentpool.models.agents import NativeAgentConfig
16
+ from agentpool.models.agents import AnyToolConfig, NativeAgentConfig # noqa: F401
16
17
  from agentpool.models.agui_agents import AGUIAgentConfig
17
18
  from agentpool.models.claude_code_agents import ClaudeCodeAgentConfig
18
19
  from agentpool.models.file_agents import FileAgentConfig
@@ -220,6 +221,52 @@ class AgentsManifest(Schema):
220
221
  Docs: https://phil65.github.io/agentpool/YAML%20Configuration/response_configuration/
221
222
  """
222
223
 
224
+ model_variants: dict[str, AnyModelConfig] = Field(
225
+ default_factory=dict,
226
+ examples=[
227
+ {
228
+ "thinking_high": {
229
+ "type": "anthropic",
230
+ "model": "claude-sonnet-4-5",
231
+ "max_thinking_tokens": 10000,
232
+ },
233
+ "fast_gpt": {
234
+ "type": "string",
235
+ "model": "openai:gpt-4o-mini",
236
+ "temperature": 0.3,
237
+ },
238
+ }
239
+ ],
240
+ )
241
+ """Named model variants with pre-configured settings.
242
+
243
+ Define reusable model configurations that can be referenced by name
244
+ in agent configs. Each variant specifies a base model and its settings.
245
+
246
+ Note: Currently only applies to native agents.
247
+
248
+ Example:
249
+ ```yaml
250
+ model_variants:
251
+ thinking_high:
252
+ type: anthropic
253
+ model: claude-sonnet-4-5
254
+ max_thinking_tokens: 10000
255
+
256
+ fast_gpt:
257
+ type: string
258
+ model: openai:gpt-4o-mini
259
+ temperature: 0.3
260
+ ```
261
+
262
+ Then use in agents:
263
+ ```yaml
264
+ agents:
265
+ assistant:
266
+ model: thinking_high # References the variant
267
+ ```
268
+ """
269
+
223
270
  jobs: dict[str, Job[Any]] = Field(default_factory=dict)
224
271
  """Pre-defined jobs, ready to be used by nodes."""
225
272
 
@@ -421,6 +468,25 @@ class AgentsManifest(Schema):
421
468
  registry.register_from_config(name, config)
422
469
  return registry
423
470
 
471
+ def resolve_model(self, model: AnyModelConfig | str) -> AnyModelConfig:
472
+ """Resolve a model specification to a model config.
473
+
474
+ If model is a string, checks model_variants first, then wraps in StringModelConfig.
475
+ If model is already an AnyModelConfig, returns it unchanged.
476
+
477
+ Args:
478
+ model: Model identifier, variant name, or config
479
+
480
+ Returns:
481
+ AnyModelConfig
482
+ """
483
+ if isinstance(model, str):
484
+ if model in self.model_variants:
485
+ return self.model_variants[model]
486
+ return StringModelConfig(identifier=model)
487
+ # Already a config
488
+ return model
489
+
424
490
  def clone_agent_config(
425
491
  self,
426
492
  name: str,
@@ -469,52 +535,6 @@ class AgentsManifest(Schema):
469
535
  self.agents[actual_name] = config
470
536
  return actual_name
471
537
 
472
- @model_validator(mode="before")
473
- @classmethod
474
- def resolve_inheritance(cls, data: dict[str, Any]) -> dict[str, Any]:
475
- """Resolve agent inheritance chains."""
476
- nodes = data.get("agents", {})
477
- resolved: dict[str, dict[str, Any]] = {}
478
- seen: set[str] = set()
479
-
480
- def resolve_node(name: str) -> dict[str, Any] | Any:
481
- if name in resolved:
482
- return resolved[name]
483
-
484
- node = nodes[name]
485
- # Skip model instances - they're already validated
486
- if not isinstance(node, dict):
487
- return node
488
-
489
- if name in seen:
490
- msg = f"Circular inheritance detected: {name}"
491
- raise ValueError(msg)
492
-
493
- seen.add(name)
494
- config = node.copy()
495
- inherit = config.get("inherits")
496
- if inherit:
497
- if inherit not in nodes:
498
- msg = f"Parent agent {inherit} not found"
499
- raise ValueError(msg)
500
-
501
- parent = resolve_node(inherit) # Get resolved parent config
502
- if isinstance(parent, dict):
503
- merged = parent.copy()
504
- merged.update(config)
505
- config = merged
506
-
507
- seen.remove(name)
508
- resolved[name] = config
509
- return config
510
-
511
- for name in nodes:
512
- resolved[name] = resolve_node(name)
513
-
514
- # Update nodes with resolved configs
515
- data["agents"] = resolved
516
- return data
517
-
518
538
  @cached_property
519
539
  def _loaded_file_agents(self) -> dict[str, NativeAgentConfig]:
520
540
  """Load and cache file-based agent configurations.
@@ -693,7 +713,7 @@ class AgentsManifest(Schema):
693
713
 
694
714
 
695
715
  if __name__ == "__main__":
696
- from llmling_models.configs import InputModelConfig
716
+ from llmling_models_config import InputModelConfig
697
717
 
698
718
  model = InputModelConfig()
699
719
  agent_cfg = NativeAgentConfig(name="test_agent", model=model)
@@ -87,7 +87,7 @@ class ConversionManager:
87
87
 
88
88
 
89
89
  if __name__ == "__main__":
90
- from docler.configs.converter_configs import MarkItDownConfig
90
+ from docler_config.converter_configs import MarkItDownConfig
91
91
 
92
92
  from agentpool_config.converters import ConversionConfig
93
93
 
@@ -8,7 +8,6 @@ import inspect
8
8
  import os
9
9
  from typing import TYPE_CHECKING, Annotated, Any, Literal, Self, assert_never
10
10
 
11
- from mcp.types import Prompt as MCPPrompt, PromptArgument
12
11
  from pydantic import ConfigDict, Field
13
12
  from pydantic_ai import BinaryContent, ImageUrl, SystemPromptPart, UserPromptPart
14
13
  from schemez import Schema
@@ -24,9 +23,9 @@ if TYPE_CHECKING:
24
23
  from collections.abc import Mapping
25
24
 
26
25
  from fastmcp.prompts.prompt import FunctionPrompt, Prompt as FastMCPPrompt
26
+ from mcp.types import Prompt as MCPPrompt, PromptArgument
27
27
  from pydantic_ai import ModelRequestPart
28
28
 
29
-
30
29
  logger = get_logger(__name__)
31
30
 
32
31
  MessageContentType = Literal["text", "resource", "image_url", "image_base64"]
@@ -421,6 +420,8 @@ class MCPClientPrompt(BasePrompt):
421
420
 
422
421
  def to_mcp_prompt(self) -> MCPPrompt:
423
422
  """Convert to MCP Prompt."""
423
+ from mcp.types import Prompt as MCPPrompt, PromptArgument
424
+
424
425
  args = [
425
426
  PromptArgument(name=i["name"], description=i["description"], required=i["required"])
426
427
  for i in self.arguments
@@ -516,6 +517,8 @@ class FilePrompt(BasePrompt):
516
517
 
517
518
  def to_mcp_prompt(self) -> MCPPrompt:
518
519
  """Convert to MCP Prompt."""
520
+ from mcp.types import Prompt as MCPPrompt
521
+
519
522
  return MCPPrompt(
520
523
  name=self.name or to_upath(self.path).name,
521
524
  description=self.description,
@@ -6,6 +6,7 @@ from agentpool.resource_providers.base import (
6
6
  ResourceProvider,
7
7
  ResourceType,
8
8
  )
9
+ from agentpool.resource_providers.resource_info import ResourceInfo
9
10
  from agentpool.resource_providers.static import StaticResourceProvider
10
11
  from agentpool.resource_providers.filtering import FilteringResourceProvider
11
12
  from agentpool.resource_providers.aggregating import AggregatingResourceProvider
@@ -19,6 +20,7 @@ __all__ = [
19
20
  "PlanProvider",
20
21
  "ProviderKind",
21
22
  "ResourceChangeEvent",
23
+ "ResourceInfo",
22
24
  "ResourceProvider",
23
25
  "ResourceType",
24
26
  "StaticResourceProvider",