-
Notifications
You must be signed in to change notification settings - Fork 768
feat: improve optimizer evaluator workflow for cloud #425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,8 +17,20 @@ | |
# The cycle continues until the letter meets a predefined quality standard. | ||
app = MCPApp(name="cover_letter_writer") | ||
|
||
|
||
async def example_usage(): | ||
@app.async_tool(name="cover_letter_writer_tool", | ||
description="This tool implements an evaluator-optimizer workflow for generating " | ||
"high-quality cover letters. It takes job postings, candidate details, " | ||
"and company information as input, then iteratively generates and refines " | ||
"cover letters until they meet excellent quality standards through " | ||
"automated evaluation and feedback.") | ||
async def example_usage( | ||
job_posting: str = "Software Engineer at LastMile AI. Responsibilities include developing AI systems, " | ||
"collaborating with cross-functional teams, and enhancing scalability. Skills required: " | ||
"Python, distributed systems, and machine learning.", | ||
candidate_details: str = "Alex Johnson, 3 years in machine learning, contributor to open-source AI projects, " | ||
"proficient in Python and TensorFlow. Motivated by building scalable AI systems to solve real-world problems.", | ||
company_information: str = "Look up from the LastMile AI About page: https://lastmileai.dev/about" | ||
): | ||
async with app.run() as cover_letter_app: | ||
context = cover_letter_app.context | ||
logger = cover_letter_app.logger | ||
|
@@ -61,27 +73,13 @@ async def example_usage(): | |
min_rating=QualityRating.EXCELLENT, | ||
) | ||
|
||
job_posting = ( | ||
"Software Engineer at LastMile AI. Responsibilities include developing AI systems, " | ||
"collaborating with cross-functional teams, and enhancing scalability. Skills required: " | ||
"Python, distributed systems, and machine learning." | ||
) | ||
candidate_details = ( | ||
"Alex Johnson, 3 years in machine learning, contributor to open-source AI projects, " | ||
"proficient in Python and TensorFlow. Motivated by building scalable AI systems to solve real-world problems." | ||
) | ||
|
||
# This should trigger a 'fetch' call to get the company information | ||
company_information = ( | ||
"Look up from the LastMile AI About page: https://lastmileai.dev/about" | ||
) | ||
|
||
result = await evaluator_optimizer.generate_str( | ||
message=f"Write a cover letter for the following job posting: {job_posting}\n\nCandidate Details: {candidate_details}\n\nCompany information: {company_information}", | ||
request_params=RequestParams(model="gpt-4o"), | ||
request_params=RequestParams(model="gpt-4.1"), | ||
) | ||
|
||
logger.info(f"{result}") | ||
logger.info(f"Generated cover letter: {result}") | ||
return result | ||
Comment on lines
+81
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid logging full generated content (PII/large payloads). The result may contain PII and can be very large. Log a preview and metadata instead. - logger.info(f"Generated cover letter: {result}")
+ logger.info(
+ "Generated cover letter",
+ preview=result[:200] + ("..." if len(result) > 200 else ""),
+ length=len(result),
+ )
🤖 Prompt for AI Agents
|
||
|
||
|
||
if __name__ == "__main__": | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,33 +1,42 @@ | ||||||
$schema: ../../../schema/mcp-agent.config.schema.json | ||||||
|
||||||
# Execution engine configuration | ||||||
execution_engine: asyncio | ||||||
|
||||||
# Logging configuration | ||||||
logger: | ||||||
type: console | ||||||
level: debug | ||||||
batch_size: 100 | ||||||
flush_interval: 2 | ||||||
max_queue_size: 2048 | ||||||
http_endpoint: | ||||||
http_headers: | ||||||
http_timeout: 5 | ||||||
type: console # Log output type (console, file, or http) | ||||||
level: debug # Logging level (debug, info, warning, error) | ||||||
batch_size: 100 # Number of logs to batch before sending | ||||||
flush_interval: 2 # Interval in seconds to flush logs | ||||||
max_queue_size: 2048 # Maximum queue size for buffered logs | ||||||
http_endpoint: # Optional: HTTP endpoint for remote logging | ||||||
http_headers: # Optional: Headers for HTTP logging | ||||||
http_timeout: 5 # Timeout for HTTP logging requests | ||||||
|
||||||
# MCP (Model Context Protocol) server configuration | ||||||
mcp: | ||||||
servers: | ||||||
# Fetch server: Enables web content fetching capabilities | ||||||
fetch: | ||||||
command: "uvx" | ||||||
args: ["mcp-server-fetch"] | ||||||
|
||||||
# Filesystem server: Provides file system access capabilities | ||||||
filesystem: | ||||||
command: "npx" | ||||||
args: ["-y", "@modelcontextprotocol/server-filesystem"] | ||||||
Comment on lines
+20
to
28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainPin MCP server versions and ensure runtime availability of uvx/npx. Unpinned npx/uvx pulls “latest” at runtime—supply‑chain and reproducibility risk. Pin versions and document that uvx/npx are present in the cloud image. - fetch:
- command: "uvx"
- args: ["mcp-server-fetch"]
+ fetch:
+ command: "uvx"
+ args: ["--from", "mcp-server-fetch==X.Y.Z", "mcp-server-fetch"]
@@
- filesystem:
- command: "npx"
- args: ["-y", "@modelcontextprotocol/server-filesystem"]
+ filesystem:
+ command: "npx"
+ args: ["-y", "@modelcontextprotocol/[email protected]"] Run-time check script to confirm availability: 🏁 Script executed: #!/bin/bash
command -v uvx && uvx --version
command -v npx && npx --version Length of output: 25 Pin MCP server versions and ensure uvx is present in the runtime image uvx not found in PATH; npx present at /usr/local/bin/npx (11.4.2).
- fetch:
- command: "uvx"
- args: ["mcp-server-fetch"]
+ fetch:
+ command: "uvx"
+ args: ["--from", "mcp-server-fetch==X.Y.Z", "mcp-server-fetch"]
@@
- filesystem:
- command: "npx"
- args: ["-y", "@modelcontextprotocol/server-filesystem"]
+ filesystem:
+ command: "npx"
+ args: ["-y", "@modelcontextprotocol/[email protected]"]
🤖 Prompt for AI Agents
|
||||||
|
||||||
# OpenAI configuration | ||||||
openai: | ||||||
# Secrets (API keys, etc.) are stored in an mcp_agent.secrets.yaml file which can be gitignored | ||||||
default_model: gpt-4o | ||||||
# API keys are stored in mcp_agent.secrets.yaml (gitignored for security) | ||||||
default_model: gpt-4.1 # Default model for OpenAI API calls | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Invalid model name 'gpt-4.1' - this model does not exist in OpenAI's API. This will cause all OpenAI API calls using the default model to fail with a model not found error. Should be changed to a valid OpenAI model name like 'gpt-4o' or 'gpt-4-turbo'.
Suggested change
Spotted by Diamond |
||||||
|
||||||
# OpenTelemetry (OTEL) configuration for distributed tracing | ||||||
otel: | ||||||
enabled: false | ||||||
exporters: ["console"] | ||||||
# If running jaeger locally, uncomment the following lines and add "otlp" to the exporters list | ||||||
enabled: false # Set to true to enable tracing | ||||||
exporters: ["console"] # Trace exporters (console, otlp) | ||||||
# Uncomment below to export traces to Jaeger running locally | ||||||
# otlp_settings: | ||||||
# endpoint: "http://localhost:4318/v1/traces" | ||||||
service_name: "WorkflowEvaluatorOptimizerExample" | ||||||
service_name: "WorkflowEvaluatorOptimizerExample" # Service name in traces |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,18 @@ | ||
$schema: ../../../schema/mcp-agent.config.schema.json | ||
|
||
# NOTE: You only need to configure ONE of the following API keys (OpenAI OR Anthropic) | ||
# Choose based on your preferred LLM provider | ||
|
||
Comment on lines
+3
to
+5
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainDocs say “OpenAI OR Anthropic,” but the workflow is hard‑wired to OpenAI. main.py uses OpenAIAugmentedLLM. If users only provide Anthropic keys (per this note), the run will fail. Either implement provider selection or tighten docs to “OpenAI only” for this example. Would you like a follow‑up patch to auto‑select OpenAI vs Anthropic based on configured secrets? 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== Show the secrets example file ==="
if [ -f examples/workflows/workflow_evaluator_optimizer/mcp_agent.secrets.yaml.example ]; then
sed -n '1,200p' examples/workflows/workflow_evaluator_optimizer/mcp_agent.secrets.yaml.example
else
echo "mcp_agent.secrets.yaml.example not found"
fi
echo
echo "=== Search repo for OpenAIAugmentedLLM ==="
rg -n --hidden --no-ignore-vcs -S "OpenAIAugmentedLLM" || true
echo
echo "=== Search repo for AugmentedLLM (generic) ==="
rg -n --hidden --no-ignore-vcs -S "AugmentedLLM" || true
echo
echo "=== Case-insensitive search for Anthropic ==="
rg -n --hidden --no-ignore-vcs -S -i "Anthropic" || true
echo
echo "=== Show main.py in workflow folder if present ==="
if [ -f examples/workflows/workflow_evaluator_optimizer/main.py ]; then
sed -n '1,300p' examples/workflows/workflow_evaluator_optimizer/main.py
else
echo "main.py not found in examples/workflows/workflow_evaluator_optimizer/"
fi
echo
echo "=== Search files in that workflow folder for OpenAI / Anthropic mentions ==="
rg -n --hidden --no-ignore-vcs -S -g 'examples/workflows/workflow_evaluator_optimizer/**' -i "OpenAI|openai|Anthropic|anthropic" || true Length of output: 264090 Fix docs/examples mismatch: example hard‑codes OpenAI while secrets/README say "OpenAI OR Anthropic" examples/workflows/workflow_evaluator_optimizer/mcp_agent.secrets.yaml.example (lines 3–16) and README.md state either provider is fine, but examples/workflows/workflow_evaluator_optimizer/main.py imports OpenAIAugmentedLLM (line 6) and sets llm_factory=OpenAIAugmentedLLM (line 72) — the example will fail if only Anthropic keys are configured. Either add runtime provider selection (use AnthropicAugmentedLLM when config.anthropic is present or resolve via the workflow factory) or change the example/docs to explicitly say "OpenAI only". 🤖 Prompt for AI Agents
|
||
# OpenAI Configuration (if using OpenAI models) | ||
# Create an API key at: https://platform.openai.com/api-keys | ||
openai: | ||
api_key: openai_api_key | ||
api_key: your-openai-api-key | ||
# For cloud deployment, use developer secrets: | ||
# api_key: !developer_secret OPENAI_API_KEY | ||
|
||
# Anthropic Configuration (if using Claude models) | ||
# Create an API key at: https://console.anthropic.com/settings/keys | ||
anthropic: | ||
api_key: anthropic_api_key | ||
api_key: your-anthropic-api-key | ||
# For cloud deployment, use developer secrets: | ||
# api_key: !developer_secret ANTHROPIC_API_KEY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify deploy slug matches the app/tool naming.
Command uses “cover-letter-writer”, app name is “cover_letter_writer”, tool is “cover_letter_writer_tool”. Confirm the expected slug for deploy.
🏁 Script executed:
Length of output: 866
Use snake_case deploy slug "cover_letter_writer"
main.py declares MCPApp(name="cover_letter_writer") and @app.async_tool(name="cover_letter_writer_tool"); README uses "cover-letter-writer". Update the deploy command in examples/workflows/workflow_evaluator_optimizer/README.md (lines 115–119) to use cover_letter_writer to match the code (see examples/workflows/workflow_evaluator_optimizer/main.py lines 18 and 20).
🤖 Prompt for AI Agents