fast-agent-mcp 0.3.2__py3-none-any.whl → 0.3.4__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.

Files changed (49) hide show
  1. fast_agent/__init__.py +6 -3
  2. fast_agent/agents/__init__.py +63 -14
  3. fast_agent/agents/llm_decorator.py +2 -1
  4. fast_agent/agents/tool_agent.py +4 -1
  5. fast_agent/agents/workflow/orchestrator_models.py +1 -1
  6. fast_agent/cli/commands/go.py +1 -1
  7. fast_agent/cli/commands/url_parser.py +3 -3
  8. fast_agent/cli/main.py +7 -1
  9. fast_agent/config.py +6 -0
  10. fast_agent/core/__init__.py +65 -25
  11. fast_agent/core/direct_decorators.py +85 -103
  12. fast_agent/core/direct_factory.py +1 -1
  13. fast_agent/core/error_handling.py +1 -1
  14. fast_agent/core/fastagent.py +153 -34
  15. fast_agent/core/logging/events.py +4 -9
  16. fast_agent/llm/prompt_utils.py +10 -4
  17. fast_agent/llm/provider/anthropic/llm_anthropic.py +16 -5
  18. fast_agent/llm/provider/bedrock/llm_bedrock.py +13 -5
  19. fast_agent/llm/provider/google/llm_google_native.py +13 -2
  20. fast_agent/llm/provider/openai/llm_openai.py +22 -13
  21. fast_agent/mcp/ui_agent.py +1 -1
  22. fast_agent/resources/examples/data-analysis/analysis-campaign.py +1 -1
  23. fast_agent/resources/examples/data-analysis/analysis.py +1 -1
  24. fast_agent/resources/examples/mcp/elicitations/forms_demo.py +1 -1
  25. fast_agent/resources/examples/mcp/elicitations/game_character.py +1 -1
  26. fast_agent/resources/examples/mcp/elicitations/tool_call.py +1 -1
  27. fast_agent/resources/examples/mcp/state-transfer/agent_one.py +1 -1
  28. fast_agent/resources/examples/mcp/state-transfer/agent_two.py +1 -1
  29. fast_agent/resources/examples/researcher/researcher-eval.py +1 -1
  30. fast_agent/resources/examples/researcher/researcher-imp.py +1 -1
  31. fast_agent/resources/examples/researcher/researcher.py +1 -1
  32. fast_agent/resources/examples/tensorzero/agent.py +1 -1
  33. fast_agent/resources/examples/tensorzero/image_demo.py +1 -1
  34. fast_agent/resources/examples/tensorzero/simple_agent.py +1 -1
  35. fast_agent/resources/examples/workflows/chaining.py +1 -1
  36. fast_agent/resources/examples/workflows/evaluator.py +1 -1
  37. fast_agent/resources/examples/workflows/human_input.py +1 -1
  38. fast_agent/resources/examples/workflows/orchestrator.py +1 -1
  39. fast_agent/resources/examples/workflows/parallel.py +1 -1
  40. fast_agent/resources/examples/workflows/router.py +1 -1
  41. fast_agent/resources/setup/agent.py +1 -1
  42. fast_agent/resources/setup/fastagent.config.yaml +1 -0
  43. fast_agent/ui/mcp_ui_utils.py +12 -1
  44. fast_agent/ui/rich_progress.py +8 -6
  45. {fast_agent_mcp-0.3.2.dist-info → fast_agent_mcp-0.3.4.dist-info}/METADATA +2 -2
  46. {fast_agent_mcp-0.3.2.dist-info → fast_agent_mcp-0.3.4.dist-info}/RECORD +49 -49
  47. {fast_agent_mcp-0.3.2.dist-info → fast_agent_mcp-0.3.4.dist-info}/WHEEL +0 -0
  48. {fast_agent_mcp-0.3.2.dist-info → fast_agent_mcp-0.3.4.dist-info}/entry_points.txt +0 -0
  49. {fast_agent_mcp-0.3.2.dist-info → fast_agent_mcp-0.3.4.dist-info}/licenses/LICENSE +0 -0
fast_agent/__init__.py CHANGED
@@ -1,5 +1,6 @@
1
1
  """fast-agent - An MCP native agent application framework"""
2
- from typing import TYPE_CHECKING as _TYPE_CHECKING
2
+
3
+ from typing import TYPE_CHECKING
3
4
 
4
5
  # Configuration and settings (safe - pure Pydantic models)
5
6
  from fast_agent.config import (
@@ -73,10 +74,12 @@ def __getattr__(name: str):
73
74
 
74
75
  return ToolAgent
75
76
  elif name == "McpAgent":
77
+ # Import directly from submodule to avoid package re-import cycles
76
78
  from fast_agent.agents.mcp_agent import McpAgent
77
79
 
78
80
  return McpAgent
79
81
  elif name == "FastAgent":
82
+ # Import from the canonical implementation to avoid recursive imports
80
83
  from fast_agent.core.fastagent import FastAgent
81
84
 
82
85
  return FastAgent
@@ -85,7 +88,8 @@ def __getattr__(name: str):
85
88
 
86
89
 
87
90
  # Help static analyzers/IDEs resolve symbols and signatures without importing at runtime.
88
- if _TYPE_CHECKING: # pragma: no cover - typing aid only
91
+ if TYPE_CHECKING: # pragma: no cover - typing aid only
92
+ # Provide a concrete import path for type checkers/IDEs
89
93
  from fast_agent.core.fastagent import FastAgent as FastAgent # noqa: F401
90
94
 
91
95
 
@@ -124,7 +128,6 @@ __all__ = [
124
128
  "LlmStopReason",
125
129
  "RequestParams",
126
130
  # Agents (lazy loaded)
127
- "ToolAgentSynchronous",
128
131
  "LlmAgent",
129
132
  "LlmDecorator",
130
133
  "ToolAgent",
@@ -1,23 +1,72 @@
1
1
  """
2
2
  Fast Agent - Agent implementations and workflow patterns.
3
3
 
4
- This module exports all agent classes from the fast_agent.agents package,
5
- providing a single import point for both core agents and workflow agents.
4
+ This module re-exports agent classes with lazy imports to avoid circular
5
+ dependencies during package initialization while preserving a clean API:
6
+
7
+ from fast_agent.agents import McpAgent, ToolAgent, LlmAgent
6
8
  """
7
9
 
8
- # Core agents
10
+ from typing import TYPE_CHECKING
11
+
9
12
  from fast_agent.agents.agent_types import AgentConfig
10
- from fast_agent.agents.llm_agent import LlmAgent
11
- from fast_agent.agents.llm_decorator import LlmDecorator
12
- from fast_agent.agents.mcp_agent import McpAgent
13
- from fast_agent.agents.tool_agent import ToolAgent
14
-
15
- # Workflow agents
16
- from fast_agent.agents.workflow.chain_agent import ChainAgent
17
- from fast_agent.agents.workflow.evaluator_optimizer import EvaluatorOptimizerAgent
18
- from fast_agent.agents.workflow.iterative_planner import IterativePlanner
19
- from fast_agent.agents.workflow.parallel_agent import ParallelAgent
20
- from fast_agent.agents.workflow.router_agent import RouterAgent
13
+
14
+
15
+ def __getattr__(name: str):
16
+ """Lazily resolve agent classes to avoid import cycles."""
17
+ if name == "LlmAgent":
18
+ from .llm_agent import LlmAgent
19
+
20
+ return LlmAgent
21
+ elif name == "LlmDecorator":
22
+ from .llm_decorator import LlmDecorator
23
+
24
+ return LlmDecorator
25
+ elif name == "ToolAgent":
26
+ from .tool_agent import ToolAgent
27
+
28
+ return ToolAgent
29
+ elif name == "McpAgent":
30
+ from .mcp_agent import McpAgent
31
+
32
+ return McpAgent
33
+ elif name == "ChainAgent":
34
+ from .workflow.chain_agent import ChainAgent
35
+
36
+ return ChainAgent
37
+ elif name == "EvaluatorOptimizerAgent":
38
+ from .workflow.evaluator_optimizer import EvaluatorOptimizerAgent
39
+
40
+ return EvaluatorOptimizerAgent
41
+ elif name == "IterativePlanner":
42
+ from .workflow.iterative_planner import IterativePlanner
43
+
44
+ return IterativePlanner
45
+ elif name == "ParallelAgent":
46
+ from .workflow.parallel_agent import ParallelAgent
47
+
48
+ return ParallelAgent
49
+ elif name == "RouterAgent":
50
+ from .workflow.router_agent import RouterAgent
51
+
52
+ return RouterAgent
53
+ else:
54
+ raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
55
+
56
+
57
+ if TYPE_CHECKING: # pragma: no cover - type checking only
58
+ from .llm_agent import LlmAgent as LlmAgent # noqa: F401
59
+ from .llm_decorator import LlmDecorator as LlmDecorator # noqa: F401
60
+ from .mcp_agent import McpAgent as McpAgent # noqa: F401
61
+ from .tool_agent import ToolAgent as ToolAgent # noqa: F401
62
+ from .workflow.chain_agent import ChainAgent as ChainAgent # noqa: F401
63
+ from .workflow.evaluator_optimizer import (
64
+ EvaluatorOptimizerAgent as EvaluatorOptimizerAgent,
65
+ ) # noqa: F401
66
+ from .workflow.iterative_planner import IterativePlanner as IterativePlanner # noqa: F401
67
+ from .workflow.parallel_agent import ParallelAgent as ParallelAgent # noqa: F401
68
+ from .workflow.router_agent import RouterAgent as RouterAgent # noqa: F401
69
+
21
70
 
22
71
  __all__ = [
23
72
  # Core agents
@@ -189,6 +189,7 @@ class LlmDecorator(AgentProtocol):
189
189
  Sequence[Union[str, PromptMessage, PromptMessageExtended]],
190
190
  ],
191
191
  request_params: RequestParams | None = None,
192
+ tools: List[Tool] | None = None,
192
193
  ) -> PromptMessageExtended:
193
194
  """
194
195
  Create a completion with the LLM using the provided messages.
@@ -212,7 +213,7 @@ class LlmDecorator(AgentProtocol):
212
213
  multipart_messages = normalize_to_extended_list(messages)
213
214
 
214
215
  with self._tracer.start_as_current_span(f"Agent: '{self._name}' generate"):
215
- return await self.generate_impl(multipart_messages, request_params, None)
216
+ return await self.generate_impl(multipart_messages, request_params, tools)
216
217
 
217
218
  async def generate_impl(
218
219
  self,
@@ -97,7 +97,10 @@ class ToolAgent(LlmAgent):
97
97
  )
98
98
 
99
99
  if LlmStopReason.TOOL_USE == result.stop_reason:
100
- messages = [await self.run_tools(result)]
100
+ if self.config.use_history:
101
+ messages = [await self.run_tools(result)]
102
+ else:
103
+ messages.extend([result, await self.run_tools(result)])
101
104
  else:
102
105
  break
103
106
 
@@ -72,7 +72,7 @@ class TaskWithResult(Task):
72
72
  class StepResult(BaseModel):
73
73
  """Result of executing a step"""
74
74
 
75
- step: Step = Field(description="The step that was executed", default_factory=Step)
75
+ step: Step = Field(description="The step that was executed")
76
76
  task_results: List[TaskWithResult] = Field(
77
77
  description="Results of executing each task", default_factory=list
78
78
  )
@@ -7,10 +7,10 @@ from typing import Dict, List, Optional
7
7
 
8
8
  import typer
9
9
 
10
+ from fast_agent import FastAgent
10
11
  from fast_agent.agents.llm_agent import LlmAgent
11
12
  from fast_agent.cli.commands.server_helpers import add_servers_to_config, generate_server_name
12
13
  from fast_agent.cli.commands.url_parser import generate_server_configs, parse_server_urls
13
- from fast_agent.core.fastagent import FastAgent
14
14
  from fast_agent.ui.console_display import ConsoleDisplay
15
15
 
16
16
  app = typer.Typer(
@@ -104,7 +104,7 @@ def generate_server_name(url: str) -> str:
104
104
 
105
105
 
106
106
  def parse_server_urls(
107
- urls_param: str, auth_token: str = None
107
+ urls_param: str, auth_token: str | None = None
108
108
  ) -> List[Tuple[str, Literal["http", "sse"], str, Dict[str, str] | None]]:
109
109
  """
110
110
  Parse a comma-separated list of URLs into server configurations.
@@ -155,7 +155,7 @@ def generate_server_configs(
155
155
  Returns:
156
156
  Dictionary of server configurations
157
157
  """
158
- server_configs = {}
158
+ server_configs: Dict[str, Dict[str, str | Dict[str, str]]] = {}
159
159
  # Keep track of server name occurrences to handle collisions
160
160
  name_counts = {}
161
161
 
@@ -178,7 +178,7 @@ def generate_server_configs(
178
178
  final_name = f"{server_name}_{suffix}"
179
179
  name_counts[server_name] += 1
180
180
 
181
- config = {
181
+ config: Dict[str, str | Dict[str, str]] = {
182
182
  "transport": transport_type,
183
183
  "url": url,
184
184
  }
fast_agent/cli/main.py CHANGED
@@ -85,7 +85,13 @@ def main(
85
85
  Use --help with any command for detailed usage information.
86
86
  """
87
87
  application.verbosity = 1 if verbose else 0 if not quiet else -1
88
- application.console = application.console if color else None
88
+ if not color:
89
+ # Recreate consoles without color when --no-color is provided
90
+ from fast_agent.ui.console import console as base_console
91
+ from fast_agent.ui.console import error_console as base_error_console
92
+
93
+ application.console = base_console.__class__(color_system=None)
94
+ application.error_console = base_error_console.__class__(color_system=None, stderr=True)
89
95
 
90
96
  # Handle version flag
91
97
  if version:
fast_agent/config.py CHANGED
@@ -470,6 +470,10 @@ class Settings(BaseSettings):
470
470
  - "auto": Extract and automatically open ui:// resources.
471
471
  """
472
472
 
473
+ # Output directory for MCP-UI generated HTML files (relative to CWD if not absolute)
474
+ mcp_ui_output_dir: str = ".fast-agent/ui"
475
+ """Directory where MCP-UI HTML files are written. Relative paths are resolved from CWD."""
476
+
473
477
  @classmethod
474
478
  def find_config(cls) -> Path | None:
475
479
  """Find the config file in the current directory or parent directories."""
@@ -547,6 +551,8 @@ def get_settings(config_path: str | None = None) -> Settings:
547
551
  return _settings
548
552
 
549
553
  # Handle config path - convert string to Path if needed
554
+ config_file: Path | None
555
+ secrets_file: Path | None
550
556
  if config_path:
551
557
  config_file = Path(config_path)
552
558
  # If it's a relative path and doesn't exist, try finding it
@@ -2,40 +2,32 @@
2
2
  Core interfaces and decorators for fast-agent.
3
3
 
4
4
  Public API:
5
- - `Core`: The core application container (lazy-loaded)
6
- - `FastAgent`: High-level, decorator-driven application class (lazy-loaded)
5
+ - `Core`: The core application container
6
+ - `AgentApp`: Container for interacting with agents
7
+ - `FastAgent`: High-level, decorator-driven application class
7
8
  - Decorators: `agent`, `custom`, `orchestrator`, `iterative_planner`,
8
- `router`, `chain`, `parallel`, `evaluator_optimizer` (lazy-loaded)
9
+ `router`, `chain`, `parallel`, `evaluator_optimizer`
10
+
11
+ Exports are resolved lazily to avoid circular imports during package init.
9
12
  """
10
13
 
11
- __all__ = [
12
- "Core",
13
- "FastAgent",
14
- # Decorators
15
- "agent",
16
- "custom",
17
- "orchestrator",
18
- "iterative_planner",
19
- "router",
20
- "chain",
21
- "parallel",
22
- "evaluator_optimizer",
23
- ]
14
+ from typing import TYPE_CHECKING
24
15
 
25
16
 
26
17
  def __getattr__(name: str):
27
- # Lazy imports to avoid heavy dependencies and circular imports at init time
28
- if name == "Core":
18
+ if name == "AgentApp":
19
+ from .agent_app import AgentApp
20
+
21
+ return AgentApp
22
+ elif name == "Core":
29
23
  from .core_app import Core
30
24
 
31
25
  return Core
32
- if name == "FastAgent":
26
+ elif name == "FastAgent":
33
27
  from .fastagent import FastAgent
34
28
 
35
29
  return FastAgent
36
-
37
- # Decorators from direct_decorators
38
- if name in {
30
+ elif name in (
39
31
  "agent",
40
32
  "custom",
41
33
  "orchestrator",
@@ -44,9 +36,57 @@ def __getattr__(name: str):
44
36
  "chain",
45
37
  "parallel",
46
38
  "evaluator_optimizer",
47
- }:
39
+ ):
48
40
  from . import direct_decorators as _dd
49
41
 
50
- return getattr(_dd, name)
51
-
42
+ return getattr(
43
+ _dd,
44
+ name,
45
+ )
52
46
  raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
47
+
48
+
49
+ if TYPE_CHECKING: # pragma: no cover - typing aid only
50
+ from .agent_app import AgentApp as AgentApp # noqa: F401
51
+ from .core_app import Core as Core # noqa: F401
52
+ from .direct_decorators import ( # noqa: F401
53
+ agent as agent,
54
+ )
55
+ from .direct_decorators import (
56
+ chain as chain,
57
+ )
58
+ from .direct_decorators import (
59
+ custom as custom,
60
+ )
61
+ from .direct_decorators import (
62
+ evaluator_optimizer as evaluator_optimizer,
63
+ )
64
+ from .direct_decorators import (
65
+ iterative_planner as iterative_planner,
66
+ )
67
+ from .direct_decorators import (
68
+ orchestrator as orchestrator,
69
+ )
70
+ from .direct_decorators import (
71
+ parallel as parallel,
72
+ )
73
+ from .direct_decorators import (
74
+ router as router,
75
+ )
76
+ from .fastagent import FastAgent as FastAgent # noqa: F401
77
+
78
+
79
+ __all__ = [
80
+ "Core",
81
+ "AgentApp",
82
+ "FastAgent",
83
+ # Decorators
84
+ "agent",
85
+ "custom",
86
+ "orchestrator",
87
+ "iterative_planner",
88
+ "router",
89
+ "chain",
90
+ "parallel",
91
+ "evaluator_optimizer",
92
+ ]
@@ -186,7 +186,7 @@ def _decorator_impl(
186
186
  resources: Optional[Dict[str, List[str]]] = None,
187
187
  prompts: Optional[Dict[str, List[str]]] = None,
188
188
  **extra_kwargs,
189
- ) -> Callable[[AgentCallable[P, R]], DecoratedAgentProtocol[P, R]]:
189
+ ) -> Callable[[AgentCallable[P, R]], AgentCallable[P, R]]:
190
190
  """
191
191
  Core implementation for agent decorators with common behavior and type safety.
192
192
 
@@ -203,7 +203,7 @@ def _decorator_impl(
203
203
  **extra_kwargs: Additional agent/workflow-specific parameters
204
204
  """
205
205
 
206
- def decorator(func: AgentCallable[P, R]) -> DecoratedAgentProtocol[P, R]:
206
+ def decorator(func: AgentCallable[P, R]) -> AgentCallable[P, R]:
207
207
  @wraps(func)
208
208
  def wrapper(*args: P.args, **kwargs: P.kwargs) -> Awaitable[R]:
209
209
  # Call the original function
@@ -249,7 +249,7 @@ def _decorator_impl(
249
249
  for key, value in extra_kwargs.items():
250
250
  setattr(wrapper, f"_{key}", value)
251
251
 
252
- return cast("DecoratedAgentProtocol[P, R]", wrapper)
252
+ return cast("AgentCallable[P, R]", wrapper)
253
253
 
254
254
  return decorator
255
255
 
@@ -271,7 +271,7 @@ def agent(
271
271
  default: bool = False,
272
272
  elicitation_handler: Optional[ElicitationFnT] = None,
273
273
  api_key: str | None = None,
274
- ) -> Callable[[AgentCallable[P, R]], DecoratedAgentProtocol[P, R]]:
274
+ ) -> Callable[[AgentCallable[P, R]], AgentCallable[P, R]]:
275
275
  """
276
276
  Decorator to create and register a standard agent with type-safe signature.
277
277
 
@@ -336,7 +336,7 @@ def custom(
336
336
  default: bool = False,
337
337
  elicitation_handler: Optional[ElicitationFnT] = None,
338
338
  api_key: str | None = None,
339
- ) -> Callable[[AgentCallable[P, R]], DecoratedAgentProtocol[P, R]]:
339
+ ) -> Callable[[AgentCallable[P, R]], AgentCallable[P, R]]:
340
340
  """
341
341
  Decorator to create and register a standard agent with type-safe signature.
342
342
 
@@ -400,7 +400,7 @@ def orchestrator(
400
400
  plan_iterations: int = 5,
401
401
  default: bool = False,
402
402
  api_key: str | None = None,
403
- ) -> Callable[[AgentCallable[P, R]], DecoratedOrchestratorProtocol[P, R]]:
403
+ ) -> Callable[[AgentCallable[P, R]], AgentCallable[P, R]]:
404
404
  """
405
405
  Decorator to create and register an orchestrator agent with type-safe signature.
406
406
 
@@ -423,24 +423,21 @@ def orchestrator(
423
423
  # Create final request params with plan_iterations
424
424
  resolved_instruction = _resolve_instruction(instruction)
425
425
 
426
- return cast(
427
- "Callable[[AgentCallable[P, R]], DecoratedOrchestratorProtocol[P, R]]",
428
- _decorator_impl(
429
- self,
430
- AgentType.ORCHESTRATOR,
431
- name=name,
432
- instruction=resolved_instruction,
433
- servers=[], # Orchestrators don't connect to servers directly
434
- model=model,
435
- use_history=use_history,
436
- request_params=request_params,
437
- human_input=human_input,
438
- child_agents=agents,
439
- plan_type=plan_type,
440
- plan_iterations=plan_iterations,
441
- default=default,
442
- api_key=api_key,
443
- ),
426
+ return _decorator_impl(
427
+ self,
428
+ AgentType.ORCHESTRATOR,
429
+ name=name,
430
+ instruction=resolved_instruction,
431
+ servers=[], # Orchestrators don't connect to servers directly
432
+ model=model,
433
+ use_history=use_history,
434
+ request_params=request_params,
435
+ human_input=human_input,
436
+ child_agents=agents,
437
+ plan_type=plan_type,
438
+ plan_iterations=plan_iterations,
439
+ default=default,
440
+ api_key=api_key,
444
441
  )
445
442
 
446
443
 
@@ -455,7 +452,7 @@ def iterative_planner(
455
452
  plan_iterations: int = -1,
456
453
  default: bool = False,
457
454
  api_key: str | None = None,
458
- ) -> Callable[[AgentCallable[P, R]], DecoratedOrchestratorProtocol[P, R]]:
455
+ ) -> Callable[[AgentCallable[P, R]], AgentCallable[P, R]]:
459
456
  """
460
457
  Decorator to create and register an orchestrator agent with type-safe signature.
461
458
 
@@ -478,22 +475,19 @@ def iterative_planner(
478
475
  # Create final request params with plan_iterations
479
476
  resolved_instruction = _resolve_instruction(instruction)
480
477
 
481
- return cast(
482
- "Callable[[AgentCallable[P, R]], DecoratedOrchestratorProtocol[P, R]]",
483
- _decorator_impl(
484
- self,
485
- AgentType.ITERATIVE_PLANNER,
486
- name=name,
487
- instruction=resolved_instruction,
488
- servers=[], # Orchestrators don't connect to servers directly
489
- model=model,
490
- use_history=False,
491
- request_params=request_params,
492
- child_agents=agents,
493
- plan_iterations=plan_iterations,
494
- default=default,
495
- api_key=api_key,
496
- ),
478
+ return _decorator_impl(
479
+ self,
480
+ AgentType.ITERATIVE_PLANNER,
481
+ name=name,
482
+ instruction=resolved_instruction,
483
+ servers=[], # Orchestrators don't connect to servers directly
484
+ model=model,
485
+ use_history=False,
486
+ request_params=request_params,
487
+ child_agents=agents,
488
+ plan_iterations=plan_iterations,
489
+ default=default,
490
+ api_key=api_key,
497
491
  )
498
492
 
499
493
 
@@ -516,7 +510,7 @@ def router(
516
510
  ElicitationFnT
517
511
  ] = None, ## exclude from docs, decide whether allowable
518
512
  api_key: str | None = None,
519
- ) -> Callable[[AgentCallable[P, R]], DecoratedRouterProtocol[P, R]]:
513
+ ) -> Callable[[AgentCallable[P, R]], AgentCallable[P, R]]:
520
514
  """
521
515
  Decorator to create and register a router agent with type-safe signature.
522
516
 
@@ -536,26 +530,23 @@ def router(
536
530
  """
537
531
  resolved_instruction = _resolve_instruction(instruction or ROUTING_SYSTEM_INSTRUCTION)
538
532
 
539
- return cast(
540
- "Callable[[AgentCallable[P, R]], DecoratedRouterProtocol[P, R]]",
541
- _decorator_impl(
542
- self,
543
- AgentType.ROUTER,
544
- name=name,
545
- instruction=resolved_instruction,
546
- servers=servers,
547
- model=model,
548
- use_history=use_history,
549
- request_params=request_params,
550
- human_input=human_input,
551
- default=default,
552
- router_agents=agents,
553
- elicitation_handler=elicitation_handler,
554
- api_key=api_key,
555
- tools=tools,
556
- prompts=prompts,
557
- resources=resources,
558
- ),
533
+ return _decorator_impl(
534
+ self,
535
+ AgentType.ROUTER,
536
+ name=name,
537
+ instruction=resolved_instruction,
538
+ servers=servers,
539
+ model=model,
540
+ use_history=use_history,
541
+ request_params=request_params,
542
+ human_input=human_input,
543
+ default=default,
544
+ router_agents=agents,
545
+ elicitation_handler=elicitation_handler,
546
+ api_key=api_key,
547
+ tools=tools,
548
+ prompts=prompts,
549
+ resources=resources,
559
550
  )
560
551
 
561
552
 
@@ -567,7 +558,7 @@ def chain(
567
558
  instruction: Optional[str | Path | AnyUrl] = None,
568
559
  cumulative: bool = False,
569
560
  default: bool = False,
570
- ) -> Callable[[AgentCallable[P, R]], DecoratedChainProtocol[P, R]]:
561
+ ) -> Callable[[AgentCallable[P, R]], AgentCallable[P, R]]:
571
562
  """
572
563
  Decorator to create and register a chain agent with type-safe signature.
573
564
 
@@ -593,17 +584,14 @@ def chain(
593
584
  """
594
585
  resolved_instruction = _resolve_instruction(instruction or default_instruction)
595
586
 
596
- return cast(
597
- "Callable[[AgentCallable[P, R]], DecoratedChainProtocol[P, R]]",
598
- _decorator_impl(
599
- self,
600
- AgentType.CHAIN,
601
- name=name,
602
- instruction=resolved_instruction,
603
- sequence=sequence,
604
- cumulative=cumulative,
605
- default=default,
606
- ),
587
+ return _decorator_impl(
588
+ self,
589
+ AgentType.CHAIN,
590
+ name=name,
591
+ instruction=resolved_instruction,
592
+ sequence=sequence,
593
+ cumulative=cumulative,
594
+ default=default,
607
595
  )
608
596
 
609
597
 
@@ -616,7 +604,7 @@ def parallel(
616
604
  instruction: Optional[str | Path | AnyUrl] = None,
617
605
  include_request: bool = True,
618
606
  default: bool = False,
619
- ) -> Callable[[AgentCallable[P, R]], DecoratedParallelProtocol[P, R]]:
607
+ ) -> Callable[[AgentCallable[P, R]], AgentCallable[P, R]]:
620
608
  """
621
609
  Decorator to create and register a parallel agent with type-safe signature.
622
610
 
@@ -637,19 +625,16 @@ def parallel(
637
625
  """
638
626
  resolved_instruction = _resolve_instruction(instruction or default_instruction)
639
627
 
640
- return cast(
641
- "Callable[[AgentCallable[P, R]], DecoratedParallelProtocol[P, R]]",
642
- _decorator_impl(
643
- self,
644
- AgentType.PARALLEL,
645
- name=name,
646
- instruction=resolved_instruction,
647
- servers=[], # Parallel agents don't connect to servers directly
648
- fan_in=fan_in,
649
- fan_out=fan_out,
650
- include_request=include_request,
651
- default=default,
652
- ),
628
+ return _decorator_impl(
629
+ self,
630
+ AgentType.PARALLEL,
631
+ name=name,
632
+ instruction=resolved_instruction,
633
+ servers=[], # Parallel agents don't connect to servers directly
634
+ fan_in=fan_in,
635
+ fan_out=fan_out,
636
+ include_request=include_request,
637
+ default=default,
653
638
  )
654
639
 
655
640
 
@@ -663,7 +648,7 @@ def evaluator_optimizer(
663
648
  min_rating: str = "GOOD",
664
649
  max_refinements: int = 3,
665
650
  default: bool = False,
666
- ) -> Callable[[AgentCallable[P, R]], DecoratedEvaluatorOptimizerProtocol[P, R]]:
651
+ ) -> Callable[[AgentCallable[P, R]], AgentCallable[P, R]]:
667
652
  """
668
653
  Decorator to create and register an evaluator-optimizer agent with type-safe signature.
669
654
 
@@ -686,18 +671,15 @@ def evaluator_optimizer(
686
671
  """
687
672
  resolved_instruction = _resolve_instruction(instruction or default_instruction)
688
673
 
689
- return cast(
690
- "Callable[[AgentCallable[P, R]], DecoratedEvaluatorOptimizerProtocol[P, R]]",
691
- _decorator_impl(
692
- self,
693
- AgentType.EVALUATOR_OPTIMIZER,
694
- name=name,
695
- instruction=resolved_instruction,
696
- servers=[], # Evaluator-optimizer doesn't connect to servers directly
697
- generator=generator,
698
- evaluator=evaluator,
699
- min_rating=min_rating,
700
- max_refinements=max_refinements,
701
- default=default,
702
- ),
674
+ return _decorator_impl(
675
+ self,
676
+ AgentType.EVALUATOR_OPTIMIZER,
677
+ name=name,
678
+ instruction=resolved_instruction,
679
+ servers=[], # Evaluator-optimizer doesn't connect to servers directly
680
+ generator=generator,
681
+ evaluator=evaluator,
682
+ min_rating=min_rating,
683
+ max_refinements=max_refinements,
684
+ default=default,
703
685
  )
@@ -5,9 +5,9 @@ Implements type-safe factories with improved error handling.
5
5
 
6
6
  from typing import Any, Dict, Optional, Protocol, TypeVar
7
7
 
8
+ from fast_agent.agents import McpAgent
8
9
  from fast_agent.agents.agent_types import AgentConfig, AgentType
9
10
  from fast_agent.agents.llm_agent import LlmAgent
10
- from fast_agent.agents.mcp_agent import McpAgent
11
11
  from fast_agent.agents.workflow.evaluator_optimizer import (
12
12
  EvaluatorOptimizerAgent,
13
13
  QualityRating,