agentpool 2.1.9__py3-none-any.whl → 2.2.3__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 (174) hide show
  1. acp/__init__.py +13 -0
  2. acp/bridge/README.md +15 -2
  3. acp/bridge/__init__.py +3 -2
  4. acp/bridge/__main__.py +60 -19
  5. acp/bridge/ws_server.py +173 -0
  6. acp/bridge/ws_server_cli.py +89 -0
  7. acp/notifications.py +2 -1
  8. acp/stdio.py +39 -9
  9. acp/transports.py +362 -2
  10. acp/utils.py +15 -2
  11. agentpool/__init__.py +4 -1
  12. agentpool/agents/__init__.py +2 -0
  13. agentpool/agents/acp_agent/acp_agent.py +203 -88
  14. agentpool/agents/acp_agent/acp_converters.py +46 -21
  15. agentpool/agents/acp_agent/client_handler.py +157 -3
  16. agentpool/agents/acp_agent/session_state.py +4 -1
  17. agentpool/agents/agent.py +314 -107
  18. agentpool/agents/agui_agent/__init__.py +0 -2
  19. agentpool/agents/agui_agent/agui_agent.py +90 -21
  20. agentpool/agents/agui_agent/agui_converters.py +0 -131
  21. agentpool/agents/base_agent.py +163 -1
  22. agentpool/agents/claude_code_agent/claude_code_agent.py +626 -179
  23. agentpool/agents/claude_code_agent/converters.py +71 -3
  24. agentpool/agents/claude_code_agent/history.py +474 -0
  25. agentpool/agents/context.py +40 -0
  26. agentpool/agents/events/__init__.py +2 -0
  27. agentpool/agents/events/builtin_handlers.py +2 -1
  28. agentpool/agents/events/event_emitter.py +29 -2
  29. agentpool/agents/events/events.py +20 -0
  30. agentpool/agents/modes.py +54 -0
  31. agentpool/agents/tool_call_accumulator.py +213 -0
  32. agentpool/common_types.py +21 -0
  33. agentpool/config_resources/__init__.py +38 -1
  34. agentpool/config_resources/claude_code_agent.yml +3 -0
  35. agentpool/delegation/pool.py +37 -29
  36. agentpool/delegation/team.py +1 -0
  37. agentpool/delegation/teamrun.py +1 -0
  38. agentpool/diagnostics/__init__.py +53 -0
  39. agentpool/diagnostics/lsp_manager.py +1593 -0
  40. agentpool/diagnostics/lsp_proxy.py +41 -0
  41. agentpool/diagnostics/lsp_proxy_script.py +229 -0
  42. agentpool/diagnostics/models.py +398 -0
  43. agentpool/mcp_server/__init__.py +0 -2
  44. agentpool/mcp_server/client.py +12 -3
  45. agentpool/mcp_server/manager.py +25 -31
  46. agentpool/mcp_server/registries/official_registry_client.py +25 -0
  47. agentpool/mcp_server/tool_bridge.py +78 -66
  48. agentpool/messaging/__init__.py +0 -2
  49. agentpool/messaging/compaction.py +72 -197
  50. agentpool/messaging/message_history.py +12 -0
  51. agentpool/messaging/messages.py +52 -9
  52. agentpool/messaging/processing.py +3 -1
  53. agentpool/models/acp_agents/base.py +0 -22
  54. agentpool/models/acp_agents/mcp_capable.py +8 -148
  55. agentpool/models/acp_agents/non_mcp.py +129 -72
  56. agentpool/models/agents.py +35 -13
  57. agentpool/models/claude_code_agents.py +33 -2
  58. agentpool/models/manifest.py +43 -0
  59. agentpool/repomap.py +1 -1
  60. agentpool/resource_providers/__init__.py +9 -1
  61. agentpool/resource_providers/aggregating.py +52 -3
  62. agentpool/resource_providers/base.py +57 -1
  63. agentpool/resource_providers/mcp_provider.py +23 -0
  64. agentpool/resource_providers/plan_provider.py +130 -41
  65. agentpool/resource_providers/pool.py +2 -0
  66. agentpool/resource_providers/static.py +2 -0
  67. agentpool/sessions/__init__.py +2 -1
  68. agentpool/sessions/manager.py +31 -2
  69. agentpool/sessions/models.py +50 -0
  70. agentpool/skills/registry.py +13 -8
  71. agentpool/storage/manager.py +217 -1
  72. agentpool/testing.py +537 -19
  73. agentpool/utils/file_watcher.py +269 -0
  74. agentpool/utils/identifiers.py +121 -0
  75. agentpool/utils/pydantic_ai_helpers.py +46 -0
  76. agentpool/utils/streams.py +690 -1
  77. agentpool/utils/subprocess_utils.py +155 -0
  78. agentpool/utils/token_breakdown.py +461 -0
  79. {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/METADATA +27 -7
  80. {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/RECORD +170 -112
  81. {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/WHEEL +1 -1
  82. agentpool_cli/__main__.py +4 -0
  83. agentpool_cli/serve_acp.py +41 -20
  84. agentpool_cli/serve_agui.py +87 -0
  85. agentpool_cli/serve_opencode.py +119 -0
  86. agentpool_commands/__init__.py +30 -0
  87. agentpool_commands/agents.py +74 -1
  88. agentpool_commands/history.py +62 -0
  89. agentpool_commands/mcp.py +176 -0
  90. agentpool_commands/models.py +56 -3
  91. agentpool_commands/tools.py +57 -0
  92. agentpool_commands/utils.py +51 -0
  93. agentpool_config/builtin_tools.py +77 -22
  94. agentpool_config/commands.py +24 -1
  95. agentpool_config/compaction.py +258 -0
  96. agentpool_config/mcp_server.py +131 -1
  97. agentpool_config/storage.py +46 -1
  98. agentpool_config/tools.py +7 -1
  99. agentpool_config/toolsets.py +92 -148
  100. agentpool_server/acp_server/acp_agent.py +134 -150
  101. agentpool_server/acp_server/commands/acp_commands.py +216 -51
  102. agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +10 -10
  103. agentpool_server/acp_server/server.py +23 -79
  104. agentpool_server/acp_server/session.py +181 -19
  105. agentpool_server/opencode_server/.rules +95 -0
  106. agentpool_server/opencode_server/ENDPOINTS.md +362 -0
  107. agentpool_server/opencode_server/__init__.py +27 -0
  108. agentpool_server/opencode_server/command_validation.py +172 -0
  109. agentpool_server/opencode_server/converters.py +869 -0
  110. agentpool_server/opencode_server/dependencies.py +24 -0
  111. agentpool_server/opencode_server/input_provider.py +269 -0
  112. agentpool_server/opencode_server/models/__init__.py +228 -0
  113. agentpool_server/opencode_server/models/agent.py +53 -0
  114. agentpool_server/opencode_server/models/app.py +60 -0
  115. agentpool_server/opencode_server/models/base.py +26 -0
  116. agentpool_server/opencode_server/models/common.py +23 -0
  117. agentpool_server/opencode_server/models/config.py +37 -0
  118. agentpool_server/opencode_server/models/events.py +647 -0
  119. agentpool_server/opencode_server/models/file.py +88 -0
  120. agentpool_server/opencode_server/models/mcp.py +25 -0
  121. agentpool_server/opencode_server/models/message.py +162 -0
  122. agentpool_server/opencode_server/models/parts.py +190 -0
  123. agentpool_server/opencode_server/models/provider.py +81 -0
  124. agentpool_server/opencode_server/models/pty.py +43 -0
  125. agentpool_server/opencode_server/models/session.py +99 -0
  126. agentpool_server/opencode_server/routes/__init__.py +25 -0
  127. agentpool_server/opencode_server/routes/agent_routes.py +442 -0
  128. agentpool_server/opencode_server/routes/app_routes.py +139 -0
  129. agentpool_server/opencode_server/routes/config_routes.py +241 -0
  130. agentpool_server/opencode_server/routes/file_routes.py +392 -0
  131. agentpool_server/opencode_server/routes/global_routes.py +94 -0
  132. agentpool_server/opencode_server/routes/lsp_routes.py +319 -0
  133. agentpool_server/opencode_server/routes/message_routes.py +705 -0
  134. agentpool_server/opencode_server/routes/pty_routes.py +299 -0
  135. agentpool_server/opencode_server/routes/session_routes.py +1205 -0
  136. agentpool_server/opencode_server/routes/tui_routes.py +139 -0
  137. agentpool_server/opencode_server/server.py +430 -0
  138. agentpool_server/opencode_server/state.py +121 -0
  139. agentpool_server/opencode_server/time_utils.py +8 -0
  140. agentpool_storage/__init__.py +16 -0
  141. agentpool_storage/base.py +103 -0
  142. agentpool_storage/claude_provider.py +907 -0
  143. agentpool_storage/file_provider.py +129 -0
  144. agentpool_storage/memory_provider.py +61 -0
  145. agentpool_storage/models.py +3 -0
  146. agentpool_storage/opencode_provider.py +730 -0
  147. agentpool_storage/project_store.py +325 -0
  148. agentpool_storage/session_store.py +6 -0
  149. agentpool_storage/sql_provider/__init__.py +4 -2
  150. agentpool_storage/sql_provider/models.py +48 -0
  151. agentpool_storage/sql_provider/sql_provider.py +134 -1
  152. agentpool_storage/sql_provider/utils.py +10 -1
  153. agentpool_storage/text_log_provider.py +1 -0
  154. agentpool_toolsets/builtin/__init__.py +0 -8
  155. agentpool_toolsets/builtin/code.py +95 -56
  156. agentpool_toolsets/builtin/debug.py +16 -21
  157. agentpool_toolsets/builtin/execution_environment.py +99 -103
  158. agentpool_toolsets/builtin/file_edit/file_edit.py +115 -7
  159. agentpool_toolsets/builtin/skills.py +86 -4
  160. agentpool_toolsets/fsspec_toolset/__init__.py +13 -1
  161. agentpool_toolsets/fsspec_toolset/diagnostics.py +860 -73
  162. agentpool_toolsets/fsspec_toolset/grep.py +74 -2
  163. agentpool_toolsets/fsspec_toolset/image_utils.py +161 -0
  164. agentpool_toolsets/fsspec_toolset/toolset.py +159 -38
  165. agentpool_toolsets/mcp_discovery/__init__.py +5 -0
  166. agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
  167. agentpool_toolsets/mcp_discovery/toolset.py +454 -0
  168. agentpool_toolsets/mcp_run_toolset.py +84 -6
  169. agentpool_toolsets/builtin/agent_management.py +0 -239
  170. agentpool_toolsets/builtin/history.py +0 -36
  171. agentpool_toolsets/builtin/integration.py +0 -85
  172. agentpool_toolsets/builtin/tool_management.py +0 -90
  173. {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/entry_points.txt +0 -0
  174. {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,239 +0,0 @@
1
- """Provider for agent pool building tools."""
2
-
3
- from __future__ import annotations
4
-
5
- from datetime import timedelta
6
- from typing import TYPE_CHECKING, Any, Literal
7
-
8
- import anyio
9
- from pydantic_ai import ModelRetry
10
-
11
- from agentpool.agents.context import AgentContext # noqa: TC001
12
- from agentpool.log import get_logger
13
- from agentpool.resource_providers import StaticResourceProvider
14
- from agentpool.tools.exceptions import ToolError
15
- from agentpool.utils.result_utils import to_type
16
-
17
-
18
- if TYPE_CHECKING:
19
- from agentpool.agents import Agent
20
-
21
- logger = get_logger(__name__)
22
-
23
-
24
- async def create_worker_agent[TDeps](
25
- ctx: AgentContext[TDeps],
26
- name: str,
27
- system_prompt: str,
28
- model: str | None = None,
29
- ) -> str:
30
- """Create a new agent and register it as a tool.
31
-
32
- The new agent will be available as a tool for delegating specific tasks.
33
- It inherits the current model unless overridden.
34
- """
35
- from agentpool import Agent
36
-
37
- if not ctx.pool:
38
- msg = "Agent needs to be in a pool to list agents"
39
- raise ToolError(msg)
40
-
41
- model = model or ctx.agent.model_name
42
- agent = Agent[TDeps](name=name, model=model, system_prompt=system_prompt, agent_pool=ctx.pool)
43
- assert ctx.agent
44
- tool_info = ctx.native_agent.register_worker(agent)
45
- return f"Created worker agent and registered as tool: {tool_info.name}"
46
-
47
-
48
- async def add_agent( # noqa: D417
49
- ctx: AgentContext,
50
- name: str,
51
- system_prompt: str,
52
- model: str | None = None,
53
- tools: list[str] | None = None,
54
- session: str | None = None,
55
- output_type: str | None = None,
56
- ) -> str:
57
- """Add a new agent to the pool.
58
-
59
- Args:
60
- name: Name for the new agent
61
- system_prompt: System prompt defining agent's role/behavior
62
- model: Optional model override (uses default if not specified)
63
- tools: Imort paths of the tools the agent should have, if any.
64
- session: Session ID to recover conversation state from
65
- output_type: Name of response type from manifest (for structured output)
66
-
67
- Returns:
68
- Confirmation message about the created agent
69
- """
70
- assert ctx.pool, "No agent pool available"
71
- try:
72
- agent: Agent[Any, Any] = await ctx.pool.add_agent(
73
- name=name,
74
- system_prompt=system_prompt,
75
- model=model,
76
- tools=tools,
77
- output_type=to_type(output_type, responses=ctx.pool.manifest.responses),
78
- session=session,
79
- )
80
- except ValueError as e: # for wrong tool imports
81
- raise ModelRetry(message=f"Error creating agent: {e}") from None
82
- return f"Created agent **{agent.name}** using model **{agent.model_name}**"
83
-
84
-
85
- async def add_team( # noqa: D417
86
- ctx: AgentContext,
87
- nodes: list[str],
88
- mode: Literal["sequential", "parallel"] = "sequential",
89
- name: str | None = None,
90
- ) -> str:
91
- """Create a team from existing agents.
92
-
93
- Args:
94
- nodes: Names of agents / sub-teams to include in team
95
- mode: How the team should operate:
96
- - sequential: Agents process in sequence (pipeline)
97
- - parallel: Agents process simultaneously
98
- name: Optional name for the team
99
- """
100
- if not ctx.pool:
101
- msg = "No agent pool available"
102
- raise ToolError(msg)
103
-
104
- # Verify all agents exist
105
- for node_name in nodes:
106
- if node_name not in ctx.pool.nodes:
107
- msg = (
108
- f"No agent or team found with name: {node_name}. "
109
- f"Available nodes: {', '.join(ctx.pool.nodes.keys())}"
110
- )
111
- raise ModelRetry(msg)
112
- if mode == "sequential":
113
- ctx.pool.create_team_run(nodes, name=name)
114
- else:
115
- ctx.pool.create_team(nodes, name=name)
116
- mode_str = "pipeline" if mode == "sequential" else "parallel"
117
- return f"Created **{mode_str}** team with nodes: **{', '.join(nodes)}**"
118
-
119
-
120
- async def connect_nodes( # noqa: D417
121
- ctx: AgentContext,
122
- source: str,
123
- target: str,
124
- *,
125
- connection_type: Literal["run", "context", "forward"] = "run",
126
- priority: int = 0,
127
- delay_seconds: float | None = None,
128
- queued: bool = False,
129
- queue_strategy: Literal["concat", "latest", "buffer"] = "latest",
130
- wait_for_completion: bool = True,
131
- name: str | None = None,
132
- ) -> str:
133
- """Connect two nodes to enable message flow between them.
134
-
135
- Nodes can be agents or teams.
136
-
137
- Args:
138
- source: Name of the source node
139
- target: Name of the target node
140
- connection_type: How messages should be handled:
141
- - run: Execute message as a new run in target
142
- - context: Add message as context to target
143
- - forward: Forward message to target's outbox
144
- priority: Task priority (lower = higher priority)
145
- delay_seconds: Optional delay before processing messages
146
- queued: Whether messages should be queued for manual processing
147
- queue_strategy: How to process queued messages:
148
- - concat: Combine all messages with newlines
149
- - latest: Use only the most recent message
150
- - buffer: Process all messages individually
151
- wait_for_completion: Whether to wait for target to complete
152
- name: Optional name for this connection
153
-
154
- Returns:
155
- Description of the created connection
156
- """
157
- if not ctx.pool:
158
- msg = "No agent pool available"
159
- raise ToolError(msg)
160
-
161
- # Get the nodes
162
- if source not in ctx.pool.nodes:
163
- msg = (
164
- f"No agent or team found with name: {source}. "
165
- f"Available nodes: {', '.join(ctx.pool.nodes.keys())}"
166
- )
167
- raise ModelRetry(msg)
168
- if target not in ctx.pool.nodes:
169
- msg = (
170
- f"No agent or team found with name: {target}. "
171
- f"Available nodes: {', '.join(ctx.pool.nodes.keys())}"
172
- )
173
- raise ModelRetry(msg)
174
-
175
- source_node = ctx.pool.nodes[source]
176
- target_node = ctx.pool.nodes[target]
177
-
178
- # Create the connection
179
- delay = timedelta(seconds=delay_seconds) if delay_seconds is not None else None
180
- _talk = source_node.connect_to(
181
- target_node,
182
- connection_type=connection_type,
183
- priority=priority,
184
- delay=delay,
185
- queued=queued,
186
- queue_strategy=queue_strategy,
187
- name=name,
188
- )
189
- source_node.connections.set_wait_state(target_node, wait=wait_for_completion)
190
-
191
- return (
192
- f"Created connection from **{source}** to **{target}** "
193
- f"*(type={connection_type}, queued={queued}, "
194
- f"strategy={queue_strategy if queued else 'n/a'})*"
195
- )
196
-
197
-
198
- class AgentManagementTools(StaticResourceProvider):
199
- """Provider for agent pool building tools."""
200
-
201
- def __init__(self, name: str = "agent_management") -> None:
202
- super().__init__(name=name)
203
- for tool in [
204
- self.create_tool(create_worker_agent, category="other", destructive=False),
205
- self.create_tool(add_agent, category="other", destructive=False),
206
- self.create_tool(add_team, category="other", destructive=False),
207
- self.create_tool(connect_nodes, category="other", destructive=False),
208
- ]:
209
- self.add_tool(tool)
210
-
211
-
212
- if __name__ == "__main__":
213
- # import logging
214
- from agentpool import AgentPool
215
-
216
- user_prompt = """Add a stdio MCP server:
217
- // "command": "npx",
218
- // "args": ["mcp-graphql"],
219
- // "env": { "ENDPOINT": "https://diego.one/graphql" }
220
-
221
- ."""
222
-
223
- async def main() -> None:
224
- from agentpool_config.toolsets import IntegrationToolsetConfig
225
-
226
- async with AgentPool() as pool:
227
- toolsets = [IntegrationToolsetConfig()]
228
- toolset_providers = [config.get_provider() for config in toolsets]
229
- agent = await pool.add_agent(
230
- "X",
231
- toolsets=toolset_providers,
232
- model="openai:gpt-5-nano",
233
- )
234
- result = await agent.run(user_prompt)
235
- print(result)
236
- result = await agent.run("Which tools does it have?")
237
- print(result)
238
-
239
- anyio.run(main)
@@ -1,36 +0,0 @@
1
- """Provider for history tools."""
2
-
3
- from __future__ import annotations
4
-
5
- from agentpool.agents.context import AgentContext # noqa: TC001
6
- from agentpool.resource_providers import StaticResourceProvider
7
-
8
-
9
- async def search_history(
10
- ctx: AgentContext,
11
- query: str | None = None,
12
- hours: int = 24,
13
- limit: int = 5,
14
- ) -> str:
15
- """Search conversation history."""
16
- from agentpool_storage.formatters import format_output
17
-
18
- if not ctx.pool:
19
- return "No agent pool available for history search"
20
- provider = ctx.pool.storage.get_history_provider()
21
- results = await provider.get_filtered_conversations(
22
- query=query,
23
- period=f"{hours}h",
24
- limit=limit,
25
- )
26
- return format_output(results)
27
-
28
-
29
- class HistoryTools(StaticResourceProvider):
30
- """Provider for history tools."""
31
-
32
- def __init__(self, name: str = "history") -> None:
33
- super().__init__(name=name)
34
- self._tools = [
35
- self.create_tool(search_history, category="search", read_only=True, idempotent=True),
36
- ]
@@ -1,85 +0,0 @@
1
- """Provider for integration tools."""
2
-
3
- from __future__ import annotations
4
-
5
- from typing import TYPE_CHECKING, Literal
6
-
7
- from pydantic import HttpUrl
8
-
9
- from agentpool.agents.context import AgentContext # noqa: TC001
10
- from agentpool.resource_providers import ResourceProvider
11
-
12
-
13
- if TYPE_CHECKING:
14
- from agentpool.tools.base import Tool
15
- from agentpool_config.mcp_server import MCPServerConfig
16
-
17
-
18
- async def add_local_mcp_server( # noqa: D417
19
- ctx: AgentContext,
20
- name: str,
21
- command: str,
22
- args: list[str] | None = None,
23
- env_vars: dict[str, str] | None = None,
24
- ) -> str:
25
- """Add a local MCP server via stdio transport.
26
-
27
- Args:
28
- name: Unique name for the MCP server
29
- command: Command to execute for the server
30
- args: Command arguments
31
- env_vars: Environment variables to pass to the server
32
-
33
- Returns:
34
- Confirmation message about the added server
35
- """
36
- from agentpool_config.mcp_server import StdioMCPServerConfig
37
-
38
- env = env_vars or {}
39
- config = StdioMCPServerConfig(name=name, command=command, args=args or [], env=env)
40
- await ctx.agent.mcp.setup_server_runtime(config)
41
- # New provider automatically available via aggregating provider
42
- return f"Added local MCP server **{name}** with command: **{command}**"
43
-
44
-
45
- async def add_remote_mcp_server( # noqa: D417
46
- ctx: AgentContext,
47
- name: str,
48
- url: str,
49
- transport: Literal["sse", "streamable-http"] = "streamable-http",
50
- ) -> str:
51
- """Add a remote MCP server via HTTP-based transport.
52
-
53
- Args:
54
- name: Unique name for the MCP server
55
- url: Server URL endpoint
56
- transport: HTTP transport type to use (http is preferred)
57
-
58
- Returns:
59
- Confirmation message about the added server
60
- """
61
- from agentpool_config.mcp_server import SSEMCPServerConfig, StreamableHTTPMCPServerConfig
62
-
63
- match transport:
64
- case "sse":
65
- config: MCPServerConfig = SSEMCPServerConfig(name=name, url=HttpUrl(url))
66
- case "streamable-http":
67
- config = StreamableHTTPMCPServerConfig(name=name, url=HttpUrl(url))
68
-
69
- await ctx.agent.mcp.setup_server_runtime(config)
70
- # New provider automatically available via aggregating provider
71
- return f"Added remote MCP server **{name}** at *{url}* using {transport} transport"
72
-
73
-
74
- class IntegrationTools(ResourceProvider):
75
- """Provider for integration tools."""
76
-
77
- def __init__(self, name: str = "integrations") -> None:
78
- super().__init__(name)
79
-
80
- async def get_tools(self) -> list[Tool]:
81
- """Get integration tools."""
82
- return [
83
- self.create_tool(add_local_mcp_server, category="other"),
84
- self.create_tool(add_remote_mcp_server, category="other", open_world=True),
85
- ]
@@ -1,90 +0,0 @@
1
- """Provider for tool management tools."""
2
-
3
- from __future__ import annotations
4
-
5
- from typing import TYPE_CHECKING, Any
6
-
7
- from agentpool.agents.context import AgentContext # noqa: TC001
8
- from agentpool.resource_providers import StaticResourceProvider
9
- from agentpool.tools.base import Tool
10
-
11
-
12
- if TYPE_CHECKING:
13
- from collections.abc import Callable
14
-
15
-
16
- async def register_tool( # noqa: D417
17
- ctx: AgentContext,
18
- tool: str | Callable[..., Any],
19
- name: str | None = None,
20
- description: str | None = None,
21
- enabled: bool = True,
22
- ) -> str:
23
- """Register a new tool from callable or import path.
24
-
25
- Args:
26
- tool: Callable function or import path string to register as tool
27
- name: Optional name override for the tool
28
- description: Optional description override for the tool
29
- enabled: Whether the tool should be enabled initially
30
-
31
- Returns:
32
- Confirmation message with registered tool name
33
- """
34
- # Create tool from callable/import path
35
- tool_obj = Tool.from_callable(
36
- tool,
37
- name_override=name,
38
- description_override=description,
39
- source="dynamic",
40
- enabled=enabled,
41
- )
42
-
43
- # Register with the agent's tool manager
44
- registered_tool = ctx.agent.tools.register_tool(tool_obj)
45
-
46
- return f"Successfully registered tool: {registered_tool.name}"
47
-
48
-
49
- async def register_code_tool( # noqa: D417
50
- ctx: AgentContext,
51
- code: str,
52
- name: str | None = None,
53
- description: str | None = None,
54
- enabled: bool = True,
55
- ) -> str:
56
- """Register a new tool from code string.
57
-
58
- Args:
59
- code: Python code string containing a callable function
60
- name: Optional name override for the tool
61
- description: Optional description override for the tool
62
- enabled: Whether the tool should be enabled initially
63
-
64
- Returns:
65
- Confirmation message with registered tool name
66
- """
67
- # Create tool from code
68
- tool_obj = Tool.from_code(
69
- code,
70
- name=name,
71
- description=description,
72
- )
73
- tool_obj.enabled = enabled
74
- tool_obj.source = "dynamic"
75
-
76
- # Register with the agent's tool manager
77
- registered_tool = ctx.agent.tools.register_tool(tool_obj)
78
-
79
- return f"Successfully registered code tool: {registered_tool.name}"
80
-
81
-
82
- class ToolManagementTools(StaticResourceProvider):
83
- """Provider for tool management tools."""
84
-
85
- def __init__(self, name: str = "tool_management") -> None:
86
- super().__init__(name=name)
87
- self._tools = [
88
- self.create_tool(register_tool, category="other"),
89
- self.create_tool(register_code_tool, category="other"),
90
- ]