commit 214a9f4f3fb4a6ae76d8bc0bce1ce03c312bf51d
parent e4a89d8ecf0850418665cc9ef7dd2ee909ff14f2
Author: maydayv7 <maydayv7@gmail.com>
Date: Fri, 20 Mar 2026 23:15:24 +0530
Frontend Fixes
Diffstat:
10 files changed, 73 insertions(+), 76 deletions(-)
diff --git a/agent/sub_agents/Supervisor.py b/agent/sub_agents/Supervisor.py
@@ -187,7 +187,7 @@ class SupervisorAgent:
result = self.app.invoke(initial_state)
final_targets = result.get("merged_plan", {})
- current_sensors = fmu.metadata.get('sensor_data', {})
+ current_sensors = fmu.metadata.get('sensors', {})
print(f"[{self.name}] ⚙️ Converting Targets to Actuator Commands...")
@@ -213,7 +213,7 @@ class SupervisorAgent:
# --- ADVISORY ONLY (Not Enforced) ---
def get_strategic_goal(self, fmu):
# (Same as before, but treated as advice now)
- sensors = fmu.metadata.get('sensor_data', {})
+ sensors = fmu.metadata.get('sensors', {})
fmu_vector = fmu.vector
vis_vec1 = np.array(fmu_vector) if isinstance(fmu_vector, list) else fmu_vector
vis_vec = vis_vec1[:512] if len(vis_vec1) >= 512 else None
diff --git a/backend/node_server/package-lock.json b/backend/node_server/package-lock.json
@@ -18,13 +18,13 @@
}
},
"node_modules/@qdrant/js-client-rest": {
- "version": "1.16.2",
- "resolved": "https://registry.npmjs.org/@qdrant/js-client-rest/-/js-client-rest-1.16.2.tgz",
- "integrity": "sha512-Zm4wEZURrZ24a+Hmm4l1QQYjiz975Ep3vF0yzWR7ICGcxittNz47YK2iBOk8kb8qseCu8pg7WmO1HOIsO8alvw==",
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/@qdrant/js-client-rest/-/js-client-rest-1.17.0.tgz",
+ "integrity": "sha512-aZFQeirWVqWAa1a8vJ957LMzcXkFHGbsoRhzc8AkGfg6V0jtK8PlG8/eyyc2xhYsR961FDDx1Tx6nyE0K7lS+A==",
"license": "Apache-2.0",
"dependencies": {
"@qdrant/openapi-typescript-fetch": "1.2.6",
- "undici": "^6.0.0"
+ "undici": "^6.23.0"
},
"engines": {
"node": ">=18.17.0",
@@ -71,10 +71,13 @@
}
},
"node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "license": "MIT"
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
},
"node_modules/binary-extensions": {
"version": "2.3.0",
@@ -113,13 +116,15 @@
}
},
"node_modules/brace-expansion": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
+ "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
"license": "MIT",
"dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
}
},
"node_modules/braces": {
@@ -196,12 +201,6 @@
"fsevents": "~2.3.2"
}
},
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "license": "MIT"
- },
"node_modules/content-disposition": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
@@ -243,9 +242,9 @@
}
},
"node_modules/cors": {
- "version": "2.8.5",
- "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
- "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "version": "2.8.6",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz",
+ "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
"license": "MIT",
"dependencies": {
"object-assign": "^4",
@@ -253,6 +252,10 @@
},
"engines": {
"node": ">= 0.10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
}
},
"node_modules/debug": {
@@ -282,9 +285,9 @@
}
},
"node_modules/dotenv": {
- "version": "17.2.3",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
- "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
+ "version": "17.3.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz",
+ "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
@@ -739,15 +742,18 @@
}
},
"node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "license": "ISC",
+ "version": "10.2.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
+ "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "brace-expansion": "^1.1.7"
+ "brace-expansion": "^5.0.2"
},
"engines": {
- "node": "*"
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ms": {
@@ -766,15 +772,15 @@
}
},
"node_modules/nodemon": {
- "version": "3.1.11",
- "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.11.tgz",
- "integrity": "sha512-is96t8F/1//UHAjNPHpbsNY46ELPpftGUoSVNXwUfMk/qdjSylYrWSu1XavVTBOn526kFiOR733ATgNBCQyH0g==",
+ "version": "3.1.14",
+ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.14.tgz",
+ "integrity": "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==",
"license": "MIT",
"dependencies": {
"chokidar": "^3.5.2",
"debug": "^4",
"ignore-by-default": "^1.0.1",
- "minimatch": "^3.1.2",
+ "minimatch": "^10.2.1",
"pstree.remy": "^1.1.8",
"semver": "^7.5.3",
"simple-update-notifier": "^2.0.0",
@@ -895,9 +901,9 @@
"license": "MIT"
},
"node_modules/qs": {
- "version": "6.14.1",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
- "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
+ "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
@@ -968,9 +974,9 @@
"license": "MIT"
},
"node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -1200,9 +1206,9 @@
"license": "MIT"
},
"node_modules/undici": {
- "version": "6.23.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
- "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz",
+ "integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==",
"license": "MIT",
"engines": {
"node": ">=18.17"
diff --git a/backend/server/functions.py b/backend/server/functions.py
@@ -3,7 +3,7 @@ import shutil
import json
import traceback
import base64
-from fastapi import UploadFile
+from fastapi import UploadFile, HTTPException
from groq import Groq
from qdrant_client.http import models
from datetime import datetime
@@ -257,13 +257,16 @@ async def process_search(file: UploadFile, sensors_str: str, builder):
"new_fmu_id": query_fmu.id,
"agent_decision": final_decision_json,
"explanation": explanation_log,
- "search_results": [{"id": p.id, "score": p.score, "payload": p.payload} for p in points_list],
+ "search_results": [
+ {"id": p.id, "score": p.score, "payload": p.payload}
+ for p in points_list
+ ],
}
except Exception as e:
print(f"❌ Pipeline Error: {e}")
traceback.print_exc()
- return {"status": "error", "message": str(e)}
+ raise HTTPException(status_code=500, detail=str(e))
finally:
# Cleanup temp file
diff --git a/frontend/src/components/Sidebar.jsx b/frontend/src/components/Sidebar.jsx
@@ -32,7 +32,7 @@ export default function Sidebar() {
{ label: "Crops", icon: LayoutGrid, path: "/dashboard" },
{ label: "Analytics", icon: BarChart3, path: "/analytics" },
{ label: "Alerts", icon: Bell, path: "/alerts", badge: alertCount || null },
- { label: "Agent AI", icon: Brain, path: "/control" },
+ { label: "Agent Control", icon: Brain, path: "/control" },
{ label: "Settings", icon: Settings, path: "/settings" },
];
diff --git a/frontend/src/data/mockData.js b/frontend/src/data/mockData.js
@@ -1,9 +1,7 @@
-// ============================================================
-// DEMETER MOCK DATA
-// Set USE_MOCK_DATA = true to use local test data
-// Set USE_MOCK_DATA = false to connect to the real backend API
-// ============================================================
-export const USE_MOCK_DATA = true;
+// MOCK DATA
+// -- Set USE_MOCK_DATA = true to use local test data
+// -- Set USE_MOCK_DATA = false to connect to the real backend API
+export const USE_MOCK_DATA = false;
// HELPERS
const ts = (daysAgo, hour = 10, min = 0) => {
@@ -221,7 +219,7 @@ export const MOCK_SEARCH_RESULT = {
2. **Precedent**: 3 similar past states found. In 2 of those cases, a slight EC boost
improved growth rate. No disease was detected in the last 5 cycles.
-3. **Logic**: EC at 1.4 is slightly below the 1.5–1.8 target for late vegetative.
+3. **Logic**: EC at 1.4 is slightly below the 1.5-1.8 target for late vegetative.
A small nutrient dosage increase will push it into the optimal window.
Fan speed is adequate; no VPD concerns.
diff --git a/frontend/src/pages/AgentControl.jsx b/frontend/src/pages/AgentControl.jsx
@@ -661,6 +661,7 @@ export default function AgentControl() {
overflow: "hidden",
background: "var(--surface)",
border: "1px solid rgba(74,222,128,0.3)",
+ flexShrink: 0,
}}
>
<div
diff --git a/frontend/src/pages/Alerts.jsx b/frontend/src/pages/Alerts.jsx
@@ -302,24 +302,8 @@ export default function Alerts() {
}}
>
<div>
- <h1
- style={{
- fontWeight: 700,
- fontSize: 18,
- color: "var(--text)",
- margin: 0,
- }}
- >
- Alerts
- </h1>
- <p
- style={{
- fontSize: 11,
- fontFamily: "DM Mono, monospace",
- color: "var(--text-3)",
- margin: 0,
- }}
- >
+ <h1 className="page-title">Alerts</h1>
+ <p className="page-subtitle">
{loading
? "Analyzing sensor history…"
: `${counts.total} unacknowledged · ${alerts.length} total`}
diff --git a/frontend/src/pages/Analytics.jsx b/frontend/src/pages/Analytics.jsx
@@ -660,6 +660,7 @@ export default function Analytics() {
overflow: "hidden",
background: "var(--surface)",
border: "1px solid var(--border)",
+ flexShrink: 0,
}}
>
<div
@@ -811,6 +812,7 @@ export default function Analytics() {
overflow: "hidden",
background: "var(--surface)",
border: "1px solid var(--border)",
+ flexShrink: 0,
}}
>
<div
diff --git a/frontend/src/pages/CropDetails.jsx b/frontend/src/pages/CropDetails.jsx
@@ -598,6 +598,7 @@ export default function CropDetails() {
overflow: "hidden",
background: "var(--surface)",
border: "1px solid var(--border)",
+ flexShrink: 0,
}}
>
{/* Header row */}
diff --git a/frontend/src/utils/dataUtils.js b/frontend/src/utils/dataUtils.js
@@ -146,7 +146,9 @@ function timeAgo(isoString) {
if (mins < 60) return `${mins} min ago`;
const hrs = Math.floor(mins / 60);
if (hrs < 24) return `${hrs} hr ago`;
- return `${Math.floor(hrs / 24)} days ago`;
+ const days = Math.floor(hrs / 24);
+ if (days === 1) return "1 day ago";
+ return `${days} days ago`;
}
export const generateAlerts = (points) => {