s
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
<title>NutriAI Elite v23.0</title>
|
<title>NutriAI Elite v24.0</title>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
@@ -114,15 +114,15 @@
|
|||||||
|
|
||||||
<div id="chat" class="chat-container">
|
<div id="chat" class="chat-container">
|
||||||
<div class="msg ai shadow">
|
<div class="msg ai shadow">
|
||||||
<h5 class="fw-bold text-primary">Precision Sync Active.</h5>
|
<h5 class="fw-bold text-primary">Intelligence Hub Updated.</h5>
|
||||||
The AI is now strictly calibrated to use **DRY/RAW weights** for all ingredient measurements and calorie counts.
|
Meal plans now include full macro breakdowns per ingredient. Shopping list recognition is fully active.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-area">
|
<div class="input-area">
|
||||||
<div class="input-group input-group-lg flex-grow-1">
|
<div class="input-group input-group-lg flex-grow-1">
|
||||||
<input type="text" id="uIn" class="form-control bg-dark text-white border-primary" placeholder="Type and press ENTER..." onkeydown="if(event.key === 'Enter') talk()">
|
<input type="text" id="uIn" class="form-control bg-dark text-white border-primary" placeholder="Type and press ENTER..." onkeydown="if(event.key === 'Enter') talk()">
|
||||||
<button class="btn btn-primary" onclick="talk()"><i class="fas fa-paper-plane"></i></button>
|
<button class="btn btn-primary" onclick="talk()"><button class="btn btn-primary" onclick="talk()"><i class="fas fa-paper-plane"></i></button></button>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn-shop shadow-sm" onclick="talk('GENERATE_SHOPPING_LIST')">
|
<button class="btn-shop shadow-sm" onclick="talk('GENERATE_SHOPPING_LIST')">
|
||||||
<i class="fas fa-shopping-basket me-1"></i> SHOPPING LIST
|
<i class="fas fa-shopping-basket me-1"></i> SHOPPING LIST
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
let isMetric = true, mChart;
|
let isMetric = true, mChart, conversationHistory = [];
|
||||||
const API = "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";
|
const API = "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";
|
||||||
|
|
||||||
function setTheme(t) { document.body.className = 'theme-' + t; }
|
function setTheme(t) { document.body.className = 'theme-' + t; }
|
||||||
@@ -178,37 +178,40 @@
|
|||||||
document.getElementById('act').selectedIndex = 0;
|
document.getElementById('act').selectedIndex = 0;
|
||||||
document.getElementById('kcal').innerText = "0";
|
document.getElementById('kcal').innerText = "0";
|
||||||
document.getElementById('h2o').innerText = isMetric ? "0.0L" : "0oz";
|
document.getElementById('h2o').innerText = isMetric ? "0.0L" : "0oz";
|
||||||
document.getElementById('chat').innerHTML = `<div class="msg ai shadow">System reset. Unit system: ${isMetric?'Metric':'Imperial'}.</div>`;
|
document.getElementById('chat').innerHTML = `<div class="msg ai shadow">System reset.</div>`;
|
||||||
|
conversationHistory = [];
|
||||||
if(mChart) { mChart.data.datasets[0].data = [1,1,1]; mChart.update(); }
|
if(mChart) { mChart.data.datasets[0].data = [1,1,1]; mChart.update(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
async function talk(custom) {
|
async function talk(custom) {
|
||||||
const box = document.getElementById('chat'), input = document.getElementById('uIn');
|
const box = document.getElementById('chat'), input = document.getElementById('uIn');
|
||||||
const isShopReq = custom === 'GENERATE_SHOPPING_LIST';
|
const isShopReq = custom === 'GENERATE_SHOPPING_LIST';
|
||||||
const text = isShopReq ? "Generate a shopping list based on the current plan." : (custom || input.value);
|
const text = isShopReq ? "GENERATE_SHOPPING_LIST: Consolidate all raw ingredients from the previously provided meal plan into a list." : (custom || input.value);
|
||||||
if(!text) return;
|
if(!text) return;
|
||||||
|
|
||||||
if(!custom) { box.innerHTML += `<div class="msg user shadow-sm">${text}</div>`; input.value=""; }
|
if(!custom) { box.innerHTML += `<div class="msg user shadow-sm">${text}</div>`; input.value=""; }
|
||||||
const id = 'ai-'+Date.now(); box.innerHTML += `<div id="${id}" class="msg ai shadow">Calculating with RAW weights...</div>`;
|
const id = 'ai-'+Date.now(); box.innerHTML += `<div id="${id}" class="msg ai shadow">Processing macros...</div>`;
|
||||||
box.scrollTop = box.scrollHeight;
|
box.scrollTop = box.scrollHeight;
|
||||||
|
|
||||||
|
const sysPrompt = {role:"system", content: `Expert Dietitian. Target: ${document.getElementById('kcal').innerText} kcal. SYSTEM: ${isMetric ? 'METRIC' : 'IMPERIAL'}.
|
||||||
|
CORE RULES:
|
||||||
|
1. Meal Plans MUST include a table with: Ingredient, Weight (DRY/RAW), Calories, P (g), C (g), F (g).
|
||||||
|
2. DRY/RAW weights are mandatory (e.g., 100g raw oats = 380kcal).
|
||||||
|
3. When user sends "GENERATE_SHOPPING_LIST", refer to the ingredients you just generated in the plan. Do NOT say there is no plan.
|
||||||
|
4. Shopping lists must use ${isMetric ? 'grams/kg' : 'oz/lbs'}.`};
|
||||||
|
|
||||||
|
conversationHistory.push({role: "user", content: text});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch("https://api.groq.com/openai/v1/chat/completions", {
|
const res = await fetch("https://api.groq.com/openai/v1/chat/completions", {
|
||||||
method: "POST", headers: {"Content-Type":"application/json", "Authorization":`Bearer ${API}`},
|
method: "POST", headers: {"Content-Type":"application/json", "Authorization":`Bearer ${API}`},
|
||||||
body: JSON.stringify({ model:"llama-3.3-70b-versatile", messages:[
|
body: JSON.stringify({ model:"llama-3.3-70b-versatile", messages:[sysPrompt, ...conversationHistory]})
|
||||||
{role:"system", content: `Expert Nutritionist. Target: ${document.getElementById('kcal').innerText} kcal. SYSTEM: ${isMetric ? 'METRIC' : 'IMPERIAL'}.
|
|
||||||
MANDATORY RULES:
|
|
||||||
1. ALWAYS use DRY/RAW weights for ingredients (e.g., 100g raw oats = ~380kcal, NOT 100g cooked).
|
|
||||||
2. Explicitly label weights as "(dry)" or "(raw)" in the meal plan tables.
|
|
||||||
3. DO NOT generate a shopping list unless requested via "GENERATE_SHOPPING_LIST".
|
|
||||||
4. If requested, provide shopping list quantities in ${isMetric ? 'grams/kilograms' : 'ounces/lbs'}.
|
|
||||||
5. Format response in Markdown tables.`},
|
|
||||||
{role:"user", content:text}
|
|
||||||
]})
|
|
||||||
});
|
});
|
||||||
const d = await res.json();
|
const d = await res.json();
|
||||||
document.getElementById(id).innerHTML = marked.parse(d.choices[0].message.content);
|
const aiMsg = d.choices[0].message.content;
|
||||||
} catch(e) { document.getElementById(id).innerText = "Connection error."; }
|
conversationHistory.push({role: "assistant", content: aiMsg});
|
||||||
|
document.getElementById(id).innerHTML = marked.parse(aiMsg);
|
||||||
|
} catch(e) { document.getElementById(id).innerText = "Sync error."; }
|
||||||
box.scrollTop = box.scrollHeight;
|
box.scrollTop = box.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user