1 line
80 KiB
JSON
1 line
80 KiB
JSON
{"repo": "caffeinepub/ayurnexis-3-1", "files": {"src/frontend/src/services/geminiService.ts": {"babbb17242385ccd00b5f423dcc671a91b6b2f5f": {"t": 1785746526.367612, "n": 11765, "h": "167c63afc21d102d", "c": "// AI Service for AyurNexis 3.1\n\nconst AI_API_KEY = \"sk-2d7fcf900b344a198815df1f571fce11\";\nconst AI_BASE_URL = \"https://api.deepseek.com/v1/chat/completions\";\nconst AI_MODEL = \"deepseek-chat\";\n\nasync function callAI(prompt: string): Promise<string | null> {\n try {\n const response = await fetch(AI_BASE_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${AI_API_KEY}`,\n },\n body: JSON.stringify({\n model: AI_MODEL,\n messages: [{ role: \"user\", content: prompt }],\n temperature: 0.7,\n max_tokens: 8192,\n }),\n });\n if (!response.ok) {\n const errText = await response.text().catch(() => \"\");\n console.warn(`AI returned ${response.status}:`, errText.slice(0, 300));\n return null;\n }\n const data = await response.json();\n return data?.choices?.[0]?.message?.content ?? null;\n } catch (err) {\n console.error(\"AI call threw:\", err);\n return null;\n }\n}\n\nfunction stripMarkdown(text: string): string {\n return text\n .replace(/```json\\s*/gi, \"\")\n .replace(/```\\s*/g, \"\")\n .trim();\n}\n\nfunction parseJSON<T>(text: string): T | null {\n try {\n return JSON.parse(stripMarkdown(text)) as T;\n } catch {\n const arrMatch = text.match(/(\\[\\s*\\{[\\s\\S]*\\}\\s*\\])/m);\n if (arrMatch) {\n try {\n return JSON.parse(arrMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n const objMatch = text.match(/(\\{[\\s\\S]*\\})/m);\n if (objMatch) {\n try {\n return JSON.parse(objMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n return null;\n }\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GeminiFormulationIngredient {\n name: string;\n quantity: number;\n unit: string;\n role: string;\n pharmacologicalEffect: string;\n}\n\nexport interface FormulationIdea {\n compositionName: string;\n ingredients: GeminiFormulationIngredient[];\n advantages: string[];\n disadvantages: string[];\n stabilityPrediction: string;\n mechanismOfAction: string;\n drugInteractions: string[];\n clinicalRationale: string;\n pharmacologicalEffects: string;\n indicationsForDisease: string;\n contraindications: string[];\n dosageInstructions: string;\n}\n\nexport interface CompatibilityPair {\n ingredient1: string;\n ingredient2: string;\n status: \"compatible\" | \"incompatible\" | \"conditional\";\n reason: string;\n}\n\nexport interface StabilityAssessment {\n physicalStability: string;\n chemicalStability: string;\n predictedShelfLife: string;\n ichClassification: string;\n stabilityScore: number;\n hygroscopicIngredients: string[];\n thermolabileIngredients: string[];\n lightSensitiveIngredients: string[];\n}\n\nexport interface InterIngredientReaction {\n ingredient1: string;\n ingredient2: string;\n reactionType: string;\n description: string;\n severity: \"low\" | \"medium\" | \"high\";\n}\n\nexport interface HplcPeak {\n constituentName: string;\n retentionTime: number;\n peakArea: number;\n ingredient: string;\n}\n\nexport interface UvSpectrum {\n lambdaMax: number;\n absorptionRange: string;\n chromophores: string[];\n}\n\nexport interface FtirPeak {\n functionalGroup: string;\n wavenumber: number;\n transmittance: number;\n}\n\nexport interface DscEvent {\n ingredient: string;\n event: string;\n temperature: number;\n enthalpy: number;\n}\n\nexport interface DissolutionPoint {\n timeMinutes: number;\n percentReleased: number;\n}\n\nexport interface FormulationAnalysis {\n compatibilityMatrix: CompatibilityPair[];\n stabilityAssessment: StabilityAssessment;\n advantages: string[];\n disadvantages: string[];\n interIngredientReactions: InterIngredientReaction[];\n hplcProfile: HplcPeak[];\n uvSpectrum: UvSpectrum;\n ftirProfile: FtirPeak[];\n dscProfile: DscEvent[];\n dissolutionProfile: DissolutionPoint[];\n}\n\n// ─── API Functions ────────────────────────────────────────────────────────────\n\nexport async function searchDiseases(query: string): Promise<string[]> {\n const prompt = `List 30 medical diseases, disorders, syndromes, or conditions that match or relate to: '${query}'. Include common conditions like fever, cold, headache, diabetes, hypertension, infections, skin diseases, GI issues, respiratory, neurological, rare diseases, pediatric, geriatric, and specialty conditions. Return ONLY a JSON array of 30 strings (disease/condition names only), no explanation. Example: [\"Type 2 Diabetes Mellitus\", \"Acute Febrile Illness\", \"Common Cold (Rhinovirus)\"]`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<string[]>(result);\n return Array.isArray(parsed)\n ? parsed.filter((s) => typeof s === \"string\")\n : [];\n}\n\nexport async function getFormulationIdeas(\n disease: string,\n dosageForm: string,\n drugType: string,\n): Promise<FormulationIdea[]> {\n const prompt = `Generate exactly 20 diverse, creative, pharmacopeia-compliant novel pharmaceutical formulation ideas for treating ${disease} as a ${dosageForm} using ${drugType} approach. Include Ayurvedic, allopathic, herbal, and combination approaches as appropriate. No restrictions on formulation types. Use real ingredient names, real pharmacopeia doses.\n\nFor each, return a JSON array of objects with these exact fields:\n- compositionName (string): unique descriptive name\n- ingredients (array): each with name (string), quantity (number), unit (string), role (string), pharmacologicalEffect (string - specific mechanism of this ingredient)\n- advantages (array of 3-5 strings)\n- disadvantages (array of 2-3 strings)\n- stabilityPrediction (string)\n- mechanismOfAction (string): 2-3 sentence combined mechanism\n- drugInteractions (array of strings)\n- clinicalRationale (string): 2-3 sentences\n- pharmacologicalEffects (string): comprehensive 4-6 sentence paragraph covering overall mechanism of action, key active constituents and their receptor/enzyme targets, therapeutic effects, bioavailability considerations, and clinical rationale for this specific disease\n- indicationsForDisease (string): comma-separated list of all diseases/conditions this formulation is indicated for\n- contraindications (array of strings): specific contraindications\n- dosageInstructions (string): dosage and administration instructions\n\nReturn ONLY valid JSON array, no markdown, no explanation.`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<FormulationIdea[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\nexport async function analyzeFormulation(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n): Promise<FormulationAnalysis | null> {\n if (ingredients.length < 2) return null;\n const prompt = `Analyze this pharmaceutical formulation with these ingredients: ${JSON.stringify(ingredients)}. Return a JSON object with these exact fields:\n- compatibilityMatrix: array of {ingredient1 (string), ingredient2 (string), status ('compatible'|'incompatible'|'conditional'), reason (string)}\n- stabilityAssessment: {physicalStability (string), chemicalStability (string), predictedShelfLife (string), ichClassification (string), stabilityScore (number 0-100), hygroscopicIngredients (string array), thermolabileIngredients (string array), lightSensitiveIngredients (string array)}\n- advantages: string array\n- disadvantages: string array\n- interIngredientReactions: array of {ingredient1 (string), ingredient2 (string), reactionType (string), description (string), severity ('low'|'medium'|'high')}\n- hplcProfile: array of {constituentName (string), retentionTime (number in minutes), peakArea (number as percentage), ingredient (string)}\n- uvSpectrum: {lambdaMax (number in nm), absorptionRange (string), chromophores (string array)}\n- ftirProfile: array of {functionalGroup (string), wavenumber (number in cm-1), transmittance (number as %)}\n- dscProfile: array of {ingredient (string), event (string), temperature (number in celsius), enthalpy (number in J/g)}\n- dissolutionProfile: array of {timeMinutes (number), percentReleased (number)}\nReturn ONLY valid JSON, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return null;\n return parseJSON<FormulationAnalysis>(result);\n}\n\n// ─── Marketed Drugs ───────────────────────────────────────────────────────────\n\nexport interface MarketedDrugResult {\n brandName: string;\n genericName: string;\n manufacturer: string;\n dosageForm: string;\n strength: string;\n}\n\nexport async function getMarketedDrugs(\n disease: string,\n _drugType: string,\n _dosageForm: string,\n): Promise<MarketedDrugResult[]> {\n const prompt = `List 20 real marketed pharmaceutical drugs for treating ${disease}. Include ALL available dosage forms (tablets, capsules, injections, syrups, creams, patches, suppositories, inhalers, etc.) and both allopathic and herbal/Ayurvedic brands. Use real brand names, manufacturers, and strengths from pharmacopoeia. Return ONLY a JSON array of objects with fields: brandName (string), genericName (string), manufacturer (string), dosageForm (string), strength (string). Example: [{\"brandName\":\"Glucophage\",\"genericName\":\"Metformin HCl\",\"manufacturer\":\"Merck\",\"dosageForm\":\"Tablet\",\"strength\":\"500 mg\"}]. Return ONLY valid JSON array, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<MarketedDrugResult[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\n// ─── Formulation Summary ──────────────────────────────────────────────────────\n\nexport interface FormulationSummaryData {\n narrative: string;\n procedure: string[];\n instruments: string[];\n glassware: string[];\n}\n\nexport async function getFormulationSummary(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n dosageForm: string,\n method: string,\n): Promise<FormulationSummaryData | null> {\n const prompt = `For a ${dosageForm} pharmaceutical formulation prepared by ${method} method using: ${ingredients.map((i) => `${i.name} ${i.quantity}${i.unit} (${i.role})`).join(\", \")}.\nReturn a JSON object with:\n- narrative: a 4-6 sentence clinical rationale for this formulation covering pharmacological mechanisms, therapeutic synergy, and clinical evidence basis (scientific, pharmacopeia-based)\n- procedure: array of 8-10 step-by-step manufacturing procedure strings (detailed, numbered context omitted, specific to ${dosageForm} by ${method})\n- instruments: array of 8-12 laboratory instruments required (e.g. \"Tablet Compression Machine\", \"Analytical Balance\", \"Dissolution Apparatus USP Type II\")\n- glassware: array of 6-10 glassware items required (e.g. \"250 mL Beaker\", \"100 mL Volumetric Flask\", \"Conical Flask 500 mL\")\nReturn ONLY valid JSON, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return null;\n return parseJSON<FormulationSummaryData>(result);\n}\n\n// ─── Composition Pharmacology ─────────────────────────────────────────────────\n\nexport async function getCompositionPharmacology(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n dosageForm: string,\n disease?: string,\n): Promise<string> {\n const prompt = `Describe the combined pharmacological effects of this ${dosageForm} formulation${disease ? ` for treating ${disease}` : \"\"}: ${ingredients.map((i) => `${i.name} ${i.quantity}${i.unit} (${i.role})`).join(\", \")}. Write a comprehensive 4-6 sentence paragraph covering: overall mechanism of action, key active constituents and their targets, therapeutic effects, bioavailability considerations, and clinical rationale. Be specific and pharmacopeia-accurate. Return ONLY the paragraph text, no JSON, no headers.`;\n const result = await callAI(prompt);\n return result ?? \"Pharmacological effects data unavailable.\";\n}\n"}, "9023851096f4331f07678d89b77129b73bcc5fda": {"t": 1785765310.0151637, "n": 11765, "h": "167c63afc21d102d", "c": "// AI Service for AyurNexis 3.1\n\nconst AI_API_KEY = \"sk-2d7fcf900b344a198815df1f571fce11\";\nconst AI_BASE_URL = \"https://api.deepseek.com/v1/chat/completions\";\nconst AI_MODEL = \"deepseek-chat\";\n\nasync function callAI(prompt: string): Promise<string | null> {\n try {\n const response = await fetch(AI_BASE_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${AI_API_KEY}`,\n },\n body: JSON.stringify({\n model: AI_MODEL,\n messages: [{ role: \"user\", content: prompt }],\n temperature: 0.7,\n max_tokens: 8192,\n }),\n });\n if (!response.ok) {\n const errText = await response.text().catch(() => \"\");\n console.warn(`AI returned ${response.status}:`, errText.slice(0, 300));\n return null;\n }\n const data = await response.json();\n return data?.choices?.[0]?.message?.content ?? null;\n } catch (err) {\n console.error(\"AI call threw:\", err);\n return null;\n }\n}\n\nfunction stripMarkdown(text: string): string {\n return text\n .replace(/```json\\s*/gi, \"\")\n .replace(/```\\s*/g, \"\")\n .trim();\n}\n\nfunction parseJSON<T>(text: string): T | null {\n try {\n return JSON.parse(stripMarkdown(text)) as T;\n } catch {\n const arrMatch = text.match(/(\\[\\s*\\{[\\s\\S]*\\}\\s*\\])/m);\n if (arrMatch) {\n try {\n return JSON.parse(arrMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n const objMatch = text.match(/(\\{[\\s\\S]*\\})/m);\n if (objMatch) {\n try {\n return JSON.parse(objMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n return null;\n }\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GeminiFormulationIngredient {\n name: string;\n quantity: number;\n unit: string;\n role: string;\n pharmacologicalEffect: string;\n}\n\nexport interface FormulationIdea {\n compositionName: string;\n ingredients: GeminiFormulationIngredient[];\n advantages: string[];\n disadvantages: string[];\n stabilityPrediction: string;\n mechanismOfAction: string;\n drugInteractions: string[];\n clinicalRationale: string;\n pharmacologicalEffects: string;\n indicationsForDisease: string;\n contraindications: string[];\n dosageInstructions: string;\n}\n\nexport interface CompatibilityPair {\n ingredient1: string;\n ingredient2: string;\n status: \"compatible\" | \"incompatible\" | \"conditional\";\n reason: string;\n}\n\nexport interface StabilityAssessment {\n physicalStability: string;\n chemicalStability: string;\n predictedShelfLife: string;\n ichClassification: string;\n stabilityScore: number;\n hygroscopicIngredients: string[];\n thermolabileIngredients: string[];\n lightSensitiveIngredients: string[];\n}\n\nexport interface InterIngredientReaction {\n ingredient1: string;\n ingredient2: string;\n reactionType: string;\n description: string;\n severity: \"low\" | \"medium\" | \"high\";\n}\n\nexport interface HplcPeak {\n constituentName: string;\n retentionTime: number;\n peakArea: number;\n ingredient: string;\n}\n\nexport interface UvSpectrum {\n lambdaMax: number;\n absorptionRange: string;\n chromophores: string[];\n}\n\nexport interface FtirPeak {\n functionalGroup: string;\n wavenumber: number;\n transmittance: number;\n}\n\nexport interface DscEvent {\n ingredient: string;\n event: string;\n temperature: number;\n enthalpy: number;\n}\n\nexport interface DissolutionPoint {\n timeMinutes: number;\n percentReleased: number;\n}\n\nexport interface FormulationAnalysis {\n compatibilityMatrix: CompatibilityPair[];\n stabilityAssessment: StabilityAssessment;\n advantages: string[];\n disadvantages: string[];\n interIngredientReactions: InterIngredientReaction[];\n hplcProfile: HplcPeak[];\n uvSpectrum: UvSpectrum;\n ftirProfile: FtirPeak[];\n dscProfile: DscEvent[];\n dissolutionProfile: DissolutionPoint[];\n}\n\n// ─── API Functions ────────────────────────────────────────────────────────────\n\nexport async function searchDiseases(query: string): Promise<string[]> {\n const prompt = `List 30 medical diseases, disorders, syndromes, or conditions that match or relate to: '${query}'. Include common conditions like fever, cold, headache, diabetes, hypertension, infections, skin diseases, GI issues, respiratory, neurological, rare diseases, pediatric, geriatric, and specialty conditions. Return ONLY a JSON array of 30 strings (disease/condition names only), no explanation. Example: [\"Type 2 Diabetes Mellitus\", \"Acute Febrile Illness\", \"Common Cold (Rhinovirus)\"]`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<string[]>(result);\n return Array.isArray(parsed)\n ? parsed.filter((s) => typeof s === \"string\")\n : [];\n}\n\nexport async function getFormulationIdeas(\n disease: string,\n dosageForm: string,\n drugType: string,\n): Promise<FormulationIdea[]> {\n const prompt = `Generate exactly 20 diverse, creative, pharmacopeia-compliant novel pharmaceutical formulation ideas for treating ${disease} as a ${dosageForm} using ${drugType} approach. Include Ayurvedic, allopathic, herbal, and combination approaches as appropriate. No restrictions on formulation types. Use real ingredient names, real pharmacopeia doses.\n\nFor each, return a JSON array of objects with these exact fields:\n- compositionName (string): unique descriptive name\n- ingredients (array): each with name (string), quantity (number), unit (string), role (string), pharmacologicalEffect (string - specific mechanism of this ingredient)\n- advantages (array of 3-5 strings)\n- disadvantages (array of 2-3 strings)\n- stabilityPrediction (string)\n- mechanismOfAction (string): 2-3 sentence combined mechanism\n- drugInteractions (array of strings)\n- clinicalRationale (string): 2-3 sentences\n- pharmacologicalEffects (string): comprehensive 4-6 sentence paragraph covering overall mechanism of action, key active constituents and their receptor/enzyme targets, therapeutic effects, bioavailability considerations, and clinical rationale for this specific disease\n- indicationsForDisease (string): comma-separated list of all diseases/conditions this formulation is indicated for\n- contraindications (array of strings): specific contraindications\n- dosageInstructions (string): dosage and administration instructions\n\nReturn ONLY valid JSON array, no markdown, no explanation.`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<FormulationIdea[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\nexport async function analyzeFormulation(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n): Promise<FormulationAnalysis | null> {\n if (ingredients.length < 2) return null;\n const prompt = `Analyze this pharmaceutical formulation with these ingredients: ${JSON.stringify(ingredients)}. Return a JSON object with these exact fields:\n- compatibilityMatrix: array of {ingredient1 (string), ingredient2 (string), status ('compatible'|'incompatible'|'conditional'), reason (string)}\n- stabilityAssessment: {physicalStability (string), chemicalStability (string), predictedShelfLife (string), ichClassification (string), stabilityScore (number 0-100), hygroscopicIngredients (string array), thermolabileIngredients (string array), lightSensitiveIngredients (string array)}\n- advantages: string array\n- disadvantages: string array\n- interIngredientReactions: array of {ingredient1 (string), ingredient2 (string), reactionType (string), description (string), severity ('low'|'medium'|'high')}\n- hplcProfile: array of {constituentName (string), retentionTime (number in minutes), peakArea (number as percentage), ingredient (string)}\n- uvSpectrum: {lambdaMax (number in nm), absorptionRange (string), chromophores (string array)}\n- ftirProfile: array of {functionalGroup (string), wavenumber (number in cm-1), transmittance (number as %)}\n- dscProfile: array of {ingredient (string), event (string), temperature (number in celsius), enthalpy (number in J/g)}\n- dissolutionProfile: array of {timeMinutes (number), percentReleased (number)}\nReturn ONLY valid JSON, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return null;\n return parseJSON<FormulationAnalysis>(result);\n}\n\n// ─── Marketed Drugs ───────────────────────────────────────────────────────────\n\nexport interface MarketedDrugResult {\n brandName: string;\n genericName: string;\n manufacturer: string;\n dosageForm: string;\n strength: string;\n}\n\nexport async function getMarketedDrugs(\n disease: string,\n _drugType: string,\n _dosageForm: string,\n): Promise<MarketedDrugResult[]> {\n const prompt = `List 20 real marketed pharmaceutical drugs for treating ${disease}. Include ALL available dosage forms (tablets, capsules, injections, syrups, creams, patches, suppositories, inhalers, etc.) and both allopathic and herbal/Ayurvedic brands. Use real brand names, manufacturers, and strengths from pharmacopoeia. Return ONLY a JSON array of objects with fields: brandName (string), genericName (string), manufacturer (string), dosageForm (string), strength (string). Example: [{\"brandName\":\"Glucophage\",\"genericName\":\"Metformin HCl\",\"manufacturer\":\"Merck\",\"dosageForm\":\"Tablet\",\"strength\":\"500 mg\"}]. Return ONLY valid JSON array, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<MarketedDrugResult[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\n// ─── Formulation Summary ──────────────────────────────────────────────────────\n\nexport interface FormulationSummaryData {\n narrative: string;\n procedure: string[];\n instruments: string[];\n glassware: string[];\n}\n\nexport async function getFormulationSummary(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n dosageForm: string,\n method: string,\n): Promise<FormulationSummaryData | null> {\n const prompt = `For a ${dosageForm} pharmaceutical formulation prepared by ${method} method using: ${ingredients.map((i) => `${i.name} ${i.quantity}${i.unit} (${i.role})`).join(\", \")}.\nReturn a JSON object with:\n- narrative: a 4-6 sentence clinical rationale for this formulation covering pharmacological mechanisms, therapeutic synergy, and clinical evidence basis (scientific, pharmacopeia-based)\n- procedure: array of 8-10 step-by-step manufacturing procedure strings (detailed, numbered context omitted, specific to ${dosageForm} by ${method})\n- instruments: array of 8-12 laboratory instruments required (e.g. \"Tablet Compression Machine\", \"Analytical Balance\", \"Dissolution Apparatus USP Type II\")\n- glassware: array of 6-10 glassware items required (e.g. \"250 mL Beaker\", \"100 mL Volumetric Flask\", \"Conical Flask 500 mL\")\nReturn ONLY valid JSON, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return null;\n return parseJSON<FormulationSummaryData>(result);\n}\n\n// ─── Composition Pharmacology ─────────────────────────────────────────────────\n\nexport async function getCompositionPharmacology(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n dosageForm: string,\n disease?: string,\n): Promise<string> {\n const prompt = `Describe the combined pharmacological effects of this ${dosageForm} formulation${disease ? ` for treating ${disease}` : \"\"}: ${ingredients.map((i) => `${i.name} ${i.quantity}${i.unit} (${i.role})`).join(\", \")}. Write a comprehensive 4-6 sentence paragraph covering: overall mechanism of action, key active constituents and their targets, therapeutic effects, bioavailability considerations, and clinical rationale. Be specific and pharmacopeia-accurate. Return ONLY the paragraph text, no JSON, no headers.`;\n const result = await callAI(prompt);\n return result ?? \"Pharmacological effects data unavailable.\";\n}\n"}, "f22e4f8532be3174999de1375dc8b62203c96ffa": {"t": 1785765311.8075144, "n": 12161, "h": "36324c4ac1865047", "c": "// AI Service for AyurNexis 3.1\n\nconst GEMINI_API_KEY = \"AIzaSyCkAAD9UcBo5KH1edlmz4vs61rAPJpRHQU\";\nconst GEMINI_MODELS = [\n \"gemini-2.0-flash\",\n \"gemini-1.5-flash\",\n \"gemini-1.5-flash-8b\",\n];\n\nasync function callAIWithModel(\n prompt: string,\n model: string,\n): Promise<string | null> {\n const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${GEMINI_API_KEY}`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: prompt }] }],\n generationConfig: { temperature: 0.7, maxOutputTokens: 8192 },\n }),\n });\n if (!response.ok) {\n const errText = await response.text().catch(() => \"\");\n console.warn(\n `AI model ${model} returned ${response.status}:`,\n errText.slice(0, 200),\n );\n return null;\n }\n const data = await response.json();\n return data?.candidates?.[0]?.content?.parts?.[0]?.text ?? null;\n}\n\nasync function callAI(prompt: string): Promise<string | null> {\n for (const model of GEMINI_MODELS) {\n try {\n const result = await callAIWithModel(prompt, model);\n if (result) return result;\n } catch (err) {\n console.warn(`AI call with model ${model} threw:`, err);\n }\n }\n console.error(\"All AI models failed. Check API key and network connection.\");\n return null;\n}\n\nfunction stripMarkdown(text: string): string {\n return text\n .replace(/```json\\s*/gi, \"\")\n .replace(/```\\s*/g, \"\")\n .trim();\n}\n\nfunction parseJSON<T>(text: string): T | null {\n try {\n return JSON.parse(stripMarkdown(text)) as T;\n } catch {\n const arrMatch = text.match(/(\\[\\s*\\{[\\s\\S]*\\}\\s*\\])/m);\n if (arrMatch) {\n try {\n return JSON.parse(arrMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n const objMatch = text.match(/(\\{[\\s\\S]*\\})/m);\n if (objMatch) {\n try {\n return JSON.parse(objMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n return null;\n }\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GeminiFormulationIngredient {\n name: string;\n quantity: number;\n unit: string;\n role: string;\n pharmacologicalEffect: string;\n}\n\nexport interface FormulationIdea {\n compositionName: string;\n ingredients: GeminiFormulationIngredient[];\n advantages: string[];\n disadvantages: string[];\n stabilityPrediction: string;\n mechanismOfAction: string;\n drugInteractions: string[];\n clinicalRationale: string;\n pharmacologicalEffects: string;\n indicationsForDisease: string;\n contraindications: string[];\n dosageInstructions: string;\n}\n\nexport interface CompatibilityPair {\n ingredient1: string;\n ingredient2: string;\n status: \"compatible\" | \"incompatible\" | \"conditional\";\n reason: string;\n}\n\nexport interface StabilityAssessment {\n physicalStability: string;\n chemicalStability: string;\n predictedShelfLife: string;\n ichClassification: string;\n stabilityScore: number;\n hygroscopicIngredients: string[];\n thermolabileIngredients: string[];\n lightSensitiveIngredients: string[];\n}\n\nexport interface InterIngredientReaction {\n ingredient1: string;\n ingredient2: string;\n reactionType: string;\n description: string;\n severity: \"low\" | \"medium\" | \"high\";\n}\n\nexport interface HplcPeak {\n constituentName: string;\n retentionTime: number;\n peakArea: number;\n ingredient: string;\n}\n\nexport interface UvSpectrum {\n lambdaMax: number;\n absorptionRange: string;\n chromophores: string[];\n}\n\nexport interface FtirPeak {\n functionalGroup: string;\n wavenumber: number;\n transmittance: number;\n}\n\nexport interface DscEvent {\n ingredient: string;\n event: string;\n temperature: number;\n enthalpy: number;\n}\n\nexport interface DissolutionPoint {\n timeMinutes: number;\n percentReleased: number;\n}\n\nexport interface FormulationAnalysis {\n compatibilityMatrix: CompatibilityPair[];\n stabilityAssessment: StabilityAssessment;\n advantages: string[];\n disadvantages: string[];\n interIngredientReactions: InterIngredientReaction[];\n hplcProfile: HplcPeak[];\n uvSpectrum: UvSpectrum;\n ftirProfile: FtirPeak[];\n dscProfile: DscEvent[];\n dissolutionProfile: DissolutionPoint[];\n}\n\n// ─── API Functions ────────────────────────────────────────────────────────────\n\nexport async function searchDiseases(query: string): Promise<string[]> {\n const prompt = `List 30 medical diseases, disorders, syndromes, or conditions that match or relate to: '${query}'. Include common conditions like fever, cold, headache, diabetes, hypertension, infections, skin diseases, GI issues, respiratory, neurological, rare diseases, pediatric, geriatric, and specialty conditions. Return ONLY a JSON array of 30 strings (disease/condition names only), no explanation. Example: [\"Type 2 Diabetes Mellitus\", \"Acute Febrile Illness\", \"Common Cold (Rhinovirus)\"]`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<string[]>(result);\n return Array.isArray(parsed)\n ? parsed.filter((s) => typeof s === \"string\")\n : [];\n}\n\nexport async function getFormulationIdeas(\n disease: string,\n dosageForm: string,\n drugType: string,\n): Promise<FormulationIdea[]> {\n const prompt = `Generate exactly 20 diverse, creative, pharmacopeia-compliant novel pharmaceutical formulation ideas for treating ${disease} as a ${dosageForm} using ${drugType} approach. Include Ayurvedic, allopathic, herbal, and combination approaches as appropriate. No restrictions on formulation types. Use real ingredient names, real pharmacopeia doses.\n\nFor each, return a JSON array of objects with these exact fields:\n- compositionName (string): unique descriptive name\n- ingredients (array): each with name (string), quantity (number), unit (string), role (string), pharmacologicalEffect (string - specific mechanism of this ingredient)\n- advantages (array of 3-5 strings)\n- disadvantages (array of 2-3 strings)\n- stabilityPrediction (string)\n- mechanismOfAction (string): 2-3 sentence combined mechanism\n- drugInteractions (array of strings)\n- clinicalRationale (string): 2-3 sentences\n- pharmacologicalEffects (string): comprehensive 4-6 sentence paragraph covering overall mechanism of action, key active constituents and their receptor/enzyme targets, therapeutic effects, bioavailability considerations, and clinical rationale for this specific disease\n- indicationsForDisease (string): comma-separated list of all diseases/conditions this formulation is indicated for\n- contraindications (array of strings): specific contraindications\n- dosageInstructions (string): dosage and administration instructions\n\nReturn ONLY valid JSON array, no markdown, no explanation.`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<FormulationIdea[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\nexport async function analyzeFormulation(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n): Promise<FormulationAnalysis | null> {\n if (ingredients.length < 2) return null;\n const prompt = `Analyze this pharmaceutical formulation with these ingredients: ${JSON.stringify(ingredients)}. Return a JSON object with these exact fields:\n- compatibilityMatrix: array of {ingredient1 (string), ingredient2 (string), status ('compatible'|'incompatible'|'conditional'), reason (string)}\n- stabilityAssessment: {physicalStability (string), chemicalStability (string), predictedShelfLife (string), ichClassification (string), stabilityScore (number 0-100), hygroscopicIngredients (string array), thermolabileIngredients (string array), lightSensitiveIngredients (string array)}\n- advantages: string array\n- disadvantages: string array\n- interIngredientReactions: array of {ingredient1 (string), ingredient2 (string), reactionType (string), description (string), severity ('low'|'medium'|'high')}\n- hplcProfile: array of {constituentName (string), retentionTime (number in minutes), peakArea (number as percentage), ingredient (string)}\n- uvSpectrum: {lambdaMax (number in nm), absorptionRange (string), chromophores (string array)}\n- ftirProfile: array of {functionalGroup (string), wavenumber (number in cm-1), transmittance (number as %)}\n- dscProfile: array of {ingredient (string), event (string), temperature (number in celsius), enthalpy (number in J/g)}\n- dissolutionProfile: array of {timeMinutes (number), percentReleased (number)}\nReturn ONLY valid JSON, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return null;\n return parseJSON<FormulationAnalysis>(result);\n}\n\n// ─── Marketed Drugs ───────────────────────────────────────────────────────────\n\nexport interface MarketedDrugResult {\n brandName: string;\n genericName: string;\n manufacturer: string;\n dosageForm: string;\n strength: string;\n}\n\nexport async function getMarketedDrugs(\n disease: string,\n _drugType: string,\n _dosageForm: string,\n): Promise<MarketedDrugResult[]> {\n const prompt = `List 20 real marketed pharmaceutical drugs for treating ${disease}. Include ALL available dosage forms (tablets, capsules, injections, syrups, creams, patches, suppositories, inhalers, etc.) and both allopathic and herbal/Ayurvedic brands. Use real brand names, manufacturers, and strengths from pharmacopoeia. Return ONLY a JSON array of objects with fields: brandName (string), genericName (string), manufacturer (string), dosageForm (string), strength (string). Example: [{\"brandName\":\"Glucophage\",\"genericName\":\"Metformin HCl\",\"manufacturer\":\"Merck\",\"dosageForm\":\"Tablet\",\"strength\":\"500 mg\"}]. Return ONLY valid JSON array, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<MarketedDrugResult[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\n// ─── Formulation Summary ──────────────────────────────────────────────────────\n\nexport interface FormulationSummaryData {\n narrative: string;\n procedure: string[];\n instruments: string[];\n glassware: string[];\n}\n\nexport async function getFormulationSummary(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n dosageForm: string,\n method: string,\n): Promise<FormulationSummaryData | null> {\n const prompt = `For a ${dosageForm} pharmaceutical formulation prepared by ${method} method using: ${ingredients.map((i) => `${i.name} ${i.quantity}${i.unit} (${i.role})`).join(\", \")}.\nReturn a JSON object with:\n- narrative: a 4-6 sentence clinical rationale for this formulation covering pharmacological mechanisms, therapeutic synergy, and clinical evidence basis (scientific, pharmacopeia-based)\n- procedure: array of 8-10 step-by-step manufacturing procedure strings (detailed, numbered context omitted, specific to ${dosageForm} by ${method})\n- instruments: array of 8-12 laboratory instruments required (e.g. \"Tablet Compression Machine\", \"Analytical Balance\", \"Dissolution Apparatus USP Type II\")\n- glassware: array of 6-10 glassware items required (e.g. \"250 mL Beaker\", \"100 mL Volumetric Flask\", \"Conical Flask 500 mL\")\nReturn ONLY valid JSON, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return null;\n return parseJSON<FormulationSummaryData>(result);\n}\n\n// ─── Composition Pharmacology ─────────────────────────────────────────────────\n\nexport async function getCompositionPharmacology(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n dosageForm: string,\n disease?: string,\n): Promise<string> {\n const prompt = `Describe the combined pharmacological effects of this ${dosageForm} formulation${disease ? ` for treating ${disease}` : \"\"}: ${ingredients.map((i) => `${i.name} ${i.quantity}${i.unit} (${i.role})`).join(\", \")}. Write a comprehensive 4-6 sentence paragraph covering: overall mechanism of action, key active constituents and their targets, therapeutic effects, bioavailability considerations, and clinical rationale. Be specific and pharmacopeia-accurate. Return ONLY the paragraph text, no JSON, no headers.`;\n const result = await callAI(prompt);\n return result ?? \"Pharmacological effects data unavailable.\";\n}\n"}, "f92e0c367eeac59e425218a0686b98e5d33b1ba5": {"t": 1785765313.648116, "n": 11746, "h": "a6a38d82c53bbacc", "c": "// AI Service for AyurNexis 3.1 (powered by Puter.js)\n\n/* global puter */\ndeclare const puter: {\n ai: {\n chat: (\n prompt: string,\n options?: { model?: string; stream?: boolean },\n ) => Promise<\n | { message?: { content?: { text?: string }[] }; toString?: () => string }\n | string\n >;\n };\n};\n\nasync function callAI(prompt: string): Promise<string | null> {\n try {\n const response = await puter.ai.chat(prompt);\n if (!response) return null;\n if (typeof response === \"string\") return response;\n // Claude-style response\n const msg = (response as { message?: { content?: { text?: string }[] } })\n .message;\n if (msg?.content?.[0]?.text) return msg.content[0].text;\n // Fallback toString\n if (\n typeof (response as { toString?: () => string }).toString === \"function\"\n ) {\n return (response as { toString: () => string }).toString();\n }\n return JSON.stringify(response);\n } catch {\n return null;\n }\n}\n\nfunction stripMarkdown(text: string): string {\n return text\n .replace(/```json\\s*/gi, \"\")\n .replace(/```\\s*/g, \"\")\n .trim();\n}\n\nfunction parseJSON<T>(text: string): T | null {\n try {\n return JSON.parse(stripMarkdown(text)) as T;\n } catch {\n const arrMatch = text.match(/(\\[\\s*\\{[\\s\\S]*\\}\\s*\\])/m);\n if (arrMatch) {\n try {\n return JSON.parse(arrMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n const objMatch = text.match(/(\\{[\\s\\S]*\\})/m);\n if (objMatch) {\n try {\n return JSON.parse(objMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n return null;\n }\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GeminiFormulationIngredient {\n name: string;\n quantity: number;\n unit: string;\n role: string;\n pharmacologicalEffect: string;\n}\n\nexport interface FormulationIdea {\n compositionName: string;\n ingredients: GeminiFormulationIngredient[];\n advantages: string[];\n disadvantages: string[];\n stabilityPrediction: string;\n mechanismOfAction: string;\n drugInteractions: string[];\n clinicalRationale: string;\n pharmacologicalEffects: string;\n indicationsForDisease: string;\n contraindications: string[];\n dosageInstructions: string;\n}\n\nexport interface CompatibilityPair {\n ingredient1: string;\n ingredient2: string;\n status: \"compatible\" | \"incompatible\" | \"conditional\";\n reason: string;\n}\n\nexport interface StabilityAssessment {\n physicalStability: string;\n chemicalStability: string;\n predictedShelfLife: string;\n ichClassification: string;\n stabilityScore: number;\n hygroscopicIngredients: string[];\n thermolabileIngredients: string[];\n lightSensitiveIngredients: string[];\n}\n\nexport interface InterIngredientReaction {\n ingredient1: string;\n ingredient2: string;\n reactionType: string;\n description: string;\n severity: \"low\" | \"medium\" | \"high\";\n}\n\nexport interface HplcPeak {\n constituentName: string;\n retentionTime: number;\n peakArea: number;\n ingredient: string;\n}\n\nexport interface UvSpectrum {\n lambdaMax: number;\n absorptionRange: string;\n chromophores: string[];\n}\n\nexport interface FtirPeak {\n functionalGroup: string;\n wavenumber: number;\n transmittance: number;\n}\n\nexport interface DscEvent {\n ingredient: string;\n event: string;\n temperature: number;\n enthalpy: number;\n}\n\nexport interface DissolutionPoint {\n timeMinutes: number;\n percentReleased: number;\n}\n\nexport interface FormulationAnalysis {\n compatibilityMatrix: CompatibilityPair[];\n stabilityAssessment: StabilityAssessment;\n advantages: string[];\n disadvantages: string[];\n interIngredientReactions: InterIngredientReaction[];\n hplcProfile: HplcPeak[];\n uvSpectrum: UvSpectrum;\n ftirProfile: FtirPeak[];\n dscProfile: DscEvent[];\n dissolutionProfile: DissolutionPoint[];\n}\n\n// ─── API Functions ────────────────────────────────────────────────────────────\n\nexport async function searchDiseases(query: string): Promise<string[]> {\n const prompt = `List 30 medical diseases, disorders, syndromes, or conditions that match or relate to: '${query}'. Include common conditions like fever, cold, headache, diabetes, hypertension, infections, skin diseases, GI issues, respiratory, neurological, rare diseases, pediatric, geriatric, and specialty conditions. Return ONLY a JSON array of 30 strings (disease/condition names only), no explanation. Example: [\"Type 2 Diabetes Mellitus\", \"Acute Febrile Illness\", \"Common Cold (Rhinovirus)\"]`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<string[]>(result);\n return Array.isArray(parsed)\n ? parsed.filter((s) => typeof s === \"string\")\n : [];\n}\n\nexport async function getFormulationIdeas(\n disease: string,\n dosageForm: string,\n drugType: string,\n): Promise<FormulationIdea[]> {\n const prompt = `Generate exactly 20 diverse, creative, pharmacopeia-compliant novel pharmaceutical formulation ideas for treating ${disease} as a ${dosageForm} using ${drugType} approach. Include Ayurvedic, allopathic, herbal, and combination approaches as appropriate. No restrictions on formulation types. Use real ingredient names, real pharmacopeia doses.\n\nFor each, return a JSON array of objects with these exact fields:\n- compositionName (string): unique descriptive name\n- ingredients (array): each with name (string), quantity (number), unit (string), role (string), pharmacologicalEffect (string - specific mechanism of this ingredient)\n- advantages (array of 3-5 strings)\n- disadvantages (array of 2-3 strings)\n- stabilityPrediction (string)\n- mechanismOfAction (string): 2-3 sentence combined mechanism\n- drugInteractions (array of strings)\n- clinicalRationale (string): 2-3 sentences\n- pharmacologicalEffects (string): comprehensive 4-6 sentence paragraph covering overall mechanism of action, key active constituents and their receptor/enzyme targets, therapeutic effects, bioavailability considerations, and clinical rationale for this specific disease\n- indicationsForDisease (string): comma-separated list of all diseases/conditions this formulation is indicated for\n- contraindications (array of strings): specific contraindications\n- dosageInstructions (string): dosage and administration instructions\n\nReturn ONLY valid JSON array, no markdown, no explanation.`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<FormulationIdea[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\nexport async function analyzeFormulation(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n): Promise<FormulationAnalysis | null> {\n if (ingredients.length < 2) return null;\n const prompt = `Analyze this pharmaceutical formulation with these ingredients: ${JSON.stringify(ingredients)}. Return a JSON object with these exact fields:\n- compatibilityMatrix: array of {ingredient1 (string), ingredient2 (string), status ('compatible'|'incompatible'|'conditional'), reason (string)}\n- stabilityAssessment: {physicalStability (string), chemicalStability (string), predictedShelfLife (string), ichClassification (string), stabilityScore (number 0-100), hygroscopicIngredients (string array), thermolabileIngredients (string array), lightSensitiveIngredients (string array)}\n- advantages: string array\n- disadvantages: string array\n- interIngredientReactions: array of {ingredient1 (string), ingredient2 (string), reactionType (string), description (string), severity ('low'|'medium'|'high')}\n- hplcProfile: array of {constituentName (string), retentionTime (number in minutes), peakArea (number as percentage), ingredient (string)}\n- uvSpectrum: {lambdaMax (number in nm), absorptionRange (string), chromophores (string array)}\n- ftirProfile: array of {functionalGroup (string), wavenumber (number in cm-1), transmittance (number as %)}\n- dscProfile: array of {ingredient (string), event (string), temperature (number in celsius), enthalpy (number in J/g)}\n- dissolutionProfile: array of {timeMinutes (number), percentReleased (number)}\nReturn ONLY valid JSON, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return null;\n return parseJSON<FormulationAnalysis>(result);\n}\n\n// ─── Marketed Drugs ───────────────────────────────────────────────────────────\n\nexport interface MarketedDrugResult {\n brandName: string;\n genericName: string;\n manufacturer: string;\n dosageForm: string;\n strength: string;\n}\n\nexport async function getMarketedDrugs(\n disease: string,\n _drugType: string,\n _dosageForm: string,\n): Promise<MarketedDrugResult[]> {\n const prompt = `List 20 real marketed pharmaceutical drugs for treating ${disease}. Include ALL available dosage forms (tablets, capsules, injections, syrups, creams, patches, suppositories, inhalers, etc.) and both allopathic and herbal/Ayurvedic brands. Use real brand names, manufacturers, and strengths from pharmacopoeia. Return ONLY a JSON array of objects with fields: brandName (string), genericName (string), manufacturer (string), dosageForm (string), strength (string). Example: [{\"brandName\":\"Glucophage\",\"genericName\":\"Metformin HCl\",\"manufacturer\":\"Merck\",\"dosageForm\":\"Tablet\",\"strength\":\"500 mg\"}]. Return ONLY valid JSON array, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return [];\n const parsed = parseJSON<MarketedDrugResult[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\n// ─── Formulation Summary ──────────────────────────────────────────────────────\n\nexport interface FormulationSummaryData {\n narrative: string;\n procedure: string[];\n instruments: string[];\n glassware: string[];\n}\n\nexport async function getFormulationSummary(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n dosageForm: string,\n method: string,\n): Promise<FormulationSummaryData | null> {\n const prompt = `For a ${dosageForm} pharmaceutical formulation prepared by ${method} method using: ${ingredients.map((i) => `${i.name} ${i.quantity}${i.unit} (${i.role})`).join(\", \")}.\nReturn a JSON object with:\n- narrative: a 4-6 sentence clinical rationale for this formulation covering pharmacological mechanisms, therapeutic synergy, and clinical evidence basis (scientific, pharmacopeia-based)\n- procedure: array of 8-10 step-by-step manufacturing procedure strings (detailed, numbered context omitted, specific to ${dosageForm} by ${method})\n- instruments: array of 8-12 laboratory instruments required (e.g. \"Tablet Compression Machine\", \"Analytical Balance\", \"Dissolution Apparatus USP Type II\")\n- glassware: array of 6-10 glassware items required (e.g. \"250 mL Beaker\", \"100 mL Volumetric Flask\", \"Conical Flask 500 mL\")\nReturn ONLY valid JSON, no markdown.`;\n const result = await callAI(prompt);\n if (!result) return null;\n return parseJSON<FormulationSummaryData>(result);\n}\n\n// ─── Composition Pharmacology ─────────────────────────────────────────────────\n\nexport async function getCompositionPharmacology(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n dosageForm: string,\n disease?: string,\n): Promise<string> {\n const prompt = `Describe the combined pharmacological effects of this ${dosageForm} formulation${disease ? ` for treating ${disease}` : \"\"}: ${ingredients.map((i) => `${i.name} ${i.quantity}${i.unit} (${i.role})`).join(\", \")}. Write a comprehensive 4-6 sentence paragraph covering: overall mechanism of action, key active constituents and their targets, therapeutic effects, bioavailability considerations, and clinical rationale. Be specific and pharmacopeia-accurate. Return ONLY the paragraph text, no JSON, no headers.`;\n const result = await callAI(prompt);\n return result ?? \"Pharmacological effects data unavailable.\";\n}\n"}, "8e6df2ea7249234472fca6ce0ac7b2197a0d280e": {"t": 1785765315.2805028, "n": 11599, "h": "714e41a8380a1f13", "c": "// Gemini API Service for AyurNexis 3.1\nconst GEMINI_API_KEY = \"AIzaSyCkAAD9UcBo5KH1edlmz4vs61rAPJpRHQU\";\nconst GEMINI_URL = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${GEMINI_API_KEY}`;\n\nasync function callGemini(prompt: string): Promise<string | null> {\n try {\n const res = await fetch(GEMINI_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: prompt }] }],\n generationConfig: { temperature: 0.8, maxOutputTokens: 8192 },\n }),\n });\n if (!res.ok) return null;\n const data = await res.json();\n return data?.candidates?.[0]?.content?.parts?.[0]?.text ?? null;\n } catch {\n return null;\n }\n}\n\nfunction stripMarkdown(text: string): string {\n return text\n .replace(/```json\\s*/gi, \"\")\n .replace(/```\\s*/g, \"\")\n .trim();\n}\n\nfunction parseJSON<T>(text: string): T | null {\n try {\n return JSON.parse(stripMarkdown(text)) as T;\n } catch {\n // Try extracting JSON from text\n const arrMatch = text.match(/(\\[\\s*\\{[\\s\\S]*\\}\\s*\\])/m);\n if (arrMatch) {\n try {\n return JSON.parse(arrMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n const objMatch = text.match(/(\\{[\\s\\S]*\\})/m);\n if (objMatch) {\n try {\n return JSON.parse(objMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n return null;\n }\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GeminiFormulationIngredient {\n name: string;\n quantity: number;\n unit: string;\n role: string;\n pharmacologicalEffect: string;\n}\n\nexport interface FormulationIdea {\n compositionName: string;\n ingredients: GeminiFormulationIngredient[];\n advantages: string[];\n disadvantages: string[];\n stabilityPrediction: string;\n mechanismOfAction: string;\n drugInteractions: string[];\n clinicalRationale: string;\n pharmacologicalEffects: string;\n indicationsForDisease: string;\n contraindications: string[];\n dosageInstructions: string;\n}\n\nexport interface CompatibilityPair {\n ingredient1: string;\n ingredient2: string;\n status: \"compatible\" | \"incompatible\" | \"conditional\";\n reason: string;\n}\n\nexport interface StabilityAssessment {\n physicalStability: string;\n chemicalStability: string;\n predictedShelfLife: string;\n ichClassification: string;\n stabilityScore: number;\n hygroscopicIngredients: string[];\n thermolabileIngredients: string[];\n lightSensitiveIngredients: string[];\n}\n\nexport interface InterIngredientReaction {\n ingredient1: string;\n ingredient2: string;\n reactionType: string;\n description: string;\n severity: \"low\" | \"medium\" | \"high\";\n}\n\nexport interface HplcPeak {\n constituentName: string;\n retentionTime: number;\n peakArea: number;\n ingredient: string;\n}\n\nexport interface UvSpectrum {\n lambdaMax: number;\n absorptionRange: string;\n chromophores: string[];\n}\n\nexport interface FtirPeak {\n functionalGroup: string;\n wavenumber: number;\n transmittance: number;\n}\n\nexport interface DscEvent {\n ingredient: string;\n event: string;\n temperature: number;\n enthalpy: number;\n}\n\nexport interface DissolutionPoint {\n timeMinutes: number;\n percentReleased: number;\n}\n\nexport interface FormulationAnalysis {\n compatibilityMatrix: CompatibilityPair[];\n stabilityAssessment: StabilityAssessment;\n advantages: string[];\n disadvantages: string[];\n interIngredientReactions: InterIngredientReaction[];\n hplcProfile: HplcPeak[];\n uvSpectrum: UvSpectrum;\n ftirProfile: FtirPeak[];\n dscProfile: DscEvent[];\n dissolutionProfile: DissolutionPoint[];\n}\n\n// ─── API Functions ────────────────────────────────────────────────────────────\n\nexport async function searchDiseases(query: string): Promise<string[]> {\n const prompt = `List 30 medical diseases, disorders, syndromes, or conditions that match or relate to: '${query}'. Include common conditions like fever, cold, headache, diabetes, hypertension, infections, skin diseases, GI issues, respiratory, neurological, rare diseases, pediatric, geriatric, and specialty conditions. Return ONLY a JSON array of 30 strings (disease/condition names only), no explanation. Example: [\"Type 2 Diabetes Mellitus\", \"Acute Febrile Illness\", \"Common Cold (Rhinovirus)\"]`;\n const result = await callGemini(prompt);\n if (!result) return [];\n const parsed = parseJSON<string[]>(result);\n return Array.isArray(parsed)\n ? parsed.filter((s) => typeof s === \"string\")\n : [];\n}\n\nexport async function getFormulationIdeas(\n disease: string,\n dosageForm: string,\n drugType: string,\n): Promise<FormulationIdea[]> {\n const prompt = `Generate exactly 20 diverse, creative, pharmacopeia-compliant novel pharmaceutical formulation ideas for treating ${disease} as a ${dosageForm} using ${drugType} approach. Include Ayurvedic, allopathic, herbal, and combination approaches as appropriate. No restrictions on formulation types. Use real ingredient names, real pharmacopeia doses.\n\nFor each, return a JSON array of objects with these exact fields:\n- compositionName (string): unique descriptive name\n- ingredients (array): each with name (string), quantity (number), unit (string), role (string), pharmacologicalEffect (string - specific mechanism of this ingredient)\n- advantages (array of 3-5 strings)\n- disadvantages (array of 2-3 strings)\n- stabilityPrediction (string)\n- mechanismOfAction (string): 2-3 sentence combined mechanism\n- drugInteractions (array of strings)\n- clinicalRationale (string): 2-3 sentences\n- pharmacologicalEffects (string): comprehensive 4-6 sentence paragraph covering overall mechanism of action, key active constituents and their receptor/enzyme targets, therapeutic effects, bioavailability considerations, and clinical rationale for this specific disease\n- indicationsForDisease (string): comma-separated list of all diseases/conditions this formulation is indicated for\n- contraindications (array of strings): specific contraindications\n- dosageInstructions (string): dosage and administration instructions\n\nReturn ONLY valid JSON array, no markdown, no explanation.`;\n const result = await callGemini(prompt);\n if (!result) return [];\n const parsed = parseJSON<FormulationIdea[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\nexport async function analyzeFormulation(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n): Promise<FormulationAnalysis | null> {\n if (ingredients.length < 2) return null;\n const prompt = `Analyze this pharmaceutical formulation with these ingredients: ${JSON.stringify(ingredients)}. Return a JSON object with these exact fields:\n- compatibilityMatrix: array of {ingredient1 (string), ingredient2 (string), status ('compatible'|'incompatible'|'conditional'), reason (string)}\n- stabilityAssessment: {physicalStability (string), chemicalStability (string), predictedShelfLife (string), ichClassification (string), stabilityScore (number 0-100), hygroscopicIngredients (string array), thermolabileIngredients (string array), lightSensitiveIngredients (string array)}\n- advantages: string array\n- disadvantages: string array\n- interIngredientReactions: array of {ingredient1 (string), ingredient2 (string), reactionType (string), description (string), severity ('low'|'medium'|'high')}\n- hplcProfile: array of {constituentName (string), retentionTime (number in minutes), peakArea (number as percentage), ingredient (string)}\n- uvSpectrum: {lambdaMax (number in nm), absorptionRange (string), chromophores (string array)}\n- ftirProfile: array of {functionalGroup (string), wavenumber (number in cm-1), transmittance (number as %)}\n- dscProfile: array of {ingredient (string), event (string), temperature (number in celsius), enthalpy (number in J/g)}\n- dissolutionProfile: array of {timeMinutes (number), percentReleased (number)}\nReturn ONLY valid JSON, no markdown.`;\n const result = await callGemini(prompt);\n if (!result) return null;\n return parseJSON<FormulationAnalysis>(result);\n}\n\n// ─── Marketed Drugs ───────────────────────────────────────────────────────────\n\nexport interface MarketedDrugResult {\n brandName: string;\n genericName: string;\n manufacturer: string;\n dosageForm: string;\n strength: string;\n}\n\nexport async function getMarketedDrugs(\n disease: string,\n _drugType: string,\n _dosageForm: string,\n): Promise<MarketedDrugResult[]> {\n const prompt = `List 20 real marketed pharmaceutical drugs for treating ${disease}. Include ALL available dosage forms (tablets, capsules, injections, syrups, creams, patches, suppositories, inhalers, etc.) and both allopathic and herbal/Ayurvedic brands. Use real brand names, manufacturers, and strengths from pharmacopoeia. Return ONLY a JSON array of objects with fields: brandName (string), genericName (string), manufacturer (string), dosageForm (string), strength (string). Example: [{\"brandName\":\"Glucophage\",\"genericName\":\"Metformin HCl\",\"manufacturer\":\"Merck\",\"dosageForm\":\"Tablet\",\"strength\":\"500 mg\"}]. Return ONLY valid JSON array, no markdown.`;\n const result = await callGemini(prompt);\n if (!result) return [];\n const parsed = parseJSON<MarketedDrugResult[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\n// ─── Formulation Summary ──────────────────────────────────────────────────────\n\nexport interface FormulationSummaryData {\n narrative: string;\n procedure: string[];\n instruments: string[];\n glassware: string[];\n}\n\nexport async function getFormulationSummary(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n dosageForm: string,\n method: string,\n): Promise<FormulationSummaryData | null> {\n const prompt = `For a ${dosageForm} pharmaceutical formulation prepared by ${method} method using: ${ingredients.map((i) => `${i.name} ${i.quantity}${i.unit} (${i.role})`).join(\", \")}.\nReturn a JSON object with:\n- narrative: a 4-6 sentence clinical rationale for this formulation covering pharmacological mechanisms, therapeutic synergy, and clinical evidence basis (scientific, pharmacopeia-based)\n- procedure: array of 8-10 step-by-step manufacturing procedure strings (detailed, numbered context omitted, specific to ${dosageForm} by ${method})\n- instruments: array of 8-12 laboratory instruments required (e.g. \"Tablet Compression Machine\", \"Analytical Balance\", \"Dissolution Apparatus USP Type II\")\n- glassware: array of 6-10 glassware items required (e.g. \"250 mL Beaker\", \"100 mL Volumetric Flask\", \"Conical Flask 500 mL\")\nReturn ONLY valid JSON, no markdown.`;\n const result = await callGemini(prompt);\n if (!result) return null;\n return parseJSON<FormulationSummaryData>(result);\n}\n\n// ─── Composition Pharmacology ─────────────────────────────────────────────────\n\nexport async function getCompositionPharmacology(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n dosageForm: string,\n disease?: string,\n): Promise<string> {\n const prompt = `Describe the combined pharmacological effects of this ${dosageForm} formulation${disease ? ` for treating ${disease}` : \"\"}: ${ingredients.map((i) => `${i.name} ${i.quantity}${i.unit} (${i.role})`).join(\", \")}. Write a comprehensive 4-6 sentence paragraph covering: overall mechanism of action, key active constituents and their targets, therapeutic effects, bioavailability considerations, and clinical rationale. Be specific and pharmacopeia-accurate. Return ONLY the paragraph text, no JSON, no headers.`;\n const result = await callGemini(prompt);\n return result ?? \"Pharmacological effects data unavailable.\";\n}\n"}, "7238a915958bdaf42723c0381216ec5829918616": {"t": 1785765318.0971282, "n": 9049, "h": "aee0f063a1482563", "c": "// Gemini API Service for AyurNexis 3.1\nconst GEMINI_API_KEY = \"AIzaSyCkAAD9UcBo5KH1edlmz4vs61rAPJpRHQU\";\nconst GEMINI_URL = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${GEMINI_API_KEY}`;\n\nasync function callGemini(prompt: string): Promise<string | null> {\n try {\n const res = await fetch(GEMINI_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: prompt }] }],\n generationConfig: { temperature: 0.7, maxOutputTokens: 8192 },\n }),\n });\n if (!res.ok) return null;\n const data = await res.json();\n return data?.candidates?.[0]?.content?.parts?.[0]?.text ?? null;\n } catch {\n return null;\n }\n}\n\nfunction stripMarkdown(text: string): string {\n return text\n .replace(/```json\\s*/gi, \"\")\n .replace(/```\\s*/g, \"\")\n .trim();\n}\n\nfunction parseJSON<T>(text: string): T | null {\n try {\n return JSON.parse(stripMarkdown(text)) as T;\n } catch {\n // Try extracting JSON from text\n const arrMatch = text.match(/(\\[\\s*\\{[\\s\\S]*\\}\\s*\\])/m);\n if (arrMatch) {\n try {\n return JSON.parse(arrMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n const objMatch = text.match(/(\\{[\\s\\S]*\\})/m);\n if (objMatch) {\n try {\n return JSON.parse(objMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n return null;\n }\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GeminiFormulationIngredient {\n name: string;\n quantity: number;\n unit: string;\n role: string;\n pharmacologicalEffect: string;\n}\n\nexport interface FormulationIdea {\n compositionName: string;\n ingredients: GeminiFormulationIngredient[];\n advantages: string[];\n disadvantages: string[];\n stabilityPrediction: string;\n mechanismOfAction: string;\n drugInteractions: string[];\n clinicalRationale: string;\n}\n\nexport interface CompatibilityPair {\n ingredient1: string;\n ingredient2: string;\n status: \"compatible\" | \"incompatible\" | \"conditional\";\n reason: string;\n}\n\nexport interface StabilityAssessment {\n physicalStability: string;\n chemicalStability: string;\n predictedShelfLife: string;\n ichClassification: string;\n stabilityScore: number;\n hygroscopicIngredients: string[];\n thermolabileIngredients: string[];\n lightSensitiveIngredients: string[];\n}\n\nexport interface InterIngredientReaction {\n ingredient1: string;\n ingredient2: string;\n reactionType: string;\n description: string;\n severity: \"low\" | \"medium\" | \"high\";\n}\n\nexport interface HplcPeak {\n constituentName: string;\n retentionTime: number;\n peakArea: number;\n ingredient: string;\n}\n\nexport interface UvSpectrum {\n lambdaMax: number;\n absorptionRange: string;\n chromophores: string[];\n}\n\nexport interface FtirPeak {\n functionalGroup: string;\n wavenumber: number;\n transmittance: number;\n}\n\nexport interface DscEvent {\n ingredient: string;\n event: string;\n temperature: number;\n enthalpy: number;\n}\n\nexport interface DissolutionPoint {\n timeMinutes: number;\n percentReleased: number;\n}\n\nexport interface FormulationAnalysis {\n compatibilityMatrix: CompatibilityPair[];\n stabilityAssessment: StabilityAssessment;\n advantages: string[];\n disadvantages: string[];\n interIngredientReactions: InterIngredientReaction[];\n hplcProfile: HplcPeak[];\n uvSpectrum: UvSpectrum;\n ftirProfile: FtirPeak[];\n dscProfile: DscEvent[];\n dissolutionProfile: DissolutionPoint[];\n}\n\n// ─── API Functions ────────────────────────────────────────────────────────────\n\nexport async function searchDiseases(query: string): Promise<string[]> {\n const prompt = `List 20 medical diseases or conditions that match or relate to: '${query}'. Return ONLY a JSON array of 20 strings, no explanation. Example: [\"Disease 1\", \"Disease 2\"]`;\n const result = await callGemini(prompt);\n if (!result) return [];\n const parsed = parseJSON<string[]>(result);\n return Array.isArray(parsed)\n ? parsed.filter((s) => typeof s === \"string\")\n : [];\n}\n\nexport async function getFormulationIdeas(\n disease: string,\n dosageForm: string,\n drugType: string,\n): Promise<FormulationIdea[]> {\n const prompt = `Generate exactly 10 novel pharmaceutical formulation ideas for treating ${disease} as a ${dosageForm} using ${drugType} approach. For each, return a JSON array of objects with these exact fields: compositionName (string), ingredients (array of objects with name (string), quantity (number), unit (string), role (string), pharmacologicalEffect (string)), advantages (array of strings), disadvantages (array of strings), stabilityPrediction (string), mechanismOfAction (string), drugInteractions (array of strings), clinicalRationale (string). Return ONLY valid JSON array, no markdown, no explanation.`;\n const result = await callGemini(prompt);\n if (!result) return [];\n const parsed = parseJSON<FormulationIdea[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\nexport async function analyzeFormulation(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n): Promise<FormulationAnalysis | null> {\n if (ingredients.length < 2) return null;\n const prompt = `Analyze this pharmaceutical formulation with these ingredients: ${JSON.stringify(ingredients)}. Return a JSON object with these exact fields:\n- compatibilityMatrix: array of {ingredient1 (string), ingredient2 (string), status ('compatible'|'incompatible'|'conditional'), reason (string)}\n- stabilityAssessment: {physicalStability (string), chemicalStability (string), predictedShelfLife (string), ichClassification (string), stabilityScore (number 0-100), hygroscopicIngredients (string array), thermolabileIngredients (string array), lightSensitiveIngredients (string array)}\n- advantages: string array\n- disadvantages: string array\n- interIngredientReactions: array of {ingredient1 (string), ingredient2 (string), reactionType (string), description (string), severity ('low'|'medium'|'high')}\n- hplcProfile: array of {constituentName (string), retentionTime (number in minutes), peakArea (number as percentage), ingredient (string)}\n- uvSpectrum: {lambdaMax (number in nm), absorptionRange (string), chromophores (string array)}\n- ftirProfile: array of {functionalGroup (string), wavenumber (number in cm-1), transmittance (number as %)}\n- dscProfile: array of {ingredient (string), event (string), temperature (number in celsius), enthalpy (number in J/g)}\n- dissolutionProfile: array of {timeMinutes (number), percentReleased (number)}\nReturn ONLY valid JSON, no markdown.`;\n const result = await callGemini(prompt);\n if (!result) return null;\n return parseJSON<FormulationAnalysis>(result);\n}\n\n// ─── Marketed Drugs ───────────────────────────────────────────────────────────\n\nexport interface MarketedDrugResult {\n brandName: string;\n genericName: string;\n manufacturer: string;\n dosageForm: string;\n strength: string;\n}\n\nexport async function getMarketedDrugs(\n disease: string,\n drugType: string,\n dosageForm: string,\n): Promise<MarketedDrugResult[]> {\n const prompt = `List 10 real marketed pharmaceutical drugs for treating ${disease} as a ${drugType} ${dosageForm}. Return ONLY a JSON array of objects with fields: brandName (string), genericName (string), manufacturer (string), dosageForm (string), strength (string). Use real drug names, manufacturers, and strengths from pharmacopoeia. Example format: [{\"brandName\":\"Glucophage\",\"genericName\":\"Metformin HCl\",\"manufacturer\":\"Merck\",\"dosageForm\":\"Tablet\",\"strength\":\"500 mg\"}]. Return ONLY valid JSON array, no markdown.`;\n const result = await callGemini(prompt);\n if (!result) return [];\n const parsed = parseJSON<MarketedDrugResult[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\n// ─── Formulation Summary ──────────────────────────────────────────────────────\n\nexport interface FormulationSummaryData {\n narrative: string;\n procedure: string[];\n instruments: string[];\n glassware: string[];\n}\n\nexport async function getFormulationSummary(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n dosageForm: string,\n method: string,\n): Promise<FormulationSummaryData | null> {\n const prompt = `For a ${dosageForm} pharmaceutical formulation prepared by ${method} method using: ${ingredients.map((i) => `${i.name} ${i.quantity}${i.unit} (${i.role})`).join(\", \")}.\nReturn a JSON object with:\n- narrative: a 3-4 sentence clinical rationale for this formulation (scientific, pharmacopeia-based)\n- procedure: array of 6-8 step-by-step manufacturing procedure strings (brief, numbered context omitted)\n- instruments: array of 6-10 laboratory instruments required (e.g. \"Tablet Compression Machine\", \"Analytical Balance\")\n- glassware: array of 5-8 glassware items required (e.g. \"250 mL Beaker\", \"100 mL Volumetric Flask\")\nReturn ONLY valid JSON, no markdown.`;\n const result = await callGemini(prompt);\n if (!result) return null;\n return parseJSON<FormulationSummaryData>(result);\n}\n"}, "f96c94fb8cb1e9d8a9ad9fd5abf8d88e3183fc69": {"t": 1785765320.6165748, "n": 6729, "h": "dce48f7afca8850f", "c": "// Gemini API Service for AyurNexis 3.1\nconst GEMINI_API_KEY = \"AIzaSyCkAAD9UcBo5KH1edlmz4vs61rAPJpRHQU\";\nconst GEMINI_URL = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${GEMINI_API_KEY}`;\n\nasync function callGemini(prompt: string): Promise<string | null> {\n try {\n const res = await fetch(GEMINI_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: prompt }] }],\n generationConfig: { temperature: 0.7, maxOutputTokens: 8192 },\n }),\n });\n if (!res.ok) return null;\n const data = await res.json();\n return data?.candidates?.[0]?.content?.parts?.[0]?.text ?? null;\n } catch {\n return null;\n }\n}\n\nfunction stripMarkdown(text: string): string {\n return text\n .replace(/```json\\s*/gi, \"\")\n .replace(/```\\s*/g, \"\")\n .trim();\n}\n\nfunction parseJSON<T>(text: string): T | null {\n try {\n return JSON.parse(stripMarkdown(text)) as T;\n } catch {\n // Try extracting JSON from text\n const arrMatch = text.match(/(\\[\\s*\\{[\\s\\S]*\\}\\s*\\])/m);\n if (arrMatch) {\n try {\n return JSON.parse(arrMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n const objMatch = text.match(/(\\{[\\s\\S]*\\})/m);\n if (objMatch) {\n try {\n return JSON.parse(objMatch[1]) as T;\n } catch {\n /* ignore */\n }\n }\n return null;\n }\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GeminiFormulationIngredient {\n name: string;\n quantity: number;\n unit: string;\n role: string;\n pharmacologicalEffect: string;\n}\n\nexport interface FormulationIdea {\n compositionName: string;\n ingredients: GeminiFormulationIngredient[];\n advantages: string[];\n disadvantages: string[];\n stabilityPrediction: string;\n mechanismOfAction: string;\n drugInteractions: string[];\n clinicalRationale: string;\n}\n\nexport interface CompatibilityPair {\n ingredient1: string;\n ingredient2: string;\n status: \"compatible\" | \"incompatible\" | \"conditional\";\n reason: string;\n}\n\nexport interface StabilityAssessment {\n physicalStability: string;\n chemicalStability: string;\n predictedShelfLife: string;\n ichClassification: string;\n stabilityScore: number;\n hygroscopicIngredients: string[];\n thermolabileIngredients: string[];\n lightSensitiveIngredients: string[];\n}\n\nexport interface InterIngredientReaction {\n ingredient1: string;\n ingredient2: string;\n reactionType: string;\n description: string;\n severity: \"low\" | \"medium\" | \"high\";\n}\n\nexport interface HplcPeak {\n constituentName: string;\n retentionTime: number;\n peakArea: number;\n ingredient: string;\n}\n\nexport interface UvSpectrum {\n lambdaMax: number;\n absorptionRange: string;\n chromophores: string[];\n}\n\nexport interface FtirPeak {\n functionalGroup: string;\n wavenumber: number;\n transmittance: number;\n}\n\nexport interface DscEvent {\n ingredient: string;\n event: string;\n temperature: number;\n enthalpy: number;\n}\n\nexport interface DissolutionPoint {\n timeMinutes: number;\n percentReleased: number;\n}\n\nexport interface FormulationAnalysis {\n compatibilityMatrix: CompatibilityPair[];\n stabilityAssessment: StabilityAssessment;\n advantages: string[];\n disadvantages: string[];\n interIngredientReactions: InterIngredientReaction[];\n hplcProfile: HplcPeak[];\n uvSpectrum: UvSpectrum;\n ftirProfile: FtirPeak[];\n dscProfile: DscEvent[];\n dissolutionProfile: DissolutionPoint[];\n}\n\n// ─── API Functions ────────────────────────────────────────────────────────────\n\nexport async function searchDiseases(query: string): Promise<string[]> {\n const prompt = `List 10 medical diseases or conditions that match or relate to: '${query}'. Return ONLY a JSON array of strings, no explanation. Example: [\"Disease 1\", \"Disease 2\"]`;\n const result = await callGemini(prompt);\n if (!result) return [];\n const parsed = parseJSON<string[]>(result);\n return Array.isArray(parsed)\n ? parsed.filter((s) => typeof s === \"string\")\n : [];\n}\n\nexport async function getFormulationIdeas(\n disease: string,\n dosageForm: string,\n drugType: string,\n): Promise<FormulationIdea[]> {\n const prompt = `Generate 5 novel pharmaceutical formulation ideas for treating ${disease} as a ${dosageForm} using ${drugType} approach. For each, return a JSON array of objects with these exact fields: compositionName (string), ingredients (array of objects with name (string), quantity (number), unit (string), role (string), pharmacologicalEffect (string)), advantages (array of strings), disadvantages (array of strings), stabilityPrediction (string), mechanismOfAction (string), drugInteractions (array of strings), clinicalRationale (string). Return ONLY valid JSON array, no markdown, no explanation.`;\n const result = await callGemini(prompt);\n if (!result) return [];\n const parsed = parseJSON<FormulationIdea[]>(result);\n return Array.isArray(parsed) ? parsed : [];\n}\n\nexport async function analyzeFormulation(\n ingredients: { name: string; quantity: number; unit: string; role: string }[],\n): Promise<FormulationAnalysis | null> {\n if (ingredients.length < 2) return null;\n const prompt = `Analyze this pharmaceutical formulation with these ingredients: ${JSON.stringify(ingredients)}. Return a JSON object with these exact fields:\n- compatibilityMatrix: array of {ingredient1 (string), ingredient2 (string), status ('compatible'|'incompatible'|'conditional'), reason (string)}\n- stabilityAssessment: {physicalStability (string), chemicalStability (string), predictedShelfLife (string), ichClassification (string), stabilityScore (number 0-100), hygroscopicIngredients (string array), thermolabileIngredients (string array), lightSensitiveIngredients (string array)}\n- advantages: string array\n- disadvantages: string array\n- interIngredientReactions: array of {ingredient1 (string), ingredient2 (string), reactionType (string), description (string), severity ('low'|'medium'|'high')}\n- hplcProfile: array of {constituentName (string), retentionTime (number in minutes), peakArea (number as percentage), ingredient (string)}\n- uvSpectrum: {lambdaMax (number in nm), absorptionRange (string), chromophores (string array)}\n- ftirProfile: array of {functionalGroup (string), wavenumber (number in cm-1), transmittance (number as %)}\n- dscProfile: array of {ingredient (string), event (string), temperature (number in celsius), enthalpy (number in J/g)}\n- dissolutionProfile: array of {timeMinutes (number), percentReleased (number)}\nReturn ONLY valid JSON, no markdown.`;\n const result = await callGemini(prompt);\n if (!result) return null;\n return parseJSON<FormulationAnalysis>(result);\n}\n"}}}} |