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.
- package/dist/package.json +1 -1
- package/dist/src/main.js +42 -8
- package/dist/src/main.js.map +1 -1
- package/dist/src/share.d.ts +3 -0
- package/dist/src/share.d.ts.map +1 -0
- package/dist/src/share.js +26 -0
- package/dist/src/share.js.map +1 -0
- package/dist/src/types.d.ts +3 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/util.d.ts +8 -4
- package/dist/src/util.d.ts.map +1 -1
- package/dist/src/util.js +52 -22
- package/dist/src/util.js.map +1 -1
- package/dist/src/web/client/assets/{index-0f6d6b29.js → index-70e6ca57.js} +1 -1
- package/dist/src/web/client/index.html +1 -1
- package/package.json +1 -1
- package/src/main.ts +47 -13
- package/src/share.ts +25 -0
- package/src/types.ts +3 -0
- package/src/util.ts +61 -31
- package/src/web/client/package-lock.json +5726 -0
- package/src/web/client/src/ResultsView.tsx +4 -1
|
@@ -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-
|
|
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
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
|
-
.
|
|
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
|
|
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:
|
|
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 (
|
|
303
|
+
if (!cmdObj.write) {
|
|
275
304
|
logger.info(`${chalk.green('✔')} Evaluation complete`);
|
|
276
305
|
} else {
|
|
277
306
|
writeLatestResults(summary, config);
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
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
|
-
|
|
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) =>
|
|
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
|
-
|
|
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 = (
|
|
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(
|
|
161
|
+
rows = parseCsv(fs.readFileSync(resolvedVarsPath, 'utf-8'), { columns: true });
|
|
152
162
|
}
|
|
153
163
|
} else if (fileExtension === 'json') {
|
|
154
|
-
rows = parseJson(fs.readFileSync(
|
|
164
|
+
rows = parseJson(fs.readFileSync(resolvedVarsPath, 'utf-8'));
|
|
155
165
|
} else if (fileExtension === 'yaml' || fileExtension === 'yml') {
|
|
156
|
-
rows = yaml.load(fs.readFileSync(
|
|
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(
|
|
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(
|
|
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
|
-
[...
|
|
199
|
-
...
|
|
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(
|
|
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(
|
|
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
|
-
[...
|
|
210
|
-
...
|
|
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:
|
|
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');
|