fast-agent-mcp 0.1.13__py3-none-any.whl → 0.2.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.
Files changed (147) hide show
  1. {fast_agent_mcp-0.1.13.dist-info → fast_agent_mcp-0.2.0.dist-info}/METADATA +3 -4
  2. fast_agent_mcp-0.2.0.dist-info/RECORD +123 -0
  3. mcp_agent/__init__.py +75 -0
  4. mcp_agent/agents/agent.py +59 -371
  5. mcp_agent/agents/base_agent.py +522 -0
  6. mcp_agent/agents/workflow/__init__.py +1 -0
  7. mcp_agent/agents/workflow/chain_agent.py +173 -0
  8. mcp_agent/agents/workflow/evaluator_optimizer.py +362 -0
  9. mcp_agent/agents/workflow/orchestrator_agent.py +591 -0
  10. mcp_agent/{workflows/orchestrator → agents/workflow}/orchestrator_models.py +27 -11
  11. mcp_agent/agents/workflow/parallel_agent.py +182 -0
  12. mcp_agent/agents/workflow/router_agent.py +307 -0
  13. mcp_agent/app.py +3 -1
  14. mcp_agent/cli/commands/bootstrap.py +18 -7
  15. mcp_agent/cli/commands/setup.py +12 -4
  16. mcp_agent/cli/main.py +1 -1
  17. mcp_agent/cli/terminal.py +1 -1
  18. mcp_agent/config.py +24 -35
  19. mcp_agent/context.py +3 -1
  20. mcp_agent/context_dependent.py +3 -1
  21. mcp_agent/core/agent_types.py +10 -7
  22. mcp_agent/core/direct_agent_app.py +179 -0
  23. mcp_agent/core/direct_decorators.py +443 -0
  24. mcp_agent/core/direct_factory.py +476 -0
  25. mcp_agent/core/enhanced_prompt.py +15 -20
  26. mcp_agent/core/fastagent.py +151 -337
  27. mcp_agent/core/interactive_prompt.py +424 -0
  28. mcp_agent/core/mcp_content.py +19 -11
  29. mcp_agent/core/prompt.py +6 -2
  30. mcp_agent/core/validation.py +89 -16
  31. mcp_agent/executor/decorator_registry.py +6 -2
  32. mcp_agent/executor/temporal.py +35 -11
  33. mcp_agent/executor/workflow_signal.py +8 -2
  34. mcp_agent/human_input/handler.py +3 -1
  35. mcp_agent/llm/__init__.py +2 -0
  36. mcp_agent/{workflows/llm → llm}/augmented_llm.py +131 -256
  37. mcp_agent/{workflows/llm → llm}/augmented_llm_passthrough.py +35 -107
  38. mcp_agent/llm/augmented_llm_playback.py +83 -0
  39. mcp_agent/{workflows/llm → llm}/model_factory.py +26 -8
  40. mcp_agent/llm/providers/__init__.py +8 -0
  41. mcp_agent/{workflows/llm → llm/providers}/anthropic_utils.py +5 -1
  42. mcp_agent/{workflows/llm → llm/providers}/augmented_llm_anthropic.py +37 -141
  43. mcp_agent/llm/providers/augmented_llm_deepseek.py +53 -0
  44. mcp_agent/{workflows/llm → llm/providers}/augmented_llm_openai.py +112 -148
  45. mcp_agent/{workflows/llm → llm}/providers/multipart_converter_anthropic.py +78 -35
  46. mcp_agent/{workflows/llm → llm}/providers/multipart_converter_openai.py +73 -44
  47. mcp_agent/{workflows/llm → llm}/providers/openai_multipart.py +18 -4
  48. mcp_agent/{workflows/llm → llm/providers}/openai_utils.py +3 -3
  49. mcp_agent/{workflows/llm → llm}/providers/sampling_converter_anthropic.py +3 -3
  50. mcp_agent/{workflows/llm → llm}/providers/sampling_converter_openai.py +3 -3
  51. mcp_agent/{workflows/llm → llm}/sampling_converter.py +0 -21
  52. mcp_agent/{workflows/llm → llm}/sampling_format_converter.py +16 -1
  53. mcp_agent/logging/logger.py +2 -2
  54. mcp_agent/mcp/gen_client.py +9 -3
  55. mcp_agent/mcp/interfaces.py +67 -45
  56. mcp_agent/mcp/logger_textio.py +97 -0
  57. mcp_agent/mcp/mcp_agent_client_session.py +12 -4
  58. mcp_agent/mcp/mcp_agent_server.py +3 -1
  59. mcp_agent/mcp/mcp_aggregator.py +124 -93
  60. mcp_agent/mcp/mcp_connection_manager.py +21 -7
  61. mcp_agent/mcp/prompt_message_multipart.py +59 -1
  62. mcp_agent/mcp/prompt_render.py +77 -0
  63. mcp_agent/mcp/prompt_serialization.py +20 -13
  64. mcp_agent/mcp/prompts/prompt_constants.py +18 -0
  65. mcp_agent/mcp/prompts/prompt_helpers.py +327 -0
  66. mcp_agent/mcp/prompts/prompt_load.py +15 -5
  67. mcp_agent/mcp/prompts/prompt_server.py +154 -87
  68. mcp_agent/mcp/prompts/prompt_template.py +26 -35
  69. mcp_agent/mcp/resource_utils.py +3 -1
  70. mcp_agent/mcp/sampling.py +24 -15
  71. mcp_agent/mcp_server/agent_server.py +8 -5
  72. mcp_agent/mcp_server_registry.py +22 -9
  73. mcp_agent/resources/examples/{workflows → in_dev}/agent_build.py +1 -1
  74. mcp_agent/resources/examples/{data-analysis → in_dev}/slides.py +1 -1
  75. mcp_agent/resources/examples/internal/agent.py +4 -2
  76. mcp_agent/resources/examples/internal/fastagent.config.yaml +8 -2
  77. mcp_agent/resources/examples/prompting/image_server.py +3 -1
  78. mcp_agent/resources/examples/prompting/work_with_image.py +19 -0
  79. mcp_agent/ui/console_display.py +27 -7
  80. fast_agent_mcp-0.1.13.dist-info/RECORD +0 -164
  81. mcp_agent/core/agent_app.py +0 -570
  82. mcp_agent/core/agent_utils.py +0 -69
  83. mcp_agent/core/decorators.py +0 -448
  84. mcp_agent/core/factory.py +0 -422
  85. mcp_agent/core/proxies.py +0 -278
  86. mcp_agent/core/types.py +0 -22
  87. mcp_agent/eval/__init__.py +0 -0
  88. mcp_agent/mcp/stdio.py +0 -114
  89. mcp_agent/resources/examples/data-analysis/analysis-campaign.py +0 -188
  90. mcp_agent/resources/examples/data-analysis/analysis.py +0 -65
  91. mcp_agent/resources/examples/data-analysis/fastagent.config.yaml +0 -41
  92. mcp_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +0 -1471
  93. mcp_agent/resources/examples/mcp_researcher/researcher-eval.py +0 -53
  94. mcp_agent/resources/examples/researcher/fastagent.config.yaml +0 -66
  95. mcp_agent/resources/examples/researcher/researcher-eval.py +0 -53
  96. mcp_agent/resources/examples/researcher/researcher-imp.py +0 -189
  97. mcp_agent/resources/examples/researcher/researcher.py +0 -39
  98. mcp_agent/resources/examples/workflows/chaining.py +0 -45
  99. mcp_agent/resources/examples/workflows/evaluator.py +0 -79
  100. mcp_agent/resources/examples/workflows/fastagent.config.yaml +0 -24
  101. mcp_agent/resources/examples/workflows/human_input.py +0 -26
  102. mcp_agent/resources/examples/workflows/orchestrator.py +0 -74
  103. mcp_agent/resources/examples/workflows/parallel.py +0 -79
  104. mcp_agent/resources/examples/workflows/router.py +0 -54
  105. mcp_agent/resources/examples/workflows/sse.py +0 -23
  106. mcp_agent/telemetry/__init__.py +0 -0
  107. mcp_agent/telemetry/usage_tracking.py +0 -19
  108. mcp_agent/workflows/__init__.py +0 -0
  109. mcp_agent/workflows/embedding/__init__.py +0 -0
  110. mcp_agent/workflows/embedding/embedding_base.py +0 -58
  111. mcp_agent/workflows/embedding/embedding_cohere.py +0 -49
  112. mcp_agent/workflows/embedding/embedding_openai.py +0 -37
  113. mcp_agent/workflows/evaluator_optimizer/__init__.py +0 -0
  114. mcp_agent/workflows/evaluator_optimizer/evaluator_optimizer.py +0 -447
  115. mcp_agent/workflows/intent_classifier/__init__.py +0 -0
  116. mcp_agent/workflows/intent_classifier/intent_classifier_base.py +0 -117
  117. mcp_agent/workflows/intent_classifier/intent_classifier_embedding.py +0 -130
  118. mcp_agent/workflows/intent_classifier/intent_classifier_embedding_cohere.py +0 -41
  119. mcp_agent/workflows/intent_classifier/intent_classifier_embedding_openai.py +0 -41
  120. mcp_agent/workflows/intent_classifier/intent_classifier_llm.py +0 -150
  121. mcp_agent/workflows/intent_classifier/intent_classifier_llm_anthropic.py +0 -60
  122. mcp_agent/workflows/intent_classifier/intent_classifier_llm_openai.py +0 -58
  123. mcp_agent/workflows/llm/__init__.py +0 -0
  124. mcp_agent/workflows/llm/augmented_llm_playback.py +0 -111
  125. mcp_agent/workflows/llm/providers/__init__.py +0 -8
  126. mcp_agent/workflows/orchestrator/__init__.py +0 -0
  127. mcp_agent/workflows/orchestrator/orchestrator.py +0 -535
  128. mcp_agent/workflows/parallel/__init__.py +0 -0
  129. mcp_agent/workflows/parallel/fan_in.py +0 -320
  130. mcp_agent/workflows/parallel/fan_out.py +0 -181
  131. mcp_agent/workflows/parallel/parallel_llm.py +0 -149
  132. mcp_agent/workflows/router/__init__.py +0 -0
  133. mcp_agent/workflows/router/router_base.py +0 -338
  134. mcp_agent/workflows/router/router_embedding.py +0 -226
  135. mcp_agent/workflows/router/router_embedding_cohere.py +0 -59
  136. mcp_agent/workflows/router/router_embedding_openai.py +0 -59
  137. mcp_agent/workflows/router/router_llm.py +0 -304
  138. mcp_agent/workflows/swarm/__init__.py +0 -0
  139. mcp_agent/workflows/swarm/swarm.py +0 -292
  140. mcp_agent/workflows/swarm/swarm_anthropic.py +0 -42
  141. mcp_agent/workflows/swarm/swarm_openai.py +0 -41
  142. {fast_agent_mcp-0.1.13.dist-info → fast_agent_mcp-0.2.0.dist-info}/WHEEL +0 -0
  143. {fast_agent_mcp-0.1.13.dist-info → fast_agent_mcp-0.2.0.dist-info}/entry_points.txt +0 -0
  144. {fast_agent_mcp-0.1.13.dist-info → fast_agent_mcp-0.2.0.dist-info}/licenses/LICENSE +0 -0
  145. /mcp_agent/{workflows/orchestrator → agents/workflow}/orchestrator_prompts.py +0 -0
  146. /mcp_agent/{workflows/llm → llm}/memory.py +0 -0
  147. /mcp_agent/{workflows/llm → llm}/prompt_utils.py +0 -0
@@ -1,79 +0,0 @@
1
- """
2
- Parallel Workflow showing Fan Out and Fan In agents, using different models
3
- """
4
-
5
- import asyncio
6
-
7
- from mcp_agent.core.fastagent import FastAgent
8
-
9
- # Create the application
10
- fast = FastAgent(
11
- "Parallel Workflow",
12
- )
13
- SHORT_STORY = """
14
- The Battle of Glimmerwood
15
-
16
- In the heart of Glimmerwood, a mystical forest knowed for its radiant trees, a small village thrived.
17
- The villagers, who were live peacefully, shared their home with the forest's magical creatures,
18
- especially the Glimmerfoxes whose fur shimmer like moonlight.
19
-
20
- One fateful evening, the peace was shaterred when the infamous Dark Marauders attack.
21
- Lead by the cunning Captain Thorn, the bandits aim to steal the precious Glimmerstones which was believed to grant immortality.
22
-
23
- Amidst the choas, a young girl named Elara stood her ground, she rallied the villagers and devised a clever plan.
24
- Using the forests natural defenses they lured the marauders into a trap.
25
- As the bandits aproached the village square, a herd of Glimmerfoxes emerged, blinding them with their dazzling light,
26
- the villagers seized the opportunity to captured the invaders.
27
-
28
- Elara's bravery was celebrated and she was hailed as the "Guardian of Glimmerwood".
29
- The Glimmerstones were secured in a hidden grove protected by an ancient spell.
30
-
31
- However, not all was as it seemed. The Glimmerstones true power was never confirm,
32
- and whispers of a hidden agenda linger among the villagers.
33
- """
34
-
35
-
36
- @fast.agent(
37
- name="proofreader",
38
- instruction=""""Review the short story for grammar, spelling, and punctuation errors.
39
- Identify any awkward phrasing or structural issues that could improve clarity.
40
- Provide detailed feedback on corrections.""",
41
- )
42
- @fast.agent(
43
- name="fact_checker",
44
- instruction="""Verify the factual consistency within the story. Identify any contradictions,
45
- logical inconsistencies, or inaccuracies in the plot, character actions, or setting.
46
- Highlight potential issues with reasoning or coherence.""",
47
- model="gpt-4o",
48
- )
49
- @fast.agent(
50
- name="style_enforcer",
51
- instruction="""Analyze the story for adherence to style guidelines.
52
- Evaluate the narrative flow, clarity of expression, and tone. Suggest improvements to
53
- enhance storytelling, readability, and engagement.""",
54
- model="sonnet",
55
- )
56
- @fast.agent(
57
- name="grader",
58
- instruction="""Compile the feedback from the Proofreader, Fact Checker, and Style Enforcer
59
- into a structured report. Summarize key issues and categorize them by type.
60
- Provide actionable recommendations for improving the story,
61
- and give an overall grade based on the feedback.""",
62
- model="o3-mini.low",
63
- )
64
- @fast.parallel(
65
- fan_out=["proofreader", "fact_checker", "style_enforcer"],
66
- fan_in="grader",
67
- name="parallel",
68
- )
69
- async def main() -> None:
70
- # Use the app's context manager
71
- async with fast.run() as agent:
72
- await agent.parallel(f"student short story submission: {SHORT_STORY}")
73
-
74
- # follow-on prompt to task agent
75
- await agent.style_enforcer.prompt(default_prompt="STOP")
76
-
77
-
78
- if __name__ == "__main__":
79
- asyncio.run(main())
@@ -1,54 +0,0 @@
1
- """
2
- Example MCP Agent application showing router workflow with decorator syntax.
3
- Demonstrates router's ability to either:
4
- 1. Use tools directly to handle requests
5
- 2. Delegate requests to specialized agents
6
- """
7
-
8
- import asyncio
9
-
10
- from mcp_agent.core.fastagent import FastAgent
11
-
12
- # Create the application
13
- fast = FastAgent(
14
- "Router Workflow",
15
- )
16
-
17
- # Sample requests demonstrating direct tool use vs agent delegation
18
- SAMPLE_REQUESTS = [
19
- "Download and summarize https://llmindset.co.uk/posts/2024/12/mcp-build-notes/", # Router handles directly with fetch
20
- "Analyze the quality of the Python codebase in the current working directory", # Delegated to code expert
21
- "What are the key principles of effective beekeeping?", # Delegated to general assistant
22
- ]
23
-
24
-
25
- @fast.agent(
26
- name="fetcher",
27
- instruction="""You are an agent, with a tool enabling you to fetch URLs.""",
28
- servers=["fetch"],
29
- )
30
- @fast.agent(
31
- name="code_expert",
32
- instruction="""You are an expert in code analysis and software engineering.
33
- When asked about code, architecture, or development practices,
34
- you provide thorough and practical insights.""",
35
- servers=["filesystem"],
36
- )
37
- @fast.agent(
38
- name="general_assistant",
39
- instruction="""You are a knowledgeable assistant that provides clear,
40
- well-reasoned responses about general topics, concepts, and principles.""",
41
- )
42
- @fast.router(
43
- name="route",
44
- model="sonnet",
45
- agents=["code_expert", "general_assistant", "fetcher"],
46
- )
47
- async def main() -> None:
48
- async with fast.run() as agent:
49
- for request in SAMPLE_REQUESTS:
50
- await agent.route(request)
51
-
52
-
53
- if __name__ == "__main__":
54
- asyncio.run(main())
@@ -1,23 +0,0 @@
1
- # example_mcp_server.py
2
- import asyncio
3
-
4
- from mcp_agent.core.fastagent import FastAgent
5
-
6
- # Define your agents as normal
7
- fa = FastAgent("My Application")
8
-
9
-
10
- @fa.agent("analyst", "hello, world", servers=["fetch"])
11
-
12
- # Run the application with MCP server
13
- async def main() -> None:
14
- await fa.run_with_mcp_server(
15
- transport="sse", # Use "sse" for web server, "stdio" for command line
16
- port=8000,
17
- server_name="MyAgents",
18
- server_description="MCP Server exposing analyst and researcher agents",
19
- )
20
-
21
-
22
- if __name__ == "__main__":
23
- asyncio.run(main())
File without changes
@@ -1,19 +0,0 @@
1
- import logging
2
-
3
- from mcp_agent.config import get_settings
4
-
5
- logger = logging.getLogger(__name__)
6
-
7
-
8
- def send_usage_data() -> None:
9
- config = get_settings()
10
- if not config.usage_telemetry.enabled:
11
- logger.info("Usage tracking is disabled")
12
- return
13
-
14
- # TODO: saqadri - implement usage tracking
15
- # data = {"installation_id": str(uuid.uuid4()), "version": "0.1.0"}
16
- # try:
17
- # requests.post("https://telemetry.example.com/usage", json=data, timeout=2)
18
- # except:
19
- # pass
File without changes
File without changes
@@ -1,58 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from typing import Dict, List
3
-
4
- from numpy import float32
5
- from numpy.typing import NDArray
6
- from sklearn.metrics.pairwise import cosine_similarity
7
-
8
- from mcp_agent.context_dependent import ContextDependent
9
-
10
- FloatArray = NDArray[float32]
11
-
12
-
13
- class EmbeddingModel(ABC, ContextDependent):
14
- """Abstract interface for embedding models"""
15
-
16
- @abstractmethod
17
- async def embed(self, data: List[str]) -> FloatArray:
18
- """
19
- Generate embeddings for a list of messages
20
-
21
- Args:
22
- data: List of text strings to embed
23
-
24
- Returns:
25
- Array of embeddings, shape (len(texts), embedding_dim)
26
- """
27
-
28
- @property
29
- @abstractmethod
30
- def embedding_dim(self) -> int:
31
- """Return the dimensionality of the embeddings"""
32
-
33
-
34
- def compute_similarity_scores(embedding_a: FloatArray, embedding_b: FloatArray) -> Dict[str, float]:
35
- """
36
- Compute different similarity metrics between embeddings
37
- """
38
- # Reshape for sklearn's cosine_similarity
39
- a_emb = embedding_a.reshape(1, -1)
40
- b_emb = embedding_b.reshape(1, -1)
41
-
42
- cosine_sim = float(cosine_similarity(a_emb, b_emb)[0, 0])
43
-
44
- # Could add other similarity metrics here
45
- return {
46
- "cosine": cosine_sim,
47
- # "euclidean": float(euclidean_similarity),
48
- # "dot_product": float(dot_product)
49
- }
50
-
51
-
52
- def compute_confidence(similarity_scores: Dict[str, float]) -> float:
53
- """
54
- Compute overall confidence score from individual similarity metrics
55
- """
56
- # For now, just use cosine similarity as confidence
57
- # Could implement more sophisticated combination of scores
58
- return similarity_scores["cosine"]
@@ -1,49 +0,0 @@
1
- from typing import TYPE_CHECKING, List, Optional
2
-
3
- from cohere import Client
4
- from numpy import array, float32
5
-
6
- from mcp_agent.workflows.embedding.embedding_base import EmbeddingModel, FloatArray
7
-
8
- if TYPE_CHECKING:
9
- from mcp_agent.context import Context
10
-
11
-
12
- class CohereEmbeddingModel(EmbeddingModel):
13
- """Cohere embedding model implementation"""
14
-
15
- def __init__(
16
- self,
17
- model: str = "embed-multilingual-v3.0",
18
- context: Optional["Context"] = None,
19
- **kwargs,
20
- ) -> None:
21
- super().__init__(context=context, **kwargs)
22
- self.client = Client(api_key=self.context.config.cohere.api_key)
23
- self.model = model
24
- # Cache the dimension since it's fixed per model
25
- # https://docs.cohere.com/v2/docs/cohere-embed
26
- self._embedding_dim = {
27
- "embed-english-v2.0": 4096,
28
- "embed-english-light-v2.0": 1024,
29
- "embed-english-v3.0": 1024,
30
- "embed-english-light-v3.0": 384,
31
- "embed-multilingual-v2.0": 768,
32
- "embed-multilingual-v3.0": 1024,
33
- "embed-multilingual-light-v3.0": 384,
34
- }[model]
35
-
36
- async def embed(self, data: List[str]) -> FloatArray:
37
- response = self.client.embed(
38
- texts=data,
39
- model=self.model,
40
- input_type="classification",
41
- embedding_types=["float"],
42
- )
43
-
44
- embeddings = array(response.embeddings, dtype=float32)
45
- return embeddings
46
-
47
- @property
48
- def embedding_dim(self) -> int:
49
- return self._embedding_dim
@@ -1,37 +0,0 @@
1
- from typing import TYPE_CHECKING, List, Optional
2
-
3
- from numpy import array, float32, stack
4
- from openai import OpenAI
5
-
6
- from mcp_agent.workflows.embedding.embedding_base import EmbeddingModel, FloatArray
7
-
8
- if TYPE_CHECKING:
9
- from mcp_agent.context import Context
10
-
11
-
12
- class OpenAIEmbeddingModel(EmbeddingModel):
13
- """OpenAI embedding model implementation"""
14
-
15
- def __init__(self, model: str = "text-embedding-3-small", context: Optional["Context"] = None) -> None:
16
- super().__init__(context=context)
17
- self.client = OpenAI(api_key=self.context.config.openai.api_key)
18
- self.model = model
19
- # Cache the dimension since it's fixed per model
20
- self._embedding_dim = {
21
- "text-embedding-3-small": 1536,
22
- "text-embedding-3-large": 3072,
23
- }[model]
24
-
25
- async def embed(self, data: List[str]) -> FloatArray:
26
- response = self.client.embeddings.create(model=self.model, input=data, encoding_format="float")
27
-
28
- # Sort the embeddings by their index to ensure correct order
29
- sorted_embeddings = sorted(response.data, key=lambda x: x["index"])
30
-
31
- # Stack all embeddings into a single array
32
- embeddings = stack([array(embedding["embedding"], dtype=float32) for embedding in sorted_embeddings])
33
- return embeddings
34
-
35
- @property
36
- def embedding_dim(self) -> int:
37
- return self._embedding_dim
File without changes