diff --git a/eval_protocol/cli.py b/eval_protocol/cli.py index efe2d996..f94d14ba 100644 --- a/eval_protocol/cli.py +++ b/eval_protocol/cli.py @@ -25,9 +25,9 @@ ) from .cli_commands.deploy import deploy_command from .cli_commands.deploy_mcp import deploy_mcp_command +from .cli_commands.logs import logs_command from .cli_commands.preview import preview_command from .cli_commands.run_eval_cmd import hydra_cli_entry_point -from .cli_commands.logs import logs_command def parse_args(args=None): @@ -289,36 +289,6 @@ def parse_args(args=None): # Logs command logs_parser = subparsers.add_parser("logs", help="Serve logs with file watching and real-time updates") - logs_parser.add_argument( - "--build-dir", - default="dist", - help="Path to the Vite build output directory (default: dist)", - ) - logs_parser.add_argument( - "--host", - default="localhost", - help="Host to bind the server to (default: localhost)", - ) - logs_parser.add_argument( - "--port", - type=int, - default=4789, - help="Port to bind the server to (default: 4789)", - ) - logs_parser.add_argument( - "--index-file", - default="index.html", - help="Name of the main index file (default: index.html)", - ) - logs_parser.add_argument( - "--watch-paths", - help="Comma-separated list of paths to watch for file changes (default: current directory)", - ) - logs_parser.add_argument( - "--reload", - action="store_true", - help="Enable auto-reload (default: False)", - ) # Run command (for Hydra-based evaluations) # This subparser intentionally defines no arguments itself. diff --git a/eval_protocol/cli_commands/logs.py b/eval_protocol/cli_commands/logs.py index 66c3e57b..3f4eda7e 100644 --- a/eval_protocol/cli_commands/logs.py +++ b/eval_protocol/cli_commands/logs.py @@ -11,26 +11,15 @@ def logs_command(args): """Serve logs with file watching and real-time updates""" - # Parse watch paths - watch_paths = None - if args.watch_paths: - watch_paths = args.watch_paths.split(",") - watch_paths = [path.strip() for path in watch_paths if path.strip()] - print(f"šŸš€ Starting Eval Protocol Logs Server") - print(f"🌐 URL: http://{args.host}:{args.port}") - print(f"šŸ”Œ WebSocket: ws://{args.host}:{args.port}/ws") - print(f"šŸ‘€ Watching paths: {watch_paths or ['current directory']}") + print(f"🌐 URL: http://localhost:8000") + print(f"šŸ”Œ WebSocket: ws://localhost:8000/ws") + print(f"šŸ‘€ Watching paths: {['current directory']}") print("Press Ctrl+C to stop the server") print("-" * 50) try: - serve_logs( - host=args.host, - port=args.port, - watch_paths=watch_paths, - reload=args.reload, - ) + serve_logs() return 0 except KeyboardInterrupt: print("\nšŸ›‘ Server stopped by user") diff --git a/eval_protocol/utils/logs_server.py b/eval_protocol/utils/logs_server.py index d8ae3f57..545fef3d 100644 --- a/eval_protocol/utils/logs_server.py +++ b/eval_protocol/utils/logs_server.py @@ -97,6 +97,18 @@ def broadcast_file_update(self, update_type: str, file_path: str): return logger.info(f"Broadcasting file update: {update_type} {file_path}") + logs = default_logger.read() + # send initialize_logs message to all connected clients + for connection in self.active_connections: + asyncio.run_coroutine_threadsafe( + connection.send_text( + json.dumps( + {"type": "initialize_logs", "logs": [log.model_dump_json(exclude_none=True) for log in logs]} + ) + ), + self._loop, + ) + message = {"type": update_type, "path": file_path, "timestamp": time.time()} # Include file contents for created and modified events if update_type in ["file_created", "file_changed"] and os.path.exists(file_path): @@ -137,7 +149,7 @@ def __init__( os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "vite-app", "dist") ), host: str = "localhost", - port: Optional[int] = None, + port: Optional[int] = 8000, index_file: str = "index.html", watch_paths: Optional[List[str]] = None, ): diff --git a/vite-app/dist/assets/favicon-BkAAWQga.png b/vite-app/dist/assets/favicon-BkAAWQga.png new file mode 100644 index 00000000..66ff03b4 Binary files /dev/null and b/vite-app/dist/assets/favicon-BkAAWQga.png differ diff --git a/vite-app/dist/assets/index-BqeSuXV9.js b/vite-app/dist/assets/index-BqeSuXV9.js deleted file mode 100644 index b11e4e26..00000000 --- a/vite-app/dist/assets/index-BqeSuXV9.js +++ /dev/null @@ -1,61 +0,0 @@ -(function(){const o=document.createElement("link").relList;if(o&&o.supports&&o.supports("modulepreload"))return;for(const h of document.querySelectorAll('link[rel="modulepreload"]'))r(h);new MutationObserver(h=>{for(const S of h)if(S.type==="childList")for(const R of S.addedNodes)R.tagName==="LINK"&&R.rel==="modulepreload"&&r(R)}).observe(document,{childList:!0,subtree:!0});function d(h){const S={};return h.integrity&&(S.integrity=h.integrity),h.referrerPolicy&&(S.referrerPolicy=h.referrerPolicy),h.crossOrigin==="use-credentials"?S.credentials="include":h.crossOrigin==="anonymous"?S.credentials="omit":S.credentials="same-origin",S}function r(h){if(h.ep)return;h.ep=!0;const S=d(h);fetch(h.href,S)}})();function Xd(f){return f&&f.__esModule&&Object.prototype.hasOwnProperty.call(f,"default")?f.default:f}var gc={exports:{}},zu={};/** - * @license React - * react-jsx-runtime.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var zd;function Rv(){if(zd)return zu;zd=1;var f=Symbol.for("react.transitional.element"),o=Symbol.for("react.fragment");function d(r,h,S){var R=null;if(S!==void 0&&(R=""+S),h.key!==void 0&&(R=""+h.key),"key"in h){S={};for(var N in h)N!=="key"&&(S[N]=h[N])}else S=h;return h=S.ref,{$$typeof:f,type:r,key:R,ref:h!==void 0?h:null,props:S}}return zu.Fragment=o,zu.jsx=d,zu.jsxs=d,zu}var Od;function zv(){return Od||(Od=1,gc.exports=Rv()),gc.exports}var wt=zv(),Sc={exports:{}},I={};/** - * @license React - * react.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Md;function Ov(){if(Md)return I;Md=1;var f=Symbol.for("react.transitional.element"),o=Symbol.for("react.portal"),d=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),h=Symbol.for("react.profiler"),S=Symbol.for("react.consumer"),R=Symbol.for("react.context"),N=Symbol.for("react.forward_ref"),p=Symbol.for("react.suspense"),m=Symbol.for("react.memo"),M=Symbol.for("react.lazy"),H=Symbol.iterator;function C(v){return v===null||typeof v!="object"?null:(v=H&&v[H]||v["@@iterator"],typeof v=="function"?v:null)}var k={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Q=Object.assign,j={};function Z(v,x,G){this.props=v,this.context=x,this.refs=j,this.updater=G||k}Z.prototype.isReactComponent={},Z.prototype.setState=function(v,x){if(typeof v!="object"&&typeof v!="function"&&v!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,v,x,"setState")},Z.prototype.forceUpdate=function(v){this.updater.enqueueForceUpdate(this,v,"forceUpdate")};function Y(){}Y.prototype=Z.prototype;function nt(v,x,G){this.props=v,this.context=x,this.refs=j,this.updater=G||k}var P=nt.prototype=new Y;P.constructor=nt,Q(P,Z.prototype),P.isPureReactComponent=!0;var bt=Array.isArray,W={H:null,A:null,T:null,S:null,V:null},xt=Object.prototype.hasOwnProperty;function Dt(v,x,G,B,V,it){return G=it.ref,{$$typeof:f,type:v,key:x,ref:G!==void 0?G:null,props:it}}function Ht(v,x){return Dt(v.type,x,void 0,void 0,void 0,v.props)}function Et(v){return typeof v=="object"&&v!==null&&v.$$typeof===f}function It(v){var x={"=":"=0",":":"=2"};return"$"+v.replace(/[=:]/g,function(G){return x[G]})}var ol=/\/+/g;function Qt(v,x){return typeof v=="object"&&v!==null&&v.key!=null?It(""+v.key):x.toString(36)}function pe(){}function Ee(v){switch(v.status){case"fulfilled":return v.value;case"rejected":throw v.reason;default:switch(typeof v.status=="string"?v.then(pe,pe):(v.status="pending",v.then(function(x){v.status==="pending"&&(v.status="fulfilled",v.value=x)},function(x){v.status==="pending"&&(v.status="rejected",v.reason=x)})),v.status){case"fulfilled":return v.value;case"rejected":throw v.reason}}throw v}function jt(v,x,G,B,V){var it=typeof v;(it==="undefined"||it==="boolean")&&(v=null);var F=!1;if(v===null)F=!0;else switch(it){case"bigint":case"string":case"number":F=!0;break;case"object":switch(v.$$typeof){case f:case o:F=!0;break;case M:return F=v._init,jt(F(v._payload),x,G,B,V)}}if(F)return V=V(v),F=B===""?"."+Qt(v,0):B,bt(V)?(G="",F!=null&&(G=F.replace(ol,"$&/")+"/"),jt(V,x,G,"",function(kl){return kl})):V!=null&&(Et(V)&&(V=Ht(V,G+(V.key==null||v&&v.key===V.key?"":(""+V.key).replace(ol,"$&/")+"/")+F)),x.push(V)),1;F=0;var tl=B===""?".":B+":";if(bt(v))for(var gt=0;gt>>1,v=O[mt];if(0>>1;mth(B,J))Vh(it,B)?(O[mt]=it,O[V]=J,mt=V):(O[mt]=B,O[G]=J,mt=G);else if(Vh(it,J))O[mt]=it,O[V]=J,mt=V;else break t}}return q}function h(O,q){var J=O.sortIndex-q.sortIndex;return J!==0?J:O.id-q.id}if(f.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var S=performance;f.unstable_now=function(){return S.now()}}else{var R=Date,N=R.now();f.unstable_now=function(){return R.now()-N}}var p=[],m=[],M=1,H=null,C=3,k=!1,Q=!1,j=!1,Z=!1,Y=typeof setTimeout=="function"?setTimeout:null,nt=typeof clearTimeout=="function"?clearTimeout:null,P=typeof setImmediate<"u"?setImmediate:null;function bt(O){for(var q=d(m);q!==null;){if(q.callback===null)r(m);else if(q.startTime<=O)r(m),q.sortIndex=q.expirationTime,o(p,q);else break;q=d(m)}}function W(O){if(j=!1,bt(O),!Q)if(d(p)!==null)Q=!0,xt||(xt=!0,Qt());else{var q=d(m);q!==null&&jt(W,q.startTime-O)}}var xt=!1,Dt=-1,Ht=5,Et=-1;function It(){return Z?!0:!(f.unstable_now()-EtO&&It());){var mt=H.callback;if(typeof mt=="function"){H.callback=null,C=H.priorityLevel;var v=mt(H.expirationTime<=O);if(O=f.unstable_now(),typeof v=="function"){H.callback=v,bt(O),q=!0;break l}H===d(p)&&r(p),bt(O)}else r(p);H=d(p)}if(H!==null)q=!0;else{var x=d(m);x!==null&&jt(W,x.startTime-O),q=!1}}break t}finally{H=null,C=J,k=!1}q=void 0}}finally{q?Qt():xt=!1}}}var Qt;if(typeof P=="function")Qt=function(){P(ol)};else if(typeof MessageChannel<"u"){var pe=new MessageChannel,Ee=pe.port2;pe.port1.onmessage=ol,Qt=function(){Ee.postMessage(null)}}else Qt=function(){Y(ol,0)};function jt(O,q){Dt=Y(function(){O(f.unstable_now())},q)}f.unstable_IdlePriority=5,f.unstable_ImmediatePriority=1,f.unstable_LowPriority=4,f.unstable_NormalPriority=3,f.unstable_Profiling=null,f.unstable_UserBlockingPriority=2,f.unstable_cancelCallback=function(O){O.callback=null},f.unstable_forceFrameRate=function(O){0>O||125mt?(O.sortIndex=J,o(m,O),d(p)===null&&O===d(m)&&(j?(nt(Dt),Dt=-1):j=!0,jt(W,J-mt))):(O.sortIndex=v,o(p,O),Q||k||(Q=!0,xt||(xt=!0,Qt()))),O},f.unstable_shouldYield=It,f.unstable_wrapCallback=function(O){var q=C;return function(){var J=C;C=q;try{return O.apply(this,arguments)}finally{C=J}}}}(Ec)),Ec}var Ud;function _v(){return Ud||(Ud=1,pc.exports=Dv()),pc.exports}var Tc={exports:{}},Kt={};/** - * @license React - * react-dom.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Nd;function Uv(){if(Nd)return Kt;Nd=1;var f=Oc();function o(p){var m="https://react.dev/errors/"+p;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(f)}catch(o){console.error(o)}}return f(),Tc.exports=Uv(),Tc.exports}/** - * @license React - * react-dom-client.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Hd;function xv(){if(Hd)return Ou;Hd=1;var f=_v(),o=Oc(),d=Nv();function r(t){var l="https://react.dev/errors/"+t;if(1v||(t.current=mt[v],mt[v]=null,v--)}function B(t,l){v++,mt[v]=t.current,t.current=l}var V=x(null),it=x(null),F=x(null),tl=x(null);function gt(t,l){switch(B(F,l),B(it,t),B(V,null),l.nodeType){case 9:case 11:t=(t=l.documentElement)&&(t=t.namespaceURI)?Is(t):0;break;default:if(t=l.tagName,l=l.namespaceURI)l=Is(l),t=td(l,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}G(V),B(V,t)}function kl(){G(V),G(it),G(F)}function li(t){t.memoizedState!==null&&B(tl,t);var l=V.current,e=td(l,t.type);l!==e&&(B(it,t),B(V,e))}function xu(t){it.current===t&&(G(V),G(it)),tl.current===t&&(G(tl),pu._currentValue=J)}var ei=Object.prototype.hasOwnProperty,ai=f.unstable_scheduleCallback,ui=f.unstable_cancelCallback,eh=f.unstable_shouldYield,ah=f.unstable_requestPaint,Al=f.unstable_now,uh=f.unstable_getCurrentPriorityLevel,xc=f.unstable_ImmediatePriority,Hc=f.unstable_UserBlockingPriority,Hu=f.unstable_NormalPriority,nh=f.unstable_LowPriority,Cc=f.unstable_IdlePriority,ih=f.log,fh=f.unstable_setDisableYieldValue,Da=null,ll=null;function Wl(t){if(typeof ih=="function"&&fh(t),ll&&typeof ll.setStrictMode=="function")try{ll.setStrictMode(Da,t)}catch{}}var el=Math.clz32?Math.clz32:oh,ch=Math.log,rh=Math.LN2;function oh(t){return t>>>=0,t===0?32:31-(ch(t)/rh|0)|0}var Cu=256,Bu=4194304;function Te(t){var l=t&42;if(l!==0)return l;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t&4194048;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function qu(t,l,e){var a=t.pendingLanes;if(a===0)return 0;var u=0,n=t.suspendedLanes,i=t.pingedLanes;t=t.warmLanes;var c=a&134217727;return c!==0?(a=c&~n,a!==0?u=Te(a):(i&=c,i!==0?u=Te(i):e||(e=c&~t,e!==0&&(u=Te(e))))):(c=a&~n,c!==0?u=Te(c):i!==0?u=Te(i):e||(e=a&~t,e!==0&&(u=Te(e)))),u===0?0:l!==0&&l!==u&&(l&n)===0&&(n=u&-u,e=l&-l,n>=e||n===32&&(e&4194048)!==0)?l:u}function _a(t,l){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&l)===0}function sh(t,l){switch(t){case 1:case 2:case 4:case 8:case 64:return l+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return l+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Bc(){var t=Cu;return Cu<<=1,(Cu&4194048)===0&&(Cu=256),t}function qc(){var t=Bu;return Bu<<=1,(Bu&62914560)===0&&(Bu=4194304),t}function ni(t){for(var l=[],e=0;31>e;e++)l.push(t);return l}function Ua(t,l){t.pendingLanes|=l,l!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function dh(t,l,e,a,u,n){var i=t.pendingLanes;t.pendingLanes=e,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=e,t.entangledLanes&=e,t.errorRecoveryDisabledLanes&=e,t.shellSuspendCounter=0;var c=t.entanglements,s=t.expirationTimes,E=t.hiddenUpdates;for(e=i&~e;0)":-1u||s[a]!==E[u]){var z=` -`+s[a].replace(" at new "," at ");return t.displayName&&z.includes("")&&(z=z.replace("",t.displayName)),z}while(1<=a&&0<=u);break}}}finally{si=!1,Error.prepareStackTrace=e}return(e=t?t.displayName||t.name:"")?we(e):""}function Sh(t){switch(t.tag){case 26:case 27:case 5:return we(t.type);case 16:return we("Lazy");case 13:return we("Suspense");case 19:return we("SuspenseList");case 0:case 15:return di(t.type,!1);case 11:return di(t.type.render,!1);case 1:return di(t.type,!0);case 31:return we("Activity");default:return""}}function wc(t){try{var l="";do l+=Sh(t),t=t.return;while(t);return l}catch(e){return` -Error generating stack: `+e.message+` -`+e.stack}}function sl(t){switch(typeof t){case"bigint":case"boolean":case"number":case"string":case"undefined":return t;case"object":return t;default:return""}}function Jc(t){var l=t.type;return(t=t.nodeName)&&t.toLowerCase()==="input"&&(l==="checkbox"||l==="radio")}function bh(t){var l=Jc(t)?"checked":"value",e=Object.getOwnPropertyDescriptor(t.constructor.prototype,l),a=""+t[l];if(!t.hasOwnProperty(l)&&typeof e<"u"&&typeof e.get=="function"&&typeof e.set=="function"){var u=e.get,n=e.set;return Object.defineProperty(t,l,{configurable:!0,get:function(){return u.call(this)},set:function(i){a=""+i,n.call(this,i)}}),Object.defineProperty(t,l,{enumerable:e.enumerable}),{getValue:function(){return a},setValue:function(i){a=""+i},stopTracking:function(){t._valueTracker=null,delete t[l]}}}}function Lu(t){t._valueTracker||(t._valueTracker=bh(t))}function $c(t){if(!t)return!1;var l=t._valueTracker;if(!l)return!0;var e=l.getValue(),a="";return t&&(a=Jc(t)?t.checked?"true":"false":t.value),t=a,t!==e?(l.setValue(t),!0):!1}function Xu(t){if(t=t||(typeof document<"u"?document:void 0),typeof t>"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var ph=/[\n"\\]/g;function dl(t){return t.replace(ph,function(l){return"\\"+l.charCodeAt(0).toString(16)+" "})}function hi(t,l,e,a,u,n,i,c){t.name="",i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"?t.type=i:t.removeAttribute("type"),l!=null?i==="number"?(l===0&&t.value===""||t.value!=l)&&(t.value=""+sl(l)):t.value!==""+sl(l)&&(t.value=""+sl(l)):i!=="submit"&&i!=="reset"||t.removeAttribute("value"),l!=null?mi(t,i,sl(l)):e!=null?mi(t,i,sl(e)):a!=null&&t.removeAttribute("value"),u==null&&n!=null&&(t.defaultChecked=!!n),u!=null&&(t.checked=u&&typeof u!="function"&&typeof u!="symbol"),c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"?t.name=""+sl(c):t.removeAttribute("name")}function kc(t,l,e,a,u,n,i,c){if(n!=null&&typeof n!="function"&&typeof n!="symbol"&&typeof n!="boolean"&&(t.type=n),l!=null||e!=null){if(!(n!=="submit"&&n!=="reset"||l!=null))return;e=e!=null?""+sl(e):"",l=l!=null?""+sl(l):e,c||l===t.value||(t.value=l),t.defaultValue=l}a=a??u,a=typeof a!="function"&&typeof a!="symbol"&&!!a,t.checked=c?t.checked:!!a,t.defaultChecked=!!a,i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(t.name=i)}function mi(t,l,e){l==="number"&&Xu(t.ownerDocument)===t||t.defaultValue===""+e||(t.defaultValue=""+e)}function Je(t,l,e,a){if(t=t.options,l){l={};for(var u=0;u"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),bi=!1;if(xl)try{var Ca={};Object.defineProperty(Ca,"passive",{get:function(){bi=!0}}),window.addEventListener("test",Ca,Ca),window.removeEventListener("test",Ca,Ca)}catch{bi=!1}var Pl=null,pi=null,ju=null;function er(){if(ju)return ju;var t,l=pi,e=l.length,a,u="value"in Pl?Pl.value:Pl.textContent,n=u.length;for(t=0;t=Ya),cr=" ",rr=!1;function or(t,l){switch(t){case"keyup":return $h.indexOf(l.keyCode)!==-1;case"keydown":return l.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function sr(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var Fe=!1;function Wh(t,l){switch(t){case"compositionend":return sr(l);case"keypress":return l.which!==32?null:(rr=!0,cr);case"textInput":return t=l.data,t===cr&&rr?null:t;default:return null}}function Fh(t,l){if(Fe)return t==="compositionend"||!zi&&or(t,l)?(t=er(),ju=pi=Pl=null,Fe=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(l.ctrlKey||l.altKey||l.metaKey)||l.ctrlKey&&l.altKey){if(l.char&&1=l)return{node:e,offset:l-t};t=a}t:{for(;e;){if(e.nextSibling){e=e.nextSibling;break t}e=e.parentNode}e=void 0}e=br(e)}}function Er(t,l){return t&&l?t===l?!0:t&&t.nodeType===3?!1:l&&l.nodeType===3?Er(t,l.parentNode):"contains"in t?t.contains(l):t.compareDocumentPosition?!!(t.compareDocumentPosition(l)&16):!1:!1}function Tr(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var l=Xu(t.document);l instanceof t.HTMLIFrameElement;){try{var e=typeof l.contentWindow.location.href=="string"}catch{e=!1}if(e)t=l.contentWindow;else break;l=Xu(t.document)}return l}function Di(t){var l=t&&t.nodeName&&t.nodeName.toLowerCase();return l&&(l==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||l==="textarea"||t.contentEditable==="true")}var nm=xl&&"documentMode"in document&&11>=document.documentMode,Pe=null,_i=null,Qa=null,Ui=!1;function Ar(t,l,e){var a=e.window===e?e.document:e.nodeType===9?e:e.ownerDocument;Ui||Pe==null||Pe!==Xu(a)||(a=Pe,"selectionStart"in a&&Di(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),Qa&&Xa(Qa,a)||(Qa=a,a=Hn(_i,"onSelect"),0>=i,u-=i,Cl=1<<32-el(l)+u|e<n?n:8;var i=O.T,c={};O.T=c,yf(t,!1,l,e);try{var s=u(),E=O.S;if(E!==null&&E(c,s),s!==null&&typeof s=="object"&&typeof s.then=="function"){var z=mm(s,a);eu(t,l,z,cl(t))}else eu(t,l,a,cl(t))}catch(_){eu(t,l,{then:function(){},status:"rejected",reason:_},cl())}finally{q.p=n,O.T=i}}function bm(){}function mf(t,l,e,a){if(t.tag!==5)throw Error(r(476));var u=zo(t).queue;Ro(t,u,l,J,e===null?bm:function(){return Oo(t),e(a)})}function zo(t){var l=t.memoizedState;if(l!==null)return l;l={memoizedState:J,baseState:J,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Gl,lastRenderedState:J},next:null};var e={};return l.next={memoizedState:e,baseState:e,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Gl,lastRenderedState:e},next:null},t.memoizedState=l,t=t.alternate,t!==null&&(t.memoizedState=l),l}function Oo(t){var l=zo(t).next.queue;eu(t,l,{},cl())}function vf(){return Vt(pu)}function Mo(){return Mt().memoizedState}function Do(){return Mt().memoizedState}function pm(t){for(var l=t.return;l!==null;){switch(l.tag){case 24:case 3:var e=cl();t=le(e);var a=ee(l,t,e);a!==null&&(rl(a,l,e),Wa(a,l,e)),l={cache:Vi()},t.payload=l;return}l=l.return}}function Em(t,l,e){var a=cl();e={lane:a,revertLane:0,action:e,hasEagerState:!1,eagerState:null,next:null},hn(t)?Uo(l,e):(e=Ci(t,l,e,a),e!==null&&(rl(e,t,a),No(e,l,a)))}function _o(t,l,e){var a=cl();eu(t,l,e,a)}function eu(t,l,e,a){var u={lane:a,revertLane:0,action:e,hasEagerState:!1,eagerState:null,next:null};if(hn(t))Uo(l,u);else{var n=t.alternate;if(t.lanes===0&&(n===null||n.lanes===0)&&(n=l.lastRenderedReducer,n!==null))try{var i=l.lastRenderedState,c=n(i,e);if(u.hasEagerState=!0,u.eagerState=c,al(c,i))return ku(t,l,u,0),yt===null&&$u(),!1}catch{}finally{}if(e=Ci(t,l,u,a),e!==null)return rl(e,t,a),No(e,l,a),!0}return!1}function yf(t,l,e,a){if(a={lane:2,revertLane:$f(),action:a,hasEagerState:!1,eagerState:null,next:null},hn(t)){if(l)throw Error(r(479))}else l=Ci(t,e,a,2),l!==null&&rl(l,t,2)}function hn(t){var l=t.alternate;return t===tt||l!==null&&l===tt}function Uo(t,l){ca=fn=!0;var e=t.pending;e===null?l.next=l:(l.next=e.next,e.next=l),t.pending=l}function No(t,l,e){if((e&4194048)!==0){var a=l.lanes;a&=t.pendingLanes,e|=a,l.lanes=e,Gc(t,e)}}var mn={readContext:Vt,use:rn,useCallback:Rt,useContext:Rt,useEffect:Rt,useImperativeHandle:Rt,useLayoutEffect:Rt,useInsertionEffect:Rt,useMemo:Rt,useReducer:Rt,useRef:Rt,useState:Rt,useDebugValue:Rt,useDeferredValue:Rt,useTransition:Rt,useSyncExternalStore:Rt,useId:Rt,useHostTransitionStatus:Rt,useFormState:Rt,useActionState:Rt,useOptimistic:Rt,useMemoCache:Rt,useCacheRefresh:Rt},xo={readContext:Vt,use:rn,useCallback:function(t,l){return Wt().memoizedState=[t,l===void 0?null:l],t},useContext:Vt,useEffect:vo,useImperativeHandle:function(t,l,e){e=e!=null?e.concat([t]):null,dn(4194308,4,bo.bind(null,l,t),e)},useLayoutEffect:function(t,l){return dn(4194308,4,t,l)},useInsertionEffect:function(t,l){dn(4,2,t,l)},useMemo:function(t,l){var e=Wt();l=l===void 0?null:l;var a=t();if(Be){Wl(!0);try{t()}finally{Wl(!1)}}return e.memoizedState=[a,l],a},useReducer:function(t,l,e){var a=Wt();if(e!==void 0){var u=e(l);if(Be){Wl(!0);try{e(l)}finally{Wl(!1)}}}else u=l;return a.memoizedState=a.baseState=u,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:u},a.queue=t,t=t.dispatch=Em.bind(null,tt,t),[a.memoizedState,t]},useRef:function(t){var l=Wt();return t={current:t},l.memoizedState=t},useState:function(t){t=of(t);var l=t.queue,e=_o.bind(null,tt,l);return l.dispatch=e,[t.memoizedState,e]},useDebugValue:df,useDeferredValue:function(t,l){var e=Wt();return hf(e,t,l)},useTransition:function(){var t=of(!1);return t=Ro.bind(null,tt,t.queue,!0,!1),Wt().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,l,e){var a=tt,u=Wt();if(ct){if(e===void 0)throw Error(r(407));e=e()}else{if(e=l(),yt===null)throw Error(r(349));(ut&124)!==0||Pr(a,l,e)}u.memoizedState=e;var n={value:e,getSnapshot:l};return u.queue=n,vo(to.bind(null,a,n,t),[t]),a.flags|=2048,oa(9,sn(),Ir.bind(null,a,n,e,l),null),e},useId:function(){var t=Wt(),l=yt.identifierPrefix;if(ct){var e=Bl,a=Cl;e=(a&~(1<<32-el(a)-1)).toString(32)+e,l="Ā«"+l+"R"+e,e=cn++,0w?(Yt=X,X=null):Yt=X.sibling;var ft=T(g,X,b[w],D);if(ft===null){X===null&&(X=Yt);break}t&&X&&ft.alternate===null&&l(g,X),y=n(ft,y,w),lt===null?L=ft:lt.sibling=ft,lt=ft,X=Yt}if(w===b.length)return e(g,X),ct&&_e(g,w),L;if(X===null){for(;ww?(Yt=X,X=null):Yt=X.sibling;var be=T(g,X,ft.value,D);if(be===null){X===null&&(X=Yt);break}t&&X&&be.alternate===null&&l(g,X),y=n(be,y,w),lt===null?L=be:lt.sibling=be,lt=be,X=Yt}if(ft.done)return e(g,X),ct&&_e(g,w),L;if(X===null){for(;!ft.done;w++,ft=b.next())ft=_(g,ft.value,D),ft!==null&&(y=n(ft,y,w),lt===null?L=ft:lt.sibling=ft,lt=ft);return ct&&_e(g,w),L}for(X=a(X);!ft.done;w++,ft=b.next())ft=A(X,g,w,ft.value,D),ft!==null&&(t&&ft.alternate!==null&&X.delete(ft.key===null?w:ft.key),y=n(ft,y,w),lt===null?L=ft:lt.sibling=ft,lt=ft);return t&&X.forEach(function(Av){return l(g,Av)}),ct&&_e(g,w),L}function ht(g,y,b,D){if(typeof b=="object"&&b!==null&&b.type===Q&&b.key===null&&(b=b.props.children),typeof b=="object"&&b!==null){switch(b.$$typeof){case C:t:{for(var L=b.key;y!==null;){if(y.key===L){if(L=b.type,L===Q){if(y.tag===7){e(g,y.sibling),D=u(y,b.props.children),D.return=g,g=D;break t}}else if(y.elementType===L||typeof L=="object"&&L!==null&&L.$$typeof===Ht&&Co(L)===y.type){e(g,y.sibling),D=u(y,b.props),uu(D,b),D.return=g,g=D;break t}e(g,y);break}else l(g,y);y=y.sibling}b.type===Q?(D=Me(b.props.children,g.mode,D,b.key),D.return=g,g=D):(D=Fu(b.type,b.key,b.props,null,g.mode,D),uu(D,b),D.return=g,g=D)}return i(g);case k:t:{for(L=b.key;y!==null;){if(y.key===L)if(y.tag===4&&y.stateNode.containerInfo===b.containerInfo&&y.stateNode.implementation===b.implementation){e(g,y.sibling),D=u(y,b.children||[]),D.return=g,g=D;break t}else{e(g,y);break}else l(g,y);y=y.sibling}D=Yi(b,g.mode,D),D.return=g,g=D}return i(g);case Ht:return L=b._init,b=L(b._payload),ht(g,y,b,D)}if(jt(b))return $(g,y,b,D);if(Qt(b)){if(L=Qt(b),typeof L!="function")throw Error(r(150));return b=L.call(b),K(g,y,b,D)}if(typeof b.then=="function")return ht(g,y,vn(b),D);if(b.$$typeof===P)return ht(g,y,ln(g,b),D);yn(g,b)}return typeof b=="string"&&b!==""||typeof b=="number"||typeof b=="bigint"?(b=""+b,y!==null&&y.tag===6?(e(g,y.sibling),D=u(y,b),D.return=g,g=D):(e(g,y),D=qi(b,g.mode,D),D.return=g,g=D),i(g)):e(g,y)}return function(g,y,b,D){try{au=0;var L=ht(g,y,b,D);return sa=null,L}catch(X){if(X===$a||X===an)throw X;var lt=ul(29,X,null,g.mode);return lt.lanes=D,lt.return=g,lt}finally{}}}var da=Bo(!0),qo=Bo(!1),gl=x(null),zl=null;function ue(t){var l=t.alternate;B(Ut,Ut.current&1),B(gl,t),zl===null&&(l===null||fa.current!==null||l.memoizedState!==null)&&(zl=t)}function Yo(t){if(t.tag===22){if(B(Ut,Ut.current),B(gl,t),zl===null){var l=t.alternate;l!==null&&l.memoizedState!==null&&(zl=t)}}else ne()}function ne(){B(Ut,Ut.current),B(gl,gl.current)}function Ll(t){G(gl),zl===t&&(zl=null),G(Ut)}var Ut=x(0);function gn(t){for(var l=t;l!==null;){if(l.tag===13){var e=l.memoizedState;if(e!==null&&(e=e.dehydrated,e===null||e.data==="$?"||ic(e)))return l}else if(l.tag===19&&l.memoizedProps.revealOrder!==void 0){if((l.flags&128)!==0)return l}else if(l.child!==null){l.child.return=l,l=l.child;continue}if(l===t)break;for(;l.sibling===null;){if(l.return===null||l.return===t)return null;l=l.return}l.sibling.return=l.return,l=l.sibling}return null}function gf(t,l,e,a){l=t.memoizedState,e=e(a,l),e=e==null?l:M({},l,e),t.memoizedState=e,t.lanes===0&&(t.updateQueue.baseState=e)}var Sf={enqueueSetState:function(t,l,e){t=t._reactInternals;var a=cl(),u=le(a);u.payload=l,e!=null&&(u.callback=e),l=ee(t,u,a),l!==null&&(rl(l,t,a),Wa(l,t,a))},enqueueReplaceState:function(t,l,e){t=t._reactInternals;var a=cl(),u=le(a);u.tag=1,u.payload=l,e!=null&&(u.callback=e),l=ee(t,u,a),l!==null&&(rl(l,t,a),Wa(l,t,a))},enqueueForceUpdate:function(t,l){t=t._reactInternals;var e=cl(),a=le(e);a.tag=2,l!=null&&(a.callback=l),l=ee(t,a,e),l!==null&&(rl(l,t,e),Wa(l,t,e))}};function Go(t,l,e,a,u,n,i){return t=t.stateNode,typeof t.shouldComponentUpdate=="function"?t.shouldComponentUpdate(a,n,i):l.prototype&&l.prototype.isPureReactComponent?!Xa(e,a)||!Xa(u,n):!0}function Lo(t,l,e,a){t=l.state,typeof l.componentWillReceiveProps=="function"&&l.componentWillReceiveProps(e,a),typeof l.UNSAFE_componentWillReceiveProps=="function"&&l.UNSAFE_componentWillReceiveProps(e,a),l.state!==t&&Sf.enqueueReplaceState(l,l.state,null)}function qe(t,l){var e=l;if("ref"in l){e={};for(var a in l)a!=="ref"&&(e[a]=l[a])}if(t=t.defaultProps){e===l&&(e=M({},e));for(var u in t)e[u]===void 0&&(e[u]=t[u])}return e}var Sn=typeof reportError=="function"?reportError:function(t){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var l=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof t=="object"&&t!==null&&typeof t.message=="string"?String(t.message):String(t),error:t});if(!window.dispatchEvent(l))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",t);return}console.error(t)};function Xo(t){Sn(t)}function Qo(t){console.error(t)}function jo(t){Sn(t)}function bn(t,l){try{var e=t.onUncaughtError;e(l.value,{componentStack:l.stack})}catch(a){setTimeout(function(){throw a})}}function Zo(t,l,e){try{var a=t.onCaughtError;a(e.value,{componentStack:e.stack,errorBoundary:l.tag===1?l.stateNode:null})}catch(u){setTimeout(function(){throw u})}}function bf(t,l,e){return e=le(e),e.tag=3,e.payload={element:null},e.callback=function(){bn(t,l)},e}function Vo(t){return t=le(t),t.tag=3,t}function Ko(t,l,e,a){var u=e.type.getDerivedStateFromError;if(typeof u=="function"){var n=a.value;t.payload=function(){return u(n)},t.callback=function(){Zo(l,e,a)}}var i=e.stateNode;i!==null&&typeof i.componentDidCatch=="function"&&(t.callback=function(){Zo(l,e,a),typeof u!="function"&&(se===null?se=new Set([this]):se.add(this));var c=a.stack;this.componentDidCatch(a.value,{componentStack:c!==null?c:""})})}function Am(t,l,e,a,u){if(e.flags|=32768,a!==null&&typeof a=="object"&&typeof a.then=="function"){if(l=e.alternate,l!==null&&Ka(l,e,u,!0),e=gl.current,e!==null){switch(e.tag){case 13:return zl===null?Zf():e.alternate===null&&At===0&&(At=3),e.flags&=-257,e.flags|=65536,e.lanes=u,a===Ji?e.flags|=16384:(l=e.updateQueue,l===null?e.updateQueue=new Set([a]):l.add(a),Kf(t,a,u)),!1;case 22:return e.flags|=65536,a===Ji?e.flags|=16384:(l=e.updateQueue,l===null?(l={transitions:null,markerInstances:null,retryQueue:new Set([a])},e.updateQueue=l):(e=l.retryQueue,e===null?l.retryQueue=new Set([a]):e.add(a)),Kf(t,a,u)),!1}throw Error(r(435,e.tag))}return Kf(t,a,u),Zf(),!1}if(ct)return l=gl.current,l!==null?((l.flags&65536)===0&&(l.flags|=256),l.flags|=65536,l.lanes=u,a!==Xi&&(t=Error(r(422),{cause:a}),Va(hl(t,e)))):(a!==Xi&&(l=Error(r(423),{cause:a}),Va(hl(l,e))),t=t.current.alternate,t.flags|=65536,u&=-u,t.lanes|=u,a=hl(a,e),u=bf(t.stateNode,a,u),Wi(t,u),At!==4&&(At=2)),!1;var n=Error(r(520),{cause:a});if(n=hl(n,e),su===null?su=[n]:su.push(n),At!==4&&(At=2),l===null)return!0;a=hl(a,e),e=l;do{switch(e.tag){case 3:return e.flags|=65536,t=u&-u,e.lanes|=t,t=bf(e.stateNode,a,t),Wi(e,t),!1;case 1:if(l=e.type,n=e.stateNode,(e.flags&128)===0&&(typeof l.getDerivedStateFromError=="function"||n!==null&&typeof n.componentDidCatch=="function"&&(se===null||!se.has(n))))return e.flags|=65536,u&=-u,e.lanes|=u,u=Vo(u),Ko(u,t,e,a),Wi(e,u),!1}e=e.return}while(e!==null);return!1}var wo=Error(r(461)),Bt=!1;function Gt(t,l,e,a){l.child=t===null?qo(l,null,e,a):da(l,t.child,e,a)}function Jo(t,l,e,a,u){e=e.render;var n=l.ref;if("ref"in a){var i={};for(var c in a)c!=="ref"&&(i[c]=a[c])}else i=a;return He(l),a=lf(t,l,e,i,n,u),c=ef(),t!==null&&!Bt?(af(t,l,u),Xl(t,l,u)):(ct&&c&&Gi(l),l.flags|=1,Gt(t,l,a,u),l.child)}function $o(t,l,e,a,u){if(t===null){var n=e.type;return typeof n=="function"&&!Bi(n)&&n.defaultProps===void 0&&e.compare===null?(l.tag=15,l.type=n,ko(t,l,n,a,u)):(t=Fu(e.type,null,a,l,l.mode,u),t.ref=l.ref,t.return=l,l.child=t)}if(n=t.child,!Mf(t,u)){var i=n.memoizedProps;if(e=e.compare,e=e!==null?e:Xa,e(i,a)&&t.ref===l.ref)return Xl(t,l,u)}return l.flags|=1,t=Hl(n,a),t.ref=l.ref,t.return=l,l.child=t}function ko(t,l,e,a,u){if(t!==null){var n=t.memoizedProps;if(Xa(n,a)&&t.ref===l.ref)if(Bt=!1,l.pendingProps=a=n,Mf(t,u))(t.flags&131072)!==0&&(Bt=!0);else return l.lanes=t.lanes,Xl(t,l,u)}return pf(t,l,e,a,u)}function Wo(t,l,e){var a=l.pendingProps,u=a.children,n=t!==null?t.memoizedState:null;if(a.mode==="hidden"){if((l.flags&128)!==0){if(a=n!==null?n.baseLanes|e:e,t!==null){for(u=l.child=t.child,n=0;u!==null;)n=n|u.lanes|u.childLanes,u=u.sibling;l.childLanes=n&~a}else l.childLanes=0,l.child=null;return Fo(t,l,a,e)}if((e&536870912)!==0)l.memoizedState={baseLanes:0,cachePool:null},t!==null&&en(l,n!==null?n.cachePool:null),n!==null?$r(l,n):Pi(),Yo(l);else return l.lanes=l.childLanes=536870912,Fo(t,l,n!==null?n.baseLanes|e:e,e)}else n!==null?(en(l,n.cachePool),$r(l,n),ne(),l.memoizedState=null):(t!==null&&en(l,null),Pi(),ne());return Gt(t,l,u,e),l.child}function Fo(t,l,e,a){var u=wi();return u=u===null?null:{parent:_t._currentValue,pool:u},l.memoizedState={baseLanes:e,cachePool:u},t!==null&&en(l,null),Pi(),Yo(l),t!==null&&Ka(t,l,a,!0),null}function pn(t,l){var e=l.ref;if(e===null)t!==null&&t.ref!==null&&(l.flags|=4194816);else{if(typeof e!="function"&&typeof e!="object")throw Error(r(284));(t===null||t.ref!==e)&&(l.flags|=4194816)}}function pf(t,l,e,a,u){return He(l),e=lf(t,l,e,a,void 0,u),a=ef(),t!==null&&!Bt?(af(t,l,u),Xl(t,l,u)):(ct&&a&&Gi(l),l.flags|=1,Gt(t,l,e,u),l.child)}function Po(t,l,e,a,u,n){return He(l),l.updateQueue=null,e=Wr(l,a,e,u),kr(t),a=ef(),t!==null&&!Bt?(af(t,l,n),Xl(t,l,n)):(ct&&a&&Gi(l),l.flags|=1,Gt(t,l,e,n),l.child)}function Io(t,l,e,a,u){if(He(l),l.stateNode===null){var n=ea,i=e.contextType;typeof i=="object"&&i!==null&&(n=Vt(i)),n=new e(a,n),l.memoizedState=n.state!==null&&n.state!==void 0?n.state:null,n.updater=Sf,l.stateNode=n,n._reactInternals=l,n=l.stateNode,n.props=a,n.state=l.memoizedState,n.refs={},$i(l),i=e.contextType,n.context=typeof i=="object"&&i!==null?Vt(i):ea,n.state=l.memoizedState,i=e.getDerivedStateFromProps,typeof i=="function"&&(gf(l,e,i,a),n.state=l.memoizedState),typeof e.getDerivedStateFromProps=="function"||typeof n.getSnapshotBeforeUpdate=="function"||typeof n.UNSAFE_componentWillMount!="function"&&typeof n.componentWillMount!="function"||(i=n.state,typeof n.componentWillMount=="function"&&n.componentWillMount(),typeof n.UNSAFE_componentWillMount=="function"&&n.UNSAFE_componentWillMount(),i!==n.state&&Sf.enqueueReplaceState(n,n.state,null),Pa(l,a,n,u),Fa(),n.state=l.memoizedState),typeof n.componentDidMount=="function"&&(l.flags|=4194308),a=!0}else if(t===null){n=l.stateNode;var c=l.memoizedProps,s=qe(e,c);n.props=s;var E=n.context,z=e.contextType;i=ea,typeof z=="object"&&z!==null&&(i=Vt(z));var _=e.getDerivedStateFromProps;z=typeof _=="function"||typeof n.getSnapshotBeforeUpdate=="function",c=l.pendingProps!==c,z||typeof n.UNSAFE_componentWillReceiveProps!="function"&&typeof n.componentWillReceiveProps!="function"||(c||E!==i)&&Lo(l,n,a,i),te=!1;var T=l.memoizedState;n.state=T,Pa(l,a,n,u),Fa(),E=l.memoizedState,c||T!==E||te?(typeof _=="function"&&(gf(l,e,_,a),E=l.memoizedState),(s=te||Go(l,e,s,a,T,E,i))?(z||typeof n.UNSAFE_componentWillMount!="function"&&typeof n.componentWillMount!="function"||(typeof n.componentWillMount=="function"&&n.componentWillMount(),typeof n.UNSAFE_componentWillMount=="function"&&n.UNSAFE_componentWillMount()),typeof n.componentDidMount=="function"&&(l.flags|=4194308)):(typeof n.componentDidMount=="function"&&(l.flags|=4194308),l.memoizedProps=a,l.memoizedState=E),n.props=a,n.state=E,n.context=i,a=s):(typeof n.componentDidMount=="function"&&(l.flags|=4194308),a=!1)}else{n=l.stateNode,ki(t,l),i=l.memoizedProps,z=qe(e,i),n.props=z,_=l.pendingProps,T=n.context,E=e.contextType,s=ea,typeof E=="object"&&E!==null&&(s=Vt(E)),c=e.getDerivedStateFromProps,(E=typeof c=="function"||typeof n.getSnapshotBeforeUpdate=="function")||typeof n.UNSAFE_componentWillReceiveProps!="function"&&typeof n.componentWillReceiveProps!="function"||(i!==_||T!==s)&&Lo(l,n,a,s),te=!1,T=l.memoizedState,n.state=T,Pa(l,a,n,u),Fa();var A=l.memoizedState;i!==_||T!==A||te||t!==null&&t.dependencies!==null&&tn(t.dependencies)?(typeof c=="function"&&(gf(l,e,c,a),A=l.memoizedState),(z=te||Go(l,e,z,a,T,A,s)||t!==null&&t.dependencies!==null&&tn(t.dependencies))?(E||typeof n.UNSAFE_componentWillUpdate!="function"&&typeof n.componentWillUpdate!="function"||(typeof n.componentWillUpdate=="function"&&n.componentWillUpdate(a,A,s),typeof n.UNSAFE_componentWillUpdate=="function"&&n.UNSAFE_componentWillUpdate(a,A,s)),typeof n.componentDidUpdate=="function"&&(l.flags|=4),typeof n.getSnapshotBeforeUpdate=="function"&&(l.flags|=1024)):(typeof n.componentDidUpdate!="function"||i===t.memoizedProps&&T===t.memoizedState||(l.flags|=4),typeof n.getSnapshotBeforeUpdate!="function"||i===t.memoizedProps&&T===t.memoizedState||(l.flags|=1024),l.memoizedProps=a,l.memoizedState=A),n.props=a,n.state=A,n.context=s,a=z):(typeof n.componentDidUpdate!="function"||i===t.memoizedProps&&T===t.memoizedState||(l.flags|=4),typeof n.getSnapshotBeforeUpdate!="function"||i===t.memoizedProps&&T===t.memoizedState||(l.flags|=1024),a=!1)}return n=a,pn(t,l),a=(l.flags&128)!==0,n||a?(n=l.stateNode,e=a&&typeof e.getDerivedStateFromError!="function"?null:n.render(),l.flags|=1,t!==null&&a?(l.child=da(l,t.child,null,u),l.child=da(l,null,e,u)):Gt(t,l,e,u),l.memoizedState=n.state,t=l.child):t=Xl(t,l,u),t}function ts(t,l,e,a){return Za(),l.flags|=256,Gt(t,l,e,a),l.child}var Ef={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function Tf(t){return{baseLanes:t,cachePool:Xr()}}function Af(t,l,e){return t=t!==null?t.childLanes&~e:0,l&&(t|=Sl),t}function ls(t,l,e){var a=l.pendingProps,u=!1,n=(l.flags&128)!==0,i;if((i=n)||(i=t!==null&&t.memoizedState===null?!1:(Ut.current&2)!==0),i&&(u=!0,l.flags&=-129),i=(l.flags&32)!==0,l.flags&=-33,t===null){if(ct){if(u?ue(l):ne(),ct){var c=Tt,s;if(s=c){t:{for(s=c,c=Rl;s.nodeType!==8;){if(!c){c=null;break t}if(s=Tl(s.nextSibling),s===null){c=null;break t}}c=s}c!==null?(l.memoizedState={dehydrated:c,treeContext:De!==null?{id:Cl,overflow:Bl}:null,retryLane:536870912,hydrationErrors:null},s=ul(18,null,null,0),s.stateNode=c,s.return=l,l.child=s,Jt=l,Tt=null,s=!0):s=!1}s||Ne(l)}if(c=l.memoizedState,c!==null&&(c=c.dehydrated,c!==null))return ic(c)?l.lanes=32:l.lanes=536870912,null;Ll(l)}return c=a.children,a=a.fallback,u?(ne(),u=l.mode,c=En({mode:"hidden",children:c},u),a=Me(a,u,e,null),c.return=l,a.return=l,c.sibling=a,l.child=c,u=l.child,u.memoizedState=Tf(e),u.childLanes=Af(t,i,e),l.memoizedState=Ef,a):(ue(l),Rf(l,c))}if(s=t.memoizedState,s!==null&&(c=s.dehydrated,c!==null)){if(n)l.flags&256?(ue(l),l.flags&=-257,l=zf(t,l,e)):l.memoizedState!==null?(ne(),l.child=t.child,l.flags|=128,l=null):(ne(),u=a.fallback,c=l.mode,a=En({mode:"visible",children:a.children},c),u=Me(u,c,e,null),u.flags|=2,a.return=l,u.return=l,a.sibling=u,l.child=a,da(l,t.child,null,e),a=l.child,a.memoizedState=Tf(e),a.childLanes=Af(t,i,e),l.memoizedState=Ef,l=u);else if(ue(l),ic(c)){if(i=c.nextSibling&&c.nextSibling.dataset,i)var E=i.dgst;i=E,a=Error(r(419)),a.stack="",a.digest=i,Va({value:a,source:null,stack:null}),l=zf(t,l,e)}else if(Bt||Ka(t,l,e,!1),i=(e&t.childLanes)!==0,Bt||i){if(i=yt,i!==null&&(a=e&-e,a=(a&42)!==0?1:ii(a),a=(a&(i.suspendedLanes|e))!==0?0:a,a!==0&&a!==s.retryLane))throw s.retryLane=a,la(t,a),rl(i,t,a),wo;c.data==="$?"||Zf(),l=zf(t,l,e)}else c.data==="$?"?(l.flags|=192,l.child=t.child,l=null):(t=s.treeContext,Tt=Tl(c.nextSibling),Jt=l,ct=!0,Ue=null,Rl=!1,t!==null&&(vl[yl++]=Cl,vl[yl++]=Bl,vl[yl++]=De,Cl=t.id,Bl=t.overflow,De=l),l=Rf(l,a.children),l.flags|=4096);return l}return u?(ne(),u=a.fallback,c=l.mode,s=t.child,E=s.sibling,a=Hl(s,{mode:"hidden",children:a.children}),a.subtreeFlags=s.subtreeFlags&65011712,E!==null?u=Hl(E,u):(u=Me(u,c,e,null),u.flags|=2),u.return=l,a.return=l,a.sibling=u,l.child=a,a=u,u=l.child,c=t.child.memoizedState,c===null?c=Tf(e):(s=c.cachePool,s!==null?(E=_t._currentValue,s=s.parent!==E?{parent:E,pool:E}:s):s=Xr(),c={baseLanes:c.baseLanes|e,cachePool:s}),u.memoizedState=c,u.childLanes=Af(t,i,e),l.memoizedState=Ef,a):(ue(l),e=t.child,t=e.sibling,e=Hl(e,{mode:"visible",children:a.children}),e.return=l,e.sibling=null,t!==null&&(i=l.deletions,i===null?(l.deletions=[t],l.flags|=16):i.push(t)),l.child=e,l.memoizedState=null,e)}function Rf(t,l){return l=En({mode:"visible",children:l},t.mode),l.return=t,t.child=l}function En(t,l){return t=ul(22,t,null,l),t.lanes=0,t.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null},t}function zf(t,l,e){return da(l,t.child,null,e),t=Rf(l,l.pendingProps.children),t.flags|=2,l.memoizedState=null,t}function es(t,l,e){t.lanes|=l;var a=t.alternate;a!==null&&(a.lanes|=l),ji(t.return,l,e)}function Of(t,l,e,a,u){var n=t.memoizedState;n===null?t.memoizedState={isBackwards:l,rendering:null,renderingStartTime:0,last:a,tail:e,tailMode:u}:(n.isBackwards=l,n.rendering=null,n.renderingStartTime=0,n.last=a,n.tail=e,n.tailMode=u)}function as(t,l,e){var a=l.pendingProps,u=a.revealOrder,n=a.tail;if(Gt(t,l,a.children,e),a=Ut.current,(a&2)!==0)a=a&1|2,l.flags|=128;else{if(t!==null&&(t.flags&128)!==0)t:for(t=l.child;t!==null;){if(t.tag===13)t.memoizedState!==null&&es(t,e,l);else if(t.tag===19)es(t,e,l);else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===l)break t;for(;t.sibling===null;){if(t.return===null||t.return===l)break t;t=t.return}t.sibling.return=t.return,t=t.sibling}a&=1}switch(B(Ut,a),u){case"forwards":for(e=l.child,u=null;e!==null;)t=e.alternate,t!==null&&gn(t)===null&&(u=e),e=e.sibling;e=u,e===null?(u=l.child,l.child=null):(u=e.sibling,e.sibling=null),Of(l,!1,u,e,n);break;case"backwards":for(e=null,u=l.child,l.child=null;u!==null;){if(t=u.alternate,t!==null&&gn(t)===null){l.child=u;break}t=u.sibling,u.sibling=e,e=u,u=t}Of(l,!0,e,null,n);break;case"together":Of(l,!1,null,null,void 0);break;default:l.memoizedState=null}return l.child}function Xl(t,l,e){if(t!==null&&(l.dependencies=t.dependencies),oe|=l.lanes,(e&l.childLanes)===0)if(t!==null){if(Ka(t,l,e,!1),(e&l.childLanes)===0)return null}else return null;if(t!==null&&l.child!==t.child)throw Error(r(153));if(l.child!==null){for(t=l.child,e=Hl(t,t.pendingProps),l.child=e,e.return=l;t.sibling!==null;)t=t.sibling,e=e.sibling=Hl(t,t.pendingProps),e.return=l;e.sibling=null}return l.child}function Mf(t,l){return(t.lanes&l)!==0?!0:(t=t.dependencies,!!(t!==null&&tn(t)))}function Rm(t,l,e){switch(l.tag){case 3:gt(l,l.stateNode.containerInfo),Il(l,_t,t.memoizedState.cache),Za();break;case 27:case 5:li(l);break;case 4:gt(l,l.stateNode.containerInfo);break;case 10:Il(l,l.type,l.memoizedProps.value);break;case 13:var a=l.memoizedState;if(a!==null)return a.dehydrated!==null?(ue(l),l.flags|=128,null):(e&l.child.childLanes)!==0?ls(t,l,e):(ue(l),t=Xl(t,l,e),t!==null?t.sibling:null);ue(l);break;case 19:var u=(t.flags&128)!==0;if(a=(e&l.childLanes)!==0,a||(Ka(t,l,e,!1),a=(e&l.childLanes)!==0),u){if(a)return as(t,l,e);l.flags|=128}if(u=l.memoizedState,u!==null&&(u.rendering=null,u.tail=null,u.lastEffect=null),B(Ut,Ut.current),a)break;return null;case 22:case 23:return l.lanes=0,Wo(t,l,e);case 24:Il(l,_t,t.memoizedState.cache)}return Xl(t,l,e)}function us(t,l,e){if(t!==null)if(t.memoizedProps!==l.pendingProps)Bt=!0;else{if(!Mf(t,e)&&(l.flags&128)===0)return Bt=!1,Rm(t,l,e);Bt=(t.flags&131072)!==0}else Bt=!1,ct&&(l.flags&1048576)!==0&&Hr(l,Iu,l.index);switch(l.lanes=0,l.tag){case 16:t:{t=l.pendingProps;var a=l.elementType,u=a._init;if(a=u(a._payload),l.type=a,typeof a=="function")Bi(a)?(t=qe(a,t),l.tag=1,l=Io(null,l,a,t,e)):(l.tag=0,l=pf(null,l,a,t,e));else{if(a!=null){if(u=a.$$typeof,u===bt){l.tag=11,l=Jo(null,l,a,t,e);break t}else if(u===Dt){l.tag=14,l=$o(null,l,a,t,e);break t}}throw l=Ee(a)||a,Error(r(306,l,""))}}return l;case 0:return pf(t,l,l.type,l.pendingProps,e);case 1:return a=l.type,u=qe(a,l.pendingProps),Io(t,l,a,u,e);case 3:t:{if(gt(l,l.stateNode.containerInfo),t===null)throw Error(r(387));a=l.pendingProps;var n=l.memoizedState;u=n.element,ki(t,l),Pa(l,a,null,e);var i=l.memoizedState;if(a=i.cache,Il(l,_t,a),a!==n.cache&&Zi(l,[_t],e,!0),Fa(),a=i.element,n.isDehydrated)if(n={element:a,isDehydrated:!1,cache:i.cache},l.updateQueue.baseState=n,l.memoizedState=n,l.flags&256){l=ts(t,l,a,e);break t}else if(a!==u){u=hl(Error(r(424)),l),Va(u),l=ts(t,l,a,e);break t}else{switch(t=l.stateNode.containerInfo,t.nodeType){case 9:t=t.body;break;default:t=t.nodeName==="HTML"?t.ownerDocument.body:t}for(Tt=Tl(t.firstChild),Jt=l,ct=!0,Ue=null,Rl=!0,e=qo(l,null,a,e),l.child=e;e;)e.flags=e.flags&-3|4096,e=e.sibling}else{if(Za(),a===u){l=Xl(t,l,e);break t}Gt(t,l,a,e)}l=l.child}return l;case 26:return pn(t,l),t===null?(e=cd(l.type,null,l.pendingProps,null))?l.memoizedState=e:ct||(e=l.type,t=l.pendingProps,a=Bn(F.current).createElement(e),a[Zt]=l,a[$t]=t,Xt(a,e,t),Ct(a),l.stateNode=a):l.memoizedState=cd(l.type,t.memoizedProps,l.pendingProps,t.memoizedState),null;case 27:return li(l),t===null&&ct&&(a=l.stateNode=nd(l.type,l.pendingProps,F.current),Jt=l,Rl=!0,u=Tt,me(l.type)?(fc=u,Tt=Tl(a.firstChild)):Tt=u),Gt(t,l,l.pendingProps.children,e),pn(t,l),t===null&&(l.flags|=4194304),l.child;case 5:return t===null&&ct&&((u=a=Tt)&&(a=Pm(a,l.type,l.pendingProps,Rl),a!==null?(l.stateNode=a,Jt=l,Tt=Tl(a.firstChild),Rl=!1,u=!0):u=!1),u||Ne(l)),li(l),u=l.type,n=l.pendingProps,i=t!==null?t.memoizedProps:null,a=n.children,ac(u,n)?a=null:i!==null&&ac(u,i)&&(l.flags|=32),l.memoizedState!==null&&(u=lf(t,l,ym,null,null,e),pu._currentValue=u),pn(t,l),Gt(t,l,a,e),l.child;case 6:return t===null&&ct&&((t=e=Tt)&&(e=Im(e,l.pendingProps,Rl),e!==null?(l.stateNode=e,Jt=l,Tt=null,t=!0):t=!1),t||Ne(l)),null;case 13:return ls(t,l,e);case 4:return gt(l,l.stateNode.containerInfo),a=l.pendingProps,t===null?l.child=da(l,null,a,e):Gt(t,l,a,e),l.child;case 11:return Jo(t,l,l.type,l.pendingProps,e);case 7:return Gt(t,l,l.pendingProps,e),l.child;case 8:return Gt(t,l,l.pendingProps.children,e),l.child;case 12:return Gt(t,l,l.pendingProps.children,e),l.child;case 10:return a=l.pendingProps,Il(l,l.type,a.value),Gt(t,l,a.children,e),l.child;case 9:return u=l.type._context,a=l.pendingProps.children,He(l),u=Vt(u),a=a(u),l.flags|=1,Gt(t,l,a,e),l.child;case 14:return $o(t,l,l.type,l.pendingProps,e);case 15:return ko(t,l,l.type,l.pendingProps,e);case 19:return as(t,l,e);case 31:return a=l.pendingProps,e=l.mode,a={mode:a.mode,children:a.children},t===null?(e=En(a,e),e.ref=l.ref,l.child=e,e.return=l,l=e):(e=Hl(t.child,a),e.ref=l.ref,l.child=e,e.return=l,l=e),l;case 22:return Wo(t,l,e);case 24:return He(l),a=Vt(_t),t===null?(u=wi(),u===null&&(u=yt,n=Vi(),u.pooledCache=n,n.refCount++,n!==null&&(u.pooledCacheLanes|=e),u=n),l.memoizedState={parent:a,cache:u},$i(l),Il(l,_t,u)):((t.lanes&e)!==0&&(ki(t,l),Pa(l,null,null,e),Fa()),u=t.memoizedState,n=l.memoizedState,u.parent!==a?(u={parent:a,cache:a},l.memoizedState=u,l.lanes===0&&(l.memoizedState=l.updateQueue.baseState=u),Il(l,_t,a)):(a=n.cache,Il(l,_t,a),a!==u.cache&&Zi(l,[_t],e,!0))),Gt(t,l,l.pendingProps.children,e),l.child;case 29:throw l.pendingProps}throw Error(r(156,l.tag))}function Ql(t){t.flags|=4}function ns(t,l){if(l.type!=="stylesheet"||(l.state.loading&4)!==0)t.flags&=-16777217;else if(t.flags|=16777216,!hd(l)){if(l=gl.current,l!==null&&((ut&4194048)===ut?zl!==null:(ut&62914560)!==ut&&(ut&536870912)===0||l!==zl))throw ka=Ji,Qr;t.flags|=8192}}function Tn(t,l){l!==null&&(t.flags|=4),t.flags&16384&&(l=t.tag!==22?qc():536870912,t.lanes|=l,ya|=l)}function nu(t,l){if(!ct)switch(t.tailMode){case"hidden":l=t.tail;for(var e=null;l!==null;)l.alternate!==null&&(e=l),l=l.sibling;e===null?t.tail=null:e.sibling=null;break;case"collapsed":e=t.tail;for(var a=null;e!==null;)e.alternate!==null&&(a=e),e=e.sibling;a===null?l||t.tail===null?t.tail=null:t.tail.sibling=null:a.sibling=null}}function pt(t){var l=t.alternate!==null&&t.alternate.child===t.child,e=0,a=0;if(l)for(var u=t.child;u!==null;)e|=u.lanes|u.childLanes,a|=u.subtreeFlags&65011712,a|=u.flags&65011712,u.return=t,u=u.sibling;else for(u=t.child;u!==null;)e|=u.lanes|u.childLanes,a|=u.subtreeFlags,a|=u.flags,u.return=t,u=u.sibling;return t.subtreeFlags|=a,t.childLanes=e,l}function zm(t,l,e){var a=l.pendingProps;switch(Li(l),l.tag){case 31:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return pt(l),null;case 1:return pt(l),null;case 3:return e=l.stateNode,a=null,t!==null&&(a=t.memoizedState.cache),l.memoizedState.cache!==a&&(l.flags|=2048),Yl(_t),kl(),e.pendingContext&&(e.context=e.pendingContext,e.pendingContext=null),(t===null||t.child===null)&&(ja(l)?Ql(l):t===null||t.memoizedState.isDehydrated&&(l.flags&256)===0||(l.flags|=1024,qr())),pt(l),null;case 26:return e=l.memoizedState,t===null?(Ql(l),e!==null?(pt(l),ns(l,e)):(pt(l),l.flags&=-16777217)):e?e!==t.memoizedState?(Ql(l),pt(l),ns(l,e)):(pt(l),l.flags&=-16777217):(t.memoizedProps!==a&&Ql(l),pt(l),l.flags&=-16777217),null;case 27:xu(l),e=F.current;var u=l.type;if(t!==null&&l.stateNode!=null)t.memoizedProps!==a&&Ql(l);else{if(!a){if(l.stateNode===null)throw Error(r(166));return pt(l),null}t=V.current,ja(l)?Cr(l):(t=nd(u,a,e),l.stateNode=t,Ql(l))}return pt(l),null;case 5:if(xu(l),e=l.type,t!==null&&l.stateNode!=null)t.memoizedProps!==a&&Ql(l);else{if(!a){if(l.stateNode===null)throw Error(r(166));return pt(l),null}if(t=V.current,ja(l))Cr(l);else{switch(u=Bn(F.current),t){case 1:t=u.createElementNS("http://www.w3.org/2000/svg",e);break;case 2:t=u.createElementNS("http://www.w3.org/1998/Math/MathML",e);break;default:switch(e){case"svg":t=u.createElementNS("http://www.w3.org/2000/svg",e);break;case"math":t=u.createElementNS("http://www.w3.org/1998/Math/MathML",e);break;case"script":t=u.createElement("div"),t.innerHTML=" - + EP | Log Viewer + + +
- \ No newline at end of file + diff --git a/vite-app/src/GlobalState.tsx b/vite-app/src/GlobalState.tsx index c80652bc..4ffc962c 100644 --- a/vite-app/src/GlobalState.tsx +++ b/vite-app/src/GlobalState.tsx @@ -3,12 +3,47 @@ import type { EvaluationRow } from "./types/eval-protocol"; export class GlobalState { isConnected: boolean = false; - dataset: EvaluationRow[] = []; + dataset: Record = {}; + expandedRows: Record = {}; + constructor() { makeAutoObservable(this); } setDataset(dataset: EvaluationRow[]) { - this.dataset = dataset; + // Create new dataset object to avoid multiple re-renders + dataset.forEach((row) => { + this.dataset[row.input_metadata.row_id] = row; + }); + } + + toggleRowExpansion(rowId: string) { + if (this.expandedRows[rowId]) { + this.expandedRows[rowId] = false; + } else { + this.expandedRows[rowId] = true; + } + } + + isRowExpanded(rowId: string): boolean { + return this.expandedRows[rowId]; + } + + setAllRowsExpanded(expanded: boolean) { + Object.keys(this.dataset).forEach((rowId) => { + this.expandedRows[rowId] = expanded; + }); + } + + // Computed values following MobX best practices + get sortedDataset() { + return Object.values(this.dataset).sort( + (a, b) => + new Date(b.created_at).getTime() - new Date(a.created_at).getTime() + ); + } + + get totalCount() { + return Object.keys(this.dataset).length; } } diff --git a/vite-app/src/components/ChatInterface.tsx b/vite-app/src/components/ChatInterface.tsx index f9741e63..9d6c1862 100644 --- a/vite-app/src/components/ChatInterface.tsx +++ b/vite-app/src/components/ChatInterface.tsx @@ -8,7 +8,7 @@ interface ChatInterfaceProps { export const ChatInterface = ({ messages }: ChatInterfaceProps) => { const [chatWidth, setChatWidth] = useState(600); // Default width in pixels - const [chatHeight, setChatHeight] = useState(512); // Default height in pixels (32rem = 512px) + const [chatHeight, setChatHeight] = useState(400); // Default height in pixels const [isResizingWidth, setIsResizingWidth] = useState(false); const [isResizingHeight, setIsResizingHeight] = useState(false); const [initialWidth, setInitialWidth] = useState(0); @@ -16,8 +16,35 @@ export const ChatInterface = ({ messages }: ChatInterfaceProps) => { const [initialMouseX, setInitialMouseX] = useState(0); const [initialMouseY, setInitialMouseY] = useState(0); const chatContainerRef = useRef(null); + const scrollContainerRef = useRef(null); const resizeHandleRef = useRef(null); const heightResizeHandleRef = useRef(null); + const prevMessagesLengthRef = useRef(0); + + // Auto-scroll to bottom when new messages come in + useEffect(() => { + // On first render, just set the initial length without scrolling + if (prevMessagesLengthRef.current === 0) { + prevMessagesLengthRef.current = messages.length; + return; + } + + // Only scroll if we have messages and the number of messages has increased + // This prevents scrolling on initial mount or when messages are removed + if ( + messages.length > 0 && + messages.length > prevMessagesLengthRef.current + ) { + if (scrollContainerRef.current) { + scrollContainerRef.current.scrollTo({ + top: scrollContainerRef.current.scrollHeight, + behavior: "smooth", + }); + } + } + // Update the previous length for the next comparison + prevMessagesLengthRef.current = messages.length; + }, [messages]); // Handle horizontal resizing useEffect(() => { @@ -113,6 +140,7 @@ export const ChatInterface = ({ messages }: ChatInterfaceProps) => { style={{ width: `${chatWidth}px` }} >
diff --git a/vite-app/src/components/Dashboard.tsx b/vite-app/src/components/Dashboard.tsx index 684eff98..82646917 100644 --- a/vite-app/src/components/Dashboard.tsx +++ b/vite-app/src/components/Dashboard.tsx @@ -1,7 +1,7 @@ import { observer } from "mobx-react"; import { state } from "../App"; import Button from "./Button"; -import { Row } from "./Row"; +import { EvaluationTable } from "./EvaluationTable"; interface DashboardProps { onRefresh: () => void; @@ -46,67 +46,41 @@ const EmptyState = ({ onRefresh }: { onRefresh: () => void }) => { }; const Dashboard = observer(({ onRefresh }: DashboardProps) => { + const expandAll = () => state.setAllRowsExpanded(true); + const collapseAll = () => state.setAllRowsExpanded(false); + return (
{/* Summary Stats */}
-

- Dataset Summary -

-
- Total Rows:{" "} - {state.dataset.length} +
+

+ Dataset Summary +

+ {state.totalCount > 0 && ( +
+ + +
+ )} +
+
+
+ Total Rows:{" "} + {state.totalCount} +
{/* Show empty state or main table */} - {state.dataset.length === 0 ? ( + {state.totalCount === 0 ? ( ) : ( -
- - {/* Table Header */} - - - - - - - - - - - - - {/* Table Body */} - - {state.dataset - .slice() - .sort( - (a, b) => - new Date(b.created_at).getTime() - - new Date(a.created_at).getTime() - ) - .map((row, index) => ( - - ))} - -
- {/* Expand/Collapse column */} - - Name - - Status - - Row ID - - Model - - Score - - Created -
-
+ )}
); diff --git a/vite-app/src/components/EvaluationRow.tsx b/vite-app/src/components/EvaluationRow.tsx new file mode 100644 index 00000000..ffd9a8dc --- /dev/null +++ b/vite-app/src/components/EvaluationRow.tsx @@ -0,0 +1,242 @@ +import { observer } from "mobx-react"; +import type { EvaluationRow as EvaluationRowType } from "../types/eval-protocol"; +import { ChatInterface } from "./ChatInterface"; +import { MetadataSection } from "./MetadataSection"; +import StatusIndicator from "./StatusIndicator"; +import { state } from "../App"; + +// Small, focused components following "dereference values late" principle +const ExpandIcon = observer(({ rowId }: { rowId: string }) => { + const isExpanded = state.isRowExpanded(rowId); + return ( +
+ + + +
+ ); +}); + +const RowName = observer(({ name }: { name: string | undefined }) => ( + {name || "N/A"} +)); + +const RowStatus = observer( + ({ + status, + showSpinner, + }: { + status: string | undefined; + showSpinner: boolean; + }) => ( +
+ +
+ ) +); + +const RowId = observer(({ rowId }: { rowId: string }) => ( + {rowId} +)); + +const RowModel = observer(({ model }: { model: string | undefined }) => ( + {model || "N/A"} +)); + +const RowScore = observer(({ score }: { score: number | undefined }) => { + const scoreClass = score + ? score >= 0.8 + ? "text-green-700" + : score >= 0.6 + ? "text-yellow-700" + : "text-red-700" + : "text-gray-500"; + + return ( + + {score?.toFixed(3) || "N/A"} + + ); +}); + +const RowCreated = observer(({ created_at }: { created_at: Date | string }) => { + const date = created_at instanceof Date ? created_at : new Date(created_at); + + return ( + + {date.toLocaleDateString() + " " + date.toLocaleTimeString()} + + ); +}); + +// Granular metadata components following "dereference late" principle +const EvalMetadataSection = observer( + ({ data }: { data: EvaluationRowType["eval_metadata"] }) => ( + + ) +); + +const EvaluationResultSection = observer( + ({ data }: { data: EvaluationRowType["evaluation_result"] }) => ( + + ) +); + +const GroundTruthSection = observer( + ({ data }: { data: EvaluationRowType["ground_truth"] }) => ( + + ) +); + +const UsageStatsSection = observer( + ({ data }: { data: EvaluationRowType["usage"] }) => ( + + ) +); + +const InputMetadataSection = observer( + ({ data }: { data: EvaluationRowType["input_metadata"] }) => ( + + ) +); + +const ToolsSection = observer( + ({ data }: { data: EvaluationRowType["tools"] }) => ( + + ) +); + +const ChatInterfaceSection = observer( + ({ messages }: { messages: EvaluationRowType["messages"] }) => ( + + ) +); + +const ExpandedContent = observer( + ({ + messages, + eval_metadata, + evaluation_result, + ground_truth, + usage, + input_metadata, + tools, + }: { + messages: EvaluationRowType["messages"]; + eval_metadata: EvaluationRowType["eval_metadata"]; + evaluation_result: EvaluationRowType["evaluation_result"]; + ground_truth: EvaluationRowType["ground_truth"]; + usage: EvaluationRowType["usage"]; + input_metadata: EvaluationRowType["input_metadata"]; + tools: EvaluationRowType["tools"]; + }) => ( +
+
+ {/* Left Column - Chat Interface */} +
+ +
+ + {/* Right Column - Metadata */} +
+ + + + + + +
+
+
+ ) +); + +export const EvaluationRow = observer( + ({ row }: { row: EvaluationRowType; index: number }) => { + const rowId = row.input_metadata.row_id; + const isExpanded = state.isRowExpanded(rowId); + + const toggleExpanded = () => state.toggleRowExpansion(rowId); + + return ( + <> + {/* Main Table Row */} + + {/* Expand/Collapse Icon */} + + + + + {/* Name */} + + + + + {/* Status */} + + + + + {/* Row ID */} + + + + + {/* Model */} + + + + + {/* Score */} + + + + + {/* Created */} + + + + + + {/* Expanded Content Row */} + {isExpanded && ( + + + + + + )} + + ); + } +); diff --git a/vite-app/src/components/EvaluationTable.tsx b/vite-app/src/components/EvaluationTable.tsx new file mode 100644 index 00000000..7093757a --- /dev/null +++ b/vite-app/src/components/EvaluationTable.tsx @@ -0,0 +1,56 @@ +import { observer } from "mobx-react"; +import { state } from "../App"; +import { EvaluationRow } from "./EvaluationRow"; + +const TableBody = observer(() => { + return ( + + {state.sortedDataset.map((row, index) => ( + + ))} + + ); +}); + +// Dedicated component for rendering the list - following MobX best practices +export const EvaluationTable = observer(() => { + return ( +
+ + {/* Table Header */} + + + + + + + + + + + + + {/* Table Body */} + +
+ {/* Expand/Collapse column */} + + Name + + Status + + Row ID + + Model + + Score + + Created +
+
+ ); +}); diff --git a/vite-app/src/components/MessageBubble.tsx b/vite-app/src/components/MessageBubble.tsx index 2310c11d..382cb6dc 100644 --- a/vite-app/src/components/MessageBubble.tsx +++ b/vite-app/src/components/MessageBubble.tsx @@ -1,12 +1,36 @@ import type { Message } from "../types/eval-protocol"; +import { useState } from "react"; export const MessageBubble = ({ message }: { message: Message }) => { + const [isExpanded, setIsExpanded] = useState(false); const isUser = message.role === "user"; const isSystem = message.role === "system"; const isTool = message.role === "tool"; const hasToolCalls = message.tool_calls && message.tool_calls.length > 0; const hasFunctionCall = message.function_call; + // Get the message content as a string + const getMessageContent = () => { + if (typeof message.content === "string") { + return message.content; + } else if (Array.isArray(message.content)) { + return message.content + .map((part, i) => + part.type === "text" ? part.text : JSON.stringify(part) + ) + .join(""); + } else { + return JSON.stringify(message.content); + } + }; + + const messageContent = getMessageContent(); + const isLongMessage = messageContent.length > 200; // Threshold for considering a message "long" + const displayContent = + isLongMessage && !isExpanded + ? messageContent.substring(0, 200) + "..." + : messageContent; + return (
{ {message.role}
- {typeof message.content === "string" - ? message.content - : Array.isArray(message.content) - ? message.content - .map((part, i) => - part.type === "text" ? part.text : JSON.stringify(part) - ) - .join("") - : JSON.stringify(message.content)} + {displayContent}
+ {isLongMessage && ( + + )} {hasToolCalls && message.tool_calls && (
{ + const [isExpanded, setIsExpanded] = useState(defaultExpanded); + if (!data || Object.keys(data).length === 0) return null; return (
-

{title}

-
-
-          {JSON.stringify(data, null, 1)}
-        
+
setIsExpanded(!isExpanded)} + > +

{title}

+ + +
+ {isExpanded && ( +
+
+            {JSON.stringify(data, null, 1)}
+          
+
+ )}
); }; diff --git a/vite-app/src/components/Row.tsx b/vite-app/src/components/Row.tsx deleted file mode 100644 index 6b1cd52b..00000000 --- a/vite-app/src/components/Row.tsx +++ /dev/null @@ -1,160 +0,0 @@ -import { observer } from "mobx-react"; -import { useState } from "react"; -import type { EvaluationRow } from "../types/eval-protocol"; -import { ChatInterface } from "./ChatInterface"; -import { MetadataSection } from "./MetadataSection"; -import StatusIndicator from "./StatusIndicator"; - -export const Row = observer( - ({ row }: { row: EvaluationRow; index: number }) => { - const [isExpanded, setIsExpanded] = useState(false); - - const toggleExpanded = () => setIsExpanded(!isExpanded); - - return ( - <> - {/* Main Table Row */} - - {/* Expand/Collapse Icon */} - - {isExpanded ? ( - - - - ) : ( - - - - )} - - - {/* Name */} - - - {row.eval_metadata?.name || "N/A"} - - - - {/* Status */} - - - - - {/* Row ID */} - - - {row.input_metadata.row_id} - - - - {/* Model */} - - - {row.input_metadata.completion_params?.model || "N/A"} - - - - {/* Score */} - - = 0.8 - ? "text-green-700" - : row.evaluation_result.score >= 0.6 - ? "text-yellow-700" - : "text-red-700" - : "text-gray-500" - }`} - > - {row.evaluation_result?.score?.toFixed(3) || "N/A"} - - - - {/* Created */} - - - {row.created_at instanceof Date - ? row.created_at.toLocaleDateString() + - " " + - row.created_at.toLocaleTimeString() - : new Date(row.created_at).toLocaleDateString() + - " " + - new Date(row.created_at).toLocaleTimeString()} - - - - - {/* Expanded Content Row */} - {isExpanded && ( - - -
-
- {/* Left Column - Chat Interface */} - - - {/* Right Column - Metadata */} -
- {/* Eval Metadata */} - - - {/* Evaluation Result */} - - - {/* Ground Truth */} - - - {/* Usage Stats - Compact */} - - - {/* Input Metadata - Less Important */} - - - {/* Tools - Least Important */} - -
-
-
- - - )} - - ); - } -); diff --git a/vite-app/src/components/StatusIndicator.tsx b/vite-app/src/components/StatusIndicator.tsx index 07a51d84..0e2068e7 100644 --- a/vite-app/src/components/StatusIndicator.tsx +++ b/vite-app/src/components/StatusIndicator.tsx @@ -3,11 +3,19 @@ import React from "react"; interface StatusIndicatorProps { status: string; className?: string; + showSpinner?: boolean; } +const Spinner: React.FC<{ color: string }> = ({ color }) => ( +
+); + const StatusIndicator: React.FC = ({ status, className = "", + showSpinner = false, }) => { const getStatusConfig = (status: string) => { switch (status.toLowerCase()) { @@ -51,12 +59,17 @@ const StatusIndicator: React.FC = ({ }; const config = getStatusConfig(status); + const shouldShowSpinner = showSpinner && status.toLowerCase() === "running"; return (
-
+ {shouldShowSpinner ? ( + + ) : ( +
+ )} {config.text}
);