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.
- acp/__init__.py +13 -0
- acp/bridge/README.md +15 -2
- acp/bridge/__init__.py +3 -2
- acp/bridge/__main__.py +60 -19
- acp/bridge/ws_server.py +173 -0
- acp/bridge/ws_server_cli.py +89 -0
- acp/notifications.py +2 -1
- acp/stdio.py +39 -9
- acp/transports.py +362 -2
- acp/utils.py +15 -2
- agentpool/__init__.py +4 -1
- agentpool/agents/__init__.py +2 -0
- agentpool/agents/acp_agent/acp_agent.py +203 -88
- agentpool/agents/acp_agent/acp_converters.py +46 -21
- agentpool/agents/acp_agent/client_handler.py +157 -3
- agentpool/agents/acp_agent/session_state.py +4 -1
- agentpool/agents/agent.py +314 -107
- agentpool/agents/agui_agent/__init__.py +0 -2
- agentpool/agents/agui_agent/agui_agent.py +90 -21
- agentpool/agents/agui_agent/agui_converters.py +0 -131
- agentpool/agents/base_agent.py +163 -1
- agentpool/agents/claude_code_agent/claude_code_agent.py +626 -179
- agentpool/agents/claude_code_agent/converters.py +71 -3
- agentpool/agents/claude_code_agent/history.py +474 -0
- agentpool/agents/context.py +40 -0
- agentpool/agents/events/__init__.py +2 -0
- agentpool/agents/events/builtin_handlers.py +2 -1
- agentpool/agents/events/event_emitter.py +29 -2
- agentpool/agents/events/events.py +20 -0
- agentpool/agents/modes.py +54 -0
- agentpool/agents/tool_call_accumulator.py +213 -0
- agentpool/common_types.py +21 -0
- agentpool/config_resources/__init__.py +38 -1
- agentpool/config_resources/claude_code_agent.yml +3 -0
- agentpool/delegation/pool.py +37 -29
- agentpool/delegation/team.py +1 -0
- agentpool/delegation/teamrun.py +1 -0
- agentpool/diagnostics/__init__.py +53 -0
- agentpool/diagnostics/lsp_manager.py +1593 -0
- agentpool/diagnostics/lsp_proxy.py +41 -0
- agentpool/diagnostics/lsp_proxy_script.py +229 -0
- agentpool/diagnostics/models.py +398 -0
- agentpool/mcp_server/__init__.py +0 -2
- agentpool/mcp_server/client.py +12 -3
- agentpool/mcp_server/manager.py +25 -31
- agentpool/mcp_server/registries/official_registry_client.py +25 -0
- agentpool/mcp_server/tool_bridge.py +78 -66
- agentpool/messaging/__init__.py +0 -2
- agentpool/messaging/compaction.py +72 -197
- agentpool/messaging/message_history.py +12 -0
- agentpool/messaging/messages.py +52 -9
- agentpool/messaging/processing.py +3 -1
- agentpool/models/acp_agents/base.py +0 -22
- agentpool/models/acp_agents/mcp_capable.py +8 -148
- agentpool/models/acp_agents/non_mcp.py +129 -72
- agentpool/models/agents.py +35 -13
- agentpool/models/claude_code_agents.py +33 -2
- agentpool/models/manifest.py +43 -0
- agentpool/repomap.py +1 -1
- agentpool/resource_providers/__init__.py +9 -1
- agentpool/resource_providers/aggregating.py +52 -3
- agentpool/resource_providers/base.py +57 -1
- agentpool/resource_providers/mcp_provider.py +23 -0
- agentpool/resource_providers/plan_provider.py +130 -41
- agentpool/resource_providers/pool.py +2 -0
- agentpool/resource_providers/static.py +2 -0
- agentpool/sessions/__init__.py +2 -1
- agentpool/sessions/manager.py +31 -2
- agentpool/sessions/models.py +50 -0
- agentpool/skills/registry.py +13 -8
- agentpool/storage/manager.py +217 -1
- agentpool/testing.py +537 -19
- agentpool/utils/file_watcher.py +269 -0
- agentpool/utils/identifiers.py +121 -0
- agentpool/utils/pydantic_ai_helpers.py +46 -0
- agentpool/utils/streams.py +690 -1
- agentpool/utils/subprocess_utils.py +155 -0
- agentpool/utils/token_breakdown.py +461 -0
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/METADATA +27 -7
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/RECORD +170 -112
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/WHEEL +1 -1
- agentpool_cli/__main__.py +4 -0
- agentpool_cli/serve_acp.py +41 -20
- agentpool_cli/serve_agui.py +87 -0
- agentpool_cli/serve_opencode.py +119 -0
- agentpool_commands/__init__.py +30 -0
- agentpool_commands/agents.py +74 -1
- agentpool_commands/history.py +62 -0
- agentpool_commands/mcp.py +176 -0
- agentpool_commands/models.py +56 -3
- agentpool_commands/tools.py +57 -0
- agentpool_commands/utils.py +51 -0
- agentpool_config/builtin_tools.py +77 -22
- agentpool_config/commands.py +24 -1
- agentpool_config/compaction.py +258 -0
- agentpool_config/mcp_server.py +131 -1
- agentpool_config/storage.py +46 -1
- agentpool_config/tools.py +7 -1
- agentpool_config/toolsets.py +92 -148
- agentpool_server/acp_server/acp_agent.py +134 -150
- agentpool_server/acp_server/commands/acp_commands.py +216 -51
- agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +10 -10
- agentpool_server/acp_server/server.py +23 -79
- agentpool_server/acp_server/session.py +181 -19
- agentpool_server/opencode_server/.rules +95 -0
- agentpool_server/opencode_server/ENDPOINTS.md +362 -0
- agentpool_server/opencode_server/__init__.py +27 -0
- agentpool_server/opencode_server/command_validation.py +172 -0
- agentpool_server/opencode_server/converters.py +869 -0
- agentpool_server/opencode_server/dependencies.py +24 -0
- agentpool_server/opencode_server/input_provider.py +269 -0
- agentpool_server/opencode_server/models/__init__.py +228 -0
- agentpool_server/opencode_server/models/agent.py +53 -0
- agentpool_server/opencode_server/models/app.py +60 -0
- agentpool_server/opencode_server/models/base.py +26 -0
- agentpool_server/opencode_server/models/common.py +23 -0
- agentpool_server/opencode_server/models/config.py +37 -0
- agentpool_server/opencode_server/models/events.py +647 -0
- agentpool_server/opencode_server/models/file.py +88 -0
- agentpool_server/opencode_server/models/mcp.py +25 -0
- agentpool_server/opencode_server/models/message.py +162 -0
- agentpool_server/opencode_server/models/parts.py +190 -0
- agentpool_server/opencode_server/models/provider.py +81 -0
- agentpool_server/opencode_server/models/pty.py +43 -0
- agentpool_server/opencode_server/models/session.py +99 -0
- agentpool_server/opencode_server/routes/__init__.py +25 -0
- agentpool_server/opencode_server/routes/agent_routes.py +442 -0
- agentpool_server/opencode_server/routes/app_routes.py +139 -0
- agentpool_server/opencode_server/routes/config_routes.py +241 -0
- agentpool_server/opencode_server/routes/file_routes.py +392 -0
- agentpool_server/opencode_server/routes/global_routes.py +94 -0
- agentpool_server/opencode_server/routes/lsp_routes.py +319 -0
- agentpool_server/opencode_server/routes/message_routes.py +705 -0
- agentpool_server/opencode_server/routes/pty_routes.py +299 -0
- agentpool_server/opencode_server/routes/session_routes.py +1205 -0
- agentpool_server/opencode_server/routes/tui_routes.py +139 -0
- agentpool_server/opencode_server/server.py +430 -0
- agentpool_server/opencode_server/state.py +121 -0
- agentpool_server/opencode_server/time_utils.py +8 -0
- agentpool_storage/__init__.py +16 -0
- agentpool_storage/base.py +103 -0
- agentpool_storage/claude_provider.py +907 -0
- agentpool_storage/file_provider.py +129 -0
- agentpool_storage/memory_provider.py +61 -0
- agentpool_storage/models.py +3 -0
- agentpool_storage/opencode_provider.py +730 -0
- agentpool_storage/project_store.py +325 -0
- agentpool_storage/session_store.py +6 -0
- agentpool_storage/sql_provider/__init__.py +4 -2
- agentpool_storage/sql_provider/models.py +48 -0
- agentpool_storage/sql_provider/sql_provider.py +134 -1
- agentpool_storage/sql_provider/utils.py +10 -1
- agentpool_storage/text_log_provider.py +1 -0
- agentpool_toolsets/builtin/__init__.py +0 -8
- agentpool_toolsets/builtin/code.py +95 -56
- agentpool_toolsets/builtin/debug.py +16 -21
- agentpool_toolsets/builtin/execution_environment.py +99 -103
- agentpool_toolsets/builtin/file_edit/file_edit.py +115 -7
- agentpool_toolsets/builtin/skills.py +86 -4
- agentpool_toolsets/fsspec_toolset/__init__.py +13 -1
- agentpool_toolsets/fsspec_toolset/diagnostics.py +860 -73
- agentpool_toolsets/fsspec_toolset/grep.py +74 -2
- agentpool_toolsets/fsspec_toolset/image_utils.py +161 -0
- agentpool_toolsets/fsspec_toolset/toolset.py +159 -38
- agentpool_toolsets/mcp_discovery/__init__.py +5 -0
- agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
- agentpool_toolsets/mcp_discovery/toolset.py +454 -0
- agentpool_toolsets/mcp_run_toolset.py +84 -6
- agentpool_toolsets/builtin/agent_management.py +0 -239
- agentpool_toolsets/builtin/history.py +0 -36
- agentpool_toolsets/builtin/integration.py +0 -85
- agentpool_toolsets/builtin/tool_management.py +0 -90
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/entry_points.txt +0 -0
- {agentpool-2.1.9.dist-info → agentpool-2.2.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -13,15 +13,21 @@ from upathtools import is_directory
|
|
|
13
13
|
from agentpool.agents.context import AgentContext # noqa: TC001
|
|
14
14
|
from agentpool.log import get_logger
|
|
15
15
|
from agentpool.resource_providers import ResourceProvider
|
|
16
|
-
from agentpool_toolsets.fsspec_toolset.diagnostics import
|
|
16
|
+
from agentpool_toolsets.fsspec_toolset.diagnostics import (
|
|
17
|
+
DiagnosticsManager,
|
|
18
|
+
format_diagnostics_table,
|
|
19
|
+
format_run_summary,
|
|
20
|
+
)
|
|
17
21
|
|
|
18
22
|
|
|
19
23
|
if TYPE_CHECKING:
|
|
20
|
-
from anyenv.lsp_servers import Diagnostic
|
|
21
24
|
from exxec.base import ExecutionEnvironment
|
|
25
|
+
from fsspec.asyn import AsyncFileSystem
|
|
22
26
|
|
|
23
27
|
from agentpool.tools.base import Tool
|
|
24
|
-
|
|
28
|
+
from agentpool_toolsets.fsspec_toolset.diagnostics import (
|
|
29
|
+
DiagnosticsConfig,
|
|
30
|
+
)
|
|
25
31
|
|
|
26
32
|
logger = get_logger(__name__)
|
|
27
33
|
|
|
@@ -87,46 +93,58 @@ class CodeTools(ResourceProvider):
|
|
|
87
93
|
env: ExecutionEnvironment | None = None,
|
|
88
94
|
name: str = "code",
|
|
89
95
|
cwd: str | None = None,
|
|
96
|
+
diagnostics_config: DiagnosticsConfig | None = None,
|
|
90
97
|
) -> None:
|
|
91
98
|
"""Initialize with an optional execution environment.
|
|
92
99
|
|
|
93
100
|
Args:
|
|
94
101
|
env: Execution environment to operate on. If None, falls back to agent.env
|
|
95
102
|
name: Name for this toolset provider
|
|
96
|
-
cwd: Optional cwd to resolve relative paths against
|
|
103
|
+
cwd: Optional cwd to resolve relative paths against (falls back to env.cwd)
|
|
104
|
+
diagnostics_config: Configuration for diagnostic tools (server selection, etc.)
|
|
97
105
|
"""
|
|
106
|
+
super().__init__(name=name)
|
|
107
|
+
|
|
108
|
+
self._explicit_env = env
|
|
109
|
+
self._explicit_cwd = cwd
|
|
110
|
+
self._diagnostics_config = diagnostics_config
|
|
111
|
+
self._tools: list[Tool] | None = None
|
|
112
|
+
|
|
113
|
+
def _get_env(self, agent_ctx: AgentContext) -> ExecutionEnvironment | None:
|
|
114
|
+
"""Get execution environment (explicit or from agent)."""
|
|
115
|
+
return self._explicit_env or agent_ctx.agent.env
|
|
116
|
+
|
|
117
|
+
def _get_cwd(self, agent_ctx: AgentContext) -> str | None:
|
|
118
|
+
"""Get working directory (explicit, from env, or from agent.env)."""
|
|
119
|
+
if self._explicit_cwd:
|
|
120
|
+
return self._explicit_cwd
|
|
121
|
+
env = self._get_env(agent_ctx)
|
|
122
|
+
return env.cwd if env else None
|
|
123
|
+
|
|
124
|
+
def _get_fs(self, agent_ctx: AgentContext) -> AsyncFileSystem:
|
|
125
|
+
"""Get filesystem (from env or fallback to local)."""
|
|
98
126
|
from fsspec.asyn import AsyncFileSystem
|
|
99
127
|
from fsspec.implementations.asyn_wrapper import AsyncFileSystemWrapper
|
|
100
128
|
from morefs.asyn_local import AsyncLocalFileSystem
|
|
101
129
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
self.execution_env = env
|
|
105
|
-
self.cwd = cwd or (env.cwd if env else None)
|
|
130
|
+
env = self._get_env(agent_ctx)
|
|
106
131
|
fs = env.get_fs() if env else None
|
|
107
132
|
match fs:
|
|
108
133
|
case AsyncFileSystem():
|
|
109
|
-
|
|
134
|
+
return fs
|
|
110
135
|
case AbstractFileSystem():
|
|
111
|
-
|
|
112
|
-
case
|
|
113
|
-
|
|
114
|
-
self._tools: list[Tool] | None = None
|
|
115
|
-
self._diagnostics: DiagnosticsManager | None = None
|
|
116
|
-
|
|
117
|
-
def _get_env(self, agent_ctx: AgentContext) -> ExecutionEnvironment | None:
|
|
118
|
-
"""Get execution environment (explicit or from agent)."""
|
|
119
|
-
return self.execution_env or agent_ctx.agent.env
|
|
136
|
+
return AsyncFileSystemWrapper(fs)
|
|
137
|
+
case _:
|
|
138
|
+
return AsyncLocalFileSystem()
|
|
120
139
|
|
|
121
140
|
def _resolve_path(self, path: str, agent_ctx: AgentContext) -> str:
|
|
122
141
|
"""Resolve a potentially relative path to an absolute path.
|
|
123
142
|
|
|
124
|
-
Gets cwd from
|
|
143
|
+
Gets cwd from explicit cwd, env.cwd, or agent.env.cwd.
|
|
125
144
|
If cwd is set and path is relative, resolves relative to cwd.
|
|
126
145
|
Otherwise returns the path as-is.
|
|
127
146
|
"""
|
|
128
|
-
|
|
129
|
-
cwd = self.cwd or (env.cwd if env else None)
|
|
147
|
+
cwd = self._get_cwd(agent_ctx)
|
|
130
148
|
if cwd and not (path.startswith("/") or (len(path) > 1 and path[1] == ":")):
|
|
131
149
|
return str(Path(cwd) / path)
|
|
132
150
|
return path
|
|
@@ -160,8 +178,9 @@ class CodeTools(ResourceProvider):
|
|
|
160
178
|
from anyenv.language_formatters import FormatterRegistry
|
|
161
179
|
|
|
162
180
|
resolved = self._resolve_path(path, agent_ctx)
|
|
181
|
+
fs = self._get_fs(agent_ctx)
|
|
163
182
|
try:
|
|
164
|
-
content = await
|
|
183
|
+
content = await fs._cat_file(resolved)
|
|
165
184
|
code = content.decode("utf-8") if isinstance(content, bytes) else content
|
|
166
185
|
except FileNotFoundError:
|
|
167
186
|
return f"❌ File not found: {path}"
|
|
@@ -189,7 +208,7 @@ class CodeTools(ResourceProvider):
|
|
|
189
208
|
if result.success:
|
|
190
209
|
# Write back if formatted
|
|
191
210
|
if result.format_result.formatted and result.format_result.output:
|
|
192
|
-
await
|
|
211
|
+
await fs._pipe_file(resolved, result.format_result.output.encode("utf-8"))
|
|
193
212
|
changes = "formatted and saved"
|
|
194
213
|
else:
|
|
195
214
|
changes = "no changes needed"
|
|
@@ -271,6 +290,7 @@ class CodeTools(ResourceProvider):
|
|
|
271
290
|
from ast_grep_py import SgRoot
|
|
272
291
|
|
|
273
292
|
resolved = self._resolve_path(path, agent_ctx)
|
|
293
|
+
fs = self._get_fs(agent_ctx)
|
|
274
294
|
|
|
275
295
|
# Detect language from extension
|
|
276
296
|
language = _detect_language(path)
|
|
@@ -279,7 +299,7 @@ class CodeTools(ResourceProvider):
|
|
|
279
299
|
|
|
280
300
|
# Read file
|
|
281
301
|
try:
|
|
282
|
-
content = await
|
|
302
|
+
content = await fs._cat_file(resolved)
|
|
283
303
|
code = content.decode("utf-8") if isinstance(content, bytes) else content
|
|
284
304
|
except FileNotFoundError:
|
|
285
305
|
return {"error": f"File not found: {path}"}
|
|
@@ -318,7 +338,7 @@ class CodeTools(ResourceProvider):
|
|
|
318
338
|
result["dry_run"] = dry_run
|
|
319
339
|
|
|
320
340
|
if not dry_run:
|
|
321
|
-
await
|
|
341
|
+
await fs._pipe_file(resolved, fixed_code.encode("utf-8"))
|
|
322
342
|
result["written"] = True
|
|
323
343
|
|
|
324
344
|
return result
|
|
@@ -343,29 +363,46 @@ class CodeTools(ResourceProvider):
|
|
|
343
363
|
ones based on file extensions.
|
|
344
364
|
"""
|
|
345
365
|
resolved = self._resolve_path(path, agent_ctx)
|
|
366
|
+
fs = self._get_fs(agent_ctx)
|
|
367
|
+
env = self._get_env(agent_ctx)
|
|
346
368
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
369
|
+
if not env:
|
|
370
|
+
return "Diagnostics unavailable: no execution environment configured"
|
|
371
|
+
|
|
372
|
+
# Create diagnostics manager with config
|
|
373
|
+
manager = DiagnosticsManager(env, config=self._diagnostics_config)
|
|
374
|
+
|
|
375
|
+
# Progress callback that emits tool_call_progress events
|
|
376
|
+
async def progress_callback(
|
|
377
|
+
message: str,
|
|
378
|
+
*,
|
|
379
|
+
server_id: str | None = None,
|
|
380
|
+
command: str | None = None,
|
|
381
|
+
status: str = "running",
|
|
382
|
+
) -> None:
|
|
383
|
+
items = []
|
|
384
|
+
if command:
|
|
385
|
+
items.append(f"```bash\n{command}\n```")
|
|
386
|
+
await agent_ctx.events.tool_call_progress(
|
|
387
|
+
message,
|
|
388
|
+
status="in_progress",
|
|
389
|
+
items=items if items else None,
|
|
390
|
+
)
|
|
353
391
|
|
|
354
392
|
# Check if path is directory or file
|
|
355
393
|
try:
|
|
356
|
-
is_dir = await
|
|
394
|
+
is_dir = await fs._isdir(resolved)
|
|
357
395
|
except Exception: # noqa: BLE001
|
|
358
396
|
is_dir = False
|
|
359
397
|
|
|
360
398
|
if is_dir:
|
|
361
399
|
# Collect all files in directory
|
|
362
400
|
try:
|
|
363
|
-
files = await
|
|
364
|
-
# Filter to only include files (not directories)
|
|
401
|
+
files = await fs._find(resolved, detail=True)
|
|
365
402
|
file_paths = [
|
|
366
|
-
|
|
367
|
-
for
|
|
368
|
-
if not await is_directory(
|
|
403
|
+
p
|
|
404
|
+
for p, info in files.items() # pyright: ignore[reportAttributeAccessIssue]
|
|
405
|
+
if not await is_directory(fs, p, entry_type=info["type"])
|
|
369
406
|
]
|
|
370
407
|
except Exception as e: # noqa: BLE001
|
|
371
408
|
return f"Error scanning directory: {e}"
|
|
@@ -373,26 +410,28 @@ class CodeTools(ResourceProvider):
|
|
|
373
410
|
if not file_paths:
|
|
374
411
|
return f"No files found in: {path}"
|
|
375
412
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
413
|
+
result = await manager.run_for_files(file_paths, progress=progress_callback)
|
|
414
|
+
else:
|
|
415
|
+
# Single file
|
|
416
|
+
try:
|
|
417
|
+
result = await manager.run_for_file(resolved, progress=progress_callback)
|
|
418
|
+
except FileNotFoundError:
|
|
419
|
+
return f"File not found: {path}"
|
|
420
|
+
except Exception as e: # noqa: BLE001
|
|
421
|
+
return f"Error running diagnostics: {e}"
|
|
380
422
|
|
|
381
|
-
|
|
382
|
-
|
|
423
|
+
# Format output
|
|
424
|
+
if not result.diagnostics:
|
|
425
|
+
summary = format_run_summary(result)
|
|
426
|
+
return f"No issues found. {summary}"
|
|
383
427
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
# Single file
|
|
387
|
-
try:
|
|
388
|
-
diagnostics = await self._diagnostics.run_for_file(resolved)
|
|
389
|
-
except FileNotFoundError:
|
|
390
|
-
return f"File not found: {path}"
|
|
391
|
-
except Exception as e: # noqa: BLE001
|
|
392
|
-
return f"Error running diagnostics: {e}"
|
|
428
|
+
formatted = format_diagnostics_table(result.diagnostics)
|
|
429
|
+
summary = format_run_summary(result)
|
|
393
430
|
|
|
394
|
-
|
|
395
|
-
|
|
431
|
+
await agent_ctx.events.tool_call_progress(
|
|
432
|
+
summary,
|
|
433
|
+
status="in_progress",
|
|
434
|
+
items=[formatted],
|
|
435
|
+
)
|
|
396
436
|
|
|
397
|
-
formatted
|
|
398
|
-
return f"Found {len(diagnostics)} issues:\n{formatted}"
|
|
437
|
+
return f"{summary}\n\n{formatted}"
|
|
@@ -138,8 +138,8 @@ Write an async main() function that returns the result.
|
|
|
138
138
|
Example - inspect your own tools:
|
|
139
139
|
```python
|
|
140
140
|
async def main():
|
|
141
|
-
tools = me.tools.list_tools()
|
|
142
|
-
return
|
|
141
|
+
tools = await me.tools.list_tools()
|
|
142
|
+
return list(tools.keys())
|
|
143
143
|
```
|
|
144
144
|
|
|
145
145
|
Example - check pool state:
|
|
@@ -171,6 +171,13 @@ async def execute_introspection(ctx: AgentContext, run_ctx: RunContext[Any], cod
|
|
|
171
171
|
Returns:
|
|
172
172
|
Result of execution or error message
|
|
173
173
|
"""
|
|
174
|
+
# Emit progress with the code being executed
|
|
175
|
+
await ctx.events.tool_call_progress(
|
|
176
|
+
title="Executing introspection code",
|
|
177
|
+
status="in_progress",
|
|
178
|
+
items=[f"```python\n{code}\n```"],
|
|
179
|
+
)
|
|
180
|
+
|
|
174
181
|
# Build namespace with runtime context
|
|
175
182
|
namespace: dict[str, Any] = {"ctx": ctx, "run_ctx": run_ctx, "me": ctx.agent}
|
|
176
183
|
try:
|
|
@@ -178,6 +185,12 @@ async def execute_introspection(ctx: AgentContext, run_ctx: RunContext[Any], cod
|
|
|
178
185
|
if "main" not in namespace:
|
|
179
186
|
return "Error: Code must define an async main() function"
|
|
180
187
|
result = await namespace["main"]()
|
|
188
|
+
await ctx.events.tool_call_progress(
|
|
189
|
+
title="Executed introspection code successfully",
|
|
190
|
+
status="in_progress",
|
|
191
|
+
items=[f"```python\n{code}\n```\n\n```terminal\n{result}\n```"],
|
|
192
|
+
)
|
|
193
|
+
|
|
181
194
|
return str(result) if result is not None else "Code executed successfully (no return value)"
|
|
182
195
|
except Exception as e: # noqa: BLE001
|
|
183
196
|
return f"Error executing code: {type(e).__name__}: {e}"
|
|
@@ -216,18 +229,6 @@ async def get_logs(
|
|
|
216
229
|
return "\n".join(lines)
|
|
217
230
|
|
|
218
231
|
|
|
219
|
-
async def clear_logs() -> str:
|
|
220
|
-
"""Clear all captured log entries from memory.
|
|
221
|
-
|
|
222
|
-
Returns:
|
|
223
|
-
Confirmation message
|
|
224
|
-
"""
|
|
225
|
-
handler = get_memory_handler()
|
|
226
|
-
count = len(handler.records)
|
|
227
|
-
handler.clear()
|
|
228
|
-
return f"Cleared {count} log entries"
|
|
229
|
-
|
|
230
|
-
|
|
231
232
|
# =============================================================================
|
|
232
233
|
# Path Tools
|
|
233
234
|
# =============================================================================
|
|
@@ -270,22 +271,16 @@ class DebugTools(StaticResourceProvider):
|
|
|
270
271
|
- Platform path discovery
|
|
271
272
|
"""
|
|
272
273
|
|
|
273
|
-
def __init__(self, name: str = "debug"
|
|
274
|
+
def __init__(self, name: str = "debug") -> None:
|
|
274
275
|
"""Initialize debug tools.
|
|
275
276
|
|
|
276
277
|
Args:
|
|
277
278
|
name: Toolset name/namespace
|
|
278
|
-
install_log_handler: Whether to install the memory log handler
|
|
279
279
|
"""
|
|
280
280
|
super().__init__(name=name)
|
|
281
281
|
|
|
282
|
-
if install_log_handler:
|
|
283
|
-
install_memory_handler()
|
|
284
|
-
|
|
285
282
|
desc = (execute_introspection.__doc__ or "") + "\n\n" + INTROSPECTION_USAGE
|
|
286
283
|
self._tools = [
|
|
287
284
|
self.create_tool(execute_introspection, category="other", description_override=desc),
|
|
288
|
-
self.create_tool(get_logs, category="other", read_only=True, idempotent=True),
|
|
289
|
-
self.create_tool(clear_logs, category="other"),
|
|
290
285
|
self.create_tool(get_platform_paths, category="other", read_only=True, idempotent=True),
|
|
291
286
|
]
|