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

@@ -1,5 +1,6 @@
1
1
  """Simplified, robust elicitation form dialog."""
2
2
 
3
+ import re
3
4
  from datetime import date, datetime
4
5
  from typing import Any, Dict, Optional
5
6
 
@@ -63,9 +64,15 @@ class SimpleNumberValidator(Validator):
63
64
  class SimpleStringValidator(Validator):
64
65
  """Simple string validator with real-time feedback."""
65
66
 
66
- def __init__(self, min_length: Optional[int] = None, max_length: Optional[int] = None):
67
+ def __init__(
68
+ self,
69
+ min_length: Optional[int] = None,
70
+ max_length: Optional[int] = None,
71
+ pattern: Optional[str] = None
72
+ ):
67
73
  self.min_length = min_length
68
74
  self.max_length = max_length
75
+ self.pattern = re.compile(pattern, re.DOTALL) if pattern else None
69
76
 
70
77
  def validate(self, document):
71
78
  text = document.text
@@ -83,6 +90,12 @@ class SimpleStringValidator(Validator):
83
90
  cursor_position=self.max_length,
84
91
  )
85
92
 
93
+ if self.pattern is not None and self.pattern.fullmatch(text) is None:
94
+ # TODO: Wrap or truncate line if too long
95
+ raise ValidationError(
96
+ message=f"Must match pattern '{self.pattern.pattern}'", cursor_position=len(text)
97
+ )
98
+
86
99
 
87
100
  class FormatValidator(Validator):
88
101
  """Format-specific validator using Pydantic validators."""
@@ -429,6 +442,8 @@ class ElicitationForm:
429
442
  constraints["minLength"] = field_def["minLength"]
430
443
  if field_def.get("maxLength") is not None:
431
444
  constraints["maxLength"] = field_def["maxLength"]
445
+ if field_def.get("pattern") is not None:
446
+ constraints["pattern"] = field_def["pattern"]
432
447
 
433
448
  # Check anyOf constraints (for Optional fields)
434
449
  if "anyOf" in field_def:
@@ -438,6 +453,8 @@ class ElicitationForm:
438
453
  constraints["minLength"] = variant["minLength"]
439
454
  if variant.get("maxLength") is not None:
440
455
  constraints["maxLength"] = variant["maxLength"]
456
+ if variant.get("pattern") is not None:
457
+ constraints["pattern"] = variant["pattern"]
441
458
  break
442
459
 
443
460
  return constraints
@@ -468,6 +485,10 @@ class ElicitationForm:
468
485
  if constraints.get("maxLength"):
469
486
  hints.append(f"max {constraints['maxLength']} chars")
470
487
 
488
+ if constraints.get("pattern"):
489
+ # TODO: Wrap or truncate line if too long
490
+ format_hint = f"Pattern: {constraints['pattern']}"
491
+
471
492
  # Handle format hints separately (these go on next line)
472
493
  format_type = field_def.get("format")
473
494
  if format_type:
@@ -545,6 +566,7 @@ class ElicitationForm:
545
566
  validator = SimpleStringValidator(
546
567
  min_length=constraints.get("minLength"),
547
568
  max_length=constraints.get("maxLength"),
569
+ pattern=constraints.get("pattern"),
548
570
  )
549
571
  else:
550
572
  constraints = {}
@@ -684,20 +684,26 @@ async def get_enhanced_input(
684
684
  if llm:
685
685
  model_name = getattr(llm, "model_name", None)
686
686
  if not model_name:
687
- model_name = getattr(getattr(llm, "default_request_params", None), "model", None)
687
+ model_name = getattr(
688
+ getattr(llm, "default_request_params", None), "model", None
689
+ )
688
690
 
689
691
  if not model_name:
690
692
  model_name = getattr(agent.config, "model", None)
691
693
  if not model_name and getattr(agent.config, "default_request_params", None):
692
694
  model_name = getattr(agent.config.default_request_params, "model", None)
693
695
  if not model_name:
694
- context = getattr(agent, "context", None) or getattr(agent_provider, "context", None)
696
+ context = getattr(agent, "context", None) or getattr(
697
+ agent_provider, "context", None
698
+ )
695
699
  config_obj = getattr(context, "config", None) if context else None
696
700
  model_name = getattr(config_obj, "default_model", None)
697
701
 
698
702
  if model_name:
699
703
  max_len = 25
700
- model_display = model_name[: max_len - 1] + "…" if len(model_name) > max_len else model_name
704
+ model_display = (
705
+ model_name[: max_len - 1] + "…" if len(model_name) > max_len else model_name
706
+ )
701
707
  else:
702
708
  print(f"[toolbar debug] no model resolved for agent '{agent_name}'")
703
709
  model_display = "unknown"
@@ -876,6 +882,46 @@ async def get_enhanced_input(
876
882
  # Display info for all available agents with tree structure for workflows
877
883
  await _display_all_agents_with_hierarchy(available_agents, agent_provider)
878
884
 
885
+ # Show streaming status message
886
+ if agent_provider:
887
+ # Get logger settings from the agent's context (not agent_provider)
888
+ logger_settings = None
889
+ try:
890
+ agent = agent_provider._agent(agent_name)
891
+ agent_context = agent._context or agent.context
892
+ logger_settings = agent_context.config.logger
893
+ except Exception:
894
+ # If we can't get the agent or its context, logger_settings stays None
895
+ pass
896
+
897
+ # Only show streaming messages if chat display is enabled AND we have logger_settings
898
+ if logger_settings:
899
+ show_chat = getattr(logger_settings, "show_chat", True)
900
+
901
+ if show_chat:
902
+ # Check for parallel agents
903
+ has_parallel = any(
904
+ agent.agent_type == AgentType.PARALLEL
905
+ for agent in agent_provider._agents.values()
906
+ )
907
+
908
+ # Note: streaming may have been disabled by fastagent.py if parallel agents exist
909
+ # So we check has_parallel first to show the appropriate message
910
+ if has_parallel:
911
+ # Streaming is disabled due to parallel agents
912
+ rich_print(
913
+ "[dim]Markdown Streaming disabled (Parallel Agents configured)[/dim]"
914
+ )
915
+ else:
916
+ # Check if streaming is enabled
917
+ streaming_enabled = getattr(logger_settings, "streaming_display", True)
918
+ streaming_mode = getattr(logger_settings, "streaming", "markdown")
919
+ if streaming_enabled and streaming_mode != "none":
920
+ # Streaming is enabled - notify users since it's experimental
921
+ rich_print(
922
+ f"[dim]Experimental: Streaming Enabled - {streaming_mode} mode[/dim]"
923
+ )
924
+
879
925
  rich_print()
880
926
  help_message_shown = True
881
927