Medibot AI: a web-based software tool integrating Gemini API for informational over-the-counter medication guidance

preprint OA: closed CC-BY-4.0
AI-generated deep summary by claude@2026-07, 2026-07-06 · read from full text

This paper describes Medibot AI, a web-based software tool that integrates the Gemini API to provide informational guidance related to over-the-counter medications. The content appears to focus on the software implementation and delivery (i.e., a web tool architecture) rather than on any biomedical population, measurement outcomes, or clinical effectiveness evaluation. A major caveat is that the provided text does not include study design details, participant information, validation against standards, or explicit limitations regarding accuracy, safety, or performance. The paper does not explicitly discuss endometriosis or adenomyosis; it was included in the corpus via a keyword match in the upstream search index.

Read from the paper's body, not the abstract. Not a substitute for reading the paper. No clinical advice. How this works

Abstract

Background: Self-medication for common illnesses remains widespread and may lead to inappropriate drug selection, incorrect dosage, adverse interactions, and delayed professional care. In this context, artificial intelligence (AI) can provide informational support to promote safer therapeutic decisions. This paper presents Medibot AI, a web-based intelligent system designed to generate informational over-the-counter (OTC) medication recommendations from user-reported symptoms using Google’s Gemini API, with an emphasis on transparency, traceability, and safety warnings. Methods The system was developed iteratively using agile principles and implemented with a three-layer architecture: (i) user interface, (ii) recommendation and validation logic, and (iii) data persistence. The frontend was built using Next.js 18, React 18, and Tailwind CSS 3, while backend services were implemented with Node.js 20 and Prisma ORM 6.8 connected to PostgreSQL 17 (Neon). User inputs are transformed into a structured JSON prompt, and Gemini responses are constrained to return strict JSON outputs. A server-side validation layer verifies both JSON integrity and schema compliance before results are displayed or stored. The system also implements safety-oriented rules that suppress recommendations in high-risk scenarios and generate visible warnings. Results Medibot AI enables users to register, submit symptom descriptions with optional clinical context, obtain structured recommendations with dosage instructions and warnings, and download PDF reports. Functional integration testing confirmed stable data flow across modules and consistent schema-compliant outputs. Conclusions Medibot AI provides a reproducible and auditable approach for AI-assisted OTC medication guidance. While it does not replace clinical diagnosis or professional medical advice, it offers an educational tool that supports more informed and responsible self-medication practices.
Full text 111,784 characters · extracted from preprint-html · click to expand
Medibot AI: a web-based software tool integrating... | F1000Research "use strict";function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(){var t=function(){var t,e,o=[],n=window,r=n;for(;r;){try{if(r.frames.__tcfapiLocator){t=r;break}}catch(t){}if(r===n.top)break;r=r.parent}t||(!function t(){var e=n.document,o=!!n.frames.__tcfapiLocator;if(!o)if(e.body){var r=e.createElement("iframe");r.style.cssText="display:none",r.name="__tcfapiLocator",e.body.appendChild(r)}else setTimeout(t,5);return!o}(),n.__tcfapi=function(){for(var t=arguments.length,n=new Array(t),r=0;r 3&&2===parseInt(n[1],10)&&"boolean"==typeof n[3]&&(e=n[3],"function"==typeof n[2]&&n[2]("set",!0)):"ping"===n[0]?"function"==typeof n[2]&&n[2]({gdprApplies:e,cmpLoaded:!1,cmpStatus:"stub"}):o.push(n)},n.addEventListener("message",(function(t){var e="string"==typeof t.data,o={};if(e)try{o=JSON.parse(t.data)}catch(t){}else o=t.data;var n="object"===_typeof(o)&&null!==o?o.__tcfapiCall:null;n&&window.__tcfapi(n.command,n.version,(function(o,r){var a={__tcfapiReturn:{returnValue:o,success:r,callId:n.callId}};t&&t.source&&t.source.postMessage&&t.source.postMessage(e?JSON.stringify(a):a,"*")}),n.parameter)}),!1))};"undefined"!=typeof module?module.exports=t:t()}(); dataLayer = dataLayer || []; // Standard GTM initialization - Google Consent Mode handles consent automatically (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl+ '>m_auth=hzk0Vc3qFsQYhCrIoHz68A>m_preview=env-1>m_cookies_win=x';f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-MWFK8L5J'); ;window.NREUM||(NREUM={});NREUM.init={distributed_tracing:{enabled:true},privacy:{cookies_enabled:true},ajax:{deny_list:["bam.nr-data.net"]}}; ;NREUM.loader_config={accountID:"438030",trustKey:"438030",agentID:"772317073",licenseKey:"97f8f67f26",applicationID:"772317073"} ;NREUM.info={beacon:"bam.nr-data.net",errorBeacon:"bam.nr-data.net",licenseKey:"97f8f67f26",applicationID:"772317073",sa:1} ;/*! For license information please see nr-loader-spa-1.236.0.min.js.LICENSE.txt */ (()=>{"use strict";var e,t,r={5763:(e,t,r)=>{r.d(t,{P_:()=>l,Mt:()=>g,C5:()=>s,DL:()=>v,OP:()=>T,lF:()=>D,Yu:()=>y,Dg:()=>h,CX:()=>c,GE:()=>b,sU:()=>_});var n=r(8632),i=r(9567);const o={beacon:n.ce.beacon,errorBeacon:n.ce.errorBeacon,licenseKey:void 0,applicationID:void 0,sa:void 0,queueTime:void 0,applicationTime:void 0,ttGuid:void 0,user:void 0,account:void 0,product:void 0,extra:void 0,jsAttributes:{},userAttributes:void 0,atts:void 0,transactionName:void 0,tNamePlain:void 0},a={};function s(e){if(!e)throw new Error("All info objects require an agent identifier!");if(!a[e])throw new Error("Info for ".concat(e," was never set"));return a[e]}function c(e,t){if(!e)throw new Error("All info objects require an agent identifier!");a[e]=(0,i.D)(t,o),(0,n.Qy)(e,a[e],"info")}var u=r(7056);const d=()=>{const e={blockSelector:"[data-nr-block]",maskInputOptions:{password:!0}};return{allow_bfcache:!0,privacy:{cookies_enabled:!0},ajax:{deny_list:void 0,enabled:!0,harvestTimeSeconds:10},distributed_tracing:{enabled:void 0,exclude_newrelic_header:void 0,cors_use_newrelic_header:void 0,cors_use_tracecontext_headers:void 0,allowed_origins:void 0},session:{domain:void 0,expiresMs:u.oD,inactiveMs:u.Hb},ssl:void 0,obfuscate:void 0,jserrors:{enabled:!0,harvestTimeSeconds:10},metrics:{enabled:!0},page_action:{enabled:!0,harvestTimeSeconds:30},page_view_event:{enabled:!0},page_view_timing:{enabled:!0,harvestTimeSeconds:30,long_task:!1},session_trace:{enabled:!0,harvestTimeSeconds:10},harvest:{tooManyRequestsDelay:60},session_replay:{enabled:!1,harvestTimeSeconds:60,sampleRate:.1,errorSampleRate:.1,maskTextSelector:"*",maskAllInputs:!0,get blockClass(){return"nr-block"},get ignoreClass(){return"nr-ignore"},get maskTextClass(){return"nr-mask"},get blockSelector(){return e.blockSelector},set blockSelector(t){e.blockSelector+=",".concat(t)},get maskInputOptions(){return e.maskInputOptions},set maskInputOptions(t){e.maskInputOptions={...t,password:!0}}},spa:{enabled:!0,harvestTimeSeconds:10}}},f={};function l(e){if(!e)throw new Error("All configuration objects require an agent identifier!");if(!f[e])throw new Error("Configuration for ".concat(e," was never set"));return f[e]}function h(e,t){if(!e)throw new Error("All configuration objects require an agent identifier!");f[e]=(0,i.D)(t,d()),(0,n.Qy)(e,f[e],"config")}function g(e,t){if(!e)throw new Error("All configuration objects require an agent identifier!");var r=l(e);if(r){for(var n=t.split("."),i=0;i {r.d(t,{D:()=>i});var n=r(50);function i(e,t){try{if(!e||"object"!=typeof e)return(0,n.Z)("Setting a Configurable requires an object as input");if(!t||"object"!=typeof t)return(0,n.Z)("Setting a Configurable requires a model to set its initial properties");const r=Object.create(Object.getPrototypeOf(t),Object.getOwnPropertyDescriptors(t)),o=0===Object.keys(r).length?e:r;for(let a in o)if(void 0!==e[a])try{"object"==typeof e[a]&&"object"==typeof t[a]?r[a]=i(e[a],t[a]):r[a]=e[a]}catch(e){(0,n.Z)("An error occurred while setting a property of a Configurable",e)}return r}catch(e){(0,n.Z)("An error occured while setting a Configurable",e)}}},6818:(e,t,r)=>{r.d(t,{Re:()=>i,gF:()=>o,q4:()=>n});const n="1.236.0",i="PROD",o="CDN"},385:(e,t,r)=>{r.d(t,{FN:()=>a,IF:()=>u,Nk:()=>f,Tt:()=>s,_A:()=>o,il:()=>n,pL:()=>c,v6:()=>i,w1:()=>d});const n="undefined"!=typeof window&&!!window.document,i="undefined"!=typeof WorkerGlobalScope&&("undefined"!=typeof self&&self instanceof WorkerGlobalScope&&self.navigator instanceof WorkerNavigator||"undefined"!=typeof globalThis&&globalThis instanceof WorkerGlobalScope&&globalThis.navigator instanceof WorkerNavigator),o=n?window:"undefined"!=typeof WorkerGlobalScope&&("undefined"!=typeof self&&self instanceof WorkerGlobalScope&&self||"undefined"!=typeof globalThis&&globalThis instanceof WorkerGlobalScope&&globalThis),a=""+o?.location,s=/iPad|iPhone|iPod/.test(navigator.userAgent),c=s&&"undefined"==typeof SharedWorker,u=(()=>{const e=navigator.userAgent.match(/Firefox[/\s](\d+\.\d+)/);return Array.isArray(e)&&e.length>=2?+e[1]:0})(),d=Boolean(n&&window.document.documentMode),f=!!navigator.sendBeacon},1117:(e,t,r)=>{r.d(t,{w:()=>o});var n=r(50);const i={agentIdentifier:"",ee:void 0};class o{constructor(e){try{if("object"!=typeof e)return(0,n.Z)("shared context requires an object as input");this.sharedContext={},Object.assign(this.sharedContext,i),Object.entries(e).forEach((e=>{let[t,r]=e;Object.keys(i).includes(t)&&(this.sharedContext[t]=r)}))}catch(e){(0,n.Z)("An error occured while setting SharedContext",e)}}}},8e3:(e,t,r)=>{r.d(t,{L:()=>d,R:()=>c});var n=r(2177),i=r(1284),o=r(4322),a=r(3325);const s={};function c(e,t){const r={staged:!1,priority:a.p[t]||0};u(e),s[e].get(t)||s[e].set(t,r)}function u(e){e&&(s[e]||(s[e]=new Map))}function d(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"feature";if(u(e),!e||!s[e].get(t))return a(t);s[e].get(t).staged=!0;const r=[...s[e]];function a(t){const r=e?n.ee.get(e):n.ee,a=o.X.handlers;if(r.backlog&&a){var s=r.backlog[t],c=a[t];if(c){for(var u=0;s&&u {let[t,r]=e;return r.staged}))&&(r.sort(((e,t)=>e[1].priority-t[1].priority)),r.forEach((e=>{let[t]=e;a(t)})))}function f(e,t){var r=e[1];(0,i.D)(t[r],(function(t,r){var n=e[0];if(r[0]===n){var i=r[1],o=e[3],a=e[2];i.apply(o,a)}}))}},2177:(e,t,r)=>{r.d(t,{c:()=>f,ee:()=>u});var n=r(8632),i=r(2210),o=r(1284),a=r(5763),s="nr@context";let c=(0,n.fP)();var u;function d(){}function f(e){return(0,i.X)(e,s,l)}function l(){return new d}function h(){u.aborted=!0,u.backlog={}}c.ee?u=c.ee:(u=function e(t,r){var n={},c={},f={},g=!1;try{g=16===r.length&&(0,a.OP)(r).isolatedBacklog}catch(e){}var p={on:b,addEventListener:b,removeEventListener:y,emit:v,get:x,listeners:w,context:m,buffer:A,abort:h,aborted:!1,isBuffering:E,debugId:r,backlog:g?{}:t&&"object"==typeof t.backlog?t.backlog:{}};return p;function m(e){return e&&e instanceof d?e:e?(0,i.X)(e,s,l):l()}function v(e,r,n,i,o){if(!1!==o&&(o=!0),!u.aborted||i){t&&o&&t.emit(e,r,n);for(var a=m(n),s=w(e),d=s.length,f=0;fn,p:()=>i});var n=r(2177).ee.get("handle");function i(e,t,r,i,o){o?(o.buffer([e],i),o.emit(e,t,r)):(n.buffer([e],i),n.emit(e,t,r))}},4322:(e,t,r)=>{r.d(t,{X:()=>o});var n=r(5546);o.on=a;var i=o.handlers={};function o(e,t,r,o){a(o||n.E,i,e,t,r)}function a(e,t,r,i,o){o||(o="feature"),e||(e=n.E);var a=t[o]=t[o]||{};(a[r]=a[r]||[]).push([e,i])}},3239:(e,t,r)=>{r.d(t,{bP:()=>s,iz:()=>c,m$:()=>a});var n=r(385);let i=!1,o=!1;try{const e={get passive(){return i=!0,!1},get signal(){return o=!0,!1}};n._A.addEventListener("test",null,e),n._A.removeEventListener("test",null,e)}catch(e){}function a(e,t){return i||o?{capture:!!e,passive:i,signal:t}:!!e}function s(e,t){let r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=arguments.length>3?arguments[3]:void 0;window.addEventListener(e,t,a(r,n))}function c(e,t){let r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=arguments.length>3?arguments[3]:void 0;document.addEventListener(e,t,a(r,n))}},4402:(e,t,r)=>{r.d(t,{Ht:()=>u,M:()=>c,Rl:()=>a,ky:()=>s});var n=r(385);const i="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";function o(e,t){return e?15&e[t]:16*Math.random()|0}function a(){const e=n._A?.crypto||n._A?.msCrypto;let t,r=0;return e&&e.getRandomValues&&(t=e.getRandomValues(new Uint8Array(31))),i.split("").map((e=>"x"===e?o(t,++r).toString(16):"y"===e?(3&o()|8).toString(16):e)).join("")}function s(e){const t=n._A?.crypto||n._A?.msCrypto;let r,i=0;t&&t.getRandomValues&&(r=t.getRandomValues(new Uint8Array(31)));const a=[];for(var s=0;s {r.d(t,{Bq:()=>n,Hb:()=>o,oD:()=>i});const n="NRBA",i=144e5,o=18e5},7894:(e,t,r)=>{function n(){return Math.round(performance.now())}r.d(t,{z:()=>n})},7243:(e,t,r)=>{r.d(t,{e:()=>o});var n=r(385),i={};function o(e){if(e in i)return i[e];if(0===(e||"").indexOf("data:"))return{protocol:"data"};let t;var r=n._A?.location,o={};if(n.il)t=document.createElement("a"),t.href=e;else try{t=new URL(e,r.href)}catch(e){return o}o.port=t.port;var a=t.href.split("://");!o.port&&a[1]&&(o.port=a[1].split("/")[0].split("@").pop().split(":")[1]),o.port&&"0"!==o.port||(o.port="https"===a[0]?"443":"80"),o.hostname=t.hostname||r.hostname,o.pathname=t.pathname,o.protocol=a[0],"/"!==o.pathname.charAt(0)&&(o.pathname="/"+o.pathname);var s=!t.protocol||":"===t.protocol||t.protocol===r.protocol,c=t.hostname===r.hostname&&t.port===r.port;return o.sameOrigin=s&&(!t.hostname||c),"/"===o.pathname&&(i[e]=o),o}},50:(e,t,r)=>{function n(e,t){"function"==typeof console.warn&&(console.warn("New Relic: ".concat(e)),t&&console.warn(t))}r.d(t,{Z:()=>n})},2587:(e,t,r)=>{r.d(t,{N:()=>c,T:()=>u});var n=r(2177),i=r(5546),o=r(8e3),a=r(3325);const s={stn:[a.D.sessionTrace],err:[a.D.jserrors,a.D.metrics],ins:[a.D.pageAction],spa:[a.D.spa],sr:[a.D.sessionReplay,a.D.sessionTrace]};function c(e,t){const r=n.ee.get(t);e&&"object"==typeof e&&(Object.entries(e).forEach((e=>{let[t,n]=e;void 0===u[t]&&(s[t]?s[t].forEach((e=>{n?(0,i.p)("feat-"+t,[],void 0,e,r):(0,i.p)("block-"+t,[],void 0,e,r),(0,i.p)("rumresp-"+t,[Boolean(n)],void 0,e,r)})):n&&(0,i.p)("feat-"+t,[],void 0,void 0,r),u[t]=Boolean(n))})),Object.keys(s).forEach((e=>{void 0===u[e]&&(s[e]?.forEach((t=>(0,i.p)("rumresp-"+e,[!1],void 0,t,r))),u[e]=!1)})),(0,o.L)(t,a.D.pageViewEvent))}const u={}},2210:(e,t,r)=>{r.d(t,{X:()=>i});var n=Object.prototype.hasOwnProperty;function i(e,t,r){if(n.call(e,t))return e[t];var i=r();if(Object.defineProperty&&Object.keys)try{return Object.defineProperty(e,t,{value:i,writable:!0,enumerable:!1}),i}catch(e){}return e[t]=i,i}},1284:(e,t,r)=>{r.d(t,{D:()=>n});const n=(e,t)=>Object.entries(e||{}).map((e=>{let[r,n]=e;return t(r,n)}))},4351:(e,t,r)=>{r.d(t,{P:()=>o});var n=r(2177);const i=()=>{const e=new WeakSet;return(t,r)=>{if("object"==typeof r&&null!==r){if(e.has(r))return;e.add(r)}return r}};function o(e){try{return JSON.stringify(e,i())}catch(e){try{n.ee.emit("internal-error",[e])}catch(e){}}}},3960:(e,t,r)=>{r.d(t,{K:()=>a,b:()=>o});var n=r(3239);function i(){return"undefined"==typeof document||"complete"===document.readyState}function o(e,t){if(i())return e();(0,n.bP)("load",e,t)}function a(e){if(i())return e();(0,n.iz)("DOMContentLoaded",e)}},8632:(e,t,r)=>{r.d(t,{EZ:()=>u,Qy:()=>c,ce:()=>o,fP:()=>a,gG:()=>d,mF:()=>s});var n=r(7894),i=r(385);const o={beacon:"bam.nr-data.net",errorBeacon:"bam.nr-data.net"};function a(){return i._A.NREUM||(i._A.NREUM={}),void 0===i._A.newrelic&&(i._A.newrelic=i._A.NREUM),i._A.NREUM}function s(){let e=a();return e.o||(e.o={ST:i._A.setTimeout,SI:i._A.setImmediate,CT:i._A.clearTimeout,XHR:i._A.XMLHttpRequest,REQ:i._A.Request,EV:i._A.Event,PR:i._A.Promise,MO:i._A.MutationObserver,FETCH:i._A.fetch}),e}function c(e,t,r){let i=a();const o=i.initializedAgents||{},s=o[e]||{};return Object.keys(s).length||(s.initializedAt={ms:(0,n.z)(),date:new Date}),i.initializedAgents={...o,[e]:{...s,[r]:t}},i}function u(e,t){a()[e]=t}function d(){return function(){let e=a();const t=e.info||{};e.info={beacon:o.beacon,errorBeacon:o.errorBeacon,...t}}(),function(){let e=a();const t=e.init||{};e.init={...t}}(),s(),function(){let e=a();const t=e.loader_config||{};e.loader_config={...t}}(),a()}},7956:(e,t,r)=>{r.d(t,{N:()=>i});var n=r(3239);function i(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=arguments.length>2?arguments[2]:void 0,i=arguments.length>3?arguments[3]:void 0;return void(0,n.iz)("visibilitychange",(function(){if(t)return void("hidden"==document.visibilityState&&e());e(document.visibilityState)}),r,i)}},1214:(e,t,r)=>{r.d(t,{em:()=>v,u5:()=>N,QU:()=>S,_L:()=>I,Gm:()=>L,Lg:()=>M,gy:()=>U,BV:()=>Q,Kf:()=>ee});var n=r(2177);const i="nr@original";var o=Object.prototype.hasOwnProperty,a=!1;function s(e,t){return e||(e=n.ee),r.inPlace=function(e,t,n,i,o){n||(n="");var a,s,c,u="-"===n.charAt(0);for(c=0;c 2?n-2:0),o=2;o {r(A[T],e,w),r(E[T],e,w)})),r(l._A,"fetch",y),t.on(y+"end",(function(e,r){var n=this;if(r){var i=r.headers.get("content-length");null!==i&&(n.rxSize=i),t.emit(y+"done",[null,r],n)}else t.emit(y+"done",[e],n)})),t}const O={},j=["pushState","replaceState"];function S(e){const t=function(e){return(e||n.ee).get("history")}(e);return!l.il||O[t.debugId]++||(O[t.debugId]=1,s(t).inPlace(window.history,j,"-")),t}var P=r(3239);const C={},R=["appendChild","insertBefore","replaceChild"];function I(e){const t=function(e){return(e||n.ee).get("jsonp")}(e);if(!l.il||C[t.debugId])return t;C[t.debugId]=!0;var r=s(t),i=/[?&](?:callback|cb)=([^&#]+)/,o=/(.*)\.([^.]+)/,a=/^(\w+)(\.|$)(.*)$/;function c(e,t){var r=e.match(a),n=r[1],i=r[3];return i?c(i,t[n]):t[n]}return r.inPlace(Node.prototype,R,"dom-"),t.on("dom-start",(function(e){!function(e){if(!e||"string"!=typeof e.nodeName||"script"!==e.nodeName.toLowerCase())return;if("function"!=typeof e.addEventListener)return;var n=(a=e.src,s=a.match(i),s?s[1]:null);var a,s;if(!n)return;var u=function(e){var t=e.match(o);if(t&&t.length>=3)return{key:t[2],parent:c(t[1],window)};return{key:e,parent:window}}(n);if("function"!=typeof u.parent[u.key])return;var d={};function f(){t.emit("jsonp-end",[],d),e.removeEventListener("load",f,(0,P.m$)(!1)),e.removeEventListener("error",l,(0,P.m$)(!1))}function l(){t.emit("jsonp-error",[],d),t.emit("jsonp-end",[],d),e.removeEventListener("load",f,(0,P.m$)(!1)),e.removeEventListener("error",l,(0,P.m$)(!1))}r.inPlace(u.parent,[u.key],"cb-",d),e.addEventListener("load",f,(0,P.m$)(!1)),e.addEventListener("error",l,(0,P.m$)(!1)),t.emit("new-jsonp",[e.src],d)}(e[0])})),t}var k=r(5763);const H={};function L(e){const t=function(e){return(e||n.ee).get("mutation")}(e);if(!l.il||H[t.debugId])return t;H[t.debugId]=!0;var r=s(t),i=k.Yu.MO;return i&&(window.MutationObserver=function(e){return this instanceof i?new i(r(e,"fn-")):i.apply(this,arguments)},MutationObserver.prototype=i.prototype),t}const z={};function M(e){const t=function(e){return(e||n.ee).get("promise")}(e);if(z[t.debugId])return t;z[t.debugId]=!0;var r=n.c,o=s(t),a=k.Yu.PR;return a&&function(){function e(r){var n=t.context(),i=o(r,"executor-",n,null,!1);const s=Reflect.construct(a,[i],e);return t.context(s).getCtx=function(){return n},s}l._A.Promise=e,Object.defineProperty(e,"name",{value:"Promise"}),e.toString=function(){return a.toString()},Object.setPrototypeOf(e,a),["all","race"].forEach((function(r){const n=a[r];e[r]=function(e){let i=!1;[...e||[]].forEach((e=>{this.resolve(e).then(a("all"===r),a(!1))}));const o=n.apply(this,arguments);return o;function a(e){return function(){t.emit("propagate",[null,!i],o,!1,!1),i=i||!e}}}})),["resolve","reject"].forEach((function(r){const n=a[r];e[r]=function(e){const r=n.apply(this,arguments);return e!==r&&t.emit("propagate",[e,!0],r,!1,!1),r}})),e.prototype=a.prototype;const n=a.prototype.then;a.prototype.then=function(){var e=this,i=r(e);i.promise=e;for(var a=arguments.length,s=new Array(a),c=0;c e())),t};function m(e,t){i.inPlace(t,["onreadystatechange"],"fn-",E)}function b(){var e=this,t=r.context(e);e.readyState>3&&!t.resolved&&(t.resolved=!0,r.emit("xhr-resolved",[],e)),i.inPlace(e,f,"fn-",E)}if(function(e,t){for(var r in e)t[r]=e[r]}(o,p),p.prototype=o.prototype,i.inPlace(p.prototype,J,"-xhr-",E),r.on("send-xhr-start",(function(e,t){m(e,t),function(e){h.push(e),a&&(y?y.then(A):u?u(A):(w=-w,x.data=w))}(t)})),r.on("open-xhr-start",m),a){var y=c&&c.resolve();if(!u&&!c){var w=1,x=document.createTextNode(w);new a(A).observe(x,{characterData:!0})}}else t.on("fn-end",(function(e){e[0]&&e[0].type===d||A()}));function A(){for(var e=0;e {r.d(t,{t:()=>n});const n=r(3325).D.ajax},6660:(e,t,r)=>{r.d(t,{A:()=>i,t:()=>n});const n=r(3325).D.jserrors,i="nr@seenError"},3081:(e,t,r)=>{r.d(t,{gF:()=>o,mY:()=>i,t9:()=>n,vz:()=>s,xS:()=>a});const n=r(3325).D.metrics,i="sm",o="cm",a="storeSupportabilityMetrics",s="storeEventMetrics"},4649:(e,t,r)=>{r.d(t,{t:()=>n});const n=r(3325).D.pageAction},7633:(e,t,r)=>{r.d(t,{Dz:()=>i,OJ:()=>a,qw:()=>o,t9:()=>n});const n=r(3325).D.pageViewEvent,i="firstbyte",o="domcontent",a="windowload"},9251:(e,t,r)=>{r.d(t,{t:()=>n});const n=r(3325).D.pageViewTiming},3614:(e,t,r)=>{r.d(t,{BST_RESOURCE:()=>i,END:()=>s,FEATURE_NAME:()=>n,FN_END:()=>u,FN_START:()=>c,PUSH_STATE:()=>d,RESOURCE:()=>o,START:()=>a});const n=r(3325).D.sessionTrace,i="bstResource",o="resource",a="-start",s="-end",c="fn"+a,u="fn"+s,d="pushState"},7836:(e,t,r)=>{r.d(t,{BODY:()=>A,CB_END:()=>E,CB_START:()=>u,END:()=>x,FEATURE_NAME:()=>i,FETCH:()=>_,FETCH_BODY:()=>v,FETCH_DONE:()=>m,FETCH_START:()=>p,FN_END:()=>c,FN_START:()=>s,INTERACTION:()=>l,INTERACTION_API:()=>d,INTERACTION_EVENTS:()=>o,JSONP_END:()=>b,JSONP_NODE:()=>g,JS_TIME:()=>T,MAX_TIMER_BUDGET:()=>a,REMAINING:()=>f,SPA_NODE:()=>h,START:()=>w,originalSetTimeout:()=>y});var n=r(5763);const i=r(3325).D.spa,o=["click","submit","keypress","keydown","keyup","change"],a=999,s="fn-start",c="fn-end",u="cb-start",d="api-ixn-",f="remaining",l="interaction",h="spaNode",g="jsonpNode",p="fetch-start",m="fetch-done",v="fetch-body-",b="jsonp-end",y=n.Yu.ST,w="-start",x="-end",A="-body",E="cb"+x,T="jsTime",_="fetch"},5938:(e,t,r)=>{r.d(t,{W:()=>o});var n=r(5763),i=r(2177);class o{constructor(e,t,r){this.agentIdentifier=e,this.aggregator=t,this.ee=i.ee.get(e,(0,n.OP)(this.agentIdentifier).isolatedBacklog),this.featureName=r,this.blocked=!1}}},9144:(e,t,r)=>{r.d(t,{j:()=>m});var n=r(3325),i=r(5763),o=r(5546),a=r(2177),s=r(7894),c=r(8e3),u=r(3960),d=r(385),f=r(50),l=r(3081),h=r(8632);function g(){const e=(0,h.gG)();["setErrorHandler","finished","addToTrace","inlineHit","addRelease","addPageAction","setCurrentRouteName","setPageViewName","setCustomAttribute","interaction","noticeError","setUserId"].forEach((t=>{e[t]=function(){for(var r=arguments.length,n=new Array(r),i=0;i 1?r-1:0),i=1;i {e.exposed&&e.api[t]&&o.push(e.api[t](...n))})),o.length>1?o:o[0]}(t,...n)}}))}var p=r(2587);function m(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},m=arguments.length>2?arguments[2]:void 0,v=arguments.length>3?arguments[3]:void 0,{init:b,info:y,loader_config:w,runtime:x={loaderType:m},exposed:A=!0}=t;const E=(0,h.gG)();y||(b=E.init,y=E.info,w=E.loader_config),(0,i.Dg)(e,b||{}),(0,i.GE)(e,w||{}),(0,i.sU)(e,x),y.jsAttributes??={},d.v6&&(y.jsAttributes.isWorker=!0),(0,i.CX)(e,y),g();const T=function(e,t){t||(0,c.R)(e,"api");const h={};var g=a.ee.get(e),p=g.get("tracer"),m="api-",v=m+"ixn-";function b(t,r,n,o){const a=(0,i.C5)(e);return null===r?delete a.jsAttributes[t]:(0,i.CX)(e,{...a,jsAttributes:{...a.jsAttributes,[t]:r}}),x(m,n,!0,o||null===r?"session":void 0)(t,r)}function y(){}["setErrorHandler","finished","addToTrace","inlineHit","addRelease"].forEach((e=>h[e]=x(m,e,!0,"api"))),h.addPageAction=x(m,"addPageAction",!0,n.D.pageAction),h.setCurrentRouteName=x(m,"routeName",!0,n.D.spa),h.setPageViewName=function(t,r){if("string"==typeof t)return"/"!==t.charAt(0)&&(t="/"+t),(0,i.OP)(e).customTransaction=(r||"http://custom.transaction")+t,x(m,"setPageViewName",!0)()},h.setCustomAttribute=function(e,t){let r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if("string"==typeof e){if(["string","number"].includes(typeof t)||null===t)return b(e,t,"setCustomAttribute",r);(0,f.Z)("Failed to execute setCustomAttribute.\nNon-null value must be a string or number type, but a type of was provided."))}else(0,f.Z)("Failed to execute setCustomAttribute.\nName must be a string type, but a type of was provided."))},h.setUserId=function(e){if("string"==typeof e||null===e)return b("enduser.id",e,"setUserId",!0);(0,f.Z)("Failed to execute setUserId.\nNon-null value must be a string type, but a type of was provided."))},h.interaction=function(){return(new y).get()};var w=y.prototype={createTracer:function(e,t){var r={},i=this,a="function"==typeof t;return(0,o.p)(v+"tracer",[(0,s.z)(),e,r],i,n.D.spa,g),function(){if(p.emit((a?"":"no-")+"fn-start",[(0,s.z)(),i,a],r),a)try{return t.apply(this,arguments)}catch(e){throw p.emit("fn-err",[arguments,this,"string"==typeof e?new Error(e):e],r),e}finally{p.emit("fn-end",[(0,s.z)()],r)}}}};function x(e,t,r,i){return function(){return(0,o.p)(l.xS,["API/"+t+"/called"],void 0,n.D.metrics,g),i&&(0,o.p)(e+t,[(0,s.z)(),...arguments],r?null:this,i,g),r?void 0:this}}function A(){r.e(439).then(r.bind(r,7438)).then((t=>{let{setAPI:r}=t;r(e),(0,c.L)(e,"api")})).catch((()=>(0,f.Z)("Downloading runtime APIs failed...")))}return["actionText","setName","setAttribute","save","ignore","onEnd","getContext","end","get"].forEach((e=>{w[e]=x(v,e,void 0,n.D.spa)})),h.noticeError=function(e,t){"string"==typeof e&&(e=new Error(e)),(0,o.p)(l.xS,["API/noticeError/called"],void 0,n.D.metrics,g),(0,o.p)("err",[e,(0,s.z)(),!1,t],void 0,n.D.jserrors,g)},d.il?(0,u.b)((()=>A()),!0):A(),h}(e,v);return(0,h.Qy)(e,T,"api"),(0,h.Qy)(e,A,"exposed"),(0,h.EZ)("activatedFeatures",p.T),T}},3325:(e,t,r)=>{r.d(t,{D:()=>n,p:()=>i});const n={ajax:"ajax",jserrors:"jserrors",metrics:"metrics",pageAction:"page_action",pageViewEvent:"page_view_event",pageViewTiming:"page_view_timing",sessionReplay:"session_replay",sessionTrace:"session_trace",spa:"spa"},i={[n.pageViewEvent]:1,[n.pageViewTiming]:2,[n.metrics]:3,[n.jserrors]:4,[n.ajax]:5,[n.sessionTrace]:6,[n.pageAction]:7,[n.spa]:8,[n.sessionReplay]:9}}},n={};function i(e){var t=n[e];if(void 0!==t)return t.exports;var o=n[e]={exports:{}};return r[e](o,o.exports,i),o.exports}i.m=r,i.d=(e,t)=>{for(var r in t)i.o(t,r)&&!i.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},i.f={},i.e=e=>Promise.all(Object.keys(i.f).reduce(((t,r)=>(i.f[r](e,t),t)),[])),i.u=e=>(({78:"page_action-aggregate",147:"metrics-aggregate",242:"session-manager",317:"jserrors-aggregate",348:"page_view_timing-aggregate",412:"lazy-feature-loader",439:"async-api",538:"recorder",590:"session_replay-aggregate",675:"compressor",733:"session_trace-aggregate",786:"page_view_event-aggregate",873:"spa-aggregate",898:"ajax-aggregate"}[e]||e)+"."+{78:"ac76d497",147:"3dc53903",148:"1a20d5fe",242:"2a64278a",317:"49e41428",348:"bd6de33a",412:"2f55ce66",439:"30bd804e",538:"1b18459f",590:"cf0efb30",675:"ae9f91a8",733:"83105561",786:"06482edd",860:"03a8b7a5",873:"e6b09d52",898:"998ef92b"}[e]+"-1.236.0.min.js"),i.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="NRBA:",i.l=(r,n,o,a)=>{if(e[r])e[r].push(n);else{var s,c;if(void 0!==o)for(var u=document.getElementsByTagName("script"),d=0;d {s.onerror=s.onload=null,clearTimeout(h);var i=e[r];if(delete e[r],s.parentNode&&s.parentNode.removeChild(s),i&&i.forEach((e=>e(n))),t)return t(n)},h=setTimeout(l.bind(null,void 0,{type:"timeout",target:s}),12e4);s.onerror=l.bind(null,s.onerror),s.onload=l.bind(null,s.onload),c&&document.head.appendChild(s)}},i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.j=364,i.p="https://js-agent.newrelic.com/",(()=>{var e={364:0,953:0};i.f.j=(t,r)=>{var n=i.o(e,t)?e[t]:void 0;if(0!==n)if(n)r.push(n[2]);else{var o=new Promise(((r,i)=>n=e[t]=[r,i]));r.push(n[2]=o);var a=i.p+i.u(t),s=new Error;i.l(a,(r=>{if(i.o(e,t)&&(0!==(n=e[t])&&(e[t]=void 0),n)){var o=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;s.message="Loading chunk "+t+" failed.\n("+o+": "+a+")",s.name="ChunkLoadError",s.type=o,s.request=a,n[1](s)}}),"chunk-"+t,t)}};var t=(t,r)=>{var n,o,[a,s,c]=r,u=0;if(a.some((t=>0!==e[t]))){for(n in s)i.o(s,n)&&(i.m[n]=s[n]);if(c)c(i)}for(t&&t(r);u {i.r(o);var e=i(3325),t=i(5763);const r=Object.values(e.D);function n(e){const n={};return r.forEach((r=>{n[r]=function(e,r){return!1!==(0,t.Mt)(r,"".concat(e,".enabled"))}(r,e)})),n}var a=i(9144);var s=i(5546),c=i(385),u=i(8e3),d=i(5938),f=i(3960),l=i(50);class h extends d.W{constructor(e,t,r){let n=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];super(e,t,r),this.auto=n,this.abortHandler,this.featAggregate,this.onAggregateImported,n&&(0,u.R)(e,r)}importAggregator(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(this.featAggregate||!this.auto)return;const r=c.il&&!0===(0,t.Mt)(this.agentIdentifier,"privacy.cookies_enabled");let n;this.onAggregateImported=new Promise((e=>{n=e}));const o=async()=>{let t;try{if(r){const{setupAgentSession:e}=await Promise.all([i.e(860),i.e(242)]).then(i.bind(i,3228));t=e(this.agentIdentifier)}}catch(e){(0,l.Z)("A problem occurred when starting up session manager. This page will not start or extend any session.",e)}try{if(!this.shouldImportAgg(this.featureName,t))return void(0,u.L)(this.agentIdentifier,this.featureName);const{lazyFeatureLoader:r}=await i.e(412).then(i.bind(i,8582)),{Aggregate:o}=await r(this.featureName,"aggregate");this.featAggregate=new o(this.agentIdentifier,this.aggregator,e),n(!0)}catch(e){(0,l.Z)("Downloading and initializing ".concat(this.featureName," failed..."),e),this.abortHandler?.(),n(!1)}};c.il?(0,f.b)((()=>o()),!0):o()}shouldImportAgg(r,n){return r!==e.D.sessionReplay||!1!==(0,t.Mt)(this.agentIdentifier,"session_trace.enabled")&&(!!n?.isNew||!!n?.state.sessionReplay)}}var g=i(7633),p=i(7894);class m extends h{static featureName=g.t9;constructor(r,n){let i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(super(r,n,g.t9,i),("undefined"==typeof PerformanceNavigationTiming||c.Tt)&&"undefined"!=typeof PerformanceTiming){const n=(0,t.OP)(r);n[g.Dz]=Math.max(Date.now()-n.offset,0),(0,f.K)((()=>n[g.qw]=Math.max((0,p.z)()-n[g.Dz],0))),(0,f.b)((()=>{const t=(0,p.z)();n[g.OJ]=Math.max(t-n[g.Dz],0),(0,s.p)("timing",["load",t],void 0,e.D.pageViewTiming,this.ee)}))}this.importAggregator()}}var v=i(1117),b=i(1284);class y extends v.w{constructor(e){super(e),this.aggregatedData={}}store(e,t,r,n,i){var o=this.getBucket(e,t,r,i);return o.metrics=function(e,t){t||(t={count:0});return t.count+=1,(0,b.D)(e,(function(e,r){t[e]=w(r,t[e])})),t}(n,o.metrics),o}merge(e,t,r,n,i){var o=this.getBucket(e,t,n,i);if(o.metrics){var a=o.metrics;a.count+=r.count,(0,b.D)(r,(function(e,t){if("count"!==e){var n=a[e],i=r[e];i&&!i.c?a[e]=w(i.t,n):a[e]=function(e,t){if(!t)return e;t.c||(t=x(t.t));return t.min=Math.min(e.min,t.min),t.max=Math.max(e.max,t.max),t.t+=e.t,t.sos+=e.sos,t.c+=e.c,t}(i,a[e])}}))}else o.metrics=r}storeMetric(e,t,r,n){var i=this.getBucket(e,t,r);return i.stats=w(n,i.stats),i}getBucket(e,t,r,n){this.aggregatedData[e]||(this.aggregatedData[e]={});var i=this.aggregatedData[e][t];return i||(i=this.aggregatedData[e][t]={params:r||{}},n&&(i.custom=n)),i}get(e,t){return t?this.aggregatedData[e]&&this.aggregatedData[e][t]:this.aggregatedData[e]}take(e){for(var t={},r="",n=!1,i=0;i t.max&&(t.max=e),e 2&&void 0!==arguments[2])||arguments[2];super(e,r,j.t,n),c.il&&((0,t.OP)(e).initHidden=Boolean("hidden"===document.visibilityState),(0,N.N)((()=>(0,s.p)("docHidden",[(0,p.z)()],void 0,j.t,this.ee)),!0),(0,O.bP)("pagehide",(()=>(0,s.p)("winPagehide",[(0,p.z)()],void 0,j.t,this.ee))),this.importAggregator())}}var P=i(3081);class C extends h{static featureName=P.t9;constructor(e,t){let r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];super(e,t,P.t9,r),this.importAggregator()}}var R,I=i(2210),k=i(1214),H=i(2177),L={};try{R=localStorage.getItem("__nr_flags").split(","),console&&"function"==typeof console.log&&(L.console=!0,-1!==R.indexOf("dev")&&(L.dev=!0),-1!==R.indexOf("nr_dev")&&(L.nrDev=!0))}catch(e){}function z(e){try{L.console&&z(e)}catch(e){}}L.nrDev&&H.ee.on("internal-error",(function(e){z(e.stack)})),L.dev&&H.ee.on("fn-err",(function(e,t,r){z(r.stack)})),L.dev&&(z("NR AGENT IN DEVELOPMENT MODE"),z("flags: "+(0,b.D)(L,(function(e,t){return e})).join(", ")));var M=i(6660);class B extends h{static featureName=M.t;constructor(r,n){let i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];super(r,n,M.t,i),this.skipNext=0;try{this.removeOnAbort=new AbortController}catch(e){}const o=this;o.ee.on("fn-start",(function(e,t,r){o.abortHandler&&(o.skipNext+=1)})),o.ee.on("fn-err",(function(t,r,n){o.abortHandler&&!n[M.A]&&((0,I.X)(n,M.A,(function(){return!0})),this.thrown=!0,(0,s.p)("err",[n,(0,p.z)()],void 0,e.D.jserrors,o.ee))})),o.ee.on("fn-end",(function(){o.abortHandler&&!this.thrown&&o.skipNext>0&&(o.skipNext-=1)})),o.ee.on("internal-error",(function(t){(0,s.p)("ierr",[t,(0,p.z)(),!0],void 0,e.D.jserrors,o.ee)})),this.origOnerror=c._A.onerror,c._A.onerror=this.onerrorHandler.bind(this),c._A.addEventListener("unhandledrejection",(t=>{const r=function(e){let t="Unhandled Promise Rejection: ";if(e instanceof Error)try{return e.message=t+e.message,e}catch(t){return e}if(void 0===e)return new Error(t);try{return new Error(t+(0,D.P)(e))}catch(e){return new Error(t)}}(t.reason);(0,s.p)("err",[r,(0,p.z)(),!1,{unhandledPromiseRejection:1}],void 0,e.D.jserrors,this.ee)}),(0,O.m$)(!1,this.removeOnAbort?.signal)),(0,k.gy)(this.ee),(0,k.BV)(this.ee),(0,k.em)(this.ee),(0,t.OP)(r).xhrWrappable&&(0,k.Kf)(this.ee),this.abortHandler=this.#e,this.importAggregator()}#e(){this.removeOnAbort?.abort(),this.abortHandler=void 0}onerrorHandler(t,r,n,i,o){"function"==typeof this.origOnerror&&this.origOnerror(...arguments);try{this.skipNext?this.skipNext-=1:(0,s.p)("err",[o||new F(t,r,n),(0,p.z)()],void 0,e.D.jserrors,this.ee)}catch(t){try{(0,s.p)("ierr",[t,(0,p.z)(),!0],void 0,e.D.jserrors,this.ee)}catch(e){}}return!1}}function F(e,t,r){this.message=e||"Uncaught error with no additional information",this.sourceURL=t,this.line=r}let U=1;const q="nr@id";function G(e){const t=typeof e;return!e||"object"!==t&&"function"!==t?-1:e===c._A?0:(0,I.X)(e,q,(function(){return U++}))}function V(e){if("string"==typeof e&&e.length)return e.length;if("object"==typeof e){if("undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer&&e.byteLength)return e.byteLength;if("undefined"!=typeof Blob&&e instanceof Blob&&e.size)return e.size;if(!("undefined"!=typeof FormData&&e instanceof FormData))try{return(0,D.P)(e).length}catch(e){return}}}var X=i(7243);class W{constructor(e){this.agentIdentifier=e,this.generateTracePayload=this.generateTracePayload.bind(this),this.shouldGenerateTrace=this.shouldGenerateTrace.bind(this)}generateTracePayload(e){if(!this.shouldGenerateTrace(e))return null;var r=(0,t.DL)(this.agentIdentifier);if(!r)return null;var n=(r.accountID||"").toString()||null,i=(r.agentID||"").toString()||null,o=(r.trustKey||"").toString()||null;if(!n||!i)return null;var a=(0,_.M)(),s=(0,_.Ht)(),c=Date.now(),u={spanId:a,traceId:s,timestamp:c};return(e.sameOrigin||this.isAllowedOrigin(e)&&this.useTraceContextHeadersForCors())&&(u.traceContextParentHeader=this.generateTraceContextParentHeader(a,s),u.traceContextStateHeader=this.generateTraceContextStateHeader(a,c,n,i,o)),(e.sameOrigin&&!this.excludeNewrelicHeader()||!e.sameOrigin&&this.isAllowedOrigin(e)&&this.useNewrelicHeaderForCors())&&(u.newrelicHeader=this.generateTraceHeader(a,s,c,n,i,o)),u}generateTraceContextParentHeader(e,t){return"00-"+t+"-"+e+"-01"}generateTraceContextStateHeader(e,t,r,n,i){return i+"@nr=0-1-"+r+"-"+n+"-"+e+"----"+t}generateTraceHeader(e,t,r,n,i,o){if(!("function"==typeof c._A?.btoa))return null;var a={v:[0,1],d:{ty:"Browser",ac:n,ap:i,id:e,tr:t,ti:r}};return o&&n!==o&&(a.d.tk=o),btoa((0,D.P)(a))}shouldGenerateTrace(e){return this.isDtEnabled()&&this.isAllowedOrigin(e)}isAllowedOrigin(e){var r=!1,n={};if((0,t.Mt)(this.agentIdentifier,"distributed_tracing")&&(n=(0,t.P_)(this.agentIdentifier).distributed_tracing),e.sameOrigin)r=!0;else if(n.allowed_origins instanceof Array)for(var i=0;i 2&&void 0!==arguments[2])||arguments[2];super(r,n,Z.t,i),(0,t.OP)(r).xhrWrappable&&(this.dt=new W(r),this.handler=(e,t,r,n)=>(0,s.p)(e,t,r,n,this.ee),(0,k.u5)(this.ee),(0,k.Kf)(this.ee),function(r,n,i,o){function a(e){var t=this;t.totalCbs=0,t.called=0,t.cbTime=0,t.end=E,t.ended=!1,t.xhrGuids={},t.lastSize=null,t.loadCaptureCalled=!1,t.params=this.params||{},t.metrics=this.metrics||{},e.addEventListener("load",(function(r){_(t,e)}),(0,O.m$)(!1)),c.IF||e.addEventListener("progress",(function(e){t.lastSize=e.loaded}),(0,O.m$)(!1))}function s(e){this.params={method:e[0]},T(this,e[1]),this.metrics={}}function u(e,n){var i=(0,t.DL)(r);i.xpid&&this.sameOrigin&&n.setRequestHeader("X-NewRelic-ID",i.xpid);var a=o.generateTracePayload(this.parsedOrigin);if(a){var s=!1;a.newrelicHeader&&(n.setRequestHeader("newrelic",a.newrelicHeader),s=!0),a.traceContextParentHeader&&(n.setRequestHeader("traceparent",a.traceContextParentHeader),a.traceContextStateHeader&&n.setRequestHeader("tracestate",a.traceContextStateHeader),s=!0),s&&(this.dt=a)}}function d(e,t){var r=this.metrics,i=e[0],o=this;if(r&&i){var a=V(i);a&&(r.txSize=a)}this.startTime=(0,p.z)(),this.listener=function(e){try{"abort"!==e.type||o.loadCaptureCalled||(o.params.aborted=!0),("load"!==e.type||o.called===o.totalCbs&&(o.onloadCalled||"function"!=typeof t.onload)&&"function"==typeof o.end)&&o.end(t)}catch(e){try{n.emit("internal-error",[e])}catch(e){}}};for(var s=0;s 1?e[1]=i:e.push(i)}else e[0]&&e[0].headers&&s(e[0].headers,n)&&(this.dt=n);function s(e,t){var r=!1;return t.newrelicHeader&&(e.set("newrelic",t.newrelicHeader),r=!0),t.traceContextParentHeader&&(e.set("traceparent",t.traceContextParentHeader),t.traceContextStateHeader&&e.set("tracestate",t.traceContextStateHeader),r=!0),r}}function x(e,t){this.params={},this.metrics={},this.startTime=(0,p.z)(),this.dt=t,e.length>=1&&(this.target=e[0]),e.length>=2&&(this.opts=e[1]);var r,n=this.opts||{},i=this.target;"string"==typeof i?r=i:"object"==typeof i&&i instanceof Y?r=i.url:c._A?.URL&&"object"==typeof i&&i instanceof URL&&(r=i.href),T(this,r);var o=(""+(i&&i instanceof Y&&i.method||n.method||"GET")).toUpperCase();this.params.method=o,this.txSize=V(n.body)||0}function A(t,r){var n;this.endTime=(0,p.z)(),this.params||(this.params={}),this.params.status=r?r.status:0,"string"==typeof this.rxSize&&this.rxSize.length>0&&(n=+this.rxSize);var o={txSize:this.txSize,rxSize:n,duration:(0,p.z)()-this.startTime};i("xhr",[this.params,o,this.startTime,this.endTime,"fetch"],this,e.D.ajax)}function E(t){var r=this.params,n=this.metrics;if(!this.ended){this.ended=!0;for(var o=0;o 2&&void 0!==arguments[2])||arguments[2];super(e,t,we.t,r),this.importAggregator()}}new class{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(0,_.ky)(16);c._A?(this.agentIdentifier=t,this.sharedAggregator=new y({agentIdentifier:this.agentIdentifier}),this.features={},this.desiredFeatures=new Set(e.features||[]),this.desiredFeatures.add(m),Object.assign(this,(0,a.j)(this.agentIdentifier,e,e.loaderType||"agent")),this.start()):(0,l.Z)("Failed to initial the agent. Could not determine the runtime environment.")}get config(){return{info:(0,t.C5)(this.agentIdentifier),init:(0,t.P_)(this.agentIdentifier),loader_config:(0,t.DL)(this.agentIdentifier),runtime:(0,t.OP)(this.agentIdentifier)}}start(){const t="features";try{const r=n(this.agentIdentifier),i=[...this.desiredFeatures];i.sort(((t,r)=>e.p[t.featureName]-e.p[r.featureName])),i.forEach((t=>{if(r[t.featureName]||t.featureName===e.D.pageViewEvent){const n=function(t){switch(t){case e.D.ajax:return[e.D.jserrors];case e.D.sessionTrace:return[e.D.ajax,e.D.pageViewEvent];case e.D.sessionReplay:return[e.D.sessionTrace];case e.D.pageViewTiming:return[e.D.pageViewEvent];default:return[]}}(t.featureName);n.every((e=>r[e]))||(0,l.Z)("".concat(t.featureName," is enabled but one or more dependent features has been disabled (").concat((0,D.P)(n),"). This may cause unintended consequences or missing data...")),this.features[t.featureName]=new t(this.agentIdentifier,this.sharedAggregator)}})),(0,T.Qy)(this.agentIdentifier,this.features,t)}catch(e){(0,l.Z)("Failed to initialize all enabled instrument classes (agent aborted) -",e);for(const e in this.features)this.features[e].abortHandler?.();const r=(0,T.fP)();return delete r.initializedAgents[this.agentIdentifier]?.api,delete r.initializedAgents[this.agentIdentifier]?.[t],delete this.sharedAggregator,r.ee?.abort(),delete r.ee?.get(this.agentIdentifier),!1}}}({features:[J,m,S,class extends h{static featureName=oe;constructor(t,r){if(super(t,r,oe,!(arguments.length>2&&void 0!==arguments[2])||arguments[2]),!c.il)return;const n=this.ee;let i;(0,k.QU)(n),this.eventsEE=(0,k.em)(n),this.eventsEE.on(se,(function(e,t){this.bstStart=(0,p.z)()})),this.eventsEE.on(ae,(function(t,r){(0,s.p)("bst",[t[0],r,this.bstStart,(0,p.z)()],void 0,e.D.sessionTrace,n)})),n.on(ce+ne,(function(e){this.time=(0,p.z)(),this.startPath=location.pathname+location.hash})),n.on(ce+ie,(function(t){(0,s.p)("bstHist",[location.pathname+location.hash,this.startPath,this.time],void 0,e.D.sessionTrace,n)}));try{i=new PerformanceObserver((t=>{const r=t.getEntries();(0,s.p)(te,[r],void 0,e.D.sessionTrace,n)})),i.observe({type:re,buffered:!0})}catch(e){}this.importAggregator({resourceObserver:i})}},C,xe,B,class extends h{static featureName=de;constructor(e,r){if(super(e,r,de,!(arguments.length>2&&void 0!==arguments[2])||arguments[2]),!c.il)return;if(!(0,t.OP)(e).xhrWrappable)return;try{this.removeOnAbort=new AbortController}catch(e){}let n,i=0;const o=this.ee.get("tracer"),a=(0,k._L)(this.ee),s=(0,k.Lg)(this.ee),u=(0,k.BV)(this.ee),d=(0,k.Kf)(this.ee),f=this.ee.get("events"),l=(0,k.u5)(this.ee),h=(0,k.QU)(this.ee),g=(0,k.Gm)(this.ee);function m(e,t){h.emit("newURL",[""+window.location,t])}function v(){i++,n=window.location.hash,this[ve]=(0,p.z)()}function b(){i--,window.location.hash!==n&&m(0,!0);var e=(0,p.z)();this[pe]=~~this[pe]+e-this[ve],this[ye]=e}function y(e,t){e.on(t,(function(){this[t]=(0,p.z)()}))}this.ee.on(ve,v),s.on(be,v),a.on(be,v),this.ee.on(ye,b),s.on(ge,b),a.on(ge,b),this.ee.buffer([ve,ye,"xhr-resolved"],this.featureName),f.buffer([ve],this.featureName),u.buffer(["setTimeout"+le,"clearTimeout"+fe,ve],this.featureName),d.buffer([ve,"new-xhr","send-xhr"+fe],this.featureName),l.buffer([me+fe,me+"-done",me+he+fe,me+he+le],this.featureName),h.buffer(["newURL"],this.featureName),g.buffer([ve],this.featureName),s.buffer(["propagate",be,ge,"executor-err","resolve"+fe],this.featureName),o.buffer([ve,"no-"+ve],this.featureName),a.buffer(["new-jsonp","cb-start","jsonp-error","jsonp-end"],this.featureName),y(l,me+fe),y(l,me+"-done"),y(a,"new-jsonp"),y(a,"jsonp-end"),y(a,"cb-start"),h.on("pushState-end",m),h.on("replaceState-end",m),window.addEventListener("hashchange",m,(0,O.m$)(!0,this.removeOnAbort?.signal)),window.addEventListener("load",m,(0,O.m$)(!0,this.removeOnAbort?.signal)),window.addEventListener("popstate",(function(){m(0,i>1)}),(0,O.m$)(!0,this.removeOnAbort?.signal)),this.abortHandler=this.#e,this.importAggregator()}#e(){this.removeOnAbort?.abort(),this.abortHandler=void 0}}],loaderType:"spa"})})(),window.NRBA=o})(); window.jQuery || document.write(' ') CKEDITOR_BASEPATH='https://f1000research.com/js/vendor/ckeditor/' window.reactTheme = 'research'; window.MathJax = { CommonHTML: { linebreaks: { automatic: true } }, 'HTML-CSS': { linebreaks: { automatic: true } }, SVG: { linebreaks: { automatic: true } }, AuthorInit: function() { MathJax.Hub.Register.MessageHook('End Process', function () { let timeout = false; // holder for timeout id const delay = 250; // delay after event is "complete" to run callback const reflowMath = function() { const dispFormulas = document.querySelectorAll('.disp-formula.panel'); if (!dispFormulas) { return; } for (const dispFormula of dispFormulas) { const child = dispFormula.querySelector('.MathJax_Preview').nextSibling.firstChild; const isMultiline = MathJax.Hub.getAllJax(dispFormula)[0].root.isMultiline; if (dispFormula.offsetWidth < child.offsetWidth || isMultiline) { MathJax.Hub.Queue(['Rerender', MathJax.Hub, dispFormula]); } } }; window.addEventListener('resize', function() { clearTimeout(timeout); // clear the timeout timeout = setTimeout(reflowMath, delay); // start timing for event "completion" }); }); }, }; if (window.location.hash == '#_=_'){ window.location = window.location.href.split('#')[0] } !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function() {n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)} ;if(!f._fbq)f._fbq=n; n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window, document,'script','https://connect.facebook.net/en_US/fbevents.js'); fbq('init', '1641728616063202'); fbq('track', "PixelInitialized", {}); (function(h,o,t,j,a,r){ h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)}; h._hjSettings={hjid:2318163,hjsv:6}; a=o.getElementsByTagName('head')[0]; r=o.createElement('script');r.async=1; r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv; a.appendChild(r); })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv='); search file_upload Submit your research search menu close search Browse Gateways & Collections How to Publish Submit your Research My Submissions Article Guidelines Article Guidelines (New Versions) Open Data, Software and Code Guidelines Open Data and Accessible Source Materials Guidelines (HSS) Open Data, Software and Code Guidelines (PSE) Prepublication Checks Production Process Posters and Slides Guidelines Document Guidelines Article Processing Charges Peer Review Finding Article Reviewers About How it Works For Reviewers Our Advisors Policies Glossary FAQs For Developers Newsroom Contact My Research Submissions Content and Tracking Alerts My Details Sign In file_upload Submit your research { "@context": "https://schema.org", "@type": "ScholarlyArticle", "mainEntityOfPage": { "@type": "WebPage", "@id": "https://f1000research.com/articles/15-572" }, "headline": "Medibot AI: a web-based software tool integrating Gemini API for informational over-the-counter medication...", "datePublished": "2026-04-19T01:31:57", "dateModified": "2026-04-19T01:31:57", "author": [ { "@type": "Person", "name": "Piero Llanos-Sánchez" }, { "@type": "Person", "name": "Arianna Espinoza-Franco" }, { "@type": "Person", "name": "Fabián Portuguéz-Villa" }, { "@type": "Person", "name": "Gustavo Fernández-Gutiérrez" }, { "@type": "Person", "name": "Alex Pacheco" } ], "publisher": { "@type": "Organization", "name": "F1000Research", "logo": { "@type": "ImageObject", "url": "https://f1000research.com/img/AMP/F1000Research_image.png", "height": 480, "width": 60 } }, "image": { "@type": "ImageObject", "url": "https://f1000research.com/img/AMP/F1000Research_image.png", "height": 1200, "width": 150 }, "description": "Abstract* Background Self-medication for common illnesses remains widespread and may lead to inappropriate drug selection, incorrect dosage, adverse interactions, and delayed professional care. In this context, artificial intelligence (AI) can provide informational support to promote safer therapeutic decisions. This paper presents Medibot AI, a web-based intelligent system designed to generate informational over-the-counter (OTC) medication recommendations from user-reported symptoms using Google’s Gemini API, with an emphasis on transparency, traceability, and safety warnings. Methods The system was developed iteratively using agile principles and implemented with a three-layer architecture: (i) user interface, (ii) recommendation and validation logic, and (iii) data persistence. The frontend was built using Next.js 18, React 18, and Tailwind CSS 3, while backend services were implemented with Node.js 20 and Prisma ORM 6.8 connected to PostgreSQL 17 (Neon). User inputs are transformed into a structured JSON prompt, and Gemini responses are constrained to return strict JSON outputs. A server-side validation layer verifies both JSON integrity and schema compliance before results are displayed or stored. The system also implements safety-oriented rules that suppress recommendations in high-risk scenarios and generate visible warnings. Results Medibot AI enables users to register, submit symptom descriptions with optional clinical context, obtain structured recommendations with dosage instructions and warnings, and download PDF reports. Functional integration testing confirmed stable data flow across modules and consistent schema-compliant outputs. Conclusions Medibot AI provides a reproducible and auditable approach for AI-assisted OTC medication guidance. While it does not replace clinical diagnosis or professional medical advice, it offers an educational tool that supports more informed and responsible self-medication practices. " } { "@context": "http://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": "1", "item": { "@id": "https://f1000research.com/", "name": "Home" } }, { "@type": "ListItem", "position": "2", "item": { "@id": "https://f1000research.com/browse/articles", "name": "Browse" } }, { "@type": "ListItem", "position": "3", "item": { "@id": "https://f1000research.com/articles/15-572/v1", "name": "Medibot AI: a web-based software tool integrating Gemini API for informational..." } } ] } Home Browse Medibot AI: a web-based software tool integrating Gemini API for informational... ALL Metrics - Views Downloads Get PDF Get XML Cite How to cite this article Llanos-Sánchez P, Espinoza-Franco A, Portuguéz-Villa F et al. Medibot AI: a web-based software tool integrating Gemini API for informational over-the-counter medication guidance [version 1; peer review: awaiting peer review] . F1000Research 2026, 15 :572 ( https://doi.org/10.12688/f1000research.177717.1 ) NOTE: If applicable, it is important to ensure the information in square brackets after the title is included in all citations of this article. Close Copy Citation Details Export Export Citation Sciwheel EndNote Ref. Manager Bibtex ProCite Sente EXPORT Select a format first Track Share ▬ ✚ Software Tool Article Medibot AI: a web-based software tool integrating Gemini API for informational over-the-counter medication guidance [version 1; peer review: awaiting peer review] Piero Llanos-Sánchez 1 , Arianna Espinoza-Franco https://orcid.org/0009-0008-4417-9969 1 , Fabián Portuguéz-Villa https://orcid.org/0009-0006-1646-7045 1 , Gustavo Fernández-Gutiérrez https://orcid.org/0000-0001-8437-5122 1 , Alex Pacheco https://orcid.org/0000-0001-9721-0730 1 Piero Llanos-Sánchez 1 , Arianna Espinoza-Franco https://orcid.org/0009-0008-4417-9969 1 , [...] Fabián Portuguéz-Villa https://orcid.org/0009-0006-1646-7045 1 , Gustavo Fernández-Gutiérrez https://orcid.org/0000-0001-8437-5122 1 , Alex Pacheco https://orcid.org/0000-0001-9721-0730 1 PUBLISHED 19 Apr 2026 Author details Author details 1 Professional School of Systems Engineering, Universidad Nacional de Cañete, San Vicente de Cañete, Lima, 15701, Peru Piero Llanos-Sánchez Roles: Conceptualization, Methodology, Software, Writing – Original Draft Preparation, Writing – Review & Editing Arianna Espinoza-Franco Roles: Conceptualization, Methodology, Software, Writing – Original Draft Preparation, Writing – Review & Editing Fabián Portuguéz-Villa Roles: Conceptualization, Methodology, Software, Writing – Original Draft Preparation, Writing – Review & Editing Gustavo Fernández-Gutiérrez Roles: Conceptualization, Methodology, Writing – Original Draft Preparation, Writing – Review & Editing Alex Pacheco Roles: Conceptualization, Methodology, Writing – Original Draft Preparation, Writing – Review & Editing OPEN PEER REVIEW REVIEWER STATUS AWAITING PEER REVIEW This article is included in the Artificial Intelligence and Machine Learning gateway. Abstract Abstract* Background Self-medication for common illnesses remains widespread and may lead to inappropriate drug selection, incorrect dosage, adverse interactions, and delayed professional care. In this context, artificial intelligence (AI) can provide informational support to promote safer therapeutic decisions. This paper presents Medibot AI, a web-based intelligent system designed to generate informational over-the-counter (OTC) medication recommendations from user-reported symptoms using Google’s Gemini API, with an emphasis on transparency, traceability, and safety warnings. Methods The system was developed iteratively using agile principles and implemented with a three-layer architecture: (i) user interface, (ii) recommendation and validation logic, and (iii) data persistence. The frontend was built using Next.js 18, React 18, and Tailwind CSS 3, while backend services were implemented with Node.js 20 and Prisma ORM 6.8 connected to PostgreSQL 17 (Neon). User inputs are transformed into a structured JSON prompt, and Gemini responses are constrained to return strict JSON outputs. A server-side validation layer verifies both JSON integrity and schema compliance before results are displayed or stored. The system also implements safety-oriented rules that suppress recommendations in high-risk scenarios and generate visible warnings. Results Medibot AI enables users to register, submit symptom descriptions with optional clinical context, obtain structured recommendations with dosage instructions and warnings, and download PDF reports. Functional integration testing confirmed stable data flow across modules and consistent schema-compliant outputs. Conclusions Medibot AI provides a reproducible and auditable approach for AI-assisted OTC medication guidance. While it does not replace clinical diagnosis or professional medical advice, it offers an educational tool that supports more informed and responsible self-medication practices. READ ALL READ LESS Keywords artificial intelligence; OTC medication guidance; Gemini API; digital health; structured prompting; schema validation; Next.js; PostgreSQL Corresponding Author(s) Gustavo Fernández-Gutiérrez ( [email protected] ) Close Corresponding author: Gustavo Fernández-Gutiérrez Competing interests: No competing interests were disclosed. Grant information: This work was funded by the Directorate of Innovation and Technology Transfer of the Vice Presidency for Research at the Universidad Nacional de Cañete (UNDC) as part of the “First Research Competition for the Development of Innovations and Intellectual Property” [contract number 014-2024]. The funders had no role in study design, data collection and analysis, decision to publish, or preparation of the manuscript. Copyright: © 2026 Llanos-Sánchez P et al . This is an open access article distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. How to cite: Llanos-Sánchez P, Espinoza-Franco A, Portuguéz-Villa F et al. Medibot AI: a web-based software tool integrating Gemini API for informational over-the-counter medication guidance [version 1; peer review: awaiting peer review] . F1000Research 2026, 15 :572 ( https://doi.org/10.12688/f1000research.177717.1 ) First published: 19 Apr 2026, 15 :572 ( https://doi.org/10.12688/f1000research.177717.1 ) Latest published: 19 Apr 2026, 15 :572 ( https://doi.org/10.12688/f1000research.177717.1 ) Introduction Artificial intelligence is redefining digital health by enabling applications to interpret natural language, process clinical context, and generate user-tailored guidance. 1 Several studies have combined large language models (LLMs) with medical ontologies to support the identification of pathologies from clinical reports, capturing attributes such as type, severity, and location. 2 Moreover, recent evidence suggests that prompting strategies can improve LLM performance in clinical reasoning tasks, 3 reinforcing their ability to interpret symptom descriptions and produce contextual responses that may support automated medical guidance tools. 1 , 4 These advances are particularly valuable for making pharmaceutical knowledge more accessible to the general population in a responsible manner. Common illnesses—such as influenza-like syndromes, cough, fever, and mild pain—represent a frequent reason for primary care consultation. For example, acute respiratory symptoms (e.g., cough and dyspnea) and upper respiratory infections were reported among the most frequent causes of consultation in a survey of primary care professionals (34.8% of responses). 5 At the same time, self-medication without professional supervision remains widespread and is associated with risks such as incorrect self-diagnosis, inappropriate treatment selection, incorrect dosage, harmful drug interactions, and masking of more serious conditions. 6 , 7 , 8 In this context, intelligent medication guidance systems may serve as informational tools to help users make safer decisions, particularly when dealing with over-the-counter (OTC) medicines. Internationally, systems with similar objectives have been explored. For example, 9 developed a pharmaceutical conversational agent integrated with Micromedex to answer medication-related queries using natural language processing. In Europe, AI-supported clinical reasoning approaches have been studied to analyze pharmacological emergency data and support treatment decision-making. 10 In the Netherlands, intelligent systems have been shown to optimize medication alerts and recognize drug interactions using AI. 11 Similarly, research in Egypt has reported advances in predicting drug interactions using deep learning models. 12 However, many of these systems rely on complex infrastructures, closed models, or limited customization based on user profiles. In Latin America, the development of AI-assisted pharmacological tools remains at an early stage. Regional analyses indicate that AI health projects are fragmented, experimental, and often limited to isolated applications rather than integrated solutions. 13 In Colombia, for example, 14 conducted a bibliometric review showing that health chatbots are expanding—especially in mental health and medical education—while highlighting the need for stronger scientific justification prior to large-scale deployment. Overall, few systems in the region integrate open and modular architectures that enable personalization based on user context, which can limit scalability in academic and low-resource settings. In Peru, digital health has progressed in areas such as telemedicine and the adoption of information technologies for health services. Teleconsultation services expanded during the COVID-19 pandemic to improve access in areas with limited in-person coverage. 15 Nevertheless, institutional, regulatory, and structural challenges continue to hinder the full adoption of digital health solutions. 16 , 17 Despite this progress, initiatives specifically focused on AI-assisted OTC medication guidance appear to remain limited. Although the present development was implemented in Peru, its modular web-based design makes it potentially applicable in other contexts with similar needs. To address this gap, we propose an Intelligent System for the Recommendation of Medicines for Common Diseases using the Gemini API. This work focuses on the design and architecture of a web-based system rather than a clinical pilot implementation. The system processes user-reported symptoms and contextual information (e.g., age, allergies, and pre-existing conditions) and generates informational OTC medication recommendations and safety warnings using Google’s Gemini API. The system is intended for informational and educational purposes only and does not provide medical diagnosis or replace professional medical advice. Users are encouraged to consult a qualified healthcare professional, particularly when symptoms are severe, persistent, or unclear. The proposed system emphasizes transparency, adaptability, and ethical design by incorporating strict structured prompting, server-side JSON/schema validation, and safety rules that suppress recommendations in high-risk scenarios. The main contributions of this work are: (i) a modular web-based architecture for symptom-driven OTC medication guidance, (ii) structured prompt engineering with schema-constrained JSON outputs for reproducibility, and (iii) safety-oriented warning generation and risk-based recommendation suppression. Methods In this section, we describe the methods used for the design, implementation, and operation of the Intelligent System for the Recommendation of Medicines for Common Diseases. The system is a web-based application that collects patient-reported symptoms and basic clinical context (e.g., age, sex, allergies, and pre-existing conditions), structures this information into a standardized JSON prompt, and uses the Gemini API to generate informational drug recommendations and safety warnings. The output is validated server-side and can be stored for traceability and future analysis. Implementation Technologies and library integration The system was developed using a modular and scalable architecture. The frontend was implemented with Next.js 18 and React 18, enabling hybrid SSR/CSR rendering for responsive interaction and improved performance. Tailwind CSS 3 was used to implement a responsive user interface, while ShadCN/UI provided accessible and consistent UI components. The backend logic was implemented using Next.js API routes running on Node.js 20. Data persistence was implemented with PostgreSQL 17 as the relational database management system, accessed through Prisma ORM 6.8. Input validation and response verification were implemented using Zod 3.25, ensuring strict data integrity at each stage of the workflow. Communication with the Gemini API and internal services was performed using Fetch for asynchronous HTTP requests. A singleton Prisma Client instance was used to prevent connection exhaustion in serverless deployments. Deployment and file generation The system was deployed using Vercel (application hosting, optimized for Next.js serverless environments) and Neon (PostgreSQL database-as-a-service), enabling scalability and high availability. The system also supports automatic generation of downloadable PDF reports containing the generated recommendations and safety warnings using jsPDF 3.0.2. Figure 1 presents the general system architecture, showing the interaction between the user interface, backend services, database layer, Gemini API, and PDF generation module. Figure 1. Diagram of the architecture of the intelligent system for drug recommendations. Source: Own elaboration. Note: Representation of the flow between the main modules (frontend, backend, database, Gemini API, and jsPDF), from symptom entry to recommendation download by the user. System design and development workflow The system was implemented iteratively using agile principles to ensure stability of the data flow and progressive validation of each module. The development workflow followed an incremental approach inspired by the five-stage model proposed by Ramos-Miller and Pacheco 18 (analysis, planning, implementation, review, and deployment), adapted to the requirements of a modular AI-based clinical recommendation system. The process focused on: (i) defining the architecture and security model, (ii) implementing the Gemini API integration, (iii) implementing structured persistence in PostgreSQL, (iv) implementing safety rules and warnings, and (v) validating the end-to-end integration through functional testing. Database schema and persistence strategy The system uses PostgreSQL 17 to store user and interaction data. The relational model is structured to preserve traceability between patient data, symptom evaluations, and generated recommendations, as shown in Figure 2 . Figure 2. Relational model of the drug recommendation system. Source: Own elaboration. Note: The diagram illustrates the relationships between User, Patient, Evaluation, Recommendation, and MedicationRecommendation, supporting end-to-end traceability of each interaction. The main entities include: • Users: Stores account data (name, email, role). • Patients: Stores identification type, identification number, and full name. • Evaluations: Stores structured symptom and context information (symptoms, allergies, pre-existing conditions, severity, duration, and optional clinical fields). • Recommendations: Stores the overall model response (reason field and metadata). • MedicationRecommendation: Stores each recommended medication entry with dosage and warnings. To ensure data consistency, patients are created or updated using an upsert strategy based on identification number. Each system interaction generates a new evaluation record. Recommendations and medication entries are only stored if the AI output is valid and successfully validated against the expected schema. If either the form validation or AI response validation fails, no recommendation is persisted. User interface and processing flow The application provides an accessible interface where users enter symptoms in natural language and optionally provide additional context such as age, sex, weight, allergies, pregnancy status, symptom duration, severity, and current medication. The processing flow is summarized below: 1. Symptom input: The user enters free-text symptoms (e.g., “I have a very itchy throat and a dry cough”). 2. Prompt structuring: The system converts the input into a standardized JSON object. 3. AI processing: The structured JSON prompt is sent to the Gemini API, which returns a structured JSON response containing recommendations and warnings. 4. Server-side validation: The response is parsed as JSON and validated against the expected schema. Invalid responses are rejected and are not stored. 5. Presentation of results: The system displays an interactive panel with recommendations, instructions, and safety warnings, including reminders such as “Consult a specialist if symptoms persist.” 6. Persistence: Valid evaluations and recommendations are stored in PostgreSQL. 7. Export: The user can generate and download a PDF report of the results. Figure 3 illustrates the general workflow from data entry to recommendation generation and presentation. Figure 3. General flow of the intelligent drug recommendation system. Source: Own elaboration. Note: Outline of the main stages: data entry, AI processing, and presentation of results. Prompt Structuring To ensure consistency and machine-readability, the system generates a structured instruction that is sent to the Gemini API. The instruction is designed to reduce ambiguity by avoiding ranges or approximate values. The structured input is built using user-provided fields such as age, sex, symptoms, allergies, pre-existing conditions, current medication, symptom duration, and severity. The instruction embeds explicit safety constraints to prevent recommendations in high-risk scenarios (e.g., pregnancy with insufficient context, pediatric cases without weight, severe symptoms or red-flag conditions, relevant allergies, potential drug interactions, or decompensated chronic disease). In such cases, the system returns an empty recommendations list ( recommendations: [] ) and provides an explanatory reason field. The Gemini API is instructed to return only a strict JSON object following the schema below: { "recommendations" : [ { "medication" : "string" , "form" : "string" , "via" : "string" , "amount_value" : number , "amount_unit" : "string" , "every_hour" : number , "duration_days" : number , "moment" : "string" , "instructions" : "string" , "warnings" : [ "string" ] } ], "reason" : "string|null" } AI generation configuration and response validation To minimize variability and improve reproducibility, the system uses a fixed generation configuration when calling the Gemini API (model: gemini-2.5-flash-lite). The request is sent to the generateContent endpoint using structured prompts and is configured with temperature = 0.2 and maxOutputTokens = 768. To reduce malformed outputs, the system explicitly requests JSON output using responseMimeType = ‘application/json’ and constrains the response using a predefined schema (responseSchema). After receiving the response, the system performs server-side validation in two steps: 1. JSON validation: the response must be valid JSON; otherwise, it is rejected. 2. Schema validation: the JSON structure must match the expected schema; otherwise, it is rejected. Only validated responses are displayed to the user and stored in the database. This validation ensures that only well-formed and schema-compliant outputs are persisted, improving traceability and reducing the risk of unsafe or malformed recommendations. Safety rules and warning generation The system implements safety rules to reduce harmful or misleading outputs. The system applies rule-based safety checks to identify contraindication patterns, high-severity symptom indicators, and potentially unsafe combinations. When triggered, the interface displays prominent warnings and the system may suppress medication recommendations by returning an empty list. Additionally, the system enforces strict output formatting (JSON-only responses) and applies internal validation rules to ensure that generated recommendations remain consistent and clinically cautious. System testing and validation To verify correct system behavior and ensure the reliability of AI-generated outputs, Medibot AI was evaluated through functional and integration testing across its main modules: (i) user interface, (ii) recommendation and validation logic, and (iii) data persistence. The testing strategy focused on validating end-to-end execution, schema compliance, and safety-oriented behavior rather than clinical effectiveness. A set of synthetic test scenarios was designed to cover typical use cases and edge cases, including mild symptoms (e.g., headache, mild fever, common cold), moderate symptoms with contextual risk factors (e.g., allergies, chronic conditions), and high-risk presentations (e.g., severe symptoms, prolonged duration, contraindication flags). Each scenario was submitted through the web interface, verifying that user inputs were correctly validated and transformed into structured prompts. The following validation checks were systematically performed: • Form-level validation: Client-side input validation was enforced using schema-based constraints to prevent incomplete or inconsistent clinical context submission. • Response integrity validation: Gemini outputs were required to return strict JSON. Responses that were not valid JSON were rejected. • Schema compliance validation: A server-side schema validation layer verified that responses matched the expected structure (recommendation list, dosage fields, warnings, and optional reason field). Outputs failing schema validation were not displayed or persisted. • Safety rule enforcement: The system was tested to confirm that recommendations are suppressed in high-risk cases (e.g., severe symptoms or contraindication flags), returning warnings and explanatory messages instead of medication suggestions. • Persistence consistency: Only validated outputs were stored. If either form validation or AI response validation failed, no recommendation record was persisted in PostgreSQL, ensuring database consistency. Functional integration testing confirmed stable data flow across modules, consistent schema-compliant outputs, and correct behavior of safety rules. This validation approach supports transparency and reproducibility by ensuring that all system outputs displayed to the user correspond to auditable and schema-validated responses. Operation System Requirements The system requires: • Node.js v20+ and Next.js 18 • PostgreSQL 17 database (Neon) • Prisma ORM 6.8 • Zod 3.25 for validation • Modern web browser compatible with ES6+ (Chrome, Edge, Firefox) • Stable internet connection for Gemini API interaction User interaction and operational flow The system allows users to register, provide clinical information, and obtain automated medication guidance in a structured manner. The operational workflow is as follows: 1. Registration and login: Users create an account by entering their name, email address, and password. 2. Identification data entry: After authentication, users enter an identification number, which is validated and used to automatically complete the associated name. 3. Symptom entry: Users describe their symptoms in free text and may optionally provide additional information such as age, weight, sex, allergies, and current medication. 4. Structured prompt construction: The system transforms the collected input into a standardized JSON object compatible with the Gemini API. 5. Processing via the Gemini API: The prompt is sent to the API, which returns a response constrained to JSON format. 6. Presentation of results: Recommendations and safety warnings are displayed in a results panel within the user interface. 7. Internal recording: Each interaction is stored in the database along with the date, identification number, and the generated output. 8. Completion or new query: The user may restart the form to submit a new query. Use cases This section presents the main use cases of the intelligent drug recommendation system for common diseases powered by the Gemini API. The scenarios illustrate typical interactions between users and the platform, from account creation to the generation of structured over-the-counter (OTC) medication guidance. Each use case describes how the system captures user inputs, processes clinical context, produces recommendations, and displays safety warnings, maintaining an informative and educational purpose. Case 1. User registration In this use case, the user accesses the registration page and provides their name, email address, and password ( Figure 4 ). Once registration is completed, the user can authenticate and access the medication recommendation module. User credentials are securely stored to enable personalized access in future sessions. Figure 4. User registration form with fields for name, email, and password. Source: Own elaboration. Note: Screenshot of the registration interface used to create user accounts and enable authenticated access to the system. Case 2. Data entry for medication recommendations In this use case, the user accesses the main consultation form and enters their identification number. The system validates the document and automatically completes the associated full name. The user then provides additional clinical context, including symptoms, age, weight, sex, allergies, current medication, symptom duration, and perceived severity ( Figure 5 ). Figure 5. User data entry form with automatic name validation based on ID number. Source: Own elaboration. Note: Screenshot of the main consultation form showing symptom input and optional clinical context fields (e.g., age, sex, weight, allergies, duration, severity). The system validates the identification number and auto-completes the associated full name. After completing the form, the user selects “Generate Recommendation”, which triggers prompt structuring and submission to the Gemini API. Case 3. Displaying results and warnings In this use case, the system processes the submitted information and presents the generated recommendations in a results panel. The output includes suggested medications, dosage and usage instructions, and safety warnings (e.g., contraindications or recommendations to consult a healthcare professional if symptoms persist). Additionally, the user can export the results as a downloadable PDF report for personal reference ( Figure 6 ). Figure 6. Results panel with drug recommendations and informational warnings. Source: Own elaboration. Note: Example output view displaying schema-validated OTC medication recommendations, dosage instructions, and safety warnings. Users can export the results as a downloadable PDF report. Case 4. Severity management and critical warnings In this use case, when the system detects high-risk or severe symptom descriptions (e.g., “severe headache”), it prioritizes user safety by generating a prominent warning that encourages immediate medical evaluation. In these situations, the system may suppress medication recommendations and instead return an explanatory message indicating that self-medication is not advised ( Figure 7 ). Figure 7. Warning generated by the system for symptoms of high severity. Source: Own elaboration. Note: Example of safety-oriented behavior where the system detects high-risk symptom descriptions and prioritizes warnings. In such cases, medication recommendations may be suppressed, and the user is advised to seek professional medical evaluation. Overall, these use cases demonstrate that the system supports a clear and safety-oriented user experience. By combining structured data capture, AI-based processing, and explicit warnings, the platform delivers informative medication guidance while reinforcing that outputs do not replace professional medical assessment. The modular design also supports scalability and future extensions. Discussion Medibot AI was developed to address the need for accessible and structured medication guidance, particularly in contexts where timely access to professional medical consultation may be limited. By integrating Google’s Gemini API, the system leverages large language model capabilities to interpret patient-reported symptoms and clinical context and generate over-the-counter (OTC) medication recommendations accompanied by safety warnings. Unlike traditional clinical decision support tools that rely on fixed rule-based engines or curated drug databases, Medibot AI is designed as a modular web-based system that emphasizes structured prompting, response validation, and traceability of outputs. A key contribution of this work is the adoption of a structured JSON-based prompting strategy combined with server-side response verification. The system constrains model outputs through strict formatting rules, schema expectations, and validation procedures, reducing the likelihood of malformed or ambiguous recommendations. This is particularly relevant in health-related applications, where unconstrained natural language generation may lead to unclear dosage instructions or unsafe guidance. In addition, the system includes safety-oriented behavior such as suppressing recommendations and returning explanatory reasons when risk conditions are detected (e.g., severe symptoms, red flags, pediatric cases without sufficient context, pregnancy with incomplete information, relevant allergies, or potential drug interactions). Despite these design measures, the effectiveness of Medibot AI remains dependent on multiple factors. First, the accuracy and safety of recommendations are strongly influenced by the quality and completeness of user-provided data, since missing or incorrect clinical context may limit the system’s ability to detect contraindications or high-risk scenarios. Second, although the Gemini API provides advanced language understanding and reasoning capabilities, its coverage of drug interactions and clinical edge cases may not be fully comprehensive, which can reduce reliability in complex situations. 19 Therefore, Medibot AI should be interpreted as a guidance-oriented tool, rather than a substitute for professional diagnosis or prescription. From a data quality perspective, the METRIC framework proposed by 20 highlights essential dimensions such as accuracy, completeness, and representativeness. These dimensions are directly relevant to Medibot AI, since the system operates on patient-reported symptom narratives and contextual inputs that may vary widely across users. Ensuring structured input capture and validation is therefore critical to reduce noise and improve the consistency of generated outputs. Ethical and professional considerations are central to the responsible deployment of AI in healthcare. The system must preserve patient autonomy, ensure transparency regarding its limitations, and reinforce that outputs do not replace expert evaluation. In this regard, Medibot AI incorporates warnings and safety rules to encourage users to seek professional assistance when symptoms are severe, persistent, or unclear. Additionally, professional responsibility remains essential: healthcare personnel should treat Medibot AI as a complementary decision-support mechanism rather than a replacement for clinical judgment. Adequate training and clear usage protocols are necessary to improve acceptance and prevent misuse. 21 , 22 Future work could strengthen the system by improving clinical reliability and expanding its scope. Potential enhancements include integrating additional automated safety layers (e.g., stronger contraindication detection), expanding the coverage of medication scenarios, and incorporating mechanisms that align recommendations with updated scientific evidence. Collaboration with academic institutions and hospitals would be particularly valuable for expert-driven validation, iterative improvement, and formal evaluation of system performance in real-world settings. 23 Moreover, evaluating the system from the perspective of multiple stakeholders—patients, clinicians, and administrators—could support improvements in usability, integration into healthcare workflows, and long-term sustainability. 23 Overall, Medibot AI represents a relevant step toward practical AI-assisted medication guidance through a modular architecture and safety-oriented design. While important limitations remain, the system provides a structured and auditable foundation for future research and development aimed at improving access to reliable health information in a responsible manner. Conclusions This study presented the design and implementation of Medibot AI, a web-based intelligent system for informational over-the-counter (OTC) medication guidance using the Gemini API. The system demonstrates that large language models can be integrated into a modular architecture capable of transforming user-reported symptoms and clinical context into structured prompts, producing schema-constrained JSON outputs, and delivering recommendations accompanied by safety warnings. The incorporation of server-side validation, persistence mechanisms, and traceability supports robustness and reproducibility of the generated results. Despite these contributions, the system is subject to limitations inherent to LLM-based solutions. Recommendation quality depends on the accuracy and completeness of user-provided inputs and on the model’s ability to generate consistent structured responses. Although the proposed validation and safety rules reduce the risk of malformed or unsafe outputs, Medibot AI is not intended to provide diagnosis or replace professional medical advice. Therefore, its outputs should be interpreted as educational guidance, and users should consult healthcare professionals when symptoms are severe, persistent, or unclear. Future work may focus on strengthening clinical reliability and scalability. This includes expanding the medication knowledge base, improving safety coverage for contraindications and drug interactions, and integrating retrieval-based strategies (e.g., RAG) to ground recommendations in verified pharmacological sources. Additional improvements could include multilingual support, more refined risk stratification, and systematic evaluation protocols involving expert review and real-world usability studies. Overall, Medibot AI provides a practical contribution toward responsible AI-assisted medication guidance by combining structured prompting, validation, and safety-oriented design. These elements support the development of transparent and auditable systems that can enhance access to reliable health information while maintaining ethical and clinical caution. Ethics and consent This article describes the development of a software tool and does not report results from a clinical study or interventions involving patients. The system is intended for informational and educational purposes only and does not provide medical diagnosis, clinical decision-making, or professional medical advice. Medibot AI is not a medical device. Users voluntarily enter information to obtain guidance related to over-the-counter medications. The interface includes visible safety warnings encouraging consultation with a healthcare professional, particularly when symptoms are severe, persistent, or unclear. Software availability* Software available from: https://medibot-ai-prod.vercel.app/ Source code available from: https://github.com/PIEROLS15/medibot-ai Archived source code at time of publication: https://doi.org/10.5281/zenodo.17714829 . 25 License:* MIT License — https://opensource.org/license/MIT Data privacy and security The system stores user account information (e.g., name and email) and consultation history (e.g., symptoms and related form fields) in a PostgreSQL database to support traceability and reproducibility of outputs. Access requires authentication. API credentials are protected using environment variables, and input validation is enforced using Zod to reduce the risk of malformed data submissions. No real patient data were used or publicly shared. The publicly archived dataset consists exclusively of synthetic scenarios intended for reproducibility and validation purposes. Data availability* Underlying data This work describes a software package. No real-world clinical datasets were generated or collected, and no patient-identifiable data were obtained. To support transparency and reproducibility, we provide a set of synthetic test scenarios and validation artifacts (e.g., JSON cases, expected outputs, and schema definitions) archived in Zenodo. These files enable independent verification of the input/output structure and safety-related behaviors of Medibot AI without exposing sensitive clinical information. Underlying data available from: Zenodo: Medibot AI: Synthetic Test Scenarios and Validation Artifacts (Underlying Data), https://doi.org/10.5281/zenodo.18437408 . 24 Data are available under the terms of the Creative Commons Attribution 4.0 International license (CC BY 4.0) . https://creativecommons.org/licenses/by/4.0/ Acknowledgements We would like to express our sincere gratitude to the Universidad Nacional de Cañete (UNDC) and to the teachers, students, and collaborators who contributed to the development of this work as part of the academic training process. References* 1. Aracena C, Villena F, Arias F, et al. : Aplicaciones de aprendizaje automático en salud. Rev. Med. Clin. Condes. Nov. 2022; 33 (6): 568–575. Publisher Full Text 2. Torre L-PS, Quirós P, Mieres HG: Detección Automática de Patologías en Notas Clínicas en Español Combinando Modelos de Lenguaje y Ontologías Médicos.Oct. 2024; 24–27. Accessed: Oct. 16, 2025. Reference Source 3. Wu C-K, Chen W-L, Chen H-H: Large Language Models Perform Diagnostic Reasoning.Jul. 2023. Publisher Full Text 4. Chocrón P, Abella Á, de Maeztu G : ContextMEL: Classifying Contextual Modifiers in Clinical Text. Procesamiento del Lenguaje Natural. Sep. 2020; 65 : 45–52. Publisher Full Text 5. Abdel-Aal A, Lisspers K, Williams S, et al. : Prioritising primary care respiratory research needs: results from the 2020 International Primary Care Respiratory Group (IPCRG) global e-Delphi exercise. NPJ Prim. Care Respir. Med. Jan. 2022; 32 (1): 6. PubMed Abstract | Publisher Full Text | Free Full Text 6. Panda A, Pradhan S, Mohapatra G, et al. : Drug-related problems associated with self-medication and medication guided by prescription: A pharmacy-based survey. Indian J. Pharm. 2016; 48 (5): 515–521. PubMed Abstract | Publisher Full Text | Free Full Text 7. Ruiz M: Risks of Self-Medication Practices. Curr. Drug Saf. Oct. 2010; 5 (4): 315–323. Publisher Full Text 8. Zeid W, Hamed M, Mansour N, et al. : Prevalence and associated risk factors of self-medication among patients attending El-Mahsama family practice center, Ismailia, Egypt. Bull. Natl. Res. Cent. Dec. 2020; 44 (1): 92. Publisher Full Text 9. Preininger AM, South B, Heiland J, et al. : Artificial intelligence-based conversational agent to support medication prescribing. JAMIA Open. Jul. 2020; 3 (2): 225–232. PubMed Abstract | Publisher Full Text | Free Full Text 10. Hartjes MG, Richir MC, Cazaubon Y, et al. : Enhancing therapeutic reasoning: key insights and recommendations for education in prescribing. BMC Med. Educ. Nov. 2024; 24 (1): 1360. PubMed Abstract | Publisher Full Text | Free Full Text 11. Graafsma J, Murphy RM, van de Garde EMW, et al. : The use of artificial intelligence to optimize medication alerts generated by clinical decision support systems: a scoping review. J. Am. Med. Inform. Assoc. May 2024; 31 (6): 1411–1422. PubMed Abstract | Publisher Full Text | Free Full Text 12. Marzouk NH, Selim S, Elattar M, et al. : A comprehensive landscape of AI applications in broad-spectrum drug interaction prediction: a systematic review. Aust. J. Chem. Sep. 2025; 17 (1): 141. PubMed Abstract | Publisher Full Text | Free Full Text 13. Saban M, Esteban S, Rubinstein A, et al. : The Impact of Artificial Intelligence on Healthcare: Perspectives and Approaches for Latin America and the Caribbean.2023. Publisher Full Text 14. Cortés Torres JE, Saldaña Moreno CE, Mendoza Moncada JS, et al. : El chatbot aplicado a salud. Una revisión bibliométrica. Rev Comun Salud. Dec. 2024; 15 : 1–18. Publisher Full Text 15. Rees GH, Peralta F: Telemedicine in Peru: origin, implementation, pandemic escalation, and prospects in the new normal. Oxford Open Digital Health. Jan. 2024; 2 . PubMed Abstract | Publisher Full Text | Free Full Text 16. Curioso WH, Coronel-Chucos LG, Henríquez-Suarez M: Integrating Telehealth for Strengthening Health Systems in the Context of the COVID-19 Pandemic: A Perspective from Peru. Int. J. Environ. Res. Public Health. May 2023; 20 (11): 5980. PubMed Abstract | Publisher Full Text | Free Full Text 17. Ponce de León Sierra J, Merma Pillaca A: Transformación digital en el sector salud peruano: retos y avances recientes. Rev. Panam. Salud Publica. Dec. 2024; 48 : 1. Publisher Full Text 18. Ramos-Miller M, Pacheco A: Towards inventory control excellence: An innovative approach based on a web-based platform. F1000Res. Dec. 2023; 12 : 1471. Publisher Full Text 19. Khosravi M, Zare Z, Mojtabaeian SM, et al. : Artificial Intelligence and Decision-Making in Healthcare: A Thematic Analysis of a Systematic Review of Reviews. Health Serv. Res. Manag. Epidemiol. Jan. 2024; 11 . Publisher Full Text 20. Schwabe D, Becker K, Seyferth M, et al. : The METRIC-framework for assessing data quality for trustworthy AI in medicine: a systematic review. NPJ Digit. Med. Aug. 2024; 7 (1): 203. PubMed Abstract | Publisher Full Text | Free Full Text 21. Harishbhai Tilala M, Kumar Chenchala P, Choppadandi A, et al. : Ethical Considerations in the Use of Artificial Intelligence and Machine Learning in Health Care: A Comprehensive Review. Cureus. Jun. 2024; 16 : e62443. PubMed Abstract | Publisher Full Text | Free Full Text 22. Dankwa-Mullan I: Health Equity and Ethical Considerations in Using Artificial Intelligence in Public Health and Medicine. Prev. Chronic Dis. Aug. 2024; 21 : 240245. PubMed Abstract | Publisher Full Text | Free Full Text 23. Giebel GD, Raszke P, Nowak H, et al. : Improving AI-Based Clinical Decision Support Systems and Their Integration Into Care From the Perspective of Experts: Interview Study Among Different Stakeholders. JMIR Med. Inform. Jul. 2025; 13 : e69688. Publisher Full Text 24. Llanos-Sánchez PD: Medibot AI: Synthetic Test Scenarios and Validation Artifacts (Underlying Data).Jan. 30, 2026. Publisher Full Text 25. Llanos-Sánchez PD, Espinoza-Franco AA, Portuguéz-Villa FA: Medibot AI. Zenodo. Nov. 25, 2025. Publisher Full Text Comments on this article Comments (0) Version 1 VERSION 1 PUBLISHED 19 Apr 2026 ADD YOUR COMMENT Comment Author details Author details 1 Professional School of Systems Engineering, Universidad Nacional de Cañete, San Vicente de Cañete, Lima, 15701, Peru Piero Llanos-Sánchez Roles: Conceptualization, Methodology, Software, Writing – Original Draft Preparation, Writing – Review & Editing Arianna Espinoza-Franco Roles: Conceptualization, Methodology, Software, Writing – Original Draft Preparation, Writing – Review & Editing Fabián Portuguéz-Villa Roles: Conceptualization, Methodology, Software, Writing – Original Draft Preparation, Writing – Review & Editing Gustavo Fernández-Gutiérrez Roles: Conceptualization, Methodology, Writing – Original Draft Preparation, Writing – Review & Editing Alex Pacheco Roles: Conceptualization, Methodology, Writing – Original Draft Preparation, Writing – Review & Editing Competing interests No competing interests were disclosed. Grant information This work was funded by the Directorate of Innovation and Technology Transfer of the Vice Presidency for Research at the Universidad Nacional de Cañete (UNDC) as part of the “First Research Competition for the Development of Innovations and Intellectual Property” [contract number 014-2024]. The funders had no role in study design, data collection and analysis, decision to publish, or preparation of the manuscript. Article Versions (1) version 1 Published: 19 Apr 2026, 15:572 https://doi.org/10.12688/f1000research.177717.1 Copyright © 2026 Llanos-Sánchez P et al . This is an open access article distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. Download Export To Sciwheel Bibtex EndNote ProCite Ref. Manager (RIS) Sente metrics Views Downloads F1000Research - - PubMed Central info_outline Data from PMC are received and updated monthly. - - Citations open_in_new 0 open_in_new 0 open_in_new SEE MORE DETAILS CITE how to cite this article Llanos-Sánchez P, Espinoza-Franco A, Portuguéz-Villa F et al. Medibot AI: a web-based software tool integrating Gemini API for informational over-the-counter medication guidance [version 1; peer review: awaiting peer review] . F1000Research 2026, 15 :572 ( https://doi.org/10.12688/f1000research.177717.1 ) NOTE: If applicable, it is important to ensure the information in square brackets after the title is included in all citations of this article. COPY CITATION DETAILS track receive updates on this article Track an article to receive email alerts on any updates to this article. TRACK THIS ARTICLE Share Open Peer Review Current Reviewer Status: AWAITING PEER REVIEW AWAITING PEER REVIEW ? Key to Reviewer Statuses VIEW HIDE Approved The paper is scientifically sound in its current form and only minor, if any, improvements are suggested Approved with reservations A number of small changes, sometimes more significant revisions are required to address specific details and improve the papers academic merit. Not approved Fundamental flaws in the paper seriously undermine the findings and conclusions Comments on this article Comments (0) Version 1 VERSION 1 PUBLISHED 19 Apr 2026 ADD YOUR COMMENT Comment keyboard_arrow_left keyboard_arrow_right Open Peer Review Reviewer Status AWAITING PEER REVIEW Comments on this article All Comments (0) Add a comment Sign up for content alerts Sign Up You are now signed up to receive this alert Browse by related subjects Alongside their report, reviewers assign a status to the article: Approved - the paper is scientifically sound in its current form and only minor, if any, improvements are suggested Approved with reservations - A number of small changes, sometimes more significant revisions are required to address specific details and improve the papers academic merit. Not approved - fundamental flaws in the paper seriously undermine the findings and conclusions Adjust parameters to alter display View on desktop for interactive features Includes Interactive Elements View on desktop for interactive features Competing Interests Policy Provide sufficient details of any financial or non-financial competing interests to enable users to assess whether your comments might lead a reasonable person to question your impartiality. Consider the following examples, but note that this is not an exhaustive list: Examples of 'Non-Financial Competing Interests' Within the past 4 years, you have held joint grants, published or collaborated with any of the authors of the selected paper. You have a close personal relationship (e.g. parent, spouse, sibling, or domestic partner) with any of the authors. You are a close professional associate of any of the authors (e.g. scientific mentor, recent student). You work at the same institute as any of the authors. You hope/expect to benefit (e.g. favour or employment) as a result of your submission. You are an Editor for the journal in which the article is published. Examples of 'Financial Competing Interests' You expect to receive, or in the past 4 years have received, any of the following from any commercial organisation that may gain financially from your submission: a salary, fees, funding, reimbursements. You expect to receive, or in the past 4 years have received, shared grant support or other funding with any of the authors. You hold, or are currently applying for, any patents or significant stocks/shares relating to the subject matter of the paper you are commenting on. Stay Updated Sign up for content alerts and receive a weekly or monthly email with all newly published articles Register with F1000Research Already registered? Sign in Not now, thanks close PLEASE NOTE If you are an AUTHOR of this article, please check that you signed in with the account associated with this article otherwise we cannot automatically identify your role as an author and your comment will be labelled as a “User Comment”. If you are a REVIEWER of this article, please check that you have signed in with the account associated with this article and then go to your account to submit your report, please do not post your review here. If you do not have access to your original account, please contact us . All commenters must hold a formal affiliation as per our Policies . The information that you give us will be displayed next to your comment. User comments must be in English, comprehensible and relevant to the article under discussion. We reserve the right to remove any comments that we consider to be inappropriate, offensive or otherwise in breach of the User Comment Terms and Conditions . Commenters must not use a comment for personal attacks. When criticisms of the article are based on unpublished data, the data should be made available. I accept the User Comment Terms and Conditions Please confirm that you accept the User Comment Terms and Conditions. Affiliation ✕ refresh Please enter your institution. Note: To add your institution or organisation, start typing the name and then select the correct name from the list. Where applicable, the name will appear in both the original language and in English. Do not paste in the name. If the name does not appear in the drop-down list, we will display the information you have entered. ✕ refresh Country/Region * USA UK Canada China France Germany Afghanistan Aland Islands Albania Algeria American Samoa Andorra Angola Anguilla Antarctica Antigua and Barbuda Argentina Armenia Aruba Australia Austria Azerbaijan Bahamas Bahrain Bangladesh Barbados Belarus Belgium Belize Benin Bermuda Bhutan Bolivia Bosnia and Herzegovina Botswana Bouvet Island Brazil British Indian Ocean Territory British Virgin Islands Brunei Bulgaria Burkina Faso Burundi Cambodia Cameroon Canada Cape Verde Cayman Islands Central African Republic Chad Chile China Christmas Island Cocos (Keeling) Islands Colombia Comoros Congo Cook Islands Costa Rica Cote d'Ivoire Croatia Cuba Cyprus Czech Republic Democratic Republic of the Congo Denmark Djibouti Dominica Dominican Republic Ecuador Egypt El Salvador Equatorial Guinea Eritrea Estonia Ethiopia Falkland Islands Faroe Islands Federated States of Micronesia Fiji Finland France French Guiana French Polynesia French Southern Territories Gabon Georgia Germany Ghana Gibraltar Greece Greenland Grenada Guadeloupe Guam Guatemala Guernsey Guinea Guinea-Bissau Guyana Haiti Heard Island and Mcdonald Islands Holy See (Vatican City State) Honduras Hong Kong Hungary Iceland India Indonesia Iran Iraq Ireland Israel Italy Jamaica Japan Jersey Jordan Kazakhstan Kenya Kiribati Kosovo (Serbia and Montenegro) Kuwait Kyrgyzstan Lao People's Democratic Republic Latvia Lebanon Lesotho Liberia Libya Liechtenstein Lithuania Luxembourg Macao Madagascar Malawi Malaysia Maldives Mali Malta Marshall Islands Martinique Mauritania Mauritius Mayotte Mexico Minor Outlying Islands of the United States Moldova Monaco Mongolia Montenegro Montserrat Morocco Mozambique Myanmar Namibia Nauru Nepal Netherlands Antilles New Caledonia New Zealand Nicaragua Niger Nigeria Niue Norfolk Island North Korea North Macedonia Northern Mariana Islands Norway Oman Pakistan Palau Palestinian Territory Panama Papua New Guinea Paraguay Peru Philippines Pitcairn Poland Portugal Puerto Rico Qatar Reunion Romania Russian Federation Rwanda Saint Helena Saint Kitts and Nevis Saint Lucia Saint Pierre and Miquelon Saint Vincent and the Grenadines Samoa San Marino Sao Tome and Principe Saudi Arabia Senegal Serbia Seychelles Sierra Leone Singapore Slovakia Slovenia Solomon Islands Somalia South Africa South Georgia and the South Sandwich Is South Korea South Sudan Spain Sri Lanka Sudan Suriname Svalbard and Jan Mayen Swaziland Sweden Switzerland Syria Taiwan Tajikistan Tanzania Thailand The Gambia The Netherlands Timor-Leste Togo Tokelau Tonga Trinidad and Tobago Tunisia Turkey Turkmenistan Turks and Caicos Islands Tuvalu UK USA Uganda Ukraine United Arab Emirates United States Virgin Islands Uruguay Uzbekistan Vanuatu Venezuela Vietnam Wallis and Futuna West Bank and Gaza Strip Western Sahara Yemen Zambia Zimbabwe Please select your country/region. You must enter a comment. Competing Interests Please disclose any competing interests that might be construed to influence your judgment of the article's or peer review report's validity or importance. Competing Interests Policy Provide sufficient details of any financial or non-financial competing interests to enable users to assess whether your comments might lead a reasonable person to question your impartiality. Consider the following examples, but note that this is not an exhaustive list: Examples of 'Non-Financial Competing Interests' Within the past 4 years, you have held joint grants, published or collaborated with any of the authors of the selected paper. You have a close personal relationship (e.g. parent, spouse, sibling, or domestic partner) with any of the authors. You are a close professional associate of any of the authors (e.g. scientific mentor, recent student). You work at the same institute as any of the authors. You hope/expect to benefit (e.g. favour or employment) as a result of your submission. You are an Editor for the journal in which the article is published. Examples of 'Financial Competing Interests' You expect to receive, or in the past 4 years have received, any of the following from any commercial organisation that may gain financially from your submission: a salary, fees, funding, reimbursements. You expect to receive, or in the past 4 years have received, shared grant support or other funding with any of the authors. You hold, or are currently applying for, any patents or significant stocks/shares relating to the subject matter of the paper you are commenting on. Please state your competing interests The comment has been saved. An error has occurred. Please try again. Cancel Post var lTitle = "Medibot AI: a web-based software tool integrating...".replace("'", ''); var linkedInUrl = "http://www.linkedin.com/shareArticle?url=https://f1000research.com/articles/15-572/v1" + "&title=" + encodeURIComponent(lTitle) + "&summary=" + encodeURIComponent('Read the article by '); var deliciousUrl = "https://del.icio.us/post?url=https://f1000research.com/articles/15-572/v1&title=" + encodeURIComponent(lTitle); var redditUrl = "http://reddit.com/submit?url=https://f1000research.com/articles/15-572/v1" + "&title=" + encodeURIComponent(lTitle); linkedInUrl += encodeURIComponent('Llanos-Sánchez P et al.'); var offsetTop = /chrome/i.test( navigator.userAgent ) ? 4 : -10; var addthis_config = { ui_offset_top: offsetTop, services_compact : "facebook,twitter,www.linkedin.com,www.mendeley.com,reddit.com", services_expanded : "facebook,twitter,www.linkedin.com,www.mendeley.com,reddit.com", services_custom : [ { name: "LinkedIn", url: linkedInUrl, icon:"/img/icon/at_linkedin.svg" }, { name: "Mendeley", url: "http://www.mendeley.com/import/?url=https://f1000research.com/articles/15-572/v1/mendeley", icon:"/img/icon/at_mendeley.svg" }, { name: "Reddit", url: redditUrl, icon:"/img/icon/at_reddit.svg" }, ] }; var addthis_share = { url: "https://f1000research.com/articles/15-572", templates : { twitter : "Medibot AI: a web-based software tool integrating Gemini API.... Llanos-Sánchez P et al., published by " + "@F1000Research" + ", https://f1000research.com/articles/15-572/v1" } }; if (typeof(addthis) != "undefined"){ addthis.addEventListener('addthis.ready', checkCount); addthis.addEventListener('addthis.menu.share', checkCount); } $(".f1r-shares-twitter").attr("href", "https://twitter.com/intent/tweet?text=" + addthis_share.templates.twitter); $(".f1r-shares-facebook").attr("href", "https://www.facebook.com/sharer/sharer.php?u=" + addthis_share.url); $(".f1r-shares-linkedin").attr("href", addthis_config.services_custom[0].url); $(".f1r-shares-reddit").attr("href", addthis_config.services_custom[2].url); $(".f1r-shares-mendelay").attr("href", addthis_config.services_custom[1].url); function checkCount(){ setTimeout(function(){ $(".addthis_button_expanded").each(function(){ var count = $(this).text(); if (count !== "" && count != "0") $(this).removeClass("is-hidden"); else $(this).addClass("is-hidden"); }); }, 1000); } close How to cite this report {{reportCitation}} Cancel Copy Citation Details $(function(){R.ui.buttonDropdowns('.dropdown-for-downloads');}); $(function(){R.ui.toolbarDropdowns('.toolbar-dropdown-for-downloads');}); $.get("/articles/acj/177717/195984") new F1000.Clipboard(); new F1000.ThesaurusTermsDisplay("articles", "article", "195984"); $(document).ready(function() { $( "#frame1" ).on('load', function() { var mydiv = $(this).contents().find("div"); var h = mydiv.height(); console.log(h) }); var tooltipLivingFigure = jQuery(".interactive-living-figure-label .icon-more-info"), titleLivingFigure = tooltipLivingFigure.attr("title"); tooltipLivingFigure.simpletip({ fixed: true, position: ["-115", "30"], baseClass: 'small-tooltip', content:titleLivingFigure + " " }); tooltipLivingFigure.removeAttr("title"); $("body").on("click", ".cite-living-figure", function(e) { e.preventDefault(); var ref = $(this).attr("data-ref"); $(this).closest(".living-figure-list-container").find("#" + ref).fadeIn(200); }); $("body").on("click", ".close-cite-living-figure", function(e) { e.preventDefault(); $(this).closest(".popup-window-wrapper").fadeOut(200); }); $(document).on("mouseup", function(e) { var metricsContainer = $(".article-metrics-popover-wrapper"); if (!metricsContainer.is(e.target) && metricsContainer.has(e.target).length === 0) { $(".article-metrics-close-button").click(); } }); var articleId = $('#articleId').val(); if($("#main-article-count-box").attachArticleMetrics) { $("#main-article-count-box").attachArticleMetrics(articleId, { articleMetricsView: true }); } }); var figshareWidget = $(".new_figshare_widget"); if (figshareWidget.length > 0) { window.figshare.load("f1000", function(Widget) { // Select a tag/tags defined in your page. In this tag we will place the widget. _.map(figshareWidget, function(el){ var widget = new Widget({ articleId: $(el).attr("figshare_articleId") //height:300 // this is the height of the viewer part. [Default: 550] }); widget.initialize(); // initialize the widget widget.mount(el); // mount it in a tag that's on your page // this will save the widget on the global scope for later use from // your JS scripts. This line is optional. //window.widget = widget; }); }); } close Error Close Add Reset F1000.MICROSERVICES.AFFILIATION = ''; $(document).ready(function () { $('.js-affiliations-form').each((index, form) => { new AffiliationForm({ formId: form.id, institutionErrorSelector: '.comment-enter-institution', departmentErrorSelector: '.comment-enter-department', placeSelector: '.js-add-comment-place', stateSelector: '.js-add-comment-state', zipCodeSelector: '.js-add-comment-zipcode', countrySelector: '.js-add-comment-country', countryErrorSelector: '.comment-enter-country', }); }); }); $(document).ready(function () { var reportIds = { "480711": 0, "480710": 0, "480709": 0, "480708": 0, "478656": 0, "480717": 0, "480716": 0, "480715": 0, "480714": 0, "480713": 0, "480712": 0, "483415": 0, "483414": 0, "483413": 0, "483412": 0, "483421": 0, "483420": 0, "483419": 0, "483418": 0, "483417": 0, "483416": 0, "478647": 0, "478655": 0, "478654": 0, "478653": 0, "478652": 0, "478651": 0, "478650": 0, "478649": 0, "478648": 0, }; $(".referee-response-container,.js-referee-report").each(function(index, el) { var reportId = $(el).attr("data-reportid"), reportCount = reportIds[reportId] || 0; $(el).find(".comments-count-container,.js-referee-report-views").html(reportCount); }); var uuidInput = $("#article_uuid"), oldUUId = uuidInput.val(), newUUId = "a2d3e640-a508-4820-a58c-5d911ab9841b"; uuidInput.val(newUUId); $("a[href*='article_uuid=']").each(function(index, el) { var newHref = $(el).attr("href").replace(oldUUId, newUUId); $(el).attr("href", newHref); }); }); An innovative open access publishing platform offering rapid publication and open peer review, whilst supporting data deposition and sharing. Browse Gateways Collections How it Works Contact For Developers Cookie Notice Privacy Notice RSS Submit Your Research Follow us © 2012-2026 F1000 Research Ltd. ISSN 2046-1402 | Legal | Partner of Research4Life • CrossRef • ORCID • FAIRSharing R.templateTests.simpleTemplate = R.template(' $text $text $text $text $text '); R.templateTests.runTests(); var F1000platform = new F1000.Platform({ name: "f1000research", displayName: "F1000Research", hostName: "f1000research.com", id: "1", editorialEmail: "[email protected]", infoEmail: "[email protected]", usePmcStats: true }); $(function(){R.ui.dropdowns('.dropdown-for-authors, .dropdown-for-about, .dropdown-for-myresearch');}); // $(function(){R.ui.dropdowns('.dropdown-for-referees');}); $(document).ready(function () { if ($(".cookie-warning").is(":visible")) { $(".sticky").css("margin-bottom", "35px"); $(".devices").addClass("devices-and-cookie-warning"); } $(".cookie-warning .close-button").click(function (e) { $(".devices").removeClass("devices-and-cookie-warning"); $(".sticky").css("margin-bottom", "0"); }); $("#tweeter-feed .tweet-message").each(function (i, message) { var self = $(message); self.html(linkify(self.html())); }); $(".partner").on("mouseenter mouseleave", function() { $(this).find(".gray-scale, .colour").toggleClass("is-hidden"); }); }); Sign In Remember me Forgotten your password? Sign In Cancel Email or password not correct. Please try again Please wait... $(function(){ // Note: All the setup needs to run against a name attribute and *not* the id due the clonish // nature of facebox... $("a[id=googleSignInButton]").click(function(event){ event.preventDefault(); $("input[id=oAuthSystem]").val("GOOGLE"); $("form[id=oAuthForm]").submit(); }); $("a[id=facebookSignInButton]").click(function(event){ event.preventDefault(); $("input[id=oAuthSystem]").val("FACEBOOK"); $("form[id=oAuthForm]").submit(); }); $("a[id=orcidSignInButton]").click(function(event){ event.preventDefault(); $("input[id=oAuthSystem]").val("ORCID"); $("form[id=oAuthForm]").submit(); }); }); If you've forgotten your password, please enter your email address below and we'll send you instructions on how to reset your password. The email address should be the one you originally registered with F1000. Email address not valid, please try again You registered with F1000 via Google, so we cannot reset your password. To sign in, please click here . If you still need help with your Google account password, please click here . You registered with F1000 via Facebook, so we cannot reset your password. To sign in, please click here . If you still need help with your Facebook account password, please click here . Code not correct, please try again Reset password Cancel Email us for further assistance. Server error, please try again. If your email address is registered with us, we will email you instructions to reset your password. If you think you should have received this email but it has not arrived, please check your spam filters and/or contact for further assistance. Please wait... Register $(document).ready(function () { signIn.createSignInAsRow($("#sign-in-form-gfb-popup")); $(".target-field").each(function () { var uris = $(this).val().split("/"); if (uris.pop() === "login") { $(this).val(uris.toString().replace(",","/")); } }); });

Text is read by the "Ask this paper" AI Q&A widget below. Extraction quality varies by source — PMC NXML preserves structure cleanly, OA-HTML may include some navigation residue, and OA-PDF can have broken hyphenation. The publisher copy (via DOI) is the canonical version.

My notes (saved in your browser only)

Ask this paper AI returns verbatim quotes from the full text · source: preprint-html

Answers must be backed by verbatim quotes from this paper's full text. Hallucinated quotes are dropped automatically; if no verbatim passage answers the question, we say so. How this works

Citation neighborhood (no data yet)

We don't have any in-corpus citations linked to this paper yet. This is a recent paper (2026) — citers typically take a year or two to land, and the OpenAlex reference graph may still be filling in.

Source provenance

europepmc
last seen: 2026-05-20T01:45:00.602351+00:00
unpaywall
last seen: 2026-05-22T02:00:06.705733+00:00
License: CC-BY-4.0