mirror of
https://github.com/temporal-community/temporal-ai-agent.git
synced 2026-03-16 22:48:09 +01:00
Model Context Protocol (MCP) support with new use case (#42)
* initial mcp * food ordering with mcp * prompt eng * splitting out goals and updating docs * a diff so I can get tests from codex * a diff so I can get tests from codex * oops, missing files * tests, file formatting * readme and setup updates * setup.md link fixes * readme change * readme change * readme change * stripe food setup script * single agent mode default * prompt engineering for better multi agent performance * performance should be greatly improved * Update goals/finance.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update activities/tool_activities.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * co-pilot PR suggested this change, and now fixed it * stronger wording around json format response * formatting * moved docs to dir * moved image assets under docs * cleanup env example, stripe guidance * cleanup --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
1811e4cf59
commit
5d55a9fe80
33
tools/food/add_to_cart.py
Normal file
33
tools/food/add_to_cart.py
Normal file
@@ -0,0 +1,33 @@
|
||||
def add_to_cart(args: dict) -> dict:
|
||||
"""
|
||||
Simple stateless cart tool for demo purposes.
|
||||
In production, this would use proper session storage or database.
|
||||
"""
|
||||
customer_email = args.get("customer_email")
|
||||
item_name = args.get("item_name")
|
||||
item_price = float(args.get("item_price", 0))
|
||||
quantity = int(args.get("quantity", 1))
|
||||
stripe_product_id = args.get("stripe_product_id")
|
||||
|
||||
# Basic validation
|
||||
if not customer_email:
|
||||
return {"error": "Customer email is required"}
|
||||
if not item_name:
|
||||
return {"error": "Item name is required"}
|
||||
if item_price <= 0:
|
||||
return {"error": "Item price must be greater than 0"}
|
||||
if quantity <= 0:
|
||||
return {"error": "Quantity must be greater than 0"}
|
||||
|
||||
# For demo purposes, just acknowledge the addition
|
||||
# In a real system, this would store to session/database
|
||||
return {
|
||||
"status": "success",
|
||||
"message": f"Added {quantity} x {item_name} (${item_price}) to cart for {customer_email}",
|
||||
"item_added": {
|
||||
"name": item_name,
|
||||
"price": item_price,
|
||||
"quantity": quantity,
|
||||
"stripe_product_id": stripe_product_id,
|
||||
},
|
||||
}
|
||||
48
tools/food/setup/archive_food_products.py
Normal file
48
tools/food/setup/archive_food_products.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
|
||||
def delete_food_ordering_products():
|
||||
"""Archive all Stripe products with metadata use_case = food_ordering_demo (since products with prices cannot be deleted)."""
|
||||
import stripe
|
||||
|
||||
# Load environment variables and configure stripe
|
||||
load_dotenv(override=True)
|
||||
stripe.api_key = os.getenv("STRIPE_API_KEY")
|
||||
|
||||
if not stripe.api_key:
|
||||
print("Error: STRIPE_API_KEY not found in environment variables")
|
||||
return
|
||||
|
||||
try:
|
||||
# Search for products with food_ordering_demo use_case
|
||||
products = stripe.Product.search(
|
||||
query="metadata['use_case']:'food_ordering_demo'", limit=100
|
||||
)
|
||||
|
||||
if not products.data:
|
||||
print("No products found with use_case = food_ordering_demo")
|
||||
return
|
||||
|
||||
archived_count = 0
|
||||
|
||||
for product in products.data:
|
||||
try:
|
||||
# Archive the product (set active=False)
|
||||
stripe.Product.modify(product.id, active=False)
|
||||
print(f"Archived product: {product.name} (ID: {product.id})")
|
||||
archived_count += 1
|
||||
|
||||
except Exception as e:
|
||||
print(
|
||||
f"Error archiving product {product.name} (ID: {product.id}): {str(e)}"
|
||||
)
|
||||
|
||||
print(f"\nSuccessfully archived {archived_count} products")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error searching for products: {str(e)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
delete_food_ordering_products()
|
||||
92
tools/food/setup/create_stripe_products.py
Normal file
92
tools/food/setup/create_stripe_products.py
Normal file
@@ -0,0 +1,92 @@
|
||||
import json
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
|
||||
def create_stripe_products():
|
||||
"""Create Stripe products and prices from the stripe_pizza_products.json file."""
|
||||
import stripe
|
||||
|
||||
# Load environment variables and configure stripe
|
||||
load_dotenv(override=True)
|
||||
stripe.api_key = os.getenv("STRIPE_API_KEY")
|
||||
|
||||
if not stripe.api_key:
|
||||
print("Error: STRIPE_API_KEY not found in environment variables")
|
||||
return
|
||||
|
||||
# Load the products data
|
||||
current_dir = os.path.dirname(__file__)
|
||||
products_file = os.path.join(current_dir, "stripe_pizza_products.json")
|
||||
|
||||
with open(products_file, "r") as f:
|
||||
products_data = json.load(f)
|
||||
|
||||
# Filter for food ordering demo products only
|
||||
food_products = [
|
||||
p
|
||||
for p in products_data
|
||||
if p.get("metadata", {}).get("use_case") == "food_ordering_demo"
|
||||
]
|
||||
|
||||
created_products = []
|
||||
|
||||
for product_data in food_products:
|
||||
try:
|
||||
# Create the product with relevant fields
|
||||
product = stripe.Product.create(
|
||||
name=product_data["name"],
|
||||
description=product_data.get("description"),
|
||||
images=product_data.get("images", []),
|
||||
metadata=product_data.get("metadata", {}),
|
||||
type=product_data.get("type", "service"),
|
||||
active=product_data.get("active", True),
|
||||
)
|
||||
|
||||
# Create price for the product if price_info exists
|
||||
price_info = product_data.get("price_info")
|
||||
if price_info:
|
||||
price_amount = price_info.get("amount")
|
||||
currency = price_info.get("currency", "usd")
|
||||
|
||||
price = stripe.Price.create(
|
||||
currency=currency, unit_amount=price_amount, product=product.id
|
||||
)
|
||||
|
||||
# Set this price as the default price for the product
|
||||
stripe.Product.modify(product.id, default_price=price.id)
|
||||
|
||||
print(
|
||||
f"Created product: {product.name} (ID: {product.id}) with default price ${price_amount/100:.2f}"
|
||||
)
|
||||
|
||||
created_products.append(
|
||||
{
|
||||
"name": product.name,
|
||||
"id": product.id,
|
||||
"price_id": price.id,
|
||||
"price_amount": price_amount,
|
||||
"original_id": product_data["id"],
|
||||
}
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f"Created product: {product.name} (ID: {product.id}) - No price defined"
|
||||
)
|
||||
created_products.append(
|
||||
{
|
||||
"name": product.name,
|
||||
"id": product.id,
|
||||
"original_id": product_data["id"],
|
||||
}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error creating product {product_data['name']}: {str(e)}")
|
||||
|
||||
print(f"\nSuccessfully created {len(created_products)} products with prices")
|
||||
return created_products
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
create_stripe_products()
|
||||
188
tools/food/setup/stripe_pizza_products.json
Normal file
188
tools/food/setup/stripe_pizza_products.json
Normal file
@@ -0,0 +1,188 @@
|
||||
[
|
||||
{
|
||||
"id": "prod_SSWirxxS5A8gcT",
|
||||
"object": "product",
|
||||
"active": true,
|
||||
"attributes": [],
|
||||
"created": 1749360061,
|
||||
"default_price": "price_1RXbfGKVZbzw7QA57Mj1akGI",
|
||||
"description": "A large size bottle of cola.",
|
||||
"images": [
|
||||
"https://files.stripe.com/links/MDB8YWNjdF8xTkJPTHVLVlpienc3UUE1fGZsX3Rlc3RfbDJxckJKMDRnT1dDc253OHlZNWNkZkY5006Xg07kHT"
|
||||
],
|
||||
"livemode": false,
|
||||
"marketing_features": [],
|
||||
"metadata": {
|
||||
"use_case": "food_ordering_demo"
|
||||
},
|
||||
"name": "Soda",
|
||||
"price_info": {
|
||||
"amount": 349,
|
||||
"currency": "usd"
|
||||
},
|
||||
"package_dimensions": null,
|
||||
"shippable": null,
|
||||
"statement_descriptor": null,
|
||||
"tax_code": null,
|
||||
"type": "service",
|
||||
"unit_label": null,
|
||||
"updated": 1749360062,
|
||||
"url": null
|
||||
},
|
||||
{
|
||||
"id": "prod_SSWhxv3tUy1YOG",
|
||||
"object": "product",
|
||||
"active": true,
|
||||
"attributes": [],
|
||||
"created": 1749359978,
|
||||
"default_price": "price_1RXbdvKVZbzw7QA5ARomQvaf",
|
||||
"description": "Our warm, crusty bread is generously spread with a savory garlic butter and toasted to golden perfection. It's the ideal aromatic and flavorful side to accompany your main course.",
|
||||
"images": [
|
||||
"https://files.stripe.com/links/MDB8YWNjdF8xTkJPTHVLVlpienc3UUE1fGZsX3Rlc3RfWTdIZTBkUjNZNFQ1ZEhSVG9nRnduY1pS00XVgLRRZD"
|
||||
],
|
||||
"livemode": false,
|
||||
"marketing_features": [],
|
||||
"metadata": {
|
||||
"use_case": "food_ordering_demo"
|
||||
},
|
||||
"name": "Garlic Bread",
|
||||
"price_info": {
|
||||
"amount": 799,
|
||||
"currency": "usd"
|
||||
},
|
||||
"package_dimensions": null,
|
||||
"shippable": null,
|
||||
"statement_descriptor": null,
|
||||
"tax_code": null,
|
||||
"type": "service",
|
||||
"unit_label": null,
|
||||
"updated": 1749360084,
|
||||
"url": null
|
||||
},
|
||||
{
|
||||
"id": "prod_SSWgXa5bwUFCJs",
|
||||
"object": "product",
|
||||
"active": true,
|
||||
"attributes": [],
|
||||
"created": 1749359922,
|
||||
"default_price": "price_1RXbd0KVZbzw7QA5Nq36vdLW",
|
||||
"description": "A tribute to Italian simplicity, this pizza is topped with fresh mozzarella, a vibrant tomato sauce, and fragrant basil leaves. Each bite delivers a clean and authentic taste of Italy's most famous flavors.",
|
||||
"images": [
|
||||
"https://files.stripe.com/links/MDB8YWNjdF8xTkJPTHVLVlpienc3UUE1fGZsX3Rlc3RfamdmTXBFbzY0TW9rS2N0c2g0Tml2SERL00Evl60Ttq"
|
||||
],
|
||||
"livemode": false,
|
||||
"marketing_features": [],
|
||||
"metadata": {
|
||||
"use_case": "food_ordering_demo"
|
||||
},
|
||||
"name": "Margherita Pizza",
|
||||
"price_info": {
|
||||
"amount": 1699,
|
||||
"currency": "usd"
|
||||
},
|
||||
"package_dimensions": null,
|
||||
"shippable": null,
|
||||
"statement_descriptor": null,
|
||||
"tax_code": null,
|
||||
"type": "service",
|
||||
"unit_label": null,
|
||||
"updated": 1749359998,
|
||||
"url": null
|
||||
},
|
||||
{
|
||||
"id": "prod_SSWf738UqIJzzi",
|
||||
"object": "product",
|
||||
"active": true,
|
||||
"attributes": [],
|
||||
"created": 1749359845,
|
||||
"default_price": "price_1RXbbmKVZbzw7QA53EkjV2nB",
|
||||
"description": "A timeless classic featuring a generous layer of savory pepperoni over rich tomato sauce and melted mozzarella cheese. It's the perfect choice for those who love a bold, meaty flavor on a perfectly baked crust.",
|
||||
"images": [
|
||||
"https://files.stripe.com/links/MDB8YWNjdF8xTkJPTHVLVlpienc3UUE1fGZsX3Rlc3RfcGRHc0c4cEZYWmR2bm0zOHBOa0FWMk5t008QmCJoWr"
|
||||
],
|
||||
"livemode": false,
|
||||
"marketing_features": [],
|
||||
"metadata": {
|
||||
"use_case": "food_ordering_demo"
|
||||
},
|
||||
"name": "Pepperoni Pizza",
|
||||
"price_info": {
|
||||
"amount": 2299,
|
||||
"currency": "usd"
|
||||
},
|
||||
"package_dimensions": null,
|
||||
"shippable": null,
|
||||
"statement_descriptor": null,
|
||||
"tax_code": null,
|
||||
"type": "service",
|
||||
"unit_label": null,
|
||||
"updated": 1749359846,
|
||||
"url": null
|
||||
},
|
||||
{
|
||||
"id": "prod_SGMXBnatLlkJ4d",
|
||||
"object": "product",
|
||||
"active": true,
|
||||
"attributes": [],
|
||||
"created": 1746554502,
|
||||
"default_price": "price_1RLpoJKVZbzw7QA5ra76Fk6g",
|
||||
"description": null,
|
||||
"images": [],
|
||||
"livemode": false,
|
||||
"marketing_features": [],
|
||||
"metadata": {},
|
||||
"name": "ACME Scooter Token",
|
||||
"package_dimensions": null,
|
||||
"shippable": null,
|
||||
"statement_descriptor": null,
|
||||
"tax_code": null,
|
||||
"type": "service",
|
||||
"unit_label": null,
|
||||
"updated": 1746554503,
|
||||
"url": null
|
||||
},
|
||||
{
|
||||
"id": "prod_NxJPcqTWzXk45K",
|
||||
"object": "product",
|
||||
"active": true,
|
||||
"attributes": [],
|
||||
"created": 1684961969,
|
||||
"default_price": null,
|
||||
"description": "$12/Month subscription",
|
||||
"images": [],
|
||||
"livemode": false,
|
||||
"marketing_features": [],
|
||||
"metadata": {},
|
||||
"name": "Starter Subscription",
|
||||
"package_dimensions": null,
|
||||
"shippable": null,
|
||||
"statement_descriptor": null,
|
||||
"tax_code": null,
|
||||
"type": "service",
|
||||
"unit_label": null,
|
||||
"updated": 1684961969,
|
||||
"url": null
|
||||
},
|
||||
{
|
||||
"id": "prod_NxJ4KvyENd0uUu",
|
||||
"object": "product",
|
||||
"active": true,
|
||||
"attributes": [],
|
||||
"created": 1684960731,
|
||||
"default_price": null,
|
||||
"description": "Created with the Stripe CLI",
|
||||
"images": [],
|
||||
"livemode": false,
|
||||
"marketing_features": [],
|
||||
"metadata": {},
|
||||
"name": "Temporal Money Transfer",
|
||||
"package_dimensions": null,
|
||||
"shippable": null,
|
||||
"statement_descriptor": null,
|
||||
"tax_code": null,
|
||||
"type": "service",
|
||||
"unit_label": null,
|
||||
"updated": 1684960731,
|
||||
"url": null
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user