agentpool 2.1.9__py3-none-any.whl → 2.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. acp/__init__.py +13 -4
  2. acp/acp_requests.py +20 -77
  3. acp/agent/connection.py +8 -0
  4. acp/agent/implementations/debug_server/debug_server.py +6 -2
  5. acp/agent/protocol.py +6 -0
  6. acp/bridge/README.md +15 -2
  7. acp/bridge/__init__.py +3 -2
  8. acp/bridge/__main__.py +60 -19
  9. acp/bridge/ws_server.py +173 -0
  10. acp/bridge/ws_server_cli.py +89 -0
  11. acp/client/connection.py +38 -29
  12. acp/client/implementations/default_client.py +3 -2
  13. acp/client/implementations/headless_client.py +2 -2
  14. acp/connection.py +2 -2
  15. acp/notifications.py +20 -50
  16. acp/schema/__init__.py +2 -0
  17. acp/schema/agent_responses.py +21 -0
  18. acp/schema/client_requests.py +3 -3
  19. acp/schema/session_state.py +63 -29
  20. acp/stdio.py +39 -9
  21. acp/task/supervisor.py +2 -2
  22. acp/transports.py +362 -2
  23. acp/utils.py +17 -4
  24. agentpool/__init__.py +6 -1
  25. agentpool/agents/__init__.py +2 -0
  26. agentpool/agents/acp_agent/acp_agent.py +407 -277
  27. agentpool/agents/acp_agent/acp_converters.py +196 -38
  28. agentpool/agents/acp_agent/client_handler.py +191 -26
  29. agentpool/agents/acp_agent/session_state.py +17 -6
  30. agentpool/agents/agent.py +607 -572
  31. agentpool/agents/agui_agent/__init__.py +0 -2
  32. agentpool/agents/agui_agent/agui_agent.py +176 -110
  33. agentpool/agents/agui_agent/agui_converters.py +0 -131
  34. agentpool/agents/agui_agent/helpers.py +3 -4
  35. agentpool/agents/base_agent.py +632 -17
  36. agentpool/agents/claude_code_agent/FORKING.md +191 -0
  37. agentpool/agents/claude_code_agent/__init__.py +13 -1
  38. agentpool/agents/claude_code_agent/claude_code_agent.py +1058 -291
  39. agentpool/agents/claude_code_agent/converters.py +74 -143
  40. agentpool/agents/claude_code_agent/history.py +474 -0
  41. agentpool/agents/claude_code_agent/models.py +77 -0
  42. agentpool/agents/claude_code_agent/static_info.py +100 -0
  43. agentpool/agents/claude_code_agent/usage.py +242 -0
  44. agentpool/agents/context.py +40 -0
  45. agentpool/agents/events/__init__.py +24 -0
  46. agentpool/agents/events/builtin_handlers.py +67 -1
  47. agentpool/agents/events/event_emitter.py +32 -2
  48. agentpool/agents/events/events.py +104 -3
  49. agentpool/agents/events/infer_info.py +145 -0
  50. agentpool/agents/events/processors.py +254 -0
  51. agentpool/agents/interactions.py +41 -6
  52. agentpool/agents/modes.py +67 -0
  53. agentpool/agents/slashed_agent.py +5 -4
  54. agentpool/agents/tool_call_accumulator.py +213 -0
  55. agentpool/agents/tool_wrapping.py +18 -6
  56. agentpool/common_types.py +56 -21
  57. agentpool/config_resources/__init__.py +38 -1
  58. agentpool/config_resources/acp_assistant.yml +2 -2
  59. agentpool/config_resources/agents.yml +3 -0
  60. agentpool/config_resources/agents_template.yml +1 -0
  61. agentpool/config_resources/claude_code_agent.yml +10 -6
  62. agentpool/config_resources/external_acp_agents.yml +2 -1
  63. agentpool/delegation/base_team.py +4 -30
  64. agentpool/delegation/pool.py +136 -289
  65. agentpool/delegation/team.py +58 -57
  66. agentpool/delegation/teamrun.py +51 -55
  67. agentpool/diagnostics/__init__.py +53 -0
  68. agentpool/diagnostics/lsp_manager.py +1593 -0
  69. agentpool/diagnostics/lsp_proxy.py +41 -0
  70. agentpool/diagnostics/lsp_proxy_script.py +229 -0
  71. agentpool/diagnostics/models.py +398 -0
  72. agentpool/functional/run.py +10 -4
  73. agentpool/mcp_server/__init__.py +0 -2
  74. agentpool/mcp_server/client.py +76 -32
  75. agentpool/mcp_server/conversions.py +54 -13
  76. agentpool/mcp_server/manager.py +34 -54
  77. agentpool/mcp_server/registries/official_registry_client.py +35 -1
  78. agentpool/mcp_server/tool_bridge.py +186 -139
  79. agentpool/messaging/__init__.py +0 -2
  80. agentpool/messaging/compaction.py +72 -197
  81. agentpool/messaging/connection_manager.py +11 -10
  82. agentpool/messaging/event_manager.py +5 -5
  83. agentpool/messaging/message_container.py +6 -30
  84. agentpool/messaging/message_history.py +99 -8
  85. agentpool/messaging/messagenode.py +52 -14
  86. agentpool/messaging/messages.py +54 -35
  87. agentpool/messaging/processing.py +12 -22
  88. agentpool/models/__init__.py +1 -1
  89. agentpool/models/acp_agents/base.py +6 -24
  90. agentpool/models/acp_agents/mcp_capable.py +126 -157
  91. agentpool/models/acp_agents/non_mcp.py +129 -95
  92. agentpool/models/agents.py +98 -76
  93. agentpool/models/agui_agents.py +1 -1
  94. agentpool/models/claude_code_agents.py +144 -19
  95. agentpool/models/file_parsing.py +0 -1
  96. agentpool/models/manifest.py +113 -50
  97. agentpool/prompts/conversion_manager.py +1 -1
  98. agentpool/prompts/prompts.py +5 -2
  99. agentpool/repomap.py +1 -1
  100. agentpool/resource_providers/__init__.py +11 -1
  101. agentpool/resource_providers/aggregating.py +56 -5
  102. agentpool/resource_providers/base.py +70 -4
  103. agentpool/resource_providers/codemode/code_executor.py +72 -5
  104. agentpool/resource_providers/codemode/helpers.py +2 -2
  105. agentpool/resource_providers/codemode/provider.py +64 -12
  106. agentpool/resource_providers/codemode/remote_mcp_execution.py +2 -2
  107. agentpool/resource_providers/codemode/remote_provider.py +9 -12
  108. agentpool/resource_providers/filtering.py +3 -1
  109. agentpool/resource_providers/mcp_provider.py +89 -12
  110. agentpool/resource_providers/plan_provider.py +228 -46
  111. agentpool/resource_providers/pool.py +7 -3
  112. agentpool/resource_providers/resource_info.py +111 -0
  113. agentpool/resource_providers/static.py +4 -2
  114. agentpool/sessions/__init__.py +4 -1
  115. agentpool/sessions/manager.py +33 -5
  116. agentpool/sessions/models.py +59 -6
  117. agentpool/sessions/protocol.py +28 -0
  118. agentpool/sessions/session.py +11 -55
  119. agentpool/skills/registry.py +13 -8
  120. agentpool/storage/manager.py +572 -49
  121. agentpool/talk/registry.py +4 -4
  122. agentpool/talk/talk.py +9 -10
  123. agentpool/testing.py +538 -20
  124. agentpool/tool_impls/__init__.py +6 -0
  125. agentpool/tool_impls/agent_cli/__init__.py +42 -0
  126. agentpool/tool_impls/agent_cli/tool.py +95 -0
  127. agentpool/tool_impls/bash/__init__.py +64 -0
  128. agentpool/tool_impls/bash/helpers.py +35 -0
  129. agentpool/tool_impls/bash/tool.py +171 -0
  130. agentpool/tool_impls/delete_path/__init__.py +70 -0
  131. agentpool/tool_impls/delete_path/tool.py +142 -0
  132. agentpool/tool_impls/download_file/__init__.py +80 -0
  133. agentpool/tool_impls/download_file/tool.py +183 -0
  134. agentpool/tool_impls/execute_code/__init__.py +55 -0
  135. agentpool/tool_impls/execute_code/tool.py +163 -0
  136. agentpool/tool_impls/grep/__init__.py +80 -0
  137. agentpool/tool_impls/grep/tool.py +200 -0
  138. agentpool/tool_impls/list_directory/__init__.py +73 -0
  139. agentpool/tool_impls/list_directory/tool.py +197 -0
  140. agentpool/tool_impls/question/__init__.py +42 -0
  141. agentpool/tool_impls/question/tool.py +127 -0
  142. agentpool/tool_impls/read/__init__.py +104 -0
  143. agentpool/tool_impls/read/tool.py +305 -0
  144. agentpool/tools/__init__.py +2 -1
  145. agentpool/tools/base.py +114 -34
  146. agentpool/tools/manager.py +57 -1
  147. agentpool/ui/base.py +2 -2
  148. agentpool/ui/mock_provider.py +2 -2
  149. agentpool/ui/stdlib_provider.py +2 -2
  150. agentpool/utils/file_watcher.py +269 -0
  151. agentpool/utils/identifiers.py +121 -0
  152. agentpool/utils/pydantic_ai_helpers.py +46 -0
  153. agentpool/utils/streams.py +616 -2
  154. agentpool/utils/subprocess_utils.py +155 -0
  155. agentpool/utils/token_breakdown.py +461 -0
  156. agentpool/vfs_registry.py +7 -2
  157. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/METADATA +41 -27
  158. agentpool-2.5.0.dist-info/RECORD +579 -0
  159. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/WHEEL +1 -1
  160. agentpool_cli/__main__.py +24 -0
  161. agentpool_cli/create.py +1 -1
  162. agentpool_cli/serve_acp.py +100 -21
  163. agentpool_cli/serve_agui.py +87 -0
  164. agentpool_cli/serve_opencode.py +119 -0
  165. agentpool_cli/ui.py +557 -0
  166. agentpool_commands/__init__.py +42 -5
  167. agentpool_commands/agents.py +75 -2
  168. agentpool_commands/history.py +62 -0
  169. agentpool_commands/mcp.py +176 -0
  170. agentpool_commands/models.py +56 -3
  171. agentpool_commands/pool.py +260 -0
  172. agentpool_commands/session.py +1 -1
  173. agentpool_commands/text_sharing/__init__.py +119 -0
  174. agentpool_commands/text_sharing/base.py +123 -0
  175. agentpool_commands/text_sharing/github_gist.py +80 -0
  176. agentpool_commands/text_sharing/opencode.py +462 -0
  177. agentpool_commands/text_sharing/paste_rs.py +59 -0
  178. agentpool_commands/text_sharing/pastebin.py +116 -0
  179. agentpool_commands/text_sharing/shittycodingagent.py +112 -0
  180. agentpool_commands/tools.py +57 -0
  181. agentpool_commands/utils.py +80 -30
  182. agentpool_config/__init__.py +30 -2
  183. agentpool_config/agentpool_tools.py +498 -0
  184. agentpool_config/builtin_tools.py +77 -22
  185. agentpool_config/commands.py +24 -1
  186. agentpool_config/compaction.py +258 -0
  187. agentpool_config/converters.py +1 -1
  188. agentpool_config/event_handlers.py +42 -0
  189. agentpool_config/events.py +1 -1
  190. agentpool_config/forward_targets.py +1 -4
  191. agentpool_config/jinja.py +3 -3
  192. agentpool_config/mcp_server.py +132 -6
  193. agentpool_config/nodes.py +1 -1
  194. agentpool_config/observability.py +44 -0
  195. agentpool_config/session.py +0 -3
  196. agentpool_config/storage.py +82 -38
  197. agentpool_config/task.py +3 -3
  198. agentpool_config/tools.py +11 -22
  199. agentpool_config/toolsets.py +109 -233
  200. agentpool_server/a2a_server/agent_worker.py +307 -0
  201. agentpool_server/a2a_server/server.py +23 -18
  202. agentpool_server/acp_server/acp_agent.py +234 -181
  203. agentpool_server/acp_server/commands/acp_commands.py +151 -156
  204. agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +18 -17
  205. agentpool_server/acp_server/event_converter.py +651 -0
  206. agentpool_server/acp_server/input_provider.py +53 -10
  207. agentpool_server/acp_server/server.py +24 -90
  208. agentpool_server/acp_server/session.py +173 -331
  209. agentpool_server/acp_server/session_manager.py +8 -34
  210. agentpool_server/agui_server/server.py +3 -1
  211. agentpool_server/mcp_server/server.py +5 -2
  212. agentpool_server/opencode_server/.rules +95 -0
  213. agentpool_server/opencode_server/ENDPOINTS.md +401 -0
  214. agentpool_server/opencode_server/OPENCODE_UI_TOOLS_COMPLETE.md +202 -0
  215. agentpool_server/opencode_server/__init__.py +19 -0
  216. agentpool_server/opencode_server/command_validation.py +172 -0
  217. agentpool_server/opencode_server/converters.py +975 -0
  218. agentpool_server/opencode_server/dependencies.py +24 -0
  219. agentpool_server/opencode_server/input_provider.py +421 -0
  220. agentpool_server/opencode_server/models/__init__.py +250 -0
  221. agentpool_server/opencode_server/models/agent.py +53 -0
  222. agentpool_server/opencode_server/models/app.py +72 -0
  223. agentpool_server/opencode_server/models/base.py +26 -0
  224. agentpool_server/opencode_server/models/common.py +23 -0
  225. agentpool_server/opencode_server/models/config.py +37 -0
  226. agentpool_server/opencode_server/models/events.py +821 -0
  227. agentpool_server/opencode_server/models/file.py +88 -0
  228. agentpool_server/opencode_server/models/mcp.py +44 -0
  229. agentpool_server/opencode_server/models/message.py +179 -0
  230. agentpool_server/opencode_server/models/parts.py +323 -0
  231. agentpool_server/opencode_server/models/provider.py +81 -0
  232. agentpool_server/opencode_server/models/pty.py +43 -0
  233. agentpool_server/opencode_server/models/question.py +56 -0
  234. agentpool_server/opencode_server/models/session.py +111 -0
  235. agentpool_server/opencode_server/routes/__init__.py +29 -0
  236. agentpool_server/opencode_server/routes/agent_routes.py +473 -0
  237. agentpool_server/opencode_server/routes/app_routes.py +202 -0
  238. agentpool_server/opencode_server/routes/config_routes.py +302 -0
  239. agentpool_server/opencode_server/routes/file_routes.py +571 -0
  240. agentpool_server/opencode_server/routes/global_routes.py +94 -0
  241. agentpool_server/opencode_server/routes/lsp_routes.py +319 -0
  242. agentpool_server/opencode_server/routes/message_routes.py +761 -0
  243. agentpool_server/opencode_server/routes/permission_routes.py +63 -0
  244. agentpool_server/opencode_server/routes/pty_routes.py +300 -0
  245. agentpool_server/opencode_server/routes/question_routes.py +128 -0
  246. agentpool_server/opencode_server/routes/session_routes.py +1276 -0
  247. agentpool_server/opencode_server/routes/tui_routes.py +139 -0
  248. agentpool_server/opencode_server/server.py +475 -0
  249. agentpool_server/opencode_server/state.py +151 -0
  250. agentpool_server/opencode_server/time_utils.py +8 -0
  251. agentpool_storage/__init__.py +12 -0
  252. agentpool_storage/base.py +184 -2
  253. agentpool_storage/claude_provider/ARCHITECTURE.md +433 -0
  254. agentpool_storage/claude_provider/__init__.py +42 -0
  255. agentpool_storage/claude_provider/provider.py +1089 -0
  256. agentpool_storage/file_provider.py +278 -15
  257. agentpool_storage/memory_provider.py +193 -12
  258. agentpool_storage/models.py +3 -0
  259. agentpool_storage/opencode_provider/ARCHITECTURE.md +386 -0
  260. agentpool_storage/opencode_provider/__init__.py +16 -0
  261. agentpool_storage/opencode_provider/helpers.py +414 -0
  262. agentpool_storage/opencode_provider/provider.py +895 -0
  263. agentpool_storage/project_store.py +325 -0
  264. agentpool_storage/session_store.py +26 -6
  265. agentpool_storage/sql_provider/__init__.py +4 -2
  266. agentpool_storage/sql_provider/models.py +48 -0
  267. agentpool_storage/sql_provider/sql_provider.py +269 -3
  268. agentpool_storage/sql_provider/utils.py +12 -13
  269. agentpool_storage/zed_provider/__init__.py +16 -0
  270. agentpool_storage/zed_provider/helpers.py +281 -0
  271. agentpool_storage/zed_provider/models.py +130 -0
  272. agentpool_storage/zed_provider/provider.py +442 -0
  273. agentpool_storage/zed_provider.py +803 -0
  274. agentpool_toolsets/__init__.py +0 -2
  275. agentpool_toolsets/builtin/__init__.py +2 -12
  276. agentpool_toolsets/builtin/code.py +96 -57
  277. agentpool_toolsets/builtin/debug.py +118 -48
  278. agentpool_toolsets/builtin/execution_environment.py +115 -230
  279. agentpool_toolsets/builtin/file_edit/file_edit.py +115 -7
  280. agentpool_toolsets/builtin/skills.py +9 -4
  281. agentpool_toolsets/builtin/subagent_tools.py +64 -51
  282. agentpool_toolsets/builtin/workers.py +4 -2
  283. agentpool_toolsets/composio_toolset.py +2 -2
  284. agentpool_toolsets/entry_points.py +3 -1
  285. agentpool_toolsets/fsspec_toolset/__init__.py +13 -1
  286. agentpool_toolsets/fsspec_toolset/diagnostics.py +860 -73
  287. agentpool_toolsets/fsspec_toolset/grep.py +99 -7
  288. agentpool_toolsets/fsspec_toolset/helpers.py +3 -2
  289. agentpool_toolsets/fsspec_toolset/image_utils.py +161 -0
  290. agentpool_toolsets/fsspec_toolset/toolset.py +500 -95
  291. agentpool_toolsets/mcp_discovery/__init__.py +5 -0
  292. agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
  293. agentpool_toolsets/mcp_discovery/toolset.py +511 -0
  294. agentpool_toolsets/mcp_run_toolset.py +87 -12
  295. agentpool_toolsets/notifications.py +33 -33
  296. agentpool_toolsets/openapi.py +3 -1
  297. agentpool_toolsets/search_toolset.py +3 -1
  298. agentpool-2.1.9.dist-info/RECORD +0 -474
  299. agentpool_config/resources.py +0 -33
  300. agentpool_server/acp_server/acp_tools.py +0 -43
  301. agentpool_server/acp_server/commands/spawn.py +0 -210
  302. agentpool_storage/text_log_provider.py +0 -275
  303. agentpool_toolsets/builtin/agent_management.py +0 -239
  304. agentpool_toolsets/builtin/chain.py +0 -288
  305. agentpool_toolsets/builtin/history.py +0 -36
  306. agentpool_toolsets/builtin/integration.py +0 -85
  307. agentpool_toolsets/builtin/tool_management.py +0 -90
  308. agentpool_toolsets/builtin/user_interaction.py +0 -52
  309. agentpool_toolsets/semantic_memory_toolset.py +0 -536
  310. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/entry_points.txt +0 -0
  311. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -7,156 +7,18 @@ event types as native agents.
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
- from dataclasses import dataclass, field
11
- from typing import TYPE_CHECKING, Any
10
+ from typing import TYPE_CHECKING, Any, cast
12
11
 
13
12
  from pydantic_ai import PartDeltaEvent, TextPartDelta, ThinkingPartDelta
14
13
 
15
- from agentpool.agents.events import (
16
- DiffContentItem,
17
- LocationContentItem,
18
- ToolCallCompleteEvent,
19
- ToolCallStartEvent,
20
- )
14
+ from agentpool.agents.events import ToolCallCompleteEvent, ToolCallStartEvent
21
15
 
22
16
 
23
17
  if TYPE_CHECKING:
24
- from claude_agent_sdk import ContentBlock, Message, ToolUseBlock
18
+ from claude_agent_sdk import ContentBlock, McpServerConfig, Message, ToolUseBlock
25
19
 
26
- from agentpool.agents.events import RichAgentStreamEvent, ToolCallContentItem
27
- from agentpool.tools.base import ToolKind
28
-
29
-
30
- @dataclass
31
- class RichToolInfo:
32
- """Rich display information derived from tool name and input."""
33
-
34
- title: str
35
- """Human-readable title for the tool call."""
36
- kind: ToolKind = "other"
37
- """Category of tool operation."""
38
- locations: list[LocationContentItem] = field(default_factory=list)
39
- """File locations involved in the operation."""
40
- content: list[ToolCallContentItem] = field(default_factory=list)
41
- """Rich content items (diffs, text, etc.)."""
42
-
43
-
44
- def derive_rich_tool_info(name: str, input_data: dict[str, Any]) -> RichToolInfo: # noqa: PLR0911, PLR0915
45
- """Derive rich display info from tool name and input arguments.
46
-
47
- Maps MCP tool names and their inputs to human-readable titles, kinds,
48
- and location information for rich UI display. Handles both Claude Code
49
- built-in tools and MCP bridge tools.
50
-
51
- Args:
52
- name: The tool name (e.g., "Read", "mcp__server__read_file")
53
- input_data: The tool input arguments
54
-
55
- Returns:
56
- RichToolInfo with derived display information
57
- """
58
- # Extract the actual tool name if it's an MCP bridge tool
59
- # Format: mcp__{server_name}__{tool_name}
60
- actual_name = name
61
- if name.startswith("mcp__") and "__" in name[5:]:
62
- parts = name.split("__")
63
- if len(parts) >= 3: # noqa: PLR2004
64
- actual_name = parts[-1] # Get the last part (actual tool name)
65
-
66
- # Normalize to lowercase for matching
67
- tool_lower = actual_name.lower()
68
- # Read operations
69
- if tool_lower in ("read", "read_file"):
70
- path = input_data.get("file_path") or input_data.get("path", "")
71
- offset = input_data.get("offset") or input_data.get("line")
72
- limit = input_data.get("limit")
73
-
74
- suffix = ""
75
- if limit:
76
- start = (offset or 0) + 1
77
- end = (offset or 0) + limit
78
- suffix = f" ({start}-{end})"
79
- elif offset:
80
- suffix = f" (from line {offset + 1})"
81
- title = f"Read {path}{suffix}" if path else "Read File"
82
- locations = [LocationContentItem(path=path, line=offset or 0)] if path else []
83
- return RichToolInfo(title=title, kind="read", locations=locations)
84
-
85
- # Write operations
86
- if tool_lower in ("write", "write_file"):
87
- path = input_data.get("file_path") or input_data.get("path", "")
88
- content = input_data.get("content", "")
89
- return RichToolInfo(
90
- title=f"Write {path}" if path else "Write File",
91
- kind="edit",
92
- locations=[LocationContentItem(path=path)] if path else [],
93
- content=[DiffContentItem(path=path, old_text=None, new_text=content)] if path else [],
94
- )
95
- # Edit operations
96
- if tool_lower in ("edit", "edit_file"):
97
- path = input_data.get("file_path") or input_data.get("path", "")
98
- old_string = input_data.get("old_string") or input_data.get("old_text", "")
99
- new_string = input_data.get("new_string") or input_data.get("new_text", "")
100
- return RichToolInfo(
101
- title=f"Edit {path}" if path else "Edit File",
102
- kind="edit",
103
- locations=[LocationContentItem(path=path)] if path else [],
104
- content=[DiffContentItem(path=path, old_text=old_string, new_text=new_string)]
105
- if path
106
- else [],
107
- )
108
- # Delete operations
109
- if tool_lower in ("delete", "delete_path", "delete_file"):
110
- path = input_data.get("file_path") or input_data.get("path", "")
111
- locations = [LocationContentItem(path=path)] if path else []
112
- title = f"Delete {path}" if path else "Delete"
113
- return RichToolInfo(title=title, kind="delete", locations=locations)
114
- # Bash/terminal operations
115
- if tool_lower in ("bash", "execute", "run_command", "execute_command", "execute_code"):
116
- command = input_data.get("command") or input_data.get("code", "")
117
- # Escape backticks in command
118
- escaped_cmd = command.replace("`", "\\`") if command else ""
119
- title = f"`{escaped_cmd}`" if escaped_cmd else "Terminal"
120
- return RichToolInfo(title=title, kind="execute")
121
- # Search operations
122
- if tool_lower in ("grep", "search", "glob", "find"):
123
- pattern = input_data.get("pattern") or input_data.get("query", "")
124
- path = input_data.get("path", "")
125
- title = f"Search for '{pattern}'" if pattern else "Search"
126
- if path:
127
- title += f" in {path}"
128
- locations = [LocationContentItem(path=path)] if path else []
129
- return RichToolInfo(title=title, kind="search", locations=locations)
130
- # List directory
131
- if tool_lower in ("ls", "list", "list_directory"):
132
- path = input_data.get("path", ".")
133
- title = f"List {path}" if path != "." else "List current directory"
134
- locations = [LocationContentItem(path=path)] if path else []
135
- return RichToolInfo(title=title, kind="search", locations=locations)
136
- # Web operations
137
- if tool_lower in ("webfetch", "web_fetch", "fetch"):
138
- url = input_data.get("url", "")
139
- return RichToolInfo(title=f"Fetch {url}" if url else "Web Fetch", kind="fetch")
140
- if tool_lower in ("websearch", "web_search", "search_web"):
141
- query = input_data.get("query", "")
142
- return RichToolInfo(title=f"Search: {query}" if query else "Web Search", kind="fetch")
143
- # Task/subagent operations
144
- if tool_lower == "task":
145
- description = input_data.get("description", "")
146
- return RichToolInfo(title=description if description else "Task", kind="think")
147
- # Notebook operations
148
- if tool_lower in ("notebookread", "notebook_read"):
149
- path = input_data.get("notebook_path", "")
150
- title = f"Read Notebook {path}" if path else "Read Notebook"
151
- locations = [LocationContentItem(path=path)] if path else []
152
- return RichToolInfo(title=title, kind="read", locations=locations)
153
- if tool_lower in ("notebookedit", "notebook_edit"):
154
- path = input_data.get("notebook_path", "")
155
- title = f"Edit Notebook {path}" if path else "Edit Notebook"
156
- locations = [LocationContentItem(path=path)] if path else []
157
- return RichToolInfo(title=title, kind="edit", locations=locations)
158
- # Default: use the tool name as title
159
- return RichToolInfo(title=actual_name, kind="other")
20
+ from agentpool.agents.events import RichAgentStreamEvent
21
+ from agentpool_config.mcp_server import MCPServerConfig as NativeMCPServerConfig
160
22
 
161
23
 
162
24
  def content_block_to_event(block: ContentBlock, index: int = 0) -> RichAgentStreamEvent[Any] | None:
@@ -171,6 +33,8 @@ def content_block_to_event(block: ContentBlock, index: int = 0) -> RichAgentStre
171
33
  """
172
34
  from claude_agent_sdk import TextBlock, ThinkingBlock, ToolUseBlock
173
35
 
36
+ from agentpool.agents.events.infer_info import derive_rich_tool_info
37
+
174
38
  match block:
175
39
  case TextBlock(text=text):
176
40
  return PartDeltaEvent(index=index, delta=TextPartDelta(content_delta=text))
@@ -241,3 +105,70 @@ def claude_message_to_events(
241
105
  pass
242
106
 
243
107
  return events
108
+
109
+
110
+ def convert_mcp_servers_to_sdk_format(
111
+ mcp_servers: list[NativeMCPServerConfig],
112
+ ) -> dict[str, McpServerConfig]:
113
+ """Convert internal MCPServerConfig to Claude SDK format.
114
+
115
+ Returns:
116
+ Dict mapping server names to SDK-compatible config dicts
117
+ """
118
+ from claude_agent_sdk import McpServerConfig
119
+
120
+ from agentpool_config.mcp_server import (
121
+ SSEMCPServerConfig,
122
+ StdioMCPServerConfig,
123
+ StreamableHTTPMCPServerConfig,
124
+ )
125
+
126
+ result: dict[str, McpServerConfig] = {}
127
+
128
+ for idx, server in enumerate(mcp_servers):
129
+ # Determine server name
130
+ if server.name:
131
+ name = server.name
132
+ elif isinstance(server, StdioMCPServerConfig) and server.args:
133
+ name = server.args[-1].split("/")[-1].split("@")[0]
134
+ elif isinstance(server, StdioMCPServerConfig):
135
+ name = server.command
136
+ elif isinstance(server, SSEMCPServerConfig | StreamableHTTPMCPServerConfig):
137
+ from urllib.parse import urlparse
138
+
139
+ name = urlparse(str(server.url)).hostname or f"server_{idx}"
140
+ else:
141
+ name = f"server_{idx}"
142
+
143
+ # Build SDK-compatible config
144
+ config: dict[str, Any]
145
+ match server:
146
+ case StdioMCPServerConfig(command=command, args=args):
147
+ config = {"type": "stdio", "command": command, "args": args}
148
+ if server.env:
149
+ config["env"] = server.get_env_vars()
150
+ case SSEMCPServerConfig(url=url):
151
+ config = {"type": "sse", "url": str(url)}
152
+ if server.headers:
153
+ config["headers"] = server.headers
154
+ case StreamableHTTPMCPServerConfig(url=url):
155
+ config = {"type": "http", "url": str(url)}
156
+ if server.headers:
157
+ config["headers"] = server.headers
158
+
159
+ result[name] = cast(McpServerConfig, config)
160
+
161
+ return result
162
+
163
+
164
+ def to_output_format(output_type: type) -> dict[str, Any] | None:
165
+ """Convert to SDK output format dict."""
166
+ from pydantic import TypeAdapter
167
+
168
+ # Build structured output format if needed
169
+ output_format: dict[str, Any] | None = None
170
+ if output_type is not str:
171
+ adapter = TypeAdapter[Any](output_type)
172
+ schema = adapter.json_schema()
173
+ output_format = {"type": "json_schema", "schema": schema}
174
+ return output_format