agentus 0.15.3 → 0.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/docs/installation.md +1 -1
- package/docs/installation.zh-CN.md +1 -1
- package/package.json +2 -2
- package/packages/server/mock/agent.mjs +12 -6
- package/packages/server/src/acp/session-manager.ts +28 -11
- package/packages/shared/src/index.ts +13 -8
- package/packages/web/dist/assets/{index-Bn2UlcXK.js → index-9Nbjtooa.js} +3 -3
- package/packages/web/dist/index.html +1 -1
|
@@ -40,7 +40,7 @@ Error generating stack: `+r.message+`
|
|
|
40
40
|
`+r.stack}return{value:e,source:t,stack:i,digest:null}}function ef(e,t,s){return{value:e,source:null,stack:s??null,digest:t??null}}function jp(e,t){try{console.error(t.value)}catch(s){setTimeout(function(){throw s})}}var P2=typeof WeakMap=="function"?WeakMap:Map;function Ox(e,t,s){s=Ri(-1,s),s.tag=3,s.payload={element:null};var n=t.value;return s.callback=function(){vh||(vh=!0,$p=n),jp(e,t)},s}function Bx(e,t,s){s=Ri(-1,s),s.tag=3;var n=e.type.getDerivedStateFromError;if(typeof n=="function"){var i=t.value;s.payload=function(){return n(i)},s.callback=function(){jp(e,t)}}var r=e.stateNode;return r!==null&&typeof r.componentDidCatch=="function"&&(s.callback=function(){jp(e,t),typeof n!="function"&&(_r===null?_r=new Set([this]):_r.add(this));var a=t.stack;this.componentDidCatch(t.value,{componentStack:a!==null?a:""})}),s}function Av(e,t,s){var n=e.pingCache;if(n===null){n=e.pingCache=new P2;var i=new Set;n.set(t,i)}else i=n.get(t),i===void 0&&(i=new Set,n.set(t,i));i.has(s)||(i.add(s),e=G2.bind(null,e,t,s),t.then(e,e))}function Mv(e){do{var t;if((t=e.tag===13)&&(t=e.memoizedState,t=t!==null?t.dehydrated!==null:!0),t)return e;e=e.return}while(e!==null);return null}function Dv(e,t,s,n,i){return e.mode&1?(e.flags|=65536,e.lanes=i,e):(e===t?e.flags|=65536:(e.flags|=128,s.flags|=131072,s.flags&=-52805,s.tag===1&&(s.alternate===null?s.tag=17:(t=Ri(-1,1),t.tag=2,gr(s,t,1))),s.lanes|=1),e)}var L2=Li.ReactCurrentOwner,qs=!1;function Ps(e,t,s,n){t.child=e===null?fx(t,null,s,n):ma(t,e.child,s,n)}function Iv(e,t,s,n,i){s=s.render;var r=t.ref;return aa(t,i),n=Og(e,t,s,n,r,i),s=Bg(),e!==null&&!qs?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,Pi(e,t,i)):(wt&&s&&Cg(t),t.flags|=1,Ps(e,t,n,i),t.child)}function Pv(e,t,s,n,i){if(e===null){var r=s.type;return typeof r=="function"&&!Yg(r)&&r.defaultProps===void 0&&s.compare===null&&s.defaultProps===void 0?(t.tag=15,t.type=r,$x(e,t,r,n,i)):(e=Hu(s.type,null,n,t,t.mode,i),e.ref=t.ref,e.return=t,t.child=e)}if(r=e.child,!(e.lanes&i)){var a=r.memoizedProps;if(s=s.compare,s=s!==null?s:Ql,s(a,n)&&e.ref===t.ref)return Pi(e,t,i)}return t.flags|=1,e=yr(r,n),e.ref=t.ref,e.return=t,t.child=e}function $x(e,t,s,n,i){if(e!==null){var r=e.memoizedProps;if(Ql(r,n)&&e.ref===t.ref)if(qs=!1,t.pendingProps=n=r,(e.lanes&i)!==0)e.flags&131072&&(qs=!0);else return t.lanes=e.lanes,Pi(e,t,i)}return Tp(e,t,s,n,i)}function Fx(e,t,s){var n=t.pendingProps,i=n.children,r=e!==null?e.memoizedState:null;if(n.mode==="hidden")if(!(t.mode&1))t.memoizedState={baseLanes:0,cachePool:null,transitions:null},pt(ea,sn),sn|=s;else{if(!(s&1073741824))return e=r!==null?r.baseLanes|s:s,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,pt(ea,sn),sn|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},n=r!==null?r.baseLanes:s,pt(ea,sn),sn|=n}else r!==null?(n=r.baseLanes|s,t.memoizedState=null):n=s,pt(ea,sn),sn|=n;return Ps(e,t,i,s),t.child}function zx(e,t){var s=t.ref;(e===null&&s!==null||e!==null&&e.ref!==s)&&(t.flags|=512,t.flags|=2097152)}function Tp(e,t,s,n,i){var r=Ys(s)?io:js.current;return r=fa(t,r),aa(t,i),s=Og(e,t,s,n,r,i),n=Bg(),e!==null&&!qs?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,Pi(e,t,i)):(wt&&n&&Cg(t),t.flags|=1,Ps(e,t,s,i),t.child)}function Lv(e,t,s,n,i){if(Ys(s)){var r=!0;lh(t)}else r=!1;if(aa(t,i),t.stateNode===null)$u(e,t),Lx(t,s,n),Rp(t,s,n,i),n=!0;else if(e===null){var a=t.stateNode,l=t.memoizedProps;a.props=l;var c=a.context,u=s.contextType;typeof u=="object"&&u!==null?u=kn(u):(u=Ys(s)?io:js.current,u=fa(t,u));var h=s.getDerivedStateFromProps,d=typeof h=="function"||typeof a.getSnapshotBeforeUpdate=="function";d||typeof a.UNSAFE_componentWillReceiveProps!="function"&&typeof a.componentWillReceiveProps!="function"||(l!==n||c!==u)&&Tv(t,a,n,u),er=!1;var p=t.memoizedState;a.state=p,fh(t,n,a,i),c=t.memoizedState,l!==n||p!==c||Vs.current||er?(typeof h=="function"&&(Np(t,s,h,n),c=t.memoizedState),(l=er||jv(t,s,l,n,p,c,u))?(d||typeof a.UNSAFE_componentWillMount!="function"&&typeof a.componentWillMount!="function"||(typeof a.componentWillMount=="function"&&a.componentWillMount(),typeof a.UNSAFE_componentWillMount=="function"&&a.UNSAFE_componentWillMount()),typeof a.componentDidMount=="function"&&(t.flags|=4194308)):(typeof a.componentDidMount=="function"&&(t.flags|=4194308),t.memoizedProps=n,t.memoizedState=c),a.props=n,a.state=c,a.context=u,n=l):(typeof a.componentDidMount=="function"&&(t.flags|=4194308),n=!1)}else{a=t.stateNode,mx(e,t),l=t.memoizedProps,u=t.type===t.elementType?l:Pn(t.type,l),a.props=u,d=t.pendingProps,p=a.context,c=s.contextType,typeof c=="object"&&c!==null?c=kn(c):(c=Ys(s)?io:js.current,c=fa(t,c));var f=s.getDerivedStateFromProps;(h=typeof f=="function"||typeof a.getSnapshotBeforeUpdate=="function")||typeof a.UNSAFE_componentWillReceiveProps!="function"&&typeof a.componentWillReceiveProps!="function"||(l!==d||p!==c)&&Tv(t,a,n,c),er=!1,p=t.memoizedState,a.state=p,fh(t,n,a,i);var m=t.memoizedState;l!==d||p!==m||Vs.current||er?(typeof f=="function"&&(Np(t,s,f,n),m=t.memoizedState),(u=er||jv(t,s,u,n,p,m,c)||!1)?(h||typeof a.UNSAFE_componentWillUpdate!="function"&&typeof a.componentWillUpdate!="function"||(typeof a.componentWillUpdate=="function"&&a.componentWillUpdate(n,m,c),typeof a.UNSAFE_componentWillUpdate=="function"&&a.UNSAFE_componentWillUpdate(n,m,c)),typeof a.componentDidUpdate=="function"&&(t.flags|=4),typeof a.getSnapshotBeforeUpdate=="function"&&(t.flags|=1024)):(typeof a.componentDidUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),typeof a.getSnapshotBeforeUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),t.memoizedProps=n,t.memoizedState=m),a.props=n,a.state=m,a.context=c,n=u):(typeof a.componentDidUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),typeof a.getSnapshotBeforeUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),n=!1)}return Ap(e,t,s,n,r,i)}function Ap(e,t,s,n,i,r){zx(e,t);var a=(t.flags&128)!==0;if(!n&&!a)return i&&wv(t,s,!1),Pi(e,t,r);n=t.stateNode,L2.current=t;var l=a&&typeof s.getDerivedStateFromError!="function"?null:n.render();return t.flags|=1,e!==null&&a?(t.child=ma(t,e.child,null,r),t.child=ma(t,null,l,r)):Ps(e,t,l,r),t.memoizedState=n.state,i&&wv(t,s,!0),t.child}function Hx(e){var t=e.stateNode;t.pendingContext?bv(e,t.pendingContext,t.pendingContext!==t.context):t.context&&bv(e,t.context,!1),Dg(e,t.containerInfo)}function Ov(e,t,s,n,i){return pa(),Ng(i),t.flags|=256,Ps(e,t,s,n),t.child}var Mp={dehydrated:null,treeContext:null,retryLane:0};function Dp(e){return{baseLanes:e,cachePool:null,transitions:null}}function Ux(e,t,s){var n=t.pendingProps,i=Tt.current,r=!1,a=(t.flags&128)!==0,l;if((l=a)||(l=e!==null&&e.memoizedState===null?!1:(i&2)!==0),l?(r=!0,t.flags&=-129):(e===null||e.memoizedState!==null)&&(i|=1),pt(Tt,i&1),e===null)return Cp(t),e=t.memoizedState,e!==null&&(e=e.dehydrated,e!==null)?(t.mode&1?e.data==="$!"?t.lanes=8:t.lanes=1073741824:t.lanes=1,null):(a=n.children,e=n.fallback,r?(n=t.mode,r=t.child,a={mode:"hidden",children:a},!(n&1)&&r!==null?(r.childLanes=0,r.pendingProps=a):r=od(a,n,0,null),e=Xr(e,n,s,null),r.return=t,e.return=t,r.sibling=e,t.child=r,t.child.memoizedState=Dp(s),t.memoizedState=Mp,e):zg(t,a));if(i=e.memoizedState,i!==null&&(l=i.dehydrated,l!==null))return O2(e,t,a,n,l,i,s);if(r){r=n.fallback,a=t.mode,i=e.child,l=i.sibling;var c={mode:"hidden",children:n.children};return!(a&1)&&t.child!==i?(n=t.child,n.childLanes=0,n.pendingProps=c,t.deletions=null):(n=yr(i,c),n.subtreeFlags=i.subtreeFlags&14680064),l!==null?r=yr(l,r):(r=Xr(r,a,s,null),r.flags|=2),r.return=t,n.return=t,n.sibling=r,t.child=n,n=r,r=t.child,a=e.child.memoizedState,a=a===null?Dp(s):{baseLanes:a.baseLanes|s,cachePool:null,transitions:a.transitions},r.memoizedState=a,r.childLanes=e.childLanes&~s,t.memoizedState=Mp,n}return r=e.child,e=r.sibling,n=yr(r,{mode:"visible",children:n.children}),!(t.mode&1)&&(n.lanes=s),n.return=t,n.sibling=null,e!==null&&(s=t.deletions,s===null?(t.deletions=[e],t.flags|=16):s.push(e)),t.child=n,t.memoizedState=null,n}function zg(e,t){return t=od({mode:"visible",children:t},e.mode,0,null),t.return=e,e.child=t}function ru(e,t,s,n){return n!==null&&Ng(n),ma(t,e.child,null,s),e=zg(t,t.pendingProps.children),e.flags|=2,t.memoizedState=null,e}function O2(e,t,s,n,i,r,a){if(s)return t.flags&256?(t.flags&=-257,n=ef(Error(ie(422))),ru(e,t,a,n)):t.memoizedState!==null?(t.child=e.child,t.flags|=128,null):(r=n.fallback,i=t.mode,n=od({mode:"visible",children:n.children},i,0,null),r=Xr(r,i,a,null),r.flags|=2,n.return=t,r.return=t,n.sibling=r,t.child=n,t.mode&1&&ma(t,e.child,null,a),t.child.memoizedState=Dp(a),t.memoizedState=Mp,r);if(!(t.mode&1))return ru(e,t,a,null);if(i.data==="$!"){if(n=i.nextSibling&&i.nextSibling.dataset,n)var l=n.dgst;return n=l,r=Error(ie(419)),n=ef(r,n,void 0),ru(e,t,a,n)}if(l=(a&e.childLanes)!==0,qs||l){if(n=cs,n!==null){switch(a&-a){case 4:i=2;break;case 16:i=8;break;case 64: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:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:i=32;break;case 536870912:i=268435456;break;default:i=0}i=i&(n.suspendedLanes|a)?0:i,i!==0&&i!==r.retryLane&&(r.retryLane=i,Ii(e,i),zn(n,e,i,-1))}return Vg(),n=ef(Error(ie(421))),ru(e,t,a,n)}return i.data==="$?"?(t.flags|=128,t.child=e.child,t=J2.bind(null,e),i._reactRetry=t,null):(e=r.treeContext,on=mr(i.nextSibling),ln=t,wt=!0,On=null,e!==null&&(vn[yn++]=Ci,vn[yn++]=Ei,vn[yn++]=ro,Ci=e.id,Ei=e.overflow,ro=t),t=zg(t,n.children),t.flags|=4096,t)}function Bv(e,t,s){e.lanes|=t;var n=e.alternate;n!==null&&(n.lanes|=t),Ep(e.return,t,s)}function tf(e,t,s,n,i){var r=e.memoizedState;r===null?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:n,tail:s,tailMode:i}:(r.isBackwards=t,r.rendering=null,r.renderingStartTime=0,r.last=n,r.tail=s,r.tailMode=i)}function Wx(e,t,s){var n=t.pendingProps,i=n.revealOrder,r=n.tail;if(Ps(e,t,n.children,s),n=Tt.current,n&2)n=n&1|2,t.flags|=128;else{if(e!==null&&e.flags&128)e:for(e=t.child;e!==null;){if(e.tag===13)e.memoizedState!==null&&Bv(e,s,t);else if(e.tag===19)Bv(e,s,t);else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;e.sibling===null;){if(e.return===null||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}n&=1}if(pt(Tt,n),!(t.mode&1))t.memoizedState=null;else switch(i){case"forwards":for(s=t.child,i=null;s!==null;)e=s.alternate,e!==null&&ph(e)===null&&(i=s),s=s.sibling;s=i,s===null?(i=t.child,t.child=null):(i=s.sibling,s.sibling=null),tf(t,!1,i,s,r);break;case"backwards":for(s=null,i=t.child,t.child=null;i!==null;){if(e=i.alternate,e!==null&&ph(e)===null){t.child=i;break}e=i.sibling,i.sibling=s,s=i,i=e}tf(t,!0,s,null,r);break;case"together":tf(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function $u(e,t){!(t.mode&1)&&e!==null&&(e.alternate=null,t.alternate=null,t.flags|=2)}function Pi(e,t,s){if(e!==null&&(t.dependencies=e.dependencies),ao|=t.lanes,!(s&t.childLanes))return null;if(e!==null&&t.child!==e.child)throw Error(ie(153));if(t.child!==null){for(e=t.child,s=yr(e,e.pendingProps),t.child=s,s.return=t;e.sibling!==null;)e=e.sibling,s=s.sibling=yr(e,e.pendingProps),s.return=t;s.sibling=null}return t.child}function B2(e,t,s){switch(t.tag){case 3:Hx(t),pa();break;case 5:gx(t);break;case 1:Ys(t.type)&&lh(t);break;case 4:Dg(t,t.stateNode.containerInfo);break;case 10:var n=t.type._context,i=t.memoizedProps.value;pt(hh,n._currentValue),n._currentValue=i;break;case 13:if(n=t.memoizedState,n!==null)return n.dehydrated!==null?(pt(Tt,Tt.current&1),t.flags|=128,null):s&t.child.childLanes?Ux(e,t,s):(pt(Tt,Tt.current&1),e=Pi(e,t,s),e!==null?e.sibling:null);pt(Tt,Tt.current&1);break;case 19:if(n=(s&t.childLanes)!==0,e.flags&128){if(n)return Wx(e,t,s);t.flags|=128}if(i=t.memoizedState,i!==null&&(i.rendering=null,i.tail=null,i.lastEffect=null),pt(Tt,Tt.current),n)break;return null;case 22:case 23:return t.lanes=0,Fx(e,t,s)}return Pi(e,t,s)}var Kx,Ip,qx,Vx;Kx=function(e,t){for(var s=t.child;s!==null;){if(s.tag===5||s.tag===6)e.appendChild(s.stateNode);else if(s.tag!==4&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break;for(;s.sibling===null;){if(s.return===null||s.return===t)return;s=s.return}s.sibling.return=s.return,s=s.sibling}};Ip=function(){};qx=function(e,t,s,n){var i=e.memoizedProps;if(i!==n){e=t.stateNode,Vr(ai.current);var r=null;switch(s){case"input":i=sp(e,i),n=sp(e,n),r=[];break;case"select":i=Mt({},i,{value:void 0}),n=Mt({},n,{value:void 0}),r=[];break;case"textarea":i=rp(e,i),n=rp(e,n),r=[];break;default:typeof i.onClick!="function"&&typeof n.onClick=="function"&&(e.onclick=oh)}ap(s,n);var a;s=null;for(u in i)if(!n.hasOwnProperty(u)&&i.hasOwnProperty(u)&&i[u]!=null)if(u==="style"){var l=i[u];for(a in l)l.hasOwnProperty(a)&&(s||(s={}),s[a]="")}else u!=="dangerouslySetInnerHTML"&&u!=="children"&&u!=="suppressContentEditableWarning"&&u!=="suppressHydrationWarning"&&u!=="autoFocus"&&(ql.hasOwnProperty(u)?r||(r=[]):(r=r||[]).push(u,null));for(u in n){var c=n[u];if(l=i?.[u],n.hasOwnProperty(u)&&c!==l&&(c!=null||l!=null))if(u==="style")if(l){for(a in l)!l.hasOwnProperty(a)||c&&c.hasOwnProperty(a)||(s||(s={}),s[a]="");for(a in c)c.hasOwnProperty(a)&&l[a]!==c[a]&&(s||(s={}),s[a]=c[a])}else s||(r||(r=[]),r.push(u,s)),s=c;else u==="dangerouslySetInnerHTML"?(c=c?c.__html:void 0,l=l?l.__html:void 0,c!=null&&l!==c&&(r=r||[]).push(u,c)):u==="children"?typeof c!="string"&&typeof c!="number"||(r=r||[]).push(u,""+c):u!=="suppressContentEditableWarning"&&u!=="suppressHydrationWarning"&&(ql.hasOwnProperty(u)?(c!=null&&u==="onScroll"&&vt("scroll",e),r||l===c||(r=[])):(r=r||[]).push(u,c))}s&&(r=r||[]).push("style",s);var u=r;(t.updateQueue=u)&&(t.flags|=4)}};Vx=function(e,t,s,n){s!==n&&(t.flags|=4)};function Ja(e,t){if(!wt)switch(e.tailMode){case"hidden":t=e.tail;for(var s=null;t!==null;)t.alternate!==null&&(s=t),t=t.sibling;s===null?e.tail=null:s.sibling=null;break;case"collapsed":s=e.tail;for(var n=null;s!==null;)s.alternate!==null&&(n=s),s=s.sibling;n===null?t||e.tail===null?e.tail=null:e.tail.sibling=null:n.sibling=null}}function Cs(e){var t=e.alternate!==null&&e.alternate.child===e.child,s=0,n=0;if(t)for(var i=e.child;i!==null;)s|=i.lanes|i.childLanes,n|=i.subtreeFlags&14680064,n|=i.flags&14680064,i.return=e,i=i.sibling;else for(i=e.child;i!==null;)s|=i.lanes|i.childLanes,n|=i.subtreeFlags,n|=i.flags,i.return=e,i=i.sibling;return e.subtreeFlags|=n,e.childLanes=s,t}function $2(e,t,s){var n=t.pendingProps;switch(Eg(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Cs(t),null;case 1:return Ys(t.type)&&ah(),Cs(t),null;case 3:return n=t.stateNode,ga(),bt(Vs),bt(js),Pg(),n.pendingContext&&(n.context=n.pendingContext,n.pendingContext=null),(e===null||e.child===null)&&(nu(t)?t.flags|=4:e===null||e.memoizedState.isDehydrated&&!(t.flags&256)||(t.flags|=1024,On!==null&&(Hp(On),On=null))),Ip(e,t),Cs(t),null;case 5:Ig(t);var i=Vr(ic.current);if(s=t.type,e!==null&&t.stateNode!=null)qx(e,t,s,n,i),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!n){if(t.stateNode===null)throw Error(ie(166));return Cs(t),null}if(e=Vr(ai.current),nu(t)){n=t.stateNode,s=t.type;var r=t.memoizedProps;switch(n[ti]=t,n[sc]=r,e=(t.mode&1)!==0,s){case"dialog":vt("cancel",n),vt("close",n);break;case"iframe":case"object":case"embed":vt("load",n);break;case"video":case"audio":for(i=0;i<Sl.length;i++)vt(Sl[i],n);break;case"source":vt("error",n);break;case"img":case"image":case"link":vt("error",n),vt("load",n);break;case"details":vt("toggle",n);break;case"input":V_(n,r),vt("invalid",n);break;case"select":n._wrapperState={wasMultiple:!!r.multiple},vt("invalid",n);break;case"textarea":G_(n,r),vt("invalid",n)}ap(s,r),i=null;for(var a in r)if(r.hasOwnProperty(a)){var l=r[a];a==="children"?typeof l=="string"?n.textContent!==l&&(r.suppressHydrationWarning!==!0&&su(n.textContent,l,e),i=["children",l]):typeof l=="number"&&n.textContent!==""+l&&(r.suppressHydrationWarning!==!0&&su(n.textContent,l,e),i=["children",""+l]):ql.hasOwnProperty(a)&&l!=null&&a==="onScroll"&&vt("scroll",n)}switch(s){case"input":Yc(n),Y_(n,r,!0);break;case"textarea":Yc(n),J_(n);break;case"select":case"option":break;default:typeof r.onClick=="function"&&(n.onclick=oh)}n=i,t.updateQueue=n,n!==null&&(t.flags|=4)}else{a=i.nodeType===9?i:i.ownerDocument,e==="http://www.w3.org/1999/xhtml"&&(e=ww(s)),e==="http://www.w3.org/1999/xhtml"?s==="script"?(e=a.createElement("div"),e.innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):typeof n.is=="string"?e=a.createElement(s,{is:n.is}):(e=a.createElement(s),s==="select"&&(a=e,n.multiple?a.multiple=!0:n.size&&(a.size=n.size))):e=a.createElementNS(e,s),e[ti]=t,e[sc]=n,Kx(e,t,!1,!1),t.stateNode=e;e:{switch(a=lp(s,n),s){case"dialog":vt("cancel",e),vt("close",e),i=n;break;case"iframe":case"object":case"embed":vt("load",e),i=n;break;case"video":case"audio":for(i=0;i<Sl.length;i++)vt(Sl[i],e);i=n;break;case"source":vt("error",e),i=n;break;case"img":case"image":case"link":vt("error",e),vt("load",e),i=n;break;case"details":vt("toggle",e),i=n;break;case"input":V_(e,n),i=sp(e,n),vt("invalid",e);break;case"option":i=n;break;case"select":e._wrapperState={wasMultiple:!!n.multiple},i=Mt({},n,{value:void 0}),vt("invalid",e);break;case"textarea":G_(e,n),i=rp(e,n),vt("invalid",e);break;default:i=n}ap(s,i),l=i;for(r in l)if(l.hasOwnProperty(r)){var c=l[r];r==="style"?kw(e,c):r==="dangerouslySetInnerHTML"?(c=c?c.__html:void 0,c!=null&&xw(e,c)):r==="children"?typeof c=="string"?(s!=="textarea"||c!=="")&&Vl(e,c):typeof c=="number"&&Vl(e,""+c):r!=="suppressContentEditableWarning"&&r!=="suppressHydrationWarning"&&r!=="autoFocus"&&(ql.hasOwnProperty(r)?c!=null&&r==="onScroll"&&vt("scroll",e):c!=null&&hg(e,r,c,a))}switch(s){case"input":Yc(e),Y_(e,n,!1);break;case"textarea":Yc(e),J_(e);break;case"option":n.value!=null&&e.setAttribute("value",""+wr(n.value));break;case"select":e.multiple=!!n.multiple,r=n.value,r!=null?na(e,!!n.multiple,r,!1):n.defaultValue!=null&&na(e,!!n.multiple,n.defaultValue,!0);break;default:typeof i.onClick=="function"&&(e.onclick=oh)}switch(s){case"button":case"input":case"select":case"textarea":n=!!n.autoFocus;break e;case"img":n=!0;break e;default:n=!1}}n&&(t.flags|=4)}t.ref!==null&&(t.flags|=512,t.flags|=2097152)}return Cs(t),null;case 6:if(e&&t.stateNode!=null)Vx(e,t,e.memoizedProps,n);else{if(typeof n!="string"&&t.stateNode===null)throw Error(ie(166));if(s=Vr(ic.current),Vr(ai.current),nu(t)){if(n=t.stateNode,s=t.memoizedProps,n[ti]=t,(r=n.nodeValue!==s)&&(e=ln,e!==null))switch(e.tag){case 3:su(n.nodeValue,s,(e.mode&1)!==0);break;case 5:e.memoizedProps.suppressHydrationWarning!==!0&&su(n.nodeValue,s,(e.mode&1)!==0)}r&&(t.flags|=4)}else n=(s.nodeType===9?s:s.ownerDocument).createTextNode(n),n[ti]=t,t.stateNode=n}return Cs(t),null;case 13:if(bt(Tt),n=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(wt&&on!==null&&t.mode&1&&!(t.flags&128))hx(),pa(),t.flags|=98560,r=!1;else if(r=nu(t),n!==null&&n.dehydrated!==null){if(e===null){if(!r)throw Error(ie(318));if(r=t.memoizedState,r=r!==null?r.dehydrated:null,!r)throw Error(ie(317));r[ti]=t}else pa(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Cs(t),r=!1}else On!==null&&(Hp(On),On=null),r=!0;if(!r)return t.flags&65536?t:null}return t.flags&128?(t.lanes=s,t):(n=n!==null,n!==(e!==null&&e.memoizedState!==null)&&n&&(t.child.flags|=8192,t.mode&1&&(e===null||Tt.current&1?es===0&&(es=3):Vg())),t.updateQueue!==null&&(t.flags|=4),Cs(t),null);case 4:return ga(),Ip(e,t),e===null&&ec(t.stateNode.containerInfo),Cs(t),null;case 10:return Tg(t.type._context),Cs(t),null;case 17:return Ys(t.type)&&ah(),Cs(t),null;case 19:if(bt(Tt),r=t.memoizedState,r===null)return Cs(t),null;if(n=(t.flags&128)!==0,a=r.rendering,a===null)if(n)Ja(r,!1);else{if(es!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(a=ph(e),a!==null){for(t.flags|=128,Ja(r,!1),n=a.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),t.subtreeFlags=0,n=s,s=t.child;s!==null;)r=s,e=n,r.flags&=14680066,a=r.alternate,a===null?(r.childLanes=0,r.lanes=e,r.child=null,r.subtreeFlags=0,r.memoizedProps=null,r.memoizedState=null,r.updateQueue=null,r.dependencies=null,r.stateNode=null):(r.childLanes=a.childLanes,r.lanes=a.lanes,r.child=a.child,r.subtreeFlags=0,r.deletions=null,r.memoizedProps=a.memoizedProps,r.memoizedState=a.memoizedState,r.updateQueue=a.updateQueue,r.type=a.type,e=a.dependencies,r.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext}),s=s.sibling;return pt(Tt,Tt.current&1|2),t.child}e=e.sibling}r.tail!==null&&zt()>va&&(t.flags|=128,n=!0,Ja(r,!1),t.lanes=4194304)}else{if(!n)if(e=ph(a),e!==null){if(t.flags|=128,n=!0,s=e.updateQueue,s!==null&&(t.updateQueue=s,t.flags|=4),Ja(r,!0),r.tail===null&&r.tailMode==="hidden"&&!a.alternate&&!wt)return Cs(t),null}else 2*zt()-r.renderingStartTime>va&&s!==1073741824&&(t.flags|=128,n=!0,Ja(r,!1),t.lanes=4194304);r.isBackwards?(a.sibling=t.child,t.child=a):(s=r.last,s!==null?s.sibling=a:t.child=a,r.last=a)}return r.tail!==null?(t=r.tail,r.rendering=t,r.tail=t.sibling,r.renderingStartTime=zt(),t.sibling=null,s=Tt.current,pt(Tt,n?s&1|2:s&1),t):(Cs(t),null);case 22:case 23:return qg(),n=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==n&&(t.flags|=8192),n&&t.mode&1?sn&1073741824&&(Cs(t),t.subtreeFlags&6&&(t.flags|=8192)):Cs(t),null;case 24:return null;case 25:return null}throw Error(ie(156,t.tag))}function F2(e,t){switch(Eg(t),t.tag){case 1:return Ys(t.type)&&ah(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return ga(),bt(Vs),bt(js),Pg(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return Ig(t),null;case 13:if(bt(Tt),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(ie(340));pa()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return bt(Tt),null;case 4:return ga(),null;case 10:return Tg(t.type._context),null;case 22:case 23:return qg(),null;case 24:return null;default:return null}}var ou=!1,Rs=!1,z2=typeof WeakSet=="function"?WeakSet:Set,we=null;function Qo(e,t){var s=e.ref;if(s!==null)if(typeof s=="function")try{s(null)}catch(n){Pt(e,t,n)}else s.current=null}function Pp(e,t,s){try{s()}catch(n){Pt(e,t,n)}}var $v=!1;function H2(e,t){if(vp=nh,e=Zw(),kg(e)){if("selectionStart"in e)var s={start:e.selectionStart,end:e.selectionEnd};else e:{s=(s=e.ownerDocument)&&s.defaultView||window;var n=s.getSelection&&s.getSelection();if(n&&n.rangeCount!==0){s=n.anchorNode;var i=n.anchorOffset,r=n.focusNode;n=n.focusOffset;try{s.nodeType,r.nodeType}catch{s=null;break e}var a=0,l=-1,c=-1,u=0,h=0,d=e,p=null;t:for(;;){for(var f;d!==s||i!==0&&d.nodeType!==3||(l=a+i),d!==r||n!==0&&d.nodeType!==3||(c=a+n),d.nodeType===3&&(a+=d.nodeValue.length),(f=d.firstChild)!==null;)p=d,d=f;for(;;){if(d===e)break t;if(p===s&&++u===i&&(l=a),p===r&&++h===n&&(c=a),(f=d.nextSibling)!==null)break;d=p,p=d.parentNode}d=f}s=l===-1||c===-1?null:{start:l,end:c}}else s=null}s=s||{start:0,end:0}}else s=null;for(yp={focusedElem:e,selectionRange:s},nh=!1,we=t;we!==null;)if(t=we,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,we=e;else for(;we!==null;){t=we;try{var m=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(m!==null){var b=m.memoizedProps,_=m.memoizedState,v=t.stateNode,y=v.getSnapshotBeforeUpdate(t.elementType===t.type?b:Pn(t.type,b),_);v.__reactInternalSnapshotBeforeUpdate=y}break;case 3:var w=t.stateNode.containerInfo;w.nodeType===1?w.textContent="":w.nodeType===9&&w.documentElement&&w.removeChild(w.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(ie(163))}}catch(x){Pt(t,t.return,x)}if(e=t.sibling,e!==null){e.return=t.return,we=e;break}we=t.return}return m=$v,$v=!1,m}function Ol(e,t,s){var n=t.updateQueue;if(n=n!==null?n.lastEffect:null,n!==null){var i=n=n.next;do{if((i.tag&e)===e){var r=i.destroy;i.destroy=void 0,r!==void 0&&Pp(t,s,r)}i=i.next}while(i!==n)}}function id(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var s=t=t.next;do{if((s.tag&e)===e){var n=s.create;s.destroy=n()}s=s.next}while(s!==t)}}function Lp(e){var t=e.ref;if(t!==null){var s=e.stateNode;switch(e.tag){case 5:e=s;break;default:e=s}typeof t=="function"?t(e):t.current=e}}function Yx(e){var t=e.alternate;t!==null&&(e.alternate=null,Yx(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[ti],delete t[sc],delete t[xp],delete t[k2],delete t[C2])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Gx(e){return e.tag===5||e.tag===3||e.tag===4}function Fv(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Gx(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Op(e,t,s){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?s.nodeType===8?s.parentNode.insertBefore(e,t):s.insertBefore(e,t):(s.nodeType===8?(t=s.parentNode,t.insertBefore(e,s)):(t=s,t.appendChild(e)),s=s._reactRootContainer,s!=null||t.onclick!==null||(t.onclick=oh));else if(n!==4&&(e=e.child,e!==null))for(Op(e,t,s),e=e.sibling;e!==null;)Op(e,t,s),e=e.sibling}function Bp(e,t,s){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?s.insertBefore(e,t):s.appendChild(e);else if(n!==4&&(e=e.child,e!==null))for(Bp(e,t,s),e=e.sibling;e!==null;)Bp(e,t,s),e=e.sibling}var gs=null,Ln=!1;function qi(e,t,s){for(s=s.child;s!==null;)Jx(e,t,s),s=s.sibling}function Jx(e,t,s){if(oi&&typeof oi.onCommitFiberUnmount=="function")try{oi.onCommitFiberUnmount(Jh,s)}catch{}switch(s.tag){case 5:Rs||Qo(s,t);case 6:var n=gs,i=Ln;gs=null,qi(e,t,s),gs=n,Ln=i,gs!==null&&(Ln?(e=gs,s=s.stateNode,e.nodeType===8?e.parentNode.removeChild(s):e.removeChild(s)):gs.removeChild(s.stateNode));break;case 18:gs!==null&&(Ln?(e=gs,s=s.stateNode,e.nodeType===8?Yd(e.parentNode,s):e.nodeType===1&&Yd(e,s),Xl(e)):Yd(gs,s.stateNode));break;case 4:n=gs,i=Ln,gs=s.stateNode.containerInfo,Ln=!0,qi(e,t,s),gs=n,Ln=i;break;case 0:case 11:case 14:case 15:if(!Rs&&(n=s.updateQueue,n!==null&&(n=n.lastEffect,n!==null))){i=n=n.next;do{var r=i,a=r.destroy;r=r.tag,a!==void 0&&(r&2||r&4)&&Pp(s,t,a),i=i.next}while(i!==n)}qi(e,t,s);break;case 1:if(!Rs&&(Qo(s,t),n=s.stateNode,typeof n.componentWillUnmount=="function"))try{n.props=s.memoizedProps,n.state=s.memoizedState,n.componentWillUnmount()}catch(l){Pt(s,t,l)}qi(e,t,s);break;case 21:qi(e,t,s);break;case 22:s.mode&1?(Rs=(n=Rs)||s.memoizedState!==null,qi(e,t,s),Rs=n):qi(e,t,s);break;default:qi(e,t,s)}}function zv(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var s=e.stateNode;s===null&&(s=e.stateNode=new z2),t.forEach(function(n){var i=X2.bind(null,e,n);s.has(n)||(s.add(n),n.then(i,i))})}}function Dn(e,t){var s=t.deletions;if(s!==null)for(var n=0;n<s.length;n++){var i=s[n];try{var r=e,a=t,l=a;e:for(;l!==null;){switch(l.tag){case 5:gs=l.stateNode,Ln=!1;break e;case 3:gs=l.stateNode.containerInfo,Ln=!0;break e;case 4:gs=l.stateNode.containerInfo,Ln=!0;break e}l=l.return}if(gs===null)throw Error(ie(160));Jx(r,a,i),gs=null,Ln=!1;var c=i.alternate;c!==null&&(c.return=null),i.return=null}catch(u){Pt(i,t,u)}}if(t.subtreeFlags&12854)for(t=t.child;t!==null;)Xx(t,e),t=t.sibling}function Xx(e,t){var s=e.alternate,n=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(Dn(t,e),Jn(e),n&4){try{Ol(3,e,e.return),id(3,e)}catch(b){Pt(e,e.return,b)}try{Ol(5,e,e.return)}catch(b){Pt(e,e.return,b)}}break;case 1:Dn(t,e),Jn(e),n&512&&s!==null&&Qo(s,s.return);break;case 5:if(Dn(t,e),Jn(e),n&512&&s!==null&&Qo(s,s.return),e.flags&32){var i=e.stateNode;try{Vl(i,"")}catch(b){Pt(e,e.return,b)}}if(n&4&&(i=e.stateNode,i!=null)){var r=e.memoizedProps,a=s!==null?s.memoizedProps:r,l=e.type,c=e.updateQueue;if(e.updateQueue=null,c!==null)try{l==="input"&&r.type==="radio"&&r.name!=null&&yw(i,r),lp(l,a);var u=lp(l,r);for(a=0;a<c.length;a+=2){var h=c[a],d=c[a+1];h==="style"?kw(i,d):h==="dangerouslySetInnerHTML"?xw(i,d):h==="children"?Vl(i,d):hg(i,h,d,u)}switch(l){case"input":np(i,r);break;case"textarea":bw(i,r);break;case"select":var p=i._wrapperState.wasMultiple;i._wrapperState.wasMultiple=!!r.multiple;var f=r.value;f!=null?na(i,!!r.multiple,f,!1):p!==!!r.multiple&&(r.defaultValue!=null?na(i,!!r.multiple,r.defaultValue,!0):na(i,!!r.multiple,r.multiple?[]:"",!1))}i[sc]=r}catch(b){Pt(e,e.return,b)}}break;case 6:if(Dn(t,e),Jn(e),n&4){if(e.stateNode===null)throw Error(ie(162));i=e.stateNode,r=e.memoizedProps;try{i.nodeValue=r}catch(b){Pt(e,e.return,b)}}break;case 3:if(Dn(t,e),Jn(e),n&4&&s!==null&&s.memoizedState.isDehydrated)try{Xl(t.containerInfo)}catch(b){Pt(e,e.return,b)}break;case 4:Dn(t,e),Jn(e);break;case 13:Dn(t,e),Jn(e),i=e.child,i.flags&8192&&(r=i.memoizedState!==null,i.stateNode.isHidden=r,!r||i.alternate!==null&&i.alternate.memoizedState!==null||(Wg=zt())),n&4&&zv(e);break;case 22:if(h=s!==null&&s.memoizedState!==null,e.mode&1?(Rs=(u=Rs)||h,Dn(t,e),Rs=u):Dn(t,e),Jn(e),n&8192){if(u=e.memoizedState!==null,(e.stateNode.isHidden=u)&&!h&&e.mode&1)for(we=e,h=e.child;h!==null;){for(d=we=h;we!==null;){switch(p=we,f=p.child,p.tag){case 0:case 11:case 14:case 15:Ol(4,p,p.return);break;case 1:Qo(p,p.return);var m=p.stateNode;if(typeof m.componentWillUnmount=="function"){n=p,s=p.return;try{t=n,m.props=t.memoizedProps,m.state=t.memoizedState,m.componentWillUnmount()}catch(b){Pt(n,s,b)}}break;case 5:Qo(p,p.return);break;case 22:if(p.memoizedState!==null){Uv(d);continue}}f!==null?(f.return=p,we=f):Uv(d)}h=h.sibling}e:for(h=null,d=e;;){if(d.tag===5){if(h===null){h=d;try{i=d.stateNode,u?(r=i.style,typeof r.setProperty=="function"?r.setProperty("display","none","important"):r.display="none"):(l=d.stateNode,c=d.memoizedProps.style,a=c!=null&&c.hasOwnProperty("display")?c.display:null,l.style.display=Sw("display",a))}catch(b){Pt(e,e.return,b)}}}else if(d.tag===6){if(h===null)try{d.stateNode.nodeValue=u?"":d.memoizedProps}catch(b){Pt(e,e.return,b)}}else if((d.tag!==22&&d.tag!==23||d.memoizedState===null||d===e)&&d.child!==null){d.child.return=d,d=d.child;continue}if(d===e)break e;for(;d.sibling===null;){if(d.return===null||d.return===e)break e;h===d&&(h=null),d=d.return}h===d&&(h=null),d.sibling.return=d.return,d=d.sibling}}break;case 19:Dn(t,e),Jn(e),n&4&&zv(e);break;case 21:break;default:Dn(t,e),Jn(e)}}function Jn(e){var t=e.flags;if(t&2){try{e:{for(var s=e.return;s!==null;){if(Gx(s)){var n=s;break e}s=s.return}throw Error(ie(160))}switch(n.tag){case 5:var i=n.stateNode;n.flags&32&&(Vl(i,""),n.flags&=-33);var r=Fv(e);Bp(e,r,i);break;case 3:case 4:var a=n.stateNode.containerInfo,l=Fv(e);Op(e,l,a);break;default:throw Error(ie(161))}}catch(c){Pt(e,e.return,c)}e.flags&=-3}t&4096&&(e.flags&=-4097)}function U2(e,t,s){we=e,Zx(e)}function Zx(e,t,s){for(var n=(e.mode&1)!==0;we!==null;){var i=we,r=i.child;if(i.tag===22&&n){var a=i.memoizedState!==null||ou;if(!a){var l=i.alternate,c=l!==null&&l.memoizedState!==null||Rs;l=ou;var u=Rs;if(ou=a,(Rs=c)&&!u)for(we=i;we!==null;)a=we,c=a.child,a.tag===22&&a.memoizedState!==null?Wv(i):c!==null?(c.return=a,we=c):Wv(i);for(;r!==null;)we=r,Zx(r),r=r.sibling;we=i,ou=l,Rs=u}Hv(e)}else i.subtreeFlags&8772&&r!==null?(r.return=i,we=r):Hv(e)}}function Hv(e){for(;we!==null;){var t=we;if(t.flags&8772){var s=t.alternate;try{if(t.flags&8772)switch(t.tag){case 0:case 11:case 15:Rs||id(5,t);break;case 1:var n=t.stateNode;if(t.flags&4&&!Rs)if(s===null)n.componentDidMount();else{var i=t.elementType===t.type?s.memoizedProps:Pn(t.type,s.memoizedProps);n.componentDidUpdate(i,s.memoizedState,n.__reactInternalSnapshotBeforeUpdate)}var r=t.updateQueue;r!==null&&Ev(t,r,n);break;case 3:var a=t.updateQueue;if(a!==null){if(s=null,t.child!==null)switch(t.child.tag){case 5:s=t.child.stateNode;break;case 1:s=t.child.stateNode}Ev(t,a,s)}break;case 5:var l=t.stateNode;if(s===null&&t.flags&4){s=l;var c=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":c.autoFocus&&s.focus();break;case"img":c.src&&(s.src=c.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(t.memoizedState===null){var u=t.alternate;if(u!==null){var h=u.memoizedState;if(h!==null){var d=h.dehydrated;d!==null&&Xl(d)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;default:throw Error(ie(163))}Rs||t.flags&512&&Lp(t)}catch(p){Pt(t,t.return,p)}}if(t===e){we=null;break}if(s=t.sibling,s!==null){s.return=t.return,we=s;break}we=t.return}}function Uv(e){for(;we!==null;){var t=we;if(t===e){we=null;break}var s=t.sibling;if(s!==null){s.return=t.return,we=s;break}we=t.return}}function Wv(e){for(;we!==null;){var t=we;try{switch(t.tag){case 0:case 11:case 15:var s=t.return;try{id(4,t)}catch(c){Pt(t,s,c)}break;case 1:var n=t.stateNode;if(typeof n.componentDidMount=="function"){var i=t.return;try{n.componentDidMount()}catch(c){Pt(t,i,c)}}var r=t.return;try{Lp(t)}catch(c){Pt(t,r,c)}break;case 5:var a=t.return;try{Lp(t)}catch(c){Pt(t,a,c)}}}catch(c){Pt(t,t.return,c)}if(t===e){we=null;break}var l=t.sibling;if(l!==null){l.return=t.return,we=l;break}we=t.return}}var W2=Math.ceil,_h=Li.ReactCurrentDispatcher,Hg=Li.ReactCurrentOwner,xn=Li.ReactCurrentBatchConfig,it=0,cs=null,Yt=null,ys=0,sn=0,ea=Er(0),es=0,lc=null,ao=0,rd=0,Ug=0,Bl=null,Ws=null,Wg=0,va=1/0,wi=null,vh=!1,$p=null,_r=null,au=!1,lr=null,yh=0,$l=0,Fp=null,Fu=-1,zu=0;function Ls(){return it&6?zt():Fu!==-1?Fu:Fu=zt()}function vr(e){return e.mode&1?it&2&&ys!==0?ys&-ys:N2.transition!==null?(zu===0&&(zu=Lw()),zu):(e=ct,e!==0||(e=window.event,e=e===void 0?16:Uw(e.type)),e):1}function zn(e,t,s,n){if(50<$l)throw $l=0,Fp=null,Error(ie(185));Ec(e,s,n),(!(it&2)||e!==cs)&&(e===cs&&(!(it&2)&&(rd|=s),es===4&&rr(e,ys)),Gs(e,n),s===1&&it===0&&!(t.mode&1)&&(va=zt()+500,td&&Nr()))}function Gs(e,t){var s=e.callbackNode;NE(e,t);var n=sh(e,e===cs?ys:0);if(n===0)s!==null&&Q_(s),e.callbackNode=null,e.callbackPriority=0;else if(t=n&-n,e.callbackPriority!==t){if(s!=null&&Q_(s),t===1)e.tag===0?E2(Kv.bind(null,e)):lx(Kv.bind(null,e)),x2(function(){!(it&6)&&Nr()}),s=null;else{switch(Ow(n)){case 1:s=gg;break;case 4:s=Iw;break;case 16:s=th;break;case 536870912:s=Pw;break;default:s=th}s=oS(s,Qx.bind(null,e))}e.callbackPriority=t,e.callbackNode=s}}function Qx(e,t){if(Fu=-1,zu=0,it&6)throw Error(ie(327));var s=e.callbackNode;if(la()&&e.callbackNode!==s)return null;var n=sh(e,e===cs?ys:0);if(n===0)return null;if(n&30||n&e.expiredLanes||t)t=bh(e,n);else{t=n;var i=it;it|=2;var r=tS();(cs!==e||ys!==t)&&(wi=null,va=zt()+500,Jr(e,t));do try{V2();break}catch(l){eS(e,l)}while(!0);jg(),_h.current=r,it=i,Yt!==null?t=0:(cs=null,ys=0,t=es)}if(t!==0){if(t===2&&(i=fp(e),i!==0&&(n=i,t=zp(e,i))),t===1)throw s=lc,Jr(e,0),rr(e,n),Gs(e,zt()),s;if(t===6)rr(e,n);else{if(i=e.current.alternate,!(n&30)&&!K2(i)&&(t=bh(e,n),t===2&&(r=fp(e),r!==0&&(n=r,t=zp(e,r))),t===1))throw s=lc,Jr(e,0),rr(e,n),Gs(e,zt()),s;switch(e.finishedWork=i,e.finishedLanes=n,t){case 0:case 1:throw Error(ie(345));case 2:zr(e,Ws,wi);break;case 3:if(rr(e,n),(n&130023424)===n&&(t=Wg+500-zt(),10<t)){if(sh(e,0)!==0)break;if(i=e.suspendedLanes,(i&n)!==n){Ls(),e.pingedLanes|=e.suspendedLanes&i;break}e.timeoutHandle=wp(zr.bind(null,e,Ws,wi),t);break}zr(e,Ws,wi);break;case 4:if(rr(e,n),(n&4194240)===n)break;for(t=e.eventTimes,i=-1;0<n;){var a=31-Fn(n);r=1<<a,a=t[a],a>i&&(i=a),n&=~r}if(n=i,n=zt()-n,n=(120>n?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*W2(n/1960))-n,10<n){e.timeoutHandle=wp(zr.bind(null,e,Ws,wi),n);break}zr(e,Ws,wi);break;case 5:zr(e,Ws,wi);break;default:throw Error(ie(329))}}}return Gs(e,zt()),e.callbackNode===s?Qx.bind(null,e):null}function zp(e,t){var s=Bl;return e.current.memoizedState.isDehydrated&&(Jr(e,t).flags|=256),e=bh(e,t),e!==2&&(t=Ws,Ws=s,t!==null&&Hp(t)),e}function Hp(e){Ws===null?Ws=e:Ws.push.apply(Ws,e)}function K2(e){for(var t=e;;){if(t.flags&16384){var s=t.updateQueue;if(s!==null&&(s=s.stores,s!==null))for(var n=0;n<s.length;n++){var i=s[n],r=i.getSnapshot;i=i.value;try{if(!Un(r(),i))return!1}catch{return!1}}}if(s=t.child,t.subtreeFlags&16384&&s!==null)s.return=t,t=s;else{if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}function rr(e,t){for(t&=~Ug,t&=~rd,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var s=31-Fn(t),n=1<<s;e[s]=-1,t&=~n}}function Kv(e){if(it&6)throw Error(ie(327));la();var t=sh(e,0);if(!(t&1))return Gs(e,zt()),null;var s=bh(e,t);if(e.tag!==0&&s===2){var n=fp(e);n!==0&&(t=n,s=zp(e,n))}if(s===1)throw s=lc,Jr(e,0),rr(e,t),Gs(e,zt()),s;if(s===6)throw Error(ie(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,zr(e,Ws,wi),Gs(e,zt()),null}function Kg(e,t){var s=it;it|=1;try{return e(t)}finally{it=s,it===0&&(va=zt()+500,td&&Nr())}}function lo(e){lr!==null&&lr.tag===0&&!(it&6)&&la();var t=it;it|=1;var s=xn.transition,n=ct;try{if(xn.transition=null,ct=1,e)return e()}finally{ct=n,xn.transition=s,it=t,!(it&6)&&Nr()}}function qg(){sn=ea.current,bt(ea)}function Jr(e,t){e.finishedWork=null,e.finishedLanes=0;var s=e.timeoutHandle;if(s!==-1&&(e.timeoutHandle=-1,w2(s)),Yt!==null)for(s=Yt.return;s!==null;){var n=s;switch(Eg(n),n.tag){case 1:n=n.type.childContextTypes,n!=null&&ah();break;case 3:ga(),bt(Vs),bt(js),Pg();break;case 5:Ig(n);break;case 4:ga();break;case 13:bt(Tt);break;case 19:bt(Tt);break;case 10:Tg(n.type._context);break;case 22:case 23:qg()}s=s.return}if(cs=e,Yt=e=yr(e.current,null),ys=sn=t,es=0,lc=null,Ug=rd=ao=0,Ws=Bl=null,qr!==null){for(t=0;t<qr.length;t++)if(s=qr[t],n=s.interleaved,n!==null){s.interleaved=null;var i=n.next,r=s.pending;if(r!==null){var a=r.next;r.next=i,n.next=a}s.pending=n}qr=null}return e}function eS(e,t){do{var s=Yt;try{if(jg(),Ou.current=gh,mh){for(var n=At.memoizedState;n!==null;){var i=n.queue;i!==null&&(i.pending=null),n=n.next}mh=!1}if(oo=0,rs=Qt=At=null,Ll=!1,rc=0,Hg.current=null,s===null||s.return===null){es=1,lc=t,Yt=null;break}e:{var r=e,a=s.return,l=s,c=t;if(t=ys,l.flags|=32768,c!==null&&typeof c=="object"&&typeof c.then=="function"){var u=c,h=l,d=h.tag;if(!(h.mode&1)&&(d===0||d===11||d===15)){var p=h.alternate;p?(h.updateQueue=p.updateQueue,h.memoizedState=p.memoizedState,h.lanes=p.lanes):(h.updateQueue=null,h.memoizedState=null)}var f=Mv(a);if(f!==null){f.flags&=-257,Dv(f,a,l,r,t),f.mode&1&&Av(r,u,t),t=f,c=u;var m=t.updateQueue;if(m===null){var b=new Set;b.add(c),t.updateQueue=b}else m.add(c);break e}else{if(!(t&1)){Av(r,u,t),Vg();break e}c=Error(ie(426))}}else if(wt&&l.mode&1){var _=Mv(a);if(_!==null){!(_.flags&65536)&&(_.flags|=256),Dv(_,a,l,r,t),Ng(_a(c,l));break e}}r=c=_a(c,l),es!==4&&(es=2),Bl===null?Bl=[r]:Bl.push(r),r=a;do{switch(r.tag){case 3:r.flags|=65536,t&=-t,r.lanes|=t;var v=Ox(r,c,t);Cv(r,v);break e;case 1:l=c;var y=r.type,w=r.stateNode;if(!(r.flags&128)&&(typeof y.getDerivedStateFromError=="function"||w!==null&&typeof w.componentDidCatch=="function"&&(_r===null||!_r.has(w)))){r.flags|=65536,t&=-t,r.lanes|=t;var x=Bx(r,l,t);Cv(r,x);break e}}r=r.return}while(r!==null)}nS(s)}catch(S){t=S,Yt===s&&s!==null&&(Yt=s=s.return);continue}break}while(!0)}function tS(){var e=_h.current;return _h.current=gh,e===null?gh:e}function Vg(){(es===0||es===3||es===2)&&(es=4),cs===null||!(ao&268435455)&&!(rd&268435455)||rr(cs,ys)}function bh(e,t){var s=it;it|=2;var n=tS();(cs!==e||ys!==t)&&(wi=null,Jr(e,t));do try{q2();break}catch(i){eS(e,i)}while(!0);if(jg(),it=s,_h.current=n,Yt!==null)throw Error(ie(261));return cs=null,ys=0,es}function q2(){for(;Yt!==null;)sS(Yt)}function V2(){for(;Yt!==null&&!vE();)sS(Yt)}function sS(e){var t=rS(e.alternate,e,sn);e.memoizedProps=e.pendingProps,t===null?nS(e):Yt=t,Hg.current=null}function nS(e){var t=e;do{var s=t.alternate;if(e=t.return,t.flags&32768){if(s=F2(s,t),s!==null){s.flags&=32767,Yt=s;return}if(e!==null)e.flags|=32768,e.subtreeFlags=0,e.deletions=null;else{es=6,Yt=null;return}}else if(s=$2(s,t,sn),s!==null){Yt=s;return}if(t=t.sibling,t!==null){Yt=t;return}Yt=t=e}while(t!==null);es===0&&(es=5)}function zr(e,t,s){var n=ct,i=xn.transition;try{xn.transition=null,ct=1,Y2(e,t,s,n)}finally{xn.transition=i,ct=n}return null}function Y2(e,t,s,n){do la();while(lr!==null);if(it&6)throw Error(ie(327));s=e.finishedWork;var i=e.finishedLanes;if(s===null)return null;if(e.finishedWork=null,e.finishedLanes=0,s===e.current)throw Error(ie(177));e.callbackNode=null,e.callbackPriority=0;var r=s.lanes|s.childLanes;if(RE(e,r),e===cs&&(Yt=cs=null,ys=0),!(s.subtreeFlags&2064)&&!(s.flags&2064)||au||(au=!0,oS(th,function(){return la(),null})),r=(s.flags&15990)!==0,s.subtreeFlags&15990||r){r=xn.transition,xn.transition=null;var a=ct;ct=1;var l=it;it|=4,Hg.current=null,H2(e,s),Xx(s,e),p2(yp),nh=!!vp,yp=vp=null,e.current=s,U2(s),yE(),it=l,ct=a,xn.transition=r}else e.current=s;if(au&&(au=!1,lr=e,yh=i),r=e.pendingLanes,r===0&&(_r=null),xE(s.stateNode),Gs(e,zt()),t!==null)for(n=e.onRecoverableError,s=0;s<t.length;s++)i=t[s],n(i.value,{componentStack:i.stack,digest:i.digest});if(vh)throw vh=!1,e=$p,$p=null,e;return yh&1&&e.tag!==0&&la(),r=e.pendingLanes,r&1?e===Fp?$l++:($l=0,Fp=e):$l=0,Nr(),null}function la(){if(lr!==null){var e=Ow(yh),t=xn.transition,s=ct;try{if(xn.transition=null,ct=16>e?16:e,lr===null)var n=!1;else{if(e=lr,lr=null,yh=0,it&6)throw Error(ie(331));var i=it;for(it|=4,we=e.current;we!==null;){var r=we,a=r.child;if(we.flags&16){var l=r.deletions;if(l!==null){for(var c=0;c<l.length;c++){var u=l[c];for(we=u;we!==null;){var h=we;switch(h.tag){case 0:case 11:case 15:Ol(8,h,r)}var d=h.child;if(d!==null)d.return=h,we=d;else for(;we!==null;){h=we;var p=h.sibling,f=h.return;if(Yx(h),h===u){we=null;break}if(p!==null){p.return=f,we=p;break}we=f}}}var m=r.alternate;if(m!==null){var b=m.child;if(b!==null){m.child=null;do{var _=b.sibling;b.sibling=null,b=_}while(b!==null)}}we=r}}if(r.subtreeFlags&2064&&a!==null)a.return=r,we=a;else e:for(;we!==null;){if(r=we,r.flags&2048)switch(r.tag){case 0:case 11:case 15:Ol(9,r,r.return)}var v=r.sibling;if(v!==null){v.return=r.return,we=v;break e}we=r.return}}var y=e.current;for(we=y;we!==null;){a=we;var w=a.child;if(a.subtreeFlags&2064&&w!==null)w.return=a,we=w;else e:for(a=y;we!==null;){if(l=we,l.flags&2048)try{switch(l.tag){case 0:case 11:case 15:id(9,l)}}catch(S){Pt(l,l.return,S)}if(l===a){we=null;break e}var x=l.sibling;if(x!==null){x.return=l.return,we=x;break e}we=l.return}}if(it=i,Nr(),oi&&typeof oi.onPostCommitFiberRoot=="function")try{oi.onPostCommitFiberRoot(Jh,e)}catch{}n=!0}return n}finally{ct=s,xn.transition=t}}return!1}function qv(e,t,s){t=_a(s,t),t=Ox(e,t,1),e=gr(e,t,1),t=Ls(),e!==null&&(Ec(e,1,t),Gs(e,t))}function Pt(e,t,s){if(e.tag===3)qv(e,e,s);else for(;t!==null;){if(t.tag===3){qv(t,e,s);break}else if(t.tag===1){var n=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof n.componentDidCatch=="function"&&(_r===null||!_r.has(n))){e=_a(s,e),e=Bx(t,e,1),t=gr(t,e,1),e=Ls(),t!==null&&(Ec(t,1,e),Gs(t,e));break}}t=t.return}}function G2(e,t,s){var n=e.pingCache;n!==null&&n.delete(t),t=Ls(),e.pingedLanes|=e.suspendedLanes&s,cs===e&&(ys&s)===s&&(es===4||es===3&&(ys&130023424)===ys&&500>zt()-Wg?Jr(e,0):Ug|=s),Gs(e,t)}function iS(e,t){t===0&&(e.mode&1?(t=Xc,Xc<<=1,!(Xc&130023424)&&(Xc=4194304)):t=1);var s=Ls();e=Ii(e,t),e!==null&&(Ec(e,t,s),Gs(e,s))}function J2(e){var t=e.memoizedState,s=0;t!==null&&(s=t.retryLane),iS(e,s)}function X2(e,t){var s=0;switch(e.tag){case 13:var n=e.stateNode,i=e.memoizedState;i!==null&&(s=i.retryLane);break;case 19:n=e.stateNode;break;default:throw Error(ie(314))}n!==null&&n.delete(t),iS(e,s)}var rS;rS=function(e,t,s){if(e!==null)if(e.memoizedProps!==t.pendingProps||Vs.current)qs=!0;else{if(!(e.lanes&s)&&!(t.flags&128))return qs=!1,B2(e,t,s);qs=!!(e.flags&131072)}else qs=!1,wt&&t.flags&1048576&&cx(t,uh,t.index);switch(t.lanes=0,t.tag){case 2:var n=t.type;$u(e,t),e=t.pendingProps;var i=fa(t,js.current);aa(t,s),i=Og(null,t,n,e,i,s);var r=Bg();return t.flags|=1,typeof i=="object"&&i!==null&&typeof i.render=="function"&&i.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Ys(n)?(r=!0,lh(t)):r=!1,t.memoizedState=i.state!==null&&i.state!==void 0?i.state:null,Mg(t),i.updater=nd,t.stateNode=i,i._reactInternals=t,Rp(t,n,e,s),t=Ap(null,t,n,!0,r,s)):(t.tag=0,wt&&r&&Cg(t),Ps(null,t,i,s),t=t.child),t;case 16:n=t.elementType;e:{switch($u(e,t),e=t.pendingProps,i=n._init,n=i(n._payload),t.type=n,i=t.tag=Q2(n),e=Pn(n,e),i){case 0:t=Tp(null,t,n,e,s);break e;case 1:t=Lv(null,t,n,e,s);break e;case 11:t=Iv(null,t,n,e,s);break e;case 14:t=Pv(null,t,n,Pn(n.type,e),s);break e}throw Error(ie(306,n,""))}return t;case 0:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Pn(n,i),Tp(e,t,n,i,s);case 1:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Pn(n,i),Lv(e,t,n,i,s);case 3:e:{if(Hx(t),e===null)throw Error(ie(387));n=t.pendingProps,r=t.memoizedState,i=r.element,mx(e,t),fh(t,n,null,s);var a=t.memoizedState;if(n=a.element,r.isDehydrated)if(r={element:n,isDehydrated:!1,cache:a.cache,pendingSuspenseBoundaries:a.pendingSuspenseBoundaries,transitions:a.transitions},t.updateQueue.baseState=r,t.memoizedState=r,t.flags&256){i=_a(Error(ie(423)),t),t=Ov(e,t,n,s,i);break e}else if(n!==i){i=_a(Error(ie(424)),t),t=Ov(e,t,n,s,i);break e}else for(on=mr(t.stateNode.containerInfo.firstChild),ln=t,wt=!0,On=null,s=fx(t,null,n,s),t.child=s;s;)s.flags=s.flags&-3|4096,s=s.sibling;else{if(pa(),n===i){t=Pi(e,t,s);break e}Ps(e,t,n,s)}t=t.child}return t;case 5:return gx(t),e===null&&Cp(t),n=t.type,i=t.pendingProps,r=e!==null?e.memoizedProps:null,a=i.children,bp(n,i)?a=null:r!==null&&bp(n,r)&&(t.flags|=32),zx(e,t),Ps(e,t,a,s),t.child;case 6:return e===null&&Cp(t),null;case 13:return Ux(e,t,s);case 4:return Dg(t,t.stateNode.containerInfo),n=t.pendingProps,e===null?t.child=ma(t,null,n,s):Ps(e,t,n,s),t.child;case 11:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Pn(n,i),Iv(e,t,n,i,s);case 7:return Ps(e,t,t.pendingProps,s),t.child;case 8:return Ps(e,t,t.pendingProps.children,s),t.child;case 12:return Ps(e,t,t.pendingProps.children,s),t.child;case 10:e:{if(n=t.type._context,i=t.pendingProps,r=t.memoizedProps,a=i.value,pt(hh,n._currentValue),n._currentValue=a,r!==null)if(Un(r.value,a)){if(r.children===i.children&&!Vs.current){t=Pi(e,t,s);break e}}else for(r=t.child,r!==null&&(r.return=t);r!==null;){var l=r.dependencies;if(l!==null){a=r.child;for(var c=l.firstContext;c!==null;){if(c.context===n){if(r.tag===1){c=Ri(-1,s&-s),c.tag=2;var u=r.updateQueue;if(u!==null){u=u.shared;var h=u.pending;h===null?c.next=c:(c.next=h.next,h.next=c),u.pending=c}}r.lanes|=s,c=r.alternate,c!==null&&(c.lanes|=s),Ep(r.return,s,t),l.lanes|=s;break}c=c.next}}else if(r.tag===10)a=r.type===t.type?null:r.child;else if(r.tag===18){if(a=r.return,a===null)throw Error(ie(341));a.lanes|=s,l=a.alternate,l!==null&&(l.lanes|=s),Ep(a,s,t),a=r.sibling}else a=r.child;if(a!==null)a.return=r;else for(a=r;a!==null;){if(a===t){a=null;break}if(r=a.sibling,r!==null){r.return=a.return,a=r;break}a=a.return}r=a}Ps(e,t,i.children,s),t=t.child}return t;case 9:return i=t.type,n=t.pendingProps.children,aa(t,s),i=kn(i),n=n(i),t.flags|=1,Ps(e,t,n,s),t.child;case 14:return n=t.type,i=Pn(n,t.pendingProps),i=Pn(n.type,i),Pv(e,t,n,i,s);case 15:return $x(e,t,t.type,t.pendingProps,s);case 17:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Pn(n,i),$u(e,t),t.tag=1,Ys(n)?(e=!0,lh(t)):e=!1,aa(t,s),Lx(t,n,i),Rp(t,n,i,s),Ap(null,t,n,!0,e,s);case 19:return Wx(e,t,s);case 22:return Fx(e,t,s)}throw Error(ie(156,t.tag))};function oS(e,t){return Dw(e,t)}function Z2(e,t,s,n){this.tag=e,this.key=s,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=n,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function wn(e,t,s,n){return new Z2(e,t,s,n)}function Yg(e){return e=e.prototype,!(!e||!e.isReactComponent)}function Q2(e){if(typeof e=="function")return Yg(e)?1:0;if(e!=null){if(e=e.$$typeof,e===fg)return 11;if(e===pg)return 14}return 2}function yr(e,t){var s=e.alternate;return s===null?(s=wn(e.tag,t,e.key,e.mode),s.elementType=e.elementType,s.type=e.type,s.stateNode=e.stateNode,s.alternate=e,e.alternate=s):(s.pendingProps=t,s.type=e.type,s.flags=0,s.subtreeFlags=0,s.deletions=null),s.flags=e.flags&14680064,s.childLanes=e.childLanes,s.lanes=e.lanes,s.child=e.child,s.memoizedProps=e.memoizedProps,s.memoizedState=e.memoizedState,s.updateQueue=e.updateQueue,t=e.dependencies,s.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},s.sibling=e.sibling,s.index=e.index,s.ref=e.ref,s}function Hu(e,t,s,n,i,r){var a=2;if(n=e,typeof e=="function")Yg(e)&&(a=1);else if(typeof e=="string")a=5;else e:switch(e){case Wo:return Xr(s.children,i,r,t);case dg:a=8,i|=8;break;case Zf:return e=wn(12,s,t,i|2),e.elementType=Zf,e.lanes=r,e;case Qf:return e=wn(13,s,t,i),e.elementType=Qf,e.lanes=r,e;case ep:return e=wn(19,s,t,i),e.elementType=ep,e.lanes=r,e;case gw:return od(s,i,r,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case pw:a=10;break e;case mw:a=9;break e;case fg:a=11;break e;case pg:a=14;break e;case Qi:a=16,n=null;break e}throw Error(ie(130,e==null?e:typeof e,""))}return t=wn(a,s,t,i),t.elementType=e,t.type=n,t.lanes=r,t}function Xr(e,t,s,n){return e=wn(7,e,n,t),e.lanes=s,e}function od(e,t,s,n){return e=wn(22,e,n,t),e.elementType=gw,e.lanes=s,e.stateNode={isHidden:!1},e}function sf(e,t,s){return e=wn(6,e,null,t),e.lanes=s,e}function nf(e,t,s){return t=wn(4,e.children!==null?e.children:[],e.key,t),t.lanes=s,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function eN(e,t,s,n,i){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Od(0),this.expirationTimes=Od(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Od(0),this.identifierPrefix=n,this.onRecoverableError=i,this.mutableSourceEagerHydrationData=null}function Gg(e,t,s,n,i,r,a,l,c){return e=new eN(e,t,s,l,c),t===1?(t=1,r===!0&&(t|=8)):t=0,r=wn(3,null,null,t),e.current=r,r.stateNode=e,r.memoizedState={element:n,isDehydrated:s,cache:null,transitions:null,pendingSuspenseBoundaries:null},Mg(r),e}function tN(e,t,s){var n=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:Uo,key:n==null?null:""+n,children:e,containerInfo:t,implementation:s}}function aS(e){if(!e)return xr;e=e._reactInternals;e:{if(go(e)!==e||e.tag!==1)throw Error(ie(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(Ys(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(t!==null);throw Error(ie(171))}if(e.tag===1){var s=e.type;if(Ys(s))return ax(e,s,t)}return t}function lS(e,t,s,n,i,r,a,l,c){return e=Gg(s,n,!0,e,i,r,a,l,c),e.context=aS(null),s=e.current,n=Ls(),i=vr(s),r=Ri(n,i),r.callback=t??null,gr(s,r,i),e.current.lanes=i,Ec(e,i,n),Gs(e,n),e}function ad(e,t,s,n){var i=t.current,r=Ls(),a=vr(i);return s=aS(s),t.context===null?t.context=s:t.pendingContext=s,t=Ri(r,a),t.payload={element:e},n=n===void 0?null:n,n!==null&&(t.callback=n),e=gr(i,t,a),e!==null&&(zn(e,i,a,r),Lu(e,i,a)),a}function wh(e){if(e=e.current,!e.child)return null;switch(e.child.tag){case 5:return e.child.stateNode;default:return e.child.stateNode}}function Vv(e,t){if(e=e.memoizedState,e!==null&&e.dehydrated!==null){var s=e.retryLane;e.retryLane=s!==0&&s<t?s:t}}function Jg(e,t){Vv(e,t),(e=e.alternate)&&Vv(e,t)}function sN(){return null}var cS=typeof reportError=="function"?reportError:function(e){console.error(e)};function Xg(e){this._internalRoot=e}ld.prototype.render=Xg.prototype.render=function(e){var t=this._internalRoot;if(t===null)throw Error(ie(409));ad(e,t,null,null)};ld.prototype.unmount=Xg.prototype.unmount=function(){var e=this._internalRoot;if(e!==null){this._internalRoot=null;var t=e.containerInfo;lo(function(){ad(null,e,null,null)}),t[Di]=null}};function ld(e){this._internalRoot=e}ld.prototype.unstable_scheduleHydration=function(e){if(e){var t=Fw();e={blockedOn:null,target:e,priority:t};for(var s=0;s<ir.length&&t!==0&&t<ir[s].priority;s++);ir.splice(s,0,e),s===0&&Hw(e)}};function Zg(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function cd(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11&&(e.nodeType!==8||e.nodeValue!==" react-mount-point-unstable "))}function Yv(){}function nN(e,t,s,n,i){if(i){if(typeof n=="function"){var r=n;n=function(){var u=wh(a);r.call(u)}}var a=lS(t,n,e,0,null,!1,!1,"",Yv);return e._reactRootContainer=a,e[Di]=a.current,ec(e.nodeType===8?e.parentNode:e),lo(),a}for(;i=e.lastChild;)e.removeChild(i);if(typeof n=="function"){var l=n;n=function(){var u=wh(c);l.call(u)}}var c=Gg(e,0,!1,null,null,!1,!1,"",Yv);return e._reactRootContainer=c,e[Di]=c.current,ec(e.nodeType===8?e.parentNode:e),lo(function(){ad(t,c,s,n)}),c}function ud(e,t,s,n,i){var r=s._reactRootContainer;if(r){var a=r;if(typeof i=="function"){var l=i;i=function(){var c=wh(a);l.call(c)}}ad(t,a,e,i)}else a=nN(s,t,e,i,n);return wh(a)}Bw=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var s=xl(t.pendingLanes);s!==0&&(_g(t,s|1),Gs(t,zt()),!(it&6)&&(va=zt()+500,Nr()))}break;case 13:lo(function(){var n=Ii(e,1);if(n!==null){var i=Ls();zn(n,e,1,i)}}),Jg(e,1)}};vg=function(e){if(e.tag===13){var t=Ii(e,134217728);if(t!==null){var s=Ls();zn(t,e,134217728,s)}Jg(e,134217728)}};$w=function(e){if(e.tag===13){var t=vr(e),s=Ii(e,t);if(s!==null){var n=Ls();zn(s,e,t,n)}Jg(e,t)}};Fw=function(){return ct};zw=function(e,t){var s=ct;try{return ct=e,t()}finally{ct=s}};up=function(e,t,s){switch(t){case"input":if(np(e,s),t=s.name,s.type==="radio"&&t!=null){for(s=e;s.parentNode;)s=s.parentNode;for(s=s.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<s.length;t++){var n=s[t];if(n!==e&&n.form===e.form){var i=ed(n);if(!i)throw Error(ie(90));vw(n),np(n,i)}}}break;case"textarea":bw(e,s);break;case"select":t=s.value,t!=null&&na(e,!!s.multiple,t,!1)}};Nw=Kg;Rw=lo;var iN={usingClientEntryPoint:!1,Events:[Rc,Yo,ed,Cw,Ew,Kg]},Xa={findFiberByHostInstance:Kr,bundleType:0,version:"18.3.1",rendererPackageName:"react-dom"},rN={bundleType:Xa.bundleType,version:Xa.version,rendererPackageName:Xa.rendererPackageName,rendererConfig:Xa.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:Li.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return e=Aw(e),e===null?null:e.stateNode},findFiberByHostInstance:Xa.findFiberByHostInstance||sN,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1-next-f1338f8080-20240426"};if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"){var lu=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!lu.isDisabled&&lu.supportsFiber)try{Jh=lu.inject(rN),oi=lu}catch{}}un.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=iN;un.createPortal=function(e,t){var s=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!Zg(t))throw Error(ie(200));return tN(e,t,null,s)};un.createRoot=function(e,t){if(!Zg(e))throw Error(ie(299));var s=!1,n="",i=cS;return t!=null&&(t.unstable_strictMode===!0&&(s=!0),t.identifierPrefix!==void 0&&(n=t.identifierPrefix),t.onRecoverableError!==void 0&&(i=t.onRecoverableError)),t=Gg(e,1,!1,null,null,s,!1,n,i),e[Di]=t.current,ec(e.nodeType===8?e.parentNode:e),new Xg(t)};un.findDOMNode=function(e){if(e==null)return null;if(e.nodeType===1)return e;var t=e._reactInternals;if(t===void 0)throw typeof e.render=="function"?Error(ie(188)):(e=Object.keys(e).join(","),Error(ie(268,e)));return e=Aw(t),e=e===null?null:e.stateNode,e};un.flushSync=function(e){return lo(e)};un.hydrate=function(e,t,s){if(!cd(t))throw Error(ie(200));return ud(null,e,t,!0,s)};un.hydrateRoot=function(e,t,s){if(!Zg(e))throw Error(ie(405));var n=s!=null&&s.hydratedSources||null,i=!1,r="",a=cS;if(s!=null&&(s.unstable_strictMode===!0&&(i=!0),s.identifierPrefix!==void 0&&(r=s.identifierPrefix),s.onRecoverableError!==void 0&&(a=s.onRecoverableError)),t=lS(t,null,e,1,s??null,i,!1,r,a),e[Di]=t.current,ec(e),n)for(e=0;e<n.length;e++)s=n[e],i=s._getVersion,i=i(s._source),t.mutableSourceEagerHydrationData==null?t.mutableSourceEagerHydrationData=[s,i]:t.mutableSourceEagerHydrationData.push(s,i);return new ld(t)};un.render=function(e,t,s){if(!cd(t))throw Error(ie(200));return ud(null,e,t,!1,s)};un.unmountComponentAtNode=function(e){if(!cd(e))throw Error(ie(40));return e._reactRootContainer?(lo(function(){ud(null,null,e,!1,function(){e._reactRootContainer=null,e[Di]=null})}),!0):!1};un.unstable_batchedUpdates=Kg;un.unstable_renderSubtreeIntoContainer=function(e,t,s,n){if(!cd(s))throw Error(ie(200));if(e==null||e._reactInternals===void 0)throw Error(ie(38));return ud(e,t,s,!1,n)};un.version="18.3.1-next-f1338f8080-20240426";function uS(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(uS)}catch(e){console.error(e)}}uS(),uw.exports=un;var cc=uw.exports,hS,Gv=cc;hS=Gv.createRoot,Gv.hydrateRoot;const cu=10,Jv=6;function co(e,t,s){const n=g.useRef(t);n.current=t;const i=g.useRef(s);i.current=s,g.useEffect(()=>{if(!e)return;const r=c=>n.current.some(u=>u.current&&c instanceof Node&&u.current.contains(c)),a=c=>{r(c.target)||i.current()},l=c=>{c.key==="Escape"&&!c.defaultPrevented&&i.current()};return document.addEventListener("pointerdown",a,!0),document.addEventListener("keydown",l),()=>{document.removeEventListener("pointerdown",a,!0),document.removeEventListener("keydown",l)}},[e])}function dS(){const e=g.useRef(null);return g.useLayoutEffect(()=>{const t=e.current;if(!t)return;const s=()=>{if(t.style.top="",t.style.left="",t.style.maxHeight="",window.matchMedia("(max-width: 720px)").matches)return;const n=t.parentElement,i=(n?.firstElementChild??n)?.getBoundingClientRect();if(!i)return;const r=t.getBoundingClientRect().height,a=i.top-cu,l=window.innerHeight-i.bottom-cu,c=l>a,u=Math.min(Math.max(a,l),window.innerHeight*.46);t.style.maxHeight=`${Math.round(u)}px`;const h=Math.min(r,u);t.style.top=`${Math.round(c?i.bottom+Jv:i.top-Jv-h)}px`;const d=t.getBoundingClientRect().width;t.style.left=`${Math.round(Math.min(Math.max(i.left,cu),window.innerWidth-cu-d))}px`;const p=t.querySelector(".tb-opt.sel"),f=p?.closest(".tb-scroll")??t;if(p){const m=p.getBoundingClientRect(),b=f.getBoundingClientRect();m.top<b.top?f.scrollTop-=b.top-m.top+8:m.bottom>b.bottom&&(f.scrollTop+=m.bottom-b.bottom+8)}};return s(),window.addEventListener("resize",s),()=>window.removeEventListener("resize",s)},[]),e}function Ta(e,t){const s=g.useRef(t);s.current=t,g.useEffect(()=>{if(!e)return;const n=i=>{i.key==="Escape"&&!i.defaultPrevented&&s.current()};return document.addEventListener("keydown",n),()=>document.removeEventListener("keydown",n)},[e])}function Te(e,{size:t=16,className:s}){return o.jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.6,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",className:s,children:e})}const fS=(e={})=>Te(o.jsx(o.Fragment,{children:o.jsx("path",{d:"M3 6h18M3 12h18M3 18h18"})}),e),oN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("circle",{cx:"12",cy:"5",r:"1.4"}),o.jsx("circle",{cx:"12",cy:"12",r:"1.4"}),o.jsx("circle",{cx:"12",cy:"19",r:"1.4"})]}),e),pS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M12 20h9"}),o.jsx("path",{d:"M16.5 3.5a2.12 2.12 0 0 1 3 3L8 18l-4 1 1-4z"})]}),e),mS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"9",y:"9",width:"12",height:"12",rx:"2"}),o.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]}),e),gS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M12 3v11"}),o.jsx("path",{d:"M7 10l5 5 5-5"}),o.jsx("path",{d:"M4 20h16"})]}),e),aN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"7",width:"18",height:"13",rx:"2"}),o.jsx("path",{d:"M3 11h18"}),o.jsx("path",{d:"M9 3h6"})]}),e),lN=(e={})=>Te(o.jsx("path",{d:"m4 12.5 5 5L20 6.5"}),e),uo=(e={})=>Te(o.jsx("path",{d:"M3 7a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"}),e),cN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M3 7a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v1.4"}),o.jsx("path",{d:"M3 10.4h17.2a1 1 0 0 1 .97 1.24l-1.6 6.06A2 2 0 0 1 17.65 19.2H5a2 2 0 0 1-2-2z"})]}),e),uN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("circle",{cx:"9",cy:"8",r:"3"}),o.jsx("path",{d:"M3.5 20a5.5 5.5 0 0 1 11 0"}),o.jsx("circle",{cx:"17",cy:"9.2",r:"2.2"}),o.jsx("path",{d:"M16.2 20a4.6 4.6 0 0 1 5.3-3.2"})]}),e),_S=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M3 10.5 12 3l9 7.5"}),o.jsx("path",{d:"M5 9.5V21h14V9.5"})]}),e),vS=(e={})=>Te(o.jsx("path",{d:"M12 3l7 3v5c0 4.5-3 8-7 10-4-2-7-5.5-7-10V6z"}),e),Xv=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M4 17a8 8 0 1 1 16 0"}),o.jsx("path",{d:"M12 17l4-5"})]}),e),hN=(e={})=>Te(o.jsx("path",{d:"M3 12h4l2.5-7 4 14 2.5-7H21"}),e),xh=(e={})=>Te(o.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1.5",fill:"currentColor",stroke:"none"}),e),En=(e={})=>Te(o.jsx("path",{d:"M6 6l12 12M18 6L6 18"}),e),ya=(e={})=>Te(o.jsx("path",{d:"M6 9l6 6 6-6"}),e),an=(e={})=>Te(o.jsx("path",{d:"M9 6l6 6-6 6"}),e),yS=(e={})=>Te(o.jsx("path",{d:"M12 19V5M6 11l6-6 6 6"}),e),bS=(e={})=>Te(o.jsx("path",{d:"M12 5v14M6 13l6 6 6-6"}),e),Sh=(e={})=>Te(o.jsx("path",{d:"M4 12l16-8-6 8 6 8z"}),e),kh=(e={})=>Te(o.jsx("path",{d:"M12 5v14M5 12h14"}),e),dN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("circle",{cx:"11",cy:"11",r:"6.5"}),o.jsx("path",{d:"M16 16l4 4"})]}),e),wS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M12 4v8"}),o.jsx("path",{d:"M7.5 7a7 7 0 1 0 9 0"})]}),e),rf=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M3 12a9 9 0 1 0 3-6.7"}),o.jsx("path",{d:"M3 4v4h4"})]}),e),fN=(e={})=>Te(o.jsx("circle",{cx:"12",cy:"12",r:"4",fill:"currentColor",stroke:"none"}),e),pN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),o.jsx("path",{d:"M15 4v16"})]}),e),mN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),o.jsx("path",{d:"M9 4v16"})]}),e),gN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),o.jsx("path",{d:"M15 4v16"})]}),e),_N=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),o.jsx("path",{d:"m7 9 3 3-3 3M13 15h4"})]}),e),ui=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M6 2h8l4 4v16H6z"}),o.jsx("path",{d:"M14 2v4h4"})]}),e),ji=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"9",y:"3",width:"6",height:"11",rx:"3"}),o.jsx("path",{d:"M5 11a7 7 0 0 0 14 0M12 18v3M9 21h6"})]}),e),hd=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M11 5 6 9H3v6h3l5 4z"}),o.jsx("path",{d:"M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13"})]}),e),xS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M11 5 6 9H3v6h3l5 4z"}),o.jsx("path",{d:"m16 9 5 6M21 9l-5 6"})]}),e),SS=o.jsx("path",{d:"M6.6 3.5h1.9c.8 0 1.5.6 1.7 1.4l.7 2.6c.2.8-.1 1.7-.8 2.2l-1.2.8a12.5 12.5 0 0 0 5.6 5.6l.8-1.2c.5-.7 1.4-1 2.2-.8l2.6.7c.8.2 1.4.9 1.4 1.7v1.9c0 1.2-1 2.2-2.2 2.1C11 20.9 3.1 13 3.2 5.7c0-1.2 1-2.2 2.2-2.2z"}),vN=(e={})=>Te(SS,e),yN=(e={})=>Te(o.jsx("g",{transform:"rotate(135 12 12)",children:SS}),e),bN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M9 9v2a3 3 0 0 0 4.6 2.5M15 11.5V6a3 3 0 0 0-5.7-1.3"}),o.jsx("path",{d:"M5 11a7 7 0 0 0 10.8 5.9M19 11v.5"}),o.jsx("path",{d:"M12 18v3M9 21h6"}),o.jsx("path",{d:"m4 4 16 16"})]}),e),wN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"6",width:"18",height:"12",rx:"2"}),o.jsx("path",{d:"M7 10h.01M11 10h.01M15 10h.01M7 14h10"})]}),e),xN=(e={})=>Te(o.jsx("path",{d:"M20 11.5 12 19.5a5 5 0 0 1-7-7l8-8a3.5 3.5 0 0 1 5 5l-8 8a2 2 0 0 1-3-3l7-7"}),e),Tc=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("circle",{cx:"12",cy:"12",r:"3"}),o.jsx("path",{d:"M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-2.9 1.2v.2a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-2.9-1.2l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1A1.7 1.7 0 0 0 3 15a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.2-2.9l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1A1.7 1.7 0 0 0 10 4.2V4a2 2 0 1 1 4 0v.2a1.7 1.7 0 0 0 2.9 1.2l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1A1.7 1.7 0 0 0 21 11h.2a2 2 0 1 1 0 4H21z"})]}),e),Qg=(e={})=>Te(o.jsx("path",{d:"M19 12H5M11 6l-6 6 6 6"}),e),ba=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M20 11a8 8 0 1 0-2 6"}),o.jsx("path",{d:"M20 5v6h-6"})]}),e),SN=(e={})=>Te(o.jsx(o.Fragment,{children:o.jsx("path",{d:"M4 8h13l-3-3M20 16H7l3 3"})}),e),e_=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"7",y:"7",width:"10",height:"10",rx:"2"}),o.jsx("path",{d:"M10 3v4M14 3v4M10 17v4M14 17v4M3 10h4M3 14h4M17 10h4M17 14h4"})]}),e),kN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M9.5 4a2.5 2.5 0 0 1 2.5 2.5v11a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 2.26-4.9A2.5 2.5 0 0 1 9.5 4Z"}),o.jsx("path",{d:"M14.5 4A2.5 2.5 0 0 0 12 6.5v11a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-2.26-4.9A2.5 2.5 0 0 0 14.5 4Z"})]}),e),kS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("circle",{cx:"7",cy:"5",r:"2"}),o.jsx("circle",{cx:"7",cy:"19",r:"2"}),o.jsx("circle",{cx:"17",cy:"9",r:"2"}),o.jsx("path",{d:"M7 7v10M17 11c0 3-3 4-6 4H9"})]}),e),CS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M2 12s3.6-6 10-6 10 6 10 6-3.6 6-10 6-10-6-10-6z"}),o.jsx("circle",{cx:"12",cy:"12",r:"2.6"})]}),e),CN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M3 3l18 18"}),o.jsx("path",{d:"M10.6 6.2A9.9 9.9 0 0 1 12 6c6.4 0 10 6 10 6a17 17 0 0 1-2.8 3.3"}),o.jsx("path",{d:"M6.3 7.9A16.5 16.5 0 0 0 2 12s3.6 6 10 6c1.5 0 2.8-.3 4-.8"})]}),e),EN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"4",width:"18",height:"12",rx:"2"}),o.jsx("path",{d:"M8 20h8M12 16v4"})]}),e),NN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"4",y:"10",width:"16",height:"10",rx:"2"}),o.jsx("path",{d:"M8 10V7a4 4 0 0 1 8 0v3"})]}),e),RN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M3.5 12a8.5 8.5 0 1 0 2.6-6.1"}),o.jsx("path",{d:"M3 4v4h4"}),o.jsx("path",{d:"M12 8v4.4l3 1.8"})]}),e),jN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"2.5",y:"5",width:"19",height:"14",rx:"3.5"}),o.jsx("path",{d:"M6.5 10.5h4.5M13.5 10.5h4M6.5 14h7"})]}),e);function t_(e,t){const s=(e||t||"").trim();if(!s)return"";const n=s.includes("·")?s.split("·").pop().trim():s;return(n.includes(":")?n.split(":").pop().trim():n)||n||s}function Zv(e){const t=i=>i.replace(/[•·|,-]?\s*\b(current|active|selected|default)\b\s*$/i,"").replace(/[•·|,\s-]+$/g,"").trim(),s=/^\s*provider:\s*(.+)$/i.exec(e.description??"");if(s){const i=t(s[1]);if(i)return i}const n=e.modelId.includes(":")?e.modelId.split(":")[0]:e.modelId.includes("/")?e.modelId.split("/")[0]:"";return t(n)||"other"}function TN(e,t){const s=t_(e.name??"",e.modelId),n=`${t}/`;return s.startsWith(n)?s.slice(n.length):s}const AN=12;function ES({models:e,current:t,usage:s={},pending:n=null,onPick:i,bad:r={},err:a=null}){const[l,c]=g.useState(""),[u,h]=g.useState({}),d=dS(),p=g.useMemo(()=>{const f=l.trim().toLowerCase(),m=f?e.filter(w=>`${w.modelId} ${w.name} ${w.description??""}`.toLowerCase().includes(f)):e,b=new Map;for(const w of m){const x=Zv(w),S=b.get(x);S?S.push(w):b.set(x,[w])}const _=e.find(w=>w.modelId===t),v=_?Zv(_):"",y=w=>s[w]??0;return[...b.entries()].map(([w,x])=>{const S=[...x].sort((N,R)=>y(R.modelId)-y(N.modelId)||N.modelId.localeCompare(R.modelId));return{provider:w,list:S.slice(0,200),truncated:S.length>200,current:w===v,heat:S.reduce((N,R)=>N+y(R.modelId),0)}}).sort((w,x)=>w.current!==x.current?w.current?-1:1:x.heat-w.heat||w.provider.localeCompare(x.provider))},[e,l,t,s]);return o.jsxs("div",{className:"tb-list wide stacked",ref:d,children:[a?o.jsxs("div",{className:"tb-err",role:"alert","data-model-err":a.id,children:[o.jsx("span",{className:"tb-err-id",children:a.id}),o.jsx("span",{className:"tb-err-text",children:a.text})]}):null,e.length>AN?o.jsx("input",{className:"tb-search",autoFocus:!0,value:l,placeholder:`filter ${e.length} models…`,"aria-label":"filter models",onChange:f=>c(f.target.value)}):null,o.jsxs("div",{className:"tb-scroll",children:[p.map(f=>{const m=!!l.trim()||!u[f.provider];return o.jsxs("div",{className:"tb-group",children:[o.jsxs("button",{type:"button",className:`tb-group-head ${m?"open":""}`,"aria-expanded":m,title:`${f.provider} · ${f.list.length} model(s)`,"data-provider":f.provider,onClick:()=>h(b=>({...b,[f.provider]:!b[f.provider]})),children:[o.jsx(an,{size:11,className:`tb-group-chev ${m?"open":""}`}),o.jsx("span",{className:"tb-group-name",children:f.provider}),o.jsx("span",{className:"tb-group-count",children:f.list.length})]}),m?o.jsx("div",{className:"tb-group-body",children:f.list.map(b=>o.jsxs("button",{className:`tb-opt ${b.modelId===t?"sel":""} ${n===b.modelId?"pending":""} ${a?.id===b.modelId||r[b.modelId]?"bad":""}`,title:r[b.modelId]?`${b.modelId} — this agent refused it: ${r[b.modelId]}`:b.description?`${b.modelId} — ${b.description}`:b.modelId,"data-model":b.modelId,"data-model-refused":r[b.modelId]?"1":void 0,onClick:()=>i(b.modelId),children:[o.jsx("span",{className:"tb-opt-name",children:TN(b,f.provider)}),n===b.modelId?o.jsx("span",{className:"tb-opt-pending",children:"待生效"}):null]},b.modelId))}):null]},f.provider)}),p.length?null:o.jsxs("div",{className:"tb-empty",children:["no model matches “",l,"”"]})]})]})}let Zr=null,uu=null,Up=0;const Wp=new Set;function Kp(){Up+=1;for(const e of Wp)e()}function MN(e){return Wp.add(e),()=>{Wp.delete(e)}}function DN(){return Zr?Promise.resolve():(uu||(uu=fetch("/api/model-usage",{headers:{accept:"application/json"}}).then(e=>{if(!e.ok)throw new Error(`model-usage ${e.status}`);return e.json()}).then(e=>{Zr=e.usage??{},Kp()}).catch(()=>{Zr=null,uu=null,Kp()})),uu)}function IN(e,t){const s=`${e}|${t}`;Zr={...Zr??{},[s]:((Zr??{})[s]??0)+1},Kp()}function NS(e){return g.useSyncExternalStore(MN,()=>Up,()=>0),g.useEffect(()=>{DN()},[]),g.useMemo(()=>{const t={},s=Zr??{},n=`${e}|`;for(const[i,r]of Object.entries(s)){const a=i.indexOf("|");if(a<0||e&&!i.startsWith(n))continue;const l=i.slice(a+1);t[l]=(t[l]??0)+r}return t},[e,Up])}function Qv(e,t){const s=t?.messageId;return typeof s=="string"&&s?`${e}:${s}`:null}function PN(e,t){return e===t||e.replace(/\s+/g,"")===t.replace(/\s+/g,"")}function LN(e,t){const s=t.delta;if(s===void 0)return e===void 0?{action:"create",text:t.text}:t.key?PN(e,t.text)?{action:"skip"}:{action:"replace",text:t.text}:{action:"append",add:t.text};if(e===void 0)return{action:"create",text:s};if(t.n!==void 0){const i=t.n-e.length;return i<=0?{action:"skip"}:i>=s.length?{action:"append",add:s}:{action:"append",add:s.slice(s.length-i)}}const n=BN(e,s);return n?{action:"append",add:n}:{action:"skip"}}function ON(e,t,s,n){const i=e,r=d=>d,a=d=>{const p=s.key??`anon@${i.length}`;return i.push(r(n(p,{...s,text:d}))),s.key&&t.set(s.key,i.length-1),{pushed:!0,at:i.length-1}},l=s.key?t.get(s.key):void 0,c=l===void 0?void 0:i[l],u=c&&c.kind===s.kind?l:!s.key&&i.length>0&&i[i.length-1].kind===s.kind?i.length-1:void 0,h=LN(u===void 0?void 0:i[u].text,s);return h.action==="create"?a(h.text):u===void 0?h.action==="append"?a(h.add):h.action==="replace"?a(h.text):a(s.delta??s.text):h.action==="skip"?{pushed:!1,at:u}:(e[u]={...e[u],text:h.action==="append"?i[u].text+h.add:h.text},{pushed:!1,at:u})}function e0(e){const t=new Map;return e.forEach((s,n)=>{s.key.startsWith("anon@")?t.delete(s.key):t.set(s.key,n)}),t}function BN(e,t){if(!e||!t)return t;if(t.startsWith(e))return t.slice(e.length);const s=Math.min(e.length,t.length);for(let n=s;n>=16;n--)if(e.endsWith(t.slice(0,n)))return t.slice(n);return t}function s_(e,t){const s=e.length?e.replace(/\n$/,"").split(`
|
|
41
41
|
`):[],n=t.length?t.replace(/\n$/,"").split(`
|
|
42
42
|
`):[];let i=0;for(;i<s.length&&i<n.length&&s[i]===n[i];)i++;let r=0;for(;r<s.length-i&&r<n.length-i&&s[s.length-1-r]===n[n.length-1-r];)r++;const a=[],l=3;i>l&&a.push({kind:"gap",text:`⋯ 上面 ${i-l} 行未变 ⋯`,oldNo:null,newNo:null});for(let b=Math.max(0,i-l);b<i;b++)a.push({kind:"ctx",text:s[b],oldNo:b+1,newNo:b+1});const c=s.slice(i,s.length-r),u=n.slice(i,n.length-r),h=[];if(c.length*u.length>25e4)c.forEach((b,_)=>h.push({kind:"del",text:b,oldNo:i+_+1,newNo:null})),u.forEach((b,_)=>h.push({kind:"add",text:b,oldNo:null,newNo:i+_+1}));else{const b=c.length,_=u.length,v=Array.from({length:b+1},()=>new Array(_+1).fill(0));for(let x=b-1;x>=0;x--)for(let S=_-1;S>=0;S--)v[x][S]=c[x]===u[S]?v[x+1][S+1]+1:Math.max(v[x+1][S],v[x][S+1]);let y=0,w=0;for(;y<b&&w<_;)c[y]===u[w]?(h.push({kind:"ctx",text:c[y],oldNo:i+y+1,newNo:i+w+1}),y++,w++):v[y+1][w]>=v[y][w+1]?(h.push({kind:"del",text:c[y],oldNo:i+y+1,newNo:null}),y++):(h.push({kind:"add",text:u[w],oldNo:null,newNo:i+w+1}),w++);for(;y<b;)h.push({kind:"del",text:c[y],oldNo:i+y+1,newNo:null}),y++;for(;w<_;)h.push({kind:"add",text:u[w],oldNo:null,newNo:i+w+1}),w++}const d=[];for(let b=0;b<Math.min(r,l);b++)d.push({kind:"ctx",text:s[s.length-r+b],oldNo:s.length-r+b+1,newNo:n.length-r+b+1});r>l&&d.push({kind:"gap",text:`⋯ 下面 ${r-l} 行未变 ⋯`,oldNo:null,newNo:null});const p=new Array(h.length).fill(!1);h.forEach((b,_)=>{if(b.kind!=="ctx")for(let v=Math.max(0,_-l);v<=Math.min(h.length-1,_+l);v++)p[v]=!0});const f=[];let m=0;return h.forEach((b,_)=>{if(!p[_]){m++;return}m&&(f.push({kind:"gap",text:`⋯ 中间 ${m} 行未变 ⋯`,oldNo:null,newNo:null}),m=0),f.push(b)}),m&&f.push({kind:"gap",text:`⋯ 中间 ${m} 行未变 ⋯`,oldNo:null,newNo:null}),[...a,...f,...d]}const of=e=>typeof e=="string";function $N(e){const t=Math.max(e.lastIndexOf("/"),e.lastIndexOf("\\"));return t>=0?e.slice(t+1):e}function RS(e){if(!e||!/^(\+\+\+|---) /m.test(e))return null;let t="",s=0,n=0;for(const i of e.split(`
|
|
43
|
-
`)){if(i.startsWith("+++ ")){const r=i.slice(4).trim().replace(/^b\//,"").replace(/\t.*$/,"");r&&r!=="/dev/null"&&(t=r);continue}i.startsWith("--- ")||(i.startsWith("+")?s++:i.startsWith("-")&&n++)}return t?{path:t,insertions:s,deletions:n}:null}function FN(e){const t=e??{},s=Array.isArray(t.content)?t.content:[],n=[],i=new Set,r=a=>{i.has(a.path)||(i.add(a.path),n.push(a))};for(const a of s){if(!a||typeof a!="object")continue;if(of(a.path)&&a.path&&(a.oldText!=null||a.newText!=null||a.type==="diff")){r({path:a.path,oldText:a.oldText??"",newText:a.newText??""});continue}const l=of(a.text)?a.text:of(a.content?.text)?a.content.text:"";if(!l)continue;const c=RS(l);c&&r({path:c.path,diffText:l})}return n}function zN(e){const t=[],s=new Map;for(const n of e){const i=s.get(n.path);if(!i){t.push(n.path),s.set(n.path,{first:n,last:n,edits:1,diffText:n.diffText});continue}i.last=n,i.edits++,n.oldText!=null||n.newText!=null?i.diffText=void 0:i.diffText||(i.diffText=n.diffText)}return t.map(n=>{const{first:i,last:r,edits:a,diffText:l}=s.get(n),c={path:n,name:$N(n),edits:a};if(i.oldText!=null||r.newText!=null){const u=i.oldText??"",h=r.newText??r.oldText??"",d=s_(u,h);return{...c,insertions:d.filter(p=>p.kind==="add").length,deletions:d.filter(p=>p.kind==="del").length,oldText:u,newText:h}}if(l){const u=RS(l);return{...c,insertions:u?.insertions??0,deletions:u?.deletions??0,oldText:"",newText:"",diffText:l}}return{...c,insertions:0,deletions:0,oldText:"",newText:""}})}function HN(e){let t=null,s=!1,n=[];function i(){const a=n;n=[];for(const l of a)l()}async function r(){if(!s){s=!0;try{for(;t;){const a=t;t=null;try{await e(a)}catch{}}}finally{s=!1,i()}}}return{push(a){t=a,r()},hush(){t=null,s||i()},get speaking(){return s},get waiting(){return t},settled(){return!s&&!t?Promise.resolve():new Promise(a=>{n.push(a)})}}}const jS="agentus.voice",kl={autoRead:!1,speakMode:"off",voiceURI:"",rate:1,lang:typeof navigator<"u"&&navigator.language?navigator.language:"en-US",serverTts:!1,stt:"auto"};function UN(){try{const e=localStorage.getItem(jS);if(!e)return{...kl};const t=JSON.parse(e),s=Number(t.rate);return{...kl,...t,rate:Number.isFinite(s)?Math.min(2,Math.max(.5,s)):kl.rate}}catch{return{...kl}}}function TS(e){try{localStorage.setItem(jS,JSON.stringify(e))}catch{}}const n_={provider:"browser",tts:{server:!1,model:null,voice:null},stt:{server:!1,streaming:!1,model:null,batchModel:null,language:null},hotwords:{fixed:0,dynamic:!1,limit:0}};let $o=null;const qp=new Set;async function Ch(e=!1){if($o&&!e)return $o;try{const t=await fetch("/api/voice",{credentials:"same-origin"});if(!t.ok)throw new Error(String(t.status));$o=await t.json()}catch{$o=n_}for(const t of qp)t();return $o}function li(){return $o??n_}function WN(e){return qp.add(e),()=>qp.delete(e)}const t0=80,AS=220,KN=2,qN=12,VN=3,s0=2,YN=400,af=0,GN=1,JN=4,XN=400,ZN=60;let lf=0;const Za=[];async function QN(e,t,s){lf>=VN&&await new Promise((n,i)=>{const r={priority:e,run:n};Za.push(r),Za.sort((l,c)=>l.priority-c.priority);const a=()=>{const l=Za.indexOf(r);l>=0&&Za.splice(l,1),i(new rn)};t&&(t.aborted?a():t.addEventListener("abort",a,{once:!0}))}),lf++;try{return await s()}finally{const n=Za.shift();n?n.run():lf--}}function n0(e,t=AS){const s=e.replace(/```[\s\S]*?```/g," code block ").replace(/[*_`#>|]/g," ").replace(/\s+/g," ").trim();if(!s)return[];const n=[];let i=s;for(;i.length>t;){const r=i.slice(0,t),a=Math.max(r.lastIndexOf(". "),r.lastIndexOf("。"),r.lastIndexOf("! "),r.lastIndexOf("? ")),l=Math.max(r.lastIndexOf(", "),r.lastIndexOf("; "),r.lastIndexOf(",")),c=a>t*.5?a+1:l>t*.5?l+1:r.lastIndexOf(" "),u=c>0?c:t;n.push(i.slice(0,u).trim()),i=i.slice(u).trim()}return i&&n.push(i),n.filter(Boolean)}let nn=null;function MS(){return window.AudioContext??window.webkitAudioContext??null}const Fl={echoCancellation:null,noiseSuppression:null};function eR(e,t){const s=e.getAudioTracks()[0],n=typeof s?.getSettings=="function"?s.getSettings():void 0;Fl.echoCancellation=typeof n?.echoCancellation=="boolean"?n.echoCancellation:t>0?!1:null,Fl.noiseSuppression=typeof n?.noiseSuppression=="boolean"?n.noiseSuppression:t>0?!1:null,Fl.echoCancellation===!1&&console.warn("[voice] microphone opened WITHOUT echo cancellation — the call may hear itself")}function i0(){return Fl.echoCancellation!==!1}function cf(){return{...Fl}}async function r0(e){const t=[e,{audio:{channelCount:1,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1}},{audio:!0}];let s=null;for(let n=0;n<t.length;n++)try{const i=await navigator.mediaDevices.getUserMedia(t[n]);return n>0&&console.warn("[voice] microphone opened only with degraded constraints",t[n]),eR(i,n),i}catch(i){s=i;const r=i?.name??"";if(r==="NotAllowedError"||r==="SecurityError")throw i;await new Promise(a=>setTimeout(a,250))}throw s instanceof Error?s:new Error(String(s))}async function tR(){const e=MS();if(!e)return!1;try{return nn=nn??new e,nn.state==="suspended"&&await nn.resume(),nn.state==="running"}catch{return!1}}const or={analyser:null};let cr=null;function o0(){const e=or.analyser;if(!e)return-1;const t=cr&&cr.length===e.fftSize?cr:new Float32Array(new ArrayBuffer(e.fftSize*4));cr=t,e.getFloatTimeDomainData(t);let s=0;for(let n=0;n<t.length;n++)s+=t[n]*t[n];return Math.min(1,Math.sqrt(s/t.length)*4)}function sR(){const e=or.analyser;if(!e)return-1;const t=cr&&cr.length===e.fftSize?cr:new Float32Array(new ArrayBuffer(e.fftSize*4));cr=t,e.getFloatTimeDomainData(t);let s=0;for(let n=0;n<t.length;n++)s+=t[n]*t[n];return Math.min(1,Math.sqrt(s/t.length))}function nR(e){const t=or.analyser;if(!t)return!1;const s=new Float32Array(new ArrayBuffer(t.fftSize*4));t.getFloatTimeDomainData(s);const n=Math.max(1,Math.floor(s.length/e.length));for(let i=0,r=0;i<e.length;i++,r+=n)e[i]=s[r]??0;return!0}class rn extends Error{constructor(){super("stopped"),this.name="SpeechStopped"}}async function DS(e,t){const s=MS();if(s)try{nn=nn??new s,nn.state==="suspended"&&await nn.resume();const i=await nn.decodeAudioData(await e.arrayBuffer());await new Promise((r,a)=>{const l=nn.createBufferSource();l.buffer=i;const c=nn.createAnalyser();c.fftSize=512,l.connect(c),c.connect(nn.destination),or.analyser=c,l.onended=()=>{or.analyser===c&&(or.analyser=null),r()};const u=()=>{or.analyser===c&&(or.analyser=null);try{l.stop()}catch{}a(new rn)};if(t){if(t.aborted)return u();t.addEventListener("abort",u,{once:!0})}l.start()});return}catch(i){if(i instanceof rn)throw i;if(t?.aborted)throw new rn}const n=URL.createObjectURL(e);try{await new Promise((i,r)=>{const a=new Audio(n),l=()=>{try{a.pause()}catch{}r(new rn)};a.onended=()=>{c(),i()},a.onerror=()=>{c(),r(new Error("audio playback failed"))};const c=()=>{t&&t.removeEventListener("abort",l)};if(t){if(t.aborted)return l();t.addEventListener("abort",l,{once:!0})}a.play().catch(u=>{c(),r(new Error(String(u?.message??u)))})})}finally{URL.revokeObjectURL(n)}}function Qa(){return typeof window<"u"&&"speechSynthesis"in window}class iR{#e={speakingId:null,speaking:!1,error:"",note:""};#l=new Set;#i=null;#s=0;#o=!1;#t=[];#n=new Set;subscribe=t=>(this.#l.add(t),()=>this.#l.delete(t));getSnapshot=()=>this.#e;#c(t){this.#e={...this.#e,...t};for(const s of this.#l)s()}subscribeVoices=t=>(this.#n.add(t),()=>this.#n.delete(t));voices=()=>this.#t;init(){if(!Qa())return;const t=()=>{const i=window.speechSynthesis.getVoices();if(i.length!==this.#t.length){this.#t=i;for(const r of this.#n)r()}};t(),window.speechSynthesis.addEventListener("voiceschanged",t);let s=0;const n=window.setInterval(()=>{s+=1,t(),(this.#t.length||s>40)&&window.clearInterval(n)},250);window.addEventListener("pointerdown",t,{once:!0})}pickVoice(t){const s=this.#t.length?this.#t:Qa()?window.speechSynthesis.getVoices():[];if(!s.length)return null;if(t.voiceURI){const r=s.find(a=>a.voiceURI===t.voiceURI);if(r)return r}const n=t.lang.toLowerCase(),i=n.split("-")[0];return s.find(r=>r.lang.toLowerCase()===n)??s.find(r=>r.lang.toLowerCase().startsWith(i))??s.find(r=>r.default)??s[0]}async speak(t,s,n){const i=String(t??"").trim();if(!i)return;this.stop();const r=++this.#s;this.#o=!1;const a=n.serverTts&&li().tts.server,l=n0(i,a?t0:AS);if(!l.length)return;const c=new AbortController;this.#i=c,this.#c({error:"",note:"",speakingId:s,speaking:!0});try{a?await this.#v(l,n,c.signal):await this.#h(l,n,c.signal)}catch(u){if(this.#o||r!==this.#s||u instanceof rn||u?.name==="AbortError")return;if(n.serverTts&&Qa()){this.#c({note:`服务端语音这一句失败了(${String(u?.message??u)}),已改用浏览器语音`});try{await this.#h(l,n,c.signal);return}catch(h){if(this.#o||h instanceof rn)return;this.#c({error:String(h?.message??h)})}}else this.#c({error:String(u?.message??u)})}finally{this.#i===c&&(this.#i=null),r===this.#s&&this.#c({speaking:!1,speakingId:null})}}async#h(t,s,n){if(!Qa())throw new Error("this browser has no speech synthesis");const i=window.speechSynthesis,r=this.pickVoice(s);for(const[a,l]of t.entries()){if(n?.aborted)throw new rn;if(await new Promise((c,u)=>{const h=new SpeechSynthesisUtterance(l);r?(h.voice=r,h.lang=r.lang):h.lang=s.lang,h.rate=s.rate,h.onend=()=>c(),h.onerror=d=>u(new Error(`speech error: ${d.error??"unknown"}`)),i.speak(h),a===0&&i.resume()}),n?.aborted)throw new rn;i.paused&&i.resume()}}#_(t,s,n,i){return QN(i,n,async()=>{const r=await fetch("/api/tts",{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},signal:n,body:JSON.stringify({text:t,speed:s.rate})});if(!r.ok){const a=await r.json().catch(()=>({error:`${r.status}`}));throw new Error(a.error??`tts ${r.status}`)}return await r.blob()})}async#p(t,s,n,i=af){let r=null;for(let a=0;a<=s0;a++){if(n?.aborted)throw new rn;try{return await this.#_(t,s,n,i)}catch(l){if(l instanceof rn||l?.name==="AbortError"||n?.aborted)throw l;r=l,a<s0&&await new Promise(c=>{window.setTimeout(c,YN*(a+1))})}}throw r instanceof Error?r:new Error(String(r))}#d=new Map;#f(t,s){return`${s.rate}|${li().tts.voice??""}|${t}`}prefetch(t,s){if(!(s.serverTts&&li().tts.server))return;const n=String(t??"").trim();if(n)for(const i of n0(n,t0)){const r=this.#f(i,s);if(this.#d.has(r))continue;const a=this.#p(i,s,void 0,GN);for(a.catch(()=>{}),this.#d.set(r,a);this.#d.size>qN;){const l=this.#d.keys().next().value;if(l===void 0)break;this.#d.delete(l)}}}async#v(t,s,n){const i=[],r=a=>{const l=this.#f(a,s),c=this.#d.get(l);if(c)return this.#d.delete(l),c.catch(()=>this.#p(a,s,n,af));const u=this.#p(a,s,n,af);return u.catch(()=>{}),u};for(let a=0;a<t.length;a++){if(n.aborted)throw new rn;for(;i.length<Math.min(KN,t.length-a);)i.push(r(t[a+i.length]));if(await DS(await i.shift(),n),n.aborted)throw new rn}}stop(){this.#o=!0,this.#i?.abort(),this.#i=null,Qa()&&window.speechSynthesis.cancel(),this.#e.speaking&&this.#c({speaking:!1,speakingId:null})}}const Ft=new iR;Ft.init();function dd(){return g.useSyncExternalStore(Ft.subscribe,Ft.getSnapshot)}const el=new Set,rR=1024,IS=HN(e=>Ft.speak(e.text,e.key,Hn));function uc(){IS.hush(),Ft.stop()}function oR(e){IS.push({key:e.key,text:e.text})}let i_=!1;function a0(e){i_=e}function Eh(){return i_}function aR(e,t,s){if(i_||!s||el.has(e))return!1;for(el.add(e);el.size>rR;){const n=el.values().next().value;if(n===void 0)break;el.delete(n)}return!0}function PS(){const e=window;return e.SpeechRecognition??e.webkitSpeechRecognition??null}function Vp(){return!!PS()}function LS(){const e=window.AgentusMic;return e&&typeof e.start=="function"&&typeof e.stop=="function"?e:null}function OS(){const e=LS();if(!e)return!1;try{return!!e.available()}catch{return!1}}function lR(){return OS()||typeof navigator.mediaDevices?.getUserMedia=="function"}function cR(){return typeof window<"u"&&!window.isSecureContext?"当前页面是明文 http,浏览器不允许网页录音。请改用 https 入口访问(在服务前放一层终结 TLS 的反代或隧道),或走本机 localhost;手机上也可以用 Agentus app。":"this browser cannot record audio"}function uR(){return new Promise(e=>{const t=document.createElement("input");t.type="file",t.accept="audio/*",t.setAttribute("capture","microphone"),t.style.position="fixed",t.style.left="-9999px";let s=!1;const n=i=>{s||(s=!0,t.remove(),e(i))};t.onchange=()=>n(t.files?.[0]??null),window.addEventListener("focus",()=>{window.setTimeout(()=>n(t.files?.[0]??null),600)},{once:!0}),document.body.appendChild(t),t.click()})}class hR{#e={status:"idle",text:"",interim:"",error:"",engine:null,seconds:0};#l=new Set;#i=null;#s=null;#o=[];#t=null;#n=null;#c=null;#h=null;#_=null;#p=null;#d="";#f=0;#v=0;#b=new Float32Array(256);#D=null;#x=!0;#I;#k=!1;#a=0;#m=[];#S=null;#C=0;#y="";#w=!1;#E=()=>{const t=globalThis.__asFeed;return t&&typeof t=="object"?t:null};level=()=>{const t=this.#E();if(!t)return this.#f;const s=Number(t.level);return Number.isFinite(s)?s:0};levelRms=()=>{const t=this.#E();if(!t)return this.#v;const s=Number(t.rms??(Number.isFinite(Number(t.level))?Number(t.level)/6:NaN));return Number.isFinite(s)?Math.max(0,s):0};wave=()=>this.#b;setVadTap=t=>{this.#D=t};setRelay(t){if(this.#x=t,!t){this.#w=!0,this.#$();return}this.#w=!1,this.#k&&this.#N()}#$(){this.#S!==null&&(window.clearTimeout(this.#S),this.#S=null);const t=this.#n;if(this.#n=null,this.#m.length=0,!!t){t.onmessage=null,t.onerror=null,t.onclose=null;try{t.close()}catch{}}}resetText(){this.#d="",this.#r({text:"",interim:""})}commitForTest(t){this.#d=`${this.#d}${t}`.replace(/\s+/g," ").trim(),this.#r({status:"idle",text:this.#d,interim:""})}#T(t){let s=0;for(let a=0;a<t.length;a++)s+=t[a]*t[a];const n=Math.sqrt(s/t.length),i=Math.min(1,n*6);this.#f=i>this.#f?this.#f+(i-this.#f)*.6:this.#f*.72+i*.28,this.#v=n>this.#v?this.#v+(n-this.#v)*.6:this.#v*.72+n*.28,this.#D?.(t);const r=Math.max(1,Math.floor(t.length/this.#b.length));for(let a=0,l=0;a<this.#b.length&&l<t.length;a++,l+=r)this.#b[a]=t[l]}subscribe=t=>(this.#l.add(t),()=>this.#l.delete(t));#P=null;getSnapshot=()=>{const t=this.#E();if(!t)return this.#e;const s=String(t.text??""),n=String(t.interim??""),i=this.#P;return i&&i.text===s&&i.interim===n&&i.status===this.#e.status&&i.error===this.#e.error&&i.engine===this.#e.engine&&i.seconds===this.#e.seconds?i:(this.#P={...this.#e,text:s,interim:n},this.#P)};#r(t){this.#e={...this.#e,...t};for(const s of this.#l)s()}async start(t,s){if(this.#e.status!=="idle"&&this.#e.status!=="error")return!1;uc();const n=++this.#a;this.#r({status:"idle",text:"",interim:"",error:"",seconds:0}),this.#d="";const i=this.#E();if(i)return this.#x=!0,this.#r({status:"listening",engine:"stream",error:"",text:String(i.text??""),interim:String(i.interim??"")}),!0;const r=t.stt,a=li().stt.server,l=li().stt.streaming,c=(r==="browser"||r==="auto")&&Vp();try{if(r==="stream"||r==="auto"&&l){if(!l)throw new Error("streaming STT is not configured on the server (settings → 语音)");return await this.#L(t,s,n),!0}return c?(this.#H(t),!0):a?(await this.#K(t,n),!0):(this.#r({status:"error",engine:null,error:(typeof window<"u"&&!window.isSecureContext&&!lR()?`${cR()} `:"")+(r==="server"||a?"no dictation available: this browser has no speech recognition and the server has no STT endpoint (AGENTUS_STT_BASE_URL)":"no dictation available in this browser — set the server STT endpoint or use Chromium/Edge")}),!1)}catch(u){return this.#R(n)||this.#r({status:"error",error:String(u?.message??u)}),!1}}#H(t){const s=PS();if(!s)throw new Error("speech recognition unavailable");const n=new s;n.lang=t.lang,n.continuous=!0,n.interimResults=!0,n.maxAlternatives=1;let i="";n.onstart=()=>this.#r({status:"listening",engine:"browser",error:""}),n.onresult=r=>{let a="";for(let l=r.resultIndex;l<r.results.length;l+=1){const c=r.results[l],u=c[0]?.transcript??"";c.isFinal?i+=u:a+=u}this.#r({text:i.trim(),interim:a.trim()})},n.onerror=r=>{const a=String(r?.error??"unknown");this.#r({status:"error",error:a==="not-allowed"||a==="service-not-allowed"?"microphone permission denied":a==="no-speech"?"heard nothing — try again closer to the microphone":`speech recognition failed: ${a}`})},n.onend=()=>{this.#e.status==="listening"&&this.#r({status:"idle",interim:""}),this.#i=null},this.#i=n,this.#r({status:"requesting",engine:"browser"});try{n.start()}catch(r){throw this.#i=null,new Error(String(r?.message??r))}}async#L(t,s,n){const i=OS()?LS():null;if(!i&&typeof navigator.mediaDevices?.getUserMedia!="function"){await this.#u(t);return}const r=window.AudioContext??window.webkitAudioContext;if(!i&&!r)throw new Error("this browser cannot process audio");this.#r({status:"requesting",engine:"stream",error:""}),this.#x=!0,this.#w=!1,this.#C=0,this.#y="",this.#I=s,this.#k=!0,this.#m.length=0,this.#N();const a=l=>this.#U(l);if(i?await this.#F(i,a,n):await this.#W(r,a,n),this.#R(n)){this.#A(),this.#O(),this.#r({status:"idle",interim:"",text:""});return}this.#r({status:"listening",engine:"stream",seconds:0}),this.#t=window.setInterval(()=>this.#r({seconds:this.#e.seconds+1}),1e3)}#U(t){const s=this.#n;s&&s.readyState===WebSocket.OPEN?s.send(t):this.#m.length<ZN&&this.#m.push(t)}#N(){if(this.#n||!this.#k)return;const t=this.#I?`?sessionId=${encodeURIComponent(this.#I)}`:"",s=new WebSocket(`${location.protocol==="https:"?"wss":"ws"}://${location.host}/ws/asr${t}`);s.binaryType="arraybuffer",this.#n=s,s.onopen=()=>{this.#C=0,this.#y="";for(const n of this.#m)s.send(n);this.#m.length=0,this.#e.status!=="listening"&&this.#r({status:"listening",engine:"stream",error:""})},s.onmessage=n=>{let i;try{i=JSON.parse(String(n.data))}catch{return}i.t==="asr-partial"?this.#r({interim:String(i.text??"")}):i.t==="asr-final"?(this.#d=`${this.#d}${i.text??""}`.replace(/\s+/g," ").trim(),this.#r({text:this.#d,interim:""})):i.t==="asr-error"?this.#g(String(i.error??"streaming asr failed")):i.t==="asr-done"&&(this.#w||!this.#k||!this.#x?this.#j():this.#g("the recogniser ended the turn by itself"))},s.onerror=()=>this.#g("the streaming socket failed — is the server up?"),s.onclose=()=>{this.#n===s&&(this.#n=null),this.#g(this.#y||"the streaming socket failed — is the server up?")}}#g(t){if(!(!this.#k||this.#w||!this.#x)&&(this.#y||(this.#y=t),this.#S===null)){if(this.#C>=JN){this.#r({status:"error",error:this.#y}),this.#y="",this.#j();return}this.#C+=1,this.#S=window.setTimeout(()=>{this.#S=null,this.#N()},XN*this.#C)}}async#W(t,s,n){const i=await r0({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}});if(this.#R(n)){for(const u of i.getTracks())u.stop();return}this.#_=i;const r=new t({sampleRate:16e3});this.#c=r;const a=r.createMediaStreamSource(i),l=r.createScriptProcessor(2048,1,1),c=r.createGain();c.gain.value=0,this.#h=l,l.onaudioprocess=u=>{const h=u.inputBuffer.getChannelData(0);if(this.#T(h),!this.#x)return;const d=BS(h,r.sampleRate,16e3);d.length&&s(d.buffer)},a.connect(l),l.connect(c),c.connect(r.destination)}async#F(t,s,n){let i="permission";for(let r=0;r<12&&(i=String(t.start(16e3)),!(i==="ok"||i==="already"));r++){if(i==="permission"){this.#r({status:"requesting",engine:"stream"}),await new Promise(a=>setTimeout(a,600));continue}throw new Error(`手机上的原生麦克风打不开(${i})`)}if(i!=="ok"&&i!=="already")throw new Error(`手机上的原生麦克风打不开(${i})`);if(this.#R(n)){try{t.stop()}catch{}return}this.#p=t,window.__asMic=r=>{const a=atob(r),l=a.length>>1,c=new Int16Array(l);for(let h=0;h<l;h++){const d=a.charCodeAt(2*h),p=a.charCodeAt(2*h+1);c[h]=(p<<8|d)<<16>>16}const u=new Float32Array(l);for(let h=0;h<l;h++)u[h]=c[h]/32768;this.#T(u),this.#x&&s(c.buffer)}}#O(){this.#$(),this.#k=!1,this.#w=!1,this.#C=0,this.#y="",this.#A(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#x=!0}#R(t){return t!==this.#a}#A(){if(this.#h){this.#h.onaudioprocess=null;try{this.#h.disconnect()}catch{}this.#h=null}if(this.#c&&(this.#c.close().catch(()=>{}),this.#c=null),this.#_){for(const t of this.#_.getTracks())t.stop();this.#_=null}if(this.#p){try{this.#p.stop()}catch{}this.#p=null}window.__asMic=void 0,this.#f=0,this.#b.fill(0)}#j(){this.#O(),this.#r({status:"idle",interim:""})}async#K(t,s){if(typeof navigator.mediaDevices?.getUserMedia!="function"){await this.#u(t);return}this.#r({status:"requesting",engine:"server",error:""});const n=await r0({audio:!0});if(this.#R(s)){for(const a of n.getTracks())a.stop();return}const i=MediaRecorder.isTypeSupported("audio/webm;codecs=opus")?"audio/webm;codecs=opus":"",r=new MediaRecorder(n,i?{mimeType:i}:void 0);this.#o=[],r.ondataavailable=a=>{a.data.size&&this.#o.push(a.data)},r.onstop=()=>{for(const a of n.getTracks())a.stop();this.#q(t)},this.#s=r,r.start(1e3),this.#r({status:"recording",engine:"server",seconds:0}),this.#t=window.setInterval(()=>this.#r({seconds:this.#e.seconds+1}),1e3)}async#u(t){this.#r({status:"requesting",engine:"server",error:""});const s=await uR();if(!s){this.#r({status:"idle",text:"",interim:"",error:""});return}await this.#M(t,s)}async#M(t,s){this.#r({status:"transcribing"});try{const n=await fetch(`/api/stt?language=${encodeURIComponent(t.lang)}`,{method:"POST",credentials:"same-origin",headers:{"content-type":s.type||"audio/webm"},body:s}),i=await n.json().catch(()=>({}));if(!n.ok)throw new Error(i.error??`stt ${n.status}`);this.#r({status:"idle",text:String(i.text??"").trim(),interim:""})}catch(n){this.#r({status:"error",error:String(n?.message??n)})}}async#q(t){this.#t&&(window.clearInterval(this.#t),this.#t=null);const s=new Blob(this.#o,{type:this.#o[0]?.type||"audio/webm"});if(this.#o=[],this.#s=null,!s.size){this.#r({status:"error",error:"nothing was recorded — check the microphone"});return}await this.#M(t,s)}stop(){if(this.#a+=1,this.#e.status==="requesting"){this.cancel();return}if(this.#i){try{this.#i.stop()}catch{}return}if(this.#n&&this.#n.readyState===WebSocket.OPEN){this.#A(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#w=!0,this.#r({status:"transcribing"});try{this.#n.send(JSON.stringify({t:"asr-stop"}))}catch{this.#j();return}window.setTimeout(()=>{this.#e.status==="transcribing"&&this.#j()},8e3);return}this.#s&&this.#s.state!=="inactive"&&this.#s.stop(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#e.status==="listening"&&this.#r({status:"idle",interim:""})}cancel(){if(this.#a+=1,this.#i){try{this.#i.abort()}catch{}this.#i=null}this.#s&&this.#s.state!=="inactive"&&(this.#s.onstop=null,this.#s.stop(),this.#s=null),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#O(),this.#d="",this.#o=[],this.#r({status:"idle",text:"",interim:"",error:"",seconds:0})}consume(){const t=this.#e.text.trim();return this.#r({status:"idle",text:"",interim:"",seconds:0}),t}setOwner(t){this.#z=t}owns(t){return this.#z===t}#z="chat"}function BS(e,t,s){if(t===s){const a=new Int16Array(e.length);for(let l=0;l<e.length;l+=1)a[l]=l0(e[l]);return a}const n=t/s,i=Math.max(0,Math.floor(e.length/n)),r=new Int16Array(i);for(let a=0;a<i;a+=1){const l=a*n,c=Math.floor(l),u=Math.min(c+1,e.length-1),h=l-c;r[a]=l0(e[c]*(1-h)+e[u]*h)}return r}function l0(e){const t=Math.round((Number.isFinite(e)?e:0)*32767);return t>32767?32767:t<-32768?-32768:t}const pe=new hR;typeof window<"u"&&(window.__asDictation=pe);function r_(){return g.useSyncExternalStore(pe.subscribe,pe.getSnapshot)}let Hn=UN();const Nh=new Set;async function $S(){try{const e=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({prefs:Hn})});return e.ok?"":(await e.json().catch(()=>({}))).error??`save failed (${e.status})`}catch(e){return String(e?.message??e)}}function c0(e){const t={...kl};if(!e||typeof e!="object")return t;const s=e;return{autoRead:typeof s.autoRead=="boolean"?s.autoRead:t.autoRead,speakMode:s.speakMode==="off"||s.speakMode==="reply"||s.speakMode==="brief"?s.speakMode:typeof s.autoRead=="boolean"&&s.autoRead?"reply":"off",voiceURI:typeof s.voiceURI=="string"?s.voiceURI:t.voiceURI,rate:Number.isFinite(Number(s.rate))?Math.min(2,Math.max(.5,Number(s.rate))):t.rate,lang:typeof s.lang=="string"&&s.lang?s.lang:t.lang,serverTts:typeof s.serverTts=="boolean"?s.serverTts:t.serverTts,stt:s.stt==="browser"||s.stt==="stream"||s.stt==="server"?s.stt:"auto"}}function dR(e){Hn=e,TS(Hn);for(const t of Nh)t()}async function fR(){try{const e=await fetch("/api/settings",{credentials:"same-origin"});if(!e.ok)return;const t=await e.json(),s=c0(t.prefs),n=c0(t.prefsDefaults);if(uf.every(r=>s[r]===n[r])&&uf.some(r=>Hn[r]!==s[r])){$S();return}uf.some(r=>Hn[r]!==s[r])&&dR(s)}catch{}}const uf=["speakMode","voiceURI","rate","lang","serverTts","stt"];function pR(e){const t={...Hn,...e},s=Number.isFinite(t.rate)?Math.min(2,Math.max(.5,t.rate)):1;Hn={...t,rate:s},TS(Hn);for(const n of Nh)n();$S()}function mR(){return Hn}function _o(){return[g.useSyncExternalStore(t=>(Nh.add(t),()=>Nh.delete(t)),()=>Hn),pR]}function gR(e,t,s){const[n]=_o(),i=(s??n.speakMode??(n.autoRead?"reply":"off"))==="reply",r=e?.length?e.map(a=>a.key).join(""):"";g.useEffect(()=>{if(!(!i||!t||!e?.length))for(const a of e)a.text.trim()&&aR(a.key,!0,i)&&oR(a)},[r,t,i])}function _R(e,t,s){const[n]=_o(),i=(s??n.speakMode??(n.autoRead?"reply":"off"))==="brief";g.useEffect(()=>{!i||!t||!e||!e.text.trim()||Ft.speak(e.text,e.key,n)},[e?.key,t,i])}const Fo=2,Yp="agentus.webnotify",tr={on:!0,sound:"chime",volume:.6};function vR(e){return e.available&&e.permission==="granted"&&e.enabled&&e.hidden}function yR(e,t,s,n){return e.sound!=="chime"||n||!s.enabled||!s.hidden?!1:t==="approval"||t==="agent_done"||t==="error"}function bR(e){return e==="approval"?[{freq:659.25,at:0,dur:.13},{freq:987.77,at:.15,dur:.28}]:e==="error"?[{freq:739.99,at:0,dur:.11},{freq:1046.5,at:.12,dur:.13},{freq:739.99,at:.27,dur:.26}]:[{freq:880,at:0,dur:.16},{freq:659.25,at:.2,dur:.3}]}function wR(e){try{return new URL(e,typeof location>"u"?"http://localhost/":location.href).searchParams.get("session")}catch{return null}}function xR(){try{const e=localStorage.getItem(Yp);if(!e)return{...tr,v:Fo};const t=JSON.parse(e),s={on:typeof t.on=="boolean"?t.on:tr.on,sound:t.sound==="chime"||t.sound==="silent"||t.sound==="default"?t.sound:tr.sound,volume:typeof t.volume=="number"&&Number.isFinite(t.volume)?Math.min(1,Math.max(0,t.volume)):tr.volume};if(t.v!==Fo&&s.sound==="default"&&(s.sound=tr.sound),t.v!==Fo){s.v=Fo;try{localStorage.setItem(Yp,JSON.stringify(s))}catch{}}return s}catch{return{...tr,v:Fo}}}function hu(){return typeof window>"u"||!("Notification"in window)?"no-api":window.isSecureContext?"ok":"insecure"}let hf=null;function FS(){if(typeof window>"u")return null;const e=window.AudioContext??window.webkitAudioContext;if(!e)return null;if(!hf)try{hf=new e}catch{return null}return hf}function ca(){const e=FS();e&&e.state==="suspended"&&e.resume()}function SR(e,t,s,n,i){const r=e.createOscillator(),a=e.createGain();r.type="sine",r.frequency.value=t,a.gain.setValueAtTime(1e-4,s),a.gain.linearRampToValueAtTime(i,s+.012),a.gain.exponentialRampToValueAtTime(1e-4,s+n),r.connect(a),a.connect(e.destination),r.start(s),r.stop(s+n+.02)}function Gp(e,t){const s=FS();if(!s)return;s.state==="suspended"&&s.resume();const n=s.currentTime+.01;for(const i of bR(t))SR(s,i.freq,n+i.at,i.dur,e)}const Jp=new Map;let Xp=0;async function zS(){if(typeof navigator>"u"||!("serviceWorker"in navigator))return null;try{return await navigator.serviceWorker.getRegistration()??null}catch{return null}}let Zp=null;function kR(e){Zp=e}function HS(e){if(!e)return;const t=wR(e);if(t&&Zp){Zp(t);return}location.assign(e)}const u0="/icons/icon-192.png";async function h0(e,t){const s={body:e.body,tag:e.noticeId,icon:u0,badge:u0,data:{open:e.open??null,noticeId:e.noticeId},renotify:!0,requireInteraction:!!e.sticky,silent:t.sound!=="default"},n=await zS();if(n&&typeof n.showNotification=="function")try{return await n.showNotification(e.title,s),Xp=Date.now(),!0}catch{}try{const i=new Notification(e.title,s);return i.onclick=()=>{HS(e.open),i.close()},Jp.set(e.noticeId,i),Xp=Date.now(),!0}catch{return!1}}async function d0(e){const t=Jp.get(e);t&&(t.close(),Jp.delete(e));const s=await zS();if(!(!s||typeof s.getNotifications!="function"))try{for(const n of await s.getNotifications({tag:e}))n.close()}catch{}}class CR{#e=tr;#l=null;#i=new Set;#s;constructor(){this.#e=typeof localStorage>"u"?{...tr}:xR(),this.#s=this.#o()}#o(){const t=hu();return{availability:t,permission:t==="ok"?Notification.permission:"unavailable",prefs:this.#e,last:this.#l}}#t(){this.#s=this.#o();for(const t of this.#i)t()}subscribe=t=>(this.#i.add(t),()=>this.#i.delete(t));getSnapshot=()=>this.#s;setPrefs(t){this.#e={...this.#e,...t},t.volume!==void 0&&(this.#e.volume=Math.min(1,Math.max(0,t.volume)));try{localStorage.setItem(Yp,JSON.stringify({...this.#e,v:Fo}))}catch{}this.#t()}async requestPermission(){if(hu()!=="ok")return"unavailable";ca();try{const t=await Notification.requestPermission();return this.#t(),this.#o().permission}catch{return this.#o().permission}}handle(t){if(t.op==="dismiss"){d0(t.noticeId);return}const s=hu(),n={available:s==="ok",permission:s==="ok"?Notification.permission:"unavailable",enabled:this.#e.on,hidden:typeof document>"u"?!1:document.hidden},i={enabled:this.#e.on,hidden:typeof document>"u"?!1:document.hidden};yR(this.#e,t.kind,i,Eh())&&Gp(this.#e.volume,t.kind),vR(n)&&h0(t,this.#e).then(r=>{this.#l={title:t.title,at:Date.now(),drawn:r},this.#t()})}async test(){if(hu()!=="ok")return!1;ca();const t={op:"upsert",noticeId:`test:${Date.now()}`,kind:"agent_done",title:"测试通知",body:"这条通知能弹出来,就说明这台设备没问题",open:null,at:Date.now()},s=await h0(t,this.#e);return this.#l={title:t.title,at:Date.now(),drawn:s},this.#t(),this.#e.sound==="chime"&&!Eh()&&Gp(this.#e.volume,"agent_done"),s}async closeAll(t){for(const s of t)await d0(s)}lastDrawnAt(){return Xp}}const Si=new CR;function ER(){typeof navigator>"u"||!("serviceWorker"in navigator)||navigator.serviceWorker.addEventListener("message",e=>{const t=e.data;t?.t==="agentus:notify-open"&&HS(t.open??null)})}function NR(){return g.useSyncExternalStore(Si.subscribe,Si.getSnapshot)}class df extends Error{constructor(){super("unauthorized"),this.name="AuthRequired"}}const Qp="agentus.unread",RR=8e3,jR=8e3;function TR(){try{const e=localStorage.getItem(Qp),t=e?JSON.parse(e):[];return Array.isArray(t)?t.filter(s=>typeof s=="string"):[]}catch{return[]}}function AR(e){try{const t=[...e];t.length?localStorage.setItem(Qp,JSON.stringify(t)):localStorage.removeItem(Qp)}catch{}}class MR{sessions=[];cold=[];archived=[];byId=new Map;activeId=null;conn="connecting";net="ok";netError="";auth="unknown";authInfo=null;authError="";authBusy=!1;blocked=null;lastSeq={};ws=null;#e=0;#l=null;#i=[];#s=new Map;#o=new Map;#t=new Set;#n=new Map;#c=new Set;#h=new Set(TR());#_=new Set;#p=new Map;#d=new Set;#f=null;#v;#b(t){try{t?localStorage.setItem("agentus.active",t):localStorage.removeItem("agentus.active")}catch{}}#D(){try{return new URL(location.href).searchParams.get("session")}catch{return null}}#x(t){try{const s=new URL(location.href),n=t??null;if((s.searchParams.get("session")??null)===n)return;n?s.searchParams.set("session",n):s.searchParams.delete("session"),history.replaceState(history.state,"",s.toString())}catch{}}followUrl(){const t=this.#D();!t||t===this.activeId||this.byId.has(t)&&this.setActive(t)}#I(){const t=this.#D();if(t)return this.#b(t),t;try{return localStorage.getItem("agentus.active")}catch{return null}}#k=0;constructor(){this.#v=this.#w()}async#a(t,s,n){const i=n?.timeoutMs??15e3,r=n?.retry===!1?1:2;let a=null;for(let l=0;l<r;l++){const c=new AbortController,u=setTimeout(()=>c.abort(),i);try{const h=await fetch(t,{...s,signal:c.signal});if(clearTimeout(u),h.status===401)throw this.#S("会话已过期,请重新登录"),new df;const d=h.status===204?null:await h.json().catch(()=>null);if(!h.ok){const p=d?.error??`HTTP ${h.status}`,f=new Error(p);throw f.httpStatus=h.status,f.httpBody=d,f}return this.#m(!0,""),d}catch(h){if(clearTimeout(u),h instanceof df||h.httpStatus!==void 0)throw h;a=h;const d=h?.name==="AbortError"?`请求超时 ${i/1e3}s`:String(h?.message??h);if(l===r-1)throw this.#m(!1,`${d} (${t})`),new Error(d);await new Promise(p=>setTimeout(p,600))}}throw a instanceof Error?a:new Error(String(a))}#m(t,s){const n=t?"ok":"degraded";this.net===n&&this.netError===s||(this.net=n,this.netError=s,this.bump())}#S(t){const s=this.auth==="in";if(this.auth="out",this.authError=s?t:this.authError,this.ws){const n=this.ws;this.ws=null,n.onclose=null;try{n.close()}catch{}}this.conn="offline",(s||this.sessions.length)&&(this.sessions=[],this.cold=[],this.archived=[],this.byId.clear(),this.activeId=null,this.#b(null)),this.bump()}async checkAuth(){try{const t=await this.#a("/api/auth/me",void 0,{retry:!1,timeoutMs:8e3});if(this.authInfo=t,t.authEnabled&&!t.authenticated){this.#S(""),this.authError="";return}this.#e=0,this.auth="in",this.authError="",this.bump(),this.connect(),this.refreshRows()}catch(t){if(t instanceof df)return;const s=`无法连接服务端:${String(t.message??t)}`;if(this.auth==="in"){this.#m(!1,s),this.#C(Math.min(1e4,800*2**this.#e++));return}this.auth="out",this.authError=s,this.bump()}}#C(t){this.#l||(this.#l=setTimeout(()=>{this.#l=null,this.checkAuth()},t))}async login(t,s){if(this.authBusy)return!1;this.authBusy=!0,this.authError="",this.bump();try{const n=await fetch("/api/auth/login",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({username:t,password:s})});if(n.status===401)return this.authError="用户名或密码不正确",!1;if(n.status===429){const r=await n.json().catch(()=>({})),a=Math.ceil((r.retryAfterMs??3e4)/1e3);return this.authError=`尝试次数过多,请 ${a} 秒后再试`,!1}if(!n.ok)return this.authError=`登录失败:HTTP ${n.status}`,!1;const i=await n.json();return this.authInfo={authEnabled:!0,authenticated:!0,kind:"session",username:i.username,expiresAt:i.expiresAt??null,usingDefaultPassword:!!i.usingDefaultPassword},this.auth="in",this.authError="",this.bump(),this.connect(),!0}catch(n){return this.authError=`登录请求失败:${String(n.message??n)}`,!1}finally{this.authBusy=!1,this.bump()}}async logout(){try{await fetch("/api/auth/logout",{method:"POST"})}catch{}this.#S(""),this.authError="",this.bump()}subscribe=t=>(this.#d.add(t),()=>this.#d.delete(t));getSnapshot=()=>this.#v;markPermAnswered(t,s,n=!0){this.#p.set(t,{label:s,at:Date.now(),armed:n}),this.bump()}permAnswer(t){const s=this.#p.get(t);if(s)return{label:s.label,at:s.at,lapsed:s.armed&&Date.now()-s.at>RR}}#y(){if(!this.#p.size)return;const t=new Set;for(const s of this.byId.values())for(const n of s.perms)t.add(n.requestId);for(const s of[...this.#p.keys()])t.has(s)||this.#p.delete(s)}#w(){return{sessions:this.sessions,cold:this.cold,archived:this.archived,activeId:this.activeId,active:this.activeId?this.byId.get(this.activeId):void 0,conn:this.conn,net:this.net,netError:this.netError,auth:this.auth,authInfo:this.authInfo,authError:this.authError,authBusy:this.authBusy,blocked:this.blocked,unread:new Set([...this.#c,...this.#h]),version:this.#k}}bump(){this.#k++,this.#f==null&&(typeof requestAnimationFrame=="function"?this.#f=requestAnimationFrame(()=>{this.#f=null,this.#E()}):typeof setTimeout=="function"?this.#f=setTimeout(()=>{this.#f=null,this.#E()},0):this.#E()),this.#$()}#E(){this.#f!=null&&(typeof cancelAnimationFrame=="function"?cancelAnimationFrame(this.#f):typeof clearTimeout=="function"&&clearTimeout(this.#f),this.#f=null);for(const t of this.byId.values())t.busy=t.info.status==="running";this.#v=this.#w();for(const t of this.#d)t()}#$(){typeof document>"u"||!document.hidden||this.#f!=null&&this.#E()}connect(){if(this.auth==="out")return;const t=location.protocol==="https:"?"wss":"ws",s=new WebSocket(`${t}://${location.host}/ws`);this.ws=s,s.onopen=()=>{for(this.conn="online",this.net="ok",this.netError="",this.#e=0,s.send(JSON.stringify({t:"resume",lastSeq:this.lastSeq}));this.#i.length;){const n=this.#i.shift();try{s.send(JSON.stringify(n))}catch{this.#i.unshift(n);break}}this.bump(),this.refreshRows(),window.setTimeout(()=>this.drainPersistedQueues(),700)},s.onmessage=n=>this.apply(JSON.parse(n.data)),s.onclose=()=>{if(this.conn="offline",this.bump(),this.auth==="out")return;const n=Math.min(1e4,800*2**this.#e++);this.#C(n)},s.onerror=()=>s.close()}sendPrompt(t,s,n=[]){!s.trim()&&!n.length||this.#T(t,{text:s,attachments:n})}#T(t,s){const n=`p-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,i={t:"prompt",sessionId:t,text:s.text,attachments:s.attachments,pid:n,...s.interrupt?{interrupt:!0}:{}};if(!this.send(i)){if(s.rowId){const l=this.#s.get(t)??[];this.#g(t,l.map(c=>c.id===s.rowId?{...c,inflight:!1}:c))}return}const a=setTimeout(()=>this.#H(n),jR);this.#n.set(n,{sessionId:t,pid:n,text:s.text,attachments:s.attachments,rowId:s.rowId,timer:a})}#P(t,s){const n=s?this.#n.get(s):[...this.#n.values()].find(r=>r.sessionId===t);if(!n)return;for(const r of[...this.#n.values()])r.sessionId===t&&(clearTimeout(r.timer),this.#n.delete(r.pid));clearTimeout(n.timer),this.#n.delete(n.pid);const i=this.#s.get(t)??[];i.some(r=>r.pid===n.pid)&&this.#g(t,i.filter(r=>r.pid!==n.pid))}#r(t){const s=this.#n.get(t);s&&(clearTimeout(s.timer),this.#n.delete(t))}#H(t){const s=this.#n.get(t);if(!s)return;this.#n.delete(t),this.#t.delete(s.sessionId);const n=this.#s.get(s.sessionId)??[];s.rowId&&n.some(i=>i.id===s.rowId)?this.#g(s.sessionId,n.map(i=>i.id===s.rowId?{...i,inflight:!1,unsure:!0}:i)):n.some(i=>i.pid===s.pid)||this.#g(s.sessionId,[...n,{id:`q-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,text:s.text,attachments:s.attachments,at:Date.now(),unsure:!0,pid:s.pid}]),this.#m(!1,"消息未确认送达 — 已放回队列,点 ↑ 重发")}send(t){return this.auth==="out"?(this.#m(!1,"未登录 — 请先登录再发送指令"),!1):this.ws?.readyState===WebSocket.OPEN?(this.ws.send(JSON.stringify(t)),!0):t.t==="prompt"?(this.enqueuePrompt(t.sessionId,t.text,t.attachments??[]),this.#m(!1,"连接已断开 — 消息已排队,重连后自动发送"),!1):t.t==="respond-permission"?(this.#i.push(t),this.#i.length>20&&this.#i.shift(),this.#m(!1,"连接已断开 — 指令已排队,重连后自动发送"),!1):(this.#m(!1,"连接已断开 — 该操作未能送达"),!1)}#L(t){return`agentus.queue.${t}`}#U(t){try{const s=localStorage.getItem(this.#L(t)),n=s?JSON.parse(s):[];return Array.isArray(n)?n.filter(i=>i&&typeof i.text=="string"&&i.text.trim()).map(i=>({id:String(i.id??`q-${i.at??Date.now()}`),text:i.text,attachments:i.attachments??[],at:i.at??Date.now(),...i.unsure?{unsure:!0,pid:typeof i.pid=="string"?i.pid:void 0}:{}})):[]}catch{return[]}}#N(t){const s=this.#s.get(t)??this.#U(t);return s.length&&this.#s.set(t,s),s}drainPersistedQueues(){try{for(let t=0;t<localStorage.length;t++){const s=localStorage.key(t);if(!s?.startsWith("agentus.queue."))continue;const n=s.slice(14);this.#N(n),this.drainQueue(n)}}catch{}}#g(t,s){s.length?this.#s.set(t,s):this.#s.delete(t);try{s.length?localStorage.setItem(this.#L(t),JSON.stringify(s)):localStorage.removeItem(this.#L(t))}catch{}const n=this.byId.get(t);n&&(n.queue=s),this.bump()}queueSetup(t,s){s.length&&this.#o.set(t,s)}#W(t){const s=this.#o.get(t);if(s?.length){this.#o.delete(t);for(const n of s)n.kind==="model"?this.send({t:"set-model",sessionId:t,modelId:n.value}):n.kind==="mode"?this.send({t:"set-mode",sessionId:t,modeId:n.value}):this.send({t:"set-config",sessionId:t,configId:n.id,value:n.value})}}enqueuePrompt(t,s,n=[]){const i=this.#s.get(t)??[];this.#g(t,[...i,{id:`q-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,text:s,attachments:n,at:Date.now()}])}sendToCold(t,s,n=[]){const i=this.#s.get(t)??this.#N(t),r=i[i.length-1],a=this.sessions.some(u=>u.id===t&&u.status==="ready"),l=!!(r&&r.text===s&&!a&&Date.now()-r.at<5e3),c=!s.trim()&&!n.length;!l&&!c&&this.enqueuePrompt(t,s,n),this.resume(t)}dropQueued(t,s){const n=this.#s.get(t)??[];this.#g(t,n.filter(i=>i.id!==s))}editQueued(t,s,n){const i=this.#s.get(t)??[],r=n.trim();this.#g(t,r?i.map(a=>a.id===s?{...a,text:r}:a):i.filter(a=>a.id!==s))}sendQueuedNow(t,s){const n=this.#s.get(t)??[],i=n.find(r=>r.id===s);i&&(this.#t.add(t),this.#g(t,n.map(r=>r.id===s?{...r,inflight:!0,unsure:!1}:r)),this.#T(t,{text:i.text,attachments:i.attachments,interrupt:!0,rowId:s}))}sendNow(t,s,n=[]){if(!s.trim()&&!n.length)return;this.#N(t),this.enqueuePrompt(t,s,n);const i=this.#s.get(t)??[],r=i[i.length-1];r&&this.sendQueuedNow(t,r.id)}drainQueue(t){const s=this.#s.get(t)??this.#N(t),n=s[0];!n||n.inflight||n.unsure||this.#t.has(t)||Qr(this.byId.get(t))||this.sessions.find(r=>r.id===t)?.status==="running"||(this.#g(t,s.map(r=>r.id===n.id?{...r,inflight:!0}:r)),this.#T(t,{text:n.text,attachments:n.attachments,interrupt:!0,rowId:n.id}))}#F(t){this.#t.delete(t);const s=this.#s.get(t)??[];s.some(n=>n.inflight)&&this.#g(t,s.filter(n=>!n.inflight))}#O(t){this.#t.delete(t);const s=this.#s.get(t)??[];s.some(n=>n.inflight)&&this.#g(t,s.map(n=>n.inflight?{...n,inflight:!1}:n))}setActive(t){this.activeId=t,this.#b(t),this.#x(t),this.clearUnread(t),this.#v=this.#w(),this.bump();const s=this.byId.get(t);s&&!s.loaded&&this.loadHistory(t)}markUnread(t){this.#c.has(t)||(this.#c=new Set(this.#c).add(t),this.bump())}clearUnread(t){if(!this.#c.has(t))return;const s=new Set(this.#c);s.delete(t),this.#c=s,this.bump()}isUnread(t){return this.#c.has(t)||this.#h.has(t)}toggleUnread(t){if(this.isUnread(t)){const s=new Set(this.#c);s.delete(t),this.#c=s;const n=new Set(this.#h);n.delete(t),this.#h=n}else this.#h=new Set(this.#h).add(t);AR(this.#h),this.bump()}async loadHistory(t){try{const{messages:s,hasOlder:n}=await this.#a(`/api/sessions/${t}/messages?tail=1`),i=this.#u(t);i.seen.clear(),i.msgs=[],i.blocks.clear(),i.minSeq=null,i.plan=null,i.turn=0,i.turnStart=0;for(const r of s)this.#B(i,r);i.loaded=!0,i.hasOlder=!!n,this.#M(i),this.#q(i),this.bump(),this.#K(i)}catch{}}async loadEarlier(t){const s=this.#u(t);if(s.loadingOlder||!s.hasOlder||s.minSeq==null)return 0;s.loadingOlder=!0,this.bump();try{const{messages:n,hasOlder:i}=await this.#a(`/api/sessions/${t}/messages?before=${s.minSeq}`),r=[],a=new Map;for(const c of n)this.#B(s,c,{list:r,index:a});const l=[];for(const c of r){const u=s.blocks.get(c.key),h=u===void 0?void 0:s.msgs[u];if(h&&h.kind===c.kind&&(c.kind==="agent"||c.kind==="thought")&&h.kind===c.kind){const d=h,p=c;if(p.text.length>d.text.length){const f=s.msgs.indexOf(d);f>=0&&(s.msgs[f]={...d,text:p.text})}continue}l.push(c)}return l.length&&(s.msgs=[...l,...s.msgs]),s.blocks=e0(s.msgs),s.hasOlder=!!i,l.length}catch{return-1}finally{s.loadingOlder=!1,this.bump()}}async loadBackends(){return await this.#a("/api/backends")}async createBackend(t){await this.#a("/api/backends",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}async updateBackend(t,s){await this.#a(`/api/backends/${encodeURIComponent(t)}`,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(s)})}async deleteBackend(t){await this.#a(`/api/backends/${encodeURIComponent(t)}`,{method:"DELETE"})}async inspectBackend(t){return await this.#a(`/api/backends/${encodeURIComponent(t)}/inspect`,{method:"POST"},{timeoutMs:6e4,retry:!1})}async listEntries(t){return await this.#a(`/api/fs/dirs?files=1&path=${encodeURIComponent(t)}`)}async readFile(t){return await this.#a(`/api/fs/file?path=${encodeURIComponent(t)}`)}async statFile(t){return await this.#a(`/api/fs/stat?path=${encodeURIComponent(t)}`)}async writeFile(t,s,n){return await this.#a("/api/fs/file",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({path:t,content:s,...n?{ifHash:n}:{}})},{retry:!1})}async fork(t){const s=await this.#a(`/api/sessions/${t}/fork`,{method:"POST"},{timeoutMs:12e4,retry:!1});return this.sessions.some(n=>n.id===s.id)||(this.sessions=[s,...this.sessions]),this.cold=this.cold.filter(n=>n.id!==s.id),this.archived=this.archived.filter(n=>n.id!==s.id),this.setActive(s.id),s.id}async setModel(t,s){const n=await this.#a(`/api/sessions/${t}/model`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({modelId:s})},{timeoutMs:9e4,retry:!1}),i=this.byId.get(t);i&&(i.info={...i.info,...n});const r=this.sessions.findIndex(a=>a.id===t);return r>=0&&(this.sessions[r]={...this.sessions[r],...n}),this.bump(),n}async setContextLimit(t,s,n={}){const i=await this.#a(`/api/sessions/${t}/context-limit`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({limit:s,...n})}),r=this.byId.get(t);r&&(r.info={...r.info,...i});const a=this.sessions.findIndex(c=>c.id===t);a>=0&&(this.sessions[a]={...this.sessions[a],...i});const l=this.archived.findIndex(c=>c.id===t);l>=0&&(this.archived[l]={...this.archived[l],...i}),this.bump()}async setWorkspace(t,s){const n=await this.#a(`/api/sessions/${t}/workspace`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({path:s})}),i=this.byId.get(t);i&&(i.info={...i.info,...n});const r=this.sessions.findIndex(a=>a.id===t);r>=0&&(this.sessions[r]={...this.sessions[r],...n}),this.bump()}async createSession(t,s,n){const i=await this.#a("/api/sessions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({backend:t,cwd:s,title:n||void 0})},{retry:!1}),r=this.#u(i.id);return r.info={...r.info,...i},this.sessions.some(a=>a.id===i.id)||(this.sessions=[i,...this.sessions]),this.bump(),i.id}async refreshRows(){try{const{cold:t,archived:s}=await this.#a("/api/sessions");this.cold=t??[],this.archived=s??[],this.bump()}catch{}}async rename(t,s){const n=await this.#a(`/api/sessions/${t}/rename`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({title:s})}),i=this.byId.get(t);i&&(i.info={...i.info,...n});for(const r of[this.sessions,this.archived]){const a=r.findIndex(l=>l.id===t);a>=0&&(r[a]={...r[a],...n})}return this.bump(),n}async regenerateTitle(t){const s=await this.#a(`/api/sessions/${t}/title/regenerate`,{method:"POST"}),n=s.info,i=this.byId.get(t);i&&(i.info={...i.info,...n});for(const r of[this.sessions,this.cold,this.archived]){const a=r.findIndex(l=>l.id===t);a>=0&&(r[a]={...r[a],...n})}return this.bump(),s}async resume(t){if(this.#u(t),this.setActive(t),!this.#_.has(t)){this.#_.add(t),this.#u(t).resuming=!0,this.bump();try{const s=await this.#a(`/api/sessions/${t}/resume`,{method:"POST"},{timeoutMs:12e4,retry:!1});this.#u(t).info=s,this.sessions.some(n=>n.id===t)||(this.sessions=[s,...this.sessions]),this.cold=this.cold.filter(n=>n.id!==t),await this.loadHistory(t)}catch(s){const n=s.httpStatus,i=s.httpBody;if(n===409&&(i?.code==="home_mismatch"||i?.code==="context_missing")){const r=this.sessions.find(a=>a.id===t)??this.cold.find(a=>a.id===t)??this.archived.find(a=>a.id===t);this.blocked={id:t,title:r?.title??t,code:i.code,sessionHome:i.sessionHome??null,rowHome:i.rowHome??null},this.bump();return}this.#m(!1,`恢复失败:${String(s.message??s)}`)}finally{this.#_.delete(t),this.#u(t).resuming=!1,this.bump()}}}async restart(t){try{const s=await this.#a(`/api/sessions/${t}/restart`,{method:"POST"},{timeoutMs:12e4,retry:!1}),n=this.#u(t);n.info={...n.info,...s};for(const i of[this.sessions,this.cold,this.archived]){const r=i.findIndex(a=>a.id===t);r>=0&&(i[r]={...i[r],...s})}this.bump()}catch(s){const n=s.httpStatus,i=s.httpBody;if(n===409&&(i?.code==="home_mismatch"||i?.code==="context_missing")){const r=this.sessions.find(a=>a.id===t);this.blocked={id:t,title:r?.title??t,code:i.code,sessionHome:i.sessionHome??null,rowHome:i.rowHome??null},this.bump();return}this.#m(!1,`重启 agent 进程失败:${String(s.message??s)}`)}}dismissBlocked(){this.blocked=null,this.bump()}deleteBlocked(){const t=this.blocked;this.blocked=null,t&&this.purgeCold(t.id),this.bump()}purgeCold(t){this.sessions=this.sessions.filter(s=>s.id!==t),this.cold=this.cold.filter(s=>s.id!==t),this.archived=this.archived.filter(s=>s.id!==t),this.byId.delete(t),this.bump(),this.#a(`/api/sessions/${t}`,{method:"DELETE"}).catch(()=>this.refreshRows()).then(()=>this.refreshRows())}async setArchived(t,s){try{const n=await this.#a(`/api/sessions/${t}/${s?"archive":"unarchive"}`,{method:"POST"}),i=this.byId.get(t);return i&&(i.info={...i.info,...n}),s?(this.sessions=this.sessions.filter(r=>r.id!==t),this.cold=this.cold.filter(r=>r.id!==t),this.archived.some(r=>r.id===t)||(this.archived=[n,...this.archived]),this.activeId===t&&this.#R()):(this.archived=this.archived.filter(r=>r.id!==t),!this.sessions.some(r=>r.id===t)&&!this.cold.some(r=>r.id===t)&&(this.cold=[n,...this.cold])),this.bump(),n}catch(n){return this.#m(!1,`${s?"归档":"取消归档"}失败:${String(n.message??n)}`),null}}async unarchiveAndResume(t){await this.setArchived(t,!1),await this.resume(t)}#R(){const t=this.sessions[0]??this.cold[0]??this.archived[0]??null;this.activeId=t?.id??null,this.#b(this.activeId),t&&!this.sessions.some(s=>s.id===t.id)&&this.loadHistory(t.id)}#A(t,s,n,i,r,a){const l=t.plan;if(!l){t.plan={key:`plan-${t.turn}`,items:s,terminal:n,explanation:r,at:i,turn:t.turn,title:a??void 0};return}if(l.turn===t.turn){l.items=s,l.terminal=n,l.explanation=r,a!==void 0&&(l.title=a??void 0);return}const c=t.turnStart>0&&t.turnStart<=t.msgs.length?t.turnStart:t.msgs.length;t.msgs.splice(c,0,{key:l.key,kind:"plan",items:l.items,terminal:l.terminal,explanation:l.explanation,at:l.at,title:l.title}),t.blocks=e0(t.msgs),t.turnStart=Math.min(t.turnStart+1,t.msgs.length),t.plan={key:`plan-${t.turn}`,items:s,terminal:n,explanation:r,at:i,turn:t.turn,title:a??void 0}}#j(t,s){this.#A(t,s.items.map(n=>({content:n.content,status:n.status,priority:n.priority})),s.terminal??void 0,s.updatedAt,s.explanation??void 0,s.title?.trim()||null)}async#K(t){try{const{plan:s}=await this.#a(`/api/sessions/${t.info.id}/plan`);if(!s)return;this.#j(t,s),this.bump()}catch{}}#u(t){let s=this.byId.get(t);return s||(s={info:this.sessions.find(n=>n.id===t)??{id:t},msgs:[],notes:[],perms:[],busy:!1,busySince:null,loaded:!1,hasOlder:!1,loadingOlder:!1,minSeq:null,lastAt:Date.now(),rev:0,seen:new Set,blocks:new Map,plan:null,turn:0,turnStart:0,queue:this.#N(t)},this.byId.set(t,s)),s}apply(t){switch(t.t){case"hello":break;case"sessions":{this.sessions=t.sessions,t.cold&&(this.cold=t.cold),t.archived&&(this.archived=t.archived);const s=new Set([...t.sessions.map(n=>n.id),...this.cold.map(n=>n.id),...this.archived.map(n=>n.id)]);for(const n of[...t.sessions,...this.cold,...this.archived]){const i=this.#u(n.id);i.info={...i.info,...n}}if(t.background){const n=new Set(t.background.map(i=>i.sessionId));for(const i of t.background)this.#u(i.sessionId).background=i.tasks;for(const[i,r]of this.byId)!n.has(i)&&r.background?.length&&(r.background=[])}if(t.pending){const n=new Map;for(const i of t.pending){const r=n.get(i.sessionId);r?r.push(i):n.set(i.sessionId,[i])}for(const[i,r]of n)this.#u(i).perms=r;for(const i of this.byId.values())n.has(i.info.id)||(i.perms=[]);this.#y()}for(const n of[...this.byId.keys()])s.has(n)||this.byId.delete(n);if(this.activeId&&!s.has(this.activeId)&&(this.activeId=null,this.#b(null)),!this.activeId&&s.size){const n=this.#I(),i=n&&s.has(n)?n:t.sessions[0]?.id??this.cold[0]?.id??this.archived[0]?.id;i&&(this.activeId=i,this.loadHistory(i))}for(const n of this.sessions)n.status==="ready"&&this.#s.get(n.id)?.length&&this.drainQueue(n.id);break}case"session":{t.session.cold===!0?(this.sessions=this.sessions.filter(s=>s.id!==t.session.id),this.cold=this.cold.map(s=>s.id===t.session.id?t.session:s),this.cold.some(s=>s.id===t.session.id)||this.cold.push(t.session)):(this.sessions=this.sessions.map(s=>s.id===t.session.id?t.session:s),this.sessions.some(s=>s.id===t.session.id)||this.sessions.push(t.session),this.cold=this.cold.filter(s=>s.id!==t.session.id)),this.#u(t.session.id).info=t.session,t.session.status==="ready"&&this.#W(t.session.id),t.session.status==="ready"&&this.#s.get(t.session.id)?.length&&this.drainQueue(t.session.id);break}case"messages":{const s=this.#u(t.sessionId);if(t.partial){for(const n of t.messages)this.#B(s,n,{resync:!0});s.lastAt=Date.now();break}s.seen.clear(),s.msgs=[],s.blocks.clear(),s.plan=null,s.turn=0,s.turnStart=0,this.#M(s);for(const n of t.messages)this.#B(s,n);s.loaded=!0;break}case"message":{const s=this.#u(t.message.sessionId),n=t.message.payload?.rejectedPrompt,i=t.message.payload?.pid;typeof i=="string"&&this.#r(i),t.message.kind==="meta"&&typeof n=="string"&&n.trim()&&this.enqueuePrompt(t.message.sessionId,n),this.#B(s,t.message,{delta:t.delta,n:t.n}),s.lastAt=Date.now(),this.lastSeq[t.message.sessionId]=Math.max(this.lastSeq[t.message.sessionId]??0,t.message.seq);break}case"status":{const s=this.#u(t.sessionId),n=Date.now(),i=s.notes[s.notes.length-1],r=s.msgs.length?s.msgs[s.msgs.length-1].key:null;i&&t.statusKind&&i.kind===t.statusKind?(i.text=t.text,i.afterKey=r):(s.notes.push({key:`st-${n}-${s.notes.length}`,kind:t.statusKind,text:t.text,at:n,afterKey:r}),s.notes.length>200&&s.notes.splice(0,s.notes.length-200)),s.lastAt=n;break}case"background":{this.#u(t.sessionId).background=t.tasks;break}case"turn-start":{const s=this.#u(t.sessionId);s.busy=!0,s.busySince=Date.now(),s.lastAt=Date.now(),s.trace=t.trace??null,this.#F(t.sessionId),this.#P(t.sessionId,t.pid);break}case"plan":{const s=this.#u(t.sessionId);this.#j(s,t.plan),s.lastAt=Date.now();break}case"speak":{const s=this.#u(t.sessionId),n={id:t.id,text:t.text,kind:t.kind,priority:t.priority,at:Date.now()};s.speaks=[...s.speaks??[],n].slice(-10);break}case"usage":{const s=this.#u(t.sessionId);s.info={...s.info,usage:t.usage},s.lastAt=Date.now();break}case"turn-end":{const s=this.#u(t.sessionId);if(s.busy=!1,t.sessionId!==this.activeId&&this.markUnread(t.sessionId),s.busySince=null,this.#M(s),t.error&&s.msgs.push({key:`err-${Date.now()}`,kind:"meta",text:t.error}),t.error?this.#O(t.sessionId):this.#F(t.sessionId),!t.error){const n=t.sessionId;window.setTimeout(()=>this.drainQueue(n),250)}break}case"permission":this.#u(t.request.sessionId).perms.push(t.request);break;case"permission-resolved":for(const s of this.byId.values())s.perms=s.perms.filter(n=>n.requestId!==t.requestId);this.#y();break;case"permission-expired":for(const s of this.byId.values())s.perms=s.perms.filter(n=>n.requestId!==t.requestId);this.#y(),this.#u(t.sessionId).msgs.push({key:`perm-exp-${t.requestId}`,kind:"meta",text:"这条审批已经过期:agent 等不到答复、先自己放过了(或它已经放弃这一轮)。你的点击没有生效。"});break;case"config-rejected":{const s=this.#u(t.sessionId),n=t.name||t.configId;s.msgs.push({key:`cfg-rej-${t.configId}-${Date.now()}`,kind:"meta",text:`${n} 这一档没生效:agent 没有接受「${t.value}」${t.actual?`,实际仍是「${t.actual}」`:""}。(模型只认它公布的那几档;换档位或换模型再试。)`});break}case"notify":{Si.handle(t.notice);break}case"error":{this.activeId&&this.#u(this.activeId).msgs.push({key:`e-${Date.now()}`,kind:"meta",text:t.error});break}}this.bump()}#M(t){for(let s=0;s<t.msgs.length;s++){const n=t.msgs[s];(n.kind==="agent"||n.kind==="thought")&&n.open&&(t.msgs[s]={...n,open:!1})}}#q(t){const s=t.msgs[t.msgs.length-1];s&&(s.kind==="agent"||s.kind==="thought")&&t.busy&&!s.open&&(t.msgs[t.msgs.length-1]={...s,open:!0})}#z(t,s){for(let n=0;n<t.length;n++){const i=t[n];i.kind==="thought"&&i.open&&i.key!==s&&(t[n]={...i,open:!1})}}#B(t,s,n){const i=n?.list??t.msgs,r=n?.index??t.blocks,a=n?.delta,l=s.payload;let c=null;const u=a!==void 0,h=(s.kind==="agent"||s.kind==="thought")&&Qv(s.kind,l)!==null;if(!(n?.resync===!0&&(s.kind==="tool"||s.kind==="plan"||s.kind==="user"||s.kind==="meta"||h)||s.kind==="tool"||s.kind==="meta"||s.kind==="note"||s.kind==="approval"||s.kind==="project-skills"||s.seq<=0||u)){if(t.seen.has(s.seq))return;t.seen.add(s.seq)}s.seq>0&&(t.minSeq==null||s.seq<t.minSeq)&&(t.minSeq=s.seq);const f=s.payload,m=typeof s.createdAt=="number"?s.createdAt:Date.now(),b=DR(f);switch(i[i.length-1],s.kind){case"user":if(i.some(v=>v.key===`m${s.seq}`))break;const _=f.origin??null;i.push({key:`m${s.seq}`,kind:"user",text:String(f.text??""),at:m,..._&&typeof _.sessionId=="string"?{from:{id:_.sessionId,title:String(_.title??"").trim()||"另一个会话"}}:{},files:Array.isArray(f.attachments)?f.attachments.map(v=>({kind:String(v.kind??""),name:String(v.name??"file")})):[]}),n?.list||(t.turn+=1,t.turnStart=i.length-1);break;case"agent":case"thought":{const v=s.kind,y=Qv(v,f),{at:w}=ON(i,r,{key:y,kind:v,text:b,delta:a,n:n?.n},(S,N)=>({key:S,kind:N.kind,text:N.text,open:!0,at:m})),x=i[w];a!==void 0&&t.info.status==="running"&&x&&(x.kind==="agent"||x.kind==="thought")&&!x.open&&(i[w]={...x,open:!0}),v==="thought"&&(c=i[w]?.key??null);break}case"note":{const v=`n${s.seq}`,y=typeof f.hits=="number"?f.hits:void 0,w={key:v,kind:"note",category:String(f.category??""),text:typeof f.text=="string"?f.text:"",hits:y,at:m,items:Array.isArray(f.items)?f.items.filter(S=>S&&typeof S.text=="string"&&S.text.trim()):void 0,truncated:f.truncated===!0},x=r.get(v);x!==void 0&&i[x]?.kind==="note"?i[x]=w:(i.push(w),r.set(v,i.length-1));break}case"approval":{const v=`p${s.seq}`,y=f.decision,w={key:v,kind:"approval",requestId:String(f.requestId??""),title:String(f.toolCallTitle??"tool call"),kind2:String(f.kind??"other"),path:typeof f.path=="string"?f.path:null,diff:f.diff??null,options:Array.isArray(f.options)?f.options:[],decision:y??null,at:m},x=r.get(v);x!==void 0&&i[x]?.kind==="approval"?i[x]=w:(i.push(w),r.set(v,i.length-1));break}case"project-skills":{const v=`s${s.seq}`,y={key:v,kind:"project-skills",root:String(f.root??""),count:typeof f.count=="number"?f.count:0,text:String(f.text??""),state:String(f.state??"ask"),at:m},w=r.get(v);w!==void 0&&i[w]?.kind==="project-skills"?i[w]=y:(i.push(y),r.set(v,i.length-1));break}case"turn-usage":{const v=`u${s.seq}`,y=x=>typeof x=="number"&&Number.isFinite(x)?x:0,w={key:v,kind:"turn-usage",available:f.available!==!1,input:y(f.input),output:y(f.output),thought:y(f.thought),cacheRead:y(f.cacheRead),cacheWrite:y(f.cacheWrite),total:y(f.total),durationMs:typeof f.durationMs=="number"?f.durationMs:void 0,cacheHitPercent:typeof f.cacheHitPercent=="number"?f.cacheHitPercent:null,tps:typeof f.tps=="number"?f.tps:null,at:m};r.get(v)===void 0&&(i.push(w),r.set(v,i.length-1));break}case"tool":{const v=String(f.toolCallId??s.toolCallId??s.seq),y=i.find(E=>E.kind==="tool"&&E.toolCallId===v),w=IR(f),x=PR(f),S=new Set((y?.changes??[]).map(E=>`${E.path}\0${E.oldText??""}\0${E.newText??""}\0${E.diffText??""}`)),N=FN(f).filter(E=>!S.has(`${E.path}\0${E.oldText??""}\0${E.newText??""}\0${E.diffText??""}`)),R=N.length?[...y?.changes??[],...N]:y?.changes;if(y){const E=i.indexOf(y),M={...y,title:f.title?String(f.title):y.title,status:f.status?String(f.status):y.status,detail:w??y.detail,input:x??y.input,changes:R};E>=0&&(i[E]=M)}else i.push({key:`tc-${v}`,kind:"tool",toolCallId:v,at:m,title:String(f.title??"tool call"),status:String(f.status??"pending"),kind2:String(f.kind??""),detail:w,input:x,changes:R});break}case"plan":{const v=f._meta??{},y=(f.entries??[]).map(S=>({content:String(S?.content??""),status:String(S?.status??"pending"),priority:S?.priority})),w=typeof f._slotPlanTerminal=="string"?f._slotPlanTerminal:void 0,x=typeof v["agentus/explanation"]=="string"?String(v["agentus/explanation"]):void 0;if(n?.list){const S=i.find(N=>N.kind==="plan");if(S&&S.kind==="plan"){const N=i.indexOf(S);i[N]={...S,items:y,terminal:w,explanation:x}}else i.push({key:`m${s.seq}`,kind:"plan",items:y,terminal:w,explanation:x,at:m});break}this.#A(t,y,w,m,x);break}case"meta":if(i.some(v=>v.key===`m${s.seq}`))break;i.push({key:`m${s.seq}`,kind:"meta",text:b||JSON.stringify(f)});break}this.#z(i,c),this.lastSeq[t.info.id]=Math.max(this.lastSeq[t.info.id]??0,s.seq),t.rev+=1,t.lastAt=Date.now()}}function DR(e){const t=e.content;return t?.type==="text"&&typeof t.text=="string"?t.text:""}function IR(e){const s=r=>r.length>4e3?`${r.slice(0,4e3)}
|
|
43
|
+
`)){if(i.startsWith("+++ ")){const r=i.slice(4).trim().replace(/^b\//,"").replace(/\t.*$/,"");r&&r!=="/dev/null"&&(t=r);continue}i.startsWith("--- ")||(i.startsWith("+")?s++:i.startsWith("-")&&n++)}return t?{path:t,insertions:s,deletions:n}:null}function FN(e){const t=e??{},s=Array.isArray(t.content)?t.content:[],n=[],i=new Set,r=a=>{i.has(a.path)||(i.add(a.path),n.push(a))};for(const a of s){if(!a||typeof a!="object")continue;if(of(a.path)&&a.path&&(a.oldText!=null||a.newText!=null||a.type==="diff")){r({path:a.path,oldText:a.oldText??"",newText:a.newText??""});continue}const l=of(a.text)?a.text:of(a.content?.text)?a.content.text:"";if(!l)continue;const c=RS(l);c&&r({path:c.path,diffText:l})}return n}function zN(e){const t=[],s=new Map;for(const n of e){const i=s.get(n.path);if(!i){t.push(n.path),s.set(n.path,{first:n,last:n,edits:1,diffText:n.diffText});continue}i.last=n,i.edits++,n.oldText!=null||n.newText!=null?i.diffText=void 0:i.diffText||(i.diffText=n.diffText)}return t.map(n=>{const{first:i,last:r,edits:a,diffText:l}=s.get(n),c={path:n,name:$N(n),edits:a};if(i.oldText!=null||r.newText!=null){const u=i.oldText??"",h=r.newText??r.oldText??"",d=s_(u,h);return{...c,insertions:d.filter(p=>p.kind==="add").length,deletions:d.filter(p=>p.kind==="del").length,oldText:u,newText:h}}if(l){const u=RS(l);return{...c,insertions:u?.insertions??0,deletions:u?.deletions??0,oldText:"",newText:"",diffText:l}}return{...c,insertions:0,deletions:0,oldText:"",newText:""}})}function HN(e){let t=null,s=!1,n=[];function i(){const a=n;n=[];for(const l of a)l()}async function r(){if(!s){s=!0;try{for(;t;){const a=t;t=null;try{await e(a)}catch{}}}finally{s=!1,i()}}}return{push(a){t=a,r()},hush(){t=null,s||i()},get speaking(){return s},get waiting(){return t},settled(){return!s&&!t?Promise.resolve():new Promise(a=>{n.push(a)})}}}const jS="agentus.voice",kl={autoRead:!1,speakMode:"off",voiceURI:"",rate:1,lang:typeof navigator<"u"&&navigator.language?navigator.language:"en-US",serverTts:!1,stt:"auto"};function UN(){try{const e=localStorage.getItem(jS);if(!e)return{...kl};const t=JSON.parse(e),s=Number(t.rate);return{...kl,...t,rate:Number.isFinite(s)?Math.min(2,Math.max(.5,s)):kl.rate}}catch{return{...kl}}}function TS(e){try{localStorage.setItem(jS,JSON.stringify(e))}catch{}}const n_={provider:"browser",tts:{server:!1,model:null,voice:null},stt:{server:!1,streaming:!1,model:null,batchModel:null,language:null},hotwords:{fixed:0,dynamic:!1,limit:0}};let $o=null;const qp=new Set;async function Ch(e=!1){if($o&&!e)return $o;try{const t=await fetch("/api/voice",{credentials:"same-origin"});if(!t.ok)throw new Error(String(t.status));$o=await t.json()}catch{$o=n_}for(const t of qp)t();return $o}function li(){return $o??n_}function WN(e){return qp.add(e),()=>qp.delete(e)}const t0=80,AS=220,KN=2,qN=12,VN=3,s0=2,YN=400,af=0,GN=1,JN=4,XN=400,ZN=60;let lf=0;const Za=[];async function QN(e,t,s){lf>=VN&&await new Promise((n,i)=>{const r={priority:e,run:n};Za.push(r),Za.sort((l,c)=>l.priority-c.priority);const a=()=>{const l=Za.indexOf(r);l>=0&&Za.splice(l,1),i(new rn)};t&&(t.aborted?a():t.addEventListener("abort",a,{once:!0}))}),lf++;try{return await s()}finally{const n=Za.shift();n?n.run():lf--}}function n0(e,t=AS){const s=e.replace(/```[\s\S]*?```/g," code block ").replace(/[*_`#>|]/g," ").replace(/\s+/g," ").trim();if(!s)return[];const n=[];let i=s;for(;i.length>t;){const r=i.slice(0,t),a=Math.max(r.lastIndexOf(". "),r.lastIndexOf("。"),r.lastIndexOf("! "),r.lastIndexOf("? ")),l=Math.max(r.lastIndexOf(", "),r.lastIndexOf("; "),r.lastIndexOf(",")),c=a>t*.5?a+1:l>t*.5?l+1:r.lastIndexOf(" "),u=c>0?c:t;n.push(i.slice(0,u).trim()),i=i.slice(u).trim()}return i&&n.push(i),n.filter(Boolean)}let nn=null;function MS(){return window.AudioContext??window.webkitAudioContext??null}const Fl={echoCancellation:null,noiseSuppression:null};function eR(e,t){const s=e.getAudioTracks()[0],n=typeof s?.getSettings=="function"?s.getSettings():void 0;Fl.echoCancellation=typeof n?.echoCancellation=="boolean"?n.echoCancellation:t>0?!1:null,Fl.noiseSuppression=typeof n?.noiseSuppression=="boolean"?n.noiseSuppression:t>0?!1:null,Fl.echoCancellation===!1&&console.warn("[voice] microphone opened WITHOUT echo cancellation — the call may hear itself")}function i0(){return Fl.echoCancellation!==!1}function cf(){return{...Fl}}async function r0(e){const t=[e,{audio:{channelCount:1,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1}},{audio:!0}];let s=null;for(let n=0;n<t.length;n++)try{const i=await navigator.mediaDevices.getUserMedia(t[n]);return n>0&&console.warn("[voice] microphone opened only with degraded constraints",t[n]),eR(i,n),i}catch(i){s=i;const r=i?.name??"";if(r==="NotAllowedError"||r==="SecurityError")throw i;await new Promise(a=>setTimeout(a,250))}throw s instanceof Error?s:new Error(String(s))}async function tR(){const e=MS();if(!e)return!1;try{return nn=nn??new e,nn.state==="suspended"&&await nn.resume(),nn.state==="running"}catch{return!1}}const or={analyser:null};let cr=null;function o0(){const e=or.analyser;if(!e)return-1;const t=cr&&cr.length===e.fftSize?cr:new Float32Array(new ArrayBuffer(e.fftSize*4));cr=t,e.getFloatTimeDomainData(t);let s=0;for(let n=0;n<t.length;n++)s+=t[n]*t[n];return Math.min(1,Math.sqrt(s/t.length)*4)}function sR(){const e=or.analyser;if(!e)return-1;const t=cr&&cr.length===e.fftSize?cr:new Float32Array(new ArrayBuffer(e.fftSize*4));cr=t,e.getFloatTimeDomainData(t);let s=0;for(let n=0;n<t.length;n++)s+=t[n]*t[n];return Math.min(1,Math.sqrt(s/t.length))}function nR(e){const t=or.analyser;if(!t)return!1;const s=new Float32Array(new ArrayBuffer(t.fftSize*4));t.getFloatTimeDomainData(s);const n=Math.max(1,Math.floor(s.length/e.length));for(let i=0,r=0;i<e.length;i++,r+=n)e[i]=s[r]??0;return!0}class rn extends Error{constructor(){super("stopped"),this.name="SpeechStopped"}}async function DS(e,t){const s=MS();if(s)try{nn=nn??new s,nn.state==="suspended"&&await nn.resume();const i=await nn.decodeAudioData(await e.arrayBuffer());await new Promise((r,a)=>{const l=nn.createBufferSource();l.buffer=i;const c=nn.createAnalyser();c.fftSize=512,l.connect(c),c.connect(nn.destination),or.analyser=c,l.onended=()=>{or.analyser===c&&(or.analyser=null),r()};const u=()=>{or.analyser===c&&(or.analyser=null);try{l.stop()}catch{}a(new rn)};if(t){if(t.aborted)return u();t.addEventListener("abort",u,{once:!0})}l.start()});return}catch(i){if(i instanceof rn)throw i;if(t?.aborted)throw new rn}const n=URL.createObjectURL(e);try{await new Promise((i,r)=>{const a=new Audio(n),l=()=>{try{a.pause()}catch{}r(new rn)};a.onended=()=>{c(),i()},a.onerror=()=>{c(),r(new Error("audio playback failed"))};const c=()=>{t&&t.removeEventListener("abort",l)};if(t){if(t.aborted)return l();t.addEventListener("abort",l,{once:!0})}a.play().catch(u=>{c(),r(new Error(String(u?.message??u)))})})}finally{URL.revokeObjectURL(n)}}function Qa(){return typeof window<"u"&&"speechSynthesis"in window}class iR{#e={speakingId:null,speaking:!1,error:"",note:""};#l=new Set;#i=null;#s=0;#o=!1;#t=[];#n=new Set;subscribe=t=>(this.#l.add(t),()=>this.#l.delete(t));getSnapshot=()=>this.#e;#c(t){this.#e={...this.#e,...t};for(const s of this.#l)s()}subscribeVoices=t=>(this.#n.add(t),()=>this.#n.delete(t));voices=()=>this.#t;init(){if(!Qa())return;const t=()=>{const i=window.speechSynthesis.getVoices();if(i.length!==this.#t.length){this.#t=i;for(const r of this.#n)r()}};t(),window.speechSynthesis.addEventListener("voiceschanged",t);let s=0;const n=window.setInterval(()=>{s+=1,t(),(this.#t.length||s>40)&&window.clearInterval(n)},250);window.addEventListener("pointerdown",t,{once:!0})}pickVoice(t){const s=this.#t.length?this.#t:Qa()?window.speechSynthesis.getVoices():[];if(!s.length)return null;if(t.voiceURI){const r=s.find(a=>a.voiceURI===t.voiceURI);if(r)return r}const n=t.lang.toLowerCase(),i=n.split("-")[0];return s.find(r=>r.lang.toLowerCase()===n)??s.find(r=>r.lang.toLowerCase().startsWith(i))??s.find(r=>r.default)??s[0]}async speak(t,s,n){const i=String(t??"").trim();if(!i)return;this.stop();const r=++this.#s;this.#o=!1;const a=n.serverTts&&li().tts.server,l=n0(i,a?t0:AS);if(!l.length)return;const c=new AbortController;this.#i=c,this.#c({error:"",note:"",speakingId:s,speaking:!0});try{a?await this.#v(l,n,c.signal):await this.#h(l,n,c.signal)}catch(u){if(this.#o||r!==this.#s||u instanceof rn||u?.name==="AbortError")return;if(n.serverTts&&Qa()){this.#c({note:`服务端语音这一句失败了(${String(u?.message??u)}),已改用浏览器语音`});try{await this.#h(l,n,c.signal);return}catch(h){if(this.#o||h instanceof rn)return;this.#c({error:String(h?.message??h)})}}else this.#c({error:String(u?.message??u)})}finally{this.#i===c&&(this.#i=null),r===this.#s&&this.#c({speaking:!1,speakingId:null})}}async#h(t,s,n){if(!Qa())throw new Error("this browser has no speech synthesis");const i=window.speechSynthesis,r=this.pickVoice(s);for(const[a,l]of t.entries()){if(n?.aborted)throw new rn;if(await new Promise((c,u)=>{const h=new SpeechSynthesisUtterance(l);r?(h.voice=r,h.lang=r.lang):h.lang=s.lang,h.rate=s.rate,h.onend=()=>c(),h.onerror=d=>u(new Error(`speech error: ${d.error??"unknown"}`)),i.speak(h),a===0&&i.resume()}),n?.aborted)throw new rn;i.paused&&i.resume()}}#_(t,s,n,i){return QN(i,n,async()=>{const r=await fetch("/api/tts",{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},signal:n,body:JSON.stringify({text:t,speed:s.rate})});if(!r.ok){const a=await r.json().catch(()=>({error:`${r.status}`}));throw new Error(a.error??`tts ${r.status}`)}return await r.blob()})}async#p(t,s,n,i=af){let r=null;for(let a=0;a<=s0;a++){if(n?.aborted)throw new rn;try{return await this.#_(t,s,n,i)}catch(l){if(l instanceof rn||l?.name==="AbortError"||n?.aborted)throw l;r=l,a<s0&&await new Promise(c=>{window.setTimeout(c,YN*(a+1))})}}throw r instanceof Error?r:new Error(String(r))}#d=new Map;#f(t,s){return`${s.rate}|${li().tts.voice??""}|${t}`}prefetch(t,s){if(!(s.serverTts&&li().tts.server))return;const n=String(t??"").trim();if(n)for(const i of n0(n,t0)){const r=this.#f(i,s);if(this.#d.has(r))continue;const a=this.#p(i,s,void 0,GN);for(a.catch(()=>{}),this.#d.set(r,a);this.#d.size>qN;){const l=this.#d.keys().next().value;if(l===void 0)break;this.#d.delete(l)}}}async#v(t,s,n){const i=[],r=a=>{const l=this.#f(a,s),c=this.#d.get(l);if(c)return this.#d.delete(l),c.catch(()=>this.#p(a,s,n,af));const u=this.#p(a,s,n,af);return u.catch(()=>{}),u};for(let a=0;a<t.length;a++){if(n.aborted)throw new rn;for(;i.length<Math.min(KN,t.length-a);)i.push(r(t[a+i.length]));if(await DS(await i.shift(),n),n.aborted)throw new rn}}stop(){this.#o=!0,this.#i?.abort(),this.#i=null,Qa()&&window.speechSynthesis.cancel(),this.#e.speaking&&this.#c({speaking:!1,speakingId:null})}}const Ft=new iR;Ft.init();function dd(){return g.useSyncExternalStore(Ft.subscribe,Ft.getSnapshot)}const el=new Set,rR=1024,IS=HN(e=>Ft.speak(e.text,e.key,Hn));function uc(){IS.hush(),Ft.stop()}function oR(e){IS.push({key:e.key,text:e.text})}let i_=!1;function a0(e){i_=e}function Eh(){return i_}function aR(e,t,s){if(i_||!s||el.has(e))return!1;for(el.add(e);el.size>rR;){const n=el.values().next().value;if(n===void 0)break;el.delete(n)}return!0}function PS(){const e=window;return e.SpeechRecognition??e.webkitSpeechRecognition??null}function Vp(){return!!PS()}function LS(){const e=window.AgentusMic;return e&&typeof e.start=="function"&&typeof e.stop=="function"?e:null}function OS(){const e=LS();if(!e)return!1;try{return!!e.available()}catch{return!1}}function lR(){return OS()||typeof navigator.mediaDevices?.getUserMedia=="function"}function cR(){return typeof window<"u"&&!window.isSecureContext?"当前页面是明文 http,浏览器不允许网页录音。请改用 https 入口访问(在服务前放一层终结 TLS 的反代或隧道),或走本机 localhost;手机上也可以用 Agentus app。":"this browser cannot record audio"}function uR(){return new Promise(e=>{const t=document.createElement("input");t.type="file",t.accept="audio/*",t.setAttribute("capture","microphone"),t.style.position="fixed",t.style.left="-9999px";let s=!1;const n=i=>{s||(s=!0,t.remove(),e(i))};t.onchange=()=>n(t.files?.[0]??null),window.addEventListener("focus",()=>{window.setTimeout(()=>n(t.files?.[0]??null),600)},{once:!0}),document.body.appendChild(t),t.click()})}class hR{#e={status:"idle",text:"",interim:"",error:"",engine:null,seconds:0};#l=new Set;#i=null;#s=null;#o=[];#t=null;#n=null;#c=null;#h=null;#_=null;#p=null;#d="";#f=0;#v=0;#b=new Float32Array(256);#D=null;#x=!0;#I;#k=!1;#a=0;#m=[];#S=null;#C=0;#y="";#w=!1;#E=()=>{const t=globalThis.__asFeed;return t&&typeof t=="object"?t:null};level=()=>{const t=this.#E();if(!t)return this.#f;const s=Number(t.level);return Number.isFinite(s)?s:0};levelRms=()=>{const t=this.#E();if(!t)return this.#v;const s=Number(t.rms??(Number.isFinite(Number(t.level))?Number(t.level)/6:NaN));return Number.isFinite(s)?Math.max(0,s):0};wave=()=>this.#b;setVadTap=t=>{this.#D=t};setRelay(t){if(this.#x=t,!t){this.#w=!0,this.#$();return}this.#w=!1,this.#k&&this.#N()}#$(){this.#S!==null&&(window.clearTimeout(this.#S),this.#S=null);const t=this.#n;if(this.#n=null,this.#m.length=0,!!t){t.onmessage=null,t.onerror=null,t.onclose=null;try{t.close()}catch{}}}resetText(){this.#d="",this.#r({text:"",interim:""})}commitForTest(t){this.#d=`${this.#d}${t}`.replace(/\s+/g," ").trim(),this.#r({status:"idle",text:this.#d,interim:""})}#T(t){let s=0;for(let a=0;a<t.length;a++)s+=t[a]*t[a];const n=Math.sqrt(s/t.length),i=Math.min(1,n*6);this.#f=i>this.#f?this.#f+(i-this.#f)*.6:this.#f*.72+i*.28,this.#v=n>this.#v?this.#v+(n-this.#v)*.6:this.#v*.72+n*.28,this.#D?.(t);const r=Math.max(1,Math.floor(t.length/this.#b.length));for(let a=0,l=0;a<this.#b.length&&l<t.length;a++,l+=r)this.#b[a]=t[l]}subscribe=t=>(this.#l.add(t),()=>this.#l.delete(t));#P=null;getSnapshot=()=>{const t=this.#E();if(!t)return this.#e;const s=String(t.text??""),n=String(t.interim??""),i=this.#P;return i&&i.text===s&&i.interim===n&&i.status===this.#e.status&&i.error===this.#e.error&&i.engine===this.#e.engine&&i.seconds===this.#e.seconds?i:(this.#P={...this.#e,text:s,interim:n},this.#P)};#r(t){this.#e={...this.#e,...t};for(const s of this.#l)s()}async start(t,s){if(this.#e.status!=="idle"&&this.#e.status!=="error")return!1;uc();const n=++this.#a;this.#r({status:"idle",text:"",interim:"",error:"",seconds:0}),this.#d="";const i=this.#E();if(i)return this.#x=!0,this.#r({status:"listening",engine:"stream",error:"",text:String(i.text??""),interim:String(i.interim??"")}),!0;const r=t.stt,a=li().stt.server,l=li().stt.streaming,c=(r==="browser"||r==="auto")&&Vp();try{if(r==="stream"||r==="auto"&&l){if(!l)throw new Error("streaming STT is not configured on the server (settings → 语音)");return await this.#L(t,s,n),!0}return c?(this.#H(t),!0):a?(await this.#K(t,n),!0):(this.#r({status:"error",engine:null,error:(typeof window<"u"&&!window.isSecureContext&&!lR()?`${cR()} `:"")+(r==="server"||a?"no dictation available: this browser has no speech recognition and the server has no STT endpoint (AGENTUS_STT_BASE_URL)":"no dictation available in this browser — set the server STT endpoint or use Chromium/Edge")}),!1)}catch(u){return this.#R(n)||this.#r({status:"error",error:String(u?.message??u)}),!1}}#H(t){const s=PS();if(!s)throw new Error("speech recognition unavailable");const n=new s;n.lang=t.lang,n.continuous=!0,n.interimResults=!0,n.maxAlternatives=1;let i="";n.onstart=()=>this.#r({status:"listening",engine:"browser",error:""}),n.onresult=r=>{let a="";for(let l=r.resultIndex;l<r.results.length;l+=1){const c=r.results[l],u=c[0]?.transcript??"";c.isFinal?i+=u:a+=u}this.#r({text:i.trim(),interim:a.trim()})},n.onerror=r=>{const a=String(r?.error??"unknown");this.#r({status:"error",error:a==="not-allowed"||a==="service-not-allowed"?"microphone permission denied":a==="no-speech"?"heard nothing — try again closer to the microphone":`speech recognition failed: ${a}`})},n.onend=()=>{this.#e.status==="listening"&&this.#r({status:"idle",interim:""}),this.#i=null},this.#i=n,this.#r({status:"requesting",engine:"browser"});try{n.start()}catch(r){throw this.#i=null,new Error(String(r?.message??r))}}async#L(t,s,n){const i=OS()?LS():null;if(!i&&typeof navigator.mediaDevices?.getUserMedia!="function"){await this.#u(t);return}const r=window.AudioContext??window.webkitAudioContext;if(!i&&!r)throw new Error("this browser cannot process audio");this.#r({status:"requesting",engine:"stream",error:""}),this.#x=!0,this.#w=!1,this.#C=0,this.#y="",this.#I=s,this.#k=!0,this.#m.length=0,this.#N();const a=l=>this.#U(l);if(i?await this.#F(i,a,n):await this.#W(r,a,n),this.#R(n)){this.#A(),this.#O(),this.#r({status:"idle",interim:"",text:""});return}this.#r({status:"listening",engine:"stream",seconds:0}),this.#t=window.setInterval(()=>this.#r({seconds:this.#e.seconds+1}),1e3)}#U(t){const s=this.#n;s&&s.readyState===WebSocket.OPEN?s.send(t):this.#m.length<ZN&&this.#m.push(t)}#N(){if(this.#n||!this.#k)return;const t=this.#I?`?sessionId=${encodeURIComponent(this.#I)}`:"",s=new WebSocket(`${location.protocol==="https:"?"wss":"ws"}://${location.host}/ws/asr${t}`);s.binaryType="arraybuffer",this.#n=s,s.onopen=()=>{this.#C=0,this.#y="";for(const n of this.#m)s.send(n);this.#m.length=0,this.#e.status!=="listening"&&this.#r({status:"listening",engine:"stream",error:""})},s.onmessage=n=>{let i;try{i=JSON.parse(String(n.data))}catch{return}i.t==="asr-partial"?this.#r({interim:String(i.text??"")}):i.t==="asr-final"?(this.#d=`${this.#d}${i.text??""}`.replace(/\s+/g," ").trim(),this.#r({text:this.#d,interim:""})):i.t==="asr-error"?this.#g(String(i.error??"streaming asr failed")):i.t==="asr-done"&&(this.#w||!this.#k||!this.#x?this.#j():this.#g("the recogniser ended the turn by itself"))},s.onerror=()=>this.#g("the streaming socket failed — is the server up?"),s.onclose=()=>{this.#n===s&&(this.#n=null),this.#g(this.#y||"the streaming socket failed — is the server up?")}}#g(t){if(!(!this.#k||this.#w||!this.#x)&&(this.#y||(this.#y=t),this.#S===null)){if(this.#C>=JN){this.#r({status:"error",error:this.#y}),this.#y="",this.#j();return}this.#C+=1,this.#S=window.setTimeout(()=>{this.#S=null,this.#N()},XN*this.#C)}}async#W(t,s,n){const i=await r0({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}});if(this.#R(n)){for(const u of i.getTracks())u.stop();return}this.#_=i;const r=new t({sampleRate:16e3});this.#c=r;const a=r.createMediaStreamSource(i),l=r.createScriptProcessor(2048,1,1),c=r.createGain();c.gain.value=0,this.#h=l,l.onaudioprocess=u=>{const h=u.inputBuffer.getChannelData(0);if(this.#T(h),!this.#x)return;const d=BS(h,r.sampleRate,16e3);d.length&&s(d.buffer)},a.connect(l),l.connect(c),c.connect(r.destination)}async#F(t,s,n){let i="permission";for(let r=0;r<12&&(i=String(t.start(16e3)),!(i==="ok"||i==="already"));r++){if(i==="permission"){this.#r({status:"requesting",engine:"stream"}),await new Promise(a=>setTimeout(a,600));continue}throw new Error(`手机上的原生麦克风打不开(${i})`)}if(i!=="ok"&&i!=="already")throw new Error(`手机上的原生麦克风打不开(${i})`);if(this.#R(n)){try{t.stop()}catch{}return}this.#p=t,window.__asMic=r=>{const a=atob(r),l=a.length>>1,c=new Int16Array(l);for(let h=0;h<l;h++){const d=a.charCodeAt(2*h),p=a.charCodeAt(2*h+1);c[h]=(p<<8|d)<<16>>16}const u=new Float32Array(l);for(let h=0;h<l;h++)u[h]=c[h]/32768;this.#T(u),this.#x&&s(c.buffer)}}#O(){this.#$(),this.#k=!1,this.#w=!1,this.#C=0,this.#y="",this.#A(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#x=!0}#R(t){return t!==this.#a}#A(){if(this.#h){this.#h.onaudioprocess=null;try{this.#h.disconnect()}catch{}this.#h=null}if(this.#c&&(this.#c.close().catch(()=>{}),this.#c=null),this.#_){for(const t of this.#_.getTracks())t.stop();this.#_=null}if(this.#p){try{this.#p.stop()}catch{}this.#p=null}window.__asMic=void 0,this.#f=0,this.#b.fill(0)}#j(){this.#O(),this.#r({status:"idle",interim:""})}async#K(t,s){if(typeof navigator.mediaDevices?.getUserMedia!="function"){await this.#u(t);return}this.#r({status:"requesting",engine:"server",error:""});const n=await r0({audio:!0});if(this.#R(s)){for(const a of n.getTracks())a.stop();return}const i=MediaRecorder.isTypeSupported("audio/webm;codecs=opus")?"audio/webm;codecs=opus":"",r=new MediaRecorder(n,i?{mimeType:i}:void 0);this.#o=[],r.ondataavailable=a=>{a.data.size&&this.#o.push(a.data)},r.onstop=()=>{for(const a of n.getTracks())a.stop();this.#q(t)},this.#s=r,r.start(1e3),this.#r({status:"recording",engine:"server",seconds:0}),this.#t=window.setInterval(()=>this.#r({seconds:this.#e.seconds+1}),1e3)}async#u(t){this.#r({status:"requesting",engine:"server",error:""});const s=await uR();if(!s){this.#r({status:"idle",text:"",interim:"",error:""});return}await this.#M(t,s)}async#M(t,s){this.#r({status:"transcribing"});try{const n=await fetch(`/api/stt?language=${encodeURIComponent(t.lang)}`,{method:"POST",credentials:"same-origin",headers:{"content-type":s.type||"audio/webm"},body:s}),i=await n.json().catch(()=>({}));if(!n.ok)throw new Error(i.error??`stt ${n.status}`);this.#r({status:"idle",text:String(i.text??"").trim(),interim:""})}catch(n){this.#r({status:"error",error:String(n?.message??n)})}}async#q(t){this.#t&&(window.clearInterval(this.#t),this.#t=null);const s=new Blob(this.#o,{type:this.#o[0]?.type||"audio/webm"});if(this.#o=[],this.#s=null,!s.size){this.#r({status:"error",error:"nothing was recorded — check the microphone"});return}await this.#M(t,s)}stop(){if(this.#a+=1,this.#e.status==="requesting"){this.cancel();return}if(this.#i){try{this.#i.stop()}catch{}return}if(this.#n&&this.#n.readyState===WebSocket.OPEN){this.#A(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#w=!0,this.#r({status:"transcribing"});try{this.#n.send(JSON.stringify({t:"asr-stop"}))}catch{this.#j();return}window.setTimeout(()=>{this.#e.status==="transcribing"&&this.#j()},8e3);return}this.#s&&this.#s.state!=="inactive"&&this.#s.stop(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#e.status==="listening"&&this.#r({status:"idle",interim:""})}cancel(){if(this.#a+=1,this.#i){try{this.#i.abort()}catch{}this.#i=null}this.#s&&this.#s.state!=="inactive"&&(this.#s.onstop=null,this.#s.stop(),this.#s=null),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#O(),this.#d="",this.#o=[],this.#r({status:"idle",text:"",interim:"",error:"",seconds:0})}consume(){const t=this.#e.text.trim();return this.#r({status:"idle",text:"",interim:"",seconds:0}),t}setOwner(t){this.#z=t}owns(t){return this.#z===t}#z="chat"}function BS(e,t,s){if(t===s){const a=new Int16Array(e.length);for(let l=0;l<e.length;l+=1)a[l]=l0(e[l]);return a}const n=t/s,i=Math.max(0,Math.floor(e.length/n)),r=new Int16Array(i);for(let a=0;a<i;a+=1){const l=a*n,c=Math.floor(l),u=Math.min(c+1,e.length-1),h=l-c;r[a]=l0(e[c]*(1-h)+e[u]*h)}return r}function l0(e){const t=Math.round((Number.isFinite(e)?e:0)*32767);return t>32767?32767:t<-32768?-32768:t}const pe=new hR;typeof window<"u"&&(window.__asDictation=pe);function r_(){return g.useSyncExternalStore(pe.subscribe,pe.getSnapshot)}let Hn=UN();const Nh=new Set;async function $S(){try{const e=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({prefs:Hn})});return e.ok?"":(await e.json().catch(()=>({}))).error??`save failed (${e.status})`}catch(e){return String(e?.message??e)}}function c0(e){const t={...kl};if(!e||typeof e!="object")return t;const s=e;return{autoRead:typeof s.autoRead=="boolean"?s.autoRead:t.autoRead,speakMode:s.speakMode==="off"||s.speakMode==="reply"||s.speakMode==="brief"?s.speakMode:typeof s.autoRead=="boolean"&&s.autoRead?"reply":"off",voiceURI:typeof s.voiceURI=="string"?s.voiceURI:t.voiceURI,rate:Number.isFinite(Number(s.rate))?Math.min(2,Math.max(.5,Number(s.rate))):t.rate,lang:typeof s.lang=="string"&&s.lang?s.lang:t.lang,serverTts:typeof s.serverTts=="boolean"?s.serverTts:t.serverTts,stt:s.stt==="browser"||s.stt==="stream"||s.stt==="server"?s.stt:"auto"}}function dR(e){Hn=e,TS(Hn);for(const t of Nh)t()}async function fR(){try{const e=await fetch("/api/settings",{credentials:"same-origin"});if(!e.ok)return;const t=await e.json(),s=c0(t.prefs),n=c0(t.prefsDefaults);if(uf.every(r=>s[r]===n[r])&&uf.some(r=>Hn[r]!==s[r])){$S();return}uf.some(r=>Hn[r]!==s[r])&&dR(s)}catch{}}const uf=["speakMode","voiceURI","rate","lang","serverTts","stt"];function pR(e){const t={...Hn,...e},s=Number.isFinite(t.rate)?Math.min(2,Math.max(.5,t.rate)):1;Hn={...t,rate:s},TS(Hn);for(const n of Nh)n();$S()}function mR(){return Hn}function _o(){return[g.useSyncExternalStore(t=>(Nh.add(t),()=>Nh.delete(t)),()=>Hn),pR]}function gR(e,t,s){const[n]=_o(),i=(s??n.speakMode??(n.autoRead?"reply":"off"))==="reply",r=e?.length?e.map(a=>a.key).join(""):"";g.useEffect(()=>{if(!(!i||!t||!e?.length))for(const a of e)a.text.trim()&&aR(a.key,!0,i)&&oR(a)},[r,t,i])}function _R(e,t,s){const[n]=_o(),i=(s??n.speakMode??(n.autoRead?"reply":"off"))==="brief";g.useEffect(()=>{!i||!t||!e||!e.text.trim()||Ft.speak(e.text,e.key,n)},[e?.key,t,i])}const Fo=2,Yp="agentus.webnotify",tr={on:!0,sound:"chime",volume:.6};function vR(e){return e.available&&e.permission==="granted"&&e.enabled&&e.hidden}function yR(e,t,s,n){return e.sound!=="chime"||n||!s.enabled||!s.hidden?!1:t==="approval"||t==="agent_done"||t==="error"}function bR(e){return e==="approval"?[{freq:659.25,at:0,dur:.13},{freq:987.77,at:.15,dur:.28}]:e==="error"?[{freq:739.99,at:0,dur:.11},{freq:1046.5,at:.12,dur:.13},{freq:739.99,at:.27,dur:.26}]:[{freq:880,at:0,dur:.16},{freq:659.25,at:.2,dur:.3}]}function wR(e){try{return new URL(e,typeof location>"u"?"http://localhost/":location.href).searchParams.get("session")}catch{return null}}function xR(){try{const e=localStorage.getItem(Yp);if(!e)return{...tr,v:Fo};const t=JSON.parse(e),s={on:typeof t.on=="boolean"?t.on:tr.on,sound:t.sound==="chime"||t.sound==="silent"||t.sound==="default"?t.sound:tr.sound,volume:typeof t.volume=="number"&&Number.isFinite(t.volume)?Math.min(1,Math.max(0,t.volume)):tr.volume};if(t.v!==Fo&&s.sound==="default"&&(s.sound=tr.sound),t.v!==Fo){s.v=Fo;try{localStorage.setItem(Yp,JSON.stringify(s))}catch{}}return s}catch{return{...tr,v:Fo}}}function hu(){return typeof window>"u"||!("Notification"in window)?"no-api":window.isSecureContext?"ok":"insecure"}let hf=null;function FS(){if(typeof window>"u")return null;const e=window.AudioContext??window.webkitAudioContext;if(!e)return null;if(!hf)try{hf=new e}catch{return null}return hf}function ca(){const e=FS();e&&e.state==="suspended"&&e.resume()}function SR(e,t,s,n,i){const r=e.createOscillator(),a=e.createGain();r.type="sine",r.frequency.value=t,a.gain.setValueAtTime(1e-4,s),a.gain.linearRampToValueAtTime(i,s+.012),a.gain.exponentialRampToValueAtTime(1e-4,s+n),r.connect(a),a.connect(e.destination),r.start(s),r.stop(s+n+.02)}function Gp(e,t){const s=FS();if(!s)return;s.state==="suspended"&&s.resume();const n=s.currentTime+.01;for(const i of bR(t))SR(s,i.freq,n+i.at,i.dur,e)}const Jp=new Map;let Xp=0;async function zS(){if(typeof navigator>"u"||!("serviceWorker"in navigator))return null;try{return await navigator.serviceWorker.getRegistration()??null}catch{return null}}let Zp=null;function kR(e){Zp=e}function HS(e){if(!e)return;const t=wR(e);if(t&&Zp){Zp(t);return}location.assign(e)}const u0="/icons/icon-192.png";async function h0(e,t){const s={body:e.body,tag:e.noticeId,icon:u0,badge:u0,data:{open:e.open??null,noticeId:e.noticeId},renotify:!0,requireInteraction:!!e.sticky,silent:t.sound!=="default"},n=await zS();if(n&&typeof n.showNotification=="function")try{return await n.showNotification(e.title,s),Xp=Date.now(),!0}catch{}try{const i=new Notification(e.title,s);return i.onclick=()=>{HS(e.open),i.close()},Jp.set(e.noticeId,i),Xp=Date.now(),!0}catch{return!1}}async function d0(e){const t=Jp.get(e);t&&(t.close(),Jp.delete(e));const s=await zS();if(!(!s||typeof s.getNotifications!="function"))try{for(const n of await s.getNotifications({tag:e}))n.close()}catch{}}class CR{#e=tr;#l=null;#i=new Set;#s;constructor(){this.#e=typeof localStorage>"u"?{...tr}:xR(),this.#s=this.#o()}#o(){const t=hu();return{availability:t,permission:t==="ok"?Notification.permission:"unavailable",prefs:this.#e,last:this.#l}}#t(){this.#s=this.#o();for(const t of this.#i)t()}subscribe=t=>(this.#i.add(t),()=>this.#i.delete(t));getSnapshot=()=>this.#s;setPrefs(t){this.#e={...this.#e,...t},t.volume!==void 0&&(this.#e.volume=Math.min(1,Math.max(0,t.volume)));try{localStorage.setItem(Yp,JSON.stringify({...this.#e,v:Fo}))}catch{}this.#t()}async requestPermission(){if(hu()!=="ok")return"unavailable";ca();try{const t=await Notification.requestPermission();return this.#t(),this.#o().permission}catch{return this.#o().permission}}handle(t){if(t.op==="dismiss"){d0(t.noticeId);return}const s=hu(),n={available:s==="ok",permission:s==="ok"?Notification.permission:"unavailable",enabled:this.#e.on,hidden:typeof document>"u"?!1:document.hidden},i={enabled:this.#e.on,hidden:typeof document>"u"?!1:document.hidden};yR(this.#e,t.kind,i,Eh())&&Gp(this.#e.volume,t.kind),vR(n)&&h0(t,this.#e).then(r=>{this.#l={title:t.title,at:Date.now(),drawn:r},this.#t()})}async test(){if(hu()!=="ok")return!1;ca();const t={op:"upsert",noticeId:`test:${Date.now()}`,kind:"agent_done",title:"测试通知",body:"这条通知能弹出来,就说明这台设备没问题",open:null,at:Date.now()},s=await h0(t,this.#e);return this.#l={title:t.title,at:Date.now(),drawn:s},this.#t(),this.#e.sound==="chime"&&!Eh()&&Gp(this.#e.volume,"agent_done"),s}async closeAll(t){for(const s of t)await d0(s)}lastDrawnAt(){return Xp}}const Si=new CR;function ER(){typeof navigator>"u"||!("serviceWorker"in navigator)||navigator.serviceWorker.addEventListener("message",e=>{const t=e.data;t?.t==="agentus:notify-open"&&HS(t.open??null)})}function NR(){return g.useSyncExternalStore(Si.subscribe,Si.getSnapshot)}class df extends Error{constructor(){super("unauthorized"),this.name="AuthRequired"}}const Qp="agentus.unread",RR=8e3,jR=8e3;function TR(){try{const e=localStorage.getItem(Qp),t=e?JSON.parse(e):[];return Array.isArray(t)?t.filter(s=>typeof s=="string"):[]}catch{return[]}}function AR(e){try{const t=[...e];t.length?localStorage.setItem(Qp,JSON.stringify(t)):localStorage.removeItem(Qp)}catch{}}class MR{sessions=[];cold=[];archived=[];byId=new Map;activeId=null;conn="connecting";net="ok";netError="";auth="unknown";authInfo=null;authError="";authBusy=!1;blocked=null;lastSeq={};ws=null;#e=0;#l=null;#i=[];#s=new Map;#o=new Map;#t=new Set;#n=new Map;#c=new Set;#h=new Set(TR());#_=new Set;#p=new Map;#d=new Set;#f=null;#v;#b(t){try{t?localStorage.setItem("agentus.active",t):localStorage.removeItem("agentus.active")}catch{}}#D(){try{return new URL(location.href).searchParams.get("session")}catch{return null}}#x(t){try{const s=new URL(location.href),n=t??null;if((s.searchParams.get("session")??null)===n)return;n?s.searchParams.set("session",n):s.searchParams.delete("session"),history.replaceState(history.state,"",s.toString())}catch{}}followUrl(){const t=this.#D();!t||t===this.activeId||this.byId.has(t)&&this.setActive(t)}#I(){const t=this.#D();if(t)return this.#b(t),t;try{return localStorage.getItem("agentus.active")}catch{return null}}#k=0;constructor(){this.#v=this.#w()}async#a(t,s,n){const i=n?.timeoutMs??15e3,r=n?.retry===!1?1:2;let a=null;for(let l=0;l<r;l++){const c=new AbortController,u=setTimeout(()=>c.abort(),i);try{const h=await fetch(t,{...s,signal:c.signal});if(clearTimeout(u),h.status===401)throw this.#S("会话已过期,请重新登录"),new df;const d=h.status===204?null:await h.json().catch(()=>null);if(!h.ok){const p=d?.error??`HTTP ${h.status}`,f=new Error(p);throw f.httpStatus=h.status,f.httpBody=d,f}return this.#m(!0,""),d}catch(h){if(clearTimeout(u),h instanceof df||h.httpStatus!==void 0)throw h;a=h;const d=h?.name==="AbortError"?`请求超时 ${i/1e3}s`:String(h?.message??h);if(l===r-1)throw this.#m(!1,`${d} (${t})`),new Error(d);await new Promise(p=>setTimeout(p,600))}}throw a instanceof Error?a:new Error(String(a))}#m(t,s){const n=t?"ok":"degraded";this.net===n&&this.netError===s||(this.net=n,this.netError=s,this.bump())}#S(t){const s=this.auth==="in";if(this.auth="out",this.authError=s?t:this.authError,this.ws){const n=this.ws;this.ws=null,n.onclose=null;try{n.close()}catch{}}this.conn="offline",(s||this.sessions.length)&&(this.sessions=[],this.cold=[],this.archived=[],this.byId.clear(),this.activeId=null,this.#b(null)),this.bump()}async checkAuth(){try{const t=await this.#a("/api/auth/me",void 0,{retry:!1,timeoutMs:8e3});if(this.authInfo=t,t.authEnabled&&!t.authenticated){this.#S(""),this.authError="";return}this.#e=0,this.auth="in",this.authError="",this.bump(),this.connect(),this.refreshRows()}catch(t){if(t instanceof df)return;const s=`无法连接服务端:${String(t.message??t)}`;if(this.auth==="in"){this.#m(!1,s),this.#C(Math.min(1e4,800*2**this.#e++));return}this.auth="out",this.authError=s,this.bump()}}#C(t){this.#l||(this.#l=setTimeout(()=>{this.#l=null,this.checkAuth()},t))}async login(t,s){if(this.authBusy)return!1;this.authBusy=!0,this.authError="",this.bump();try{const n=await fetch("/api/auth/login",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({username:t,password:s})});if(n.status===401)return this.authError="用户名或密码不正确",!1;if(n.status===429){const r=await n.json().catch(()=>({})),a=Math.ceil((r.retryAfterMs??3e4)/1e3);return this.authError=`尝试次数过多,请 ${a} 秒后再试`,!1}if(!n.ok)return this.authError=`登录失败:HTTP ${n.status}`,!1;const i=await n.json();return this.authInfo={authEnabled:!0,authenticated:!0,kind:"session",username:i.username,expiresAt:i.expiresAt??null,usingDefaultPassword:!!i.usingDefaultPassword},this.auth="in",this.authError="",this.bump(),this.connect(),!0}catch(n){return this.authError=`登录请求失败:${String(n.message??n)}`,!1}finally{this.authBusy=!1,this.bump()}}async logout(){try{await fetch("/api/auth/logout",{method:"POST"})}catch{}this.#S(""),this.authError="",this.bump()}subscribe=t=>(this.#d.add(t),()=>this.#d.delete(t));getSnapshot=()=>this.#v;markPermAnswered(t,s,n=!0){this.#p.set(t,{label:s,at:Date.now(),armed:n}),this.bump()}permAnswer(t){const s=this.#p.get(t);if(s)return{label:s.label,at:s.at,lapsed:s.armed&&Date.now()-s.at>RR}}#y(){if(!this.#p.size)return;const t=new Set;for(const s of this.byId.values())for(const n of s.perms)t.add(n.requestId);for(const s of[...this.#p.keys()])t.has(s)||this.#p.delete(s)}#w(){return{sessions:this.sessions,cold:this.cold,archived:this.archived,activeId:this.activeId,active:this.activeId?this.byId.get(this.activeId):void 0,conn:this.conn,net:this.net,netError:this.netError,auth:this.auth,authInfo:this.authInfo,authError:this.authError,authBusy:this.authBusy,blocked:this.blocked,unread:new Set([...this.#c,...this.#h]),version:this.#k}}bump(){this.#k++,this.#f==null&&(typeof requestAnimationFrame=="function"?this.#f=requestAnimationFrame(()=>{this.#f=null,this.#E()}):typeof setTimeout=="function"?this.#f=setTimeout(()=>{this.#f=null,this.#E()},0):this.#E()),this.#$()}#E(){this.#f!=null&&(typeof cancelAnimationFrame=="function"?cancelAnimationFrame(this.#f):typeof clearTimeout=="function"&&clearTimeout(this.#f),this.#f=null);for(const t of this.byId.values())t.busy=t.info.status==="running";this.#v=this.#w();for(const t of this.#d)t()}#$(){typeof document>"u"||!document.hidden||this.#f!=null&&this.#E()}connect(){if(this.auth==="out")return;const t=location.protocol==="https:"?"wss":"ws",s=new WebSocket(`${t}://${location.host}/ws`);this.ws=s,s.onopen=()=>{for(this.conn="online",this.net="ok",this.netError="",this.#e=0,s.send(JSON.stringify({t:"resume",lastSeq:this.lastSeq}));this.#i.length;){const n=this.#i.shift();try{s.send(JSON.stringify(n))}catch{this.#i.unshift(n);break}}this.bump(),this.refreshRows(),window.setTimeout(()=>this.drainPersistedQueues(),700)},s.onmessage=n=>this.apply(JSON.parse(n.data)),s.onclose=()=>{if(this.conn="offline",this.bump(),this.auth==="out")return;const n=Math.min(1e4,800*2**this.#e++);this.#C(n)},s.onerror=()=>s.close()}sendPrompt(t,s,n=[]){!s.trim()&&!n.length||this.#T(t,{text:s,attachments:n})}#T(t,s){const n=`p-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,i={t:"prompt",sessionId:t,text:s.text,attachments:s.attachments,pid:n,...s.interrupt?{interrupt:!0}:{}};if(!this.send(i)){if(s.rowId){const l=this.#s.get(t)??[];this.#g(t,l.map(c=>c.id===s.rowId?{...c,inflight:!1}:c))}return}const a=setTimeout(()=>this.#H(n),jR);this.#n.set(n,{sessionId:t,pid:n,text:s.text,attachments:s.attachments,rowId:s.rowId,timer:a})}#P(t,s){const n=s?this.#n.get(s):[...this.#n.values()].find(r=>r.sessionId===t);if(!n)return;for(const r of[...this.#n.values()])r.sessionId===t&&(clearTimeout(r.timer),this.#n.delete(r.pid));clearTimeout(n.timer),this.#n.delete(n.pid);const i=this.#s.get(t)??[];i.some(r=>r.pid===n.pid)&&this.#g(t,i.filter(r=>r.pid!==n.pid))}#r(t){const s=this.#n.get(t);s&&(clearTimeout(s.timer),this.#n.delete(t))}#H(t){const s=this.#n.get(t);if(!s)return;this.#n.delete(t),this.#t.delete(s.sessionId);const n=this.#s.get(s.sessionId)??[];s.rowId&&n.some(i=>i.id===s.rowId)?this.#g(s.sessionId,n.map(i=>i.id===s.rowId?{...i,inflight:!1,unsure:!0}:i)):n.some(i=>i.pid===s.pid)||this.#g(s.sessionId,[...n,{id:`q-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,text:s.text,attachments:s.attachments,at:Date.now(),unsure:!0,pid:s.pid}]),this.#m(!1,"消息未确认送达 — 已放回队列,点 ↑ 重发")}send(t){return this.auth==="out"?(this.#m(!1,"未登录 — 请先登录再发送指令"),!1):this.ws?.readyState===WebSocket.OPEN?(this.ws.send(JSON.stringify(t)),!0):t.t==="prompt"?(this.enqueuePrompt(t.sessionId,t.text,t.attachments??[]),this.#m(!1,"连接已断开 — 消息已排队,重连后自动发送"),!1):t.t==="respond-permission"?(this.#i.push(t),this.#i.length>20&&this.#i.shift(),this.#m(!1,"连接已断开 — 指令已排队,重连后自动发送"),!1):(this.#m(!1,"连接已断开 — 该操作未能送达"),!1)}#L(t){return`agentus.queue.${t}`}#U(t){try{const s=localStorage.getItem(this.#L(t)),n=s?JSON.parse(s):[];return Array.isArray(n)?n.filter(i=>i&&typeof i.text=="string"&&i.text.trim()).map(i=>({id:String(i.id??`q-${i.at??Date.now()}`),text:i.text,attachments:i.attachments??[],at:i.at??Date.now(),...i.unsure?{unsure:!0,pid:typeof i.pid=="string"?i.pid:void 0}:{}})):[]}catch{return[]}}#N(t){const s=this.#s.get(t)??this.#U(t);return s.length&&this.#s.set(t,s),s}drainPersistedQueues(){try{for(let t=0;t<localStorage.length;t++){const s=localStorage.key(t);if(!s?.startsWith("agentus.queue."))continue;const n=s.slice(14);this.#N(n),this.drainQueue(n)}}catch{}}#g(t,s){s.length?this.#s.set(t,s):this.#s.delete(t);try{s.length?localStorage.setItem(this.#L(t),JSON.stringify(s)):localStorage.removeItem(this.#L(t))}catch{}const n=this.byId.get(t);n&&(n.queue=s),this.bump()}queueSetup(t,s){s.length&&this.#o.set(t,s)}#W(t){const s=this.#o.get(t);if(s?.length){this.#o.delete(t);for(const n of s)n.kind==="model"?this.send({t:"set-model",sessionId:t,modelId:n.value}):n.kind==="mode"?this.send({t:"set-mode",sessionId:t,modeId:n.value}):this.send({t:"set-config",sessionId:t,configId:n.id,value:n.value})}}enqueuePrompt(t,s,n=[]){const i=this.#s.get(t)??[];this.#g(t,[...i,{id:`q-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,text:s,attachments:n,at:Date.now()}])}sendToCold(t,s,n=[]){const i=this.#s.get(t)??this.#N(t),r=i[i.length-1],a=this.sessions.some(u=>u.id===t&&u.status==="ready"),l=!!(r&&r.text===s&&!a&&Date.now()-r.at<5e3),c=!s.trim()&&!n.length;!l&&!c&&this.enqueuePrompt(t,s,n),this.resume(t)}dropQueued(t,s){const n=this.#s.get(t)??[];this.#g(t,n.filter(i=>i.id!==s))}editQueued(t,s,n){const i=this.#s.get(t)??[],r=n.trim();this.#g(t,r?i.map(a=>a.id===s?{...a,text:r}:a):i.filter(a=>a.id!==s))}sendQueuedNow(t,s){const n=this.#s.get(t)??[],i=n.find(r=>r.id===s);i&&(this.#t.add(t),this.#g(t,n.map(r=>r.id===s?{...r,inflight:!0,unsure:!1}:r)),this.#T(t,{text:i.text,attachments:i.attachments,interrupt:!0,rowId:s}))}sendNow(t,s,n=[]){if(!s.trim()&&!n.length)return;this.#N(t),this.enqueuePrompt(t,s,n);const i=this.#s.get(t)??[],r=i[i.length-1];r&&this.sendQueuedNow(t,r.id)}drainQueue(t){const s=this.#s.get(t)??this.#N(t),n=s[0];!n||n.inflight||n.unsure||this.#t.has(t)||Qr(this.byId.get(t))||this.sessions.find(r=>r.id===t)?.status==="running"||(this.#g(t,s.map(r=>r.id===n.id?{...r,inflight:!0}:r)),this.#T(t,{text:n.text,attachments:n.attachments,interrupt:!0,rowId:n.id}))}#F(t){this.#t.delete(t);const s=this.#s.get(t)??[];s.some(n=>n.inflight)&&this.#g(t,s.filter(n=>!n.inflight))}#O(t){this.#t.delete(t);const s=this.#s.get(t)??[];s.some(n=>n.inflight)&&this.#g(t,s.map(n=>n.inflight?{...n,inflight:!1}:n))}setActive(t){this.activeId=t,this.#b(t),this.#x(t),this.clearUnread(t),this.#v=this.#w(),this.bump();const s=this.byId.get(t);s&&!s.loaded&&this.loadHistory(t)}markUnread(t){this.#c.has(t)||(this.#c=new Set(this.#c).add(t),this.bump())}clearUnread(t){if(!this.#c.has(t))return;const s=new Set(this.#c);s.delete(t),this.#c=s,this.bump()}isUnread(t){return this.#c.has(t)||this.#h.has(t)}toggleUnread(t){if(this.isUnread(t)){const s=new Set(this.#c);s.delete(t),this.#c=s;const n=new Set(this.#h);n.delete(t),this.#h=n}else this.#h=new Set(this.#h).add(t);AR(this.#h),this.bump()}async loadHistory(t){try{const{messages:s,hasOlder:n}=await this.#a(`/api/sessions/${t}/messages?tail=1`),i=this.#u(t);i.seen.clear(),i.msgs=[],i.blocks.clear(),i.minSeq=null,i.plan=null,i.turn=0,i.turnStart=0;for(const r of s)this.#B(i,r);i.loaded=!0,i.hasOlder=!!n,this.#M(i),this.#q(i),this.bump(),this.#K(i)}catch{}}async loadEarlier(t){const s=this.#u(t);if(s.loadingOlder||!s.hasOlder||s.minSeq==null)return 0;s.loadingOlder=!0,this.bump();try{const{messages:n,hasOlder:i}=await this.#a(`/api/sessions/${t}/messages?before=${s.minSeq}`),r=[],a=new Map;for(const c of n)this.#B(s,c,{list:r,index:a});const l=[];for(const c of r){const u=s.blocks.get(c.key),h=u===void 0?void 0:s.msgs[u];if(h&&h.kind===c.kind&&(c.kind==="agent"||c.kind==="thought")&&h.kind===c.kind){const d=h,p=c;if(p.text.length>d.text.length){const f=s.msgs.indexOf(d);f>=0&&(s.msgs[f]={...d,text:p.text})}continue}l.push(c)}return l.length&&(s.msgs=[...l,...s.msgs]),s.blocks=e0(s.msgs),s.hasOlder=!!i,l.length}catch{return-1}finally{s.loadingOlder=!1,this.bump()}}async loadBackends(){return await this.#a("/api/backends")}async createBackend(t){await this.#a("/api/backends",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}async updateBackend(t,s){await this.#a(`/api/backends/${encodeURIComponent(t)}`,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(s)})}async deleteBackend(t){await this.#a(`/api/backends/${encodeURIComponent(t)}`,{method:"DELETE"})}async inspectBackend(t){return await this.#a(`/api/backends/${encodeURIComponent(t)}/inspect`,{method:"POST"},{timeoutMs:6e4,retry:!1})}async listEntries(t){return await this.#a(`/api/fs/dirs?files=1&path=${encodeURIComponent(t)}`)}async readFile(t){return await this.#a(`/api/fs/file?path=${encodeURIComponent(t)}`)}async statFile(t){return await this.#a(`/api/fs/stat?path=${encodeURIComponent(t)}`)}async writeFile(t,s,n){return await this.#a("/api/fs/file",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({path:t,content:s,...n?{ifHash:n}:{}})},{retry:!1})}async fork(t){const s=await this.#a(`/api/sessions/${t}/fork`,{method:"POST"},{timeoutMs:12e4,retry:!1});return this.sessions.some(n=>n.id===s.id)||(this.sessions=[s,...this.sessions]),this.cold=this.cold.filter(n=>n.id!==s.id),this.archived=this.archived.filter(n=>n.id!==s.id),this.setActive(s.id),s.id}async setModel(t,s){const n=await this.#a(`/api/sessions/${t}/model`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({modelId:s})},{timeoutMs:9e4,retry:!1}),i=this.byId.get(t);i&&(i.info={...i.info,...n});const r=this.sessions.findIndex(a=>a.id===t);return r>=0&&(this.sessions[r]={...this.sessions[r],...n}),this.bump(),n}async setContextLimit(t,s,n={}){const i=await this.#a(`/api/sessions/${t}/context-limit`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({limit:s,...n})}),r=this.byId.get(t);r&&(r.info={...r.info,...i});const a=this.sessions.findIndex(c=>c.id===t);a>=0&&(this.sessions[a]={...this.sessions[a],...i});const l=this.archived.findIndex(c=>c.id===t);l>=0&&(this.archived[l]={...this.archived[l],...i}),this.bump()}async setWorkspace(t,s){const n=await this.#a(`/api/sessions/${t}/workspace`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({path:s})}),i=this.byId.get(t);i&&(i.info={...i.info,...n});const r=this.sessions.findIndex(a=>a.id===t);r>=0&&(this.sessions[r]={...this.sessions[r],...n}),this.bump()}async createSession(t,s,n){const i=await this.#a("/api/sessions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({backend:t,cwd:s,title:n||void 0})},{retry:!1}),r=this.#u(i.id);return r.info={...r.info,...i},this.sessions.some(a=>a.id===i.id)||(this.sessions=[i,...this.sessions]),this.bump(),i.id}async refreshRows(){try{const{cold:t,archived:s}=await this.#a("/api/sessions");this.cold=t??[],this.archived=s??[],this.bump()}catch{}}async rename(t,s){const n=await this.#a(`/api/sessions/${t}/rename`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({title:s})}),i=this.byId.get(t);i&&(i.info={...i.info,...n});for(const r of[this.sessions,this.archived]){const a=r.findIndex(l=>l.id===t);a>=0&&(r[a]={...r[a],...n})}return this.bump(),n}async regenerateTitle(t){const s=await this.#a(`/api/sessions/${t}/title/regenerate`,{method:"POST"}),n=s.info,i=this.byId.get(t);i&&(i.info={...i.info,...n});for(const r of[this.sessions,this.cold,this.archived]){const a=r.findIndex(l=>l.id===t);a>=0&&(r[a]={...r[a],...n})}return this.bump(),s}async resume(t){if(this.#u(t),this.setActive(t),!this.#_.has(t)){this.#_.add(t),this.#u(t).resuming=!0,this.bump();try{const s=await this.#a(`/api/sessions/${t}/resume`,{method:"POST"},{timeoutMs:12e4,retry:!1});this.#u(t).info=s,this.sessions.some(n=>n.id===t)||(this.sessions=[s,...this.sessions]),this.cold=this.cold.filter(n=>n.id!==t),await this.loadHistory(t)}catch(s){const n=s.httpStatus,i=s.httpBody;if(n===409&&(i?.code==="home_mismatch"||i?.code==="context_missing")){const r=this.sessions.find(a=>a.id===t)??this.cold.find(a=>a.id===t)??this.archived.find(a=>a.id===t);this.blocked={id:t,title:r?.title??t,code:i.code,sessionHome:i.sessionHome??null,rowHome:i.rowHome??null},this.bump();return}this.#m(!1,`恢复失败:${String(s.message??s)}`)}finally{this.#_.delete(t),this.#u(t).resuming=!1,this.bump()}}}async restart(t){try{const s=await this.#a(`/api/sessions/${t}/restart`,{method:"POST"},{timeoutMs:12e4,retry:!1}),n=this.#u(t);n.info={...n.info,...s};for(const i of[this.sessions,this.cold,this.archived]){const r=i.findIndex(a=>a.id===t);r>=0&&(i[r]={...i[r],...s})}this.bump()}catch(s){const n=s.httpStatus,i=s.httpBody;if(n===409&&(i?.code==="home_mismatch"||i?.code==="context_missing")){const r=this.sessions.find(a=>a.id===t);this.blocked={id:t,title:r?.title??t,code:i.code,sessionHome:i.sessionHome??null,rowHome:i.rowHome??null},this.bump();return}this.#m(!1,`重启 agent 进程失败:${String(s.message??s)}`)}}dismissBlocked(){this.blocked=null,this.bump()}deleteBlocked(){const t=this.blocked;this.blocked=null,t&&this.purgeCold(t.id),this.bump()}purgeCold(t){this.sessions=this.sessions.filter(s=>s.id!==t),this.cold=this.cold.filter(s=>s.id!==t),this.archived=this.archived.filter(s=>s.id!==t),this.byId.delete(t),this.bump(),this.#a(`/api/sessions/${t}`,{method:"DELETE"}).catch(()=>this.refreshRows()).then(()=>this.refreshRows())}async setArchived(t,s){try{const n=await this.#a(`/api/sessions/${t}/${s?"archive":"unarchive"}`,{method:"POST"}),i=this.byId.get(t);return i&&(i.info={...i.info,...n}),s?(this.sessions=this.sessions.filter(r=>r.id!==t),this.cold=this.cold.filter(r=>r.id!==t),this.archived.some(r=>r.id===t)||(this.archived=[n,...this.archived]),this.activeId===t&&this.#R()):(this.archived=this.archived.filter(r=>r.id!==t),!this.sessions.some(r=>r.id===t)&&!this.cold.some(r=>r.id===t)&&(this.cold=[n,...this.cold])),this.bump(),n}catch(n){return this.#m(!1,`${s?"归档":"取消归档"}失败:${String(n.message??n)}`),null}}async unarchiveAndResume(t){await this.setArchived(t,!1),await this.resume(t)}#R(){const t=this.sessions[0]??this.cold[0]??this.archived[0]??null;this.activeId=t?.id??null,this.#b(this.activeId),t&&!this.sessions.some(s=>s.id===t.id)&&this.loadHistory(t.id)}#A(t,s,n,i,r,a){const l=t.plan;if(!l){t.plan={key:`plan-${t.turn}`,items:s,terminal:n,explanation:r,at:i,turn:t.turn,title:a??void 0};return}if(l.turn===t.turn){l.items=s,l.terminal=n,l.explanation=r,a!==void 0&&(l.title=a??void 0);return}const c=t.turnStart>0&&t.turnStart<=t.msgs.length?t.turnStart:t.msgs.length;t.msgs.splice(c,0,{key:l.key,kind:"plan",items:l.items,terminal:l.terminal,explanation:l.explanation,at:l.at,title:l.title}),t.blocks=e0(t.msgs),t.turnStart=Math.min(t.turnStart+1,t.msgs.length),t.plan={key:`plan-${t.turn}`,items:s,terminal:n,explanation:r,at:i,turn:t.turn,title:a??void 0}}#j(t,s){this.#A(t,s.items.map(n=>({content:n.content,status:n.status,priority:n.priority})),s.terminal??void 0,s.updatedAt,s.explanation??void 0,s.title?.trim()||null)}async#K(t){try{const{plan:s}=await this.#a(`/api/sessions/${t.info.id}/plan`);if(!s)return;this.#j(t,s),this.bump()}catch{}}#u(t){let s=this.byId.get(t);return s||(s={info:this.sessions.find(n=>n.id===t)??{id:t},msgs:[],notes:[],perms:[],busy:!1,busySince:null,loaded:!1,hasOlder:!1,loadingOlder:!1,minSeq:null,lastAt:Date.now(),rev:0,seen:new Set,blocks:new Map,plan:null,turn:0,turnStart:0,queue:this.#N(t)},this.byId.set(t,s)),s}apply(t){switch(t.t){case"hello":break;case"sessions":{this.sessions=t.sessions,t.cold&&(this.cold=t.cold),t.archived&&(this.archived=t.archived);const s=new Set([...t.sessions.map(n=>n.id),...this.cold.map(n=>n.id),...this.archived.map(n=>n.id)]);for(const n of[...t.sessions,...this.cold,...this.archived]){const i=this.#u(n.id);i.info={...i.info,...n}}if(t.background){const n=new Set(t.background.map(i=>i.sessionId));for(const i of t.background)this.#u(i.sessionId).background=i.tasks;for(const[i,r]of this.byId)!n.has(i)&&r.background?.length&&(r.background=[])}if(t.pending){const n=new Map;for(const i of t.pending){const r=n.get(i.sessionId);r?r.push(i):n.set(i.sessionId,[i])}for(const[i,r]of n)this.#u(i).perms=r;for(const i of this.byId.values())n.has(i.info.id)||(i.perms=[]);this.#y()}for(const n of[...this.byId.keys()])s.has(n)||this.byId.delete(n);if(this.activeId&&!s.has(this.activeId)&&(this.activeId=null,this.#b(null)),!this.activeId&&s.size){const n=this.#I(),i=n&&s.has(n)?n:t.sessions[0]?.id??this.cold[0]?.id??this.archived[0]?.id;i&&(this.activeId=i,this.loadHistory(i))}for(const n of this.sessions)n.status==="ready"&&this.#s.get(n.id)?.length&&this.drainQueue(n.id);break}case"session":{t.session.cold===!0?(this.sessions=this.sessions.filter(s=>s.id!==t.session.id),this.cold=this.cold.map(s=>s.id===t.session.id?t.session:s),this.cold.some(s=>s.id===t.session.id)||this.cold.push(t.session)):(this.sessions=this.sessions.map(s=>s.id===t.session.id?t.session:s),this.sessions.some(s=>s.id===t.session.id)||this.sessions.push(t.session),this.cold=this.cold.filter(s=>s.id!==t.session.id)),this.#u(t.session.id).info=t.session,t.session.status==="ready"&&this.#W(t.session.id),t.session.status==="ready"&&this.#s.get(t.session.id)?.length&&this.drainQueue(t.session.id);break}case"messages":{const s=this.#u(t.sessionId);if(t.partial){for(const n of t.messages)this.#B(s,n,{resync:!0});s.lastAt=Date.now();break}s.seen.clear(),s.msgs=[],s.blocks.clear(),s.plan=null,s.turn=0,s.turnStart=0,this.#M(s);for(const n of t.messages)this.#B(s,n);s.loaded=!0;break}case"message":{const s=this.#u(t.message.sessionId),n=t.message.payload?.rejectedPrompt,i=t.message.payload?.pid;typeof i=="string"&&this.#r(i),t.message.kind==="meta"&&typeof n=="string"&&n.trim()&&this.enqueuePrompt(t.message.sessionId,n),this.#B(s,t.message,{delta:t.delta,n:t.n}),s.lastAt=Date.now(),this.lastSeq[t.message.sessionId]=Math.max(this.lastSeq[t.message.sessionId]??0,t.message.seq);break}case"status":{const s=this.#u(t.sessionId),n=Date.now(),i=s.notes[s.notes.length-1],r=s.msgs.length?s.msgs[s.msgs.length-1].key:null;i&&t.statusKind&&i.kind===t.statusKind?(i.text=t.text,i.afterKey=r):(s.notes.push({key:`st-${n}-${s.notes.length}`,kind:t.statusKind,text:t.text,at:n,afterKey:r}),s.notes.length>200&&s.notes.splice(0,s.notes.length-200)),s.lastAt=n;break}case"background":{this.#u(t.sessionId).background=t.tasks;break}case"turn-start":{const s=this.#u(t.sessionId);s.busy=!0,s.busySince=Date.now(),s.lastAt=Date.now(),s.trace=t.trace??null,this.#F(t.sessionId),this.#P(t.sessionId,t.pid);break}case"plan":{const s=this.#u(t.sessionId);this.#j(s,t.plan),s.lastAt=Date.now();break}case"speak":{const s=this.#u(t.sessionId),n={id:t.id,text:t.text,kind:t.kind,priority:t.priority,at:Date.now()};s.speaks=[...s.speaks??[],n].slice(-10);break}case"usage":{const s=this.#u(t.sessionId);s.info={...s.info,usage:t.usage},s.lastAt=Date.now();break}case"turn-end":{const s=this.#u(t.sessionId);if(s.busy=!1,t.sessionId!==this.activeId&&this.markUnread(t.sessionId),s.busySince=null,this.#M(s),t.error&&s.msgs.push({key:`err-${Date.now()}`,kind:"meta",text:t.error}),t.error?this.#O(t.sessionId):this.#F(t.sessionId),!t.error){const n=t.sessionId;window.setTimeout(()=>this.drainQueue(n),250)}break}case"permission":this.#u(t.request.sessionId).perms.push(t.request);break;case"permission-resolved":for(const s of this.byId.values())s.perms=s.perms.filter(n=>n.requestId!==t.requestId);this.#y();break;case"permission-expired":for(const s of this.byId.values())s.perms=s.perms.filter(n=>n.requestId!==t.requestId);this.#y(),this.#u(t.sessionId).msgs.push({key:`perm-exp-${t.requestId}`,kind:"meta",text:"这条审批已经过期:agent 等不到答复、先自己放过了(或它已经放弃这一轮)。你的点击没有生效。"});break;case"config-rejected":{const s=this.#u(t.sessionId),n=t.name||t.configId;s.msgs.push({key:`cfg-rej-${t.configId}-${Date.now()}`,kind:"meta",text:`${n} 这一档没生效:agent 没有接受「${t.value}」${t.actual?`,实际仍是「${t.actual}」`:""}。(模型只认它公布的那几档;换档位或换模型再试。)`});break}case"notify":{Si.handle(t.notice);break}case"error":{this.activeId&&this.#u(this.activeId).msgs.push({key:`e-${Date.now()}`,kind:"meta",text:t.error});break}}this.bump()}#M(t){for(let s=0;s<t.msgs.length;s++){const n=t.msgs[s];(n.kind==="agent"||n.kind==="thought")&&n.open&&(t.msgs[s]={...n,open:!1})}}#q(t){const s=t.msgs[t.msgs.length-1];s&&(s.kind==="agent"||s.kind==="thought")&&t.busy&&!s.open&&(t.msgs[t.msgs.length-1]={...s,open:!0})}#z(t,s){for(let n=0;n<t.length;n++){const i=t[n];i.kind==="thought"&&i.open&&i.key!==s&&(t[n]={...i,open:!1})}}#B(t,s,n){const i=n?.list??t.msgs,r=n?.index??t.blocks,a=n?.delta,l=s.payload;let c=null;const u=a!==void 0,h=(s.kind==="agent"||s.kind==="thought")&&Qv(s.kind,l)!==null;if(!(n?.resync===!0&&(s.kind==="tool"||s.kind==="plan"||s.kind==="user"||s.kind==="meta"||h)||s.kind==="tool"||s.kind==="meta"||s.kind==="note"||s.kind==="approval"||s.kind==="project-skills"||s.seq<=0||u)){if(t.seen.has(s.seq))return;t.seen.add(s.seq)}s.seq>0&&(t.minSeq==null||s.seq<t.minSeq)&&(t.minSeq=s.seq);const f=s.payload,m=typeof s.createdAt=="number"?s.createdAt:Date.now(),b=DR(f);switch(i[i.length-1],s.kind){case"user":if(i.some(v=>v.key===`m${s.seq}`))break;const _=f.origin??null;i.push({key:`m${s.seq}`,kind:"user",text:String(f.text??""),at:m,..._&&typeof _.sessionId=="string"?{from:{id:_.sessionId,title:String(_.title??"").trim()||"另一个会话"}}:{},files:Array.isArray(f.attachments)?f.attachments.map(v=>({kind:String(v.kind??""),name:String(v.name??"file")})):[]}),n?.list||(t.turn+=1,t.turnStart=i.length-1);break;case"agent":case"thought":{const v=s.kind,y=Qv(v,f),{at:w}=ON(i,r,{key:y,kind:v,text:b,delta:a,n:n?.n},(S,N)=>({key:S,kind:N.kind,text:N.text,open:!0,at:m})),x=i[w];a!==void 0&&t.info.status==="running"&&x&&(x.kind==="agent"||x.kind==="thought")&&!x.open&&(i[w]={...x,open:!0}),v==="thought"&&(c=i[w]?.key??null);break}case"note":{const v=`n${s.seq}`,y=typeof f.hits=="number"?f.hits:void 0,w={key:v,kind:"note",category:String(f.category??""),text:typeof f.text=="string"?f.text:"",hits:y,at:m,items:Array.isArray(f.items)?f.items.filter(S=>S&&typeof S.text=="string"&&S.text.trim()):void 0,truncated:f.truncated===!0},x=r.get(v);x!==void 0&&i[x]?.kind==="note"?i[x]=w:(i.push(w),r.set(v,i.length-1));break}case"approval":{const v=`p${s.seq}`,y=f.decision,w={key:v,kind:"approval",requestId:String(f.requestId??""),title:String(f.toolCallTitle??"tool call"),kind2:String(f.kind??"other"),path:typeof f.path=="string"?f.path:null,diff:f.diff??null,options:Array.isArray(f.options)?f.options:[],decision:y??null,at:m},x=r.get(v);x!==void 0&&i[x]?.kind==="approval"?i[x]=w:(i.push(w),r.set(v,i.length-1));break}case"project-skills":{const v=`s${s.seq}`,y={key:v,kind:"project-skills",root:String(f.root??""),count:typeof f.count=="number"?f.count:0,text:String(f.text??""),state:String(f.state??"ask"),at:m},w=r.get(v);w!==void 0&&i[w]?.kind==="project-skills"?i[w]=y:(i.push(y),r.set(v,i.length-1));break}case"turn-usage":{const v=`u${s.seq}`,y=S=>typeof S=="number"&&Number.isFinite(S)?S:0,w=S=>typeof S=="number"&&Number.isFinite(S)?S:null,x={key:v,kind:"turn-usage",available:f.available!==!1,input:y(f.input),output:y(f.output),thought:y(f.thought),cacheRead:w(f.cacheRead),cacheWrite:w(f.cacheWrite),total:y(f.total),durationMs:typeof f.durationMs=="number"?f.durationMs:void 0,cacheHitPercent:typeof f.cacheHitPercent=="number"?f.cacheHitPercent:null,tps:typeof f.tps=="number"?f.tps:null,at:m};r.get(v)===void 0&&(i.push(x),r.set(v,i.length-1));break}case"tool":{const v=String(f.toolCallId??s.toolCallId??s.seq),y=i.find(E=>E.kind==="tool"&&E.toolCallId===v),w=IR(f),x=PR(f),S=new Set((y?.changes??[]).map(E=>`${E.path}\0${E.oldText??""}\0${E.newText??""}\0${E.diffText??""}`)),N=FN(f).filter(E=>!S.has(`${E.path}\0${E.oldText??""}\0${E.newText??""}\0${E.diffText??""}`)),R=N.length?[...y?.changes??[],...N]:y?.changes;if(y){const E=i.indexOf(y),M={...y,title:f.title?String(f.title):y.title,status:f.status?String(f.status):y.status,detail:w??y.detail,input:x??y.input,changes:R};E>=0&&(i[E]=M)}else i.push({key:`tc-${v}`,kind:"tool",toolCallId:v,at:m,title:String(f.title??"tool call"),status:String(f.status??"pending"),kind2:String(f.kind??""),detail:w,input:x,changes:R});break}case"plan":{const v=f._meta??{},y=(f.entries??[]).map(S=>({content:String(S?.content??""),status:String(S?.status??"pending"),priority:S?.priority})),w=typeof f._slotPlanTerminal=="string"?f._slotPlanTerminal:void 0,x=typeof v["agentus/explanation"]=="string"?String(v["agentus/explanation"]):void 0;if(n?.list){const S=i.find(N=>N.kind==="plan");if(S&&S.kind==="plan"){const N=i.indexOf(S);i[N]={...S,items:y,terminal:w,explanation:x}}else i.push({key:`m${s.seq}`,kind:"plan",items:y,terminal:w,explanation:x,at:m});break}this.#A(t,y,w,m,x);break}case"meta":if(i.some(v=>v.key===`m${s.seq}`))break;i.push({key:`m${s.seq}`,kind:"meta",text:b||JSON.stringify(f)});break}this.#z(i,c),this.lastSeq[t.info.id]=Math.max(this.lastSeq[t.info.id]??0,s.seq),t.rev+=1,t.lastAt=Date.now()}}function DR(e){const t=e.content;return t?.type==="text"&&typeof t.text=="string"?t.text:""}function IR(e){const s=r=>r.length>4e3?`${r.slice(0,4e3)}
|
|
44
44
|
… (${r.length-4e3} more chars)`:r,n=e.rawOutput;if(typeof n=="string"&&n.trim())return s(n);if(n&&typeof n=="object")try{return s(JSON.stringify(n,null,1))}catch{}const i=e.content;if(Array.isArray(i)){const r=[];for(const a of i){const l=String(a?.type??"");if(l==="content"){const c=a.content;c?.type==="text"&&c.text&&r.push(String(c.text))}else if(l==="diff"){const c=String(a.path??"file"),u=typeof a.newText=="string"?a.newText:"";r.push(`--- ${c}
|
|
45
45
|
${u.slice(0,1500)}`)}else if(l==="terminal"){const c=a.output;c&&r.push(String(c))}}if(r.length)return s(r.join(`
|
|
46
46
|
`))}return""}function PR(e){const t=e.rawInput;if(typeof t=="string"&&t.trim())return t.slice(0,1200);if(t&&typeof t=="object")try{return JSON.stringify(t,null,1).slice(0,1200)}catch{return""}return""}const ee=new MR;if(typeof window<"u"){const e=window;e.__agentusOpenSession=t=>{const s=String(t??"").trim();if(!s||!ee.byId.has(s))return!1;ee.setActive(s);const n=ee.byId.get(s);return n&&!n.loaded&&ee.resume(s).catch(()=>{}),!0},window.addEventListener("popstate",()=>ee.followUrl())}function Qr(e){return!!(e&&(e.busy||e.info.status==="running"))}function Rh(e){return`/api/fs/raw?path=${encodeURIComponent(e)}`}async function fd(e){try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}try{const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.top="-1000px",t.style.opacity="0",document.body.appendChild(t),t.select(),t.setSelectionRange(0,t.value.length);const s=document.execCommand("copy");return t.remove(),s}catch{return!1}}const em=new Set;function LR(e){return em.add(e),()=>{em.delete(e)}}function US(e){for(const t of[...em])try{t(e)}catch{}}const tm="data-agentus-table",OR=4,sm="⇕",BR={asc:"▲",desc:"▼",none:sm};function nm(e){if(!e)return"";const t=e.querySelector(".md-table-sort");return t?(t.querySelector(".md-table-sort-label")?.textContent??"").trim():(e.textContent??"").trim()}function $R(e,t,s){const n=e.tBodies[0];if(!n)return;const i=Array.from(n.rows).filter(a=>a.parentElement===n),r=a=>Number(a.dataset.mdRow??0);i.sort((a,l)=>{if(s==="none")return r(a)-r(l);const c=nm(a.cells[t]).localeCompare(nm(l.cells[t]),void 0,{numeric:!0,sensitivity:"base"});return c!==0?s==="asc"?c:-c:r(a)-r(l)});for(const a of i)n.appendChild(a)}function FR(e){const t=e.cloneNode(!0);t.removeAttribute(tm);for(const s of Array.from(t.querySelectorAll(".md-table-sort"))){const n=s.querySelector(".md-table-sort-label"),i=s.parentElement;i&&n&&(i.textContent=n.textContent??"",i.removeAttribute("aria-sort"))}return t}function zR(e){if(document.querySelector(".md-table-overlay"))return;const t=document.createElement("div");t.className="md-table-overlay",t.setAttribute("role","dialog"),t.setAttribute("aria-modal","true"),t.setAttribute("aria-label","table");const s=document.createElement("div");s.className="md-table-bar";const n=document.createElement("button");n.type="button",n.className="md-table-btn",n.textContent="rotate";const i=document.createElement("span");i.className="head-spacer";const r=document.createElement("button");r.type="button",r.className="md-table-btn",r.textContent="copy";const a=document.createElement("button");a.type="button",a.className="md-table-btn",a.textContent="close",a.setAttribute("aria-label","close table"),s.append(n,i,r,a);const l=document.createElement("div");l.className="md-table-stage";const c=document.createElement("div");c.className="md-table-zoom md";const u=FR(e);c.appendChild(u),l.appendChild(c),t.append(s,l),document.body.appendChild(t),o_(c);const h=window.innerHeight>window.innerWidth;c.classList.toggle("rot",h);const d=()=>{t.remove(),window.removeEventListener("keydown",p)},p=f=>{f.key==="Escape"&&d()};window.addEventListener("keydown",p),n.addEventListener("click",()=>c.classList.toggle("rot")),a.addEventListener("click",d),t.addEventListener("click",f=>{(f.target===t||f.target===l)&&d()}),r.addEventListener("click",()=>{const f=Array.from(u.rows).map(m=>Array.from(m.cells).map(b=>nm(b).replace(/\s+/g," ")).join(" "));fd(f.join(`
|
|
@@ -72,7 +72,7 @@ PYTHONPATH=/srv/app/lib`,onChange:k=>x("env",k.target.value)})]}),o.jsxs("div",{
|
|
|
72
72
|
`)}}const m3=(e,t)=>JSON.stringify(e)===JSON.stringify(t);function g3({onClose:e,sessionId:t}){const s=X1(),[n,i]=g.useState(null),[r,a]=g.useState(null),[l,c]=g.useState(null),[u,h]=g.useState(""),[d,p]=g.useState(n_),[f,m]=g.useState(null),[b,_]=g.useState(""),[v,y]=g.useState(""),[w,x]=g.useState(()=>Math.round(ak()*100)),[S,N]=g.useState(""),[R,E]=g.useState(""),[M,F]=g.useState(""),[B,k]=g.useState(""),[A,D]=g.useState(!1),[H,I]=g.useState("Agentus 语音合成自测:龙安欢音色。"),[z,T]=g.useState(null),[O,K]=_o(),U=r_(),[re,J]=g.useState(null),[Y,_e]=g.useState(""),[xe,fe]=g.useState(null),[et,Oe]=g.useState(null),[tt,Pe]=g.useState(""),[Le,Ee]=g.useState(null),[Ae,Ze]=g.useState(null),[me,Ye]=g.useState(""),[de,lt]=g.useState(null),[ae,be]=g.useState(""),[Be,W]=g.useState(null),[Se,He]=g.useState(null),[q,Z]=g.useState(""),[ge,P]=g.useState(null),[le,je]=g.useState(""),[Ie,Ge]=g.useState(null),[ot,dt]=g.useState(""),[at,Q]=g.useState(null),[ke,Ne]=g.useState(""),[$e,gt]=g.useState([]),St=g.useCallback(async()=>{F("");try{const j=await fetch("/api/auth/me",{credentials:"same-origin"});if(j.ok){const Ue=await j.json().catch(()=>({}));Ue.configuredUsername&&T({configuredUsername:Ue.configuredUsername,credentialSource:Ue.credentialSource??"default",minPasswordLen:Ue.minPasswordLen??6,usingDefaultPassword:!!Ue.usingDefaultPassword})}const V=await fetch("/api/settings",{credentials:"same-origin"}),se=await V.json().catch(()=>({}));if(!V.ok)throw new Error(se.error??`settings ${V.status}`);i(se),a(Ue=>Ue??ll(se)),typeof se.agent?.idleKillMin=="number"&&J(se.agent.idleKillMin),typeof se.agent?.warmSlots=="number"&&fe(se.agent.warmSlots),typeof se.agent?.warmTtlHours=="number"&&Oe(se.agent.warmTtlHours),typeof se.agent?.recallItemChars=="number"&&Ee(se.agent.recallItemChars),typeof se.agent?.recallTotalChars=="number"&&Ze(se.agent.recallTotalChars),se.prefs?.planHint&<(se.prefs.planHint),typeof se.agent?.cockpitSend=="boolean"&&W(se.agent.cockpitSend),typeof se.agent?.modelWriteBack=="boolean"&&He(se.agent.modelWriteBack),typeof se.agent?.showSilentBackground=="boolean"&&P(se.agent.showSilentBackground),se.observer&&Ge(se.observer),se.summary&&Q(se.summary);const ze=await fetch("/api/backends",{credentials:"same-origin"}).then(Ue=>Ue.ok?Ue.json():[]).catch(()=>[]);gt((Array.isArray(ze)?ze:[]).map(Ue=>({id:Ue.id,label:Ue.label??Ue.id}))),await Ch(!0),p(li());const[Je,Ct]=await Promise.all([fetch("/api/voice/models",{credentials:"same-origin"}),fetch(`/api/voice/hotwords${t?`?sessionId=${encodeURIComponent(t)}`:""}`,{credentials:"same-origin"})]);if(Je.ok)c(await Je.json()),h("");else{const Ue=await Je.json().catch(()=>({}));h(Ue.error??`model list ${Je.status}`)}Ct.ok&&m(await Ct.json())}catch(j){F(String(j?.message??j))}},[t]);g.useEffect(()=>{St()},[St]);const Jt=!!(n&&r&&!m3(r,ll(n))),dn=async()=>{if(re==null)return;const[j,V]=n?.agentIdleRange??[0,60],se=Math.max(j,Math.min(V,Math.round(re)));J(se),_e("");try{const ze=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({agent:{idleKillMin:se}})}),Je=await ze.json().catch(()=>({}));if(!ze.ok)throw new Error(Je.error??`save failed (${ze.status})`);i(Je),_e(se===0?"已保存:空闲槽位不再被回收。":`已保存:空闲 ${se} 分钟后停掉 agent 进程。`)}catch(ze){_e(`保存失败:${String(ze?.message??ze)}`)}},ye=async()=>{if(xe==null&&et==null)return;const[j,V]=n?.agentWarmRange??[0,20],[se,ze]=n?.agentWarmTtlRange??[0,168],Je=Math.max(j,Math.min(V,Math.round(xe??n?.agentDefaults?.warmSlots??5))),Ct=Math.max(se,Math.min(ze,Math.round(et??n?.agentDefaults?.warmTtlHours??24)));fe(Je),Oe(Ct),Pe("");try{const Ue=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({agent:{warmSlots:Je,warmTtlHours:Ct}})}),st=await Ue.json().catch(()=>({}));if(!Ue.ok)throw new Error(st.error??`save failed (${Ue.status})`);i(st),Pe(Je===0?"已保存:热备已关闭,只按上面的空闲时长回收。":Ct===0?`已保存:最近 ${Je} 个会话保底保活,不过期。`:`已保存:最近 ${Je} 个会话保活,闲置超过 ${Ct} 小时才回收。`)}catch(Ue){Pe(`保存失败:${String(Ue?.message??Ue)}`)}},Dt=async()=>{if(Le==null&&Ae==null)return;const[j,V]=n?.agentRecallItemRange??[80,2e3],[se,ze]=n?.agentRecallTotalRange??[2e3,6e4],Je=Math.max(j,Math.min(V,Math.round(Le??n?.agentDefaults?.recallItemChars??400))),Ct=Math.max(se,Math.min(ze,Math.round(Ae??n?.agentDefaults?.recallTotalChars??12e3)));Ee(Je),Ze(Ct),Ye("");try{const Ue=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({agent:{recallItemChars:Je,recallTotalChars:Ct}})}),st=await Ue.json().catch(()=>({}));if(!Ue.ok)throw new Error(st.error??`save failed (${Ue.status})`);i(st),Ye(`已保存:单条最多 ${Je} 字、一轮最多 ${Ct} 字(下一个回合生效)。`)}catch(Ue){Ye(`保存失败:${String(Ue?.message??Ue)}`)}},Me=async j=>{const V={enabled:Ie?.enabled??!1,backend:Ie?.backend??null,systemPrompt:Ie?.systemPrompt??"",throttleSec:Ie?.throttleSec??120,intervalSec:Ie?.intervalSec??0,...j};Ge(V),dt("");try{const se=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({observer:V})}),ze=await se.json().catch(()=>({}));if(!se.ok)throw new Error(ze.error??`save failed (${se.status})`);i(ze),ze.observer&&Ge(ze.observer),dt("已保存:下一次播报就是新设置。")}catch(se){dt(`保存失败:${String(se?.message??se)}`)}},kt=async j=>{const V={enabled:at?.enabled??!0,prompt:at?.prompt??"",maxChars:at?.maxChars??120,followSession:at?.followSession??!0,model:at?.model??"",timeoutSec:at?.timeoutSec??20,...j};Q(V),Ne("");try{const se=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({summary:V})}),ze=await se.json().catch(()=>({}));if(!se.ok)throw new Error(ze.error??`save failed (${se.status})`);i(ze),ze.summary&&Q(ze.summary),Ne("已保存 —— 下一次长按就用新的设置。")}catch(se){Ne(`保存失败:${String(se?.message??se)}`)}},Nn=async j=>{W(j),je("");try{const V=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({agent:{cockpitSend:j}})}),se=await V.json().catch(()=>({}));if(!V.ok)throw new Error(se.error??`save failed (${V.status})`);i(se),W(!!se.agent?.cockpitSend),je(j?"已保存:会话之间可以互发消息了(仅限空闲的会话)。":"已保存:agent 只能读,不能给别的会话发消息。")}catch(V){W(!j),je(`保存失败:${String(V?.message??V)}`)}},Ts=async j=>{He(j),Z("");try{const V=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({agent:{modelWriteBack:j}})}),se=await V.json().catch(()=>({}));if(!V.ok)throw new Error(se.error??`save failed (${V.status})`);i(se),He(!!se.agent?.modelWriteBack),Z(j?"已开启:换一次模型,agent 的默认模型就跟着变(新会话、命令行都吃这个默认)。":"已关闭:换模型只影响当前会话,agent 自己的配置文件不动。")}catch(V){He(!j),Z(`保存失败:${String(V?.message??V)}`)}},Rn=async j=>{P(j);try{const V=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({agent:{showSilentBackground:j}})}),se=await V.json().catch(()=>({}));if(!V.ok)throw new Error(se.error??`save failed (${V.status})`);i(se),P(!!se.agent?.showSilentBackground)}catch{P(!j)}},Wn=async j=>{const V={on:de?.on??!0,everyTurn:de?.everyTurn??!0,instruction:de?.instruction??"",...j};lt(V),be("");try{const se=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({prefs:{planHint:V}})}),ze=await se.json().catch(()=>({}));if(!se.ok)throw new Error(ze.error??`save failed (${se.status})`);i(ze),lt(ze.prefs?.planHint??V),be(V.on?V.everyTurn?"已保存:每回合都提醒 agent 用 update_plan。":"已保存:只在每个 agent 进程的首条提醒一次。":"已保存:prompt 里不再追加计划提示。")}catch(se){be(`保存失败:${String(se?.message??se)}`)}},jn=async()=>{if(!r)return!1;N("save"),F(""),E("");try{const j={...r,hotwords:r.hotwordsText.split(`
|
|
73
73
|
`).map(Je=>Je.trim()).filter(Boolean)};delete j.hotwordsText,A&&b.trim()&&(j.apiKey=b.trim());const V=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({voice:j})}),se=await V.json().catch(()=>({}));if(!V.ok)throw k(typeof se.field=="string"?se.field:""),new Error(se.error??`save failed (${V.status})`);k(""),D(!1),i(se),a(ll(se)),_(""),await Ch(!0),p(li());const ze=await fetch(`/api/voice/hotwords${t?`?sessionId=${encodeURIComponent(t)}`:""}`,{credentials:"same-origin"});return ze.ok&&m(await ze.json()),E("已保存"),window.setTimeout(()=>E(""),2500),!0}catch(j){return F(String(j?.message??j)),!1}finally{N("")}},zs=async j=>{const V=await BD(j);V&&F(V)},Rr=async()=>{if(await tR(),!(Jt&&!await jn())){N("tts"),F(""),E("");try{const j=await fetch("/api/tts",{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({text:H,voice:r?.ttsVoice})});if(!j.ok){const se=await j.json().catch(()=>({}));throw new Error(se.error??`tts ${j.status}`)}const V=await j.blob();await DS(V),E(`合成成功 · ${V.type||"audio"} · ${Math.round(V.size/1024)} KB`)}catch(j){F(String(j?.message??j))}finally{N("")}}},$i=()=>{F(""),pe.start(mR(),t)},wo=async()=>{N("models"),h("");try{const j=await fetch("/api/voice/models",{credentials:"same-origin"}),V=await j.json().catch(()=>({}));if(!j.ok)throw new Error(V.error??`model list ${j.status}`);c(V),E(`endpoint 报告 ${V.total} 个模型`)}catch(j){h(String(j?.message??j))}finally{N("")}},Ot=(j,V)=>{a(se=>se&&{...se,[j]:V})},ws=U.status==="listening"||U.status==="requesting"||U.status==="recording",ds=g.useRef(null),[Tn,jr]=g.useState(al[0].id),[rt,Qe]=g.useState(al[0].items[0].anchor),Tr=g.useCallback(j=>{const V=al.find(se=>se.id===j);jr(j),Qe(V?.items[0]?.anchor??""),ds.current?.scrollTo({top:0,behavior:"auto"})},[]),Ar=g.useCallback(j=>{document.getElementById(j)?.scrollIntoView({block:"start",behavior:"smooth"}),Qe(j)},[]);return g.useEffect(()=>{const j=ds.current;if(!j)return;const V=(al.find(ze=>ze.id===Tn)?.items??[]).map(ze=>ze.anchor);if(!V.length)return;const se=()=>{const ze=j.getBoundingClientRect().top;let Je=V[0];for(const Ct of V){const Ue=document.getElementById(Ct);Ue&&Ue.getBoundingClientRect().height>0&&Ue.getBoundingClientRect().top-ze<=32&&(Je=Ct)}j.scrollTop+j.clientHeight>=j.scrollHeight-4&&(Je=V[V.length-1]),Qe(Ct=>Ct===Je?Ct:Je)};return j.addEventListener("scroll",se,{passive:!0}),se(),()=>j.removeEventListener("scroll",se)},[Tn]),o.jsxs("div",{className:"main",children:[o.jsxs("div",{className:"chat-head set-head",children:[o.jsx("button",{className:"icon-btn",onClick:e,title:"返回会话","aria-label":"back",children:o.jsx(Qg,{size:16})}),o.jsxs("span",{className:"title",children:[o.jsx(Tc,{size:14})," 设置"]}),o.jsx("span",{className:"head-spacer"}),R?o.jsx("span",{className:"set-toast",children:R}):null,o.jsx("button",{className:"set-save",onClick:()=>void jn(),disabled:S==="save"||!Jt,children:S==="save"?"保存中…":Jt?"保存":"已保存"})]}),o.jsxs("div",{className:"set-main",children:[o.jsx("nav",{className:"set-nav","aria-label":"设置分类",children:al.map(j=>o.jsxs("div",{className:"set-nav-group",children:[o.jsx("button",{type:"button",className:`set-nav-cat ${Tn===j.id?"on":""}`,"aria-current":Tn===j.id?"page":void 0,onClick:()=>Tr(j.id),title:j.hint,children:j.label}),Tn===j.id?j.items.map(V=>o.jsx("button",{type:"button",className:`set-nav-item ${rt===V.anchor?"on":""}`,"aria-current":rt===V.anchor?"true":void 0,onClick:()=>Ar(V.anchor),children:V.label},V.anchor)):null]},j.id))}),o.jsxs("div",{className:"set-body",ref:ds,"data-cat":Tn,"data-set-scroll":!0,children:[M?o.jsxs("div",{className:"set-err",role:"alert",children:[M,o.jsx("button",{className:"draft-x",onClick:()=>F(""),"aria-label":"dismiss",children:o.jsx(En,{size:11})})]}):null,o.jsx("h4",{className:"set-group",id:"grp-account","data-setgroup":"account",children:"账号与安全"}),o.jsx(UD,{account:z,onChanged:j=>T(V=>V&&{...V,...j})}),o.jsx("h4",{className:"set-group",id:"grp-agent","data-setgroup":"agent",children:"智能体"}),o.jsx(u3,{}),o.jsx("h4",{className:"set-group",id:"grp-notify","data-setgroup":"notify",children:"通知"}),o.jsx(i3,{}),o.jsx(JD,{sessionId:t}),o.jsx(QD,{}),o.jsx("h4",{className:"set-group",id:"grp-look","data-setgroup":"look",children:"外观"}),o.jsxs("section",{className:"set-card",id:"set-theme","data-setgroup":"look",children:[o.jsx("h3",{children:"主题"}),o.jsx("p",{className:"set-hint",children:"亮/暗跟随系统;强调色会重新给整套驾驶舱上色(按钮、链接、流式光标、用量环)。 选择存在服务端,换一台设备也一致。"}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"外观"}),o.jsx("div",{className:"set-seg",role:"group","aria-label":"theme mode",children:[["system","跟随系统"],["light","亮"],["dark","暗"]].map(([j,V])=>o.jsx("button",{type:"button",className:s.mode===j?"on":"","aria-pressed":s.mode===j,onClick:()=>void zs({...s,mode:j}),children:V},j))})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"强调色"}),o.jsxs("div",{className:"set-swatches",children:[p3.map(j=>o.jsx("button",{type:"button",className:`set-swatch ${s.accent===j?"on":""}`,style:{background:j},title:j,"aria-label":`accent ${j}`,onClick:()=>void zs({...s,accent:j})},j)),o.jsx("input",{type:"color",className:"set-color",value:s.accent||"#4aacdf",onChange:j=>void zs({...s,accent:j.target.value}),"aria-label":"custom accent"}),o.jsx("button",{type:"button",className:"set-mini",onClick:()=>void zs({...s,accent:""}),children:"默认"})]})]})]}),o.jsx("h4",{className:"set-group",id:"grp-voice","data-setgroup":"voice",children:"语音"}),o.jsxs("section",{className:"set-card",id:"set-lifecycle","data-setgroup":"agent",children:[o.jsx("h3",{children:"槽位回收与热备"}),o.jsxs("p",{className:"set-hint",children:["空闲超过这个时长后,自动停掉槽位的 ",o.jsx("b",{children:"agent 进程"})," 以释放内存 —— 对话记录、模型、思考深度全都 保留,点一下该槽位就会重新起来(状态显示「已回收(空闲)」)。这是「回收进程」,不是「归档会话」: 归档只在你手动点击时发生,两者互不影响。数值对齐 AionUi 的「Agent 空闲超时」,",o.jsx("b",{children:"0 = 关闭"}),"。"]}),o.jsxs("p",{className:"set-hint",children:["下面的 ",o.jsx("b",{children:"热备"})," 是保底,不是上限:最近 N 个会话即使空闲也留着进程 —— 「我只是离开浏览器」 不该丢掉刚才那个会话的 agent。名额自己也有寿命(小时),超时照样回收:5 个热备 × 约 137 MB ≈ 700 MB,这就是它默认 24 小时过期的原因。正在跑回合、等你审批、你正看着的会话从不被回收。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"Agent 空闲超时(分钟)"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-num",type:"number",min:n?.agentIdleRange?.[0]??0,max:n?.agentIdleRange?.[1]??60,step:5,value:re??n?.agentDefaults?.idleKillMin??5,onChange:j=>J(Number(j.target.value)),onBlur:()=>void dn()}),o.jsx("span",{className:"set-hint",children:re===0?"已关闭:空闲的槽位不会被回收(长跑任务可以这么做)":`空闲 ${re??n?.agentDefaults?.idleKillMin??5} 分钟后回收`})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"热备槽位(最近 N 个)"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-num",type:"number",min:n?.agentWarmRange?.[0]??0,max:n?.agentWarmRange?.[1]??20,step:1,value:xe??n?.agentDefaults?.warmSlots??5,onChange:j=>fe(Number(j.target.value)),onBlur:()=>void ye()}),o.jsx("span",{className:"set-hint",children:xe===0?"已关闭:没有保底名额,只按上面的空闲时长回收":`最近 ${xe??n?.agentDefaults?.warmSlots??5} 个会话即使空闲也不回收`})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"热备最长闲置(小时)"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-num",type:"number",min:n?.agentWarmTtlRange?.[0]??0,max:n?.agentWarmTtlRange?.[1]??168,step:1,value:et??n?.agentDefaults?.warmTtlHours??24,onChange:j=>Oe(Number(j.target.value)),onBlur:()=>void ye()}),o.jsx("span",{className:"set-hint",children:et===0?"不过期:一直留着(内存也就一直占着)":`闲置超过 ${et??n?.agentDefaults?.warmTtlHours??24} 小时,连热备名额也停掉`})]})]}),Y?o.jsx("p",{className:"set-hint",children:Y}):null,tt?o.jsx("p",{className:"set-hint",children:tt}):null,o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"召回条目:单条字数"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-num",type:"number",min:n?.agentRecallItemRange?.[0]??80,max:n?.agentRecallItemRange?.[1]??2e3,step:50,value:Le??n?.agentDefaults?.recallItemChars??400,onChange:j=>Ee(Number(j.target.value)),onBlur:()=>void Dt()}),o.jsxs("span",{className:"set-hint",children:["展开「N 条」后每条最多 ",Le??n?.agentDefaults?.recallItemChars??400," 字,超了截断"]})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"召回条目:一轮总字数"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-num",type:"number",min:n?.agentRecallTotalRange?.[0]??2e3,max:n?.agentRecallTotalRange?.[1]??6e4,step:1e3,value:Ae??n?.agentDefaults?.recallTotalChars??12e3,onChange:j=>Ze(Number(j.target.value)),onBlur:()=>void Dt()}),o.jsx("span",{className:"set-hint",children:"不按条数限制,只按这个总量截:短记忆能多进几条,长记忆少进几条"})]})]}),me?o.jsx("p",{className:"set-hint",children:me}):null]}),o.jsxs("section",{className:"set-card",id:"set-plan","data-setgroup":"agent",children:[o.jsx("h3",{children:"计划提示注入"}),o.jsxs("p",{className:"set-hint",children:["驾驶舱给每个会话挂了一个 ",o.jsx("b",{children:"plan MCP"}),"(工具名 ",o.jsx("code",{children:"update_plan"}),"),会话卡片上那份计划就是它写进来的。 问题出在最后一公里:这类工具在 agent 侧是",o.jsx("b",{children:"懒加载"}),"的 —— 它自己的工具描述写着「优先于你自带的 todo」, 但模型不去检索就永远看不到这句话,于是 agent 全程用自己那个「进程一死就没了、驾驶舱也看不见」的 todo, 计划卡片一直是空的。"]}),o.jsxs("p",{className:"set-hint",children:["打开后,驾驶舱会在你那条消息的尾部追加一小段指引,告诉 agent 这个工具存在、多步任务应当用它发布并逐步更新、 以及懒加载时怎么检索到它。做法对齐 Hermes Studio 的",o.jsx("b",{children:"每回合注入"})," —— 它就是这么做到 agent 爱用的。",o.jsx("b",{children:"关掉后,prompt 里只有你自己打的那句话。"}),"改完立刻对下一个回合生效,不用重启会话。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"注入计划使用提示"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{type:"checkbox",checked:de?.on??!0,onChange:j=>void Wn({on:j.target.checked})}),o.jsx("span",{className:"set-hint",children:de?.on??!0?"已开启:让 agent 知道该用 update_plan 维护计划":"已关闭:prompt 不再被追加任何内容"})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"注入频率"}),o.jsx("div",{className:"set-pair",children:o.jsxs("select",{className:"set-select",value:de?.everyTurn??!0?"every":"first",disabled:!(de?.on??!0),onChange:j=>void Wn({everyTurn:j.target.value==="every"}),children:[o.jsx("option",{value:"every",children:"每回合(默认,对齐 Studio)"}),o.jsx("option",{value:"first",children:"仅每个 agent 进程的首条(省 token)"})]})})]}),o.jsx("div",{className:"set-row",children:o.jsx("label",{children:"注入内容"})}),o.jsx("textarea",{className:"set-textarea",rows:6,spellCheck:!1,disabled:!(de?.on??!0),value:de?.instruction??"",placeholder:"留空即用内置文案 —— 原文就在下面「内置文案」里,能直接看、能照着改。",onChange:j=>lt(V=>({...V??{on:!0,everyTurn:!0,instruction:""},instruction:j.target.value})),onBlur:j=>void Wn({instruction:j.target.value})}),o.jsxs("details",{className:"set-builtin",open:!de?.instruction?.trim(),children:[o.jsx("summary",{children:de?.instruction?.trim()?"内置文案(你写了自定义的,下面这些不再生效;清空即可恢复)":"内置文案(留空时生效的就是它,按情况三选一)"}),o.jsxs("p",{className:"set-hint",children:["驾驶舱按这次的情况挑一条,接在「这次还有哪些步骤没做完」后面一起发给你那条消息的尾部。 内容会随计划变,所以这里只列",o.jsx("b",{children:"指引"}),"那半段的原文。"]}),VD.map(j=>o.jsxs("div",{className:"set-builtin-item",children:[o.jsx("div",{className:"set-builtin-when",children:j.when}),o.jsx("pre",{className:"set-builtin-text",children:j.text})]},j.id))]}),o.jsxs("p",{className:"set-hint",children:["这里写的只是",o.jsx("b",{children:"指引"}),"那一半(告诉 agent 有个计划工具、该怎么用它)。另一半是",o.jsx("b",{children:"计划状态"})," —— 「哪些步骤还没做完」,那是每个回合从驾驶舱的计划卡片现取的,任何人都改不了,所以这里的文字永远不会和卡片说的不一样。 清空即恢复内置文案。"]}),o.jsx("p",{className:"set-hint",children:"没有计划可提醒时不会硬凑字数:频率选「每回合」也只在该会话确有未完成计划时才重复注入; 一步就能做完的请求不受影响。没注入过的那次不会作废,打开开关或从「仅首条」切回来的那一回合会补上。"}),ae?o.jsx("p",{className:"set-hint",children:ae}):null]}),o.jsxs("section",{className:"set-card",id:"set-observer","data-setgroup":"agent",children:[o.jsx("h3",{children:"观察智能体(工作播报)"}),o.jsxs("p",{className:"set-hint",children:["「工作播报」不是把长回复念一遍,而是由一个",o.jsx("b",{children:"观察员"}),"念一句进展。它就是一个普通的 ACP 会话, 每个被观察的会话配一个,",o.jsx("b",{children:"常驻、上下文连续"}),":第一次看完之后它就记得这个会话在做什么, 之后每次只收到一行触发语(「这一轮结束了,看看进展」)。"]}),o.jsxs("p",{className:"set-hint",children:["事实",o.jsx("b",{children:"全靠它自己查"}),":它用 ",o.jsx("code",{children:"$AGENTUS_COCKPIT_BIN"})," 读会话、消息尾部、计划、待审批, 驾驶舱",o.jsx("b",{children:"不塞任何现成数据"}),"进去 —— 这样播报不会跟着我们的模板一起说错。 它跑在自己的",o.jsx("b",{children:"草稿目录"}),"里(",o.jsx("code",{children:"~/.hermes/agentus/observers/<会话 id>"}),"), 不看你的项目目录,也不出现在会话列表里。"]}),o.jsxs("p",{className:"set-hint",children:["花钱的地方只有一处:",o.jsx("b",{children:"回合结束"}),"时让它写一句。待审批、计划里完成一步这类事件是现成的事实, 驾驶舱直接念,",o.jsx("b",{children:"不花 token"}),"。观察员起不来时,会降级成 #11 的那句「会话名 · 任务名」。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"启用观察员"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{type:"checkbox",checked:Ie?.enabled??!1,onChange:j=>void Me({enabled:j.target.checked})}),o.jsx("span",{className:"set-hint",children:Ie?.enabled?"已启用:回合结束时由它念一句进展":"已关闭:播报降级成「会话名 · 任务名」,不起任何模型"})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"用哪个后端跑它"}),o.jsxs("div",{className:"set-pair",children:[o.jsxs("select",{className:"set-select",value:Ie?.backend??"",disabled:!(Ie?.enabled??!1),onChange:j=>void Me({backend:j.target.value||null}),children:[o.jsx("option",{value:"",children:"跟被观察的会话同一个后端(默认)"}),$e.map(j=>o.jsx("option",{value:j.id,children:j.label},j.id))]}),o.jsx("span",{className:"set-hint",children:"建议挑一个便宜、快的模型 —— 它只做「看一眼、说一句」。"})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"同一会话最短间隔(秒)"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-num",type:"number",min:n?.observerThrottleRange?.[0]??0,max:n?.observerThrottleRange?.[1]??3600,step:30,value:Ie?.throttleSec??120,onChange:j=>Ge(V=>V&&{...V,throttleSec:Number(j.target.value)}),onBlur:j=>void Me({throttleSec:Number(j.target.value)})}),o.jsx("span",{className:"set-hint",children:"0 = 每回合都播报;待审批这类零成本事件不受它限制。"})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"节拍(每 N 秒报一次)"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-num",type:"number",min:n?.observerIntervalRange?.[0]??0,max:n?.observerIntervalRange?.[1]??3600,step:30,value:Ie?.intervalSec??0,onChange:j=>Ge(V=>V&&{...V,intervalSec:Number(j.target.value)}),onBlur:j=>void Me({intervalSec:Number(j.target.value)})}),o.jsxs("span",{className:"set-hint",children:["0 = 关(只在回合结束、待审批时说)。设了节拍之后,",o.jsx("b",{children:"只有「有任务在跑」"}),"时才按节拍说话 —— 空闲的会话不报平安;同一个回合最多 8 条。顶部喇叭长按也能直接选 1/2/5 分钟。"]})]})]}),o.jsx("div",{className:"set-row",children:o.jsx("label",{children:"它的设定(system prompt)"})}),o.jsx("textarea",{className:"set-textarea",rows:6,spellCheck:!1,disabled:!(Ie?.enabled??!1),value:Ie?.systemPrompt??"",placeholder:"留空即用内置模板 —— 原文就在下面,能直接看、能照着改。",onChange:j=>Ge(V=>V&&{...V,systemPrompt:j.target.value}),onBlur:j=>void Me({systemPrompt:j.target.value})}),o.jsxs("details",{className:"set-builtin",open:!(Ie?.systemPrompt??"").trim(),children:[o.jsx("summary",{children:(Ie?.systemPrompt??"").trim()?"内置模板(你写了自定义的,它不再生效;清空即可恢复)":"内置模板(留空时生效的就是它)"}),o.jsx("pre",{className:"set-builtin-text",children:n?.observerPromptDefault??""})]}),o.jsx("p",{className:"set-hint",children:"你写的设定之后会自动补上一句「你负责的会话 id 是 …」,那一句不能改 —— 观察员靠它才知道看哪一个。 改完立刻对下一次播报生效,不用重启会话。"}),ot?o.jsx("p",{className:"set-hint",children:ot}):null]}),o.jsxs("section",{className:"set-card",id:"set-cockpit","data-setgroup":"agent",children:[o.jsx("h3",{children:"驾驶舱互发消息(cockpit CLI)"}),o.jsxs("p",{className:"set-hint",children:["每个会话里的 agent 都拿到了一个本机命令 ",o.jsx("code",{children:"$AGENTUS_COCKPIT_BIN"}),",可以用它",o.jsx("b",{children:"读"})," 这个驾驶舱:有哪些会话、谁在跑、各自的消息尾部、计划、正在等哪个审批。 数据面只做选择和截断,不做摘要、不改写 —— 会转述驾驶舱的机器就会说错驾驶舱。"]}),o.jsxs("p",{className:"set-hint",children:["下面这个开关管的是另一半:",o.jsx("b",{children:"往别的会话里发消息"}),"。默认关,因为两个 agent 互相回话 会变成一台烧 token 的循环生成器。打开后也只对",o.jsx("b",{children:"空闲"}),"会话生效 —— 正在跑回合的会话会 直接拒绝(",o.jsx("code",{children:"target_busy"}),"),",o.jsx("b",{children:"绝不抢占你开的那一轮"}),";已回收/归档的会话也拒绝 (",o.jsx("code",{children:"target_cold"})," / ",o.jsx("code",{children:"out_of_scope"}),"),驾驶舱不会替你把它唤醒。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"允许会话之间互发消息"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{type:"checkbox",checked:Be??!1,onChange:j=>void Nn(j.target.checked)}),o.jsx("span",{className:"set-hint",children:Be?"已开启:agent 可以给空闲会话留话(对方不一定读、也不一定回)":"已关闭:agent 只能读驾驶舱,不能往里写"})]})]}),o.jsxs("p",{className:"set-hint",children:["这个通道的身份是",o.jsx("b",{children:"随进程发的一次性令牌"}),"(放在环境变量里,不进命令行、不进 ",o.jsx("code",{children:"ps"}),"), 进程一死就失效;也只听本机回环地址。改动立刻对下一轮生效,不用重启会话。"]}),le?o.jsx("p",{className:"set-hint",children:le}):null]}),o.jsxs("section",{className:"set-card",id:"set-model-default","data-setgroup":"agent",children:[o.jsx("h3",{children:"模型默认值"}),o.jsxs("p",{className:"set-hint",children:['在会话里换一次模型,就是"以后都用这个"的意思 —— 所以选定',o.jsx("b",{children:"成功之后"}),",server 会把 它写进 agent 自己的配置文件。新会话、常驻服务、命令行都吃这个默认,重启也还在。"]}),o.jsxs("p",{className:"set-hint",children:[o.jsx("b",{children:"只对 Hermes 后端生效"}),":写的是 ",o.jsx("code",{children:"$HERMES_HOME/config.yaml"})," 里的",o.jsx("code",{children:"model.default"}),"(用了 ",o.jsx("code",{children:"-p"})," profile 的会话写",o.jsx("code",{children:"profiles/<名字>/config.yaml"}),")。",o.jsx("code",{children:"model.provider"}),' 只在 agent 自己报了 provider 时才一起同步 —— 描述里带人话标签("Anthropic (Claude Sonnet 4.5)") 的就不猜,宁可只改一行。Qoder 等其它后端目前不回写,开关留在开也没有副作用。']}),o.jsxs("p",{className:"set-hint",children:["只动那两行,其它字节原样保留;写入是原子的(临时文件 + rename),比 0600 宽的权限会被 收紧,改之前留一份 ",o.jsx("code",{children:".bak"}),'。写完会用 YAML 解析器验一遍能不能读回来 —— 验不过就一个字都不写。被 agent 拒绝的模型不会落盘,和"用过才算数"的排序是同一个收口点。']}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"选定模型时同步为全局默认"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{type:"checkbox",checked:Se??!0,onChange:j=>void Ts(j.target.checked)}),o.jsx("span",{className:"set-hint",children:Se===!1?"已关闭:换模型只影响当前会话":"已开启:最近一次选择就是这个 agent 的默认模型"})]})]}),q?o.jsx("p",{className:"set-hint",children:q}):null]}),o.jsxs("section",{className:"set-card",id:"set-background","data-setgroup":"agent",children:[o.jsx("h3",{children:"后台任务行"}),o.jsxs("p",{className:"set-hint",children:["后台任务行和会话轨上的 ",o.jsx("b",{children:"⚡ 角标"}),"默认只显示",o.jsx("b",{children:"会唤醒 agent 的进程"}),"(",o.jsx("code",{children:"notify_on_complete"}),")—— 那种进程意味着 agent 没有真正收工,它还在等这次 结果回来继续干活,所以那一行是绿的、会呼吸,会话也保持「进行中」。"]}),o.jsx("p",{className:"set-hint",children:"静默进程(agent 自己轮询取结果、不打算被唤醒的那种)默认不显示:它们只是噪音, 会把「这个会话还要不要我看」这个问题淹没。打开下面的开关就会显示全部, 包括跑完就静默消失的那些。"}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"显示不唤醒的后台进程"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{type:"checkbox",checked:ge??!1,onChange:j=>void Rn(j.target.checked)}),o.jsx("span",{className:"set-hint",children:ge?"已开启:所有后台进程都显示(静默型跑完即消失)":"已关闭:只显示会唤醒会话的进程"})]})]}),o.jsxs("p",{className:"set-hint",children:["需要带这个标记的后端(Hermes fork ",o.jsx("code",{children:"agentus/v0.22.0/merge-*"})," 那一版起)。 旧后端不发这个字段,于是所有进程都被当作静默型 —— 那时这一行不会出现, 开关也没有东西可显示。"]})]}),o.jsxs("section",{className:"set-card",id:"set-asr","data-setgroup":"voice",children:[o.jsx("h3",{children:"语音识别(ASR)"}),o.jsxs("p",{className:"set-hint",children:["当前生效:",o.jsx("b",{children:d.provider}),d.stt.streaming?" · 流式":"",d.stt.server?` · ${d.stt.streaming?d.stt.model:d.stt.batchModel}`:" · 未配置(只能用浏览器自带识别)"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"提供方"}),o.jsxs("select",{className:"set-select",value:r?.provider??"browser",onChange:j=>Ot("provider",j.target.value),children:[o.jsx("option",{value:"dashscope",children:"阿里百炼(DashScope,本文档默认)"}),o.jsx("option",{value:"openai",children:"OpenAI 兼容端点"}),o.jsx("option",{value:"browser",children:"浏览器自带(不经过服务端)"})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"端点"}),o.jsx("input",{className:"set-input",placeholder:"https://llm-xxxx.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",value:r?.baseUrl??"",onChange:j=>Ot("baseUrl",j.target.value),spellCheck:!1})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"API Key"}),A?o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-input",type:"password",name:"agentus-voice-apikey",autoComplete:"new-password",placeholder:n?.apiKeySet?`已保存 ${n.apiKeyMasked}(留空不改)`:"sk-…",value:b,onChange:j=>_(j.target.value),spellCheck:!1,autoFocus:!0}),o.jsx("button",{type:"button",className:"set-btn",onClick:()=>{D(!1),_(""),F(""),k("")},children:"取消"})]}):o.jsxs("div",{className:"set-pair",children:[o.jsx("span",{className:"set-hint",children:n?.apiKeySet?`已保存 ${n.apiKeyMasked}`:"未设置"}),o.jsx("button",{type:"button",className:"set-btn",onClick:()=>D(!0),children:"改密钥"}),n?.apiKeySet?o.jsx("button",{type:"button",className:"set-btn",onClick:()=>{fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({voice:{apiKey:""}})}).then(j=>j.ok?j.json():null).then(j=>{j&&(i(j),a(ll(j)),E("已清除密钥"))}).catch(()=>{})},children:"清除"}):null]})]}),M&&B==="voice.apiKey"?o.jsx("p",{className:"set-hint",style:{color:"#e5534b"},children:M}):null,n?.apiKeySource?o.jsxs("p",{className:"set-hint",children:["密钥来自环境:",o.jsx("code",{children:n.apiKeySource}),"(",o.jsx("code",{children:"DASHSCOPE_API_KEY"})," / ",o.jsx("code",{children:"DASHSCOPE_BASE_URL"}),")"]}):null,o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"流式模型"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-input",list:"asr-models",value:r?.asrModel??"",onChange:j=>Ot("asrModel",j.target.value),spellCheck:!1}),o.jsxs("label",{className:"set-check",children:[o.jsx("input",{type:"checkbox",checked:!!r?.asrStream,onChange:j=>Ot("asrStream",j.target.checked)}),"启用流式(边说边出字)"]})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"批量模型"}),o.jsx("input",{className:"set-input",list:"asr-models",value:r?.asrBatchModel??"",onChange:j=>Ot("asrBatchModel",j.target.value),spellCheck:!1})]}),o.jsx("datalist",{id:"asr-models",children:(l?.asr??[]).map(j=>o.jsx("option",{value:j},j))}),o.jsxs("p",{className:"set-hint",children:[u?`无法读取端点模型列表:${u}`:l?`端点报告 ${l.total} 个模型,其中识别类 ${l.asr.length} 个(上面可直接选,也可以手填任意 id)`:"正在读取端点模型列表…",o.jsxs("button",{className:"set-mini",onClick:()=>void wo(),disabled:S==="models",children:[o.jsx(ba,{size:11})," 重新读取"]})]})]}),o.jsxs("section",{className:"set-card",id:"set-sfx","data-setgroup":"voice",children:[o.jsx("h3",{children:"通话状态音"}),o.jsx("p",{className:"set-hint",children:"它干活的时候有一点很轻的底音,它开口说话就停;你打断它的时候响一声短的。 这里放的和通话里放的是同一份素材、同一个音频上下文,所以这里能听到、通话里就该能听到。"}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"音量"}),o.jsx("input",{type:"range",min:5,max:100,value:w,onChange:j=>{const V=Number(j.target.value);x(V),Wu(),zl().then(()=>lk(V/100,1.6))}}),o.jsxs("span",{className:"set-hint",children:[w,"%"]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("button",{type:"button",className:"set-btn",onClick:()=>{Wu(),y("正在解码…"),zl().then(()=>{const j=Lh();y_(3),y(`上下文 ${j.ctxState} · 通道 ${j.channel} · 背景音 ${j.bed?j.bed.toFixed(1)+"s":"没解码"} · 打断音 ${j.cut?j.cut.toFixed(2)+"s":"没解码"}${j.error?" · 错误:"+j.error:""}`)})},children:"试听背景音(3 秒)"}),o.jsx("button",{type:"button",className:"set-btn",onClick:()=>{Wu(),y("正在解码…"),zl().then(()=>{const j=Lh();v_(),y(`上下文 ${j.ctxState} · 通道 ${j.channel} · 打断音 ${j.cut?j.cut.toFixed(2)+"s":"没解码"}${j.error?" · 错误:"+j.error:""}`)})},children:"试听打断音"})]}),v?o.jsx("p",{className:"set-hint",children:o.jsx("b",{children:v})}):null,o.jsx("p",{className:"set-hint",children:"如果这里显示「上下文 suspended」或者「没解码」,问题在浏览器或格式,不在通话页 —— 把这一行发我。"})]}),o.jsxs("section",{className:"set-card",id:"set-hotwords","data-setgroup":"voice",children:[o.jsx("h3",{children:"热词"}),o.jsxs("p",{className:"set-hint",children:["固定热词每行一个,可写 ",o.jsx("code",{children:"词=权重"}),"(1–5,",o.jsx("code",{children:"50"})," 是超级热词); 动态热词从当前会话的上下文里自动抽取高频实体词,一起送进识别。"]}),o.jsx("textarea",{className:"set-textarea",rows:5,placeholder:`Agentus=5
|
|
74
74
|
ACP
|
|
75
|
-
qodercli`,value:r?.hotwordsText??"",onChange:j=>Ot("hotwordsText",j.target.value),spellCheck:!1}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"动态热词"}),o.jsxs("div",{className:"set-pair",children:[o.jsxs("label",{className:"set-check",children:[o.jsx("input",{type:"checkbox",checked:!!r?.dynamicHotwords,onChange:j=>Ot("dynamicHotwords",j.target.checked)}),"从上下文抽取"]}),o.jsxs("label",{className:"set-check",children:["上限",o.jsx("input",{className:"set-num",type:"number",min:0,max:200,value:r?.hotwordLimit??30,onChange:j=>Ot("hotwordLimit",Number(j.target.value))})]})]})]}),o.jsxs("div",{className:"set-hot",children:[o.jsx("span",{className:"set-hot-title",children:f?`下次识别携带 ${f.words.length} 个热词(固定 ${f.fixed} / 动态 ${f.dynamic}),上下文 ${f.contextTurns??0} 轮`:"…"}),o.jsxs("div",{className:"set-hot-list",children:[(f?.words??[]).slice(0,40).map(j=>o.jsxs("span",{className:`set-chip ${j.origin}`,title:`${j.origin} · 权重 ${j.weight}`,children:[j.word,j.weight>=5?o.jsx("b",{children:j.weight===50?"50":j.weight}):null]},`${j.origin}-${j.word}`)),f&&!f.words.length?o.jsx("span",{className:"set-hint",children:"还没有热词:写几个固定词,或先聊两句再回来看动态抽取。"}):null]})]})]}),o.jsxs("section",{className:"set-card",id:"set-summary","data-setgroup":"voice",children:[o.jsx("h3",{children:"语音总结(消息喇叭长按)"}),o.jsxs("p",{className:"set-hint",children:[o.jsx("b",{children:"长按"}),"任意一条消息旁边的喇叭(电脑上右键)→「语音播报总结」:把这一条压成几十秒能听完的一段话再念出来。 适合那种一屏表格、或者很长的输出 —— 通勤时听完就能知道结论。"]}),o.jsxs("p",{className:"set-hint",children:["它",o.jsx("b",{children:"不经过 agent"}),",也不带会话历史:只把",o.jsx("b",{children:"这一条消息"}),"加下面这段指令,发一次",o.jsx("code",{children:"chat/completions"}),",拿回一段话交给同一个 TTS 念。 消息本身就短于字数上限时",o.jsx("b",{children:"直接念原文"}),",不花一次模型调用。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"启用"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{type:"checkbox",checked:at?.enabled??!0,onChange:j=>void kt({enabled:j.target.checked})}),o.jsx("span",{className:"set-hint",children:at?.enabled??!0?"已启用:长按菜单里会出现「语音播报总结」":"已关闭:长按只出菜单,没有这一项"})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"用会话自己的模型"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{type:"checkbox",checked:at?.followSession??!0,onChange:j=>void kt({followSession:j.target.checked})}),o.jsx("span",{className:"set-hint",children:at?.followSession??!0?"已开启:跟这个会话当前选的 provider 和模型走 —— 你在用 DeepSeek,这笔就记在 DeepSeek 上":"已关闭:改用下面那个模型,走「语音」里配的 DashScope 端点"})]})]}),o.jsxs("p",{className:"set-hint",children:["端点与 key ",o.jsx("b",{children:"不在这里配第二份"}),":驾驶舱读 agent 自己的家 —— ",o.jsx("code",{children:"config.yaml"})," 里的",o.jsx("code",{children:"providers.<id>"}),"(本机的 ",o.jsx("code",{children:"lab"})," 就是),或那几家的 key (",o.jsx("code",{children:"~/.hermes/.env"})," 的 ",o.jsx("code",{children:"DEEPSEEK_API_KEY"}),"、",o.jsx("code",{children:"OPENROUTER_API_KEY"})," 等)。 只认 OpenAI 兼容的 ",o.jsx("code",{children:"/v1/chat/completions"}),";Anthropic Messages / Bedrock / Vertex 这类形状解析不出来, 会退到下面那个模型,并在播报稿那一行写明「语音端点」。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"字数上限"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-num",type:"number",min:n?.summaryCharsRange?.[0]??40,max:n?.summaryCharsRange?.[1]??400,step:10,value:at?.maxChars??120,onChange:j=>Q(V=>V&&{...V,maxChars:Number(j.target.value)}),onBlur:j=>void kt({maxChars:Number(j.target.value)})}),o.jsx("span",{className:"set-hint",children:"中文大约每字 0.2–0.3 秒(120 字 ≈ 25–35 秒)。它同时也是「短于此就念原文」的阈值。"})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"备用模型(语音端点)"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-input",type:"text",placeholder:`${n?.summaryModelDefault??"qwen-flash"}(默认)`,value:at?.model??"",onChange:j=>Q(V=>V&&{...V,model:j.target.value}),onBlur:j=>void kt({model:j.target.value})}),o.jsxs("span",{className:"set-hint",children:["只在上面关掉、或会话那个 provider 解析不出来时用。",o.jsx("code",{children:n?.summaryModelDefault??"qwen-flash"})," 是默认。"]})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"超时(秒)"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-num",type:"number",min:n?.summaryTimeoutRange?.[0]??5,max:n?.summaryTimeoutRange?.[1]??60,step:5,value:at?.timeoutSec??20,onChange:j=>Q(V=>V&&{...V,timeoutSec:Number(j.target.value)}),onBlur:j=>void kt({timeoutSec:Number(j.target.value)})}),o.jsxs("span",{className:"set-hint",children:["超时就",o.jsx("b",{children:"明说失败"}),",不会拿原文冒充总结。可以重试。"]})]})]}),o.jsx("div",{className:"set-row",children:o.jsx("label",{children:"怎么改写"})}),o.jsx("textarea",{className:"set-textarea",rows:7,spellCheck:!1,value:at?.prompt??"",placeholder:"留空即用内置模板 —— 原文就在下面,能直接看、能照着改。",onChange:j=>Q(V=>V&&{...V,prompt:j.target.value}),onBlur:j=>void kt({prompt:j.target.value})}),o.jsxs("details",{className:"set-builtin",open:!(at?.prompt??"").trim(),children:[o.jsx("summary",{children:(at?.prompt??"").trim()?"内置模板(你写了自定义的,它不再生效;清空即可恢复)":"内置模板(留空时生效的就是它)"}),o.jsx("pre",{className:"set-builtin-text",children:n?.summaryPromptDefault??""})]}),o.jsxs("p",{className:"set-hint",children:[o.jsx("code",{children:"{maxChars}"})," 会被换成上面的字数上限。消息正文作为",o.jsx("b",{children:"用户那一轮"}),"单独发出去, 不带系统人设、不带历史、不带工具 —— 所以它只会总结你长按的那一条。"]}),ke?o.jsx("p",{className:"set-hint",children:ke}):null]}),o.jsxs("section",{className:"set-card",id:"set-tts","data-setgroup":"voice",children:[o.jsx("h3",{children:"语音合成(TTS)"}),o.jsxs("p",{className:"set-hint",children:["走百炼的 ",o.jsx("code",{children:"SpeechSynthesizer"}),"(合成结果由服务端取回,密钥不出服务端)。 朗读按钮仍可在下面选择走浏览器自带声音。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"模型"}),o.jsx("input",{className:"set-input",list:"tts-models",value:r?.ttsModel??"",onChange:j=>Ot("ttsModel",j.target.value),spellCheck:!1})]}),o.jsx("datalist",{id:"tts-models",children:(l?.tts??[]).map(j=>o.jsx("option",{value:j},j))}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"音色"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-input",list:"tts-voices",value:r?.ttsVoice??"",onChange:j=>Ot("ttsVoice",j.target.value),spellCheck:!1}),o.jsxs("select",{className:"set-select",value:r?.ttsFormat??"wav",onChange:j=>Ot("ttsFormat",j.target.value),children:[o.jsx("option",{value:"wav",children:"wav"}),o.jsx("option",{value:"mp3",children:"mp3"})]})]})]}),o.jsx("datalist",{id:"tts-voices",children:(n?.ttsVoices??[]).map(j=>o.jsx("option",{value:j},j))}),o.jsxs("p",{className:"set-hint",children:["默认 ",o.jsx("code",{children:"longanhuan_v3.6"})," = 龙安欢。系统音色还有 loongjielidou / loongeva / loongjohn,手填任意音色 id 也可以。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"试听"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-input",value:H,onChange:j=>I(j.target.value)}),o.jsxs("button",{className:"set-mini",onClick:()=>void Rr(),disabled:S==="tts",children:[o.jsx(hd,{size:12})," ",S==="tts"?"合成中…":"合成并播放"]})]})]}),o.jsx("p",{className:"set-hint",children:"试听使用已保存的配置(有未保存修改会先保存)。"})]}),o.jsxs("section",{className:"set-card",id:"set-browser","data-setgroup":"voice",children:[o.jsx("h3",{children:"这个浏览器"}),o.jsx("p",{className:"set-hint",children:"听写引擎与朗读声音是本机设置:手机和电脑的麦克风/声音本来就不一样。"}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"听写引擎"}),o.jsxs("select",{className:"set-select",value:O.stt,onChange:j=>K({stt:j.target.value}),children:[o.jsx("option",{value:"auto",children:"自动(优先服务端流式)"}),o.jsx("option",{value:"stream",children:"服务端流式(百炼,带热词)"}),o.jsx("option",{value:"browser",children:"浏览器自带"}),o.jsx("option",{value:"server",children:"服务端批量上传"})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"测试识别"}),o.jsxs("div",{className:"set-pair",children:[o.jsxs("button",{className:"set-mini",onClick:$i,disabled:ws||U.status==="transcribing",children:[o.jsx(ji,{size:12})," 开麦说一句"]}),ws||U.status==="transcribing"?o.jsxs("button",{className:"set-mini",onClick:()=>pe.stop(),children:[o.jsx(xh,{size:11})," 停止"]}):null,o.jsx("span",{className:`dict-chip ${U.error?"err":""}`,style:{margin:0},children:U.error?U.error:U.status==="requesting"?"等待麦克风…":U.status==="transcribing"?"收尾中…":`${U.text}${U.interim?` ${U.interim}`:""}${U.engine?` · ${U.engine}`:""}`})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"朗读"}),o.jsxs("div",{className:"set-pair",children:[o.jsxs("select",{className:"set-select",value:O.speakMode??(O.autoRead?"reply":"off"),onChange:j=>{const V=j.target.value;K({speakMode:V,autoRead:V==="reply"})},children:[o.jsx("option",{value:"off",children:"关(不自动出声)"}),o.jsx("option",{value:"reply",children:"自动朗读(念整条回复)"}),o.jsx("option",{value:"brief",children:"工作播报(念驾驶舱的一句话)"})]}),o.jsxs("label",{className:"set-check",children:[o.jsx("input",{type:"checkbox",checked:O.serverTts,onChange:j=>K({serverTts:j.target.checked})}),"用服务端声音(否则用系统声音)"]})]})]})]}),o.jsxs("div",{className:"set-actions",children:[o.jsx("button",{className:"set-save",onClick:()=>void jn(),disabled:S==="save"||!Jt,children:S==="save"?"保存中…":"保存"}),Jt?o.jsx("button",{className:"set-mini",onClick:()=>a(n?ll(n):null),children:"撤销修改"}):null]})]})]})]})}const Ca=e=>String(e).padStart(2,"0"),_3=["周日","周一","周二","周三","周四","周五","周六"];function Ai(e){const t=new Date(e);return`${Ca(t.getHours())}:${Ca(t.getMinutes())}`}function ho(e){const t=new Date(e);return`${t.getFullYear()}-${Ca(t.getMonth()+1)}-${Ca(t.getDate())} ${Ai(e)}`}function ck(e,t){const s=new Date(e),n=new Date(t),i=new Date(s.getFullYear(),s.getMonth(),s.getDate()).getTime(),r=new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime();return Math.round((r-i)/864e5)}function gm(e,t=Date.now()){const s=new Date(e),n=ck(e,t);return n<=0?Ai(e):n===1?`昨天 ${Ai(e)}`:s.getFullYear()===new Date(t).getFullYear()?`${s.getMonth()+1}月${s.getDate()}日 ${Ai(e)}`:ho(e)}function v3(e,t=Date.now()){const s=Math.floor((t-e)/1e3);if(s<0)return Ai(e);if(s<45)return"刚刚";if(s<3600)return`${Math.max(1,Math.floor(s/60))} 分钟前`;const n=new Date(e),i=ck(e,t);return i<=0?Ai(e):i===1?"昨天":i<7?_3[n.getDay()]:n.getFullYear()===new Date(t).getFullYear()?`${n.getMonth()+1}月${n.getDate()}日`:`${n.getFullYear()}-${Ca(n.getMonth()+1)}-${Ca(n.getDate())}`}const y3=6e4;function Oh(e){const t=Math.round(Math.max(0,e)/1e3);return t<60?`${t} 秒`:`${Math.floor(t/60)} 分 ${t%60} 秒`}function b3(e,t){const s=Math.max(0,t-e),n=s>=y3;return{quiet:n,gapMs:s,said:n?`agent 已经 ${Oh(s)} 没有输出了 —— 回合还在跑,可以点下面的停止`:"agent 正在工作(有输出就会重置这个计时)"}}const w3={hermes:{letter:"H",label:"Hermes",icon:"/coding-agents/hermes.png"},qoder:{letter:"Q",label:"Qoder",icon:"/coding-agents/qoder.svg"},mock:{letter:"M",label:"Mock"}};function vd(e){return w3[e]??{letter:e.slice(0,1).toUpperCase(),label:e}}function vy(e,t){const s=e.filter(n=>n.kind!=="mock"||t);return s.length?s:e}function x3(e,t){const s=[],n=/(\*\*[^*]+\*\*|`[^`]+`|\[[^\]]+\]\([^)]+\))/g;let i=0,r,a=0;for(;r=n.exec(e);){r.index>i&&s.push(e.slice(i,r.index));const l=r[0],c=`${t}-i${a++}`;if(l.startsWith("**"))s.push(o.jsx("strong",{children:l.slice(2,-2)},c));else if(l.startsWith("`"))s.push(o.jsx("code",{className:"inline",children:l.slice(1,-1)},c));else{const u=/\[([^\]]+)\]\(([^)]+)\)/.exec(l);s.push(o.jsx("a",{href:u[2],target:"_blank",rel:"noreferrer",children:u[1]},c))}i=r.index+l.length}return i<e.length&&s.push(e.slice(i)),s}function S3({text:e}){const t=e.split(/```/);return o.jsx(o.Fragment,{children:t.map((s,n)=>n%2===1?o.jsx("pre",{className:"code",children:o.jsx("code",{children:s.replace(/^[a-z]*\n/,"").replace(/\n$/,"")})},n):o.jsx(g.Fragment,{children:x3(s,`p${n}`)},n))})}function $n(e){const t=Number.isFinite(e)?Math.max(0,Math.round(e)):0;return t<1024?String(t):t<1048576?`${yy(t/1024)}k`:`${yy(t/1048576)}m`}function yy(e){return Number.isInteger(e)?String(e):e.toFixed(1)}function uk(e){if(!e.available)return"agent 未上报用量";const t=[`${$n(e.input)} in`,`${$n(e.output)} out`];return e.thought>0&&t.push(`思考 ${$n(e.thought)}`),(e.cacheRead>0||e.cacheWrite>0)&&t.push(`缓存 读 ${$n(e.cacheRead)} / 写 ${$n(e.cacheWrite)}`),e.cacheHitPercent!=null&&t.push(`命中 ${e.cacheHitPercent}%`),e.tps!=null&&e.tps>0&&t.push(`${e.tps>=100?Math.round(e.tps):e.tps.toFixed(1)} t/s 平均`),e.durationMs!=null&&e.durationMs>0&&t.push(k3(e.durationMs)),t.join(" · ")}function k3(e){const t=Math.max(1,Math.round(e/1e3));if(t<60)return`${t}s`;const s=Math.floor(t/60);return t%60?`${s}m ${t%60}s`:`${s}m`}const by=12,C3=80;function E3(e){const t=[],s=/[^。!?!?\n…]*[。!?!?\n…]+/g;let n=0;for(const l of e.matchAll(s)){const c=l[0].trim();c&&t.push(c),n=(l.index??0)+l[0].length}const i=[];for(const l of t){const c=i[i.length-1];c!==void 0&&c.length<by&&c.length+l.length<=C3?i[i.length-1]=`${c} ${l}`:i.push(l)}const r=[],a=i[i.length-1];return a!==void 0&&a.length<by&&r.push(i.pop()),{done:i,tail:[...r,e.slice(n).trim()].filter(Boolean).join(" ")}}const N3={leadingDelayMs:2e3,firstToolGapMs:5e3,minGapMs:1e4,dwellMs:9e3,maxCues:3},R3=/[\u0000-\u001f]|^\s*$/;function j3(e){const t=e.replace(/\s*·.*$/,"").trim();if(!t||R3.test(t))return"在跑一个工具";const s=t.split(/[\s/\\]+/).find(n=>n.length>0)??"";return s?`在跑 ${s.slice(0,12)}`:"在跑一个工具"}class wy{#e;#l=0;#i=!1;#s=0;#o=0;#t=null;#n=0;#c=!1;#h=!1;constructor(t={}){this.#e={...N3,...t}}turnStarted(t){this.#i=!0,this.#l=t,this.#s=0,this.#o=0,this.#t=null,this.#n=0,this.#c=!1,this.#h=!1}get turnActive(){return this.#i&&!this.#c}get cuesSpoken(){return this.#o}thinking(t){return!this.turnActive||this.#h||t-this.#l<this.#e.leadingDelayMs?null:(this.#h=!0,this.#p({text:"我查一下",kind:"leading"},t))}tool(t,s){if(!this.turnActive)return null;const n={text:j3(s),kind:"tool"};return this.#o===0&&(this.#s!==0||t-this.#l>=this.#e.firstToolGapMs)?this.#p(n,t):(this.#_(n,t),null)}plan(t,s,n){if(!this.turnActive||n<=0)return null;const i={text:`第 ${Math.min(s+1,n)} 步,共 ${n} 步`,kind:"plan"};return this.#o===0&&t-this.#l>=this.#e.firstToolGapMs?this.#p(i,t):(this.#_(i,t),null)}tick(t){if(!this.turnActive||!this.#t||t-this.#n<this.#e.dwellMs)return null;const s=this.#p(this.#t,t);return s&&(this.#t=null),s}answerStarted(){this.#c=!0,this.#t=null}turnEnded(){this.#i=!1,this.#l=0,this.#t=null,this.#c=!1}#_(t,s){this.#t?.kind==="plan"&&t.kind==="tool"||(this.#t=t,this.#n=s)}#p(t,s){return this.#o>=this.#e.maxCues?null:this.#s&&s-this.#s<this.#e.minGapMs?(this.#t?this.#n=Math.min(this.#n,s):this.#_(t,s),null):(this.#o+=1,this.#s=s,t)}}const Gi=(e,t,s,n,i,r)=>[{off:e,wid:t,lidY:s,oval:n,tilt:i,ridge:r},{off:e,wid:t,lidY:s,oval:n,tilt:i,ridge:r}],hk={neutral:Gi([0,0],.13,1,[0,0],0,[0,0,-.155,.155]),happy:Gi([.03,.03],.1305,1,[0,0],0,[-.16,.16,-.04,.12]),surprised:Gi([.03,0],.21,1,[0,0],0,[0,0,-.22,.22]),inspecting:[{off:[.04,0],wid:.27,lidY:1,oval:[0,0],tilt:0,ridge:[0,0,0,0]},{off:[.04,0],wid:.18,lidY:1,oval:[0,0],tilt:0,ridge:[0,0,0,0]}],sad:Gi([-.05,0],.13,1,[0,0],0,[-.0563,.0563,-.106,.106]),sleepy:Gi([.01,0],.13,1,[0,0],0,[-.11,.11,-.0125,.025]),squinted:Gi([.01,0],.13,1,[0,0],0,[-.12,.12,0,0]),calm:Gi([.05,0],.247,1,[.296,.247],0,[-.296,.296,0,0]),confused:Gi([-.1,0],.1305,1,[0,0],0,[-.08,.01,-.16,.16])},T3=Object.keys(hk);new Set(T3);const A3={idle:"neutral",happy:"happy",surprise:"surprised",curious:"inspecting",sad:"sad",drowsy:"sleepy",focus:"squinted",calm:"calm",confused:"confused"},Io={x:34/.26,y:70/.57},xy={w:64,h:82};function M3(e,t){const s=hk[e][t?1:0],[n,i,r,a]=s.ridge,l=2*Math.max(Math.abs(n),Math.abs(i))+2*s.wid,c=a-r+2*s.wid*s.lidY,u=Math.min(1,xy.w/(l*Io.x),xy.h/(c*Io.y));return{w:l*Io.x*u,h:c*Io.y*u,x:s.off[0]*Io.x*u,y:s.off[1]*Io.y*u,rot:s.tilt*180/Math.PI}}function D3(e){switch(e){case"focus":case"strive":return 48;case"curious":return 54;case"drowsy":case"sleep":return 56;case"working":return 46;case"asking":return 52;case"calm":return 62;case"confused":return 54;default:return 60}}function I3(e){const t=a=>Number.isFinite(a)?Math.max(0,a):0,s=e.ballR,n=s!==void 0&&Number.isFinite(s)&&s>0?s:98,i=D3(e.mood)+(t(e.leftW)+t(e.rightW))/2,r=Math.min(1,Math.max(0,i/(2*n)));return Math.asin(r)*180/Math.PI*2}const dk=["happy","sad","confused","focus","drowsy","error","scan","loading","strive","sleep"];function fk(e=Math.random){return 2800+e()*3600}const _m=260,cl=70.833,Tf=33.333,P3=1.06,L3=.01;function O3(e){if(!Number.isFinite(e)||e<0||e>=_m)return 0;const t=n=>n*n*(3-2*n);if(e<cl)return t(e/cl);if(e<cl+Tf)return 1;const s=_m-cl-Tf;return 1-t((e-cl-Tf)/s)}const Sy=2400,B3=3e4,$3=9e4,F3=12e4,z3=1600,pk=6e3,H3=.56;function U3(e,t,s,n={}){const i=bn(n.warmth??0);switch(e){case"listening":return{mode:"listening",attention:Math.min(1,.72+t*.38),energy:.78,warmth:i,phaseElapsed:s};case"thinking":return{mode:"thinking",attention:.88,energy:Math.min(1,.62+s*.08),warmth:i,phaseElapsed:s};case"speaking":return{mode:"speaking",attention:.7,energy:Math.min(1,.72+t*.35),warmth:Math.max(i,.25),phaseElapsed:s};case"curious":case"asking":return{mode:"listening",attention:Math.min(1,.82+t*.34),energy:.86,warmth:i,phaseElapsed:s};case"focus":case"working":case"strive":case"loading":return{mode:"thinking",attention:.9,energy:Math.min(1,.64+s*.08),warmth:i,phaseElapsed:s};case"talking":case"happy":case"surprise":case"wink":return{mode:"speaking",attention:.74,energy:Math.min(1,.76+t*.33),warmth:Math.max(i,.28),phaseElapsed:s};case"lookLeft":case"lookRight":case"scan":return{mode:"listening",attention:.66,energy:.7,warmth:i,phaseElapsed:s};case"drowsy":case"sleep":return{mode:"idle",attention:.1,energy:.16+i*.1,warmth:i,phaseElapsed:s};case"calm":return{mode:"idle",attention:.5,energy:.56,warmth:i,phaseElapsed:s};case"confused":return{mode:"listening",attention:.64,energy:.6,warmth:i,phaseElapsed:s};default:return{mode:"idle",attention:n.resting?.12:.38,energy:(n.resting?.18:.48)+i*.2,warmth:i,phaseElapsed:s}}}function W3(e){const{phase:t,activity:s="none",emotion:n,life:i,resting:r,drowsy:a}=e;return t==="error"?"error":t==="connecting"?"loading":s==="asking"?(e.askingMs??0)>=F3?"drowsy":"asking":e.waking?"surprise":t==="speaking"?n&&n!=="idle"?n:"talking":s==="tools"?"working":r?"sleep":a?"drowsy":t==="listening"?i??"calm":t==="thinking"?"focus":i??"idle"}function mk(e){return e<1.2?0:e<3.2?1:2}function ky(e){const{mood:t,right:s,t:n,expr:i}=e,r=e.blinking??!1,a=bn(e.blink??(r?1:0)),l=e.substate??"idle",c=bn(e.level),u=bn(e.sleep??0),{right:h}={right:s},d=A3[t],p=d?M3(d,s):null;if(t==="error")return Af({shape:"x",w:45,h:45,yScale:1,xScale:1,rot:0,x:0,y:0,alpha:.86,glow:10,jitter:6},l,s,n);if(t==="happy"||t==="sad")return Af({shape:"arc",w:p.w,h:p.h,yScale:1,xScale:1,rot:p.rot,x:p.x*2,y:(t==="happy"?20+Math.sin(n*10)*3:-10)+p.y,alpha:bn(.72+i.energy*.22+i.warmth*.06),glow:9+c*12+i.warmth*5,jitter:0,arc:t},l,s,n);const f=mk(i.phaseElapsed),m=f===0?48:f===1?56:60,b=f===0?18:f===1?13:10+Math.sin(n*2)*2,_=f===0?12:f===1?22:28,v=f===0?4:f===1?10:14,y=t==="focus"&&i.mode==="thinking",w=t==="focus"&&i.mode==="listening";let x,S;if(p)x=p.w,S=p.h;else{switch(t){case"scan":x=65+c*8;break;case"strive":x=m;break;case"sleep":x=45;break;case"loading":x=16;break;case"working":x=46;break;case"asking":x=38;break;default:x=34}switch(t){case"scan":S=12+c*8;break;case"strive":S=b;break;case"sleep":S=4+Math.sin(n*1.1)*1.2+1.2;break;case"loading":S=16;break;case"wink":S=h?2:40;break;case"working":S=46;break;case"asking":S=74;break;default:S=70}}let N=0;t==="strive"?N=h?-_:_:t==="asking"?N=8:t==="confused"?N=p.rot-8:p?N=p.rot:y&&(N=h?4:-4);let R=0;switch(t){case"lookLeft":R=-40;break;case"lookRight":R=40;break;case"scan":R=Math.sin(n*3.5)*45;break;case"working":R=0;break;case"asking":R=Math.sin(n*.9)*1.2;break;case"strive":R=Math.sin(n*(f===0?1.8:f===1?4.2:5))*v;break}if(p){const k=t==="calm"?Math.sin(n*.7)*1.2:t==="confused"?Math.sin(n*1.3)*2:t==="focus"?Math.sin(n*2.4)*(i.phaseElapsed<1.2?2.5:6):0;R=p.x*2+k}let E=0;switch(t){case"talking":E=Math.sin(n*10)*2-c*4+i.warmth*2;break;case"strive":E=Math.cos(n*3.2)*(2+i.energy*2);break;case"drowsy":E=4+u*12+Math.sin(n*1.2)*1.4;break;case"wink":E=h?0:-10;break;case"working":E=6+Math.sin(n*1.6)*1.2;break}if(p){const k=t==="calm"?Math.sin(n*1.1)*1.1:t==="confused"?Math.sin(n*1.7)*1.5:0;E+=p.y+k}let M=1;t==="talking"?M=.72+c*.42+Math.sin(n*8)*.06+i.warmth*.04:t==="drowsy"?M=Math.max(.18,1-u*.74):t==="working"?M=.58+Math.sin(n*1.6)*.02:t==="calm"?M=.82+Math.sin(n*1.1)*.02:t==="confused"?M=.98+Math.sin(n*1.7)*.015:t==="focus"&&(M=w?.9+c*.12+Math.sin(n*1.4)*.015:y?.82+Math.sin(n*1.8)*.025:.94+i.attention*.06+Math.sin(n*2)*.02);let F=1;t==="lookLeft"?F=h?1.2:.8:t==="lookRight"&&(F=h?.8:1.2);let B;return t==="drowsy"?B=.72-u*.44:t==="sleep"?B=.18:B=Math.min(1,.72+i.energy*.22+i.warmth*.06),a>0&&!dk.includes(t)&&(M=Math.min(M,Math.max(L3,1-P3*a))),Af({shape:"capsule",w:x,h:S,yScale:M,xScale:F,rot:N,x:R,y:E,alpha:bn(B),glow:9+c*12+i.warmth*5,jitter:t==="strive"?.8:0},l,s,n)}function Af(e,t,s,n){switch(t){case"reading":return{...e,w:e.w*.9,h:e.h*.82,rot:e.rot+3,y:e.y+2};case"running":return{...e,w:e.w*1.06,h:e.h*.74,yScale:e.yScale*.82,jitter:Math.max(e.jitter,1.1),y:e.y+Math.sin(n*5.5)*1.2};case"writing":return{...e,w:e.w*(s?.76:.88),h:e.h*.9,rot:e.rot+(s?4:1),y:e.y+3};case"awaiting":return{...e,w:e.w*.94,h:e.h*1.08,alpha:Math.min(1,e.alpha+.06),glow:e.glow+3,rot:e.rot*.3};case"done":return{...e,w:e.w*.92,h:e.h*.72,y:e.y-5,rot:e.rot*.4,alpha:Math.min(1,e.alpha+.04)};case"failed":return{...e,w:e.w*.96,h:e.h*.8,y:e.y+5,rot:e.rot+(s?5:-5),alpha:e.alpha*.88,glow:e.glow*.8};default:return e}}const K3=2e4;function q3(e){return e.pending>0?"asking":e.busy?e.newestKind==="tool"?"tools":"thinking":"none"}function V3(e="",t=""){const s=t.toLowerCase();if(s==="edit"||s==="write"||s==="patch"||s==="create")return"writing";if(s==="read"||s==="search"||s==="fetch")return"reading";if(s==="execute"||s==="run"||s==="command"||s==="terminal")return"running";const n=e.toLowerCase();return/\b(write|edit|patch|apply_patch|multi_edit|create|mkdir|delete|move|rename)\b|写入|编辑|修改/.test(n)?"writing":/\b(read|cat|head|tail|view|open|glob|grep|search|find|list|ls|tree)\b|读取|查看|搜索/.test(n)?"reading":"running"}function Y3(e){if(e.pending>0)return"awaiting";if(!e.busy||e.newestKind!=="tool")return"idle";const t=String(e.newestToolStatus??"").toLowerCase();return t==="failed"||t==="error"||t==="cancelled"?"failed":t==="completed"||t==="success"?"done":V3(e.newestToolTitle,e.newestToolKind)}function G3(e,t=Math.random,s={}){if(e>$3)return s.busy?null:"rest";const n=e>B3?["lookLeft","lookRight","curious","wink","focus","calm"]:["lookLeft","lookRight","wink"];if(t()>=H3)return null;const i=n[Math.min(n.length-1,Math.floor(t()*n.length))];return{mood:i,durationMs:i==="wink"?750:1800+t()*1400}}const J3=[{mood:"happy",words:["开心","高兴","太好了","喜欢","棒","恭喜","成功","完成了","搞定","哈哈","谢谢"]},{mood:"sad",words:["抱歉","难过","遗憾","可惜","失败了","没成功","不舒服","唉"]},{mood:"surprise",words:["竟然","居然","没想到","原来","意外","真的吗"]},{mood:"curious",words:["要不要","是不是","你觉得","哪个","为什么","要我","需要我"]},{mood:"strive",words:["麻烦","麻烦你","冲突","错误","报错","卡住","超时"]}],X3=/[不没别未无](?:有|是|会|太|要)?\s*$/;function Z3(e){const t=String(e??"");if(!t)return null;let s=null;for(const{mood:n,words:i}of J3)for(const r of i){let a=t.indexOf(r);for(;a>=0;){if(!X3.test(t.slice(Math.max(0,a-2),a))){(!s||a<s.at)&&(s={mood:n,at:a});break}a=t.indexOf(r,a+1)}}return s?.mood??null}const gk=2e4,Q3=45e3,e5={neutral:"idle",happy:"happy",surprised:"surprise",inspecting:"curious",sad:"sad",sleepy:"drowsy",squinted:"focus",calm:"calm",confused:"confused",smile:"happy",inspect:"curious",strange:"curious",squint:"focus",idle:"idle",thinking:"sad",focus:"focus",angry:"strive",sleep:"sleep",joy:"happy",love:"happy",surprise:"surprise",curious:"curious",strive:"strive",shy:"wink",wink:"wink"},b_=/\[\s*(?:emo|emotion)\s*[::]\s*([a-zA-Z\u4e00-\u9fa5_-]{1,16})\s*\]/gi;function t5(e){const t=[];for(const s of String(e??"").matchAll(b_)){const n=e5[s[1].toLowerCase()];n&&t.push(n)}return t}const Cy=/\s*\[\s*(?:emo|emotion)\s*[::]\s*[a-zA-Z\u4e00-\u9fa5_-]*\s*\]?\s*$/i,s5=new RegExp(b_.source,"i");function Bh(e){const t=String(e??"");return!s5.test(t)&&!Cy.test(t)?t:t.replace(b_,"").replace(Cy,"").trim()}function n5(e){return String(e??"").replace(/[ \t]{2,}/g," ").trim()}function bn(e){return e<0?0:e>1?1:e}function i5(e,t,s=.55,n=.1){const i=bn(e),r=bn(t);return bn(i+(r-i)*(r>i?s:n))}function r5(e,t){return bn(t)-bn(e)>.18&&t>.22?"tick":null}const Ey=2400,o5=4600;function a5(e=Math.random){return Ey+e()*(o5-Ey)}function l5(e=Math.random){const t=e();return{mood:t<.42?"lookLeft":t<.84?"lookRight":"wink",durationMs:300+e()*220}}function c5(e,t={}){const s=u5(e,t);return h5(s,t.substate??"idle")}function u5(e,t){const s=bn(t.level??0),n=t.breath??0,i=e==="sleep",r=e==="drowsy";switch(e){case"talking":return{r:96+s*7,sx:1+s*.03,sy:1-s*.025,dy:-1.5-s*2,rot:0};case"happy":case"wink":return{r:100,sx:1.03,sy:.97,dy:-3,rot:-4};case"surprise":return{r:104,sx:.98,sy:1.04,dy:-4,rot:0};case"sad":return{r:93,sx:1.02,sy:.94,dy:3,rot:3};case"strive":return{r:95,sx:1.05,sy:.92,dy:1,rot:-3};case"working":return{r:92,sx:1.06,sy:.9,dy:4,rot:7};case"asking":return{r:99,sx:.99,sy:1.01,dy:-1,rot:0};case"calm":return{r:100,sx:1.01,sy:.99,dy:-1,rot:-2};case"confused":return{r:96,sx:1.02,sy:.96,dy:2,rot:8};case"focus":return{r:94,sx:.98,sy:1,dy:0,rot:-5};case"drowsy":return{r:97,sx:1.02,sy:.95,dy:6,rot:6};case"sleep":return{r:95,sx:1.04,sy:.93,dy:7,rot:8};case"loading":return{r:92+(t.breath??0)*3,sx:1,sy:1,dy:0,rot:0};case"error":return{r:96,sx:1.03,sy:.96,dy:0,rot:0};default:return{r:i?95:98,sx:1+n*.006,sy:1-n*.006,dy:r?5:-n*2,rot:e==="curious"?4:e==="lookLeft"?-3:e==="lookRight"?3:0}}}function h5(e,t){switch(t){case"reading":return{...e,r:e.r-1,rot:e.rot-4,dy:e.dy+2};case"running":return{...e,r:e.r-2,sx:e.sx*.98,sy:e.sy*.96,rot:e.rot+2,dy:e.dy+3};case"writing":return{...e,r:e.r-2,sx:e.sx*1.02,sy:e.sy*.95,rot:e.rot+9,dy:e.dy+4};case"awaiting":return{...e,r:e.r+3,sy:e.sy*1.02,dy:e.dy-2,rot:e.rot*.4};case"done":return{...e,r:e.r+4,sy:e.sy*1.05,dy:e.dy-5,rot:e.rot-3};case"failed":return{...e,r:e.r-4,sy:e.sy*.94,dy:e.dy+5,rot:e.rot+3};default:return e}}const d5=6,f5=9,Yr={min:1.36,max:1.5},Kt={r:1,sx:1,sy:1,dy:0,rot:0},Ny={"listen-in":{frames:[Kt,{r:1.02,sx:1.03,sy:1.06,dy:-1.42,rot:-.6},{r:1.01,sx:.99,sy:1.02,dy:.8,rot:.35},Kt],ms:[180,260,960],ease:["out","inOut","out"]},"say-in":{frames:[Kt,{r:1.05,sx:1.05,sy:.93,dy:-1.1,rot:.2},{r:1.06,sx:.98,sy:1.08,dy:1.4,rot:-.3},Kt],ms:[120,220,1160],ease:["in","out","inOut"]},"think-turn":{frames:[Kt,{r:.99,sx:1.06,sy:.92,dy:.7,rot:-1.36},{r:1.01,sx:.98,sy:1.03,dy:-.9,rot:.5},Kt],ms:[200,700,1100],ease:["out","inOut","out"]},"tool-start":{frames:[Kt,{r:.98,sx:1.12,sy:.86,dy:1.2,rot:.3},{r:1.02,sx:.96,sy:1.06,dy:-1.42,rot:-.6},Kt],ms:[150,250,1400],ease:["in","out","inOut"]},"tool-done":{frames:[Kt,{r:1.04,sx:1,sy:1.08,dy:-1.45,rot:-1.1},{r:1.01,sx:1.03,sy:.96,dy:1.36,rot:.5},Kt],ms:[220,380,1400],ease:["out","in","out"]},"error-frown":{frames:[Kt,{r:.95,sx:1.06,sy:.92,dy:1.3,rot:-1.45},{r:.98,sx:1.02,sy:.96,dy:.7,rot:1.36},Kt],ms:[180,520,1200],ease:["out","inOut","out"]},"ask-hold":{frames:[Kt,{r:1.02,sx:.99,sy:1.02,dy:-.7,rot:1.36},{r:1.01,sx:1.02,sy:1,dy:.5,rot:1.1},Kt],ms:[260,1200,1600],ease:["out","inOut","inOut"]},"blink-pop":{frames:[Kt,{r:.99,sx:1.01,sy:.97,dy:1.4,rot:0},Kt],ms:[180,1220],ease:["out","out"]},"tool-fail":{frames:[Kt,{r:.94,sx:1.08,sy:.9,dy:1.45,rot:-.8},{r:.97,sx:.98,sy:.96,dy:.4,rot:.7},Kt],ms:[160,380,1400],ease:["out","inOut","out"]},wake:{frames:[Kt,{r:1.05,sx:.97,sy:1.06,dy:-1.45,rot:.4},{r:1,sx:1.02,sy:.98,dy:.6,rot:-.2},Kt],ms:[200,600,1800],ease:["out","inOut","out"]}};function p5(e){let t=0;for(const s of e.frames)t=Math.max(t,Math.abs(s.r-1),Math.abs(s.sx-1),Math.abs(s.sy-1),Math.abs(s.dy),Math.abs(s.rot));return t}function m5(e){const t=p5(e);if(!(t>0))return e;const s=t>Yr.max?Yr.max/t:t<Yr.min?Yr.min/t:1;return s===1?e:{...e,frames:e.frames.map(n=>({r:1+(n.r-1)*s,sx:1+(n.sx-1)*s,sy:1+(n.sy-1)*s,dy:n.dy*s,rot:n.rot*s}))}}const Ry=Object.fromEntries(Object.keys(Ny).map(e=>[e,m5(Ny[e])])),jy={"blink-pop":0,"tool-start":1,"listen-in":2,"say-in":2,"think-turn":2,wake:2,"ask-hold":3,"tool-done":4,"tool-fail":4,"error-frown":4};function g5(e){return e.ms.reduce((t,s)=>t+s,0)}const _5={linear:e=>e,in:e=>e*e*e,out:e=>1-Math.pow(1-e,3),inOut:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2};function v5(e){const t=n=>Math.min(Yr.max,Math.max(1/Yr.max,n)),s=n=>Math.min(Yr.max,Math.max(-1.5,n));return{r:t(e.r),sx:t(e.sx),sy:t(e.sy),dy:s(e.dy),rot:s(e.rot)}}function y5(e,t){if(!Number.isFinite(t)||t<0)return null;let s=t;for(let n=0;n<e.ms.length;n++){const i=e.ms[n];if(s<=i){const r=i>0?s/i:1,a=_5[e.ease[n]??"linear"](r),l=e.frames[n],c=e.frames[n+1]??l;return v5({r:l.r+(c.r-l.r)*a,sx:l.sx+(c.sx-l.sx)*a,sy:l.sy+(c.sy-l.sy)*a,dy:l.dy+(c.dy-l.dy)*a,rot:l.rot+(c.rot-l.rot)*a})}s-=i}return null}function b5(e,t){return{r:e.r*t.r,sx:e.sx*t.sx,sy:e.sy*t.sy,dy:e.dy+t.dy*d5,rot:e.rot+t.rot*f5}}function Ty(e){switch(e.kind){case"tool":return e.status==="start"?"tool-start":e.status==="done"?"tool-done":"tool-fail";case"blink":return"blink-pop";case"think":return e.stage===0?null:"think-turn";case"mood":{const{from:t,to:s}=e;return s==="error"?"error-frown":s==="asking"?"ask-hold":s==="working"?"tool-start":s==="talking"?"say-in":s==="focus"?"think-turn":s==="curious"?t==="lookLeft"||t==="lookRight"||t==="wink"||t==="scan"?null:"listen-in":(s==="idle"||s==="happy")&&(t==="sleep"||t==="drowsy")?"wake":null}}}function ul(e,t,s,n,i=26,r=.55){const a=-2*r*i*t-i*i*(e-s),l=t+a*n;return{x:e+l*n,v:l}}const Ay={maxX:14,maxY:18};function w5(e){const t=e.elapsed??0;let s=0,n=0;switch(e.mood){case"focus":s=-.55,n=-.7;break;case"working":s=-.25,n=.85;break;case"asking":s=0,n=.1;break;case"sad":s=0,n=.8;break;case"happy":case"wink":s=.15,n=-.25;break;case"surprise":s=0,n=-.15;break;case"drowsy":case"sleep":s=0,n=.75;break;case"lookLeft":s=-.9;break;case"lookRight":s=.9;break;case"scan":s=Math.sin(t*2.2)*.9;break;case"curious":s=.35,n=-.2;break;case"calm":s=.08,n=.05;break;case"confused":s=-.4,n=-.12;break}switch(e.substate??"idle"){case"reading":s-=.35,n+=.55;break;case"running":s+=.05,n+=.75;break;case"writing":s+=.4,n+=.75;break;case"awaiting":s*=.3,n=.15;break;case"done":s+=.1,n-=.5;break;case"failed":s*=.6,n+=.65;break}return{ax:s*.7*Ay.maxX,ay:n*.7*Ay.maxY}}function x5(e){const t=(e.ax+e.side*e.sep/2)*Math.PI/180,s=e.ay*Math.PI/180;return{x:e.R*Math.sin(t),y:e.R*Math.sin(s),cos:Math.max(0,Math.cos(t)*Math.cos(s))}}function S5(e){const t=e.k??1,s=Number.isFinite(t)&&t>0?t:1,n=e.ballR,i=(n!==void 0&&Number.isFinite(n)&&n>0?n:98)*s,r=I3({mood:e.mood,leftW:e.left.w,rightW:e.right.w,ballR:e.ballR}),a=(d,p,f,m)=>{const b=x5({ax:e.gaze.ax,ay:e.gaze.ay,side:p,R:i,sep:f}),_=.55+.45*b.cos;return{x:b.x+d.x*s*.5*m,y:b.y+d.y*s,w:Math.max(2,d.w*s*d.xScale*_),cos:b.cos}},l=1.05*i,c=(d,p)=>{const f=a(e.left,-1,d,p),m=a(e.right,1,d,p);return{l:f,r:m,out:Math.max(Math.abs(f.x)+f.w/2,Math.abs(m.x)+m.w/2)}};let u=r,h=c(u,1);if(h.out>l)if(c(u,0).out<=l){let d=0,p=1;for(let f=0;f<18;f++){const m=(d+p)/2;c(u,m).out>l?p=m:d=m}h=c(u,d)}else{let d=0,p=r;for(let f=0;f<18;f++){const m=(d+p)/2;c(m,0).out>l?p=m:d=m}u=d,h=c(u,0)}return{left:h.l,right:h.r,gap:h.r.x-h.r.w/2-(h.l.x+h.l.w/2),sep:u}}const k5=e=>({phase:"idle",life:null,lifeUntil:0,nextBlinkAt:e+fk(),blinkAt:e-_m,nextBeatAt:e+pk,nextActionAt:e+gk,resting:!1,drowsy:!1,sleep:0,sleepTarget:0,phaseAt:e,warmthUntil:0,lastEventAt:e,quietSince:e,micro:null,microAt:0,microUntil:0,mood:"idle",moodAt:e,ticks:0,level:0,rawLevel:0,toolStatus:"",clip:null,clipAt:0,clipMs:0,thinkStage:0,nextSaccadeAt:e+900,ball:{r:98,sx:1,sy:1,dy:0},ballV:{r:0,sx:0,sy:0,dy:0},ballRot:0,ballRotV:0,askingSince:0,wakeUntil:0,dots:0});function C5({phase:e,activity:t,substate:s="idle",emotion:n=null,ticks:i=0,toolStatus:r="",getLevel:a,onMood:l}){const c=g.useRef(null),u=g.useRef({phase:e,activity:t,substate:s,emotion:n,ticks:i,toolStatus:r});u.current={phase:e,activity:t,substate:s,emotion:n,ticks:i,toolStatus:r};const h=g.useRef(a);h.current=a;const d=g.useRef(l);d.current=l,g.useEffect(()=>{const f=c.current;if(!f)return;const m=f.getContext("2d");if(!m)return;const b=Math.min(1.5,window.devicePixelRatio||1),_=k5(performance.now());_.ticks=u.current.ticks,_.toolStatus=u.current.toolStatus;const v=(R,E)=>{_.clip&&_.clipAt===E&&jy[R]<jy[_.clip]||(_.clip=R,_.clipAt=E,_.clipMs=g5(Ry[R]))};let y=0,w=0;const x=()=>{const R=f.getBoundingClientRect();f.width=Math.max(1,Math.round(R.width*b)),f.height=Math.max(1,Math.round(R.height*b))};x();const S=new ResizeObserver(x);S.observe(f);const N=R=>{if(y=window.requestAnimationFrame(N),R-w<33)return;w=R;const E=R/1e3,M=u.current;_.rawLevel=Math.max(0,Math.min(1,h.current()||0));const F=_.level;_.level=i5(_.level,_.rawLevel);const B=r5(F,_.level);if(B&&M.phase==="listening"&&(_.micro=B,_.microAt=R,_.microUntil=R+280,_.quietSince=R),M.phase!==_.phase&&(_.phase=M.phase,_.phaseAt=R,_.quietSince=R),M.ticks!==_.ticks&&(_.ticks=M.ticks,_.lastEventAt=R,_.quietSince=R,_.micro="tick",_.microAt=R,_.microUntil=R+260,v("tool-start",R)),M.toolStatus!==_.toolStatus){const ae=M.toolStatus.toLowerCase();_.toolStatus=M.toolStatus,ae==="completed"||ae==="success"?v("tool-done",R):ae==="failed"||ae==="error"||ae==="cancelled"?v("tool-fail",R):ae&&v("tool-start",R)}const k=M.activity!=="none"||M.phase==="thinking"||M.phase==="speaking";if(R>=_.nextBlinkAt&&(_.nextBlinkAt=R+fk(),dk.includes(_.mood)||(_.blinkAt=R,_.clip||v("blink-pop",R))),R>=_.nextBeatAt){_.nextBeatAt=R+pk;const ae=G3(R-_.quietSince,Math.random,{busy:k});ae==="rest"?(_.drowsy=!0,_.sleepTarget=1):ae&&(_.life=ae.mood,_.lifeUntil=R+ae.durationMs)}if(M.phase==="listening"&&R>=_.nextSaccadeAt&&(_.nextSaccadeAt=R+a5(),!_.life)){const ae=l5();_.life=ae.mood,_.lifeUntil=R+ae.durationMs,_.lastEventAt=R}_.life&&R>_.lifeUntil&&(_.life=null),_.drowsy&&_.sleepTarget>0&&_.sleep>=.995&&(_.drowsy=!1,_.resting=!0),_.sleep+=Math.max(-1,Math.min(1,(_.sleepTarget-_.sleep)*.06)),(_.resting||_.drowsy)&&k&&(_.resting=!1,_.drowsy=!1,_.sleepTarget=0,_.wakeUntil=R+z3,v("wake",R)),M.activity==="asking"?_.askingSince||(_.askingSince=R):_.askingSince=0;const A=R-_.lastEventAt;if(k&&A>K3&&R-_.microAt>gk){const ae=A>Q3?"stretch":Math.random()<.7?"flick":"tick";_.micro=ae,_.microAt=R,_.microUntil=R+(ae==="stretch"?1400:420)}_.micro&&R>_.microUntil&&(_.micro=null);const D=W3({phase:M.phase,activity:M.activity,emotion:M.emotion,life:_.life,resting:_.resting,drowsy:_.drowsy,waking:R<_.wakeUntil,askingMs:_.askingSince?R-_.askingSince:0});if(D!==_.mood){const ae=Ty({kind:"mood",from:_.mood,to:D});_.moodAt=R;try{d.current?.(D)}catch{}D!=="sleep"&&(_.resting||_.drowsy)&&(_.resting=!1,_.drowsy=!1,_.sleepTarget=0,_.sleep=0),M.phase!=="speaking"&&(_.warmthUntil=R+Sy),_.mood=D,ae&&v(ae,R)}const H=M.phase==="thinking"&&D==="focus"?1:0;_.dots+=(H-_.dots)*.14,_.dots<.002?_.dots=0:_.dots>.998&&(_.dots=1);const I=Math.max(0,Math.min(1,(_.warmthUntil-R)/Sy)),z=(R-_.phaseAt)/1e3,T=U3(D,_.level,z,{resting:_.resting,warmth:I}),O=mk(z);if(O!==_.thinkStage&&(_.thinkStage=O,D==="focus")){const ae=Ty({kind:"think",stage:O});ae&&v(ae,R)}const K=O3(R-_.blinkAt),U=ky({mood:D,right:!1,blink:K,t:E,level:_.level,expr:T,sleep:_.sleep,substate:M.substate}),re=ky({mood:D,right:!0,blink:K,t:E,level:_.level,expr:T,sleep:_.sleep,substate:M.substate}),J=f.width,Y=f.height;m.setTransform(1,0,0,1,0,0),m.clearRect(0,0,J,Y),m.scale(b,b);const _e=J/b,xe=Y/b,fe=Math.max(.5,Math.min(3.2,Math.min(_e/260,xe/260)));let et=c5(D,{level:_.level,breath:["idle","drowsy","sleep","curious","asking","working"].includes(D)?Math.sin(E*Math.PI*2/2)*6:0,substate:M.substate});if(_.clip)if(R-_.clipAt>=_.clipMs)_.clip=null;else{const ae=y5(Ry[_.clip],R-_.clipAt);ae?et=b5(et,ae):_.clip=null}const Oe=_.clip??"";f.dataset.clip!==Oe&&(Oe?f.dataset.clip=Oe:delete f.dataset.clip),f.dataset.substate!==M.substate&&(f.dataset.substate=M.substate);const tt=_.dots>=.5?"1":"";(f.dataset.dots??"")!==tt&&(tt?f.dataset.dots=tt:delete f.dataset.dots);for(let ae=0;ae<4;ae++){const be=.008333333333333333,Be=ul(_.ball.r,_.ballV.r,et.r,be,22,.6);_.ball.r=Be.x,_.ballV.r=Be.v;const W=ul(_.ball.sx,_.ballV.sx,et.sx,be,30,.5);_.ball.sx=W.x,_.ballV.sx=W.v;const Se=ul(_.ball.sy,_.ballV.sy,et.sy,be,30,.5);_.ball.sy=Se.x,_.ballV.sy=Se.v;const He=ul(_.ball.dy,_.ballV.dy,et.dy,be,24,.62);_.ball.dy=He.x,_.ballV.dy=He.v;const q=ul(_.ballRot,_.ballRotV,et.rot,be,18,.5);_.ballRot=q.x,_.ballRotV=q.v}const Pe=_.ball.r*fe,Le=_e/2,Ee=xe/2+_.ball.dy*fe,Ae=["idle","drowsy","sleep","curious","asking","working","calm"].includes(D)?Math.sin(E*Math.PI*2/2)*6*fe:0;let Ze=0,me=0;_.micro==="tick"?me=2.5*fe:_.micro==="flick"?(Ze=4*fe,me=1.5*fe):_.micro==="stretch"&&(me=-5*fe),m.save(),m.globalAlpha=1-_.dots,m.translate(Le,Ee),m.rotate(_.ballRot*Math.PI/180),m.scale(_.ball.sx,_.ball.sy),m.beginPath(),m.arc(0,0,Pe,0,Math.PI*2),m.shadowColor="rgba(15,20,26,0.30)",m.shadowBlur=30*fe,m.shadowOffsetY=12*fe;const Ye=m.createRadialGradient(-Pe*.32,-Pe*.42,Pe*.06,0,0,Pe*1.02);Ye.addColorStop(0,"#31383f"),Ye.addColorStop(.52,"#171b20"),Ye.addColorStop(1,"#0a0c0f"),m.fillStyle=Ye,m.fill(),m.shadowBlur=0,m.shadowOffsetY=0,m.strokeStyle="rgba(255,255,255,0.12)",m.lineWidth=Math.max(1,1.6*fe),m.stroke(),m.restore(),m.save(),m.translate(Le,Ee),m.rotate(_.ballRot*Math.PI/180),m.beginPath(),m.ellipse(0,0,Pe*_.ball.sx,Pe*_.ball.sy,0,0,Math.PI*2),m.clip(),m.translate(-Le,-Ee);const de=w5({mood:D,elapsed:z,substate:M.substate}),lt=S5({mood:D,left:U,right:re,gaze:de,ballR:_.ball.r,k:fe});for(const ae of[U,re]){const Be=(ae===re?1:-1)===1?lt.right:lt.left,W=Le+Be.x+Ze,Se=Ee+Be.y+Ae*.4+me;m.save(),m.translate(W,Se),m.rotate(ae.rot*Math.PI/180),m.globalAlpha=Math.max(0,Math.min(1,ae.alpha))*(1-_.dots);const He=D==="error"?"248,113,113":D==="sad"?"190,190,200":"255,255,255";if(m.shadowColor=`rgba(${He},${Math.min(.5,.16+_.level*.2+I*.14)})`,m.shadowBlur=Math.min(ae.w*fe*.45,ae.glow*fe),m.fillStyle=`rgba(${He},1)`,m.strokeStyle=`rgba(${He},1)`,ae.shape==="x"){const q=Be.w/2,Z=Math.sin(E*24)*ae.jitter*fe;m.lineWidth=6*fe,m.beginPath(),m.moveTo(-q+Z,-q),m.lineTo(q+Z,q),m.moveTo(q+Z,-q),m.lineTo(-q+Z,q),m.stroke()}else if(ae.shape==="arc"){const q=Be.w/2;m.lineWidth=6*fe,m.beginPath(),ae.arc==="happy"?m.arc(0,q,q,Math.PI,Math.PI*2):m.arc(0,-q,q,0,Math.PI),m.stroke()}else{const q=Be.w,Z=Math.max(1,ae.h*fe*ae.yScale),ge=Math.min(q,Z)/2,P=ae.jitter?Math.sin(E*24)*ae.jitter*fe:0,le=ae.jitter?Math.cos(E*19)*ae.jitter*fe:0,je=m.createLinearGradient(0,-Z/2,0,Z/2);je.addColorStop(0,`rgba(${He},1)`),je.addColorStop(1,`rgba(${He},0.94)`),m.fillStyle=je,m.beginPath(),typeof m.roundRect=="function"?m.roundRect(-q/2+P,-Z/2+le,q,Z,ge):m.ellipse(0,0,q/2,Z/2,0,0,Math.PI*2),m.fill(),m.shadowBlur=0,m.lineWidth=1,m.strokeStyle=`rgba(${He},0.5)`,m.stroke()}m.restore()}if(m.restore(),_.dots>0){const ae=Pe*.56,be=Pe*.08,Be=Se=>Math.sin(E*Math.PI*2/1.4+Se*Math.PI*2),W=[{x:Le-ae,r:Pe*.17,tone:"109,114,120",offset:-.12},{x:Le,r:Pe*.24,tone:"13,15,18",offset:0},{x:Le+ae,r:Pe*.19,tone:"125,131,139",offset:.12}];m.save();for(const Se of W){const He=Ee+Be(Se.offset)*be,q=Se.r*(1+.04*Be(Se.offset+.25));m.globalAlpha=_.dots,m.fillStyle=`rgb(${Se.tone})`,m.shadowColor=`rgba(${Se.tone},0.28)`,m.shadowBlur=q*.9,m.beginPath(),m.arc(Se.x,He,q,0,Math.PI*2),m.fill()}m.restore()}};return y=window.requestAnimationFrame(N),()=>{window.cancelAnimationFrame(y),S.disconnect()}},[]);const p=g.useRef(e);return p.current!==e&&(p.current=e),o.jsx("canvas",{ref:c,className:"tus-face-canvas","aria-hidden":"true"})}const hl={ratio:2.6,minRms:.004,hangMs:700,rise:.3,fall:.35};function E5(e=0){return{floor:e,lastVoiceAt:-1/0,prev:Number.NaN,speech:!1}}function N5(e,t,s,n={}){const i=n.hangMs??hl.hangMs,r=e.prev;if(!Number.isFinite(t))return e.speech=s-e.lastVoiceAt<=i,e.speech;const a=Math.max(0,t);e.prev=a;const l=n.ratio??hl.ratio,c=Math.max(n.minRms??hl.minRms,e.floor*l),u=a>c,h=Number.isFinite(r)&&Math.abs(a-r)<=Math.max(.0015,a*.08);if(!u||h){const d=a<e.floor?n.fall??hl.fall:n.rise??hl.rise;e.floor=e.floor===0?a:e.floor+(a-e.floor)*d}return u&&(e.lastVoiceAt=s),e.speech=s-e.lastVoiceAt<=i,e.speech}const R5="modulepreload",j5=function(e){return"/"+e},My={},T5=function(t,s,n){let i=Promise.resolve();if(s&&s.length>0){document.getElementsByTagName("link");const a=document.querySelector("meta[property=csp-nonce]"),l=a?.nonce||a?.getAttribute("nonce");i=Promise.allSettled(s.map(c=>{if(c=j5(c),c in My)return;My[c]=!0;const u=c.endsWith(".css"),h=u?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${c}"]${h}`))return;const d=document.createElement("link");if(d.rel=u?"stylesheet":R5,u||(d.as="script"),d.crossOrigin="",d.href=c,l&&d.setAttribute("nonce",l),document.head.appendChild(d),u)return new Promise((p,f)=>{d.addEventListener("load",p),d.addEventListener("error",()=>f(new Error(`Unable to preload CSS for ${c}`)))})}))}function r(a){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=a,window.dispatchEvent(l),!l.defaultPrevented)throw a}return i.then(a=>{for(const l of a||[])l.status==="rejected"&&r(l.reason);return t().catch(r)})},A5=.5,M5=.35,dl=512,fl=64,D5=700;function Dy(){return{prob:-1,speech:!1,lastVoiceAt:-1/0,frames:0}}function I5(e,t,s,n=D5){return e.prob=t,t>=A5?e.lastVoiceAt=s:t<M5&&(e.lastVoiceAt=s-n-1),e.speech=s-e.lastVoiceAt<=n,e.frames+=1,e.speech}class P5{#e=null;#l=null;#i=null;#s=new Float32Array(fl);#o=[];#t=!1;#n=[];#c=0;st=Dy();get ready(){return this.#e!==null}async load(t){if(this.#e)return!0;try{const s=await T5(()=>import("./ort.wasm.bundle.min-kEi4lvn9.js"),[]);return s.env.wasm.numThreads=1,s.env.logLevel="error",this.#l=s,this.#e=await s.InferenceSession.create(t,{executionProviders:["wasm"],graphOptimizationLevel:"all"}),this.#i=new s.Tensor("float32",new Float32Array(2*1*128),[2,1,128]),!0}catch(s){return console.warn("[vad] silero unavailable, falling back to the level gate:",s?.message??s),this.#e=null,this.#l=null,!1}}reset(){this.st=Dy(),this.#s.fill(0),this.#o=[],this.#n=[],this.#l&&this.#i&&(this.#i=new this.#l.Tensor("float32",new Float32Array(2*1*128),[2,1,128]))}push(t){if(this.#e){for(let s=0;s<t.length;s++)this.#o.push(t[s]);for(;this.#o.length>=dl;){const s=new Float32Array(this.#o.splice(0,dl));this.#n.push(s),this.#n.length>2&&this.#n.shift()}this.#h()}}async#h(){if(!(this.#t||!this.#e||!this.#l||!this.#i)){this.#t=!0;try{for(;this.#n.length&&this.#e;){const t=this.#n.shift(),s=new Float32Array(fl+dl);s.set(this.#s,0),s.set(t,fl);const n=await this.#e.run({input:new this.#l.Tensor("float32",s,[1,fl+dl]),state:this.#i,sr:new this.#l.Tensor("int64",BigInt64Array.from([16000n]),[])});this.#i=n.stateN,this.#s.set(t.subarray(dl-fl));const i=Number(n.output.data[0]);I5(this.st,Number.isFinite(i)?i:0,Date.now())}}catch(t){++this.#c>=3&&(console.warn("[vad] silero run failed, falling back to the level gate:",t?.message??t),this.#e=null,this.#n=[])}finally{this.#t=!1}}}}const Po=new P5,Ac={interruptMode:"voice",bargeSensitivity:60,bargeMs:300,silenceMs:1500,minChars:3,wakePhrase:"hi, Tus"},_k=[{id:"voice",label:"语音打断",hint:"说一句就能打断它(灵敏度、持续时间在设置里调)"},{id:"keyword",label:"关键词打断",hint:"要先说出你设的那句话才算打断(设置里填),比语音打断稳、不用碰屏幕"},{id:"button",label:"按键打断",hint:"只认按钮:它说话的时候麦克风关着,不识别、不抢话——外放串音、环境吵的时候用它"}],$h={bargeSensitivity:[0,100],bargeMs:[100,1e3],silenceMs:[400,4e3],minChars:[1,20]},L5=[{key:"bargeSensitivity",label:"抢话灵敏度",show:e=>`${Math.round(e)}%`,ends:["迟钝","灵敏"],hint:"越高越容易打断它(100% 最灵敏)。手机外放容易串音,串音频繁就调低一点"},{key:"bargeMs",label:"抢话持续时间",show:e=>e>=1e3?`${(e/1e3).toFixed(1)} 秒`:`${e} 毫秒`,ends:["快","稳"],hint:"要连续这么大声才算抢话"},{key:"silenceMs",label:"说完停顿",show:e=>`${(e/1e3).toFixed(1)} 秒`,ends:["快","慢"],hint:"静音这么久就算你说完了,自动把话发出去;怕被提前截断就用「按住说话」"},{key:"minChars",label:"最少字数",show:e=>e<=1?"不限制":`${e} 字`,ends:["1","20"],hint:"自动发送时少于这个字数不发送(1 = 不限制);点一下圆球是明确指令,照发。默认 3 字,挡掉语气词和噪音"}];function O5(e){const t=Math.min(100,Math.max(0,Number(e)));return .008+.075*Math.pow(1-t/100,1.2)}const Iy={aec:.55,raw:1.4},B5=1.6;function Py(e,t,s,n,i){return e>O5(n)?t>.002?s>.002?e>s*B5:e>t*(i?Iy.aec:Iy.raw):!0:!1}const Ly=600,Oy=900,vk="agentus.call",$5=Object.keys($h);function F5(e,t){const[s,n]=$h[e],i=Number(t);return Number.isFinite(i)?Math.min(n,Math.max(s,i)):Ac[e]}function w_(e){const t={...Ac};if(!e||typeof e!="object")return t;const s=e;_k.some(n=>n.id===s.interruptMode)&&(t.interruptMode=s.interruptMode);for(const n of $5)n in s&&(t[n]=F5(n,s[n]));return"wakePhrase"in s&&(t.wakePhrase=yk(s.wakePhrase)),t}function yk(e){const t=[...String(e??"").replace(/\s+/g," ").trim()].slice(0,z5).join("");return t.replace(/[\s\p{P}\p{S}]/gu,"")===""?"":t}const z5=24;function vm(e,t){const s=i=>String(i??"").toLowerCase().replace(/[\s\p{P}\p{S}]/gu,""),n=s(t);return n?s(e).includes(n):!1}const H5=2500;function U5(e){return!(e.muted||!e.heard||!e.phrase||!e.graceOpen||!(e.heardAgoMs<=H5)||e.own&&vm(e.own,e.phrase)||!vm(e.heard,e.phrase)||e.playRms>=0&&!e.evidence)}function W5(){try{return w_(JSON.parse(localStorage.getItem(vk)??"null"))}catch{return{...Ac}}}let bc=W5();const ym=new Set;function bk(e){bc=e;try{localStorage.setItem(vk,JSON.stringify(bc))}catch{}for(const t of ym)t()}async function wk(e){const t=w_({...bc,...e});bk(t);try{const s=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({call:t})});return s.ok?(xk((await s.json()).call),""):(await s.json().catch(()=>({}))).error??`save failed (${s.status})`}catch(s){return String(s?.message??s)}}function xk(e){const t=w_(e);Object.keys(Ac).every(s=>t[s]===bc[s])||bk(t)}async function K5(){try{const e=await fetch("/api/settings",{credentials:"same-origin"});if(!e.ok)return;xk((await e.json()).call)}catch{}}function q5(){return[g.useSyncExternalStore(t=>(ym.add(t),()=>ym.delete(t)),()=>bc),t=>void wk(t)]}const V5={connecting:{core:[125,145,200],glow:"rgba(125,145,200,0.30)"},listening:{core:[56,189,248],glow:"rgba(56,189,248,0.34)"},thinking:{core:[167,139,250],glow:"rgba(167,139,250,0.30)"},speaking:{core:[251,191,36],glow:"rgba(251,191,36,0.32)"},error:{core:[248,113,113],glow:"rgba(248,113,113,0.30)"}},Lo={connecting:"正在接通…",listening:"在听你说",thinking:"思考中…",speaking:"正在回答",error:"出错了"},Y5=.01,By=120,G5=/^(?:Stopped waiting for another Hermes process on this session\. Your message was not processed\.|⏳? ?Another Hermes process kept this session busy too long[\s\S]*not processed[\s\S]*)$/;function $y(e){return[...e].length}const J5=1,X5=4e3,Z5=15e3,Q5=45e3,eI=3e3,Fy="agentus.call.caption",zy="agentus.call.voiceMode",Hy="agentus.call.brief",tI=g.memo(function({kind:t,who:s,text:n,current:i}){return n.trim()?o.jsxs("div",{className:`call-hm ${t}${i?" current":""}`,children:[s?o.jsx("span",{className:"call-hm-who",children:s}):null,t==="agent"||t==="user"?o.jsx(S3,{text:n}):o.jsx("span",{children:n})]}):null});function Uy(e){switch(e.kind){case"user":return{kind:"user",who:e.from?`来自「${e.from.title}」`:"你",text:e.text};case"agent":return{kind:"agent",who:"它",text:e.text};case"meta":return{kind:"meta",who:"",text:e.text};case"tool":return{kind:"tool",who:"",text:`${e.title||e.kind2||"工具"}${e.status?` · ${e.status}`:""}`};case"plan":return{kind:"tool",who:"",text:`计划:${e.items.map(t=>t.content).join(";")}`};case"thought":return{kind:"tool",who:"",text:e.text};case"note":return{kind:"meta",who:"",text:e.text};case"approval":return{kind:"meta",who:"",text:`审批:${e.title}${e.decision?e.decision.outcome==="selected"?"(已答)":"(已取消)":""}`};case"project-skills":return{kind:"meta",who:"",text:e.text};case"turn-usage":return{kind:"meta",who:"",text:uk(e)}}}function sI({sessionId:e,onClose:t,onKeyboard:s,renderTranscript:n,tus:i=!1,pending:r=0}){const[a]=_o(),l=dd(),[c,u]=g.useState("connecting"),[h,d]=g.useState(!1),[p,f]=g.useState(""),[m,b]=g.useState(""),[_,v]=g.useState(0),[y,w]=g.useState(!1),[x,S]=g.useState(""),[N]=q5(),[R,E]=g.useState(!1),[M,F]=g.useState(!1),[B,k]=g.useState(!0),A=g.useRef(null),[D,H]=g.useState(()=>{try{return localStorage.getItem(Fy)==="1"}catch{return!1}}),I=g.useRef(D);I.current=D;const[z,T]=g.useState(()=>{try{return localStorage.getItem(Hy)!=="0"}catch{return!0}}),O=g.useRef(z);O.current=z;const K=()=>{const L=!z;T(L);try{localStorage.setItem(Hy,L?"1":"0")}catch{}L||Dt.current.turnEnded()},[U,re]=g.useState(()=>{try{return localStorage.getItem(zy)==="1"}catch{return!1}}),J=()=>{const L=!U;re(L);try{localStorage.setItem(zy,L?"1":"0")}catch{}},[Y,_e]=g.useState(!0),xe=g.useRef(null),[fe,et]=g.useState(""),[Oe,tt]=g.useState(null),Pe=i?{...N,interruptMode:"keyword"}:N,Le=g.useRef(Pe);Le.current=Pe;const Ee=L=>{wk(L).then(et)},Ae=g.useRef(null),Ze=g.useRef(null),me=g.useRef("connecting");me.current=c;const Ye=g.useRef(0),de=g.useRef([]),lt=g.useRef(0),ae=g.useRef(0),be=g.useRef(E5()),Be=g.useRef(0),W=g.useRef(0),Se=g.useRef(0),He=g.useRef(0),q=g.useRef(0),Z=g.useRef(""),ge=g.useRef(null),P=g.useRef(-1),le=g.useRef(0),je=g.useRef(""),Ie=g.useRef(0),Ge=g.useRef(0),ot=g.useRef(!1),dt=g.useRef(!1),[at,Q]=g.useState(!1),ke=g.useRef(!1),Ne=g.useRef([]),$e=g.useRef(!1),gt=g.useRef(0),St=g.useRef(""),Jt=g.useRef(""),dn=g.useRef(""),ye=g.useRef(!1),Dt=g.useRef(new wy),Me=g.useRef(new Set),[kt,Nn]=g.useState(""),Ts=g.useRef(Promise.resolve()),Rn=async L=>{const ce=Ts.current;let X=()=>{};Ts.current=new Promise(ue=>{X=ue}),await ce;try{await L()}finally{X()}},Wn=g.useRef(""),jn=g.useRef(0),zs=g.useRef(""),Rr=g.useRef(!1),$i=g.useRef(!1),wo=g.useRef(Date.now()),Ot=g.useRef(""),ws=g.useRef(!0),ds=g.useRef(!1);ds.current=h;const Tn=g.useSyncExternalStore(ee.subscribe,ee.getSnapshot),jr=g.useMemo(()=>typeof window<"u"&&window.matchMedia?.("(prefers-reduced-motion: reduce)").matches,[]);g.useEffect(()=>{let L=!1;a0(!0);const ce=ue=>{fetch("/api/notify/presence",{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({sessionId:ue?e:null,visible:ue,call:ue})}).catch(()=>{})};return ce(!0),(async()=>{try{const ue=ee.getSnapshot(),Fe=ue.active?.info.id===e?ue.active:void 0;if(pe.cancel(),Fe?.busy){if(L)return;ke.current=!0,$i.current=!0,St.current="",u("thinking");return}const Ut=[...Fe?.msgs??[]].reverse().find(Wt=>Wt.kind==="agent");if(zs.current=Ut?.key??"",Le.current.interruptMode!=="button"){const Wt=await pe.start(a,e);if(L)return;if(!Wt)throw new Error(pe.getSnapshot().error||"无法打开麦克风");u("listening"),Po.load("/vad/silero_vad.onnx").then(Bt=>{L||!Bt||(Po.reset(),pe.setVadTap(_i=>Po.push(_i)))})}else u("listening")}catch(ue){if(L)return;f(String(ue?.message??ue)),u("error")}})(),()=>{L=!0,pe.setVadTap(null),Po.reset(),ws.current=!1,Ft.stop(),pe.cancel(),a0(!1),ce(!1)}},[]),g.useEffect(()=>{if(!_)return;const L=window.setTimeout(()=>v(0),2600);return()=>window.clearTimeout(L)},[_]),g.useEffect(()=>{const L=window.setInterval(()=>{const ce=Le.current,X=pe.getSnapshot(),ue=pe.levelRms(),Fe=sR();P.current=Fe,Fe>.004&&He.current<=.004&&(Se.current=Date.now()),Fe>.004&&(q.current=Date.now()),He.current=Fe;const Ut=`${X.text||""} ${X.interim||""}`.trim();if(Ut!==je.current&&(je.current=Ut,le.current=Date.now()),X.error&&me.current==="listening"){f(X.error),u("error");return}if(ce.interruptMode==="button"&&(me.current==="speaking"||me.current==="thinking")){X.status!=="idle"&&!ds.current&&pe.stop(),Be.current=0,Ge.current=0;return}if(ce.interruptMode==="keyword"&&(me.current==="speaking"||me.current==="thinking")){ds.current||pe.setRelay(!0),Be.current=0;const Bt=Date.now(),_i=Ut,Ir=Math.max(W.current,Se.current),Ui=Bt-Ir>Ly&&Bt-Ie.current>Oy,Ba=Py(ue,Fe,Ge.current,ce.bargeSensitivity,i0()),Ss=U5({heard:_i,own:Z.current,heardAgoMs:Bt-le.current,phrase:ce.wakePhrase,graceOpen:Ui,evidence:Ba,playRms:Fe,muted:ds.current});if(Ss){Ie.current=Bt,pe.resetText(),Dr();return}Fe>.002&&!Ba&&!Ss&&(Ge.current=Ge.current*.88+ue*.12);return}const Wt=me.current==="listening"?Po.ready?Po.st.speech:N5(be.current,ue,Date.now()):!1;if(me.current==="listening"&&(Wt||ue>Y5)&&(ae.current=Date.now()),me.current==="listening"){b((X.text+(X.interim?` ${X.interim}`:"")).trim());const Bt=(X.text||X.interim).trim();if(ce.interruptMode==="keyword"&&!ds.current&&Bt&&vm(Bt,ce.wakePhrase)){pe.resetText(),v(Date.now()),ae.current=0;return}const _i=Date.now()-ae.current;Bt&&!ds.current&&!ot.current&&!dt.current&&$y(Bt)>=ce.minChars&&_i>ce.silenceMs&&!ke.current&&(ke.current=!0,u("thinking"),b(Bt),f(""),zs.current=Ot.current,pe.setRelay(!1),ee.send({t:"prompt",sessionId:e,text:Bt,interrupt:!0}),pe.resetText())}else if(me.current==="speaking"){const Bt=Date.now(),_i=Math.max(W.current,Se.current),Ir=Bt-_i>Ly&&Bt-Ie.current>Oy,Ui=ce.interruptMode==="voice"&&!ds.current&&Ir&&Py(ue,Fe,Ge.current,ce.bargeSensitivity,i0());Ir&&!Ui&&(Ge.current=Ge.current*.88+ue*.12),Be.current=Ui?Be.current+By:0,Be.current>=ce.bargeMs&&(Be.current=0,Ie.current=Bt,Dr())}else Be.current=0},By);return()=>window.clearInterval(L)},[e]);const rt=Tn.active?.info.id===e?Tn.active:void 0,Qe=rt?.msgs??[],Tr=Qe.map(L=>L.kind),Ar=Tr.lastIndexOf("user"),j=Tr.lastIndexOf("agent");Ot.current=j>=0?Qe[j].key??"":"";const V=j>Ar?Qe[j]:void 0,se=V?.kind==="agent"?V.text:"",ze=V?V.at??0:0,Je=V?.key??"",Ct=Tr.lastIndexOf("meta"),Ue=Ct>Ar&&Qe[Ct]?.kind==="meta"?Qe[Ct].text:"",st=!!rt?.busy,Lc=Qe.reduce((L,ce)=>L+(ce.kind==="tool"?1:0),0),mi=Qe.length?Qe[Qe.length-1]:void 0,gi=(()=>{for(let L=Qe.length-1;L>=0;L--){const ce=Qe[L];if(ce.kind==="tool")return ce}})(),Sd=q3({busy:st||c==="thinking",pending:r,newestKind:mi?.kind}),Fi=mi?.kind==="tool"?mi:void 0,xo=Y3({busy:st||c==="thinking",pending:r,newestKind:mi?.kind,newestToolStatus:Fi?.status,newestToolTitle:Fi?.title,newestToolKind:Fi?.kind2}),[kd,Oc]=g.useState(null),Da=(()=>{const L=t5(se);return L.length?L[L.length-1]:Z3(Bh(se))})(),So=()=>{const L=me.current==="speaking"?o0():pe.level();return Number.isFinite(L)?Math.max(0,Math.min(1,L)):0},Mr=()=>{for(const L of Ne.current.slice(0,J5))Ft.prefetch(L,a)};g.useEffect(()=>{const L=me.current;if(L==="connecting"||L==="error"||!Je||Je===zs.current||Je&&Je===Wn.current||jn.current&&ze&&ze<=jn.current)return;if(!Rr.current&&(Rr.current=!0,!zs.current&&!$i.current&&!ke.current&&Je&&Date.now()-wo.current<eI)){zs.current=Je;return}if(G5.test(se.trim())){f("刚才那句没被处理(这个会话正被另一个 Hermes 进程占用),再说一次即可。"),As(!1);return}if(se.trim()&&(Dt.current.answerStarted(),Nn("")),Je!==St.current){const Fe=St.current;St.current=Je,Jt.current&&!ye.current&&dn.current===Fe&&(Ne.current.push(Jt.current),ye.current=!0,Mr()),gt.current=0}const{done:ce,tail:X}=E3(n5(Bh(se)));Jt.current=X,X&&(dn.current=Je),ye.current=!1;const ue=ce.slice(gt.current);ue.length&&(gt.current=ce.length,Ne.current.push(...ue),S(Fe=>`${Fe}${Fe?" ":""}${ue.join(" ")}`),me.current!=="speaking"&&u("speaking"),Mr()),!st&&X&>.current>=ce.length&&(gt.current=ce.length+1,ye.current=!0,Ne.current.push(X),S(Fe=>`${Fe}${Fe?" ":""}${X}`)),!st&&me.current==="thinking"&&!Ne.current.length&&ce.length===0&&!X&&(Ue&&f(Ue),As(!1))},[se,Je,st,Ue]);const[Js,Kn]=g.useState(""),qn=g.useRef(0),fs=g.useRef(0),[Bc,ko]=g.useState(!1),$c=(L=[880,1180])=>{try{const ce=window.AudioContext??window.webkitAudioContext;if(!ce)return;const X=new ce;L.forEach((ue,Fe)=>{const Ut=X.createOscillator(),Wt=X.createGain();Ut.type="sine",Ut.frequency.value=ue,Wt.gain.setValueAtTime(1e-4,X.currentTime+Fe*.16),Wt.gain.exponentialRampToValueAtTime(.16,X.currentTime+Fe*.16+.02),Wt.gain.exponentialRampToValueAtTime(1e-4,X.currentTime+Fe*.16+.15),Ut.connect(Wt).connect(X.destination),Ut.start(X.currentTime+Fe*.16),Ut.stop(X.currentTime+Fe*.16+.18)}),window.setTimeout(()=>void X.close().catch(()=>{}),800)}catch{}};g.useEffect(()=>{const L=()=>{Wu();const ue=Lh();(ue.ctxState==="running"||ue.ctxState==="unavailable")&&X()},ce=["pointerdown","touchstart","keydown","click"],X=()=>{for(const ue of ce)window.removeEventListener(ue,L,!0)};for(const ue of ce)window.addEventListener(ue,L,{capture:!0});return L(),X},[]),g.useEffect(()=>{let L=!0;return zl().then(()=>{L&&ko(!0)}),()=>{L=!1}},[]),g.useEffect(()=>{const L=(st||c==="thinking")&&c!=="speaking"&&Bc&&d3();mm(L),window.__callBed=L?{playing:!0,level:.1}:{playing:!1,level:0}},[st,c,Bc]),g.useEffect(()=>()=>{mm(!1,0)},[]);const Ia=g.useRef(r);g.useEffect(()=>{const L=r>Ia.current,ce=r===0;if(Ia.current=r,L){qn.current=Date.now(),fs.current=0,Kn(r===1?"有个操作等你批准":`有 ${r} 个操作等你批准`),$c(),An({text:r===1?"有个操作等你批准":`有 ${r} 个操作等你批准`,kind:"approval"});return}ce&&(qn.current=0,fs.current=0,Kn(""))},[r]),g.useEffect(()=>{if(r<=0||!qn.current)return;const L=window.__approveRemindMs??[6e4,3e5],ce=window.setInterval(()=>{const X=Date.now()-qn.current;for(;fs.current<L.length&&X>=L[fs.current];){fs.current+=1;const ue=L[fs.current-1],Ut=`审批还挂着,${ue<6e4?`${Math.round(ue/1e3)} 秒`:ue>=3e5?"已经五分钟":`${Math.round(ue/6e4)} 分钟`}了`;Kn(Ut),$c(),An({text:Ut,kind:"approval"})}},1e3);return()=>window.clearInterval(ce)},[r]);const An=async L=>{if(!ws.current||L.kind!=="approval"&&!O.current)return;const ce=me.current;ce!=="thinking"&&ce!=="listening"||dt.current||ot.current||m||Z.current||$e.current||(Nn(L.text),await Rn(async()=>{await Ft.speak(L.text,"call",a).catch(()=>{})}))},Co=g.useRef(!1);g.useEffect(()=>{const L=Date.now();st&&!Co.current?(Dt.current=new wy,Me.current=new Set,Dt.current.turnStarted(L),Nn("")):!st&&Co.current&&(Dt.current.turnEnded(),Nn("")),Co.current=st},[st]),g.useEffect(()=>{if(!st||!O.current)return;const L=Qe[Qe.length-1];if(!L||Me.current.has(L.key))return;const ce=Date.now(),X=Dt.current;let ue=null;if(L.kind==="tool")Me.current.add(L.key),ue=X.tool(ce,L.title||L.kind2||"工具");else if(L.kind==="plan"){Me.current.add(L.key);const Fe=L.items.filter(Ut=>Ut.status==="completed").length;ue=X.plan(ce,Fe,L.items.length)}ue&&An(ue)},[Qe,st,z]),g.useEffect(()=>{if(!st||!z)return;const L=window.setInterval(()=>{const ce=Date.now(),X=Dt.current.thinking(ce)??Dt.current.tick(ce);X&&An(X)},500);return()=>window.clearInterval(L)},[st,z]),g.useEffect(()=>{me.current!=="speaking"||$e.current||($e.current=!0,(async()=>{try{for(;ws.current&&Ne.current.length&&me.current!=="error";){const L=Ne.current.shift();Mr(),W.current=Date.now(),Ge.current=0,Z.current=L;try{await Rn(()=>new Promise((ce,X)=>{ge.current=()=>X(new Error("clip abandoned")),Ft.speak(L,"call",a).then(ce,X)}))}catch{}finally{ge.current=null,Z.current=""}if(!ws.current||me.current!=="speaking")break}}catch{}finally{$e.current=!1,ws.current&&me.current==="speaking"&&!Ne.current.length&&!st&&As(!1)}})())},[c,x,st]);const Pa=g.useRef(!1);Pa.current=st;const zi=g.useRef(l);zi.current=l;const Vn=g.useRef(0);g.useEffect(()=>{const L=window.setInterval(()=>{const ce=me.current;if(ce!=="speaking"&&ce!=="thinking"){Vn.current=0;return}if(me.current==="speaking"&&zi.current.speaking){const ue=P.current>=0,Fe=Date.now()-Math.max(q.current,W.current);if(ue?Fe>Z5:Fe>Q5){Vn.current=0,f(zi.current.error||(ue?"这一句卡住了(合成或播放没有响应),已跳过它继续往下念。":"这一句卡住了,已跳过它继续往下念。")),ge.current?.(),Ft.stop();return}}if(!(!$e.current&&!Ne.current.length&&!zi.current.speaking&&!Pa.current)){Vn.current=0;return}if(!Vn.current){Vn.current=Date.now();return}Date.now()-Vn.current<X5||(Vn.current=0,zi.current.error&&f(zi.current.error),As(!1))},1e3);return()=>window.clearInterval(L)},[e]);const Cd=()=>{ws.current&&v_()},Dr=async()=>{Eo(),await As(!1)},Eo=()=>{Wn.current=Ot.current||St.current,jn.current=Date.now(),Ft.stop();const L=ee.getSnapshot().sessions.find(ue=>ue.id===e)?.status==="running";L&&ee.send({t:"cancel",sessionId:e});const ce=me.current;(L||$e.current||ce==="speaking"||ce==="thinking")&&Cd(),Ne.current=[],gt.current=0,$e.current=!1,ke.current=!1,Jt.current="",dn.current="",ye.current=!0,q.current=Date.now(),pe.setRelay(!1),pe.resetText()},As=async L=>{if(ws.current&&(L&&Ft.stop(),dt.current=!1,Q(!1),Ne.current=[],gt.current=0,$e.current=!1,ke.current=!1,Jt.current="",dn.current="",ye.current=!0,q.current=Date.now(),u("listening"),S(""),b(""),ae.current=Date.now(),pe.setRelay(!1),pe.resetText(),Le.current.interruptMode!=="button"))try{const ce=pe.getSnapshot();if(ce.status==="transcribing"&&pe.cancel(),ce.status==="idle"||ce.status==="error"||ce.status==="transcribing"){if(!await pe.start(a,e))throw new Error(pe.getSnapshot().error||"无法打开麦克风");pe.setRelay(!0)}else pe.setRelay(!0)}catch(ce){f(String(ce?.message??ce)),u("error")}},La=()=>{ws.current=!1,Ft.stop(),pe.cancel(),t()},ne=async()=>{if(h){d(!1);try{await pe.start(a,e),pe.setRelay(me.current==="listening")}catch(L){f(String(L?.message??L))}return}d(!0),pe.stop()},C=async()=>{const L=me.current;if(Le.current.interruptMode==="button"){dt.current?We():await Re();return}if(L==="listening"){const ce=pe.getSnapshot(),X=(ce.text||ce.interim).trim();X&&(ke.current=!0,u("thinking"),f(""),zs.current=Ot.current,pe.setRelay(!1),ee.send({t:"prompt",sessionId:e,text:X,interrupt:!0}),pe.resetText());return}if(L==="speaking"){await Dr();return}if(L==="thinking"){await Dr();return}L==="error"&&await As(!1)},$=async()=>{if(!(ot.current||!ws.current)){ot.current=!0,w(!0),dt.current=!1,Q(!1),Eo(),u("listening"),S(""),b(""),ae.current=Date.now();try{const L=pe.getSnapshot();L.status==="idle"||L.status==="error"||L.status==="transcribing"?await pe.start(a,e):pe.resetText(),pe.setRelay(!0)}catch(L){f(String(L?.message??L)),u("error")}}},te=()=>{const L=pe.getSnapshot(),ce=(L.text||L.interim).trim();ce&&(ke.current=!0,u("thinking"),b(ce),f(""),dt.current=!1,Q(!1),zs.current=Ot.current,Le.current.interruptMode==="button"?pe.cancel():pe.setRelay(!1),ee.send({t:"prompt",sessionId:e,text:ce,interrupt:!0}),pe.resetText())},oe=()=>{if(!ot.current)return;ot.current=!1,w(!1);const L=pe.getSnapshot();if(!(L.text||L.interim).trim()){if(pe.resetText(),Le.current.interruptMode==="button"){pe.cancel(),As(!1);return}pe.setRelay(!0),u("listening");return}te()},Re=async()=>{if(ws.current){ot.current=!1,w(!1),Eo(),dt.current=!0,Q(!0),u("listening"),S(""),b(""),f(""),ae.current=Date.now();try{if(pe.cancel(),!await pe.start(a,e))throw new Error(pe.getSnapshot().error||"无法打开麦克风");pe.setRelay(!0)}catch(L){dt.current=!1,Q(!1),f(String(L?.message??L)),u("error")}}},We=()=>{dt.current=!1,Q(!1);const L=pe.getSnapshot();if(!(L.text||L.interim).trim()){pe.cancel(),As(!1);return}te()},Ke=g.useRef(null),ft=g.useRef({pttStart:$,pttEnd:oe,backToListening:As});ft.current={pttStart:$,pttEnd:oe,backToListening:As},g.useEffect(()=>{const L=ue=>{const Fe=ue;return!Fe||!Fe.tagName?!1:Fe.tagName==="INPUT"||Fe.tagName==="TEXTAREA"||Fe.tagName==="SELECT"||Fe.isContentEditable},ce=ue=>{ue.code!=="Space"||ue.repeat||ue.metaKey||ue.ctrlKey||ue.altKey||!ws.current||L(ue.target)||(ue.preventDefault(),!(Le.current.interruptMode==="button"&&dt.current)&&(Ke.current||(Ke.current={at:Date.now()},ft.current.pttStart())))},X=ue=>{if(ue.code!=="Space"||!Ke.current)return;const Fe=Date.now()-Ke.current.at;if(Ke.current=null,ue.preventDefault(),Fe<150){ot.current=!1,w(!1),pe.cancel(),ft.current.backToListening(!1);return}ft.current.pttEnd()};return window.addEventListener("keydown",ce),window.addEventListener("keyup",X),()=>{window.removeEventListener("keydown",ce),window.removeEventListener("keyup",X)}},[]),g.useEffect(()=>{const L=Ae.current,ce=Ze.current;if(!L||!ce)return;const X=L.getContext("2d"),ue=ce.getContext("2d");if(!X||!ue||i)return;const Fe=Math.min(2,window.devicePixelRatio||1),Ut=()=>I.current?1.25:Fe,Wt=new Float32Array(96);let Bt=0,_i=0;const Ir=()=>{const Ss=Ut(),vi=L.getBoundingClientRect();L.width=Math.max(1,Math.round(vi.width*Ss)),L.height=Math.max(1,Math.round(vi.height*Ss));const Ds=ce.getBoundingClientRect();ce.width=Math.max(1,Math.round(Ds.width*Ss)),ce.height=Math.max(1,Math.round(Ds.height*Ss))};Ir();const Ui=new ResizeObserver(Ir);Ui.observe(L),Ui.observe(ce);const Ba=Ss=>{if(Bt=window.requestAnimationFrame(Ba),I.current&&_i++&1)return;const vi=me.current,Ds=V5[vi],$a=vi==="listening"?pe.level():vi==="speaking"?Math.max(0,o0()):-1,zc=$a<0?-1:$a;Ye.current=zc<0?Ye.current*.9:zc>Ye.current?Ye.current+(zc-Ye.current)*.45:Ye.current*.88+zc*.12;const Hc=Math.min(1,Ye.current),F_=1+.05*Math.sin(Ss/1150),fn=$a<0?.22+.1*Math.sin(Ss/1150):.2+.8*Hc,Wi=Ut(),Uc=L.width/Wi,Wc=L.height/Wi;X.setTransform(Wi,0,0,Wi,0,0),X.clearRect(0,0,Uc,Wc);const Yn=Uc/2,Gn=Wc/2,MC=Math.min(Uc,Wc)*(I.current?.52:.33),jo=Math.sin(Ss/900)*(3+14*fn),To=Math.cos(Ss/1410)*(2+10*fn),DC=1+.05*Math.sin(Ss/770)*(.4+fn),Et=MC*(.86+.34*fn)*F_*DC,Mn=`${Ds.core[0]},${Ds.core[1]},${Ds.core[2]}`,Pr=de.current,Fa=Ss;($a>=0?Hc>.4&&Fa-lt.current>380:Fa-lt.current>1300)&&vi!=="connecting"&&(lt.current=Fa,Pr.push({born:Fa,strength:$a>=0?.6+.4*Hc:.4}),Pr.length>6&&Pr.shift()),X.globalCompositeOperation="lighter";for(let _t=0;_t<3;_t++){const ms=Ss/(2100+_t*900)+_t*Math.PI*2/3,ut=Et*(.1+.11*_t)*(.8+.5*fn),Nt=Yn+Math.cos(ms)*ut+jo*.8,Lr=Gn+Math.sin(ms)*ut+To*.8,Or=Et*Math.min(1.22+.16*_t,.98*(Math.min(Uc,Wc)/2)/Et)*(.95+.2*fn),Kc=X.createRadialGradient(Nt,Lr,0,Nt,Lr,Or);Kc.addColorStop(0,`rgba(${Mn},0.20)`),Kc.addColorStop(.45,`rgba(${Mn},0.09)`),Kc.addColorStop(1,"rgba(0,0,0,0)"),X.fillStyle=Kc,X.beginPath(),X.arc(Nt,Lr,Or,0,Math.PI*2),X.fill()}const za=X.createRadialGradient(Yn+jo,Gn+To,Et*.82,Yn+jo,Gn+To,Et*1.42);za.addColorStop(0,`rgba(${Mn},0)`),za.addColorStop(.22,`rgba(${Mn},${.42-.16*fn})`),za.addColorStop(.6,`rgba(${Mn},${.14-.06*fn})`),za.addColorStop(1,"rgba(0,0,0,0)"),X.fillStyle=za,X.beginPath(),X.arc(Yn+jo,Gn+To,Et*1.42,0,Math.PI*2),X.fill();for(let _t=Pr.length-1;_t>=0;_t--){const ms=(Fa-Pr[_t].born)/(jr?2600:1400);if(ms>=1){Pr.splice(_t,1);continue}const ut=Et*(1+ms*1.05)*F_;X.beginPath(),X.arc(Yn+jo*.3,Gn+To*.3,ut,0,Math.PI*2),X.strokeStyle=`rgba(${Mn},${(1-ms)*.5*Pr[_t].strength})`,X.lineWidth=1.2+2.4*(1-ms),X.stroke()}const Ha=Yn+jo*.7,Ua=Gn+To*.7,Ao=X.createRadialGradient(Ha-Et*.18,Ua-Et*.18,Et*.05,Ha,Ua,Et);Ao.addColorStop(0,`rgba(255,255,255,${.92-.18*fn})`),Ao.addColorStop(.3,`rgba(${Mn},0.92)`),Ao.addColorStop(.66,`rgba(${Mn},0.62)`),Ao.addColorStop(.88,`rgba(${Mn},0.28)`),Ao.addColorStop(1,`rgba(${Mn},0)`),X.fillStyle=Ao,X.beginPath(),X.arc(Ha,Ua,Et,0,Math.PI*2),X.fill(),X.globalCompositeOperation="source-over",X.beginPath(),X.arc(Ha,Ua,Et*.97,0,Math.PI*2),X.strokeStyle="rgba(255,255,255,0.10)",X.lineWidth=1.4,X.stroke(),X.beginPath(),X.arc(Ha,Ua,Et*.985,-2.5,-.35),X.strokeStyle=`rgba(255,255,255,${.42-.12*fn})`,X.lineWidth=2,X.lineCap="round",X.stroke();const jd=X.createRadialGradient(Yn-Et*.34,Gn-Et*.42,0,Yn-Et*.34,Gn-Et*.42,Et*.55);if(jd.addColorStop(0,"rgba(255,255,255,0.40)"),jd.addColorStop(1,"rgba(255,255,255,0)"),X.fillStyle=jd,X.beginPath(),X.arc(Yn-Et*.34,Gn-Et*.42,Et*.55,0,Math.PI*2),X.fill(),!jr){X.globalCompositeOperation="lighter";for(let _t=0;_t<3;_t++){const ms=Ss/(1150+_t*520)+_t*2.1,ut=Et*(1.08+.11*_t),Nt=Yn+Math.cos(ms)*ut,Lr=Gn+Math.sin(ms)*ut*.95,Or=X.createRadialGradient(Nt,Lr,0,Nt,Lr,9);Or.addColorStop(0,`rgba(255,255,255,${.5+.4*fn})`),Or.addColorStop(.35,`rgba(${Mn},${.4+.3*fn})`),Or.addColorStop(1,"rgba(0,0,0,0)"),X.fillStyle=Or,X.beginPath(),X.arc(Nt,Lr,9,0,Math.PI*2),X.fill()}}X.globalCompositeOperation="source-over";const Td=ce.width/Wi,Ki=ce.height/Wi;ue.setTransform(Wi,0,0,Wi,0,0),ue.clearRect(0,0,Td,Ki);let Ad=!1;if(vi==="listening"){const _t=pe.wave(),ms=Math.max(1,Math.floor(_t.length/Wt.length));for(let ut=0,Nt=0;ut<Wt.length;ut++,Nt+=ms)Wt[ut]=_t[Nt]??0;Ad=!0}else vi==="speaking"&&(Ad=nR(Wt));if(Ad){const _t=ut=>({x:ut/(Wt.length-1)*Td,y:Ki/2-Wt[ut]*Ki*1.35});ue.beginPath();for(let ut=0;ut<Wt.length;ut++){const Nt=_t(ut);ut?ue.lineTo(Nt.x,Nt.y):ue.moveTo(Nt.x,Nt.y)}for(let ut=Wt.length-1;ut>=0;ut--){const Nt=_t(ut);ue.lineTo(Nt.x,Ki/2-(Nt.y-Ki/2)*.35)}ue.closePath();const ms=ue.createLinearGradient(0,0,0,Ki);ms.addColorStop(0,`rgba(${Ds.core[0]},${Ds.core[1]},${Ds.core[2]},0.05)`),ms.addColorStop(.5,`rgba(${Ds.core[0]},${Ds.core[1]},${Ds.core[2]},0.30)`),ms.addColorStop(1,`rgba(${Ds.core[0]},${Ds.core[1]},${Ds.core[2]},0.05)`),ue.fillStyle=ms,ue.fill(),ue.beginPath();for(let ut=0;ut<Wt.length;ut++){const Nt=_t(ut);ut?ue.lineTo(Nt.x,Nt.y):ue.moveTo(Nt.x,Nt.y)}ue.strokeStyle=`rgba(255,255,255,${.55+.3*Hc})`,ue.lineWidth=1.7,ue.lineJoin="round",ue.lineCap="round",ue.stroke()}else ue.beginPath(),ue.moveTo(0,Ki/2),ue.lineTo(Td,Ki/2),ue.strokeStyle="rgba(255,255,255,0.07)",ue.lineWidth=1,ue.stroke()};return Bt=window.requestAnimationFrame(Ba),()=>{window.cancelAnimationFrame(Bt),Ui.disconnect()}},[jr,i]);const xs=Qe.length?Uy(Qe[Qe.length-1]).text:"";g.useEffect(()=>{if(!M||!B)return;const L=A.current;L&&(L.scrollTop=L.scrollHeight)},[M,B,Qe.length,xs]);const Ms=()=>{const L=A.current;L&&k(L.scrollHeight-L.scrollTop-L.clientHeight<24)},Hi=()=>{const L=A.current;L&&(L.scrollTop=L.scrollHeight),k(!0)},Oa=()=>{M||k(!0),F(!M)},ps=()=>{const L=!D;H(L),L&&_e(!0);try{localStorage.setItem(Fy,L?"1":"0")}catch{}},Fc=()=>{const L=xe.current;L&&_e(L.scrollHeight-L.scrollTop-L.clientHeight<28)},jC=()=>{const L=xe.current;L&&(L.scrollTop=L.scrollHeight),_e(!0)};g.useEffect(()=>{if(!D||!Y)return;const L=xe.current;L&&(L.scrollTop=L.scrollHeight)},[D,Y,Qe.length,m,x,c]);const Ed=$y(m),B_=c==="listening"&&Ed>0&&Ed<N.minChars,Nd=N.interruptMode==="keyword"?`唤醒词「${N.wakePhrase||"未设置"}」${m?` · 听到:${m.slice(-18)}`:""}`:"",No=c==="listening"&&_?`听到「${N.wakePhrase}」了`:c==="listening"?m?Ed<N.minChars?`太短了(少于 ${N.minChars} 字,不会自动发送)——继续说,或点一下圆球直接发送`:"点一下直接发送,或说完停一下":h?"麦克风已静音":N.interruptMode==="button"?at?"正在听你说,说完点「结束」":"点「开始说话」,或按住圆球/空格说话":Nd||"说点什么…":c==="speaking"?N.interruptMode==="voice"?"说一句就能打断它,点圆球也可以":N.interruptMode==="keyword"?`${Nd} · 说唤醒词打断`:"点「打断」就开口,说完再点「结束」":c==="thinking"?N.interruptMode==="keyword"?`${Nd} · 说唤醒词打断`:N.interruptMode==="button"?"点「打断」就开口,说完再点「结束」":"点一下停止它":"",Ro=c==="speaking"||c==="thinking",TC=c==="listening"&&!y&&m.trim().length>0,Rd=o.jsxs("button",{type:"button",className:`call-floor is-ptt${y?" on":""}`,onPointerDown:L=>{L.preventDefault();try{L.currentTarget.setPointerCapture(L.pointerId)}catch{}$()},onPointerUp:L=>{L.preventDefault(),oe()},onPointerCancel:()=>oe(),onLostPointerCapture:()=>oe(),onContextMenu:L=>L.preventDefault(),"aria-pressed":y,title:"按住说话,松开就发出去;按住的时候不会自动发送","aria-label":y?"松开发送":"按住说话",children:[o.jsx(ji,{size:17}),o.jsx("span",{children:y?"松开发送":"按住说话"})]}),AC=_k.filter(L=>L.id!=="voice"||U||N.interruptMode==="voice"),$_=o.jsx("div",{className:"call-modes",role:"group","aria-label":"打断方式","data-mode":N.interruptMode,children:AC.map(L=>o.jsx("button",{type:"button",className:`call-mode-btn ${N.interruptMode===L.id?"on":""}`,"aria-pressed":N.interruptMode===L.id,title:L.hint,onClick:()=>Ee({interruptMode:L.id}),children:L.label},L.id))});return cc.createPortal(o.jsxs("div",{className:"call-mode","data-phase":c,"data-mood":i?Da:void 0,"data-face":i?kd??void 0:void 0,"data-substate":i?xo:void 0,"data-caption":D,"data-tus":i?"true":"false",role:"dialog","aria-modal":"true","aria-label":i?"Tus 模式通话":"语音通话",children:[o.jsx("button",{type:"button",className:"call-gear",onClick:()=>E(!0),"aria-label":"通话设置",title:"通话设置",children:o.jsx(Tc,{size:18})}),o.jsx("button",{type:"button",className:`call-cc-btn${D?" on":""}`,onClick:ps,"aria-pressed":D,"aria-label":D?"收起聊天记录":"显示聊天记录",title:D?"收起聊天记录":"显示聊天记录",children:o.jsx(jN,{size:18})}),!D&&!i?o.jsxs("div",{className:"call-head",children:[o.jsx("span",{className:"call-title",children:Lo[c]}),o.jsx("span",{className:"call-sub",children:h?"麦克风已静音":"免提 · 语音通话"}),$_]}):null,Js&&!D?o.jsx("p",{className:"call-cue call-cue-stage call-approve","data-cue":Js,children:Js}):null,!Js&&kt&&!D?o.jsx("p",{className:"call-cue call-cue-stage","data-cue":kt,children:kt}):null,o.jsx("button",{type:"button",className:"call-orb",onClick:()=>void C(),"aria-label":`${Lo[c]} — ${No||"点击切换"}`,title:No,children:o.jsx("canvas",{ref:Ae,className:"call-orb-canvas"})}),i?o.jsxs("div",{className:"call-tus-face","data-substate":xo,children:[o.jsx(C5,{phase:c,activity:Sd,substate:xo,emotion:Da,ticks:Lc,toolStatus:gi?.status??"",getLevel:So,onMood:Oc}),o.jsxs("div",{className:"tus-face-foot",children:[o.jsx("span",{className:"tus-face-state",children:Lo[c]}),i&&!N.wakePhrase?o.jsx("span",{className:"tus-face-warn",title:"Tus 模式固定用关键词打断;没设唤醒词时只有按住说话能抢话筒",children:"Tus 模式用关键词打断 · 还没设唤醒词"}):null]})]}):null,D||i?o.jsxs("div",{className:"call-cc",children:[o.jsxs("div",{className:"call-cc-head",children:[o.jsxs("button",{type:"button",className:"call-cc-state",onClick:()=>void C(),title:No||"点击切换","aria-label":`${Lo[c]} — ${No||"点击切换"}`,children:[o.jsx("span",{className:"call-cc-dot","aria-hidden":"true"}),Lo[c]]}),$_,o.jsxs("span",{className:"call-cc-n",children:[Qe.length," 条"]})]}),o.jsx("div",{className:"call-cc-list",ref:xe,onScroll:Fc,role:"log","aria-live":"polite",children:o.jsxs("div",{className:"call-cc-inner",children:[n&&rt?n({msgs:Qe,sid:e,backend:rt.info.backend,busy:!!rt.busy,base:rt.info.workspace||rt.info.cwd,speaking:c==="speaking"}):null,c==="listening"&&m?o.jsxs("div",{className:"msg user live",children:[o.jsx("div",{className:"role",children:"YOU"}),o.jsx("div",{className:"bubble",children:m})]}):null,Js&&!p?o.jsx("p",{className:"call-cue call-approve","data-cue":Js,children:Js}):null,!Js&&kt&&!p?o.jsx("p",{className:"call-cue","data-cue":kt,children:kt}):null,p?o.jsx("p",{className:"call-err",children:p}):null,!p&&l.error?o.jsx("p",{className:"call-err",children:l.error}):null,!p&&l.note?o.jsx("p",{className:"call-note",children:l.note}):null,!m&&!Qe.length||B_?o.jsx("p",{className:"call-hint",children:No}):null]})}),Y?null:o.jsx("button",{type:"button",className:"call-cc-latest",onClick:jC,children:"回到最新 ↓"}),o.jsx("div",{className:`call-floor-row${Ro||N.interruptMode==="button"?"":" single"}`,children:N.interruptMode==="button"?o.jsxs(o.Fragment,{children:[o.jsxs("button",{type:"button",className:`call-floor is-take${at?" on":""}`,onClick:()=>{at?We():Re()},title:Ro?"停下它,接着说你的":at?"说完了,再点一下就发出去":"点一下开始说,说完再点一下发送;不会自己发出去","aria-label":Ro?"打断":at?"结束":"开始说话","aria-pressed":at,children:[Ro?o.jsx(xh,{size:17}):at?o.jsx(Sh,{size:17}):o.jsx(ji,{size:17}),o.jsx("span",{children:Ro?"打断":at?"结束":"开始说话"})]}),Rd]}):Ro?o.jsxs(o.Fragment,{children:[o.jsxs("button",{type:"button",className:"call-floor is-take",onClick:()=>void Dr(),title:"停下它,接着说你的","aria-label":"打断",children:[o.jsx(xh,{size:17}),o.jsx("span",{children:"打断"})]}),Rd]}):TC?o.jsxs("button",{type:"button",className:"call-floor is-done",onClick:()=>te(),title:"说完了就把这句发出去,不用等它判断停顿","aria-label":"说完了",children:[o.jsx(Sh,{size:17}),o.jsx("span",{children:"说完了"})]}):Rd})]}):o.jsxs(o.Fragment,{children:[o.jsxs("div",{className:"call-lines",children:[m?o.jsx("p",{className:"call-heard",children:m}):null,x?o.jsx("p",{className:"call-reply",children:x}):null,p?o.jsx("p",{className:"call-err",children:p}):null,!p&&l.error?o.jsx("p",{className:"call-err",children:l.error}):null,!p&&l.note?o.jsx("p",{className:"call-note",children:l.note}):null,!m&&!x&&!p||B_?o.jsx("p",{className:"call-hint",children:No}):null]}),o.jsxs("div",{className:"call-hist","data-open":M,children:[o.jsxs("button",{type:"button",className:"call-hist-bar",onClick:Oa,"aria-expanded":M,"aria-label":M?"收起历史聊天记录":"翻阅历史聊天记录",title:M?"收起":"翻阅历史聊天记录",children:[o.jsx(RN,{size:15}),o.jsx("span",{className:"call-hist-title",children:"历史记录"}),o.jsxs("span",{className:"call-hist-n",children:[Qe.length," 条"]}),!M&&xs?o.jsx("span",{className:"call-hist-peek",children:xs.slice(0,60)}):null,o.jsx("span",{className:"call-hist-chev","aria-hidden":"true",children:o.jsx(ya,{size:14})})]}),M?o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"call-hist-list",ref:A,onScroll:Ms,children:Qe.map((L,ce)=>{const X=Uy(L);return o.jsx(tI,{kind:X.kind,who:X.who,text:X.text,current:ce===Qe.length-1&&c==="speaking"},L.key)})}),B?null:o.jsx("button",{type:"button",className:"call-hist-back",onClick:Hi,children:"回到最新 ↓"})]}):null]})]}),o.jsx("canvas",{ref:Ze,className:"call-wave","aria-hidden":"true"}),o.jsxs("div",{className:"call-controls",children:[o.jsx("button",{type:"button",className:`call-btn ${h?"on":""}`,onClick:()=>void ne(),"aria-pressed":h,title:h?"打开麦克风":"静音麦克风",children:h?o.jsx(bN,{size:18}):o.jsx(ji,{size:18})}),o.jsx("button",{type:"button",className:"call-btn hangup",onClick:La,title:"挂断","aria-label":"挂断",children:o.jsx(yN,{size:20})}),o.jsx("button",{type:"button",className:"call-btn",onClick:s,title:"改用键盘","aria-label":"改用键盘",children:o.jsx(wN,{size:18})})]}),R?o.jsx("div",{className:"call-sheet",role:"dialog","aria-label":"通话设置",children:o.jsxs("div",{className:"call-sheet-card",children:[o.jsxs("div",{className:"call-sheet-head",children:[o.jsx("span",{children:"通话设置"}),o.jsx("button",{type:"button",className:"call-sheet-x",onClick:()=>E(!1),"aria-label":"关闭设置",children:o.jsx(En,{size:16})})]}),o.jsx("p",{className:"call-sheet-note",children:fe?`保存失败:${fe}(已在本机生效)`:"调整立即生效,并保存到服务器(换设备也一样)"}),N.interruptMode==="button"?o.jsx("p",{className:"call-sheet-warn",children:"现在是「按键打断」:它说话的时候麦克风是关的 —— 不识别、不抢话,只在你说完之后才重新打开。 所以灵敏度和持续时间这会儿不起作用(切回「语音打断」就恢复)。"}):null,Pe.interruptMode==="keyword"?o.jsxs("label",{className:"call-knob",children:[o.jsxs("span",{className:"call-knob-top",children:[o.jsx("span",{className:"call-knob-name",children:"唤醒词"}),o.jsx("span",{className:"call-knob-val",children:(Oe??N.wakePhrase)||"未设置"})]}),o.jsx("input",{type:"text",value:Oe??N.wakePhrase,placeholder:"例如:小灵 / hey agent",onChange:L=>tt(L.target.value),onBlur:()=>{Oe!==null&&(Ee({wakePhrase:yk(Oe)}),tt(null))},onKeyDown:L=>{L.key==="Enter"&&L.currentTarget.blur()},"aria-label":"唤醒词"}),o.jsx("span",{className:"call-knob-hint",children:"只有听到这句话才抢话(关键词打断)。空着 = 这个模式不生效,不会误触发。 灵敏度在这一档仍然有用:它决定「多大声才算压过外放的回声」;持续时间不起作用。"})]}):null,o.jsx("p",{className:`call-sheet-echo ${cf().echoCancellation===!1?"bad":""}`,children:cf().echoCancellation===!1?"回声消除没生效:这台设备只给了原始麦克风。外放时它容易把自己当成你——用「按键打断」,或者戴耳机":cf().echoCancellation===!0?"回声消除:已生效(抢话要盖过你听到的那个声音,不会自己打断自己)":"回声消除:这台设备没报告(浏览器语音路径)——抢话按「比回复更响」判断"}),o.jsxs("label",{className:"call-check",children:[o.jsx("input",{type:"checkbox",checked:z,onChange:K,"aria-label":"干活期间报进度"}),o.jsxs("span",{children:[o.jsx("span",{className:"call-check-name",children:"干活期间报进度"}),o.jsx("span",{className:"call-check-hint",children:"它去跑工具、深思考、等计划推进的时候,隔一阵用一句话告诉你还在干什么(「我查一下」 「在跑 terminal」「第 2 步,共 5 步」)。答案一开始读就闭嘴,一轮最多三句。"})]})]}),o.jsxs("label",{className:"call-check",children:[o.jsx("input",{type:"checkbox",checked:U,onChange:J,"aria-label":"在通话页显示语音打断"}),o.jsxs("span",{children:[o.jsx("span",{className:"call-check-name",children:"在通话页显示「语音打断」"}),o.jsx("span",{className:"call-check-hint",children:"默认收起:它说一句就能打断,外放、嘈杂的房间里也最容易自己打断自己。 勾上之后它回到通话页那一排,阈值和判定跟以前一样。"})]})]}),L5.map(L=>o.jsxs("label",{className:`call-knob ${L.key==="bargeMs"?N.interruptMode!=="voice"?"off":"":N.interruptMode==="button"?"off":""}`,children:[o.jsxs("span",{className:"call-knob-top",children:[o.jsx("span",{className:"call-knob-name",children:L.label}),o.jsx("span",{className:"call-knob-val",children:L.show(N[L.key])})]}),o.jsx("input",{type:"range",min:$h[L.key][0],max:$h[L.key][1],step:L.key==="bargeSensitivity"?5:L.key==="silenceMs"?100:L.key==="minChars"?1:50,value:N[L.key],onChange:ce=>Ee({[L.key]:Number(ce.target.value)}),"aria-label":L.label,disabled:N.interruptMode!=="voice"&&L.key.startsWith("barge")}),o.jsxs("span",{className:"call-knob-ends",children:[o.jsx("span",{children:L.ends[0]}),o.jsx("span",{children:L.ends[1]})]}),o.jsx("span",{className:"call-knob-hint",children:L.hint})]},L.key)),o.jsxs("div",{className:"call-sheet-foot",children:[o.jsx("button",{type:"button",className:"call-sheet-btn",onClick:()=>Ee(Ac),children:"恢复默认"}),o.jsx("button",{type:"button",className:"call-sheet-btn primary",onClick:()=>E(!1),children:"完成"})]})]})}):null,o.jsx("p",{className:"sr-only","aria-live":"polite",children:Lo[c]})]}),document.body)}function x_({size:e=22}){const t=tk();return o.jsx("img",{className:"brand-mark",src:t?"/icons/agentus-mark-inverse.svg":"/icons/agentus-mark.svg",width:e,height:Math.round(e*(880/1484)),alt:"","aria-hidden":"true",draggable:!1})}const nI=12e4;function iI(e){if(!e.visible)return!1;const t=e.idleMs??nI;return e.now-e.lastInputAt<t}const rI=6;function S_({value:e,onChange:t}){const[s,n]=g.useState(null),[i,r]=g.useState(e),[a,l]=g.useState(!1),[c,u]=g.useState(""),h=async f=>{const m=f?`?path=${encodeURIComponent(f)}`:"",b=await fetch(`/api/fs/dirs${m}`),_=await b.json().catch(()=>({}));if(!b.ok)throw new Error(_.error??`HTTP ${b.status}`);return _},d=async(f,m=!1)=>{l(!0),u("");try{const b=await h(f);if(n(b),!m)return;const _=b.recent?.[0]||b.path;if(!_)return;t(_),_!==b.path&&n(await h(_))}catch(b){u(String(b?.message??b))}finally{l(!1)}};g.useEffect(()=>{d(e||"",!e)},[]),g.useEffect(()=>{r(e)},[e]);const p=f=>{const m=f.trim();m&&(t(m),d(m))};return o.jsxs("div",{className:"wp",children:[o.jsxs("div",{className:"wp-bar",children:[o.jsx("input",{className:"wp-path",value:i,spellCheck:!1,onChange:f=>r(f.target.value),onKeyDown:f=>{f.key==="Enter"&&(f.preventDefault(),p(i))},placeholder:"~/project — Enter 选中","aria-label":"选中的工作目录"}),o.jsx("button",{className:"wp-use",disabled:a||!i.trim()||i.trim()===e,title:"选中这个目录",onClick:()=>p(i),children:"选中"}),o.jsx("button",{className:"icon-btn",title:"home","aria-label":"home",disabled:a,onClick:()=>void d(s?.home??""),children:o.jsx(_S,{size:14})}),o.jsx("button",{className:"icon-btn",title:"上一级目录","aria-label":"上一级目录",disabled:a||!s?.parent,onClick:()=>s?.parent&&void d(s.parent),children:o.jsx(yS,{size:14})})]}),s?.recent?.length?o.jsx("div",{className:"wp-recent",children:s.recent.slice(0,rI).map(f=>o.jsx("button",{className:`wp-chip ${e===f?"sel":""}`,title:`选中 ${f}`,onClick:()=>p(f),children:f.split("/").filter(Boolean).pop()??f},f))}):null,o.jsxs("div",{className:"wp-list",role:"listbox","aria-label":"folders",children:[a&&!s?o.jsx("div",{className:"wp-note",children:"loading…"}):null,c?o.jsx("div",{className:"wp-note err",children:c}):null,s?.entries.map(f=>o.jsxs("div",{role:"option","aria-selected":e===f.path,className:`wp-row ${e===f.path?"sel":""}`,onClick:()=>t(f.path),title:`选中 ${f.path}`,children:[o.jsx(uo,{size:13}),o.jsx("span",{className:"wp-name",children:f.name}),o.jsx("button",{className:"wp-enter",title:`进入 ${f.name}`,"aria-label":`进入 ${f.name}`,onClick:m=>{m.stopPropagation(),d(f.path)},children:o.jsx(an,{size:13})})]},f.path)),s&&!s.entries.length&&!c?o.jsx("div",{className:"wp-note",children:"这里没有子目录 —— 点这一行就是选中它"}):null,s?.truncated?o.jsx("div",{className:"wp-note",children:"只列出前 300 项"}):null]})]})}function oI(e){const t=e.split("/").filter(Boolean);return t.length?t[t.length-1]:e}function aI({value:e,onChange:t,locked:s=!1,testId:n="ws-pill"}){const[i,r]=g.useState(!1),[a,l]=g.useState(e);return o.jsxs(o.Fragment,{children:[o.jsxs("button",{type:"button",className:`ws-pill ${e?"":"empty"} ${s?"locked":""}`,"data-testid":n,"aria-label":"工作空间",title:e||"选择这个会话在哪个目录里跑",disabled:s,onClick:()=>{l(e),r(!0)},children:[o.jsx(uo,{size:14}),o.jsx("span",{className:"ws-pill-name",children:e?oI(e):"选择工作空间"}),s?null:o.jsx(ya,{size:11})]}),i?o.jsx("div",{className:"modal-bg ws-modal-bg",onClick:()=>r(!1),children:o.jsxs("div",{className:"modal ws-modal",onClick:c=>c.stopPropagation(),children:[o.jsx("h3",{children:"工作空间"}),o.jsx(S_,{value:a,onChange:c=>{t(c),r(!1)}}),o.jsx("div",{className:"row",children:o.jsx("button",{className:"cancel",onClick:()=>r(!1),children:"取消"})})]})}):null]})}/**
|
|
75
|
+
qodercli`,value:r?.hotwordsText??"",onChange:j=>Ot("hotwordsText",j.target.value),spellCheck:!1}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"动态热词"}),o.jsxs("div",{className:"set-pair",children:[o.jsxs("label",{className:"set-check",children:[o.jsx("input",{type:"checkbox",checked:!!r?.dynamicHotwords,onChange:j=>Ot("dynamicHotwords",j.target.checked)}),"从上下文抽取"]}),o.jsxs("label",{className:"set-check",children:["上限",o.jsx("input",{className:"set-num",type:"number",min:0,max:200,value:r?.hotwordLimit??30,onChange:j=>Ot("hotwordLimit",Number(j.target.value))})]})]})]}),o.jsxs("div",{className:"set-hot",children:[o.jsx("span",{className:"set-hot-title",children:f?`下次识别携带 ${f.words.length} 个热词(固定 ${f.fixed} / 动态 ${f.dynamic}),上下文 ${f.contextTurns??0} 轮`:"…"}),o.jsxs("div",{className:"set-hot-list",children:[(f?.words??[]).slice(0,40).map(j=>o.jsxs("span",{className:`set-chip ${j.origin}`,title:`${j.origin} · 权重 ${j.weight}`,children:[j.word,j.weight>=5?o.jsx("b",{children:j.weight===50?"50":j.weight}):null]},`${j.origin}-${j.word}`)),f&&!f.words.length?o.jsx("span",{className:"set-hint",children:"还没有热词:写几个固定词,或先聊两句再回来看动态抽取。"}):null]})]})]}),o.jsxs("section",{className:"set-card",id:"set-summary","data-setgroup":"voice",children:[o.jsx("h3",{children:"语音总结(消息喇叭长按)"}),o.jsxs("p",{className:"set-hint",children:[o.jsx("b",{children:"长按"}),"任意一条消息旁边的喇叭(电脑上右键)→「语音播报总结」:把这一条压成几十秒能听完的一段话再念出来。 适合那种一屏表格、或者很长的输出 —— 通勤时听完就能知道结论。"]}),o.jsxs("p",{className:"set-hint",children:["它",o.jsx("b",{children:"不经过 agent"}),",也不带会话历史:只把",o.jsx("b",{children:"这一条消息"}),"加下面这段指令,发一次",o.jsx("code",{children:"chat/completions"}),",拿回一段话交给同一个 TTS 念。 消息本身就短于字数上限时",o.jsx("b",{children:"直接念原文"}),",不花一次模型调用。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"启用"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{type:"checkbox",checked:at?.enabled??!0,onChange:j=>void kt({enabled:j.target.checked})}),o.jsx("span",{className:"set-hint",children:at?.enabled??!0?"已启用:长按菜单里会出现「语音播报总结」":"已关闭:长按只出菜单,没有这一项"})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"用会话自己的模型"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{type:"checkbox",checked:at?.followSession??!0,onChange:j=>void kt({followSession:j.target.checked})}),o.jsx("span",{className:"set-hint",children:at?.followSession??!0?"已开启:跟这个会话当前选的 provider 和模型走 —— 你在用 DeepSeek,这笔就记在 DeepSeek 上":"已关闭:改用下面那个模型,走「语音」里配的 DashScope 端点"})]})]}),o.jsxs("p",{className:"set-hint",children:["端点与 key ",o.jsx("b",{children:"不在这里配第二份"}),":驾驶舱读 agent 自己的家 —— ",o.jsx("code",{children:"config.yaml"})," 里的",o.jsx("code",{children:"providers.<id>"}),"(本机的 ",o.jsx("code",{children:"lab"})," 就是),或那几家的 key (",o.jsx("code",{children:"~/.hermes/.env"})," 的 ",o.jsx("code",{children:"DEEPSEEK_API_KEY"}),"、",o.jsx("code",{children:"OPENROUTER_API_KEY"})," 等)。 只认 OpenAI 兼容的 ",o.jsx("code",{children:"/v1/chat/completions"}),";Anthropic Messages / Bedrock / Vertex 这类形状解析不出来, 会退到下面那个模型,并在播报稿那一行写明「语音端点」。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"字数上限"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-num",type:"number",min:n?.summaryCharsRange?.[0]??40,max:n?.summaryCharsRange?.[1]??400,step:10,value:at?.maxChars??120,onChange:j=>Q(V=>V&&{...V,maxChars:Number(j.target.value)}),onBlur:j=>void kt({maxChars:Number(j.target.value)})}),o.jsx("span",{className:"set-hint",children:"中文大约每字 0.2–0.3 秒(120 字 ≈ 25–35 秒)。它同时也是「短于此就念原文」的阈值。"})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"备用模型(语音端点)"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-input",type:"text",placeholder:`${n?.summaryModelDefault??"qwen-flash"}(默认)`,value:at?.model??"",onChange:j=>Q(V=>V&&{...V,model:j.target.value}),onBlur:j=>void kt({model:j.target.value})}),o.jsxs("span",{className:"set-hint",children:["只在上面关掉、或会话那个 provider 解析不出来时用。",o.jsx("code",{children:n?.summaryModelDefault??"qwen-flash"})," 是默认。"]})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"超时(秒)"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-num",type:"number",min:n?.summaryTimeoutRange?.[0]??5,max:n?.summaryTimeoutRange?.[1]??60,step:5,value:at?.timeoutSec??20,onChange:j=>Q(V=>V&&{...V,timeoutSec:Number(j.target.value)}),onBlur:j=>void kt({timeoutSec:Number(j.target.value)})}),o.jsxs("span",{className:"set-hint",children:["超时就",o.jsx("b",{children:"明说失败"}),",不会拿原文冒充总结。可以重试。"]})]})]}),o.jsx("div",{className:"set-row",children:o.jsx("label",{children:"怎么改写"})}),o.jsx("textarea",{className:"set-textarea",rows:7,spellCheck:!1,value:at?.prompt??"",placeholder:"留空即用内置模板 —— 原文就在下面,能直接看、能照着改。",onChange:j=>Q(V=>V&&{...V,prompt:j.target.value}),onBlur:j=>void kt({prompt:j.target.value})}),o.jsxs("details",{className:"set-builtin",open:!(at?.prompt??"").trim(),children:[o.jsx("summary",{children:(at?.prompt??"").trim()?"内置模板(你写了自定义的,它不再生效;清空即可恢复)":"内置模板(留空时生效的就是它)"}),o.jsx("pre",{className:"set-builtin-text",children:n?.summaryPromptDefault??""})]}),o.jsxs("p",{className:"set-hint",children:[o.jsx("code",{children:"{maxChars}"})," 会被换成上面的字数上限。消息正文作为",o.jsx("b",{children:"用户那一轮"}),"单独发出去, 不带系统人设、不带历史、不带工具 —— 所以它只会总结你长按的那一条。"]}),ke?o.jsx("p",{className:"set-hint",children:ke}):null]}),o.jsxs("section",{className:"set-card",id:"set-tts","data-setgroup":"voice",children:[o.jsx("h3",{children:"语音合成(TTS)"}),o.jsxs("p",{className:"set-hint",children:["走百炼的 ",o.jsx("code",{children:"SpeechSynthesizer"}),"(合成结果由服务端取回,密钥不出服务端)。 朗读按钮仍可在下面选择走浏览器自带声音。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"模型"}),o.jsx("input",{className:"set-input",list:"tts-models",value:r?.ttsModel??"",onChange:j=>Ot("ttsModel",j.target.value),spellCheck:!1})]}),o.jsx("datalist",{id:"tts-models",children:(l?.tts??[]).map(j=>o.jsx("option",{value:j},j))}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"音色"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-input",list:"tts-voices",value:r?.ttsVoice??"",onChange:j=>Ot("ttsVoice",j.target.value),spellCheck:!1}),o.jsxs("select",{className:"set-select",value:r?.ttsFormat??"wav",onChange:j=>Ot("ttsFormat",j.target.value),children:[o.jsx("option",{value:"wav",children:"wav"}),o.jsx("option",{value:"mp3",children:"mp3"})]})]})]}),o.jsx("datalist",{id:"tts-voices",children:(n?.ttsVoices??[]).map(j=>o.jsx("option",{value:j},j))}),o.jsxs("p",{className:"set-hint",children:["默认 ",o.jsx("code",{children:"longanhuan_v3.6"})," = 龙安欢。系统音色还有 loongjielidou / loongeva / loongjohn,手填任意音色 id 也可以。"]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"试听"}),o.jsxs("div",{className:"set-pair",children:[o.jsx("input",{className:"set-input",value:H,onChange:j=>I(j.target.value)}),o.jsxs("button",{className:"set-mini",onClick:()=>void Rr(),disabled:S==="tts",children:[o.jsx(hd,{size:12})," ",S==="tts"?"合成中…":"合成并播放"]})]})]}),o.jsx("p",{className:"set-hint",children:"试听使用已保存的配置(有未保存修改会先保存)。"})]}),o.jsxs("section",{className:"set-card",id:"set-browser","data-setgroup":"voice",children:[o.jsx("h3",{children:"这个浏览器"}),o.jsx("p",{className:"set-hint",children:"听写引擎与朗读声音是本机设置:手机和电脑的麦克风/声音本来就不一样。"}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"听写引擎"}),o.jsxs("select",{className:"set-select",value:O.stt,onChange:j=>K({stt:j.target.value}),children:[o.jsx("option",{value:"auto",children:"自动(优先服务端流式)"}),o.jsx("option",{value:"stream",children:"服务端流式(百炼,带热词)"}),o.jsx("option",{value:"browser",children:"浏览器自带"}),o.jsx("option",{value:"server",children:"服务端批量上传"})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"测试识别"}),o.jsxs("div",{className:"set-pair",children:[o.jsxs("button",{className:"set-mini",onClick:$i,disabled:ws||U.status==="transcribing",children:[o.jsx(ji,{size:12})," 开麦说一句"]}),ws||U.status==="transcribing"?o.jsxs("button",{className:"set-mini",onClick:()=>pe.stop(),children:[o.jsx(xh,{size:11})," 停止"]}):null,o.jsx("span",{className:`dict-chip ${U.error?"err":""}`,style:{margin:0},children:U.error?U.error:U.status==="requesting"?"等待麦克风…":U.status==="transcribing"?"收尾中…":`${U.text}${U.interim?` ${U.interim}`:""}${U.engine?` · ${U.engine}`:""}`})]})]}),o.jsxs("div",{className:"set-row",children:[o.jsx("label",{children:"朗读"}),o.jsxs("div",{className:"set-pair",children:[o.jsxs("select",{className:"set-select",value:O.speakMode??(O.autoRead?"reply":"off"),onChange:j=>{const V=j.target.value;K({speakMode:V,autoRead:V==="reply"})},children:[o.jsx("option",{value:"off",children:"关(不自动出声)"}),o.jsx("option",{value:"reply",children:"自动朗读(念整条回复)"}),o.jsx("option",{value:"brief",children:"工作播报(念驾驶舱的一句话)"})]}),o.jsxs("label",{className:"set-check",children:[o.jsx("input",{type:"checkbox",checked:O.serverTts,onChange:j=>K({serverTts:j.target.checked})}),"用服务端声音(否则用系统声音)"]})]})]})]}),o.jsxs("div",{className:"set-actions",children:[o.jsx("button",{className:"set-save",onClick:()=>void jn(),disabled:S==="save"||!Jt,children:S==="save"?"保存中…":"保存"}),Jt?o.jsx("button",{className:"set-mini",onClick:()=>a(n?ll(n):null),children:"撤销修改"}):null]})]})]})]})}const Ca=e=>String(e).padStart(2,"0"),_3=["周日","周一","周二","周三","周四","周五","周六"];function Ai(e){const t=new Date(e);return`${Ca(t.getHours())}:${Ca(t.getMinutes())}`}function ho(e){const t=new Date(e);return`${t.getFullYear()}-${Ca(t.getMonth()+1)}-${Ca(t.getDate())} ${Ai(e)}`}function ck(e,t){const s=new Date(e),n=new Date(t),i=new Date(s.getFullYear(),s.getMonth(),s.getDate()).getTime(),r=new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime();return Math.round((r-i)/864e5)}function gm(e,t=Date.now()){const s=new Date(e),n=ck(e,t);return n<=0?Ai(e):n===1?`昨天 ${Ai(e)}`:s.getFullYear()===new Date(t).getFullYear()?`${s.getMonth()+1}月${s.getDate()}日 ${Ai(e)}`:ho(e)}function v3(e,t=Date.now()){const s=Math.floor((t-e)/1e3);if(s<0)return Ai(e);if(s<45)return"刚刚";if(s<3600)return`${Math.max(1,Math.floor(s/60))} 分钟前`;const n=new Date(e),i=ck(e,t);return i<=0?Ai(e):i===1?"昨天":i<7?_3[n.getDay()]:n.getFullYear()===new Date(t).getFullYear()?`${n.getMonth()+1}月${n.getDate()}日`:`${n.getFullYear()}-${Ca(n.getMonth()+1)}-${Ca(n.getDate())}`}const y3=6e4;function Oh(e){const t=Math.round(Math.max(0,e)/1e3);return t<60?`${t} 秒`:`${Math.floor(t/60)} 分 ${t%60} 秒`}function b3(e,t){const s=Math.max(0,t-e),n=s>=y3;return{quiet:n,gapMs:s,said:n?`agent 已经 ${Oh(s)} 没有输出了 —— 回合还在跑,可以点下面的停止`:"agent 正在工作(有输出就会重置这个计时)"}}const w3={hermes:{letter:"H",label:"Hermes",icon:"/coding-agents/hermes.png"},qoder:{letter:"Q",label:"Qoder",icon:"/coding-agents/qoder.svg"},mock:{letter:"M",label:"Mock"}};function vd(e){return w3[e]??{letter:e.slice(0,1).toUpperCase(),label:e}}function vy(e,t){const s=e.filter(n=>n.kind!=="mock"||t);return s.length?s:e}function x3(e,t){const s=[],n=/(\*\*[^*]+\*\*|`[^`]+`|\[[^\]]+\]\([^)]+\))/g;let i=0,r,a=0;for(;r=n.exec(e);){r.index>i&&s.push(e.slice(i,r.index));const l=r[0],c=`${t}-i${a++}`;if(l.startsWith("**"))s.push(o.jsx("strong",{children:l.slice(2,-2)},c));else if(l.startsWith("`"))s.push(o.jsx("code",{className:"inline",children:l.slice(1,-1)},c));else{const u=/\[([^\]]+)\]\(([^)]+)\)/.exec(l);s.push(o.jsx("a",{href:u[2],target:"_blank",rel:"noreferrer",children:u[1]},c))}i=r.index+l.length}return i<e.length&&s.push(e.slice(i)),s}function S3({text:e}){const t=e.split(/```/);return o.jsx(o.Fragment,{children:t.map((s,n)=>n%2===1?o.jsx("pre",{className:"code",children:o.jsx("code",{children:s.replace(/^[a-z]*\n/,"").replace(/\n$/,"")})},n):o.jsx(g.Fragment,{children:x3(s,`p${n}`)},n))})}function $n(e){const t=Number.isFinite(e)?Math.max(0,Math.round(e)):0;return t<1024?String(t):t<1048576?`${yy(t/1024)}k`:`${yy(t/1048576)}m`}function yy(e){return Number.isInteger(e)?String(e):e.toFixed(1)}function uk(e){if(!e.available)return"agent 未上报用量";const t=[`${$n(e.input)} in`,`${$n(e.output)} out`];if(e.thought>0&&t.push(`思考 ${$n(e.thought)}`),e.cacheRead!=null||e.cacheWrite!=null){const s=[`读 ${$n(e.cacheRead??0)}`];e.cacheWrite!=null&&s.push(`写 ${$n(e.cacheWrite)}`),t.push(`缓存 ${s.join(" / ")}`)}return e.cacheHitPercent!=null&&t.push(`命中 ${e.cacheHitPercent}%`),e.tps!=null&&e.tps>0&&t.push(`${e.tps>=100?Math.round(e.tps):e.tps.toFixed(1)} t/s 平均`),e.durationMs!=null&&e.durationMs>0&&t.push(k3(e.durationMs)),t.join(" · ")}function k3(e){const t=Math.max(1,Math.round(e/1e3));if(t<60)return`${t}s`;const s=Math.floor(t/60);return t%60?`${s}m ${t%60}s`:`${s}m`}const by=12,C3=80;function E3(e){const t=[],s=/[^。!?!?\n…]*[。!?!?\n…]+/g;let n=0;for(const l of e.matchAll(s)){const c=l[0].trim();c&&t.push(c),n=(l.index??0)+l[0].length}const i=[];for(const l of t){const c=i[i.length-1];c!==void 0&&c.length<by&&c.length+l.length<=C3?i[i.length-1]=`${c} ${l}`:i.push(l)}const r=[],a=i[i.length-1];return a!==void 0&&a.length<by&&r.push(i.pop()),{done:i,tail:[...r,e.slice(n).trim()].filter(Boolean).join(" ")}}const N3={leadingDelayMs:2e3,firstToolGapMs:5e3,minGapMs:1e4,dwellMs:9e3,maxCues:3},R3=/[\u0000-\u001f]|^\s*$/;function j3(e){const t=e.replace(/\s*·.*$/,"").trim();if(!t||R3.test(t))return"在跑一个工具";const s=t.split(/[\s/\\]+/).find(n=>n.length>0)??"";return s?`在跑 ${s.slice(0,12)}`:"在跑一个工具"}class wy{#e;#l=0;#i=!1;#s=0;#o=0;#t=null;#n=0;#c=!1;#h=!1;constructor(t={}){this.#e={...N3,...t}}turnStarted(t){this.#i=!0,this.#l=t,this.#s=0,this.#o=0,this.#t=null,this.#n=0,this.#c=!1,this.#h=!1}get turnActive(){return this.#i&&!this.#c}get cuesSpoken(){return this.#o}thinking(t){return!this.turnActive||this.#h||t-this.#l<this.#e.leadingDelayMs?null:(this.#h=!0,this.#p({text:"我查一下",kind:"leading"},t))}tool(t,s){if(!this.turnActive)return null;const n={text:j3(s),kind:"tool"};return this.#o===0&&(this.#s!==0||t-this.#l>=this.#e.firstToolGapMs)?this.#p(n,t):(this.#_(n,t),null)}plan(t,s,n){if(!this.turnActive||n<=0)return null;const i={text:`第 ${Math.min(s+1,n)} 步,共 ${n} 步`,kind:"plan"};return this.#o===0&&t-this.#l>=this.#e.firstToolGapMs?this.#p(i,t):(this.#_(i,t),null)}tick(t){if(!this.turnActive||!this.#t||t-this.#n<this.#e.dwellMs)return null;const s=this.#p(this.#t,t);return s&&(this.#t=null),s}answerStarted(){this.#c=!0,this.#t=null}turnEnded(){this.#i=!1,this.#l=0,this.#t=null,this.#c=!1}#_(t,s){this.#t?.kind==="plan"&&t.kind==="tool"||(this.#t=t,this.#n=s)}#p(t,s){return this.#o>=this.#e.maxCues?null:this.#s&&s-this.#s<this.#e.minGapMs?(this.#t?this.#n=Math.min(this.#n,s):this.#_(t,s),null):(this.#o+=1,this.#s=s,t)}}const Gi=(e,t,s,n,i,r)=>[{off:e,wid:t,lidY:s,oval:n,tilt:i,ridge:r},{off:e,wid:t,lidY:s,oval:n,tilt:i,ridge:r}],hk={neutral:Gi([0,0],.13,1,[0,0],0,[0,0,-.155,.155]),happy:Gi([.03,.03],.1305,1,[0,0],0,[-.16,.16,-.04,.12]),surprised:Gi([.03,0],.21,1,[0,0],0,[0,0,-.22,.22]),inspecting:[{off:[.04,0],wid:.27,lidY:1,oval:[0,0],tilt:0,ridge:[0,0,0,0]},{off:[.04,0],wid:.18,lidY:1,oval:[0,0],tilt:0,ridge:[0,0,0,0]}],sad:Gi([-.05,0],.13,1,[0,0],0,[-.0563,.0563,-.106,.106]),sleepy:Gi([.01,0],.13,1,[0,0],0,[-.11,.11,-.0125,.025]),squinted:Gi([.01,0],.13,1,[0,0],0,[-.12,.12,0,0]),calm:Gi([.05,0],.247,1,[.296,.247],0,[-.296,.296,0,0]),confused:Gi([-.1,0],.1305,1,[0,0],0,[-.08,.01,-.16,.16])},T3=Object.keys(hk);new Set(T3);const A3={idle:"neutral",happy:"happy",surprise:"surprised",curious:"inspecting",sad:"sad",drowsy:"sleepy",focus:"squinted",calm:"calm",confused:"confused"},Io={x:34/.26,y:70/.57},xy={w:64,h:82};function M3(e,t){const s=hk[e][t?1:0],[n,i,r,a]=s.ridge,l=2*Math.max(Math.abs(n),Math.abs(i))+2*s.wid,c=a-r+2*s.wid*s.lidY,u=Math.min(1,xy.w/(l*Io.x),xy.h/(c*Io.y));return{w:l*Io.x*u,h:c*Io.y*u,x:s.off[0]*Io.x*u,y:s.off[1]*Io.y*u,rot:s.tilt*180/Math.PI}}function D3(e){switch(e){case"focus":case"strive":return 48;case"curious":return 54;case"drowsy":case"sleep":return 56;case"working":return 46;case"asking":return 52;case"calm":return 62;case"confused":return 54;default:return 60}}function I3(e){const t=a=>Number.isFinite(a)?Math.max(0,a):0,s=e.ballR,n=s!==void 0&&Number.isFinite(s)&&s>0?s:98,i=D3(e.mood)+(t(e.leftW)+t(e.rightW))/2,r=Math.min(1,Math.max(0,i/(2*n)));return Math.asin(r)*180/Math.PI*2}const dk=["happy","sad","confused","focus","drowsy","error","scan","loading","strive","sleep"];function fk(e=Math.random){return 2800+e()*3600}const _m=260,cl=70.833,Tf=33.333,P3=1.06,L3=.01;function O3(e){if(!Number.isFinite(e)||e<0||e>=_m)return 0;const t=n=>n*n*(3-2*n);if(e<cl)return t(e/cl);if(e<cl+Tf)return 1;const s=_m-cl-Tf;return 1-t((e-cl-Tf)/s)}const Sy=2400,B3=3e4,$3=9e4,F3=12e4,z3=1600,pk=6e3,H3=.56;function U3(e,t,s,n={}){const i=bn(n.warmth??0);switch(e){case"listening":return{mode:"listening",attention:Math.min(1,.72+t*.38),energy:.78,warmth:i,phaseElapsed:s};case"thinking":return{mode:"thinking",attention:.88,energy:Math.min(1,.62+s*.08),warmth:i,phaseElapsed:s};case"speaking":return{mode:"speaking",attention:.7,energy:Math.min(1,.72+t*.35),warmth:Math.max(i,.25),phaseElapsed:s};case"curious":case"asking":return{mode:"listening",attention:Math.min(1,.82+t*.34),energy:.86,warmth:i,phaseElapsed:s};case"focus":case"working":case"strive":case"loading":return{mode:"thinking",attention:.9,energy:Math.min(1,.64+s*.08),warmth:i,phaseElapsed:s};case"talking":case"happy":case"surprise":case"wink":return{mode:"speaking",attention:.74,energy:Math.min(1,.76+t*.33),warmth:Math.max(i,.28),phaseElapsed:s};case"lookLeft":case"lookRight":case"scan":return{mode:"listening",attention:.66,energy:.7,warmth:i,phaseElapsed:s};case"drowsy":case"sleep":return{mode:"idle",attention:.1,energy:.16+i*.1,warmth:i,phaseElapsed:s};case"calm":return{mode:"idle",attention:.5,energy:.56,warmth:i,phaseElapsed:s};case"confused":return{mode:"listening",attention:.64,energy:.6,warmth:i,phaseElapsed:s};default:return{mode:"idle",attention:n.resting?.12:.38,energy:(n.resting?.18:.48)+i*.2,warmth:i,phaseElapsed:s}}}function W3(e){const{phase:t,activity:s="none",emotion:n,life:i,resting:r,drowsy:a}=e;return t==="error"?"error":t==="connecting"?"loading":s==="asking"?(e.askingMs??0)>=F3?"drowsy":"asking":e.waking?"surprise":t==="speaking"?n&&n!=="idle"?n:"talking":s==="tools"?"working":r?"sleep":a?"drowsy":t==="listening"?i??"calm":t==="thinking"?"focus":i??"idle"}function mk(e){return e<1.2?0:e<3.2?1:2}function ky(e){const{mood:t,right:s,t:n,expr:i}=e,r=e.blinking??!1,a=bn(e.blink??(r?1:0)),l=e.substate??"idle",c=bn(e.level),u=bn(e.sleep??0),{right:h}={right:s},d=A3[t],p=d?M3(d,s):null;if(t==="error")return Af({shape:"x",w:45,h:45,yScale:1,xScale:1,rot:0,x:0,y:0,alpha:.86,glow:10,jitter:6},l,s,n);if(t==="happy"||t==="sad")return Af({shape:"arc",w:p.w,h:p.h,yScale:1,xScale:1,rot:p.rot,x:p.x*2,y:(t==="happy"?20+Math.sin(n*10)*3:-10)+p.y,alpha:bn(.72+i.energy*.22+i.warmth*.06),glow:9+c*12+i.warmth*5,jitter:0,arc:t},l,s,n);const f=mk(i.phaseElapsed),m=f===0?48:f===1?56:60,b=f===0?18:f===1?13:10+Math.sin(n*2)*2,_=f===0?12:f===1?22:28,v=f===0?4:f===1?10:14,y=t==="focus"&&i.mode==="thinking",w=t==="focus"&&i.mode==="listening";let x,S;if(p)x=p.w,S=p.h;else{switch(t){case"scan":x=65+c*8;break;case"strive":x=m;break;case"sleep":x=45;break;case"loading":x=16;break;case"working":x=46;break;case"asking":x=38;break;default:x=34}switch(t){case"scan":S=12+c*8;break;case"strive":S=b;break;case"sleep":S=4+Math.sin(n*1.1)*1.2+1.2;break;case"loading":S=16;break;case"wink":S=h?2:40;break;case"working":S=46;break;case"asking":S=74;break;default:S=70}}let N=0;t==="strive"?N=h?-_:_:t==="asking"?N=8:t==="confused"?N=p.rot-8:p?N=p.rot:y&&(N=h?4:-4);let R=0;switch(t){case"lookLeft":R=-40;break;case"lookRight":R=40;break;case"scan":R=Math.sin(n*3.5)*45;break;case"working":R=0;break;case"asking":R=Math.sin(n*.9)*1.2;break;case"strive":R=Math.sin(n*(f===0?1.8:f===1?4.2:5))*v;break}if(p){const k=t==="calm"?Math.sin(n*.7)*1.2:t==="confused"?Math.sin(n*1.3)*2:t==="focus"?Math.sin(n*2.4)*(i.phaseElapsed<1.2?2.5:6):0;R=p.x*2+k}let E=0;switch(t){case"talking":E=Math.sin(n*10)*2-c*4+i.warmth*2;break;case"strive":E=Math.cos(n*3.2)*(2+i.energy*2);break;case"drowsy":E=4+u*12+Math.sin(n*1.2)*1.4;break;case"wink":E=h?0:-10;break;case"working":E=6+Math.sin(n*1.6)*1.2;break}if(p){const k=t==="calm"?Math.sin(n*1.1)*1.1:t==="confused"?Math.sin(n*1.7)*1.5:0;E+=p.y+k}let M=1;t==="talking"?M=.72+c*.42+Math.sin(n*8)*.06+i.warmth*.04:t==="drowsy"?M=Math.max(.18,1-u*.74):t==="working"?M=.58+Math.sin(n*1.6)*.02:t==="calm"?M=.82+Math.sin(n*1.1)*.02:t==="confused"?M=.98+Math.sin(n*1.7)*.015:t==="focus"&&(M=w?.9+c*.12+Math.sin(n*1.4)*.015:y?.82+Math.sin(n*1.8)*.025:.94+i.attention*.06+Math.sin(n*2)*.02);let F=1;t==="lookLeft"?F=h?1.2:.8:t==="lookRight"&&(F=h?.8:1.2);let B;return t==="drowsy"?B=.72-u*.44:t==="sleep"?B=.18:B=Math.min(1,.72+i.energy*.22+i.warmth*.06),a>0&&!dk.includes(t)&&(M=Math.min(M,Math.max(L3,1-P3*a))),Af({shape:"capsule",w:x,h:S,yScale:M,xScale:F,rot:N,x:R,y:E,alpha:bn(B),glow:9+c*12+i.warmth*5,jitter:t==="strive"?.8:0},l,s,n)}function Af(e,t,s,n){switch(t){case"reading":return{...e,w:e.w*.9,h:e.h*.82,rot:e.rot+3,y:e.y+2};case"running":return{...e,w:e.w*1.06,h:e.h*.74,yScale:e.yScale*.82,jitter:Math.max(e.jitter,1.1),y:e.y+Math.sin(n*5.5)*1.2};case"writing":return{...e,w:e.w*(s?.76:.88),h:e.h*.9,rot:e.rot+(s?4:1),y:e.y+3};case"awaiting":return{...e,w:e.w*.94,h:e.h*1.08,alpha:Math.min(1,e.alpha+.06),glow:e.glow+3,rot:e.rot*.3};case"done":return{...e,w:e.w*.92,h:e.h*.72,y:e.y-5,rot:e.rot*.4,alpha:Math.min(1,e.alpha+.04)};case"failed":return{...e,w:e.w*.96,h:e.h*.8,y:e.y+5,rot:e.rot+(s?5:-5),alpha:e.alpha*.88,glow:e.glow*.8};default:return e}}const K3=2e4;function q3(e){return e.pending>0?"asking":e.busy?e.newestKind==="tool"?"tools":"thinking":"none"}function V3(e="",t=""){const s=t.toLowerCase();if(s==="edit"||s==="write"||s==="patch"||s==="create")return"writing";if(s==="read"||s==="search"||s==="fetch")return"reading";if(s==="execute"||s==="run"||s==="command"||s==="terminal")return"running";const n=e.toLowerCase();return/\b(write|edit|patch|apply_patch|multi_edit|create|mkdir|delete|move|rename)\b|写入|编辑|修改/.test(n)?"writing":/\b(read|cat|head|tail|view|open|glob|grep|search|find|list|ls|tree)\b|读取|查看|搜索/.test(n)?"reading":"running"}function Y3(e){if(e.pending>0)return"awaiting";if(!e.busy||e.newestKind!=="tool")return"idle";const t=String(e.newestToolStatus??"").toLowerCase();return t==="failed"||t==="error"||t==="cancelled"?"failed":t==="completed"||t==="success"?"done":V3(e.newestToolTitle,e.newestToolKind)}function G3(e,t=Math.random,s={}){if(e>$3)return s.busy?null:"rest";const n=e>B3?["lookLeft","lookRight","curious","wink","focus","calm"]:["lookLeft","lookRight","wink"];if(t()>=H3)return null;const i=n[Math.min(n.length-1,Math.floor(t()*n.length))];return{mood:i,durationMs:i==="wink"?750:1800+t()*1400}}const J3=[{mood:"happy",words:["开心","高兴","太好了","喜欢","棒","恭喜","成功","完成了","搞定","哈哈","谢谢"]},{mood:"sad",words:["抱歉","难过","遗憾","可惜","失败了","没成功","不舒服","唉"]},{mood:"surprise",words:["竟然","居然","没想到","原来","意外","真的吗"]},{mood:"curious",words:["要不要","是不是","你觉得","哪个","为什么","要我","需要我"]},{mood:"strive",words:["麻烦","麻烦你","冲突","错误","报错","卡住","超时"]}],X3=/[不没别未无](?:有|是|会|太|要)?\s*$/;function Z3(e){const t=String(e??"");if(!t)return null;let s=null;for(const{mood:n,words:i}of J3)for(const r of i){let a=t.indexOf(r);for(;a>=0;){if(!X3.test(t.slice(Math.max(0,a-2),a))){(!s||a<s.at)&&(s={mood:n,at:a});break}a=t.indexOf(r,a+1)}}return s?.mood??null}const gk=2e4,Q3=45e3,e5={neutral:"idle",happy:"happy",surprised:"surprise",inspecting:"curious",sad:"sad",sleepy:"drowsy",squinted:"focus",calm:"calm",confused:"confused",smile:"happy",inspect:"curious",strange:"curious",squint:"focus",idle:"idle",thinking:"sad",focus:"focus",angry:"strive",sleep:"sleep",joy:"happy",love:"happy",surprise:"surprise",curious:"curious",strive:"strive",shy:"wink",wink:"wink"},b_=/\[\s*(?:emo|emotion)\s*[::]\s*([a-zA-Z\u4e00-\u9fa5_-]{1,16})\s*\]/gi;function t5(e){const t=[];for(const s of String(e??"").matchAll(b_)){const n=e5[s[1].toLowerCase()];n&&t.push(n)}return t}const Cy=/\s*\[\s*(?:emo|emotion)\s*[::]\s*[a-zA-Z\u4e00-\u9fa5_-]*\s*\]?\s*$/i,s5=new RegExp(b_.source,"i");function Bh(e){const t=String(e??"");return!s5.test(t)&&!Cy.test(t)?t:t.replace(b_,"").replace(Cy,"").trim()}function n5(e){return String(e??"").replace(/[ \t]{2,}/g," ").trim()}function bn(e){return e<0?0:e>1?1:e}function i5(e,t,s=.55,n=.1){const i=bn(e),r=bn(t);return bn(i+(r-i)*(r>i?s:n))}function r5(e,t){return bn(t)-bn(e)>.18&&t>.22?"tick":null}const Ey=2400,o5=4600;function a5(e=Math.random){return Ey+e()*(o5-Ey)}function l5(e=Math.random){const t=e();return{mood:t<.42?"lookLeft":t<.84?"lookRight":"wink",durationMs:300+e()*220}}function c5(e,t={}){const s=u5(e,t);return h5(s,t.substate??"idle")}function u5(e,t){const s=bn(t.level??0),n=t.breath??0,i=e==="sleep",r=e==="drowsy";switch(e){case"talking":return{r:96+s*7,sx:1+s*.03,sy:1-s*.025,dy:-1.5-s*2,rot:0};case"happy":case"wink":return{r:100,sx:1.03,sy:.97,dy:-3,rot:-4};case"surprise":return{r:104,sx:.98,sy:1.04,dy:-4,rot:0};case"sad":return{r:93,sx:1.02,sy:.94,dy:3,rot:3};case"strive":return{r:95,sx:1.05,sy:.92,dy:1,rot:-3};case"working":return{r:92,sx:1.06,sy:.9,dy:4,rot:7};case"asking":return{r:99,sx:.99,sy:1.01,dy:-1,rot:0};case"calm":return{r:100,sx:1.01,sy:.99,dy:-1,rot:-2};case"confused":return{r:96,sx:1.02,sy:.96,dy:2,rot:8};case"focus":return{r:94,sx:.98,sy:1,dy:0,rot:-5};case"drowsy":return{r:97,sx:1.02,sy:.95,dy:6,rot:6};case"sleep":return{r:95,sx:1.04,sy:.93,dy:7,rot:8};case"loading":return{r:92+(t.breath??0)*3,sx:1,sy:1,dy:0,rot:0};case"error":return{r:96,sx:1.03,sy:.96,dy:0,rot:0};default:return{r:i?95:98,sx:1+n*.006,sy:1-n*.006,dy:r?5:-n*2,rot:e==="curious"?4:e==="lookLeft"?-3:e==="lookRight"?3:0}}}function h5(e,t){switch(t){case"reading":return{...e,r:e.r-1,rot:e.rot-4,dy:e.dy+2};case"running":return{...e,r:e.r-2,sx:e.sx*.98,sy:e.sy*.96,rot:e.rot+2,dy:e.dy+3};case"writing":return{...e,r:e.r-2,sx:e.sx*1.02,sy:e.sy*.95,rot:e.rot+9,dy:e.dy+4};case"awaiting":return{...e,r:e.r+3,sy:e.sy*1.02,dy:e.dy-2,rot:e.rot*.4};case"done":return{...e,r:e.r+4,sy:e.sy*1.05,dy:e.dy-5,rot:e.rot-3};case"failed":return{...e,r:e.r-4,sy:e.sy*.94,dy:e.dy+5,rot:e.rot+3};default:return e}}const d5=6,f5=9,Yr={min:1.36,max:1.5},Kt={r:1,sx:1,sy:1,dy:0,rot:0},Ny={"listen-in":{frames:[Kt,{r:1.02,sx:1.03,sy:1.06,dy:-1.42,rot:-.6},{r:1.01,sx:.99,sy:1.02,dy:.8,rot:.35},Kt],ms:[180,260,960],ease:["out","inOut","out"]},"say-in":{frames:[Kt,{r:1.05,sx:1.05,sy:.93,dy:-1.1,rot:.2},{r:1.06,sx:.98,sy:1.08,dy:1.4,rot:-.3},Kt],ms:[120,220,1160],ease:["in","out","inOut"]},"think-turn":{frames:[Kt,{r:.99,sx:1.06,sy:.92,dy:.7,rot:-1.36},{r:1.01,sx:.98,sy:1.03,dy:-.9,rot:.5},Kt],ms:[200,700,1100],ease:["out","inOut","out"]},"tool-start":{frames:[Kt,{r:.98,sx:1.12,sy:.86,dy:1.2,rot:.3},{r:1.02,sx:.96,sy:1.06,dy:-1.42,rot:-.6},Kt],ms:[150,250,1400],ease:["in","out","inOut"]},"tool-done":{frames:[Kt,{r:1.04,sx:1,sy:1.08,dy:-1.45,rot:-1.1},{r:1.01,sx:1.03,sy:.96,dy:1.36,rot:.5},Kt],ms:[220,380,1400],ease:["out","in","out"]},"error-frown":{frames:[Kt,{r:.95,sx:1.06,sy:.92,dy:1.3,rot:-1.45},{r:.98,sx:1.02,sy:.96,dy:.7,rot:1.36},Kt],ms:[180,520,1200],ease:["out","inOut","out"]},"ask-hold":{frames:[Kt,{r:1.02,sx:.99,sy:1.02,dy:-.7,rot:1.36},{r:1.01,sx:1.02,sy:1,dy:.5,rot:1.1},Kt],ms:[260,1200,1600],ease:["out","inOut","inOut"]},"blink-pop":{frames:[Kt,{r:.99,sx:1.01,sy:.97,dy:1.4,rot:0},Kt],ms:[180,1220],ease:["out","out"]},"tool-fail":{frames:[Kt,{r:.94,sx:1.08,sy:.9,dy:1.45,rot:-.8},{r:.97,sx:.98,sy:.96,dy:.4,rot:.7},Kt],ms:[160,380,1400],ease:["out","inOut","out"]},wake:{frames:[Kt,{r:1.05,sx:.97,sy:1.06,dy:-1.45,rot:.4},{r:1,sx:1.02,sy:.98,dy:.6,rot:-.2},Kt],ms:[200,600,1800],ease:["out","inOut","out"]}};function p5(e){let t=0;for(const s of e.frames)t=Math.max(t,Math.abs(s.r-1),Math.abs(s.sx-1),Math.abs(s.sy-1),Math.abs(s.dy),Math.abs(s.rot));return t}function m5(e){const t=p5(e);if(!(t>0))return e;const s=t>Yr.max?Yr.max/t:t<Yr.min?Yr.min/t:1;return s===1?e:{...e,frames:e.frames.map(n=>({r:1+(n.r-1)*s,sx:1+(n.sx-1)*s,sy:1+(n.sy-1)*s,dy:n.dy*s,rot:n.rot*s}))}}const Ry=Object.fromEntries(Object.keys(Ny).map(e=>[e,m5(Ny[e])])),jy={"blink-pop":0,"tool-start":1,"listen-in":2,"say-in":2,"think-turn":2,wake:2,"ask-hold":3,"tool-done":4,"tool-fail":4,"error-frown":4};function g5(e){return e.ms.reduce((t,s)=>t+s,0)}const _5={linear:e=>e,in:e=>e*e*e,out:e=>1-Math.pow(1-e,3),inOut:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2};function v5(e){const t=n=>Math.min(Yr.max,Math.max(1/Yr.max,n)),s=n=>Math.min(Yr.max,Math.max(-1.5,n));return{r:t(e.r),sx:t(e.sx),sy:t(e.sy),dy:s(e.dy),rot:s(e.rot)}}function y5(e,t){if(!Number.isFinite(t)||t<0)return null;let s=t;for(let n=0;n<e.ms.length;n++){const i=e.ms[n];if(s<=i){const r=i>0?s/i:1,a=_5[e.ease[n]??"linear"](r),l=e.frames[n],c=e.frames[n+1]??l;return v5({r:l.r+(c.r-l.r)*a,sx:l.sx+(c.sx-l.sx)*a,sy:l.sy+(c.sy-l.sy)*a,dy:l.dy+(c.dy-l.dy)*a,rot:l.rot+(c.rot-l.rot)*a})}s-=i}return null}function b5(e,t){return{r:e.r*t.r,sx:e.sx*t.sx,sy:e.sy*t.sy,dy:e.dy+t.dy*d5,rot:e.rot+t.rot*f5}}function Ty(e){switch(e.kind){case"tool":return e.status==="start"?"tool-start":e.status==="done"?"tool-done":"tool-fail";case"blink":return"blink-pop";case"think":return e.stage===0?null:"think-turn";case"mood":{const{from:t,to:s}=e;return s==="error"?"error-frown":s==="asking"?"ask-hold":s==="working"?"tool-start":s==="talking"?"say-in":s==="focus"?"think-turn":s==="curious"?t==="lookLeft"||t==="lookRight"||t==="wink"||t==="scan"?null:"listen-in":(s==="idle"||s==="happy")&&(t==="sleep"||t==="drowsy")?"wake":null}}}function ul(e,t,s,n,i=26,r=.55){const a=-2*r*i*t-i*i*(e-s),l=t+a*n;return{x:e+l*n,v:l}}const Ay={maxX:14,maxY:18};function w5(e){const t=e.elapsed??0;let s=0,n=0;switch(e.mood){case"focus":s=-.55,n=-.7;break;case"working":s=-.25,n=.85;break;case"asking":s=0,n=.1;break;case"sad":s=0,n=.8;break;case"happy":case"wink":s=.15,n=-.25;break;case"surprise":s=0,n=-.15;break;case"drowsy":case"sleep":s=0,n=.75;break;case"lookLeft":s=-.9;break;case"lookRight":s=.9;break;case"scan":s=Math.sin(t*2.2)*.9;break;case"curious":s=.35,n=-.2;break;case"calm":s=.08,n=.05;break;case"confused":s=-.4,n=-.12;break}switch(e.substate??"idle"){case"reading":s-=.35,n+=.55;break;case"running":s+=.05,n+=.75;break;case"writing":s+=.4,n+=.75;break;case"awaiting":s*=.3,n=.15;break;case"done":s+=.1,n-=.5;break;case"failed":s*=.6,n+=.65;break}return{ax:s*.7*Ay.maxX,ay:n*.7*Ay.maxY}}function x5(e){const t=(e.ax+e.side*e.sep/2)*Math.PI/180,s=e.ay*Math.PI/180;return{x:e.R*Math.sin(t),y:e.R*Math.sin(s),cos:Math.max(0,Math.cos(t)*Math.cos(s))}}function S5(e){const t=e.k??1,s=Number.isFinite(t)&&t>0?t:1,n=e.ballR,i=(n!==void 0&&Number.isFinite(n)&&n>0?n:98)*s,r=I3({mood:e.mood,leftW:e.left.w,rightW:e.right.w,ballR:e.ballR}),a=(d,p,f,m)=>{const b=x5({ax:e.gaze.ax,ay:e.gaze.ay,side:p,R:i,sep:f}),_=.55+.45*b.cos;return{x:b.x+d.x*s*.5*m,y:b.y+d.y*s,w:Math.max(2,d.w*s*d.xScale*_),cos:b.cos}},l=1.05*i,c=(d,p)=>{const f=a(e.left,-1,d,p),m=a(e.right,1,d,p);return{l:f,r:m,out:Math.max(Math.abs(f.x)+f.w/2,Math.abs(m.x)+m.w/2)}};let u=r,h=c(u,1);if(h.out>l)if(c(u,0).out<=l){let d=0,p=1;for(let f=0;f<18;f++){const m=(d+p)/2;c(u,m).out>l?p=m:d=m}h=c(u,d)}else{let d=0,p=r;for(let f=0;f<18;f++){const m=(d+p)/2;c(m,0).out>l?p=m:d=m}u=d,h=c(u,0)}return{left:h.l,right:h.r,gap:h.r.x-h.r.w/2-(h.l.x+h.l.w/2),sep:u}}const k5=e=>({phase:"idle",life:null,lifeUntil:0,nextBlinkAt:e+fk(),blinkAt:e-_m,nextBeatAt:e+pk,nextActionAt:e+gk,resting:!1,drowsy:!1,sleep:0,sleepTarget:0,phaseAt:e,warmthUntil:0,lastEventAt:e,quietSince:e,micro:null,microAt:0,microUntil:0,mood:"idle",moodAt:e,ticks:0,level:0,rawLevel:0,toolStatus:"",clip:null,clipAt:0,clipMs:0,thinkStage:0,nextSaccadeAt:e+900,ball:{r:98,sx:1,sy:1,dy:0},ballV:{r:0,sx:0,sy:0,dy:0},ballRot:0,ballRotV:0,askingSince:0,wakeUntil:0,dots:0});function C5({phase:e,activity:t,substate:s="idle",emotion:n=null,ticks:i=0,toolStatus:r="",getLevel:a,onMood:l}){const c=g.useRef(null),u=g.useRef({phase:e,activity:t,substate:s,emotion:n,ticks:i,toolStatus:r});u.current={phase:e,activity:t,substate:s,emotion:n,ticks:i,toolStatus:r};const h=g.useRef(a);h.current=a;const d=g.useRef(l);d.current=l,g.useEffect(()=>{const f=c.current;if(!f)return;const m=f.getContext("2d");if(!m)return;const b=Math.min(1.5,window.devicePixelRatio||1),_=k5(performance.now());_.ticks=u.current.ticks,_.toolStatus=u.current.toolStatus;const v=(R,E)=>{_.clip&&_.clipAt===E&&jy[R]<jy[_.clip]||(_.clip=R,_.clipAt=E,_.clipMs=g5(Ry[R]))};let y=0,w=0;const x=()=>{const R=f.getBoundingClientRect();f.width=Math.max(1,Math.round(R.width*b)),f.height=Math.max(1,Math.round(R.height*b))};x();const S=new ResizeObserver(x);S.observe(f);const N=R=>{if(y=window.requestAnimationFrame(N),R-w<33)return;w=R;const E=R/1e3,M=u.current;_.rawLevel=Math.max(0,Math.min(1,h.current()||0));const F=_.level;_.level=i5(_.level,_.rawLevel);const B=r5(F,_.level);if(B&&M.phase==="listening"&&(_.micro=B,_.microAt=R,_.microUntil=R+280,_.quietSince=R),M.phase!==_.phase&&(_.phase=M.phase,_.phaseAt=R,_.quietSince=R),M.ticks!==_.ticks&&(_.ticks=M.ticks,_.lastEventAt=R,_.quietSince=R,_.micro="tick",_.microAt=R,_.microUntil=R+260,v("tool-start",R)),M.toolStatus!==_.toolStatus){const ae=M.toolStatus.toLowerCase();_.toolStatus=M.toolStatus,ae==="completed"||ae==="success"?v("tool-done",R):ae==="failed"||ae==="error"||ae==="cancelled"?v("tool-fail",R):ae&&v("tool-start",R)}const k=M.activity!=="none"||M.phase==="thinking"||M.phase==="speaking";if(R>=_.nextBlinkAt&&(_.nextBlinkAt=R+fk(),dk.includes(_.mood)||(_.blinkAt=R,_.clip||v("blink-pop",R))),R>=_.nextBeatAt){_.nextBeatAt=R+pk;const ae=G3(R-_.quietSince,Math.random,{busy:k});ae==="rest"?(_.drowsy=!0,_.sleepTarget=1):ae&&(_.life=ae.mood,_.lifeUntil=R+ae.durationMs)}if(M.phase==="listening"&&R>=_.nextSaccadeAt&&(_.nextSaccadeAt=R+a5(),!_.life)){const ae=l5();_.life=ae.mood,_.lifeUntil=R+ae.durationMs,_.lastEventAt=R}_.life&&R>_.lifeUntil&&(_.life=null),_.drowsy&&_.sleepTarget>0&&_.sleep>=.995&&(_.drowsy=!1,_.resting=!0),_.sleep+=Math.max(-1,Math.min(1,(_.sleepTarget-_.sleep)*.06)),(_.resting||_.drowsy)&&k&&(_.resting=!1,_.drowsy=!1,_.sleepTarget=0,_.wakeUntil=R+z3,v("wake",R)),M.activity==="asking"?_.askingSince||(_.askingSince=R):_.askingSince=0;const A=R-_.lastEventAt;if(k&&A>K3&&R-_.microAt>gk){const ae=A>Q3?"stretch":Math.random()<.7?"flick":"tick";_.micro=ae,_.microAt=R,_.microUntil=R+(ae==="stretch"?1400:420)}_.micro&&R>_.microUntil&&(_.micro=null);const D=W3({phase:M.phase,activity:M.activity,emotion:M.emotion,life:_.life,resting:_.resting,drowsy:_.drowsy,waking:R<_.wakeUntil,askingMs:_.askingSince?R-_.askingSince:0});if(D!==_.mood){const ae=Ty({kind:"mood",from:_.mood,to:D});_.moodAt=R;try{d.current?.(D)}catch{}D!=="sleep"&&(_.resting||_.drowsy)&&(_.resting=!1,_.drowsy=!1,_.sleepTarget=0,_.sleep=0),M.phase!=="speaking"&&(_.warmthUntil=R+Sy),_.mood=D,ae&&v(ae,R)}const H=M.phase==="thinking"&&D==="focus"?1:0;_.dots+=(H-_.dots)*.14,_.dots<.002?_.dots=0:_.dots>.998&&(_.dots=1);const I=Math.max(0,Math.min(1,(_.warmthUntil-R)/Sy)),z=(R-_.phaseAt)/1e3,T=U3(D,_.level,z,{resting:_.resting,warmth:I}),O=mk(z);if(O!==_.thinkStage&&(_.thinkStage=O,D==="focus")){const ae=Ty({kind:"think",stage:O});ae&&v(ae,R)}const K=O3(R-_.blinkAt),U=ky({mood:D,right:!1,blink:K,t:E,level:_.level,expr:T,sleep:_.sleep,substate:M.substate}),re=ky({mood:D,right:!0,blink:K,t:E,level:_.level,expr:T,sleep:_.sleep,substate:M.substate}),J=f.width,Y=f.height;m.setTransform(1,0,0,1,0,0),m.clearRect(0,0,J,Y),m.scale(b,b);const _e=J/b,xe=Y/b,fe=Math.max(.5,Math.min(3.2,Math.min(_e/260,xe/260)));let et=c5(D,{level:_.level,breath:["idle","drowsy","sleep","curious","asking","working"].includes(D)?Math.sin(E*Math.PI*2/2)*6:0,substate:M.substate});if(_.clip)if(R-_.clipAt>=_.clipMs)_.clip=null;else{const ae=y5(Ry[_.clip],R-_.clipAt);ae?et=b5(et,ae):_.clip=null}const Oe=_.clip??"";f.dataset.clip!==Oe&&(Oe?f.dataset.clip=Oe:delete f.dataset.clip),f.dataset.substate!==M.substate&&(f.dataset.substate=M.substate);const tt=_.dots>=.5?"1":"";(f.dataset.dots??"")!==tt&&(tt?f.dataset.dots=tt:delete f.dataset.dots);for(let ae=0;ae<4;ae++){const be=.008333333333333333,Be=ul(_.ball.r,_.ballV.r,et.r,be,22,.6);_.ball.r=Be.x,_.ballV.r=Be.v;const W=ul(_.ball.sx,_.ballV.sx,et.sx,be,30,.5);_.ball.sx=W.x,_.ballV.sx=W.v;const Se=ul(_.ball.sy,_.ballV.sy,et.sy,be,30,.5);_.ball.sy=Se.x,_.ballV.sy=Se.v;const He=ul(_.ball.dy,_.ballV.dy,et.dy,be,24,.62);_.ball.dy=He.x,_.ballV.dy=He.v;const q=ul(_.ballRot,_.ballRotV,et.rot,be,18,.5);_.ballRot=q.x,_.ballRotV=q.v}const Pe=_.ball.r*fe,Le=_e/2,Ee=xe/2+_.ball.dy*fe,Ae=["idle","drowsy","sleep","curious","asking","working","calm"].includes(D)?Math.sin(E*Math.PI*2/2)*6*fe:0;let Ze=0,me=0;_.micro==="tick"?me=2.5*fe:_.micro==="flick"?(Ze=4*fe,me=1.5*fe):_.micro==="stretch"&&(me=-5*fe),m.save(),m.globalAlpha=1-_.dots,m.translate(Le,Ee),m.rotate(_.ballRot*Math.PI/180),m.scale(_.ball.sx,_.ball.sy),m.beginPath(),m.arc(0,0,Pe,0,Math.PI*2),m.shadowColor="rgba(15,20,26,0.30)",m.shadowBlur=30*fe,m.shadowOffsetY=12*fe;const Ye=m.createRadialGradient(-Pe*.32,-Pe*.42,Pe*.06,0,0,Pe*1.02);Ye.addColorStop(0,"#31383f"),Ye.addColorStop(.52,"#171b20"),Ye.addColorStop(1,"#0a0c0f"),m.fillStyle=Ye,m.fill(),m.shadowBlur=0,m.shadowOffsetY=0,m.strokeStyle="rgba(255,255,255,0.12)",m.lineWidth=Math.max(1,1.6*fe),m.stroke(),m.restore(),m.save(),m.translate(Le,Ee),m.rotate(_.ballRot*Math.PI/180),m.beginPath(),m.ellipse(0,0,Pe*_.ball.sx,Pe*_.ball.sy,0,0,Math.PI*2),m.clip(),m.translate(-Le,-Ee);const de=w5({mood:D,elapsed:z,substate:M.substate}),lt=S5({mood:D,left:U,right:re,gaze:de,ballR:_.ball.r,k:fe});for(const ae of[U,re]){const Be=(ae===re?1:-1)===1?lt.right:lt.left,W=Le+Be.x+Ze,Se=Ee+Be.y+Ae*.4+me;m.save(),m.translate(W,Se),m.rotate(ae.rot*Math.PI/180),m.globalAlpha=Math.max(0,Math.min(1,ae.alpha))*(1-_.dots);const He=D==="error"?"248,113,113":D==="sad"?"190,190,200":"255,255,255";if(m.shadowColor=`rgba(${He},${Math.min(.5,.16+_.level*.2+I*.14)})`,m.shadowBlur=Math.min(ae.w*fe*.45,ae.glow*fe),m.fillStyle=`rgba(${He},1)`,m.strokeStyle=`rgba(${He},1)`,ae.shape==="x"){const q=Be.w/2,Z=Math.sin(E*24)*ae.jitter*fe;m.lineWidth=6*fe,m.beginPath(),m.moveTo(-q+Z,-q),m.lineTo(q+Z,q),m.moveTo(q+Z,-q),m.lineTo(-q+Z,q),m.stroke()}else if(ae.shape==="arc"){const q=Be.w/2;m.lineWidth=6*fe,m.beginPath(),ae.arc==="happy"?m.arc(0,q,q,Math.PI,Math.PI*2):m.arc(0,-q,q,0,Math.PI),m.stroke()}else{const q=Be.w,Z=Math.max(1,ae.h*fe*ae.yScale),ge=Math.min(q,Z)/2,P=ae.jitter?Math.sin(E*24)*ae.jitter*fe:0,le=ae.jitter?Math.cos(E*19)*ae.jitter*fe:0,je=m.createLinearGradient(0,-Z/2,0,Z/2);je.addColorStop(0,`rgba(${He},1)`),je.addColorStop(1,`rgba(${He},0.94)`),m.fillStyle=je,m.beginPath(),typeof m.roundRect=="function"?m.roundRect(-q/2+P,-Z/2+le,q,Z,ge):m.ellipse(0,0,q/2,Z/2,0,0,Math.PI*2),m.fill(),m.shadowBlur=0,m.lineWidth=1,m.strokeStyle=`rgba(${He},0.5)`,m.stroke()}m.restore()}if(m.restore(),_.dots>0){const ae=Pe*.56,be=Pe*.08,Be=Se=>Math.sin(E*Math.PI*2/1.4+Se*Math.PI*2),W=[{x:Le-ae,r:Pe*.17,tone:"109,114,120",offset:-.12},{x:Le,r:Pe*.24,tone:"13,15,18",offset:0},{x:Le+ae,r:Pe*.19,tone:"125,131,139",offset:.12}];m.save();for(const Se of W){const He=Ee+Be(Se.offset)*be,q=Se.r*(1+.04*Be(Se.offset+.25));m.globalAlpha=_.dots,m.fillStyle=`rgb(${Se.tone})`,m.shadowColor=`rgba(${Se.tone},0.28)`,m.shadowBlur=q*.9,m.beginPath(),m.arc(Se.x,He,q,0,Math.PI*2),m.fill()}m.restore()}};return y=window.requestAnimationFrame(N),()=>{window.cancelAnimationFrame(y),S.disconnect()}},[]);const p=g.useRef(e);return p.current!==e&&(p.current=e),o.jsx("canvas",{ref:c,className:"tus-face-canvas","aria-hidden":"true"})}const hl={ratio:2.6,minRms:.004,hangMs:700,rise:.3,fall:.35};function E5(e=0){return{floor:e,lastVoiceAt:-1/0,prev:Number.NaN,speech:!1}}function N5(e,t,s,n={}){const i=n.hangMs??hl.hangMs,r=e.prev;if(!Number.isFinite(t))return e.speech=s-e.lastVoiceAt<=i,e.speech;const a=Math.max(0,t);e.prev=a;const l=n.ratio??hl.ratio,c=Math.max(n.minRms??hl.minRms,e.floor*l),u=a>c,h=Number.isFinite(r)&&Math.abs(a-r)<=Math.max(.0015,a*.08);if(!u||h){const d=a<e.floor?n.fall??hl.fall:n.rise??hl.rise;e.floor=e.floor===0?a:e.floor+(a-e.floor)*d}return u&&(e.lastVoiceAt=s),e.speech=s-e.lastVoiceAt<=i,e.speech}const R5="modulepreload",j5=function(e){return"/"+e},My={},T5=function(t,s,n){let i=Promise.resolve();if(s&&s.length>0){document.getElementsByTagName("link");const a=document.querySelector("meta[property=csp-nonce]"),l=a?.nonce||a?.getAttribute("nonce");i=Promise.allSettled(s.map(c=>{if(c=j5(c),c in My)return;My[c]=!0;const u=c.endsWith(".css"),h=u?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${c}"]${h}`))return;const d=document.createElement("link");if(d.rel=u?"stylesheet":R5,u||(d.as="script"),d.crossOrigin="",d.href=c,l&&d.setAttribute("nonce",l),document.head.appendChild(d),u)return new Promise((p,f)=>{d.addEventListener("load",p),d.addEventListener("error",()=>f(new Error(`Unable to preload CSS for ${c}`)))})}))}function r(a){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=a,window.dispatchEvent(l),!l.defaultPrevented)throw a}return i.then(a=>{for(const l of a||[])l.status==="rejected"&&r(l.reason);return t().catch(r)})},A5=.5,M5=.35,dl=512,fl=64,D5=700;function Dy(){return{prob:-1,speech:!1,lastVoiceAt:-1/0,frames:0}}function I5(e,t,s,n=D5){return e.prob=t,t>=A5?e.lastVoiceAt=s:t<M5&&(e.lastVoiceAt=s-n-1),e.speech=s-e.lastVoiceAt<=n,e.frames+=1,e.speech}class P5{#e=null;#l=null;#i=null;#s=new Float32Array(fl);#o=[];#t=!1;#n=[];#c=0;st=Dy();get ready(){return this.#e!==null}async load(t){if(this.#e)return!0;try{const s=await T5(()=>import("./ort.wasm.bundle.min-kEi4lvn9.js"),[]);return s.env.wasm.numThreads=1,s.env.logLevel="error",this.#l=s,this.#e=await s.InferenceSession.create(t,{executionProviders:["wasm"],graphOptimizationLevel:"all"}),this.#i=new s.Tensor("float32",new Float32Array(2*1*128),[2,1,128]),!0}catch(s){return console.warn("[vad] silero unavailable, falling back to the level gate:",s?.message??s),this.#e=null,this.#l=null,!1}}reset(){this.st=Dy(),this.#s.fill(0),this.#o=[],this.#n=[],this.#l&&this.#i&&(this.#i=new this.#l.Tensor("float32",new Float32Array(2*1*128),[2,1,128]))}push(t){if(this.#e){for(let s=0;s<t.length;s++)this.#o.push(t[s]);for(;this.#o.length>=dl;){const s=new Float32Array(this.#o.splice(0,dl));this.#n.push(s),this.#n.length>2&&this.#n.shift()}this.#h()}}async#h(){if(!(this.#t||!this.#e||!this.#l||!this.#i)){this.#t=!0;try{for(;this.#n.length&&this.#e;){const t=this.#n.shift(),s=new Float32Array(fl+dl);s.set(this.#s,0),s.set(t,fl);const n=await this.#e.run({input:new this.#l.Tensor("float32",s,[1,fl+dl]),state:this.#i,sr:new this.#l.Tensor("int64",BigInt64Array.from([16000n]),[])});this.#i=n.stateN,this.#s.set(t.subarray(dl-fl));const i=Number(n.output.data[0]);I5(this.st,Number.isFinite(i)?i:0,Date.now())}}catch(t){++this.#c>=3&&(console.warn("[vad] silero run failed, falling back to the level gate:",t?.message??t),this.#e=null,this.#n=[])}finally{this.#t=!1}}}}const Po=new P5,Ac={interruptMode:"voice",bargeSensitivity:60,bargeMs:300,silenceMs:1500,minChars:3,wakePhrase:"hi, Tus"},_k=[{id:"voice",label:"语音打断",hint:"说一句就能打断它(灵敏度、持续时间在设置里调)"},{id:"keyword",label:"关键词打断",hint:"要先说出你设的那句话才算打断(设置里填),比语音打断稳、不用碰屏幕"},{id:"button",label:"按键打断",hint:"只认按钮:它说话的时候麦克风关着,不识别、不抢话——外放串音、环境吵的时候用它"}],$h={bargeSensitivity:[0,100],bargeMs:[100,1e3],silenceMs:[400,4e3],minChars:[1,20]},L5=[{key:"bargeSensitivity",label:"抢话灵敏度",show:e=>`${Math.round(e)}%`,ends:["迟钝","灵敏"],hint:"越高越容易打断它(100% 最灵敏)。手机外放容易串音,串音频繁就调低一点"},{key:"bargeMs",label:"抢话持续时间",show:e=>e>=1e3?`${(e/1e3).toFixed(1)} 秒`:`${e} 毫秒`,ends:["快","稳"],hint:"要连续这么大声才算抢话"},{key:"silenceMs",label:"说完停顿",show:e=>`${(e/1e3).toFixed(1)} 秒`,ends:["快","慢"],hint:"静音这么久就算你说完了,自动把话发出去;怕被提前截断就用「按住说话」"},{key:"minChars",label:"最少字数",show:e=>e<=1?"不限制":`${e} 字`,ends:["1","20"],hint:"自动发送时少于这个字数不发送(1 = 不限制);点一下圆球是明确指令,照发。默认 3 字,挡掉语气词和噪音"}];function O5(e){const t=Math.min(100,Math.max(0,Number(e)));return .008+.075*Math.pow(1-t/100,1.2)}const Iy={aec:.55,raw:1.4},B5=1.6;function Py(e,t,s,n,i){return e>O5(n)?t>.002?s>.002?e>s*B5:e>t*(i?Iy.aec:Iy.raw):!0:!1}const Ly=600,Oy=900,vk="agentus.call",$5=Object.keys($h);function F5(e,t){const[s,n]=$h[e],i=Number(t);return Number.isFinite(i)?Math.min(n,Math.max(s,i)):Ac[e]}function w_(e){const t={...Ac};if(!e||typeof e!="object")return t;const s=e;_k.some(n=>n.id===s.interruptMode)&&(t.interruptMode=s.interruptMode);for(const n of $5)n in s&&(t[n]=F5(n,s[n]));return"wakePhrase"in s&&(t.wakePhrase=yk(s.wakePhrase)),t}function yk(e){const t=[...String(e??"").replace(/\s+/g," ").trim()].slice(0,z5).join("");return t.replace(/[\s\p{P}\p{S}]/gu,"")===""?"":t}const z5=24;function vm(e,t){const s=i=>String(i??"").toLowerCase().replace(/[\s\p{P}\p{S}]/gu,""),n=s(t);return n?s(e).includes(n):!1}const H5=2500;function U5(e){return!(e.muted||!e.heard||!e.phrase||!e.graceOpen||!(e.heardAgoMs<=H5)||e.own&&vm(e.own,e.phrase)||!vm(e.heard,e.phrase)||e.playRms>=0&&!e.evidence)}function W5(){try{return w_(JSON.parse(localStorage.getItem(vk)??"null"))}catch{return{...Ac}}}let bc=W5();const ym=new Set;function bk(e){bc=e;try{localStorage.setItem(vk,JSON.stringify(bc))}catch{}for(const t of ym)t()}async function wk(e){const t=w_({...bc,...e});bk(t);try{const s=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({call:t})});return s.ok?(xk((await s.json()).call),""):(await s.json().catch(()=>({}))).error??`save failed (${s.status})`}catch(s){return String(s?.message??s)}}function xk(e){const t=w_(e);Object.keys(Ac).every(s=>t[s]===bc[s])||bk(t)}async function K5(){try{const e=await fetch("/api/settings",{credentials:"same-origin"});if(!e.ok)return;xk((await e.json()).call)}catch{}}function q5(){return[g.useSyncExternalStore(t=>(ym.add(t),()=>ym.delete(t)),()=>bc),t=>void wk(t)]}const V5={connecting:{core:[125,145,200],glow:"rgba(125,145,200,0.30)"},listening:{core:[56,189,248],glow:"rgba(56,189,248,0.34)"},thinking:{core:[167,139,250],glow:"rgba(167,139,250,0.30)"},speaking:{core:[251,191,36],glow:"rgba(251,191,36,0.32)"},error:{core:[248,113,113],glow:"rgba(248,113,113,0.30)"}},Lo={connecting:"正在接通…",listening:"在听你说",thinking:"思考中…",speaking:"正在回答",error:"出错了"},Y5=.01,By=120,G5=/^(?:Stopped waiting for another Hermes process on this session\. Your message was not processed\.|⏳? ?Another Hermes process kept this session busy too long[\s\S]*not processed[\s\S]*)$/;function $y(e){return[...e].length}const J5=1,X5=4e3,Z5=15e3,Q5=45e3,eI=3e3,Fy="agentus.call.caption",zy="agentus.call.voiceMode",Hy="agentus.call.brief",tI=g.memo(function({kind:t,who:s,text:n,current:i}){return n.trim()?o.jsxs("div",{className:`call-hm ${t}${i?" current":""}`,children:[s?o.jsx("span",{className:"call-hm-who",children:s}):null,t==="agent"||t==="user"?o.jsx(S3,{text:n}):o.jsx("span",{children:n})]}):null});function Uy(e){switch(e.kind){case"user":return{kind:"user",who:e.from?`来自「${e.from.title}」`:"你",text:e.text};case"agent":return{kind:"agent",who:"它",text:e.text};case"meta":return{kind:"meta",who:"",text:e.text};case"tool":return{kind:"tool",who:"",text:`${e.title||e.kind2||"工具"}${e.status?` · ${e.status}`:""}`};case"plan":return{kind:"tool",who:"",text:`计划:${e.items.map(t=>t.content).join(";")}`};case"thought":return{kind:"tool",who:"",text:e.text};case"note":return{kind:"meta",who:"",text:e.text};case"approval":return{kind:"meta",who:"",text:`审批:${e.title}${e.decision?e.decision.outcome==="selected"?"(已答)":"(已取消)":""}`};case"project-skills":return{kind:"meta",who:"",text:e.text};case"turn-usage":return{kind:"meta",who:"",text:uk(e)}}}function sI({sessionId:e,onClose:t,onKeyboard:s,renderTranscript:n,tus:i=!1,pending:r=0}){const[a]=_o(),l=dd(),[c,u]=g.useState("connecting"),[h,d]=g.useState(!1),[p,f]=g.useState(""),[m,b]=g.useState(""),[_,v]=g.useState(0),[y,w]=g.useState(!1),[x,S]=g.useState(""),[N]=q5(),[R,E]=g.useState(!1),[M,F]=g.useState(!1),[B,k]=g.useState(!0),A=g.useRef(null),[D,H]=g.useState(()=>{try{return localStorage.getItem(Fy)==="1"}catch{return!1}}),I=g.useRef(D);I.current=D;const[z,T]=g.useState(()=>{try{return localStorage.getItem(Hy)!=="0"}catch{return!0}}),O=g.useRef(z);O.current=z;const K=()=>{const L=!z;T(L);try{localStorage.setItem(Hy,L?"1":"0")}catch{}L||Dt.current.turnEnded()},[U,re]=g.useState(()=>{try{return localStorage.getItem(zy)==="1"}catch{return!1}}),J=()=>{const L=!U;re(L);try{localStorage.setItem(zy,L?"1":"0")}catch{}},[Y,_e]=g.useState(!0),xe=g.useRef(null),[fe,et]=g.useState(""),[Oe,tt]=g.useState(null),Pe=i?{...N,interruptMode:"keyword"}:N,Le=g.useRef(Pe);Le.current=Pe;const Ee=L=>{wk(L).then(et)},Ae=g.useRef(null),Ze=g.useRef(null),me=g.useRef("connecting");me.current=c;const Ye=g.useRef(0),de=g.useRef([]),lt=g.useRef(0),ae=g.useRef(0),be=g.useRef(E5()),Be=g.useRef(0),W=g.useRef(0),Se=g.useRef(0),He=g.useRef(0),q=g.useRef(0),Z=g.useRef(""),ge=g.useRef(null),P=g.useRef(-1),le=g.useRef(0),je=g.useRef(""),Ie=g.useRef(0),Ge=g.useRef(0),ot=g.useRef(!1),dt=g.useRef(!1),[at,Q]=g.useState(!1),ke=g.useRef(!1),Ne=g.useRef([]),$e=g.useRef(!1),gt=g.useRef(0),St=g.useRef(""),Jt=g.useRef(""),dn=g.useRef(""),ye=g.useRef(!1),Dt=g.useRef(new wy),Me=g.useRef(new Set),[kt,Nn]=g.useState(""),Ts=g.useRef(Promise.resolve()),Rn=async L=>{const ce=Ts.current;let X=()=>{};Ts.current=new Promise(ue=>{X=ue}),await ce;try{await L()}finally{X()}},Wn=g.useRef(""),jn=g.useRef(0),zs=g.useRef(""),Rr=g.useRef(!1),$i=g.useRef(!1),wo=g.useRef(Date.now()),Ot=g.useRef(""),ws=g.useRef(!0),ds=g.useRef(!1);ds.current=h;const Tn=g.useSyncExternalStore(ee.subscribe,ee.getSnapshot),jr=g.useMemo(()=>typeof window<"u"&&window.matchMedia?.("(prefers-reduced-motion: reduce)").matches,[]);g.useEffect(()=>{let L=!1;a0(!0);const ce=ue=>{fetch("/api/notify/presence",{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({sessionId:ue?e:null,visible:ue,call:ue})}).catch(()=>{})};return ce(!0),(async()=>{try{const ue=ee.getSnapshot(),Fe=ue.active?.info.id===e?ue.active:void 0;if(pe.cancel(),Fe?.busy){if(L)return;ke.current=!0,$i.current=!0,St.current="",u("thinking");return}const Ut=[...Fe?.msgs??[]].reverse().find(Wt=>Wt.kind==="agent");if(zs.current=Ut?.key??"",Le.current.interruptMode!=="button"){const Wt=await pe.start(a,e);if(L)return;if(!Wt)throw new Error(pe.getSnapshot().error||"无法打开麦克风");u("listening"),Po.load("/vad/silero_vad.onnx").then(Bt=>{L||!Bt||(Po.reset(),pe.setVadTap(_i=>Po.push(_i)))})}else u("listening")}catch(ue){if(L)return;f(String(ue?.message??ue)),u("error")}})(),()=>{L=!0,pe.setVadTap(null),Po.reset(),ws.current=!1,Ft.stop(),pe.cancel(),a0(!1),ce(!1)}},[]),g.useEffect(()=>{if(!_)return;const L=window.setTimeout(()=>v(0),2600);return()=>window.clearTimeout(L)},[_]),g.useEffect(()=>{const L=window.setInterval(()=>{const ce=Le.current,X=pe.getSnapshot(),ue=pe.levelRms(),Fe=sR();P.current=Fe,Fe>.004&&He.current<=.004&&(Se.current=Date.now()),Fe>.004&&(q.current=Date.now()),He.current=Fe;const Ut=`${X.text||""} ${X.interim||""}`.trim();if(Ut!==je.current&&(je.current=Ut,le.current=Date.now()),X.error&&me.current==="listening"){f(X.error),u("error");return}if(ce.interruptMode==="button"&&(me.current==="speaking"||me.current==="thinking")){X.status!=="idle"&&!ds.current&&pe.stop(),Be.current=0,Ge.current=0;return}if(ce.interruptMode==="keyword"&&(me.current==="speaking"||me.current==="thinking")){ds.current||pe.setRelay(!0),Be.current=0;const Bt=Date.now(),_i=Ut,Ir=Math.max(W.current,Se.current),Ui=Bt-Ir>Ly&&Bt-Ie.current>Oy,Ba=Py(ue,Fe,Ge.current,ce.bargeSensitivity,i0()),Ss=U5({heard:_i,own:Z.current,heardAgoMs:Bt-le.current,phrase:ce.wakePhrase,graceOpen:Ui,evidence:Ba,playRms:Fe,muted:ds.current});if(Ss){Ie.current=Bt,pe.resetText(),Dr();return}Fe>.002&&!Ba&&!Ss&&(Ge.current=Ge.current*.88+ue*.12);return}const Wt=me.current==="listening"?Po.ready?Po.st.speech:N5(be.current,ue,Date.now()):!1;if(me.current==="listening"&&(Wt||ue>Y5)&&(ae.current=Date.now()),me.current==="listening"){b((X.text+(X.interim?` ${X.interim}`:"")).trim());const Bt=(X.text||X.interim).trim();if(ce.interruptMode==="keyword"&&!ds.current&&Bt&&vm(Bt,ce.wakePhrase)){pe.resetText(),v(Date.now()),ae.current=0;return}const _i=Date.now()-ae.current;Bt&&!ds.current&&!ot.current&&!dt.current&&$y(Bt)>=ce.minChars&&_i>ce.silenceMs&&!ke.current&&(ke.current=!0,u("thinking"),b(Bt),f(""),zs.current=Ot.current,pe.setRelay(!1),ee.send({t:"prompt",sessionId:e,text:Bt,interrupt:!0}),pe.resetText())}else if(me.current==="speaking"){const Bt=Date.now(),_i=Math.max(W.current,Se.current),Ir=Bt-_i>Ly&&Bt-Ie.current>Oy,Ui=ce.interruptMode==="voice"&&!ds.current&&Ir&&Py(ue,Fe,Ge.current,ce.bargeSensitivity,i0());Ir&&!Ui&&(Ge.current=Ge.current*.88+ue*.12),Be.current=Ui?Be.current+By:0,Be.current>=ce.bargeMs&&(Be.current=0,Ie.current=Bt,Dr())}else Be.current=0},By);return()=>window.clearInterval(L)},[e]);const rt=Tn.active?.info.id===e?Tn.active:void 0,Qe=rt?.msgs??[],Tr=Qe.map(L=>L.kind),Ar=Tr.lastIndexOf("user"),j=Tr.lastIndexOf("agent");Ot.current=j>=0?Qe[j].key??"":"";const V=j>Ar?Qe[j]:void 0,se=V?.kind==="agent"?V.text:"",ze=V?V.at??0:0,Je=V?.key??"",Ct=Tr.lastIndexOf("meta"),Ue=Ct>Ar&&Qe[Ct]?.kind==="meta"?Qe[Ct].text:"",st=!!rt?.busy,Lc=Qe.reduce((L,ce)=>L+(ce.kind==="tool"?1:0),0),mi=Qe.length?Qe[Qe.length-1]:void 0,gi=(()=>{for(let L=Qe.length-1;L>=0;L--){const ce=Qe[L];if(ce.kind==="tool")return ce}})(),Sd=q3({busy:st||c==="thinking",pending:r,newestKind:mi?.kind}),Fi=mi?.kind==="tool"?mi:void 0,xo=Y3({busy:st||c==="thinking",pending:r,newestKind:mi?.kind,newestToolStatus:Fi?.status,newestToolTitle:Fi?.title,newestToolKind:Fi?.kind2}),[kd,Oc]=g.useState(null),Da=(()=>{const L=t5(se);return L.length?L[L.length-1]:Z3(Bh(se))})(),So=()=>{const L=me.current==="speaking"?o0():pe.level();return Number.isFinite(L)?Math.max(0,Math.min(1,L)):0},Mr=()=>{for(const L of Ne.current.slice(0,J5))Ft.prefetch(L,a)};g.useEffect(()=>{const L=me.current;if(L==="connecting"||L==="error"||!Je||Je===zs.current||Je&&Je===Wn.current||jn.current&&ze&&ze<=jn.current)return;if(!Rr.current&&(Rr.current=!0,!zs.current&&!$i.current&&!ke.current&&Je&&Date.now()-wo.current<eI)){zs.current=Je;return}if(G5.test(se.trim())){f("刚才那句没被处理(这个会话正被另一个 Hermes 进程占用),再说一次即可。"),As(!1);return}if(se.trim()&&(Dt.current.answerStarted(),Nn("")),Je!==St.current){const Fe=St.current;St.current=Je,Jt.current&&!ye.current&&dn.current===Fe&&(Ne.current.push(Jt.current),ye.current=!0,Mr()),gt.current=0}const{done:ce,tail:X}=E3(n5(Bh(se)));Jt.current=X,X&&(dn.current=Je),ye.current=!1;const ue=ce.slice(gt.current);ue.length&&(gt.current=ce.length,Ne.current.push(...ue),S(Fe=>`${Fe}${Fe?" ":""}${ue.join(" ")}`),me.current!=="speaking"&&u("speaking"),Mr()),!st&&X&>.current>=ce.length&&(gt.current=ce.length+1,ye.current=!0,Ne.current.push(X),S(Fe=>`${Fe}${Fe?" ":""}${X}`)),!st&&me.current==="thinking"&&!Ne.current.length&&ce.length===0&&!X&&(Ue&&f(Ue),As(!1))},[se,Je,st,Ue]);const[Js,Kn]=g.useState(""),qn=g.useRef(0),fs=g.useRef(0),[Bc,ko]=g.useState(!1),$c=(L=[880,1180])=>{try{const ce=window.AudioContext??window.webkitAudioContext;if(!ce)return;const X=new ce;L.forEach((ue,Fe)=>{const Ut=X.createOscillator(),Wt=X.createGain();Ut.type="sine",Ut.frequency.value=ue,Wt.gain.setValueAtTime(1e-4,X.currentTime+Fe*.16),Wt.gain.exponentialRampToValueAtTime(.16,X.currentTime+Fe*.16+.02),Wt.gain.exponentialRampToValueAtTime(1e-4,X.currentTime+Fe*.16+.15),Ut.connect(Wt).connect(X.destination),Ut.start(X.currentTime+Fe*.16),Ut.stop(X.currentTime+Fe*.16+.18)}),window.setTimeout(()=>void X.close().catch(()=>{}),800)}catch{}};g.useEffect(()=>{const L=()=>{Wu();const ue=Lh();(ue.ctxState==="running"||ue.ctxState==="unavailable")&&X()},ce=["pointerdown","touchstart","keydown","click"],X=()=>{for(const ue of ce)window.removeEventListener(ue,L,!0)};for(const ue of ce)window.addEventListener(ue,L,{capture:!0});return L(),X},[]),g.useEffect(()=>{let L=!0;return zl().then(()=>{L&&ko(!0)}),()=>{L=!1}},[]),g.useEffect(()=>{const L=(st||c==="thinking")&&c!=="speaking"&&Bc&&d3();mm(L),window.__callBed=L?{playing:!0,level:.1}:{playing:!1,level:0}},[st,c,Bc]),g.useEffect(()=>()=>{mm(!1,0)},[]);const Ia=g.useRef(r);g.useEffect(()=>{const L=r>Ia.current,ce=r===0;if(Ia.current=r,L){qn.current=Date.now(),fs.current=0,Kn(r===1?"有个操作等你批准":`有 ${r} 个操作等你批准`),$c(),An({text:r===1?"有个操作等你批准":`有 ${r} 个操作等你批准`,kind:"approval"});return}ce&&(qn.current=0,fs.current=0,Kn(""))},[r]),g.useEffect(()=>{if(r<=0||!qn.current)return;const L=window.__approveRemindMs??[6e4,3e5],ce=window.setInterval(()=>{const X=Date.now()-qn.current;for(;fs.current<L.length&&X>=L[fs.current];){fs.current+=1;const ue=L[fs.current-1],Ut=`审批还挂着,${ue<6e4?`${Math.round(ue/1e3)} 秒`:ue>=3e5?"已经五分钟":`${Math.round(ue/6e4)} 分钟`}了`;Kn(Ut),$c(),An({text:Ut,kind:"approval"})}},1e3);return()=>window.clearInterval(ce)},[r]);const An=async L=>{if(!ws.current||L.kind!=="approval"&&!O.current)return;const ce=me.current;ce!=="thinking"&&ce!=="listening"||dt.current||ot.current||m||Z.current||$e.current||(Nn(L.text),await Rn(async()=>{await Ft.speak(L.text,"call",a).catch(()=>{})}))},Co=g.useRef(!1);g.useEffect(()=>{const L=Date.now();st&&!Co.current?(Dt.current=new wy,Me.current=new Set,Dt.current.turnStarted(L),Nn("")):!st&&Co.current&&(Dt.current.turnEnded(),Nn("")),Co.current=st},[st]),g.useEffect(()=>{if(!st||!O.current)return;const L=Qe[Qe.length-1];if(!L||Me.current.has(L.key))return;const ce=Date.now(),X=Dt.current;let ue=null;if(L.kind==="tool")Me.current.add(L.key),ue=X.tool(ce,L.title||L.kind2||"工具");else if(L.kind==="plan"){Me.current.add(L.key);const Fe=L.items.filter(Ut=>Ut.status==="completed").length;ue=X.plan(ce,Fe,L.items.length)}ue&&An(ue)},[Qe,st,z]),g.useEffect(()=>{if(!st||!z)return;const L=window.setInterval(()=>{const ce=Date.now(),X=Dt.current.thinking(ce)??Dt.current.tick(ce);X&&An(X)},500);return()=>window.clearInterval(L)},[st,z]),g.useEffect(()=>{me.current!=="speaking"||$e.current||($e.current=!0,(async()=>{try{for(;ws.current&&Ne.current.length&&me.current!=="error";){const L=Ne.current.shift();Mr(),W.current=Date.now(),Ge.current=0,Z.current=L;try{await Rn(()=>new Promise((ce,X)=>{ge.current=()=>X(new Error("clip abandoned")),Ft.speak(L,"call",a).then(ce,X)}))}catch{}finally{ge.current=null,Z.current=""}if(!ws.current||me.current!=="speaking")break}}catch{}finally{$e.current=!1,ws.current&&me.current==="speaking"&&!Ne.current.length&&!st&&As(!1)}})())},[c,x,st]);const Pa=g.useRef(!1);Pa.current=st;const zi=g.useRef(l);zi.current=l;const Vn=g.useRef(0);g.useEffect(()=>{const L=window.setInterval(()=>{const ce=me.current;if(ce!=="speaking"&&ce!=="thinking"){Vn.current=0;return}if(me.current==="speaking"&&zi.current.speaking){const ue=P.current>=0,Fe=Date.now()-Math.max(q.current,W.current);if(ue?Fe>Z5:Fe>Q5){Vn.current=0,f(zi.current.error||(ue?"这一句卡住了(合成或播放没有响应),已跳过它继续往下念。":"这一句卡住了,已跳过它继续往下念。")),ge.current?.(),Ft.stop();return}}if(!(!$e.current&&!Ne.current.length&&!zi.current.speaking&&!Pa.current)){Vn.current=0;return}if(!Vn.current){Vn.current=Date.now();return}Date.now()-Vn.current<X5||(Vn.current=0,zi.current.error&&f(zi.current.error),As(!1))},1e3);return()=>window.clearInterval(L)},[e]);const Cd=()=>{ws.current&&v_()},Dr=async()=>{Eo(),await As(!1)},Eo=()=>{Wn.current=Ot.current||St.current,jn.current=Date.now(),Ft.stop();const L=ee.getSnapshot().sessions.find(ue=>ue.id===e)?.status==="running";L&&ee.send({t:"cancel",sessionId:e});const ce=me.current;(L||$e.current||ce==="speaking"||ce==="thinking")&&Cd(),Ne.current=[],gt.current=0,$e.current=!1,ke.current=!1,Jt.current="",dn.current="",ye.current=!0,q.current=Date.now(),pe.setRelay(!1),pe.resetText()},As=async L=>{if(ws.current&&(L&&Ft.stop(),dt.current=!1,Q(!1),Ne.current=[],gt.current=0,$e.current=!1,ke.current=!1,Jt.current="",dn.current="",ye.current=!0,q.current=Date.now(),u("listening"),S(""),b(""),ae.current=Date.now(),pe.setRelay(!1),pe.resetText(),Le.current.interruptMode!=="button"))try{const ce=pe.getSnapshot();if(ce.status==="transcribing"&&pe.cancel(),ce.status==="idle"||ce.status==="error"||ce.status==="transcribing"){if(!await pe.start(a,e))throw new Error(pe.getSnapshot().error||"无法打开麦克风");pe.setRelay(!0)}else pe.setRelay(!0)}catch(ce){f(String(ce?.message??ce)),u("error")}},La=()=>{ws.current=!1,Ft.stop(),pe.cancel(),t()},ne=async()=>{if(h){d(!1);try{await pe.start(a,e),pe.setRelay(me.current==="listening")}catch(L){f(String(L?.message??L))}return}d(!0),pe.stop()},C=async()=>{const L=me.current;if(Le.current.interruptMode==="button"){dt.current?We():await Re();return}if(L==="listening"){const ce=pe.getSnapshot(),X=(ce.text||ce.interim).trim();X&&(ke.current=!0,u("thinking"),f(""),zs.current=Ot.current,pe.setRelay(!1),ee.send({t:"prompt",sessionId:e,text:X,interrupt:!0}),pe.resetText());return}if(L==="speaking"){await Dr();return}if(L==="thinking"){await Dr();return}L==="error"&&await As(!1)},$=async()=>{if(!(ot.current||!ws.current)){ot.current=!0,w(!0),dt.current=!1,Q(!1),Eo(),u("listening"),S(""),b(""),ae.current=Date.now();try{const L=pe.getSnapshot();L.status==="idle"||L.status==="error"||L.status==="transcribing"?await pe.start(a,e):pe.resetText(),pe.setRelay(!0)}catch(L){f(String(L?.message??L)),u("error")}}},te=()=>{const L=pe.getSnapshot(),ce=(L.text||L.interim).trim();ce&&(ke.current=!0,u("thinking"),b(ce),f(""),dt.current=!1,Q(!1),zs.current=Ot.current,Le.current.interruptMode==="button"?pe.cancel():pe.setRelay(!1),ee.send({t:"prompt",sessionId:e,text:ce,interrupt:!0}),pe.resetText())},oe=()=>{if(!ot.current)return;ot.current=!1,w(!1);const L=pe.getSnapshot();if(!(L.text||L.interim).trim()){if(pe.resetText(),Le.current.interruptMode==="button"){pe.cancel(),As(!1);return}pe.setRelay(!0),u("listening");return}te()},Re=async()=>{if(ws.current){ot.current=!1,w(!1),Eo(),dt.current=!0,Q(!0),u("listening"),S(""),b(""),f(""),ae.current=Date.now();try{if(pe.cancel(),!await pe.start(a,e))throw new Error(pe.getSnapshot().error||"无法打开麦克风");pe.setRelay(!0)}catch(L){dt.current=!1,Q(!1),f(String(L?.message??L)),u("error")}}},We=()=>{dt.current=!1,Q(!1);const L=pe.getSnapshot();if(!(L.text||L.interim).trim()){pe.cancel(),As(!1);return}te()},Ke=g.useRef(null),ft=g.useRef({pttStart:$,pttEnd:oe,backToListening:As});ft.current={pttStart:$,pttEnd:oe,backToListening:As},g.useEffect(()=>{const L=ue=>{const Fe=ue;return!Fe||!Fe.tagName?!1:Fe.tagName==="INPUT"||Fe.tagName==="TEXTAREA"||Fe.tagName==="SELECT"||Fe.isContentEditable},ce=ue=>{ue.code!=="Space"||ue.repeat||ue.metaKey||ue.ctrlKey||ue.altKey||!ws.current||L(ue.target)||(ue.preventDefault(),!(Le.current.interruptMode==="button"&&dt.current)&&(Ke.current||(Ke.current={at:Date.now()},ft.current.pttStart())))},X=ue=>{if(ue.code!=="Space"||!Ke.current)return;const Fe=Date.now()-Ke.current.at;if(Ke.current=null,ue.preventDefault(),Fe<150){ot.current=!1,w(!1),pe.cancel(),ft.current.backToListening(!1);return}ft.current.pttEnd()};return window.addEventListener("keydown",ce),window.addEventListener("keyup",X),()=>{window.removeEventListener("keydown",ce),window.removeEventListener("keyup",X)}},[]),g.useEffect(()=>{const L=Ae.current,ce=Ze.current;if(!L||!ce)return;const X=L.getContext("2d"),ue=ce.getContext("2d");if(!X||!ue||i)return;const Fe=Math.min(2,window.devicePixelRatio||1),Ut=()=>I.current?1.25:Fe,Wt=new Float32Array(96);let Bt=0,_i=0;const Ir=()=>{const Ss=Ut(),vi=L.getBoundingClientRect();L.width=Math.max(1,Math.round(vi.width*Ss)),L.height=Math.max(1,Math.round(vi.height*Ss));const Ds=ce.getBoundingClientRect();ce.width=Math.max(1,Math.round(Ds.width*Ss)),ce.height=Math.max(1,Math.round(Ds.height*Ss))};Ir();const Ui=new ResizeObserver(Ir);Ui.observe(L),Ui.observe(ce);const Ba=Ss=>{if(Bt=window.requestAnimationFrame(Ba),I.current&&_i++&1)return;const vi=me.current,Ds=V5[vi],$a=vi==="listening"?pe.level():vi==="speaking"?Math.max(0,o0()):-1,zc=$a<0?-1:$a;Ye.current=zc<0?Ye.current*.9:zc>Ye.current?Ye.current+(zc-Ye.current)*.45:Ye.current*.88+zc*.12;const Hc=Math.min(1,Ye.current),F_=1+.05*Math.sin(Ss/1150),fn=$a<0?.22+.1*Math.sin(Ss/1150):.2+.8*Hc,Wi=Ut(),Uc=L.width/Wi,Wc=L.height/Wi;X.setTransform(Wi,0,0,Wi,0,0),X.clearRect(0,0,Uc,Wc);const Yn=Uc/2,Gn=Wc/2,MC=Math.min(Uc,Wc)*(I.current?.52:.33),jo=Math.sin(Ss/900)*(3+14*fn),To=Math.cos(Ss/1410)*(2+10*fn),DC=1+.05*Math.sin(Ss/770)*(.4+fn),Et=MC*(.86+.34*fn)*F_*DC,Mn=`${Ds.core[0]},${Ds.core[1]},${Ds.core[2]}`,Pr=de.current,Fa=Ss;($a>=0?Hc>.4&&Fa-lt.current>380:Fa-lt.current>1300)&&vi!=="connecting"&&(lt.current=Fa,Pr.push({born:Fa,strength:$a>=0?.6+.4*Hc:.4}),Pr.length>6&&Pr.shift()),X.globalCompositeOperation="lighter";for(let _t=0;_t<3;_t++){const ms=Ss/(2100+_t*900)+_t*Math.PI*2/3,ut=Et*(.1+.11*_t)*(.8+.5*fn),Nt=Yn+Math.cos(ms)*ut+jo*.8,Lr=Gn+Math.sin(ms)*ut+To*.8,Or=Et*Math.min(1.22+.16*_t,.98*(Math.min(Uc,Wc)/2)/Et)*(.95+.2*fn),Kc=X.createRadialGradient(Nt,Lr,0,Nt,Lr,Or);Kc.addColorStop(0,`rgba(${Mn},0.20)`),Kc.addColorStop(.45,`rgba(${Mn},0.09)`),Kc.addColorStop(1,"rgba(0,0,0,0)"),X.fillStyle=Kc,X.beginPath(),X.arc(Nt,Lr,Or,0,Math.PI*2),X.fill()}const za=X.createRadialGradient(Yn+jo,Gn+To,Et*.82,Yn+jo,Gn+To,Et*1.42);za.addColorStop(0,`rgba(${Mn},0)`),za.addColorStop(.22,`rgba(${Mn},${.42-.16*fn})`),za.addColorStop(.6,`rgba(${Mn},${.14-.06*fn})`),za.addColorStop(1,"rgba(0,0,0,0)"),X.fillStyle=za,X.beginPath(),X.arc(Yn+jo,Gn+To,Et*1.42,0,Math.PI*2),X.fill();for(let _t=Pr.length-1;_t>=0;_t--){const ms=(Fa-Pr[_t].born)/(jr?2600:1400);if(ms>=1){Pr.splice(_t,1);continue}const ut=Et*(1+ms*1.05)*F_;X.beginPath(),X.arc(Yn+jo*.3,Gn+To*.3,ut,0,Math.PI*2),X.strokeStyle=`rgba(${Mn},${(1-ms)*.5*Pr[_t].strength})`,X.lineWidth=1.2+2.4*(1-ms),X.stroke()}const Ha=Yn+jo*.7,Ua=Gn+To*.7,Ao=X.createRadialGradient(Ha-Et*.18,Ua-Et*.18,Et*.05,Ha,Ua,Et);Ao.addColorStop(0,`rgba(255,255,255,${.92-.18*fn})`),Ao.addColorStop(.3,`rgba(${Mn},0.92)`),Ao.addColorStop(.66,`rgba(${Mn},0.62)`),Ao.addColorStop(.88,`rgba(${Mn},0.28)`),Ao.addColorStop(1,`rgba(${Mn},0)`),X.fillStyle=Ao,X.beginPath(),X.arc(Ha,Ua,Et,0,Math.PI*2),X.fill(),X.globalCompositeOperation="source-over",X.beginPath(),X.arc(Ha,Ua,Et*.97,0,Math.PI*2),X.strokeStyle="rgba(255,255,255,0.10)",X.lineWidth=1.4,X.stroke(),X.beginPath(),X.arc(Ha,Ua,Et*.985,-2.5,-.35),X.strokeStyle=`rgba(255,255,255,${.42-.12*fn})`,X.lineWidth=2,X.lineCap="round",X.stroke();const jd=X.createRadialGradient(Yn-Et*.34,Gn-Et*.42,0,Yn-Et*.34,Gn-Et*.42,Et*.55);if(jd.addColorStop(0,"rgba(255,255,255,0.40)"),jd.addColorStop(1,"rgba(255,255,255,0)"),X.fillStyle=jd,X.beginPath(),X.arc(Yn-Et*.34,Gn-Et*.42,Et*.55,0,Math.PI*2),X.fill(),!jr){X.globalCompositeOperation="lighter";for(let _t=0;_t<3;_t++){const ms=Ss/(1150+_t*520)+_t*2.1,ut=Et*(1.08+.11*_t),Nt=Yn+Math.cos(ms)*ut,Lr=Gn+Math.sin(ms)*ut*.95,Or=X.createRadialGradient(Nt,Lr,0,Nt,Lr,9);Or.addColorStop(0,`rgba(255,255,255,${.5+.4*fn})`),Or.addColorStop(.35,`rgba(${Mn},${.4+.3*fn})`),Or.addColorStop(1,"rgba(0,0,0,0)"),X.fillStyle=Or,X.beginPath(),X.arc(Nt,Lr,9,0,Math.PI*2),X.fill()}}X.globalCompositeOperation="source-over";const Td=ce.width/Wi,Ki=ce.height/Wi;ue.setTransform(Wi,0,0,Wi,0,0),ue.clearRect(0,0,Td,Ki);let Ad=!1;if(vi==="listening"){const _t=pe.wave(),ms=Math.max(1,Math.floor(_t.length/Wt.length));for(let ut=0,Nt=0;ut<Wt.length;ut++,Nt+=ms)Wt[ut]=_t[Nt]??0;Ad=!0}else vi==="speaking"&&(Ad=nR(Wt));if(Ad){const _t=ut=>({x:ut/(Wt.length-1)*Td,y:Ki/2-Wt[ut]*Ki*1.35});ue.beginPath();for(let ut=0;ut<Wt.length;ut++){const Nt=_t(ut);ut?ue.lineTo(Nt.x,Nt.y):ue.moveTo(Nt.x,Nt.y)}for(let ut=Wt.length-1;ut>=0;ut--){const Nt=_t(ut);ue.lineTo(Nt.x,Ki/2-(Nt.y-Ki/2)*.35)}ue.closePath();const ms=ue.createLinearGradient(0,0,0,Ki);ms.addColorStop(0,`rgba(${Ds.core[0]},${Ds.core[1]},${Ds.core[2]},0.05)`),ms.addColorStop(.5,`rgba(${Ds.core[0]},${Ds.core[1]},${Ds.core[2]},0.30)`),ms.addColorStop(1,`rgba(${Ds.core[0]},${Ds.core[1]},${Ds.core[2]},0.05)`),ue.fillStyle=ms,ue.fill(),ue.beginPath();for(let ut=0;ut<Wt.length;ut++){const Nt=_t(ut);ut?ue.lineTo(Nt.x,Nt.y):ue.moveTo(Nt.x,Nt.y)}ue.strokeStyle=`rgba(255,255,255,${.55+.3*Hc})`,ue.lineWidth=1.7,ue.lineJoin="round",ue.lineCap="round",ue.stroke()}else ue.beginPath(),ue.moveTo(0,Ki/2),ue.lineTo(Td,Ki/2),ue.strokeStyle="rgba(255,255,255,0.07)",ue.lineWidth=1,ue.stroke()};return Bt=window.requestAnimationFrame(Ba),()=>{window.cancelAnimationFrame(Bt),Ui.disconnect()}},[jr,i]);const xs=Qe.length?Uy(Qe[Qe.length-1]).text:"";g.useEffect(()=>{if(!M||!B)return;const L=A.current;L&&(L.scrollTop=L.scrollHeight)},[M,B,Qe.length,xs]);const Ms=()=>{const L=A.current;L&&k(L.scrollHeight-L.scrollTop-L.clientHeight<24)},Hi=()=>{const L=A.current;L&&(L.scrollTop=L.scrollHeight),k(!0)},Oa=()=>{M||k(!0),F(!M)},ps=()=>{const L=!D;H(L),L&&_e(!0);try{localStorage.setItem(Fy,L?"1":"0")}catch{}},Fc=()=>{const L=xe.current;L&&_e(L.scrollHeight-L.scrollTop-L.clientHeight<28)},jC=()=>{const L=xe.current;L&&(L.scrollTop=L.scrollHeight),_e(!0)};g.useEffect(()=>{if(!D||!Y)return;const L=xe.current;L&&(L.scrollTop=L.scrollHeight)},[D,Y,Qe.length,m,x,c]);const Ed=$y(m),B_=c==="listening"&&Ed>0&&Ed<N.minChars,Nd=N.interruptMode==="keyword"?`唤醒词「${N.wakePhrase||"未设置"}」${m?` · 听到:${m.slice(-18)}`:""}`:"",No=c==="listening"&&_?`听到「${N.wakePhrase}」了`:c==="listening"?m?Ed<N.minChars?`太短了(少于 ${N.minChars} 字,不会自动发送)——继续说,或点一下圆球直接发送`:"点一下直接发送,或说完停一下":h?"麦克风已静音":N.interruptMode==="button"?at?"正在听你说,说完点「结束」":"点「开始说话」,或按住圆球/空格说话":Nd||"说点什么…":c==="speaking"?N.interruptMode==="voice"?"说一句就能打断它,点圆球也可以":N.interruptMode==="keyword"?`${Nd} · 说唤醒词打断`:"点「打断」就开口,说完再点「结束」":c==="thinking"?N.interruptMode==="keyword"?`${Nd} · 说唤醒词打断`:N.interruptMode==="button"?"点「打断」就开口,说完再点「结束」":"点一下停止它":"",Ro=c==="speaking"||c==="thinking",TC=c==="listening"&&!y&&m.trim().length>0,Rd=o.jsxs("button",{type:"button",className:`call-floor is-ptt${y?" on":""}`,onPointerDown:L=>{L.preventDefault();try{L.currentTarget.setPointerCapture(L.pointerId)}catch{}$()},onPointerUp:L=>{L.preventDefault(),oe()},onPointerCancel:()=>oe(),onLostPointerCapture:()=>oe(),onContextMenu:L=>L.preventDefault(),"aria-pressed":y,title:"按住说话,松开就发出去;按住的时候不会自动发送","aria-label":y?"松开发送":"按住说话",children:[o.jsx(ji,{size:17}),o.jsx("span",{children:y?"松开发送":"按住说话"})]}),AC=_k.filter(L=>L.id!=="voice"||U||N.interruptMode==="voice"),$_=o.jsx("div",{className:"call-modes",role:"group","aria-label":"打断方式","data-mode":N.interruptMode,children:AC.map(L=>o.jsx("button",{type:"button",className:`call-mode-btn ${N.interruptMode===L.id?"on":""}`,"aria-pressed":N.interruptMode===L.id,title:L.hint,onClick:()=>Ee({interruptMode:L.id}),children:L.label},L.id))});return cc.createPortal(o.jsxs("div",{className:"call-mode","data-phase":c,"data-mood":i?Da:void 0,"data-face":i?kd??void 0:void 0,"data-substate":i?xo:void 0,"data-caption":D,"data-tus":i?"true":"false",role:"dialog","aria-modal":"true","aria-label":i?"Tus 模式通话":"语音通话",children:[o.jsx("button",{type:"button",className:"call-gear",onClick:()=>E(!0),"aria-label":"通话设置",title:"通话设置",children:o.jsx(Tc,{size:18})}),o.jsx("button",{type:"button",className:`call-cc-btn${D?" on":""}`,onClick:ps,"aria-pressed":D,"aria-label":D?"收起聊天记录":"显示聊天记录",title:D?"收起聊天记录":"显示聊天记录",children:o.jsx(jN,{size:18})}),!D&&!i?o.jsxs("div",{className:"call-head",children:[o.jsx("span",{className:"call-title",children:Lo[c]}),o.jsx("span",{className:"call-sub",children:h?"麦克风已静音":"免提 · 语音通话"}),$_]}):null,Js&&!D?o.jsx("p",{className:"call-cue call-cue-stage call-approve","data-cue":Js,children:Js}):null,!Js&&kt&&!D?o.jsx("p",{className:"call-cue call-cue-stage","data-cue":kt,children:kt}):null,o.jsx("button",{type:"button",className:"call-orb",onClick:()=>void C(),"aria-label":`${Lo[c]} — ${No||"点击切换"}`,title:No,children:o.jsx("canvas",{ref:Ae,className:"call-orb-canvas"})}),i?o.jsxs("div",{className:"call-tus-face","data-substate":xo,children:[o.jsx(C5,{phase:c,activity:Sd,substate:xo,emotion:Da,ticks:Lc,toolStatus:gi?.status??"",getLevel:So,onMood:Oc}),o.jsxs("div",{className:"tus-face-foot",children:[o.jsx("span",{className:"tus-face-state",children:Lo[c]}),i&&!N.wakePhrase?o.jsx("span",{className:"tus-face-warn",title:"Tus 模式固定用关键词打断;没设唤醒词时只有按住说话能抢话筒",children:"Tus 模式用关键词打断 · 还没设唤醒词"}):null]})]}):null,D||i?o.jsxs("div",{className:"call-cc",children:[o.jsxs("div",{className:"call-cc-head",children:[o.jsxs("button",{type:"button",className:"call-cc-state",onClick:()=>void C(),title:No||"点击切换","aria-label":`${Lo[c]} — ${No||"点击切换"}`,children:[o.jsx("span",{className:"call-cc-dot","aria-hidden":"true"}),Lo[c]]}),$_,o.jsxs("span",{className:"call-cc-n",children:[Qe.length," 条"]})]}),o.jsx("div",{className:"call-cc-list",ref:xe,onScroll:Fc,role:"log","aria-live":"polite",children:o.jsxs("div",{className:"call-cc-inner",children:[n&&rt?n({msgs:Qe,sid:e,backend:rt.info.backend,busy:!!rt.busy,base:rt.info.workspace||rt.info.cwd,speaking:c==="speaking"}):null,c==="listening"&&m?o.jsxs("div",{className:"msg user live",children:[o.jsx("div",{className:"role",children:"YOU"}),o.jsx("div",{className:"bubble",children:m})]}):null,Js&&!p?o.jsx("p",{className:"call-cue call-approve","data-cue":Js,children:Js}):null,!Js&&kt&&!p?o.jsx("p",{className:"call-cue","data-cue":kt,children:kt}):null,p?o.jsx("p",{className:"call-err",children:p}):null,!p&&l.error?o.jsx("p",{className:"call-err",children:l.error}):null,!p&&l.note?o.jsx("p",{className:"call-note",children:l.note}):null,!m&&!Qe.length||B_?o.jsx("p",{className:"call-hint",children:No}):null]})}),Y?null:o.jsx("button",{type:"button",className:"call-cc-latest",onClick:jC,children:"回到最新 ↓"}),o.jsx("div",{className:`call-floor-row${Ro||N.interruptMode==="button"?"":" single"}`,children:N.interruptMode==="button"?o.jsxs(o.Fragment,{children:[o.jsxs("button",{type:"button",className:`call-floor is-take${at?" on":""}`,onClick:()=>{at?We():Re()},title:Ro?"停下它,接着说你的":at?"说完了,再点一下就发出去":"点一下开始说,说完再点一下发送;不会自己发出去","aria-label":Ro?"打断":at?"结束":"开始说话","aria-pressed":at,children:[Ro?o.jsx(xh,{size:17}):at?o.jsx(Sh,{size:17}):o.jsx(ji,{size:17}),o.jsx("span",{children:Ro?"打断":at?"结束":"开始说话"})]}),Rd]}):Ro?o.jsxs(o.Fragment,{children:[o.jsxs("button",{type:"button",className:"call-floor is-take",onClick:()=>void Dr(),title:"停下它,接着说你的","aria-label":"打断",children:[o.jsx(xh,{size:17}),o.jsx("span",{children:"打断"})]}),Rd]}):TC?o.jsxs("button",{type:"button",className:"call-floor is-done",onClick:()=>te(),title:"说完了就把这句发出去,不用等它判断停顿","aria-label":"说完了",children:[o.jsx(Sh,{size:17}),o.jsx("span",{children:"说完了"})]}):Rd})]}):o.jsxs(o.Fragment,{children:[o.jsxs("div",{className:"call-lines",children:[m?o.jsx("p",{className:"call-heard",children:m}):null,x?o.jsx("p",{className:"call-reply",children:x}):null,p?o.jsx("p",{className:"call-err",children:p}):null,!p&&l.error?o.jsx("p",{className:"call-err",children:l.error}):null,!p&&l.note?o.jsx("p",{className:"call-note",children:l.note}):null,!m&&!x&&!p||B_?o.jsx("p",{className:"call-hint",children:No}):null]}),o.jsxs("div",{className:"call-hist","data-open":M,children:[o.jsxs("button",{type:"button",className:"call-hist-bar",onClick:Oa,"aria-expanded":M,"aria-label":M?"收起历史聊天记录":"翻阅历史聊天记录",title:M?"收起":"翻阅历史聊天记录",children:[o.jsx(RN,{size:15}),o.jsx("span",{className:"call-hist-title",children:"历史记录"}),o.jsxs("span",{className:"call-hist-n",children:[Qe.length," 条"]}),!M&&xs?o.jsx("span",{className:"call-hist-peek",children:xs.slice(0,60)}):null,o.jsx("span",{className:"call-hist-chev","aria-hidden":"true",children:o.jsx(ya,{size:14})})]}),M?o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"call-hist-list",ref:A,onScroll:Ms,children:Qe.map((L,ce)=>{const X=Uy(L);return o.jsx(tI,{kind:X.kind,who:X.who,text:X.text,current:ce===Qe.length-1&&c==="speaking"},L.key)})}),B?null:o.jsx("button",{type:"button",className:"call-hist-back",onClick:Hi,children:"回到最新 ↓"})]}):null]})]}),o.jsx("canvas",{ref:Ze,className:"call-wave","aria-hidden":"true"}),o.jsxs("div",{className:"call-controls",children:[o.jsx("button",{type:"button",className:`call-btn ${h?"on":""}`,onClick:()=>void ne(),"aria-pressed":h,title:h?"打开麦克风":"静音麦克风",children:h?o.jsx(bN,{size:18}):o.jsx(ji,{size:18})}),o.jsx("button",{type:"button",className:"call-btn hangup",onClick:La,title:"挂断","aria-label":"挂断",children:o.jsx(yN,{size:20})}),o.jsx("button",{type:"button",className:"call-btn",onClick:s,title:"改用键盘","aria-label":"改用键盘",children:o.jsx(wN,{size:18})})]}),R?o.jsx("div",{className:"call-sheet",role:"dialog","aria-label":"通话设置",children:o.jsxs("div",{className:"call-sheet-card",children:[o.jsxs("div",{className:"call-sheet-head",children:[o.jsx("span",{children:"通话设置"}),o.jsx("button",{type:"button",className:"call-sheet-x",onClick:()=>E(!1),"aria-label":"关闭设置",children:o.jsx(En,{size:16})})]}),o.jsx("p",{className:"call-sheet-note",children:fe?`保存失败:${fe}(已在本机生效)`:"调整立即生效,并保存到服务器(换设备也一样)"}),N.interruptMode==="button"?o.jsx("p",{className:"call-sheet-warn",children:"现在是「按键打断」:它说话的时候麦克风是关的 —— 不识别、不抢话,只在你说完之后才重新打开。 所以灵敏度和持续时间这会儿不起作用(切回「语音打断」就恢复)。"}):null,Pe.interruptMode==="keyword"?o.jsxs("label",{className:"call-knob",children:[o.jsxs("span",{className:"call-knob-top",children:[o.jsx("span",{className:"call-knob-name",children:"唤醒词"}),o.jsx("span",{className:"call-knob-val",children:(Oe??N.wakePhrase)||"未设置"})]}),o.jsx("input",{type:"text",value:Oe??N.wakePhrase,placeholder:"例如:小灵 / hey agent",onChange:L=>tt(L.target.value),onBlur:()=>{Oe!==null&&(Ee({wakePhrase:yk(Oe)}),tt(null))},onKeyDown:L=>{L.key==="Enter"&&L.currentTarget.blur()},"aria-label":"唤醒词"}),o.jsx("span",{className:"call-knob-hint",children:"只有听到这句话才抢话(关键词打断)。空着 = 这个模式不生效,不会误触发。 灵敏度在这一档仍然有用:它决定「多大声才算压过外放的回声」;持续时间不起作用。"})]}):null,o.jsx("p",{className:`call-sheet-echo ${cf().echoCancellation===!1?"bad":""}`,children:cf().echoCancellation===!1?"回声消除没生效:这台设备只给了原始麦克风。外放时它容易把自己当成你——用「按键打断」,或者戴耳机":cf().echoCancellation===!0?"回声消除:已生效(抢话要盖过你听到的那个声音,不会自己打断自己)":"回声消除:这台设备没报告(浏览器语音路径)——抢话按「比回复更响」判断"}),o.jsxs("label",{className:"call-check",children:[o.jsx("input",{type:"checkbox",checked:z,onChange:K,"aria-label":"干活期间报进度"}),o.jsxs("span",{children:[o.jsx("span",{className:"call-check-name",children:"干活期间报进度"}),o.jsx("span",{className:"call-check-hint",children:"它去跑工具、深思考、等计划推进的时候,隔一阵用一句话告诉你还在干什么(「我查一下」 「在跑 terminal」「第 2 步,共 5 步」)。答案一开始读就闭嘴,一轮最多三句。"})]})]}),o.jsxs("label",{className:"call-check",children:[o.jsx("input",{type:"checkbox",checked:U,onChange:J,"aria-label":"在通话页显示语音打断"}),o.jsxs("span",{children:[o.jsx("span",{className:"call-check-name",children:"在通话页显示「语音打断」"}),o.jsx("span",{className:"call-check-hint",children:"默认收起:它说一句就能打断,外放、嘈杂的房间里也最容易自己打断自己。 勾上之后它回到通话页那一排,阈值和判定跟以前一样。"})]})]}),L5.map(L=>o.jsxs("label",{className:`call-knob ${L.key==="bargeMs"?N.interruptMode!=="voice"?"off":"":N.interruptMode==="button"?"off":""}`,children:[o.jsxs("span",{className:"call-knob-top",children:[o.jsx("span",{className:"call-knob-name",children:L.label}),o.jsx("span",{className:"call-knob-val",children:L.show(N[L.key])})]}),o.jsx("input",{type:"range",min:$h[L.key][0],max:$h[L.key][1],step:L.key==="bargeSensitivity"?5:L.key==="silenceMs"?100:L.key==="minChars"?1:50,value:N[L.key],onChange:ce=>Ee({[L.key]:Number(ce.target.value)}),"aria-label":L.label,disabled:N.interruptMode!=="voice"&&L.key.startsWith("barge")}),o.jsxs("span",{className:"call-knob-ends",children:[o.jsx("span",{children:L.ends[0]}),o.jsx("span",{children:L.ends[1]})]}),o.jsx("span",{className:"call-knob-hint",children:L.hint})]},L.key)),o.jsxs("div",{className:"call-sheet-foot",children:[o.jsx("button",{type:"button",className:"call-sheet-btn",onClick:()=>Ee(Ac),children:"恢复默认"}),o.jsx("button",{type:"button",className:"call-sheet-btn primary",onClick:()=>E(!1),children:"完成"})]})]})}):null,o.jsx("p",{className:"sr-only","aria-live":"polite",children:Lo[c]})]}),document.body)}function x_({size:e=22}){const t=tk();return o.jsx("img",{className:"brand-mark",src:t?"/icons/agentus-mark-inverse.svg":"/icons/agentus-mark.svg",width:e,height:Math.round(e*(880/1484)),alt:"","aria-hidden":"true",draggable:!1})}const nI=12e4;function iI(e){if(!e.visible)return!1;const t=e.idleMs??nI;return e.now-e.lastInputAt<t}const rI=6;function S_({value:e,onChange:t}){const[s,n]=g.useState(null),[i,r]=g.useState(e),[a,l]=g.useState(!1),[c,u]=g.useState(""),h=async f=>{const m=f?`?path=${encodeURIComponent(f)}`:"",b=await fetch(`/api/fs/dirs${m}`),_=await b.json().catch(()=>({}));if(!b.ok)throw new Error(_.error??`HTTP ${b.status}`);return _},d=async(f,m=!1)=>{l(!0),u("");try{const b=await h(f);if(n(b),!m)return;const _=b.recent?.[0]||b.path;if(!_)return;t(_),_!==b.path&&n(await h(_))}catch(b){u(String(b?.message??b))}finally{l(!1)}};g.useEffect(()=>{d(e||"",!e)},[]),g.useEffect(()=>{r(e)},[e]);const p=f=>{const m=f.trim();m&&(t(m),d(m))};return o.jsxs("div",{className:"wp",children:[o.jsxs("div",{className:"wp-bar",children:[o.jsx("input",{className:"wp-path",value:i,spellCheck:!1,onChange:f=>r(f.target.value),onKeyDown:f=>{f.key==="Enter"&&(f.preventDefault(),p(i))},placeholder:"~/project — Enter 选中","aria-label":"选中的工作目录"}),o.jsx("button",{className:"wp-use",disabled:a||!i.trim()||i.trim()===e,title:"选中这个目录",onClick:()=>p(i),children:"选中"}),o.jsx("button",{className:"icon-btn",title:"home","aria-label":"home",disabled:a,onClick:()=>void d(s?.home??""),children:o.jsx(_S,{size:14})}),o.jsx("button",{className:"icon-btn",title:"上一级目录","aria-label":"上一级目录",disabled:a||!s?.parent,onClick:()=>s?.parent&&void d(s.parent),children:o.jsx(yS,{size:14})})]}),s?.recent?.length?o.jsx("div",{className:"wp-recent",children:s.recent.slice(0,rI).map(f=>o.jsx("button",{className:`wp-chip ${e===f?"sel":""}`,title:`选中 ${f}`,onClick:()=>p(f),children:f.split("/").filter(Boolean).pop()??f},f))}):null,o.jsxs("div",{className:"wp-list",role:"listbox","aria-label":"folders",children:[a&&!s?o.jsx("div",{className:"wp-note",children:"loading…"}):null,c?o.jsx("div",{className:"wp-note err",children:c}):null,s?.entries.map(f=>o.jsxs("div",{role:"option","aria-selected":e===f.path,className:`wp-row ${e===f.path?"sel":""}`,onClick:()=>t(f.path),title:`选中 ${f.path}`,children:[o.jsx(uo,{size:13}),o.jsx("span",{className:"wp-name",children:f.name}),o.jsx("button",{className:"wp-enter",title:`进入 ${f.name}`,"aria-label":`进入 ${f.name}`,onClick:m=>{m.stopPropagation(),d(f.path)},children:o.jsx(an,{size:13})})]},f.path)),s&&!s.entries.length&&!c?o.jsx("div",{className:"wp-note",children:"这里没有子目录 —— 点这一行就是选中它"}):null,s?.truncated?o.jsx("div",{className:"wp-note",children:"只列出前 300 项"}):null]})]})}function oI(e){const t=e.split("/").filter(Boolean);return t.length?t[t.length-1]:e}function aI({value:e,onChange:t,locked:s=!1,testId:n="ws-pill"}){const[i,r]=g.useState(!1),[a,l]=g.useState(e);return o.jsxs(o.Fragment,{children:[o.jsxs("button",{type:"button",className:`ws-pill ${e?"":"empty"} ${s?"locked":""}`,"data-testid":n,"aria-label":"工作空间",title:e||"选择这个会话在哪个目录里跑",disabled:s,onClick:()=>{l(e),r(!0)},children:[o.jsx(uo,{size:14}),o.jsx("span",{className:"ws-pill-name",children:e?oI(e):"选择工作空间"}),s?null:o.jsx(ya,{size:11})]}),i?o.jsx("div",{className:"modal-bg ws-modal-bg",onClick:()=>r(!1),children:o.jsxs("div",{className:"modal ws-modal",onClick:c=>c.stopPropagation(),children:[o.jsx("h3",{children:"工作空间"}),o.jsx(S_,{value:a,onChange:c=>{t(c),r(!1)}}),o.jsx("div",{className:"row",children:o.jsx("button",{className:"cancel",onClick:()=>r(!1),children:"取消"})})]})}):null]})}/**
|
|
76
76
|
* Copyright (c) 2014-2024 The xterm.js authors. All rights reserved.
|
|
77
77
|
* @license MIT
|
|
78
78
|
*
|
|
@@ -126,6 +126,6 @@ click to point this session at another directory`,"aria-label":"change workspace
|
|
|
126
126
|
click to point this session at another directory`,"aria-label":"workspace",onClick:i,children:o.jsx(uo,{})}),o.jsx("button",{className:`icon-btn ${s?"on":""}`,title:"workspace panel — files and terminal","aria-label":"workspace panel","aria-expanded":s,onClick:n,children:o.jsx(pN,{})})]})]})}const Kl={current:()=>{}},Yb=4,pB=g.memo(function({busy:t,lastAt:s}){const[,n]=g.useState(0);if(g.useEffect(()=>{if(!t)return;const a=window.setInterval(()=>n(l=>l+1),1e3);return()=>window.clearInterval(a)},[t]),!t)return null;const{quiet:i,said:r}=b3(s,Date.now());return o.jsx("span",{className:`turn-pulse ${i?"quiet":""}`,role:"status","aria-label":r,title:r})}),mB=g.memo(function({busy:t,since:s}){const[n,i]=g.useState(null),[r,a]=g.useState(()=>Date.now());if(g.useEffect(()=>{if(!t){i(null);return}i(s??Date.now()),a(Date.now());const c=window.setInterval(()=>a(Date.now()),1e3);return()=>window.clearInterval(c)},[t,s]),!t)return null;const l=n??s;return o.jsxs("div",{className:"stream-hint",role:"status","data-anchor":l??void 0,children:[o.jsx("span",{className:"stream-spin","aria-hidden":"true"}),o.jsx("span",{children:"处理中"}),l!=null?o.jsxs("span",{className:"elapsed",children:["(",Oh(r-l),")"]}):null]})});function gB({v:e}){const t=e.background??[],[s,n]=g.useState(!1);if(!t.length)return null;const i=t.filter(c=>c.status==="running"),r=t.filter(c=>c.status!=="running"),a=i.reduce((c,u)=>c+(u.kind==="delegation"?u.taskCount??1:0),0),l=i.length?`后台任务 ${i.length} 个运行中${a?`(含 ${a} 个子任务)`:""} · 完成后会唤醒会话`:`${r.length} 个后台任务已结束`;return o.jsxs("div",{className:`bg-row ${s?"open":""}`,"data-count":t.length,children:[o.jsxs("button",{type:"button",className:"bg-head","aria-expanded":s,onClick:()=>n(!s),children:[o.jsx("span",{className:"bg-dot","aria-hidden":"true","data-state":i.length?"running":"exited","data-wake":i.length?"1":void 0}),o.jsx("span",{className:"bg-text",children:l}),i.length&&!e.busy?o.jsx("span",{className:"bg-hint",children:"会话已空闲,后台仍在跑"}):null,o.jsx("span",{className:"bg-caret","aria-hidden":"true",children:s?"▾":"▸"})]}),s&&o.jsx("ul",{className:"bg-list",children:t.map(c=>o.jsxs("li",{className:"bg-item","data-state":c.status,"data-kind":c.kind??"process",children:[c.kind==="delegation"?o.jsx("span",{className:"bg-tag",children:"子任务"}):null,o.jsx("pre",{className:"bg-cmd-full",children:c.command||c.id}),o.jsxs("div",{className:"bg-item-foot",children:[o.jsx("span",{className:"bg-meta",children:c.kind==="delegation"?o.jsxs(o.Fragment,{children:[(c.taskCount??1)>1?`${c.taskCount} 个子代理 · `:"",c.status==="running"?`运行 ${Oh((c.uptimeSeconds??0)*1e3)}${c.phase==="stalling"?" · 停滞中":c.phase==="finalizing"?" · 收尾中":""}`:"已结束"]}):o.jsxs(o.Fragment,{children:[c.pid?`pid ${c.pid} · `:"",c.status==="running"?`运行 ${Oh((c.uptimeSeconds??0)*1e3)}`:`exit ${c.exitCode??"?"}`]})}),c.command?o.jsx(Vh,{text:c.command,what:c.kind==="delegation"?"这个目标":"这条命令"}):null]})]},c.id))})]})}function ju({n:e}){const t=new Date(e.at),s=`${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}:${String(t.getSeconds()).padStart(2,"0")}`,n=e.items??[],[i,r]=g.useState(!1),a=g.useRef(null),[l,c]=g.useState(!1);return g.useLayoutEffect(()=>{if(!i){c(!1);return}const u=a.current;if(!u)return;const h=()=>c(u.scrollHeight-u.clientHeight>4);h();const d=new ResizeObserver(h);return d.observe(u),()=>d.disconnect()},[i,n.length]),o.jsxs("div",{className:"status-note","data-kind":e.kind||"lifecycle",role:"note",title:t.toLocaleString(),children:[o.jsx("span",{className:"status-note-time",children:s}),o.jsx("span",{className:"status-note-text",children:e.text}),n.length?o.jsxs(o.Fragment,{children:[o.jsx("button",{type:"button",className:"status-note-toggle","aria-expanded":i,"aria-label":`${i?"收起":"展开"}这 ${n.length} 条记忆`,onClick:()=>r(u=>!u),children:i?"收起":`${n.length} 条`}),i?o.jsx("div",{className:"status-note-drawer-wrap",children:o.jsxs("div",{className:"status-note-drawer","data-scroll":l?"1":"0",children:[o.jsxs("div",{className:"status-note-drawer-head",children:[o.jsxs("span",{children:["共 ",n.length," 条"]}),l?o.jsx("span",{className:"status-note-drawer-hint",children:"滚轮查看"}):null]}),o.jsxs("ol",{className:"status-note-items",ref:a,children:[n.map((u,h)=>o.jsxs("li",{className:"status-note-item",children:[o.jsx("span",{className:"status-note-item-n",children:h+1}),o.jsxs("span",{className:"status-note-item-body",children:[o.jsx("span",{className:"status-note-item-text",children:u.text}),u.tags?.length?o.jsx("span",{className:"status-note-item-tags",children:u.tags.join(" · ")}):null]})]},h)),e.truncated?o.jsx("li",{className:"status-note-item more",children:"…还有更多,已截断"}):null]})]})}):null]}):null]})}function gC({msgs:e,sid:t,backend:s,busy:n,base:i,notes:r=[],speaking:a=!1}){const l=jB(e),c=a?l.map(d=>d.kind==="msg"&&d.m.kind==="thought"&&d.live?{...d,live:!1}:d):l,u=[];let h=0;for(;h<r.length&&r[h].afterKey===null;)u.push(o.jsx(ju,{n:r[h]},r[h].key)),h++;for(const d of c){d.kind==="work"?(u.push(o.jsx(TB,{items:d.items},d.key)),u.push(o.jsx(Xb,{msgs:d.items},`fc-${d.key}`))):d.m.kind==="note"?u.push(o.jsx(ju,{n:{key:d.m.key,kind:d.m.category,text:d.m.text,at:d.m.at??Date.now(),hits:d.m.hits,items:d.m.items,truncated:d.m.truncated}},d.m.key)):(u.push(o.jsx(kB,{m:d.m,sid:t,backend:s,busy:n,last:d.tail,live:d.live,base:i},d.m.key)),d.m.kind==="tool"&&u.push(o.jsx(Xb,{msgs:[d.m]},`fc-${d.m.key}`)));const p=new Set(d.kind==="msg"?[d.m.key]:d.items.map(f=>f.key));for(let f=r[h];f&&f.afterKey!==null&&p.has(f.afterKey);f=r[h])u.push(o.jsx(ju,{n:f},f.key)),h++}for(;h<r.length;)u.push(o.jsx(ju,{n:r[h]},r[h].key)),h++;return o.jsx(o.Fragment,{children:u})}function _B({v:e}){const t=g.useRef(null),s=g.useRef(!0),n=g.useRef(0),i=g.useRef(-1e9),r=g.useRef(0),a=g.useRef(0),l=g.useRef(0),[c,u]=g.useState(!0),[h,d]=g.useState(!1),p=64,f=()=>performance.now(),m=B=>B.scrollHeight-B.scrollTop-B.clientHeight<=p,b=1200,_=B=>{r.current=f()+150,a.current=B.scrollTop,l.current=B.scrollHeight},v=()=>{const B=t.current;B&&(B.scrollTop=B.scrollHeight,_(B))},y=()=>{s.current=!1,n.current=0,u(!1)};Kl.current=()=>{s.current=!0,n.current=f()+1200,u(!0),d(!1),v()},g.useEffect(()=>{const B=t.current;if(!B)return;const k=()=>{i.current=f()},A=()=>{const K=B.scrollTop,U=K-a.current;a.current=K;const re=B.scrollHeight,J=re<l.current-1;if(l.current=re,U<-2&&!J&&f()-i.current<b){y();return}if(f()<r.current)return;const Y=m(B);Y!==s.current&&(s.current=Y,u(Y)),Y&&d(!1)},D=K=>{k(),K.deltaY<0&&y()};let H=0;const I=K=>{k(),H=K.touches[0]?.clientY??0},z=K=>{k(),(K.touches[0]?.clientY??0)>H+4&&y()},T=K=>{k(),(K.key==="PageUp"||K.key==="ArrowUp"||K.key==="Home")&&y()},O=()=>k();return B.addEventListener("scroll",A,{passive:!0}),B.addEventListener("wheel",D,{passive:!0}),B.addEventListener("touchstart",I,{passive:!0}),B.addEventListener("touchmove",z,{passive:!0}),B.addEventListener("keydown",T),B.addEventListener("pointerdown",O,{passive:!0}),_(B),()=>{B.removeEventListener("scroll",A),B.removeEventListener("wheel",D),B.removeEventListener("touchstart",I),B.removeEventListener("touchmove",z),B.removeEventListener("keydown",T),B.removeEventListener("pointerdown",O)}},[]),g.useEffect(()=>{if(s.current||f()<n.current){v();return}e.msgs.length&&d(!0)},[e.rev,e.busy,e.perms.length]),g.useEffect(()=>{const B=t.current,k=B?.firstElementChild??null;if(!B||!k||typeof ResizeObserver>"u")return;const A=new ResizeObserver(()=>{!s.current&&f()>=n.current||requestAnimationFrame(()=>{(s.current||f()<n.current)&&v()})});return A.observe(k),()=>A.disconnect()},[e.info.id]);const[w,x]=g.useState(null);g.useEffect(()=>{x(null)},[e.info.id]);const S=async B=>{const k=t.current,A=k?.scrollHeight??0,D=k?.scrollTop??0;B||(s.current=!1,u(!1)),F(!0);const H=await ee.loadEarlier(e.info.id);H===0?x("这一页没有新内容(更早的记录都是屏幕上已有内容的碎片)"):H>0&&x(null),requestAnimationFrame(()=>{const I=t.current;I&&(I.scrollTop=I.scrollHeight-A+D,_(I))})},N=()=>{S(!1)},R=async B=>{const k=[...B.queue];try{const A=await ee.createSession(String(B.info.backend),B.info.cwd,"");ee.setActive(A);for(const D of k)ee.enqueuePrompt(A,D.text,D.attachments);ee.purgeCold(B.info.id)}catch{}},E=g.useRef(0),[M,F]=g.useState(!1);return g.useEffect(()=>{E.current=0,F(!1)},[e.info.id]),g.useEffect(()=>{const B=t.current;!B||!e.hasOlder||e.loadingOlder||E.current>=Yb||B.scrollHeight>B.clientHeight+80||(E.current+=1,S(!0))},[e.rev,e.hasOlder,e.loadingOlder,e.info.id]),g.useEffect(()=>{const B=t.current;if(!B)return;const k=()=>{!e.hasOlder||e.loadingOlder||E.current>=Yb||B.scrollTop>B.clientHeight*1.5||(E.current+=1,S(!0))};return B.addEventListener("scroll",k,{passive:!0}),()=>B.removeEventListener("scroll",k)},[e.info.id,e.hasOlder,e.loadingOlder]),o.jsxs("div",{className:"stream-wrap",children:[o.jsx("div",{className:"stream",ref:t,tabIndex:0,children:o.jsxs("div",{className:"stream-inner",children:[e.info.status==="starting"?o.jsxs("div",{className:"start-hold",role:"status",children:[o.jsx("span",{className:"stream-spin","aria-hidden":"true"}),o.jsx("span",{children:"正在启动 agent 进程…好了会自动把消息发出去"})]}):null,e.info.status==="error"&&e.info.lastError?o.jsxs("div",{className:"start-fail",role:"alert",children:[o.jsxs("div",{className:"start-fail-why",children:["会话启动失败:",e.info.lastError]}),o.jsxs("div",{className:"start-fail-act",children:[o.jsx("button",{className:"ghost-btn",onClick:()=>void R(e),children:"再试一次"}),o.jsx("button",{className:"ghost-btn",onClick:()=>ee.purgeCold(e.info.id),children:"删除这个会话"})]})]}):null,e.hasOlder?o.jsxs("div",{className:"load-earlier",children:[e.loadingOlder?o.jsx("span",{className:"load-earlier-busy",children:"正在加载更早的消息…"}):o.jsx("button",{className:"ghost-btn",onClick:()=>N(),children:"↑ load earlier messages"}),w&&!e.loadingOlder?o.jsx("span",{className:"load-earlier-end",children:w}):null]}):M&&e.msgs.length?o.jsx("div",{className:"load-earlier",children:o.jsx("span",{className:"load-earlier-end",children:"已到开头"})}):null,o.jsx(gC,{msgs:e.msgs,notes:e.notes,sid:e.info.id,backend:e.info.backend,busy:Qr(e),base:e.info.workspace||e.info.cwd}),o.jsx(mB,{busy:Qr(e),since:e.busySince}),e.perms.filter(B=>!e.msgs.some(k=>k.kind==="approval"&&k.requestId===B.requestId)).map(B=>o.jsx(yC,{sid:e.info.id,req:B},B.requestId))]})}),!c&&o.jsxs("button",{className:`jump-latest ${h?"has-new":""}`,onClick:()=>Kl.current(),title:h?"new output — jump to the newest":"jump to the newest","aria-label":"jump to newest output",children:[o.jsx(bS,{size:14}),h?o.jsx("span",{className:"jump-dot","aria-hidden":"true"}):null]})]})}const _C=g.memo(RB,(e,t)=>e.live===t.live&&e.m.key===t.m.key&&e.m.text===t.m.text&&e.m.at===t.m.at),vB=(e,t)=>{const s=e.m,n=t.m;return s.key===n.key&&s.title===n.title&&s.status===n.status&&s.detail===n.detail&&s.input===n.input&&s.at===n.at},vC=g.memo(NB,vB),yB=(e,t)=>{const s=e.m,n=t.m;return e.busy===t.busy&&s.key===n.key&&s.at===n.at&&s.terminal===n.terminal&&s.explanation===n.explanation&&JSON.stringify(s.items)===JSON.stringify(n.items)},bB=g.memo(EB,yB);function wB({text:e}){const t=FO(e),[s,n]=g.useState(!1);return t?o.jsxs("div",{className:`bg-notice ${s?"open":""}`,"data-ok":t.ok?"ok":"fail",children:[o.jsxs("button",{type:"button",className:"bg-notice-head","aria-expanded":s,onClick:()=>n(!s),children:[o.jsx("span",{className:"bg-notice-dot","aria-hidden":"true"}),o.jsx("span",{className:"bg-notice-title",children:t.kind==="watch"?"后台任务命中":"后台任务完成"}),o.jsx("code",{className:"bg-notice-cmd",title:t.command,children:Kb(t.command)}),t.kind==="watch"?o.jsxs("code",{className:"bg-notice-code",title:t.pattern,children:["「",Kb(t.pattern,28),"」"]}):t.exitCode===null?o.jsx("span",{className:"bg-notice-code",children:"已结束"}):o.jsxs("span",{className:"bg-notice-code",children:["exit ",t.exitCode]}),o.jsx("span",{className:"bg-notice-caret","aria-hidden":"true",children:s?"▾":"▸"})]}),s?o.jsxs("div",{className:"bg-notice-body",children:[o.jsx("div",{className:"bg-notice-label",children:"命令"}),o.jsx("pre",{className:"bg-notice-pre",children:t.command||"(未报告)"}),o.jsxs("div",{className:"bg-notice-label",children:[t.kind==="watch"?"命中行":"输出",t.output?"":"(空)"]}),t.output?o.jsx("pre",{className:"bg-notice-pre",children:t.output}):null]}):null]}):o.jsx(o.Fragment,{children:e})}function xB({d:e,base:t}){const[s,n]=g.useState(!1),i=e.tasks.filter(r=>!r.ok).length;return o.jsxs("div",{className:`bg-notice deleg-notice ${s?"open":""}`,"data-ok":i?"fail":"ok",children:[o.jsxs("button",{type:"button",className:"bg-notice-head","aria-expanded":s,onClick:()=>n(!s),children:[o.jsx("span",{className:"bg-notice-dot","aria-hidden":"true"}),o.jsx("span",{className:"bg-notice-title",children:"子代理回来了"}),o.jsx("code",{className:"bg-notice-cmd",title:e.tasks.map(r=>r.goal).join(`
|
|
127
127
|
`),children:WO(e)}),o.jsx("span",{className:"bg-notice-caret","aria-hidden":"true",children:s?"▾":"▸"})]}),s?o.jsxs("div",{className:"bg-notice-body",children:[e.dispatched?o.jsxs("div",{className:"bg-notice-label",children:["派发于 ",e.dispatched,e.role?` · ${e.role}`:"",e.total?` · 合计 ${e.total}`:""," · ",e.id]}):null,e.tasks.map(r=>o.jsxs("div",{className:"deleg-task","data-ok":r.ok?"ok":"fail",children:[o.jsxs("div",{className:"deleg-task-head",children:[o.jsx("span",{className:"deleg-mark","aria-hidden":"true",children:r.ok?"✓":"✗"}),o.jsx("span",{className:"deleg-goal",children:r.goal||`任务 ${r.index}`}),o.jsxs("span",{className:"deleg-meta",children:[r.status,r.meta?` · ${r.meta}`:""]})]}),r.body?o.jsx("div",{className:"deleg-body",children:o.jsx(Y1,{text:r.body,base:t})}):null]},r.index))]}):null]})}function SB({text:e,base:t}){const s=UO(e);return s?o.jsx(xB,{d:s,base:t}):o.jsx(wB,{text:e})}function kB({m:e,sid:t,backend:s,last:n,busy:i,live:r,base:a}){switch(e.kind){case"user":return o.jsxs("div",{className:`msg user${e.from?" from-agent":""}`,children:[o.jsx("div",{className:"role",title:e.from?`会话 ${e.from.id}`:void 0,children:e.from?`来自「${e.from.title}」`:"YOU"}),o.jsxs("div",{className:"bubble",children:[e.files.length>0?o.jsx("div",{className:"bubble-files",children:e.files.map((l,c)=>o.jsxs("span",{className:"bubble-file",title:l.name,children:[l.kind==="image"?o.jsx(xN,{size:12}):o.jsx(ui,{size:12}),l.name]},`${l.name}-${c}`))}):null,o.jsx(SB,{text:e.text,base:a}),o.jsxs("div",{className:"bubble-actions",children:[e.at?o.jsx("span",{className:"msg-at",title:ho(e.at),children:gm(e.at)}):null,o.jsx(Vh,{text:e.text,what:"这条消息"})]})]})]});case"agent":{const l=Bh(e.text);return o.jsxs("div",{className:"msg agent",children:[o.jsxs("div",{className:"role with-mark",children:[o.jsx(oB,{backend:s}),vd(s).label||"AGENT"]}),o.jsxs("div",{className:"bubble",children:[o.jsx(Y1,{text:l,base:a}),o.jsxs("div",{className:"bubble-actions",children:[e.at?o.jsx("span",{className:"msg-at",title:ho(e.at),children:gm(e.at)}):null,o.jsx(Vh,{text:l,what:"这条回复"}),o.jsx(OB,{id:e.key,text:l,sid:t}),n&&!i?o.jsx(iB,{sid:t,busy:i}):null]}),o.jsx(BB,{mkey:e.key})]})]})}case"thought":return e.text.trim()?o.jsx(_C,{m:e,live:!!r}):null;case"approval":return o.jsx(AB,{m:e,sid:t});case"project-skills":return o.jsx(DB,{m:e,sid:t});case"turn-usage":return o.jsx(MB,{m:e});case"tool":return o.jsx(vC,{m:e});case"plan":return o.jsx(bB,{m:e,busy:i});case"meta":return o.jsx("div",{className:"msg meta",children:o.jsx("div",{className:"bubble",children:e.text})});default:return null}}function CB({v:e}){const[t,s]=g.useState(!1),n=g.useRef(null),i=e.plan;if(g.useLayoutEffect(()=>{t&&fC(n.current)},[t,i]),!i||!i.items.length)return null;const r=i.items.length,a=i.items.filter(h=>h.status==="completed").length,l=a===r,c=i.terminal==="interrupted"?"已打断":i.terminal==="failed"?"运行出错":i.terminal==="ended"?"回合结束":l?"已完成":e.busy?"进行中":"待命中",u=i.terminal?"terminal":l?"done":e.busy?"running":"";return o.jsxs("div",{className:`plan-bar ${l&&!i.terminal?"completed":""}`,children:[o.jsxs("button",{type:"button",className:"plan-head",onClick:()=>s(h=>!h),"aria-expanded":t,title:"任务计划 · 点击展开/折叠",children:[o.jsx("span",{className:"plan-title",children:"任务计划"}),o.jsx("span",{className:"plan-dots","aria-hidden":"true",children:i.items.map((h,d)=>o.jsx("span",{className:`dot ${h.status}`},d))}),o.jsxs("span",{className:"plan-count",children:[a,"/",r]}),o.jsx("span",{className:`plan-state ${u}`,children:c}),o.jsx(an,{size:11,className:`tool-chev ${t?"open":""}`})]}),t?o.jsxs("ol",{className:"plan-body",ref:n,children:[i.title?o.jsx("li",{className:"plan-name","aria-label":"计划名",children:i.title}):null,i.items.map((h,d)=>o.jsxs("li",{className:`plan-step ${h.status}`,children:[o.jsx("span",{className:"step-icon","aria-hidden":"true",children:h.status==="completed"?"✓":h.status==="in_progress"?"◉":h.status==="cancelled"?"✕":"○"}),o.jsx("span",{className:"step-title",children:h.content})]},d))]}):null,t&&i.explanation?o.jsx("p",{className:"plan-explanation",children:i.explanation}):null]})}function EB({m:e,busy:t}){const[s,n]=g.useState(!1),i=g.useRef(null);g.useLayoutEffect(()=>{s&&fC(i.current)},[s,e]);const r=e.items.length;if(!r)return null;const a=e.items.filter(h=>h.status==="completed").length,l=a===r,c=e.terminal==="interrupted"?"已打断":e.terminal==="failed"?"运行出错":e.terminal==="ended"?"回合结束":l?"已完成":t?"进行中":"",u=e.terminal?"terminal":l?"done":t?"running":"";return o.jsx("div",{className:"msg",children:o.jsxs("div",{className:`plan-card ${l&&!e.terminal?"completed":""}`,children:[o.jsxs("button",{type:"button",className:"plan-head",onClick:()=>n(h=>!h),"aria-expanded":s,title:"任务计划 · click to collapse/expand",children:[o.jsx("span",{className:"plan-title",children:"任务计划"}),o.jsx("span",{className:"plan-dots","aria-hidden":"true",children:e.items.map((h,d)=>o.jsx("span",{className:`dot ${h.status}`},d))}),o.jsxs("span",{className:"plan-count",children:[a,"/",r]}),c?o.jsx("span",{className:`plan-state ${u}`,children:c}):null,o.jsx(an,{size:11,className:`tool-chev ${s?"open":""}`})]}),s?o.jsxs("ol",{className:"plan-body",ref:i,children:[e.title?o.jsx("li",{className:"plan-name","aria-label":"计划名",children:e.title}):null,e.items.map((h,d)=>o.jsxs("li",{className:`plan-step ${h.status}`,children:[o.jsx("span",{className:"step-icon","aria-hidden":"true",children:h.status==="completed"?"✓":h.status==="in_progress"?"◉":h.status==="cancelled"?"✕":"○"}),o.jsx("span",{className:"step-title",children:h.content})]},d))]}):null,s&&e.explanation?o.jsx("p",{className:"plan-explanation",children:e.explanation}):null]})})}function NB({m:e}){const[t,s]=g.useState(!1),n=!!(e.input||e.detail),i=ig(e.status);return o.jsx("div",{className:"msg",children:o.jsxs("div",{className:`tool-card ${e.status}`,children:[o.jsxs("button",{type:"button",className:"tool-head",onClick:()=>n&&s(r=>!r),title:n?`${e.title}
|
|
128
128
|
click for the full call and its result`:e.title,"aria-expanded":n?t:void 0,children:[o.jsx("span",{className:`tool-dot ${i}`,"aria-hidden":"true"}),o.jsx("span",{className:"tool-title",children:e.title}),e.at?o.jsx("span",{className:"msg-at",title:ho(e.at),children:Ai(e.at)}):null,n?o.jsx(an,{size:11,className:`tool-chev ${t?"open":""}`}):null]}),t&&o.jsxs("div",{className:"tool-body",children:[o.jsx("div",{className:"lbl",children:"tool"}),o.jsx("pre",{className:"tool-meta",children:e.title}),o.jsx("div",{className:"lbl",children:"kind · status"}),o.jsxs("pre",{className:"tool-meta",children:[e.kind2?`${e.kind2} · `:"",e.status]}),e.input?o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"lbl",children:"input"}),o.jsx("pre",{children:e.input})]}):null,e.detail?o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"lbl",children:"output"}),o.jsx("pre",{children:e.detail})]}):null]})]})})}function ig(e){const t=String(e||"").toLowerCase();return t==="completed"||t==="success"?"ok":t==="failed"||t==="error"||t==="cancelled"?"err":t==="in_progress"||t==="running"||t==="pending"?"running":"idle"}function RB({m:e,live:t}){const[s,n]=g.useState(null),i=s??t,r=g.useRef(null),[a,l]=g.useState(!0),c=24;g.useEffect(()=>{const h=r.current;if(!h||!t)return;let d=h.scrollTop;const p=()=>h.scrollHeight-h.scrollTop-h.clientHeight<=c,f=()=>{const w=h.scrollTop,x=w-d;if(d=w,x<-2){l(!1);return}l(p())},m=w=>{w.deltaY<0&&l(!1)};let b=0;const _=w=>{b=w.touches[0]?.clientY??0},v=w=>{(w.touches[0]?.clientY??0)>b+4&&l(!1)},y=w=>{(w.key==="PageUp"||w.key==="ArrowUp"||w.key==="Home")&&l(!1)};return h.addEventListener("scroll",f,{passive:!0}),h.addEventListener("wheel",m,{passive:!0}),h.addEventListener("touchstart",_,{passive:!0}),h.addEventListener("touchmove",v,{passive:!0}),h.addEventListener("keydown",y),()=>{h.removeEventListener("scroll",f),h.removeEventListener("wheel",m),h.removeEventListener("touchstart",_),h.removeEventListener("touchmove",v),h.removeEventListener("keydown",y)}},[t,i]),g.useEffect(()=>{if(!t||!a)return;const h=r.current;h&&(h.scrollTop=h.scrollHeight)},[e.text,t,a]);const u=()=>{l(!0);const h=r.current;h&&(h.scrollTop=h.scrollHeight)};return o.jsxs("div",{className:`msg thought${t?" live":""}`,children:[o.jsxs("button",{type:"button",className:"role thought-head","aria-expanded":i,"aria-label":`${i?"fold":"open"} the agent's thinking`,onClick:()=>n(!i),children:[o.jsx(an,{size:11,className:`thought-chev${i?" open":""}`}),"💭 ",t?"思考中…":"思考",o.jsxs("span",{className:"thought-meta",children:[e.at?`${gm(e.at)} · `:"",e.text.length," 字"]})]}),i&&o.jsxs("div",{className:`bubble${t?" live":""}`,ref:r,children:[e.text,t?null:o.jsx("div",{className:"bubble-actions",children:o.jsx(Vh,{text:e.text,what:"这段思考"})})]}),t&&i&&!a&&o.jsxs("button",{type:"button",className:"thought-stick",onClick:u,title:"follow the newest thinking again","aria-label":"follow the newest thinking again",children:[o.jsx(bS,{size:11})," 回到最新"]})]})}const Gf=e=>e.kind==="thought"||e.kind==="tool";function jB(e){const t=[];let s=0;for(;s<e.length;){const c=e[s];if(!Gf(c)){t.push({kind:"msg",m:c}),s++;continue}let u=s;for(;u<e.length&&Gf(e[u]);)u++;t.push({kind:"work",items:e.slice(s,u).filter(Gf),current:!1}),s=u}const n=t.map(c=>c.kind).lastIndexOf("work");let i=-1;if(t.forEach((c,u)=>{c.kind==="msg"&&c.m.kind==="user"&&(i=u)}),n>i){const c=t[n];c.kind==="work"&&(c.current=!0)}const r=[],a=c=>({kind:"msg",m:c,live:!1,tail:!1});for(const c of t){if(c.kind==="msg"){r.push(a(c.m));continue}const u=c.current?c.items.slice(-5):[],h=c.items.slice(0,c.items.length-u.length);h.length>=(c.current?1:2)?r.push({kind:"work",key:`work-${r.length}`,items:h,tail:!1}):h.forEach(d=>r.push(a(d))),u.forEach(d=>r.push(a(d)))}const l=[...r].reverse().find(c=>c.kind==="msg");l&&l.kind==="msg"&&(l.tail=!0);for(const c of r)c.kind==="msg"&&(c.m.kind==="agent"||c.m.kind==="thought")&&(c.live=!!c.m.open);return r}function TB({items:e}){const[t,s]=g.useState(!1),n=e.filter(m=>m.kind==="tool"),i=e.filter(m=>m.kind==="thought"),r=n.filter(m=>ig(m.status)==="err").length,a=n.some(m=>ig(m.status)==="running"),l=i.reduce((m,b)=>m+b.text.length,0),c=[...new Set(n.map(m=>m.title.replace(/\s+/g," ").trim()))],u=c.slice(0,2).map(m=>m.length>34?`${m.slice(0,33)}…`:m).join(" · "),h=n.length&&i.length?`${n.length} 次工具调用 · ${i.length} 段思考`:n.length?`${n.length} 次工具调用`:`${i.length} 段思考`,d=e.map(m=>m.at).filter(m=>typeof m=="number"),p=d.length?Math.min(...d):null,f=d.length?Math.max(...d):null;return o.jsx("div",{className:"msg",children:o.jsxs("div",{className:"work-run",children:[o.jsxs("button",{type:"button",className:"work-run-head","aria-expanded":t,title:[`折叠了 ${n.length} 次工具调用、${i.length} 段思考(${l} 字)`,"点开看它们",...n.map(m=>`· ${m.title}`)].join(`
|
|
129
|
-
`),onClick:()=>s(m=>!m),children:[o.jsx(an,{size:11,className:`work-chev${t?" open":""}`}),o.jsx("span",{className:"work-run-icon","aria-hidden":"true",children:n.length?"⚙":"💭"}),o.jsx("span",{className:"work-run-count",children:h}),c.length?o.jsx("span",{className:"work-run-names",children:c.length>2?`${u} +${c.length-2}`:u}):o.jsxs("span",{className:"work-run-chars",children:[l," 字"]}),o.jsx("span",{className:`work-run-state ${r?"err":a?"run":"ok"}`,"aria-hidden":"true",children:r?`✗ ${r}`:a?"•••":"✓"}),p?o.jsxs("span",{className:"msg-at",title:`${ho(p)}${f&&f!==p?` → ${ho(f)}`:""}`,children:[Ai(p),f&&f-p>=6e4?`–${Ai(f)}`:""]}):null]}),t&&o.jsx("div",{className:"work-run-items",children:e.map(m=>m.kind==="thought"?o.jsx(_C,{m,live:!1},m.key):o.jsx(vC,{m},m.key))})]})})}function yC({sid:e,req:t}){return o.jsx("div",{className:"msg",children:o.jsxs("div",{className:"perm-card",children:[o.jsxs("div",{className:"q",children:["🔑 agent 要执行:",o.jsx("b",{children:t.toolCallTitle}),"(",t.kind,")"]}),o.jsx(P_,{req:t}),o.jsx("div",{className:"opts",children:o.jsx(bC,{sid:e,req:t})})]})})}function AB({m:e,sid:t}){const s=g.useSyncExternalStore(ee.subscribe,ee.getSnapshot),n=s.active?.info.id===t&&!!s.active?.perms.some(r=>r.requestId===e.requestId),i={requestId:e.requestId,sessionId:t,toolCallTitle:e.title,kind:e.kind2,options:e.options,createdAt:e.at??Date.now(),path:e.path,diff:e.diff};return e.decision?o.jsx(Gb,{m:e}):n||!s.active?o.jsx(yC,{sid:t,req:i}):o.jsx(Gb,{m:e,lapsed:!0})}function Gb({m:e,lapsed:t}){const s=e.decision&&e.decision.outcome==="selected"?e.decision.optionId:null,n=e.options.find(a=>a.optionId===s),i=t?"已作废(服务端不再等这个请求了)":e.decision?.outcome==="selected"?`已答:${n?.name??"已选"}`:"已取消",r=t||e.decision?.outcome!=="selected"?"no":"yes";return o.jsx("div",{className:"msg",children:o.jsxs("div",{className:`perm-card done ${r}`,children:[o.jsxs("div",{className:"q",children:["🔑 agent 曾要执行:",o.jsx("b",{children:e.title}),"(",e.kind2,")"]}),o.jsx(P_,{req:{requestId:e.requestId,sessionId:"",toolCallTitle:e.title,kind:e.kind2,options:e.options,createdAt:e.at??0,path:e.path,diff:e.diff}}),o.jsx("div",{className:"perm-decision",children:i})]})})}function MB({m:e}){return o.jsx("div",{className:`status-note turn-usage${e.available?"":" na"}`,"data-kind":"usage",role:"note",title:e.available?"这一轮的真实用量:agent 上报的会话累计值 · 本次差分;缓存命中率 = 缓存读 /(输入 + 缓存读 + 缓存写)":"这个 agent 不通过 ACP 上报 token 用量",children:o.jsx("span",{className:"status-note-text",children:uk(e)})})}function DB({m:e,sid:t}){const s=e.state==="trusted"||e.state==="ignore",n=i=>{ee.send({t:"set-config",sessionId:t,configId:"project_skills",value:i})};return o.jsx("div",{className:"msg",children:o.jsxs("div",{className:`perm-card skills ${s?"done":""} ${e.state==="trusted"?"yes":e.state==="ignore"?"no":""}`,children:[o.jsxs("div",{className:"q",children:["📦 ",e.text]}),e.root?o.jsxs("div",{className:"perm-file",title:e.root,children:[o.jsx(ui,{size:12}),o.jsx("code",{children:e.root})]}):null,s?o.jsx("div",{className:"perm-decision",children:e.state==="trusted"?"已信任:这个仓库的 skill 会随会话加载":"已忽略:不再问,也不加载"}):o.jsxs("div",{className:"opts",children:[o.jsxs("button",{className:"opt primary",onClick:()=>n("trusted"),children:["信任这个仓库(",e.count," 个 skill)"]}),o.jsx("button",{className:"opt",onClick:()=>n("ignore"),children:"这个仓库不用问"})]})]})})}function P_({req:e}){if(e.diff)return o.jsx(IB,{diff:e.diff});const t=e.path??null;return t?o.jsxs("div",{className:"perm-file",title:t,children:[o.jsx(ui,{size:12}),o.jsx("code",{children:t})]}):null}function bC({sid:e,req:t,onAnswered:s}){const n=(a,l,c)=>{const u=ee.permAnswer(t.requestId);if(u&&!u.lapsed)return;const h=ee.send({t:"respond-permission",sessionId:e,requestId:t.requestId,decision:a,...c?{optionKind:c.kind,signature:`${t.kind}:${t.toolCallTitle}`}:{}});ee.markPermAnswered(t.requestId,l,h),s?.(l)},i=ee.permAnswer(t.requestId),[,r]=g.useState(0);return g.useEffect(()=>{if(!i||i.lapsed)return;const a=window.setInterval(()=>r(l=>l+1),1e3);return()=>window.clearInterval(a)},[i?.lapsed,t.requestId]),i&&!i.lapsed?o.jsxs("div",{className:"perm-answered",role:"status","aria-live":"polite",children:[o.jsx("span",{className:"perm-answered-tick","aria-hidden":"true",children:"✓"}),o.jsxs("span",{children:["已提交「",i.label,"」—— 正在等 agent 那边回应"]})]}):o.jsxs(o.Fragment,{children:[i?.lapsed&&o.jsxs("div",{className:"perm-unconfirmed",role:"status","aria-live":"polite",children:["还没收到 agent 那边的确认(等了 ",Math.max(1,Math.round((Date.now()-i.at)/1e3))," 秒) —— 可能是这一次答复没送出去,可以再点一次。"]}),t.options.map(a=>o.jsx("button",{className:a.kind.startsWith("allow")?"allow":"reject",onClick:()=>n({outcome:"selected",optionId:a.optionId},a.name,a),children:a.name},a.optionId)),o.jsx("button",{title:"不选任何一项:agent 会收到 cancelled,这一轮就停在这里",onClick:()=>n({outcome:"cancelled"},"取消这次请求"),children:"取消这次请求"})]})}function wC({lines:e}){return o.jsx("div",{className:"perm-diff",role:"region","aria-label":"变更内容",children:e.map((t,s)=>t.kind==="gap"?o.jsx("div",{className:"perm-diff-gap",children:t.text},s):o.jsxs("div",{className:`perm-diff-line ${t.kind}`,children:[o.jsx("span",{className:"no",children:t.oldNo??""}),o.jsx("span",{className:"no",children:t.newNo??""}),o.jsx("span",{className:"sig",children:t.kind==="add"?"+":t.kind==="del"?"−":" "}),o.jsx("span",{className:"txt",children:t.text||" "})]},s))})}function IB({diff:e}){const[t,s]=g.useState(!1),n=e.oldText??"",i=e.newText??"",r=i.length>0&&n.length===0,a=s_(n,i),l=a.filter(u=>u.kind==="add").length,c=a.filter(u=>u.kind==="del").length;return o.jsxs("div",{className:"perm-changes",children:[o.jsxs("button",{type:"button",className:"perm-change-row","aria-expanded":t,"aria-label":`${t?"收起":"查看"} ${e.path??"这份文件"} 的变更`,onClick:()=>s(u=>!u),children:[o.jsx(ui,{size:13}),o.jsx("code",{title:e.path??"",children:e.path??"(未命名文件)"}),o.jsx("span",{className:"perm-counts",children:r?o.jsxs("span",{className:"add",children:["新文件 · ",l," 行"]}):o.jsxs(o.Fragment,{children:[o.jsxs("span",{className:"add",children:["+",l]}),o.jsxs("span",{className:"del",children:["−",c]})]})}),o.jsx("span",{className:"perm-caret","aria-hidden":"true",children:t?"▾":"▸"})]}),t?o.jsx(wC,{lines:a}):null,e.truncated?o.jsx("div",{className:"perm-cut",children:"agent 发来的是整份文件,这里只保留了改动附近的部分"}):null]})}function Jb({f:e}){const[t,s]=g.useState(!1),n=e.oldText.length===0&&e.newText.length>0,i=n||e.oldText.length>0||e.newText.length>0,r=g.useMemo(()=>i?s_(e.oldText,e.newText):[],[i,e.oldText,e.newText]),a=e.path===e.name?"":e.path.slice(0,e.path.length-e.name.length).replace(/[\\/]+$/,"");return o.jsxs("div",{className:"fc-row",children:[o.jsxs("div",{className:"fc-line",children:[o.jsx("span",{className:"fc-dot","aria-hidden":"true"}),o.jsxs("button",{type:"button",className:"fc-name",title:`在右侧面板打开 ${e.path}`,onClick:()=>US({path:e.path}),children:[e.name,a?o.jsx("span",{className:"fc-dir",children:a}):null,e.edits>1?o.jsxs("span",{className:"fc-edits",children:["改了 ",e.edits," 次"]}):null]}),o.jsx("button",{type:"button",className:"fc-counts","aria-expanded":t,"aria-label":`${t?"收起":"查看"} ${e.path} 的变更`,disabled:!i,onClick:()=>s(l=>!l),children:n?o.jsxs("span",{className:"add",children:["新文件 · ",e.insertions," 行"]}):o.jsxs(o.Fragment,{children:[o.jsxs("span",{className:"add",children:["+",e.insertions]}),o.jsxs("span",{className:"del",children:["−",e.deletions]})]})})]}),t&&i?o.jsx(wC,{lines:r}):null]})}function Xb({msgs:e}){const t=g.useMemo(()=>{const a=[];for(const l of e)l.kind==="tool"&&l.changes?.length&&a.push(...l.changes);return zN(a)},[e]),[s,n]=g.useState(!0);if(!t.length)return null;if(t.length===1)return o.jsx("div",{className:"file-changes one",children:o.jsx(Jb,{f:t[0]})});const i=t.reduce((a,l)=>a+l.insertions,0),r=t.reduce((a,l)=>a+l.deletions,0);return o.jsxs("div",{className:"file-changes",children:[o.jsxs("button",{type:"button",className:"fc-head","aria-expanded":s,"aria-label":`${s?"收起":"展开"} ${t.length} 个文件变更`,onClick:()=>n(a=>!a),children:[o.jsx(ui,{size:13}),o.jsxs("span",{className:"fc-title",children:[t.length," 个文件变更"]}),o.jsxs("span",{className:"fc-counts static",children:[o.jsxs("span",{className:"add",children:["+",i]}),o.jsxs("span",{className:"del",children:["−",r]})]}),o.jsx("span",{className:"perm-caret","aria-hidden":"true",children:s?"▾":"▸"})]}),s?t.map(a=>o.jsx(Jb,{f:a},a.path)):null]})}function PB({req:e,sessionTitle:t,waiting:s,onSkip:n}){Ta(!0,n);const[i,r]=g.useState(()=>Date.now());g.useEffect(()=>{const u=window.setInterval(()=>r(Date.now()),1e3);return()=>window.clearInterval(u)},[e.requestId]);const a=Math.max(0,Math.round((i-e.createdAt)/1e3)),l=ee.permAnswer(e.requestId),c=Math.max(0,s-1);return o.jsx("div",{className:"modal-bg perm-bg",onClick:n,children:o.jsxs("div",{className:"modal perm-dialog",role:"dialog","aria-modal":"true","aria-label":"agent 请求授权","data-request-id":e.requestId,"data-session-id":e.sessionId,"data-waiting":s,onClick:u=>u.stopPropagation(),children:[o.jsx("h3",{children:"Agent 请求授权"}),o.jsxs("div",{className:"perm-ask",children:["「",t,"」里的 agent 停在这里等你答复 —— 它要执行 ",o.jsx("b",{children:e.toolCallTitle}),"(",e.kind,")。"]}),o.jsx(P_,{req:e}),o.jsx("div",{className:"opts perm-opts",children:o.jsx(bC,{sid:e.sessionId,req:e})}),c>0&&o.jsxs("div",{className:"perm-queue",role:"note",children:["这个会话还有 ",o.jsx("b",{children:c})," 个请求等着答复 —— 答完这个,下一个会接着显示在这里。"]}),o.jsxs("div",{className:"perm-note",children:["已等待 ",a," 秒。一直不答复的话,agent 那边会自己放弃这次请求(等同拒绝),这一轮就停在这里。"]}),!l&&o.jsx("div",{className:"row",children:o.jsx("button",{className:"cancel",onClick:n,children:"稍后处理"})})]})})}function Jf(e){if(e<=0)return"";if(e%60===0){const t=e/60;return t<60?`${t} 分钟`:`${Math.round(t/60)} 小时`}return`${e} 秒`}function LB(e){const t=e??"",[s,n]=g.useState({mode:"off",intervalSec:0,source:"default"}),[i,r]=g.useState(!0);g.useEffect(()=>{if(!t)return;let c=!0;return fetch(`/api/sessions/${encodeURIComponent(t)}/speak`,{credentials:"same-origin"}).then(u=>u.ok?u.json():null).then(u=>{c&&u?.speak&&n(u.speak)}).catch(()=>{}),()=>{c=!1}},[t]),g.useEffect(()=>{let c=!0;return fetch("/api/speak-modes",{credentials:"same-origin"}).then(u=>u.ok?u.json():null).then(u=>{c&&typeof u?.observerEnabled=="boolean"&&r(u.observerEnabled)}).catch(()=>{}),()=>{c=!1}},[]);const a=g.useCallback((c,u=0)=>{t&&(n({mode:c,intervalSec:c==="brief"?u:0,source:"session"}),fetch(`/api/sessions/${encodeURIComponent(t)}/speak`,{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({mode:c,intervalSec:c==="brief"?u:0})}).catch(()=>{}))},[t]),l=g.useCallback(()=>{t&&fetch(`/api/sessions/${encodeURIComponent(t)}/speak`,{method:"DELETE",credentials:"same-origin"}).then(c=>c.ok?c.json():null).then(c=>{c?.resolved&&n(c.resolved)}).catch(()=>{})},[t]);return{...s,observerEnabled:i,save:a,reset:l}}function OB({id:e,text:t,sid:s}){const[n]=_o(),i=dd(),[r,a]=g.useState(!1),[l,c]=g.useState(!1),[u,h]=g.useState(null),d=g.useRef(null);co(r,[d],()=>a(!1));const p=g.useRef({timer:null,fired:!1}),f=()=>{p.current.timer&&(window.clearTimeout(p.current.timer),p.current.timer=null)};g.useEffect(()=>f,[]);const m=()=>{p.current.fired=!1,f(),p.current.timer=window.setTimeout(()=>{p.current.fired=!0,a(!0)},500)};if(!t.trim())return null;const b=i.speaking&&i.speakingId===e;if(typeof window<"u"&&!("speechSynthesis"in window)&&!n.serverTts)return o.jsx("span",{className:"bubble-note",title:"this browser has no speech synthesis",children:"no voices"});const _=async v=>{if(l)return;const y=qO(pC(e,v));if(y){a(!1),Ft.speak(y.text,`${e}#summary:${v??"cfg"}`,n);return}c(!0),h(null);try{const w=await XO(s,e,v);a(!1),Ft.speak(w.text,`${e}#summary:${v??"cfg"}`,n)}catch(w){const x=w;h({msg:x?.message??String(w),hint:x?.hint}),a(!1)}finally{c(!1)}};return o.jsxs(o.Fragment,{children:[o.jsxs("span",{className:"speak-wrap bubble-speak",ref:d,children:[o.jsx("button",{className:`bubble-btn speak ${b?"on":""} ${l?"working":""}`,title:l?"正在生成语音播报总结…":b?"stop reading(长按:语音播报总结)":"read this reply aloud(长按:语音播报总结)","aria-label":b?"stop reading":"read aloud","aria-haspopup":"menu","aria-expanded":r,onClick:()=>{if(p.current.fired){p.current.fired=!1;return}b?uc():Ft.speak(t,e,n)},onPointerDown:m,onPointerUp:f,onPointerLeave:f,onPointerCancel:f,onContextMenu:v=>{v.preventDefault(),f(),a(!0)},onKeyDown:v=>{(v.key==="F10"&&v.shiftKey||v.key==="ContextMenu")&&(v.preventDefault(),a(!0))},children:l?o.jsx(ba,{size:13,className:"spin"}):b?o.jsx(xS,{size:13}):o.jsx(hd,{size:13})}),r?o.jsxs("div",{className:"speak-menu bubble-menu",role:"menu",children:[o.jsxs("button",{type:"button",role:"menuitem",className:"speak-menu-item","data-speak-summary":"verbatim",onClick:()=>{a(!1),Ft.speak(t,e,n)},children:[o.jsx("span",{className:"speak-check",children:"›"}),o.jsx("span",{className:"speak-name",children:"读整条"})]}),[100,150,200].map(v=>o.jsxs("button",{type:"button",role:"menuitem",className:"speak-menu-item",disabled:l,"data-speak-summary":String(v),onClick:()=>void _(v),children:[o.jsx("span",{className:"speak-check",children:l?"•":"›"}),o.jsx("span",{className:"speak-name",children:l?"总结中…":`语音播报总结 · 约 ${v} 字`})]},v)),o.jsxs("button",{type:"button",role:"menuitem",className:"speak-menu-item",disabled:l,"data-speak-summary":"cfg",onClick:()=>void _(),children:[o.jsx("span",{className:"speak-check",children:"›"}),o.jsx("span",{className:"speak-name",children:l?"总结中…":"语音播报总结 · 按设置"})]}),o.jsx("p",{className:"speak-hint",children:"把这条压成一段能听完的话;字数写进提示词交给模型(提示词在 设置 → 语音总结)"})]}):null]}),u?o.jsxs("span",{className:"bubble-note err",role:"status",children:[u.msg,u.hint?` · ${u.hint}`:""]}):null]})}function BB({mkey:e}){const t=g.useSyncExternalStore(KO,qb,qb),[s,n]=g.useState(!1),i=VO(e);if(!i)return null;const r=i.route==="session"?`${i.provider??""}${i.provider?" · ":""}${i.model??""}`:i.model?`语音端点 · ${i.model}`:"",a=i.maxChars?` · 按 ${i.maxChars} 字压`:"",l=i.via==="verbatim"?"原文本身就够短,直接念":`${i.chars} 字${a} · ${(i.ms/1e3).toFixed(1)}s${r?` · ${r}`:""}`;return o.jsxs("div",{className:`bubble-note speech-note${s?" open":""}`,"data-summary-chars":i.chars,children:[o.jsx("button",{type:"button",className:"speech-note-tag","aria-expanded":s,onClick:()=>n(c=>!c),children:"播报稿"}),o.jsx("span",{className:"speech-note-text",onClick:()=>n(c=>!c),title:"点击展开/收起",children:i.text}),o.jsx("span",{className:"speech-note-meta",title:i.routeNote??void 0,children:l}),o.jsx("button",{type:"button",className:"speech-note-x",title:"丢掉这份稿子(下次长按会重新生成)","aria-label":"drop this summary",onClick:()=>GO(e),children:o.jsx(En,{size:11})}),o.jsx("span",{hidden:!0,children:t})]})}const L_=["image/png","image/jpeg","image/webp","image/gif"],$B=4*1024*1024,FB=256*1024;function O_(){const e=g.useRef(!1);return{handlers:{onCompositionStart:()=>{e.current=!0},onCompositionEnd:()=>{e.current=!1}},isComposing:t=>e.current||t.nativeEvent.isComposing===!0}}function xC(e){return L_.includes(e.type)?e.size>$B?Promise.resolve({error:`${e.name}: image larger than 4MB`}):new Promise(s=>{const n=new FileReader;n.onload=()=>{const i=String(n.result??"");s({id:`${e.name}-${e.size}-${Math.random().toString(36).slice(2,7)}`,name:e.name,kind:"image",mimeType:e.type,preview:i,payload:i.slice(i.indexOf(",")+1),bytes:e.size})},n.onerror=()=>s({error:`${e.name}: could not be read`}),n.readAsDataURL(e)}):e.size>FB?Promise.resolve({error:`${e.name}: larger than 256kB — attach it as a path instead`}):new Promise(s=>{const n=new FileReader;n.onload=()=>s({id:`${e.name}-${e.size}-${Math.random().toString(36).slice(2,7)}`,name:e.name,kind:"text",mimeType:e.type||"text/plain",payload:String(n.result??""),bytes:e.size}),n.onerror=()=>s({error:`${e.name}: could not be read`}),n.readAsText(e)})}function SC(e){if(!e)return[];const t=Array.from(e.files??[]);for(const s of Array.from(e.items??[])){if(s.kind!=="file")continue;const n=s.getAsFile();n&&!t.some(i=>i.name===n.name&&i.size===n.size&&i.type===n.type)&&t.push(n)}return t}function kC(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(0)} kB`:`${(e/1048576).toFixed(1)} MB`}const kr=["#7f8c98","#5fb3a1","#7fb069","#d9a441","#e8843c","#f0603f","#ff4d4d"];function CC(e,t){const s=Math.max(1,t.length),n=t.findIndex(a=>String(a.value)===String(e)),i=n<0?0:n+1;return{color:n<0?"var(--text-dim)":kr[Math.min(n,kr.length-1)],level:i,total:s}}function EC({level:e,total:t,color:s}){const n=Math.min(7,t),i=Math.max(0,Math.min(n,Math.round(e/t*n)));return o.jsx("span",{className:"tb-pips","aria-hidden":"true",children:Array.from({length:n}).map((r,a)=>o.jsx("i",{style:{background:a<i?s:"var(--line)"}},a))})}function kc(e,t){const s=t==="effort"?["thought_level","reasoning"]:["model","model_config"],n=t==="effort"?/reason|effort|think|depth/i:/model/i;return e.find(i=>i.type==="select"&&i.category&&s.includes(String(i.category)))??e.find(i=>i.type==="select"&&n.test(i.id))}function NC({label:e,title:t,icon:s,value:n,children:i,open:r,onToggle:a,testId:l}){const c=g.useRef(null);return co(r,[c],a),o.jsxs("div",{className:"tb-wrap",ref:c,children:[o.jsxs("button",{type:"button",className:`tb-btn ${r?"on":""}`,title:t,"aria-label":t,"aria-expanded":r,"data-testid":l,onClick:a,children:[s,o.jsx("span",{className:"tb-label",children:n||e}),o.jsx(ya,{size:11,className:"tb-chev"})]}),r?i:null]})}function Yh({items:e,current:t,onPick:s,empty:n}){const i=dS();return e.length?o.jsx("div",{className:"tb-list",role:"listbox",ref:i,children:e.map(r=>o.jsxs("button",{role:"option","aria-selected":r.value===t,className:`tb-opt ${r.value===t?"sel":""}`,title:r.hint?`${r.name} — ${r.hint}`:r.name,onClick:()=>s(r.value),children:[o.jsxs("span",{className:"tb-opt-name",children:[r.color?o.jsx("i",{className:"tb-dot",style:{background:r.color}}):null,r.name]}),r.hint?o.jsx("span",{className:"tb-opt-hint",children:r.hint}):null]},r.value))}):o.jsx("div",{className:"tb-list",ref:i,children:o.jsx("div",{className:"tb-empty",children:n})})}function RC(e){return e.category==="_context_window"?!0:/budget|context/i.test(`${e.id} ${e.name??""}`)}function zB({v:e}){const t=e.info.usage,s=e.info.configOptions.find(RC),[n,i]=g.useState(!1),r=g.useRef(null),[a,l]=g.useState(!1),[c,u]=g.useState(""),[h,d]=g.useState(!0),[p,f]=g.useState(""),[m,b]=g.useState(""),_=O_(),v=e.trace;co(n,[r],()=>{i(!1),l(!1)});const y=t?.used??0,w=t?.size??0,x=y>0||w>0,S=e.info.contextLimit&&e.info.contextLimit>0?e.info.contextLimit:null,N=e.info.modelContextLimit&&e.info.modelContextLimit>0?e.info.modelContextLimit:null,R=S?"session":N?"model":"agent",E=S??N??w,M=E>0?Math.min(100,Math.round(y/E*100)):0,F=x?M>=85?"hot":M>=65?"warn":"ok":"ok",B=E>0?Math.max(0,E-y):0,k=e.info.commands??[],A=O=>k.some(K=>K.name===O),D=R==="session"?"你为本会话声明":R==="model"?"你为这个模型记下的":"agent 上报(usage_update)",H=async(O,K={})=>{f(K.forgetModel?"forget":"save"),b("");try{await ee.setContextLimit(e.info.id,O,K),l(!1)}catch(U){b(String(U?.message??U))}finally{f("")}},I=O=>{if(e.info.cold){i(!1),ee.resume(e.info.id);return}ee.send({t:"prompt",sessionId:e.info.id,text:`/${O}`}),i(!1)},z=(O,K)=>{const U=K.trim();U&&(ee.send({t:"set-config",sessionId:e.info.id,configId:O,value:U}),u(""))},T=String(s?.currentValue??"");return o.jsxs("div",{className:`usage-row ${F}`,ref:r,children:[o.jsxs("button",{className:"usage-text",onClick:()=>i(O=>!O),title:"上下文窗口 — 点这里改",children:[o.jsx(Xv,{size:12,className:"usage-icon"}),x?E>0?`${$n(y)} / ${$n(E)}`:`${$n(y)} / —`:E>0?`未上报用量 · 窗口 ${$n(E)}`:"agent 未上报用量 · 设窗口",x&&E>0?` · ${M}%`:"",R==="session"?" · 声明":R==="model"?" · 模型记录":""]}),E>0?o.jsx("div",{className:"usage-bar",title:x?`${y} / ${E} tokens (${M}%)`:`agent 未上报用量 · 已声明 ${E} tokens`,children:o.jsx("i",{style:{width:`${x?M:0}%`}})}):null,F==="hot"&&A("compress")&&!e.busy?o.jsxs("button",{className:"usage-act",onClick:()=>I("compress"),title:"发送 /compress:让 agent 压缩上下文(这是它自己公告的命令)",children:[o.jsx(e_,{size:11})," 压缩上下文"]}):null,n?o.jsxs("div",{className:"usage-detail",children:[o.jsxs("div",{className:"usage-set",children:[o.jsxs("div",{className:"usage-set-head",children:[o.jsx(Xv,{size:12})," 上下文窗口",o.jsx("span",{className:"usage-set-scope",children:s?String(s.meta?.scope??"")==="model"?"按模型":"":"仅声明"})]}),s?o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"usage-set-chips",children:(s.options??[]).map(O=>o.jsx("button",{className:`usage-chip ${T===String(O.value)?"sel":""}`,onClick:()=>z(s.id,String(O.value)),children:String(O.value)==="auto"?"自动":O.name},String(O.value)))}),o.jsxs("div",{className:"usage-edit",children:[o.jsx("input",{value:c,inputMode:"numeric","aria-label":"context window in tokens",placeholder:s.meta?.freeform===!0?"任意 token 数,如 300000":"填一个数",onChange:O=>u(O.target.value),onKeyDown:O=>{_.isComposing(O)||(O.key==="Enter"&&z(s.id,c),O.key==="Escape"&&(O.stopPropagation(),i(!1)))}}),o.jsx("button",{className:"usage-edit-btn",disabled:!c.trim(),onClick:()=>z(s.id,c),children:"set"})]}),o.jsx("div",{className:"settings-note",children:"常用:256k / 512k / 768k / 1m;填 auto 回到模型自己的窗口。"}),o.jsxs("div",{className:"usage-note",children:["改的是",o.jsx("b",{children:"这个模型"}),":同模型的所有会话(含新开的、别的槽位)都用同一个上限。它只会让 Hermes 更早压缩,不会把窗口撑过模型本身。"]})]}):o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"usage-note",children:e.info.backend==="qoder"?o.jsxs(o.Fragment,{children:["这个后端不公告上下文旋钮,也不上报用量(所以没有仪表盘数字)。下面的",o.jsx("b",{children:"声明"}),"对 qoder 是真的: 它会在",o.jsx("b",{children:"下次启动"}),"(冷启 / 重启 / 恢复)时作为 ",o.jsx("code",{children:"--context-window"})," 交给 CLI, 当场改要先停一次会话。"]}):o.jsxs(o.Fragment,{children:["这个后端没公告上下文旋钮,所以下面这个数只是仪表盘的",o.jsx("b",{children:"声明"}),",只影响百分比;真减上下文用压缩命令或换模型。"]})}),a?o.jsxs("div",{className:"usage-edit",children:[o.jsx("input",{autoFocus:!0,value:c,inputMode:"numeric","aria-label":"context window in tokens",placeholder:String(w||e.info.contextLimit||2e5),onChange:O=>u(O.target.value),..._.handlers,onKeyDown:O=>{if(!_.isComposing(O)){if(O.key==="Enter"){const K=Number(c.replace(/[^0-9]/g,""));K>0&&H(K,{remember:h})}O.key==="Escape"&&(O.stopPropagation(),l(!1))}}}),o.jsx("button",{className:"usage-edit-btn",disabled:p!==""||!Number(c.replace(/[^0-9]/g,"")),onClick:()=>void H(Number(c.replace(/[^0-9]/g,"")),{remember:h}),children:p==="save"?"…":"set"}),o.jsxs("label",{className:"usage-check",title:"像 studio 那样按模型记住:下次用这个模型自动带回来",children:[o.jsx("input",{type:"checkbox",checked:h,onChange:O=>d(O.target.checked)}),"记到本模型"]}),N?o.jsx("button",{className:"usage-edit-btn",disabled:p!=="",onClick:()=>void H(null,{forgetModel:!0}),children:p==="forget"?"…":"忘掉本模型记录"}):null]}):o.jsx("button",{className:"usage-edit-btn",onClick:()=>{u(String(E||2e5)),l(!0)},children:"声明窗口长度"})]})]}),o.jsx("div",{children:x?`已用 ${y} / ${E||"—"} tokens(${M}%)`:"agent 未上报用量(这个后端不发 usage_update)"}),o.jsxs("div",{children:["剩余:",x&&E>0?`${B} tokens`:"unknown"]}),o.jsxs("div",{children:["窗口来源:",o.jsx("b",{children:D})]}),w>0&&R!=="agent"?o.jsxs("div",{children:["agent 上报:",$n(w)," tokens (usage_update)"]}):null,N&&R==="session"?o.jsxs("div",{children:["本模型记录:",$n(N)," tokens"]}):null,t?.cost!=null?o.jsxs("div",{children:["本轮花费:$",t.cost.toFixed(6)]}):null,v?.model?o.jsxs("div",{children:["model:",v.model]}):null,v&&(v.effort||v.mode)?o.jsxs("div",{children:["本轮:",[v.effort&&`思考强度 ${v.effort}`,v.mode&&`模式 ${v.mode}`].filter(Boolean).join(",")]}):null,A("compress")||A("context")?o.jsxs("div",{className:"usage-actions",children:[A("compress")?o.jsx("button",{className:"usage-act",onClick:()=>I("compress"),title:"让 agent 压缩上下文(/compress,它自己公告的命令)",children:"压缩上下文"}):null,A("context")?o.jsx("button",{className:"usage-act",onClick:()=>I("context"),title:"看消息按角色分布(/context)",children:"消息分布"}):null]}):null,m?o.jsx("div",{className:"usage-edit-err",children:m}):null]}):null]})}function HB({o:e,sessionId:t}){const s=e.meta??{},n=s.freeform===!0,[i,r]=g.useState(""),a=String(e.currentValue??""),l=typeof s.unit=="string"?s.unit:"tokens",c=h=>ee.send({t:"set-config",sessionId:t,configId:e.id,value:h}),u=O_();return o.jsxs("div",{className:"settings-group",children:[o.jsxs("div",{className:"settings-label",children:[o.jsx(Tc,{size:13})," ",e.name||e.id]}),e.options?.map(h=>o.jsx("button",{className:`settings-opt ${a===String(h.value)?"sel":""}`,onClick:()=>c(String(h.value)),children:h.name},String(h.value))),n?o.jsxs("div",{className:"settings-freeform",children:[o.jsx("input",{className:"settings-input",type:"number",inputMode:"numeric",min:typeof s.min=="number"?s.min:void 0,step:typeof s.step=="number"?s.step:1024,placeholder:`任意 ${l}`,"aria-label":`${e.name||e.id} value`,value:i,onChange:h=>r(h.target.value),...u.handlers,onKeyDown:h=>{u.isComposing(h)||h.key==="Enter"&&i.trim()&&c(i.trim())}}),o.jsx("button",{className:"settings-opt",disabled:!i.trim(),onClick:()=>c(i.trim()),children:"set"})]}):null]})}function UB({v:e,prefs:t,setPrefs:s,onClose:n,panelRef:i}){const r=e.info,a=r.modes?.availableModes??[],l=kc(r.configOptions,"effort"),c=kc(r.configOptions,"model"),h=g.useSyncExternalStore(Ft.subscribeVoices,()=>Ft.voices().length)?Ft.voices():[],d=li();return o.jsxs("div",{className:"settings-pop",role:"dialog","aria-label":"chat settings",ref:i,children:[o.jsxs("div",{className:"settings-head",children:[o.jsx("span",{children:"chat settings"}),o.jsx("span",{className:"head-spacer"}),o.jsx("button",{className:"icon-btn",title:"close","aria-label":"close",onClick:n,children:o.jsx(En,{size:13})})]}),a.length>0&&o.jsxs("div",{className:"settings-group",children:[o.jsxs("div",{className:"settings-label",children:[o.jsx(vS,{size:13})," permission mode"]}),a.map(p=>o.jsx("button",{className:`settings-opt ${r.modes?.currentModeId===p.id?"sel":""}`,onClick:()=>ee.send({t:"set-mode",sessionId:r.id,modeId:p.id}),children:p.name},p.id))]}),l?.options?.length?o.jsxs("div",{className:"settings-group",children:[o.jsxs("div",{className:"settings-label",children:[o.jsx(kN,{size:13})," thinking depth"]}),l.options.map((p,f)=>o.jsxs("button",{className:`settings-opt ${String(l.currentValue??"")===String(p.value)?"sel":""}`,onClick:()=>ee.send({t:"set-config",sessionId:r.id,configId:l.id,value:String(p.value)}),children:[o.jsx("i",{className:"settings-dot",style:{"--effort":kr[Math.min(f,kr.length-1)]}}),p.name]},String(p.value))),o.jsx("div",{className:"settings-note",children:"只列这个路由真支持的档;改的是本会话。"})]}):null,r.configOptions.filter(p=>p.type==="select"&&p.options&&p!==l&&p!==c&&!RC(p)).map(p=>o.jsx(HB,{o:p,sessionId:r.id},p.id)),o.jsxs("div",{className:"settings-group",children:[o.jsxs("div",{className:"settings-label",children:[o.jsx(hd,{size:13})," read replies aloud"]}),o.jsxs("label",{className:"settings-toggle",children:[o.jsx("input",{type:"checkbox",checked:t.autoRead,onChange:p=>s({autoRead:p.target.checked})}),o.jsx("span",{children:"speak every finished reply"})]}),h.length>0&&o.jsxs("select",{className:"settings-select",value:t.voiceURI,onChange:p=>s({voiceURI:p.target.value}),"aria-label":"voice",children:[o.jsxs("option",{value:"",children:["auto voice (",t.lang,")"]}),h.map(p=>o.jsxs("option",{value:p.voiceURI,children:[p.name," — ",p.lang]},p.voiceURI))]}),h.length===0?o.jsx("div",{className:"settings-note",children:"this browser exposes no voices"}):null,o.jsxs("label",{className:"settings-range",children:[o.jsxs("span",{children:["speed ",t.rate.toFixed(2),"×"]}),o.jsx("input",{type:"range",min:.5,max:2,step:.05,value:t.rate,onChange:p=>s({rate:Number(p.target.value)})})]}),d.tts.server?o.jsxs("label",{className:"settings-toggle",children:[o.jsx("input",{type:"checkbox",checked:t.serverTts,onChange:p=>s({serverTts:p.target.checked})}),o.jsxs("span",{children:["use the server voice (",d.tts.model??"configured",")"]})]}):null]}),o.jsxs("div",{className:"settings-group",children:[o.jsxs("div",{className:"settings-label",children:[o.jsx(ji,{size:13})," dictation"]}),o.jsxs("select",{className:"settings-select",value:t.stt,onChange:p=>s({stt:p.target.value}),"aria-label":"dictation engine",children:[o.jsx("option",{value:"auto",children:"auto — 服务端流式 > 浏览器 > 批量"}),o.jsxs("option",{value:"stream",children:["stream",d.stt.streaming?` (${d.stt.model??"百炼"})`:" (not configured)"]}),o.jsxs("option",{value:"browser",children:["browser",Vp()?"":" (unavailable)"]}),o.jsxs("option",{value:"server",children:["server",d.stt.server?` (${d.stt.batchModel??"configured"})`:" (not configured)"]})]}),o.jsx("input",{className:"settings-input",value:t.lang,onChange:p=>s({lang:p.target.value}),placeholder:"language, e.g. zh-CN","aria-label":"speech language"}),o.jsxs("div",{className:"settings-note",children:["browser dictation ",Vp()?"available":"unavailable"," · ",d.provider," STT"," ",d.stt.streaming?"streaming":d.stt.server?"batch":"not configured"]})]})]})}const Tu=new Map;function WB({v:e,call:t,tus:s,onCloseCall:n}){const[i,r]=g.useState(()=>Tu.get(e.info.id)??""),a=NS(e.info.backend),l=window.innerWidth<720?"message… (/ for commands)":"message… (Enter send, Shift+Enter newline, / for commands)",c=/Mac|iPhone|iPad/.test(navigator.platform??"")?"⌘":"Ctrl+",u=window.innerWidth<=720?"message… (Enter queues)":`message… (${c}Enter interrupts · Enter queues)`,[h,d]=g.useState(0),[p,f]=g.useState(!1),m=g.useRef(null),b=g.useRef(null),_=g.useRef(null),v=g.useRef(!1),y=g.useRef(null),w=g.useRef(""),x=g.useRef(!1),S=g.useMemo(()=>e.msgs.filter(P=>P.kind==="user").map(P=>P.text).filter(P=>P.trim()),[e.msgs]),N=g.useRef(e.info.id);g.useEffect(()=>{Tu.set(N.current,i)},[i]),g.useEffect(()=>{N.current!==e.info.id&&(Tu.set(N.current,i),N.current=e.info.id,r(Tu.get(e.info.id)??""),y.current=null,w.current="",f(!1),d(0))},[e.info.id,i]);const[R,E]=g.useState([]),[M,F]=g.useState(null),[B,k]=g.useState(""),[A,D]=g.useState(!1),[H,I]=g.useState(!1),[z,T]=g.useState(null);g.useEffect(()=>{const P=Oe.current;P&&(P.style.height="42px",P.style.height=`${Math.min(P.scrollHeight,window.innerHeight*.4)}px`)},[i]);const[O,K]=g.useState(!1),[U,re]=g.useState(null),[J,Y]=g.useState({});g.useEffect(()=>{Y({}),re(null)},[e.info.id]);const[_e,xe]=_o(),fe=r_(),et=dd(),Oe=g.useRef(null),tt=g.useRef(null),Pe=async P=>{const le=Array.from(P);if(!le.length)return;const je=await Promise.all(le.map(ot=>xC(ot))),Ie=[],Ge=[];for(const ot of je)"error"in ot?Ge.push(ot.error):Ie.push(ot);Ie.length&&E(ot=>[...ot,...Ie]),k(Ge.join(" · "))},Le=()=>R.map(P=>P.kind==="image"?{kind:"image",mimeType:P.mimeType,data:P.payload,name:P.name}:{kind:"text",name:P.name,text:P.payload}),Ee=P=>{if(P.key!=="ArrowUp"&&P.key!=="ArrowDown"||P.shiftKey||P.altKey||P.metaKey||P.ctrlKey||!S.length)return!1;const le=P.currentTarget,je=le.selectionStart??0;if(P.key==="ArrowUp"&&le.value.slice(0,je).includes(`
|
|
129
|
+
`),onClick:()=>s(m=>!m),children:[o.jsx(an,{size:11,className:`work-chev${t?" open":""}`}),o.jsx("span",{className:"work-run-icon","aria-hidden":"true",children:n.length?"⚙":"💭"}),o.jsx("span",{className:"work-run-count",children:h}),c.length?o.jsx("span",{className:"work-run-names",children:c.length>2?`${u} +${c.length-2}`:u}):o.jsxs("span",{className:"work-run-chars",children:[l," 字"]}),o.jsx("span",{className:`work-run-state ${r?"err":a?"run":"ok"}`,"aria-hidden":"true",children:r?`✗ ${r}`:a?"•••":"✓"}),p?o.jsxs("span",{className:"msg-at",title:`${ho(p)}${f&&f!==p?` → ${ho(f)}`:""}`,children:[Ai(p),f&&f-p>=6e4?`–${Ai(f)}`:""]}):null]}),t&&o.jsx("div",{className:"work-run-items",children:e.map(m=>m.kind==="thought"?o.jsx(_C,{m,live:!1},m.key):o.jsx(vC,{m},m.key))})]})})}function yC({sid:e,req:t}){return o.jsx("div",{className:"msg",children:o.jsxs("div",{className:"perm-card",children:[o.jsxs("div",{className:"q",children:["🔑 agent 要执行:",o.jsx("b",{children:t.toolCallTitle}),"(",t.kind,")"]}),o.jsx(P_,{req:t}),o.jsx("div",{className:"opts",children:o.jsx(bC,{sid:e,req:t})})]})})}function AB({m:e,sid:t}){const s=g.useSyncExternalStore(ee.subscribe,ee.getSnapshot),n=s.active?.info.id===t&&!!s.active?.perms.some(r=>r.requestId===e.requestId),i={requestId:e.requestId,sessionId:t,toolCallTitle:e.title,kind:e.kind2,options:e.options,createdAt:e.at??Date.now(),path:e.path,diff:e.diff};return e.decision?o.jsx(Gb,{m:e}):n||!s.active?o.jsx(yC,{sid:t,req:i}):o.jsx(Gb,{m:e,lapsed:!0})}function Gb({m:e,lapsed:t}){const s=e.decision&&e.decision.outcome==="selected"?e.decision.optionId:null,n=e.options.find(a=>a.optionId===s),i=t?"已作废(服务端不再等这个请求了)":e.decision?.outcome==="selected"?`已答:${n?.name??"已选"}`:"已取消",r=t||e.decision?.outcome!=="selected"?"no":"yes";return o.jsx("div",{className:"msg",children:o.jsxs("div",{className:`perm-card done ${r}`,children:[o.jsxs("div",{className:"q",children:["🔑 agent 曾要执行:",o.jsx("b",{children:e.title}),"(",e.kind2,")"]}),o.jsx(P_,{req:{requestId:e.requestId,sessionId:"",toolCallTitle:e.title,kind:e.kind2,options:e.options,createdAt:e.at??0,path:e.path,diff:e.diff}}),o.jsx("div",{className:"perm-decision",children:i})]})})}function MB({m:e}){return o.jsx("div",{className:`status-note turn-usage${e.available?"":" na"}`,"data-kind":"usage",role:"note",title:e.available?"这一轮的真实用量:agent 上报的会话累计值 · 本次差分。in = 本回合所有 API 调用的 prompt 累加(计费口径,含缓存读;工具回合会超过上下文窗口,窗口占用看上面的环);缓存命中率 = 缓存读 / in":"这个 agent 不通过 ACP 上报 token 用量",children:o.jsx("span",{className:"status-note-text",children:uk(e)})})}function DB({m:e,sid:t}){const s=e.state==="trusted"||e.state==="ignore",n=i=>{ee.send({t:"set-config",sessionId:t,configId:"project_skills",value:i})};return o.jsx("div",{className:"msg",children:o.jsxs("div",{className:`perm-card skills ${s?"done":""} ${e.state==="trusted"?"yes":e.state==="ignore"?"no":""}`,children:[o.jsxs("div",{className:"q",children:["📦 ",e.text]}),e.root?o.jsxs("div",{className:"perm-file",title:e.root,children:[o.jsx(ui,{size:12}),o.jsx("code",{children:e.root})]}):null,s?o.jsx("div",{className:"perm-decision",children:e.state==="trusted"?"已信任:这个仓库的 skill 会随会话加载":"已忽略:不再问,也不加载"}):o.jsxs("div",{className:"opts",children:[o.jsxs("button",{className:"opt primary",onClick:()=>n("trusted"),children:["信任这个仓库(",e.count," 个 skill)"]}),o.jsx("button",{className:"opt",onClick:()=>n("ignore"),children:"这个仓库不用问"})]})]})})}function P_({req:e}){if(e.diff)return o.jsx(IB,{diff:e.diff});const t=e.path??null;return t?o.jsxs("div",{className:"perm-file",title:t,children:[o.jsx(ui,{size:12}),o.jsx("code",{children:t})]}):null}function bC({sid:e,req:t,onAnswered:s}){const n=(a,l,c)=>{const u=ee.permAnswer(t.requestId);if(u&&!u.lapsed)return;const h=ee.send({t:"respond-permission",sessionId:e,requestId:t.requestId,decision:a,...c?{optionKind:c.kind,signature:`${t.kind}:${t.toolCallTitle}`}:{}});ee.markPermAnswered(t.requestId,l,h),s?.(l)},i=ee.permAnswer(t.requestId),[,r]=g.useState(0);return g.useEffect(()=>{if(!i||i.lapsed)return;const a=window.setInterval(()=>r(l=>l+1),1e3);return()=>window.clearInterval(a)},[i?.lapsed,t.requestId]),i&&!i.lapsed?o.jsxs("div",{className:"perm-answered",role:"status","aria-live":"polite",children:[o.jsx("span",{className:"perm-answered-tick","aria-hidden":"true",children:"✓"}),o.jsxs("span",{children:["已提交「",i.label,"」—— 正在等 agent 那边回应"]})]}):o.jsxs(o.Fragment,{children:[i?.lapsed&&o.jsxs("div",{className:"perm-unconfirmed",role:"status","aria-live":"polite",children:["还没收到 agent 那边的确认(等了 ",Math.max(1,Math.round((Date.now()-i.at)/1e3))," 秒) —— 可能是这一次答复没送出去,可以再点一次。"]}),t.options.map(a=>o.jsx("button",{className:a.kind.startsWith("allow")?"allow":"reject",onClick:()=>n({outcome:"selected",optionId:a.optionId},a.name,a),children:a.name},a.optionId)),o.jsx("button",{title:"不选任何一项:agent 会收到 cancelled,这一轮就停在这里",onClick:()=>n({outcome:"cancelled"},"取消这次请求"),children:"取消这次请求"})]})}function wC({lines:e}){return o.jsx("div",{className:"perm-diff",role:"region","aria-label":"变更内容",children:e.map((t,s)=>t.kind==="gap"?o.jsx("div",{className:"perm-diff-gap",children:t.text},s):o.jsxs("div",{className:`perm-diff-line ${t.kind}`,children:[o.jsx("span",{className:"no",children:t.oldNo??""}),o.jsx("span",{className:"no",children:t.newNo??""}),o.jsx("span",{className:"sig",children:t.kind==="add"?"+":t.kind==="del"?"−":" "}),o.jsx("span",{className:"txt",children:t.text||" "})]},s))})}function IB({diff:e}){const[t,s]=g.useState(!1),n=e.oldText??"",i=e.newText??"",r=i.length>0&&n.length===0,a=s_(n,i),l=a.filter(u=>u.kind==="add").length,c=a.filter(u=>u.kind==="del").length;return o.jsxs("div",{className:"perm-changes",children:[o.jsxs("button",{type:"button",className:"perm-change-row","aria-expanded":t,"aria-label":`${t?"收起":"查看"} ${e.path??"这份文件"} 的变更`,onClick:()=>s(u=>!u),children:[o.jsx(ui,{size:13}),o.jsx("code",{title:e.path??"",children:e.path??"(未命名文件)"}),o.jsx("span",{className:"perm-counts",children:r?o.jsxs("span",{className:"add",children:["新文件 · ",l," 行"]}):o.jsxs(o.Fragment,{children:[o.jsxs("span",{className:"add",children:["+",l]}),o.jsxs("span",{className:"del",children:["−",c]})]})}),o.jsx("span",{className:"perm-caret","aria-hidden":"true",children:t?"▾":"▸"})]}),t?o.jsx(wC,{lines:a}):null,e.truncated?o.jsx("div",{className:"perm-cut",children:"agent 发来的是整份文件,这里只保留了改动附近的部分"}):null]})}function Jb({f:e}){const[t,s]=g.useState(!1),n=e.oldText.length===0&&e.newText.length>0,i=n||e.oldText.length>0||e.newText.length>0,r=g.useMemo(()=>i?s_(e.oldText,e.newText):[],[i,e.oldText,e.newText]),a=e.path===e.name?"":e.path.slice(0,e.path.length-e.name.length).replace(/[\\/]+$/,"");return o.jsxs("div",{className:"fc-row",children:[o.jsxs("div",{className:"fc-line",children:[o.jsx("span",{className:"fc-dot","aria-hidden":"true"}),o.jsxs("button",{type:"button",className:"fc-name",title:`在右侧面板打开 ${e.path}`,onClick:()=>US({path:e.path}),children:[e.name,a?o.jsx("span",{className:"fc-dir",children:a}):null,e.edits>1?o.jsxs("span",{className:"fc-edits",children:["改了 ",e.edits," 次"]}):null]}),o.jsx("button",{type:"button",className:"fc-counts","aria-expanded":t,"aria-label":`${t?"收起":"查看"} ${e.path} 的变更`,disabled:!i,onClick:()=>s(l=>!l),children:n?o.jsxs("span",{className:"add",children:["新文件 · ",e.insertions," 行"]}):o.jsxs(o.Fragment,{children:[o.jsxs("span",{className:"add",children:["+",e.insertions]}),o.jsxs("span",{className:"del",children:["−",e.deletions]})]})})]}),t&&i?o.jsx(wC,{lines:r}):null]})}function Xb({msgs:e}){const t=g.useMemo(()=>{const a=[];for(const l of e)l.kind==="tool"&&l.changes?.length&&a.push(...l.changes);return zN(a)},[e]),[s,n]=g.useState(!0);if(!t.length)return null;if(t.length===1)return o.jsx("div",{className:"file-changes one",children:o.jsx(Jb,{f:t[0]})});const i=t.reduce((a,l)=>a+l.insertions,0),r=t.reduce((a,l)=>a+l.deletions,0);return o.jsxs("div",{className:"file-changes",children:[o.jsxs("button",{type:"button",className:"fc-head","aria-expanded":s,"aria-label":`${s?"收起":"展开"} ${t.length} 个文件变更`,onClick:()=>n(a=>!a),children:[o.jsx(ui,{size:13}),o.jsxs("span",{className:"fc-title",children:[t.length," 个文件变更"]}),o.jsxs("span",{className:"fc-counts static",children:[o.jsxs("span",{className:"add",children:["+",i]}),o.jsxs("span",{className:"del",children:["−",r]})]}),o.jsx("span",{className:"perm-caret","aria-hidden":"true",children:s?"▾":"▸"})]}),s?t.map(a=>o.jsx(Jb,{f:a},a.path)):null]})}function PB({req:e,sessionTitle:t,waiting:s,onSkip:n}){Ta(!0,n);const[i,r]=g.useState(()=>Date.now());g.useEffect(()=>{const u=window.setInterval(()=>r(Date.now()),1e3);return()=>window.clearInterval(u)},[e.requestId]);const a=Math.max(0,Math.round((i-e.createdAt)/1e3)),l=ee.permAnswer(e.requestId),c=Math.max(0,s-1);return o.jsx("div",{className:"modal-bg perm-bg",onClick:n,children:o.jsxs("div",{className:"modal perm-dialog",role:"dialog","aria-modal":"true","aria-label":"agent 请求授权","data-request-id":e.requestId,"data-session-id":e.sessionId,"data-waiting":s,onClick:u=>u.stopPropagation(),children:[o.jsx("h3",{children:"Agent 请求授权"}),o.jsxs("div",{className:"perm-ask",children:["「",t,"」里的 agent 停在这里等你答复 —— 它要执行 ",o.jsx("b",{children:e.toolCallTitle}),"(",e.kind,")。"]}),o.jsx(P_,{req:e}),o.jsx("div",{className:"opts perm-opts",children:o.jsx(bC,{sid:e.sessionId,req:e})}),c>0&&o.jsxs("div",{className:"perm-queue",role:"note",children:["这个会话还有 ",o.jsx("b",{children:c})," 个请求等着答复 —— 答完这个,下一个会接着显示在这里。"]}),o.jsxs("div",{className:"perm-note",children:["已等待 ",a," 秒。一直不答复的话,agent 那边会自己放弃这次请求(等同拒绝),这一轮就停在这里。"]}),!l&&o.jsx("div",{className:"row",children:o.jsx("button",{className:"cancel",onClick:n,children:"稍后处理"})})]})})}function Jf(e){if(e<=0)return"";if(e%60===0){const t=e/60;return t<60?`${t} 分钟`:`${Math.round(t/60)} 小时`}return`${e} 秒`}function LB(e){const t=e??"",[s,n]=g.useState({mode:"off",intervalSec:0,source:"default"}),[i,r]=g.useState(!0);g.useEffect(()=>{if(!t)return;let c=!0;return fetch(`/api/sessions/${encodeURIComponent(t)}/speak`,{credentials:"same-origin"}).then(u=>u.ok?u.json():null).then(u=>{c&&u?.speak&&n(u.speak)}).catch(()=>{}),()=>{c=!1}},[t]),g.useEffect(()=>{let c=!0;return fetch("/api/speak-modes",{credentials:"same-origin"}).then(u=>u.ok?u.json():null).then(u=>{c&&typeof u?.observerEnabled=="boolean"&&r(u.observerEnabled)}).catch(()=>{}),()=>{c=!1}},[]);const a=g.useCallback((c,u=0)=>{t&&(n({mode:c,intervalSec:c==="brief"?u:0,source:"session"}),fetch(`/api/sessions/${encodeURIComponent(t)}/speak`,{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({mode:c,intervalSec:c==="brief"?u:0})}).catch(()=>{}))},[t]),l=g.useCallback(()=>{t&&fetch(`/api/sessions/${encodeURIComponent(t)}/speak`,{method:"DELETE",credentials:"same-origin"}).then(c=>c.ok?c.json():null).then(c=>{c?.resolved&&n(c.resolved)}).catch(()=>{})},[t]);return{...s,observerEnabled:i,save:a,reset:l}}function OB({id:e,text:t,sid:s}){const[n]=_o(),i=dd(),[r,a]=g.useState(!1),[l,c]=g.useState(!1),[u,h]=g.useState(null),d=g.useRef(null);co(r,[d],()=>a(!1));const p=g.useRef({timer:null,fired:!1}),f=()=>{p.current.timer&&(window.clearTimeout(p.current.timer),p.current.timer=null)};g.useEffect(()=>f,[]);const m=()=>{p.current.fired=!1,f(),p.current.timer=window.setTimeout(()=>{p.current.fired=!0,a(!0)},500)};if(!t.trim())return null;const b=i.speaking&&i.speakingId===e;if(typeof window<"u"&&!("speechSynthesis"in window)&&!n.serverTts)return o.jsx("span",{className:"bubble-note",title:"this browser has no speech synthesis",children:"no voices"});const _=async v=>{if(l)return;const y=qO(pC(e,v));if(y){a(!1),Ft.speak(y.text,`${e}#summary:${v??"cfg"}`,n);return}c(!0),h(null);try{const w=await XO(s,e,v);a(!1),Ft.speak(w.text,`${e}#summary:${v??"cfg"}`,n)}catch(w){const x=w;h({msg:x?.message??String(w),hint:x?.hint}),a(!1)}finally{c(!1)}};return o.jsxs(o.Fragment,{children:[o.jsxs("span",{className:"speak-wrap bubble-speak",ref:d,children:[o.jsx("button",{className:`bubble-btn speak ${b?"on":""} ${l?"working":""}`,title:l?"正在生成语音播报总结…":b?"stop reading(长按:语音播报总结)":"read this reply aloud(长按:语音播报总结)","aria-label":b?"stop reading":"read aloud","aria-haspopup":"menu","aria-expanded":r,onClick:()=>{if(p.current.fired){p.current.fired=!1;return}b?uc():Ft.speak(t,e,n)},onPointerDown:m,onPointerUp:f,onPointerLeave:f,onPointerCancel:f,onContextMenu:v=>{v.preventDefault(),f(),a(!0)},onKeyDown:v=>{(v.key==="F10"&&v.shiftKey||v.key==="ContextMenu")&&(v.preventDefault(),a(!0))},children:l?o.jsx(ba,{size:13,className:"spin"}):b?o.jsx(xS,{size:13}):o.jsx(hd,{size:13})}),r?o.jsxs("div",{className:"speak-menu bubble-menu",role:"menu",children:[o.jsxs("button",{type:"button",role:"menuitem",className:"speak-menu-item","data-speak-summary":"verbatim",onClick:()=>{a(!1),Ft.speak(t,e,n)},children:[o.jsx("span",{className:"speak-check",children:"›"}),o.jsx("span",{className:"speak-name",children:"读整条"})]}),[100,150,200].map(v=>o.jsxs("button",{type:"button",role:"menuitem",className:"speak-menu-item",disabled:l,"data-speak-summary":String(v),onClick:()=>void _(v),children:[o.jsx("span",{className:"speak-check",children:l?"•":"›"}),o.jsx("span",{className:"speak-name",children:l?"总结中…":`语音播报总结 · 约 ${v} 字`})]},v)),o.jsxs("button",{type:"button",role:"menuitem",className:"speak-menu-item",disabled:l,"data-speak-summary":"cfg",onClick:()=>void _(),children:[o.jsx("span",{className:"speak-check",children:"›"}),o.jsx("span",{className:"speak-name",children:l?"总结中…":"语音播报总结 · 按设置"})]}),o.jsx("p",{className:"speak-hint",children:"把这条压成一段能听完的话;字数写进提示词交给模型(提示词在 设置 → 语音总结)"})]}):null]}),u?o.jsxs("span",{className:"bubble-note err",role:"status",children:[u.msg,u.hint?` · ${u.hint}`:""]}):null]})}function BB({mkey:e}){const t=g.useSyncExternalStore(KO,qb,qb),[s,n]=g.useState(!1),i=VO(e);if(!i)return null;const r=i.route==="session"?`${i.provider??""}${i.provider?" · ":""}${i.model??""}`:i.model?`语音端点 · ${i.model}`:"",a=i.maxChars?` · 按 ${i.maxChars} 字压`:"",l=i.via==="verbatim"?"原文本身就够短,直接念":`${i.chars} 字${a} · ${(i.ms/1e3).toFixed(1)}s${r?` · ${r}`:""}`;return o.jsxs("div",{className:`bubble-note speech-note${s?" open":""}`,"data-summary-chars":i.chars,children:[o.jsx("button",{type:"button",className:"speech-note-tag","aria-expanded":s,onClick:()=>n(c=>!c),children:"播报稿"}),o.jsx("span",{className:"speech-note-text",onClick:()=>n(c=>!c),title:"点击展开/收起",children:i.text}),o.jsx("span",{className:"speech-note-meta",title:i.routeNote??void 0,children:l}),o.jsx("button",{type:"button",className:"speech-note-x",title:"丢掉这份稿子(下次长按会重新生成)","aria-label":"drop this summary",onClick:()=>GO(e),children:o.jsx(En,{size:11})}),o.jsx("span",{hidden:!0,children:t})]})}const L_=["image/png","image/jpeg","image/webp","image/gif"],$B=4*1024*1024,FB=256*1024;function O_(){const e=g.useRef(!1);return{handlers:{onCompositionStart:()=>{e.current=!0},onCompositionEnd:()=>{e.current=!1}},isComposing:t=>e.current||t.nativeEvent.isComposing===!0}}function xC(e){return L_.includes(e.type)?e.size>$B?Promise.resolve({error:`${e.name}: image larger than 4MB`}):new Promise(s=>{const n=new FileReader;n.onload=()=>{const i=String(n.result??"");s({id:`${e.name}-${e.size}-${Math.random().toString(36).slice(2,7)}`,name:e.name,kind:"image",mimeType:e.type,preview:i,payload:i.slice(i.indexOf(",")+1),bytes:e.size})},n.onerror=()=>s({error:`${e.name}: could not be read`}),n.readAsDataURL(e)}):e.size>FB?Promise.resolve({error:`${e.name}: larger than 256kB — attach it as a path instead`}):new Promise(s=>{const n=new FileReader;n.onload=()=>s({id:`${e.name}-${e.size}-${Math.random().toString(36).slice(2,7)}`,name:e.name,kind:"text",mimeType:e.type||"text/plain",payload:String(n.result??""),bytes:e.size}),n.onerror=()=>s({error:`${e.name}: could not be read`}),n.readAsText(e)})}function SC(e){if(!e)return[];const t=Array.from(e.files??[]);for(const s of Array.from(e.items??[])){if(s.kind!=="file")continue;const n=s.getAsFile();n&&!t.some(i=>i.name===n.name&&i.size===n.size&&i.type===n.type)&&t.push(n)}return t}function kC(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(0)} kB`:`${(e/1048576).toFixed(1)} MB`}const kr=["#7f8c98","#5fb3a1","#7fb069","#d9a441","#e8843c","#f0603f","#ff4d4d"];function CC(e,t){const s=Math.max(1,t.length),n=t.findIndex(a=>String(a.value)===String(e)),i=n<0?0:n+1;return{color:n<0?"var(--text-dim)":kr[Math.min(n,kr.length-1)],level:i,total:s}}function EC({level:e,total:t,color:s}){const n=Math.min(7,t),i=Math.max(0,Math.min(n,Math.round(e/t*n)));return o.jsx("span",{className:"tb-pips","aria-hidden":"true",children:Array.from({length:n}).map((r,a)=>o.jsx("i",{style:{background:a<i?s:"var(--line)"}},a))})}function kc(e,t){const s=t==="effort"?["thought_level","reasoning"]:["model","model_config"],n=t==="effort"?/reason|effort|think|depth/i:/model/i;return e.find(i=>i.type==="select"&&i.category&&s.includes(String(i.category)))??e.find(i=>i.type==="select"&&n.test(i.id))}function NC({label:e,title:t,icon:s,value:n,children:i,open:r,onToggle:a,testId:l}){const c=g.useRef(null);return co(r,[c],a),o.jsxs("div",{className:"tb-wrap",ref:c,children:[o.jsxs("button",{type:"button",className:`tb-btn ${r?"on":""}`,title:t,"aria-label":t,"aria-expanded":r,"data-testid":l,onClick:a,children:[s,o.jsx("span",{className:"tb-label",children:n||e}),o.jsx(ya,{size:11,className:"tb-chev"})]}),r?i:null]})}function Yh({items:e,current:t,onPick:s,empty:n}){const i=dS();return e.length?o.jsx("div",{className:"tb-list",role:"listbox",ref:i,children:e.map(r=>o.jsxs("button",{role:"option","aria-selected":r.value===t,className:`tb-opt ${r.value===t?"sel":""}`,title:r.hint?`${r.name} — ${r.hint}`:r.name,onClick:()=>s(r.value),children:[o.jsxs("span",{className:"tb-opt-name",children:[r.color?o.jsx("i",{className:"tb-dot",style:{background:r.color}}):null,r.name]}),r.hint?o.jsx("span",{className:"tb-opt-hint",children:r.hint}):null]},r.value))}):o.jsx("div",{className:"tb-list",ref:i,children:o.jsx("div",{className:"tb-empty",children:n})})}function RC(e){return e.category==="_context_window"?!0:/budget|context/i.test(`${e.id} ${e.name??""}`)}function zB({v:e}){const t=e.info.usage,s=e.info.configOptions.find(RC),[n,i]=g.useState(!1),r=g.useRef(null),[a,l]=g.useState(!1),[c,u]=g.useState(""),[h,d]=g.useState(!0),[p,f]=g.useState(""),[m,b]=g.useState(""),_=O_(),v=e.trace;co(n,[r],()=>{i(!1),l(!1)});const y=t?.used??0,w=t?.size??0,x=y>0||w>0,S=e.info.contextLimit&&e.info.contextLimit>0?e.info.contextLimit:null,N=e.info.modelContextLimit&&e.info.modelContextLimit>0?e.info.modelContextLimit:null,R=S?"session":N?"model":"agent",E=S??N??w,M=E>0?Math.min(100,Math.round(y/E*100)):0,F=x?M>=85?"hot":M>=65?"warn":"ok":"ok",B=E>0?Math.max(0,E-y):0,k=e.info.commands??[],A=O=>k.some(K=>K.name===O),D=R==="session"?"你为本会话声明":R==="model"?"你为这个模型记下的":"agent 上报(usage_update)",H=async(O,K={})=>{f(K.forgetModel?"forget":"save"),b("");try{await ee.setContextLimit(e.info.id,O,K),l(!1)}catch(U){b(String(U?.message??U))}finally{f("")}},I=O=>{if(e.info.cold){i(!1),ee.resume(e.info.id);return}ee.send({t:"prompt",sessionId:e.info.id,text:`/${O}`}),i(!1)},z=(O,K)=>{const U=K.trim();U&&(ee.send({t:"set-config",sessionId:e.info.id,configId:O,value:U}),u(""))},T=String(s?.currentValue??"");return o.jsxs("div",{className:`usage-row ${F}`,ref:r,children:[o.jsxs("button",{className:"usage-text",onClick:()=>i(O=>!O),title:"上下文窗口 — 点这里改",children:[o.jsx(Xv,{size:12,className:"usage-icon"}),x?E>0?`${$n(y)} / ${$n(E)}`:`${$n(y)} / —`:E>0?`未上报用量 · 窗口 ${$n(E)}`:"agent 未上报用量 · 设窗口",x&&E>0?` · ${M}%`:"",R==="session"?" · 声明":R==="model"?" · 模型记录":""]}),E>0?o.jsx("div",{className:"usage-bar",title:x?`${y} / ${E} tokens (${M}%)`:`agent 未上报用量 · 已声明 ${E} tokens`,children:o.jsx("i",{style:{width:`${x?M:0}%`}})}):null,F==="hot"&&A("compress")&&!e.busy?o.jsxs("button",{className:"usage-act",onClick:()=>I("compress"),title:"发送 /compress:让 agent 压缩上下文(这是它自己公告的命令)",children:[o.jsx(e_,{size:11})," 压缩上下文"]}):null,n?o.jsxs("div",{className:"usage-detail",children:[o.jsxs("div",{className:"usage-set",children:[o.jsxs("div",{className:"usage-set-head",children:[o.jsx(Xv,{size:12})," 上下文窗口",o.jsx("span",{className:"usage-set-scope",children:s?String(s.meta?.scope??"")==="model"?"按模型":"":"仅声明"})]}),s?o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"usage-set-chips",children:(s.options??[]).map(O=>o.jsx("button",{className:`usage-chip ${T===String(O.value)?"sel":""}`,onClick:()=>z(s.id,String(O.value)),children:String(O.value)==="auto"?"自动":O.name},String(O.value)))}),o.jsxs("div",{className:"usage-edit",children:[o.jsx("input",{value:c,inputMode:"numeric","aria-label":"context window in tokens",placeholder:s.meta?.freeform===!0?"任意 token 数,如 300000":"填一个数",onChange:O=>u(O.target.value),onKeyDown:O=>{_.isComposing(O)||(O.key==="Enter"&&z(s.id,c),O.key==="Escape"&&(O.stopPropagation(),i(!1)))}}),o.jsx("button",{className:"usage-edit-btn",disabled:!c.trim(),onClick:()=>z(s.id,c),children:"set"})]}),o.jsx("div",{className:"settings-note",children:"常用:256k / 512k / 768k / 1m;填 auto 回到模型自己的窗口。"}),o.jsxs("div",{className:"usage-note",children:["改的是",o.jsx("b",{children:"这个模型"}),":同模型的所有会话(含新开的、别的槽位)都用同一个上限。它只会让 Hermes 更早压缩,不会把窗口撑过模型本身。"]})]}):o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"usage-note",children:e.info.backend==="qoder"?o.jsxs(o.Fragment,{children:["这个后端不公告上下文旋钮,也不上报用量(所以没有仪表盘数字)。下面的",o.jsx("b",{children:"声明"}),"对 qoder 是真的: 它会在",o.jsx("b",{children:"下次启动"}),"(冷启 / 重启 / 恢复)时作为 ",o.jsx("code",{children:"--context-window"})," 交给 CLI, 当场改要先停一次会话。"]}):o.jsxs(o.Fragment,{children:["这个后端没公告上下文旋钮,所以下面这个数只是仪表盘的",o.jsx("b",{children:"声明"}),",只影响百分比;真减上下文用压缩命令或换模型。"]})}),a?o.jsxs("div",{className:"usage-edit",children:[o.jsx("input",{autoFocus:!0,value:c,inputMode:"numeric","aria-label":"context window in tokens",placeholder:String(w||e.info.contextLimit||2e5),onChange:O=>u(O.target.value),..._.handlers,onKeyDown:O=>{if(!_.isComposing(O)){if(O.key==="Enter"){const K=Number(c.replace(/[^0-9]/g,""));K>0&&H(K,{remember:h})}O.key==="Escape"&&(O.stopPropagation(),l(!1))}}}),o.jsx("button",{className:"usage-edit-btn",disabled:p!==""||!Number(c.replace(/[^0-9]/g,"")),onClick:()=>void H(Number(c.replace(/[^0-9]/g,"")),{remember:h}),children:p==="save"?"…":"set"}),o.jsxs("label",{className:"usage-check",title:"像 studio 那样按模型记住:下次用这个模型自动带回来",children:[o.jsx("input",{type:"checkbox",checked:h,onChange:O=>d(O.target.checked)}),"记到本模型"]}),N?o.jsx("button",{className:"usage-edit-btn",disabled:p!=="",onClick:()=>void H(null,{forgetModel:!0}),children:p==="forget"?"…":"忘掉本模型记录"}):null]}):o.jsx("button",{className:"usage-edit-btn",onClick:()=>{u(String(E||2e5)),l(!0)},children:"声明窗口长度"})]})]}),o.jsx("div",{children:x?`已用 ${y} / ${E||"—"} tokens(${M}%)`:"agent 未上报用量(这个后端不发 usage_update)"}),o.jsxs("div",{children:["剩余:",x&&E>0?`${B} tokens`:"unknown"]}),o.jsxs("div",{children:["窗口来源:",o.jsx("b",{children:D})]}),w>0&&R!=="agent"?o.jsxs("div",{children:["agent 上报:",$n(w)," tokens (usage_update)"]}):null,N&&R==="session"?o.jsxs("div",{children:["本模型记录:",$n(N)," tokens"]}):null,t?.cost!=null?o.jsxs("div",{children:["本轮花费:$",t.cost.toFixed(6)]}):null,v?.model?o.jsxs("div",{children:["model:",v.model]}):null,v&&(v.effort||v.mode)?o.jsxs("div",{children:["本轮:",[v.effort&&`思考强度 ${v.effort}`,v.mode&&`模式 ${v.mode}`].filter(Boolean).join(",")]}):null,A("compress")||A("context")?o.jsxs("div",{className:"usage-actions",children:[A("compress")?o.jsx("button",{className:"usage-act",onClick:()=>I("compress"),title:"让 agent 压缩上下文(/compress,它自己公告的命令)",children:"压缩上下文"}):null,A("context")?o.jsx("button",{className:"usage-act",onClick:()=>I("context"),title:"看消息按角色分布(/context)",children:"消息分布"}):null]}):null,m?o.jsx("div",{className:"usage-edit-err",children:m}):null]}):null]})}function HB({o:e,sessionId:t}){const s=e.meta??{},n=s.freeform===!0,[i,r]=g.useState(""),a=String(e.currentValue??""),l=typeof s.unit=="string"?s.unit:"tokens",c=h=>ee.send({t:"set-config",sessionId:t,configId:e.id,value:h}),u=O_();return o.jsxs("div",{className:"settings-group",children:[o.jsxs("div",{className:"settings-label",children:[o.jsx(Tc,{size:13})," ",e.name||e.id]}),e.options?.map(h=>o.jsx("button",{className:`settings-opt ${a===String(h.value)?"sel":""}`,onClick:()=>c(String(h.value)),children:h.name},String(h.value))),n?o.jsxs("div",{className:"settings-freeform",children:[o.jsx("input",{className:"settings-input",type:"number",inputMode:"numeric",min:typeof s.min=="number"?s.min:void 0,step:typeof s.step=="number"?s.step:1024,placeholder:`任意 ${l}`,"aria-label":`${e.name||e.id} value`,value:i,onChange:h=>r(h.target.value),...u.handlers,onKeyDown:h=>{u.isComposing(h)||h.key==="Enter"&&i.trim()&&c(i.trim())}}),o.jsx("button",{className:"settings-opt",disabled:!i.trim(),onClick:()=>c(i.trim()),children:"set"})]}):null]})}function UB({v:e,prefs:t,setPrefs:s,onClose:n,panelRef:i}){const r=e.info,a=r.modes?.availableModes??[],l=kc(r.configOptions,"effort"),c=kc(r.configOptions,"model"),h=g.useSyncExternalStore(Ft.subscribeVoices,()=>Ft.voices().length)?Ft.voices():[],d=li();return o.jsxs("div",{className:"settings-pop",role:"dialog","aria-label":"chat settings",ref:i,children:[o.jsxs("div",{className:"settings-head",children:[o.jsx("span",{children:"chat settings"}),o.jsx("span",{className:"head-spacer"}),o.jsx("button",{className:"icon-btn",title:"close","aria-label":"close",onClick:n,children:o.jsx(En,{size:13})})]}),a.length>0&&o.jsxs("div",{className:"settings-group",children:[o.jsxs("div",{className:"settings-label",children:[o.jsx(vS,{size:13})," permission mode"]}),a.map(p=>o.jsx("button",{className:`settings-opt ${r.modes?.currentModeId===p.id?"sel":""}`,onClick:()=>ee.send({t:"set-mode",sessionId:r.id,modeId:p.id}),children:p.name},p.id))]}),l?.options?.length?o.jsxs("div",{className:"settings-group",children:[o.jsxs("div",{className:"settings-label",children:[o.jsx(kN,{size:13})," thinking depth"]}),l.options.map((p,f)=>o.jsxs("button",{className:`settings-opt ${String(l.currentValue??"")===String(p.value)?"sel":""}`,onClick:()=>ee.send({t:"set-config",sessionId:r.id,configId:l.id,value:String(p.value)}),children:[o.jsx("i",{className:"settings-dot",style:{"--effort":kr[Math.min(f,kr.length-1)]}}),p.name]},String(p.value))),o.jsx("div",{className:"settings-note",children:"只列这个路由真支持的档;改的是本会话。"})]}):null,r.configOptions.filter(p=>p.type==="select"&&p.options&&p!==l&&p!==c&&!RC(p)).map(p=>o.jsx(HB,{o:p,sessionId:r.id},p.id)),o.jsxs("div",{className:"settings-group",children:[o.jsxs("div",{className:"settings-label",children:[o.jsx(hd,{size:13})," read replies aloud"]}),o.jsxs("label",{className:"settings-toggle",children:[o.jsx("input",{type:"checkbox",checked:t.autoRead,onChange:p=>s({autoRead:p.target.checked})}),o.jsx("span",{children:"speak every finished reply"})]}),h.length>0&&o.jsxs("select",{className:"settings-select",value:t.voiceURI,onChange:p=>s({voiceURI:p.target.value}),"aria-label":"voice",children:[o.jsxs("option",{value:"",children:["auto voice (",t.lang,")"]}),h.map(p=>o.jsxs("option",{value:p.voiceURI,children:[p.name," — ",p.lang]},p.voiceURI))]}),h.length===0?o.jsx("div",{className:"settings-note",children:"this browser exposes no voices"}):null,o.jsxs("label",{className:"settings-range",children:[o.jsxs("span",{children:["speed ",t.rate.toFixed(2),"×"]}),o.jsx("input",{type:"range",min:.5,max:2,step:.05,value:t.rate,onChange:p=>s({rate:Number(p.target.value)})})]}),d.tts.server?o.jsxs("label",{className:"settings-toggle",children:[o.jsx("input",{type:"checkbox",checked:t.serverTts,onChange:p=>s({serverTts:p.target.checked})}),o.jsxs("span",{children:["use the server voice (",d.tts.model??"configured",")"]})]}):null]}),o.jsxs("div",{className:"settings-group",children:[o.jsxs("div",{className:"settings-label",children:[o.jsx(ji,{size:13})," dictation"]}),o.jsxs("select",{className:"settings-select",value:t.stt,onChange:p=>s({stt:p.target.value}),"aria-label":"dictation engine",children:[o.jsx("option",{value:"auto",children:"auto — 服务端流式 > 浏览器 > 批量"}),o.jsxs("option",{value:"stream",children:["stream",d.stt.streaming?` (${d.stt.model??"百炼"})`:" (not configured)"]}),o.jsxs("option",{value:"browser",children:["browser",Vp()?"":" (unavailable)"]}),o.jsxs("option",{value:"server",children:["server",d.stt.server?` (${d.stt.batchModel??"configured"})`:" (not configured)"]})]}),o.jsx("input",{className:"settings-input",value:t.lang,onChange:p=>s({lang:p.target.value}),placeholder:"language, e.g. zh-CN","aria-label":"speech language"}),o.jsxs("div",{className:"settings-note",children:["browser dictation ",Vp()?"available":"unavailable"," · ",d.provider," STT"," ",d.stt.streaming?"streaming":d.stt.server?"batch":"not configured"]})]})]})}const Tu=new Map;function WB({v:e,call:t,tus:s,onCloseCall:n}){const[i,r]=g.useState(()=>Tu.get(e.info.id)??""),a=NS(e.info.backend),l=window.innerWidth<720?"message… (/ for commands)":"message… (Enter send, Shift+Enter newline, / for commands)",c=/Mac|iPhone|iPad/.test(navigator.platform??"")?"⌘":"Ctrl+",u=window.innerWidth<=720?"message… (Enter queues)":`message… (${c}Enter interrupts · Enter queues)`,[h,d]=g.useState(0),[p,f]=g.useState(!1),m=g.useRef(null),b=g.useRef(null),_=g.useRef(null),v=g.useRef(!1),y=g.useRef(null),w=g.useRef(""),x=g.useRef(!1),S=g.useMemo(()=>e.msgs.filter(P=>P.kind==="user").map(P=>P.text).filter(P=>P.trim()),[e.msgs]),N=g.useRef(e.info.id);g.useEffect(()=>{Tu.set(N.current,i)},[i]),g.useEffect(()=>{N.current!==e.info.id&&(Tu.set(N.current,i),N.current=e.info.id,r(Tu.get(e.info.id)??""),y.current=null,w.current="",f(!1),d(0))},[e.info.id,i]);const[R,E]=g.useState([]),[M,F]=g.useState(null),[B,k]=g.useState(""),[A,D]=g.useState(!1),[H,I]=g.useState(!1),[z,T]=g.useState(null);g.useEffect(()=>{const P=Oe.current;P&&(P.style.height="42px",P.style.height=`${Math.min(P.scrollHeight,window.innerHeight*.4)}px`)},[i]);const[O,K]=g.useState(!1),[U,re]=g.useState(null),[J,Y]=g.useState({});g.useEffect(()=>{Y({}),re(null)},[e.info.id]);const[_e,xe]=_o(),fe=r_(),et=dd(),Oe=g.useRef(null),tt=g.useRef(null),Pe=async P=>{const le=Array.from(P);if(!le.length)return;const je=await Promise.all(le.map(ot=>xC(ot))),Ie=[],Ge=[];for(const ot of je)"error"in ot?Ge.push(ot.error):Ie.push(ot);Ie.length&&E(ot=>[...ot,...Ie]),k(Ge.join(" · "))},Le=()=>R.map(P=>P.kind==="image"?{kind:"image",mimeType:P.mimeType,data:P.payload,name:P.name}:{kind:"text",name:P.name,text:P.payload}),Ee=P=>{if(P.key!=="ArrowUp"&&P.key!=="ArrowDown"||P.shiftKey||P.altKey||P.metaKey||P.ctrlKey||!S.length)return!1;const le=P.currentTarget,je=le.selectionStart??0;if(P.key==="ArrowUp"&&le.value.slice(0,je).includes(`
|
|
130
130
|
`)||P.key==="ArrowDown"&&le.value.slice(je).includes(`
|
|
131
131
|
`))return!1;if(P.preventDefault(),P.key==="ArrowUp")y.current===null?(w.current=le.value,y.current=S.length-1):y.current=Math.max(0,y.current-1);else{if(y.current===null)return!0;if(y.current>=S.length-1)return y.current=null,x.current=!0,r(w.current),requestAnimationFrame(()=>Oe.current?.setSelectionRange(w.current.length,w.current.length)),!0;y.current+=1}const Ie=S[y.current];return x.current=!0,r(Ie),requestAnimationFrame(()=>Oe.current?.setSelectionRange(Ie.length,Ie.length)),!0},Ae=()=>{const P=i.trim();if(!P&&!R.length)return;uc();const le=Le();if(e.info.cold){ee.sendToCold(e.info.id,P,le),r(""),E([]),k(""),d(0),Kl.current();return}if(Qr(e)||e.info.status!=="ready"){if(!P&&!le.length)return;ee.enqueuePrompt(e.info.id,P,le)}else ee.sendPrompt(e.info.id,P,le);r(""),E([]),k(""),d(0),y.current=null,w.current="",Kl.current()},Ze=()=>{const P=i.trim();if(!P&&!R.length)return;uc();const le=Le();e.info.cold?ee.sendToCold(e.info.id,P,le):ee.sendNow(e.info.id,P,le),r(""),E([]),k(""),d(0),Kl.current()};g.useEffect(()=>{if(t||!pe.owns("chat")||fe.status!=="idle"||!fe.text)return;const P=pe.consume();P&&(r(le=>le.trim()?`${le.trim()} ${P}`:P),Oe.current?.focus())},[fe.status,fe.text,t]),g.useEffect(()=>{if(t)return;let P=null,le=!1;const je=()=>{P!==null&&(window.clearTimeout(P),P=null)},Ie=dt=>{if(dt.key!=="Control"){P!==null&&je();return}dt.repeat||P!==null||le||document.activeElement===Oe.current&&(P=window.setTimeout(()=>{P=null,le=!0,pe.cancel(),pe.start(_e,e.info.id)},250))},Ge=dt=>{dt.key==="Control"&&(je(),le&&(le=!1,pe.owns("chat")&&pe.stop()))},ot=()=>{je(),le&&(le=!1,pe.owns("chat")&&pe.stop())};return window.addEventListener("keydown",Ie),window.addEventListener("keyup",Ge),window.addEventListener("blur",ot),()=>{je(),window.removeEventListener("keydown",Ie),window.removeEventListener("keyup",Ge),window.removeEventListener("blur",ot)}},[t,_e,e.info.id]);const me=/^\/\S*$/.test(i)?i.slice(1).toLowerCase():null,Ye=me===null?[]:e.info.commands.filter(P=>P.name.toLowerCase().includes(me)).slice(0,8),de=me!==null&&e.info.status==="ready"&&!p;co(de,[m],()=>f(!0)),co(H||z!==null,[b,_],()=>{T(null),I(!1)}),g.useEffect(()=>{T(null),I(!1),f(!1)},[e.info.id]);const lt=P=>{r(`/${P} `),d(0),Oe.current?.focus()},ae=fe.status==="listening"||fe.status==="recording"||fe.status==="requesting",be=kc(e.info.configOptions,"effort"),Be=kc(e.info.configOptions,"model"),W=e.info.models?.availableModels??[],Se=e.info.models?.currentModelId??"",He=W.find(P=>P.modelId===Se)?.name??Be?.options?.find(P=>String(P.value)===String(Be.currentValue??""))?.name??Se,q=t_(He,Se),Z=be?.options?.find(P=>String(P.value)===String(be.currentValue??""))?.name??"",ge=be?CC(String(be.currentValue??""),be.options??[]):null;return o.jsxs("div",{className:`composer ${A?"drop-active":""}`,onDragOver:P=>{P.preventDefault(),D(!0)},onDragLeave:()=>D(!1),onDrop:P=>{P.preventDefault(),D(!1),P.dataTransfer?.files?.length&&Pe(P.dataTransfer.files)},onPaste:P=>{const le=SC(P.clipboardData);le.length&&(P.preventDefault(),Pe(le))},children:[o.jsx(gB,{v:e}),o.jsx(CB,{v:e}),o.jsx(zB,{v:e}),o.jsxs("div",{className:"composer-inner",ref:m,children:[de&&o.jsx("div",{className:"slash-palette",role:"listbox","aria-label":"slash commands",children:Ye.length?Ye.map((P,le)=>o.jsxs("div",{role:"option","aria-selected":le===h,className:`slash-item ${le===h?"sel":""}`,onMouseEnter:()=>d(le),onClick:()=>lt(P.name),children:[o.jsxs("span",{className:"cmd",children:["/",P.name]}),P.description?o.jsx("span",{className:"desc",children:P.description}):null,o.jsx("span",{className:"src",title:"advertised by the agent over ACP",children:"agent"})]},P.name)):o.jsx("div",{className:"slash-item empty",children:e.info.commands.length?`no command matches “/${me}”`:"this agent advertises no slash commands"})}),H&&o.jsx(UB,{v:e,prefs:_e,setPrefs:xe,onClose:()=>I(!1),panelRef:b}),R.length>0&&o.jsxs("div",{className:"draft-row",children:[R.map(P=>o.jsxs("span",{className:`draft ${P.kind}`,title:`${P.name} · ${kC(P.bytes)}`,children:[P.preview?o.jsx("img",{src:P.preview,alt:P.name}):o.jsx(ui,{size:13}),o.jsx("span",{className:"draft-name",children:P.name}),o.jsx("button",{className:"draft-x","aria-label":`remove ${P.name}`,onClick:()=>E(le=>le.filter(je=>je.id!==P.id)),children:o.jsx(En,{size:11})})]},P.id)),o.jsx("button",{className:"draft-clear",onClick:()=>E([]),children:"clear"})]}),B&&o.jsx("div",{className:"composer-note err",children:B}),e.queue.length>0&&o.jsxs("div",{className:"queue-list","aria-label":"queued messages",children:[o.jsxs("div",{className:"queue-head",children:[o.jsxs("span",{className:"queue-title",children:["Queued · ",e.queue.length]}),o.jsx("span",{className:"queue-hint",children:e.queue.some(P=>P.unsure)?"未确认送达 — 点 ↑ 重发,或 ✕ 丢掉":e.queue.some(P=>P.inflight)?"sending…":e.resuming?"waking the agent — sends once it is up":e.info.cold?"sends when you wake this session":e.info.status!=="ready"?"process starting — sends once ready":"goes out when this turn ends"})]}),e.queue.map((P,le)=>o.jsxs("div",{className:`queue-row${P.inflight?" inflight":""}${P.unsure?" unsure":""}`,"data-queue-id":P.id,children:[o.jsx("span",{className:"queue-idx","aria-hidden":"true",children:le+1}),M?.id===P.id?o.jsx("textarea",{className:"queue-edit",rows:1,autoFocus:!0,value:M.text,"aria-label":"edit the queued message",onChange:je=>F({id:P.id,text:je.target.value}),onKeyDown:je=>{if(je.key==="Escape"){je.preventDefault(),F(null);return}je.key==="Enter"&&!je.shiftKey&&(je.preventDefault(),ee.editQueued(e.info.id,P.id,M.text),F(null))},onBlur:()=>{ee.editQueued(e.info.id,P.id,M.text),F(null)}}):o.jsx("span",{className:"queue-text",title:P.text,children:P.text}),P.unsure?o.jsx("span",{className:"queue-flag",title:"服务器没回执 —— 点 ↑ 重发",children:"未送达"}):null,o.jsxs("span",{className:"queue-actions",children:[o.jsx("button",{className:"queue-btn",title:"send now — stops the running turn and takes the floor","aria-label":"send this one now",onClick:()=>ee.sendQueuedNow(e.info.id,P.id),children:o.jsx(yS,{size:13})}),o.jsx("button",{className:"queue-btn",title:"edit this message","aria-label":"edit this queued message",onClick:()=>F(M?.id===P.id?null:{id:P.id,text:P.text}),children:o.jsx(pS,{size:13})}),o.jsx("button",{className:"queue-btn danger",title:"drop it — it will not be sent","aria-label":"drop this queued message",onClick:()=>ee.dropQueued(e.info.id,P.id),children:o.jsx(En,{size:13})})]})]},P.id))]}),et.note?o.jsx("div",{className:"composer-note",children:et.note}):null,et.error?o.jsx("div",{className:"composer-note err",children:et.error}):null,ae||fe.status==="transcribing"||fe.error?o.jsxs("div",{className:`dict-chip ${fe.error?"err":""}`,children:[o.jsx(ji,{size:13}),fe.error?fe.error:fe.status==="requesting"?"waiting for the microphone…":fe.status==="transcribing"?"transcribing…":o.jsxs(o.Fragment,{children:[fe.text," ",o.jsx("span",{className:"interim",children:fe.interim}),fe.engine==="stream"?" · 流式":"",fe.engine==="server"?` · ${fe.seconds}s`:""]}),ae?o.jsx("button",{className:"dict-stop",onClick:()=>pe.stop(),children:"stop"}):null]}):null,o.jsxs("div",{className:"composer-box",children:[o.jsx("textarea",{ref:Oe,rows:1,value:i,onFocus:()=>f(!1),placeholder:e.resuming?"waking the agent…":e.info.cold?"no ACP process — Enter wakes it":Qr(e)?u:e.info.status==="ready"?l:e.info.status,onChange:P=>{r(P.target.value),f(!1),d(0),x.current?x.current=!1:y.current=null},onCompositionStart:()=>{v.current=!0},onCompositionEnd:()=>{v.current=!1},onKeyDown:P=>{if(!(v.current||P.nativeEvent.isComposing)){if(P.key==="Enter"&&(P.metaKey||P.ctrlKey)&&!P.shiftKey){P.preventDefault(),Ze();return}if(de&&Ye.length){if(P.key==="ArrowDown"){P.preventDefault(),d(le=>(le+1)%Ye.length);return}if(P.key==="ArrowUp"){P.preventDefault(),d(le=>(le-1+Ye.length)%Ye.length);return}if(P.key==="Tab"||P.key==="Enter"&&!P.shiftKey){P.preventDefault(),lt(Ye[h].name);return}if(P.key==="Escape"){P.preventDefault(),r("");return}}if(!Ee(P)){if(P.key==="Escape"&&y.current!==null){P.preventDefault(),y.current=null,r(w.current);return}P.key==="Enter"&&!P.shiftKey&&(P.preventDefault(),Ae())}}}}),o.jsxs("div",{className:"composer-bar",ref:_,children:[o.jsx("input",{ref:tt,type:"file",multiple:!0,hidden:!0,accept:`${L_.join(",")},.txt,.md,.json,.log,.csv,.ts,.tsx,.js,.jsx,.py,.rb,.go,.rs,.java,.c,.cpp,.h,.sh,.yaml,.yml,.toml,.ini,.html,.css`,onChange:P=>{const le=P.target.files;le&&le.length?Pe(le):k("选择器没有返回文件 —— 再试一次,或从相册 / 文件管理里选"),P.target.value=""}}),o.jsx("button",{className:"icon-btn",title:"attach an image or a text file","aria-label":"attach",onClick:()=>tt.current?.click(),children:o.jsx(kh,{size:16})}),be&&ge?o.jsxs("div",{className:"tb-wrap",style:{"--effort":ge.color},children:[o.jsxs("button",{type:"button",className:`tb-btn tb-effort ${z==="effort"?"on":""}`,style:{color:ge.level?ge.color:void 0},title:`thinking depth — ${Z||"agent default"}`,"aria-label":`thinking depth: ${Z||"agent default"}`,"aria-expanded":z==="effort","data-testid":"tb-effort",onClick:()=>{I(!1),T(P=>P==="effort"?null:"effort")},children:[o.jsx(EC,{level:ge.level,total:ge.total,color:ge.color}),o.jsx(ya,{size:11,className:"tb-chev"})]}),z==="effort"?o.jsx(Yh,{items:(be.options??[]).map((P,le)=>({value:String(P.value),name:P.name,hint:null,color:kr[Math.min(le,kr.length-1)]})),current:String(be.currentValue??""),empty:"the agent advertises no levels",onPick:P=>{ee.send({t:"set-config",sessionId:e.info.id,configId:be.id,value:P}),T(null)}}):null]}):null,o.jsx("button",{className:`icon-btn ${H?"on":""}`,title:"chat settings — permission mode, voice","aria-label":"chat settings","aria-expanded":H,onClick:()=>{T(null),I(P=>!P)},children:o.jsx(Tc,{size:16})}),W.length>0||Be?o.jsx(NC,{label:"model",title:`model — currently ${q||"unknown"}`,icon:o.jsx(e_,{size:15}),value:O?`${q} …`:q,testId:"tb-model",open:z==="model",onToggle:()=>{I(!1),T(P=>P==="model"?null:"model")},children:W.length>0?o.jsx(ES,{models:W,current:Se,usage:a,pending:e.info.pendingModelId??null,bad:J,err:U,onPick:P=>{if(P===Se){T(null);return}K(!0),re(null),ee.setModel(e.info.id,P).then(le=>{le?.models?.currentModelId===P&&IN(e.info.backend,P),T(null),re(null),k("")}).catch(le=>{const je=String(le?.message??le);re({id:P,text:je}),Y(Ie=>({...Ie,[P]:je})),k(`model switch failed: ${je}`)}).finally(()=>K(!1))}}):o.jsx(Yh,{items:(Be?.options??[]).map(P=>({value:String(P.value),name:P.name})),current:String(Be?.currentValue??""),empty:"the agent lists no models",onPick:P=>{Be&&ee.send({t:"set-config",sessionId:e.info.id,configId:Be.id,value:P}),T(null)}})}):null,o.jsx("span",{className:"head-spacer"}),o.jsx("button",{className:`icon-btn ${ae?"on rec":""}`,title:fe.error?fe.error:ae?"stop dictation(或松开 Ctrl)":"dictate a prompt(或按住 Ctrl 说话)","aria-label":"dictate",onClick:()=>{pe.cancel(),pe.start(_e,e.info.id)},children:o.jsx(ji,{size:16})}),t?o.jsx(sI,{sessionId:e.info.id,tus:s,pending:e.perms.length,onClose:n,onKeyboard:()=>{n(),window.setTimeout(()=>Oe.current?.focus(),30)},renderTranscript:P=>o.jsx(gC,{...P,notes:e.notes})}):null,Qr(e)?o.jsx("button",{className:"send-btn stop",title:"stop this turn","aria-label":"stop this turn",onClick:()=>ee.send({t:"cancel",sessionId:e.info.id}),children:o.jsx(xh,{size:14})}):o.jsx("button",{className:"send-btn",onClick:Ae,disabled:!i.trim()&&!R.length||e.resuming||!e.info.cold&&e.info.status!=="ready",title:e.resuming?"正在唤醒 agent 进程…":e.info.cold?"唤醒会话 (Enter)":"send (Enter)","aria-label":"send",children:o.jsx(Sh,{size:16})})]})]})]})]})}function KB({backend:e}){const t=vd(e),[s,n]=g.useState(!1);return o.jsx("span",{className:"be-card-mark","data-backend":e,"data-letter":t.letter,children:t.icon&&!s?o.jsx("img",{src:t.icon,alt:"",draggable:!1,onError:()=>n(!0)}):t.letter})}function qB({cwd:e,onClose:t}){Ta(!0,t);const[s,n]=g.useState(""),i=NS(s),[r,a]=g.useState(e??""),l=e??"",[c,u]=g.useState(""),[h,d]=g.useState([]),[p,f]=g.useState(""),[m,b]=g.useState(!1),[_,v]=g.useState(""),[y,w]=g.useState(!0),[x,S]=g.useState([]),[N,R]=g.useState(!1),[E,M]=g.useState(!1),[F,B]=g.useState(null),[k,A]=g.useState(null),[D,H]=g.useState(null),[I,z]=g.useState(null),[T]=_o(),O=r_(),K=O.status==="listening"||O.status==="recording"||O.status==="requesting",U=g.useRef(!1),re=g.useRef(null),J=g.useRef(null);g.useEffect(()=>{const W=re.current;W&&(W.style.height="42px",W.style.height=`${Math.min(W.scrollHeight,window.innerHeight*.4)}px`)},[c]);const Y=()=>{w(!0),v(""),Promise.all([ee.loadBackends(),fetch("/api/version",{cache:"no-store"}).then(W=>W.json()).catch(()=>({dev:!1})),fetch("/api/fs/dirs",{cache:"no-store"}).then(W=>W.json()).catch(()=>({}))]).then(([W,Se,He])=>{S(W),R(!!Se?.dev),n(q=>q||vy(W,!!Se?.dev)[0]?.id||""),a(q=>q||He?.home||"")}).catch(W=>v(`后端列表拉取失败:${String(W.message??W)}`)).finally(()=>w(!1))};g.useEffect(Y,[]),g.useLayoutEffect(()=>(pe.setOwner("start"),()=>pe.setOwner("chat")),[]),g.useEffect(()=>{if(!pe.owns("start")||O.status!=="idle"||!O.text)return;const W=pe.consume();W&&(u(Se=>Se.trim()?`${Se.trim()} ${W}`:W),re.current?.focus())},[O.status,O.text]);const _e=vy(x,N),xe=x.find(W=>W.id===s)??null,fe=xe?.handshake??null,et=fe?.configOptions??[],Oe=kc(et,"effort"),tt=Oe?.options??[],Pe=k??String(Oe?.currentValue??""),Le=Oe?CC(Pe,tt):null,Ee=tt.find(W=>String(W.value)===Pe)?.name??"",Ae=fe?.modes?.available??[],Ze=D??fe?.modes?.currentModeId??"",me=Ze?fe?.modes?.names?.[Ze]??Ze:"默认权限",Ye=fe?.models?.available??[],de=F??fe?.models?.currentModelId??"",lt=de?t_(de):"默认模型",ae=()=>{const W=[];return F&&W.push({kind:"model",value:F}),k&&Oe&&W.push({kind:"config",id:String(Oe.id),value:k}),D&&W.push({kind:"mode",value:D}),W},be=async W=>{const Se=Array.from(W);if(!Se.length)return;const He=await Promise.all(Se.map(ge=>xC(ge))),q=[],Z=[];for(const ge of He)"error"in ge?Z.push(ge.error):q.push(ge);q.length&&d(ge=>[...ge,...q]),f(Z.join(" · "))},Be=async()=>{const W=c.trim();if(!(!W&&!h.length||!s||!r.trim())){b(!0),v("");try{K&&pe.stop();const Se=h.map(q=>q.kind==="image"?{kind:"image",mimeType:q.mimeType,data:q.payload,name:q.name}:{kind:"text",name:q.name,text:q.payload}),He=await ee.createSession(s,r.trim(),"");ee.queueSetup(He,ae()),ee.setActive(He),ee.enqueuePrompt(He,W,Se),t()}catch(Se){v(String(Se.message??Se))}finally{b(!1)}}};return o.jsx("div",{className:"modal-bg",onClick:t,children:o.jsxs("div",{className:"modal start-page",onClick:W=>W.stopPropagation(),children:[o.jsxs("div",{className:"start-head",children:[o.jsx("h3",{children:"新建会话"}),o.jsx(aI,{value:l||r,onChange:a,locked:!!l})]}),o.jsx("div",{className:"composer start-composer",onPaste:W=>{const Se=SC(W.clipboardData);Se.length&&(W.preventDefault(),be(Se))},children:o.jsxs("div",{className:"composer-inner",children:[h.length>0&&o.jsxs("div",{className:"draft-row",children:[h.map(W=>o.jsxs("span",{className:`draft ${W.kind}`,title:`${W.name} · ${kC(W.bytes)}`,children:[W.preview?o.jsx("img",{src:W.preview,alt:W.name}):o.jsx(ui,{size:13}),o.jsx("span",{className:"draft-name",children:W.name}),o.jsx("button",{className:"draft-x","aria-label":`remove ${W.name}`,onClick:()=>d(Se=>Se.filter(He=>He.id!==W.id)),children:o.jsx(En,{size:11})})]},W.id)),o.jsx("button",{className:"draft-clear",onClick:()=>d([]),children:"clear"})]}),p&&o.jsx("div",{className:"composer-note err",children:p}),o.jsxs("div",{className:"composer-box",children:[o.jsx("textarea",{ref:re,rows:1,autoFocus:!0,value:c,"aria-label":"first message",placeholder:"say something to start… (Enter sends)",onChange:W=>u(W.target.value),onCompositionStart:()=>{U.current=!0},onCompositionEnd:()=>{U.current=!1},onKeyDown:W=>{U.current||W.nativeEvent.isComposing||W.key==="Enter"&&!W.shiftKey&&(W.preventDefault(),Be())}}),o.jsxs("div",{className:"composer-bar",children:[o.jsx("input",{ref:J,type:"file",multiple:!0,hidden:!0,accept:`${L_.join(",")},.txt,.md,.json,.log,.csv,.ts,.tsx,.js,.jsx,.py,.rb,.go,.rs,.java,.c,.cpp,.h,.sh,.yaml,.yml,.toml,.ini,.html,.css`,onChange:W=>{const Se=W.target.files;Se&&Se.length?be(Se):f("选择器没有返回文件 —— 再试一次,或从相册 / 文件管理里选"),W.target.value=""}}),o.jsx("button",{className:"icon-btn",title:"attach an image or a text file","aria-label":"attach",onClick:()=>J.current?.click(),children:o.jsx(kh,{size:16})}),Oe&&tt.length?o.jsxs("div",{className:"tb-wrap",style:{"--effort":Le?.color},children:[o.jsxs("button",{type:"button",className:`tb-btn tb-effort ${I==="effort"?"on":""}`,style:{color:Pe?Le?.color:void 0},title:`thinking depth — ${Ee||"agent default"}`,"aria-label":`thinking depth: ${Ee||"agent default"}`,"aria-expanded":I==="effort","data-testid":"start-effort",onClick:()=>z(W=>W==="effort"?null:"effort"),children:[o.jsx(EC,{level:Le?.level??0,total:Le?.total??1,color:Le?.color??"var(--text-dim)"}),o.jsx(ya,{size:11,className:"tb-chev"})]}),I==="effort"?o.jsx(Yh,{items:tt.map((W,Se)=>({value:String(W.value),name:String(W.name??W.value),hint:null,color:kr[Math.min(Se,kr.length-1)]})),current:Pe,empty:"the agent advertises no levels",onPick:W=>{A(W),z(null)}}):null]}):null,Ae.length?o.jsxs("div",{className:"tb-wrap",children:[o.jsxs("button",{type:"button",className:`tb-btn ${I==="mode"?"on":""}`,title:`权限模式 — ${me}`,"aria-label":`permission mode: ${me}`,"aria-expanded":I==="mode","data-testid":"start-mode",onClick:()=>z(W=>W==="mode"?null:"mode"),children:[o.jsx(vS,{size:14}),o.jsx("span",{className:"tb-label",children:me}),o.jsx(ya,{size:11,className:"tb-chev"})]}),I==="mode"?o.jsx(Yh,{items:Ae.map(W=>({value:W,name:fe?.modes?.names?.[W]??W})),current:Ze,empty:"the agent lists no modes",onPick:W=>{H(W),z(null)}}):null]}):null,Ye.length?o.jsx(NC,{label:"model",title:`model — ${lt}`,icon:o.jsx(e_,{size:15}),value:lt,testId:"start-model",open:I==="model",onToggle:()=>z(W=>W==="model"?null:"model"),children:o.jsx(ES,{models:Ye.map(W=>({modelId:W})),current:de,usage:i,onPick:W=>{B(W),z(null)}})}):null,o.jsx("span",{className:"head-spacer"}),o.jsx("button",{className:`icon-btn ${K?"on rec":""}`,title:O.error?O.error:K?"stop dictation(或松开 Ctrl)":"dictate a prompt(或按住 Ctrl 说话)","aria-label":"dictate",onClick:()=>{pe.cancel(),pe.start(T)},children:o.jsx(ji,{size:16})}),o.jsx("button",{className:"send-btn",onClick:()=>void Be(),disabled:m||!c.trim()&&!h.length||!r.trim(),title:m?"创建中…":"创建并发送 (Enter)","aria-label":"send",children:o.jsx(Sh,{size:16})})]})]}),K||O.status==="transcribing"||O.error?o.jsxs("div",{className:`dict-chip ${O.error?"err":""}`,children:[o.jsx(ji,{size:13}),O.error?O.error:O.status==="requesting"?"waiting for the microphone…":O.status==="transcribing"?"transcribing…":o.jsxs(o.Fragment,{children:[O.text," ",o.jsx("span",{className:"interim",children:O.interim})]}),K?o.jsx("button",{className:"dict-stop",onClick:()=>pe.stop(),children:"stop"}):null]}):null]})}),o.jsxs("div",{className:"backend-pick",role:"radiogroup","aria-label":"backend",children:[y&&!x.length&&o.jsx("span",{className:"dim",children:"loading…"}),!y&&!_e.length&&o.jsx("span",{className:"dim",children:"no backends"}),_e.map(W=>o.jsxs("button",{type:"button",role:"radio","aria-checked":s===W.id,"data-backend":W.id,title:W.home?`${W.label} · home: ${W.home}`:W.label,className:`be-card ${s===W.id?"sel":""}`,onClick:()=>n(W.id),children:[o.jsx(KB,{backend:W.kind||W.id}),o.jsx("span",{className:"be-card-label",children:W.label})]},W.id)),o.jsx("button",{type:"button",className:"be-card reload",title:"重新拉取后端列表","aria-label":"重新拉取后端列表",onClick:Y,children:"⟳"})]}),(xe?.warnings??[]).map((W,Se)=>o.jsx("div",{className:"hint-warn",children:W},Se)),xe?o.jsxs("div",{className:`be-detail ${E?"open":""}`,children:[o.jsxs("button",{type:"button",className:"be-detail-head","aria-expanded":E,onClick:()=>M(W=>!W),children:[o.jsx(an,{size:12,className:"be-detail-arrow"})," 后端详情"]}),E?o.jsxs("div",{className:"hint be-hint",children:[o.jsxs("div",{children:["runs: ",o.jsxs("code",{children:[xe.cmd," ",(xe.args??[]).join(" ")]}),xe.profile?o.jsxs(o.Fragment,{children:[" · profile ",o.jsx("code",{children:xe.profile})]}):null]}),xe.home?o.jsxs("div",{children:["home: ",o.jsx("code",{children:xe.home})]}):null,xe.cwd?o.jsxs("div",{children:["cwd: ",o.jsx("code",{children:xe.cwd})]}):null,(xe.env??[]).length?o.jsxs("div",{children:["env: ",o.jsx("code",{children:(xe.env??[]).join(", ")})]}):null,fe&&!et.length&&!Ye.length?o.jsx("div",{children:"这个后端还没真跑过,所以没有可选的模型 / 设置 —— 建会话后由 agent 自己的清单决定"}):null]}):null]}):null,_&&o.jsx("div",{className:"err",children:_})]})})}FD();window.__cockpit=ee;window.__voice={dictation:pe,loadVoiceCaps:Ch,resampleToPcm16:BS,voiceCaps:li};window.__renderMarkdown=g_;hS(document.getElementById("root")).render(o.jsx(GC.StrictMode,{children:o.jsx(eB,{})}));
|