fast-agent-mcp 0.4.7__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.
- fast_agent/__init__.py +183 -0
- fast_agent/acp/__init__.py +19 -0
- fast_agent/acp/acp_aware_mixin.py +304 -0
- fast_agent/acp/acp_context.py +437 -0
- fast_agent/acp/content_conversion.py +136 -0
- fast_agent/acp/filesystem_runtime.py +427 -0
- fast_agent/acp/permission_store.py +269 -0
- fast_agent/acp/server/__init__.py +5 -0
- fast_agent/acp/server/agent_acp_server.py +1472 -0
- fast_agent/acp/slash_commands.py +1050 -0
- fast_agent/acp/terminal_runtime.py +408 -0
- fast_agent/acp/tool_permission_adapter.py +125 -0
- fast_agent/acp/tool_permissions.py +474 -0
- fast_agent/acp/tool_progress.py +814 -0
- fast_agent/agents/__init__.py +85 -0
- fast_agent/agents/agent_types.py +64 -0
- fast_agent/agents/llm_agent.py +350 -0
- fast_agent/agents/llm_decorator.py +1139 -0
- fast_agent/agents/mcp_agent.py +1337 -0
- fast_agent/agents/tool_agent.py +271 -0
- fast_agent/agents/workflow/agents_as_tools_agent.py +849 -0
- fast_agent/agents/workflow/chain_agent.py +212 -0
- fast_agent/agents/workflow/evaluator_optimizer.py +380 -0
- fast_agent/agents/workflow/iterative_planner.py +652 -0
- fast_agent/agents/workflow/maker_agent.py +379 -0
- fast_agent/agents/workflow/orchestrator_models.py +218 -0
- fast_agent/agents/workflow/orchestrator_prompts.py +248 -0
- fast_agent/agents/workflow/parallel_agent.py +250 -0
- fast_agent/agents/workflow/router_agent.py +353 -0
- fast_agent/cli/__init__.py +0 -0
- fast_agent/cli/__main__.py +73 -0
- fast_agent/cli/commands/acp.py +159 -0
- fast_agent/cli/commands/auth.py +404 -0
- fast_agent/cli/commands/check_config.py +783 -0
- fast_agent/cli/commands/go.py +514 -0
- fast_agent/cli/commands/quickstart.py +557 -0
- fast_agent/cli/commands/serve.py +143 -0
- fast_agent/cli/commands/server_helpers.py +114 -0
- fast_agent/cli/commands/setup.py +174 -0
- fast_agent/cli/commands/url_parser.py +190 -0
- fast_agent/cli/constants.py +40 -0
- fast_agent/cli/main.py +115 -0
- fast_agent/cli/terminal.py +24 -0
- fast_agent/config.py +798 -0
- fast_agent/constants.py +41 -0
- fast_agent/context.py +279 -0
- fast_agent/context_dependent.py +50 -0
- fast_agent/core/__init__.py +92 -0
- fast_agent/core/agent_app.py +448 -0
- fast_agent/core/core_app.py +137 -0
- fast_agent/core/direct_decorators.py +784 -0
- fast_agent/core/direct_factory.py +620 -0
- fast_agent/core/error_handling.py +27 -0
- fast_agent/core/exceptions.py +90 -0
- fast_agent/core/executor/__init__.py +0 -0
- fast_agent/core/executor/executor.py +280 -0
- fast_agent/core/executor/task_registry.py +32 -0
- fast_agent/core/executor/workflow_signal.py +324 -0
- fast_agent/core/fastagent.py +1186 -0
- fast_agent/core/logging/__init__.py +5 -0
- fast_agent/core/logging/events.py +138 -0
- fast_agent/core/logging/json_serializer.py +164 -0
- fast_agent/core/logging/listeners.py +309 -0
- fast_agent/core/logging/logger.py +278 -0
- fast_agent/core/logging/transport.py +481 -0
- fast_agent/core/prompt.py +9 -0
- fast_agent/core/prompt_templates.py +183 -0
- fast_agent/core/validation.py +326 -0
- fast_agent/event_progress.py +62 -0
- fast_agent/history/history_exporter.py +49 -0
- fast_agent/human_input/__init__.py +47 -0
- fast_agent/human_input/elicitation_handler.py +123 -0
- fast_agent/human_input/elicitation_state.py +33 -0
- fast_agent/human_input/form_elements.py +59 -0
- fast_agent/human_input/form_fields.py +256 -0
- fast_agent/human_input/simple_form.py +113 -0
- fast_agent/human_input/types.py +40 -0
- fast_agent/interfaces.py +310 -0
- fast_agent/llm/__init__.py +9 -0
- fast_agent/llm/cancellation.py +22 -0
- fast_agent/llm/fastagent_llm.py +931 -0
- fast_agent/llm/internal/passthrough.py +161 -0
- fast_agent/llm/internal/playback.py +129 -0
- fast_agent/llm/internal/silent.py +41 -0
- fast_agent/llm/internal/slow.py +38 -0
- fast_agent/llm/memory.py +275 -0
- fast_agent/llm/model_database.py +490 -0
- fast_agent/llm/model_factory.py +388 -0
- fast_agent/llm/model_info.py +102 -0
- fast_agent/llm/prompt_utils.py +155 -0
- fast_agent/llm/provider/anthropic/anthropic_utils.py +84 -0
- fast_agent/llm/provider/anthropic/cache_planner.py +56 -0
- fast_agent/llm/provider/anthropic/llm_anthropic.py +796 -0
- fast_agent/llm/provider/anthropic/multipart_converter_anthropic.py +462 -0
- fast_agent/llm/provider/bedrock/bedrock_utils.py +218 -0
- fast_agent/llm/provider/bedrock/llm_bedrock.py +2207 -0
- fast_agent/llm/provider/bedrock/multipart_converter_bedrock.py +84 -0
- fast_agent/llm/provider/google/google_converter.py +466 -0
- fast_agent/llm/provider/google/llm_google_native.py +681 -0
- fast_agent/llm/provider/openai/llm_aliyun.py +31 -0
- fast_agent/llm/provider/openai/llm_azure.py +143 -0
- fast_agent/llm/provider/openai/llm_deepseek.py +76 -0
- fast_agent/llm/provider/openai/llm_generic.py +35 -0
- fast_agent/llm/provider/openai/llm_google_oai.py +32 -0
- fast_agent/llm/provider/openai/llm_groq.py +42 -0
- fast_agent/llm/provider/openai/llm_huggingface.py +85 -0
- fast_agent/llm/provider/openai/llm_openai.py +1195 -0
- fast_agent/llm/provider/openai/llm_openai_compatible.py +138 -0
- fast_agent/llm/provider/openai/llm_openrouter.py +45 -0
- fast_agent/llm/provider/openai/llm_tensorzero_openai.py +128 -0
- fast_agent/llm/provider/openai/llm_xai.py +38 -0
- fast_agent/llm/provider/openai/multipart_converter_openai.py +561 -0
- fast_agent/llm/provider/openai/openai_multipart.py +169 -0
- fast_agent/llm/provider/openai/openai_utils.py +67 -0
- fast_agent/llm/provider/openai/responses.py +133 -0
- fast_agent/llm/provider_key_manager.py +139 -0
- fast_agent/llm/provider_types.py +34 -0
- fast_agent/llm/request_params.py +61 -0
- fast_agent/llm/sampling_converter.py +98 -0
- fast_agent/llm/stream_types.py +9 -0
- fast_agent/llm/usage_tracking.py +445 -0
- fast_agent/mcp/__init__.py +56 -0
- fast_agent/mcp/common.py +26 -0
- fast_agent/mcp/elicitation_factory.py +84 -0
- fast_agent/mcp/elicitation_handlers.py +164 -0
- fast_agent/mcp/gen_client.py +83 -0
- fast_agent/mcp/helpers/__init__.py +36 -0
- fast_agent/mcp/helpers/content_helpers.py +352 -0
- fast_agent/mcp/helpers/server_config_helpers.py +25 -0
- fast_agent/mcp/hf_auth.py +147 -0
- fast_agent/mcp/interfaces.py +92 -0
- fast_agent/mcp/logger_textio.py +108 -0
- fast_agent/mcp/mcp_agent_client_session.py +411 -0
- fast_agent/mcp/mcp_aggregator.py +2175 -0
- fast_agent/mcp/mcp_connection_manager.py +723 -0
- fast_agent/mcp/mcp_content.py +262 -0
- fast_agent/mcp/mime_utils.py +108 -0
- fast_agent/mcp/oauth_client.py +509 -0
- fast_agent/mcp/prompt.py +159 -0
- fast_agent/mcp/prompt_message_extended.py +155 -0
- fast_agent/mcp/prompt_render.py +84 -0
- fast_agent/mcp/prompt_serialization.py +580 -0
- fast_agent/mcp/prompts/__init__.py +0 -0
- fast_agent/mcp/prompts/__main__.py +7 -0
- fast_agent/mcp/prompts/prompt_constants.py +18 -0
- fast_agent/mcp/prompts/prompt_helpers.py +238 -0
- fast_agent/mcp/prompts/prompt_load.py +186 -0
- fast_agent/mcp/prompts/prompt_server.py +552 -0
- fast_agent/mcp/prompts/prompt_template.py +438 -0
- fast_agent/mcp/resource_utils.py +215 -0
- fast_agent/mcp/sampling.py +200 -0
- fast_agent/mcp/server/__init__.py +4 -0
- fast_agent/mcp/server/agent_server.py +613 -0
- fast_agent/mcp/skybridge.py +44 -0
- fast_agent/mcp/sse_tracking.py +287 -0
- fast_agent/mcp/stdio_tracking_simple.py +59 -0
- fast_agent/mcp/streamable_http_tracking.py +309 -0
- fast_agent/mcp/tool_execution_handler.py +137 -0
- fast_agent/mcp/tool_permission_handler.py +88 -0
- fast_agent/mcp/transport_tracking.py +634 -0
- fast_agent/mcp/types.py +24 -0
- fast_agent/mcp/ui_agent.py +48 -0
- fast_agent/mcp/ui_mixin.py +209 -0
- fast_agent/mcp_server_registry.py +89 -0
- fast_agent/py.typed +0 -0
- fast_agent/resources/examples/data-analysis/analysis-campaign.py +189 -0
- fast_agent/resources/examples/data-analysis/analysis.py +68 -0
- fast_agent/resources/examples/data-analysis/fastagent.config.yaml +41 -0
- fast_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +1471 -0
- fast_agent/resources/examples/mcp/elicitations/elicitation_account_server.py +88 -0
- fast_agent/resources/examples/mcp/elicitations/elicitation_forms_server.py +297 -0
- fast_agent/resources/examples/mcp/elicitations/elicitation_game_server.py +164 -0
- fast_agent/resources/examples/mcp/elicitations/fastagent.config.yaml +35 -0
- fast_agent/resources/examples/mcp/elicitations/fastagent.secrets.yaml.example +17 -0
- fast_agent/resources/examples/mcp/elicitations/forms_demo.py +107 -0
- fast_agent/resources/examples/mcp/elicitations/game_character.py +65 -0
- fast_agent/resources/examples/mcp/elicitations/game_character_handler.py +256 -0
- fast_agent/resources/examples/mcp/elicitations/tool_call.py +21 -0
- fast_agent/resources/examples/mcp/state-transfer/agent_one.py +18 -0
- fast_agent/resources/examples/mcp/state-transfer/agent_two.py +18 -0
- fast_agent/resources/examples/mcp/state-transfer/fastagent.config.yaml +27 -0
- fast_agent/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +15 -0
- fast_agent/resources/examples/researcher/fastagent.config.yaml +61 -0
- fast_agent/resources/examples/researcher/researcher-eval.py +53 -0
- fast_agent/resources/examples/researcher/researcher-imp.py +189 -0
- fast_agent/resources/examples/researcher/researcher.py +36 -0
- fast_agent/resources/examples/tensorzero/.env.sample +2 -0
- fast_agent/resources/examples/tensorzero/Makefile +31 -0
- fast_agent/resources/examples/tensorzero/README.md +56 -0
- fast_agent/resources/examples/tensorzero/agent.py +35 -0
- fast_agent/resources/examples/tensorzero/demo_images/clam.jpg +0 -0
- fast_agent/resources/examples/tensorzero/demo_images/crab.png +0 -0
- fast_agent/resources/examples/tensorzero/demo_images/shrimp.png +0 -0
- fast_agent/resources/examples/tensorzero/docker-compose.yml +105 -0
- fast_agent/resources/examples/tensorzero/fastagent.config.yaml +19 -0
- fast_agent/resources/examples/tensorzero/image_demo.py +67 -0
- fast_agent/resources/examples/tensorzero/mcp_server/Dockerfile +25 -0
- fast_agent/resources/examples/tensorzero/mcp_server/entrypoint.sh +35 -0
- fast_agent/resources/examples/tensorzero/mcp_server/mcp_server.py +31 -0
- fast_agent/resources/examples/tensorzero/mcp_server/pyproject.toml +11 -0
- fast_agent/resources/examples/tensorzero/simple_agent.py +25 -0
- fast_agent/resources/examples/tensorzero/tensorzero_config/system_schema.json +29 -0
- fast_agent/resources/examples/tensorzero/tensorzero_config/system_template.minijinja +11 -0
- fast_agent/resources/examples/tensorzero/tensorzero_config/tensorzero.toml +35 -0
- fast_agent/resources/examples/workflows/agents_as_tools_extended.py +73 -0
- fast_agent/resources/examples/workflows/agents_as_tools_simple.py +50 -0
- fast_agent/resources/examples/workflows/chaining.py +37 -0
- fast_agent/resources/examples/workflows/evaluator.py +77 -0
- fast_agent/resources/examples/workflows/fastagent.config.yaml +26 -0
- fast_agent/resources/examples/workflows/graded_report.md +89 -0
- fast_agent/resources/examples/workflows/human_input.py +28 -0
- fast_agent/resources/examples/workflows/maker.py +156 -0
- fast_agent/resources/examples/workflows/orchestrator.py +70 -0
- fast_agent/resources/examples/workflows/parallel.py +56 -0
- fast_agent/resources/examples/workflows/router.py +69 -0
- fast_agent/resources/examples/workflows/short_story.md +13 -0
- fast_agent/resources/examples/workflows/short_story.txt +19 -0
- fast_agent/resources/setup/.gitignore +30 -0
- fast_agent/resources/setup/agent.py +28 -0
- fast_agent/resources/setup/fastagent.config.yaml +65 -0
- fast_agent/resources/setup/fastagent.secrets.yaml.example +38 -0
- fast_agent/resources/setup/pyproject.toml.tmpl +23 -0
- fast_agent/skills/__init__.py +9 -0
- fast_agent/skills/registry.py +235 -0
- fast_agent/tools/elicitation.py +369 -0
- fast_agent/tools/shell_runtime.py +402 -0
- fast_agent/types/__init__.py +59 -0
- fast_agent/types/conversation_summary.py +294 -0
- fast_agent/types/llm_stop_reason.py +78 -0
- fast_agent/types/message_search.py +249 -0
- fast_agent/ui/__init__.py +38 -0
- fast_agent/ui/console.py +59 -0
- fast_agent/ui/console_display.py +1080 -0
- fast_agent/ui/elicitation_form.py +946 -0
- fast_agent/ui/elicitation_style.py +59 -0
- fast_agent/ui/enhanced_prompt.py +1400 -0
- fast_agent/ui/history_display.py +734 -0
- fast_agent/ui/interactive_prompt.py +1199 -0
- fast_agent/ui/markdown_helpers.py +104 -0
- fast_agent/ui/markdown_truncator.py +1004 -0
- fast_agent/ui/mcp_display.py +857 -0
- fast_agent/ui/mcp_ui_utils.py +235 -0
- fast_agent/ui/mermaid_utils.py +169 -0
- fast_agent/ui/message_primitives.py +50 -0
- fast_agent/ui/notification_tracker.py +205 -0
- fast_agent/ui/plain_text_truncator.py +68 -0
- fast_agent/ui/progress_display.py +10 -0
- fast_agent/ui/rich_progress.py +195 -0
- fast_agent/ui/streaming.py +774 -0
- fast_agent/ui/streaming_buffer.py +449 -0
- fast_agent/ui/tool_display.py +422 -0
- fast_agent/ui/usage_display.py +204 -0
- fast_agent/utils/__init__.py +5 -0
- fast_agent/utils/reasoning_stream_parser.py +77 -0
- fast_agent/utils/time.py +22 -0
- fast_agent/workflow_telemetry.py +261 -0
- fast_agent_mcp-0.4.7.dist-info/METADATA +788 -0
- fast_agent_mcp-0.4.7.dist-info/RECORD +261 -0
- fast_agent_mcp-0.4.7.dist-info/WHEEL +4 -0
- fast_agent_mcp-0.4.7.dist-info/entry_points.txt +7 -0
- fast_agent_mcp-0.4.7.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tool execution handler protocol for MCP aggregator.
|
|
3
|
+
|
|
4
|
+
Provides a clean interface for hooking into tool execution lifecycle,
|
|
5
|
+
similar to how elicitation handlers work.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Protocol, runtime_checkable
|
|
9
|
+
|
|
10
|
+
from mcp.types import ContentBlock
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@runtime_checkable
|
|
14
|
+
class ToolExecutionHandler(Protocol):
|
|
15
|
+
"""
|
|
16
|
+
Protocol for handling tool execution lifecycle events.
|
|
17
|
+
|
|
18
|
+
Implementations can hook into tool execution to track progress,
|
|
19
|
+
request permissions, or send notifications (e.g., for ACP).
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
async def on_tool_start(
|
|
23
|
+
self,
|
|
24
|
+
tool_name: str,
|
|
25
|
+
server_name: str,
|
|
26
|
+
arguments: dict | None,
|
|
27
|
+
tool_use_id: str | None = None,
|
|
28
|
+
) -> str:
|
|
29
|
+
"""
|
|
30
|
+
Called when a tool execution starts.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
tool_name: Name of the tool being called
|
|
34
|
+
server_name: Name of the MCP server providing the tool
|
|
35
|
+
arguments: Tool arguments
|
|
36
|
+
tool_use_id: LLM's tool use ID (for matching with stream events)
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
A unique tool_call_id for tracking this execution
|
|
40
|
+
"""
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
async def on_tool_progress(
|
|
44
|
+
self,
|
|
45
|
+
tool_call_id: str,
|
|
46
|
+
progress: float,
|
|
47
|
+
total: float | None,
|
|
48
|
+
message: str | None,
|
|
49
|
+
) -> None:
|
|
50
|
+
"""
|
|
51
|
+
Called when tool execution reports progress.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
tool_call_id: The tracking ID from on_tool_start
|
|
55
|
+
progress: Current progress value
|
|
56
|
+
total: Total value for progress calculation (optional)
|
|
57
|
+
message: Optional progress message
|
|
58
|
+
"""
|
|
59
|
+
...
|
|
60
|
+
|
|
61
|
+
async def on_tool_complete(
|
|
62
|
+
self,
|
|
63
|
+
tool_call_id: str,
|
|
64
|
+
success: bool,
|
|
65
|
+
content: list[ContentBlock] | None,
|
|
66
|
+
error: str | None,
|
|
67
|
+
) -> None:
|
|
68
|
+
"""
|
|
69
|
+
Called when tool execution completes.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
tool_call_id: The tracking ID from on_tool_start
|
|
73
|
+
success: Whether the tool executed successfully
|
|
74
|
+
content: Optional content blocks (text, images, etc.) if successful
|
|
75
|
+
error: Optional error message if failed
|
|
76
|
+
"""
|
|
77
|
+
...
|
|
78
|
+
|
|
79
|
+
async def on_tool_permission_denied(
|
|
80
|
+
self,
|
|
81
|
+
tool_name: str,
|
|
82
|
+
server_name: str,
|
|
83
|
+
tool_use_id: str | None,
|
|
84
|
+
error: str | None = None,
|
|
85
|
+
) -> None:
|
|
86
|
+
"""
|
|
87
|
+
Optional hook invoked when tool execution is denied before start.
|
|
88
|
+
|
|
89
|
+
Implementations can use this to notify external systems (e.g., ACP)
|
|
90
|
+
that a tool call was cancelled or declined.
|
|
91
|
+
"""
|
|
92
|
+
...
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class NoOpToolExecutionHandler(ToolExecutionHandler):
|
|
96
|
+
"""Default no-op handler that maintains existing behavior."""
|
|
97
|
+
|
|
98
|
+
async def on_tool_start(
|
|
99
|
+
self,
|
|
100
|
+
tool_name: str,
|
|
101
|
+
server_name: str,
|
|
102
|
+
arguments: dict | None,
|
|
103
|
+
tool_use_id: str | None = None,
|
|
104
|
+
) -> str:
|
|
105
|
+
"""Generate a simple UUID for tracking."""
|
|
106
|
+
import uuid
|
|
107
|
+
return str(uuid.uuid4())
|
|
108
|
+
|
|
109
|
+
async def on_tool_progress(
|
|
110
|
+
self,
|
|
111
|
+
tool_call_id: str,
|
|
112
|
+
progress: float,
|
|
113
|
+
total: float | None,
|
|
114
|
+
message: str | None,
|
|
115
|
+
) -> None:
|
|
116
|
+
"""No-op - does nothing."""
|
|
117
|
+
pass
|
|
118
|
+
|
|
119
|
+
async def on_tool_complete(
|
|
120
|
+
self,
|
|
121
|
+
tool_call_id: str,
|
|
122
|
+
success: bool,
|
|
123
|
+
content: list[ContentBlock] | None,
|
|
124
|
+
error: str | None,
|
|
125
|
+
) -> None:
|
|
126
|
+
"""No-op - does nothing."""
|
|
127
|
+
pass
|
|
128
|
+
|
|
129
|
+
async def on_tool_permission_denied(
|
|
130
|
+
self,
|
|
131
|
+
tool_name: str,
|
|
132
|
+
server_name: str,
|
|
133
|
+
tool_use_id: str | None,
|
|
134
|
+
error: str | None = None,
|
|
135
|
+
) -> None:
|
|
136
|
+
"""No-op - does nothing."""
|
|
137
|
+
pass
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tool permission handler protocol for MCP aggregator.
|
|
3
|
+
|
|
4
|
+
Provides a clean interface for hooking into tool permission checks,
|
|
5
|
+
allowing permission systems (like ACP) to be integrated without tight coupling.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import Any, Protocol, runtime_checkable
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class ToolPermissionResult:
|
|
14
|
+
"""Result of a tool permission check."""
|
|
15
|
+
|
|
16
|
+
allowed: bool
|
|
17
|
+
"""Whether the tool execution is permitted."""
|
|
18
|
+
|
|
19
|
+
remember: bool = False
|
|
20
|
+
"""Whether this decision was remembered (from cache/persistence)."""
|
|
21
|
+
|
|
22
|
+
is_cancelled: bool = False
|
|
23
|
+
"""Whether the permission request was cancelled by the user."""
|
|
24
|
+
|
|
25
|
+
error_message: str | None = None
|
|
26
|
+
"""Optional error message to return to the LLM when permission is denied."""
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def allow(cls) -> "ToolPermissionResult":
|
|
30
|
+
"""Create an allowed result."""
|
|
31
|
+
return cls(allowed=True)
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def deny(cls, message: str | None = None) -> "ToolPermissionResult":
|
|
35
|
+
"""Create a denied result with optional error message."""
|
|
36
|
+
return cls(allowed=False, error_message=message)
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def cancelled(cls) -> "ToolPermissionResult":
|
|
40
|
+
"""Create a cancelled result."""
|
|
41
|
+
return cls(allowed=False, is_cancelled=True, error_message="Permission request cancelled")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@runtime_checkable
|
|
45
|
+
class ToolPermissionHandler(Protocol):
|
|
46
|
+
"""
|
|
47
|
+
Protocol for handling tool permission checks.
|
|
48
|
+
|
|
49
|
+
Implementations can check permissions via various mechanisms:
|
|
50
|
+
- ACP session/request_permission
|
|
51
|
+
- Local permission store
|
|
52
|
+
- Custom permission logic
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
async def check_permission(
|
|
56
|
+
self,
|
|
57
|
+
tool_name: str,
|
|
58
|
+
server_name: str,
|
|
59
|
+
arguments: dict[str, Any] | None = None,
|
|
60
|
+
tool_use_id: str | None = None,
|
|
61
|
+
) -> ToolPermissionResult:
|
|
62
|
+
"""
|
|
63
|
+
Check if tool execution is permitted.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
tool_name: Name of the tool to execute
|
|
67
|
+
server_name: Name of the MCP server providing the tool
|
|
68
|
+
arguments: Tool arguments
|
|
69
|
+
tool_use_id: LLM's tool use ID (for tracking)
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
ToolPermissionResult indicating whether execution is allowed
|
|
73
|
+
"""
|
|
74
|
+
...
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class NoOpToolPermissionHandler(ToolPermissionHandler):
|
|
78
|
+
"""Default no-op handler that allows all tool executions."""
|
|
79
|
+
|
|
80
|
+
async def check_permission(
|
|
81
|
+
self,
|
|
82
|
+
tool_name: str,
|
|
83
|
+
server_name: str,
|
|
84
|
+
arguments: dict[str, Any] | None = None,
|
|
85
|
+
tool_use_id: str | None = None,
|
|
86
|
+
) -> ToolPermissionResult:
|
|
87
|
+
"""Always allows tool execution."""
|
|
88
|
+
return ToolPermissionResult.allow()
|