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.
- acp/__init__.py +13 -4
- acp/acp_requests.py +20 -77
- acp/agent/connection.py +8 -0
- acp/agent/implementations/debug_server/debug_server.py +6 -2
- acp/agent/protocol.py +6 -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/client/connection.py +38 -29
- acp/client/implementations/default_client.py +3 -2
- acp/client/implementations/headless_client.py +2 -2
- acp/connection.py +2 -2
- acp/notifications.py +20 -50
- acp/schema/__init__.py +2 -0
- acp/schema/agent_responses.py +21 -0
- acp/schema/client_requests.py +3 -3
- acp/schema/session_state.py +63 -29
- acp/stdio.py +39 -9
- acp/task/supervisor.py +2 -2
- acp/transports.py +362 -2
- acp/utils.py +17 -4
- agentpool/__init__.py +6 -1
- agentpool/agents/__init__.py +2 -0
- agentpool/agents/acp_agent/acp_agent.py +407 -277
- agentpool/agents/acp_agent/acp_converters.py +196 -38
- agentpool/agents/acp_agent/client_handler.py +191 -26
- agentpool/agents/acp_agent/session_state.py +17 -6
- agentpool/agents/agent.py +607 -572
- agentpool/agents/agui_agent/__init__.py +0 -2
- agentpool/agents/agui_agent/agui_agent.py +176 -110
- agentpool/agents/agui_agent/agui_converters.py +0 -131
- agentpool/agents/agui_agent/helpers.py +3 -4
- agentpool/agents/base_agent.py +632 -17
- agentpool/agents/claude_code_agent/FORKING.md +191 -0
- agentpool/agents/claude_code_agent/__init__.py +13 -1
- agentpool/agents/claude_code_agent/claude_code_agent.py +1058 -291
- agentpool/agents/claude_code_agent/converters.py +74 -143
- agentpool/agents/claude_code_agent/history.py +474 -0
- agentpool/agents/claude_code_agent/models.py +77 -0
- agentpool/agents/claude_code_agent/static_info.py +100 -0
- agentpool/agents/claude_code_agent/usage.py +242 -0
- agentpool/agents/context.py +40 -0
- agentpool/agents/events/__init__.py +24 -0
- agentpool/agents/events/builtin_handlers.py +67 -1
- agentpool/agents/events/event_emitter.py +32 -2
- agentpool/agents/events/events.py +104 -3
- agentpool/agents/events/infer_info.py +145 -0
- agentpool/agents/events/processors.py +254 -0
- agentpool/agents/interactions.py +41 -6
- agentpool/agents/modes.py +67 -0
- agentpool/agents/slashed_agent.py +5 -4
- agentpool/agents/tool_call_accumulator.py +213 -0
- agentpool/agents/tool_wrapping.py +18 -6
- agentpool/common_types.py +56 -21
- agentpool/config_resources/__init__.py +38 -1
- agentpool/config_resources/acp_assistant.yml +2 -2
- agentpool/config_resources/agents.yml +3 -0
- agentpool/config_resources/agents_template.yml +1 -0
- agentpool/config_resources/claude_code_agent.yml +10 -6
- agentpool/config_resources/external_acp_agents.yml +2 -1
- agentpool/delegation/base_team.py +4 -30
- agentpool/delegation/pool.py +136 -289
- agentpool/delegation/team.py +58 -57
- agentpool/delegation/teamrun.py +51 -55
- 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/functional/run.py +10 -4
- agentpool/mcp_server/__init__.py +0 -2
- agentpool/mcp_server/client.py +76 -32
- agentpool/mcp_server/conversions.py +54 -13
- agentpool/mcp_server/manager.py +34 -54
- agentpool/mcp_server/registries/official_registry_client.py +35 -1
- agentpool/mcp_server/tool_bridge.py +186 -139
- agentpool/messaging/__init__.py +0 -2
- agentpool/messaging/compaction.py +72 -197
- agentpool/messaging/connection_manager.py +11 -10
- agentpool/messaging/event_manager.py +5 -5
- agentpool/messaging/message_container.py +6 -30
- agentpool/messaging/message_history.py +99 -8
- agentpool/messaging/messagenode.py +52 -14
- agentpool/messaging/messages.py +54 -35
- agentpool/messaging/processing.py +12 -22
- agentpool/models/__init__.py +1 -1
- agentpool/models/acp_agents/base.py +6 -24
- agentpool/models/acp_agents/mcp_capable.py +126 -157
- agentpool/models/acp_agents/non_mcp.py +129 -95
- agentpool/models/agents.py +98 -76
- agentpool/models/agui_agents.py +1 -1
- agentpool/models/claude_code_agents.py +144 -19
- agentpool/models/file_parsing.py +0 -1
- agentpool/models/manifest.py +113 -50
- agentpool/prompts/conversion_manager.py +1 -1
- agentpool/prompts/prompts.py +5 -2
- agentpool/repomap.py +1 -1
- agentpool/resource_providers/__init__.py +11 -1
- agentpool/resource_providers/aggregating.py +56 -5
- agentpool/resource_providers/base.py +70 -4
- agentpool/resource_providers/codemode/code_executor.py +72 -5
- agentpool/resource_providers/codemode/helpers.py +2 -2
- agentpool/resource_providers/codemode/provider.py +64 -12
- agentpool/resource_providers/codemode/remote_mcp_execution.py +2 -2
- agentpool/resource_providers/codemode/remote_provider.py +9 -12
- agentpool/resource_providers/filtering.py +3 -1
- agentpool/resource_providers/mcp_provider.py +89 -12
- agentpool/resource_providers/plan_provider.py +228 -46
- agentpool/resource_providers/pool.py +7 -3
- agentpool/resource_providers/resource_info.py +111 -0
- agentpool/resource_providers/static.py +4 -2
- agentpool/sessions/__init__.py +4 -1
- agentpool/sessions/manager.py +33 -5
- agentpool/sessions/models.py +59 -6
- agentpool/sessions/protocol.py +28 -0
- agentpool/sessions/session.py +11 -55
- agentpool/skills/registry.py +13 -8
- agentpool/storage/manager.py +572 -49
- agentpool/talk/registry.py +4 -4
- agentpool/talk/talk.py +9 -10
- agentpool/testing.py +538 -20
- agentpool/tool_impls/__init__.py +6 -0
- agentpool/tool_impls/agent_cli/__init__.py +42 -0
- agentpool/tool_impls/agent_cli/tool.py +95 -0
- agentpool/tool_impls/bash/__init__.py +64 -0
- agentpool/tool_impls/bash/helpers.py +35 -0
- agentpool/tool_impls/bash/tool.py +171 -0
- agentpool/tool_impls/delete_path/__init__.py +70 -0
- agentpool/tool_impls/delete_path/tool.py +142 -0
- agentpool/tool_impls/download_file/__init__.py +80 -0
- agentpool/tool_impls/download_file/tool.py +183 -0
- agentpool/tool_impls/execute_code/__init__.py +55 -0
- agentpool/tool_impls/execute_code/tool.py +163 -0
- agentpool/tool_impls/grep/__init__.py +80 -0
- agentpool/tool_impls/grep/tool.py +200 -0
- agentpool/tool_impls/list_directory/__init__.py +73 -0
- agentpool/tool_impls/list_directory/tool.py +197 -0
- agentpool/tool_impls/question/__init__.py +42 -0
- agentpool/tool_impls/question/tool.py +127 -0
- agentpool/tool_impls/read/__init__.py +104 -0
- agentpool/tool_impls/read/tool.py +305 -0
- agentpool/tools/__init__.py +2 -1
- agentpool/tools/base.py +114 -34
- agentpool/tools/manager.py +57 -1
- agentpool/ui/base.py +2 -2
- agentpool/ui/mock_provider.py +2 -2
- agentpool/ui/stdlib_provider.py +2 -2
- 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 +616 -2
- agentpool/utils/subprocess_utils.py +155 -0
- agentpool/utils/token_breakdown.py +461 -0
- agentpool/vfs_registry.py +7 -2
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/METADATA +41 -27
- agentpool-2.5.0.dist-info/RECORD +579 -0
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/WHEEL +1 -1
- agentpool_cli/__main__.py +24 -0
- agentpool_cli/create.py +1 -1
- agentpool_cli/serve_acp.py +100 -21
- agentpool_cli/serve_agui.py +87 -0
- agentpool_cli/serve_opencode.py +119 -0
- agentpool_cli/ui.py +557 -0
- agentpool_commands/__init__.py +42 -5
- agentpool_commands/agents.py +75 -2
- agentpool_commands/history.py +62 -0
- agentpool_commands/mcp.py +176 -0
- agentpool_commands/models.py +56 -3
- agentpool_commands/pool.py +260 -0
- agentpool_commands/session.py +1 -1
- agentpool_commands/text_sharing/__init__.py +119 -0
- agentpool_commands/text_sharing/base.py +123 -0
- agentpool_commands/text_sharing/github_gist.py +80 -0
- agentpool_commands/text_sharing/opencode.py +462 -0
- agentpool_commands/text_sharing/paste_rs.py +59 -0
- agentpool_commands/text_sharing/pastebin.py +116 -0
- agentpool_commands/text_sharing/shittycodingagent.py +112 -0
- agentpool_commands/tools.py +57 -0
- agentpool_commands/utils.py +80 -30
- agentpool_config/__init__.py +30 -2
- agentpool_config/agentpool_tools.py +498 -0
- agentpool_config/builtin_tools.py +77 -22
- agentpool_config/commands.py +24 -1
- agentpool_config/compaction.py +258 -0
- agentpool_config/converters.py +1 -1
- agentpool_config/event_handlers.py +42 -0
- agentpool_config/events.py +1 -1
- agentpool_config/forward_targets.py +1 -4
- agentpool_config/jinja.py +3 -3
- agentpool_config/mcp_server.py +132 -6
- agentpool_config/nodes.py +1 -1
- agentpool_config/observability.py +44 -0
- agentpool_config/session.py +0 -3
- agentpool_config/storage.py +82 -38
- agentpool_config/task.py +3 -3
- agentpool_config/tools.py +11 -22
- agentpool_config/toolsets.py +109 -233
- agentpool_server/a2a_server/agent_worker.py +307 -0
- agentpool_server/a2a_server/server.py +23 -18
- agentpool_server/acp_server/acp_agent.py +234 -181
- agentpool_server/acp_server/commands/acp_commands.py +151 -156
- agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +18 -17
- agentpool_server/acp_server/event_converter.py +651 -0
- agentpool_server/acp_server/input_provider.py +53 -10
- agentpool_server/acp_server/server.py +24 -90
- agentpool_server/acp_server/session.py +173 -331
- agentpool_server/acp_server/session_manager.py +8 -34
- agentpool_server/agui_server/server.py +3 -1
- agentpool_server/mcp_server/server.py +5 -2
- agentpool_server/opencode_server/.rules +95 -0
- agentpool_server/opencode_server/ENDPOINTS.md +401 -0
- agentpool_server/opencode_server/OPENCODE_UI_TOOLS_COMPLETE.md +202 -0
- agentpool_server/opencode_server/__init__.py +19 -0
- agentpool_server/opencode_server/command_validation.py +172 -0
- agentpool_server/opencode_server/converters.py +975 -0
- agentpool_server/opencode_server/dependencies.py +24 -0
- agentpool_server/opencode_server/input_provider.py +421 -0
- agentpool_server/opencode_server/models/__init__.py +250 -0
- agentpool_server/opencode_server/models/agent.py +53 -0
- agentpool_server/opencode_server/models/app.py +72 -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 +821 -0
- agentpool_server/opencode_server/models/file.py +88 -0
- agentpool_server/opencode_server/models/mcp.py +44 -0
- agentpool_server/opencode_server/models/message.py +179 -0
- agentpool_server/opencode_server/models/parts.py +323 -0
- agentpool_server/opencode_server/models/provider.py +81 -0
- agentpool_server/opencode_server/models/pty.py +43 -0
- agentpool_server/opencode_server/models/question.py +56 -0
- agentpool_server/opencode_server/models/session.py +111 -0
- agentpool_server/opencode_server/routes/__init__.py +29 -0
- agentpool_server/opencode_server/routes/agent_routes.py +473 -0
- agentpool_server/opencode_server/routes/app_routes.py +202 -0
- agentpool_server/opencode_server/routes/config_routes.py +302 -0
- agentpool_server/opencode_server/routes/file_routes.py +571 -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 +761 -0
- agentpool_server/opencode_server/routes/permission_routes.py +63 -0
- agentpool_server/opencode_server/routes/pty_routes.py +300 -0
- agentpool_server/opencode_server/routes/question_routes.py +128 -0
- agentpool_server/opencode_server/routes/session_routes.py +1276 -0
- agentpool_server/opencode_server/routes/tui_routes.py +139 -0
- agentpool_server/opencode_server/server.py +475 -0
- agentpool_server/opencode_server/state.py +151 -0
- agentpool_server/opencode_server/time_utils.py +8 -0
- agentpool_storage/__init__.py +12 -0
- agentpool_storage/base.py +184 -2
- agentpool_storage/claude_provider/ARCHITECTURE.md +433 -0
- agentpool_storage/claude_provider/__init__.py +42 -0
- agentpool_storage/claude_provider/provider.py +1089 -0
- agentpool_storage/file_provider.py +278 -15
- agentpool_storage/memory_provider.py +193 -12
- agentpool_storage/models.py +3 -0
- agentpool_storage/opencode_provider/ARCHITECTURE.md +386 -0
- agentpool_storage/opencode_provider/__init__.py +16 -0
- agentpool_storage/opencode_provider/helpers.py +414 -0
- agentpool_storage/opencode_provider/provider.py +895 -0
- agentpool_storage/project_store.py +325 -0
- agentpool_storage/session_store.py +26 -6
- agentpool_storage/sql_provider/__init__.py +4 -2
- agentpool_storage/sql_provider/models.py +48 -0
- agentpool_storage/sql_provider/sql_provider.py +269 -3
- agentpool_storage/sql_provider/utils.py +12 -13
- agentpool_storage/zed_provider/__init__.py +16 -0
- agentpool_storage/zed_provider/helpers.py +281 -0
- agentpool_storage/zed_provider/models.py +130 -0
- agentpool_storage/zed_provider/provider.py +442 -0
- agentpool_storage/zed_provider.py +803 -0
- agentpool_toolsets/__init__.py +0 -2
- agentpool_toolsets/builtin/__init__.py +2 -12
- agentpool_toolsets/builtin/code.py +96 -57
- agentpool_toolsets/builtin/debug.py +118 -48
- agentpool_toolsets/builtin/execution_environment.py +115 -230
- agentpool_toolsets/builtin/file_edit/file_edit.py +115 -7
- agentpool_toolsets/builtin/skills.py +9 -4
- agentpool_toolsets/builtin/subagent_tools.py +64 -51
- agentpool_toolsets/builtin/workers.py +4 -2
- agentpool_toolsets/composio_toolset.py +2 -2
- agentpool_toolsets/entry_points.py +3 -1
- agentpool_toolsets/fsspec_toolset/__init__.py +13 -1
- agentpool_toolsets/fsspec_toolset/diagnostics.py +860 -73
- agentpool_toolsets/fsspec_toolset/grep.py +99 -7
- agentpool_toolsets/fsspec_toolset/helpers.py +3 -2
- agentpool_toolsets/fsspec_toolset/image_utils.py +161 -0
- agentpool_toolsets/fsspec_toolset/toolset.py +500 -95
- agentpool_toolsets/mcp_discovery/__init__.py +5 -0
- agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
- agentpool_toolsets/mcp_discovery/toolset.py +511 -0
- agentpool_toolsets/mcp_run_toolset.py +87 -12
- agentpool_toolsets/notifications.py +33 -33
- agentpool_toolsets/openapi.py +3 -1
- agentpool_toolsets/search_toolset.py +3 -1
- agentpool-2.1.9.dist-info/RECORD +0 -474
- agentpool_config/resources.py +0 -33
- agentpool_server/acp_server/acp_tools.py +0 -43
- agentpool_server/acp_server/commands/spawn.py +0 -210
- agentpool_storage/text_log_provider.py +0 -275
- agentpool_toolsets/builtin/agent_management.py +0 -239
- agentpool_toolsets/builtin/chain.py +0 -288
- agentpool_toolsets/builtin/history.py +0 -36
- agentpool_toolsets/builtin/integration.py +0 -85
- agentpool_toolsets/builtin/tool_management.py +0 -90
- agentpool_toolsets/builtin/user_interaction.py +0 -52
- agentpool_toolsets/semantic_memory_toolset.py +0 -536
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/entry_points.txt +0 -0
- {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""ShittyCodingAgent.ai text sharing provider.
|
|
2
|
+
|
|
3
|
+
Creates a GitHub Gist and returns a preview URL via shittycodingagent.ai.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
from typing import TYPE_CHECKING, Any
|
|
10
|
+
|
|
11
|
+
from agentpool_commands.text_sharing.base import ShareResult, TextSharer
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from agentpool_commands.text_sharing.base import Visibility
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
PREVIEW_BASE_URL = "https://shittycodingagent.ai/session"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ShittyCodingAgentSharer(TextSharer):
|
|
22
|
+
"""Share text via GitHub Gists with shittycodingagent.ai preview URL.
|
|
23
|
+
|
|
24
|
+
Creates a secret (unlisted) GitHub Gist and returns a URL in the format:
|
|
25
|
+
https://shittycodingagent.ai/session?{gist_id}
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, token: str | None = None) -> None:
|
|
29
|
+
"""Initialize the ShittyCodingAgent sharer.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
token: GitHub personal access token. If not provided,
|
|
33
|
+
reads from GITHUB_TOKEN environment variable.
|
|
34
|
+
"""
|
|
35
|
+
self._token = token or os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN")
|
|
36
|
+
if not self._token:
|
|
37
|
+
msg = "GitHub token required. Set GITHUB_TOKEN/GH_TOKEN or pass token parameter."
|
|
38
|
+
raise ValueError(msg)
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def name(self) -> str:
|
|
42
|
+
"""Name of the sharing service."""
|
|
43
|
+
return "ShittyCodingAgent.ai"
|
|
44
|
+
|
|
45
|
+
async def share(
|
|
46
|
+
self,
|
|
47
|
+
content: str,
|
|
48
|
+
*,
|
|
49
|
+
title: str | None = None,
|
|
50
|
+
syntax: str | None = None,
|
|
51
|
+
visibility: Visibility = "unlisted",
|
|
52
|
+
expires_in: int | None = None,
|
|
53
|
+
) -> ShareResult:
|
|
54
|
+
"""Share content via GitHub Gist with shittycodingagent.ai preview.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
content: The text content to share
|
|
58
|
+
title: Filename for the gist (defaults to "session.html")
|
|
59
|
+
syntax: File extension hint (e.g. "html")
|
|
60
|
+
visibility: Always creates unlisted gist (visibility param ignored)
|
|
61
|
+
expires_in: Ignored (gists don't expire)
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
ShareResult with shittycodingagent.ai preview URL
|
|
65
|
+
"""
|
|
66
|
+
import anyenv
|
|
67
|
+
|
|
68
|
+
# Default to session.html for the typical use case
|
|
69
|
+
filename = title or f"session.{syntax or 'html'}"
|
|
70
|
+
|
|
71
|
+
# Always create as unlisted (secret) gist
|
|
72
|
+
payload: dict[str, Any] = {
|
|
73
|
+
"files": {filename: {"content": content}},
|
|
74
|
+
"public": False,
|
|
75
|
+
}
|
|
76
|
+
headers = {
|
|
77
|
+
"Authorization": f"Bearer {self._token}",
|
|
78
|
+
"Accept": "application/vnd.github+json",
|
|
79
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
80
|
+
}
|
|
81
|
+
url = "https://api.github.com/gists"
|
|
82
|
+
response: dict[str, Any] = await anyenv.post_json(url, payload, headers=headers)
|
|
83
|
+
|
|
84
|
+
gist_id = response["id"]
|
|
85
|
+
raw_url = response["files"][filename]["raw_url"]
|
|
86
|
+
|
|
87
|
+
# Build the shittycodingagent.ai preview URL
|
|
88
|
+
preview_url = f"{PREVIEW_BASE_URL}?{gist_id}"
|
|
89
|
+
|
|
90
|
+
return ShareResult(
|
|
91
|
+
url=preview_url,
|
|
92
|
+
raw_url=raw_url,
|
|
93
|
+
delete_url=None,
|
|
94
|
+
id=gist_id,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
if __name__ == "__main__":
|
|
99
|
+
import asyncio
|
|
100
|
+
|
|
101
|
+
async def main() -> None:
|
|
102
|
+
"""Example usage of the ShittyCodingAgentSharer class."""
|
|
103
|
+
sharer = ShittyCodingAgentSharer()
|
|
104
|
+
result = await sharer.share(
|
|
105
|
+
"<html><body><h1>Test Session</h1></body></html>",
|
|
106
|
+
title="session.html",
|
|
107
|
+
)
|
|
108
|
+
print(f"Preview URL: {result.url}")
|
|
109
|
+
print(f"Raw: {result.raw_url}")
|
|
110
|
+
print(f"Gist ID: {result.id}")
|
|
111
|
+
|
|
112
|
+
asyncio.run(main())
|
agentpool_commands/tools.py
CHANGED
|
@@ -264,6 +264,63 @@ class RegisterToolCommand(NodeCommand):
|
|
|
264
264
|
raise CommandError(msg) from e
|
|
265
265
|
|
|
266
266
|
|
|
267
|
+
class RegisterCodeToolCommand(NodeCommand):
|
|
268
|
+
"""Register a new tool from Python code.
|
|
269
|
+
|
|
270
|
+
The code should define a function that will become the tool.
|
|
271
|
+
The function name becomes the tool name unless overridden.
|
|
272
|
+
|
|
273
|
+
Options:
|
|
274
|
+
--name tool_name Custom name for the tool
|
|
275
|
+
--description "text" Custom description
|
|
276
|
+
|
|
277
|
+
Examples:
|
|
278
|
+
/register-code-tool "def greet(name: str) -> str: return f'Hello {name}'"
|
|
279
|
+
/register-code-tool "def add(a: int, b: int) -> int: return a + b" --name sum
|
|
280
|
+
"""
|
|
281
|
+
|
|
282
|
+
name = "register-code-tool"
|
|
283
|
+
category = "tools"
|
|
284
|
+
|
|
285
|
+
@classmethod
|
|
286
|
+
def supports_node(cls, node: MessageNode[Any, Any]) -> bool:
|
|
287
|
+
from agentpool import Agent
|
|
288
|
+
|
|
289
|
+
return isinstance(node, Agent)
|
|
290
|
+
|
|
291
|
+
async def execute_command(
|
|
292
|
+
self,
|
|
293
|
+
ctx: CommandContext[AgentContext],
|
|
294
|
+
code: str,
|
|
295
|
+
*,
|
|
296
|
+
name: str | None = None,
|
|
297
|
+
description: str | None = None,
|
|
298
|
+
) -> None:
|
|
299
|
+
"""Register a new tool from code string.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
ctx: Command context
|
|
303
|
+
code: Python code defining a function
|
|
304
|
+
name: Optional custom name for the tool
|
|
305
|
+
description: Optional custom description
|
|
306
|
+
"""
|
|
307
|
+
from agentpool.tools.base import Tool
|
|
308
|
+
|
|
309
|
+
try:
|
|
310
|
+
tool_obj = Tool.from_code(code, name=name, description=description)
|
|
311
|
+
tool_obj.enabled = True
|
|
312
|
+
tool_obj.source = "dynamic"
|
|
313
|
+
|
|
314
|
+
registered = ctx.context.agent.tools.register_tool(tool_obj)
|
|
315
|
+
await ctx.print(
|
|
316
|
+
f"**Tool registered:** `{registered.name}`"
|
|
317
|
+
f" - {registered.description or '*No description*'}"
|
|
318
|
+
)
|
|
319
|
+
except Exception as e:
|
|
320
|
+
msg = f"Failed to register code tool: {e}"
|
|
321
|
+
raise CommandError(msg) from e
|
|
322
|
+
|
|
323
|
+
|
|
267
324
|
async def get_tool_names(ctx: CompletionContext[AgentContext]) -> list[str]:
|
|
268
325
|
manager = ctx.command_context.context.agent.tools
|
|
269
326
|
return list({t.name for t in await manager.get_tools()})
|
agentpool_commands/utils.py
CHANGED
|
@@ -3,25 +3,31 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import importlib.util
|
|
6
|
+
from typing import TYPE_CHECKING, Literal
|
|
6
7
|
import webbrowser
|
|
7
8
|
|
|
8
|
-
from anyenv.text_sharing import TextSharerStr, Visibility # noqa: TC002
|
|
9
9
|
from slashed import CommandContext, CommandError # noqa: TC002
|
|
10
10
|
|
|
11
11
|
from agentpool.messaging.context import NodeContext # noqa: TC001
|
|
12
12
|
from agentpool_commands.base import NodeCommand
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from agentpool_commands.text_sharing import TextSharerStr, Visibility
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
LogLevel = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
|
20
|
+
|
|
21
|
+
|
|
15
22
|
class CopyClipboardCommand(NodeCommand):
|
|
16
23
|
"""Copy messages from conversation history to system clipboard.
|
|
17
24
|
|
|
18
25
|
Allows copying a configurable number of messages with options for:
|
|
19
26
|
- Number of messages to include
|
|
20
|
-
- Including/excluding system messages
|
|
21
27
|
- Token limit for context size
|
|
22
28
|
- Custom format templates
|
|
23
29
|
|
|
24
|
-
Requires
|
|
30
|
+
Requires copykitten package to be installed.
|
|
25
31
|
"""
|
|
26
32
|
|
|
27
33
|
name = "copy-clipboard"
|
|
@@ -32,7 +38,6 @@ class CopyClipboardCommand(NodeCommand):
|
|
|
32
38
|
ctx: CommandContext[NodeContext],
|
|
33
39
|
*,
|
|
34
40
|
num_messages: int = 1,
|
|
35
|
-
include_system: bool = False,
|
|
36
41
|
max_tokens: int | None = None,
|
|
37
42
|
format_template: str | None = None,
|
|
38
43
|
) -> None:
|
|
@@ -41,19 +46,17 @@ class CopyClipboardCommand(NodeCommand):
|
|
|
41
46
|
Args:
|
|
42
47
|
ctx: Command context
|
|
43
48
|
num_messages: Number of messages to copy (default: 1)
|
|
44
|
-
include_system: Include system messages
|
|
45
49
|
max_tokens: Only include messages up to token limit
|
|
46
50
|
format_template: Custom format template
|
|
47
51
|
"""
|
|
48
52
|
try:
|
|
49
|
-
import
|
|
53
|
+
import copykitten
|
|
50
54
|
except ImportError as e:
|
|
51
|
-
msg = "
|
|
55
|
+
msg = "copykitten package required for clipboard operations"
|
|
52
56
|
raise CommandError(msg) from e
|
|
53
57
|
|
|
54
58
|
content = await ctx.context.agent.conversation.format_history(
|
|
55
59
|
num_messages=num_messages,
|
|
56
|
-
include_system=include_system,
|
|
57
60
|
max_tokens=max_tokens,
|
|
58
61
|
format_template=format_template,
|
|
59
62
|
)
|
|
@@ -63,8 +66,7 @@ class CopyClipboardCommand(NodeCommand):
|
|
|
63
66
|
return
|
|
64
67
|
|
|
65
68
|
try:
|
|
66
|
-
|
|
67
|
-
clipman.copy(content)
|
|
69
|
+
copykitten.copy(content)
|
|
68
70
|
await ctx.print("📋 **Messages copied to clipboard**")
|
|
69
71
|
except Exception as e:
|
|
70
72
|
msg = f"Failed to copy to clipboard: {e}"
|
|
@@ -72,8 +74,8 @@ class CopyClipboardCommand(NodeCommand):
|
|
|
72
74
|
|
|
73
75
|
@classmethod
|
|
74
76
|
def condition(cls) -> bool:
|
|
75
|
-
"""Check if
|
|
76
|
-
return importlib.util.find_spec("
|
|
77
|
+
"""Check if copykitten is available."""
|
|
78
|
+
return importlib.util.find_spec("copykitten") is not None
|
|
77
79
|
|
|
78
80
|
|
|
79
81
|
class EditAgentFileCommand(NodeCommand):
|
|
@@ -130,8 +132,7 @@ class ShareHistoryCommand(NodeCommand):
|
|
|
130
132
|
ctx: CommandContext[NodeContext],
|
|
131
133
|
*,
|
|
132
134
|
provider: TextSharerStr = "paste_rs",
|
|
133
|
-
num_messages: int =
|
|
134
|
-
include_system: bool = False,
|
|
135
|
+
num_messages: int | None = None,
|
|
135
136
|
max_tokens: int | None = None,
|
|
136
137
|
format_template: str | None = None,
|
|
137
138
|
title: str | None = None,
|
|
@@ -143,32 +144,39 @@ class ShareHistoryCommand(NodeCommand):
|
|
|
143
144
|
Args:
|
|
144
145
|
ctx: Command context
|
|
145
146
|
provider: Text sharing provider to use
|
|
146
|
-
num_messages: Number of messages from history to share (
|
|
147
|
-
include_system: Include system messages in history
|
|
147
|
+
num_messages: Number of messages from history to share (None = all messages)
|
|
148
148
|
max_tokens: Token limit for conversation history
|
|
149
149
|
format_template: Custom format template for history
|
|
150
150
|
title: Title/filename for the shared content
|
|
151
151
|
syntax: Syntax highlighting (e.g., "python", "markdown")
|
|
152
152
|
visibility: Visibility level
|
|
153
153
|
"""
|
|
154
|
-
from
|
|
154
|
+
from agentpool_commands.text_sharing import get_sharer
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
num_messages=num_messages,
|
|
158
|
-
include_system=include_system,
|
|
159
|
-
max_tokens=max_tokens,
|
|
160
|
-
format_template=format_template,
|
|
161
|
-
)
|
|
156
|
+
conversation = ctx.context.agent.conversation
|
|
162
157
|
|
|
163
|
-
if
|
|
158
|
+
# Check if there's content to share
|
|
159
|
+
messages_to_check = (
|
|
160
|
+
conversation.chat_messages[-num_messages:]
|
|
161
|
+
if num_messages
|
|
162
|
+
else conversation.chat_messages
|
|
163
|
+
)
|
|
164
|
+
if not messages_to_check:
|
|
164
165
|
await ctx.print("ℹ️ **No content to share**") # noqa: RUF001
|
|
165
166
|
return
|
|
166
167
|
|
|
167
168
|
try:
|
|
168
169
|
# Get the appropriate sharer
|
|
169
170
|
sharer = get_sharer(provider)
|
|
170
|
-
|
|
171
|
-
|
|
171
|
+
|
|
172
|
+
# Use structured sharing for providers that support it (OpenCode)
|
|
173
|
+
# Otherwise fall back to plain text sharing
|
|
174
|
+
result = await sharer.share_conversation(
|
|
175
|
+
conversation,
|
|
176
|
+
title=title,
|
|
177
|
+
visibility=visibility,
|
|
178
|
+
num_messages=num_messages,
|
|
179
|
+
)
|
|
172
180
|
# Format success message
|
|
173
181
|
provider_name = sharer.name
|
|
174
182
|
msg_parts = [f"🔗 **Content shared via {provider_name}:**", f"• URL: {result.url}"]
|
|
@@ -183,7 +191,49 @@ class ShareHistoryCommand(NodeCommand):
|
|
|
183
191
|
msg = f"Failed to share content via {provider}: {e}"
|
|
184
192
|
raise CommandError(msg) from e
|
|
185
193
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
194
|
+
|
|
195
|
+
class GetLogsCommand(NodeCommand):
|
|
196
|
+
"""Get recent log entries from memory.
|
|
197
|
+
|
|
198
|
+
Shows captured log entries with filtering options:
|
|
199
|
+
- Filter by minimum log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
|
200
|
+
- Filter by logger name substring
|
|
201
|
+
- Limit number of entries returned
|
|
202
|
+
|
|
203
|
+
Logs are shown newest first.
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
name = "get-logs"
|
|
207
|
+
category = "debug"
|
|
208
|
+
|
|
209
|
+
async def execute_command(
|
|
210
|
+
self,
|
|
211
|
+
ctx: CommandContext[NodeContext],
|
|
212
|
+
*,
|
|
213
|
+
level: LogLevel = "INFO",
|
|
214
|
+
logger_filter: str | None = None,
|
|
215
|
+
limit: int | str = 50,
|
|
216
|
+
) -> None:
|
|
217
|
+
"""Get recent log entries.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
ctx: Command context
|
|
221
|
+
level: Minimum log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
|
222
|
+
logger_filter: Only show logs from loggers containing this string
|
|
223
|
+
limit: Maximum number of log entries to return
|
|
224
|
+
"""
|
|
225
|
+
from agentpool_toolsets.builtin.debug import get_memory_handler
|
|
226
|
+
|
|
227
|
+
# Convert limit to int (slashed passes args as strings)
|
|
228
|
+
limit_int = int(limit) if isinstance(limit, str) else limit
|
|
229
|
+
|
|
230
|
+
handler = get_memory_handler()
|
|
231
|
+
records = handler.get_records(level=level, logger_filter=logger_filter, limit=limit_int)
|
|
232
|
+
|
|
233
|
+
if not records:
|
|
234
|
+
await ctx.print("No log entries found matching criteria")
|
|
235
|
+
return
|
|
236
|
+
|
|
237
|
+
await ctx.print(f"## 📋 {len(records)} Log Entries (newest first)\n")
|
|
238
|
+
for record in records:
|
|
239
|
+
await ctx.print(record.message)
|
agentpool_config/__init__.py
CHANGED
|
@@ -2,7 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
from typing import Annotated
|
|
7
|
+
from pydantic import Field
|
|
8
|
+
|
|
9
|
+
from agentpool_config.tools import ImportToolConfig, BaseToolConfig
|
|
10
|
+
from agentpool_config.agentpool_tools import AgentpoolToolConfig
|
|
11
|
+
from agentpool_config.builtin_tools import BuiltinToolConfig
|
|
12
|
+
|
|
6
13
|
from agentpool_config.forward_targets import ForwardingTarget
|
|
7
14
|
from agentpool_config.session import SessionQuery
|
|
8
15
|
from agentpool_config.teams import TeamConfig
|
|
@@ -28,11 +35,30 @@ from agentpool_config.hooks import (
|
|
|
28
35
|
HooksConfig,
|
|
29
36
|
PromptHookConfig,
|
|
30
37
|
)
|
|
38
|
+
from agentpool_config.toolsets import ToolsetConfig
|
|
31
39
|
|
|
40
|
+
|
|
41
|
+
ToolConfig = Annotated[
|
|
42
|
+
ImportToolConfig | AgentpoolToolConfig,
|
|
43
|
+
Field(discriminator="type"),
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
NativeAgentToolConfig = Annotated[
|
|
47
|
+
ToolConfig | BuiltinToolConfig,
|
|
48
|
+
Field(discriminator="type"),
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
# Unified type for all tool configurations (single tools + toolsets)
|
|
52
|
+
AnyToolConfig = Annotated[
|
|
53
|
+
NativeAgentToolConfig | ToolsetConfig,
|
|
54
|
+
Field(discriminator="type"),
|
|
55
|
+
]
|
|
32
56
|
__all__ = [
|
|
57
|
+
"AnyToolConfig",
|
|
33
58
|
"BaseEventHandlerConfig",
|
|
34
59
|
"BaseHookConfig",
|
|
35
60
|
"BaseMCPServerConfig",
|
|
61
|
+
"BaseToolConfig",
|
|
36
62
|
"CallableHookConfig",
|
|
37
63
|
"CallbackEventHandlerConfig",
|
|
38
64
|
"CommandHookConfig",
|
|
@@ -41,13 +67,15 @@ __all__ = [
|
|
|
41
67
|
"HookConfig",
|
|
42
68
|
"HooksConfig",
|
|
43
69
|
"MCPServerConfig",
|
|
70
|
+
"NativeAgentToolConfig",
|
|
44
71
|
"PromptHookConfig",
|
|
45
|
-
"ResourceInfo",
|
|
46
72
|
"SSEMCPServerConfig",
|
|
47
73
|
"SessionQuery",
|
|
48
74
|
"StdioMCPServerConfig",
|
|
49
75
|
"StdoutEventHandlerConfig",
|
|
50
76
|
"StreamableHTTPMCPServerConfig",
|
|
51
77
|
"TeamConfig",
|
|
78
|
+
"ToolConfig",
|
|
79
|
+
"ToolsetConfig",
|
|
52
80
|
"resolve_handler_configs",
|
|
53
81
|
]
|