promptfoo 0.13.1 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -196,4 +196,4 @@ Error generating stack: `+i.message+`
196
196
  *
197
197
  * This source code is licensed under the MIT license found in the
198
198
  * LICENSE file in the root directory of this source tree.
199
- */var zu=b,WO=HO;function UO(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var GO=typeof Object.is=="function"?Object.is:UO,KO=WO.useSyncExternalStore,qO=zu.useRef,YO=zu.useEffect,XO=zu.useMemo,QO=zu.useDebugValue;B1.useSyncExternalStoreWithSelector=function(e,t,n,r,o){var i=qO(null);if(i.current===null){var s={hasValue:!1,value:null};i.current=s}else s=i.current;i=XO(function(){function a(m){if(!u){if(u=!0,c=m,m=r(m),o!==void 0&&s.hasValue){var y=s.value;if(o(y,m))return d=y}return d=m}if(y=d,GO(c,m))return y;var v=r(m);return o!==void 0&&o(y,v)?y:(c=m,d=v)}var u=!1,c,d,f=n===void 0?null:n;return[function(){return a(t())},f===null?void 0:function(){return a(f())}]},[t,n,r,o]);var l=KO(e,i[0],i[1]);return YO(function(){s.hasValue=!0,s.value=l},[l]),QO(l),l};D1.exports=B1;var ZO=D1.exports;const JO=of(ZO),{useSyncExternalStoreWithSelector:eI}=JO;function tI(e,t=e.getState,n){const r=eI(e.subscribe,e.getState,e.getServerState||e.getState,t,n);return b.useDebugValue(r),r}const Eg=e=>{({BASE_URL:"/",MODE:"production",DEV:!1,PROD:!0,SSR:!1}&&"production")!=="production"&&typeof e!="function"&&console.warn("[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`.");const t=typeof e=="function"?IO(e):e,n=(r,o)=>tI(t,r,o);return Object.assign(n,t),n},nI=e=>e?Eg(e):Eg;var rI=e=>(({BASE_URL:"/",MODE:"production",DEV:!1,PROD:!0,SSR:!1}&&"production")!=="production"&&console.warn("[DEPRECATED] Default export is deprecated. Instead use `import { create } from 'zustand'`."),nI(e));const Du=rI(e=>({table:null,setTable:t=>e(()=>({table:t})),config:null,setConfig:t=>e(()=>({config:t}))}));function Hp({text:e,maxLength:t}){const[n,r]=b.useState(!0),o=()=>{r(!n)},i=()=>e.length<=t?e:n?C.jsx(C.Fragment,{children:C.jsxs("span",{style:{cursor:"pointer"},onClick:o,children:[e.substring(0,t)," ..."]})}):C.jsx(C.Fragment,{children:C.jsx("span",{style:{cursor:"pointer"},onClick:o,children:e})});return C.jsx("div",{children:i()})}function oI({text:e,maxTextLength:t,rowIndex:n,promptIndex:r,onRating:o}){const i=e.startsWith("[PASS] "),s=e.startsWith("[FAIL] ");let l=[];i?e=e.substring(7):s&&(e.includes("---")?(l=e.split("---"),e=l.slice(1).join("---")):(l=["[FAIL]"],e.startsWith("[FAIL] ")&&(e=e.substring(7))));const a=u=>{o(n,r,u)};return C.jsxs(C.Fragment,{children:[C.jsxs("div",{className:"cell",children:[i&&C.jsx("div",{className:"status pass",children:"[PASS]"}),s&&C.jsx("div",{className:"status fail",children:l[0]})," ",C.jsx(Hp,{text:e,maxLength:t})]}),C.jsxs("div",{className:"cell-rating",children:[C.jsx("span",{className:"rating",onClick:()=>a(!0),children:"👍"}),C.jsx("span",{className:"rating",onClick:()=>a(!1),children:"👎"})]})]})}function Pg({text:e,maxLength:t,smallText:n}){return C.jsxs("div",{children:[C.jsx(Hp,{text:e,maxLength:t}),C.jsx("span",{className:"smalltext",children:n})]})}function iI({maxTextLength:e,columnVisibility:t,wordBreak:n,filterMode:r,failureFilter:o,onFailureFilterToggle:i}){const{table:s,setTable:l}=Du();Uy(s,"Table should be defined");const{head:a,body:u}=s,c=a.prompts.map((p,h)=>u.reduce((x,w)=>x+(w.outputs[h].startsWith("[PASS]")?1:0),0)),d=(p,h,x)=>{const w=[...u],R={...w[p]},$=[...R.outputs],E=x?`[PASS] ${$[h].replace(/^\[(PASS|FAIL)\] /,"")}`:`[FAIL] ${$[h].replace(/^\[(PASS|FAIL)\] /,"")}`;$[h]=E,R.outputs=$,w[p]=R,l({head:a,body:w})},f=c.reduce((p,h,x,w)=>h>w[p]?x:p,0),m=c[f],y=EO(),v=[y.group({id:"vars",header:()=>C.jsx("span",{children:"Variables"}),columns:a.vars.map((p,h)=>y.accessor(x=>x.vars[h],{id:`Variable ${h+1}`,header:()=>C.jsx(Pg,{smallText:`Variable ${h+1}`,text:p,maxLength:e}),cell:x=>C.jsx(Hp,{text:x.getValue(),maxLength:e}),size:50}))}),y.group({id:"prompts",header:()=>C.jsx("span",{children:"Outputs"}),columns:a.prompts.map((p,h)=>y.accessor(x=>x.outputs[h],{id:`Prompt ${h+1}`,header:()=>{const x=(c[h]/u.length*100).toFixed(2),w=c[h]===m&&m!==0,R=`Prompt ${h+1}`,$=o[R]||!1;return C.jsxs(C.Fragment,{children:[C.jsx(Pg,{smallText:`Prompt ${h+1}`,text:p,maxLength:e}),r==="failures"&&C.jsx(c1,{sx:{"& .MuiFormControlLabel-label":{fontSize:"0.75rem"}},control:C.jsx(qd,{checked:$,onChange:E=>i(R,E.target.checked)}),label:"Show failures"}),C.jsxs("div",{className:`summary ${w?"highlight":""}`,children:["Passing: ",C.jsxs("strong",{children:[x,"%"]})," (",c[h]," / ",u.length,")"]})]})},cell:x=>C.jsx(oI,{text:x.getValue(),maxTextLength:e,rowIndex:x.row.index,promptIndex:h,onRating:d})}))})],k=b.useMemo(()=>r==="failures"?Object.values(o).every(p=>!p)?u:u.filter(p=>p.outputs.some((h,x)=>{const w=`Prompt ${x+1}`,R=h.startsWith("[FAIL] ");return o[w]&&R})):u,[u,o,r]),g=OO({data:k,columns:v,columnResizeMode:"onChange",getCoreRowModel:PO(),state:{columnVisibility:t}});return C.jsxs("table",{style:{wordBreak:n},children:[C.jsx("thead",{children:g.getHeaderGroups().map(p=>C.jsx("tr",{className:"header",children:p.headers.map(h=>C.jsxs("th",{key:h.id,colSpan:h.colSpan,style:{width:h.getSize()},children:[h.isPlaceholder?null:Rg(h.column.columnDef.header,h.getContext()),C.jsx("div",{onMouseDown:h.getResizeHandler(),onTouchStart:h.getResizeHandler(),className:`resizer ${h.column.getIsResizing()?"isResizing":""}`})]}))},p.id))}),C.jsx("tbody",{children:g.getRowModel().rows.map((p,h)=>{let x=!1;return C.jsx("tr",{children:p.getVisibleCells().map(w=>{const R=w.column.id.startsWith("Variable"),$=!R&&!x;$&&(x=!0);const E=h===0&&!R;return C.jsx("td",{key:w.id,style:{width:w.column.getSize()},className:`${R?"variable":""} ${E?"first-prompt-row":""} ${$?"first-prompt-col":""}`,children:Rg(w.column.columnDef.cell,w.getContext())})})},p.id)})})]})}const sI="modulepreload",lI=function(e){return"/"+e},_g={},aI=function(t,n,r){if(!n||n.length===0)return t();const o=document.getElementsByTagName("link");return Promise.all(n.map(i=>{if(i=lI(i),i in _g)return;_g[i]=!0;const s=i.endsWith(".css"),l=s?'[rel="stylesheet"]':"";if(!!r)for(let c=o.length-1;c>=0;c--){const d=o[c];if(d.href===i&&(!s||d.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${i}"]${l}`))return;const u=document.createElement("link");if(u.rel=s?"stylesheet":sI,s||(u.as="script",u.crossOrigin=""),u.href=i,document.head.appendChild(u),s)return new Promise((c,d)=>{u.addEventListener("load",c),u.addEventListener("error",()=>d(new Error(`Unable to preload CSS for ${i}`)))})})).then(()=>t())};function uI(e){return pe("MuiDialog",e)}const cI=fe("MuiDialog",["root","scrollPaper","scrollBody","container","paper","paperScrollPaper","paperScrollBody","paperWidthFalse","paperWidthXs","paperWidthSm","paperWidthMd","paperWidthLg","paperWidthXl","paperFullWidth","paperFullScreen"]),Nc=cI,dI=b.createContext({}),H1=dI,fI=["aria-describedby","aria-labelledby","BackdropComponent","BackdropProps","children","className","disableEscapeKeyDown","fullScreen","fullWidth","maxWidth","onBackdropClick","onClose","open","PaperComponent","PaperProps","scroll","TransitionComponent","transitionDuration","TransitionProps"],pI=H(v1,{name:"MuiDialog",slot:"Backdrop",overrides:(e,t)=>t.backdrop})({zIndex:-1}),hI=e=>{const{classes:t,scroll:n,maxWidth:r,fullWidth:o,fullScreen:i}=e,s={root:["root"],container:["container",`scroll${Y(n)}`],paper:["paper",`paperScroll${Y(n)}`,`paperWidth${Y(String(r))}`,o&&"paperFullWidth",i&&"paperFullScreen"]};return me(s,uI,t)},mI=H(y1,{name:"MuiDialog",slot:"Root",overridesResolver:(e,t)=>t.root})({"@media print":{position:"absolute !important"}}),gI=H("div",{name:"MuiDialog",slot:"Container",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.container,t[`scroll${Y(n.scroll)}`]]}})(({ownerState:e})=>S({height:"100%","@media print":{height:"auto"},outline:0},e.scroll==="paper"&&{display:"flex",justifyContent:"center",alignItems:"center"},e.scroll==="body"&&{overflowY:"auto",overflowX:"hidden",textAlign:"center","&:after":{content:'""',display:"inline-block",verticalAlign:"middle",height:"100%",width:"0"}})),vI=H(Nu,{name:"MuiDialog",slot:"Paper",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.paper,t[`scrollPaper${Y(n.scroll)}`],t[`paperWidth${Y(String(n.maxWidth))}`],n.fullWidth&&t.paperFullWidth,n.fullScreen&&t.paperFullScreen]}})(({theme:e,ownerState:t})=>S({margin:32,position:"relative",overflowY:"auto","@media print":{overflowY:"visible",boxShadow:"none"}},t.scroll==="paper"&&{display:"flex",flexDirection:"column",maxHeight:"calc(100% - 64px)"},t.scroll==="body"&&{display:"inline-block",verticalAlign:"middle",textAlign:"left"},!t.maxWidth&&{maxWidth:"calc(100% - 64px)"},t.maxWidth==="xs"&&{maxWidth:e.breakpoints.unit==="px"?Math.max(e.breakpoints.values.xs,444):`${e.breakpoints.values.xs}${e.breakpoints.unit}`,[`&.${Nc.paperScrollBody}`]:{[e.breakpoints.down(Math.max(e.breakpoints.values.xs,444)+32*2)]:{maxWidth:"calc(100% - 64px)"}}},t.maxWidth&&t.maxWidth!=="xs"&&{maxWidth:`${e.breakpoints.values[t.maxWidth]}${e.breakpoints.unit}`,[`&.${Nc.paperScrollBody}`]:{[e.breakpoints.down(e.breakpoints.values[t.maxWidth]+32*2)]:{maxWidth:"calc(100% - 64px)"}}},t.fullWidth&&{width:"calc(100% - 64px)"},t.fullScreen&&{margin:0,width:"100%",maxWidth:"100%",height:"100%",maxHeight:"none",borderRadius:0,[`&.${Nc.paperScrollBody}`]:{margin:0,maxWidth:"100%"}})),yI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiDialog"}),o=si(),i={enter:o.transitions.duration.enteringScreen,exit:o.transitions.duration.leavingScreen},{"aria-describedby":s,"aria-labelledby":l,BackdropComponent:a,BackdropProps:u,children:c,className:d,disableEscapeKeyDown:f=!1,fullScreen:m=!1,fullWidth:y=!1,maxWidth:v="sm",onBackdropClick:k,onClose:g,open:p,PaperComponent:h=Nu,PaperProps:x={},scroll:w="paper",TransitionComponent:R=g1,transitionDuration:$=i,TransitionProps:E}=r,M=X(r,fI),P=S({},r,{disableEscapeKeyDown:f,fullScreen:m,fullWidth:y,maxWidth:v,scroll:w}),I=hI(P),j=b.useRef(),A=z=>{j.current=z.target===z.currentTarget},_=z=>{j.current&&(j.current=null,k&&k(z),g&&g(z,"backdropClick"))},O=Va(l),N=b.useMemo(()=>({titleId:O}),[O]);return C.jsx(mI,S({className:J(I.root,d),closeAfterTransition:!0,components:{Backdrop:pI},componentsProps:{backdrop:S({transitionDuration:$,as:a},u)},disableEscapeKeyDown:f,onClose:g,open:p,ref:n,onClick:_,ownerState:P},M,{children:C.jsx(R,S({appear:!0,in:p,timeout:$,role:"presentation"},E,{children:C.jsx(gI,{className:J(I.container),onMouseDown:A,ownerState:P,children:C.jsx(vI,S({as:h,elevation:24,role:"dialog","aria-describedby":s,"aria-labelledby":O},x,{className:J(I.paper,x.className),ownerState:P,children:C.jsx(H1.Provider,{value:N,children:c})}))})}))}))}),W1=yI;function xI(e){return pe("MuiDialogTitle",e)}const SI=fe("MuiDialogTitle",["root"]),bI=SI,wI=["className","id"],CI=e=>{const{classes:t}=e;return me({root:["root"]},xI,t)},kI=H(yn,{name:"MuiDialogTitle",slot:"Root",overridesResolver:(e,t)=>t.root})({padding:"16px 24px",flex:"0 0 auto"}),RI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiDialogTitle"}),{className:o,id:i}=r,s=X(r,wI),l=r,a=CI(l),{titleId:u=i}=b.useContext(H1);return C.jsx(kI,S({component:"h2",className:J(a.root,o),ownerState:l,ref:n,variant:"h6",id:i??u},s))}),U1=RI;function $I(e){return pe("MuiDialogContent",e)}fe("MuiDialogContent",["root","dividers"]);const EI=["className","dividers"],PI=e=>{const{classes:t,dividers:n}=e;return me({root:["root",n&&"dividers"]},$I,t)},_I=H("div",{name:"MuiDialogContent",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.dividers&&t.dividers]}})(({theme:e,ownerState:t})=>S({flex:"1 1 auto",WebkitOverflowScrolling:"touch",overflowY:"auto",padding:"20px 24px"},t.dividers?{padding:"16px 24px",borderTop:`1px solid ${(e.vars||e).palette.divider}`,borderBottom:`1px solid ${(e.vars||e).palette.divider}`}:{[`.${bI.root} + &`]:{paddingTop:0}})),TI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiDialogContent"}),{className:o,dividers:i=!1}=r,s=X(r,EI),l=S({},r,{dividers:i}),a=PI(l);return C.jsx(_I,S({className:J(a.root,o),ownerState:l,ref:n},s))}),G1=TI;function MI(e){return pe("MuiDialogActions",e)}fe("MuiDialogActions",["root","spacing"]);const OI=["className","disableSpacing"],II=e=>{const{classes:t,disableSpacing:n}=e;return me({root:["root",!n&&"spacing"]},MI,t)},AI=H("div",{name:"MuiDialogActions",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,!n.disableSpacing&&t.spacing]}})(({ownerState:e})=>S({display:"flex",alignItems:"center",padding:8,justifyContent:"flex-end",flex:"0 0 auto"},!e.disableSpacing&&{"& > :not(:first-of-type)":{marginLeft:8}})),FI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiDialogActions"}),{className:o,disableSpacing:i=!1}=r,s=X(r,OI),l=S({},r,{disableSpacing:i}),a=II(l);return C.jsx(AI,S({className:J(a.root,o),ownerState:l,ref:n},s))}),K1=FI;function LI(e){return pe("MuiIconButton",e)}const NI=fe("MuiIconButton",["root","disabled","colorInherit","colorPrimary","colorSecondary","colorError","colorInfo","colorSuccess","colorWarning","edgeStart","edgeEnd","sizeSmall","sizeMedium","sizeLarge"]),zI=NI,DI=["edge","children","className","color","disabled","disableFocusRipple","size"],BI=e=>{const{classes:t,disabled:n,color:r,edge:o,size:i}=e,s={root:["root",n&&"disabled",r!=="default"&&`color${Y(r)}`,o&&`edge${Y(o)}`,`size${Y(i)}`]};return me(s,LI,t)},jI=H(bu,{name:"MuiIconButton",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.color!=="default"&&t[`color${Y(n.color)}`],n.edge&&t[`edge${Y(n.edge)}`],t[`size${Y(n.size)}`]]}})(({theme:e,ownerState:t})=>S({textAlign:"center",flex:"0 0 auto",fontSize:e.typography.pxToRem(24),padding:8,borderRadius:"50%",overflow:"visible",color:(e.vars||e).palette.action.active,transition:e.transitions.create("background-color",{duration:e.transitions.duration.shortest})},!t.disableRipple&&{"&:hover":{backgroundColor:e.vars?`rgba(${e.vars.palette.action.activeChannel} / ${e.vars.palette.action.hoverOpacity})`:ft(e.palette.action.active,e.palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:"transparent"}}},t.edge==="start"&&{marginLeft:t.size==="small"?-3:-12},t.edge==="end"&&{marginRight:t.size==="small"?-3:-12}),({theme:e,ownerState:t})=>{var n;const r=(n=(e.vars||e).palette)==null?void 0:n[t.color];return S({},t.color==="inherit"&&{color:"inherit"},t.color!=="inherit"&&t.color!=="default"&&S({color:r==null?void 0:r.main},!t.disableRipple&&{"&:hover":S({},r&&{backgroundColor:e.vars?`rgba(${r.mainChannel} / ${e.vars.palette.action.hoverOpacity})`:ft(r.main,e.palette.action.hoverOpacity)},{"@media (hover: none)":{backgroundColor:"transparent"}})}),t.size==="small"&&{padding:5,fontSize:e.typography.pxToRem(18)},t.size==="large"&&{padding:12,fontSize:e.typography.pxToRem(28)},{[`&.${zI.disabled}`]:{backgroundColor:"transparent",color:(e.vars||e).palette.action.disabled}})}),VI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiIconButton"}),{edge:o=!1,children:i,className:s,color:l="default",disabled:a=!1,disableFocusRipple:u=!1,size:c="medium"}=r,d=X(r,DI),f=S({},r,{edge:o,color:l,disabled:a,disableFocusRipple:u,size:c}),m=BI(f);return C.jsx(jI,S({className:J(m.root,s),centerRipple:!0,focusRipple:!u,disabled:a,ref:n,ownerState:f},d,{children:i}))}),q1=VI;function HI(e){return pe("MuiDialogContentText",e)}fe("MuiDialogContentText",["root"]);const WI=["children","className"],UI=e=>{const{classes:t}=e,r=me({root:["root"]},HI,t);return S({},t,r)},GI=H(yn,{shouldForwardProp:e=>an(e)||e==="classes",name:"MuiDialogContentText",slot:"Root",overridesResolver:(e,t)=>t.root})({}),KI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiDialogContentText"}),{className:o}=r,i=X(r,WI),s=UI(i);return C.jsx(GI,S({component:"p",variant:"body1",color:"text.secondary",ref:n,ownerState:i,className:J(s.root,o)},r,{classes:s}))}),qI=KI;function YI(e){return pe("MuiFormHelperText",e)}const XI=fe("MuiFormHelperText",["root","error","disabled","sizeSmall","sizeMedium","contained","focused","filled","required"]),Tg=XI;var Mg;const QI=["children","className","component","disabled","error","filled","focused","margin","required","variant"],ZI=e=>{const{classes:t,contained:n,size:r,disabled:o,error:i,filled:s,focused:l,required:a}=e,u={root:["root",o&&"disabled",i&&"error",r&&`size${Y(r)}`,n&&"contained",l&&"focused",s&&"filled",a&&"required"]};return me(u,YI,t)},JI=H("p",{name:"MuiFormHelperText",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.size&&t[`size${Y(n.size)}`],n.contained&&t.contained,n.filled&&t.filled]}})(({theme:e,ownerState:t})=>S({color:(e.vars||e).palette.text.secondary},e.typography.caption,{textAlign:"left",marginTop:3,marginRight:0,marginBottom:0,marginLeft:0,[`&.${Tg.disabled}`]:{color:(e.vars||e).palette.text.disabled},[`&.${Tg.error}`]:{color:(e.vars||e).palette.error.main}},t.size==="small"&&{marginTop:4},t.contained&&{marginLeft:14,marginRight:14})),eA=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiFormHelperText"}),{children:o,className:i,component:s="p"}=r,l=X(r,QI),a=_r(),u=ro({props:r,muiFormControl:a,states:["variant","size","disabled","error","filled","focused","required"]}),c=S({},r,{component:s,contained:u.variant==="filled"||u.variant==="outlined",variant:u.variant,size:u.size,disabled:u.disabled,error:u.error,filled:u.filled,focused:u.focused,required:u.required}),d=ZI(c);return C.jsx(JI,S({as:s,ownerState:c,className:J(d.root,i),ref:n},l,{children:o===" "?Mg||(Mg=C.jsx("span",{className:"notranslate",children:"​"})):o}))}),tA=eA;function nA(e){return pe("MuiTextField",e)}fe("MuiTextField",["root"]);const rA=["autoComplete","autoFocus","children","className","color","defaultValue","disabled","error","FormHelperTextProps","fullWidth","helperText","id","InputLabelProps","inputProps","InputProps","inputRef","label","maxRows","minRows","multiline","name","onBlur","onChange","onClick","onFocus","placeholder","required","rows","select","SelectProps","type","value","variant"],oA={standard:w1,filled:k1,outlined:Ip},iA=e=>{const{classes:t}=e;return me({root:["root"]},nA,t)},sA=H(Yd,{name:"MuiTextField",slot:"Root",overridesResolver:(e,t)=>t.root})({}),lA=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiTextField"}),{autoComplete:o,autoFocus:i=!1,children:s,className:l,color:a="primary",defaultValue:u,disabled:c=!1,error:d=!1,FormHelperTextProps:f,fullWidth:m=!1,helperText:y,id:v,InputLabelProps:k,inputProps:g,InputProps:p,inputRef:h,label:x,maxRows:w,minRows:R,multiline:$=!1,name:E,onBlur:M,onChange:P,onClick:I,onFocus:j,placeholder:A,required:_=!1,rows:O,select:N=!1,SelectProps:z,type:T,value:L,variant:F="outlined"}=r,q=X(r,rA),G=S({},r,{autoFocus:i,color:a,disabled:c,error:d,fullWidth:m,multiline:$,required:_,select:N,variant:F}),oe=iA(G),te={};F==="outlined"&&(k&&typeof k.shrink<"u"&&(te.notched=k.shrink),te.label=x),N&&((!z||!z.native)&&(te.id=void 0),te["aria-describedby"]=void 0);const Q=Va(v),se=y&&Q?`${Q}-helper-text`:void 0,Ce=x&&Q?`${Q}-label`:void 0,Se=oA[F],ae=C.jsx(Se,S({"aria-describedby":se,autoComplete:o,autoFocus:i,defaultValue:u,fullWidth:m,multiline:$,name:E,rows:O,maxRows:w,minRows:R,type:T,value:L,id:Q,inputRef:h,onBlur:M,onChange:P,onFocus:j,onClick:I,placeholder:A,inputProps:g},te,p));return C.jsxs(sA,S({className:J(oe.root,l),disabled:c,error:d,fullWidth:m,ref:n,required:_,color:a,variant:F,ownerState:G},q,{children:[x!=null&&x!==""&&C.jsx(Xd,S({htmlFor:Q,id:Ce},k,{children:x})),N?C.jsx(Jd,S({"aria-describedby":se,id:Q,labelId:Ce,value:L,input:ae},z,{children:s})):ae,y&&C.jsx(tA,S({id:se},f,{children:y}))]}))}),aA=lA,uA=no(C.jsx("path",{d:"M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"}),"Check"),cA=no(C.jsx("path",{d:"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4 6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"}),"FileCopy");function dA({open:e,onClose:t}){const{config:n}=Du(),r=wt.useRef(null),[o,i]=wt.useState(!1),[s,l]=wt.useState("");wt.useEffect(()=>{e&&(async()=>{const{default:c}=await aI(()=>import("./js-yaml-8bbf9398.js"),[]);l(c.dump(n))})()},[e,n]);const a=()=>{r.current&&(r.current.select(),document.execCommand("copy"),i(!0))},u=()=>{i(!1),t()};return C.jsxs(W1,{open:e,onClose:u,"aria-labelledby":"config-dialog-title",maxWidth:"md",fullWidth:!0,children:[C.jsx(U1,{id:"config-dialog-title",children:C.jsxs(Vn,{display:"flex",justifyContent:"space-between",alignItems:"center",children:[C.jsx(yn,{variant:"h6",children:"Config"}),C.jsx(q1,{onClick:a,children:o?C.jsx(uA,{}):C.jsx(cA,{})})]})}),C.jsx(G1,{children:C.jsx(yn,{variant:"body1",component:"div",children:C.jsx("textarea",{ref:r,readOnly:!0,value:s,style:{width:"100%",minHeight:"400px",fontFamily:"monospace",border:"1px solid #ccc"}})})}),C.jsx(K1,{children:C.jsx(xa,{onClick:u,color:"primary",children:"Close"})})]})}var Wp={},fA=ai;Object.defineProperty(Wp,"__esModule",{value:!0});var Y1=Wp.default=void 0,pA=fA(ui()),hA=C,mA=(0,pA.default)((0,hA.jsx)("path",{d:"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4 6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"}),"FileCopy");Y1=Wp.default=mA;var Up={},gA=ai;Object.defineProperty(Up,"__esModule",{value:!0});var X1=Up.default=void 0,vA=gA(ui()),yA=C,xA=(0,vA.default)((0,yA.jsx)("path",{d:"M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"}),"Check");X1=Up.default=xA;const SA=({open:e,onClose:t,shareUrl:n})=>{const r=b.useRef(null),[o,i]=b.useState(!1),s=()=>{r.current&&(r.current.select(),document.execCommand("copy"),i(!0))},l=()=>{t(),i(!1)};return C.jsxs(W1,{open:e,onClose:l,PaperProps:{style:{minWidth:"min(660px, 100%)"}},children:[C.jsx(U1,{children:"Your eval is ready to share"}),C.jsxs(G1,{children:[C.jsx(aA,{inputRef:r,value:n,fullWidth:!0,InputProps:{readOnly:!0,endAdornment:C.jsx(q1,{onClick:s,children:o?C.jsx(X1,{}):C.jsx(Y1,{})})}}),C.jsx(qI,{sx:{fontSize:"0.75rem"},children:"Shared URLs are deleted after 1 week."})]}),C.jsx(K1,{children:C.jsx(xa,{onClick:l,color:"primary",children:"Close"})})]})},Og=by(CM)(({theme:e})=>({maxWidth:"100%",flexWrap:"wrap",[e.breakpoints.down("sm")]:{flexDirection:"column"}}));function bA(){const{table:e,config:t}=Du(),[n,r]=b.useState(250),[o,i]=b.useState({}),[s,l]=b.useState([]),[a,u]=b.useState({}),c=(A,_)=>{u(O=>({...O,[A]:_}))},[d,f]=b.useState("all"),m=A=>{const _=A.target.value;f(_);const O={};P.prompts.forEach((N,z)=>{const T=`Prompt ${z+1}`;O[T]=_==="failures"}),u(O)},[y,v]=b.useState("break-all"),k=A=>{v(A.target.checked?"break-all":"break-word")},[g,p]=b.useState(!1),[h,x]=b.useState(""),[w,R]=b.useState(!1),$=async()=>{R(!0);try{const A=await fetch("https://api.promptfoo.dev/eval",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:{version:1,table:e}})}),{id:_}=await A.json(),O=`https://app.promptfoo.dev/eval/${_}`;x(O),p(!0)}catch{alert("Sorry, something went wrong.")}finally{R(!1)}},[E,M]=b.useState(!1);Uy(e,"Table data must be loaded before rendering ResultsView");const{head:P}=e,I=A=>{const{target:{value:_}}=A;l(typeof _=="string"?_.split(","):_);const O=[...P.vars.map((z,T)=>`Variable ${T+1}`),...P.prompts.map((z,T)=>`Prompt ${T+1}`)],N={};O.forEach(z=>{N[z]=(typeof _=="string"?_.split(","):_).includes(z)}),i(N)},j=[...P.vars.map((A,_)=>({value:`Variable ${_+1}`,label:`Variable ${_+1}`,group:"Variables"})),...P.prompts.map((A,_)=>({value:`Prompt ${_+1}`,label:`Prompt ${_+1}`,group:"Prompts"}))];return b.useEffect(()=>{l([...P.vars.map((A,_)=>`Variable ${_+1}`),...P.prompts.map((A,_)=>`Prompt ${_+1}`)])},[P]),C.jsxs("div",{children:[C.jsx(Vn,{py:"md",children:C.jsxs(Og,{direction:"row",spacing:8,alignItems:"center",children:[C.jsx(Vn,{children:C.jsxs(Yd,{sx:{m:1,minWidth:200},size:"small",children:[C.jsx(Xd,{id:"visible-columns-label",children:"Visible columns"}),C.jsx(Jd,{labelId:"visible-columns-label",id:"visible-columns",multiple:!0,value:s,onChange:I,input:C.jsx(Ip,{label:"Visible columns"}),renderValue:A=>A.join(", "),children:j.map(A=>C.jsxs(Cc,{dense:!0,value:A.value,children:[C.jsx(qd,{checked:s.indexOf(A.value)>-1}),C.jsx(J2,{primary:A.label})]},A.value))})]})}),C.jsx(Vn,{children:C.jsxs(Yd,{sx:{minWidth:180},size:"small",children:[C.jsx(Xd,{id:"failure-filter-mode-label",children:"Filter"}),C.jsxs(Jd,{labelId:"filter-mode-label",id:"filter-mode",value:d,onChange:m,label:"Filter",children:[C.jsx(Cc,{value:"all",children:"Show all results"}),C.jsx(Cc,{value:"failures",children:"Show only failures"})]})]})}),C.jsxs(Vn,{children:[C.jsxs(yn,{mt:2,children:["Max text length: ",n]}),C.jsx(bM,{min:25,max:1e3,value:n,onChange:(A,_)=>r(_)})]}),C.jsx(Vn,{children:C.jsx(Pc,{title:"Forcing line breaks makes it easier to adjust column widths to your liking",children:C.jsx(c1,{control:C.jsx(qd,{checked:y==="break-all",onChange:k}),label:"Force line breaks"})})}),C.jsx(Vn,{flexGrow:1}),C.jsx(Vn,{display:"flex",justifyContent:"flex-end",children:C.jsxs(Og,{direction:"row",spacing:2,children:[t&&C.jsx(Pc,{title:"View config",children:C.jsx(xa,{color:"primary",onClick:()=>M(!0),startIcon:C.jsx(_1,{}),children:"Config"})}),C.jsx(Pc,{title:"Generate a unique URL that others can access",children:C.jsx(xa,{color:"primary",onClick:$,disabled:w,startIcon:w?C.jsx(f2,{size:16}):C.jsx(P1,{}),children:"Share"})})]})})]})}),C.jsx(iI,{maxTextLength:n,columnVisibility:o,wordBreak:y,filterMode:d,failureFilter:a,onFailureFilterToggle:c}),C.jsx(dA,{open:E,onClose:()=>M(!1)}),C.jsx(SA,{open:g,onClose:()=>p(!1),shareUrl:h})]})}function wA(){return C.jsxs(Vn,{className:"logo",children:[C.jsx("img",{src:"/logo.svg",alt:"Promptfoo logo"})," ",C.jsx("span",{children:"promptfoo"})]})}var Gp={},CA=ai;Object.defineProperty(Gp,"__esModule",{value:!0});var Q1=Gp.default=void 0,kA=CA(ui()),RA=C,$A=(0,kA.default)((0,RA.jsx)("path",{d:"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z"}),"DarkMode");Q1=Gp.default=$A;var Kp={},EA=ai;Object.defineProperty(Kp,"__esModule",{value:!0});var Z1=Kp.default=void 0,PA=EA(ui()),_A=C,TA=(0,PA.default)((0,_A.jsx)("path",{d:"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z"}),"LightMode");Z1=Kp.default=TA;function MA({darkMode:e,onToggleDarkMode:t}){return C.jsxs("nav",{children:[C.jsx(wA,{}),C.jsx("div",{className:"dark-mode-toggle",onClick:t,children:e?C.jsx(Q1,{}):C.jsx(Z1,{})})]})}function OA(){const{table:e,setTable:t,setConfig:n}=Du(),[r,o]=b.useState(!1),i=b.useRef(!1),s=Sk("(prefers-color-scheme: dark)"),[l,a]=b.useState(s),u=b.useMemo(()=>yp({palette:{mode:l?"dark":"light"}}),[l]),c=()=>{a(!l),l?document.documentElement.removeAttribute("data-theme"):document.documentElement.setAttribute("data-theme","dark")};return b.useEffect(()=>{const d=async y=>{var g;if(i.current)return;i.current=!0;const k=await(await fetch(`https://api.promptfoo.dev/eval/${y}`)).json();t(((g=k.data.results)==null?void 0:g.table)||k.data.table),n(k.data.config),o(!0)},f=Bl("http://localhost:15500"),m=window.location.pathname.match(/\/eval\/([\w:-]+)/);if(m){const y=m[1];d(y)}else f.on("init",y=>{console.log("Initialized socket connection",y),o(!0),t(y.results.table),n(y.config)}),f.on("update",y=>{console.log("Received data update",y),t(y.results.table),n(y.config)});return()=>{f.disconnect()}},[t,n]),C.jsxs(oR,{theme:u,children:[C.jsx(MA,{darkMode:l,onToggleDarkMode:c}),r&&e?C.jsx(bA,{}):C.jsx("div",{children:"Loading..."})]})}zc.createRoot(document.getElementById("root")).render(C.jsx(wt.StrictMode,{children:C.jsx(OA,{})}));
199
+ */var zu=b,WO=HO;function UO(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var GO=typeof Object.is=="function"?Object.is:UO,KO=WO.useSyncExternalStore,qO=zu.useRef,YO=zu.useEffect,XO=zu.useMemo,QO=zu.useDebugValue;B1.useSyncExternalStoreWithSelector=function(e,t,n,r,o){var i=qO(null);if(i.current===null){var s={hasValue:!1,value:null};i.current=s}else s=i.current;i=XO(function(){function a(m){if(!u){if(u=!0,c=m,m=r(m),o!==void 0&&s.hasValue){var y=s.value;if(o(y,m))return d=y}return d=m}if(y=d,GO(c,m))return y;var v=r(m);return o!==void 0&&o(y,v)?y:(c=m,d=v)}var u=!1,c,d,f=n===void 0?null:n;return[function(){return a(t())},f===null?void 0:function(){return a(f())}]},[t,n,r,o]);var l=KO(e,i[0],i[1]);return YO(function(){s.hasValue=!0,s.value=l},[l]),QO(l),l};D1.exports=B1;var ZO=D1.exports;const JO=of(ZO),{useSyncExternalStoreWithSelector:eI}=JO;function tI(e,t=e.getState,n){const r=eI(e.subscribe,e.getState,e.getServerState||e.getState,t,n);return b.useDebugValue(r),r}const Eg=e=>{({BASE_URL:"/",MODE:"production",DEV:!1,PROD:!0,SSR:!1}&&"production")!=="production"&&typeof e!="function"&&console.warn("[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`.");const t=typeof e=="function"?IO(e):e,n=(r,o)=>tI(t,r,o);return Object.assign(n,t),n},nI=e=>e?Eg(e):Eg;var rI=e=>(({BASE_URL:"/",MODE:"production",DEV:!1,PROD:!0,SSR:!1}&&"production")!=="production"&&console.warn("[DEPRECATED] Default export is deprecated. Instead use `import { create } from 'zustand'`."),nI(e));const Du=rI(e=>({table:null,setTable:t=>e(()=>({table:t})),config:null,setConfig:t=>e(()=>({config:t}))}));function Hp({text:e,maxLength:t}){const[n,r]=b.useState(!0),o=()=>{r(!n)},i=()=>e.length<=t?e:n?C.jsx(C.Fragment,{children:C.jsxs("span",{style:{cursor:"pointer"},onClick:o,children:[e.substring(0,t)," ..."]})}):C.jsx(C.Fragment,{children:C.jsx("span",{style:{cursor:"pointer"},onClick:o,children:e})});return C.jsx("div",{children:i()})}function oI({text:e,maxTextLength:t,rowIndex:n,promptIndex:r,onRating:o}){const i=e.startsWith("[PASS] "),s=e.startsWith("[FAIL] ");let l=[];i?e=e.substring(7):s&&(e.includes("---")?(l=e.split("---"),e=l.slice(1).join("---")):(l=["[FAIL]"],e.startsWith("[FAIL] ")&&(e=e.substring(7))));const a=u=>{o(n,r,u)};return C.jsxs(C.Fragment,{children:[C.jsxs("div",{className:"cell",children:[i&&C.jsx("div",{className:"status pass",children:"[PASS]"}),s&&C.jsx("div",{className:"status fail",children:l[0]})," ",C.jsx(Hp,{text:e,maxLength:t})]}),C.jsxs("div",{className:"cell-rating",children:[C.jsx("span",{className:"rating",onClick:()=>a(!0),children:"👍"}),C.jsx("span",{className:"rating",onClick:()=>a(!1),children:"👎"})]})]})}function Pg({text:e,maxLength:t,smallText:n}){return C.jsxs("div",{children:[C.jsx(Hp,{text:e,maxLength:t}),C.jsx("span",{className:"smalltext",children:n})]})}function iI({maxTextLength:e,columnVisibility:t,wordBreak:n,filterMode:r,failureFilter:o,onFailureFilterToggle:i}){const{table:s,setTable:l}=Du();Uy(s,"Table should be defined");const{head:a,body:u}=s,c=a.prompts.map((p,h)=>u.reduce((x,w)=>x+(w.outputs[h].startsWith("[PASS]")?1:0),0)),d=(p,h,x)=>{const w=[...u],R={...w[p]},$=[...R.outputs],E=x?`[PASS] ${$[h].replace(/^\[(PASS|FAIL)\] /,"")}`:`[FAIL] ${$[h].replace(/^\[(PASS|FAIL)\] /,"")}`;$[h]=E,R.outputs=$,w[p]=R,l({head:a,body:w})},f=c.reduce((p,h,x,w)=>h>w[p]?x:p,0),m=c[f],y=EO(),v=[y.group({id:"vars",header:()=>C.jsx("span",{children:"Variables"}),columns:a.vars.map((p,h)=>y.accessor(x=>x.vars[h],{id:`Variable ${h+1}`,header:()=>C.jsx(Pg,{smallText:`Variable ${h+1}`,text:p,maxLength:e}),cell:x=>C.jsx(Hp,{text:x.getValue(),maxLength:e}),size:50}))}),y.group({id:"prompts",header:()=>C.jsx("span",{children:"Outputs"}),columns:a.prompts.map((p,h)=>y.accessor(x=>x.outputs[h],{id:`Prompt ${h+1}`,header:()=>{const x=(c[h]/u.length*100).toFixed(2),w=c[h]===m&&m!==0,R=`Prompt ${h+1}`,$=o[R]||!1;return C.jsxs(C.Fragment,{children:[C.jsx(Pg,{smallText:`Prompt ${h+1}`,text:p,maxLength:e}),r==="failures"&&C.jsx(c1,{sx:{"& .MuiFormControlLabel-label":{fontSize:"0.75rem"}},control:C.jsx(qd,{checked:$,onChange:E=>i(R,E.target.checked)}),label:"Show failures"}),C.jsxs("div",{className:`summary ${w?"highlight":""}`,children:["Passing: ",C.jsxs("strong",{children:[x,"%"]})," (",c[h]," / ",u.length,")"]})]})},cell:x=>C.jsx(oI,{text:x.getValue(),maxTextLength:e,rowIndex:x.row.index,promptIndex:h,onRating:d})}))})],k=b.useMemo(()=>r==="failures"?Object.values(o).every(p=>!p)?u:u.filter(p=>p.outputs.some((h,x)=>{const w=`Prompt ${x+1}`,R=h.startsWith("[FAIL] ");return o[w]&&R})):u,[u,o,r]),g=OO({data:k,columns:v,columnResizeMode:"onChange",getCoreRowModel:PO(),state:{columnVisibility:t}});return C.jsxs("table",{style:{wordBreak:n},children:[C.jsx("thead",{children:g.getHeaderGroups().map(p=>C.jsx("tr",{className:"header",children:p.headers.map(h=>C.jsxs("th",{key:h.id,colSpan:h.colSpan,style:{width:h.getSize()},children:[h.isPlaceholder?null:Rg(h.column.columnDef.header,h.getContext()),C.jsx("div",{onMouseDown:h.getResizeHandler(),onTouchStart:h.getResizeHandler(),className:`resizer ${h.column.getIsResizing()?"isResizing":""}`})]}))},p.id))}),C.jsx("tbody",{children:g.getRowModel().rows.map((p,h)=>{let x=!1;return C.jsx("tr",{children:p.getVisibleCells().map(w=>{const R=w.column.id.startsWith("Variable"),$=!R&&!x;$&&(x=!0);const E=h===0&&!R;return C.jsx("td",{key:w.id,style:{width:w.column.getSize()},className:`${R?"variable":""} ${E?"first-prompt-row":""} ${$?"first-prompt-col":""}`,children:Rg(w.column.columnDef.cell,w.getContext())})})},p.id)})})]})}const sI="modulepreload",lI=function(e){return"/"+e},_g={},aI=function(t,n,r){if(!n||n.length===0)return t();const o=document.getElementsByTagName("link");return Promise.all(n.map(i=>{if(i=lI(i),i in _g)return;_g[i]=!0;const s=i.endsWith(".css"),l=s?'[rel="stylesheet"]':"";if(!!r)for(let c=o.length-1;c>=0;c--){const d=o[c];if(d.href===i&&(!s||d.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${i}"]${l}`))return;const u=document.createElement("link");if(u.rel=s?"stylesheet":sI,s||(u.as="script",u.crossOrigin=""),u.href=i,document.head.appendChild(u),s)return new Promise((c,d)=>{u.addEventListener("load",c),u.addEventListener("error",()=>d(new Error(`Unable to preload CSS for ${i}`)))})})).then(()=>t())};function uI(e){return pe("MuiDialog",e)}const cI=fe("MuiDialog",["root","scrollPaper","scrollBody","container","paper","paperScrollPaper","paperScrollBody","paperWidthFalse","paperWidthXs","paperWidthSm","paperWidthMd","paperWidthLg","paperWidthXl","paperFullWidth","paperFullScreen"]),Nc=cI,dI=b.createContext({}),H1=dI,fI=["aria-describedby","aria-labelledby","BackdropComponent","BackdropProps","children","className","disableEscapeKeyDown","fullScreen","fullWidth","maxWidth","onBackdropClick","onClose","open","PaperComponent","PaperProps","scroll","TransitionComponent","transitionDuration","TransitionProps"],pI=H(v1,{name:"MuiDialog",slot:"Backdrop",overrides:(e,t)=>t.backdrop})({zIndex:-1}),hI=e=>{const{classes:t,scroll:n,maxWidth:r,fullWidth:o,fullScreen:i}=e,s={root:["root"],container:["container",`scroll${Y(n)}`],paper:["paper",`paperScroll${Y(n)}`,`paperWidth${Y(String(r))}`,o&&"paperFullWidth",i&&"paperFullScreen"]};return me(s,uI,t)},mI=H(y1,{name:"MuiDialog",slot:"Root",overridesResolver:(e,t)=>t.root})({"@media print":{position:"absolute !important"}}),gI=H("div",{name:"MuiDialog",slot:"Container",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.container,t[`scroll${Y(n.scroll)}`]]}})(({ownerState:e})=>S({height:"100%","@media print":{height:"auto"},outline:0},e.scroll==="paper"&&{display:"flex",justifyContent:"center",alignItems:"center"},e.scroll==="body"&&{overflowY:"auto",overflowX:"hidden",textAlign:"center","&:after":{content:'""',display:"inline-block",verticalAlign:"middle",height:"100%",width:"0"}})),vI=H(Nu,{name:"MuiDialog",slot:"Paper",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.paper,t[`scrollPaper${Y(n.scroll)}`],t[`paperWidth${Y(String(n.maxWidth))}`],n.fullWidth&&t.paperFullWidth,n.fullScreen&&t.paperFullScreen]}})(({theme:e,ownerState:t})=>S({margin:32,position:"relative",overflowY:"auto","@media print":{overflowY:"visible",boxShadow:"none"}},t.scroll==="paper"&&{display:"flex",flexDirection:"column",maxHeight:"calc(100% - 64px)"},t.scroll==="body"&&{display:"inline-block",verticalAlign:"middle",textAlign:"left"},!t.maxWidth&&{maxWidth:"calc(100% - 64px)"},t.maxWidth==="xs"&&{maxWidth:e.breakpoints.unit==="px"?Math.max(e.breakpoints.values.xs,444):`${e.breakpoints.values.xs}${e.breakpoints.unit}`,[`&.${Nc.paperScrollBody}`]:{[e.breakpoints.down(Math.max(e.breakpoints.values.xs,444)+32*2)]:{maxWidth:"calc(100% - 64px)"}}},t.maxWidth&&t.maxWidth!=="xs"&&{maxWidth:`${e.breakpoints.values[t.maxWidth]}${e.breakpoints.unit}`,[`&.${Nc.paperScrollBody}`]:{[e.breakpoints.down(e.breakpoints.values[t.maxWidth]+32*2)]:{maxWidth:"calc(100% - 64px)"}}},t.fullWidth&&{width:"calc(100% - 64px)"},t.fullScreen&&{margin:0,width:"100%",maxWidth:"100%",height:"100%",maxHeight:"none",borderRadius:0,[`&.${Nc.paperScrollBody}`]:{margin:0,maxWidth:"100%"}})),yI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiDialog"}),o=si(),i={enter:o.transitions.duration.enteringScreen,exit:o.transitions.duration.leavingScreen},{"aria-describedby":s,"aria-labelledby":l,BackdropComponent:a,BackdropProps:u,children:c,className:d,disableEscapeKeyDown:f=!1,fullScreen:m=!1,fullWidth:y=!1,maxWidth:v="sm",onBackdropClick:k,onClose:g,open:p,PaperComponent:h=Nu,PaperProps:x={},scroll:w="paper",TransitionComponent:R=g1,transitionDuration:$=i,TransitionProps:E}=r,M=X(r,fI),P=S({},r,{disableEscapeKeyDown:f,fullScreen:m,fullWidth:y,maxWidth:v,scroll:w}),I=hI(P),j=b.useRef(),A=z=>{j.current=z.target===z.currentTarget},_=z=>{j.current&&(j.current=null,k&&k(z),g&&g(z,"backdropClick"))},O=Va(l),N=b.useMemo(()=>({titleId:O}),[O]);return C.jsx(mI,S({className:J(I.root,d),closeAfterTransition:!0,components:{Backdrop:pI},componentsProps:{backdrop:S({transitionDuration:$,as:a},u)},disableEscapeKeyDown:f,onClose:g,open:p,ref:n,onClick:_,ownerState:P},M,{children:C.jsx(R,S({appear:!0,in:p,timeout:$,role:"presentation"},E,{children:C.jsx(gI,{className:J(I.container),onMouseDown:A,ownerState:P,children:C.jsx(vI,S({as:h,elevation:24,role:"dialog","aria-describedby":s,"aria-labelledby":O},x,{className:J(I.paper,x.className),ownerState:P,children:C.jsx(H1.Provider,{value:N,children:c})}))})}))}))}),W1=yI;function xI(e){return pe("MuiDialogTitle",e)}const SI=fe("MuiDialogTitle",["root"]),bI=SI,wI=["className","id"],CI=e=>{const{classes:t}=e;return me({root:["root"]},xI,t)},kI=H(yn,{name:"MuiDialogTitle",slot:"Root",overridesResolver:(e,t)=>t.root})({padding:"16px 24px",flex:"0 0 auto"}),RI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiDialogTitle"}),{className:o,id:i}=r,s=X(r,wI),l=r,a=CI(l),{titleId:u=i}=b.useContext(H1);return C.jsx(kI,S({component:"h2",className:J(a.root,o),ownerState:l,ref:n,variant:"h6",id:i??u},s))}),U1=RI;function $I(e){return pe("MuiDialogContent",e)}fe("MuiDialogContent",["root","dividers"]);const EI=["className","dividers"],PI=e=>{const{classes:t,dividers:n}=e;return me({root:["root",n&&"dividers"]},$I,t)},_I=H("div",{name:"MuiDialogContent",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.dividers&&t.dividers]}})(({theme:e,ownerState:t})=>S({flex:"1 1 auto",WebkitOverflowScrolling:"touch",overflowY:"auto",padding:"20px 24px"},t.dividers?{padding:"16px 24px",borderTop:`1px solid ${(e.vars||e).palette.divider}`,borderBottom:`1px solid ${(e.vars||e).palette.divider}`}:{[`.${bI.root} + &`]:{paddingTop:0}})),TI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiDialogContent"}),{className:o,dividers:i=!1}=r,s=X(r,EI),l=S({},r,{dividers:i}),a=PI(l);return C.jsx(_I,S({className:J(a.root,o),ownerState:l,ref:n},s))}),G1=TI;function MI(e){return pe("MuiDialogActions",e)}fe("MuiDialogActions",["root","spacing"]);const OI=["className","disableSpacing"],II=e=>{const{classes:t,disableSpacing:n}=e;return me({root:["root",!n&&"spacing"]},MI,t)},AI=H("div",{name:"MuiDialogActions",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,!n.disableSpacing&&t.spacing]}})(({ownerState:e})=>S({display:"flex",alignItems:"center",padding:8,justifyContent:"flex-end",flex:"0 0 auto"},!e.disableSpacing&&{"& > :not(:first-of-type)":{marginLeft:8}})),FI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiDialogActions"}),{className:o,disableSpacing:i=!1}=r,s=X(r,OI),l=S({},r,{disableSpacing:i}),a=II(l);return C.jsx(AI,S({className:J(a.root,o),ownerState:l,ref:n},s))}),K1=FI;function LI(e){return pe("MuiIconButton",e)}const NI=fe("MuiIconButton",["root","disabled","colorInherit","colorPrimary","colorSecondary","colorError","colorInfo","colorSuccess","colorWarning","edgeStart","edgeEnd","sizeSmall","sizeMedium","sizeLarge"]),zI=NI,DI=["edge","children","className","color","disabled","disableFocusRipple","size"],BI=e=>{const{classes:t,disabled:n,color:r,edge:o,size:i}=e,s={root:["root",n&&"disabled",r!=="default"&&`color${Y(r)}`,o&&`edge${Y(o)}`,`size${Y(i)}`]};return me(s,LI,t)},jI=H(bu,{name:"MuiIconButton",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.color!=="default"&&t[`color${Y(n.color)}`],n.edge&&t[`edge${Y(n.edge)}`],t[`size${Y(n.size)}`]]}})(({theme:e,ownerState:t})=>S({textAlign:"center",flex:"0 0 auto",fontSize:e.typography.pxToRem(24),padding:8,borderRadius:"50%",overflow:"visible",color:(e.vars||e).palette.action.active,transition:e.transitions.create("background-color",{duration:e.transitions.duration.shortest})},!t.disableRipple&&{"&:hover":{backgroundColor:e.vars?`rgba(${e.vars.palette.action.activeChannel} / ${e.vars.palette.action.hoverOpacity})`:ft(e.palette.action.active,e.palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:"transparent"}}},t.edge==="start"&&{marginLeft:t.size==="small"?-3:-12},t.edge==="end"&&{marginRight:t.size==="small"?-3:-12}),({theme:e,ownerState:t})=>{var n;const r=(n=(e.vars||e).palette)==null?void 0:n[t.color];return S({},t.color==="inherit"&&{color:"inherit"},t.color!=="inherit"&&t.color!=="default"&&S({color:r==null?void 0:r.main},!t.disableRipple&&{"&:hover":S({},r&&{backgroundColor:e.vars?`rgba(${r.mainChannel} / ${e.vars.palette.action.hoverOpacity})`:ft(r.main,e.palette.action.hoverOpacity)},{"@media (hover: none)":{backgroundColor:"transparent"}})}),t.size==="small"&&{padding:5,fontSize:e.typography.pxToRem(18)},t.size==="large"&&{padding:12,fontSize:e.typography.pxToRem(28)},{[`&.${zI.disabled}`]:{backgroundColor:"transparent",color:(e.vars||e).palette.action.disabled}})}),VI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiIconButton"}),{edge:o=!1,children:i,className:s,color:l="default",disabled:a=!1,disableFocusRipple:u=!1,size:c="medium"}=r,d=X(r,DI),f=S({},r,{edge:o,color:l,disabled:a,disableFocusRipple:u,size:c}),m=BI(f);return C.jsx(jI,S({className:J(m.root,s),centerRipple:!0,focusRipple:!u,disabled:a,ref:n,ownerState:f},d,{children:i}))}),q1=VI;function HI(e){return pe("MuiDialogContentText",e)}fe("MuiDialogContentText",["root"]);const WI=["children","className"],UI=e=>{const{classes:t}=e,r=me({root:["root"]},HI,t);return S({},t,r)},GI=H(yn,{shouldForwardProp:e=>an(e)||e==="classes",name:"MuiDialogContentText",slot:"Root",overridesResolver:(e,t)=>t.root})({}),KI=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiDialogContentText"}),{className:o}=r,i=X(r,WI),s=UI(i);return C.jsx(GI,S({component:"p",variant:"body1",color:"text.secondary",ref:n,ownerState:i,className:J(s.root,o)},r,{classes:s}))}),qI=KI;function YI(e){return pe("MuiFormHelperText",e)}const XI=fe("MuiFormHelperText",["root","error","disabled","sizeSmall","sizeMedium","contained","focused","filled","required"]),Tg=XI;var Mg;const QI=["children","className","component","disabled","error","filled","focused","margin","required","variant"],ZI=e=>{const{classes:t,contained:n,size:r,disabled:o,error:i,filled:s,focused:l,required:a}=e,u={root:["root",o&&"disabled",i&&"error",r&&`size${Y(r)}`,n&&"contained",l&&"focused",s&&"filled",a&&"required"]};return me(u,YI,t)},JI=H("p",{name:"MuiFormHelperText",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:n}=e;return[t.root,n.size&&t[`size${Y(n.size)}`],n.contained&&t.contained,n.filled&&t.filled]}})(({theme:e,ownerState:t})=>S({color:(e.vars||e).palette.text.secondary},e.typography.caption,{textAlign:"left",marginTop:3,marginRight:0,marginBottom:0,marginLeft:0,[`&.${Tg.disabled}`]:{color:(e.vars||e).palette.text.disabled},[`&.${Tg.error}`]:{color:(e.vars||e).palette.error.main}},t.size==="small"&&{marginTop:4},t.contained&&{marginLeft:14,marginRight:14})),eA=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiFormHelperText"}),{children:o,className:i,component:s="p"}=r,l=X(r,QI),a=_r(),u=ro({props:r,muiFormControl:a,states:["variant","size","disabled","error","filled","focused","required"]}),c=S({},r,{component:s,contained:u.variant==="filled"||u.variant==="outlined",variant:u.variant,size:u.size,disabled:u.disabled,error:u.error,filled:u.filled,focused:u.focused,required:u.required}),d=ZI(c);return C.jsx(JI,S({as:s,ownerState:c,className:J(d.root,i),ref:n},l,{children:o===" "?Mg||(Mg=C.jsx("span",{className:"notranslate",children:"​"})):o}))}),tA=eA;function nA(e){return pe("MuiTextField",e)}fe("MuiTextField",["root"]);const rA=["autoComplete","autoFocus","children","className","color","defaultValue","disabled","error","FormHelperTextProps","fullWidth","helperText","id","InputLabelProps","inputProps","InputProps","inputRef","label","maxRows","minRows","multiline","name","onBlur","onChange","onClick","onFocus","placeholder","required","rows","select","SelectProps","type","value","variant"],oA={standard:w1,filled:k1,outlined:Ip},iA=e=>{const{classes:t}=e;return me({root:["root"]},nA,t)},sA=H(Yd,{name:"MuiTextField",slot:"Root",overridesResolver:(e,t)=>t.root})({}),lA=b.forwardRef(function(t,n){const r=xe({props:t,name:"MuiTextField"}),{autoComplete:o,autoFocus:i=!1,children:s,className:l,color:a="primary",defaultValue:u,disabled:c=!1,error:d=!1,FormHelperTextProps:f,fullWidth:m=!1,helperText:y,id:v,InputLabelProps:k,inputProps:g,InputProps:p,inputRef:h,label:x,maxRows:w,minRows:R,multiline:$=!1,name:E,onBlur:M,onChange:P,onClick:I,onFocus:j,placeholder:A,required:_=!1,rows:O,select:N=!1,SelectProps:z,type:T,value:L,variant:F="outlined"}=r,q=X(r,rA),G=S({},r,{autoFocus:i,color:a,disabled:c,error:d,fullWidth:m,multiline:$,required:_,select:N,variant:F}),oe=iA(G),te={};F==="outlined"&&(k&&typeof k.shrink<"u"&&(te.notched=k.shrink),te.label=x),N&&((!z||!z.native)&&(te.id=void 0),te["aria-describedby"]=void 0);const Q=Va(v),se=y&&Q?`${Q}-helper-text`:void 0,Ce=x&&Q?`${Q}-label`:void 0,Se=oA[F],ae=C.jsx(Se,S({"aria-describedby":se,autoComplete:o,autoFocus:i,defaultValue:u,fullWidth:m,multiline:$,name:E,rows:O,maxRows:w,minRows:R,type:T,value:L,id:Q,inputRef:h,onBlur:M,onChange:P,onFocus:j,onClick:I,placeholder:A,inputProps:g},te,p));return C.jsxs(sA,S({className:J(oe.root,l),disabled:c,error:d,fullWidth:m,ref:n,required:_,color:a,variant:F,ownerState:G},q,{children:[x!=null&&x!==""&&C.jsx(Xd,S({htmlFor:Q,id:Ce},k,{children:x})),N?C.jsx(Jd,S({"aria-describedby":se,id:Q,labelId:Ce,value:L,input:ae},z,{children:s})):ae,y&&C.jsx(tA,S({id:se},f,{children:y}))]}))}),aA=lA,uA=no(C.jsx("path",{d:"M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"}),"Check"),cA=no(C.jsx("path",{d:"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4 6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"}),"FileCopy");function dA({open:e,onClose:t}){const{config:n}=Du(),r=wt.useRef(null),[o,i]=wt.useState(!1),[s,l]=wt.useState("");wt.useEffect(()=>{e&&(async()=>{const{default:c}=await aI(()=>import("./js-yaml-8bbf9398.js"),[]);l(c.dump(n))})()},[e,n]);const a=()=>{r.current&&(r.current.select(),document.execCommand("copy"),i(!0))},u=()=>{i(!1),t()};return C.jsxs(W1,{open:e,onClose:u,"aria-labelledby":"config-dialog-title",maxWidth:"md",fullWidth:!0,children:[C.jsx(U1,{id:"config-dialog-title",children:C.jsxs(Vn,{display:"flex",justifyContent:"space-between",alignItems:"center",children:[C.jsx(yn,{variant:"h6",children:"Config"}),C.jsx(q1,{onClick:a,children:o?C.jsx(uA,{}):C.jsx(cA,{})})]})}),C.jsx(G1,{children:C.jsx(yn,{variant:"body1",component:"div",children:C.jsx("textarea",{ref:r,readOnly:!0,value:s,style:{width:"100%",minHeight:"400px",fontFamily:"monospace",border:"1px solid #ccc"}})})}),C.jsx(K1,{children:C.jsx(xa,{onClick:u,color:"primary",children:"Close"})})]})}var Wp={},fA=ai;Object.defineProperty(Wp,"__esModule",{value:!0});var Y1=Wp.default=void 0,pA=fA(ui()),hA=C,mA=(0,pA.default)((0,hA.jsx)("path",{d:"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4 6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"}),"FileCopy");Y1=Wp.default=mA;var Up={},gA=ai;Object.defineProperty(Up,"__esModule",{value:!0});var X1=Up.default=void 0,vA=gA(ui()),yA=C,xA=(0,vA.default)((0,yA.jsx)("path",{d:"M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"}),"Check");X1=Up.default=xA;const SA=({open:e,onClose:t,shareUrl:n})=>{const r=b.useRef(null),[o,i]=b.useState(!1),s=()=>{r.current&&(r.current.select(),document.execCommand("copy"),i(!0))},l=()=>{t(),i(!1)};return C.jsxs(W1,{open:e,onClose:l,PaperProps:{style:{minWidth:"min(660px, 100%)"}},children:[C.jsx(U1,{children:"Your eval is ready to share"}),C.jsxs(G1,{children:[C.jsx(aA,{inputRef:r,value:n,fullWidth:!0,InputProps:{readOnly:!0,endAdornment:C.jsx(q1,{onClick:s,children:o?C.jsx(X1,{}):C.jsx(Y1,{})})}}),C.jsx(qI,{sx:{fontSize:"0.75rem"},children:"Shared URLs are deleted after 1 week."})]}),C.jsx(K1,{children:C.jsx(xa,{onClick:l,color:"primary",children:"Close"})})]})},Og=by(CM)(({theme:e})=>({maxWidth:"100%",flexWrap:"wrap",[e.breakpoints.down("sm")]:{flexDirection:"column"}}));function bA(){const{table:e,config:t}=Du(),[n,r]=b.useState(250),[o,i]=b.useState({}),[s,l]=b.useState([]),[a,u]=b.useState({}),c=(A,_)=>{u(O=>({...O,[A]:_}))},[d,f]=b.useState("all"),m=A=>{const _=A.target.value;f(_);const O={};P.prompts.forEach((N,z)=>{const T=`Prompt ${z+1}`;O[T]=_==="failures"}),u(O)},[y,v]=b.useState("break-all"),k=A=>{v(A.target.checked?"break-all":"break-word")},[g,p]=b.useState(!1),[h,x]=b.useState(""),[w,R]=b.useState(!1),$=async()=>{R(!0);try{const A=await fetch("https://api.promptfoo.dev/eval",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:{version:1,results:{table:e},config:t}})}),{id:_}=await A.json(),O=`https://app.promptfoo.dev/eval/${_}`;x(O),p(!0)}catch{alert("Sorry, something went wrong.")}finally{R(!1)}},[E,M]=b.useState(!1);Uy(e,"Table data must be loaded before rendering ResultsView");const{head:P}=e,I=A=>{const{target:{value:_}}=A;l(typeof _=="string"?_.split(","):_);const O=[...P.vars.map((z,T)=>`Variable ${T+1}`),...P.prompts.map((z,T)=>`Prompt ${T+1}`)],N={};O.forEach(z=>{N[z]=(typeof _=="string"?_.split(","):_).includes(z)}),i(N)},j=[...P.vars.map((A,_)=>({value:`Variable ${_+1}`,label:`Variable ${_+1}`,group:"Variables"})),...P.prompts.map((A,_)=>({value:`Prompt ${_+1}`,label:`Prompt ${_+1}`,group:"Prompts"}))];return b.useEffect(()=>{l([...P.vars.map((A,_)=>`Variable ${_+1}`),...P.prompts.map((A,_)=>`Prompt ${_+1}`)])},[P]),C.jsxs("div",{children:[C.jsx(Vn,{py:"md",children:C.jsxs(Og,{direction:"row",spacing:8,alignItems:"center",children:[C.jsx(Vn,{children:C.jsxs(Yd,{sx:{m:1,minWidth:200},size:"small",children:[C.jsx(Xd,{id:"visible-columns-label",children:"Visible columns"}),C.jsx(Jd,{labelId:"visible-columns-label",id:"visible-columns",multiple:!0,value:s,onChange:I,input:C.jsx(Ip,{label:"Visible columns"}),renderValue:A=>A.join(", "),children:j.map(A=>C.jsxs(Cc,{dense:!0,value:A.value,children:[C.jsx(qd,{checked:s.indexOf(A.value)>-1}),C.jsx(J2,{primary:A.label})]},A.value))})]})}),C.jsx(Vn,{children:C.jsxs(Yd,{sx:{minWidth:180},size:"small",children:[C.jsx(Xd,{id:"failure-filter-mode-label",children:"Filter"}),C.jsxs(Jd,{labelId:"filter-mode-label",id:"filter-mode",value:d,onChange:m,label:"Filter",children:[C.jsx(Cc,{value:"all",children:"Show all results"}),C.jsx(Cc,{value:"failures",children:"Show only failures"})]})]})}),C.jsxs(Vn,{children:[C.jsxs(yn,{mt:2,children:["Max text length: ",n]}),C.jsx(bM,{min:25,max:1e3,value:n,onChange:(A,_)=>r(_)})]}),C.jsx(Vn,{children:C.jsx(Pc,{title:"Forcing line breaks makes it easier to adjust column widths to your liking",children:C.jsx(c1,{control:C.jsx(qd,{checked:y==="break-all",onChange:k}),label:"Force line breaks"})})}),C.jsx(Vn,{flexGrow:1}),C.jsx(Vn,{display:"flex",justifyContent:"flex-end",children:C.jsxs(Og,{direction:"row",spacing:2,children:[t&&C.jsx(Pc,{title:"View config",children:C.jsx(xa,{color:"primary",onClick:()=>M(!0),startIcon:C.jsx(_1,{}),children:"Config"})}),C.jsx(Pc,{title:"Generate a unique URL that others can access",children:C.jsx(xa,{color:"primary",onClick:$,disabled:w,startIcon:w?C.jsx(f2,{size:16}):C.jsx(P1,{}),children:"Share"})})]})})]})}),C.jsx(iI,{maxTextLength:n,columnVisibility:o,wordBreak:y,filterMode:d,failureFilter:a,onFailureFilterToggle:c}),C.jsx(dA,{open:E,onClose:()=>M(!1)}),C.jsx(SA,{open:g,onClose:()=>p(!1),shareUrl:h})]})}function wA(){return C.jsxs(Vn,{className:"logo",children:[C.jsx("img",{src:"/logo.svg",alt:"Promptfoo logo"})," ",C.jsx("span",{children:"promptfoo"})]})}var Gp={},CA=ai;Object.defineProperty(Gp,"__esModule",{value:!0});var Q1=Gp.default=void 0,kA=CA(ui()),RA=C,$A=(0,kA.default)((0,RA.jsx)("path",{d:"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z"}),"DarkMode");Q1=Gp.default=$A;var Kp={},EA=ai;Object.defineProperty(Kp,"__esModule",{value:!0});var Z1=Kp.default=void 0,PA=EA(ui()),_A=C,TA=(0,PA.default)((0,_A.jsx)("path",{d:"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z"}),"LightMode");Z1=Kp.default=TA;function MA({darkMode:e,onToggleDarkMode:t}){return C.jsxs("nav",{children:[C.jsx(wA,{}),C.jsx("div",{className:"dark-mode-toggle",onClick:t,children:e?C.jsx(Q1,{}):C.jsx(Z1,{})})]})}function OA(){const{table:e,setTable:t,setConfig:n}=Du(),[r,o]=b.useState(!1),i=b.useRef(!1),s=Sk("(prefers-color-scheme: dark)"),[l,a]=b.useState(s),u=b.useMemo(()=>yp({palette:{mode:l?"dark":"light"}}),[l]),c=()=>{a(!l),l?document.documentElement.removeAttribute("data-theme"):document.documentElement.setAttribute("data-theme","dark")};return b.useEffect(()=>{const d=async y=>{var g;if(i.current)return;i.current=!0;const k=await(await fetch(`https://api.promptfoo.dev/eval/${y}`)).json();t(((g=k.data.results)==null?void 0:g.table)||k.data.table),n(k.data.config),o(!0)},f=Bl("http://localhost:15500"),m=window.location.pathname.match(/\/eval\/([\w:-]+)/);if(m){const y=m[1];d(y)}else f.on("init",y=>{console.log("Initialized socket connection",y),o(!0),t(y.results.table),n(y.config)}),f.on("update",y=>{console.log("Received data update",y),t(y.results.table),n(y.config)});return()=>{f.disconnect()}},[t,n]),C.jsxs(oR,{theme:u,children:[C.jsx(MA,{darkMode:l,onToggleDarkMode:c}),r&&e?C.jsx(bA,{}):C.jsx("div",{children:"Loading..."})]})}zc.createRoot(document.getElementById("root")).render(C.jsx(wt.StrictMode,{children:C.jsx(OA,{})}));
@@ -5,7 +5,7 @@
5
5
  <link rel="icon" type="image/svg+xml" href="favicon.ico" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>promptfoo web viewer</title>
8
- <script type="module" crossorigin src="/assets/index-0f6d6b29.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-70e6ca57.js"></script>
9
9
  <link rel="stylesheet" href="/assets/index-87905193.css">
10
10
  </head>
11
11
  <body>
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "promptfoo",
3
3
  "description": "Prompt engineering toolkit",
4
4
  "author": "Ian Webster",
5
- "version": "0.13.1",
5
+ "version": "0.14.0",
6
6
  "license": "MIT",
7
7
  "type": "commonjs",
8
8
  "main": "dist/src/index.js",
package/src/main.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
3
- import { join as pathJoin } from 'path';
3
+ import { join as pathJoin, dirname } from 'path';
4
4
 
5
5
  import chalk from 'chalk';
6
6
  import { Command } from 'commander';
@@ -12,6 +12,7 @@ import { evaluate } from './evaluator';
12
12
  import {
13
13
  maybeReadConfig,
14
14
  readConfig,
15
+ readLatestResults,
15
16
  readPrompts,
16
17
  readTests,
17
18
  writeLatestResults,
@@ -31,6 +32,7 @@ import type {
31
32
  UnifiedConfig,
32
33
  } from './types';
33
34
  import { generateTable } from './table';
35
+ import { createShareableUrl } from './share';
34
36
 
35
37
  function createDummyFiles(directory: string | null) {
36
38
  if (directory) {
@@ -119,10 +121,28 @@ async function main() {
119
121
  init(cmdObj.port);
120
122
  });
121
123
 
124
+ program
125
+ .command('share')
126
+ .description('Share your most recent result')
127
+ .action(async (cmdObj: { port: number } & Command) => {
128
+ telemetry.record('command_used', {
129
+ name: 'share',
130
+ });
131
+ await telemetry.send();
132
+
133
+ const latestResults = readLatestResults();
134
+ if (!latestResults) {
135
+ logger.error('Could not load results. Do you need to run `promptfoo eval` first?');
136
+ process.exit(1);
137
+ }
138
+ const url = await createShareableUrl(latestResults.results, latestResults.config);
139
+ logger.info(`View results: ${chalk.greenBright.bold(url)}`);
140
+ });
141
+
122
142
  program
123
143
  .command('eval')
124
144
  .description('Evaluate prompts')
125
- .requiredOption('-p, --prompts <paths...>', 'Paths to prompt files (.txt)', config.prompts)
145
+ .option('-p, --prompts <paths...>', 'Paths to prompt files (.txt)', config.prompts)
126
146
  .option(
127
147
  '-r, --providers <name or path...>',
128
148
  'One of: openai:chat, openai:completion, openai:<model name>, or path to custom API caller module',
@@ -175,6 +195,9 @@ async function main() {
175
195
  'Do not read or write results to disk cache',
176
196
  config?.commandLineOptions?.cache,
177
197
  )
198
+ .option('--no-progress-bar', 'Do not show progress bar')
199
+ .option('--no-table', 'Do not output table in CLI', config?.commandLineOptions?.table)
200
+ .option('--share', 'Create a shareable URL', config?.commandLineOptions?.share)
178
201
  .option('--grader', 'Model that will grade outputs', config?.commandLineOptions?.grader)
179
202
  .option('--verbose', 'Show debug logs', config?.commandLineOptions?.verbose)
180
203
  .option('--view [port]', 'View in browser ui')
@@ -212,9 +235,10 @@ async function main() {
212
235
  }
213
236
 
214
237
  // Parse prompts, providers, and tests
215
- const parsedPrompts = readPrompts(config.prompts);
238
+ const basePath = configPath ? dirname(configPath) : '';
239
+ const parsedPrompts = readPrompts(config.prompts, basePath);
216
240
  const parsedProviders = await loadApiProviders(config.providers);
217
- const parsedTests: TestCase[] = await readTests(config.tests);
241
+ const parsedTests: TestCase[] = await readTests(config.tests, basePath);
218
242
 
219
243
  if (parsedPrompts.length === 0) {
220
244
  logger.error(chalk.red('No prompts found'));
@@ -240,7 +264,10 @@ async function main() {
240
264
  };
241
265
 
242
266
  const options: EvaluateOptions = {
243
- showProgressBar: getLogLevel() !== 'debug',
267
+ showProgressBar:
268
+ typeof cmdObj.progressBar === 'undefined'
269
+ ? getLogLevel() !== 'debug'
270
+ : cmdObj.progressBar,
244
271
  maxConcurrency: !isNaN(maxConcurrency) && maxConcurrency > 0 ? maxConcurrency : undefined,
245
272
  ...evaluateOptions,
246
273
  };
@@ -255,10 +282,12 @@ async function main() {
255
282
 
256
283
  const summary = await evaluate(testSuite, options);
257
284
 
285
+ const shareableUrl = cmdObj.share ? await createShareableUrl(summary, config) : null;
286
+
258
287
  if (cmdObj.output) {
259
288
  logger.info(chalk.yellow(`Writing output to ${cmdObj.output}`));
260
- writeOutput(cmdObj.output, summary);
261
- } else if (getLogLevel() !== 'debug') {
289
+ writeOutput(cmdObj.output, summary, config, shareableUrl);
290
+ } else if (cmdObj.table && getLogLevel() !== 'debug') {
262
291
  // Output table by default
263
292
  const table = generateTable(summary, parseInt(cmdObj.tableCellMaxLength || '', 10));
264
293
 
@@ -271,15 +300,20 @@ async function main() {
271
300
 
272
301
  const border = '='.repeat(process.stdout.columns - 10);
273
302
  logger.info(border);
274
- if (cmdObj.view || !cmdObj.write) {
303
+ if (!cmdObj.write) {
275
304
  logger.info(`${chalk.green('✔')} Evaluation complete`);
276
305
  } else {
277
306
  writeLatestResults(summary, config);
278
- logger.info(
279
- `${chalk.green('✔')} Evaluation complete. To use web viewer, run ${chalk.green(
280
- 'promptfoo view',
281
- )}`,
282
- );
307
+
308
+ if (cmdObj.view) {
309
+ logger.info(`${chalk.green('✔')} Evaluation complete. Launching web viewer...`);
310
+ } else if (shareableUrl) {
311
+ logger.info(`${chalk.green('✔')} Evaluation complete: ${shareableUrl}`);
312
+ } else {
313
+ logger.info(`${chalk.green('✔')} Evaluation complete.\n`);
314
+ logger.info(`Run ${chalk.greenBright('promptfoo view')} to use the local web viewer`);
315
+ logger.info(`Run ${chalk.greenBright('promptfoo share')} to create a shareable URL`);
316
+ }
283
317
  }
284
318
  logger.info(border);
285
319
  logger.info(chalk.green.bold(`Successes: ${summary.stats.successes}`));
package/src/share.ts ADDED
@@ -0,0 +1,25 @@
1
+ import fetch from 'node-fetch';
2
+
3
+ import type { EvaluateSummary, UnifiedConfig } from './types';
4
+
5
+ export async function createShareableUrl(
6
+ results: EvaluateSummary,
7
+ config: Partial<UnifiedConfig>,
8
+ ): Promise<string> {
9
+ const response = await fetch('https://api.promptfoo.dev/eval', {
10
+ method: 'POST',
11
+ headers: {
12
+ 'Content-Type': 'application/json',
13
+ },
14
+ body: JSON.stringify({
15
+ data: {
16
+ version: 1,
17
+ results,
18
+ config,
19
+ },
20
+ }),
21
+ });
22
+
23
+ const { id } = (await response.json()) as { id: string };
24
+ return `https://app.promptfoo.dev/eval/${id}`;
25
+ }
package/src/types.ts CHANGED
@@ -17,6 +17,9 @@ export interface CommandLineOptions {
17
17
  tableCellMaxLength?: string;
18
18
  write?: boolean;
19
19
  cache?: boolean;
20
+ table?: boolean;
21
+ share?: boolean;
22
+ progressBar?: boolean;
20
23
 
21
24
  generateSuggestions?: boolean;
22
25
  promptPrefix?: string;
package/src/util.ts CHANGED
@@ -12,20 +12,12 @@ import { parse as parseCsv } from 'csv-parse/sync';
12
12
  import { stringify } from 'csv-stringify/sync';
13
13
 
14
14
  import logger from './logger';
15
+ import { assertionFromString } from './assertions';
15
16
  import { getDirectory } from './esm';
16
17
 
17
18
  import type { RequestInfo, RequestInit, Response } from 'node-fetch';
18
19
 
19
- import type {
20
- Assertion,
21
- CsvRow,
22
- EvaluateSummary,
23
- UnifiedConfig,
24
- TestCase,
25
- Prompt,
26
- TestSuite,
27
- } from './types';
28
- import { assertionFromString } from './assertions';
20
+ import type { Assertion, CsvRow, EvaluateSummary, UnifiedConfig, TestCase, Prompt } from './types';
29
21
 
30
22
  const PROMPT_DELIMITER = '---';
31
23
 
@@ -70,36 +62,53 @@ enum PromptInputType {
70
62
 
71
63
  export function readPrompts(
72
64
  promptPathOrGlobs: string | string[] | Record<string, string>,
65
+ basePath: string = '',
73
66
  ): Prompt[] {
74
67
  let promptPaths: string[] = [];
75
68
  let promptContents: Prompt[] = [];
76
69
 
77
70
  let inputType: PromptInputType | undefined;
71
+ let resolvedPath: string | undefined;
72
+ const resolvedPathToDisplay = new Map<string, string>();
78
73
  if (typeof promptPathOrGlobs === 'string') {
79
- promptPaths = [promptPathOrGlobs];
74
+ resolvedPath = path.resolve(basePath, promptPathOrGlobs);
75
+ promptPaths = [resolvedPath];
76
+ resolvedPathToDisplay.set(resolvedPath, promptPathOrGlobs);
80
77
  inputType = PromptInputType.STRING;
81
78
  } else if (Array.isArray(promptPathOrGlobs)) {
82
- promptPaths = promptPathOrGlobs.flatMap((pathOrGlob) => globSync(pathOrGlob));
79
+ promptPaths = promptPathOrGlobs.flatMap((pathOrGlob) => {
80
+ resolvedPath = path.resolve(basePath, pathOrGlob);
81
+ resolvedPathToDisplay.set(resolvedPath, pathOrGlob);
82
+ return globSync(resolvedPath);
83
+ });
83
84
  inputType = PromptInputType.ARRAY;
84
85
  } else if (typeof promptPathOrGlobs === 'object') {
85
- promptPaths = Object.keys(promptPathOrGlobs);
86
+ promptPaths = Object.keys(promptPathOrGlobs).map((key) => {
87
+ resolvedPath = path.resolve(basePath, key);
88
+ resolvedPathToDisplay.set(resolvedPath, promptPathOrGlobs[key]);
89
+ return resolvedPath;
90
+ });
86
91
  inputType = PromptInputType.NAMED;
87
92
  }
88
93
 
89
94
  for (const promptPath of promptPaths) {
90
95
  const stat = fs.statSync(promptPath);
91
96
  if (stat.isDirectory()) {
97
+ // FIXME(ian): Make directory handling share logic with file handling.
92
98
  const filesInDirectory = fs.readdirSync(promptPath);
93
- const fileContents = filesInDirectory.map((fileName) =>
94
- fs.readFileSync(path.join(promptPath, fileName), 'utf-8'),
95
- );
99
+ const fileContents = filesInDirectory.map((fileName) => {
100
+ const joinedPath = path.join(promptPath, fileName);
101
+ resolvedPath = path.resolve(basePath, joinedPath);
102
+ resolvedPathToDisplay.set(resolvedPath, joinedPath);
103
+ return fs.readFileSync(resolvedPath, 'utf-8');
104
+ });
96
105
  promptContents.push(...fileContents.map((content) => ({ raw: content, display: content })));
97
106
  } else {
98
107
  const fileContent = fs.readFileSync(promptPath, 'utf-8');
99
108
 
100
109
  let display: string | undefined;
101
110
  if (inputType === PromptInputType.NAMED) {
102
- display = (promptPathOrGlobs as Record<string, string>)[promptPath];
111
+ display = resolvedPathToDisplay.get(promptPath) || promptPath;
103
112
  } else {
104
113
  display = fileContent.length > 200 ? promptPath : fileContent;
105
114
 
@@ -139,7 +148,8 @@ export async function fetchCsvFromGoogleSheet(url: string): Promise<string> {
139
148
  return csvData;
140
149
  }
141
150
 
142
- export async function readVars(varsPath: string): Promise<CsvRow[]> {
151
+ export async function readVars(varsPath: string, basePath: string = ''): Promise<CsvRow[]> {
152
+ const resolvedVarsPath = path.resolve(basePath, varsPath);
143
153
  const fileExtension = parsePath(varsPath).ext.slice(1);
144
154
  let rows: CsvRow[] = [];
145
155
 
@@ -148,25 +158,28 @@ export async function readVars(varsPath: string): Promise<CsvRow[]> {
148
158
  const csvData = await fetchCsvFromGoogleSheet(varsPath);
149
159
  rows = parseCsv(csvData, { columns: true });
150
160
  } else {
151
- rows = parseCsv(fs.readFileSync(varsPath, 'utf-8'), { columns: true });
161
+ rows = parseCsv(fs.readFileSync(resolvedVarsPath, 'utf-8'), { columns: true });
152
162
  }
153
163
  } else if (fileExtension === 'json') {
154
- rows = parseJson(fs.readFileSync(varsPath, 'utf-8'));
164
+ rows = parseJson(fs.readFileSync(resolvedVarsPath, 'utf-8'));
155
165
  } else if (fileExtension === 'yaml' || fileExtension === 'yml') {
156
- rows = yaml.load(fs.readFileSync(varsPath, 'utf-8')) as unknown as any;
166
+ rows = yaml.load(fs.readFileSync(resolvedVarsPath, 'utf-8')) as unknown as any;
157
167
  }
158
168
 
159
169
  return rows;
160
170
  }
161
171
 
162
- export async function readTests(tests: string | TestCase[] | undefined): Promise<TestCase[]> {
172
+ export async function readTests(
173
+ tests: string | TestCase[] | undefined,
174
+ basePath: string = '',
175
+ ): Promise<TestCase[]> {
163
176
  if (!tests) {
164
177
  return [];
165
178
  }
166
179
 
167
180
  if (typeof tests === 'string') {
168
181
  // It's a filepath, load from CSV
169
- const vars = await readVars(tests);
182
+ const vars = await readVars(tests, basePath);
170
183
  return vars.map((row, idx) => {
171
184
  const test = testCaseFromCsvRow(row);
172
185
  test.description = `Row #${idx + 1}`;
@@ -190,28 +203,33 @@ export async function readTests(tests: string | TestCase[] | undefined): Promise
190
203
  return tests;
191
204
  }
192
205
 
193
- export function writeOutput(outputPath: string, summary: EvaluateSummary): void {
206
+ export function writeOutput(
207
+ outputPath: string,
208
+ results: EvaluateSummary,
209
+ config: Partial<UnifiedConfig>,
210
+ shareableUrl: string | null,
211
+ ): void {
194
212
  const outputExtension = outputPath.split('.').pop()?.toLowerCase();
195
213
 
196
214
  if (outputExtension === 'csv' || outputExtension === 'txt') {
197
215
  const csvOutput = stringify([
198
- [...summary.table.head.prompts, ...summary.table.head.vars],
199
- ...summary.table.body.map((row) => [...row.outputs, ...row.vars]),
216
+ [...results.table.head.prompts, ...results.table.head.vars],
217
+ ...results.table.body.map((row) => [...row.outputs, ...row.vars]),
200
218
  ]);
201
219
  fs.writeFileSync(outputPath, csvOutput);
202
220
  } else if (outputExtension === 'json') {
203
- fs.writeFileSync(outputPath, JSON.stringify(summary, null, 2));
221
+ fs.writeFileSync(outputPath, JSON.stringify({ results, config, shareableUrl }, null, 2));
204
222
  } else if (outputExtension === 'yaml' || outputExtension === 'yml') {
205
- fs.writeFileSync(outputPath, yaml.dump(summary));
223
+ fs.writeFileSync(outputPath, yaml.dump({ results, config, shareableUrl }));
206
224
  } else if (outputExtension === 'html') {
207
225
  const template = fs.readFileSync(`${getDirectory()}/tableOutput.html`, 'utf-8');
208
226
  const table = [
209
- [...summary.table.head.prompts, ...summary.table.head.vars],
210
- ...summary.table.body.map((row) => [...row.outputs, ...row.vars]),
227
+ [...results.table.head.prompts, ...results.table.head.vars],
228
+ ...results.table.body.map((row) => [...row.outputs, ...row.vars]),
211
229
  ];
212
230
  const htmlOutput = nunjucks.renderString(template, {
213
231
  table,
214
- results: summary.results,
232
+ results: results.results,
215
233
  });
216
234
  fs.writeFileSync(outputPath, htmlOutput);
217
235
  } else {
@@ -278,6 +296,18 @@ export function writeLatestResults(results: EvaluateSummary, config: Partial<Uni
278
296
  }
279
297
  }
280
298
 
299
+ export function readLatestResults():
300
+ | { results: EvaluateSummary; config: Partial<UnifiedConfig> }
301
+ | undefined {
302
+ const latestResultsPath = getLatestResultsPath();
303
+ try {
304
+ const latestResults = JSON.parse(fs.readFileSync(latestResultsPath, 'utf-8'));
305
+ return latestResults;
306
+ } catch (err) {
307
+ logger.error(`Failed to read latest results from ${latestResultsPath}:\n${err}`);
308
+ }
309
+ }
310
+
281
311
  export function cosineSimilarity(vecA: number[], vecB: number[]) {
282
312
  if (vecA.length !== vecB.length) {
283
313
  throw new Error('Vectors must be of equal length');