fast-agent-mcp 0.2.57__py3-none-any.whl → 0.3.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.
Potentially problematic release.
This version of fast-agent-mcp might be problematic. Click here for more details.
- fast_agent/__init__.py +127 -0
- fast_agent/agents/__init__.py +36 -0
- {mcp_agent/core → fast_agent/agents}/agent_types.py +2 -1
- fast_agent/agents/llm_agent.py +217 -0
- fast_agent/agents/llm_decorator.py +486 -0
- mcp_agent/agents/base_agent.py → fast_agent/agents/mcp_agent.py +377 -385
- fast_agent/agents/tool_agent.py +168 -0
- {mcp_agent → fast_agent}/agents/workflow/chain_agent.py +43 -33
- {mcp_agent → fast_agent}/agents/workflow/evaluator_optimizer.py +31 -35
- {mcp_agent → fast_agent}/agents/workflow/iterative_planner.py +56 -47
- {mcp_agent → fast_agent}/agents/workflow/orchestrator_models.py +4 -4
- {mcp_agent → fast_agent}/agents/workflow/parallel_agent.py +34 -41
- {mcp_agent → fast_agent}/agents/workflow/router_agent.py +54 -39
- {mcp_agent → fast_agent}/cli/__main__.py +5 -3
- {mcp_agent → fast_agent}/cli/commands/check_config.py +95 -66
- {mcp_agent → fast_agent}/cli/commands/go.py +20 -11
- {mcp_agent → fast_agent}/cli/commands/quickstart.py +4 -4
- {mcp_agent → fast_agent}/cli/commands/server_helpers.py +1 -1
- {mcp_agent → fast_agent}/cli/commands/setup.py +64 -134
- {mcp_agent → fast_agent}/cli/commands/url_parser.py +9 -8
- {mcp_agent → fast_agent}/cli/main.py +36 -16
- {mcp_agent → fast_agent}/cli/terminal.py +2 -2
- {mcp_agent → fast_agent}/config.py +13 -2
- fast_agent/constants.py +8 -0
- {mcp_agent → fast_agent}/context.py +24 -19
- {mcp_agent → fast_agent}/context_dependent.py +9 -5
- fast_agent/core/__init__.py +17 -0
- {mcp_agent → fast_agent}/core/agent_app.py +39 -36
- fast_agent/core/core_app.py +135 -0
- {mcp_agent → fast_agent}/core/direct_decorators.py +12 -26
- {mcp_agent → fast_agent}/core/direct_factory.py +95 -73
- {mcp_agent → fast_agent/core}/executor/executor.py +4 -5
- {mcp_agent → fast_agent}/core/fastagent.py +32 -32
- fast_agent/core/logging/__init__.py +5 -0
- {mcp_agent → fast_agent/core}/logging/events.py +3 -3
- {mcp_agent → fast_agent/core}/logging/json_serializer.py +1 -1
- {mcp_agent → fast_agent/core}/logging/listeners.py +85 -7
- {mcp_agent → fast_agent/core}/logging/logger.py +7 -7
- {mcp_agent → fast_agent/core}/logging/transport.py +10 -11
- fast_agent/core/prompt.py +9 -0
- {mcp_agent → fast_agent}/core/validation.py +4 -4
- fast_agent/event_progress.py +61 -0
- fast_agent/history/history_exporter.py +44 -0
- {mcp_agent → fast_agent}/human_input/__init__.py +9 -12
- {mcp_agent → fast_agent}/human_input/elicitation_handler.py +26 -8
- {mcp_agent → fast_agent}/human_input/elicitation_state.py +7 -7
- {mcp_agent → fast_agent}/human_input/simple_form.py +6 -4
- {mcp_agent → fast_agent}/human_input/types.py +1 -18
- fast_agent/interfaces.py +228 -0
- fast_agent/llm/__init__.py +9 -0
- mcp_agent/llm/augmented_llm.py → fast_agent/llm/fastagent_llm.py +128 -218
- fast_agent/llm/internal/passthrough.py +137 -0
- mcp_agent/llm/augmented_llm_playback.py → fast_agent/llm/internal/playback.py +29 -25
- mcp_agent/llm/augmented_llm_silent.py → fast_agent/llm/internal/silent.py +10 -17
- fast_agent/llm/internal/slow.py +38 -0
- {mcp_agent → fast_agent}/llm/memory.py +40 -30
- {mcp_agent → fast_agent}/llm/model_database.py +35 -2
- {mcp_agent → fast_agent}/llm/model_factory.py +103 -77
- fast_agent/llm/model_info.py +126 -0
- {mcp_agent/llm/providers → fast_agent/llm/provider/anthropic}/anthropic_utils.py +7 -7
- fast_agent/llm/provider/anthropic/llm_anthropic.py +603 -0
- {mcp_agent/llm/providers → fast_agent/llm/provider/anthropic}/multipart_converter_anthropic.py +79 -86
- fast_agent/llm/provider/bedrock/bedrock_utils.py +218 -0
- fast_agent/llm/provider/bedrock/llm_bedrock.py +2192 -0
- {mcp_agent/llm/providers → fast_agent/llm/provider/google}/google_converter.py +66 -14
- fast_agent/llm/provider/google/llm_google_native.py +431 -0
- mcp_agent/llm/providers/augmented_llm_aliyun.py → fast_agent/llm/provider/openai/llm_aliyun.py +6 -7
- mcp_agent/llm/providers/augmented_llm_azure.py → fast_agent/llm/provider/openai/llm_azure.py +4 -4
- mcp_agent/llm/providers/augmented_llm_deepseek.py → fast_agent/llm/provider/openai/llm_deepseek.py +10 -11
- mcp_agent/llm/providers/augmented_llm_generic.py → fast_agent/llm/provider/openai/llm_generic.py +4 -4
- mcp_agent/llm/providers/augmented_llm_google_oai.py → fast_agent/llm/provider/openai/llm_google_oai.py +4 -4
- mcp_agent/llm/providers/augmented_llm_groq.py → fast_agent/llm/provider/openai/llm_groq.py +14 -16
- mcp_agent/llm/providers/augmented_llm_openai.py → fast_agent/llm/provider/openai/llm_openai.py +133 -206
- mcp_agent/llm/providers/augmented_llm_openrouter.py → fast_agent/llm/provider/openai/llm_openrouter.py +6 -6
- mcp_agent/llm/providers/augmented_llm_tensorzero_openai.py → fast_agent/llm/provider/openai/llm_tensorzero_openai.py +17 -16
- mcp_agent/llm/providers/augmented_llm_xai.py → fast_agent/llm/provider/openai/llm_xai.py +6 -6
- {mcp_agent/llm/providers → fast_agent/llm/provider/openai}/multipart_converter_openai.py +125 -63
- {mcp_agent/llm/providers → fast_agent/llm/provider/openai}/openai_multipart.py +12 -12
- {mcp_agent/llm/providers → fast_agent/llm/provider/openai}/openai_utils.py +18 -16
- {mcp_agent → fast_agent}/llm/provider_key_manager.py +2 -2
- {mcp_agent → fast_agent}/llm/provider_types.py +2 -0
- {mcp_agent → fast_agent}/llm/sampling_converter.py +15 -12
- {mcp_agent → fast_agent}/llm/usage_tracking.py +23 -5
- fast_agent/mcp/__init__.py +43 -0
- {mcp_agent → fast_agent}/mcp/elicitation_factory.py +3 -3
- {mcp_agent → fast_agent}/mcp/elicitation_handlers.py +19 -10
- {mcp_agent → fast_agent}/mcp/gen_client.py +3 -3
- fast_agent/mcp/helpers/__init__.py +36 -0
- fast_agent/mcp/helpers/content_helpers.py +183 -0
- {mcp_agent → fast_agent}/mcp/helpers/server_config_helpers.py +8 -8
- {mcp_agent → fast_agent}/mcp/hf_auth.py +25 -23
- fast_agent/mcp/interfaces.py +93 -0
- {mcp_agent → fast_agent}/mcp/logger_textio.py +4 -4
- {mcp_agent → fast_agent}/mcp/mcp_agent_client_session.py +49 -44
- {mcp_agent → fast_agent}/mcp/mcp_aggregator.py +66 -115
- {mcp_agent → fast_agent}/mcp/mcp_connection_manager.py +16 -23
- {mcp_agent/core → fast_agent/mcp}/mcp_content.py +23 -15
- {mcp_agent → fast_agent}/mcp/mime_utils.py +39 -0
- fast_agent/mcp/prompt.py +159 -0
- mcp_agent/mcp/prompt_message_multipart.py → fast_agent/mcp/prompt_message_extended.py +27 -20
- {mcp_agent → fast_agent}/mcp/prompt_render.py +21 -19
- {mcp_agent → fast_agent}/mcp/prompt_serialization.py +46 -46
- fast_agent/mcp/prompts/__main__.py +7 -0
- {mcp_agent → fast_agent}/mcp/prompts/prompt_helpers.py +31 -30
- {mcp_agent → fast_agent}/mcp/prompts/prompt_load.py +8 -8
- {mcp_agent → fast_agent}/mcp/prompts/prompt_server.py +11 -19
- {mcp_agent → fast_agent}/mcp/prompts/prompt_template.py +18 -18
- {mcp_agent → fast_agent}/mcp/resource_utils.py +1 -1
- {mcp_agent → fast_agent}/mcp/sampling.py +31 -26
- {mcp_agent/mcp_server → fast_agent/mcp/server}/__init__.py +1 -1
- {mcp_agent/mcp_server → fast_agent/mcp/server}/agent_server.py +5 -6
- fast_agent/mcp/ui_agent.py +48 -0
- fast_agent/mcp/ui_mixin.py +209 -0
- fast_agent/mcp_server_registry.py +90 -0
- {mcp_agent → fast_agent}/resources/examples/data-analysis/analysis-campaign.py +5 -4
- {mcp_agent → fast_agent}/resources/examples/data-analysis/analysis.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/elicitation_forms_server.py +25 -3
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/forms_demo.py +3 -3
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/game_character.py +2 -2
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/game_character_handler.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/tool_call.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/mcp/state-transfer/agent_one.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/mcp/state-transfer/agent_two.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/researcher/researcher-eval.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/researcher/researcher-imp.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/researcher/researcher.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/tensorzero/agent.py +2 -2
- {mcp_agent → fast_agent}/resources/examples/tensorzero/image_demo.py +3 -3
- {mcp_agent → fast_agent}/resources/examples/tensorzero/simple_agent.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/workflows/chaining.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/workflows/evaluator.py +3 -3
- {mcp_agent → fast_agent}/resources/examples/workflows/human_input.py +5 -3
- {mcp_agent → fast_agent}/resources/examples/workflows/orchestrator.py +1 -1
- {mcp_agent → fast_agent}/resources/examples/workflows/parallel.py +2 -2
- {mcp_agent → fast_agent}/resources/examples/workflows/router.py +5 -2
- fast_agent/resources/setup/.gitignore +24 -0
- fast_agent/resources/setup/agent.py +18 -0
- fast_agent/resources/setup/fastagent.config.yaml +44 -0
- fast_agent/resources/setup/fastagent.secrets.yaml.example +38 -0
- fast_agent/tools/elicitation.py +369 -0
- fast_agent/types/__init__.py +32 -0
- fast_agent/types/llm_stop_reason.py +77 -0
- fast_agent/ui/__init__.py +38 -0
- fast_agent/ui/console_display.py +1005 -0
- {mcp_agent/human_input → fast_agent/ui}/elicitation_form.py +56 -39
- mcp_agent/human_input/elicitation_forms.py → fast_agent/ui/elicitation_style.py +1 -1
- {mcp_agent/core → fast_agent/ui}/enhanced_prompt.py +96 -25
- {mcp_agent/core → fast_agent/ui}/interactive_prompt.py +330 -125
- fast_agent/ui/mcp_ui_utils.py +224 -0
- {mcp_agent → fast_agent/ui}/progress_display.py +2 -2
- {mcp_agent/logging → fast_agent/ui}/rich_progress.py +4 -4
- {mcp_agent/core → fast_agent/ui}/usage_display.py +3 -8
- {fast_agent_mcp-0.2.57.dist-info → fast_agent_mcp-0.3.0.dist-info}/METADATA +7 -7
- fast_agent_mcp-0.3.0.dist-info/RECORD +202 -0
- fast_agent_mcp-0.3.0.dist-info/entry_points.txt +5 -0
- fast_agent_mcp-0.2.57.dist-info/RECORD +0 -192
- fast_agent_mcp-0.2.57.dist-info/entry_points.txt +0 -6
- mcp_agent/__init__.py +0 -114
- mcp_agent/agents/agent.py +0 -92
- mcp_agent/agents/workflow/__init__.py +0 -1
- mcp_agent/agents/workflow/orchestrator_agent.py +0 -597
- mcp_agent/app.py +0 -175
- mcp_agent/core/__init__.py +0 -26
- mcp_agent/core/prompt.py +0 -191
- mcp_agent/event_progress.py +0 -134
- mcp_agent/human_input/handler.py +0 -81
- mcp_agent/llm/__init__.py +0 -2
- mcp_agent/llm/augmented_llm_passthrough.py +0 -232
- mcp_agent/llm/augmented_llm_slow.py +0 -53
- mcp_agent/llm/providers/__init__.py +0 -8
- mcp_agent/llm/providers/augmented_llm_anthropic.py +0 -717
- mcp_agent/llm/providers/augmented_llm_bedrock.py +0 -1788
- mcp_agent/llm/providers/augmented_llm_google_native.py +0 -495
- mcp_agent/llm/providers/sampling_converter_anthropic.py +0 -57
- mcp_agent/llm/providers/sampling_converter_openai.py +0 -26
- mcp_agent/llm/sampling_format_converter.py +0 -37
- mcp_agent/logging/__init__.py +0 -0
- mcp_agent/mcp/__init__.py +0 -50
- mcp_agent/mcp/helpers/__init__.py +0 -25
- mcp_agent/mcp/helpers/content_helpers.py +0 -187
- mcp_agent/mcp/interfaces.py +0 -266
- mcp_agent/mcp/prompts/__init__.py +0 -0
- mcp_agent/mcp/prompts/__main__.py +0 -10
- mcp_agent/mcp_server_registry.py +0 -343
- mcp_agent/tools/tool_definition.py +0 -14
- mcp_agent/ui/console_display.py +0 -790
- mcp_agent/ui/console_display_legacy.py +0 -401
- {mcp_agent → fast_agent}/agents/workflow/orchestrator_prompts.py +0 -0
- {mcp_agent/agents → fast_agent/cli}/__init__.py +0 -0
- {mcp_agent → fast_agent}/cli/constants.py +0 -0
- {mcp_agent → fast_agent}/core/error_handling.py +0 -0
- {mcp_agent → fast_agent}/core/exceptions.py +0 -0
- {mcp_agent/cli → fast_agent/core/executor}/__init__.py +0 -0
- {mcp_agent → fast_agent/core}/executor/task_registry.py +0 -0
- {mcp_agent → fast_agent/core}/executor/workflow_signal.py +0 -0
- {mcp_agent → fast_agent}/human_input/form_fields.py +0 -0
- {mcp_agent → fast_agent}/llm/prompt_utils.py +0 -0
- {mcp_agent/core → fast_agent/llm}/request_params.py +0 -0
- {mcp_agent → fast_agent}/mcp/common.py +0 -0
- {mcp_agent/executor → fast_agent/mcp/prompts}/__init__.py +0 -0
- {mcp_agent → fast_agent}/mcp/prompts/prompt_constants.py +0 -0
- {mcp_agent → fast_agent}/py.typed +0 -0
- {mcp_agent → fast_agent}/resources/examples/data-analysis/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/elicitation_account_server.py +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/elicitation_game_server.py +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/elicitations/fastagent.secrets.yaml.example +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/state-transfer/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +0 -0
- {mcp_agent → fast_agent}/resources/examples/researcher/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/.env.sample +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/Makefile +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/README.md +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/demo_images/clam.jpg +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/demo_images/crab.png +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/demo_images/shrimp.png +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/docker-compose.yml +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/mcp_server/Dockerfile +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/mcp_server/entrypoint.sh +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/mcp_server/mcp_server.py +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/mcp_server/pyproject.toml +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/tensorzero_config/system_schema.json +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/tensorzero_config/system_template.minijinja +0 -0
- {mcp_agent → fast_agent}/resources/examples/tensorzero/tensorzero_config/tensorzero.toml +0 -0
- {mcp_agent → fast_agent}/resources/examples/workflows/fastagent.config.yaml +0 -0
- {mcp_agent → fast_agent}/resources/examples/workflows/graded_report.md +0 -0
- {mcp_agent → fast_agent}/resources/examples/workflows/short_story.md +0 -0
- {mcp_agent → fast_agent}/resources/examples/workflows/short_story.txt +0 -0
- {mcp_agent → fast_agent/ui}/console.py +0 -0
- {mcp_agent/core → fast_agent/ui}/mermaid_utils.py +0 -0
- {fast_agent_mcp-0.2.57.dist-info → fast_agent_mcp-0.3.0.dist-info}/WHEEL +0 -0
- {fast_agent_mcp-0.2.57.dist-info → fast_agent_mcp-0.3.0.dist-info}/licenses/LICENSE +0 -0
mcp_agent/app.py
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from contextlib import asynccontextmanager
|
|
3
|
-
from typing import TYPE_CHECKING, Dict, Optional, Type, TypeVar
|
|
4
|
-
|
|
5
|
-
from mcp_agent.config import Settings
|
|
6
|
-
from mcp_agent.context import Context, cleanup_context, initialize_context
|
|
7
|
-
from mcp_agent.event_progress import ProgressAction
|
|
8
|
-
from mcp_agent.executor.workflow_signal import SignalWaitCallback
|
|
9
|
-
from mcp_agent.human_input.handler import console_input_callback
|
|
10
|
-
from mcp_agent.human_input.types import HumanInputCallback
|
|
11
|
-
from mcp_agent.logging.logger import get_logger
|
|
12
|
-
|
|
13
|
-
if TYPE_CHECKING:
|
|
14
|
-
from mcp import ServerSession
|
|
15
|
-
|
|
16
|
-
R = TypeVar("R")
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class MCPApp:
|
|
20
|
-
"""
|
|
21
|
-
Main application class that manages global state and can host workflows.
|
|
22
|
-
|
|
23
|
-
Example usage:
|
|
24
|
-
app = MCPApp()
|
|
25
|
-
|
|
26
|
-
@app.workflow
|
|
27
|
-
class MyWorkflow(Workflow[str]):
|
|
28
|
-
@app.task
|
|
29
|
-
async def my_task(self):
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
async def run(self):
|
|
33
|
-
await self.my_task()
|
|
34
|
-
|
|
35
|
-
async with app.run() as running_app:
|
|
36
|
-
workflow = MyWorkflow()
|
|
37
|
-
result = await workflow.execute()
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
|
-
def __init__(
|
|
41
|
-
self,
|
|
42
|
-
name: str = "mcp_application",
|
|
43
|
-
settings: Optional[Settings] | str = None,
|
|
44
|
-
human_input_callback: Optional[HumanInputCallback] = console_input_callback,
|
|
45
|
-
signal_notification: Optional[SignalWaitCallback] = None,
|
|
46
|
-
upstream_session: Optional["ServerSession"] = None,
|
|
47
|
-
) -> None:
|
|
48
|
-
"""
|
|
49
|
-
Initialize the application with a name and optional settings.
|
|
50
|
-
Args:
|
|
51
|
-
name: Name of the application
|
|
52
|
-
settings: Application configuration - If unspecified, the settings are loaded from mcp_agent.config.yaml.
|
|
53
|
-
If this is a string, it is treated as the path to the config file to load.
|
|
54
|
-
human_input_callback: Callback for handling human input
|
|
55
|
-
signal_notification: Callback for getting notified on workflow signals/events.
|
|
56
|
-
upstream_session: Optional upstream session if the MCPApp is running as a server to an MCP client.
|
|
57
|
-
"""
|
|
58
|
-
self.name = name
|
|
59
|
-
|
|
60
|
-
# We use these to initialize the context in initialize()
|
|
61
|
-
self._config_or_path = settings
|
|
62
|
-
self._human_input_callback = human_input_callback
|
|
63
|
-
self._signal_notification = signal_notification
|
|
64
|
-
self._upstream_session = upstream_session
|
|
65
|
-
|
|
66
|
-
self._workflows: Dict[str, Type] = {} # id to workflow class
|
|
67
|
-
self._logger = None
|
|
68
|
-
self._context: Optional[Context] = None
|
|
69
|
-
self._initialized = False
|
|
70
|
-
|
|
71
|
-
@property
|
|
72
|
-
def context(self) -> Context:
|
|
73
|
-
if self._context is None:
|
|
74
|
-
raise RuntimeError(
|
|
75
|
-
"MCPApp not initialized, please call initialize() first, or use async with app.run()."
|
|
76
|
-
)
|
|
77
|
-
return self._context
|
|
78
|
-
|
|
79
|
-
@property
|
|
80
|
-
def config(self):
|
|
81
|
-
return self._context.config
|
|
82
|
-
|
|
83
|
-
@property
|
|
84
|
-
def server_registry(self):
|
|
85
|
-
return self._context.server_registry
|
|
86
|
-
|
|
87
|
-
@property
|
|
88
|
-
def executor(self):
|
|
89
|
-
return self._context.executor
|
|
90
|
-
|
|
91
|
-
@property
|
|
92
|
-
def engine(self):
|
|
93
|
-
return self.executor.execution_engine
|
|
94
|
-
|
|
95
|
-
@property
|
|
96
|
-
def upstream_session(self):
|
|
97
|
-
return self._context.upstream_session
|
|
98
|
-
|
|
99
|
-
@upstream_session.setter
|
|
100
|
-
def upstream_session(self, value) -> None:
|
|
101
|
-
self._context.upstream_session = value
|
|
102
|
-
|
|
103
|
-
@property
|
|
104
|
-
def workflows(self):
|
|
105
|
-
return self._workflows
|
|
106
|
-
|
|
107
|
-
@property
|
|
108
|
-
def tasks(self):
|
|
109
|
-
return self.context.task_registry.list_activities()
|
|
110
|
-
|
|
111
|
-
@property
|
|
112
|
-
def logger(self):
|
|
113
|
-
if self._logger is None:
|
|
114
|
-
self._logger = get_logger(f"mcp_agent.{self.name}")
|
|
115
|
-
return self._logger
|
|
116
|
-
|
|
117
|
-
async def initialize(self) -> None:
|
|
118
|
-
"""Initialize the application."""
|
|
119
|
-
if self._initialized:
|
|
120
|
-
return
|
|
121
|
-
|
|
122
|
-
self._context = await initialize_context(self._config_or_path, store_globally=True)
|
|
123
|
-
|
|
124
|
-
# Set the properties that were passed in the constructor
|
|
125
|
-
self._context.human_input_handler = self._human_input_callback
|
|
126
|
-
self._context.signal_notification = self._signal_notification
|
|
127
|
-
self._context.upstream_session = self._upstream_session
|
|
128
|
-
|
|
129
|
-
self._initialized = True
|
|
130
|
-
self.logger.info(
|
|
131
|
-
"MCPAgent initialized",
|
|
132
|
-
data={
|
|
133
|
-
"progress_action": "Running",
|
|
134
|
-
"target": self.name or "mcp_application",
|
|
135
|
-
"agent_name": self.name or "fastagent loop",
|
|
136
|
-
},
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
async def cleanup(self) -> None:
|
|
140
|
-
"""Cleanup application resources."""
|
|
141
|
-
if not self._initialized:
|
|
142
|
-
return
|
|
143
|
-
|
|
144
|
-
# Updatre progress display before logging is shut down
|
|
145
|
-
self.logger.info(
|
|
146
|
-
"MCPAgent cleanup",
|
|
147
|
-
data={
|
|
148
|
-
"progress_action": ProgressAction.FINISHED,
|
|
149
|
-
"target": self.name or "mcp_application",
|
|
150
|
-
"agent_name": self.name or "fastagent loop",
|
|
151
|
-
},
|
|
152
|
-
)
|
|
153
|
-
try:
|
|
154
|
-
await cleanup_context()
|
|
155
|
-
except asyncio.CancelledError:
|
|
156
|
-
self.logger.debug("Cleanup cancelled error during shutdown")
|
|
157
|
-
|
|
158
|
-
self._context = None
|
|
159
|
-
self._initialized = False
|
|
160
|
-
|
|
161
|
-
@asynccontextmanager
|
|
162
|
-
async def run(self):
|
|
163
|
-
"""
|
|
164
|
-
Run the application. Use as context manager.
|
|
165
|
-
|
|
166
|
-
Example:
|
|
167
|
-
async with app.run() as running_app:
|
|
168
|
-
# App is initialized here
|
|
169
|
-
pass
|
|
170
|
-
"""
|
|
171
|
-
await self.initialize()
|
|
172
|
-
try:
|
|
173
|
-
yield self
|
|
174
|
-
finally:
|
|
175
|
-
await self.cleanup()
|
mcp_agent/core/__init__.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Core components and utilities for MCP Agent.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from .mcp_content import (
|
|
6
|
-
Assistant,
|
|
7
|
-
MCPContentType,
|
|
8
|
-
MCPFile,
|
|
9
|
-
MCPImage,
|
|
10
|
-
MCPPrompt,
|
|
11
|
-
MCPText,
|
|
12
|
-
User,
|
|
13
|
-
create_message,
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
__all__ = [
|
|
17
|
-
# MCP content creation functions
|
|
18
|
-
"MCPText",
|
|
19
|
-
"MCPImage",
|
|
20
|
-
"MCPFile",
|
|
21
|
-
"MCPPrompt",
|
|
22
|
-
"User",
|
|
23
|
-
"Assistant",
|
|
24
|
-
"create_message",
|
|
25
|
-
"MCPContentType",
|
|
26
|
-
]
|
mcp_agent/core/prompt.py
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Prompt class for easily creating and working with MCP prompt content.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from typing import List, Literal, Union
|
|
7
|
-
|
|
8
|
-
from mcp.types import PromptMessage
|
|
9
|
-
|
|
10
|
-
from mcp_agent.mcp.prompt_message_multipart import PromptMessageMultipart
|
|
11
|
-
|
|
12
|
-
# Import our content helper functions
|
|
13
|
-
from .mcp_content import Assistant, MCPContentType, MCPPrompt, User
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class Prompt:
|
|
17
|
-
"""
|
|
18
|
-
A helper class for working with MCP prompt content.
|
|
19
|
-
|
|
20
|
-
This class provides static methods to create:
|
|
21
|
-
- PromptMessage instances
|
|
22
|
-
- PromptMessageMultipart instances
|
|
23
|
-
- Lists of messages for conversations
|
|
24
|
-
|
|
25
|
-
All methods intelligently handle various content types:
|
|
26
|
-
- Strings become TextContent
|
|
27
|
-
- Image file paths become ImageContent
|
|
28
|
-
- Other file paths become EmbeddedResource
|
|
29
|
-
- TextContent objects are used directly
|
|
30
|
-
- ImageContent objects are used directly
|
|
31
|
-
- EmbeddedResource objects are used directly
|
|
32
|
-
- Pre-formatted messages pass through unchanged
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
@classmethod
|
|
36
|
-
def user(cls, *content_items: Union[str, Path, bytes, dict, MCPContentType, PromptMessage, PromptMessageMultipart]) -> PromptMessageMultipart:
|
|
37
|
-
"""
|
|
38
|
-
Create a user PromptMessageMultipart with various content items.
|
|
39
|
-
|
|
40
|
-
Args:
|
|
41
|
-
*content_items: Content items in various formats:
|
|
42
|
-
- Strings: Converted to TextContent
|
|
43
|
-
- Path objects: Converted based on file type (image/text/binary)
|
|
44
|
-
- Bytes: Treated as image data
|
|
45
|
-
- Dicts with role/content: Content extracted
|
|
46
|
-
- TextContent: Used directly
|
|
47
|
-
- ImageContent: Used directly
|
|
48
|
-
- EmbeddedResource: Used directly
|
|
49
|
-
- PromptMessage: Content extracted
|
|
50
|
-
- PromptMessageMultipart: Content extracted with role changed to user
|
|
51
|
-
|
|
52
|
-
Returns:
|
|
53
|
-
A PromptMessageMultipart with user role and the specified content
|
|
54
|
-
"""
|
|
55
|
-
# Handle PromptMessage and PromptMessageMultipart directly
|
|
56
|
-
if len(content_items) == 1:
|
|
57
|
-
item = content_items[0]
|
|
58
|
-
if isinstance(item, PromptMessage):
|
|
59
|
-
return PromptMessageMultipart(role="user", content=[item.content])
|
|
60
|
-
elif isinstance(item, PromptMessageMultipart):
|
|
61
|
-
# Keep the content but change role to user
|
|
62
|
-
return PromptMessageMultipart(role="user", content=item.content)
|
|
63
|
-
|
|
64
|
-
# Use the original implementation for other types
|
|
65
|
-
messages = User(*content_items)
|
|
66
|
-
return PromptMessageMultipart(role="user", content=[msg["content"] for msg in messages])
|
|
67
|
-
|
|
68
|
-
@classmethod
|
|
69
|
-
def assistant(cls, *content_items: Union[str, Path, bytes, dict, MCPContentType, PromptMessage, PromptMessageMultipart]) -> PromptMessageMultipart:
|
|
70
|
-
"""
|
|
71
|
-
Create an assistant PromptMessageMultipart with various content items.
|
|
72
|
-
|
|
73
|
-
Args:
|
|
74
|
-
*content_items: Content items in various formats:
|
|
75
|
-
- Strings: Converted to TextContent
|
|
76
|
-
- Path objects: Converted based on file type (image/text/binary)
|
|
77
|
-
- Bytes: Treated as image data
|
|
78
|
-
- Dicts with role/content: Content extracted
|
|
79
|
-
- TextContent: Used directly
|
|
80
|
-
- ImageContent: Used directly
|
|
81
|
-
- EmbeddedResource: Used directly
|
|
82
|
-
- PromptMessage: Content extracted
|
|
83
|
-
- PromptMessageMultipart: Content extracted with role changed to assistant
|
|
84
|
-
|
|
85
|
-
Returns:
|
|
86
|
-
A PromptMessageMultipart with assistant role and the specified content
|
|
87
|
-
"""
|
|
88
|
-
# Handle PromptMessage and PromptMessageMultipart directly
|
|
89
|
-
if len(content_items) == 1:
|
|
90
|
-
item = content_items[0]
|
|
91
|
-
if isinstance(item, PromptMessage):
|
|
92
|
-
return PromptMessageMultipart(role="assistant", content=[item.content])
|
|
93
|
-
elif isinstance(item, PromptMessageMultipart):
|
|
94
|
-
# Keep the content but change role to assistant
|
|
95
|
-
return PromptMessageMultipart(role="assistant", content=item.content)
|
|
96
|
-
|
|
97
|
-
# Use the original implementation for other types
|
|
98
|
-
messages = Assistant(*content_items)
|
|
99
|
-
return PromptMessageMultipart(
|
|
100
|
-
role="assistant", content=[msg["content"] for msg in messages]
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
@classmethod
|
|
104
|
-
def message(
|
|
105
|
-
cls, *content_items: Union[str, Path, bytes, dict, MCPContentType, PromptMessage, PromptMessageMultipart],
|
|
106
|
-
role: Literal["user", "assistant"] = "user"
|
|
107
|
-
) -> PromptMessageMultipart:
|
|
108
|
-
"""
|
|
109
|
-
Create a PromptMessageMultipart with the specified role and content items.
|
|
110
|
-
|
|
111
|
-
Args:
|
|
112
|
-
*content_items: Content items in various formats:
|
|
113
|
-
- Strings: Converted to TextContent
|
|
114
|
-
- Path objects: Converted based on file type (image/text/binary)
|
|
115
|
-
- Bytes: Treated as image data
|
|
116
|
-
- Dicts with role/content: Content extracted
|
|
117
|
-
- TextContent: Used directly
|
|
118
|
-
- ImageContent: Used directly
|
|
119
|
-
- EmbeddedResource: Used directly
|
|
120
|
-
- PromptMessage: Content extracted
|
|
121
|
-
- PromptMessageMultipart: Content extracted with role changed as specified
|
|
122
|
-
role: Role for the message (user or assistant)
|
|
123
|
-
|
|
124
|
-
Returns:
|
|
125
|
-
A PromptMessageMultipart with the specified role and content
|
|
126
|
-
"""
|
|
127
|
-
# Handle PromptMessage and PromptMessageMultipart directly
|
|
128
|
-
if len(content_items) == 1:
|
|
129
|
-
item = content_items[0]
|
|
130
|
-
if isinstance(item, PromptMessage):
|
|
131
|
-
return PromptMessageMultipart(role=role, content=[item.content])
|
|
132
|
-
elif isinstance(item, PromptMessageMultipart):
|
|
133
|
-
# Keep the content but change role as specified
|
|
134
|
-
return PromptMessageMultipart(role=role, content=item.content)
|
|
135
|
-
|
|
136
|
-
# Use the original implementation for other types
|
|
137
|
-
messages = MCPPrompt(*content_items, role=role)
|
|
138
|
-
return PromptMessageMultipart(
|
|
139
|
-
role=messages[0]["role"] if messages else role,
|
|
140
|
-
content=[msg["content"] for msg in messages],
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
@classmethod
|
|
144
|
-
def conversation(cls, *messages) -> List[PromptMessage]:
|
|
145
|
-
"""
|
|
146
|
-
Create a list of PromptMessages from various inputs.
|
|
147
|
-
|
|
148
|
-
This method accepts:
|
|
149
|
-
- PromptMessageMultipart instances
|
|
150
|
-
- Dictionaries with role and content
|
|
151
|
-
- Lists of dictionaries with role and content
|
|
152
|
-
|
|
153
|
-
Args:
|
|
154
|
-
*messages: Messages to include in the conversation
|
|
155
|
-
|
|
156
|
-
Returns:
|
|
157
|
-
A list of PromptMessage objects for the conversation
|
|
158
|
-
"""
|
|
159
|
-
result = []
|
|
160
|
-
|
|
161
|
-
for item in messages:
|
|
162
|
-
if isinstance(item, PromptMessageMultipart):
|
|
163
|
-
# Convert PromptMessageMultipart to a list of PromptMessages
|
|
164
|
-
result.extend(item.from_multipart())
|
|
165
|
-
elif isinstance(item, dict) and "role" in item and "content" in item:
|
|
166
|
-
# Convert a single message dict to PromptMessage
|
|
167
|
-
result.append(PromptMessage(**item))
|
|
168
|
-
elif isinstance(item, list):
|
|
169
|
-
# Process each item in the list
|
|
170
|
-
for msg in item:
|
|
171
|
-
if isinstance(msg, dict) and "role" in msg and "content" in msg:
|
|
172
|
-
result.append(PromptMessage(**msg))
|
|
173
|
-
# Ignore other types
|
|
174
|
-
|
|
175
|
-
return result
|
|
176
|
-
|
|
177
|
-
@classmethod
|
|
178
|
-
def from_multipart(cls, multipart: List[PromptMessageMultipart]) -> List[PromptMessage]:
|
|
179
|
-
"""
|
|
180
|
-
Convert a list of PromptMessageMultipart objects to PromptMessages.
|
|
181
|
-
|
|
182
|
-
Args:
|
|
183
|
-
multipart: List of PromptMessageMultipart objects
|
|
184
|
-
|
|
185
|
-
Returns:
|
|
186
|
-
A flat list of PromptMessage objects
|
|
187
|
-
"""
|
|
188
|
-
result = []
|
|
189
|
-
for mp in multipart:
|
|
190
|
-
result.extend(mp.from_multipart())
|
|
191
|
-
return result
|
mcp_agent/event_progress.py
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
"""Module for converting log events to progress events."""
|
|
2
|
-
|
|
3
|
-
from enum import Enum
|
|
4
|
-
from typing import Optional
|
|
5
|
-
|
|
6
|
-
from pydantic import BaseModel
|
|
7
|
-
|
|
8
|
-
from mcp_agent.logging.events import Event
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class ProgressAction(str, Enum):
|
|
12
|
-
"""Progress actions available in the system."""
|
|
13
|
-
|
|
14
|
-
STARTING = "Starting"
|
|
15
|
-
LOADED = "Loaded"
|
|
16
|
-
INITIALIZED = "Initialized"
|
|
17
|
-
CHATTING = "Chatting"
|
|
18
|
-
STREAMING = "Streaming" # Special action for real-time streaming updates
|
|
19
|
-
ROUTING = "Routing"
|
|
20
|
-
PLANNING = "Planning"
|
|
21
|
-
READY = "Ready"
|
|
22
|
-
CALLING_TOOL = "Calling Tool"
|
|
23
|
-
TOOL_PROGRESS = "Tool Progress"
|
|
24
|
-
UPDATED = "Updated"
|
|
25
|
-
FINISHED = "Finished"
|
|
26
|
-
SHUTDOWN = "Shutdown"
|
|
27
|
-
AGGREGATOR_INITIALIZED = "Running"
|
|
28
|
-
SERVER_OFFLINE = "Offline"
|
|
29
|
-
SERVER_RECONNECTING = "Reconnecting"
|
|
30
|
-
SERVER_ONLINE = "Online"
|
|
31
|
-
FATAL_ERROR = "Error"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class ProgressEvent(BaseModel):
|
|
35
|
-
"""Represents a progress event converted from a log event."""
|
|
36
|
-
|
|
37
|
-
action: ProgressAction
|
|
38
|
-
target: str
|
|
39
|
-
details: Optional[str] = None
|
|
40
|
-
agent_name: Optional[str] = None
|
|
41
|
-
streaming_tokens: Optional[str] = None # Special field for streaming token count
|
|
42
|
-
progress: Optional[float] = None # Current progress value
|
|
43
|
-
total: Optional[float] = None # Total value for progress calculation
|
|
44
|
-
|
|
45
|
-
def __str__(self) -> str:
|
|
46
|
-
"""Format the progress event for display."""
|
|
47
|
-
# Special handling for streaming - show token count in action position
|
|
48
|
-
if self.action == ProgressAction.STREAMING and self.streaming_tokens:
|
|
49
|
-
# For streaming, show just the token count instead of "Streaming"
|
|
50
|
-
action_display = self.streaming_tokens.ljust(11)
|
|
51
|
-
base = f"{action_display}. {self.target}"
|
|
52
|
-
if self.details:
|
|
53
|
-
base += f" - {self.details}"
|
|
54
|
-
else:
|
|
55
|
-
base = f"{self.action.ljust(11)}. {self.target}"
|
|
56
|
-
if self.details:
|
|
57
|
-
base += f" - {self.details}"
|
|
58
|
-
|
|
59
|
-
if self.agent_name:
|
|
60
|
-
base = f"[{self.agent_name}] {base}"
|
|
61
|
-
return base
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def convert_log_event(event: Event) -> Optional[ProgressEvent]:
|
|
65
|
-
"""Convert a log event to a progress event if applicable."""
|
|
66
|
-
|
|
67
|
-
# Check to see if there is any additional data
|
|
68
|
-
if not event.data:
|
|
69
|
-
return None
|
|
70
|
-
|
|
71
|
-
event_data = event.data.get("data")
|
|
72
|
-
if not isinstance(event_data, dict):
|
|
73
|
-
return None
|
|
74
|
-
|
|
75
|
-
progress_action = event_data.get("progress_action")
|
|
76
|
-
if not progress_action:
|
|
77
|
-
return None
|
|
78
|
-
|
|
79
|
-
# Build target string based on the event type.
|
|
80
|
-
# Progress display is currently [time] [event] --- [target] [details]
|
|
81
|
-
namespace = event.namespace
|
|
82
|
-
agent_name = event_data.get("agent_name")
|
|
83
|
-
target = agent_name
|
|
84
|
-
details = ""
|
|
85
|
-
if progress_action == ProgressAction.FATAL_ERROR:
|
|
86
|
-
details = event_data.get("error_message", "An error occurred")
|
|
87
|
-
elif "mcp_aggregator" in namespace:
|
|
88
|
-
server_name = event_data.get("server_name", "")
|
|
89
|
-
tool_name = event_data.get("tool_name")
|
|
90
|
-
if tool_name:
|
|
91
|
-
# fetch(fetch)
|
|
92
|
-
details = f"{server_name} ({tool_name})"
|
|
93
|
-
else:
|
|
94
|
-
details = f"{server_name}"
|
|
95
|
-
|
|
96
|
-
# For TOOL_PROGRESS, use progress message if available, otherwise keep default
|
|
97
|
-
if progress_action == ProgressAction.TOOL_PROGRESS:
|
|
98
|
-
progress_message = event_data.get("details", "")
|
|
99
|
-
if progress_message: # Only override if message is non-empty
|
|
100
|
-
details = progress_message
|
|
101
|
-
|
|
102
|
-
elif "augmented_llm" in namespace:
|
|
103
|
-
model = event_data.get("model", "")
|
|
104
|
-
|
|
105
|
-
# For all augmented_llm events, put model info in details column
|
|
106
|
-
details = f"{model}"
|
|
107
|
-
chat_turn = event_data.get("chat_turn")
|
|
108
|
-
if chat_turn is not None:
|
|
109
|
-
details = f"{model} turn {chat_turn}"
|
|
110
|
-
else:
|
|
111
|
-
if not target:
|
|
112
|
-
target = event_data.get("target", "unknown")
|
|
113
|
-
|
|
114
|
-
# Extract streaming token count for STREAMING actions
|
|
115
|
-
streaming_tokens = None
|
|
116
|
-
if progress_action == ProgressAction.STREAMING:
|
|
117
|
-
streaming_tokens = event_data.get("details", "")
|
|
118
|
-
|
|
119
|
-
# Extract progress data for TOOL_PROGRESS actions
|
|
120
|
-
progress = None
|
|
121
|
-
total = None
|
|
122
|
-
if progress_action == ProgressAction.TOOL_PROGRESS:
|
|
123
|
-
progress = event_data.get("progress")
|
|
124
|
-
total = event_data.get("total")
|
|
125
|
-
|
|
126
|
-
return ProgressEvent(
|
|
127
|
-
action=ProgressAction(progress_action),
|
|
128
|
-
target=target or "unknown",
|
|
129
|
-
details=details,
|
|
130
|
-
agent_name=event_data.get("agent_name"),
|
|
131
|
-
streaming_tokens=streaming_tokens,
|
|
132
|
-
progress=progress,
|
|
133
|
-
total=total,
|
|
134
|
-
)
|
mcp_agent/human_input/handler.py
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
|
|
3
|
-
from rich.panel import Panel
|
|
4
|
-
|
|
5
|
-
from mcp_agent.console import console
|
|
6
|
-
from mcp_agent.core.enhanced_prompt import get_enhanced_input, handle_special_commands
|
|
7
|
-
from mcp_agent.human_input.types import (
|
|
8
|
-
HumanInputRequest,
|
|
9
|
-
HumanInputResponse,
|
|
10
|
-
)
|
|
11
|
-
from mcp_agent.progress_display import progress_display
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
async def console_input_callback(request: HumanInputRequest) -> HumanInputResponse:
|
|
15
|
-
"""Request input from a human user via console using prompt_toolkit."""
|
|
16
|
-
|
|
17
|
-
# Prepare the prompt text
|
|
18
|
-
prompt_text = request.prompt
|
|
19
|
-
if request.description:
|
|
20
|
-
prompt_text = f"[bold]{request.description}[/bold]\n\n{request.prompt}"
|
|
21
|
-
|
|
22
|
-
# Create a panel with the prompt
|
|
23
|
-
panel = Panel(
|
|
24
|
-
prompt_text,
|
|
25
|
-
title="[HUMAN INPUT REQUESTED]",
|
|
26
|
-
title_align="left",
|
|
27
|
-
style="green",
|
|
28
|
-
border_style="bold white",
|
|
29
|
-
padding=(1, 2),
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
# Extract agent name from metadata dictionary
|
|
33
|
-
agent_name = (
|
|
34
|
-
request.metadata.get("agent_name", "Unknown Agent") if request.metadata else "Unknown Agent"
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
# Use the context manager to pause the progress display while getting input
|
|
38
|
-
with progress_display.paused():
|
|
39
|
-
console.print(panel)
|
|
40
|
-
|
|
41
|
-
try:
|
|
42
|
-
if request.timeout_seconds:
|
|
43
|
-
try:
|
|
44
|
-
# Use get_enhanced_input with empty agent list to disable agent switching
|
|
45
|
-
response = await asyncio.wait_for(
|
|
46
|
-
get_enhanced_input(
|
|
47
|
-
agent_name=agent_name,
|
|
48
|
-
available_agent_names=[], # No agents for selection
|
|
49
|
-
show_stop_hint=False,
|
|
50
|
-
is_human_input=True,
|
|
51
|
-
toolbar_color="ansimagenta",
|
|
52
|
-
),
|
|
53
|
-
request.timeout_seconds,
|
|
54
|
-
)
|
|
55
|
-
except asyncio.TimeoutError:
|
|
56
|
-
console.print("\n[red]Timeout waiting for input[/red]")
|
|
57
|
-
raise TimeoutError("No response received within timeout period")
|
|
58
|
-
else:
|
|
59
|
-
response = await get_enhanced_input(
|
|
60
|
-
agent_name=agent_name,
|
|
61
|
-
available_agent_names=[], # No agents for selection
|
|
62
|
-
show_stop_hint=False,
|
|
63
|
-
is_human_input=True,
|
|
64
|
-
toolbar_color="ansimagenta",
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
# Handle special commands but ignore dictionary results as they require app context
|
|
68
|
-
command_result = await handle_special_commands(response)
|
|
69
|
-
if isinstance(command_result, dict) and "list_prompts" in command_result:
|
|
70
|
-
from rich import print as rich_print
|
|
71
|
-
|
|
72
|
-
rich_print("[yellow]Prompt listing not available in human input context[/yellow]")
|
|
73
|
-
|
|
74
|
-
except KeyboardInterrupt:
|
|
75
|
-
console.print("\n[yellow]Input interrupted[/yellow]")
|
|
76
|
-
response = ""
|
|
77
|
-
except EOFError:
|
|
78
|
-
console.print("\n[yellow]Input terminated[/yellow]")
|
|
79
|
-
response = ""
|
|
80
|
-
|
|
81
|
-
return HumanInputResponse(request_id=request.request_id, response=response.strip())
|
mcp_agent/llm/__init__.py
DELETED