Spaces:
Sleeping
Sleeping
File size: 4,632 Bytes
87edca7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
import gradio as gr
import requests
import os
from fpdf import FPDF
import uuid
import re
import matplotlib.pyplot as plt
# Load your Nebius API key and Folder ID from environment variables
NEBIUS_API_KEY = os.getenv("NEBIUS_API_KEY") or "YOUR_NEBIUS_API_KEY"
FOLDER_ID = os.getenv("FOLDER_ID") or "YOUR_FOLDER_ID"
def generate_meal(preferences, ingredients, time):
prompt = f"""
You're a smart kitchen agent.
Given:
- Dietary preferences: {preferences}
- Ingredients available: {ingredients}
- Time available: {time} minutes
Tasks:
1. Suggest one meal idea
2. Provide step-by-step recipe instructions
3. List missing ingredients (Shopping List)
4. Estimate nutrition (calories, protein, carbs, fat)
Output in this format:
Meal Name: ...
Steps:
1. ...
2. ...
Shopping List:
- ...
Nutrition:
- Calories: ... kcal
- Protein: ... g
- Carbs: ... g
- Fat: ... g
"""
headers = {
"Authorization": f"Api-Key {NEBIUS_API_KEY}",
"Content-Type": "application/json"
}
data = {
"modelUri": f"gpt://{FOLDER_ID}/yandexgpt-lite",
"completionOptions": {"stream": False, "temperature": 0.7, "maxTokens": 700},
"messages": [{"role": "user", "text": prompt.strip()}]
}
response = requests.post("https://llm.api.cloud.yandex.net/foundationModels/v1/completion",
headers=headers, json=data)
try:
text = response.json()["result"]["alternatives"][0]["message"]["text"]
except Exception as e:
return f"❌ Error: Could not fetch recipe. {e}"
return text
def extract_nutrition(recipe_text):
pattern = r"Calories:\s*([\d\.]+)\s*kcal.*Protein:\s*([\d\.]+)g.*Carbs:\s*([\d\.]+)g.*Fat:\s*([\d\.]+)g"
match = re.search(pattern, recipe_text.replace("\n", " "))
if match:
calories, protein, carbs, fat = map(float, match.groups())
return {"Calories": calories, "Protein": protein, "Carbs": carbs, "Fat": fat}
return None
def plot_nutrition_chart(nutrition):
fig, ax = plt.subplots()
nutrients = list(nutrition.keys())
values = list(nutrition.values())
colors = ['#ff9999','#66b3ff','#99ff99','#ffcc99']
ax.pie(values, labels=nutrients, autopct='%1.1f%%', startangle=140, colors=colors)
ax.axis('equal')
plt.tight_layout()
filename = f"/tmp/nutrition_{uuid.uuid4().hex}.png"
plt.savefig(filename)
plt.close(fig)
return filename
def handle_generate(preferences, ingredients, time):
recipe = generate_meal(preferences, ingredients, time)
nutrition = extract_nutrition(recipe)
chart_path = None
if nutrition:
chart_path = plot_nutrition_chart(nutrition)
return recipe, chart_path
def save_pdf(recipe_text):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
for line in recipe_text.split('\n'):
pdf.multi_cell(0, 10, line)
filename = f"/tmp/AgentChef_Recipe_{uuid.uuid4().hex}.pdf"
pdf.output(filename)
return filename
with gr.Blocks(css="""
body { background-color: #111; color: #eee; font-family: 'Segoe UI', sans-serif; }
.gradio-container { max-width: 900px; margin: auto; }
.input-label { font-weight: 600; margin-bottom: 5px; }
.footer { font-size: 0.8rem; color: #666; padding: 10px; text-align: center; }
@media (max-width: 600px) {
.gradio-container { padding: 10px; }
}
""") as demo:
gr.Markdown("# 👨🍳 AgentChef: AI Recipe Planner & Smart Kitchen Assistant")
with gr.Row():
with gr.Column(scale=1, min_width=200):
preferences = gr.Textbox(label="🥗 Dietary Preferences", placeholder="e.g. vegetarian, keto")
ingredients = gr.Textbox(label="🧂 Ingredients You Have", placeholder="e.g. rice, tomato, onion", lines=3)
mic = gr.Microphone(label="🎤 Speak Ingredients")
mic.stream(lambda audio: audio if audio else "", inputs=None, outputs=ingredients)
time = gr.Slider(5, 60, value=20, step=5, label="⏱️ Time Available (minutes)")
generate_btn = gr.Button("🍽️ Generate Recipe")
with gr.Column(scale=1, min_width=300):
recipe_output = gr.Textbox(label="📝 Recipe Output", lines=15)
nutrition_chart = gr.Image(label="📊 Nutrition Breakdown", interactive=False)
pdf_btn = gr.Button("📄 Export as PDF")
generate_btn.click(handle_generate,
inputs=[preferences, ingredients, time],
outputs=[recipe_output, nutrition_chart])
pdf_btn.click(save_pdf, inputs=[recipe_output], outputs=gr.File(label="📥 Download Recipe PDF"))
demo.launch()
|