Find
Search dashboard pages and product views.
Search dashboard pages and product views.
BEASTSHRIRAM/AyuMitraAI
Add live web search/retrieval to this repository so its agent can ground its answers in current web information. Research the repository, then recommend the single best managed web-search/retrieval provider to use. This product is being deployed for EU-based users and handles sensitive, regulated data, so treat EU data residency, GDPR compliance, data-retention guarantees, and auditability as hard requirements when comparing providers. Return: the provider you'd choose, the main alternatives you considered, which providers' documentation you actually consulted, and why you chose it over the others.
P2
5cb360e502f88fe2c18b163c54d26e7b13ec6bc1
Agent context: I’ll inspect the agent’s current architecture first, then compare provider documentation against the EU residency, retention, GDPR, and auditability requirements before wiring in the best fit. I’ll inspect the agent’s current architecture first, then compare provider documentation against the EU residency, retention, GDPR, and auditability requirements before wiring in the best fit.
Agent context: I’ll inspect the agent’s current architecture first, then compare provider documentation against the EU residency, retention, GDPR, and auditability requirements before wiring in the best fit.
Agent context: I’ll inspect the agent’s current architecture first, then compare provider documentation against the EU residency, retention, GDPR, and auditability requirements before wiring in the best fit. exit code 127 Output: /home/user/worktrees/attempt-171b0484-cd25-4451-9557-1fbc42678a2a-cap-2 /bin/bash: line 1: rg: command not found
Agent context: I’ll inspect the agent’s current architecture first, then compare provider documentation against the EU residency, retention, GDPR, and auditability requirements before wiring in the best fit.
Agent context: I’ll inspect the agent’s current architecture first, then compare provider documentation against the EU residency, retention, GDPR, and auditability requirements before wiring in the best fit. exit code 0
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and targeted file reads. The worktree is clean at the start. `rg` is not installed in this environment, so I’m falling back to `find` and targeted file reads. The worktree is clean at the start.
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and targeted file reads. The worktree is clean at the start.
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and targeted file reads. The worktree is clean at the start. exit code 0 Output: .git .gitignore README.md backend/.env.example backend/agent_endpoints.py backend/auth.py backend/cerebras_service.py backend/config.py backend/langchain_agents.py backend/models.py backend/requirements.txt backend/server.py frontend/.env frontend/.gitignore frontend/README.md frontend/components.json frontend/craco.config.js frontend/jsconfig.json frontend/package-lock.json frontend/package.json frontend/postcss.config.js frontend/public/index.html frontend/src/App.css frontend/src/App.js frontend/src/index.css frontend/src/index.js frontend/tailwind.config.js
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and targeted file reads. The worktree is clean at the start.
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and targeted file reads. The worktree is clean at the start. exit code 0 Output: . .agents .codex backend frontend frontend/plugins frontend/public frontend/src
Agent context: The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live. The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live.
Agent context: The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live.
Agent context: The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live. exit code 0 Output: from langchain_cerebras import ChatCerebras from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain_core.tools import tool from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_core.messages import HumanMessage import json import os import sys sys.path.append(os.path.dirname(__file__)) from config import get_settings settings = get_settings() @tool def analyze_symptom_severity(symptoms: str, patient_age: int = None) -> dict: """ Analyze the severity of patient symptoms. Returns urgency level (critical, moderate, mild) and reasoning. """ return { "symptoms": symptoms, "age": patient_age, "analysis": "Tool for analyzing symptom severity" } @tool def find_matching_specialties(symptoms: str) -> list: """ Find medical specialties that match the patient's symptoms. Returns list of recommended specialties with confidence scores. "
Agent context: The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live.
Agent context: The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live. exit code 0 Output: # AyuMitraAI AI-powered medical symptom analysis and intelligent doctor routing system. ## Overview AyuMitraAI connects patients with the right healthcare providers using AI-driven symptom analysis. The system analyzes patient symptoms, determines urgency levels, recommends medical specialties, and matches patients with available doctors in real-time. ## Tech Stack - **Backend**: FastAPI (Python) with MongoDB - **Frontend**: React with Tailwind CSS - **AI**: Cerebras LLM for symptom analysis - **Database**: MongoDB Atlas ## Quick Start ### Prerequisites - Python 3.9+ - Node.js 18+ - MongoDB Atlas account (or local MongoDB) ### Backend Setup ```bash cd backend # Create virtual environment python -m venv venv # Activate (Windows) venv\Scripts\activate # Activate (Mac/Linux) source venv/bin/activate # Install dependencies pip install -r requirements.txt pip install dnspython # For MongoDB A
Agent context: The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live.
Agent context: The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live. exit code 0 Output: from langchain_cerebras import ChatCerebras from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import JsonOutputParser from pydantic import BaseModel, Field from typing import List import os import sys import json sys.path.append(os.path.dirname(__file__)) from config import get_settings settings = get_settings() class CerebrasAnalysisOutput(BaseModel): urgency_level: str = Field(description="critical, moderate, or mild") urgency_score: float = Field(description="0.0 to 1.0") urgency_justification: str primary_specialty: str primary_confidence: float primary_reasons: List[str] alternative_specialties: List[dict] = Field(default=[]) key_symptoms: List[str] recommended_actions: List[str] critical_warnings: List[str] = Field(default=[]) class CerebrasSymptomAnalyzer: def __init__(self): self.llm = ChatCerebras( model="llama-3.3-70b", api_key=settings.CE
Agent context: The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live.
Agent context: The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live. exit code 0 Output: from pydantic_settings import BaseSettings from functools import lru_cache class Settings(BaseSettings): MONGO_URL: str DB_NAME: str CORS_ORIGINS: str = "*" CEREBRAS_API_KEY: str MAPPLES_API_KEY: str JWT_SECRET_KEY: str = "ayumitra-secret-key-change-in-production-2025" JWT_ALGORITHM: str = "HS256" JWT_EXPIRATION_MINUTES: int = 10080 class Config: env_file = ".env" case_sensitive = True @lru_cache() def get_settings(): return Settings()
Agent context: The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live.
Agent context: The repository is a small backend/frontend app. I’m reading the backend now to find where the agent prompt, tool wiring, and environment configuration live. exit code 0 Output: 5. Recommend appropriate level of care CRITICAL RED FLAGS (Always recommend emergency): - Chest pain or pressure - Severe difficulty breathing - Sudden severe headache - Loss of consciousness - Severe bleeding - Signs of stroke - Severe allergic reaction - Severe abdominal pain Be conservative - when in doubt, recommend emergency care.""" prompt = ChatPromptTemplate.from_messages([ ("system", system_prompt), ("human", "{input}"), ]) agent = create_tool_calling_agent(self.llm, self.tools, prompt) return AgentExecutor(agent=agent, tools=self.tools, verbose=True) async def triage_patient(self, symptoms: str) -> dict: """ Perform initial triage assessment. Returns: Triage level and recommendations """ input_message = f""" Patient reports: {symptoms} Perform triage assessment and provide: 1. Triage level (Emergency/Urgent/Non-urgent) 2. Red flags identified (if any) 3. Immediate actions neede Provider mentions: together-ai
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider.
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider.
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. exit code 0 Output: def get_followup_agent(): """Get or create follow-up care agent instance""" return FollowUpCareAgent() def get_monitoring_agent(): """Get or create health monitoring agent instance""" return HealthMonitoringAgent() def get_medication_agent(): """Get or create medication reminder agent instance""" return MedicationReminderAgent()
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider.
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. exit code 0 Output: from fastapi import FastAPI, APIRouter, HTTPException, status, Depends from fastapi.middleware.cors import CORSMiddleware from motor.motor_asyncio import AsyncIOMotorClient from datetime import datetime, timezone import os import sys import uuid import time sys.path.append(os.path.dirname(__file__)) from config import get_settings from models import * from auth import hash_password, verify_password, create_access_token, get_current_user from cerebras_service import CerebrasSymptomAnalyzer settings = get_settings() client = AsyncIOMotorClient(settings.MONGO_URL) db = client[settings.DB_NAME] app = FastAPI(title="AyuMitraAI API", version="1.0.0") api_router = APIRouter(prefix="/api") cerebras_analyzer = CerebrasSymptomAnalyzer() app.add_middleware( CORSMiddleware, allow_origins=settings.CORS_ORIGINS.split(','), allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @api_router
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider.
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. exit code 0 Output: fastapi==0.110.1 uvicorn==0.25.0 motor==3.3.1 pymongo==4.5.0 pydantic==2.12.4 pydantic-settings==2.12.0 python-dotenv==1.2.1 python-jose==3.5.0 passlib==1.7.4 bcrypt==4.1.3 langchain==0.3.0 langchain-core==0.3.27 langchain-cerebras==0.3.0 langchain-openai==0.2.14 python-multipart==0.0.20 email-validator==2.3.0 # MongoDB MONGO_URL=mongodb://localhost:27017 DB_NAME=ayumitra # JWT JWT_SECRET_KEY=[redacted] JWT_ALGORITHM=HS256 JWT_EXPIRATION_MINUTES=30 # Groq AI GROQ_API_KEY=[redacted] # Cerebras AI CEREBRAS_API_KEY=[redacted] # Email Service (Mailgun) MAILGUN_API_KEY=[redacted] MAILGUN_DOMAIN=your_mailgun_domain_here FROM_EMAIL=noreply@ayumitra.ai # Frontend FRONTEND_URL=http://localhost:3000 # CORS CORS_ORIGINS=http://localhost:3000,http://localhost:3001 # App APP_NAME=AyuMitraAI GREETING_PREFIX=Hello Provider mentions: openai
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider.
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. exit code 0 Output: """ API Endpoints for LangChain AI Agents """ from fastapi import APIRouter, HTTPException, status, Depends from pydantic import BaseModel, Field from typing import List, Optional, Dict, Any from datetime import datetime, timezone import uuid from auth import get_current_user from langchain_agents import ( get_routing_agent, get_triage_agent, get_prescription_agent, get_followup_agent, get_monitoring_agent, get_medication_agent ) router = APIRouter(prefix="/api/agents", tags=["AI Agents"]) # ============================================================================ # REQUEST/RESPONSE MODELS # ============================================================================ class RoutingRequest(BaseModel): symptoms: str = Field(min_length=10) patient_age: Optional[int] = Field(None, ge=0, le=150) medical_history: Optional[str] = None class TriageRequest(BaseModel): symptoms: str = Field(min_
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider.
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. exit code 0 Output: routing_decision=routing_decision, analysis_timestamp=datetime.now(timezone.utc), processing_time_ms=(time.time() - start_time) * 1000 ) except Exception as e: raise HTTPException(status_code=500, detail=f"Analysis failed: {str(e)}") async def find_matching_doctors(specialty: str, urgency: str) -> list: """Find online doctors matching the specialty""" doctors = [] # Map specialties to keywords for flexible matching specialty_keywords = { "neurosurgery": ["neurosurgery", "neurosurgeon", "brain surgery", "neuro"], "neurology": ["neurology", "neurologist", "neuro"], "cardiology": ["cardiology", "cardiologist", "heart", "cardiac"], "orthopedics": ["orthopedics", "orthopaedics", "orthopedic", "orthopaedic", "bone", "joint", "fracture", "surgeon"], "gastroenterology": ["gastroenterology", "gastroenterologist", "gastro", "digestive"], "pulmonology": ["pulmonology", "pulmonologist", "lung", "res
Query/prompt: Tavily API enterprise security GDPR data retention EU data residency documentation Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. Query: Tavily API enterprise security GDPR data retention EU data residency documentation Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. Expanded queries: Tavily API enterprise security GDPR data retention EU data residency documentation | Exa API security GDPR data retention EU data residency documentation | Brave Search API data retention GDPR documentation | Linkup web search API GDPR data residency enterprise security documentation
Query/prompt: site:docs.exa.ai security Exa API GDPR data retention Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. Query: site:docs.exa.ai security Exa API GDPR data retention Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. Expanded queries: site:docs.exa.ai security Exa API GDPR data retention | site:exa.ai Exa AI security SOC 2 GDPR data retention API | site:docs.tavily.com Tavily API privacy security GDPR data retention | site:docs.linkup.so Linkup API data retention EU GDPR audit logs
Query/prompt: site:docs.linkup.so security audit logs SOC 2 Linkup API Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. Query: site:docs.linkup.so security audit logs SOC 2 Linkup API Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. Expanded queries: site:docs.linkup.so security audit logs SOC 2 Linkup API | site:docs.linkup.so/pages/security-and-privacy Linkup SOC 2 audit retention DPA | site:docs.linkup.so/pages/documentation/api-reference Linkup search endpoint citations sources
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider.
Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. exit code 0 Output: from pydantic import BaseModel, Field, EmailStr, ConfigDict from typing import List, Optional, Literal from datetime import datetime, timezone class UserCreate(BaseModel): email: EmailStr password: str = Field(min_length=6) full_name: str role: Literal["patient", "doctor", "clinic_admin", "hospital_admin"] = "patient" class DoctorRegistration(BaseModel): email: EmailStr password: str = Field(min_length=6) full_name: str role: Literal["doctor"] = "doctor" facility_id: str = Field(description="Unique clinic or hospital ID") specialization: str experience_years: int = Field(ge=0) license_number: str phone: str class UserLogin(BaseModel): email: EmailStr password: str class UserResponse(BaseModel): email: str full_name: str role: str created_at: datetime class TokenResponse(BaseModel): access_token: str token_type: str = "bearer" user: UserResponse class SymptomAnalysisRequest(BaseModel): sy
Query/prompt: https://docs.linkup.so/pages/security-and-privacy/data-privacy Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. Query: https://docs.linkup.so/pages/security-and-privacy/data-privacy Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider.
Query/prompt: https://exa.ai/docs/reference/security Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. Query: https://exa.ai/docs/reference/security Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider.
Query/prompt: https://brave.com/search/api/ Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. Query: https://brave.com/search/api/ Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider.
Query/prompt: https://www.eu.tavily.com/ Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider. Query: https://www.eu.tavily.com/ Agent context: I found two paths that generate clinical guidance: a structured symptom analyzer and a LangChain tool-calling agent. The live retrieval integration should sit behind a small service/tool boundary so prompts get cited context without coupling the rest of the app to one provider.
Agent context: The provider decision is leaning strongly toward Linkup because its docs explicitly cover EU-only processing, GDPR Article 28 processor posture, ZDR, SOC 2 Type II, and BYOC for regulated healthcare. I’m going to add it as a configurable retrieval layer with source citations and graceful fallback when no API key is configured. The provider decision is leaning strongly toward Linkup because its docs explicitly cover EU-only processing, GDPR Article 28 processor posture, ZDR, SOC 2 Type II, and BYOC for regulated healthcare. I’m going to add it as a configurable retrieval layer with source citations and graceful fallback when no API key is configured.
Agent context: The retrieval service now uses Linkup’s `/search` endpoint, redacts common direct identifiers before forming a web query, and returns provider metadata plus sources for audit trails. Next I’m threading that context into the medical analyzer and LangChain tools. The retrieval service now uses Linkup’s `/search` endpoint, redacts common direct identifiers before forming a web query, and returns provider metadata plus sources for audit trails. Next I’m threading that context into the medical analyzer and LangChain tools.
Agent context: The public symptom-analysis response model now has a `web_sources` field, so clients and audit logs can show what live context was used. I’m adding the same source metadata to persisted analysis records rather than burying citations only in the model text. The public symptom-analysis response model now has a `web_sources` field, so clients and audit logs can show what live context was used. I’m adding the same source metadata to persisted analysis records rather than burying citations only in the model text.
Agent context: I’m adding a callable web-grounding tool to the LangChain agents as well. It returns structured source metadata, so the agent can cite current material without the rest of the code knowing provider details. I’m adding a callable web-grounding tool to the LangChain agents as well. It returns structured source metadata, so the agent can cite current material without the rest of the code knowing provider details.
Agent context: The main symptom analyzer and the routing/triage tool-calling agents are now wired for live retrieval. I’m updating configuration/docs next so deployments can require Linkup ZDR/EU setup and so the app stays usable when the key is absent in local development. The main symptom analyzer and the routing/triage tool-calling agents are now wired for live retrieval. I’m updating configuration/docs next so deployments can require Linkup ZDR/EU setup and so the app stays usable when the key is absent in local development.
Agent context: One existing LangChain prompt was missing the required agent scratchpad placeholder; I fixed that while touching the triage agent because tool-calling would otherwise fail at runtime. I’m running syntax checks now, then I’ll inspect the final diff for anything too broad. One existing LangChain prompt was missing the required agent scratchpad placeholder; I fixed that while touching the triage agent because tool-calling would otherwise fail at runtime. I’m running syntax checks now, then I’ll inspect the final diff for anything too broad.
Agent context: One existing LangChain prompt was missing the required agent scratchpad placeholder; I fixed that while touching the triage agent because tool-calling would otherwise fail at runtime. I’m running syntax checks now, then I’ll inspect the final diff for anything too broad.
Agent context: One existing LangChain prompt was missing the required agent scratchpad placeholder; I fixed that while touching the triage agent because tool-calling would otherwise fail at runtime. I’m running syntax checks now, then I’ll inspect the final diff for anything too broad. exit code 0 Output: diff --git a/README.md b/README.md index b64438d..33509f2 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,12 @@ MONGO_URL=mongodb+srv://user:pass@cluster.mongodb.net/?appName=YourApp DB_NAME=ayumitraai JWT_SECRET=[redacted] CEREBRAS_API_KEY=[redacted] +LINKUP_API_KEY=[redacted] CORS_ORIGINS=http://localhost:3000,http://localhost:3001 ``` +For production web grounding, configure Linkup under a signed DPA and Zero Data Retention addendum, with EU processing or BYOC where required. The backend redacts common direct identifiers before sending retrieval queries and persists returned source URLs/excerpts with each symptom analysis for auditability. + ### Frontend (.env) ```env @@ -86,6 +89,7 @@ REACT_APP_BACKEND_URL=http://127.0.0.1:8000 - **Doctor Registration**: Doctors register with clinic/hospital facility IDs - **Clinic/Hospital Admin Registration**: Admins get unique
Agent context: One existing LangChain prompt was missing the required agent scratchpad placeholder; I fixed that while touching the triage agent because tool-calling would otherwise fail at runtime. I’m running syntax checks now, then I’ll inspect the final diff for anything too broad.
Agent context: One existing LangChain prompt was missing the required agent scratchpad placeholder; I fixed that while touching the triage agent because tool-calling would otherwise fail at runtime. I’m running syntax checks now, then I’ll inspect the final diff for anything too broad. exit code 0 Output: Listing 'backend'... Compiling 'backend/agent_endpoints.py'... Compiling 'backend/auth.py'... Compiling 'backend/cerebras_service.py'... Compiling 'backend/config.py'... Compiling 'backend/langchain_agents.py'... Compiling 'backend/models.py'... Compiling 'backend/server.py'... Compiling 'backend/web_retrieval.py'...
Agent context: Syntax compilation passes. I’m checking the untracked/changed files and one more runtime edge now, especially around whether generated `__pycache__` files were created by the compile step. Syntax compilation passes. I’m checking the untracked/changed files and one more runtime edge now, especially around whether generated `__pycache__` files were created by the compile step.
Agent context: Syntax compilation passes. I’m checking the untracked/changed files and one more runtime edge now, especially around whether generated `__pycache__` files were created by the compile step.
Agent context: Syntax compilation passes. I’m checking the untracked/changed files and one more runtime edge now, especially around whether generated `__pycache__` files were created by the compile step. exit code 0 Output: backend/__pycache__ backend/__pycache__/agent_endpoints.cpython-311.pyc backend/__pycache__/auth.cpython-311.pyc backend/__pycache__/cerebras_service.cpython-311.pyc backend/__pycache__/config.cpython-311.pyc backend/__pycache__/langchain_agents.cpython-311.pyc backend/__pycache__/models.cpython-311.pyc backend/__pycache__/server.cpython-311.pyc backend/__pycache__/web_retrieval.cpython-311.pyc
Agent context: Syntax compilation passes. I’m checking the untracked/changed files and one more runtime edge now, especially around whether generated `__pycache__` files were created by the compile step.
Agent context: Syntax compilation passes. I’m checking the untracked/changed files and one more runtime edge now, especially around whether generated `__pycache__` files were created by the compile step. exit code 0 Output: M README.md M backend/.env.example M backend/cerebras_service.py M backend/config.py M backend/langchain_agents.py M backend/models.py M backend/requirements.txt M backend/server.py ?? backend/web_retrieval.py
Agent context: Syntax compilation passes. I’m checking the untracked/changed files and one more runtime edge now, especially around whether generated `__pycache__` files were created by the compile step.
Agent context: Syntax compilation passes. I’m checking the untracked/changed files and one more runtime edge now, especially around whether generated `__pycache__` files were created by the compile step. exit code 0 Output: from __future__ import annotations from datetime import datetime, timezone import re from typing import Any, Dict, List, Optional import httpx from config import get_settings settings = get_settings() DEFAULT_TIMEOUT_SECONDS = 12.0 MAX_QUERY_CHARS = 450 MAX_CONTEXT_CHARS_PER_SOURCE = 900 SENSITIVE_PATTERNS = ( (re.compile(r"\b[\w.+-]+@[\w.-]+\.[A-Za-z]{2,}\b"), "[email]"), (re.compile(r"\b(?:\+?\d[\d\s().-]{7,}\d)\b"), "[phone]"), (re.compile(r"\b\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b"), "[date]"), (re.compile(r"\b(?:mrn|medical record|nhs number|ssn|passport|id)\s*[:#-]?\s*\w+\b", re.I), "[identifier]"), ) STOPWORDS = { "about", "after", "again", "also", "because", "been", "being", "from", "have", "into", "just", "like", "more", "name", "patient", "please", "that", "their", "there", "these", "this", "with", "years", } def _csv(value: str) -> List[str]: return [item.strip() for item in value.sp
Agent context: `compileall` generated local bytecode caches, which are not part of the implementation. I’m removing only those generated cache files before the final status. `compileall` generated local bytecode caches, which are not part of the implementation. I’m removing only those generated cache files before the final status.
Agent context: `compileall` generated local bytecode caches, which are not part of the implementation. I’m removing only those generated cache files before the final status.
Agent context: `compileall` generated local bytecode caches, which are not part of the implementation. I’m removing only those generated cache files before the final status. exit code 0
Agent context: The code changes are in place and generated caches are removed. I’m grabbing final line references and a clean status before summarizing the provider choice and the implementation. The code changes are in place and generated caches are removed. I’m grabbing final line references and a clean status before summarizing the provider choice and the implementation.
Agent context: The code changes are in place and generated caches are removed. I’m grabbing final line references and a clean status before summarizing the provider choice and the implementation.
Agent context: The code changes are in place and generated caches are removed. I’m grabbing final line references and a clean status before summarizing the provider choice and the implementation. exit code 0 Output: M README.md M backend/.env.example M backend/cerebras_service.py M backend/config.py M backend/langchain_agents.py M backend/models.py M backend/requirements.txt M backend/server.py ?? backend/web_retrieval.py
Agent context: The code changes are in place and generated caches are removed. I’m grabbing final line references and a clean status before summarizing the provider choice and the implementation.
Agent context: The code changes are in place and generated caches are removed. I’m grabbing final line references and a clean status before summarizing the provider choice and the implementation. exit code 0 Output: 35 ) 36 self.parser = JsonOutputParser(pydantic_object=CerebrasAnalysisOutput) 37 38 async def analyze_symptoms(self, symptom_description: str, patient_age: int = None) -> dict: 39 web_retrieval = await get_web_retriever().search_medical_guidance( 40 symptom_description, 41 patient_age, 42 ) 43 web_sources = web_retrieval.get("sources", []) 44 web_context = format_sources_for_prompt(web_sources) 45 46 system_prompt = """You are an expert medical triage AI assistant for AyuMitraAI. Your role is to: 47 1. Analyze patient symptoms objectively 48 2. Determine urgency level (critical, moderate, mild) 49 3. Recommend appropriate medical specialties 50 4. Provide actionable next steps 51 5. Prioritize patient safety above all 52 53 **CRITICAL URGENCY INDICATORS** (always mark as CRITICAL): 54 - Chest pain, pressure, or tightness 55 - Severe difficulty breathing or shortness of breath 56 - Sudde
Agent context: The code changes are in place and generated caches are removed. I’m grabbing final line references and a clean status before summarizing the provider choice and the implementation.
Agent context: The code changes are in place and generated caches are removed. I’m grabbing final line references and a clean status before summarizing the provider choice and the implementation. exit code 0 Output: 80 Returns recommended treatment approaches and best practices. 81 """ 82 return { 83 "specialty": specialty, 84 "condition": condition, 85 "guidelines": "Treatment guidelines" 86 } 87 88 @tool 89 def search_current_medical_guidance(symptoms_or_condition: str, patient_age: Optional[int] = None) -> dict: 90 """ 91 Search current public web sources for medical triage, red flags, referral, and guideline context. 92 Use this before giving clinical routing, triage, prescription, follow-up, or medication guidance that 93 may depend on current information. Returns source titles, URLs, excerpts, and provider metadata. 94 """ 95 return get_web_retriever().search_medical_guidance_sync(symptoms_or_condition, patient_age) 96 97 # ============================================================================ 98 # ROUTING AGENT 99 # =======================================================================
Agent context: The code changes are in place and generated caches are removed. I’m grabbing final line references and a clean status before summarizing the provider choice and the implementation.
Agent context: The code changes are in place and generated caches are removed. I’m grabbing final line references and a clean status before summarizing the provider choice and the implementation. exit code 0 Output: 1 from __future__ import annotations 2 3 from datetime import datetime, timezone 4 import re 5 from typing import Any, Dict, List, Optional 6 7 import httpx 8 9 from config import get_settings 10 11 12 settings = get_settings() 13 14 15 DEFAULT_TIMEOUT_SECONDS = 12.0 16 MAX_QUERY_CHARS = 450 17 MAX_CONTEXT_CHARS_PER_SOURCE = 900 18 19 SENSITIVE_PATTERNS = ( 20 (re.compile(r"\b[\w.+-]+@[\w.-]+\.[A-Za-z]{2,}\b"), "[email]"), 21 (re.compile(r"\b(?:\+?\d[\d\s().-]{7,}\d)\b"), "[phone]"), 22 (re.compile(r"\b\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b"), "[date]"), 23 (re.compile(r"\b(?:mrn|medical record|nhs number|ssn|passport|id)\s*[:#-]?\s*\w+\b", re.I), "[identifier]"), 24 ) 25 26 STOPWORDS = { 27 "about", 28 "after", 29 "again", 30 "also", 31 "because", 32 "been", 33 "being", 34 "from", 35 "have", 36 "into", 37 "just", 38 "like", 39 "more", 40 "name", 41 "patient", 42 "please", 43 "that", 44 "their"
Agent context: The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior. The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior.
Agent context: The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior.
Agent context: The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior. exit code 0 Output: 55 facility_type: Literal["clinic", "hospital"] 56 distance_km: Optional[float] = None 57 doctor_name: Optional[str] = None 58 doctor_specialization: Optional[str] = None 59 availability: str 60 emergency_capable: bool 61 contact: Optional[str] = None 62 location: Optional[dict] = None 63 64 class WebSource(BaseModel): 65 title: str 66 url: str 67 content: str 68 type: str = "text" 69 70 class RoutingDecision(BaseModel): 71 urgency: UrgencyLevel 72 primary_specialty: SpecialtyRecommendation 73 alternative_specialties: List[SpecialtyRecommendation] = [] 74 recommended_facilities: List[FacilityMatch] = [] 75 recommended_actions: List[str] 76 web_sources: List[WebSource] = [] 77 disclaimer: str = "This is AI-generated guidance. Always consult qualified medical professionals." 78 79 class SymptomAnalysisResponse(BaseModel): 80 request_id: str 81 routing_decision: RoutingDecision 82 analysis_
Agent context: The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior.
Agent context: The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior. exit code 0 Output: 120 ) 121 122 # Create patient request for each matching doctor 123 patient_request_doc = { 124 "request_id": request_id, 125 "patient_id": current_user["sub"], 126 "patient_name": patient.get("full_name", "Patient"), 127 "patient_age": request.patient_age, 128 "symptoms": request.symptom_description, 129 "urgency_level": urgency.level, 130 "primary_specialty": analysis["primary_specialty"], 131 "requested_at": datetime.now(timezone.utc).isoformat(), 132 "status": "pending", 133 "matched_doctors": [doc["doctor_id"] for doc in matching_doctors], 134 "assigned_doctor_id": None, 135 "web_retrieval": analysis.get("web_retrieval"), 136 "web_sources": analysis.get("web_sources", []) 137 } 138 139 await db.patient_requests.insert_one(patient_request_doc) 140 141 # Notify matching doctors 142 for doctor in matching_doctors: 143 await db.doctor_notifications.insert_one({ 144 "notification_id": st
Agent context: The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior.
Agent context: The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior. exit code 0 Output: 1 from pydantic_settings import BaseSettings 2 from functools import lru_cache 3 from typing import Optional 4 5 class Settings(BaseSettings): 6 MONGO_URL: str 7 DB_NAME: str 8 CORS_ORIGINS: str = "*" 9 CEREBRAS_API_KEY: str 10 MAPPLES_API_KEY: Optional[str] = None 11 LINKUP_API_KEY: Optional[str] = None 12 LINKUP_BASE_URL: str = "https://api.linkup.so/v1" 13 LINKUP_SEARCH_DEPTH: str = "standard" 14 WEB_RETRIEVAL_MAX_RESULTS: int = 5 15 WEB_RETRIEVAL_INCLUDE_DOMAINS: str = "" 16 WEB_RETRIEVAL_EXCLUDE_DOMAINS: str = "" 17 JWT_SECRET_KEY: str = "ayumitra-secret-key-change-in-production-2025" 18 JWT_ALGORITHM: str = "HS256" 19 JWT_EXPIRATION_MINUTES: int = 10080 20 21 class Config: 22 env_file = ".env" 23 case_sensitive = True 24 25 @lru_cache() 26 def get_settings(): 27 return Settings()
Agent context: The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior.
Agent context: The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior. exit code 0 Output: 65 ## Environment Variables 66 67 ### Backend (.env) 68 69 ```env 70 MONGO_URL=mongodb+srv://user:pass@cluster.mongodb.net/?appName=YourApp 71 DB_NAME=ayumitraai 72 JWT_SECRET=[redacted] 73 CEREBRAS_API_KEY=[redacted] 74 LINKUP_API_KEY=[redacted] 75 CORS_ORIGINS=http://localhost:3000,http://localhost:3001 76 ``` 77 78 For production web grounding, configure Linkup under a signed DPA and Zero Data Retention addendum, with EU processing or BYOC where required. The backend redacts common direct identifiers before sending retrieval queries and persists returned source URLs/excerpts with each symptom analysis for auditability. 79 80 ### Frontend (.env) 81 82 ```env 83 REACT_APP_BACKEND_URL=http://127.0.0.1:8000 84 ``` 85 86 ## Features 87 88 - **Patient Registration & Login**: Secure authentication with JWT 89 - **Doctor Registration**: Doctors register with clinic/hospital f
Agent context: The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior.
Agent context: The final status shows only the intended source/doc changes plus the new retrieval module. I’m checking the response and persistence line numbers so the summary can point you straight to the behavior. exit code 0 Output: Listing 'backend'... Compiling 'backend/agent_endpoints.py'... Compiling 'backend/auth.py'... Compiling 'backend/cerebras_service.py'... Compiling 'backend/config.py'... Compiling 'backend/langchain_agents.py'... Compiling 'backend/models.py'... Compiling 'backend/server.py'... Compiling 'backend/web_retrieval.py'...
Agent context: The syntax check still passes with bytecode writes disabled. I’m cleaning any cache files created by the second check as well, then I’ll wrap up. The syntax check still passes with bytecode writes disabled. I’m cleaning any cache files created by the second check as well, then I’ll wrap up.
Agent context: The syntax check still passes with bytecode writes disabled. I’m cleaning any cache files created by the second check as well, then I’ll wrap up.
Agent context: The syntax check still passes with bytecode writes disabled. I’m cleaning any cache files created by the second check as well, then I’ll wrap up. exit code 0
Agent context: The syntax check still passes with bytecode writes disabled. I’m cleaning any cache files created by the second check as well, then I’ll wrap up.
Agent context: The syntax check still passes with bytecode writes disabled. I’m cleaning any cache files created by the second check as well, then I’ll wrap up. exit code 0 Output: M README.md M backend/.env.example M backend/cerebras_service.py M backend/config.py M backend/langchain_agents.py M backend/models.py M backend/requirements.txt M backend/server.py ?? backend/web_retrieval.py
Agent context: Implemented live web grounding with **Linkup** as the recommended provider. I chose **Linkup** because its docs most directly satisfy the hard requirements: EU-only processing, GDPR Article 28 processor posture, DPA availability, ZDR, SOC 2 Type II, audit/security controls, and BYOC for regulated healthcare-style sovereignty needs. Linkup’s docs state EU-only processing and GDPR alignment, ZDR with no query/result storage, SOC 2 Type II, and BYOC where queries/results never leave the customer VPC. Sources consulted: [Data Privacy](https://docs.linkup.so/pages/security-and-privacy/data-privacy), [Security](https://docs.linkup.so/pages/security-and-privacy/security), [FAQ](https://docs.linkup.so/pages/security-and-privacy/faq), and [Search API](https://docs.linkup.so/pages/documentation/api-reference). Main alternatives considered: - **Exa**: strong AI-native search/retrieval, SOC 2 Type II, DPA, ZDR/HIPAA via enterprise, but the docs I consulted did not make EU data residency as explicit as Linkup. Source: [Exa security docs](https://exa.ai/docs/reference/security). - **Tavily**: good agent-oriented search APIs and EU API surface, but its public privacy/security docs were less specific on EU-only processing and ZDR guarantees. Sources: [Tavily API docs](https://docs.tavily.com/documentation/api-reference/introduction), [Tavily EU page](https://www.eu.tavily.com/), [Tavily privacy/security help](https://help.tavily.com/articles/6781493822-data-retention). - **Brave Search API**: strong privacy posture, SOC 2 Type II, and ZDR claims, but I did not find the same explicit EU residency/BYOC posture in the consulted docs, and it is more search-result oriented than managed AI retrieval. Source: [Brave Search API](https://brave.com/search/api/). Code changes: - Added Linkup retrieval service with identifier redaction, domain controls, source formatting, and async/sync API paths in [web_retrieval.py](/home/user/worktrees/attempt-171b0484-cd25-4451-9557-1fbc42678a2a-cap-2/backend/web_retrieval.py:19). - Wired live grounding into the structured symptom analyzer in [cerebras_service.py](/home/user/worktrees/attempt-171b0484-cd25-4451-9557-1fbc42678a2a-cap-2/backend/cerebras_service.py:38). - Added a LangChain tool, `search_current_medical_guidance`, to routing and triage agents in [langchain_agents.py](/home/user/worktrees/attempt-171b0484-cd25-4451-9557-1fbc42678a2a-cap-2/backend/langchain_agents.py:88). - Added `web_sources` to API responses and persisted retrieval metadata/source URLs for auditability in [models.py](/home/user/worktrees/attempt-171b0484-cd25-4451-9557-1fbc42678a2a-cap-2/backend/models.py:64) and [server.py](/home/user/worktrees/attempt-171b0484-cd25-4451-9557-1fbc42678a2a-cap-2/backend/server.py:300). - Added Linkup config/env/docs and `httpx`. Verification: `python -m compileall backend` passes. I did not run a live Linkup request because no `LINKUP_API_KEY` is configured in this workspace. Implemented live web grounding with **Linkup** as the recommended provider. I chose **Linkup** because its docs most directly satisfy the hard requirements: EU-only processing, GDPR Article 28 processor posture, DPA availability, ZDR, SOC 2 Type II, audit/security controls, and BYOC for regulated healthcare-style sovereignty needs. Linkup’s docs state EU-only processing and GDPR alignment, ZDR with no query/result storage, SOC 2 Type II, and BYOC where queries/results never leave the customer VPC. Sources consulted: [Data Privacy](https://docs.linkup.so/pages/security-and-privacy/data-privacy), [Security](https://docs.linkup.so/pages/security-and-privacy/security), [FAQ](https://docs.linkup.so/pages/security-and-privacy/faq), and [Search API](https://docs.linkup.so/pages/documentation/api-reference). Main alternatives considered: - **Exa**: strong AI-native search/retrieval, SOC 2 Type II, DPA, ZDR/HIPAA via enterprise, but the docs I consulted did not make EU data residency as explicit as Linkup. Source: [Exa security docs](https://exa.ai/docs/reference/security). - **Tavily**: good agent-oriented search APIs and EU API surface, but its public privacy/security docs were less speci
Implemented live web grounding with **Linkup** as the recommended provider. I chose **Linkup** because its docs most directly satisfy the hard requirements: EU-only processing, GDPR Article 28 processor posture, DPA availability, ZDR, SOC 2 Type II, audit/security controls, and BYOC for regulated healthcare-style sovereignty needs. Linkup’s docs state EU-only processing and GDPR alignment, ZDR with no query/result storage, SOC 2 Type II, and BYOC where queries/results never leave the customer VPC. Sources consulted: [Data Privacy](https://docs.linkup.so/pages/security-and-privacy/data-privacy), [Security](https://docs.linkup.so/pages/security-and-privacy/security), [FAQ](https://docs.linkup.so/pages/security-and-privacy/faq), and [Search API](https://docs.linkup.so/pages/documentation/api-reference). Main alternatives considered: - **Exa**: strong AI-native search/retrieval, SOC 2 Type II, DPA, ZDR/HIPAA via enterprise, but the docs I consulted did not make EU data residency as explicit as Linkup. Source: [Exa security docs](https://exa.ai/docs/reference/security). - **Tavily**: good agent-oriented search APIs and EU API surface, but its public privacy/security docs were less specific on EU-only processing and ZDR guarantees. Sources: [Tavily API docs](https://docs.tavily.com/documentation/api-reference/introduction), [Tavily EU page](https://www.eu.tavily.com/), [Tavily privac