From a45a659f64e0b3216270ad288100c6e937244e35 Mon Sep 17 00:00:00 2001 From: Kingshuk-Microsoft Date: Thu, 18 Dec 2025 18:53:53 +0530 Subject: [PATCH 1/3] enhance error logging, escape HTML and remove unused state update test imports --- package-lock.json | 6 ++++ .../v4/magentic_agents/common/lifecycle.py | 29 +++++++++---------- src/frontend/frontend_server.py | 8 +++-- src/frontend/package-lock.json | 25 +--------------- .../src/components/content/HomeInput.tsx | 4 --- src/tests/agents/test_foundry_integration.py | 2 +- .../agents/test_human_approval_manager.py | 2 +- 7 files changed, 29 insertions(+), 47 deletions(-) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..61d91fc72 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "Multi-Agent-Custom-Automation-Engine-Solution-Accelerator", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/src/backend/v4/magentic_agents/common/lifecycle.py b/src/backend/v4/magentic_agents/common/lifecycle.py index ecc1eceee..ed0fe79e4 100644 --- a/src/backend/v4/magentic_agents/common/lifecycle.py +++ b/src/backend/v4/magentic_agents/common/lifecycle.py @@ -85,8 +85,8 @@ async def open(self) -> "MCPEnabledBase": # Register agent (best effort) try: agent_registry.register_agent(self) - except Exception: - pass + except Exception as ex: + self.logger.debug("Failed to register agent in registry: %s", ex) return self @@ -98,13 +98,13 @@ async def close(self) -> None: if self._agent and hasattr(self._agent, "close"): try: await self._agent.close() # AzureAIAgentClient has async close - except Exception: - pass + except Exception as ex: + self.logger.debug("Failed to close agent: %s", ex) # Unregister from registry if present try: agent_registry.unregister_agent(self) - except Exception: - pass + except Exception as ex: + self.logger.debug("Failed to unregister agent from registry: %s", ex) await self._stack.aclose() finally: self._stack = None @@ -309,27 +309,26 @@ async def close(self) -> None: if self._agent and hasattr(self._agent, "close"): try: await self._agent.close() - except Exception: - pass + except Exception as ex: + self.logger.debug("Failed to close agent in AzureAgentBase: %s", ex) # Unregister from registry try: agent_registry.unregister_agent(self) - except Exception: - pass + except Exception as ex: + self.logger.debug("Failed to unregister agent from registry: %s", ex) # Close credential and project client if self.client: try: await self.client.close() - except Exception: - pass + except Exception as ex: + self.logger.debug("Failed to close Azure AI client: %s", ex) if self.creds: try: await self.creds.close() - except Exception: - pass - + except Exception as ex: + self.logger.debug("Failed to close Azure credentials: %s", ex) finally: await super().close() self.client = None diff --git a/src/frontend/frontend_server.py b/src/frontend/frontend_server.py index 1566c8a87..d816337da 100644 --- a/src/frontend/frontend_server.py +++ b/src/frontend/frontend_server.py @@ -41,9 +41,13 @@ async def get_config(): auth_enabled = os.getenv("AUTH_ENABLED", "false") backend_url = backend_url + "/api" + # Escape the values for safe inclusion in HTML + escaped_backend_url = html.escape(backend_url) + escaped_auth_enabled = html.escape(auth_enabled) + config = { - "API_URL": backend_url, - "ENABLE_AUTH": auth_enabled, + "API_URL": escaped_backend_url, + "ENABLE_AUTH": escaped_auth_enabled, } return config diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index 6f2d97599..3e17847f7 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -99,7 +99,6 @@ "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", @@ -467,7 +466,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -491,7 +489,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -1039,7 +1036,6 @@ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", "license": "MIT", - "peer": true, "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" @@ -3091,7 +3087,6 @@ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -3313,7 +3308,6 @@ "integrity": "sha512-yCAeZl7a0DxgNVteXFHt9+uyFbqXGy/ShC4BlcHkoE0AfGXYv/BUiplV72DjMYXHDBXFjhvr6DD1NiRVfB4j8g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -3329,7 +3323,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.24.tgz", "integrity": "sha512-0dLEBsA1kI3OezMBF8nSsb7Nk19ZnsyE1LLhB8r27KbgU5H4pvuqZLdtE+aUkJVoXgTVuA+iLIwmZ0TuK4tx6A==", "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -3340,7 +3333,6 @@ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^18.0.0" } @@ -3399,7 +3391,6 @@ "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -3688,7 +3679,6 @@ "integrity": "sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/utils": "3.2.4", "fflate": "^0.8.2", @@ -3726,7 +3716,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4079,7 +4068,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001737", "electron-to-chromium": "^1.5.211", @@ -4661,8 +4649,7 @@ "version": "8.6.0", "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz", "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/embla-carousel-autoplay": { "version": "8.6.0", @@ -4946,7 +4933,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -6562,7 +6548,6 @@ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", @@ -8248,7 +8233,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -8261,7 +8245,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -9315,7 +9298,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -9581,7 +9563,6 @@ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -9621,7 +9602,6 @@ "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", "license": "MIT", - "peer": true, "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", @@ -9819,7 +9799,6 @@ "integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -9936,7 +9915,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -9950,7 +9928,6 @@ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", diff --git a/src/frontend/src/components/content/HomeInput.tsx b/src/frontend/src/components/content/HomeInput.tsx index 3b8c88d84..48d66c571 100644 --- a/src/frontend/src/components/content/HomeInput.tsx +++ b/src/frontend/src/components/content/HomeInput.tsx @@ -63,7 +63,6 @@ interface ExtendedQuickTask extends QuickTask { const HomeInput: React.FC = ({ selectedTeam }) => { const [submitting, setSubmitting] = useState(false); const [input, setInput] = useState(""); - const [raiError, setRAIError] = useState(null); const textareaRef = useRef(null); const navigate = useNavigate(); @@ -79,7 +78,6 @@ const HomeInput: React.FC = ({ selectedTeam }) => { const resetTextarea = () => { setInput(""); - setRAIError(null); // Clear any RAI errors if (textareaRef.current) { textareaRef.current.style.height = "auto"; textareaRef.current.focus(); @@ -94,7 +92,6 @@ const HomeInput: React.FC = ({ selectedTeam }) => { const handleSubmit = async () => { if (input.trim()) { setSubmitting(true); - setRAIError(null); // Clear any previous RAI errors let id = showToast("Creating a plan", "progress"); try { @@ -140,7 +137,6 @@ const HomeInput: React.FC = ({ selectedTeam }) => { const handleQuickTaskClick = (task: ExtendedQuickTask) => { setInput(task.fullDescription); - setRAIError(null); // Clear any RAI errors when selecting a quick task if (textareaRef.current) { textareaRef.current.focus(); } diff --git a/src/tests/agents/test_foundry_integration.py b/src/tests/agents/test_foundry_integration.py index 28cd108b8..b2ef9ab60 100644 --- a/src/tests/agents/test_foundry_integration.py +++ b/src/tests/agents/test_foundry_integration.py @@ -15,7 +15,7 @@ # Now import from the v4 package from src.backend.v4.magentic_agents.foundry_agent import FoundryAgentTemplate -from src.backend.v4.magentic_agents.models.agent_models import (BingConfig, MCPConfig, +from src.backend.v4.magentic_agents.models.agent_models import (MCPConfig, SearchConfig) diff --git a/src/tests/agents/test_human_approval_manager.py b/src/tests/agents/test_human_approval_manager.py index 2a600c82c..375c918fe 100644 --- a/src/tests/agents/test_human_approval_manager.py +++ b/src/tests/agents/test_human_approval_manager.py @@ -7,7 +7,7 @@ backend_path = Path(__file__).parent.parent.parent / "backend" sys.path.insert(0, str(backend_path)) -from af.models.models import MPlan, MStep +from af.models.models import MPlan from af.orchestration.human_approval_manager import \ HumanApprovalMagenticManager From 42b728c23d055f412e70857ccc793456df5b68c1 Mon Sep 17 00:00:00 2001 From: Kingshuk-Microsoft Date: Fri, 19 Dec 2025 10:35:33 +0530 Subject: [PATCH 2/3] validate backend URL and auth enabled values in config endpoint --- src/frontend/frontend_server.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/frontend/frontend_server.py b/src/frontend/frontend_server.py index d816337da..0edcb71c4 100644 --- a/src/frontend/frontend_server.py +++ b/src/frontend/frontend_server.py @@ -39,15 +39,19 @@ async def serve_index(): async def get_config(): backend_url = os.getenv("BACKEND_API_URL", "http://localhost:8000") auth_enabled = os.getenv("AUTH_ENABLED", "false") + + # Validate backend_url is a proper URL + if not backend_url.startswith(("http://", "https://")): + backend_url = "http://localhost:8000" + backend_url = backend_url + "/api" - - # Escape the values for safe inclusion in HTML - escaped_backend_url = html.escape(backend_url) - escaped_auth_enabled = html.escape(auth_enabled) + + # Validate auth_enabled is a boolean string + auth_enabled = auth_enabled.lower() if auth_enabled.lower() in ["true", "false"] else "false" config = { - "API_URL": escaped_backend_url, - "ENABLE_AUTH": escaped_auth_enabled, + "API_URL": backend_url, + "ENABLE_AUTH": auth_enabled, } return config From 45c3ae77b89e6bc42ff35daf19a88f4638bbfccf Mon Sep 17 00:00:00 2001 From: Kingshuk-Microsoft Date: Fri, 19 Dec 2025 12:27:45 +0530 Subject: [PATCH 3/3] validate backend URL and auth_enabled values in config endpoint; remove unused error card import in HomeInput component --- src/frontend/frontend_server.py | 14 +++++++++++--- src/frontend/src/components/content/HomeInput.tsx | 1 - 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/frontend/frontend_server.py b/src/frontend/frontend_server.py index 0edcb71c4..a0694cc82 100644 --- a/src/frontend/frontend_server.py +++ b/src/frontend/frontend_server.py @@ -7,6 +7,7 @@ from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse, HTMLResponse from fastapi.staticfiles import StaticFiles +from urllib.parse import urlparse # Load environment variables from .env file load_dotenv() @@ -40,14 +41,21 @@ async def get_config(): backend_url = os.getenv("BACKEND_API_URL", "http://localhost:8000") auth_enabled = os.getenv("AUTH_ENABLED", "false") - # Validate backend_url is a proper URL - if not backend_url.startswith(("http://", "https://")): + # Validate backend_url is a proper URL with scheme and netloc + try: + parsed = urlparse(backend_url) + if not (parsed.scheme in ["http", "https"] and parsed.netloc): + backend_url = "http://localhost:8000" + except Exception: backend_url = "http://localhost:8000" backend_url = backend_url + "/api" # Validate auth_enabled is a boolean string - auth_enabled = auth_enabled.lower() if auth_enabled.lower() in ["true", "false"] else "false" + if auth_enabled and auth_enabled.lower() in ["true", "false"]: + auth_enabled = auth_enabled.lower() + else: + auth_enabled = "false" config = { "API_URL": backend_url, diff --git a/src/frontend/src/components/content/HomeInput.tsx b/src/frontend/src/components/content/HomeInput.tsx index 48d66c571..4686e41f5 100644 --- a/src/frontend/src/components/content/HomeInput.tsx +++ b/src/frontend/src/components/content/HomeInput.tsx @@ -17,7 +17,6 @@ import "./../../styles/HomeInput.css"; import { HomeInputProps, iconMap, QuickTask } from "../../models/homeInput"; import { TaskService } from "../../services/TaskService"; import { NewTaskService } from "../../services/NewTaskService"; -import { RAIErrorCard, RAIErrorData } from "../errors"; import ChatInput from "@/coral/modules/ChatInput"; import InlineToaster, { useInlineToaster } from "../toast/InlineToaster";