fast-agent-mcp 0.4.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fast_agent/__init__.py +183 -0
- fast_agent/acp/__init__.py +19 -0
- fast_agent/acp/acp_aware_mixin.py +304 -0
- fast_agent/acp/acp_context.py +437 -0
- fast_agent/acp/content_conversion.py +136 -0
- fast_agent/acp/filesystem_runtime.py +427 -0
- fast_agent/acp/permission_store.py +269 -0
- fast_agent/acp/server/__init__.py +5 -0
- fast_agent/acp/server/agent_acp_server.py +1472 -0
- fast_agent/acp/slash_commands.py +1050 -0
- fast_agent/acp/terminal_runtime.py +408 -0
- fast_agent/acp/tool_permission_adapter.py +125 -0
- fast_agent/acp/tool_permissions.py +474 -0
- fast_agent/acp/tool_progress.py +814 -0
- fast_agent/agents/__init__.py +85 -0
- fast_agent/agents/agent_types.py +64 -0
- fast_agent/agents/llm_agent.py +350 -0
- fast_agent/agents/llm_decorator.py +1139 -0
- fast_agent/agents/mcp_agent.py +1337 -0
- fast_agent/agents/tool_agent.py +271 -0
- fast_agent/agents/workflow/agents_as_tools_agent.py +849 -0
- fast_agent/agents/workflow/chain_agent.py +212 -0
- fast_agent/agents/workflow/evaluator_optimizer.py +380 -0
- fast_agent/agents/workflow/iterative_planner.py +652 -0
- fast_agent/agents/workflow/maker_agent.py +379 -0
- fast_agent/agents/workflow/orchestrator_models.py +218 -0
- fast_agent/agents/workflow/orchestrator_prompts.py +248 -0
- fast_agent/agents/workflow/parallel_agent.py +250 -0
- fast_agent/agents/workflow/router_agent.py +353 -0
- fast_agent/cli/__init__.py +0 -0
- fast_agent/cli/__main__.py +73 -0
- fast_agent/cli/commands/acp.py +159 -0
- fast_agent/cli/commands/auth.py +404 -0
- fast_agent/cli/commands/check_config.py +783 -0
- fast_agent/cli/commands/go.py +514 -0
- fast_agent/cli/commands/quickstart.py +557 -0
- fast_agent/cli/commands/serve.py +143 -0
- fast_agent/cli/commands/server_helpers.py +114 -0
- fast_agent/cli/commands/setup.py +174 -0
- fast_agent/cli/commands/url_parser.py +190 -0
- fast_agent/cli/constants.py +40 -0
- fast_agent/cli/main.py +115 -0
- fast_agent/cli/terminal.py +24 -0
- fast_agent/config.py +798 -0
- fast_agent/constants.py +41 -0
- fast_agent/context.py +279 -0
- fast_agent/context_dependent.py +50 -0
- fast_agent/core/__init__.py +92 -0
- fast_agent/core/agent_app.py +448 -0
- fast_agent/core/core_app.py +137 -0
- fast_agent/core/direct_decorators.py +784 -0
- fast_agent/core/direct_factory.py +620 -0
- fast_agent/core/error_handling.py +27 -0
- fast_agent/core/exceptions.py +90 -0
- fast_agent/core/executor/__init__.py +0 -0
- fast_agent/core/executor/executor.py +280 -0
- fast_agent/core/executor/task_registry.py +32 -0
- fast_agent/core/executor/workflow_signal.py +324 -0
- fast_agent/core/fastagent.py +1186 -0
- fast_agent/core/logging/__init__.py +5 -0
- fast_agent/core/logging/events.py +138 -0
- fast_agent/core/logging/json_serializer.py +164 -0
- fast_agent/core/logging/listeners.py +309 -0
- fast_agent/core/logging/logger.py +278 -0
- fast_agent/core/logging/transport.py +481 -0
- fast_agent/core/prompt.py +9 -0
- fast_agent/core/prompt_templates.py +183 -0
- fast_agent/core/validation.py +326 -0
- fast_agent/event_progress.py +62 -0
- fast_agent/history/history_exporter.py +49 -0
- fast_agent/human_input/__init__.py +47 -0
- fast_agent/human_input/elicitation_handler.py +123 -0
- fast_agent/human_input/elicitation_state.py +33 -0
- fast_agent/human_input/form_elements.py +59 -0
- fast_agent/human_input/form_fields.py +256 -0
- fast_agent/human_input/simple_form.py +113 -0
- fast_agent/human_input/types.py +40 -0
- fast_agent/interfaces.py +310 -0
- fast_agent/llm/__init__.py +9 -0
- fast_agent/llm/cancellation.py +22 -0
- fast_agent/llm/fastagent_llm.py +931 -0
- fast_agent/llm/internal/passthrough.py +161 -0
- fast_agent/llm/internal/playback.py +129 -0
- fast_agent/llm/internal/silent.py +41 -0
- fast_agent/llm/internal/slow.py +38 -0
- fast_agent/llm/memory.py +275 -0
- fast_agent/llm/model_database.py +490 -0
- fast_agent/llm/model_factory.py +388 -0
- fast_agent/llm/model_info.py +102 -0
- fast_agent/llm/prompt_utils.py +155 -0
- fast_agent/llm/provider/anthropic/anthropic_utils.py +84 -0
- fast_agent/llm/provider/anthropic/cache_planner.py +56 -0
- fast_agent/llm/provider/anthropic/llm_anthropic.py +796 -0
- fast_agent/llm/provider/anthropic/multipart_converter_anthropic.py +462 -0
- fast_agent/llm/provider/bedrock/bedrock_utils.py +218 -0
- fast_agent/llm/provider/bedrock/llm_bedrock.py +2207 -0
- fast_agent/llm/provider/bedrock/multipart_converter_bedrock.py +84 -0
- fast_agent/llm/provider/google/google_converter.py +466 -0
- fast_agent/llm/provider/google/llm_google_native.py +681 -0
- fast_agent/llm/provider/openai/llm_aliyun.py +31 -0
- fast_agent/llm/provider/openai/llm_azure.py +143 -0
- fast_agent/llm/provider/openai/llm_deepseek.py +76 -0
- fast_agent/llm/provider/openai/llm_generic.py +35 -0
- fast_agent/llm/provider/openai/llm_google_oai.py +32 -0
- fast_agent/llm/provider/openai/llm_groq.py +42 -0
- fast_agent/llm/provider/openai/llm_huggingface.py +85 -0
- fast_agent/llm/provider/openai/llm_openai.py +1195 -0
- fast_agent/llm/provider/openai/llm_openai_compatible.py +138 -0
- fast_agent/llm/provider/openai/llm_openrouter.py +45 -0
- fast_agent/llm/provider/openai/llm_tensorzero_openai.py +128 -0
- fast_agent/llm/provider/openai/llm_xai.py +38 -0
- fast_agent/llm/provider/openai/multipart_converter_openai.py +561 -0
- fast_agent/llm/provider/openai/openai_multipart.py +169 -0
- fast_agent/llm/provider/openai/openai_utils.py +67 -0
- fast_agent/llm/provider/openai/responses.py +133 -0
- fast_agent/llm/provider_key_manager.py +139 -0
- fast_agent/llm/provider_types.py +34 -0
- fast_agent/llm/request_params.py +61 -0
- fast_agent/llm/sampling_converter.py +98 -0
- fast_agent/llm/stream_types.py +9 -0
- fast_agent/llm/usage_tracking.py +445 -0
- fast_agent/mcp/__init__.py +56 -0
- fast_agent/mcp/common.py +26 -0
- fast_agent/mcp/elicitation_factory.py +84 -0
- fast_agent/mcp/elicitation_handlers.py +164 -0
- fast_agent/mcp/gen_client.py +83 -0
- fast_agent/mcp/helpers/__init__.py +36 -0
- fast_agent/mcp/helpers/content_helpers.py +352 -0
- fast_agent/mcp/helpers/server_config_helpers.py +25 -0
- fast_agent/mcp/hf_auth.py +147 -0
- fast_agent/mcp/interfaces.py +92 -0
- fast_agent/mcp/logger_textio.py +108 -0
- fast_agent/mcp/mcp_agent_client_session.py +411 -0
- fast_agent/mcp/mcp_aggregator.py +2175 -0
- fast_agent/mcp/mcp_connection_manager.py +723 -0
- fast_agent/mcp/mcp_content.py +262 -0
- fast_agent/mcp/mime_utils.py +108 -0
- fast_agent/mcp/oauth_client.py +509 -0
- fast_agent/mcp/prompt.py +159 -0
- fast_agent/mcp/prompt_message_extended.py +155 -0
- fast_agent/mcp/prompt_render.py +84 -0
- fast_agent/mcp/prompt_serialization.py +580 -0
- fast_agent/mcp/prompts/__init__.py +0 -0
- fast_agent/mcp/prompts/__main__.py +7 -0
- fast_agent/mcp/prompts/prompt_constants.py +18 -0
- fast_agent/mcp/prompts/prompt_helpers.py +238 -0
- fast_agent/mcp/prompts/prompt_load.py +186 -0
- fast_agent/mcp/prompts/prompt_server.py +552 -0
- fast_agent/mcp/prompts/prompt_template.py +438 -0
- fast_agent/mcp/resource_utils.py +215 -0
- fast_agent/mcp/sampling.py +200 -0
- fast_agent/mcp/server/__init__.py +4 -0
- fast_agent/mcp/server/agent_server.py +613 -0
- fast_agent/mcp/skybridge.py +44 -0
- fast_agent/mcp/sse_tracking.py +287 -0
- fast_agent/mcp/stdio_tracking_simple.py +59 -0
- fast_agent/mcp/streamable_http_tracking.py +309 -0
- fast_agent/mcp/tool_execution_handler.py +137 -0
- fast_agent/mcp/tool_permission_handler.py +88 -0
- fast_agent/mcp/transport_tracking.py +634 -0
- fast_agent/mcp/types.py +24 -0
- fast_agent/mcp/ui_agent.py +48 -0
- fast_agent/mcp/ui_mixin.py +209 -0
- fast_agent/mcp_server_registry.py +89 -0
- fast_agent/py.typed +0 -0
- fast_agent/resources/examples/data-analysis/analysis-campaign.py +189 -0
- fast_agent/resources/examples/data-analysis/analysis.py +68 -0
- fast_agent/resources/examples/data-analysis/fastagent.config.yaml +41 -0
- fast_agent/resources/examples/data-analysis/mount-point/WA_Fn-UseC_-HR-Employee-Attrition.csv +1471 -0
- fast_agent/resources/examples/mcp/elicitations/elicitation_account_server.py +88 -0
- fast_agent/resources/examples/mcp/elicitations/elicitation_forms_server.py +297 -0
- fast_agent/resources/examples/mcp/elicitations/elicitation_game_server.py +164 -0
- fast_agent/resources/examples/mcp/elicitations/fastagent.config.yaml +35 -0
- fast_agent/resources/examples/mcp/elicitations/fastagent.secrets.yaml.example +17 -0
- fast_agent/resources/examples/mcp/elicitations/forms_demo.py +107 -0
- fast_agent/resources/examples/mcp/elicitations/game_character.py +65 -0
- fast_agent/resources/examples/mcp/elicitations/game_character_handler.py +256 -0
- fast_agent/resources/examples/mcp/elicitations/tool_call.py +21 -0
- fast_agent/resources/examples/mcp/state-transfer/agent_one.py +18 -0
- fast_agent/resources/examples/mcp/state-transfer/agent_two.py +18 -0
- fast_agent/resources/examples/mcp/state-transfer/fastagent.config.yaml +27 -0
- fast_agent/resources/examples/mcp/state-transfer/fastagent.secrets.yaml.example +15 -0
- fast_agent/resources/examples/researcher/fastagent.config.yaml +61 -0
- fast_agent/resources/examples/researcher/researcher-eval.py +53 -0
- fast_agent/resources/examples/researcher/researcher-imp.py +189 -0
- fast_agent/resources/examples/researcher/researcher.py +36 -0
- fast_agent/resources/examples/tensorzero/.env.sample +2 -0
- fast_agent/resources/examples/tensorzero/Makefile +31 -0
- fast_agent/resources/examples/tensorzero/README.md +56 -0
- fast_agent/resources/examples/tensorzero/agent.py +35 -0
- fast_agent/resources/examples/tensorzero/demo_images/clam.jpg +0 -0
- fast_agent/resources/examples/tensorzero/demo_images/crab.png +0 -0
- fast_agent/resources/examples/tensorzero/demo_images/shrimp.png +0 -0
- fast_agent/resources/examples/tensorzero/docker-compose.yml +105 -0
- fast_agent/resources/examples/tensorzero/fastagent.config.yaml +19 -0
- fast_agent/resources/examples/tensorzero/image_demo.py +67 -0
- fast_agent/resources/examples/tensorzero/mcp_server/Dockerfile +25 -0
- fast_agent/resources/examples/tensorzero/mcp_server/entrypoint.sh +35 -0
- fast_agent/resources/examples/tensorzero/mcp_server/mcp_server.py +31 -0
- fast_agent/resources/examples/tensorzero/mcp_server/pyproject.toml +11 -0
- fast_agent/resources/examples/tensorzero/simple_agent.py +25 -0
- fast_agent/resources/examples/tensorzero/tensorzero_config/system_schema.json +29 -0
- fast_agent/resources/examples/tensorzero/tensorzero_config/system_template.minijinja +11 -0
- fast_agent/resources/examples/tensorzero/tensorzero_config/tensorzero.toml +35 -0
- fast_agent/resources/examples/workflows/agents_as_tools_extended.py +73 -0
- fast_agent/resources/examples/workflows/agents_as_tools_simple.py +50 -0
- fast_agent/resources/examples/workflows/chaining.py +37 -0
- fast_agent/resources/examples/workflows/evaluator.py +77 -0
- fast_agent/resources/examples/workflows/fastagent.config.yaml +26 -0
- fast_agent/resources/examples/workflows/graded_report.md +89 -0
- fast_agent/resources/examples/workflows/human_input.py +28 -0
- fast_agent/resources/examples/workflows/maker.py +156 -0
- fast_agent/resources/examples/workflows/orchestrator.py +70 -0
- fast_agent/resources/examples/workflows/parallel.py +56 -0
- fast_agent/resources/examples/workflows/router.py +69 -0
- fast_agent/resources/examples/workflows/short_story.md +13 -0
- fast_agent/resources/examples/workflows/short_story.txt +19 -0
- fast_agent/resources/setup/.gitignore +30 -0
- fast_agent/resources/setup/agent.py +28 -0
- fast_agent/resources/setup/fastagent.config.yaml +65 -0
- fast_agent/resources/setup/fastagent.secrets.yaml.example +38 -0
- fast_agent/resources/setup/pyproject.toml.tmpl +23 -0
- fast_agent/skills/__init__.py +9 -0
- fast_agent/skills/registry.py +235 -0
- fast_agent/tools/elicitation.py +369 -0
- fast_agent/tools/shell_runtime.py +402 -0
- fast_agent/types/__init__.py +59 -0
- fast_agent/types/conversation_summary.py +294 -0
- fast_agent/types/llm_stop_reason.py +78 -0
- fast_agent/types/message_search.py +249 -0
- fast_agent/ui/__init__.py +38 -0
- fast_agent/ui/console.py +59 -0
- fast_agent/ui/console_display.py +1080 -0
- fast_agent/ui/elicitation_form.py +946 -0
- fast_agent/ui/elicitation_style.py +59 -0
- fast_agent/ui/enhanced_prompt.py +1400 -0
- fast_agent/ui/history_display.py +734 -0
- fast_agent/ui/interactive_prompt.py +1199 -0
- fast_agent/ui/markdown_helpers.py +104 -0
- fast_agent/ui/markdown_truncator.py +1004 -0
- fast_agent/ui/mcp_display.py +857 -0
- fast_agent/ui/mcp_ui_utils.py +235 -0
- fast_agent/ui/mermaid_utils.py +169 -0
- fast_agent/ui/message_primitives.py +50 -0
- fast_agent/ui/notification_tracker.py +205 -0
- fast_agent/ui/plain_text_truncator.py +68 -0
- fast_agent/ui/progress_display.py +10 -0
- fast_agent/ui/rich_progress.py +195 -0
- fast_agent/ui/streaming.py +774 -0
- fast_agent/ui/streaming_buffer.py +449 -0
- fast_agent/ui/tool_display.py +422 -0
- fast_agent/ui/usage_display.py +204 -0
- fast_agent/utils/__init__.py +5 -0
- fast_agent/utils/reasoning_stream_parser.py +77 -0
- fast_agent/utils/time.py +22 -0
- fast_agent/workflow_telemetry.py +261 -0
- fast_agent_mcp-0.4.7.dist-info/METADATA +788 -0
- fast_agent_mcp-0.4.7.dist-info/RECORD +261 -0
- fast_agent_mcp-0.4.7.dist-info/WHEEL +4 -0
- fast_agent_mcp-0.4.7.dist-info/entry_points.txt +7 -0
- fast_agent_mcp-0.4.7.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
from fast_agent import FastAgent
|
|
4
|
+
|
|
5
|
+
agents = FastAgent(name="Enhanced Researcher")
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@agents.agent(
|
|
9
|
+
name="ResearchPlanner",
|
|
10
|
+
model="sonnet", # Using a more capable model for planning
|
|
11
|
+
instruction="""
|
|
12
|
+
You are a strategic research planner. Your job is to:
|
|
13
|
+
1. Break down complex research questions into specific sub-questions
|
|
14
|
+
2. Identify the key information sources needed to answer each sub-question
|
|
15
|
+
3. Outline a structured research plan
|
|
16
|
+
|
|
17
|
+
When given a research topic:
|
|
18
|
+
- Analyze what is being asked and identify the core components
|
|
19
|
+
- Define 3-5 specific sub-questions that need to be answered
|
|
20
|
+
- For each sub-question, suggest specific search queries and information sources
|
|
21
|
+
- Prioritize the most important areas to investigate first
|
|
22
|
+
- Include suggestions for data visualization or analysis if appropriate
|
|
23
|
+
|
|
24
|
+
Your output should be a clear, structured research plan that the Researcher can follow.
|
|
25
|
+
""",
|
|
26
|
+
servers=["brave"],
|
|
27
|
+
)
|
|
28
|
+
@agents.agent(
|
|
29
|
+
name="Researcher",
|
|
30
|
+
model="sonnet", # Using a more capable model for deep research
|
|
31
|
+
instruction="""
|
|
32
|
+
You are an expert research assistant with access to multiple resources:
|
|
33
|
+
- Brave Search for initial exploration and discovering sources
|
|
34
|
+
- Website fetching to read and extract information directly from webpages
|
|
35
|
+
- Python interpreter for data analysis and visualization
|
|
36
|
+
- Filesystem tools to save and organize your findings
|
|
37
|
+
|
|
38
|
+
RESEARCH METHODOLOGY:
|
|
39
|
+
1. First understand the research plan provided
|
|
40
|
+
2. For each sub-question, use search tools to find multiple relevant sources
|
|
41
|
+
3. Go beyond surface-level information by:
|
|
42
|
+
- Consulting primary sources when possible
|
|
43
|
+
- Cross-referencing information across multiple sources
|
|
44
|
+
- Using the fetch tool to access complete articles rather than just search snippets
|
|
45
|
+
- Analyzing data with Python when numerical evidence is needed
|
|
46
|
+
- Creating visualizations when they help clarify complex information
|
|
47
|
+
|
|
48
|
+
CRITICAL INFORMATION ASSESSMENT:
|
|
49
|
+
- Evaluate the credibility of each source (consider recency, authority, potential bias)
|
|
50
|
+
- Look for consensus across multiple sources
|
|
51
|
+
- Highlight any contradictions or areas of debate in the research
|
|
52
|
+
- Clearly state limitations in the available information
|
|
53
|
+
|
|
54
|
+
DOCUMENTATION:
|
|
55
|
+
- Save important information, data, and visualizations to files
|
|
56
|
+
- Always create a comprehensive bibliography with links to all sources
|
|
57
|
+
- Include specific citation details (author, date, publication) when available
|
|
58
|
+
- Note which specific information came from which source
|
|
59
|
+
|
|
60
|
+
FINAL RESPONSE:
|
|
61
|
+
- Structure your findings logically with clear headings
|
|
62
|
+
- Synthesize the information rather than just listing facts
|
|
63
|
+
- Directly address each sub-question from the research plan
|
|
64
|
+
- Use data and visualizations to support key points
|
|
65
|
+
- End with a concise executive summary of your findings
|
|
66
|
+
- Include a "Methodology" section explaining how you conducted your research
|
|
67
|
+
""",
|
|
68
|
+
servers=["brave", "interpreter", "filesystem", "fetch"],
|
|
69
|
+
use_history=True,
|
|
70
|
+
)
|
|
71
|
+
@agents.agent(
|
|
72
|
+
name="FactChecker",
|
|
73
|
+
instruction="""
|
|
74
|
+
You are a meticulous fact-checker and critical evaluator of research. Your responsibilities are to:
|
|
75
|
+
|
|
76
|
+
1. Verify factual claims by cross-checking with authoritative sources
|
|
77
|
+
2. Identify any unsupported assertions or logical fallacies
|
|
78
|
+
3. Detect potential biases or limitations in the research methodology
|
|
79
|
+
4. Ensure proper representation of diverse perspectives on controversial topics
|
|
80
|
+
5. Evaluate the quality, reliability, and currency of cited sources
|
|
81
|
+
|
|
82
|
+
When reviewing research:
|
|
83
|
+
- Flag any claims that lack sufficient evidence or citation
|
|
84
|
+
- Identify information that seems outdated or contradicts current consensus
|
|
85
|
+
- Check for oversimplifications of complex topics
|
|
86
|
+
- Ensure numerical data and statistics are accurately represented
|
|
87
|
+
- Verify that quotations are accurate and in proper context
|
|
88
|
+
- Look for any gaps in the research or important perspectives that were omitted
|
|
89
|
+
|
|
90
|
+
Your feedback should be specific, actionable, and structured to help improve accuracy and comprehensiveness.
|
|
91
|
+
""",
|
|
92
|
+
servers=["brave", "fetch"],
|
|
93
|
+
)
|
|
94
|
+
@agents.agent(
|
|
95
|
+
name="Evaluator",
|
|
96
|
+
model="sonnet",
|
|
97
|
+
instruction="""
|
|
98
|
+
You are a senior research quality evaluator with expertise in academic and professional research standards.
|
|
99
|
+
|
|
100
|
+
COMPREHENSIVE EVALUATION CRITERIA:
|
|
101
|
+
1. Research Methodology
|
|
102
|
+
- Has the researcher followed a structured approach?
|
|
103
|
+
- Were appropriate research methods applied?
|
|
104
|
+
- Is there evidence of strategic information gathering?
|
|
105
|
+
|
|
106
|
+
2. Source Quality & Diversity
|
|
107
|
+
- Are sources authoritative, current, and relevant?
|
|
108
|
+
- Is there appropriate diversity of sources?
|
|
109
|
+
- Were primary sources consulted when appropriate?
|
|
110
|
+
|
|
111
|
+
3. Information Depth
|
|
112
|
+
- Does the research go beyond surface-level information?
|
|
113
|
+
- Is there evidence of in-depth analysis?
|
|
114
|
+
- Has the researcher explored multiple aspects of the topic?
|
|
115
|
+
|
|
116
|
+
4. Critical Analysis
|
|
117
|
+
- Has information been critically evaluated rather than simply reported?
|
|
118
|
+
- Are limitations and uncertainties acknowledged?
|
|
119
|
+
- Are multiple perspectives considered on controversial topics?
|
|
120
|
+
|
|
121
|
+
5. Data & Evidence
|
|
122
|
+
- Is quantitative data properly analyzed and presented?
|
|
123
|
+
- Are visualizations clear, accurate, and informative?
|
|
124
|
+
- Is qualitative information presented with appropriate context?
|
|
125
|
+
|
|
126
|
+
6. Documentation & Attribution
|
|
127
|
+
- Are all sources properly cited with complete reference information?
|
|
128
|
+
- Is it clear which information came from which source?
|
|
129
|
+
- Is the bibliography comprehensive and well-formatted?
|
|
130
|
+
|
|
131
|
+
7. Structure & Communication
|
|
132
|
+
- Is the research presented in a logical, well-organized manner?
|
|
133
|
+
- Are findings communicated clearly and precisely?
|
|
134
|
+
- Is the level of technical language appropriate for the intended audience?
|
|
135
|
+
|
|
136
|
+
8. Alignment with Previous Feedback
|
|
137
|
+
- Has the researcher addressed specific feedback from previous evaluations?
|
|
138
|
+
- Have requested improvements been successfully implemented?
|
|
139
|
+
|
|
140
|
+
For each criterion, provide:
|
|
141
|
+
- A detailed RATING (EXCELLENT, GOOD, FAIR, or POOR)
|
|
142
|
+
- Specific examples from the research that justify your rating
|
|
143
|
+
- Clear, actionable suggestions for improvement
|
|
144
|
+
|
|
145
|
+
Your evaluation should conclude with:
|
|
146
|
+
- An OVERALL RATING that reflects the research quality
|
|
147
|
+
- A concise summary of the research's major strengths
|
|
148
|
+
- A prioritized list of the most important areas for improvement
|
|
149
|
+
|
|
150
|
+
The researcher should be able to understand exactly why they received their rating and what specific steps they can take to improve.
|
|
151
|
+
""",
|
|
152
|
+
)
|
|
153
|
+
@agents.chain(
|
|
154
|
+
name="ResearchProcess",
|
|
155
|
+
sequence=["ResearchPlanner", "Researcher", "FactChecker"],
|
|
156
|
+
instruction="A comprehensive research workflow that plans, executes, and verifies research",
|
|
157
|
+
cumulative=True,
|
|
158
|
+
)
|
|
159
|
+
@agents.evaluator_optimizer(
|
|
160
|
+
generator="ResearchProcess",
|
|
161
|
+
evaluator="Evaluator",
|
|
162
|
+
max_refinements=3,
|
|
163
|
+
min_rating="EXCELLENT",
|
|
164
|
+
name="EnhancedResearcher",
|
|
165
|
+
)
|
|
166
|
+
async def main() -> None:
|
|
167
|
+
async with agents.run() as agent:
|
|
168
|
+
# Start with a warm-up to set expectations and explain the research approach
|
|
169
|
+
await agent.Researcher.send(
|
|
170
|
+
"""I'm an enhanced research assistant trained to conduct thorough, evidence-based research.
|
|
171
|
+
I'll approach your question by:
|
|
172
|
+
1. Creating a structured research plan
|
|
173
|
+
2. Gathering information from multiple authoritative sources
|
|
174
|
+
3. Analyzing data and creating visualizations when helpful
|
|
175
|
+
4. Fact-checking and verifying all information
|
|
176
|
+
5. Providing a comprehensive, well-documented answer
|
|
177
|
+
|
|
178
|
+
What would you like me to research for you today?"""
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Start the main research workflow
|
|
182
|
+
await agent.prompt("EnhancedResearcher")
|
|
183
|
+
|
|
184
|
+
print("\nWould you like to ask follow-up questions to the Researcher? (Type 'STOP' to end)")
|
|
185
|
+
await agent.prompt("Researcher", default_prompt="STOP")
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
if __name__ == "__main__":
|
|
189
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
from fast_agent import FastAgent
|
|
4
|
+
|
|
5
|
+
# from rich import print
|
|
6
|
+
|
|
7
|
+
agents = FastAgent(name="Researcher Agent")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@agents.agent(
|
|
11
|
+
"Researcher",
|
|
12
|
+
instruction="""
|
|
13
|
+
You are a research assistant, with access to internet search (via Brave),
|
|
14
|
+
website fetch, a python interpreter (you can install packages with uv) and a filesystem.
|
|
15
|
+
Use the current working directory to save and create files with both the Interpreter and Filesystem tools.
|
|
16
|
+
The interpreter has numpy, pandas, matplotlib and seaborn already installed
|
|
17
|
+
""",
|
|
18
|
+
servers=["brave", "interpreter", "filesystem", "fetch"],
|
|
19
|
+
)
|
|
20
|
+
async def main() -> None:
|
|
21
|
+
research_prompt = """
|
|
22
|
+
Produce an investment report for the company Eutelsat. The final report should be saved in the filesystem in markdown format, and
|
|
23
|
+
contain at least the following:
|
|
24
|
+
1 - A brief description of the company
|
|
25
|
+
2 - Current financial position (find data, create and incorporate charts)
|
|
26
|
+
3 - A PESTLE analysis
|
|
27
|
+
4 - An investment thesis for the next 3 years. Include both 'buy side' and 'sell side' arguments, and a final
|
|
28
|
+
summary and recommendation.
|
|
29
|
+
Todays date is 15 February 2025. Include the main data sources consulted in presenting the report.""" # noqa: F841
|
|
30
|
+
|
|
31
|
+
async with agents.run() as agent:
|
|
32
|
+
await agent.prompt()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == "__main__":
|
|
36
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
.PHONY: all
|
|
2
|
+
|
|
3
|
+
build:
|
|
4
|
+
docker compose build
|
|
5
|
+
|
|
6
|
+
up:
|
|
7
|
+
docker compose up -d
|
|
8
|
+
|
|
9
|
+
logs:
|
|
10
|
+
docker compose logs -f
|
|
11
|
+
|
|
12
|
+
tensorzero-logs:
|
|
13
|
+
docker compose logs -f gateway
|
|
14
|
+
|
|
15
|
+
mcp-logs:
|
|
16
|
+
docker compose logs -f mcp-server
|
|
17
|
+
|
|
18
|
+
minio-logs:
|
|
19
|
+
docker compose logs -f minio
|
|
20
|
+
|
|
21
|
+
stop:
|
|
22
|
+
docker compose stop
|
|
23
|
+
|
|
24
|
+
agent:
|
|
25
|
+
uv run agent.py --model=tensorzero.test_chat
|
|
26
|
+
|
|
27
|
+
simple-agent:
|
|
28
|
+
uv run simple_agent.py --model=tensorzero.simple_chat
|
|
29
|
+
|
|
30
|
+
image-test:
|
|
31
|
+
uv run image_demo.py
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# About the tensorzero / fast-agent integration
|
|
2
|
+
|
|
3
|
+
[TensorZero](https://www.tensorzero.com/) is an open source project designed to help LLM application developers rapidly improve their inference calls. Its core features include:
|
|
4
|
+
|
|
5
|
+
- A uniform inference interface to all leading LLM platforms.
|
|
6
|
+
- The ability to dynamic route to different platforms and program failovers.
|
|
7
|
+
- Automated parameter tuning and training
|
|
8
|
+
- Advance templating features for your system prompts
|
|
9
|
+
- Organization of LLM inference data into a Clickhouse DB allowing for sophisticated downstream analytics
|
|
10
|
+
- A bunch of other good stuff is always in development
|
|
11
|
+
|
|
12
|
+
`tensorzero` is powerful heavy, so we provide here a quickstart example that combines the basic components of `fast-agent`, an MCP server, `tensorzero`, and other supporting services into a cohesive whole.
|
|
13
|
+
|
|
14
|
+
## Quickstart guide
|
|
15
|
+
|
|
16
|
+
- Install `fast-agent` with the `[tensorzero]` dependency e.g. `uv pip install -U fast-agent-mcp[tensorzero]`
|
|
17
|
+
- Build and activate the `uv` `fast-agent` environment
|
|
18
|
+
- Ensure that ports `3000`, `4000`, `8000`, `9000`, and `9001` are unallocated before running this demo.
|
|
19
|
+
- Run `cp .env.sample .env` and then drop in at least one of `OPENAI_API_KEY` or `ANTHROPIC_API_KEY`. Make sure the accounts are funded.
|
|
20
|
+
- `make up`
|
|
21
|
+
- `make agent`
|
|
22
|
+
|
|
23
|
+
The demo test's our implementation's ability to:
|
|
24
|
+
|
|
25
|
+
- Implement the T0 model gateway as an inference backend
|
|
26
|
+
- Implement T0's dynamic templating feature
|
|
27
|
+
- Have in-conversation memory
|
|
28
|
+
- Describe and execute tool calls
|
|
29
|
+
- Remember previous tool calls
|
|
30
|
+
|
|
31
|
+
A version of a conversation to test all of this could be:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Hi.
|
|
35
|
+
|
|
36
|
+
Tell me a poem.
|
|
37
|
+
|
|
38
|
+
Do you have any tools that you can use?
|
|
39
|
+
|
|
40
|
+
Please demonstrate the use of that tool on your last response.
|
|
41
|
+
|
|
42
|
+
Please summarize the conversation so far.
|
|
43
|
+
|
|
44
|
+
What tool calls have you executed in this session, and what were their results?
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Multimodal support
|
|
48
|
+
|
|
49
|
+
Run `make image-test` to test the gateway's ability to handle base64-encoded image data
|
|
50
|
+
|
|
51
|
+
## Development notes:
|
|
52
|
+
|
|
53
|
+
- `make stop` will stop the MCP server and the tensorzero server
|
|
54
|
+
- `make tenzorzero-logs` will tail the tensorzero server logs
|
|
55
|
+
- `make mcp-logs` will tail the MCP server logs
|
|
56
|
+
- Generic `make logs` dumps all log output from all services to terminal
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
from fast_agent import FastAgent
|
|
4
|
+
from fast_agent.llm.request_params import RequestParams
|
|
5
|
+
|
|
6
|
+
# Explicitly provide the path to the config file in the current directory
|
|
7
|
+
CONFIG_FILE = "fastagent.config.yaml"
|
|
8
|
+
fast = FastAgent("fast-agent example", config_path=CONFIG_FILE, ignore_unknown_args=True)
|
|
9
|
+
|
|
10
|
+
# Define T0 system variables here
|
|
11
|
+
my_t0_system_vars = {
|
|
12
|
+
"TEST_VARIABLE_1": "Roses are red",
|
|
13
|
+
"TEST_VARIABLE_2": "Violets are blue",
|
|
14
|
+
"TEST_VARIABLE_3": "Sugar is sweet",
|
|
15
|
+
"TEST_VARIABLE_4": "Vibe code responsibly 👍",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@fast.agent(
|
|
20
|
+
name="default",
|
|
21
|
+
instruction="""
|
|
22
|
+
You are an agent dedicated to helping developers understand the relationship between TensoZero and fast-agent. If the user makes a request
|
|
23
|
+
that requires you to invoke the test tools, please do so. When you use the tool, describe your rationale for doing so.
|
|
24
|
+
""",
|
|
25
|
+
servers=["tester"],
|
|
26
|
+
request_params=RequestParams(template_vars=my_t0_system_vars),
|
|
27
|
+
)
|
|
28
|
+
async def main():
|
|
29
|
+
async with fast.run() as agent_app: # Get the AgentApp wrapper
|
|
30
|
+
print("\nStarting interactive session with template_vars set via decorator...")
|
|
31
|
+
await agent_app.interactive()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
if __name__ == "__main__":
|
|
35
|
+
asyncio.run(main()) # type: ignore
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# This is a simplified example for learning purposes. Do not use this in production.
|
|
2
|
+
# For production-ready deployments, see: https://www.tensorzero.com/docs/gateway/deployment
|
|
3
|
+
|
|
4
|
+
# Top-level volumes definition
|
|
5
|
+
volumes:
|
|
6
|
+
minio_data: {}
|
|
7
|
+
|
|
8
|
+
services:
|
|
9
|
+
clickhouse:
|
|
10
|
+
image: clickhouse/clickhouse-server:24.12-alpine
|
|
11
|
+
environment:
|
|
12
|
+
CLICKHOUSE_USER: chuser
|
|
13
|
+
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
|
|
14
|
+
CLICKHOUSE_PASSWORD: chpassword
|
|
15
|
+
ports:
|
|
16
|
+
- "8123:8123"
|
|
17
|
+
healthcheck:
|
|
18
|
+
test: wget --spider --tries 1 http://chuser:chpassword@clickhouse:8123/ping
|
|
19
|
+
start_period: 30s
|
|
20
|
+
start_interval: 1s
|
|
21
|
+
timeout: 1s
|
|
22
|
+
|
|
23
|
+
gateway:
|
|
24
|
+
image: tensorzero/gateway
|
|
25
|
+
volumes:
|
|
26
|
+
- ./tensorzero_config:/app/config:ro
|
|
27
|
+
env_file:
|
|
28
|
+
- ./.env
|
|
29
|
+
command: --config-file /app/config/tensorzero.toml
|
|
30
|
+
environment: # WARNING: Insecure default credentials for local testing ONLY. Don't send this to production.
|
|
31
|
+
TENSORZERO_CLICKHOUSE_URL: http://chuser:chpassword@clickhouse:8123/tensorzero
|
|
32
|
+
S3_ACCESS_KEY_ID: user
|
|
33
|
+
S3_SECRET_ACCESS_KEY: password
|
|
34
|
+
ports:
|
|
35
|
+
- "3000:3000"
|
|
36
|
+
extra_hosts:
|
|
37
|
+
- "host.docker.internal:host-gateway"
|
|
38
|
+
depends_on:
|
|
39
|
+
clickhouse:
|
|
40
|
+
condition: service_healthy
|
|
41
|
+
minio:
|
|
42
|
+
condition: service_healthy
|
|
43
|
+
mcp-server:
|
|
44
|
+
condition: service_healthy
|
|
45
|
+
|
|
46
|
+
gateway-ui:
|
|
47
|
+
image: tensorzero/ui
|
|
48
|
+
volumes:
|
|
49
|
+
- ./tensorzero_config:/app/config:ro
|
|
50
|
+
env_file:
|
|
51
|
+
- ./.env
|
|
52
|
+
command: --config-file /app/config/tensorzero.toml
|
|
53
|
+
environment:
|
|
54
|
+
TENSORZERO_CLICKHOUSE_URL: http://chuser:chpassword@clickhouse:8123/tensorzero
|
|
55
|
+
TENSORZERO_GATEWAY_URL: http://gateway:3000
|
|
56
|
+
S3_ACCESS_KEY_ID: user
|
|
57
|
+
S3_SECRET_ACCESS_KEY: password
|
|
58
|
+
ports:
|
|
59
|
+
- "4000:4000"
|
|
60
|
+
depends_on:
|
|
61
|
+
clickhouse:
|
|
62
|
+
condition: service_healthy
|
|
63
|
+
|
|
64
|
+
mcp-server:
|
|
65
|
+
build:
|
|
66
|
+
context: ./mcp_server
|
|
67
|
+
dockerfile: Dockerfile
|
|
68
|
+
working_dir: /app
|
|
69
|
+
volumes:
|
|
70
|
+
- ./mcp_server:/app
|
|
71
|
+
ports:
|
|
72
|
+
- "8000:8000"
|
|
73
|
+
depends_on:
|
|
74
|
+
minio:
|
|
75
|
+
condition: service_healthy
|
|
76
|
+
healthcheck:
|
|
77
|
+
test:
|
|
78
|
+
[
|
|
79
|
+
"CMD",
|
|
80
|
+
"wget",
|
|
81
|
+
"--spider",
|
|
82
|
+
"--tries=1",
|
|
83
|
+
"http://localhost:8000/t0-example-server/sse",
|
|
84
|
+
]
|
|
85
|
+
interval: 10s
|
|
86
|
+
timeout: 5s
|
|
87
|
+
retries: 12
|
|
88
|
+
start_period: 20s
|
|
89
|
+
|
|
90
|
+
minio:
|
|
91
|
+
image: minio/minio:latest
|
|
92
|
+
ports:
|
|
93
|
+
- "9000:9000" # API port
|
|
94
|
+
- "9001:9001" # Console port
|
|
95
|
+
volumes:
|
|
96
|
+
- minio_data:/data
|
|
97
|
+
environment: # WARNING: Insecure default credentials for local testing ONLY.
|
|
98
|
+
MINIO_ROOT_USER: user
|
|
99
|
+
MINIO_ROOT_PASSWORD: password
|
|
100
|
+
command: server /data --console-address :9001
|
|
101
|
+
healthcheck:
|
|
102
|
+
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
|
103
|
+
interval: 30s
|
|
104
|
+
timeout: 20s
|
|
105
|
+
retries: 3
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
default_model: haiku
|
|
2
|
+
|
|
3
|
+
tensorzero:
|
|
4
|
+
base_url: http://localhost:3000
|
|
5
|
+
api_key: verysecret
|
|
6
|
+
|
|
7
|
+
logger:
|
|
8
|
+
level: "info"
|
|
9
|
+
progress_display: true
|
|
10
|
+
show_chat: true
|
|
11
|
+
show_tools: true
|
|
12
|
+
truncate_tools: true
|
|
13
|
+
|
|
14
|
+
mcp:
|
|
15
|
+
servers:
|
|
16
|
+
tester:
|
|
17
|
+
transport: "sse"
|
|
18
|
+
url: "http://localhost:8000/t0-example-server/sse"
|
|
19
|
+
read_transport_sse_timeout_seconds: 300
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import base64
|
|
3
|
+
import mimetypes
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Union
|
|
6
|
+
|
|
7
|
+
from mcp.types import ImageContent, TextContent
|
|
8
|
+
|
|
9
|
+
from fast_agent import FastAgent
|
|
10
|
+
from fast_agent.core.prompt import Prompt
|
|
11
|
+
from fast_agent.llm.request_params import RequestParams
|
|
12
|
+
|
|
13
|
+
AGENT_NAME = "tensorzero_image_tester"
|
|
14
|
+
TENSORZERO_MODEL = "tensorzero.test_chat"
|
|
15
|
+
TEXT_PROMPT = (
|
|
16
|
+
"Provide a description of the similarities and differences between these three images."
|
|
17
|
+
)
|
|
18
|
+
LOCAL_IMAGE_FILES = [
|
|
19
|
+
Path("./demo_images/clam.jpg"),
|
|
20
|
+
Path("./demo_images/shrimp.png"),
|
|
21
|
+
Path("./demo_images/crab.png"),
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
MY_T0_SYSTEM_VARS = {
|
|
25
|
+
"TEST_VARIABLE_1": "Roses are red",
|
|
26
|
+
"TEST_VARIABLE_2": "Violets are blue",
|
|
27
|
+
"TEST_VARIABLE_3": "Sugar is sweet",
|
|
28
|
+
"TEST_VARIABLE_4": "Vibe code responsibly 👍",
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fast = FastAgent("TensorZero Image Demo - Base64 Only")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@fast.agent(
|
|
35
|
+
name=AGENT_NAME,
|
|
36
|
+
model=TENSORZERO_MODEL,
|
|
37
|
+
request_params=RequestParams(template_vars=MY_T0_SYSTEM_VARS),
|
|
38
|
+
)
|
|
39
|
+
async def main():
|
|
40
|
+
content_parts: list[Union[TextContent, ImageContent]] = []
|
|
41
|
+
content_parts.append(TextContent(type="text", text=TEXT_PROMPT))
|
|
42
|
+
|
|
43
|
+
for file_path in LOCAL_IMAGE_FILES:
|
|
44
|
+
mime_type, _ = mimetypes.guess_type(file_path)
|
|
45
|
+
if not mime_type or not mime_type.startswith("image/"):
|
|
46
|
+
ext = file_path.suffix.lower()
|
|
47
|
+
if ext == ".jpg" or ext == ".jpeg":
|
|
48
|
+
mime_type = "image/jpeg"
|
|
49
|
+
elif ext == ".png":
|
|
50
|
+
mime_type = "image/png"
|
|
51
|
+
if mime_type is None:
|
|
52
|
+
mime_type = "image/png" # Default fallback if still None
|
|
53
|
+
|
|
54
|
+
with open(file_path, "rb") as image_file:
|
|
55
|
+
image_bytes = image_file.read()
|
|
56
|
+
|
|
57
|
+
encoded_data = base64.b64encode(image_bytes).decode("utf-8")
|
|
58
|
+
content_parts.append(ImageContent(type="image", mimeType=mime_type, data=encoded_data))
|
|
59
|
+
|
|
60
|
+
message = Prompt.user(*content_parts)
|
|
61
|
+
async with fast.run() as agent_app:
|
|
62
|
+
agent = getattr(agent_app, AGENT_NAME)
|
|
63
|
+
await agent.send(message)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
if __name__ == "__main__":
|
|
67
|
+
asyncio.run(main()) # type: ignore
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
FROM python:3.12-slim
|
|
2
|
+
WORKDIR /app
|
|
3
|
+
|
|
4
|
+
RUN apt-get update && apt-get install -y curl wget && \
|
|
5
|
+
wget https://dl.min.io/client/mc/release/linux-amd64/mc -O /usr/local/bin/mc && \
|
|
6
|
+
chmod +x /usr/local/bin/mc && \
|
|
7
|
+
apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
8
|
+
|
|
9
|
+
RUN pip install uv
|
|
10
|
+
|
|
11
|
+
# Copy dependency files only
|
|
12
|
+
COPY pyproject.toml /tmp/
|
|
13
|
+
#COPY uv.lock /tmp/
|
|
14
|
+
|
|
15
|
+
# Install dependencies
|
|
16
|
+
WORKDIR /tmp
|
|
17
|
+
RUN uv pip install --system .
|
|
18
|
+
|
|
19
|
+
# Switch back to /app (this will be overridden by volume mount)
|
|
20
|
+
WORKDIR /app
|
|
21
|
+
|
|
22
|
+
# These files will come from the volume mount at runtime
|
|
23
|
+
EXPOSE 8000
|
|
24
|
+
ENTRYPOINT ["/app/entrypoint.sh"]
|
|
25
|
+
CMD ["uvicorn", "mcp_server:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
echo "Entrypoint: Waiting for MinIO to be healthy..."
|
|
4
|
+
|
|
5
|
+
# Simple loop to check MinIO health endpoint (within the Docker network)
|
|
6
|
+
# Adjust timeout as needed
|
|
7
|
+
TIMEOUT=60
|
|
8
|
+
START_TIME=$(date +%s)
|
|
9
|
+
while ! curl -sf http://minio:9000/minio/health/live > /dev/null; do
|
|
10
|
+
CURRENT_TIME=$(date +%s)
|
|
11
|
+
ELAPSED=$(($CURRENT_TIME - $START_TIME))
|
|
12
|
+
if [ $ELAPSED -ge $TIMEOUT ]; then
|
|
13
|
+
echo "Entrypoint: Timeout waiting for MinIO!"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
echo "Entrypoint: MinIO not ready, sleeping..."
|
|
17
|
+
sleep 2
|
|
18
|
+
done
|
|
19
|
+
echo "Entrypoint: MinIO is healthy."
|
|
20
|
+
|
|
21
|
+
echo "Entrypoint: Configuring mc client and creating bucket 'tensorzero'..."
|
|
22
|
+
|
|
23
|
+
# Configure mc to talk to the MinIO server using the service name
|
|
24
|
+
# Use --insecure because we are using http
|
|
25
|
+
mc --insecure alias set local http://minio:9000 user password
|
|
26
|
+
|
|
27
|
+
# Create the bucket if it doesn't exist
|
|
28
|
+
# Use --insecure because we are using http
|
|
29
|
+
mc --insecure ls local/tensorzero > /dev/null 2>&1 || mc --insecure mb local/tensorzero
|
|
30
|
+
|
|
31
|
+
echo "Entrypoint: Bucket 'tensorzero' check/creation complete."
|
|
32
|
+
|
|
33
|
+
echo "Entrypoint: Executing the main container command: $@"
|
|
34
|
+
|
|
35
|
+
exec "$@"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import uvicorn
|
|
2
|
+
from mcp.server.fastmcp.server import FastMCP
|
|
3
|
+
from starlette.applications import Starlette
|
|
4
|
+
from starlette.routing import Mount
|
|
5
|
+
|
|
6
|
+
SERVER_PATH = "t0-example-server"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
mcp_instance = FastMCP(name="t0-example-server")
|
|
10
|
+
mcp_instance.settings.message_path = f"/{SERVER_PATH}/messages/"
|
|
11
|
+
mcp_instance.settings.sse_path = f"/{SERVER_PATH}/sse"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@mcp_instance.tool()
|
|
15
|
+
def example_tool(input_text: str) -> str:
|
|
16
|
+
"""Example tool that reverses the text of a given string."""
|
|
17
|
+
reversed_text = input_text[::-1]
|
|
18
|
+
return reversed_text
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
app = Starlette(
|
|
22
|
+
routes=[
|
|
23
|
+
Mount("/", app=mcp_instance.sse_app()),
|
|
24
|
+
]
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if __name__ == "__main__":
|
|
28
|
+
print(f"Starting minimal MCP server ({mcp_instance.name}) on http://127.0.0.1:8000")
|
|
29
|
+
print(f" -> SSE endpoint: {mcp_instance.settings.sse_path}")
|
|
30
|
+
print(f" -> Message endpoint: {mcp_instance.settings.message_path}")
|
|
31
|
+
uvicorn.run(app, host="127.0.0.1", port=8000)
|