From f52533d0f763ab8532fe44bf29505ca4c889032f Mon Sep 17 00:00:00 2001 From: krish020902 Date: Sun, 22 Mar 2026 18:10:46 -0400 Subject: [PATCH 1/3] feat: add Recipe AI Agent template --- recipe-ai-agent/README.md | 175 +++++++++++++ recipe-ai-agent/config.json | 497 ++++++++++++++++++++++++++++++++++++ recipe-ai-agent/inputs.json | 3 + recipe-ai-agent/meta.json | 15 ++ 4 files changed, 690 insertions(+) create mode 100644 recipe-ai-agent/README.md create mode 100644 recipe-ai-agent/config.json create mode 100644 recipe-ai-agent/inputs.json create mode 100644 recipe-ai-agent/meta.json diff --git a/recipe-ai-agent/README.md b/recipe-ai-agent/README.md new file mode 100644 index 00000000..69f337c0 --- /dev/null +++ b/recipe-ai-agent/README.md @@ -0,0 +1,175 @@ +# Recipe AI Agent + +## About This Flow + +The **Recipe AI Agent** is a conversational AI flow that understands natural language cooking requests and responds intelligently. Send it any food-related message and it automatically detects what you need — a recipe, a meal plan, a grocery list, or a cooking tip — then returns a clean, structured response. + +This flow includes **10 nodes** working together across intent detection, routing, generation, and formatting. + +--- + +## What It Does + +| User Message | Agent Response | +|---|---| +| *"Give me a recipe for butter chicken"* | Full recipe with ingredients and steps | +| *"Plan my meals for the week"* | 7-day breakfast, lunch, dinner plan | +| *"What do I need to make pasta and salad?"* | Merged grocery list by category | +| *"How do I know when oil is hot enough to fry?"* | Clear, friendly cooking answer | + +--- + +## Flow Structure + +``` +[API Request Trigger] + ↓ +[Recipe Supervisor Agent] + ├──→ [Intent Detector LLM] + │ ↓ + │ [Route by Intent - Condition Node] + │ ├──→ [Recipe Generator LLM] + │ ├──→ [Menu Planner LLM] + │ ├──→ [Grocery List Builder LLM] + │ └──→ [Cooking Q&A LLM] + │ + ├──→ [Response Formatter (InstructorLLM)] + ↓ +[Agent Loop End] + ↓ +[API Response] +``` + +--- + +## Flow Components + +This workflow uses the following node types: + +- `graphqlNode` — API trigger that accepts the user message +- `agentNode` — Supervisor that orchestrates the full flow +- `agentLoopEndNode` — Closes the agent loop and returns the final response +- `LLMNode` — Intent Detector, Recipe Generator, Menu Planner, Grocery Builder, Cooking Q&A +- `conditionNode` — Routes to the correct sub-agent based on detected intent +- `InstructorLLMNode` — Formats the raw structured JSON into a clean user-facing response +- `graphqlResponseNode` — Returns the final output + +--- + +## Files Included + +- **config.json** — Complete flow structure with all nodes and edges +- **inputs.json** — Private inputs requiring configuration (Gemini API key) +- **meta.json** — Flow metadata and author information +- **README.md** — This file + +--- + +## Setup Instructions + +### 1. Import the template +Import this template into your Lamatic workspace via the Template Library or by uploading `config.json` directly. + +### 2. Configure your API key +Open `inputs.json` and replace the placeholder with your actual key: +```json +{ + "GEMINI_API_KEY": "your_google_gemini_api_key_here" +} +``` +You can get a free Gemini API key at [aistudio.google.com](https://aistudio.google.com). + +### 3. Test the flow +Use the built-in test input from `meta.json`: +```json +{ + "user_message": "Give me a recipe for butter chicken" +} +``` + +### 4. Deploy +Deploy the flow and integrate the API endpoint into your app or chat interface. + +--- + +## Example Inputs & Outputs + +### Recipe Generation +**Input:** +```json +{ "user_message": "Give me a recipe for chocolate lava cake" } +``` +**Output:** +``` +🍫 Chocolate Lava Cake (Serves 4) +Prep: 15 mins | Cook: 12 mins + +Ingredients: +- 200g dark chocolate +- 100g butter +... + +Steps: +1. Preheat oven to 200°C... +2. Melt chocolate and butter together... + +#dessert #chocolate #quick +``` + +--- + +### Menu Planning +**Input:** +```json +{ "user_message": "Plan a healthy meal plan for 3 days" } +``` +**Output:** +``` +📅 Your 3-Day Meal Plan + +Monday +🌅 Oats with berries and honey +🌞 Grilled chicken salad +🌙 Baked salmon with vegetables +... +``` + +--- + +### Grocery List +**Input:** +```json +{ "user_message": "What do I need to make pasta and caesar salad?" } +``` +**Output:** +``` +🛒 Grocery List (12 items) + +Vegetables: +- 1 head romaine lettuce +- 2 cloves garlic + +Dairy: +- 50g parmesan cheese +... +``` + +--- + +## Why This Agent + +- **Single entry point** — One API call handles all recipe-related intents +- **Smart routing** — No need to pre-classify requests; the agent figures it out +- **Structured outputs** — Every sub-agent returns typed JSON before formatting +- **Extensible** — New intents (e.g. nutrition analysis, substitutions) can be added as new condition branches + +--- + +## Tags + +🍳 Food · 🤖 AI Agent · 🌱 Growth · 🛒 Grocery · 📅 Planning + +--- + +*Exported from Lamatic Template Library* +*Template: Recipe AI Agent* diff --git a/recipe-ai-agent/config.json b/recipe-ai-agent/config.json new file mode 100644 index 00000000..7604b4ff --- /dev/null +++ b/recipe-ai-agent/config.json @@ -0,0 +1,497 @@ +{ + "nodes": [ + { + "id": "triggerNode_1", + "type": "triggerNode", + "position": { + "x": 0, + "y": 0 + }, + "data": { + "nodeId": "graphqlNode", + "modes": {}, + "trigger": true, + "values": { + "nodeName": "API Request", + "headers": "", + "retries": "0", + "webhookUrl": "", + "responeType": "realtime", + "retry_deplay": "0", + "advance_schema": "{\n \"user_message\": \"string\"\n}" + } + } + }, + { + "id": "agentNode_101", + "type": "agentNode", + "position": { + "x": 0, + "y": 0 + }, + "data": { + "nodeId": "agentNode", + "values": { + "nodeName": "Recipe Supervisor", + "tools": [], + "agents": [ + { + "name": "IntentRouter", + "schema": "{\n \"type\": \"object\",\n \"properties\": {\n \"user_message\": {\n \"type\": \"string\",\n \"required\": true,\n \"description\": \"The raw message from the user to detect intent and route accordingly\"\n }\n }\n}", + "description": "This path detects the user intent from the message and routes it to the correct sub-agent: recipe generation, menu planning, grocery list, or general Q&A" + }, + { + "name": "ResponseFormatter", + "schema": "{\n \"type\": \"object\",\n \"properties\": {\n \"raw_response\": {\n \"type\": \"string\",\n \"required\": true,\n \"description\": \"The raw output from the intent-specific LLM node that needs to be formatted into a final clean response\"\n }\n }\n}", + "description": "This path takes the raw structured JSON from the sub-agent and formats it into a clean, human-readable response for the user" + } + ], + "prompts": [ + { + "id": "a1b2c3d4-0001-4000-a000-000000000001", + "role": "user", + "content": "USER MESSAGE : {{triggerNode_1.output.user_message}}" + }, + { + "id": "a1b2c3d4-0001-4000-a000-000000000002", + "role": "system", + "content": "You are the Recipe AI Supervisor. You receive a user message about cooking and coordinate two agents to produce a final response.\n\nYour job:\n1. Pass the user message to the IntentRouter agent, which will detect the intent (recipe / menu / grocery / general) and call the correct LLM sub-agent.\n2. Once the IntentRouter returns a structured JSON response, pass that to the ResponseFormatter agent to produce a clean human-readable reply.\n3. Return the final formatted response to the user.\n\nAgent order is always: INTENTROUTER -> RESPONSEFORMATTER\n\nThe final answer must contain no backticks, no JSON labels, no leading statements. Just the final formatted text reply." + } + ], + "messages": "[]", + "stopWord": "", + "connectedTo": "agentLoopEndNode_102", + "maxIterations": 5, + "generativeModelName": {} + } + } + }, + { + "id": "agentLoopEndNode_102", + "type": "agentLoopEndNode", + "position": { + "x": 0, + "y": 0 + }, + "data": { + "nodeId": "agentLoopEndNode", + "modes": {}, + "values": { + "nodeName": "Agent Loop End", + "connectedTo": "agentNode_101" + } + } + }, + { + "id": "LLMNode_201", + "type": "dynamicNode", + "position": { + "x": 0, + "y": 0 + }, + "data": { + "nodeId": "LLMNode", + "modes": {}, + "values": { + "nodeName": "Intent Detector", + "tools": [], + "prompts": [ + { + "id": "b2c3d4e5-0002-4000-b000-000000000001", + "role": "user", + "content": "USER MESSAGE : {{agentNode_101.output.user_message}}" + }, + { + "id": "b2c3d4e5-0002-4000-b000-000000000002", + "role": "system", + "content": "You are an intent detection agent for a Recipe AI app. Read the user message and classify it into exactly one of these intents:\n\n- RECIPE: User wants to generate a recipe for a specific dish\n- MENU: User wants a meal plan (daily or weekly)\n- GROCERY: User wants a grocery/shopping list for one or more recipes\n- GENERAL: User is asking a general cooking question\n\nRespond with only the intent label. No extra text. No punctuation. Just one word: RECIPE, MENU, GROCERY, or GENERAL." + } + ], + "memories": "[]", + "messages": "[]", + "attachments": "", + "generativeModelName": {} + } + } + }, + { + "id": "conditionNode_301", + "type": "conditionNode", + "position": { + "x": 0, + "y": 0 + }, + "data": { + "nodeId": "conditionNode", + "modes": [], + "values": { + "nodeName": "Route by Intent", + "conditions": [ + { + "label": "Recipe", + "value": "conditionNode_301-LLMNode_401", + "condition": "{\n \"operator\": null,\n \"operands\": [\n {\n \"name\": \"{{LLMNode_201.output.generatedResponse}}\",\n \"operator\": \"==\",\n \"value\": \"RECIPE\"\n }\n ]\n}" + }, + { + "label": "Menu", + "value": "conditionNode_301-LLMNode_402", + "condition": "{\n \"operator\": null,\n \"operands\": [\n {\n \"name\": \"{{LLMNode_201.output.generatedResponse}}\",\n \"operator\": \"==\",\n \"value\": \"MENU\"\n }\n ]\n}" + }, + { + "label": "Grocery", + "value": "conditionNode_301-LLMNode_403", + "condition": "{\n \"operator\": null,\n \"operands\": [\n {\n \"name\": \"{{LLMNode_201.output.generatedResponse}}\",\n \"operator\": \"==\",\n \"value\": \"GROCERY\"\n }\n ]\n}" + }, + { + "label": "Else", + "value": "conditionNode_301-LLMNode_404", + "condition": {} + } + ] + } + } + }, + { + "id": "LLMNode_401", + "type": "dynamicNode", + "position": { + "x": 0, + "y": 0 + }, + "data": { + "nodeId": "LLMNode", + "modes": {}, + "values": { + "nodeName": "Recipe Generator", + "tools": [], + "prompts": [ + { + "id": "c3d4e5f6-0003-4000-c000-000000000001", + "role": "user", + "content": "USER MESSAGE : {{agentNode_101.output.user_message}}" + }, + { + "id": "c3d4e5f6-0003-4000-c000-000000000002", + "role": "system", + "content": "You are a professional chef AI. Generate a complete, detailed recipe based on the user's request.\n\nAlways respond with this exact JSON structure and nothing else:\n{\n \"type\": \"recipe\",\n \"title\": \"Recipe Title\",\n \"servings\": 4,\n \"prepTime\": \"15 mins\",\n \"cookTime\": \"30 mins\",\n \"ingredients\": [\n { \"amount\": \"2\", \"unit\": \"cups\", \"name\": \"ingredient name\" }\n ],\n \"steps\": [\n \"Step 1 description\",\n \"Step 2 description\"\n ],\n \"tags\": [\"vegetarian\", \"quick\"]\n}\n\nRules:\n- Include at least 5 ingredients\n- Include at least 4 steps\n- Be specific with amounts and units\n- No backticks, no markdown, no leading text — just raw JSON" + } + ], + "memories": "[]", + "messages": "[]", + "attachments": "", + "generativeModelName": {} + } + } + }, + { + "id": "LLMNode_402", + "type": "dynamicNode", + "position": { + "x": 0, + "y": 0 + }, + "data": { + "nodeId": "LLMNode", + "modes": {}, + "values": { + "nodeName": "Menu Planner", + "tools": [], + "prompts": [ + { + "id": "d4e5f6g7-0004-4000-d000-000000000001", + "role": "user", + "content": "USER MESSAGE : {{agentNode_101.output.user_message}}" + }, + { + "id": "d4e5f6g7-0004-4000-d000-000000000002", + "role": "system", + "content": "You are a nutrition-aware meal planning AI. Create a practical and balanced meal plan based on the user's request.\n\nAlways respond with this exact JSON structure and nothing else:\n{\n \"type\": \"menu\",\n \"days\": [\n {\n \"day\": \"Monday\",\n \"breakfast\": \"Dish name\",\n \"lunch\": \"Dish name\",\n \"dinner\": \"Dish name\"\n }\n ]\n}\n\nRules:\n- If user asks for a week, return 7 days. If a day, return 1.\n- Vary the meals — no repeated dishes across days\n- Keep meals realistic and easy to cook\n- No backticks, no markdown, no leading text — just raw JSON" + } + ], + "memories": "[]", + "messages": "[]", + "attachments": "", + "generativeModelName": {} + } + } + }, + { + "id": "LLMNode_403", + "type": "dynamicNode", + "position": { + "x": 0, + "y": 0 + }, + "data": { + "nodeId": "LLMNode", + "modes": {}, + "values": { + "nodeName": "Grocery List Builder", + "tools": [], + "prompts": [ + { + "id": "e5f6g7h8-0005-4000-e000-000000000001", + "role": "user", + "content": "USER MESSAGE : {{agentNode_101.output.user_message}}" + }, + { + "id": "e5f6g7h8-0005-4000-e000-000000000002", + "role": "system", + "content": "You are a grocery planning AI. Extract and compile a complete ingredient shopping list from the recipes mentioned by the user. Merge duplicate ingredients by summing amounts where possible.\n\nAlways respond with this exact JSON structure and nothing else:\n{\n \"type\": \"grocery\",\n \"items\": [\n {\n \"amount\": \"3\",\n \"unit\": \"cups\",\n \"name\": \"ingredient name\",\n \"category\": \"Grains\"\n }\n ]\n}\n\nValid categories: Vegetables, Fruits, Grains, Dairy, Protein, Spices, Condiments, Beverages, Other\n\nRules:\n- Merge same ingredient + unit combinations by adding amounts\n- Sort items alphabetically within each category\n- No backticks, no markdown, no leading text — just raw JSON" + } + ], + "memories": "[]", + "messages": "[]", + "attachments": "", + "generativeModelName": {} + } + } + }, + { + "id": "LLMNode_404", + "type": "dynamicNode", + "position": { + "x": 0, + "y": 0 + }, + "data": { + "nodeId": "LLMNode", + "modes": {}, + "values": { + "nodeName": "Cooking Q&A", + "tools": [], + "prompts": [ + { + "id": "f6g7h8i9-0006-4000-f000-000000000001", + "role": "user", + "content": "USER MESSAGE : {{agentNode_101.output.user_message}}" + }, + { + "id": "f6g7h8i9-0006-4000-f000-000000000002", + "role": "system", + "content": "You are a friendly and knowledgeable cooking assistant. Answer general cooking questions clearly and helpfully. This includes techniques, substitutions, storage tips, cooking times, equipment advice, and food science.\n\nAlways respond with this exact JSON structure and nothing else:\n{\n \"type\": \"general\",\n \"message\": \"Your helpful answer here. Keep it concise, clear, and practical.\"\n}\n\nRules:\n- Keep the answer under 200 words\n- Be warm and encouraging\n- No backticks, no markdown outside the value — just raw JSON" + } + ], + "memories": "[]", + "messages": "[]", + "attachments": "", + "generativeModelName": {} + } + } + }, + { + "id": "InstructorLLMNode_501", + "type": "dynamicNode", + "position": { + "x": 0, + "y": 0 + }, + "data": { + "nodeId": "InstructorLLMNode", + "modes": {}, + "values": { + "nodeName": "Response Formatter", + "tools": [], + "schema": "{\n \"type\": \"object\",\n \"properties\": {\n \"formatted_response\": {\n \"type\": \"string\",\n \"required\": true,\n \"description\": \"The final human-readable response to show to the user based on the structured JSON input\"\n },\n \"response_type\": {\n \"type\": \"string\",\n \"required\": true,\n \"description\": \"One of: recipe, menu, grocery, general\"\n }\n }\n}", + "prompts": [ + { + "id": "g7h8i9j0-0007-4000-g000-000000000001", + "role": "user", + "content": "RAW AGENT OUTPUT : {{agentNode_101.output.raw_response}}" + }, + { + "id": "g7h8i9j0-0007-4000-g000-000000000002", + "role": "system", + "content": "You are a response formatting agent. You receive a structured JSON output from a recipe AI and convert it into a clean, readable, friendly response for the user.\n\nFormatting rules by type:\n\nFor 'recipe':\n- Start with the recipe title in bold\n- Show servings, prep time, cook time\n- List all ingredients with amounts\n- Number the steps clearly\n- End with the tags as hashtags\n\nFor 'menu':\n- Show each day as a section header\n- List breakfast, lunch, dinner with emoji: 🌅 🌞 🌙\n\nFor 'grocery':\n- Group items by category\n- Show each item as: amount + unit + name\n- Add a total item count at the end\n\nFor 'general':\n- Return the message as-is with a friendly tone\n\nAlways produce a warm, clear, well-structured plain text response. No raw JSON in the output." + } + ], + "memories": "[]", + "messages": "[]", + "attachments": "", + "generativeModelName": {} + } + } + }, + { + "id": "graphqlResponseNode_601", + "type": "dynamicNode", + "position": { + "x": 0, + "y": 0 + }, + "data": { + "nodeId": "graphqlResponseNode", + "values": { + "nodeName": "API Response", + "outputMapping": "{\n \"output\": \"{{agentLoopEndNode_102.output.finalResponse}}\"\n}" + } + } + } + ], + "edges": [ + { + "id": "triggerNode_1-agentNode_101", + "source": "triggerNode_1", + "target": "agentNode_101", + "type": "defaultEdge", + "sourceHandle": "bottom", + "targetHandle": "top" + }, + { + "id": "agentNode_101-LLMNode_201", + "source": "agentNode_101", + "target": "LLMNode_201", + "type": "conditionEdge", + "sourceHandle": "bottom", + "targetHandle": "top", + "data": { + "condition": "IntentRouter", + "invisible": false + } + }, + { + "id": "agentNode_101-InstructorLLMNode_501", + "source": "agentNode_101", + "target": "InstructorLLMNode_501", + "type": "conditionEdge", + "sourceHandle": "bottom", + "targetHandle": "top", + "data": { + "condition": "ResponseFormatter", + "invisible": false + } + }, + { + "id": "agentNode_101-agentLoopEndNode_102", + "source": "agentNode_101", + "target": "agentLoopEndNode_102", + "type": "agentLoopEdge", + "sourceHandle": "bottom", + "targetHandle": "top", + "data": { + "condition": "Agent Loop End", + "invisible": true + } + }, + { + "id": "LLMNode_201-conditionNode_301", + "source": "LLMNode_201", + "target": "conditionNode_301", + "type": "defaultEdge", + "sourceHandle": "bottom", + "targetHandle": "top" + }, + { + "id": "conditionNode_301-LLMNode_401", + "source": "conditionNode_301", + "target": "LLMNode_401", + "type": "conditionEdge", + "sourceHandle": "bottom", + "targetHandle": "top", + "data": { + "condition": "Recipe" + } + }, + { + "id": "conditionNode_301-LLMNode_402", + "source": "conditionNode_301", + "target": "LLMNode_402", + "type": "conditionEdge", + "sourceHandle": "bottom", + "targetHandle": "top", + "data": { + "condition": "Menu" + } + }, + { + "id": "conditionNode_301-LLMNode_403", + "source": "conditionNode_301", + "target": "LLMNode_403", + "type": "conditionEdge", + "sourceHandle": "bottom", + "targetHandle": "top", + "data": { + "condition": "Grocery" + } + }, + { + "id": "conditionNode_301-LLMNode_404", + "source": "conditionNode_301", + "target": "LLMNode_404", + "type": "conditionEdge", + "sourceHandle": "bottom", + "targetHandle": "top", + "data": { + "condition": "Else" + } + }, + { + "id": "LLMNode_401-agentLoopEndNode_102", + "source": "LLMNode_401", + "target": "agentLoopEndNode_102", + "type": "defaultEdge", + "sourceHandle": "bottom", + "targetHandle": "top" + }, + { + "id": "LLMNode_402-agentLoopEndNode_102", + "source": "LLMNode_402", + "target": "agentLoopEndNode_102", + "type": "defaultEdge", + "sourceHandle": "bottom", + "targetHandle": "top" + }, + { + "id": "LLMNode_403-agentLoopEndNode_102", + "source": "LLMNode_403", + "target": "agentLoopEndNode_102", + "type": "defaultEdge", + "sourceHandle": "bottom", + "targetHandle": "top" + }, + { + "id": "LLMNode_404-agentLoopEndNode_102", + "source": "LLMNode_404", + "target": "agentLoopEndNode_102", + "type": "defaultEdge", + "sourceHandle": "bottom", + "targetHandle": "top" + }, + { + "id": "InstructorLLMNode_501-agentLoopEndNode_102", + "source": "InstructorLLMNode_501", + "target": "agentLoopEndNode_102", + "type": "defaultEdge", + "sourceHandle": "bottom", + "targetHandle": "top" + }, + { + "id": "agentLoopEndNode_102-agentNode_101", + "source": "agentLoopEndNode_102", + "target": "agentNode_101", + "type": "agentLoopEdge", + "sourceHandle": "bottom", + "targetHandle": "top", + "data": { + "condition": "Agent Loop End", + "invisible": false + } + }, + { + "id": "agentLoopEndNode_102-graphqlResponseNode_601", + "source": "agentLoopEndNode_102", + "target": "graphqlResponseNode_601", + "sourceHandle": "bottom", + "targetHandle": "top", + "type": "defaultEdge" + }, + { + "id": "response-graphqlResponseNode_601", + "source": "triggerNode_1", + "target": "graphqlResponseNode_601", + "sourceHandle": "to-response", + "targetHandle": "from-trigger", + "type": "responseEdge" + } + ] +} diff --git a/recipe-ai-agent/inputs.json b/recipe-ai-agent/inputs.json new file mode 100644 index 00000000..59650674 --- /dev/null +++ b/recipe-ai-agent/inputs.json @@ -0,0 +1,3 @@ +{ + "GEMINI_API_KEY": "AIzaSyBFXZ-DMi4owfkTAQ-MijefHVwTlB4cNnA" +} \ No newline at end of file diff --git a/recipe-ai-agent/meta.json b/recipe-ai-agent/meta.json new file mode 100644 index 00000000..36ffd498 --- /dev/null +++ b/recipe-ai-agent/meta.json @@ -0,0 +1,15 @@ +{ + "name": "Recipe AI Agent", + "description": "A conversational AI agent that detects user intent and responds with generated recipes, weekly meal plans, grocery lists, or cooking answers — all from a single natural language message.", + "tags": ["🍳 Food", "🤖 AI Agent", "🌱 Growth", "🛒 Grocery", "📅 Planning"], + "testInput": { + "user_message": "Give me a recipe for butter chicken" + }, + "githubUrl": "", + "documentationUrl": "", + "deployUrl": "https://studio.lamatic.ai/template/recipe-ai-agent", + "author": { + "name": "Krish Mehta", + "email": "krish.mehta@umbc.edu" + } +} From 9a52490a9aa8bdaf85d8939225e191ae2e725e92 Mon Sep 17 00:00:00 2001 From: krish020902 Date: Sun, 22 Mar 2026 19:24:38 -0400 Subject: [PATCH 2/3] feat: add Recipe AI Agent template --- recipe-ai-agent/README.md | 37 ++++++++++++++++++++++++++++--------- recipe-ai-agent/config.json | 22 +++++++++++++--------- recipe-ai-agent/inputs.json | 2 +- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/recipe-ai-agent/README.md b/recipe-ai-agent/README.md index 69f337c0..1a668208 100644 --- a/recipe-ai-agent/README.md +++ b/recipe-ai-agent/README.md @@ -4,18 +4,18 @@ The **Recipe AI Agent** is a conversational AI flow that understands natural language cooking requests and responds intelligently. Send it any food-related message and it automatically detects what you need — a recipe, a meal plan, a grocery list, or a cooking tip — then returns a clean, structured response. -This flow includes **10 nodes** working together across intent detection, routing, generation, and formatting. +This flow includes **11 nodes** working together across intent detection, routing, generation, and formatting. --- ## What It Does -| User Message | Agent Response | -|---|---| -| *"Give me a recipe for butter chicken"* | Full recipe with ingredients and steps | -| *"Plan my meals for the week"* | 7-day breakfast, lunch, dinner plan | -| *"What do I need to make pasta and salad?"* | Merged grocery list by category | -| *"How do I know when oil is hot enough to fry?"* | Clear, friendly cooking answer | +| User Message | Agent Response | +| ------------------------------------------------ | -------------------------------------- | +| _"Give me a recipe for butter chicken"_ | Full recipe with ingredients and steps | +| _"Plan my meals for the week"_ | 7-day breakfast, lunch, dinner plan | +| _"What do I need to make pasta and salad?"_ | Merged grocery list by category | +| _"How do I know when oil is hot enough to fry?"_ | Clear, friendly cooking answer | --- @@ -68,19 +68,25 @@ This workflow uses the following node types: ## Setup Instructions ### 1. Import the template + Import this template into your Lamatic workspace via the Template Library or by uploading `config.json` directly. ### 2. Configure your API key + Open `inputs.json` and replace the placeholder with your actual key: + ```json { "GEMINI_API_KEY": "your_google_gemini_api_key_here" } ``` + You can get a free Gemini API key at [aistudio.google.com](https://aistudio.google.com). ### 3. Test the flow + Use the built-in test input from `meta.json`: + ```json { "user_message": "Give me a recipe for butter chicken" @@ -88,6 +94,7 @@ Use the built-in test input from `meta.json`: ``` ### 4. Deploy + Deploy the flow and integrate the API endpoint into your app or chat interface. --- @@ -95,11 +102,15 @@ Deploy the flow and integrate the API endpoint into your app or chat interface. ## Example Inputs & Outputs ### Recipe Generation + **Input:** + ```json { "user_message": "Give me a recipe for chocolate lava cake" } ``` + **Output:** + ``` 🍫 Chocolate Lava Cake (Serves 4) Prep: 15 mins | Cook: 12 mins @@ -119,11 +130,15 @@ Steps: --- ### Menu Planning + **Input:** + ```json { "user_message": "Plan a healthy meal plan for 3 days" } ``` + **Output:** + ``` 📅 Your 3-Day Meal Plan @@ -137,11 +152,15 @@ Monday --- ### Grocery List + **Input:** + ```json { "user_message": "What do I need to make pasta and caesar salad?" } ``` + **Output:** + ``` 🛒 Grocery List (12 items) @@ -171,5 +190,5 @@ Dairy: --- -*Exported from Lamatic Template Library* -*Template: Recipe AI Agent* +_Exported from Lamatic Template Library_ +_Template: Recipe AI Agent_ diff --git a/recipe-ai-agent/config.json b/recipe-ai-agent/config.json index 7604b4ff..d1a39810 100644 --- a/recipe-ai-agent/config.json +++ b/recipe-ai-agent/config.json @@ -159,11 +159,12 @@ "y": 0 }, "data": { - "nodeId": "LLMNode", + "nodeId": "InstructorLLMNode", "modes": {}, "values": { "nodeName": "Recipe Generator", "tools": [], + "schema": "{\n \"type\": \"object\",\n \"properties\": {\n \"type\": { \"type\": \"string\", \"required\": true, \"description\": \"Always the string: recipe\" },\n \"title\": { \"type\": \"string\", \"required\": true, \"description\": \"Name of the recipe\" },\n \"servings\": { \"type\": \"number\", \"required\": true, \"description\": \"Number of servings\" },\n \"prepTime\": { \"type\": \"string\", \"required\": true, \"description\": \"Preparation time e.g. 15 mins\" },\n \"cookTime\": { \"type\": \"string\", \"required\": true, \"description\": \"Cooking time e.g. 30 mins\" },\n \"ingredients\": { \"type\": \"array\", \"required\": true, \"description\": \"List of ingredient objects with amount, unit, name\" },\n \"steps\": { \"type\": \"array\", \"required\": true, \"description\": \"Ordered list of step strings\" },\n \"tags\": { \"type\": \"array\", \"required\": true, \"description\": \"Short keyword tags for the recipe\" }\n }\n}", "prompts": [ { "id": "c3d4e5f6-0003-4000-c000-000000000001", @@ -173,7 +174,7 @@ { "id": "c3d4e5f6-0003-4000-c000-000000000002", "role": "system", - "content": "You are a professional chef AI. Generate a complete, detailed recipe based on the user's request.\n\nAlways respond with this exact JSON structure and nothing else:\n{\n \"type\": \"recipe\",\n \"title\": \"Recipe Title\",\n \"servings\": 4,\n \"prepTime\": \"15 mins\",\n \"cookTime\": \"30 mins\",\n \"ingredients\": [\n { \"amount\": \"2\", \"unit\": \"cups\", \"name\": \"ingredient name\" }\n ],\n \"steps\": [\n \"Step 1 description\",\n \"Step 2 description\"\n ],\n \"tags\": [\"vegetarian\", \"quick\"]\n}\n\nRules:\n- Include at least 5 ingredients\n- Include at least 4 steps\n- Be specific with amounts and units\n- No backticks, no markdown, no leading text — just raw JSON" + "content": "You are a professional chef AI. Generate a complete, detailed recipe based on the user's request. Include at least 5 ingredients and at least 4 steps. Be specific with amounts and units." } ], "memories": "[]", @@ -191,11 +192,12 @@ "y": 0 }, "data": { - "nodeId": "LLMNode", + "nodeId": "InstructorLLMNode", "modes": {}, "values": { "nodeName": "Menu Planner", "tools": [], + "schema": "{\n \"type\": \"object\",\n \"properties\": {\n \"type\": { \"type\": \"string\", \"required\": true, \"description\": \"Always the string: menu\" },\n \"days\": { \"type\": \"array\", \"required\": true, \"description\": \"Array of day objects each with: day (string), breakfast (string), lunch (string), dinner (string)\" }\n }\n}", "prompts": [ { "id": "d4e5f6g7-0004-4000-d000-000000000001", @@ -205,7 +207,7 @@ { "id": "d4e5f6g7-0004-4000-d000-000000000002", "role": "system", - "content": "You are a nutrition-aware meal planning AI. Create a practical and balanced meal plan based on the user's request.\n\nAlways respond with this exact JSON structure and nothing else:\n{\n \"type\": \"menu\",\n \"days\": [\n {\n \"day\": \"Monday\",\n \"breakfast\": \"Dish name\",\n \"lunch\": \"Dish name\",\n \"dinner\": \"Dish name\"\n }\n ]\n}\n\nRules:\n- If user asks for a week, return 7 days. If a day, return 1.\n- Vary the meals — no repeated dishes across days\n- Keep meals realistic and easy to cook\n- No backticks, no markdown, no leading text — just raw JSON" + "content": "You are a nutrition-aware meal planning AI. Create a practical and balanced meal plan based on the user's request. If the user asks for N days, return exactly N days. If the user asks for a week, return 7 days. If the user asks for a day, return 1 day. Vary the meals — no repeated dishes across days. Keep meals realistic and easy to cook." } ], "memories": "[]", @@ -223,11 +225,12 @@ "y": 0 }, "data": { - "nodeId": "LLMNode", + "nodeId": "InstructorLLMNode", "modes": {}, "values": { "nodeName": "Grocery List Builder", "tools": [], + "schema": "{\n \"type\": \"object\",\n \"properties\": {\n \"type\": { \"type\": \"string\", \"required\": true, \"description\": \"Always the string: grocery\" },\n \"items\": { \"type\": \"array\", \"required\": true, \"description\": \"Array of grocery item objects each with: amount (string), unit (string), name (string), category (string). Valid categories: Vegetables, Fruits, Grains, Dairy, Protein, Spices, Condiments, Beverages, Other\" }\n }\n}", "prompts": [ { "id": "e5f6g7h8-0005-4000-e000-000000000001", @@ -237,7 +240,7 @@ { "id": "e5f6g7h8-0005-4000-e000-000000000002", "role": "system", - "content": "You are a grocery planning AI. Extract and compile a complete ingredient shopping list from the recipes mentioned by the user. Merge duplicate ingredients by summing amounts where possible.\n\nAlways respond with this exact JSON structure and nothing else:\n{\n \"type\": \"grocery\",\n \"items\": [\n {\n \"amount\": \"3\",\n \"unit\": \"cups\",\n \"name\": \"ingredient name\",\n \"category\": \"Grains\"\n }\n ]\n}\n\nValid categories: Vegetables, Fruits, Grains, Dairy, Protein, Spices, Condiments, Beverages, Other\n\nRules:\n- Merge same ingredient + unit combinations by adding amounts\n- Sort items alphabetically within each category\n- No backticks, no markdown, no leading text — just raw JSON" + "content": "You are a grocery planning AI. Extract and compile a complete ingredient shopping list from the recipes mentioned by the user. Merge duplicate ingredients by summing amounts where possible. Sort items alphabetically within each category." } ], "memories": "[]", @@ -255,11 +258,12 @@ "y": 0 }, "data": { - "nodeId": "LLMNode", + "nodeId": "InstructorLLMNode", "modes": {}, "values": { "nodeName": "Cooking Q&A", "tools": [], + "schema": "{\n \"type\": \"object\",\n \"properties\": {\n \"type\": { \"type\": \"string\", \"required\": true, \"description\": \"Always the string: general\" },\n \"message\": { \"type\": \"string\", \"required\": true, \"description\": \"Clear, friendly, practical cooking answer under 200 words\" }\n }\n}", "prompts": [ { "id": "f6g7h8i9-0006-4000-f000-000000000001", @@ -269,7 +273,7 @@ { "id": "f6g7h8i9-0006-4000-f000-000000000002", "role": "system", - "content": "You are a friendly and knowledgeable cooking assistant. Answer general cooking questions clearly and helpfully. This includes techniques, substitutions, storage tips, cooking times, equipment advice, and food science.\n\nAlways respond with this exact JSON structure and nothing else:\n{\n \"type\": \"general\",\n \"message\": \"Your helpful answer here. Keep it concise, clear, and practical.\"\n}\n\nRules:\n- Keep the answer under 200 words\n- Be warm and encouraging\n- No backticks, no markdown outside the value — just raw JSON" + "content": "You are a friendly and knowledgeable cooking assistant. Answer general cooking questions clearly and helpfully. This includes techniques, substitutions, storage tips, cooking times, equipment advice, and food science. Keep the answer under 200 words. Be warm and encouraging." } ], "memories": "[]", @@ -494,4 +498,4 @@ "type": "responseEdge" } ] -} +} \ No newline at end of file diff --git a/recipe-ai-agent/inputs.json b/recipe-ai-agent/inputs.json index 59650674..ae08f4ac 100644 --- a/recipe-ai-agent/inputs.json +++ b/recipe-ai-agent/inputs.json @@ -1,3 +1,3 @@ { - "GEMINI_API_KEY": "AIzaSyBFXZ-DMi4owfkTAQ-MijefHVwTlB4cNnA" + "GEMINI_API_KEY": "your_google_gemini_api_key_here" } \ No newline at end of file From 5a72850470ccc1b9404df1c10c613d93ddeae6ae Mon Sep 17 00:00:00 2001 From: krish020902 Date: Sun, 22 Mar 2026 19:53:54 -0400 Subject: [PATCH 3/3] feat: add Recipe AI Agent template --- recipe-ai-agent/README.md | 47 +++++++++++-------------------------- recipe-ai-agent/config.json | 17 +++++++------- 2 files changed, 23 insertions(+), 41 deletions(-) diff --git a/recipe-ai-agent/README.md b/recipe-ai-agent/README.md index 1a668208..687b1e70 100644 --- a/recipe-ai-agent/README.md +++ b/recipe-ai-agent/README.md @@ -10,18 +10,18 @@ This flow includes **11 nodes** working together across intent detection, routin ## What It Does -| User Message | Agent Response | -| ------------------------------------------------ | -------------------------------------- | -| _"Give me a recipe for butter chicken"_ | Full recipe with ingredients and steps | -| _"Plan my meals for the week"_ | 7-day breakfast, lunch, dinner plan | -| _"What do I need to make pasta and salad?"_ | Merged grocery list by category | -| _"How do I know when oil is hot enough to fry?"_ | Clear, friendly cooking answer | +| User Message | Agent Response | +|---|---| +| *"Give me a recipe for butter chicken"* | Full recipe with ingredients and steps | +| *"Plan my meals for the week"* | 7-day breakfast, lunch, dinner plan | +| *"What do I need to make pasta and salad?"* | Merged grocery list by category | +| *"How do I know when oil is hot enough to fry?"* | Clear, friendly cooking answer | --- ## Flow Structure -``` +```text [API Request Trigger] ↓ [Recipe Supervisor Agent] @@ -49,9 +49,9 @@ This workflow uses the following node types: - `graphqlNode` — API trigger that accepts the user message - `agentNode` — Supervisor that orchestrates the full flow - `agentLoopEndNode` — Closes the agent loop and returns the final response -- `LLMNode` — Intent Detector, Recipe Generator, Menu Planner, Grocery Builder, Cooking Q&A +- `LLMNode` — Intent Detector - `conditionNode` — Routes to the correct sub-agent based on detected intent -- `InstructorLLMNode` — Formats the raw structured JSON into a clean user-facing response +- `InstructorLLMNode` — Recipe Generator, Menu Planner, Grocery Builder, Cooking Q&A, and final response formatting - `graphqlResponseNode` — Returns the final output --- @@ -68,25 +68,19 @@ This workflow uses the following node types: ## Setup Instructions ### 1. Import the template - Import this template into your Lamatic workspace via the Template Library or by uploading `config.json` directly. ### 2. Configure your API key - Open `inputs.json` and replace the placeholder with your actual key: - ```json { "GEMINI_API_KEY": "your_google_gemini_api_key_here" } ``` - You can get a free Gemini API key at [aistudio.google.com](https://aistudio.google.com). ### 3. Test the flow - Use the built-in test input from `meta.json`: - ```json { "user_message": "Give me a recipe for butter chicken" @@ -94,7 +88,6 @@ Use the built-in test input from `meta.json`: ``` ### 4. Deploy - Deploy the flow and integrate the API endpoint into your app or chat interface. --- @@ -102,16 +95,12 @@ Deploy the flow and integrate the API endpoint into your app or chat interface. ## Example Inputs & Outputs ### Recipe Generation - **Input:** - ```json { "user_message": "Give me a recipe for chocolate lava cake" } ``` - **Output:** - -``` +```text 🍫 Chocolate Lava Cake (Serves 4) Prep: 15 mins | Cook: 12 mins @@ -130,16 +119,12 @@ Steps: --- ### Menu Planning - **Input:** - ```json { "user_message": "Plan a healthy meal plan for 3 days" } ``` - **Output:** - -``` +```text 📅 Your 3-Day Meal Plan Monday @@ -152,16 +137,12 @@ Monday --- ### Grocery List - **Input:** - ```json { "user_message": "What do I need to make pasta and caesar salad?" } ``` - **Output:** - -``` +```text 🛒 Grocery List (12 items) Vegetables: @@ -190,5 +171,5 @@ Dairy: --- -_Exported from Lamatic Template Library_ -_Template: Recipe AI Agent_ +*Exported from Lamatic Template Library* +*Template: Recipe AI Agent* diff --git a/recipe-ai-agent/config.json b/recipe-ai-agent/config.json index d1a39810..658bcb10 100644 --- a/recipe-ai-agent/config.json +++ b/recipe-ai-agent/config.json @@ -16,8 +16,8 @@ "headers": "", "retries": "0", "webhookUrl": "", - "responeType": "realtime", - "retry_deplay": "0", + "responseType": "realtime", + "retry_delay": "0", "advance_schema": "{\n \"user_message\": \"string\"\n}" } } @@ -90,11 +90,12 @@ "y": 0 }, "data": { - "nodeId": "LLMNode", + "nodeId": "InstructorLLMNode", "modes": {}, "values": { "nodeName": "Intent Detector", "tools": [], + "schema": "{\n \"type\": \"object\",\n \"properties\": {\n \"intent\": {\n \"type\": \"string\",\n \"required\": true,\n \"enum\": [\"RECIPE\", \"MENU\", \"GROCERY\", \"GENERAL\"],\n \"description\": \"The detected intent from the user message\"\n }\n }\n}", "prompts": [ { "id": "b2c3d4e5-0002-4000-b000-000000000001", @@ -104,7 +105,7 @@ { "id": "b2c3d4e5-0002-4000-b000-000000000002", "role": "system", - "content": "You are an intent detection agent for a Recipe AI app. Read the user message and classify it into exactly one of these intents:\n\n- RECIPE: User wants to generate a recipe for a specific dish\n- MENU: User wants a meal plan (daily or weekly)\n- GROCERY: User wants a grocery/shopping list for one or more recipes\n- GENERAL: User is asking a general cooking question\n\nRespond with only the intent label. No extra text. No punctuation. Just one word: RECIPE, MENU, GROCERY, or GENERAL." + "content": "You are an intent detection agent for a Recipe AI app. Read the user message and classify it into exactly one of these intents:\n\n- RECIPE: User wants to generate a recipe for a specific dish\n- MENU: User wants a meal plan (daily or weekly)\n- GROCERY: User wants a grocery/shopping list for one or more recipes\n- GENERAL: User is asking a general cooking question" } ], "memories": "[]", @@ -130,17 +131,17 @@ { "label": "Recipe", "value": "conditionNode_301-LLMNode_401", - "condition": "{\n \"operator\": null,\n \"operands\": [\n {\n \"name\": \"{{LLMNode_201.output.generatedResponse}}\",\n \"operator\": \"==\",\n \"value\": \"RECIPE\"\n }\n ]\n}" + "condition": "{\n \"operator\": null,\n \"operands\": [\n {\n \"name\": \"{{LLMNode_201.output.intent}}\",\n \"operator\": \"==\",\n \"value\": \"RECIPE\"\n }\n ]\n}" }, { "label": "Menu", "value": "conditionNode_301-LLMNode_402", - "condition": "{\n \"operator\": null,\n \"operands\": [\n {\n \"name\": \"{{LLMNode_201.output.generatedResponse}}\",\n \"operator\": \"==\",\n \"value\": \"MENU\"\n }\n ]\n}" + "condition": "{\n \"operator\": null,\n \"operands\": [\n {\n \"name\": \"{{LLMNode_201.output.intent}}\",\n \"operator\": \"==\",\n \"value\": \"MENU\"\n }\n ]\n}" }, { "label": "Grocery", "value": "conditionNode_301-LLMNode_403", - "condition": "{\n \"operator\": null,\n \"operands\": [\n {\n \"name\": \"{{LLMNode_201.output.generatedResponse}}\",\n \"operator\": \"==\",\n \"value\": \"GROCERY\"\n }\n ]\n}" + "condition": "{\n \"operator\": null,\n \"operands\": [\n {\n \"name\": \"{{LLMNode_201.output.intent}}\",\n \"operator\": \"==\",\n \"value\": \"GROCERY\"\n }\n ]\n}" }, { "label": "Else", @@ -498,4 +499,4 @@ "type": "responseEdge" } ] -} \ No newline at end of file +}