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
fast_agent/__init__.py
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""fast-agent - An MCP native agent application framework"""
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
# Configuration and settings (safe - pure Pydantic models)
|
|
6
|
+
from fast_agent.config import (
|
|
7
|
+
AnthropicSettings,
|
|
8
|
+
AzureSettings,
|
|
9
|
+
BedrockSettings,
|
|
10
|
+
DeepSeekSettings,
|
|
11
|
+
GenericSettings,
|
|
12
|
+
GoogleSettings,
|
|
13
|
+
GroqSettings,
|
|
14
|
+
HuggingFaceSettings,
|
|
15
|
+
LoggerSettings,
|
|
16
|
+
MCPElicitationSettings,
|
|
17
|
+
MCPRootSettings,
|
|
18
|
+
MCPSamplingSettings,
|
|
19
|
+
MCPServerAuthSettings,
|
|
20
|
+
MCPServerSettings,
|
|
21
|
+
MCPSettings,
|
|
22
|
+
OpenAISettings,
|
|
23
|
+
OpenRouterSettings,
|
|
24
|
+
OpenTelemetrySettings,
|
|
25
|
+
Settings,
|
|
26
|
+
SkillsSettings,
|
|
27
|
+
TensorZeroSettings,
|
|
28
|
+
XAISettings,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Type definitions and enums (safe - no dependencies)
|
|
32
|
+
from fast_agent.types import (
|
|
33
|
+
ConversationSummary,
|
|
34
|
+
LlmStopReason,
|
|
35
|
+
PromptMessageExtended,
|
|
36
|
+
RequestParams,
|
|
37
|
+
ResourceLink,
|
|
38
|
+
audio_link,
|
|
39
|
+
extract_first,
|
|
40
|
+
extract_last,
|
|
41
|
+
find_matches,
|
|
42
|
+
image_link,
|
|
43
|
+
resource_link,
|
|
44
|
+
search_messages,
|
|
45
|
+
text_content,
|
|
46
|
+
video_link,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def __getattr__(name: str):
|
|
51
|
+
"""Lazy import heavy modules to avoid circular imports during package initialization."""
|
|
52
|
+
if name == "Core":
|
|
53
|
+
from fast_agent.core import Core
|
|
54
|
+
|
|
55
|
+
return Core
|
|
56
|
+
elif name == "Context":
|
|
57
|
+
from fast_agent.context import Context
|
|
58
|
+
|
|
59
|
+
return Context
|
|
60
|
+
elif name == "ContextDependent":
|
|
61
|
+
from fast_agent.context_dependent import ContextDependent
|
|
62
|
+
|
|
63
|
+
return ContextDependent
|
|
64
|
+
elif name == "ServerRegistry":
|
|
65
|
+
from fast_agent.mcp_server_registry import ServerRegistry
|
|
66
|
+
|
|
67
|
+
return ServerRegistry
|
|
68
|
+
elif name == "ProgressAction":
|
|
69
|
+
from fast_agent.event_progress import ProgressAction
|
|
70
|
+
|
|
71
|
+
return ProgressAction
|
|
72
|
+
elif name == "ProgressEvent":
|
|
73
|
+
from fast_agent.event_progress import ProgressEvent
|
|
74
|
+
|
|
75
|
+
return ProgressEvent
|
|
76
|
+
elif name == "ToolAgentSynchronous":
|
|
77
|
+
from fast_agent.agents.tool_agent import ToolAgent
|
|
78
|
+
|
|
79
|
+
return ToolAgent
|
|
80
|
+
elif name == "LlmAgent":
|
|
81
|
+
from fast_agent.agents.llm_agent import LlmAgent
|
|
82
|
+
|
|
83
|
+
return LlmAgent
|
|
84
|
+
elif name == "LlmDecorator":
|
|
85
|
+
from fast_agent.agents.llm_decorator import LlmDecorator
|
|
86
|
+
|
|
87
|
+
return LlmDecorator
|
|
88
|
+
elif name == "ToolAgent":
|
|
89
|
+
from fast_agent.agents.tool_agent import ToolAgent
|
|
90
|
+
|
|
91
|
+
return ToolAgent
|
|
92
|
+
elif name == "McpAgent":
|
|
93
|
+
# Import directly from submodule to avoid package re-import cycles
|
|
94
|
+
from fast_agent.agents.mcp_agent import McpAgent
|
|
95
|
+
|
|
96
|
+
return McpAgent
|
|
97
|
+
elif name == "FastAgent":
|
|
98
|
+
# Import from the canonical implementation to avoid recursive imports
|
|
99
|
+
from fast_agent.core.fastagent import FastAgent
|
|
100
|
+
|
|
101
|
+
return FastAgent
|
|
102
|
+
elif name == "Prompt":
|
|
103
|
+
# Prompt helper relies on MCP types; load lazily to speed up import time.
|
|
104
|
+
from fast_agent.mcp.prompt import Prompt
|
|
105
|
+
|
|
106
|
+
return Prompt
|
|
107
|
+
elif name == "load_prompt":
|
|
108
|
+
# Prompt loader also depends on MCP; defer import until explicitly requested.
|
|
109
|
+
from fast_agent.mcp.prompts.prompt_load import load_prompt
|
|
110
|
+
|
|
111
|
+
return load_prompt
|
|
112
|
+
else:
|
|
113
|
+
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
# Help static analyzers/IDEs resolve symbols and signatures without importing at runtime.
|
|
117
|
+
if TYPE_CHECKING: # pragma: no cover - typing aid only
|
|
118
|
+
# Provide a concrete import path for type checkers/IDEs
|
|
119
|
+
from fast_agent.core.fastagent import FastAgent as FastAgent # noqa: F401
|
|
120
|
+
from fast_agent.mcp.prompt import Prompt as Prompt # noqa: F401
|
|
121
|
+
from fast_agent.types import ConversationSummary as ConversationSummary # noqa: F401
|
|
122
|
+
from fast_agent.types import PromptMessageExtended as PromptMessageExtended # noqa: F401
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
__all__ = [
|
|
126
|
+
# Core fast-agent components (lazy loaded)
|
|
127
|
+
"Core",
|
|
128
|
+
"Context",
|
|
129
|
+
"ContextDependent",
|
|
130
|
+
"ServerRegistry",
|
|
131
|
+
# Configuration and settings (eagerly loaded)
|
|
132
|
+
"Settings",
|
|
133
|
+
"MCPSettings",
|
|
134
|
+
"MCPServerSettings",
|
|
135
|
+
"MCPServerAuthSettings",
|
|
136
|
+
"MCPSamplingSettings",
|
|
137
|
+
"MCPElicitationSettings",
|
|
138
|
+
"MCPRootSettings",
|
|
139
|
+
"AnthropicSettings",
|
|
140
|
+
"OpenAISettings",
|
|
141
|
+
"DeepSeekSettings",
|
|
142
|
+
"GoogleSettings",
|
|
143
|
+
"XAISettings",
|
|
144
|
+
"GenericSettings",
|
|
145
|
+
"OpenRouterSettings",
|
|
146
|
+
"AzureSettings",
|
|
147
|
+
"GroqSettings",
|
|
148
|
+
"OpenTelemetrySettings",
|
|
149
|
+
"TensorZeroSettings",
|
|
150
|
+
"BedrockSettings",
|
|
151
|
+
"HuggingFaceSettings",
|
|
152
|
+
"LoggerSettings",
|
|
153
|
+
"SkillsSettings",
|
|
154
|
+
# Progress and event tracking (lazy loaded)
|
|
155
|
+
"ProgressAction",
|
|
156
|
+
"ProgressEvent",
|
|
157
|
+
# Type definitions and enums (eagerly loaded)
|
|
158
|
+
"LlmStopReason",
|
|
159
|
+
"RequestParams",
|
|
160
|
+
"PromptMessageExtended",
|
|
161
|
+
"ResourceLink",
|
|
162
|
+
"ConversationSummary",
|
|
163
|
+
# Content helpers (eagerly loaded)
|
|
164
|
+
"text_content",
|
|
165
|
+
"resource_link",
|
|
166
|
+
"image_link",
|
|
167
|
+
"video_link",
|
|
168
|
+
"audio_link",
|
|
169
|
+
# Search utilities (eagerly loaded)
|
|
170
|
+
"search_messages",
|
|
171
|
+
"find_matches",
|
|
172
|
+
"extract_first",
|
|
173
|
+
"extract_last",
|
|
174
|
+
# Prompt helpers (eagerly loaded)
|
|
175
|
+
"Prompt",
|
|
176
|
+
"load_prompt",
|
|
177
|
+
# Agents (lazy loaded)
|
|
178
|
+
"LlmAgent",
|
|
179
|
+
"LlmDecorator",
|
|
180
|
+
"ToolAgent",
|
|
181
|
+
"McpAgent",
|
|
182
|
+
"FastAgent",
|
|
183
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Agent Client Protocol (ACP) support for fast-agent."""
|
|
2
|
+
|
|
3
|
+
from fast_agent.acp.acp_aware_mixin import ACPAwareMixin, ACPCommand, ACPModeInfo
|
|
4
|
+
from fast_agent.acp.acp_context import ACPContext, ClientCapabilities, ClientInfo
|
|
5
|
+
from fast_agent.acp.filesystem_runtime import ACPFilesystemRuntime
|
|
6
|
+
from fast_agent.acp.server.agent_acp_server import AgentACPServer
|
|
7
|
+
from fast_agent.acp.terminal_runtime import ACPTerminalRuntime
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"ACPCommand",
|
|
11
|
+
"ACPModeInfo",
|
|
12
|
+
"ACPContext",
|
|
13
|
+
"ACPAwareMixin",
|
|
14
|
+
"ClientCapabilities",
|
|
15
|
+
"ClientInfo",
|
|
16
|
+
"AgentACPServer",
|
|
17
|
+
"ACPFilesystemRuntime",
|
|
18
|
+
"ACPTerminalRuntime",
|
|
19
|
+
]
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ACPAwareMixin - Mixin providing convenient ACP access for agents.
|
|
3
|
+
|
|
4
|
+
This mixin extends ContextDependent to provide easy access to ACP features
|
|
5
|
+
when running in ACP mode. Agents inheriting this mixin can:
|
|
6
|
+
|
|
7
|
+
- Check if they're running in ACP mode
|
|
8
|
+
- Access ACP capabilities (terminal, filesystem, etc.)
|
|
9
|
+
- Switch modes programmatically
|
|
10
|
+
- Define slash commands declaratively via acp_commands property
|
|
11
|
+
- Query client capabilities
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from typing import TYPE_CHECKING, Awaitable, Callable
|
|
18
|
+
|
|
19
|
+
from fast_agent.context_dependent import ContextDependent
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from fast_agent.acp.acp_context import ACPContext
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Type alias for slash command handlers
|
|
26
|
+
SlashCommandHandlerFunc = Callable[[str], Awaitable[str]]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class ACPCommand:
|
|
31
|
+
"""
|
|
32
|
+
Defines a slash command that an agent can expose via ACP.
|
|
33
|
+
|
|
34
|
+
Agents declare their commands by overriding the `acp_commands` property
|
|
35
|
+
to return a dict mapping command names to ACPCommand instances.
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
@property
|
|
39
|
+
def acp_commands(self) -> dict[str, ACPCommand]:
|
|
40
|
+
return {
|
|
41
|
+
"analyze": ACPCommand(
|
|
42
|
+
description="Analyze the current context",
|
|
43
|
+
handler=self._handle_analyze,
|
|
44
|
+
),
|
|
45
|
+
}
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
description: str
|
|
49
|
+
handler: SlashCommandHandlerFunc
|
|
50
|
+
input_hint: str | None = None
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass
|
|
54
|
+
class ACPModeInfo:
|
|
55
|
+
"""
|
|
56
|
+
Optional display metadata for ACP modes.
|
|
57
|
+
|
|
58
|
+
Agents can override `acp_mode_info()` to provide a custom name and/or
|
|
59
|
+
description that will be surfaced to ACP clients.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
name: str | None = None
|
|
63
|
+
description: str | None = None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class ACPAwareMixin(ContextDependent):
|
|
67
|
+
"""
|
|
68
|
+
Mixin providing convenient ACP access for agents.
|
|
69
|
+
|
|
70
|
+
This mixin builds on ContextDependent to provide easy access to ACP features.
|
|
71
|
+
It checks for the presence of an ACPContext in the application Context and
|
|
72
|
+
provides convenient properties and methods for ACP operations.
|
|
73
|
+
|
|
74
|
+
Usage:
|
|
75
|
+
class MyAgent(ACPAwareMixin, McpAgent):
|
|
76
|
+
async def initialize(self):
|
|
77
|
+
await super().initialize()
|
|
78
|
+
|
|
79
|
+
# Check if running in ACP mode
|
|
80
|
+
if self.is_acp_mode:
|
|
81
|
+
# Register a dynamic slash command
|
|
82
|
+
await self.acp_add_command(
|
|
83
|
+
name="analyze",
|
|
84
|
+
description="Run analysis",
|
|
85
|
+
handler=self._handle_analyze
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
async def generate_impl(self, request):
|
|
89
|
+
if self.is_acp_mode:
|
|
90
|
+
# Check client capabilities
|
|
91
|
+
if self.acp.supports_terminal:
|
|
92
|
+
...
|
|
93
|
+
|
|
94
|
+
# Get current mode
|
|
95
|
+
print(f"Current mode: {self.acp_current_mode}")
|
|
96
|
+
|
|
97
|
+
# Maybe switch modes
|
|
98
|
+
if should_delegate:
|
|
99
|
+
await self.acp_switch_mode("specialist_agent")
|
|
100
|
+
|
|
101
|
+
return await super().generate_impl(request)
|
|
102
|
+
|
|
103
|
+
async def _handle_analyze(self, arguments: str) -> str:
|
|
104
|
+
return f"Analysis result for: {arguments}"
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def acp(self) -> "ACPContext | None":
|
|
109
|
+
"""
|
|
110
|
+
Get the ACP context if available.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
ACPContext if running in ACP mode, None otherwise
|
|
114
|
+
"""
|
|
115
|
+
try:
|
|
116
|
+
ctx = self.context
|
|
117
|
+
return getattr(ctx, "acp", None)
|
|
118
|
+
except RuntimeError:
|
|
119
|
+
# No context available
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def is_acp_mode(self) -> bool:
|
|
124
|
+
"""
|
|
125
|
+
Check if the agent is running in ACP mode.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
True if ACP context is available, False otherwise
|
|
129
|
+
"""
|
|
130
|
+
return self.acp is not None
|
|
131
|
+
|
|
132
|
+
# =========================================================================
|
|
133
|
+
# Mode Management Shortcuts
|
|
134
|
+
# =========================================================================
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def acp_current_mode(self) -> str | None:
|
|
138
|
+
"""
|
|
139
|
+
Get the current ACP mode (agent ID).
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
Current mode ID, or None if not in ACP mode
|
|
143
|
+
"""
|
|
144
|
+
acp = self.acp
|
|
145
|
+
return acp.current_mode if acp else None
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def acp_session_id(self) -> str | None:
|
|
149
|
+
"""
|
|
150
|
+
Get the ACP session ID.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
Session ID, or None if not in ACP mode
|
|
154
|
+
"""
|
|
155
|
+
acp = self.acp
|
|
156
|
+
return acp.session_id if acp else None
|
|
157
|
+
|
|
158
|
+
async def acp_switch_mode(self, mode_id: str) -> bool:
|
|
159
|
+
"""
|
|
160
|
+
Switch to a different mode (agent).
|
|
161
|
+
|
|
162
|
+
This sends a CurrentModeUpdate notification to the ACP client,
|
|
163
|
+
telling it that the agent has autonomously switched modes.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
mode_id: The mode ID to switch to
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
True if switch was successful, False if not in ACP mode
|
|
170
|
+
|
|
171
|
+
Raises:
|
|
172
|
+
ValueError: If the mode_id is not in available modes
|
|
173
|
+
"""
|
|
174
|
+
acp = self.acp
|
|
175
|
+
if not acp:
|
|
176
|
+
return False
|
|
177
|
+
|
|
178
|
+
await acp.switch_mode(mode_id)
|
|
179
|
+
return True
|
|
180
|
+
|
|
181
|
+
def acp_available_modes(self) -> list[str]:
|
|
182
|
+
"""
|
|
183
|
+
Get list of available mode IDs.
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
List of mode IDs, or empty list if not in ACP mode
|
|
187
|
+
"""
|
|
188
|
+
acp = self.acp
|
|
189
|
+
return list(acp.available_modes.keys()) if acp else []
|
|
190
|
+
|
|
191
|
+
# =========================================================================
|
|
192
|
+
# Client Capability Shortcuts
|
|
193
|
+
# =========================================================================
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
def acp_supports_terminal(self) -> bool:
|
|
197
|
+
"""Check if ACP client supports terminal operations."""
|
|
198
|
+
acp = self.acp
|
|
199
|
+
return acp.supports_terminal if acp else False
|
|
200
|
+
|
|
201
|
+
@property
|
|
202
|
+
def acp_supports_fs_read(self) -> bool:
|
|
203
|
+
"""Check if ACP client supports file reading."""
|
|
204
|
+
acp = self.acp
|
|
205
|
+
return acp.supports_fs_read if acp else False
|
|
206
|
+
|
|
207
|
+
@property
|
|
208
|
+
def acp_supports_fs_write(self) -> bool:
|
|
209
|
+
"""Check if ACP client supports file writing."""
|
|
210
|
+
acp = self.acp
|
|
211
|
+
return acp.supports_fs_write if acp else False
|
|
212
|
+
|
|
213
|
+
@property
|
|
214
|
+
def acp_supports_filesystem(self) -> bool:
|
|
215
|
+
"""Check if ACP client supports any filesystem operations."""
|
|
216
|
+
acp = self.acp
|
|
217
|
+
return acp.supports_filesystem if acp else False
|
|
218
|
+
|
|
219
|
+
# =========================================================================
|
|
220
|
+
# Slash Commands (Declarative)
|
|
221
|
+
# =========================================================================
|
|
222
|
+
|
|
223
|
+
@property
|
|
224
|
+
def acp_commands(self) -> dict[str, "ACPCommand"]:
|
|
225
|
+
"""
|
|
226
|
+
Declare slash commands this agent exposes via ACP.
|
|
227
|
+
|
|
228
|
+
Override this property to provide agent-specific commands.
|
|
229
|
+
Commands are queried dynamically when the agent is the active mode.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
Dict mapping command names (without slash) to ACPCommand instances.
|
|
233
|
+
|
|
234
|
+
Example:
|
|
235
|
+
@property
|
|
236
|
+
def acp_commands(self) -> dict[str, ACPCommand]:
|
|
237
|
+
return {
|
|
238
|
+
"analyze": ACPCommand(
|
|
239
|
+
description="Analyze the current context",
|
|
240
|
+
handler=self._handle_analyze,
|
|
241
|
+
),
|
|
242
|
+
"report": ACPCommand(
|
|
243
|
+
description="Generate a report",
|
|
244
|
+
handler=self._handle_report,
|
|
245
|
+
input_hint="<format>",
|
|
246
|
+
),
|
|
247
|
+
}
|
|
248
|
+
"""
|
|
249
|
+
return {}
|
|
250
|
+
|
|
251
|
+
def acp_mode_info(self) -> ACPModeInfo | None:
|
|
252
|
+
"""
|
|
253
|
+
Optional ACP mode metadata (name/description) for display in clients.
|
|
254
|
+
Override to customize the label and description for this agent's mode.
|
|
255
|
+
"""
|
|
256
|
+
return None
|
|
257
|
+
|
|
258
|
+
# =========================================================================
|
|
259
|
+
# Runtime Access Shortcuts
|
|
260
|
+
# =========================================================================
|
|
261
|
+
|
|
262
|
+
@property
|
|
263
|
+
def acp_terminal_runtime(self):
|
|
264
|
+
"""
|
|
265
|
+
Get the ACP terminal runtime (if available).
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
ACPTerminalRuntime or None
|
|
269
|
+
"""
|
|
270
|
+
acp = self.acp
|
|
271
|
+
return acp.terminal_runtime if acp else None
|
|
272
|
+
|
|
273
|
+
@property
|
|
274
|
+
def acp_filesystem_runtime(self):
|
|
275
|
+
"""
|
|
276
|
+
Get the ACP filesystem runtime (if available).
|
|
277
|
+
|
|
278
|
+
Returns:
|
|
279
|
+
ACPFilesystemRuntime or None
|
|
280
|
+
"""
|
|
281
|
+
acp = self.acp
|
|
282
|
+
return acp.filesystem_runtime if acp else None
|
|
283
|
+
|
|
284
|
+
@property
|
|
285
|
+
def acp_permission_handler(self):
|
|
286
|
+
"""
|
|
287
|
+
Get the ACP permission handler (if available).
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
ACPToolPermissionAdapter or None
|
|
291
|
+
"""
|
|
292
|
+
acp = self.acp
|
|
293
|
+
return acp.permission_handler if acp else None
|
|
294
|
+
|
|
295
|
+
@property
|
|
296
|
+
def acp_progress_manager(self):
|
|
297
|
+
"""
|
|
298
|
+
Get the ACP progress manager (if available).
|
|
299
|
+
|
|
300
|
+
Returns:
|
|
301
|
+
ACPToolProgressManager or None
|
|
302
|
+
"""
|
|
303
|
+
acp = self.acp
|
|
304
|
+
return acp.progress_manager if acp else None
|