@inspectr/mcplab 1.24.0 → 1.24.1
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.
|
@@ -124,7 +124,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
124
124
|
`)});continue}if(/^---+$/.test(c)||/^\*\*\*+$/.test(c)){n.push({type:"hr"}),r+=1;continue}if(c.startsWith(">")){const v=[];for(;r<t.length&&t[r].trim().startsWith(">");)v.push(t[r].trim().replace(/^>\s?/,"")),r+=1;n.push({type:"blockquote",text:v.join(`
|
|
125
125
|
`)});continue}const d=c.match(/^(#{1,4})\s+(.+)$/);if(d){n.push({type:"heading",level:d[1].length,text:d[2].trim()}),r+=1;continue}if(N$(t,r)){const v=C$(t[r]);r+=2;const x=[];for(;r<t.length&&t[r].includes("|")&&!a(t[r]);)x.push(C$(t[r])),r+=1;n.push({type:"table",headers:v,rows:x});continue}const f=c.match(/^\d+\.\s+/),h=c.match(/^[-*+]\s+/);if(f||h){const v=!!f,x=[];for(;r<t.length;){const j=t[r].trim();if(v?/^\d+\.\s+/.test(j):/^[-*+]\s+/.test(j)){x.push(j.replace(v?/^\d+\.\s+/:/^[-*+]\s+/,"")),r+=1;continue}a(t[r])&&(r+=1);break}n.push({type:"list",ordered:v,items:x});continue}const p=[o];for(r+=1;r<t.length;){const v=t[r],x=v.trim();if(a(v)||i(v)||/^---+$/.test(x)||/^#{1,4}\s+/.test(x)||x.startsWith(">")||N$(t,r)||/^\d+\.\s+/.test(x)||/^[-*+]\s+/.test(x))break;p.push(v),r+=1}n.push({type:"paragraph",text:p.join(`
|
|
126
126
|
`)})}return n}function N$(e,t){if(t+1>=e.length)return!1;const n=e[t].trim(),r=e[t+1].trim();return n.includes("|")?/^\|?(\s*:?-{3,}:?\s*\|)+\s*:?-{3,}:?\s*\|?$/.test(r):!1}function C$(e){return e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(t=>t.trim())}function xve(e,t,n){if(e.type==="hr")return s.jsx("hr",{className:"border-border/60"});if(e.type==="heading"){const r=e.level===1?"text-base font-semibold":e.level===2?"text-sm font-semibold":"text-sm font-medium";return s.jsx("h4",{className:r,children:yc(e.text,`${t}-h`)})}if(e.type==="paragraph")return s.jsx("p",{className:Te("whitespace-pre-wrap leading-relaxed",n==="system"&&"leading-normal"),children:yc(e.text,`${t}-p`)});if(e.type==="blockquote")return s.jsx("blockquote",{className:"border-l-2 border-muted-foreground/30 pl-3 text-muted-foreground italic",children:yc(e.text,`${t}-bq`)});if(e.type==="code")return s.jsxs("div",{className:"rounded-md border bg-muted/70",children:[e.lang&&s.jsx("div",{className:"border-b px-2 py-1 text-[10px] uppercase tracking-wide text-muted-foreground",children:e.lang}),s.jsx("pre",{className:"max-h-72 overflow-auto p-2 text-xs",children:s.jsx("code",{children:e.code})})]});if(e.type==="list"){const r=e.ordered?"ol":"ul";return s.jsx(r,{className:Te("space-y-1 pl-5",e.ordered?"list-decimal":"list-disc"),children:e.items.map((a,i)=>s.jsx("li",{className:"leading-relaxed",children:yc(a,`${t}-li-${i}`)},`${t}-li-${i}`))})}return e.type==="table"?s.jsx("div",{className:"overflow-x-auto rounded-md border",children:s.jsxs("table",{className:"w-full min-w-[480px] border-collapse text-xs",children:[s.jsx("thead",{className:"bg-muted/40",children:s.jsx("tr",{children:e.headers.map((r,a)=>s.jsx("th",{className:"border-b px-2 py-1.5 text-left font-semibold align-top",children:yc(r,`${t}-thc-${a}`)},`${t}-th-${a}`))})}),s.jsx("tbody",{children:e.rows.map((r,a)=>s.jsx("tr",{className:"border-t",children:r.map((i,o)=>s.jsx("td",{className:"px-2 py-1.5 align-top",children:yc(i,`${t}-tdc-${a}-${o}`)},`${t}-td-${a}-${o}`))},`${t}-row-${a}`))})]})}):null}function yc(e,t){return e.split(/(`[^`]+`|\*\*[^*]+\*\*|\*[^*\n]+\*|_[^_\n]+_|~~[^~\n]+~~|\[[^\]]+\]\([^)]+\))/g).filter(Boolean).map((r,a)=>{if(r.startsWith("`")&&r.endsWith("`"))return s.jsx("code",{className:"rounded bg-muted px-1 py-0.5 font-mono text-[0.92em]",children:r.slice(1,-1)},`${t}-${a}`);if(r.startsWith("**")&&r.endsWith("**"))return s.jsx("strong",{children:r.slice(2,-2)},`${t}-${a}`);if(r.startsWith("*")&&r.endsWith("*"))return s.jsx("em",{children:r.slice(1,-1)},`${t}-${a}`);if(r.startsWith("_")&&r.endsWith("_"))return s.jsx("em",{children:r.slice(1,-1)},`${t}-${a}`);if(r.startsWith("~~")&&r.endsWith("~~"))return s.jsx("s",{children:r.slice(2,-2)},`${t}-${a}`);const i=r.match(/^\[([^\]]+)\]\(([^)]+)\)$/);return i?s.jsx("a",{href:i[2],target:"_blank",rel:"noreferrer",className:"underline underline-offset-2",children:i[1]},`${t}-${a}`):s.jsx(m.Fragment,{children:r},`${t}-${a}`)})}function F6({message:e,className:t,assistantLabel:n,renderActions:r}){const a=e.role;if(a==="tool"){const c=String(e.text??"").trim();return/^(Approved|Denied) tool call\b/i.test(c)?null:s.jsxs("div",{className:Te("rounded-md border border-sky-500/30 bg-sky-500/10 px-3 py-2 text-sm",t),children:[s.jsxs("div",{className:"mb-1 flex items-center gap-2 text-[11px] font-semibold uppercase tracking-wide text-sky-700",children:[s.jsx(pa,{className:"h-3.5 w-3.5"}),"Tool",s.jsx("span",{className:"font-normal normal-case text-sky-700/80",children:new Date(e.createdAt).toLocaleTimeString()})]}),s.jsx("p",{className:"whitespace-pre-wrap text-sky-900",children:e.text})]})}if(a==="system")return s.jsxs("div",{className:Te("flex items-start gap-2 text-xs",t),children:[s.jsx("div",{className:"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-700",children:s.jsx(BN,{className:"h-3 w-3"})}),s.jsx("div",{className:"max-w-[92%] rounded-md border border-amber-400/30 bg-amber-50/70 p-3 text-sm",children:s.jsx(Fs,{text:e.text,variant:"assistant"})})]});const i=a==="user",o=i?Uc:Fr;return s.jsxs("div",{className:Te(`flex items-start gap-2 text-xs ${i?"justify-end":"justify-start"}`,t),children:[!i&&s.jsx("div",{className:"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-700",children:s.jsx(o,{className:"h-3 w-3"})}),s.jsxs("div",{className:"relative max-w-[92%]",children:[s.jsxs("div",{className:`max-w-full break-words rounded-md border px-3 py-2 text-sm ${i?"border-primary/20 bg-primary/10":"border-border/80 bg-background shadow-sm"}`,children:[!i&&n&&s.jsx("p",{className:"mb-2 text-[11px] font-semibold text-muted-foreground",children:n}),i?s.jsx("p",{className:"whitespace-pre-wrap",children:e.text}):s.jsx(Fs,{text:e.text,variant:"assistant",className:"text-sm"})]}),r]}),i&&s.jsx("div",{className:"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-primary/30 bg-primary/15 text-primary",children:s.jsx(Uc,{className:"h-3 w-3"})})]})}function wN({call:e,loading:t=!1,onApprove:n,onDeny:r,defaultOpen:a,className:i,description:o}){const c=e.status==="pending",d=e.tool||e.publicToolName||"unknown_tool";return s.jsxs("details",{open:a??c,className:Te("group overflow-hidden rounded-md border border-border/60 bg-background",i),children:[s.jsxs("summary",{className:"flex cursor-pointer list-none items-center justify-between gap-3 px-3 py-2",children:[s.jsx("div",{className:"min-w-0 flex-1",children:s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx(pa,{className:"h-3.5 w-3.5 shrink-0 text-muted-foreground"}),s.jsx("span",{className:"min-w-0 truncate text-sm font-medium",children:`Tool call ${d}`}),s.jsx("span",{className:`shrink-0 whitespace-nowrap rounded px-1.5 py-0.5 text-[10px] font-semibold ${c?"bg-amber-100 text-amber-900":e.status==="error"?"bg-red-100 text-red-900":e.status==="denied"?"bg-gray-100 text-gray-700":"bg-muted text-muted-foreground"}`,children:c?"Needs approval":e.status==="error"?"Error":e.status==="denied"?"Denied":"Approved"})]})}),s.jsx(tn,{className:"h-4 w-4 shrink-0 text-muted-foreground transition-transform group-open:rotate-180"})]}),s.jsxs("div",{className:"space-y-2 border-t border-border/50 px-3 py-2",children:[o&&s.jsx(Fs,{text:o,variant:"assistant",className:"text-sm"}),s.jsx("pre",{className:"max-h-40 w-full max-w-full overflow-x-auto overflow-y-auto whitespace-pre rounded border bg-muted/50 p-2 text-xs",children:s.jsx("code",{children:JSON.stringify(e.arguments??{},null,2)})}),e.error&&s.jsx("p",{className:"text-xs text-destructive",children:e.error}),c&&s.jsxs("div",{className:"mt-2 flex justify-end gap-2",children:[s.jsx(ee,{type:"button",size:"sm",variant:"outline",className:"h-7 px-2 text-xs",disabled:t,onClick:()=>r?.(e.id),children:"Deny"}),s.jsx(ee,{type:"button",size:"sm",className:"h-7 px-2 text-xs",disabled:t,onClick:()=>n?.(e.id),children:"Approve"})]})]})]})}function z6(){return s.jsxs("div",{className:"flex items-start gap-2",children:[s.jsx("div",{className:"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-700",children:s.jsx(Fr,{className:"h-3 w-3"})}),s.jsxs("div",{className:"inline-flex items-center gap-2 rounded-md border bg-background px-3 py-2 text-sm text-muted-foreground",children:[s.jsx(wr,{className:"h-4 w-4 animate-spin"}),"Thinking..."]})]})}function yve({snippets:e,snippetsLabel:t,onSnippetSelect:n,disabled:r=!1,contentClassName:a="w-[360px]"}){return s.jsxs(lp,{children:[s.jsx(cp,{asChild:!0,children:s.jsxs(ee,{type:"button",variant:"ghost",size:"sm",className:"h-7 shrink-0 gap-1 px-1.5 text-[11px] font-normal text-muted-foreground/80 hover:text-muted-foreground",disabled:r,children:[s.jsx(yi,{className:"h-3 w-3"}),"Snippets",s.jsx(tn,{className:"h-3 w-3"})]})}),s.jsxs($u,{align:"start",className:a,children:[s.jsx(_B,{children:t}),s.jsx(AB,{}),e.map(i=>s.jsx(Or,{className:"items-start whitespace-normal px-2 py-2",onSelect:()=>n(i.prompt),children:s.jsxs("div",{className:"space-y-0.5",children:[s.jsx("div",{className:"text-xs font-medium leading-tight",children:i.label}),s.jsx("div",{className:"text-[11px] leading-snug text-muted-foreground",children:i.description})]})},i.label))]})]})}function B6({input:e,onInputChange:t,onSend:n,onCancel:r,inputPlaceholder:a,snippets:i,snippetsLabel:o,onSnippetSelect:c,loading:d=!1,disabled:f=!1,inputRef:h,snippetContentClassName:p}){const v=f||d;return s.jsxs("div",{className:"rounded-xl border bg-background p-2 shadow-sm",children:[s.jsx(ba,{ref:h,value:e,onChange:x=>t(x.target.value),placeholder:a,disabled:f,rows:1,className:"min-h-10 max-h-40 resize-none border-0 bg-transparent px-2 py-1 text-sm shadow-none focus-visible:ring-0 focus-visible:ring-offset-0",onKeyDown:x=>{x.key==="Enter"&&!x.shiftKey&&(x.preventDefault(),v||n())}}),s.jsxs("div",{className:"mt-1 flex items-center justify-between gap-2 px-1 pt-1",children:[s.jsx(yve,{snippets:i,snippetsLabel:o,onSnippetSelect:c,disabled:v,contentClassName:p}),d&&r?s.jsxs(ee,{type:"button",variant:"outline",size:"sm",className:"relative h-8 w-8 shrink-0 overflow-hidden rounded-full",onClick:r,"aria-label":"Cancel assistant message",title:"Cancel assistant message",children:[s.jsx("span",{className:"pointer-events-none absolute inset-[2px] rounded-full border border-primary/20 border-t-primary/70 motion-reduce:animate-none animate-[spin_2.2s_linear_infinite]"}),s.jsx("span",{className:"pointer-events-none absolute inset-[4px] rounded-full border border-primary/10 motion-reduce:animate-none animate-pulse"}),s.jsx(Ld,{className:"relative z-10 h-4 w-4"})]}):d?s.jsx(ee,{type:"button",size:"icon",className:"h-8 w-8 shrink-0 rounded-full",disabled:!0,"aria-label":"Assistant is loading",title:"Assistant is loading",children:s.jsx(wr,{className:"h-4 w-4 animate-spin"})}):s.jsx(ee,{type:"button",size:"icon",className:"h-8 w-8 shrink-0 rounded-full pr-0.5",onClick:n,disabled:v||!e.trim(),"aria-label":"Send assistant message",title:"Send assistant message",children:s.jsx($9,{className:"h-4 w-4"})})]})]})}const bve=Bg,wve=qg,q6=m.forwardRef(({className:e,...t},n)=>s.jsx(_u,{ref:n,className:Te("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",e),...t}));q6.displayName=_u.displayName;const U6=m.forwardRef(({className:e,children:t,...n},r)=>s.jsxs(wve,{children:[s.jsx(q6,{}),s.jsxs(Au,{ref:r,className:Te("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",e),...n,children:[t,s.jsxs(Ug,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none",children:[s.jsx(ns,{className:"h-4 w-4"}),s.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));U6.displayName=Au.displayName;const W6=({className:e,...t})=>s.jsx("div",{className:Te("flex flex-col space-y-1.5 text-center sm:text-left",e),...t});W6.displayName="DialogHeader";const V6=m.forwardRef(({className:e,...t},n)=>s.jsx(Hf,{ref:n,className:Te("text-lg font-semibold leading-none tracking-tight",e),...t}));V6.displayName=Hf.displayName;const H6=m.forwardRef(({className:e,...t},n)=>s.jsx(Kf,{ref:n,className:Te("text-sm text-muted-foreground",e),...t}));H6.displayName=Kf.displayName;function jve(e,t){return m.useReducer((n,r)=>t[n][r]??n,e)}var k_="ScrollArea",[K6]=jr(k_),[Sve,Zs]=K6(k_),G6=m.forwardRef((e,t)=>{const{__scopeScrollArea:n,type:r="hover",dir:a,scrollHideDelay:i=600,...o}=e,[c,d]=m.useState(null),[f,h]=m.useState(null),[p,v]=m.useState(null),[x,j]=m.useState(null),[b,y]=m.useState(null),[S,N]=m.useState(0),[_,A]=m.useState(0),[k,E]=m.useState(!1),[P,R]=m.useState(!1),M=Mt(t,U=>d(U)),D=Iu(a);return s.jsx(Sve,{scope:n,type:r,dir:D,scrollHideDelay:i,scrollArea:c,viewport:f,onViewportChange:h,content:p,onContentChange:v,scrollbarX:x,onScrollbarXChange:j,scrollbarXEnabled:k,onScrollbarXEnabledChange:E,scrollbarY:b,onScrollbarYChange:y,scrollbarYEnabled:P,onScrollbarYEnabledChange:R,onCornerWidthChange:N,onCornerHeightChange:A,children:s.jsx(ut.div,{dir:D,...o,ref:M,style:{position:"relative","--radix-scroll-area-corner-width":S+"px","--radix-scroll-area-corner-height":_+"px",...e.style}})})});G6.displayName=k_;var Y6="ScrollAreaViewport",X6=m.forwardRef((e,t)=>{const{__scopeScrollArea:n,children:r,nonce:a,...i}=e,o=Zs(Y6,n),c=m.useRef(null),d=Mt(t,c,o.onViewportChange);return s.jsxs(s.Fragment,{children:[s.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}"},nonce:a}),s.jsx(ut.div,{"data-radix-scroll-area-viewport":"",...i,ref:d,style:{overflowX:o.scrollbarXEnabled?"scroll":"hidden",overflowY:o.scrollbarYEnabled?"scroll":"hidden",...e.style},children:s.jsx("div",{ref:o.onContentChange,style:{minWidth:"100%",display:"table"},children:r})})]})});X6.displayName=Y6;var Ga="ScrollAreaScrollbar",E_=m.forwardRef((e,t)=>{const{forceMount:n,...r}=e,a=Zs(Ga,e.__scopeScrollArea),{onScrollbarXEnabledChange:i,onScrollbarYEnabledChange:o}=a,c=e.orientation==="horizontal";return m.useEffect(()=>(c?i(!0):o(!0),()=>{c?i(!1):o(!1)}),[c,i,o]),a.type==="hover"?s.jsx(Nve,{...r,ref:t,forceMount:n}):a.type==="scroll"?s.jsx(Cve,{...r,ref:t,forceMount:n}):a.type==="auto"?s.jsx(Q6,{...r,ref:t,forceMount:n}):a.type==="always"?s.jsx(P_,{...r,ref:t}):null});E_.displayName=Ga;var Nve=m.forwardRef((e,t)=>{const{forceMount:n,...r}=e,a=Zs(Ga,e.__scopeScrollArea),[i,o]=m.useState(!1);return m.useEffect(()=>{const c=a.scrollArea;let d=0;if(c){const f=()=>{window.clearTimeout(d),o(!0)},h=()=>{d=window.setTimeout(()=>o(!1),a.scrollHideDelay)};return c.addEventListener("pointerenter",f),c.addEventListener("pointerleave",h),()=>{window.clearTimeout(d),c.removeEventListener("pointerenter",f),c.removeEventListener("pointerleave",h)}}},[a.scrollArea,a.scrollHideDelay]),s.jsx(Zn,{present:n||i,children:s.jsx(Q6,{"data-state":i?"visible":"hidden",...r,ref:t})})}),Cve=m.forwardRef((e,t)=>{const{forceMount:n,...r}=e,a=Zs(Ga,e.__scopeScrollArea),i=e.orientation==="horizontal",o=Bv(()=>d("SCROLL_END"),100),[c,d]=jve("hidden",{hidden:{SCROLL:"scrolling"},scrolling:{SCROLL_END:"idle",POINTER_ENTER:"interacting"},interacting:{SCROLL:"interacting",POINTER_LEAVE:"idle"},idle:{HIDE:"hidden",SCROLL:"scrolling",POINTER_ENTER:"interacting"}});return m.useEffect(()=>{if(c==="idle"){const f=window.setTimeout(()=>d("HIDE"),a.scrollHideDelay);return()=>window.clearTimeout(f)}},[c,a.scrollHideDelay,d]),m.useEffect(()=>{const f=a.viewport,h=i?"scrollLeft":"scrollTop";if(f){let p=f[h];const v=()=>{const x=f[h];p!==x&&(d("SCROLL"),o()),p=x};return f.addEventListener("scroll",v),()=>f.removeEventListener("scroll",v)}},[a.viewport,i,d,o]),s.jsx(Zn,{present:n||c!=="hidden",children:s.jsx(P_,{"data-state":c==="hidden"?"hidden":"visible",...r,ref:t,onPointerEnter:qe(e.onPointerEnter,()=>d("POINTER_ENTER")),onPointerLeave:qe(e.onPointerLeave,()=>d("POINTER_LEAVE"))})})}),Q6=m.forwardRef((e,t)=>{const n=Zs(Ga,e.__scopeScrollArea),{forceMount:r,...a}=e,[i,o]=m.useState(!1),c=e.orientation==="horizontal",d=Bv(()=>{if(n.viewport){const f=n.viewport.offsetWidth<n.viewport.scrollWidth,h=n.viewport.offsetHeight<n.viewport.scrollHeight;o(c?f:h)}},10);return xu(n.viewport,d),xu(n.content,d),s.jsx(Zn,{present:r||i,children:s.jsx(P_,{"data-state":i?"visible":"hidden",...a,ref:t})})}),P_=m.forwardRef((e,t)=>{const{orientation:n="vertical",...r}=e,a=Zs(Ga,e.__scopeScrollArea),i=m.useRef(null),o=m.useRef(0),[c,d]=m.useState({content:0,viewport:0,scrollbar:{size:0,paddingStart:0,paddingEnd:0}}),f=n8(c.viewport,c.content),h={...r,sizes:c,onSizesChange:d,hasThumb:f>0&&f<1,onThumbChange:v=>i.current=v,onThumbPointerUp:()=>o.current=0,onThumbPointerDown:v=>o.current=v};function p(v,x){return Tve(v,o.current,c,x)}return n==="horizontal"?s.jsx(_ve,{...h,ref:t,onThumbPositionChange:()=>{if(a.viewport&&i.current){const v=a.viewport.scrollLeft,x=_$(v,c,a.dir);i.current.style.transform=`translate3d(${x}px, 0, 0)`}},onWheelScroll:v=>{a.viewport&&(a.viewport.scrollLeft=v)},onDragScroll:v=>{a.viewport&&(a.viewport.scrollLeft=p(v,a.dir))}}):n==="vertical"?s.jsx(Ave,{...h,ref:t,onThumbPositionChange:()=>{if(a.viewport&&i.current){const v=a.viewport.scrollTop,x=_$(v,c);i.current.style.transform=`translate3d(0, ${x}px, 0)`}},onWheelScroll:v=>{a.viewport&&(a.viewport.scrollTop=v)},onDragScroll:v=>{a.viewport&&(a.viewport.scrollTop=p(v))}}):null}),_ve=m.forwardRef((e,t)=>{const{sizes:n,onSizesChange:r,...a}=e,i=Zs(Ga,e.__scopeScrollArea),[o,c]=m.useState(),d=m.useRef(null),f=Mt(t,d,i.onScrollbarXChange);return m.useEffect(()=>{d.current&&c(getComputedStyle(d.current))},[d]),s.jsx(J6,{"data-orientation":"horizontal",...a,ref:f,sizes:n,style:{bottom:0,left:i.dir==="rtl"?"var(--radix-scroll-area-corner-width)":0,right:i.dir==="ltr"?"var(--radix-scroll-area-corner-width)":0,"--radix-scroll-area-thumb-width":zv(n)+"px",...e.style},onThumbPointerDown:h=>e.onThumbPointerDown(h.x),onDragScroll:h=>e.onDragScroll(h.x),onWheelScroll:(h,p)=>{if(i.viewport){const v=i.viewport.scrollLeft+h.deltaX;e.onWheelScroll(v),s8(v,p)&&h.preventDefault()}},onResize:()=>{d.current&&i.viewport&&o&&r({content:i.viewport.scrollWidth,viewport:i.viewport.offsetWidth,scrollbar:{size:d.current.clientWidth,paddingStart:fg(o.paddingLeft),paddingEnd:fg(o.paddingRight)}})}})}),Ave=m.forwardRef((e,t)=>{const{sizes:n,onSizesChange:r,...a}=e,i=Zs(Ga,e.__scopeScrollArea),[o,c]=m.useState(),d=m.useRef(null),f=Mt(t,d,i.onScrollbarYChange);return m.useEffect(()=>{d.current&&c(getComputedStyle(d.current))},[d]),s.jsx(J6,{"data-orientation":"vertical",...a,ref:f,sizes:n,style:{top:0,right:i.dir==="ltr"?0:void 0,left:i.dir==="rtl"?0:void 0,bottom:"var(--radix-scroll-area-corner-height)","--radix-scroll-area-thumb-height":zv(n)+"px",...e.style},onThumbPointerDown:h=>e.onThumbPointerDown(h.y),onDragScroll:h=>e.onDragScroll(h.y),onWheelScroll:(h,p)=>{if(i.viewport){const v=i.viewport.scrollTop+h.deltaY;e.onWheelScroll(v),s8(v,p)&&h.preventDefault()}},onResize:()=>{d.current&&i.viewport&&o&&r({content:i.viewport.scrollHeight,viewport:i.viewport.offsetHeight,scrollbar:{size:d.current.clientHeight,paddingStart:fg(o.paddingTop),paddingEnd:fg(o.paddingBottom)}})}})}),[kve,Z6]=K6(Ga),J6=m.forwardRef((e,t)=>{const{__scopeScrollArea:n,sizes:r,hasThumb:a,onThumbChange:i,onThumbPointerUp:o,onThumbPointerDown:c,onThumbPositionChange:d,onDragScroll:f,onWheelScroll:h,onResize:p,...v}=e,x=Zs(Ga,n),[j,b]=m.useState(null),y=Mt(t,M=>b(M)),S=m.useRef(null),N=m.useRef(""),_=x.viewport,A=r.content-r.viewport,k=Gn(h),E=Gn(d),P=Bv(p,10);function R(M){if(S.current){const D=M.clientX-S.current.left,U=M.clientY-S.current.top;f({x:D,y:U})}}return m.useEffect(()=>{const M=D=>{const U=D.target;j?.contains(U)&&k(D,A)};return document.addEventListener("wheel",M,{passive:!1}),()=>document.removeEventListener("wheel",M,{passive:!1})},[_,j,A,k]),m.useEffect(E,[r,E]),xu(j,P),xu(x.content,P),s.jsx(kve,{scope:n,scrollbar:j,hasThumb:a,onThumbChange:Gn(i),onThumbPointerUp:Gn(o),onThumbPositionChange:E,onThumbPointerDown:Gn(c),children:s.jsx(ut.div,{...v,ref:y,style:{position:"absolute",...v.style},onPointerDown:qe(e.onPointerDown,M=>{M.button===0&&(M.target.setPointerCapture(M.pointerId),S.current=j.getBoundingClientRect(),N.current=document.body.style.webkitUserSelect,document.body.style.webkitUserSelect="none",x.viewport&&(x.viewport.style.scrollBehavior="auto"),R(M))}),onPointerMove:qe(e.onPointerMove,R),onPointerUp:qe(e.onPointerUp,M=>{const D=M.target;D.hasPointerCapture(M.pointerId)&&D.releasePointerCapture(M.pointerId),document.body.style.webkitUserSelect=N.current,x.viewport&&(x.viewport.style.scrollBehavior=""),S.current=null})})})}),dg="ScrollAreaThumb",e8=m.forwardRef((e,t)=>{const{forceMount:n,...r}=e,a=Z6(dg,e.__scopeScrollArea);return s.jsx(Zn,{present:n||a.hasThumb,children:s.jsx(Eve,{ref:t,...r})})}),Eve=m.forwardRef((e,t)=>{const{__scopeScrollArea:n,style:r,...a}=e,i=Zs(dg,n),o=Z6(dg,n),{onThumbPositionChange:c}=o,d=Mt(t,p=>o.onThumbChange(p)),f=m.useRef(void 0),h=Bv(()=>{f.current&&(f.current(),f.current=void 0)},100);return m.useEffect(()=>{const p=i.viewport;if(p){const v=()=>{if(h(),!f.current){const x=Rve(p,c);f.current=x,c()}};return c(),p.addEventListener("scroll",v),()=>p.removeEventListener("scroll",v)}},[i.viewport,h,c]),s.jsx(ut.div,{"data-state":o.hasThumb?"visible":"hidden",...a,ref:d,style:{width:"var(--radix-scroll-area-thumb-width)",height:"var(--radix-scroll-area-thumb-height)",...r},onPointerDownCapture:qe(e.onPointerDownCapture,p=>{const x=p.target.getBoundingClientRect(),j=p.clientX-x.left,b=p.clientY-x.top;o.onThumbPointerDown({x:j,y:b})}),onPointerUp:qe(e.onPointerUp,o.onThumbPointerUp)})});e8.displayName=dg;var T_="ScrollAreaCorner",t8=m.forwardRef((e,t)=>{const n=Zs(T_,e.__scopeScrollArea),r=!!(n.scrollbarX&&n.scrollbarY);return n.type!=="scroll"&&r?s.jsx(Pve,{...e,ref:t}):null});t8.displayName=T_;var Pve=m.forwardRef((e,t)=>{const{__scopeScrollArea:n,...r}=e,a=Zs(T_,n),[i,o]=m.useState(0),[c,d]=m.useState(0),f=!!(i&&c);return xu(a.scrollbarX,()=>{const h=a.scrollbarX?.offsetHeight||0;a.onCornerHeightChange(h),d(h)}),xu(a.scrollbarY,()=>{const h=a.scrollbarY?.offsetWidth||0;a.onCornerWidthChange(h),o(h)}),f?s.jsx(ut.div,{...r,ref:t,style:{width:i,height:c,position:"absolute",right:a.dir==="ltr"?0:void 0,left:a.dir==="rtl"?0:void 0,bottom:0,...e.style}}):null});function fg(e){return e?parseInt(e,10):0}function n8(e,t){const n=e/t;return isNaN(n)?0:n}function zv(e){const t=n8(e.viewport,e.content),n=e.scrollbar.paddingStart+e.scrollbar.paddingEnd,r=(e.scrollbar.size-n)*t;return Math.max(r,18)}function Tve(e,t,n,r="ltr"){const a=zv(n),i=a/2,o=t||i,c=a-o,d=n.scrollbar.paddingStart+o,f=n.scrollbar.size-n.scrollbar.paddingEnd-c,h=n.content-n.viewport,p=r==="ltr"?[0,h]:[h*-1,0];return r8([d,f],p)(e)}function _$(e,t,n="ltr"){const r=zv(t),a=t.scrollbar.paddingStart+t.scrollbar.paddingEnd,i=t.scrollbar.size-a,o=t.content-t.viewport,c=i-r,d=n==="ltr"?[0,o]:[o*-1,0],f=Df(e,d);return r8([0,o],[0,c])(f)}function r8(e,t){return n=>{if(e[0]===e[1]||t[0]===t[1])return t[0];const r=(t[1]-t[0])/(e[1]-e[0]);return t[0]+r*(n-e[0])}}function s8(e,t){return e>0&&e<t}var Rve=(e,t=()=>{})=>{let n={left:e.scrollLeft,top:e.scrollTop},r=0;return(function a(){const i={left:e.scrollLeft,top:e.scrollTop},o=n.left!==i.left,c=n.top!==i.top;(o||c)&&t(),n=i,r=window.requestAnimationFrame(a)})(),()=>window.cancelAnimationFrame(r)};function Bv(e,t){const n=Gn(e),r=m.useRef(0);return m.useEffect(()=>()=>window.clearTimeout(r.current),[]),m.useCallback(()=>{window.clearTimeout(r.current),r.current=window.setTimeout(n,t)},[n,t])}function xu(e,t){const n=Gn(t);ir(()=>{let r=0;if(e){const a=new ResizeObserver(()=>{cancelAnimationFrame(r),r=window.requestAnimationFrame(n)});return a.observe(e),()=>{window.cancelAnimationFrame(r),a.unobserve(e)}}},[e,n])}var a8=G6,Ove=X6,Mve=t8;const R_=m.forwardRef(({className:e,children:t,...n},r)=>s.jsxs(a8,{ref:r,className:Te("relative overflow-hidden",e),...n,children:[s.jsx(Ove,{className:"h-full w-full rounded-[inherit]",children:t}),s.jsx(i8,{}),s.jsx(Mve,{})]}));R_.displayName=a8.displayName;const i8=m.forwardRef(({className:e,orientation:t="vertical",...n},r)=>s.jsx(E_,{ref:r,orientation:t,className:Te("flex touch-none select-none transition-colors",t==="vertical"&&"h-full w-2.5 border-l border-l-transparent p-[1px]",t==="horizontal"&&"h-2.5 flex-col border-t border-t-transparent p-[1px]",e),...n,children:s.jsx(e8,{className:"relative flex-1 rounded-full bg-border"})}));i8.displayName=E_.displayName;function jN(e){return e instanceof Error&&e.name==="AbortError"||typeof e=="object"&&e!==null&&"name"in e&&e.name==="AbortError"}async function Ive(e){const{sessionId:t,source:n,serverName:r,onLaunchUrl:a,timeoutMs:i=5*6e4}=e,o=Date.now()+i;let c=!1;for(;Date.now()<o;){const{session:d}=await n.getOAuthRuntimeSession(t),f=d.authorizeLaunchUrl||d.authorizationUrl||"";if(f&&a&&a(f),d.status==="completed"&&d.hasAccessToken){c=!0;break}if(d.status==="error"||d.status==="stopped")throw new Error(`OAuth login failed for '${r}' (${d.status}). ${d.lastError||""}`.trim());await new Promise(h=>setTimeout(h,1500))}if(!c)throw new Error(`OAuth login timed out for '${r}'. Authorization was not completed within 5 minutes.`)}const $ve=250;async function vi(e){const{serverNames:t,source:n,onServerAuthStart:r,onServerStatus:a,timeoutMs:i=5*6e4}=e,o=Array.from(new Set(t.filter(Boolean)));if(o.length===0)return;const c=Date.now()+i,d=new Set,f=new Map;for(;Date.now()<c;){const h=await n.ensureOAuthServers({serverNames:o});for(const v of h.servers){const x=`${v.status}:${v.debugState??""}:${v.runtimeSessionId??""}`;f.get(v.serverName)!==x&&(f.set(v.serverName,x),a?.({serverName:v.serverName,status:v.status,debugState:v.debugState,tokenExpiresAt:v.tokenExpiresAt,tokenExpiresInSeconds:v.tokenExpiresInSeconds,message:v.message}))}const p=h.servers.filter(v=>v.status==="auth_required");if(p.length===0&&h.allReady)return;for(const v of p){const x=v.runtimeSessionId;if(!x)throw new Error(v.message||`OAuth login required for '${v.serverName}'.`);d.has(x)||(d.add(x),r?.(v.serverName));const j=(()=>{let b=!1;return y=>{if(b||!y)return;b=!0;const S=y.startsWith("http")?y:`${window.location.origin}${y}`;window.open(S,"_blank","noopener,noreferrer")}})();j(v.authorizeLaunchUrl||v.authorizationUrl||""),await Ive({sessionId:x,source:n,serverName:v.serverName,onLaunchUrl:j,timeoutMs:Math.max(1e4,c-Date.now())})}await new Promise(v=>{window.setTimeout(v,$ve)})}throw new Error("OAuth login timed out before all required servers were authorized.")}const Dve=[{label:"Suggest Checks",description:"Propose stronger evaluation checks for this scenario.",prompt:"Review the current checks in this scenario and suggest stronger alternatives. For each suggestion, explain what failure mode it catches that the existing checks miss. Prioritize checks that are deterministic, not sensitive to minor phrasing changes, and that would reliably catch regressions."},{label:"Suggest Value Capture Rules",description:"Recommend extract/value capture rules for key outputs.",prompt:"Analyze the expected tool calls and outputs in this scenario and suggest value capture rules that extract the most meaningful structured data. For each rule, explain which field to capture, why it matters for evaluation, and what a good vs. bad captured value looks like."},{label:"Generate Structured Updates",description:"Return apply-ready Checks and Value Capture suggestions.",prompt:["Propose concrete scenario updates and include structured suggestions that can be applied directly.","Return ONLY valid JSON envelope and no markdown.","Required shape:",'{"type":"assistant_message","text":"short rationale","suggestions":{"evalRules":{"replacement":[...]}, "extractRules":{"replacement":[...]}}}',"If tool usage is clear, include at least one required_tool check.","Prefer deterministic checks and concise capture patterns."].join(`
|
|
127
|
-
`)},{label:"Improve Prompt Determinism",description:"Reduce ambiguity and improve reproducibility.",prompt:"Identify parts of this scenario's prompt or context that are ambiguous, open-ended, or likely to produce different results across runs. Suggest specific rewrites that make the expected behavior more deterministic — without changing the intent of what is being tested."},{label:"Generate Scenario Draft",description:"Create a draft scenario from the current context.",prompt:"Based on the current tool configuration and context, generate a complete scenario draft. Include a clear prompt, realistic expected tool calls with arguments, meaningful checks that validate the core behavior, and at least one value capture rule. Explain your choices so I can adjust them."}];function Lve({open:e,onOpenChange:t,configId:n,configPath:r,scenario:a,agents:i,servers:o,defaultAssistantAgentName:c,initialUserMessage:d,onApplyPatch:f}){const{source:h}=On(),[p,v]=m.useState(null),[x,j]=m.useState(null),[b,y]=m.useState(""),[S,N]=m.useState(!1),[_,A]=m.useState(!1),[k,E]=m.useState(new Set),P=m.useRef(null),R=m.useRef(null),M=m.useRef(null),D=m.useRef(null),U=m.useRef(0),[F,G]=m.useState(!1),H=m.useRef(!1),L=c||i[0]?.id||"",I=m.useCallback(()=>{const Q=D.current;Q&&Q.controller.abort()},[]);m.useEffect(()=>{if(!e||!L||p)return;let Q=!1;return N(!0),(async()=>{const Fe=Array.from(new Set(a.serverIds.filter(ot=>o.find(wt=>wt.id===ot)?.authType==="oauth2")));await vi({serverNames:Fe,source:h});const pt=await h.createScenarioAssistantSession({configId:n,configPath:r,scenarioId:a.id,selectedAssistantAgentName:L,context:{scenario:{id:a.id,name:a.name,prompt:a.prompt,serverNames:a.serverIds,evalRules:a.evalRules,extractRules:a.extractRules},availableServers:o.map(ot=>({name:ot.name||ot.id,url:ot.url})),availableAgents:i.map(ot=>({name:ot.name||ot.id,provider:ot.provider,model:ot.model}))}});Q||(v(pt.sessionId),W(pt.session),N(!1))})().catch(Fe=>{Q||Ie({title:"Could not start Scenario Assistant",description:Fe instanceof Error?Fe.message:String(Fe),variant:"destructive"})}).finally(()=>{Q||N(!1)}),()=>{Q=!0}},[e,h,p,n,r,a,i,o,L]);const Y=()=>{I(),v(null),j(null),y(""),E(new Set),M.current=null},W=m.useCallback(Q=>{j(Ne=>Ne&&Ne.messages.length>Q.messages.length?Ne:Q)},[]),O=m.useCallback(()=>{const Q=D.current;Q&&(I(),y(Q.prompt),N(!1),A(!1))},[I]),Z=Q=>{Y(),h.closeScenarioAssistantSession(Q).catch(()=>{})};m.useEffect(()=>{e||p&&(H.current||F||Z(p))},[e,p,h,F]),m.useEffect(()=>()=>{I(),p&&h.closeScenarioAssistantSession(p).catch(()=>{})},[I,p,h]),m.useEffect(()=>{if(!e)return;F&&G(!1),H.current&&(H.current=!1);const Q=window.setTimeout(()=>{P.current?.scrollIntoView({behavior:"smooth",block:"end"})},0);return()=>window.clearTimeout(Q)},[e,S,x?.messages.length,x?.pendingToolCalls.length,x?.warnings.length]),m.useEffect(()=>{const Q=R.current;if(!Q)return;Q.style.height="0px";const Ne=Math.min(Q.scrollHeight,160);Q.style.height=`${Math.max(40,Ne)}px`},[b,e]);const q=i.length>0&&a.serverIds.length>0&&!!L,z=async Q=>{if(!p)return;const Ne=Q.trim();if(!Ne)return;const Fe=++U.current,pt=new AbortController,ot=`msg-local-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,bt={id:ot,role:"user",text:Ne,createdAt:new Date().toISOString()};D.current={id:Fe,controller:pt,prompt:Ne},A(!0),j(wt=>wt&&{...wt,messages:[...wt.messages,bt]}),y(""),N(!0);try{const wt=await h.sendScenarioAssistantMessage(p,Ne,pt.signal);if(pt.signal.aborted||D.current?.id!==Fe)return;W(wt.session)}catch(wt){if(jN(wt)||pt.signal.aborted||D.current?.id!==Fe)return;j(et=>et&&{...et,messages:et.messages.filter(_e=>_e.id!==ot)}),y(et=>et.trim()?et:Ne),Ie({title:"Scenario Assistant error",description:wt instanceof Error?wt.message:String(wt),variant:"destructive"})}finally{D.current?.id===Fe&&(D.current=null,N(!1),A(!1))}},K=Q=>{y(Q),requestAnimationFrame(()=>R.current?.focus())};m.useEffect(()=>{if(!e||!p||!x||!q||D.current)return;const Q=String(d??"").trim();Q&&M.current!==Q&&(M.current=Q,z(Q))},[e,p,x,q,d]),m.useEffect(()=>{if(!(!e||!p||!x))return h.subscribeScenarioAssistantSessionEvents(p,Q=>{W(Q.payload.session)})},[e,p,h,W]);const J=async Q=>{if(p){N(!0);try{const Ne=await h.approveScenarioAssistantToolCall(p,Q);W(Ne.session)}catch(Ne){Ie({title:"Tool call failed",description:Ne instanceof Error?Ne.message:String(Ne),variant:"destructive"})}finally{N(!1)}}},re=async Q=>{if(p){N(!0);try{const Ne=await h.denyScenarioAssistantToolCall(p,Q);W(Ne.session)}catch(Ne){Ie({title:"Could not deny tool call",description:Ne instanceof Error?Ne.message:String(Ne),variant:"destructive"})}finally{N(!1)}}},he=async()=>{if(p){N(!0);try{const Q=await h.approveAllScenarioAssistantToolCalls(p);W(Q.session)}catch(Q){Ie({title:"Could not approve all tool calls",description:Q instanceof Error?Q.message:String(Q),variant:"destructive"})}finally{N(!1)}}},oe=(Q,Ne,Fe)=>{if(!Ne)return;if(Fe==="prompt"&&Ne.prompt&&f({prompt:Ne.prompt.replacement}),Fe==="evalRules"&&Ne.evalRules&&f({evalRules:Ne.evalRules.replacement}),Fe==="extractRules"&&Ne.extractRules&&f({extractRules:Ne.extractRules.replacement}),Q){const ot=`${Q}:${Fe}`;E(bt=>new Set([...bt,ot]))}Ie({title:"Applied suggestion",description:`Updated ${{prompt:"Prompt",evalRules:"Checks",extractRules:"Value Capture Rules"}[Fe]}`})},me=()=>{const Q=document.activeElement;Q instanceof HTMLElement&&Q.blur()},ie=Q=>{Q||(me(),G(!1),H.current=!1),t(Q)},ge=()=>{me(),H.current=!0,G(!0),t(!1)},Re=()=>{me(),H.current=!1,G(!1),p&&Z(p)};return s.jsxs(s.Fragment,{children:[!e&&p&&s.jsxs("div",{className:"mt-3 flex items-center justify-between gap-2 rounded-md border bg-background px-3 py-2",children:[s.jsxs("div",{className:"min-w-0",children:[s.jsx("p",{className:"text-sm font-medium",children:"Scenario Assistant (session active)"}),s.jsxs("p",{className:"truncate text-xs text-muted-foreground",children:["Resume conversation for ",s.jsx("span",{className:"font-mono",children:a.id}),x?` · ${x.messages.length} messages`:""]})]}),s.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[s.jsxs(ee,{type:"button",size:"sm",variant:"outline",onClick:()=>t(!0),children:[s.jsx(Zr,{className:"mr-1.5 h-3.5 w-3.5"}),"Resume"]}),s.jsx(ee,{type:"button",size:"sm",variant:"ghost",className:"h-8 px-2 text-muted-foreground",onClick:Re,"aria-label":"Discard assistant session",title:"Discard assistant session",children:s.jsx(ns,{className:"h-4 w-4"})})]})]}),s.jsx(bve,{open:e,onOpenChange:ie,children:s.jsxs(U6,{className:"max-w-6xl h-[85vh] flex flex-col",children:[p&&s.jsxs("button",{type:"button",className:"absolute right-12 top-4 z-10 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",onClick:ge,"aria-label":"Minimize assistant",title:"Minimize assistant",children:[s.jsx(O9,{className:"h-4 w-4"}),s.jsx("span",{className:"sr-only",children:"Minimize"})]}),s.jsx(W6,{className:"pr-20",children:s.jsx("div",{className:"flex items-start justify-between gap-3",children:s.jsxs("div",{className:"min-w-0",children:[s.jsxs(V6,{className:"flex items-center gap-2",children:[s.jsx(Zr,{className:"h-4 w-4"}),"Scenario Assistant"]}),s.jsx(H6,{children:"LLM-guided scenario authoring with MCP tool introspection and per-tool-call approval."})]})})}),q?s.jsxs("div",{className:"min-h-0 flex flex-1 flex-col gap-3",children:[s.jsx("div",{className:"grid gap-3 sm:grid-cols-1",children:s.jsxs("div",{className:"space-y-1.5",children:[s.jsx(Ve,{className:"text-xs",children:"MCP Context"}),s.jsxs("div",{className:"h-8 rounded-md border px-2 text-xs flex items-center gap-2",children:[s.jsx(pa,{className:"h-3.5 w-3.5"}),x?`Loaded ${x.toolsLoaded} tools`:"Preparing..."]})]})}),s.jsx(R_,{className:"min-h-0 flex-1 rounded-md border p-3",children:s.jsxs("div",{className:"space-y-3",children:[x?.warnings?.map((Q,Ne)=>s.jsx("div",{className:"rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-900",children:Q},`${Q}-${Ne}`)),x?.messages.map(Q=>s.jsxs(m.Fragment,{children:[(()=>{const Ne=Q.pendingToolCallIds??(Q.pendingToolCallId?[Q.pendingToolCallId]:[]),Fe=Ne.map(et=>(x?.pendingToolCalls??[]).find(_e=>_e.id===et)).filter(et=>!!et),pt=Ne.map(et=>x.pendingToolCalls.find(_e=>_e.id===et)??x.pendingToolCalls.find(_e=>_e.id===et)).filter(Boolean);if(!(Q.role==="assistant"&&Ne.length>0))return s.jsx("div",{className:"space-y-2",children:s.jsx(Fve,{message:Q})});const bt=Fe.length,wt=pt.length-bt;return s.jsxs("div",{className:"flex items-start gap-2",children:[s.jsx("div",{className:"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-700",children:s.jsx(Fr,{className:"h-3 w-3"})}),s.jsxs("div",{className:"w-full max-w-[92%] space-y-2",children:[pt.length>1&&bt>0&&s.jsxs("div",{className:"flex items-center justify-between gap-2 rounded-md border border-amber-200 bg-amber-50/50 px-3 py-1.5",children:[s.jsxs("span",{className:"text-xs text-amber-900",children:[wt," of ",pt.length," tool calls resolved"]}),s.jsxs(ee,{type:"button",size:"sm",className:"h-7 px-2 text-xs",disabled:bt===0,onClick:()=>{he()},children:["Approve All (",bt,")"]})]}),pt.map((et,_e)=>s.jsx(wN,{call:et,loading:S,description:_e===0?Q.text:void 0,onApprove:Ee=>{J(Ee)},onDeny:Ee=>{re(Ee)}},et.id))]})]})})(),Q.suggestions&&s.jsxs("div",{className:"ml-0 space-y-3 rounded-md border border-dashed bg-muted/10 p-3",children:[s.jsxs("div",{className:"flex items-center gap-2 text-xs font-medium text-muted-foreground",children:[s.jsx(Zr,{className:"h-3.5 w-3.5"}),"Structured Suggestions"]}),Q.suggestions.prompt&&s.jsx(nS,{title:"Prompt",rationale:Q.suggestions.prompt.rationale,preview:Q.suggestions.prompt.replacement,applied:k.has(`${Q.id}:prompt`),onApply:()=>oe(Q.id,Q.suggestions,"prompt")}),Q.suggestions.evalRules&&s.jsx(nS,{title:"Checks",rationale:Q.suggestions.evalRules.rationale,preview:JSON.stringify(Q.suggestions.evalRules.replacement,null,2),applied:k.has(`${Q.id}:evalRules`),onApply:()=>oe(Q.id,Q.suggestions,"evalRules")}),Q.suggestions.extractRules&&s.jsx(nS,{title:"Value Capture Rules",rationale:Q.suggestions.extractRules.rationale,preview:JSON.stringify(Q.suggestions.extractRules.replacement,null,2),applied:k.has(`${Q.id}:extractRules`),onApply:()=>oe(Q.id,Q.suggestions,"extractRules")}),(()=>{const Ne=Q.suggestions?.notes,Fe=Array.isArray(Ne)?Ne:typeof Ne=="string"?[Ne]:[];return Fe.length===0?null:s.jsxs("div",{className:"space-y-2 rounded-md border p-3",children:[s.jsx("h5",{className:"text-sm font-medium",children:"Notes"}),s.jsx("ul",{className:"space-y-1 text-xs text-muted-foreground list-disc pl-4",children:Fe.map((pt,ot)=>s.jsx("li",{children:pt},`${Q.id}-note-${ot}`))})]})})()]})]},Q.id)),(x?.pendingToolCalls??[]).filter(Q=>!(x?.messages??[]).some(Ne=>Ne.pendingToolCallId===Q.id||Ne.pendingToolCallIds?.includes(Q.id))).map(Q=>s.jsx(wN,{call:Q,loading:S,onApprove:Ne=>{J(Ne)},onDeny:Ne=>{re(Ne)}},Q.id)),!x&&S&&s.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[s.jsx(wr,{className:"h-4 w-4 animate-spin"}),"Starting assistant session..."]}),x&&S&&s.jsx(z6,{}),s.jsx("div",{ref:P})]})}),s.jsx(B6,{input:b,onInputChange:y,onSend:()=>{z(b)},onCancel:p&&_?O:void 0,inputPlaceholder:"Get assistance with creating or refining this scenario ...",snippets:Dve,snippetsLabel:"Scenario Assistant Snippets",onSnippetSelect:K,loading:S,disabled:!p,inputRef:R,snippetContentClassName:"w-[320px]"})]}):s.jsx("div",{className:"rounded-md border p-3 text-sm text-muted-foreground",children:"Scenario Assistant requires a configured assistant agent and at least one selected server on the scenario."})]})})]})}function nS({title:e,rationale:t,preview:n,applied:r=!1,onApply:a}){return s.jsxs("div",{className:`space-y-2 rounded-md border p-3 ${r?"border-emerald-300 bg-emerald-50/40":""}`,children:[s.jsxs("div",{className:"flex items-center justify-between gap-2",children:[s.jsx("h5",{className:"text-sm font-medium",children:e}),s.jsx(ee,{type:"button",size:"sm",variant:r?"secondary":"outline",onClick:a,disabled:r,children:r?s.jsxs(s.Fragment,{children:[s.jsx(fi,{className:"mr-1.5 h-3.5 w-3.5"}),"Applied"]}):"Apply"})]}),t&&s.jsx("p",{className:"text-xs text-muted-foreground",children:t}),s.jsx("pre",{className:"max-h-56 overflow-auto rounded bg-muted p-2 text-xs whitespace-pre-wrap",children:n})]})}function Fve({message:e}){const t=async a=>{try{await navigator.clipboard.writeText(a),Ie({title:"Copied"})}catch(i){Ie({title:"Could not copy",description:i instanceof Error?i.message:String(i),variant:"destructive"})}},n=e.role==="user"||e.role==="assistant",r=e.role==="user";return s.jsx(F6,{message:e,assistantLabel:e.role==="assistant"?"Assistant":void 0,renderActions:n?s.jsx(ee,{type:"button",variant:"ghost",size:"icon",className:`absolute bottom-1 h-6 w-6 text-muted-foreground ${r?"-left-8":"-right-8"}`,onClick:()=>{t(e.text)},"aria-label":"Copy message",title:"Copy message",children:s.jsx(ss,{className:"h-3.5 w-3.5"})}):void 0})}function Yr(e){return typeof e=="number"?e.toLocaleString():"n/a"}function SN(e,t){const n=t?.nonPositiveLabel??"0s";if(!Number.isFinite(e)||e<=0)return n;const r=Math.floor(e),a=Math.floor(r/3600),i=Math.floor(r%3600/60),o=r%60;return a>0?`${a}h ${i}m ${o}s`:i>0?`${i}m ${o}s`:`${o}s`}function zve({run:e,fallbackUserPrompt:t}){const[n,r]=m.useState(!0),[a,i]=m.useState(!1);return s.jsxs("div",{className:"space-y-2",children:[s.jsx(da,{open:n,onOpenChange:r,children:s.jsxs("div",{className:"rounded-md border border-muted-foreground/20 bg-card p-2",children:[s.jsx(Ms,{asChild:!0,children:s.jsx("button",{type:"button",className:"mb-2 flex w-full items-center justify-between gap-2 text-left",children:s.jsxs("p",{className:"flex items-center gap-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground",children:[s.jsx(tn,{className:`h-3.5 w-3.5 transition-transform ${n?"rotate-180":""}`}),s.jsx(Fr,{className:"h-3.5 w-3.5"}),"Final answer"]})})}),s.jsx(fa,{children:s.jsx(NN,{text:e.finalAnswer||"No final answer captured.",maxLength:1200,className:"text-xs text-foreground"})})]})}),s.jsx(da,{open:a,onOpenChange:i,children:s.jsxs("div",{className:"rounded-md border border-muted-foreground/20 bg-card p-2",children:[s.jsxs("div",{className:"mb-2 flex flex-wrap items-center justify-between gap-2",children:[s.jsx(Ms,{asChild:!0,children:s.jsxs("button",{type:"button",className:"flex min-w-0 items-center gap-2 text-left",children:[s.jsx(tn,{className:`h-3.5 w-3.5 transition-transform ${a?"rotate-180":""}`}),s.jsx("p",{className:"text-[11px] font-semibold uppercase tracking-wide text-muted-foreground",children:"Conversation trace"})]})}),s.jsxs(st,{variant:"outline",className:"h-5 text-[10px]",children:[e.toolCalls.length," tool calls"]})]}),s.jsx(fa,{children:s.jsx("div",{className:"space-y-2 rounded-md border bg-muted/20 p-2",children:e.conversation.length===0?s.jsx("p",{className:"text-xs text-muted-foreground",children:"No conversation trace captured."}):e.conversation.map(o=>s.jsx(Bve,{item:o,fallbackUserPrompt:t},o.id))})})]})})]})}function Bve({item:e,fallbackUserPrompt:t}){if(e.kind==="tool_call"){const d=A$(e,"input");return s.jsx(E$,{variant:"call",title:`Tool call · ${e.toolName||"unknown"}${d}`,text:e.text})}if(e.kind==="tool_result"){const d=A$(e,"output"),f=e.ok?s.jsx(fi,{className:"h-3.5 w-3.5 text-emerald-700 dark:text-emerald-300"}):s.jsx(tl,{className:"h-3.5 w-3.5 text-rose-700 dark:text-rose-300"});return s.jsx(E$,{variant:e.ok?"result_ok":"result_error",title:`Tool result · ${e.toolName||"unknown"} · ${e.ok?"ok":"error"}${typeof e.durationMs=="number"?` · ${e.durationMs}ms`:""}${d}`,text:e.text,icon:f})}const n=e.kind==="user_prompt",r=k$(e.text,e.kind),a=t?k$(t,"user_prompt"):"",i=n&&!r&&a?a:r,o=n?"User prompt":e.kind==="assistant_final"?"Agent final":"Agent",c=n?Uc:Fr;return s.jsxs("div",{className:`flex items-start gap-2 text-xs ${n?"justify-end":"justify-start"}`,children:[!n&&s.jsx("div",{className:"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",children:s.jsx(c,{className:"h-3 w-3"})}),s.jsxs("div",{className:`max-w-[90%] rounded-md p-2 ${n?"bg-primary/10":"bg-muted/50"}`,children:[s.jsx("p",{className:`mb-1 text-[11px] font-semibold text-muted-foreground ${n?"text-right":""}`,children:o}),n?s.jsx(NN,{text:i,maxLength:280,className:"text-xs"}):s.jsx(NN,{text:i,maxLength:500,className:"text-xs"})]}),n&&s.jsx("div",{className:"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-primary/30 bg-primary/15 text-primary",children:s.jsx(c,{className:"h-3 w-3"})})]})}function A$(e,t){const n=t==="input"?e.estimatedTokens?.inputTokens:e.estimatedTokens?.outputTokens;return typeof n!="number"?"":` · estimated ${Yr(n)} tokens`}function k$(e,t){const r=String(e??"").replace(/^\s+/,"");return t==="user_prompt"?r.replace(/^user:\s*/i,""):t==="assistant_final"||t==="assistant_thought"?r.replace(/^assistant:\s*/i,""):r}function E$({variant:e,title:t,text:n,icon:r}){const[a,i]=m.useState(!1),o={call:"border-sky-500/30 bg-sky-500/10 text-sky-700 dark:text-sky-300",result_ok:"border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",result_error:"border-rose-500/30 bg-rose-500/10 text-rose-700 dark:text-rose-300"};return s.jsx(da,{open:a,onOpenChange:i,children:s.jsxs("div",{className:`rounded-md border p-2 text-xs ${o[e]}`,children:[s.jsx(Ms,{asChild:!0,children:s.jsxs("button",{type:"button",className:"flex w-full items-center justify-between gap-2 text-left",children:[s.jsxs("div",{className:"flex items-center gap-1.5 font-mono text-[11px]",children:[r??s.jsx(pa,{className:"h-3.5 w-3.5"}),s.jsx("span",{children:t})]}),s.jsx("span",{className:"text-[11px] font-semibold",children:a?"Hide content":"Show content"})]})}),s.jsx(fa,{children:s.jsx("p",{className:"mt-2 font-mono whitespace-pre-wrap text-foreground",children:n})})]})})}function NN({text:e,maxLength:t,className:n}){const[r,a]=m.useState(!1),i=e.length>t,o=r||!i?e:`${e.slice(0,t)}...`;return s.jsxs("div",{children:[s.jsx(Fs,{text:o,className:n}),i&&s.jsx("button",{type:"button",className:"mt-1 text-[11px] font-medium text-primary hover:underline",onClick:()=>a(c=>!c),children:r?"Show less":"Show all"})]})}const o8=["image/jpeg","image/png","image/gif","image/webp"],l8=["application/pdf","text/plain","text/markdown","text/csv"];function qve(e){return o8.includes(e)||l8.includes(e)}function Uve(e,t,n){if(e.type==="agent_check"){const a=String(e.label??"").trim();return a?t.find(i=>i.type==="agent_check"&&i.label===a):void 0}const r=n(e);return t.find(a=>a.type===e.type&&a.label===r)}function c8({evalRules:e,failureReasons:t,runError:n,checkResults:r}){return n||t.find(i=>i.startsWith("Scenario error:"))?e.map(i=>({rule:i,status:"not_evaluated",failureReason:void 0})):r?.length?e.map(i=>{const o=Uve(i,r,O_);return{rule:i,status:o?.status??"not_evaluated",failureReason:o?.reason}}):e.map(i=>{const o=Vve(i,t);return{rule:i,status:o?"failed":"passed",failureReason:o}})}function O_(e){return e.type==="required_tool"?`Required tool · ${e.value}`:e.type==="forbidden_tool"?`Forbidden tool · ${e.value}`:e.type==="tool_sequence"?A_(e.sequence??[]):e.type==="response_contains"?`Text contains · ${e.value}`:e.type==="response_not_contains"?`Text does not contain · ${e.value}`:e.type==="response_starts_with"?`Text starts with · ${e.value}`:e.type==="response_ends_with"?`Text ends with · ${e.value}`:e.type==="response_equals"?`Text equals · ${e.value}`:e.type==="response_regex"?`Text matches regex · ${e.value}`:e.type==="response_jsonpath"?e.equals!==void 0?`JSONPath equals · ${e.path} == ${String(e.equals)}`:`JSONPath exists · ${e.path}`:e.type==="response_jsonpath_exists"?`JSONPath exists · ${e.path}`:e.type==="response_jsonpath_not_exists"?`JSONPath not exists · ${e.path}`:e.type==="agent_check"?`Agent check · ${e.label}`:`${e.type} · ${e.value}`}function Wve(e){return A_(e).replace(/^Tool sequence · /,"")}function Vve(e,t){if(e.type==="response_jsonpath_exists"){const a=String(e.path??"").trim();return a?t.find(i=>i.startsWith(`JSONPath assertion failed: ${a}`)||i.startsWith(`JSONPath assertion failed: invalid JSON for path ${a}`)):void 0}const n=e.type==="required_tool"?`Required tool not used: ${e.value}`:e.type==="forbidden_tool"?`Forbidden tool used: ${e.value}`:e.type==="tool_sequence"?`Tool sequence order was not satisfied: ${(e.sequence??[]).join(" -> ")}`:e.type==="response_contains"?`Contains assertion failed: ${e.value}`:e.type==="response_not_contains"?`Not-contains assertion failed: ${e.value}`:e.type==="response_starts_with"?`Starts-with assertion failed: ${e.value}`:e.type==="response_ends_with"?`Ends-with assertion failed: ${e.value}`:e.type==="response_equals"?`Equals assertion failed: ${e.value}`:e.type==="response_regex"?`Regex assertion failed: ${e.value}`:e.type==="response_jsonpath"?e.equals!==void 0?`JSONPath equals assertion failed: ${e.path}`:`JSONPath assertion failed: ${e.path}`:e.type==="response_jsonpath_not_exists"?`JSONPath not-exists assertion failed: ${e.path}`:e.type==="agent_check"?String(e.label??""):"";if(!n)return;const r=t.find(a=>a===n);return r||(e.type==="response_regex"?t.find(a=>a.startsWith("Regex assertion failed:")&&a.includes(e.value??"")):e.type==="response_jsonpath"||e.type==="response_jsonpath_not_exists"?t.find(a=>a.includes(e.path??"")):e.type==="tool_sequence"?t.find(a=>a.startsWith(`Tool sequence order was not satisfied: ${Wve(e.sequence??[])}`)||a.startsWith("Required tool in sequence not used:")):t.find(a=>a.startsWith(n)))}function P$({value:e,onValueChange:t,className:n,hideToolSequence:r=!1}){return s.jsxs(In,{value:e,onValueChange:a=>t(a),children:[s.jsx(Tn,{className:n,children:s.jsx($n,{})}),s.jsxs(Rn,{children:[s.jsx(mt,{value:"required_tool",children:"Required Tool"}),s.jsx(mt,{value:"forbidden_tool",children:"Forbidden Tool"}),!r&&s.jsx(mt,{value:"tool_sequence",children:"Tool Sequence"}),s.jsx(mt,{value:"agent_check",children:"Judge Agent"}),s.jsx(mt,{value:"response_contains",children:"Text contains"}),s.jsx(mt,{value:"response_not_contains",children:"Text does not contain"}),s.jsx(mt,{value:"response_starts_with",children:"Text starts with"}),s.jsx(mt,{value:"response_ends_with",children:"Text ends with"}),s.jsx(mt,{value:"response_equals",children:"Text equals"}),s.jsx(mt,{value:"response_regex",children:"Text matches regex"}),s.jsx(mt,{value:"response_jsonpath",children:"JSONPath (optional equals)"}),s.jsx(mt,{value:"response_jsonpath_exists",children:"JSONPath exists"}),s.jsx(mt,{value:"response_jsonpath_not_exists",children:"JSONPath not exists"})]})]})}const Hve=()=>({id:`scn-${Date.now()}`,name:"",serverIds:[],prompt:"",evalRules:[],extractRules:[]});function u8(e){return A_(e).replace(/^Tool sequence · /,"")}function CN({scenarios:e,scenarioOrigins:t,scenarioOverrides:n,agents:r,servers:a,configId:i,configPath:o,defaultAssistantAgentName:c,assistantInitialPromptByScenarioId:d,assistantAutoOpenNonceByScenarioId:f,testCaseReturnToPath:h,onChange:p,readOnly:v,allowAdd:x=!v,allowStructureEdits:j=!v}){const b=(_,A)=>{const k=e.map((E,P)=>P===_?{...E,...A}:E);p(k)},y=_=>p(e.filter((A,k)=>k!==_)),S=()=>p([...e,Hve()]),N=(_,A)=>{const k=_+A;if(k<0||k>=e.length)return;const E=[...e],[P]=E.splice(_,1);E.splice(k,0,P),p(E)};return s.jsxs("div",{className:v?"space-y-2":"space-y-4",children:[!v&&s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx("h3",{className:"text-sm font-semibold",children:"Scenarios"}),x&&j&&s.jsxs(ee,{type:"button",variant:"outline",size:"sm",onClick:S,children:[s.jsx(yi,{className:"mr-1.5 h-3.5 w-3.5"}),"Add Scenario"]})]}),e.map((_,A)=>s.jsx(Kve,{scenario:_,scenarioOrigin:t?.[A],hasMcpServerOverride:n?.[A],index:A,total:e.length,agents:r,servers:a,configId:i,configPath:o,defaultAssistantAgentName:c,assistantInitialPrompt:d?.[_.id],assistantAutoOpenNonce:f?.[_.id],testCaseReturnToPath:h,onUpdate:k=>b(A,k),onMoveUp:()=>N(A,-1),onMoveDown:()=>N(A,1),onRemove:()=>y(A),readOnly:v,allowStructureEdits:j},_.id)),e.length===0&&s.jsx("p",{className:"text-sm text-muted-foreground text-center py-6",children:"No scenarios configured. Add one to get started."})]})}function Kve({scenario:e,scenarioOrigin:t,hasMcpServerOverride:n,index:r,total:a,agents:i,servers:o,configId:c,configPath:d,defaultAssistantAgentName:f,assistantInitialPrompt:h,assistantAutoOpenNonce:p,testCaseReturnToPath:v,onUpdate:x,onMoveUp:j,onMoveDown:b,onRemove:y,readOnly:S,allowStructureEdits:N}){const{source:_}=On(),[A,k]=m.useState("required_tool"),[E,P]=m.useState(""),[R,M]=m.useState(""),[D,U]=m.useState(""),[F,G]=m.useState(""),[H,L]=m.useState(""),[I,Y]=m.useState(""),[W,O]=m.useState([]),[Z,q]=m.useState(!1),[z,K]=m.useState(null),[J,re]=m.useState(null),[he,oe]=m.useState(!1),[me,ie]=m.useState(null),[ge,Re]=m.useState(""),[Q,Ne]=m.useState(null),[Fe,pt]=m.useState(!1),[ot,bt]=m.useState(null),[wt,et]=m.useState(""),[_e,Ee]=m.useState(""),[tt,ct]=m.useState(!1),[Pt,Xt]=m.useState(f||i[0]?.id||""),[kt,nn]=m.useState(!1),[Jt,zt]=m.useState(null),[Se,Xe]=m.useState(""),Qe=m.useRef(null);function At(ce){if(!ce)return;const it=Array.from(ce),Wt=new Array(it.length).fill(null);let Dt=0,qt=0;const dn=()=>{const lr=Wt.filter(os=>os!==null);lr.length>0?(x({attachments:[...e.attachments??[],...lr]}),qt>0&&Ie({title:`${qt} file${qt>1?"s":""} skipped`,description:"Unsupported file type. Images must be JPEG/PNG/GIF/WebP; documents must be PDF, TXT, MD, or CSV.",variant:"destructive"})):it.length>0&&Ie({title:"Could not attach files",description:qt>0?"Unsupported file type. Images must be JPEG/PNG/GIF/WebP; documents must be PDF, TXT, MD, or CSV.":"Files could not be read.",variant:"destructive"})};it.forEach((lr,os)=>{const gr=new FileReader;gr.onload=()=>{const Ro=gr.result,vr=Ro.indexOf(","),Wl=vr>=0?Ro.slice(vr+1):"";if(Wl){const ae=Ro.slice(0,vr).replace("data:","").replace(";base64",""),ke=ae.startsWith("image/");qve(ae)?Wt[os]={type:ke?"image":"document",media_type:ae,data:Wl,name:lr.name}:qt++}++Dt===it.length&&dn()},gr.onerror=()=>{++Dt===it.length&&dn()},gr.readAsDataURL(lr)})}function Bt(ce){x({attachments:(e.attachments??[]).filter((it,Wt)=>Wt!==ce)})}const[de,Ke]=m.useState(null),[$e,se]=m.useState(!S),we=ce=>{const it=ce.target;it&&(it.closest("button, a, input, select, textarea, [role='button']")||se(Wt=>!Wt))},Ue=ce=>ce?e.evalRules.findIndex(it=>it===ce):-1,B=()=>{if(A==="response_jsonpath"||A==="response_jsonpath_exists"||A==="response_jsonpath_not_exists"){const Dt=R.trim();if(!Dt)return;if(A==="response_jsonpath"){const qt=D.trim();let dn;qt.length>0&&(qt==="true"?dn=!0:qt==="false"?dn=!1:Number.isNaN(Number(qt))?dn=qt:dn=Number(qt)),x({evalRules:[...e.evalRules,{type:A,path:Dt,...dn!==void 0?{equals:dn}:{}}]})}else x({evalRules:[...e.evalRules,{type:A,path:Dt}]});M(""),U("");return}if(A==="agent_check"){const Dt=F.trim(),qt=H.trim();if(!Dt||!qt)return;const dn=[...e.evalRules],lr={type:"agent_check",label:Dt,prompt:qt},os=Ue(J);os>=0?dn[os]=lr:dn.push(lr),x({evalRules:dn}),G(""),L(""),re(null),oe(!1),k("required_tool");return}if(A==="tool_sequence"){const Dt=W.map(qt=>qt.trim()).filter(qt=>typeof qt=="string"&&qt.length>0);if(Dt.length===0)return;ve(Dt);return}if(!E.trim())return;const ce=[...e.evalRules],it={type:A,value:E.trim()},Wt=Ue(me);Wt>=0?ce[Wt]=it:ce.push(it),x({evalRules:ce}),P(""),Re(""),ie(null),k("required_tool")},le=()=>{const ce=I.trim();ce&&(O(it=>[...it,ce]),Y(""))},fe=(ce,it)=>{const Wt=ce+it;O(Dt=>{if(Wt<0||Wt>=Dt.length)return Dt;const qt=[...Dt],[dn]=qt.splice(ce,1);return qt.splice(Wt,0,dn),qt})},De=ce=>{O(it=>it.filter((Wt,Dt)=>Dt!==ce))},Me=e.evalRules.findIndex(ce=>ce.type==="tool_sequence"),Ge=Me>=0?e.evalRules[Me]:void 0,Oe=Ge?.type==="tool_sequence"?Ge.sequence:[],V=Me>=0,ve=ce=>{const it=[...e.evalRules],Wt=ce.length>0?{type:"tool_sequence",sequence:ce}:null,Dt=Ue(z),qt=Dt>=0?Dt:Me;qt>=0?Wt?it[qt]=Wt:it.splice(qt,1):Wt&&it.push(Wt),x({evalRules:it}),q(!1),O([]),Y(""),K(null),A==="tool_sequence"&&k("required_tool")};m.useEffect(()=>{Z&&O(Oe)},[Z,Me,Oe.join("|")]),m.useEffect(()=>{q(A==="tool_sequence")},[A]),m.useEffect(()=>{oe(A==="agent_check")},[A]),m.useEffect(()=>{z&&Ue(z)<0&&K(null),J&&Ue(J)<0&&re(null),me&&Ue(me)<0&&ie(null)},[e.evalRules,z,J,me]),m.useEffect(()=>{z&&A!=="tool_sequence"&&K(null),J&&A!=="agent_check"&&re(null),me&&me.type!==A&&ie(null)},[A,z,J,me]);const Ae=ce=>{const it=e.evalRules.filter((Dt,qt)=>qt!==ce),Wt=it.some(Dt=>Dt.type==="agent_check");x({evalRules:it,agentContext:Wt?e.agentContext:void 0})},Je=["response_contains","response_not_contains","response_starts_with","response_ends_with","response_equals","response_regex"],ne=()=>{!wt.trim()||!_e.trim()||(x({extractRules:[...e.extractRules,{name:wt.trim(),pattern:_e.trim()}]}),et(""),Ee(""))},Le=ce=>{x({extractRules:e.extractRules.filter((it,Wt)=>Wt!==ce)})},ht=ce=>{const it=e.serverIds.includes(ce)?e.serverIds.filter(Wt=>Wt!==ce):[...e.serverIds,ce];x({serverIds:it})},Qt={required_tool:"Required",forbidden_tool:"Forbidden",tool_sequence:"Sequence",response_contains:"Contains",response_not_contains:"Not Contains",response_starts_with:"Starts With",response_ends_with:"Ends With",response_equals:"Equals",response_regex:"Regex",response_jsonpath:"JSONPath",response_jsonpath_exists:"JSONPath Exists",response_jsonpath_not_exists:"JSONPath Not Exists",agent_check:"Agent"},Ce={required_tool:"border-sky-300/60 bg-sky-500/10 text-sky-700",forbidden_tool:"border-rose-300/60 bg-rose-500/10 text-rose-700",tool_sequence:"border-teal-300/60 bg-teal-500/10 text-teal-700",response_contains:"border-violet-300/60 bg-violet-500/10 text-violet-700",response_not_contains:"border-amber-300/60 bg-amber-500/10 text-amber-700",response_starts_with:"border-cyan-300/60 bg-cyan-500/10 text-cyan-700",response_ends_with:"border-indigo-300/60 bg-indigo-500/10 text-indigo-700",response_equals:"border-lime-300/60 bg-lime-500/10 text-lime-700",response_regex:"border-fuchsia-300/60 bg-fuchsia-500/10 text-fuchsia-700",response_jsonpath:"border-emerald-300/60 bg-emerald-500/10 text-emerald-700",response_jsonpath_exists:"border-green-300/60 bg-green-500/10 text-green-700",response_jsonpath_not_exists:"border-orange-300/60 bg-orange-500/10 text-orange-700",agent_check:"border-teal-300/60 bg-teal-500/10 text-teal-700"},en=A==="required_tool"||A==="forbidden_tool",_t=A==="response_jsonpath"||A==="response_jsonpath_exists"||A==="response_jsonpath_not_exists",Kt=A==="tool_sequence"&&Z,Hn=A==="agent_check"&&he,_n=e.serverIds.filter(ce=>o.some(it=>it.id===ce)),Ya=i.map(ce=>ce.id).filter(Boolean),Xa=_n.length>0,[$i,To]=m.useState(""),[Di,Ul]=m.useState(0);m.useEffect(()=>{const ce=(h??"").trim();ce&&$i!==ce&&(ct(!0),To(ce))},[h,$i]),m.useEffect(()=>{p&&p!==Di&&(ct(!0),Ul(p))},[p,Di]),m.useEffect(()=>{Ne(null),bt(null),Re("")},[e.serverIds.join("|")]),m.useEffect(()=>{Re(""),M(""),U(""),Y("")},[A]),m.useEffect(()=>{Pt&&Ya.includes(Pt)||Xt(f||i[0]?.id||"")},[Pt,f,i,Ya]);const qn=async()=>{if(Pt){nn(!0),zt(null);try{const ce=e.serverIds.filter(Wt=>o.find(qt=>qt.id===Wt)?.authType==="oauth2");await vi({serverNames:ce,source:_});const it=await _.runScenarioPreview({selectedAgentName:Pt,scenario:{id:e.id,name:e.name,prompt:e.prompt,serverNames:e.serverIds,attachments:e.attachments??[],evalRules:e.evalRules,extractRules:e.extractRules}});Ke(it)}catch(ce){zt(ce instanceof Error?ce.message:String(ce))}finally{nn(!1)}}},Fu=()=>{if(!de)return;const ce=T$(e.evalRules,de.run.failureReasons,de.run.checkResults),it=ce.length?ce.map(dn=>`${dn.status.toUpperCase()} - ${Gve(dn.rule)}${dn.failureReason?` (${dn.failureReason})`:""}`).join(`
|
|
127
|
+
`)},{label:"Improve Prompt Determinism",description:"Reduce ambiguity and improve reproducibility.",prompt:"Identify parts of this scenario's prompt or context that are ambiguous, open-ended, or likely to produce different results across runs. Suggest specific rewrites that make the expected behavior more deterministic — without changing the intent of what is being tested."},{label:"Generate Scenario Draft",description:"Create a draft scenario from the current context.",prompt:"Based on the current tool configuration and context, generate a complete scenario draft. Include a clear prompt, realistic expected tool calls with arguments, meaningful checks that validate the core behavior, and at least one value capture rule. Explain your choices so I can adjust them."}];function Lve({open:e,onOpenChange:t,configId:n,configPath:r,scenario:a,agents:i,servers:o,defaultAssistantAgentName:c,initialUserMessage:d,onApplyPatch:f}){const{source:h}=On(),[p,v]=m.useState(null),[x,j]=m.useState(null),[b,y]=m.useState(""),[S,N]=m.useState(!1),[_,A]=m.useState(!1),[k,E]=m.useState(new Set),P=m.useRef(null),R=m.useRef(null),M=m.useRef(null),D=m.useRef(null),U=m.useRef(0),[F,G]=m.useState(!1),H=m.useRef(!1),L=c||i[0]?.id||"",I=m.useCallback(()=>{const Q=D.current;Q&&Q.controller.abort()},[]);m.useEffect(()=>{if(!e||!L||p)return;let Q=!1;return N(!0),(async()=>{const Fe=Array.from(new Set(a.serverIds.filter(ot=>o.find(wt=>wt.id===ot)?.authType==="oauth2")));await vi({serverNames:Fe,source:h});const pt=await h.createScenarioAssistantSession({configId:n,configPath:r,scenarioId:a.id,selectedAssistantAgentName:L,context:{scenario:{id:a.id,name:a.name,prompt:a.prompt,serverNames:a.serverIds,evalRules:a.evalRules,extractRules:a.extractRules},availableServers:o.map(ot=>({name:ot.name||ot.id,url:ot.url})),availableAgents:i.map(ot=>({name:ot.name||ot.id,provider:ot.provider,model:ot.model}))}});Q||(v(pt.sessionId),W(pt.session),N(!1))})().catch(Fe=>{Q||Ie({title:"Could not start Scenario Assistant",description:Fe instanceof Error?Fe.message:String(Fe),variant:"destructive"})}).finally(()=>{Q||N(!1)}),()=>{Q=!0}},[e,h,p,n,r,a,i,o,L]);const Y=()=>{I(),v(null),j(null),y(""),E(new Set),M.current=null},W=m.useCallback(Q=>{j(Ne=>Ne&&Ne.messages.length>Q.messages.length?Ne:Q)},[]),O=m.useCallback(()=>{const Q=D.current;Q&&(I(),y(Q.prompt),N(!1),A(!1))},[I]),Z=Q=>{Y(),h.closeScenarioAssistantSession(Q).catch(()=>{})};m.useEffect(()=>{e||p&&(H.current||F||Z(p))},[e,p,h,F]),m.useEffect(()=>()=>{I(),p&&h.closeScenarioAssistantSession(p).catch(()=>{})},[I,p,h]),m.useEffect(()=>{if(!e)return;F&&G(!1),H.current&&(H.current=!1);const Q=window.setTimeout(()=>{P.current?.scrollIntoView({behavior:"smooth",block:"end"})},0);return()=>window.clearTimeout(Q)},[e,S,x?.messages.length,x?.pendingToolCalls.length,x?.warnings.length]),m.useEffect(()=>{const Q=R.current;if(!Q)return;Q.style.height="0px";const Ne=Math.min(Q.scrollHeight,160);Q.style.height=`${Math.max(40,Ne)}px`},[b,e]);const q=i.length>0&&a.serverIds.length>0&&!!L,z=async Q=>{if(!p)return;const Ne=Q.trim();if(!Ne)return;const Fe=++U.current,pt=new AbortController,ot=`msg-local-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,bt={id:ot,role:"user",text:Ne,createdAt:new Date().toISOString()};D.current={id:Fe,controller:pt,prompt:Ne},A(!0),j(wt=>wt&&{...wt,messages:[...wt.messages,bt]}),y(""),N(!0);try{const wt=await h.sendScenarioAssistantMessage(p,Ne,pt.signal);if(pt.signal.aborted||D.current?.id!==Fe)return;W(wt.session)}catch(wt){if(jN(wt)||pt.signal.aborted||D.current?.id!==Fe)return;j(et=>et&&{...et,messages:et.messages.filter(_e=>_e.id!==ot)}),y(et=>et.trim()?et:Ne),Ie({title:"Scenario Assistant error",description:wt instanceof Error?wt.message:String(wt),variant:"destructive"})}finally{D.current?.id===Fe&&(D.current=null,N(!1),A(!1))}},K=Q=>{y(Q),requestAnimationFrame(()=>R.current?.focus())};m.useEffect(()=>{if(!e||!p||!x||!q||D.current)return;const Q=String(d??"").trim();Q&&M.current!==Q&&(M.current=Q,z(Q))},[e,p,x,q,d]),m.useEffect(()=>{if(!(!e||!p||!x))return h.subscribeScenarioAssistantSessionEvents(p,Q=>{W(Q.payload.session)})},[e,p,h,W]);const J=async Q=>{if(p){N(!0);try{const Ne=await h.approveScenarioAssistantToolCall(p,Q);W(Ne.session)}catch(Ne){Ie({title:"Tool call failed",description:Ne instanceof Error?Ne.message:String(Ne),variant:"destructive"})}finally{N(!1)}}},re=async Q=>{if(p){N(!0);try{const Ne=await h.denyScenarioAssistantToolCall(p,Q);W(Ne.session)}catch(Ne){Ie({title:"Could not deny tool call",description:Ne instanceof Error?Ne.message:String(Ne),variant:"destructive"})}finally{N(!1)}}},he=async()=>{if(p){N(!0);try{const Q=await h.approveAllScenarioAssistantToolCalls(p);W(Q.session)}catch(Q){Ie({title:"Could not approve all tool calls",description:Q instanceof Error?Q.message:String(Q),variant:"destructive"})}finally{N(!1)}}},oe=(Q,Ne,Fe)=>{if(!Ne)return;if(Fe==="prompt"&&Ne.prompt&&f({prompt:Ne.prompt.replacement}),Fe==="evalRules"&&Ne.evalRules&&f({evalRules:Ne.evalRules.replacement}),Fe==="extractRules"&&Ne.extractRules&&f({extractRules:Ne.extractRules.replacement}),Q){const ot=`${Q}:${Fe}`;E(bt=>new Set([...bt,ot]))}Ie({title:"Applied suggestion",description:`Updated ${{prompt:"Prompt",evalRules:"Checks",extractRules:"Value Capture Rules"}[Fe]}`})},me=()=>{const Q=document.activeElement;Q instanceof HTMLElement&&Q.blur()},ie=Q=>{Q||(me(),G(!1),H.current=!1),t(Q)},ge=()=>{me(),H.current=!0,G(!0),t(!1)},Re=()=>{me(),H.current=!1,G(!1),p&&Z(p)};return s.jsxs(s.Fragment,{children:[!e&&p&&s.jsxs("div",{className:"mt-3 flex items-center justify-between gap-2 rounded-md border bg-background px-3 py-2",children:[s.jsxs("div",{className:"min-w-0",children:[s.jsx("p",{className:"text-sm font-medium",children:"Scenario Assistant (session active)"}),s.jsxs("p",{className:"truncate text-xs text-muted-foreground",children:["Resume conversation for ",s.jsx("span",{className:"font-mono",children:a.id}),x?` · ${x.messages.length} messages`:""]})]}),s.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[s.jsxs(ee,{type:"button",size:"sm",variant:"outline",onClick:()=>t(!0),children:[s.jsx(Zr,{className:"mr-1.5 h-3.5 w-3.5"}),"Resume"]}),s.jsx(ee,{type:"button",size:"sm",variant:"ghost",className:"h-8 px-2 text-muted-foreground",onClick:Re,"aria-label":"Discard assistant session",title:"Discard assistant session",children:s.jsx(ns,{className:"h-4 w-4"})})]})]}),s.jsx(bve,{open:e,onOpenChange:ie,children:s.jsxs(U6,{className:"max-w-6xl h-[85vh] flex flex-col",children:[p&&s.jsxs("button",{type:"button",className:"absolute right-12 top-4 z-10 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",onClick:ge,"aria-label":"Minimize assistant",title:"Minimize assistant",children:[s.jsx(O9,{className:"h-4 w-4"}),s.jsx("span",{className:"sr-only",children:"Minimize"})]}),s.jsx(W6,{className:"pr-20",children:s.jsx("div",{className:"flex items-start justify-between gap-3",children:s.jsxs("div",{className:"min-w-0",children:[s.jsxs(V6,{className:"flex items-center gap-2",children:[s.jsx(Zr,{className:"h-4 w-4"}),"Scenario Assistant"]}),s.jsx(H6,{children:"LLM-guided scenario authoring with MCP tool introspection and per-tool-call approval."})]})})}),q?s.jsxs("div",{className:"min-h-0 flex flex-1 flex-col gap-3",children:[s.jsx("div",{className:"grid gap-3 sm:grid-cols-1",children:s.jsxs("div",{className:"space-y-1.5",children:[s.jsx(Ve,{className:"text-xs",children:"MCP Context"}),s.jsxs("div",{className:"h-8 rounded-md border px-2 text-xs flex items-center gap-2",children:[s.jsx(pa,{className:"h-3.5 w-3.5"}),x?`Loaded ${x.toolsLoaded} tools`:"Preparing..."]})]})}),s.jsx(R_,{className:"min-h-0 flex-1 rounded-md border p-3",children:s.jsxs("div",{className:"space-y-3",children:[x?.warnings?.map((Q,Ne)=>s.jsx("div",{className:"rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-xs text-amber-900",children:Q},`${Q}-${Ne}`)),x?.messages.map(Q=>s.jsxs(m.Fragment,{children:[(()=>{const Ne=Q.pendingToolCallIds??(Q.pendingToolCallId?[Q.pendingToolCallId]:[]),Fe=Ne.map(et=>(x?.pendingToolCalls??[]).find(_e=>_e.id===et)).filter(et=>!!et),pt=Ne.map(et=>x.pendingToolCalls.find(_e=>_e.id===et)??x.pendingToolCalls.find(_e=>_e.id===et)).filter(Boolean);if(!(Q.role==="assistant"&&Ne.length>0))return s.jsx("div",{className:"space-y-2",children:s.jsx(Fve,{message:Q})});const bt=Fe.length,wt=pt.length-bt;return s.jsxs("div",{className:"flex items-start gap-2",children:[s.jsx("div",{className:"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-700",children:s.jsx(Fr,{className:"h-3 w-3"})}),s.jsxs("div",{className:"w-full max-w-[92%] space-y-2",children:[pt.length>1&&bt>0&&s.jsxs("div",{className:"flex items-center justify-between gap-2 rounded-md border border-amber-200 bg-amber-50/50 px-3 py-1.5",children:[s.jsxs("span",{className:"text-xs text-amber-900",children:[wt," of ",pt.length," tool calls resolved"]}),s.jsxs(ee,{type:"button",size:"sm",className:"h-7 px-2 text-xs",disabled:bt===0,onClick:()=>{he()},children:["Approve All (",bt,")"]})]}),pt.map((et,_e)=>s.jsx(wN,{call:et,loading:S,description:_e===0?Q.text:void 0,onApprove:Ee=>{J(Ee)},onDeny:Ee=>{re(Ee)}},et.id))]})]})})(),Q.suggestions&&s.jsxs("div",{className:"ml-0 space-y-3 rounded-md border border-dashed bg-muted/10 p-3",children:[s.jsxs("div",{className:"flex items-center gap-2 text-xs font-medium text-muted-foreground",children:[s.jsx(Zr,{className:"h-3.5 w-3.5"}),"Structured Suggestions"]}),Q.suggestions.prompt&&s.jsx(nS,{title:"Prompt",rationale:Q.suggestions.prompt.rationale,preview:Q.suggestions.prompt.replacement,applied:k.has(`${Q.id}:prompt`),onApply:()=>oe(Q.id,Q.suggestions,"prompt")}),Q.suggestions.evalRules&&s.jsx(nS,{title:"Checks",rationale:Q.suggestions.evalRules.rationale,preview:JSON.stringify(Q.suggestions.evalRules.replacement,null,2),applied:k.has(`${Q.id}:evalRules`),onApply:()=>oe(Q.id,Q.suggestions,"evalRules")}),Q.suggestions.extractRules&&s.jsx(nS,{title:"Value Capture Rules",rationale:Q.suggestions.extractRules.rationale,preview:JSON.stringify(Q.suggestions.extractRules.replacement,null,2),applied:k.has(`${Q.id}:extractRules`),onApply:()=>oe(Q.id,Q.suggestions,"extractRules")}),(()=>{const Ne=Q.suggestions?.notes,Fe=Array.isArray(Ne)?Ne:typeof Ne=="string"?[Ne]:[];return Fe.length===0?null:s.jsxs("div",{className:"space-y-2 rounded-md border p-3",children:[s.jsx("h5",{className:"text-sm font-medium",children:"Notes"}),s.jsx("ul",{className:"space-y-1 text-xs text-muted-foreground list-disc pl-4",children:Fe.map((pt,ot)=>s.jsx("li",{children:pt},`${Q.id}-note-${ot}`))})]})})()]})]},Q.id)),(x?.pendingToolCalls??[]).filter(Q=>!(x?.messages??[]).some(Ne=>Ne.pendingToolCallId===Q.id||Ne.pendingToolCallIds?.includes(Q.id))).map(Q=>s.jsx(wN,{call:Q,loading:S,onApprove:Ne=>{J(Ne)},onDeny:Ne=>{re(Ne)}},Q.id)),!x&&S&&s.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[s.jsx(wr,{className:"h-4 w-4 animate-spin"}),"Starting assistant session..."]}),x&&S&&s.jsx(z6,{}),s.jsx("div",{ref:P})]})}),s.jsx(B6,{input:b,onInputChange:y,onSend:()=>{z(b)},onCancel:p&&_?O:void 0,inputPlaceholder:"Get assistance with creating or refining this scenario ...",snippets:Dve,snippetsLabel:"Scenario Assistant Snippets",onSnippetSelect:K,loading:S,disabled:!p,inputRef:R,snippetContentClassName:"w-[320px]"})]}):s.jsx("div",{className:"rounded-md border p-3 text-sm text-muted-foreground",children:"Scenario Assistant requires a configured assistant agent and at least one selected server on the scenario."})]})})]})}function nS({title:e,rationale:t,preview:n,applied:r=!1,onApply:a}){return s.jsxs("div",{className:`space-y-2 rounded-md border p-3 ${r?"border-emerald-300 bg-emerald-50/40":""}`,children:[s.jsxs("div",{className:"flex items-center justify-between gap-2",children:[s.jsx("h5",{className:"text-sm font-medium",children:e}),s.jsx(ee,{type:"button",size:"sm",variant:r?"secondary":"outline",onClick:a,disabled:r,children:r?s.jsxs(s.Fragment,{children:[s.jsx(fi,{className:"mr-1.5 h-3.5 w-3.5"}),"Applied"]}):"Apply"})]}),t&&s.jsx("p",{className:"text-xs text-muted-foreground",children:t}),s.jsx("pre",{className:"max-h-56 overflow-auto rounded bg-muted p-2 text-xs whitespace-pre-wrap",children:n})]})}function Fve({message:e}){const t=async a=>{try{await navigator.clipboard.writeText(a),Ie({title:"Copied"})}catch(i){Ie({title:"Could not copy",description:i instanceof Error?i.message:String(i),variant:"destructive"})}},n=e.role==="user"||e.role==="assistant",r=e.role==="user";return s.jsx(F6,{message:e,assistantLabel:e.role==="assistant"?"Assistant":void 0,renderActions:n?s.jsx(ee,{type:"button",variant:"ghost",size:"icon",className:`absolute bottom-1 h-6 w-6 text-muted-foreground ${r?"-left-8":"-right-8"}`,onClick:()=>{t(e.text)},"aria-label":"Copy message",title:"Copy message",children:s.jsx(ss,{className:"h-3.5 w-3.5"})}):void 0})}function Yr(e){return typeof e=="number"?e.toLocaleString():"n/a"}function SN(e,t){const n=t?.nonPositiveLabel??"0s";if(!Number.isFinite(e)||e<=0)return n;const r=Math.floor(e),a=Math.floor(r/3600),i=Math.floor(r%3600/60),o=r%60;return a>0?`${a}h ${i}m ${o}s`:i>0?`${i}m ${o}s`:`${o}s`}function zve({run:e,fallbackUserPrompt:t}){const[n,r]=m.useState(!0),[a,i]=m.useState(!1);return s.jsxs("div",{className:"space-y-2",children:[s.jsx(da,{open:n,onOpenChange:r,children:s.jsxs("div",{className:"rounded-md border border-muted-foreground/20 bg-card p-2",children:[s.jsx(Ms,{asChild:!0,children:s.jsx("button",{type:"button",className:"mb-2 flex w-full items-center justify-between gap-2 text-left",children:s.jsxs("p",{className:"flex items-center gap-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground",children:[s.jsx(tn,{className:`h-3.5 w-3.5 transition-transform ${n?"rotate-180":""}`}),s.jsx(Fr,{className:"h-3.5 w-3.5"}),"Final answer"]})})}),s.jsx(fa,{children:s.jsx(NN,{text:e.finalAnswer||"No final answer captured.",maxLength:1200,className:"text-xs text-foreground"})})]})}),s.jsx(da,{open:a,onOpenChange:i,children:s.jsxs("div",{className:"rounded-md border border-muted-foreground/20 bg-card p-2",children:[s.jsxs("div",{className:"mb-2 flex flex-wrap items-center justify-between gap-2",children:[s.jsx(Ms,{asChild:!0,children:s.jsxs("button",{type:"button",className:"flex min-w-0 items-center gap-2 text-left",children:[s.jsx(tn,{className:`h-3.5 w-3.5 transition-transform ${a?"rotate-180":""}`}),s.jsx("p",{className:"text-[11px] font-semibold uppercase tracking-wide text-muted-foreground",children:"Conversation trace"})]})}),s.jsxs(st,{variant:"outline",className:"h-5 text-[10px]",children:[e.toolCalls.length," tool calls"]})]}),s.jsx(fa,{children:s.jsx("div",{className:"space-y-2 rounded-md border bg-muted/20 p-2",children:e.conversation.length===0?s.jsx("p",{className:"text-xs text-muted-foreground",children:"No conversation trace captured."}):e.conversation.map(o=>s.jsx(Bve,{item:o,fallbackUserPrompt:t},o.id))})})]})})]})}function Bve({item:e,fallbackUserPrompt:t}){if(e.kind==="tool_call"){const d=A$(e,"input");return s.jsx(E$,{variant:"call",title:`Tool call · ${e.toolName||"unknown"}${d}`,text:e.text})}if(e.kind==="tool_result"){const d=A$(e,"output"),f=e.ok?s.jsx(fi,{className:"h-3.5 w-3.5 text-emerald-700 dark:text-emerald-300"}):s.jsx(tl,{className:"h-3.5 w-3.5 text-rose-700 dark:text-rose-300"});return s.jsx(E$,{variant:e.ok?"result_ok":"result_error",title:`Tool result · ${e.toolName||"unknown"} · ${e.ok?"ok":"error"}${typeof e.durationMs=="number"?` · ${e.durationMs}ms`:""}${d}`,text:e.text,icon:f})}const n=e.kind==="user_prompt",r=k$(e.text,e.kind),a=t?k$(t,"user_prompt"):"",i=n&&!r&&a?a:r,o=n?"User prompt":e.kind==="assistant_final"?"Agent final":"Agent",c=n?Uc:Fr;return s.jsxs("div",{className:`flex items-start gap-2 text-xs ${n?"justify-end":"justify-start"}`,children:[!n&&s.jsx("div",{className:"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",children:s.jsx(c,{className:"h-3 w-3"})}),s.jsxs("div",{className:`max-w-[90%] rounded-md p-2 ${n?"bg-primary/10":"bg-muted/50"}`,children:[s.jsx("p",{className:`mb-1 text-[11px] font-semibold text-muted-foreground ${n?"text-right":""}`,children:o}),n?s.jsx(NN,{text:i,maxLength:280,className:"text-xs"}):s.jsx(NN,{text:i,maxLength:500,className:"text-xs"})]}),n&&s.jsx("div",{className:"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-primary/30 bg-primary/15 text-primary",children:s.jsx(c,{className:"h-3 w-3"})})]})}function A$(e,t){const n=t==="input"?e.estimatedTokens?.inputTokens:e.estimatedTokens?.outputTokens;return typeof n!="number"?"":` · estimated ${Yr(n)} tokens`}function k$(e,t){const r=String(e??"").replace(/^\s+/,"");return t==="user_prompt"?r.replace(/^user:\s*/i,""):t==="assistant_final"||t==="assistant_thought"?r.replace(/^assistant:\s*/i,""):r}function E$({variant:e,title:t,text:n,icon:r}){const[a,i]=m.useState(!1),o={call:"border-sky-500/30 bg-sky-500/10 text-sky-700 dark:text-sky-300",result_ok:"border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",result_error:"border-rose-500/30 bg-rose-500/10 text-rose-700 dark:text-rose-300"};return s.jsx(da,{open:a,onOpenChange:i,children:s.jsxs("div",{className:`rounded-md border p-2 text-xs ${o[e]}`,children:[s.jsx(Ms,{asChild:!0,children:s.jsxs("button",{type:"button",className:"flex w-full items-center justify-between gap-2 text-left",children:[s.jsxs("div",{className:"flex items-center gap-1.5 font-mono text-[11px]",children:[r??s.jsx(pa,{className:"h-3.5 w-3.5"}),s.jsx("span",{children:t})]}),s.jsx("span",{className:"text-[11px] font-semibold",children:a?"Hide content":"Show content"})]})}),s.jsx(fa,{children:s.jsx("p",{className:"mt-2 font-mono whitespace-pre-wrap text-foreground",children:n})})]})})}function NN({text:e,maxLength:t,className:n}){const[r,a]=m.useState(!1),i=e.length>t,o=r||!i?e:`${e.slice(0,t)}...`;return s.jsxs("div",{children:[s.jsx(Fs,{text:o,className:n}),i&&s.jsx("button",{type:"button",className:"mt-1 text-[11px] font-medium text-primary hover:underline",onClick:()=>a(c=>!c),children:r?"Show less":"Show all"})]})}const o8=["image/jpeg","image/png","image/gif","image/webp"],l8=["application/pdf","text/plain","text/markdown","text/csv"];function qve(e){return o8.includes(e)||l8.includes(e)}function Uve(e,t,n){if(e.type==="agent_check"){const a=String(e.label??"").trim();return a?t.find(i=>i.type==="agent_check"&&i.label===a):void 0}const r=n(e);return t.find(a=>a.type===e.type&&a.label===r)}function c8({evalRules:e,failureReasons:t,runError:n,checkResults:r}){return n||t.find(i=>i.startsWith("Scenario error:"))?e.map(i=>({rule:i,status:"not_evaluated",failureReason:void 0})):r?.length?e.map(i=>{const o=Uve(i,r,O_);return{rule:i,status:o?.status??"not_evaluated",failureReason:o?.reason}}):e.map(i=>{const o=Vve(i,t);return{rule:i,status:o?"failed":"passed",failureReason:o}})}function O_(e){return e.type==="required_tool"?`Required tool · ${e.value}`:e.type==="forbidden_tool"?`Forbidden tool · ${e.value}`:e.type==="tool_sequence"?A_(e.sequence??[]):e.type==="response_contains"?`Text contains · ${e.value}`:e.type==="response_not_contains"?`Text does not contain · ${e.value}`:e.type==="response_starts_with"?`Text starts with · ${e.value}`:e.type==="response_ends_with"?`Text ends with · ${e.value}`:e.type==="response_equals"?`Text equals · ${e.value}`:e.type==="response_regex"?`Text matches regex · ${e.value}`:e.type==="response_jsonpath"?e.equals!==void 0?`JSONPath equals · ${e.path} == ${String(e.equals)}`:`JSONPath exists · ${e.path}`:e.type==="response_jsonpath_exists"?`JSONPath exists · ${e.path}`:e.type==="response_jsonpath_not_exists"?`JSONPath not exists · ${e.path}`:e.type==="agent_check"?`Agent check · ${e.label}`:`${e.type} · ${e.value}`}function Wve(e){return A_(e).replace(/^Tool sequence · /,"")}function Vve(e,t){if(e.type==="response_jsonpath_exists"){const a=String(e.path??"").trim();return a?t.find(i=>i.startsWith(`JSONPath assertion failed: ${a}`)||i.startsWith(`JSONPath assertion failed: invalid JSON for path ${a}`)):void 0}const n=e.type==="required_tool"?`Required tool not used: ${e.value}`:e.type==="forbidden_tool"?`Forbidden tool used: ${e.value}`:e.type==="tool_sequence"?`Tool sequence order was not satisfied: ${(e.sequence??[]).join(" -> ")}`:e.type==="response_contains"?`Contains assertion failed: ${e.value}`:e.type==="response_not_contains"?`Not-contains assertion failed: ${e.value}`:e.type==="response_starts_with"?`Starts-with assertion failed: ${e.value}`:e.type==="response_ends_with"?`Ends-with assertion failed: ${e.value}`:e.type==="response_equals"?`Equals assertion failed: ${e.value}`:e.type==="response_regex"?`Regex assertion failed: ${e.value}`:e.type==="response_jsonpath"?e.equals!==void 0?`JSONPath equals assertion failed: ${e.path}`:`JSONPath assertion failed: ${e.path}`:e.type==="response_jsonpath_not_exists"?`JSONPath not-exists assertion failed: ${e.path}`:e.type==="agent_check"?String(e.label??""):"";if(!n)return;const r=t.find(a=>a===n);return r||(e.type==="response_regex"?t.find(a=>a.startsWith("Regex assertion failed:")&&a.includes(e.value??"")):e.type==="response_jsonpath"||e.type==="response_jsonpath_not_exists"?t.find(a=>a.includes(e.path??"")):e.type==="tool_sequence"?t.find(a=>a.startsWith(`Tool sequence order was not satisfied: ${Wve(e.sequence??[])}`)||a.startsWith("Required tool in sequence not used:")):t.find(a=>a.startsWith(n)))}function P$({value:e,onValueChange:t,className:n,hideToolSequence:r=!1}){return s.jsxs(In,{value:e,onValueChange:a=>t(a),children:[s.jsx(Tn,{className:n,children:s.jsx($n,{})}),s.jsxs(Rn,{children:[s.jsx(mt,{value:"required_tool",children:"Required Tool"}),s.jsx(mt,{value:"forbidden_tool",children:"Forbidden Tool"}),!r&&s.jsx(mt,{value:"tool_sequence",children:"Tool Sequence"}),s.jsx(mt,{value:"agent_check",children:"Judge Agent"}),s.jsx(mt,{value:"response_contains",children:"Text contains"}),s.jsx(mt,{value:"response_not_contains",children:"Text does not contain"}),s.jsx(mt,{value:"response_starts_with",children:"Text starts with"}),s.jsx(mt,{value:"response_ends_with",children:"Text ends with"}),s.jsx(mt,{value:"response_equals",children:"Text equals"}),s.jsx(mt,{value:"response_regex",children:"Text matches regex"}),s.jsx(mt,{value:"response_jsonpath",children:"JSONPath (optional equals)"}),s.jsx(mt,{value:"response_jsonpath_exists",children:"JSONPath exists"}),s.jsx(mt,{value:"response_jsonpath_not_exists",children:"JSONPath not exists"})]})]})}const Hve=()=>({id:`scn-${Date.now()}`,name:"",serverIds:[],prompt:"",evalRules:[],extractRules:[]});function u8(e){return A_(e).replace(/^Tool sequence · /,"")}function CN({scenarios:e,scenarioOrigins:t,scenarioOverrides:n,agents:r,servers:a,configId:i,configPath:o,defaultAssistantAgentName:c,assistantInitialPromptByScenarioId:d,assistantAutoOpenNonceByScenarioId:f,testCaseReturnToPath:h,onChange:p,readOnly:v,allowAdd:x=!v,allowStructureEdits:j=!v}){const b=(_,A)=>{const k=e.map((E,P)=>P===_?{...E,...A}:E);p(k)},y=_=>p(e.filter((A,k)=>k!==_)),S=()=>p([...e,Hve()]),N=(_,A)=>{const k=_+A;if(k<0||k>=e.length)return;const E=[...e],[P]=E.splice(_,1);E.splice(k,0,P),p(E)};return s.jsxs("div",{className:v?"space-y-2":"space-y-4",children:[!v&&s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx("h3",{className:"text-sm font-semibold",children:"Scenarios"}),x&&j&&s.jsxs(ee,{type:"button",variant:"outline",size:"sm",onClick:S,children:[s.jsx(yi,{className:"mr-1.5 h-3.5 w-3.5"}),"Add Scenario"]})]}),e.map((_,A)=>s.jsx(Kve,{scenario:_,scenarioOrigin:t?.[A],hasMcpServerOverride:n?.[A],index:A,total:e.length,agents:r,servers:a,configId:i,configPath:o,defaultAssistantAgentName:c,assistantInitialPrompt:d?.[_.id],assistantAutoOpenNonce:f?.[_.id],testCaseReturnToPath:h,onUpdate:k=>b(A,k),onMoveUp:()=>N(A,-1),onMoveDown:()=>N(A,1),onRemove:()=>y(A),readOnly:v,allowStructureEdits:j},_.id)),e.length===0&&s.jsx("p",{className:"text-sm text-muted-foreground text-center py-6",children:"No scenarios configured. Add one to get started."})]})}function Kve({scenario:e,scenarioOrigin:t,hasMcpServerOverride:n,index:r,total:a,agents:i,servers:o,configId:c,configPath:d,defaultAssistantAgentName:f,assistantInitialPrompt:h,assistantAutoOpenNonce:p,testCaseReturnToPath:v,onUpdate:x,onMoveUp:j,onMoveDown:b,onRemove:y,readOnly:S,allowStructureEdits:N}){const{source:_}=On(),[A,k]=m.useState("required_tool"),[E,P]=m.useState(""),[R,M]=m.useState(""),[D,U]=m.useState(""),[F,G]=m.useState(""),[H,L]=m.useState(""),[I,Y]=m.useState(""),[W,O]=m.useState([]),[Z,q]=m.useState(!1),[z,K]=m.useState(null),[J,re]=m.useState(null),[he,oe]=m.useState(!1),[me,ie]=m.useState(null),[ge,Re]=m.useState(""),[Q,Ne]=m.useState(null),[Fe,pt]=m.useState(!1),[ot,bt]=m.useState(null),[wt,et]=m.useState(""),[_e,Ee]=m.useState(""),[tt,ct]=m.useState(!1),[Pt,Xt]=m.useState(f||i[0]?.id||""),[kt,nn]=m.useState(!1),[Jt,zt]=m.useState(null),[Se,Xe]=m.useState(""),Qe=m.useRef(null);function At(ce){if(!ce)return;const it=Array.from(ce),Wt=new Array(it.length).fill(null);let Dt=0,qt=0;const dn=()=>{const lr=Wt.filter(os=>os!==null);lr.length>0?(x({attachments:[...e.attachments??[],...lr]}),qt>0&&Ie({title:`${qt} file${qt>1?"s":""} skipped`,description:"Unsupported file type. Images must be JPEG/PNG/GIF/WebP; documents must be PDF, TXT, MD, or CSV.",variant:"destructive"})):it.length>0&&Ie({title:"Could not attach files",description:qt>0?"Unsupported file type. Images must be JPEG/PNG/GIF/WebP; documents must be PDF, TXT, MD, or CSV.":"Files could not be read.",variant:"destructive"})};it.forEach((lr,os)=>{const gr=new FileReader;gr.onload=()=>{const Ro=gr.result,vr=Ro.indexOf(","),Wl=vr>=0?Ro.slice(vr+1):"";if(Wl){const ae=Ro.slice(0,vr).replace("data:","").replace(";base64",""),ke=ae.startsWith("image/");qve(ae)?Wt[os]={type:ke?"image":"document",media_type:ae,data:Wl,name:lr.name}:qt++}++Dt===it.length&&dn()},gr.onerror=()=>{++Dt===it.length&&dn()},gr.readAsDataURL(lr)})}function Bt(ce){x({attachments:(e.attachments??[]).filter((it,Wt)=>Wt!==ce)})}const[de,Ke]=m.useState(null),[$e,se]=m.useState(!S),we=ce=>{const it=ce.target;it&&(it.closest("button, a, input, select, textarea, [role='button']")||se(Wt=>!Wt))},Ue=ce=>ce?e.evalRules.findIndex(it=>it===ce):-1,B=()=>{if(A==="response_jsonpath"||A==="response_jsonpath_exists"||A==="response_jsonpath_not_exists"){const Dt=R.trim();if(!Dt)return;if(A==="response_jsonpath"){const qt=D.trim();let dn;qt.length>0&&(qt==="true"?dn=!0:qt==="false"?dn=!1:Number.isNaN(Number(qt))?dn=qt:dn=Number(qt)),x({evalRules:[...e.evalRules,{type:A,path:Dt,...dn!==void 0?{equals:dn}:{}}]})}else x({evalRules:[...e.evalRules,{type:A,path:Dt}]});M(""),U("");return}if(A==="agent_check"){const Dt=F.trim(),qt=H.trim();if(!Dt||!qt)return;const dn=[...e.evalRules],lr={type:"agent_check",label:Dt,prompt:qt},os=Ue(J);os>=0?dn[os]=lr:dn.push(lr),x({evalRules:dn}),G(""),L(""),re(null),oe(!1),k("required_tool");return}if(A==="tool_sequence"){const Dt=W.map(qt=>qt.trim()).filter(qt=>typeof qt=="string"&&qt.length>0);if(Dt.length===0)return;ve(Dt);return}if(!E.trim())return;const ce=[...e.evalRules],it={type:A,value:E.trim()},Wt=Ue(me);Wt>=0?ce[Wt]=it:ce.push(it),x({evalRules:ce}),P(""),Re(""),ie(null),k("required_tool")},le=()=>{const ce=I.trim();ce&&(O(it=>[...it,ce]),Y(""))},fe=(ce,it)=>{const Wt=ce+it;O(Dt=>{if(Wt<0||Wt>=Dt.length)return Dt;const qt=[...Dt],[dn]=qt.splice(ce,1);return qt.splice(Wt,0,dn),qt})},De=ce=>{O(it=>it.filter((Wt,Dt)=>Dt!==ce))},Me=e.evalRules.findIndex(ce=>ce.type==="tool_sequence"),Ge=Me>=0?e.evalRules[Me]:void 0,Oe=Ge?.type==="tool_sequence"?Ge.sequence??[]:[],V=Me>=0,ve=ce=>{const it=[...e.evalRules],Wt=ce.length>0?{type:"tool_sequence",sequence:ce}:null,Dt=Ue(z),qt=Dt>=0?Dt:Me;qt>=0?Wt?it[qt]=Wt:it.splice(qt,1):Wt&&it.push(Wt),x({evalRules:it}),q(!1),O([]),Y(""),K(null),A==="tool_sequence"&&k("required_tool")};m.useEffect(()=>{Z&&O(Oe)},[Z,Me,Oe.join("|")]),m.useEffect(()=>{q(A==="tool_sequence")},[A]),m.useEffect(()=>{oe(A==="agent_check")},[A]),m.useEffect(()=>{z&&Ue(z)<0&&K(null),J&&Ue(J)<0&&re(null),me&&Ue(me)<0&&ie(null)},[e.evalRules,z,J,me]),m.useEffect(()=>{z&&A!=="tool_sequence"&&K(null),J&&A!=="agent_check"&&re(null),me&&me.type!==A&&ie(null)},[A,z,J,me]);const Ae=ce=>{const it=e.evalRules.filter((Dt,qt)=>qt!==ce),Wt=it.some(Dt=>Dt.type==="agent_check");x({evalRules:it,agentContext:Wt?e.agentContext:void 0})},Je=["response_contains","response_not_contains","response_starts_with","response_ends_with","response_equals","response_regex"],ne=()=>{!wt.trim()||!_e.trim()||(x({extractRules:[...e.extractRules,{name:wt.trim(),pattern:_e.trim()}]}),et(""),Ee(""))},Le=ce=>{x({extractRules:e.extractRules.filter((it,Wt)=>Wt!==ce)})},ht=ce=>{const it=e.serverIds.includes(ce)?e.serverIds.filter(Wt=>Wt!==ce):[...e.serverIds,ce];x({serverIds:it})},Qt={required_tool:"Required",forbidden_tool:"Forbidden",tool_sequence:"Sequence",response_contains:"Contains",response_not_contains:"Not Contains",response_starts_with:"Starts With",response_ends_with:"Ends With",response_equals:"Equals",response_regex:"Regex",response_jsonpath:"JSONPath",response_jsonpath_exists:"JSONPath Exists",response_jsonpath_not_exists:"JSONPath Not Exists",agent_check:"Agent"},Ce={required_tool:"border-sky-300/60 bg-sky-500/10 text-sky-700",forbidden_tool:"border-rose-300/60 bg-rose-500/10 text-rose-700",tool_sequence:"border-teal-300/60 bg-teal-500/10 text-teal-700",response_contains:"border-violet-300/60 bg-violet-500/10 text-violet-700",response_not_contains:"border-amber-300/60 bg-amber-500/10 text-amber-700",response_starts_with:"border-cyan-300/60 bg-cyan-500/10 text-cyan-700",response_ends_with:"border-indigo-300/60 bg-indigo-500/10 text-indigo-700",response_equals:"border-lime-300/60 bg-lime-500/10 text-lime-700",response_regex:"border-fuchsia-300/60 bg-fuchsia-500/10 text-fuchsia-700",response_jsonpath:"border-emerald-300/60 bg-emerald-500/10 text-emerald-700",response_jsonpath_exists:"border-green-300/60 bg-green-500/10 text-green-700",response_jsonpath_not_exists:"border-orange-300/60 bg-orange-500/10 text-orange-700",agent_check:"border-teal-300/60 bg-teal-500/10 text-teal-700"},en=A==="required_tool"||A==="forbidden_tool",_t=A==="response_jsonpath"||A==="response_jsonpath_exists"||A==="response_jsonpath_not_exists",Kt=A==="tool_sequence"&&Z,Hn=A==="agent_check"&&he,_n=e.serverIds.filter(ce=>o.some(it=>it.id===ce)),Ya=i.map(ce=>ce.id).filter(Boolean),Xa=_n.length>0,[$i,To]=m.useState(""),[Di,Ul]=m.useState(0);m.useEffect(()=>{const ce=(h??"").trim();ce&&$i!==ce&&(ct(!0),To(ce))},[h,$i]),m.useEffect(()=>{p&&p!==Di&&(ct(!0),Ul(p))},[p,Di]),m.useEffect(()=>{Ne(null),bt(null),Re("")},[e.serverIds.join("|")]),m.useEffect(()=>{Re(""),M(""),U(""),Y("")},[A]),m.useEffect(()=>{Pt&&Ya.includes(Pt)||Xt(f||i[0]?.id||"")},[Pt,f,i,Ya]);const qn=async()=>{if(Pt){nn(!0),zt(null);try{const ce=e.serverIds.filter(Wt=>o.find(qt=>qt.id===Wt)?.authType==="oauth2");await vi({serverNames:ce,source:_});const it=await _.runScenarioPreview({selectedAgentName:Pt,scenario:{id:e.id,name:e.name,prompt:e.prompt,serverNames:e.serverIds,attachments:e.attachments??[],evalRules:e.evalRules,extractRules:e.extractRules}});Ke(it)}catch(ce){zt(ce instanceof Error?ce.message:String(ce))}finally{nn(!1)}}},Fu=()=>{if(!de)return;const ce=T$(e.evalRules,de.run.failureReasons,de.run.checkResults),it=ce.length?ce.map(dn=>`${dn.status.toUpperCase()} - ${Gve(dn.rule)}${dn.failureReason?` (${dn.failureReason})`:""}`).join(`
|
|
128
128
|
`):"No checks configured.",Wt=Object.keys(de.run.extractedValues).length>0?Object.entries(de.run.extractedValues).map(([dn,lr])=>`${dn}: ${String(lr)}`).join(`
|
|
129
129
|
`):"No extracted values.",Dt=de.run.toolCalls.length>0?de.run.toolCalls.map((dn,lr)=>`${lr+1}. ${dn.name} (${dn.duration}ms)`).join(`
|
|
130
130
|
`):"No tool calls.",qt=[`I ran a prompt preview for scenario '${e.id}' and want you to suggest concrete updates.`,`Run ID: ${de.runId}`,`Agent: ${de.agentName}`,`Outcome: ${de.run.passed?"passed":"failed"}`,`Duration: ${de.run.duration}ms`,"","Current check outcomes:",it,"","Tool sequence:",Dt,"","Extracted values:",Wt,"","Final answer:",de.run.finalAnswer||"(empty)","","If the run has a meaningful ordered tool path, suggest a tool_sequence check using the raw tool names in the tool sequence order, even if other tools appear between them.","Use agent_check only for semantic or fuzzy validation;","Please propose concrete updates to the Prompt, Checks, and/or Value Capture Rules based on this preview."].join(`
|
package/dist/app/index.html
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<meta name="twitter:card" content="summary_large_image" />
|
|
17
17
|
<meta name="twitter:site" content="@Inspectr" />
|
|
18
18
|
<meta name="twitter:image" content="" />
|
|
19
|
-
<script type="module" crossorigin src="/assets/index-
|
|
19
|
+
<script type="module" crossorigin src="/assets/index-6zaiXZWP.js"></script>
|
|
20
20
|
<link rel="stylesheet" crossorigin href="/assets/index-DBjVHflA.css">
|
|
21
21
|
</head>
|
|
22
22
|
|
|
@@ -5,151 +5,177 @@ import type { AssistantSseEvent } from './assistant-events.js';
|
|
|
5
5
|
import { readLibraries } from './libraries-store.js';
|
|
6
6
|
export { truncateJson } from './assistant-common.js';
|
|
7
7
|
interface ScenarioAssistantContextInput {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}>;
|
|
22
|
-
extractRules: Array<{
|
|
23
|
-
name: string;
|
|
24
|
-
pattern: string;
|
|
25
|
-
}>;
|
|
26
|
-
};
|
|
27
|
-
availableServers?: Array<{
|
|
28
|
-
name: string;
|
|
29
|
-
url?: string;
|
|
8
|
+
scenario: {
|
|
9
|
+
id: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
prompt: string;
|
|
12
|
+
serverNames: string[];
|
|
13
|
+
evalRules: Array<{
|
|
14
|
+
type: string;
|
|
15
|
+
value?: string;
|
|
16
|
+
sequence?: string[];
|
|
17
|
+
path?: string;
|
|
18
|
+
equals?: string | number | boolean;
|
|
19
|
+
label?: string;
|
|
20
|
+
prompt?: string;
|
|
30
21
|
}>;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
model: string;
|
|
22
|
+
extractRules: Array<{
|
|
23
|
+
name: string;
|
|
24
|
+
pattern: string;
|
|
35
25
|
}>;
|
|
26
|
+
};
|
|
27
|
+
availableServers?: Array<{
|
|
28
|
+
name: string;
|
|
29
|
+
url?: string;
|
|
30
|
+
}>;
|
|
31
|
+
availableAgents?: Array<{
|
|
32
|
+
name: string;
|
|
33
|
+
provider: string;
|
|
34
|
+
model: string;
|
|
35
|
+
}>;
|
|
36
36
|
}
|
|
37
37
|
interface ScenarioAssistantSuggestionBundle {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
38
|
+
prompt?: {
|
|
39
|
+
replacement: string;
|
|
40
|
+
rationale?: string;
|
|
41
|
+
};
|
|
42
|
+
evalRules?: {
|
|
43
|
+
replacement: Array<{
|
|
44
|
+
type: string;
|
|
45
|
+
value?: string;
|
|
46
|
+
sequence?: string[];
|
|
47
|
+
path?: string;
|
|
48
|
+
equals?: string | number | boolean;
|
|
49
|
+
label?: string;
|
|
50
|
+
prompt?: string;
|
|
51
|
+
}>;
|
|
52
|
+
rationale?: string;
|
|
53
|
+
};
|
|
54
|
+
extractRules?: {
|
|
55
|
+
replacement: Array<{
|
|
56
|
+
name: string;
|
|
57
|
+
pattern: string;
|
|
58
|
+
}>;
|
|
59
|
+
rationale?: string;
|
|
60
|
+
};
|
|
61
|
+
notes?: string[];
|
|
62
62
|
}
|
|
63
63
|
interface ScenarioAssistantEvalRuleSuggestion {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
type: string;
|
|
65
|
+
value?: string;
|
|
66
|
+
sequence?: string[];
|
|
67
|
+
path?: string;
|
|
68
|
+
equals?: string | number | boolean;
|
|
69
|
+
label?: string;
|
|
70
|
+
prompt?: string;
|
|
71
71
|
}
|
|
72
72
|
interface AssistantPendingToolCall {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
id: string;
|
|
74
|
+
server: string;
|
|
75
|
+
tool: string;
|
|
76
|
+
publicToolName: string;
|
|
77
|
+
arguments: unknown;
|
|
78
|
+
status: 'pending' | 'approved' | 'denied' | 'error';
|
|
79
|
+
createdAt: string;
|
|
80
|
+
resultPreview?: string;
|
|
81
|
+
error?: string;
|
|
82
82
|
}
|
|
83
83
|
interface AssistantChatMessage {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
84
|
+
id: string;
|
|
85
|
+
role: 'user' | 'assistant' | 'tool' | 'system';
|
|
86
|
+
text: string;
|
|
87
|
+
createdAt: string;
|
|
88
|
+
suggestions?: ScenarioAssistantSuggestionBundle;
|
|
89
|
+
pendingToolCallId?: string;
|
|
90
|
+
pendingToolCallIds?: string[];
|
|
91
|
+
toolRequestServer?: string;
|
|
92
|
+
toolRequestName?: string;
|
|
93
|
+
toolRequestPublicName?: string;
|
|
94
94
|
}
|
|
95
95
|
export interface ScenarioAssistantSession {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
96
|
+
id: string;
|
|
97
|
+
createdAt: number;
|
|
98
|
+
lastTouchedAt: number;
|
|
99
|
+
configPath?: string;
|
|
100
|
+
selectedAssistantAgentName: string;
|
|
101
|
+
context: ScenarioAssistantContextInput;
|
|
102
|
+
agentConfig: AgentConfig;
|
|
103
|
+
mcp: McpClientManager;
|
|
104
|
+
tools: ToolDef[];
|
|
105
|
+
toolPublicMap: Map<
|
|
106
|
+
string,
|
|
107
|
+
{
|
|
108
|
+
server: string;
|
|
109
|
+
tool: string;
|
|
110
|
+
}
|
|
111
|
+
>;
|
|
112
|
+
pendingToolCalls: AssistantPendingToolCall[];
|
|
113
|
+
chatMessages: AssistantChatMessage[];
|
|
114
|
+
llmMessages: LlmMessage[];
|
|
115
|
+
warnings: string[];
|
|
116
|
+
systemPromptCache?: string;
|
|
117
|
+
events: AssistantSseEvent[];
|
|
118
|
+
clients: Set<ServerResponse>;
|
|
116
119
|
}
|
|
117
|
-
export declare function cleanupAssistantSessions(
|
|
120
|
+
export declare function cleanupAssistantSessions(
|
|
121
|
+
sessions: Map<string, ScenarioAssistantSession>,
|
|
122
|
+
now?: number
|
|
123
|
+
): void;
|
|
118
124
|
export declare function touchAssistantSession(session: ScenarioAssistantSession): void;
|
|
119
125
|
export declare function assistantSessionView(session: ScenarioAssistantSession): {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
126
|
+
id: string;
|
|
127
|
+
createdAt: string;
|
|
128
|
+
updatedAt: string;
|
|
129
|
+
selectedAssistantAgentName: string;
|
|
130
|
+
model: string;
|
|
131
|
+
provider: 'openai' | 'anthropic' | 'azure_openai';
|
|
132
|
+
warnings: string[];
|
|
133
|
+
toolsLoaded: number;
|
|
134
|
+
toolServers: string[];
|
|
135
|
+
messages: AssistantChatMessage[];
|
|
136
|
+
pendingToolCalls: AssistantPendingToolCall[];
|
|
131
137
|
};
|
|
132
|
-
export declare function preloadAssistantTools(
|
|
138
|
+
export declare function preloadAssistantTools(
|
|
139
|
+
session: ScenarioAssistantSession,
|
|
140
|
+
serversByName: Record<string, EvalConfig['servers'][string]>,
|
|
141
|
+
selectedServerNames: string[],
|
|
142
|
+
options?: {
|
|
133
143
|
serverAuthHeaders?: Record<string, Record<string, string>>;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export declare function
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
}
|
|
145
|
+
): Promise<void>;
|
|
146
|
+
export declare function normalizeScenarioAssistantEvalRules(
|
|
147
|
+
replacement: ScenarioAssistantEvalRuleSuggestion[]
|
|
148
|
+
): ScenarioAssistantEvalRuleSuggestion[];
|
|
149
|
+
export declare function continueAssistantTurn(
|
|
150
|
+
session: ScenarioAssistantSession,
|
|
151
|
+
signal?: AbortSignal
|
|
152
|
+
): Promise<{
|
|
153
|
+
session: ReturnType<typeof assistantSessionView>;
|
|
154
|
+
response: {
|
|
155
|
+
type: 'assistant_message' | 'tool_call_request';
|
|
156
|
+
text: string;
|
|
157
|
+
suggestions?: ScenarioAssistantSuggestionBundle;
|
|
158
|
+
pendingToolCall?: AssistantPendingToolCall;
|
|
159
|
+
pendingToolCalls?: AssistantPendingToolCall[];
|
|
160
|
+
};
|
|
145
161
|
}>;
|
|
146
|
-
export declare function executeAssistantToolCall(
|
|
162
|
+
export declare function executeAssistantToolCall(
|
|
163
|
+
session: ScenarioAssistantSession,
|
|
164
|
+
pending: AssistantPendingToolCall,
|
|
165
|
+
signal?: AbortSignal
|
|
166
|
+
): Promise<unknown>;
|
|
147
167
|
export declare function summarizeToolResultForAssistant(result: unknown): string;
|
|
148
|
-
export declare function resolveAssistantAgentFromConfig(
|
|
149
|
-
|
|
168
|
+
export declare function resolveAssistantAgentFromConfig(
|
|
169
|
+
config: EvalConfig,
|
|
170
|
+
selectedAssistantAgentName: string
|
|
171
|
+
): AgentConfig;
|
|
172
|
+
export declare function resolveAssistantAgentFromLibraries(
|
|
173
|
+
libraries: ReturnType<typeof readLibraries>,
|
|
174
|
+
selectedAssistantAgentName: string
|
|
175
|
+
): AgentConfig;
|
|
150
176
|
export declare function pickDefaultAssistantAgentName(params: {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
177
|
+
requested?: string;
|
|
178
|
+
settingsDefault?: string;
|
|
179
|
+
agentNames: string[];
|
|
154
180
|
}): string;
|
|
155
|
-
//# sourceMappingURL=scenario-assistant-domain.d.ts.map
|
|
181
|
+
//# sourceMappingURL=scenario-assistant-domain.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inspectr/mcplab",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.1",
|
|
4
4
|
"description": "MCPLab - Test and evaluate MCP servers with LLMs — run evals, compare agents and launch the MCPLab web app",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://mcplab.inspectr.dev",
|