@bigduu/lotus-next 2026.9.12
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 +113 -0
- package/dist/asset-manifest.json +303 -0
- package/dist/assets/CodeBlock-dYUQ9iue.js +2 -0
- package/dist/assets/ErrorBoundary-DLCRl4Er.js +1 -0
- package/dist/assets/Markdown-DBG0vWxL.js +2 -0
- package/dist/assets/MermaidChart-U1Z5JCRh.js +1 -0
- package/dist/assets/Root-dWsRRTlH.js +7 -0
- package/dist/assets/Settings-BcsRaEDP.js +7 -0
- package/dist/assets/StreamdownMarkdown-CiLy0KJD.js +2 -0
- package/dist/assets/StreamdownMermaid-J7jSRtO6.js +1 -0
- package/dist/assets/bundle-mjs-B_AA55HL.js +1 -0
- package/dist/assets/defineProperty-o0OkIQd4.js +1 -0
- package/dist/assets/en-US-DOXBXLLy.js +3 -0
- package/dist/assets/html2canvas-ChX2ETZ3.js +1 -0
- package/dist/assets/index-CjY6eMv8.js +2 -0
- package/dist/assets/index-xUf4TnkE.css +2 -0
- package/dist/assets/index.es-BpPlqG76.js +5 -0
- package/dist/assets/lib-CFLxRXs3.js +1 -0
- package/dist/assets/renderPdf-DbvJnEQL.js +111 -0
- package/dist/assets/rolldown-runtime-QTnfLwEv.js +1 -0
- package/dist/assets/select-DYBAIyVx.js +131 -0
- package/dist/assets/strictConfig-Bf8nyKvx.js +1 -0
- package/dist/assets/unsupportedIterableToArray-BTCP7Haa.js +1 -0
- package/dist/assets/vendor-highlighter-ClvlgmIK.js +8 -0
- package/dist/assets/vendor-markdown-CfSBref-.js +30 -0
- package/dist/assets/vendor-mermaid-Da_wWrs4.js +3535 -0
- package/dist/assets/vendor-react-CCIEwYL0.js +9 -0
- package/dist/assets/vendor-streamdown-BIRX7zKm.js +113 -0
- package/dist/assets/vendor-streamdown-CXvuy5h3.css +1 -0
- package/dist/assets/vendor-streamdown-code-B6SuuZwa.js +152 -0
- package/dist/assets/zh-CN-C4xbZjjC.js +3 -0
- package/dist/bundle-ownership.json +597 -0
- package/dist/favicon.svg +1 -0
- package/dist/icons.svg +24 -0
- package/dist/index.html +27 -0
- package/dist/lotus-next-manifest.json +181 -0
- package/package.json +94 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{i as t,t as n}from"./vendor-react-CCIEwYL0.js";import{n as r}from"./index-CjY6eMv8.js";import{f as i,i as a,l as o,r as s}from"./ErrorBoundary-DLCRl4Er.js";import{$t as c,A as l,Bt as u,Ct as d,D as f,Dt as p,E as m,Et as h,F as g,Gt as _,Ht as v,I as y,Jt as b,Kt as x,Lt as S,M as C,Mt as w,N as T,O as E,Ot as D,P as O,Q as k,Qt as A,Rt as j,S as M,T as N,Tt as P,Ut as F,Vt as ee,Wt as I,Xt as L,Yt as te,Zt as R,_t as ne,a as z,b as re,c as ie,dt as ae,et as oe,ft as se,gt as ce,h as le,ht as ue,i as de,j as fe,k as pe,kt as me,l as he,mt as ge,n as _e,nt as ve,o as ye,pt as B,qt as be,r as V,rt as xe,s as H,st as Se,t as Ce,v as we,w as Te,wt as U,x as Ee,y as De,yt as W,zt as Oe}from"./select-DYBAIyVx.js";var ke=i(`triangle-alert`,[[`path`,{d:`m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3`,key:`wmoenq`}],[`path`,{d:`M12 9v4`,key:`juzpu7`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),Ae=i(`history`,[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}],[`path`,{d:`M12 7v5l4 2`,key:`1fdv2h`}]]),je=i(`play`,[[`path`,{d:`M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z`,key:`10ikf1`}]]),Me=i(`refresh-cw`,[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]),Ne=i(`rotate-cw`,[[`path`,{d:`M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8`,key:`1p45f6`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}]]),Pe=i(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]),G=e(t(),1),Fe=`lotus_experience_mode_v1`,Ie=new Set([`skills`,`env`,`masking`,`clusters`,`metrics`,`jiandu`]);function Le(){try{let e=localStorage.getItem(Fe);if(e===`simple`||e===`advanced`)return e}catch{}return`advanced`}var K=Oe(e=>({mode:Le(),isAdvanced:Le()===`advanced`,setMode:t=>{try{localStorage.setItem(Fe,t)}catch{}e({mode:t,isAdvanced:t===`advanced`})},toggleMode:()=>e(e=>{let t=e.mode===`simple`?`advanced`:`simple`;try{localStorage.setItem(Fe,t)}catch{}return{mode:t,isAdvanced:t===`advanced`}})})),Re=e=>{let t=new URLSearchParams;Object.entries(e).forEach(([e,n])=>{n===void 0||n===``||t.set(e,String(n))});let n=t.toString();return n?`?${n}`:``},ze=new class{async getSummary(e={}){let t=Re({start_date:e.startDate,end_date:e.endDate});return w.get(`metrics/summary${t}`)}async getByModel(e={}){let t=Re({start_date:e.startDate,end_date:e.endDate});return w.get(`metrics/by-model${t}`)}async getSessions(e={}){let t=Re({start_date:e.startDate,end_date:e.endDate,model:e.model,limit:e.limit});return w.get(`metrics/sessions${t}`)}async getSessionDetail(e){try{return await w.get(`metrics/sessions/${encodeURIComponent(e)}`)}catch(e){if(e instanceof Error&&e.message.includes(`not found`))return null;throw e}}async getUsageBreakdown(e={}){let t=Re({start_date:e.startDate,end_date:e.endDate,model:e.model});return w.get(`metrics/usage-breakdown${t}`)}async getDaily(e={}){let t=Re({days:e.days,end_date:e.endDate,granularity:e.granularity});return w.get(`metrics/daily${t}`)}async getForwardSummary(e={}){let t=Re({start_date:e.startDate,end_date:e.endDate,endpoint:e.endpoint,model:e.model,limit:e.limit});return w.get(`metrics/forward/summary${t}`)}async getForwardByEndpoint(e={}){let t=Re({start_date:e.startDate,end_date:e.endDate,endpoint:e.endpoint,model:e.model,limit:e.limit});return w.get(`metrics/forward/by-endpoint${t}`)}async getForwardRequests(e={}){let t=Re({start_date:e.startDate,end_date:e.endDate,endpoint:e.endpoint,model:e.model,limit:e.limit});return w.get(`metrics/forward/requests${t}`)}async getMemorySummary(e={}){let t=Re({scope:e.scope,project_key:e.projectKey});return w.get(`metrics/memory/summary${t}`)}async getMemoryTimeline(e={}){let t=Re({scope:e.scope,project_key:e.projectKey,days:e.days,end_date:e.endDate,granularity:e.granularity});return w.get(`metrics/memory/timeline${t}`)}async getUnifiedSummary(e={}){let t=Re({start_date:e.startDate,end_date:e.endDate});return w.get(`metrics/v2/summary${t}`)}async getUnifiedTimeline(e={}){let t=Re({days:e.days,end_date:e.endDate,granularity:e.granularity});return w.get(`metrics/v2/timeline${t}`)}},q=n(),Be=`Switch`,[Ve,He]=ve(Be),[Ue,We]=Ve(Be);function Ge(e){let{__scopeSwitch:t,checked:n,children:r,defaultChecked:i,disabled:a,form:o,name:s,onCheckedChange:c,required:l,value:u=`on`,internal_do_not_use_render:d}=e,[f,p]=oe({prop:n,defaultProp:i??!1,onChange:c,caller:Be}),[m,h]=G.useState(null),[g,_]=G.useState(null),v={checked:f,setChecked:p,disabled:a,control:m,setControl:h,name:s,form:o,value:u,hasConsumerStoppedPropagationRef:G.useRef(!1),required:l,defaultChecked:i,isFormControl:m?!!o||!!m.closest(`form`):!0,bubbleInput:g,setBubbleInput:_};return(0,q.jsx)(Ue,{scope:t,...v,children:$e(d)?d(v):r})}var Ke=`SwitchTrigger`,qe=G.forwardRef(({__scopeSwitch:e,onClick:t,...n},r)=>{let{value:i,disabled:a,checked:s,required:c,setControl:l,setChecked:u,hasConsumerStoppedPropagationRef:d,isFormControl:f,bubbleInput:p}=We(Ke,e),m=o(r,l);return(0,q.jsx)(k.button,{type:`button`,role:`switch`,"aria-checked":s,"aria-required":c,"data-state":et(s),"data-disabled":a?``:void 0,disabled:a,value:i,...n,ref:m,onClick:xe(t,e=>{u(e=>!e),p&&f&&(d.current=e.isPropagationStopped(),d.current||e.stopPropagation())})})});qe.displayName=Ke;var Je=G.forwardRef((e,t)=>{let{__scopeSwitch:n,name:r,checked:i,defaultChecked:a,required:o,disabled:s,value:c,onCheckedChange:l,form:u,...d}=e;return(0,q.jsx)(Ge,{__scopeSwitch:n,checked:i,defaultChecked:a,disabled:s,required:o,onCheckedChange:l,name:r,form:u,value:c,internal_do_not_use_render:({isFormControl:e})=>(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(qe,{...d,ref:t,__scopeSwitch:n}),e&&(0,q.jsx)(Qe,{__scopeSwitch:n})]})})});Je.displayName=Be;var Ye=`SwitchThumb`,Xe=G.forwardRef((e,t)=>{let{__scopeSwitch:n,...r}=e,i=We(Ye,n);return(0,q.jsx)(k.span,{"data-state":et(i.checked),"data-disabled":i.disabled?``:void 0,...r,ref:t})});Xe.displayName=Ye;var Ze=`SwitchBubbleInput`,Qe=G.forwardRef(({__scopeSwitch:e,...t},n)=>{let{control:r,hasConsumerStoppedPropagationRef:i,checked:a,defaultChecked:s,required:c,disabled:l,name:u,value:d,form:f,bubbleInput:p,setBubbleInput:m}=We(Ze,e),h=o(n,m),g=ye(a),_=le(r);G.useEffect(()=>{let e=p;if(!e)return;let t=window.HTMLInputElement.prototype,n=Object.getOwnPropertyDescriptor(t,`checked`).set,r=!i.current;if(g!==a&&n){let t=new Event(`click`,{bubbles:r});n.call(e,a),e.dispatchEvent(t)}},[p,g,a,i]);let v=G.useRef(a);return(0,q.jsx)(k.input,{type:`checkbox`,"aria-hidden":!0,defaultChecked:s??v.current,required:c,disabled:l,name:u,value:d,form:f,...t,tabIndex:-1,ref:h,style:{...t.style,..._,position:`absolute`,pointerEvents:`none`,opacity:0,margin:0,transform:`translateX(-100%)`}})});Qe.displayName=Ze;function $e(e){return typeof e==`function`}function et(e){return e?`checked`:`unchecked`}function J({className:e,...t}){return(0,q.jsx)(Je,{"data-slot":`switch`,className:a(`peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50`,e),...t,children:(0,q.jsx)(Xe,{"data-slot":`switch-thumb`,className:a(`bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0`)})})}var tt=e=>typeof e==`string`&&e.trim().length>0&&[...e.trim()].every(e=>e===`*`||e===`.`),nt=[{id:`deepseek`,label:`DeepSeek`,provider_type:`openai`,base_url:`https://api.deepseek.com/v1`,suggested_models:[`deepseek-chat`,`deepseek-reasoner`]},{id:`deepseek-anthropic`,label:`DeepSeek (Anthropic 协议)`,provider_type:`anthropic`,base_url:`https://api.deepseek.com/anthropic`,suggested_models:[`deepseek-chat`,`deepseek-reasoner`]},{id:`zhipu`,label:`智谱 GLM (bigmodel.cn)`,provider_type:`openai`,base_url:`https://open.bigmodel.cn/api/paas/v4`,suggested_models:[`glm-5.2`],note:`Coding Plan 套餐需改用 https://open.bigmodel.cn/api/coding/paas/v4`},{id:`zhipu-anthropic`,label:`智谱 GLM (Anthropic 协议)`,provider_type:`anthropic`,base_url:`https://open.bigmodel.cn/api/anthropic`,suggested_models:[`glm-5.2`]},{id:`zai`,label:`Z.ai (国际版)`,provider_type:`openai`,base_url:`https://api.z.ai/api/paas/v4`,suggested_models:[`glm-5.2`],note:`Coding Plan 套餐需改用 https://api.z.ai/api/coding/paas/v4`},{id:`minimax`,label:`MiniMax (国际版)`,provider_type:`openai`,base_url:`https://api.minimax.io/v1`,suggested_models:[`MiniMax-M3`]},{id:`minimax-cn`,label:`MiniMax (国内版)`,provider_type:`openai`,base_url:`https://api.minimaxi.com/v1`,suggested_models:[`MiniMax-M3`]},{id:`qwen`,label:`通义千问 (DashScope)`,provider_type:`openai`,base_url:`https://dashscope.aliyuncs.com/compatible-mode/v1`,suggested_models:[`qwen-plus`],note:`阿里云推荐迁移至业务空间专属域名,旧公共域名当前仍可用`},{id:`kimi`,label:`Kimi (Moonshot)`,provider_type:`openai`,base_url:`https://api.moonshot.cn/v1`,suggested_models:[`kimi-k2.6`,`kimi-k2.7-code`]}];function rt(e){let t=Math.floor(e/60),n=e%60;return`${t}:${String(n).padStart(2,`0`)}`}function it(){let[e,t]=(0,G.useState)(`unknown`),[n,r]=(0,G.useState)(!1),[i,a]=(0,G.useState)(null),[o,c]=(0,G.useState)(0),[l,u]=(0,G.useState)(!1),[d,f]=(0,G.useState)(!1),[p,m]=(0,G.useState)(null),h=(0,G.useCallback)(async()=>{r(!0);try{t((await D.getCopilotAuthStatus()).authenticated?`authenticated`:`not_authenticated`),m(null)}catch(e){t(`unknown`),m(S(e))}finally{r(!1)}},[]);(0,G.useEffect)(()=>{h()},[h]),(0,G.useEffect)(()=>{if(!i)return;c(i.expires_in);let e=setInterval(()=>c(e=>e>0?e-1:0),1e3);return()=>clearInterval(e)},[i]);let g=async()=>{u(!0),m(null);try{let e=await D.startCopilotAuth();a(e);try{window.open(e.verification_uri,`_blank`,`noopener`)}catch{}await D.completeCopilotAuth({device_code:e.device_code,interval:e.interval??5,expires_in:e.expires_in}),t(`authenticated`)}catch(e){m(S(e)),h()}finally{a(null),u(!1)}},_=async()=>{m(null);try{await D.logoutCopilot(),t(`not_authenticated`)}catch(e){m(S(e))}},v=async()=>{if(i)try{await navigator.clipboard.writeText(i.user_code),f(!0),setTimeout(()=>f(!1),2e3)}catch{m(`复制失败,请手动选择代码复制`)}};return(0,q.jsxs)(`div`,{className:`space-y-2 rounded-md border bg-muted/30 p-2.5`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,q.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:`Copilot 授权`}),(0,q.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[e===`authenticated`?(0,q.jsx)(H,{className:`bg-emerald-500/15 text-emerald-600 dark:text-emerald-400`,variant:`secondary`,children:`已登录`}):e===`not_authenticated`?(0,q.jsx)(H,{variant:`secondary`,children:`未登录`}):(0,q.jsx)(H,{variant:`outline`,children:`未知`}),(0,q.jsx)(`button`,{type:`button`,onClick:()=>void h(),"aria-label":`刷新状态`,className:`rounded p-1 text-muted-foreground hover:text-foreground`,disabled:n,children:(0,q.jsx)(Me,{className:n?`size-3.5 animate-spin`:`size-3.5`})})]})]}),i?(0,q.jsxs)(`div`,{className:`space-y-1.5 text-sm`,children:[(0,q.jsxs)(`p`,{children:[`打开`,` `,(0,q.jsx)(`a`,{href:i.verification_uri,target:`_blank`,rel:`noopener noreferrer`,className:`text-primary underline`,children:i.verification_uri}),` `,`并输入代码:`]}),(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,q.jsx)(`span`,{className:`font-mono text-base font-semibold tracking-wider`,children:i.user_code}),(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,className:`h-7 px-2`,onClick:()=>void v(),children:[d?(0,q.jsx)(R,{className:`size-3.5 text-emerald-500`}):(0,q.jsx)(b,{className:`size-3.5`}),d?`已复制`:`复制`]})]}),(0,q.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[o>0?`代码有效期剩余 ${rt(o)}`:`代码已过期,请重新登录`,o>0?` · 授权后这里会自动完成…`:``]})]}):e===`authenticated`?(0,q.jsxs)(`div`,{className:`flex items-center justify-between text-sm`,children:[(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:`GitHub Copilot 账号已连接`}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:()=>void _(),children:`退出`})]}):(0,q.jsx)(s,{size:`sm`,onClick:()=>void g(),disabled:l,children:l?`登录中…`:`登录 GitHub Copilot`}),p?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:p}):null]})}function at({label:e,value:t,onChange:n,models:r=[],placeholder:i,disabled:o=!1,hideLabel:s=!1}){let c=(0,G.useRef)(null),l=(0,G.useId)(),u=(0,G.useId)(),[d,f]=(0,G.useState)(!1),[p,m]=(0,G.useState)(-1),h=(0,G.useMemo)(()=>{let e=new Map;for(let t of r){let n=t.reference.model.trim();n&&!e.has(n)&&e.set(n,t)}return[...e.values()]},[r]),g=(0,G.useMemo)(()=>{let e=t.trim().toLocaleLowerCase();if(!e)return h;let n=h.filter(t=>{let n=t.reference.model.toLocaleLowerCase(),r=t.display_name.toLocaleLowerCase();return n.includes(e)||r.includes(e)});return n.length>0?n:h},[h,t]),_=d&&g.length>0;(0,G.useEffect)(()=>{!_||p<0||document.getElementById(`${l}-option-${p}`)?.scrollIntoView?.({block:`nearest`})},[p,l,_]);let v=e=>{n(e),f(!1),m(-1),c.current?.focus()},y=e=>{g.length!==0&&(f(!0),m(t=>t<0?e===1?0:g.length-1:(t+e+g.length)%g.length))};return(0,q.jsxs)(`div`,{className:`relative`,onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||(f(!1),m(-1))},children:[(0,q.jsx)(`span`,{id:u,className:a(s?`sr-only`:`mb-1 block text-xs text-muted-foreground`),children:e}),(0,q.jsxs)(`div`,{className:`relative`,children:[(0,q.jsx)(C,{ref:c,role:`combobox`,"aria-labelledby":u,"aria-autocomplete":`list`,"aria-controls":l,"aria-expanded":_,"aria-activedescendant":_&&p>=0?`${l}-option-${p}`:void 0,autoComplete:`off`,value:t,placeholder:i,disabled:o,className:a(h.length>0&&`pr-9`),onFocus:()=>f(h.length>0),onChange:e=>{n(e.target.value),f(h.length>0),m(-1)},onKeyDown:e=>{if(e.key===`ArrowDown`)e.preventDefault(),y(1);else if(e.key===`ArrowUp`)e.preventDefault(),y(-1);else if(e.key===`Enter`&&_&&p>=0){e.preventDefault();let t=g[p];t&&v(t.reference.model)}else e.key===`Escape`&&d&&(e.preventDefault(),e.stopPropagation(),f(!1),m(-1))}}),h.length>0?(0,q.jsx)(`button`,{type:`button`,"aria-label":`展开${e}选项`,tabIndex:-1,disabled:o,className:`absolute inset-y-0 right-0 flex w-9 items-center justify-center text-muted-foreground disabled:opacity-50`,onMouseDown:e=>e.preventDefault(),onClick:()=>{f(e=>!e),m(-1),c.current?.focus()},children:(0,q.jsx)(L,{className:`size-4`})}):null]}),_?(0,q.jsx)(`div`,{id:l,role:`listbox`,"aria-labelledby":u,className:`absolute inset-x-0 top-full z-[140] mt-1 max-h-52 overflow-y-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md`,children:g.map((e,n)=>{let r=e.reference.model,i=r===t;return(0,q.jsxs)(`button`,{id:`${l}-option-${n}`,type:`button`,role:`option`,"aria-selected":i,className:a(`flex w-full items-start gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none`,n===p&&`bg-accent text-accent-foreground`),onMouseDown:e=>e.preventDefault(),onMouseEnter:()=>m(n),onClick:()=>v(r),children:[(0,q.jsx)(R,{className:a(`mt-0.5 size-3.5 shrink-0`,i?`opacity-100`:`opacity-0`)}),(0,q.jsxs)(`span`,{className:`min-w-0`,children:[(0,q.jsx)(`span`,{className:`block truncate`,children:r}),e.display_name&&e.display_name!==r?(0,q.jsx)(`span`,{className:`block truncate text-xs text-muted-foreground`,children:e.display_name}):null]})]},r)})}):null]})}var ot=[`anthropic`,`openai`,`gemini`,`copilot`,`bodhi`],st=[`low`,`medium`,`high`,`xhigh`,`max`],ct=`__unset__`,lt={anthropic:`sk-ant-…`,openai:`sk-…`,gemini:`AIza…`,copilot:``,bodhi:`bhi_sk_…`},ut=e=>typeof e==`string`?e:e==null?``:String(e);function dt(e){let t=e?.config??{};return{type:e?.type??`anthropic`,label:e?.label??``,enabled:e?.enabled??!0,apiKey:tt(t.api_key)?``:ut(t.api_key),baseUrl:ut(t.base_url),model:ut(t.model),reasoningEffort:ut(t.reasoning_effort),responsesOnlyModels:Array.isArray(t.responses_only_models)?t.responses_only_models.map(ut).filter(Boolean).join(`
|
|
2
|
+
`):``,headlessAuth:t.headless_auth===!0,targetProvider:ut(t.target_provider),requestOverridesJson:t.request_overrides==null?``:JSON.stringify(t.request_overrides,null,2)}}function ft(e,t,n){let r=e.type,i={},a=(e,n,r)=>{r?i[e]=n:t&&(i[e]=null)};if(r!==`copilot`){let r=e.apiKey.trim();if(r&&tt(r)){if(!(t&&n))return{error:`API Key 不能使用掩码`}}else if(r)i.api_key=r;else if(!(t&&n))return{error:`API Key 不能为空`};a(`base_url`,e.baseUrl.trim(),e.baseUrl.trim()!==``)}if(a(`model`,e.model.trim(),e.model.trim()!==``),a(`reasoning_effort`,e.reasoningEffort,e.reasoningEffort!==``),r===`openai`||r===`copilot`){let n=e.responsesOnlyModels.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean);(n.length>0||t)&&(i.responses_only_models=n)}r===`copilot`&&(i.headless_auth=e.headlessAuth),r===`bodhi`&&a(`target_provider`,e.targetProvider,e.targetProvider!==``);let o=e.requestOverridesJson.trim();if(o)try{i.request_overrides=JSON.parse(o)}catch(e){return{error:`request_overrides JSON 解析失败:${e.message}`}}else t&&(i.request_overrides=null);return{payload:{type:r,label:e.label.trim()||h[r]||r,enabled:e.enabled,config:i}}}var pt=(e,t)=>{let n=S(e);for(let e of t)typeof e!=`string`||e.trim()===``||(n=n.replaceAll(e,`[REDACTED]`));return n.replace(/[*.]{4,}/g,`[REDACTED]`)};function mt({label:e,value:t,onChange:n,type:r=`text`,placeholder:i}){return(0,q.jsxs)(`label`,{className:`block`,children:[(0,q.jsx)(`span`,{className:`mb-1 block text-xs text-muted-foreground`,children:e}),(0,q.jsx)(C,{type:r,value:t,placeholder:i,onChange:e=>n(e.target.value)})]})}function ht({instance:e,onSave:t,onCancel:n,modelOptions:r=[]}){let i=e!=null,a=tt((e?.config??{}).api_key),[o,c]=(0,G.useState)(()=>dt(e)),[l,u]=(0,G.useState)(()=>{let t=dt(e);return t.requestOverridesJson!==``||t.responsesOnlyModels!==``}),[d,f]=(0,G.useState)(!1),[p,m]=(0,G.useState)(null),[g,_]=(0,G.useState)(``),v=e=>c(t=>({...t,...e})),y=o.type,b=nt.find(e=>e.id===g)??null,x=e=>{if(e===ct){_(``);return}let t=nt.find(t=>t.id===e);t&&(_(e),c(e=>({...e,type:t.provider_type,baseUrl:t.base_url,label:e.label.trim()===``?t.label:e.label})))},S=async()=>{let n=ft(o,i,a);if(`error`in n){m(n.error);return}f(!0),m(null);try{await t(n.payload)}catch(t){let n=(e?.config??{}).api_key;m(pt(t,[o.apiKey.trim(),n])),f(!1)}};return(0,q.jsxs)(`div`,{className:`space-y-2.5 rounded-lg border bg-muted/30 p-3`,children:[(0,q.jsxs)(`label`,{className:`block`,children:[(0,q.jsx)(`span`,{className:`mb-1 block text-xs text-muted-foreground`,children:`厂商预设(可选,仅快速填充表单,不会保存)`}),(0,q.jsxs)(Ce,{value:g||ct,onValueChange:x,children:[(0,q.jsx)(de,{className:`w-full`,"aria-label":`厂商预设`,children:(0,q.jsx)(z,{})}),(0,q.jsxs)(_e,{children:[(0,q.jsx)(V,{value:ct,children:`不使用预设`}),nt.map(e=>(0,q.jsx)(V,{value:e.id,disabled:i&&e.provider_type!==y,children:e.label},e.id))]})]}),b?.note?(0,q.jsx)(`span`,{className:`mt-1 block text-xs text-muted-foreground`,children:b.note}):null]}),(0,q.jsxs)(`label`,{className:`block`,children:[(0,q.jsxs)(`span`,{className:`mb-1 block text-xs text-muted-foreground`,children:[`类型`,i?`(创建后不可修改)`:``]}),(0,q.jsxs)(Ce,{value:y,onValueChange:e=>{_(``),v({type:e})},disabled:i,children:[(0,q.jsx)(de,{className:`w-full`,"aria-label":`提供方类型`,children:(0,q.jsx)(z,{})}),(0,q.jsx)(_e,{children:ot.map(e=>(0,q.jsx)(V,{value:e,children:h[e]??e},e))})]})]}),(0,q.jsx)(mt,{label:`名称`,value:o.label,onChange:e=>v({label:e}),placeholder:`如 我的 ${h[y]}`}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between rounded-md border bg-background px-2.5 py-2`,children:[(0,q.jsx)(`span`,{className:`text-sm`,children:`启用该实例`}),(0,q.jsx)(J,{checked:o.enabled,onCheckedChange:e=>v({enabled:e})})]}),y===`copilot`?(0,q.jsx)(it,{}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(mt,{label:`API Key`,value:o.apiKey,onChange:e=>v({apiKey:e}),type:`password`,placeholder:a?`已配置,留空保持不变`:lt[y]}),(0,q.jsx)(mt,{label:`Base URL(可选)`,value:o.baseUrl,onChange:e=>v({baseUrl:e}),placeholder:y===`anthropic`?`https://api.anthropic.com`:y===`openai`?`https://api.openai.com/v1`:y===`gemini`?`https://generativelanguage.googleapis.com/v1beta`:`http://localhost:8080`})]}),y===`bodhi`?(0,q.jsxs)(`label`,{className:`block`,children:[(0,q.jsx)(`span`,{className:`mb-1 block text-xs text-muted-foreground`,children:`目标上游(可选)`}),(0,q.jsxs)(Ce,{value:o.targetProvider||ct,onValueChange:e=>v({targetProvider:e===ct?``:e}),children:[(0,q.jsx)(de,{className:`w-full`,children:(0,q.jsx)(z,{})}),(0,q.jsxs)(_e,{children:[(0,q.jsx)(V,{value:ct,children:`未设置`}),(0,q.jsx)(V,{value:`openai`,children:`OpenAI`}),(0,q.jsx)(V,{value:`anthropic`,children:`Anthropic`}),(0,q.jsx)(V,{value:`gemini`,children:`Gemini`})]})]})]}):null,y===`copilot`?(0,q.jsxs)(`div`,{className:`flex items-center justify-between rounded-md border bg-background px-2.5 py-2`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`text-sm`,children:`Headless 授权`}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`在控制台打印登录链接,不自动打开浏览器`})]}),(0,q.jsx)(J,{checked:o.headlessAuth,onCheckedChange:e=>v({headlessAuth:e})})]}):null,(0,q.jsx)(at,{label:`默认模型(可选)`,value:o.model,onChange:e=>v({model:e}),models:r,placeholder:b?b.suggested_models.join(`, `):`glm-5.2`}),(0,q.jsx)(`div`,{children:(0,q.jsxs)(`label`,{className:`block`,children:[(0,q.jsx)(`span`,{className:`mb-1 block text-xs text-muted-foreground`,children:`推理强度(可选)`}),(0,q.jsxs)(Ce,{value:o.reasoningEffort||ct,onValueChange:e=>v({reasoningEffort:e===ct?``:e}),children:[(0,q.jsx)(de,{className:`w-full`,children:(0,q.jsx)(z,{})}),(0,q.jsxs)(_e,{children:[(0,q.jsx)(V,{value:ct,children:`默认(不指定)`}),st.map(e=>(0,q.jsx)(V,{value:e,children:e},e))]})]})]})}),(0,q.jsxs)(`button`,{type:`button`,onClick:()=>u(e=>!e),className:`flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground`,children:[l?(0,q.jsx)(L,{className:`size-3.5`}):(0,q.jsx)(te,{className:`size-3.5`}),`高级设置`]}),l?(0,q.jsxs)(`div`,{className:`space-y-2.5`,children:[y===`openai`||y===`copilot`?(0,q.jsxs)(`label`,{className:`block`,children:[(0,q.jsx)(`span`,{className:`mb-1 block text-xs text-muted-foreground`,children:`Responses-only 模型(可选,空格/逗号/换行分隔,支持尾部通配 gpt-5*)`}),(0,q.jsx)(he,{className:`min-h-14 resize-y font-mono text-xs`,value:o.responsesOnlyModels,placeholder:`gpt-5.3-codex
|
|
3
|
+
gpt-5*`,onChange:e=>v({responsesOnlyModels:e.target.value})})]}):null,(0,q.jsxs)(`label`,{className:`block`,children:[(0,q.jsx)(`span`,{className:`mb-1 block text-xs text-muted-foreground`,children:`请求覆写 request_overrides(可选,JSON)`}),(0,q.jsx)(he,{className:`min-h-20 resize-y font-mono text-xs`,value:o.requestOverridesJson,placeholder:`{"common":{"headers":{"X-Custom":"value"}}}`,onChange:e=>v({requestOverridesJson:e.target.value})})]})]}):null,p?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:p}):null,(0,q.jsxs)(`div`,{className:`flex justify-end gap-2 pt-1`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:n,disabled:d,children:`取消`}),(0,q.jsx)(s,{size:`sm`,onClick:()=>void S(),disabled:d,children:d?`保存中…`:`保存`})]})]})}var gt=`__unset__`,_t=[{key:`chat`,label:`对话(必填)`,required:!0},{key:`fast`,label:`快速`,required:!1},{key:`task_summary`,label:`任务摘要`,required:!1},{key:`vision`,label:`视觉`,required:!1},{key:`memory_background`,label:`记忆后台`,required:!1},{key:`planning`,label:`规划`,required:!1},{key:`search`,label:`搜索`,required:!1},{key:`code_review`,label:`代码审查`,required:!1},{key:`sub_agent`,label:`子代理`,required:!1}],vt=()=>({provider:``,model:``}),yt=e=>({provider:e?.provider??``,model:e?.model??``});function bt(e){return{roles:Object.fromEntries(P.map(t=>[t,yt(e?.[t])])),subagentModels:Object.fromEntries(Object.entries(e?.subagent_models??{}).map(([e,t])=>[e,yt(t)]))}}var xt=e=>JSON.stringify(e),St=e=>e.some(e=>e.kind===`default_provider_instance`),Ct=(e,t)=>e.some(e=>e.kind===`default_model_ref`&&e.role===t),wt=(e,t)=>e.some(e=>e.kind===`subagent_model_ref`&&e.subagent===t);function Tt(){let e=U(e=>e.providerSnapshot),t=U(e=>e.providerRepairSnapshot),n=U(e=>e.providerRepairIssues),r=U(e=>e.providerStatus),i=U(e=>e.providerError),o=U(e=>e.loadProviderInstances),c=U(e=>e.getModelsForProvider),l=U(e=>e.catalog),u=e??t,d=u?.instances??[],f=u?.defaults,m=r===`ready`||r===`degraded`,h=bt(f),[g,_]=(0,G.useState)(()=>h),[v,y]=(0,G.useState)(()=>xt(h)),[b,x]=(0,G.useState)(!1),[C,T]=(0,G.useState)(null),[E,D]=(0,G.useState)(!1),O=(0,G.useMemo)(()=>xt(g)!==v,[g,v]),k=(f?.chat.provider??``)!==``&&f?.chat.provider!==(u?.default_provider_instance_id??``),A=(0,G.useRef)(O),j=(0,G.useRef)(!1);A.current=O,(0,G.useEffect)(()=>{if(A.current||j.current)return;let e=bt(f);_(e),y(xt(e))},[f]);let M=(e,t)=>_(n=>({...n,roles:{...n.roles,[e]:{...n.roles[e],...t}}})),N=(e,t)=>_(n=>({...n,subagentModels:{...n.subagentModels,[e]:{...n.subagentModels[e]??vt(),...t}}})),P=async()=>{let e=new Map(d.map(e=>[e.id,e]));for(let t of _t){let r=g.roles[t.key];if(!r.provider&&!r.model.trim()){if(t.required){T(`对话(chat)默认模型必须选择提供方并填写模型`);return}if(Ct(n,t.key)){T(`「${t.label}」的失效引用必须显式替换为现有实例和模型`);return}continue}if(!r.provider||!r.model.trim()){T(`「${t.label}」必须同时选择提供方并填写模型`);return}let i=e.get(r.provider);if(!i){T(`「${t.label}」引用的提供方已失效,请选择现有实例`);return}if(!i.enabled){T(`「${t.label}」引用的提供方已停用,请先启用该实例或选择其他已启用实例`);return}}for(let[t,n]of Object.entries(g.subagentModels)){let r=e.get(n.provider);if(!n.provider||!n.model.trim()||!r){T(`子代理「${t}」的失效引用必须显式替换为现有实例和模型`);return}if(!r.enabled){T(`子代理「${t}」引用的提供方已停用,请先启用该实例或选择其他已启用实例`);return}}j.current=!0,x(!0),T(null),D(!1);try{let e={};for(let t of _t){let n=g.roles[t.key],r=n.provider!==``&&n.model.trim()!==``;e[t.key]=r?{provider:n.provider,model:n.model.trim()}:null}e.subagent_models=Object.fromEntries(Object.entries(g.subagentModels).map(([e,t])=>[e,{provider:t.provider,model:t.model.trim()}]));let t=await w.get(`/bamboo/config`);await w.post(`/bamboo/config`,{defaults:e,default_provider_instance:g.roles.chat.provider,...t?.model_limits===void 0?{}:{model_limits:t.model_limits}});let n=await o(),r=bt(n.defaults);_(r),y(xt(r)),A.current=!1;let i=p(n);i.length>0?T(`偏好已保存,但仍有 ${i.length} 处失效引用;请完成其余替换后再使用聊天。`):(D(!0),setTimeout(()=>D(!1),2500))}catch(e){T(S(e))}finally{j.current=!1,x(!1)}},F=e=>{let t=d.some(t=>t.id===e);return(0,q.jsxs)(q.Fragment,{children:[e&&!t?(0,q.jsxs)(V,{value:e,disabled:!0,children:[e,`(已失效,请替换)`]}):null,d.map(e=>(0,q.jsxs)(V,{value:e.id,disabled:!e.enabled,children:[e.label||e.type,e.enabled?``:`(已停用)`]},e.id))]})};return m?(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`默认模型偏好`}),(0,q.jsx)(`p`,{className:`mb-2 text-xs text-muted-foreground`,children:`按用途指定模型;未设置的用途回落到「对话」模型。模型 ID 可从发现结果选择,也可手动输入。`}),St(n)||k?(0,q.jsx)(`p`,{role:`alert`,className:`mb-2 rounded-md border border-amber-500/50 p-2 text-xs text-amber-700 dark:text-amber-300`,children:`当前提供方路由尚未与「对话」模型偏好同步。确认「对话」提供方和模型后保存偏好,Lotus Next 会自动完成同步。`}):null,(0,q.jsx)(`div`,{className:`space-y-2`,children:_t.map(e=>{let t=g.roles[e.key],r=t.provider&&l?c(t.provider):[],i=Ct(n,e.key);return(0,q.jsxs)(`div`,{className:a(`grid grid-cols-[5.5rem_1fr_1fr] items-center gap-2 rounded-md`,i&&`border border-amber-500/50 bg-amber-500/5 p-1`),children:[(0,q.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,children:e.label}),(0,q.jsxs)(Ce,{value:t.provider||gt,onValueChange:n=>{if(n===gt){M(e.key,vt());return}M(e.key,{provider:n,model:n===t.provider?t.model:``})},children:[(0,q.jsx)(de,{className:`w-full`,"aria-label":`${e.label}提供方`,children:(0,q.jsx)(z,{placeholder:`提供方`})}),(0,q.jsxs)(_e,{children:[!e.required&&!i?(0,q.jsx)(V,{value:gt,children:`未设置`}):null,F(t.provider)]})]}),(0,q.jsx)(at,{label:`${e.label}模型`,hideLabel:!0,value:t.model,models:r,placeholder:`模型 ID`,disabled:!t.provider,onChange:t=>M(e.key,{model:t})})]},e.key)})}),Object.keys(g.subagentModels).length>0?(0,q.jsxs)(`div`,{className:`mt-3 space-y-2`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`子代理模型映射`}),Object.entries(g.subagentModels).map(([e,t])=>{let r=t.provider&&l?c(t.provider):[];return(0,q.jsxs)(`div`,{className:a(`grid grid-cols-[5.5rem_1fr_1fr] items-center gap-2 rounded-md`,wt(n,e)&&`border border-amber-500/50 bg-amber-500/5 p-1`),children:[(0,q.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,title:e,children:e}),(0,q.jsxs)(Ce,{value:t.provider,onValueChange:n=>N(e,{provider:n,model:n===t.provider?t.model:``}),children:[(0,q.jsx)(de,{className:`w-full`,"aria-label":`子代理 ${e} 提供方`,children:(0,q.jsx)(z,{placeholder:`提供方`})}),(0,q.jsx)(_e,{children:F(t.provider)})]}),(0,q.jsx)(at,{label:`子代理 ${e} 模型`,hideLabel:!0,value:t.model,models:r,placeholder:`模型 ID`,disabled:!t.provider,onChange:t=>N(e,{model:t})})]},e)})]}):null,C?(0,q.jsx)(`p`,{className:`mt-2 text-xs text-destructive`,children:C}):null,(0,q.jsxs)(`div`,{className:`mt-2.5 flex items-center justify-end gap-2`,children:[E?(0,q.jsx)(`span`,{className:`text-xs text-emerald-500`,children:`已保存`}):null,(0,q.jsx)(s,{size:`sm`,onClick:()=>void P(),disabled:b||!O&&!k,children:b?`保存中…`:`保存偏好`})]})]}):(0,q.jsx)(`section`,{className:`rounded-lg border p-3`,children:(0,q.jsxs)(`p`,{role:r===`unavailable`||r===`incompatible`?`alert`:void 0,className:`text-xs text-muted-foreground`,children:[r===`incompatible`?`当前 Bamboo 的提供方配置格式与 Lotus Next 不兼容。`:r===`unavailable`?`提供方设置当前不可用。`:`正在加载提供方设置…`,i?` ${i}`:``]})})}function Et(){let e=U(e=>e.providerSnapshot),t=U(e=>e.providerRepairSnapshot),n=U(e=>e.providerRepairIssues),r=U(e=>e.providerStatus),i=U(e=>e.providerError),o=U(e=>e.loadProviderInstances),c=U(e=>e.createProviderInstance),l=U(e=>e.updateProviderInstance),u=U(e=>e.deleteProviderInstance),d=U(e=>e.loadCatalog),f=U(e=>e.fetchCatalogModels),p=U(e=>e.catalog),m=e??t,b=m?.instances??[],C=m?.defaults?.chat.provider??null,w=m?.default_provider_instance_id??null,E=r===`ready`||r===`degraded`,[D,k]=(0,G.useState)(null),[A,j]=(0,G.useState)(!1),[M,N]=(0,G.useState)(null),[P,F]=(0,G.useState)(null),[ee,I]=(0,G.useState)(!1),[L,te]=(0,G.useState)(null),[R,ne]=(0,G.useState)(null),[z,re]=(0,G.useState)(null),[ie,ae]=(0,G.useState)(null),[oe,se]=(0,G.useState)(null),ce=(0,G.useRef)(!1);(0,G.useEffect)(()=>{o().catch(()=>void 0)},[o]),(0,G.useEffect)(()=>{!E||p!==null||ce.current||(ce.current=!0,d())},[E,p,d]);let le=async e=>{let t=await c({type:e.type,label:e.label,enabled:e.enabled,config:e.config});if(j(!1),!t.responseValid||!t.instance){se(null),ae(t.authorityRefreshed?`实例已保存且列表已重新加载,但创建响应缺少有效实例 ID。请从列表中选择实例继续,勿重复创建。`:`实例已保存,但创建响应和实例列表均无法安全确认。请重新加载列表后继续,勿重复创建。`);return}let n=t.instance;t.instanceConfirmed?(k(n.id),se(null),ae(null)):(se(n.id),ae(t.authorityRefreshed?`「${n.label}」实例已保存,但重新加载的列表尚未确认该实例。模型发现仍会继续;请重新加载后编辑,勿重复创建。`:`「${n.label}」实例已保存,但实例列表重新加载失败。模型发现仍会继续;请重新加载后编辑,勿重复创建。`)),ne(n.id),re(t.instanceConfirmed?{id:n.id,text:`实例已保存,正在获取模型…`,tone:`loading`}:null);try{await f(n.id);let e=U.getState().getModelsForProvider(n.id).length,r=e>0?`实例已保存,并发现 ${e} 个模型。请选择模型后再次保存。`:`实例已保存,但未发现模型。可手动输入自定义模型 ID 后再次保存。`;t.instanceConfirmed?re({id:n.id,text:r,tone:e>0?`success`:`warning`}):ae(`${r} 实例列表重新加载失败,请重新加载后继续,勿重复创建。`)}catch{let e=`实例已保存,但模型发现失败。可手动输入自定义模型 ID 后再次保存。`;t.instanceConfirmed?re({id:n.id,text:e,tone:`warning`}):ae(`${e} 实例列表重新加载失败,请重新加载后继续,勿重复创建。`)}finally{ne(null)}},ue=e=>e===C?`请先将「对话」模型偏好切换到其他已启用提供方并保存,再停用此实例。`:e===w?`请先在「默认模型偏好」中确认并保存「对话」提供方,再停用此实例。`:null,de=async(e,t)=>{if(!t.enabled){let t=ue(e);if(t)throw Error(t)}await l(e,{label:t.label,enabled:t.enabled,config:t.config}),re(t=>t?.id===e?null:t),k(null)},fe=async(e,t)=>{if(N(null),!t){let t=ue(e.id);if(t){N(t);return}}try{await l(e.id,{enabled:t})}catch(n){N(`「${e.label||e.type}」${t?`启用`:`停用`}失败:${S(n)}`)}},pe=async e=>{ne(e.id),re(null);try{await f(e.id);let t=U.getState().getModelsForProvider(e.id).length;re({id:e.id,text:t>0?`已刷新 ${t} 个模型`:`未发现模型,可在编辑器中手动输入自定义模型 ID。`,tone:t>0?`success`:`warning`})}catch{re({id:e.id,text:`模型发现失败,请检查实例配置后重试。`,tone:`error`})}finally{ne(null)}},me=async()=>{N(null);try{let e=await o(),t=oe;t&&e.instances.some(e=>e.id===t)?(ae(null),se(null),k(t)):ae(t?`实例已保存,但重新加载的列表仍未确认该实例。请稍后重试并勿重复创建。`:`列表已重新加载,但创建响应缺少有效实例 ID。请从列表中选择刚保存的实例继续,勿重复创建。`)}catch{N(`实例已保存,但提供方列表仍无法重新加载。请稍后重试,勿重复创建。`)}},he=e=>p?.models.filter(t=>t.reference.provider===e)??[],ge=async()=>{if(P){I(!0),te(null);try{await u(P.id),F(null)}catch(e){te(S(e))}finally{I(!1)}}};return(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`配置 LLM 提供方、API Key 与可用模型。`}),!A&&E&&!ie?(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,onClick:()=>{j(!0)},children:[(0,q.jsx)(_,{className:`size-4`}),` 新增`]}):null]}),r===`idle`||r===`loading`?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`正在加载提供方设置…`}):null,r===`unavailable`?(0,q.jsxs)(`div`,{role:`alert`,className:`rounded-lg border border-destructive/40 p-3 text-xs text-destructive`,children:[`提供方设置当前不可用。`,i?` ${i}`:``]}):null,r===`incompatible`?(0,q.jsxs)(`div`,{role:`alert`,className:`rounded-lg border border-destructive/40 p-3 text-xs text-destructive`,children:[`当前 Bamboo 的提供方配置格式与 Lotus Next 不兼容。`,i?` ${i}`:``]}):null,r===`degraded`?(0,q.jsxs)(`div`,{role:`alert`,className:`rounded-lg border border-amber-500/50 bg-amber-500/5 p-3 text-xs text-amber-700 dark:text-amber-300`,children:[`提供方或模型偏好中有失效引用(`,n.length,` 处)。有效实例仍可管理,但聊天与运行时暂不会使用这些偏好;请在下方选择现有实例和模型并保存偏好完成修复。`]}):null,ie?(0,q.jsxs)(`div`,{role:`status`,className:`flex items-start justify-between gap-3 rounded-lg border border-amber-500/50 bg-amber-500/5 p-3 text-xs text-amber-700 dark:text-amber-300`,children:[(0,q.jsx)(`span`,{children:ie}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:()=>void me(),children:`重新加载`})]}):null,M?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:M}):null,A&&E?(0,q.jsx)(ht,{instance:null,onCancel:()=>j(!1),onSave:le}):null,E?(0,q.jsx)(`ul`,{className:`space-y-2`,children:b.map(e=>(0,q.jsxs)(`li`,{className:`rounded-lg border p-3`,children:[D===e.id?(0,q.jsx)(ht,{instance:e,modelOptions:he(e.id),onCancel:()=>k(null),onSave:t=>de(e.id,t)}):(0,q.jsx)(q.Fragment,{children:(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(`span`,{className:`truncate text-sm font-medium`,children:e.label||e.type}),e.enabled?null:(0,q.jsx)(H,{variant:`secondary`,className:`shrink-0 px-1.5 text-[10px]`,children:`已停用`})]}),(0,q.jsx)(`div`,{className:`truncate text-xs text-muted-foreground`,children:h[e.type]??e.type})]}),(0,q.jsx)(J,{checked:e.enabled,onCheckedChange:t=>void fe(e,t),"aria-label":e.enabled?`停用`:`启用`,className:`shrink-0`}),(0,q.jsx)(`button`,{onClick:()=>void pe(e),"aria-label":`拉取模型列表`,title:`拉取模型列表`,disabled:R===e.id,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-foreground disabled:opacity-50`,children:(0,q.jsx)(Me,{className:a(`size-3.5`,R===e.id&&`animate-spin`)})}),(0,q.jsx)(`button`,{onClick:()=>{k(e.id),ie&&oe===null&&ae(null)},"aria-label":`编辑`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-foreground`,children:(0,q.jsx)(x,{className:`size-3.5`})}),(0,q.jsx)(`button`,{onClick:()=>{te(null),F(e)},"aria-label":`删除`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(v,{className:`size-3.5`})})]})}),z&&z.id===e.id?(0,q.jsx)(`p`,{role:`status`,className:a(`mt-1.5 text-xs`,z.tone===`success`&&`text-emerald-500`,z.tone===`loading`&&`text-muted-foreground`,z.tone===`warning`&&`text-amber-600 dark:text-amber-300`,z.tone===`error`&&`text-destructive`),children:z.text}):null]},e.id))}):null,E&&b.length===0&&!A?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无提供方实例,点击「新增」创建。`}):null,(0,q.jsx)(`div`,{hidden:!E,children:(0,q.jsx)(Tt,{})}),(0,q.jsx)(T,{open:P!=null,onOpenChange:e=>e?null:F(null),children:(0,q.jsxs)(O,{className:`gap-3 p-4`,children:[(0,q.jsx)(y,{children:`删除提供方实例`}),(0,q.jsxs)(g,{children:[`确定删除「`,P?.label||P?.type,`」?引用它的默认模型偏好将失效。`]}),L?(0,q.jsxs)(`p`,{className:`text-xs text-destructive`,children:[`删除失败:`,L]}):null,(0,q.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:()=>F(null),disabled:ee,children:`取消`}),(0,q.jsx)(s,{size:`sm`,variant:`destructive`,onClick:()=>void ge(),disabled:ee,children:ee?`删除中…`:`删除`})]})]})})]})}var Dt=function(e){return e.Connecting=`connecting`,e.Ready=`ready`,e.Degraded=`degraded`,e.Stopped=`stopped`,e.Error=`error`,e}({}),Ot=/^[a-zA-Z0-9_-]+$/,kt=6e4,At=3e4,jt=2e4,Mt=1e4,Nt=e=>({id:e,enabled:!0,transport:{type:`stdio`,command:``,args:[],env:{},startup_timeout_ms:jt},request_timeout_ms:kt,healthcheck_interval_ms:At,allowed_tools:[],denied_tools:[]}),Pt=()=>({status:`stopped`,tool_count:0,restart_count:0}),Ft=500,It=e=>typeof e==`object`&&!!e&&!Array.isArray(e),Lt=(e,t)=>Object.hasOwn(e,t),Rt=(e,t)=>Object.keys(e).every(e=>t.includes(e)),zt=e=>typeof e==`string`,Bt=e=>typeof e==`boolean`,Vt=e=>Array.isArray(e)&&e.every(zt),Ht=e=>It(e)&&Object.values(e).every(zt),Ut=e=>typeof e==`number`&&Number.isSafeInteger(e)&&e>=0,Y=(e,t,n,r=!1)=>!Lt(e,t)||r&&e[t]===null||n(e[t]),Wt=[`id`,`name`,`enabled`,`request_timeout_ms`,`healthcheck_interval_ms`,`reconnect`,`allowed_tools`,`denied_tools`],Gt=[`command`,`args`,`cwd`,`env`,`env_encrypted`,`env_credential_refs`,`startup_timeout_ms`],Kt=[`url`,`headers`,`connect_timeout_ms`],qt=[...Wt,...Gt,...Kt,`disabled`,`transport_kind`,`headers_encrypted`,`header_credential_refs`];function Jt(e,t){return t&&(e===null||Ht(e))?!0:Array.isArray(e)&&e.every(e=>It(e)&&Rt(e,[`name`,`value`,`value_encrypted`,`credential_ref`])&&typeof e.name==`string`&&!!e.name.trim()&&Y(e,`value`,zt)&&Y(e,`value_encrypted`,zt,!0)&&Y(e,`credential_ref`,zt,!0))}function Yt(e,t){if(!Y(e,`name`,zt,!0)||!Y(e,`enabled`,Bt,t)||!Y(e,`allowed_tools`,Vt)||!Y(e,`denied_tools`,Vt)||!Y(e,`request_timeout_ms`,Ut,t)||!Y(e,`healthcheck_interval_ms`,Ut,t))return!1;if(!Lt(e,`reconnect`)||t&&e.reconnect===null)return!0;let n=e.reconnect;return It(n)&&Rt(n,[`enabled`,`initial_backoff_ms`,`max_backoff_ms`,`max_attempts`])&&Y(n,`enabled`,Bt)&&Y(n,`initial_backoff_ms`,Ut)&&Y(n,`max_backoff_ms`,Ut)&&Y(n,`max_attempts`,e=>Ut(e)&&e<=4294967295)}function Xt(e){let t=e=>({ok:!1,error:e});if(!e.trim())return t(`请提供包含 mcpServers 对象的完整 JSON 配置。`);if(e.length>1048576||new TextEncoder().encode(e).length>1048576)return t(`JSON 配置不能超过 1 MiB。`);let n;try{n=JSON.parse(e)}catch{return t(`JSON 格式无效。请检查引号、逗号和括号;错误详情不会显示配置内容。`)}if(!It(n)||!Rt(n,[`mcpServers`])||!It(n.mcpServers))return t(`仅支持完整的 {"mcpServers": {"服务器 ID": {...}}} 对象。`);let r=Object.entries(n.mcpServers);if(!r.length)return t(`mcpServers 不能为空;导入不能用于清空全部服务器。`);if(r.length>Ft)return t(`一次最多导入 500 个服务器。`);if(Lt(n.mcpServers,`servers`))return t(`不支持 legacy servers 列表,且 servers 是保留的服务器 ID。`);let i=[];for(let[e,[n,a]]of r.entries()){let r=n=>t(`第 ${e+1} 项:${n}`);if(n!==n.trim()||!Ot.test(n))return r(`服务器 ID 只能包含字母、数字、- 和 _,不能包含空白。`);if(!It(a))return r(`服务器配置必须是对象。`);let o=Lt(a,`transport`);if(o&&Lt(a,`disabled`))return r(`内部 transport 配置请使用 enabled;disabled 会被后端忽略。`);if(!Rt(a,o?[...Wt,`transport`]:qt))return r(`包含不支持或混合的字段;HTTP 请使用 transport_kind: "streamable_http",不能使用 type: "http"。`);if(!Yt(a,!o)||!Y(a,`disabled`,Bt))return r(`启用状态、工具列表或超时配置类型无效。`);let s=o?a.transport:a;if(!It(s))return r(`transport 必须是对象。`);let c;if(o){if(s.type!==`stdio`&&s.type!==`sse`&&s.type!==`streamable_http`)return r(`不支持此 transport 类型。`);if(c=s.type,!Rt(s,[`type`,...c===`stdio`?Gt:Kt]))return r(`transport 包含不支持的字段。`)}else{let e=a.command!==void 0&&a.command!==null;if(e===(a.url!==void 0&&a.url!==null))return r(`必须提供 command 或 url,且不能同时提供两者。`);if(a.transport_kind!==void 0&&a.transport_kind!==null&&(e||a.transport_kind!==`sse`&&a.transport_kind!==`streamable_http`))return r(`transport_kind 仅支持远程 sse 或 streamable_http。`);if(c=e?`stdio`:a.transport_kind===`streamable_http`?`streamable_http`:`sse`,!Rt(a,[...Wt,`disabled`,...c===`stdio`?Gt:[...Kt,`transport_kind`,`headers_encrypted`,`header_credential_refs`]]))return r(`不能混合不同传输方式的配置字段。`)}if(c===`stdio`){if(typeof s.command!=`string`||!s.command.trim()||!Y(s,`args`,Vt)||!Y(s,`cwd`,zt,!0)||!Y(s,`startup_timeout_ms`,Ut,!o))return r(`stdio 命令、参数、工作目录或启动超时无效。`);for(let e of[`env`,`env_encrypted`,`env_credential_refs`])if(!Y(s,e,Ht))return r(`环境变量及凭据引用必须是字符串映射。`)}else{try{if(typeof s.url!=`string`||![`http:`,`https:`].includes(new URL(s.url).protocol))return r(`远程 URL 必须使用 HTTP 或 HTTPS。`)}catch{return r(`远程 URL 格式无效。`)}if(!Y(s,`headers`,e=>Jt(e,!o))||!Y(s,`connect_timeout_ms`,Ut,!o)||!Y(a,`headers_encrypted`,Ht)||!Y(a,`header_credential_refs`,Ht))return r(`请求头或连接超时无效;请求头值必须是字符串。`)}i.push({id:n,transport:c,enabled:typeof a.enabled==`boolean`?a.enabled:o||!a.disabled})}return{ok:!0,value:{mcpServers:n.mcpServers,servers:i}}}var Zt=e=>JSON.stringify([...e].sort());function Qt(e,t,n){let r=new Set(e),i=new Set(t);return{added:e.filter(e=>!i.has(e)),updated:e.filter(e=>i.has(e)),removed:n===`replace`?t.filter(e=>!r.has(e)).sort():[]}}var $t=class extends Error{kind;constructor(e){super({busy:`已有导入正在进行。请等待完成后刷新列表;没有再次发送导入请求。`,rejected:`服务器拒绝了导入,未提交配置。请检查配置后重新操作;错误详情已隐藏。`,uncertain:`导入结果尚未确认,配置可能已更新。请刷新实际列表核对;没有自动重发请求。`,list_changed:`当前服务器列表已变化。请重新查看预览并确认;尚未发送导入请求。`,list_unavailable:`无法确认当前服务器列表。请刷新后重新预览;尚未发送导入请求。`}[e]),this.kind=e,this.name=`McpImportFailure`}};function en(e,t){let n=Object.keys(t.mcpServers);if(!It(e)||e.mode!==t.mode||!Ut(e.added)||!Ut(e.updated)||!Ut(e.removed)||e.added+e.updated!==n.length||t.mode===`merge`&&e.removed!==0||!Vt(e.server_ids)||Zt(e.server_ids)!==Zt(n)||e.start_errors!==void 0&&(!Array.isArray(e.start_errors)||e.start_errors.length>0))throw new $t(`uncertain`);return{mode:t.mode,added:e.added,updated:e.updated,removed:e.removed,server_ids:n.sort()}}var tn=e=>{switch(typeof e==`string`?e.trim().toLowerCase():``){case Dt.Connecting:return Dt.Connecting;case Dt.Ready:return Dt.Ready;case Dt.Degraded:return Dt.Degraded;case Dt.Error:return Dt.Error;case Dt.Stopped:default:return Dt.Stopped}},nn=(e,t)=>{if(typeof e==`number`&&Number.isFinite(e))return e;if(typeof e==`string`){let t=Number(e);if(Number.isFinite(t))return t}return t},rn=(e,t)=>{if(!e||typeof e!=`object`)return t;let n=e;if(n.type===`sse`||n.type===`streamablehttp`||n.type===`streamable_http`){let e=Array.isArray(n.headers)?n.headers.map(e=>{if(!e||typeof e!=`object`)return null;let t=e;return typeof t.name!=`string`||typeof t.value!=`string`?null:{name:t.name,value:t.value}}).filter(e=>!!e):[];return{type:n.type===`sse`?`sse`:`streamable_http`,url:typeof n.url==`string`?n.url:``,headers:e,connect_timeout_ms:nn(n.connect_timeout_ms,Mt)}}let r=Array.isArray(n.args)?n.args.filter(e=>typeof e==`string`):[],i=n.env&&typeof n.env==`object`?Object.entries(n.env):[];return{type:`stdio`,command:typeof n.command==`string`?n.command:``,args:r,cwd:typeof n.cwd==`string`?n.cwd:void 0,env:i.reduce((e,[t,n])=>(typeof n==`string`&&(e[t]=n),e),{}),startup_timeout_ms:nn(n.startup_timeout_ms,jt)}},an=(e,t)=>{let n=Nt(e.id),r=t??{};return{...n,...r,id:e.id,name:typeof r.name==`string`?r.name:typeof e.name==`string`?e.name:void 0,enabled:typeof e.enabled==`boolean`?e.enabled:typeof r.enabled==`boolean`?r.enabled:!0,request_timeout_ms:nn(r.request_timeout_ms,kt),healthcheck_interval_ms:nn(r.healthcheck_interval_ms,At),allowed_tools:Array.isArray(r.allowed_tools)?r.allowed_tools.filter(e=>typeof e==`string`):[],denied_tools:Array.isArray(r.denied_tools)?r.denied_tools.filter(e=>typeof e==`string`):[],reconnect:r.reconnect&&typeof r.reconnect==`object`?{enabled:typeof r.reconnect.enabled==`boolean`?r.reconnect.enabled:!0,initial_backoff_ms:nn(r.reconnect.initial_backoff_ms,1e3),max_backoff_ms:nn(r.reconnect.max_backoff_ms,3e4),max_attempts:nn(r.reconnect.max_attempts,0)}:void 0,transport:rn(r.transport,n.transport)}},on=e=>{let t=Pt(),n=e.runtime??{};return{status:tn(n.status??e.status),last_error:typeof n.last_error==`string`?n.last_error:typeof e.last_error==`string`?e.last_error:void 0,connected_at:typeof n.connected_at==`string`?n.connected_at:void 0,disconnected_at:typeof n.disconnected_at==`string`?n.disconnected_at:void 0,tool_count:nn(n.tool_count??e.tool_count,t.tool_count),restart_count:nn(n.restart_count??e.restart_count,t.restart_count),last_ping_at:typeof n.last_ping_at==`string`?n.last_ping_at:void 0}},sn=e=>{let t=an(e,e.config);return{id:e.id,name:typeof e.name==`string`?e.name:typeof t.name==`string`?t.name:e.id,enabled:typeof e.enabled==`boolean`?e.enabled:t.enabled,config:t,runtime:on(e)}},cn=(e,t)=>`mcp__${e}__${t}`,ln=e=>{if(!e.startsWith(`mcp__`))return null;let t=e.slice(5),n=t.indexOf(`__`);if(n<=0)return null;let r=t.slice(0,n),i=t.slice(n+2);return!r||!i?null:{server_id:r,original_name:i}},un=(e,t,n=0)=>{if(!e||typeof e!=`object`)return null;let r=e,i=typeof r.alias==`string`?r.alias:typeof r.name==`string`&&r.name.startsWith(`mcp__`)?r.name:void 0,a=i&&typeof i==`string`?ln(i):null,o=(typeof r.server_id==`string`?r.server_id:void 0)??(typeof r.serverId==`string`?r.serverId:void 0)??a?.server_id??t??``,s=(typeof r.original_name==`string`?r.original_name:void 0)??(typeof r.originalName==`string`?r.originalName:void 0)??a?.original_name??(typeof r.name==`string`?r.name:void 0)??``,c=i??(o&&s?cn(o,s):``),l=typeof r.description==`string`?r.description:``,u=r,d=`parameters`in u?u.parameters:`inputSchema`in u?u.inputSchema:`input_schema`in u?u.input_schema:void 0,f=c||s||`mcp_tool_${n}`;return{alias:f,server_id:o||`unknown`,original_name:s||f,description:l,parameters:d}},dn=new class{importInFlight=!1;async getServers(){let e=await w.get(`mcp/servers`),t=new Set;if(!It(e)||!Array.isArray(e.servers)||!e.servers.every(e=>{if(!It(e)||typeof e.id!=`string`||!e.id.trim()||t.has(e.id)||typeof e.enabled!=`boolean`||!It(e.config)||!It(e.config.transport))return!1;let n=e.config.transport;if(e.config.id!==void 0&&e.config.id!==e.id)return!1;if(n.type===`stdio`){if(typeof n.command!=`string`||n.args!==void 0&&(!Array.isArray(n.args)||!n.args.every(e=>typeof e==`string`))||n.env!==void 0&&(!It(n.env)||!Object.values(n.env).every(e=>typeof e==`string`)))return!1}else if([`sse`,`streamablehttp`,`streamable_http`].includes(n.type)){if(typeof n.url!=`string`||n.headers!==void 0&&(!Array.isArray(n.headers)||!n.headers.every(e=>It(e)&&typeof e.name==`string`&&typeof e.value==`string`)))return!1}else return!1;return t.add(e.id),!0}))throw Error(`MCP server list could not be verified.`);return e.servers.map(sn)}async addServer(e){return w.post(`mcp/servers`,e)}async updateServer(e,t){let n={...t,id:e};return w.put(`mcp/servers/${e}`,n)}async deleteServer(e){return w.delete(`mcp/servers/${e}`)}async connectServer(e){return w.post(`mcp/servers/${e}/connect`)}async disconnectServer(e){return w.post(`mcp/servers/${e}/disconnect`)}async refreshTools(e){return w.post(`mcp/servers/${e}/refresh`)}async getTools(e){let t=e?`mcp/servers/${e}/tools`:`mcp/tools`,n=await w.get(t);return(Array.isArray(n.tools)?n.tools:[]).map((t,n)=>un(t,e,n)).filter(e=>!!e)}async importServers(e){if(this.importInFlight)throw new $t(`busy`);this.importInFlight=!0;try{return en(await w.post(`mcp/servers/import`,e),e)}catch(e){throw e instanceof $t?e:new $t(j(e)&&e.status>=400&&e.status<500?`rejected`:`uncertain`)}finally{this.importInFlight=!1}}};function fn({label:e,children:t}){return(0,q.jsxs)(`label`,{className:`block`,children:[(0,q.jsx)(`span`,{className:`mb-1 block text-xs text-muted-foreground`,children:e}),t]})}function pn({title:e,addLabel:t,keyPlaceholder:n,valuePlaceholder:r,entries:i,onChange:a}){return(0,q.jsxs)(`div`,{children:[(0,q.jsxs)(`div`,{className:`mb-1.5 flex items-center justify-between`,children:[(0,q.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:e}),(0,q.jsxs)(s,{type:`button`,size:`sm`,variant:`secondary`,className:`h-7 px-2 text-xs`,onClick:()=>a([...i,{k:``,v:``}]),children:[(0,q.jsx)(_,{className:`size-3.5`}),` `,t]})]}),i.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground/70`,children:`无`}):(0,q.jsx)(`div`,{className:`space-y-1.5`,children:i.map((e,t)=>(0,q.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(C,{className:`h-8 flex-1 font-mono text-xs`,placeholder:n,value:e.k,onChange:e=>a(i.map((n,r)=>r===t?{...n,k:e.target.value}:n))}),(0,q.jsx)(C,{className:`h-8 flex-1 font-mono text-xs`,placeholder:r,value:e.v,onChange:e=>a(i.map((n,r)=>r===t?{...n,v:e.target.value}:n))}),(0,q.jsx)(`button`,{type:`button`,onClick:()=>a(i.filter((e,n)=>n!==t)),"aria-label":`移除`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(ee,{className:`size-3.5`})})]},t))})]})}function mn({open:e,mode:t,initial:n,existingIds:r,onCancel:i,onSubmit:a}){let[o,c]=(0,G.useState)(``),[l,u]=(0,G.useState)(``),[d,f]=(0,G.useState)(!0),[p,m]=(0,G.useState)(`stdio`),[h,g]=(0,G.useState)(``),[_,v]=(0,G.useState)(``),[b,x]=(0,G.useState)(``),[w,E]=(0,G.useState)([]),[D,k]=(0,G.useState)(``),[A,j]=(0,G.useState)([]),[M,N]=(0,G.useState)(null),[P,F]=(0,G.useState)(!1);(0,G.useEffect)(()=>{if(!e)return;let r=t===`edit`&&n?n:null;c(r?.id??``),u(r?.name??``),f(r?.enabled??!0);let i=r?.transport;m(i?.type??`stdio`),g(i?.type===`stdio`?i.command:``),v(i?.type===`stdio`?i.args.join(`
|
|
4
|
+
`):``),x(i?.type===`stdio`?i.cwd??``:``),E(i?.type===`stdio`?Object.entries(i.env??{}).map(([e,t])=>({k:e,v:t})):[]),k(i&&i.type!==`stdio`?i.url:``),j(i&&i.type!==`stdio`?i.headers.map(e=>({k:e.name,v:e.value})):[]),N(null),F(!1)},[e,t,n]);let ee=()=>{if(t===`create`){if(!o.trim())return`服务器 ID 不能为空`;if(!Ot.test(o.trim()))return`服务器 ID 只能包含字母、数字、- 和 _`;if(r.includes(o.trim()))return`该服务器 ID 已存在`}if(p===`stdio`){if(!h.trim())return`命令不能为空`}else{if(!D.trim())return`URL 不能为空`;try{new URL(D.trim())}catch{return`URL 格式无效`}}return null},I=()=>{let e=t===`edit`&&n?n.id:o.trim(),r=t===`edit`&&n?n:Nt(e),i=p===`stdio`?{type:`stdio`,command:h.trim(),args:_.split(`
|
|
5
|
+
`).map(e=>e.trim()).filter(Boolean),cwd:b.trim()?b.trim():void 0,env:w.reduce((e,t)=>(t.k.trim()&&(e[t.k.trim()]=t.v),e),{}),startup_timeout_ms:n?.transport.type===`stdio`?n.transport.startup_timeout_ms??2e4:jt}:{type:p,url:D.trim(),headers:A.filter(e=>e.k.trim()).map(e=>({name:e.k.trim(),value:e.v})),connect_timeout_ms:n&&n.transport.type!==`stdio`?n.transport.connect_timeout_ms??1e4:Mt};return{...r,id:e,name:l.trim()||void 0,enabled:d,transport:i}};return(0,q.jsx)(T,{open:e,onOpenChange:e=>{e||i()},children:(0,q.jsxs)(O,{className:`sm:max-w-lg`,children:[(0,q.jsx)(`div`,{className:`border-b px-4 py-3.5`,children:(0,q.jsx)(y,{children:t===`edit`?`编辑 MCP 服务器`:`新增 MCP 服务器`})}),(0,q.jsxs)(`div`,{className:`min-h-0 flex-1 space-y-3 overflow-y-auto p-4`,children:[(0,q.jsx)(fn,{label:`服务器 ID`,children:(0,q.jsx)(C,{placeholder:`filesystem`,value:o,disabled:t===`edit`,autoComplete:`off`,onChange:e=>c(e.target.value)})}),(0,q.jsx)(fn,{label:`显示名称(可选)`,children:(0,q.jsx)(C,{placeholder:`Filesystem MCP`,value:l,autoComplete:`off`,onChange:e=>u(e.target.value)})}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between rounded-md border bg-muted/30 px-3 py-2`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`text-sm`,children:`启用`}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`保存后自动连接该服务器`})]}),(0,q.jsx)(J,{checked:d,onCheckedChange:f})]}),(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`mb-1 text-xs text-muted-foreground`,children:`传输方式`}),(0,q.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:[`stdio`,`sse`,`streamable_http`].map(e=>(0,q.jsx)(s,{type:`button`,size:`sm`,variant:p===e?`default`:`secondary`,"aria-pressed":p===e,className:`flex-1`,onClick:()=>m(e),children:e===`stdio`?`stdio(本地进程)`:e===`sse`?`SSE(远程)`:`Streamable HTTP(远程)`},e))})]}),p===`stdio`?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(fn,{label:`命令`,children:(0,q.jsx)(C,{placeholder:`npx`,value:h,autoComplete:`off`,onChange:e=>g(e.target.value)})}),(0,q.jsx)(fn,{label:`参数(每行一个)`,children:(0,q.jsx)(he,{className:`min-h-16 resize-y font-mono text-xs`,placeholder:`-y
|
|
6
|
+
@modelcontextprotocol/server-filesystem
|
|
7
|
+
/Users/me`,value:_,onChange:e=>v(e.target.value)})}),(0,q.jsx)(fn,{label:`工作目录 cwd(可选)`,children:(0,q.jsx)(C,{placeholder:`/Users/me/project`,value:b,autoComplete:`off`,onChange:e=>x(e.target.value)})}),(0,q.jsx)(pn,{title:`环境变量`,addLabel:`添加`,keyPlaceholder:`MCP_ROOT`,valuePlaceholder:`/Users/me/workspace`,entries:w,onChange:E})]}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(fn,{label:`URL`,children:(0,q.jsx)(C,{placeholder:`http://localhost:4000/sse`,value:D,autoComplete:`off`,onChange:e=>k(e.target.value)})}),(0,q.jsx)(pn,{title:`请求头 Headers`,addLabel:`添加`,keyPlaceholder:`Authorization`,valuePlaceholder:`Bearer token`,entries:A,onChange:j})]})]}),(0,q.jsxs)(`div`,{className:`border-t p-3`,children:[M?(0,q.jsx)(`p`,{className:`mb-2 text-xs break-all text-destructive`,role:`alert`,children:M}):null,(0,q.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:i,disabled:P,children:`取消`}),(0,q.jsx)(s,{size:`sm`,onClick:async()=>{let e=ee();if(e){N(e);return}F(!0),N(null);try{await a(I())}catch(e){N(S(e))}finally{F(!1)}},disabled:P,children:P?`保存中…`:t===`edit`?`保存`:`添加`})]})]})]})})}function hn({serverId:e,version:t}){let[n,r]=(0,G.useState)(null),[i,a]=(0,G.useState)(null);return(0,G.useEffect)(()=>{let t=!1;return a(null),dn.getTools(e).then(e=>{t||r(e)}).catch(e=>{t||(r([]),a(S(e)))}),()=>{t=!0}},[e,t]),i?(0,q.jsxs)(`p`,{className:`text-xs break-all text-destructive`,role:`alert`,children:[`加载工具失败:`,i]}):n===null?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载工具中…`}):n.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`该服务器未暴露任何工具`}):(0,q.jsx)(`ul`,{className:`space-y-1.5`,children:n.map(e=>(0,q.jsxs)(`li`,{className:`rounded-md border bg-muted/30 p-2`,children:[(0,q.jsx)(`div`,{className:`font-mono text-xs font-medium break-all`,children:e.original_name}),e.description?(0,q.jsx)(`div`,{className:`mt-0.5 text-xs whitespace-pre-wrap text-muted-foreground`,children:e.description}):null,e.parameters==null?null:(0,q.jsxs)(`details`,{className:`mt-1`,children:[(0,q.jsx)(`summary`,{className:`cursor-pointer text-[11px] text-muted-foreground select-none`,children:`参数 schema`}),(0,q.jsx)(`pre`,{className:`mt-1 max-h-48 overflow-auto rounded bg-muted p-2 text-[11px] leading-relaxed`,children:JSON.stringify(e.parameters,null,2)})]})]},e.alias))})}function gn({existingIds:e,listConfirmed:t,listRevision:n,onClose:r,onReturnFocus:i,onImport:a,onReload:o}){let[c,l]=(0,G.useState)({text:``,revision:0}),[u,d]=(0,G.useState)(`merge`),[f,p]=(0,G.useState)(null),[m,h]=(0,G.useState)(!1),[_,v]=(0,G.useState)(!1),[b,x]=(0,G.useState)(null),[S,C]=(0,G.useState)(!1),[w,E]=(0,G.useState)(null),D=(0,G.useRef)(!0),k=(0,G.useRef)(!1),A=(0,G.useRef)(0),j=(0,G.useRef)(null);(0,G.useEffect)(()=>(D.current=!0,()=>{D.current=!1,A.current+=1}),[]);let M=(0,G.useMemo)(()=>Xt(c.text),[c.text]),N=Qt(M.ok?M.value.servers.map(e=>e.id):[],e,u),P=Zt(e),F=JSON.stringify([c.revision,u,n,P,Zt(N.removed)]),ee=f===F&&t,I=M.ok&&t&&!_&&!m&&!S&&!w&&(u===`merge`||ee),L=e=>{k.current||(A.current+=1,h(!1),l(t=>({text:e,revision:t.revision+1})),p(null),x(null),C(!1))},te=async e=>{if(!e||k.current)return;L(``);let t=A.current;if(e.size>1048576){x(`JSON 文件不能超过 1 MiB。`);return}h(!0);try{let n=await e.text();if(!D.current||t!==A.current)return;L(n)}catch{D.current&&t===A.current&&x(`无法读取 JSON 文件。请重新选择文件或粘贴配置;文件内容未发送。`)}finally{D.current&&t===A.current&&h(!1)}},R=async()=>{if(!(k.current||!I||!M.ok)){k.current=!0,v(!0),x(null);try{let e=await a({mcpServers:M.value.mcpServers,mode:u},P);if(!D.current)return;E(e),l(e=>({text:``,revision:e.revision+1})),p(null)}catch(e){if(!D.current)return;let t=e instanceof $t?e:new $t(`uncertain`);x(t.message),C(t.kind===`uncertain`),p(null)}finally{k.current=!1,D.current&&v(!1)}}},ne=async()=>{if(!k.current){k.current=!0,v(!0),p(null);try{let e=await o();if(!D.current)return;w&&E({...w,refreshed:e}),e||x(`无法刷新实际列表,请稍后再试;没有发送导入请求。`)}catch{D.current&&x(`无法刷新实际列表,请稍后再试;没有发送导入请求。`)}finally{k.current=!1,D.current&&v(!1)}}},z=()=>{k.current||(A.current+=1,r())};return(0,q.jsx)(T,{open:!0,onOpenChange:e=>{e||z()},children:(0,q.jsxs)(O,{className:`sm:max-w-2xl`,dismissable:!_,showCloseButton:!1,onCloseAutoFocus:e=>{e.preventDefault(),i()},onOpenAutoFocus:e=>{e.preventDefault(),j.current?.focus()},children:[(0,q.jsxs)(`div`,{className:`border-b px-4 py-3.5`,children:[(0,q.jsx)(y,{children:`导入 MCP JSON`}),(0,q.jsx)(g,{className:`mt-2 text-xs`,children:`仅导入 mcpServers。配置只保留在此窗口内存,不写入浏览器存储;启用的服务器会在提交前尝试启动。`})]}),(0,q.jsxs)(`div`,{className:`min-h-0 flex-1 space-y-4 overflow-y-auto p-4`,children:[w?(0,q.jsxs)(`section`,{role:`status`,"aria-label":`导入结果`,className:`space-y-2 rounded-md border p-3 text-sm`,children:[(0,q.jsx)(`h3`,{className:`font-medium`,children:`导入已完成`}),(0,q.jsxs)(`p`,{children:[`新增 `,w.result.added,` · 更新 `,w.result.updated,` · 删除 `,w.result.removed]}),(0,q.jsxs)(`p`,{className:`break-all text-xs`,children:[`服务器 ID:`,w.result.server_ids.join(`、`)]}),(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:w.refreshed?`实际服务器列表与运行状态已刷新。`:`配置已提交,但列表刷新失败。请刷新实际列表核对运行状态。`})]}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`label`,{className:`block space-y-1.5 text-xs`,children:[(0,q.jsx)(`span`,{children:`MCP JSON 配置`}),(0,q.jsx)(he,{value:c.text,onChange:e=>L(e.target.value),disabled:_,className:`min-h-44 resize-y font-mono text-xs`,autoComplete:`off`,autoCapitalize:`off`,spellCheck:!1,placeholder:`{"mcpServers":{"example":{"command":"mcp-server","disabled":true}}}`})]}),(0,q.jsxs)(`label`,{className:`block space-y-1.5 text-xs`,children:[(0,q.jsx)(`span`,{children:`选择 JSON 文件`}),(0,q.jsx)(`input`,{type:`file`,accept:`.json,application/json`,disabled:_,className:`block w-full min-w-0 text-xs`,onChange:e=>{let t=e.target.files?.[0];e.target.value=``,te(t)}})]}),(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`最多 1 MiB、500 个服务器。预览只显示 ID、传输方式和启用状态,不显示环境变量或请求头值。`}),m?(0,q.jsx)(`p`,{role:`status`,className:`text-xs`,children:`正在读取 JSON 文件…`}):null,c.revision>0&&!m&&!b&&!M.ok?(0,q.jsx)(`p`,{role:`alert`,className:`text-xs text-destructive`,children:M.error}):null,(0,q.jsxs)(`fieldset`,{disabled:_,className:`space-y-2`,children:[(0,q.jsx)(`legend`,{className:`mb-1 text-xs font-medium`,children:`导入模式`}),[`merge`,`replace`].map(e=>(0,q.jsxs)(`label`,{className:`flex items-center gap-2 text-sm`,children:[(0,q.jsx)(`input`,{type:`radio`,name:`mcp-import-mode`,value:e,checked:u===e,onChange:()=>{k.current||(d(e),p(null),x(null),C(!1))}}),e===`merge`?`Merge(按 ID 合并)`:`Replace(替换全部)`]},e))]}),(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:u===`merge`?`Merge 按 ID 整条覆盖同名服务器,不递归合并字段;未出现在导入中的 ID 会保留。`:`Replace 使用导入集合替换配置,并删除缺席的 ID。预览基于当前列表,不能锁定其他客户端的并发修改。`}),M.ok?(0,q.jsxs)(`section`,{"aria-label":`导入预览`,className:`space-y-2 rounded-md border p-3 text-xs`,children:[(0,q.jsx)(`h3`,{className:`font-medium`,children:`导入预览`}),(0,q.jsxs)(`p`,{children:[`预计新增 `,N.added.length,` · 整条更新 `,N.updated.length,` · 删除 `,N.removed.length]}),(0,q.jsx)(`ul`,{className:`max-h-36 space-y-1 overflow-y-auto`,children:M.value.servers.map(e=>(0,q.jsxs)(`li`,{className:`break-all`,children:[(0,q.jsx)(`code`,{children:e.id}),` · `,e.transport===`streamable_http`?`Streamable HTTP`:e.transport,` · `,e.enabled?`启用`:`停用`]},e.id))}),(0,q.jsx)(`p`,{children:`服务器 ID 取自 mcpServers 的键;内部 id 字段不改变目标。`}),u===`replace`?(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`p`,{className:`font-medium text-destructive`,children:`将删除的现有 ID:`}),N.removed.length?(0,q.jsx)(`ul`,{"aria-label":`将删除的服务器`,className:`max-h-28 overflow-y-auto`,children:N.removed.map(e=>(0,q.jsx)(`li`,{className:`break-all`,children:(0,q.jsx)(`code`,{children:e})},e))}):(0,q.jsx)(`p`,{children:`无`}),(0,q.jsxs)(`label`,{className:`mt-3 flex items-start gap-2 text-sm`,children:[(0,q.jsx)(`input`,{type:`checkbox`,className:`mt-1`,checked:ee,disabled:_||m||!t,onChange:e=>p(e.target.checked?F:null)}),`我确认使用当前配置替换,并删除以上服务器`]})]}):null]}):null,t?null:(0,q.jsx)(`p`,{role:`alert`,className:`text-xs text-destructive`,children:`当前服务器列表尚未确认,请刷新后再导入。`})]}),b?(0,q.jsx)(`p`,{role:`alert`,className:`text-xs text-destructive`,children:b}):null,S?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`核对实际列表后,修改配置或重新选择模式才能开始新的导入;不会重放本次写入。`}):null]}),(0,q.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-2 border-t p-3`,children:[b||!t||w&&!w.refreshed?(0,q.jsx)(s,{size:`sm`,variant:`ghost`,disabled:_,onClick:()=>void ne(),children:`刷新当前列表`}):null,(0,q.jsx)(s,{ref:j,size:`sm`,variant:`secondary`,disabled:_,onClick:z,children:w?`完成`:`取消`}),w?null:(0,q.jsx)(s,{size:`sm`,disabled:!I,onClick:()=>void R(),children:_?`导入中…`:`导入`})]})]})})}var _n=1e4;function vn(e){return e.type===`stdio`?`stdio · ${[e.command,...e.args].filter(Boolean).join(` `)}`:`${e.type===`sse`?`sse`:`Streamable HTTP`} · ${e.url}`}function yn({server:e}){let t=e.runtime;switch(t?.status??Dt.Stopped){case Dt.Ready:return(0,q.jsxs)(H,{variant:`success`,children:[`已连接 · `,t?.tool_count??0,` 工具`]});case Dt.Connecting:return(0,q.jsx)(H,{variant:`warning`,children:`连接中`});case Dt.Degraded:return(0,q.jsxs)(H,{variant:`warning`,children:[`降级 · `,t?.tool_count??0,` 工具`]});case Dt.Error:return(0,q.jsx)(H,{variant:`destructive`,children:`错误`});case Dt.Stopped:default:return(0,q.jsx)(H,{variant:`outline`,children:`已停止`})}}function bn(){let[e,t]=(0,G.useState)({servers:[],confirmed:!1,revision:0}),{servers:n,confirmed:r,revision:i}=e,[o,c]=(0,G.useState)(!0),[l,u]=(0,G.useState)(null),[d,f]=(0,G.useState)(null),[p,m]=(0,G.useState)(null),[h,g]=(0,G.useState)(!1),[b,S]=(0,G.useState)(null),[C,w]=(0,G.useState)({}),[E,D]=(0,G.useState)({}),[k,A]=(0,G.useState)({}),[j,M]=(0,G.useState)(!1),N=(0,G.useRef)(null),P=(0,G.useRef)(!1),F=(0,G.useRef)(0),ee=(0,G.useRef)(null),I=(0,G.useRef)(!0);(0,G.useEffect)(()=>(I.current=!0,()=>{I.current=!1,F.current+=1}),[]);let L=(0,G.useCallback)(async(e=!1)=>{let n=++F.current;ee.current=n;try{let e=await dn.getServers();return!I.current||n!==F.current?null:(t(t=>({servers:e,confirmed:!0,revision:t.revision+ +(!t.confirmed||Zt(t.servers.map(e=>e.id))!==Zt(e.map(e=>e.id)))})),u(null),e)}catch{return!I.current||n!==F.current?null:(t(e=>({...e,confirmed:!1,revision:e.revision+1})),e||u(`无法确认 MCP 服务器列表,请刷新后重试。错误详情已隐藏。`),null)}finally{ee.current===n&&(ee.current=null),I.current&&n===F.current&&c(!1)}},[]);(0,G.useEffect)(()=>{L();let e=window.setInterval(()=>{!P.current&&ee.current===null&&L(!0)},_n);return()=>window.clearInterval(e)},[L]);let R=async(e,t)=>{if(P.current)throw new $t(`busy`);P.current=!0,F.current+=1;try{if(e.mode===`replace`){let e=await L(!0);if(!e)throw new $t(`list_unavailable`);if(Zt(e.map(e=>e.id))!==t)throw new $t(`list_changed`)}if(!I.current)throw new $t(`list_unavailable`);let n=await dn.importServers(e),r=await L(!0);return I.current&&A(e=>{let t={...e};for(let e of n.server_ids)t[e]=(t[e]??0)+1;return t}),{result:n,refreshed:r!==null}}catch(e){let t=e instanceof $t?e:new $t(`uncertain`);throw t.kind!==`list_changed`&&t.kind!==`list_unavailable`&&await L(!0),t}finally{P.current=!1}},ne=(e,t)=>w(n=>({...n,[e]:t})),z=async(e,t)=>{ne(e.id,!0);try{await(t?dn.connectServer(e.id):dn.disconnectServer(e.id)),u(null)}catch{u(`无法更改服务器启用状态。请核对实际列表;错误详情已隐藏。`)}finally{ne(e.id,!1),L(!0)}},re=async e=>{ne(e.id,!0);try{await dn.refreshTools(e.id),A(t=>({...t,[e.id]:(t[e.id]??0)+1})),u(null)}catch{u(`无法刷新服务器工具。请核对运行状态;错误详情已隐藏。`)}finally{ne(e.id,!1),L(!0)}},ie=async e=>{d?.mode===`edit`?await dn.updateServer(e.id,e):await dn.addServer(e),f(null),A(t=>({...t,[e.id]:(t[e.id]??0)+1})),await L(!0)},ae=async()=>{if(p){g(!0),S(null);try{await dn.deleteServer(p.id),m(null),await L(!0)}catch{S(`无法确认删除结果,请刷新实际列表;错误详情已隐藏。`)}finally{g(!1)}}};return(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`连接 MCP 工具服务器(stdio、SSE 或 Streamable HTTP)。`}),(0,q.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,q.jsx)(s,{size:`sm`,variant:`ghost`,"aria-label":`刷新 MCP 列表`,onClick:()=>{P.current||L()},children:(0,q.jsx)(Me,{className:`size-4`})}),(0,q.jsxs)(s,{ref:N,size:`sm`,variant:`secondary`,disabled:!r||o,onClick:()=>M(!0),children:[(0,q.jsx)(Pe,{className:`size-4`}),` 导入 JSON`]}),(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,onClick:()=>f({mode:`create`,initial:null}),children:[(0,q.jsx)(_,{className:`size-4`}),` 新增`]})]})]}),l?(0,q.jsx)(`div`,{className:`rounded-md border border-destructive/50 bg-destructive/10 px-3 py-2 text-xs break-all text-destructive`,role:`alert`,children:l}):null,o?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):n.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:r?`暂无 MCP 服务器`:`服务器列表尚未确认,请刷新。`}):(0,q.jsx)(`ul`,{className:`space-y-2`,children:n.map(e=>{let t=!!C[e.id],n=!!E[e.id],r=e.runtime?.last_error&&(e.runtime?.status===Dt.Error||e.runtime?.status===Dt.Degraded);return(0,q.jsxs)(`li`,{className:`rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,q.jsx)(`button`,{onClick:()=>D(t=>({...t,[e.id]:!t[e.id]})),"aria-label":n?`收起工具列表`:`展开工具列表`,"aria-expanded":n,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-foreground`,children:(0,q.jsx)(te,{className:a(`size-4 transition-transform`,n&&`rotate-90`)})}),(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,q.jsx)(`span`,{className:`truncate text-sm font-medium`,children:e.name||e.id}),(0,q.jsx)(yn,{server:e})]}),(0,q.jsx)(`div`,{className:`truncate text-xs text-muted-foreground`,title:vn(e.config.transport),children:vn(e.config.transport)})]}),(0,q.jsx)(J,{checked:e.enabled,disabled:t,onCheckedChange:t=>void z(e,t),"aria-label":e.enabled?`停用`:`启用`}),(0,q.jsx)(`button`,{onClick:()=>void re(e),disabled:t||!e.enabled,"aria-label":`刷新工具`,title:e.enabled?`刷新工具列表`:`先启用服务器`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-foreground disabled:opacity-40`,children:(0,q.jsx)(Me,{className:a(`size-3.5`,t&&`animate-spin`)})}),(0,q.jsx)(`button`,{onClick:()=>f({mode:`edit`,initial:{...e.config,name:e.config.name??e.name,enabled:e.enabled}}),"aria-label":`编辑`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-foreground`,children:(0,q.jsx)(x,{className:`size-3.5`})}),(0,q.jsx)(`button`,{onClick:()=>{S(null),m(e)},"aria-label":`删除`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(v,{className:`size-3.5`})})]}),r?(0,q.jsx)(`p`,{className:`mt-1.5 text-xs text-destructive`,children:`服务器运行异常。详细错误已隐藏,以保护配置中的凭据。`}):null,n?(0,q.jsx)(`div`,{className:`mt-2 border-t pt-2`,children:(0,q.jsx)(hn,{serverId:e.id,version:k[e.id]??0})}):null]},e.id)})}),j?(0,q.jsx)(gn,{existingIds:n.map(e=>e.id),listConfirmed:r,listRevision:i,onClose:()=>M(!1),onReturnFocus:()=>N.current?.focus(),onImport:R,onReload:async()=>await L()!==null}):null,(0,q.jsx)(mn,{open:d!==null,mode:d?.mode??`create`,initial:d?.initial,existingIds:n.map(e=>e.id),onCancel:()=>f(null),onSubmit:ie}),(0,q.jsx)(T,{open:p!==null,onOpenChange:e=>{e||m(null)},children:(0,q.jsxs)(O,{showCloseButton:!1,className:`p-5`,children:[(0,q.jsx)(y,{children:`删除 MCP 服务器`}),(0,q.jsxs)(`p`,{className:`mt-2 text-sm leading-relaxed text-muted-foreground`,children:[`确定删除「`,p?.name||p?.id,`」?已连接的会话将无法再使用其工具,该操作不可撤销。`]}),b?(0,q.jsx)(`p`,{className:`mt-2 text-xs break-all text-destructive`,role:`alert`,children:b}):null,(0,q.jsxs)(`div`,{className:`mt-5 flex justify-end gap-2`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:()=>m(null),disabled:h,children:`取消`}),(0,q.jsx)(s,{size:`sm`,variant:`destructive`,onClick:()=>void ae(),disabled:h,children:h?`删除中…`:`删除`})]})]})})]})}var xn=e=>e===`installing`?`installing`:`installed`,Sn=e=>{if(!Array.isArray(e))return;let t=e.filter(e=>typeof e==`string`);return t.length>0?t:void 0},Cn=e=>{if(!e||typeof e!=`object`)return{};let t=e,n={},r=Sn(t.mcp_server_ids),i=Sn(t.preset_ids),a=Sn(t.skill_dirs),o=Sn(t.workflow_filenames);return r&&(n.mcp_server_ids=r),i&&(n.preset_ids=i),a&&(n.skill_dirs=a),o&&(n.workflow_filenames=o),n},wn=e=>{if(e&&typeof e==`object`){let t=e;if(t.type===`local_dir`&&typeof t.path==`string`)return{type:`local_dir`,path:t.path};if(t.type===`local_archive`&&typeof t.path==`string`)return{type:`local_archive`,path:t.path};if(t.type===`url`&&typeof t.url==`string`)return{type:`url`,url:t.url,sha256:typeof t.sha256==`string`?t.sha256:void 0}}return{type:`local_dir`,path:``}},Tn=e=>({id:typeof e.id==`string`?e.id:``,name:typeof e.name==`string`?e.name:void 0,version:typeof e.version==`string`?e.version:``,source:wn(e.source),status:xn(e.status),registered:Cn(e.registered)}),En=new class{async listPlugins(){let e=await w.get(`plugins`);return Array.isArray(e?.plugins)?e.plugins.map(Tn):[]}async installPlugin(e){return Tn(await w.post(`plugins/install`,{source:e})??{})}async updatePlugin(e,t){return Tn(await w.post(`plugins/${encodeURIComponent(e)}/update`,{source:t})??{})}async removePlugin(e){await w.delete(`plugins/${encodeURIComponent(e)}`)}},Dn=[{value:`url`,label:`URL`},{value:`local_dir`,label:`本地目录`},{value:`local_archive`,label:`本地压缩包`}];function On({label:e,children:t}){return(0,q.jsxs)(`label`,{className:`block`,children:[(0,q.jsx)(`span`,{className:`mb-1 block text-xs text-muted-foreground`,children:e}),t]})}function kn({open:e,mode:t,pluginId:n,pluginName:r,initialSource:i,onCancel:a,onSubmit:o}){let[c,l]=(0,G.useState)(`url`),[u,d]=(0,G.useState)(``),[f,p]=(0,G.useState)(``),[m,h]=(0,G.useState)(``),[g,_]=(0,G.useState)(null),[v,b]=(0,G.useState)(!1);(0,G.useEffect)(()=>{if(!e)return;let t=i??null;l(t?.type??`url`),d(t?.type===`url`?t.url:``),p(t?.type===`url`?t.sha256??``:``),h(t&&(t.type===`local_dir`||t.type===`local_archive`)?t.path:``),_(null),b(!1)},[e,i]);let x=()=>{if(c===`url`){if(!u.trim())return`URL 不能为空`;try{new URL(u.trim())}catch{return`URL 格式无效`}}else if(!m.trim())return`路径不能为空`;return null},w=()=>c===`url`?{type:`url`,url:u.trim(),sha256:f.trim()?f.trim():void 0}:c===`local_archive`?{type:`local_archive`,path:m.trim()}:{type:`local_dir`,path:m.trim()},E=async()=>{let e=x();if(e){_(e);return}b(!0),_(null);try{await o(w())}catch(e){_(S(e))}finally{b(!1)}};return(0,q.jsx)(T,{open:e,onOpenChange:e=>{e||a()},children:(0,q.jsxs)(O,{className:`sm:max-w-lg`,children:[(0,q.jsx)(`div`,{className:`border-b px-4 py-3.5`,children:(0,q.jsx)(y,{children:t===`update`?`更新插件「${r||n}」`:`安装插件`})}),(0,q.jsxs)(`div`,{className:`min-h-0 flex-1 space-y-3 overflow-y-auto p-4`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`mb-1 text-xs text-muted-foreground`,children:`来源类型`}),(0,q.jsx)(`div`,{className:`flex gap-2`,children:Dn.map(e=>(0,q.jsx)(s,{type:`button`,size:`sm`,variant:c===e.value?`default`:`secondary`,className:`flex-1`,onClick:()=>l(e.value),children:e.label},e.value))})]}),c===`url`?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(On,{label:`URL`,children:(0,q.jsx)(C,{placeholder:`https://example.com/plugin.zip`,value:u,autoComplete:`off`,onChange:e=>d(e.target.value)})}),(0,q.jsx)(On,{label:`sha256 校验和(可选)`,children:(0,q.jsx)(C,{placeholder:`用于校验下载内容完整性`,value:f,autoComplete:`off`,className:`font-mono text-xs`,onChange:e=>p(e.target.value)})})]}):(0,q.jsx)(On,{label:c===`local_dir`?`本地目录路径`:`本地压缩包路径`,children:(0,q.jsx)(C,{placeholder:c===`local_dir`?`/Users/me/my-plugin`:`/Users/me/my-plugin.zip`,value:m,autoComplete:`off`,onChange:e=>h(e.target.value)})}),(0,q.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-xs leading-relaxed text-amber-700 dark:text-amber-400`,children:[(0,q.jsx)(ke,{className:`mt-0.5 size-3.5 shrink-0`}),(0,q.jsxs)(`span`,{children:[t===`update`?`更新`:`安装`,`插件可能会注册新的 MCP 服务器,或运行插件自带的可执行程序。请确认来源可信后再继续。`]})]})]}),(0,q.jsxs)(`div`,{className:`border-t p-3`,children:[g?(0,q.jsx)(`p`,{className:`mb-2 text-xs break-all text-destructive`,role:`alert`,children:g}):null,(0,q.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:a,disabled:v,children:`取消`}),(0,q.jsx)(s,{size:`sm`,onClick:()=>void E(),disabled:v,children:v?t===`update`?`更新中…`:`安装中…`:t===`update`?`更新`:`安装`})]})]})]})})}function An({status:e}){return e===`installing`?(0,q.jsx)(H,{variant:`warning`,children:`安装中(可能为异常残留)`}):(0,q.jsx)(H,{variant:`secondary`,children:`已安装`})}function jn(e){switch(e.type){case`local_dir`:return`本地目录 · ${e.path}`;case`local_archive`:return`本地压缩包 · ${e.path}`;case`url`:return`URL · ${e.url}`;default:return``}}function Mn(e){let t=[];return e.mcp_server_ids?.length&&t.push({key:`mcp`,label:`${e.mcp_server_ids.length} 个 MCP 服务器`}),e.skill_dirs?.length&&t.push({key:`skills`,label:`${e.skill_dirs.length} 个技能`}),e.preset_ids?.length&&t.push({key:`prompts`,label:`${e.preset_ids.length} 个提示词`}),e.workflow_filenames?.length&&t.push({key:`workflows`,label:`${e.workflow_filenames.length} 个工作流`}),t}function Nn(){let[e,t]=(0,G.useState)([]),[n,r]=(0,G.useState)(!0),[i,o]=(0,G.useState)(null),[c,l]=(0,G.useState)(null),[u,d]=(0,G.useState)(null),[f,p]=(0,G.useState)(!1),[m,h]=(0,G.useState)(null),g=(0,G.useRef)(!0);(0,G.useEffect)(()=>(g.current=!0,()=>{g.current=!1}),[]);let b=(0,G.useCallback)(async(e=!1)=>{e||r(!0);try{let e=await En.listPlugins();if(!g.current)return;t(e),o(null)}catch(e){if(!g.current)return;o(S(e))}finally{g.current&&r(!1)}},[]);(0,G.useEffect)(()=>{b()},[b]);let x=async e=>{try{c?.mode===`update`&&c.pluginId?await En.updatePlugin(c.pluginId,e):await En.installPlugin(e)}catch(e){throw c?.mode===`install`&&j(e)&&e.status===409?Error(`${S(e)}(该插件已安装,请改用「更新」)`):e}l(null),await b(!0)},C=async()=>{if(u){p(!0),h(null);try{await En.removePlugin(u.id),d(null),await b(!0)}catch(e){h(S(e))}finally{p(!1)}}};return(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:`安装 / 更新 / 卸载扩展插件。插件可能会注册 MCP 服务器、技能、提示词或工作流。`}),(0,q.jsxs)(`div`,{className:`flex shrink-0 gap-2`,children:[(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,onClick:()=>void b(),disabled:n,children:[(0,q.jsx)(Me,{className:a(`size-4`,n&&`animate-spin`)}),` 刷新`]}),(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,onClick:()=>l({mode:`install`}),children:[(0,q.jsx)(_,{className:`size-4`}),` 安装插件`]})]})]}),i?(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2 rounded-md border border-destructive/50 bg-destructive/10 px-3 py-2 text-xs break-all text-destructive`,role:`alert`,children:[(0,q.jsx)(`span`,{children:i}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,className:`h-7 shrink-0 px-2`,onClick:()=>void b(),children:`重试`})]}):null,n&&e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无插件`}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`共 `,e.length,` 个插件`]}),(0,q.jsx)(`ul`,{className:`space-y-2`,children:e.map(e=>{let t=Mn(e.registered);return(0,q.jsxs)(`li`,{className:`rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,q.jsx)(`span`,{className:`truncate text-sm font-medium`,children:e.name||e.id}),(0,q.jsxs)(`span`,{className:`shrink-0 text-xs text-muted-foreground`,children:[`v`,e.version]}),(0,q.jsx)(An,{status:e.status})]}),e.name?(0,q.jsx)(`div`,{className:`mt-0.5 truncate text-xs text-muted-foreground`,children:e.id}):null,(0,q.jsx)(`div`,{className:`mt-1 truncate text-xs text-muted-foreground`,title:jn(e.source),children:jn(e.source)}),t.length>0?(0,q.jsx)(`div`,{className:`mt-2 flex flex-wrap items-center gap-1`,children:t.map(e=>(0,q.jsx)(H,{variant:`outline`,className:`text-[10px] font-normal text-muted-foreground`,children:e.label},e.key))}):null,(0,q.jsxs)(`div`,{className:`mt-2 flex justify-end gap-2`,children:[(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,className:`h-7 px-2 text-xs`,onClick:()=>l({mode:`update`,pluginId:e.id,pluginName:e.name,initialSource:e.source}),children:[(0,q.jsx)(Ne,{className:`size-3.5`}),` 更新`]}),(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,className:`h-7 px-2 text-xs text-destructive hover:text-destructive`,onClick:()=>{h(null),d(e)},children:[(0,q.jsx)(v,{className:`size-3.5`}),` 删除`]})]})]},e.id)})})]}),(0,q.jsx)(kn,{open:c!==null,mode:c?.mode??`install`,pluginId:c?.pluginId,pluginName:c?.pluginName,initialSource:c?.initialSource,onCancel:()=>l(null),onSubmit:x}),(0,q.jsx)(T,{open:u!==null,onOpenChange:e=>{e||d(null)},children:(0,q.jsxs)(O,{showCloseButton:!1,className:`p-5`,children:[(0,q.jsx)(y,{children:`删除插件`}),(0,q.jsxs)(`p`,{className:`mt-2 text-sm leading-relaxed text-muted-foreground`,children:[`确定删除「`,u?.name||u?.id,`」?其注册的 MCP 服务器、技能、提示词或工作流将一并移除,该操作不可撤销。`]}),m?(0,q.jsx)(`p`,{className:`mt-2 text-xs break-all text-destructive`,role:`alert`,children:m}):null,(0,q.jsxs)(`div`,{className:`mt-5 flex justify-end gap-2`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:()=>d(null),disabled:f,children:`取消`}),(0,q.jsx)(s,{size:`sm`,variant:`destructive`,onClick:()=>void C(),disabled:f,children:f?`删除中…`:`删除`})]})]})})]})}function Pn(){let e=ne(e=>e.config),t=ne(e=>e.loadConfig),n=ne(e=>e.saveConfig),r=Se(e=>e.loadSkills),[i,o]=(0,G.useState)([]),[c,l]=(0,G.useState)(!0),[u,d]=(0,G.useState)(null),[f,p]=(0,G.useState)(null),[m,h]=(0,G.useState)(null),[g,_]=(0,G.useState)(``),v=(0,G.useMemo)(()=>new Set((e?.skills?.disabled??[]).map(e=>e.trim()).filter(Boolean)),[e]),y=(0,G.useCallback)(async e=>{l(!0),d(null);try{let[n]=await Promise.all([ce.listSkills({includeDisabled:!0},e),t({force:e})]);o(n.skills)}catch(e){d(e instanceof Error?e.message:`加载技能失败`)}finally{l(!1)}},[t]);(0,G.useEffect)(()=>{y(!0)},[y]);let b=async(e,i)=>{p(e.id),h(null);try{let a=await t({force:!0}),o=a?.skills?.disabled??[],s=Array.from(new Set((i?o.filter(t=>t!==e.id):[...o,e.id]).map(e=>e.trim()).filter(Boolean))).sort();await n({skills:{...a?.skills??{},disabled:s},...a&&a.model_limits!==void 0?{model_limits:a.model_limits}:{}}),r()}catch(t){h({id:e.id,message:t instanceof Error?t.message:`保存技能状态失败`})}finally{p(null)}},x=g.trim().toLowerCase(),S=x?i.filter(e=>[e.id,e.name,e.description,e.license??``,e.compatibility??``,...e.tool_refs??[]].join(` `).toLowerCase().includes(x)):i;return(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-start justify-between gap-2`,children:[(0,q.jsxs)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:[`在输入框输入 `,(0,q.jsx)(`code`,{children:`/`}),` 触发技能。被禁用的技能不会进入系统提示,运行时也禁止 load_skill。`]}),(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,className:`shrink-0`,onClick:()=>void y(!0),disabled:c,children:[(0,q.jsx)(Me,{className:a(`size-4`,c&&`animate-spin`)}),` 刷新`]})]}),(0,q.jsxs)(`div`,{className:`relative`,children:[(0,q.jsx)(I,{className:`pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground`}),(0,q.jsx)(C,{className:`pl-8`,placeholder:`搜索技能(名称 / 描述 / 工具)`,value:g,onChange:e=>_(e.target.value)})]}),u?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:u}):null,c&&i.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):S.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:x?`没有匹配的技能`:`暂无技能`}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`共 `,i.length,` 个技能`,v.size>0?`,已禁用 ${v.size} 个`:``]}),(0,q.jsx)(`ul`,{className:`space-y-2`,children:S.map(e=>{let t=v.has(e.id);return(0,q.jsxs)(`li`,{className:a(`rounded-lg border p-3`,t&&`opacity-70`),children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-medium`,children:e.name}),t?(0,q.jsx)(H,{variant:`outline`,className:`text-[10px]`,children:`已禁用`}):null,(0,q.jsx)(J,{checked:!t,disabled:f===e.id,onCheckedChange:t=>void b(e,t),"aria-label":t?`启用 ${e.name}`:`禁用 ${e.name}`})]}),e.description?(0,q.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:e.description}):null,e.license||e.compatibility||(e.tool_refs?.length??0)>0?(0,q.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-1`,children:[e.license?(0,q.jsxs)(H,{variant:`secondary`,className:`text-[10px]`,children:[`License: `,e.license]}):null,e.compatibility?(0,q.jsxs)(H,{variant:`secondary`,className:`text-[10px]`,children:[`兼容: `,e.compatibility]}):null,(e.tool_refs??[]).map(e=>(0,q.jsx)(H,{variant:`outline`,className:`text-[10px] font-normal text-muted-foreground`,children:e},e))]}):null,m?.id===e.id?(0,q.jsx)(`p`,{className:`mt-2 text-xs text-destructive`,children:m.message}):null]},e.id)})})]})]})}function Fn(){let[e,t]=(0,G.useState)([]),[n,r]=(0,G.useState)(!0),[i,a]=(0,G.useState)(``);(0,G.useEffect)(()=>{D.getPermissionAskRules().then(t).catch(()=>{}).finally(()=>r(!1))},[]);let o=async e=>{t(e);try{t(await D.updatePermissionAskRules(e))}catch{}},c=()=>{let t=i.trim();!t||e.includes(t)||(o([...e,t]),a(``))};return(0,q.jsxs)(`div`,{className:`space-y-4`,children:[(0,q.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`匹配这些规则的工具调用会在执行前弹出审批。规则可以是工具名或模式(如 `,(0,q.jsx)(`code`,{children:`Bash`}),`、`,(0,q.jsx)(`code`,{children:`write_file`}),`)。`]}),(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`新增规则`}),(0,q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,q.jsx)(C,{className:`flex-1`,placeholder:`工具名 / 模式`,value:i,onChange:e=>a(e.target.value),onKeyDown:e=>{e.key===`Enter`&&c()}}),(0,q.jsxs)(s,{size:`sm`,onClick:c,disabled:!i.trim(),children:[(0,q.jsx)(_,{className:`size-4`}),` 添加`]})]})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:[`需审批的规则 (`,e.length,`)`]}),n?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无 —— 所有工具直接执行`}):(0,q.jsx)(`ul`,{className:`space-y-1.5`,children:e.map(t=>(0,q.jsxs)(`li`,{className:`flex items-center gap-2 rounded-md bg-muted/40 px-2.5 py-1.5`,children:[(0,q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-xs`,children:t}),(0,q.jsx)(`button`,{onClick:()=>void o(e.filter(e=>e!==t)),"aria-label":`删除`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(v,{className:`size-3.5`})})]},t))})]})]})}var In=`Label`,Ln=G.forwardRef((e,t)=>(0,q.jsx)(k.label,{...e,ref:t,onMouseDown:t=>{t.target.closest(`button, input, select, textarea`)||(e.onMouseDown?.(t),!t.defaultPrevented&&t.detail>1&&t.preventDefault())}}));Ln.displayName=In;var Rn=Ln;function X({className:e,...t}){return(0,q.jsx)(Rn,{"data-slot":`label`,className:a(`flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50`,e),...t})}function zn(){let[e,t]=(0,G.useState)([]),[n,r]=(0,G.useState)(!0),[i,a]=(0,G.useState)(``),[o,c]=(0,G.useState)(``),[l,u]=(0,G.useState)(!1),[d,f]=(0,G.useState)(!1);(0,G.useEffect)(()=>{D.getEnvVars().then(e=>t(e.entries)).catch(()=>{}).finally(()=>r(!1))},[]);let p=async()=>{if(!(!i.trim()||d)){f(!0);try{t((await D.upsertEnvVar({name:i.trim(),value:o,secret:l})).entries),a(``),c(``),u(!1)}catch{}finally{f(!1)}}},m=async e=>{try{t((await D.deleteEnvVar(e)).entries)}catch{}};return(0,q.jsxs)(`div`,{className:`space-y-4`,children:[(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`传递给后端 / 工具的环境变量。标记为密钥的值会在保存后被掩码显示。`}),(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`新增变量`}),(0,q.jsx)(C,{placeholder:`名称(如 OPENAI_API_KEY)`,value:i,onChange:e=>a(e.target.value)}),(0,q.jsx)(C,{placeholder:`值`,type:l?`password`:`text`,value:o,onChange:e=>c(e.target.value)}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,q.jsxs)(X,{className:`text-muted-foreground font-normal`,children:[(0,q.jsx)(J,{checked:l,onCheckedChange:u}),`密钥(掩码)`]}),(0,q.jsxs)(s,{size:`sm`,onClick:p,disabled:!i.trim()||d,children:[(0,q.jsx)(_,{className:`size-4`}),` 添加`]})]})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:[`已配置 (`,e.length,`)`]}),n?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无`}):(0,q.jsx)(`ul`,{className:`space-y-1.5`,children:e.map(e=>(0,q.jsxs)(`li`,{className:`flex items-center gap-2 rounded-md bg-muted/40 px-2.5 py-1.5`,children:[(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(`span`,{className:`truncate font-mono text-xs`,children:e.name}),e.secret?(0,q.jsx)(`span`,{className:`rounded bg-muted px-1 text-[10px] text-muted-foreground`,children:`密钥`}):null]}),(0,q.jsx)(`div`,{className:`truncate font-mono text-[11px] text-muted-foreground`,children:e.has_value?e.value:(0,q.jsx)(`span`,{className:`italic`,children:`未设置`})})]}),(0,q.jsx)(`button`,{onClick:()=>void m(e.name),"aria-label":`删除`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(v,{className:`size-3.5`})})]},e.name))})]})]})}var Bn=[{value:`mon`,label:`一`},{value:`tue`,label:`二`},{value:`wed`,label:`三`},{value:`thu`,label:`四`},{value:`fri`,label:`五`},{value:`sat`,label:`六`},{value:`sun`,label:`日`}],Vn=[{value:`interval`,label:`间隔`},{value:`daily`,label:`每天`},{value:`weekly`,label:`每周`},{value:`monthly`,label:`每月`},{value:`cron`,label:`Cron`}],Hn=[{value:`run_once`,label:`补跑一次`},{value:`skip`,label:`跳过`},{value:`catch_up_all`,label:`全部补跑`},{value:`catch_up_window`,label:`窗口内补跑`}],Un=[{value:`queue_one`,label:`排队一个`},{value:`skip`,label:`跳过`},{value:`allow`,label:`允许并行`}],Wn={name:``,enabled:!1,trigger_type:`interval`,interval_value:`60`,interval_unit:`minutes`,hour:`9`,minute:`0`,weekly_weekdays:[`mon`],monthly_days:`1`,cron_expr:`0 9 * * *`,timezone:``,start_at:``,end_at:``,misfire_policy:`run_once`,catch_up_max_runs:`1`,catch_up_max_lateness_seconds:`60`,overlap_policy:`queue_one`,task_message:``,system_prompt:``,model:``,workspace_path:``,enhance_prompt:``,auto_execute:!0};function Gn(e){return e.trim()||void 0}var Kn={seconds:1,minutes:60,hours:3600};function qn(e){return e>0&&e%3600==0?{value:String(e/3600),unit:`hours`}:e>0&&e%60==0?{value:String(e/60),unit:`minutes`}:{value:String(e),unit:`seconds`}}function Jn(e){let t=e.trim();if(!t)return{days:[],invalid:!1};let n=t.split(/[\s,,]+/).filter(Boolean).map(e=>Number(e)),r=n.some(e=>!Number.isInteger(e)||e<1||e>31);return{days:Array.from(new Set(n.filter(e=>Number.isInteger(e)&&e>=1&&e<=31))).sort((e,t)=>e-t),invalid:r}}function Yn(e){let t=Number(e.hour),n=Number(e.minute);return!Number.isInteger(t)||t<0||t>23||!Number.isInteger(n)||n<0||n>59?null:{hour:t,minute:n}}function Xn(e){switch(e.trigger_type){case`interval`:{let t=Number(e.interval_value);if(!Number.isFinite(t)||t<=0)return{error:`请填写大于 0 的间隔`};let n=Math.round(t*Kn[e.interval_unit]);return n<=0?{error:`请填写大于 0 的间隔`}:{trigger:{type:`interval`,every_seconds:n}}}case`daily`:{let t=Yn(e);return t?{trigger:{type:`daily`,...t,second:0}}:{error:`请填写有效的时间(时 0-23,分 0-59)`}}case`weekly`:{if(e.weekly_weekdays.length===0)return{error:`请至少选择一个星期几`};let t=Yn(e);return t?{trigger:{type:`weekly`,weekdays:e.weekly_weekdays,...t,second:0}}:{error:`请填写有效的时间(时 0-23,分 0-59)`}}case`monthly`:{let{days:t,invalid:n}=Jn(e.monthly_days);if(n)return{error:`每月日期必须是 1-31 的整数(逗号分隔)`};if(t.length===0)return{error:`请填写每月执行的日期(如 1, 15)`};let r=Yn(e);return r?{trigger:{type:`monthly`,days:t,...r,second:0}}:{error:`请填写有效的时间(时 0-23,分 0-59)`}}case`cron`:{let t=Gn(e.cron_expr);return t?{trigger:{type:`cron`,expr:t}}:{error:`请填写 cron 表达式`}}default:return{error:`请选择触发类型`}}}function Zn(e){switch(e.misfire_policy){case`skip`:return{type:`skip`};case`catch_up_all`:return{type:`catch_up_all`};case`catch_up_window`:return{type:`catch_up_window`,max_catch_up_runs:Math.max(1,Number(e.catch_up_max_runs)||1),max_lateness_seconds:Math.max(1,Number(e.catch_up_max_lateness_seconds)||60)};default:return{type:`run_once`}}}function Qn(e,t){return{...t??{},system_prompt:Gn(e.system_prompt),task_message:Gn(e.task_message),model:Gn(e.model),workspace_path:Gn(e.workspace_path),enhance_prompt:Gn(e.enhance_prompt),auto_execute:e.auto_execute}}function $n(e){let t={...Wn,name:e.name,enabled:e.enabled,trigger_type:e.trigger.type,timezone:e.timezone??``,start_at:e.start_at??``,end_at:e.end_at??``,misfire_policy:e.misfire_policy?.type??`run_once`,overlap_policy:e.overlap_policy??`queue_one`,task_message:e.run_config?.task_message??``,system_prompt:e.run_config?.system_prompt??``,model:e.run_config?.model??``,workspace_path:e.run_config?.workspace_path??``,enhance_prompt:e.run_config?.enhance_prompt??``,auto_execute:!!e.run_config?.auto_execute};switch(e.misfire_policy?.type===`catch_up_window`&&(t.catch_up_max_runs=String(e.misfire_policy.max_catch_up_runs),t.catch_up_max_lateness_seconds=String(e.misfire_policy.max_lateness_seconds)),e.trigger.type){case`interval`:{let{value:n,unit:r}=qn(e.trigger.every_seconds);t.interval_value=n,t.interval_unit=r;break}case`daily`:t.hour=String(e.trigger.hour),t.minute=String(e.trigger.minute);break;case`weekly`:t.weekly_weekdays=e.trigger.weekdays,t.hour=String(e.trigger.hour),t.minute=String(e.trigger.minute);break;case`monthly`:t.monthly_days=e.trigger.days.join(`, `),t.hour=String(e.trigger.hour),t.minute=String(e.trigger.minute);break;case`cron`:t.cron_expr=e.trigger.expr;break}return t}function er(e){return String(e).padStart(2,`0`)}function tr(e){switch(e.type){case`interval`:{let t=e.every_seconds??0;return t>0&&t%3600==0?`每 ${t/3600} 小时`:t>0&&t%60==0?`每 ${t/60} 分钟`:`每 ${t} 秒`}case`daily`:return`每天 ${er(e.hour)}:${er(e.minute)}`;case`weekly`:return`每周${e.weekdays.map(e=>Bn.find(t=>t.value===e)?.label??e).join(`、`)} ${er(e.hour)}:${er(e.minute)}`;case`monthly`:return`每月 ${e.days.join(`, `)} 日 ${er(e.hour)}:${er(e.minute)}`;case`cron`:return`cron: ${e.expr}`;default:return e.type}}function nr(e){switch(e?.type){case`skip`:return`错过跳过`;case`catch_up_all`:return`错过全部补跑`;case`catch_up_window`:return`错过窗口补跑`;default:return`错过补跑一次`}}function rr(e){switch(e){case`allow`:return`允许并行`;case`skip`:return`重叠跳过`;default:return`重叠排队一个`}}function ir(e){if(!e)return`-`;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(`zh-CN`,{hour12:!1})}function ar(e){return e instanceof Error?e.message:String(e)}function or({children:e}){return(0,q.jsx)(`div`,{className:`mb-1 text-xs font-medium text-muted-foreground`,children:e})}function sr({values:e,onChange:t}){return(0,q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,q.jsxs)(`div`,{className:`flex-1`,children:[(0,q.jsx)(or,{children:`时(0-23)`}),(0,q.jsx)(C,{type:`number`,min:0,max:23,value:e.hour,onChange:e=>t({hour:e.target.value})})]}),(0,q.jsxs)(`div`,{className:`flex-1`,children:[(0,q.jsx)(or,{children:`分(0-59)`}),(0,q.jsx)(C,{type:`number`,min:0,max:59,value:e.minute,onChange:e=>t({minute:e.target.value})})]})]})}function cr({values:e,onChange:t,error:n,saving:r,submitLabel:i,onSubmit:o,onCancel:c}){let[l,u]=(0,G.useState)(!1),d=n=>{t({weekly_weekdays:e.weekly_weekdays.includes(n)?e.weekly_weekdays.filter(e=>e!==n):[...e.weekly_weekdays,n]})};return(0,q.jsxs)(`div`,{className:`space-y-3 rounded-lg border bg-muted/30 p-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-end gap-2`,children:[(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsx)(or,{children:`名称`}),(0,q.jsx)(C,{placeholder:`定时任务名称`,value:e.name,onChange:e=>t({name:e.target.value})})]}),(0,q.jsxs)(`label`,{className:`flex h-9 shrink-0 items-center gap-2 text-xs text-muted-foreground`,children:[`启用`,(0,q.jsx)(J,{checked:e.enabled,onCheckedChange:e=>t({enabled:e})})]})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border bg-background/50 p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`触发`}),(0,q.jsxs)(`div`,{className:`space-y-2.5`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(or,{children:`触发类型`}),(0,q.jsxs)(Ce,{value:e.trigger_type,onValueChange:e=>t({trigger_type:e}),children:[(0,q.jsx)(de,{className:`w-full`,children:(0,q.jsx)(z,{})}),(0,q.jsx)(_e,{children:Vn.map(e=>(0,q.jsx)(V,{value:e.value,children:e.label},e.value))})]})]}),e.trigger_type===`interval`?(0,q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,q.jsxs)(`div`,{className:`flex-1`,children:[(0,q.jsx)(or,{children:`每隔`}),(0,q.jsx)(C,{type:`number`,min:1,value:e.interval_value,onChange:e=>t({interval_value:e.target.value})})]}),(0,q.jsxs)(`div`,{className:`w-28 shrink-0`,children:[(0,q.jsx)(or,{children:`单位`}),(0,q.jsxs)(Ce,{value:e.interval_unit,onValueChange:e=>t({interval_unit:e}),children:[(0,q.jsx)(de,{className:`w-full`,children:(0,q.jsx)(z,{})}),(0,q.jsxs)(_e,{children:[(0,q.jsx)(V,{value:`minutes`,children:`分钟`}),(0,q.jsx)(V,{value:`hours`,children:`小时`}),(0,q.jsx)(V,{value:`seconds`,children:`秒`})]})]})]})]}):null,e.trigger_type===`daily`?(0,q.jsx)(sr,{values:e,onChange:t}):null,e.trigger_type===`weekly`?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(or,{children:`星期`}),(0,q.jsx)(`div`,{className:`flex flex-wrap gap-1.5`,children:Bn.map(t=>(0,q.jsx)(`button`,{type:`button`,onClick:()=>d(t.value),className:a(`size-8 rounded-md border text-xs transition-colors`,e.weekly_weekdays.includes(t.value)?`border-primary bg-primary text-primary-foreground`:`bg-background text-muted-foreground hover:text-foreground`),children:t.label},t.value))})]}),(0,q.jsx)(sr,{values:e,onChange:t})]}):null,e.trigger_type===`monthly`?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(or,{children:`每月日期(1-31,逗号分隔)`}),(0,q.jsx)(C,{placeholder:`如 1, 15`,value:e.monthly_days,onChange:e=>t({monthly_days:e.target.value})})]}),(0,q.jsx)(sr,{values:e,onChange:t})]}):null,e.trigger_type===`cron`?(0,q.jsxs)(`div`,{children:[(0,q.jsx)(or,{children:`cron 表达式`}),(0,q.jsx)(C,{placeholder:`如 0 9 * * *`,value:e.cron_expr,onChange:e=>t({cron_expr:e.target.value})})]}):null]})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border bg-background/50 p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`执行内容`}),(0,q.jsxs)(`div`,{className:`space-y-2.5`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(or,{children:`任务内容`}),(0,q.jsx)(he,{className:`min-h-16 resize-y`,placeholder:`任务内容(自动执行时必填)`,value:e.task_message,onChange:e=>t({task_message:e.target.value})})]}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,q.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`自动执行(触发后直接运行任务)`}),(0,q.jsx)(J,{checked:e.auto_execute,onCheckedChange:e=>t({auto_execute:e})})]}),(0,q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,q.jsxs)(`div`,{className:`flex-1`,children:[(0,q.jsx)(or,{children:`模型(可选)`}),(0,q.jsx)(C,{placeholder:`默认模型`,value:e.model,onChange:e=>t({model:e.target.value})})]}),(0,q.jsxs)(`div`,{className:`flex-1`,children:[(0,q.jsx)(or,{children:`工作目录(可选)`}),(0,q.jsx)(C,{placeholder:`workspace 路径`,value:e.workspace_path,onChange:e=>t({workspace_path:e.target.value})})]})]}),(0,q.jsxs)(`div`,{children:[(0,q.jsx)(or,{children:`系统提示词(可选)`}),(0,q.jsx)(he,{className:`min-h-12 resize-y`,placeholder:`覆盖默认系统提示词`,value:e.system_prompt,onChange:e=>t({system_prompt:e.target.value})})]})]})]}),(0,q.jsx)(`button`,{type:`button`,onClick:()=>u(e=>!e),className:`text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline`,children:l?`收起高级选项`:`高级选项(策略 / 时区 / 生效时间)`}),l?(0,q.jsxs)(`section`,{className:`rounded-lg border bg-background/50 p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`高级`}),(0,q.jsxs)(`div`,{className:`space-y-2.5`,children:[(0,q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,q.jsxs)(`div`,{className:`flex-1`,children:[(0,q.jsx)(or,{children:`错过策略`}),(0,q.jsxs)(Ce,{value:e.misfire_policy,onValueChange:e=>t({misfire_policy:e}),children:[(0,q.jsx)(de,{className:`w-full`,children:(0,q.jsx)(z,{})}),(0,q.jsx)(_e,{children:Hn.map(e=>(0,q.jsx)(V,{value:e.value,children:e.label},e.value))})]})]}),(0,q.jsxs)(`div`,{className:`flex-1`,children:[(0,q.jsx)(or,{children:`重叠策略`}),(0,q.jsxs)(Ce,{value:e.overlap_policy,onValueChange:e=>t({overlap_policy:e}),children:[(0,q.jsx)(de,{className:`w-full`,children:(0,q.jsx)(z,{})}),(0,q.jsx)(_e,{children:Un.map(e=>(0,q.jsx)(V,{value:e.value,children:e.label},e.value))})]})]})]}),e.misfire_policy===`catch_up_window`?(0,q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,q.jsxs)(`div`,{className:`flex-1`,children:[(0,q.jsx)(or,{children:`最多补跑次数`}),(0,q.jsx)(C,{type:`number`,min:1,value:e.catch_up_max_runs,onChange:e=>t({catch_up_max_runs:e.target.value})})]}),(0,q.jsxs)(`div`,{className:`flex-1`,children:[(0,q.jsx)(or,{children:`最大延迟(秒)`}),(0,q.jsx)(C,{type:`number`,min:1,value:e.catch_up_max_lateness_seconds,onChange:e=>t({catch_up_max_lateness_seconds:e.target.value})})]})]}):null,(0,q.jsxs)(`div`,{children:[(0,q.jsx)(or,{children:`时区(可选)`}),(0,q.jsx)(C,{placeholder:`如 Asia/Shanghai`,value:e.timezone,onChange:e=>t({timezone:e.target.value})})]}),(0,q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,q.jsxs)(`div`,{className:`flex-1`,children:[(0,q.jsx)(or,{children:`开始时间(可选)`}),(0,q.jsx)(C,{placeholder:`2026-01-01T00:00:00Z`,value:e.start_at,onChange:e=>t({start_at:e.target.value})})]}),(0,q.jsxs)(`div`,{className:`flex-1`,children:[(0,q.jsx)(or,{children:`结束时间(可选)`}),(0,q.jsx)(C,{placeholder:`2026-12-31T00:00:00Z`,value:e.end_at,onChange:e=>t({end_at:e.target.value})})]})]}),(0,q.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:`注:清空时区 / 开始 / 结束时间后保存不会移除已保存的值(后端暂不支持清除)。`}),(0,q.jsxs)(`div`,{children:[(0,q.jsx)(or,{children:`增强提示词(可选)`}),(0,q.jsx)(he,{className:`min-h-12 resize-y`,placeholder:`附加到任务的增强提示`,value:e.enhance_prompt,onChange:e=>t({enhance_prompt:e.target.value})})]})]})]}):null,n?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:n}):null,(0,q.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:c,disabled:r,children:`取消`}),(0,q.jsx)(s,{size:`sm`,onClick:o,disabled:r||!e.name.trim(),children:r?`保存中…`:i})]})]})}var lr={queued:`排队中`,running:`运行中`,success:`成功`,failed:`失败`,skipped:`已跳过`,missed:`已错过`,cancelled:`已取消`};function ur(e){switch(e){case`success`:return`success`;case`failed`:case`cancelled`:return`destructive`;case`running`:return`default`;case`queued`:return`warning`;default:return`secondary`}}function dr(e){return e==null?null:e<1e3?`${e}ms`:`${(e/1e3).toFixed(1)}s`}function fr({scheduleId:e}){let[t,n]=(0,G.useState)([]),[r,i]=(0,G.useState)(!0),[a,o]=(0,G.useState)(null);return(0,G.useEffect)(()=>{let t=!1;return i(!0),o(null),me.listScheduleRuns(e).then(e=>{t||n(e.runs??[])}).catch(e=>{t||o(`加载运行记录失败:${ar(e)}`)}).finally(()=>{t||i(!1)}),()=>{t=!0}},[e]),r?(0,q.jsx)(`p`,{className:`px-1 py-2 text-xs text-muted-foreground`,children:`加载运行记录中…`}):a?(0,q.jsx)(`p`,{className:`px-1 py-2 text-xs text-destructive`,children:a}):t.length===0?(0,q.jsx)(`p`,{className:`px-1 py-2 text-xs text-muted-foreground`,children:`暂无运行记录`}):(0,q.jsx)(`ul`,{className:`divide-y`,children:t.map(e=>{let t=dr(e.execution_duration_ms);return(0,q.jsxs)(`li`,{className:`space-y-1 px-1 py-2`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5`,children:[(0,q.jsx)(H,{variant:ur(e.status),children:lr[e.status]??e.status}),(0,q.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`计划 `,ir(e.scheduled_for)]}),e.was_catch_up?(0,q.jsx)(H,{variant:`outline`,children:`补跑`}):null]}),(0,q.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`开始 `,ir(e.started_at),` · 结束 `,ir(e.completed_at),t?` · 耗时 ${t}`:``]}),e.session_id?(0,q.jsxs)(`div`,{className:`truncate text-xs text-muted-foreground`,children:[`会话 `,e.session_id]}):null,e.outcome_reason?(0,q.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`原因:`,e.outcome_reason]}):null]},e.run_id)})})}function pr(e){return(e.state?.running_run_count??0)>0?{variant:`default`,label:`运行中 ×${e.state.running_run_count}`}:(e.state?.queued_run_count??0)>0?{variant:`warning`,label:`排队 ×${e.state.queued_run_count}`}:(e.state?.consecutive_failures??0)>0?{variant:`destructive`,label:`连续失败 ×${e.state.consecutive_failures}`}:e.enabled?e.state?.last_success_at?{variant:`success`,label:`正常`}:{variant:`secondary`,label:`空闲`}:{variant:`secondary`,label:`已停用`}}function mr(e){return ir(e.state?.last_success_at??e.state?.last_finished_at)}function hr(){let[e,t]=(0,G.useState)([]),[n,r]=(0,G.useState)(!0),[i,o]=(0,G.useState)(null),[c,l]=(0,G.useState)(!1),[u,d]=(0,G.useState)(null),[f,p]=(0,G.useState)(Wn),[m,h]=(0,G.useState)(null),[g,y]=(0,G.useState)(!1),[b,S]=(0,G.useState)(null),[C,w]=(0,G.useState)(null),[T,E]=(0,G.useState)(null),[D,O]=(0,G.useState)(null),k=(0,G.useCallback)(()=>{me.listSchedules().then(e=>{t(e.schedules??[]),o(null)}).catch(e=>o(`加载定时任务失败:${ar(e)}`)).finally(()=>r(!1))},[]);(0,G.useEffect)(k,[k]);let A=e=>p(t=>({...t,...e})),j=()=>{d(null),p(Wn),h(null),l(!0)},M=e=>{l(!1),d(e.id),p($n(e)),h(null)},N=()=>{l(!1),d(null),p(Wn),h(null)},P=async()=>{if(!f.name.trim()){h(`请填写名称`);return}let{trigger:t,error:n}=Xn(f);if(!t){h(n??`请完善触发配置`);return}let r=Qn(f,u?e.find(e=>e.id===u)?.run_config:null);if(f.auto_execute&&!r.task_message){h(`启用自动执行时必须填写任务内容`);return}y(!0),h(null);try{u?await me.patchSchedule(u,{name:f.name.trim(),enabled:f.enabled,trigger:t,timezone:Gn(f.timezone),start_at:Gn(f.start_at),end_at:Gn(f.end_at),misfire_policy:Zn(f),overlap_policy:f.overlap_policy,run_config:r}):await me.createSchedule({name:f.name.trim(),enabled:f.enabled,trigger:t,timezone:Gn(f.timezone),start_at:Gn(f.start_at),end_at:Gn(f.end_at),misfire_policy:Zn(f),overlap_policy:f.overlap_policy,run_config:r}),N(),k()}catch(e){h(`保存失败:${ar(e)}`)}finally{y(!1)}},F=async(e,t)=>{S(null),w(null);try{await e(),t&&w(t),k()}catch(e){S(ar(e))}};return(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`按计划自动触发的任务。`}),!c&&!u?(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,onClick:j,children:[(0,q.jsx)(_,{className:`size-4`}),` 新增`]}):null]}),c?(0,q.jsx)(cr,{values:f,onChange:A,error:m,saving:g,submitLabel:`添加`,onSubmit:P,onCancel:N}):null,i?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:i}):null,b?(0,q.jsxs)(`p`,{className:`text-xs text-destructive`,children:[`操作失败:`,b]}):null,C?(0,q.jsx)(`p`,{className:`text-xs text-primary`,children:C}):null,n?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):e.length===0?!c&&(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无定时任务`}):(0,q.jsx)(`ul`,{className:`space-y-2`,children:e.map(e=>{let t=pr(e),n=u===e.id;return(0,q.jsxs)(`li`,{className:`rounded-lg border`,children:[(0,q.jsxs)(`div`,{className:`space-y-1.5 p-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,q.jsx)(`div`,{className:`min-w-0 flex-1 truncate text-sm font-medium`,children:e.name}),(0,q.jsx)(H,{variant:t.variant,children:t.label}),(0,q.jsx)(J,{checked:e.enabled,"aria-label":e.enabled?`停用`:`启用`,onCheckedChange:t=>F(async()=>{await me.patchSchedule(e.id,{enabled:t})})})]}),(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-muted-foreground`,children:[(0,q.jsx)(`span`,{children:tr(e.trigger)}),e.timezone?(0,q.jsxs)(`span`,{children:[`· `,e.timezone]}):null,(0,q.jsxs)(`span`,{children:[`· `,nr(e.misfire_policy)]}),(0,q.jsxs)(`span`,{children:[`· `,rr(e.overlap_policy)]}),e.run_config?.auto_execute?(0,q.jsx)(`span`,{children:`· 自动执行`}):null,e.run_config?.model?(0,q.jsxs)(`span`,{children:[`· `,e.run_config.model]}):null]}),(0,q.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`下次 `,ir(e.state?.next_fire_at),` · 上次 `,mr(e)]}),(0,q.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`成功 `,e.state?.total_success_count??0,` · 失败 `,e.state?.total_failure_count??0,` · 错过`,` `,e.state?.total_missed_count??0,` · 共 `,e.state?.total_run_count??0,` 次`]}),(0,q.jsxs)(`div`,{className:`flex items-center gap-1 pt-1`,children:[(0,q.jsx)(`button`,{onClick:()=>F(async()=>{await me.runScheduleNow(e.id)},`「${e.name}」已加入执行队列`),"aria-label":`立即运行`,title:`立即运行`,className:`rounded p-1 text-muted-foreground hover:text-foreground`,children:(0,q.jsx)(je,{className:`size-4`})}),(0,q.jsx)(`button`,{onClick:()=>E(t=>t===e.id?null:e.id),"aria-label":`运行记录`,title:`运行记录`,className:a(`rounded p-1 hover:text-foreground`,T===e.id?`text-primary`:`text-muted-foreground`),children:(0,q.jsx)(Ae,{className:`size-4`})}),(0,q.jsx)(`button`,{onClick:()=>n?N():M(e),"aria-label":`编辑`,title:`编辑`,className:a(`rounded p-1 hover:text-foreground`,n?`text-primary`:`text-muted-foreground`),children:(0,q.jsx)(x,{className:`size-3.5`})}),(0,q.jsx)(`button`,{onClick:()=>O(t=>t===e.id?null:e.id),"aria-label":`删除`,title:`删除`,className:`rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(v,{className:`size-3.5`})})]}),D===e.id?(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2 rounded-md border border-destructive/40 bg-destructive/5 px-2 py-1.5`,children:[(0,q.jsxs)(`span`,{className:`text-xs text-destructive`,children:[`确定删除「`,e.name,`」?`]}),(0,q.jsxs)(`div`,{className:`flex shrink-0 gap-1.5`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:()=>O(null),children:`取消`}),(0,q.jsx)(s,{size:`sm`,variant:`destructive`,onClick:()=>{O(null),F(async()=>{await me.deleteSchedule(e.id)},`已删除「${e.name}」`)},children:`删除`})]})]}):null]}),n?(0,q.jsx)(`div`,{className:`border-t p-2`,children:(0,q.jsx)(cr,{values:f,onChange:A,error:m,saving:g,submitLabel:`保存`,onSubmit:P,onCancel:N})}):null,T===e.id?(0,q.jsx)(`div`,{className:`border-t px-2 py-1`,children:(0,q.jsx)(fr,{scheduleId:e.id})}):null]},e.id)})})]})}var gr=`notifications/preferences`;function _r(e){return{enabled:e.enabled,onClarification:e.on_clarification,onToolApproval:e.on_tool_approval,onContextPressure:e.on_context_pressure,onSubAgentComplete:e.on_subagent_complete,onBackgroundTaskComplete:e.on_background_task_complete,onRunComplete:e.on_run_complete,onRunFailed:e.on_run_failed}}function vr(e){return{enabled:e.enabled,on_clarification:e.onClarification,on_tool_approval:e.onToolApproval,on_context_pressure:e.onContextPressure,on_subagent_complete:e.onSubAgentComplete,on_background_task_complete:e.onBackgroundTaskComplete,on_run_complete:e.onRunComplete,on_run_failed:e.onRunFailed}}async function yr(){return _r(await w.get(gr))}async function br(e){return _r(await w.put(gr,vr(e)))}var xr=`https://ntfy.sh`,Sr=`https://api.day.app`;function Cr(e){let t=e?.desktop?.enabled;return{desktopMode:t===!0?`on`:t===!1?`off`:`auto`,ntfyEnabled:e?.ntfy?.enabled??!1,ntfyBaseUrl:e?.ntfy?.base_url??xr,ntfyTopic:e?.ntfy?.topic??``,ntfyToken:tt(e?.ntfy?.token)?``:e?.ntfy?.token??``,barkEnabled:e?.bark?.enabled??!1,barkBaseUrl:e?.bark?.base_url??Sr,barkDeviceKey:tt(e?.bark?.device_key)?``:e?.bark?.device_key??``}}function wr({label:e,value:t,onChange:n,type:r=`text`,placeholder:i}){return(0,q.jsxs)(`label`,{className:`block`,children:[(0,q.jsx)(`span`,{className:`mb-1 block text-xs text-muted-foreground`,children:e}),(0,q.jsx)(C,{type:r,value:t,placeholder:i,onChange:e=>n(e.target.value)})]})}function Tr(){let[e,t]=(0,G.useState)(void 0),[n,r]=(0,G.useState)(()=>Cr(void 0)),[i,a]=(0,G.useState)(!0),[o,c]=(0,G.useState)(null),[l,u]=(0,G.useState)(!1),[d,f]=(0,G.useState)(null),[p,m]=(0,G.useState)(!1),[h,g]=(0,G.useState)(!1),[_,v]=(0,G.useState)(null),[y,b]=(0,G.useState)(null),x=async()=>{a(!0),c(null);try{let e=await w.get(`bamboo/config`);t(e.notifications),r(Cr(e.notifications))}catch(e){c(S(e))}finally{a(!1)}};(0,G.useEffect)(()=>{x()},[]);let C=e=>r(t=>({...t,...e})),T=tt(e?.ntfy?.token),E=tt(e?.bark?.device_key),D=async()=>{u(!0),f(null),m(!1);try{let e=n.ntfyToken.trim(),i=n.barkDeviceKey.trim(),a={notifications:{desktop:{enabled:n.desktopMode===`auto`?null:n.desktopMode===`on`},ntfy:{enabled:n.ntfyEnabled,base_url:n.ntfyBaseUrl.trim()||xr,topic:n.ntfyTopic.trim(),...e?{token:e}:{}},bark:{enabled:n.barkEnabled,base_url:n.barkBaseUrl.trim()||Sr,...i?{device_key:i}:{}}}},o=await w.post(`bamboo/config`,a);t(o.notifications),r(Cr(o.notifications)),m(!0),setTimeout(()=>m(!1),2500)}catch(e){f(S(e))}finally{u(!1)}},O=async()=>{g(!0),v(null),b(null);try{b((await w.post(`notifications/test`)).attempted)}catch(e){v(S(e))}finally{g(!1)}};return i?(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`通知渠道`}),(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`})]}):o?(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`通知渠道`}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:o}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,className:`shrink-0`,onClick:()=>void x(),children:`重试`})]})]}):(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`通知渠道`}),(0,q.jsx)(`p`,{className:`mb-3 text-xs leading-relaxed text-muted-foreground`,children:`配置后端如何投递通知(桌面通知、ntfy、Bark),保存后对所有设备生效。`}),(0,q.jsxs)(`div`,{className:`space-y-4`,children:[(0,q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,q.jsx)(`div`,{className:`text-sm font-medium`,children:`桌面通知`}),(0,q.jsxs)(Ce,{value:n.desktopMode,onValueChange:e=>C({desktopMode:e}),children:[(0,q.jsx)(de,{className:`w-full`,children:(0,q.jsx)(z,{})}),(0,q.jsxs)(_e,{children:[(0,q.jsx)(V,{value:`auto`,children:`自动(独立运行时开启,Bodhi 内嵌时关闭)`}),(0,q.jsx)(V,{value:`on`,children:`开启`}),(0,q.jsx)(V,{value:`off`,children:`关闭`})]})]})]}),(0,q.jsxs)(`div`,{className:`space-y-2 border-t pt-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,q.jsx)(`div`,{className:`text-sm font-medium`,children:`ntfy`}),(0,q.jsx)(J,{checked:n.ntfyEnabled,onCheckedChange:e=>C({ntfyEnabled:e}),"aria-label":`启用 ntfy`})]}),(0,q.jsx)(wr,{label:`Base URL`,value:n.ntfyBaseUrl,onChange:e=>C({ntfyBaseUrl:e}),placeholder:xr}),(0,q.jsx)(wr,{label:`Topic`,value:n.ntfyTopic,onChange:e=>C({ntfyTopic:e}),placeholder:`my-bamboo-topic`}),(0,q.jsx)(wr,{label:`Token(可选,自托管实例)`,value:n.ntfyToken,onChange:e=>C({ntfyToken:e}),type:`password`,placeholder:T?`已配置,留空保持不变`:`公共 ntfy.sh 主题无需填写`})]}),(0,q.jsxs)(`div`,{className:`space-y-2 border-t pt-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,q.jsx)(`div`,{className:`text-sm font-medium`,children:`Bark`}),(0,q.jsx)(J,{checked:n.barkEnabled,onCheckedChange:e=>C({barkEnabled:e}),"aria-label":`启用 Bark`})]}),(0,q.jsx)(wr,{label:`Base URL`,value:n.barkBaseUrl,onChange:e=>C({barkBaseUrl:e}),placeholder:Sr}),(0,q.jsx)(wr,{label:`Device Key`,value:n.barkDeviceKey,onChange:e=>C({barkDeviceKey:e}),type:`password`,placeholder:E?`已配置,留空保持不变`:`iOS Bark app 中的设备密钥`})]}),d?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:d}):null,(0,q.jsxs)(`div`,{className:`flex items-end justify-between gap-2 border-t pt-3`,children:[(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:()=>void O(),disabled:h,children:h?`发送中…`:`测试通知渠道`}),y?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:y.length>0?`已尝试:${y.join(`, `)}`:`未启用任何渠道`}):null,_?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:_}):null]}),(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[p?(0,q.jsx)(`span`,{className:`text-xs text-emerald-500`,children:`已保存`}):null,(0,q.jsx)(s,{size:`sm`,onClick:()=>void D(),disabled:l,children:l?`保存中…`:`保存渠道设置`})]})]})]})]})}var Er=[{key:`onClarification`,label:`Agent 需要澄清时`},{key:`onToolApproval`,label:`工具执行需要批准时`},{key:`onContextPressure`,label:`上下文接近上限时`},{key:`onSubAgentComplete`,label:`后台子任务完成时`},{key:`onRunComplete`,label:`任务运行成功完成时`},{key:`onRunFailed`,label:`任务运行失败时`}];function Dr(){let[e,t]=(0,G.useState)(ae()),[n,r]=(0,G.useState)(B()),[i,o]=(0,G.useState)(null),[c,l]=(0,G.useState)(!0),[u,d]=(0,G.useState)(null),[f,p]=(0,G.useState)(null),m=async()=>{l(!0),d(null);try{o(await yr())}catch(e){d(e instanceof Error?e.message:`加载通知偏好失败`)}finally{l(!1)}};(0,G.useEffect)(()=>{m()},[]);let h=(e,t)=>{if(!i)return;let n=i,r={...i,[e]:t};o(r),p(null),br(r).then(e=>o(e)).catch(e=>{o(n),p(e instanceof Error?e.message:`保存通知偏好失败`)})},g=async()=>{if(!e){let e=await ge();if(r(B()),!e)return}let n=!e;t(n),ue(n)};return(0,q.jsxs)(`div`,{className:`space-y-4`,children:[(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`通知偏好(服务端)`}),(0,q.jsx)(`p`,{className:`mb-3 text-xs leading-relaxed text-muted-foreground`,children:`何时提醒由后端统一判定(分类、去重、偏好过滤)。以下设置保存在服务端,对所有设备生效。`}),c?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):u?(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:u}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,className:`shrink-0`,onClick:()=>void m(),children:`重试`})]}):i?(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,q.jsx)(`div`,{className:`text-sm`,children:`启用通知(总开关)`}),(0,q.jsx)(J,{checked:i.enabled,onCheckedChange:e=>h(`enabled`,e),"aria-label":`启用通知`})]}),(0,q.jsxs)(`div`,{className:a(`space-y-2.5 border-t pt-2.5`,!i.enabled&&`pointer-events-none opacity-50`),children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`在以下情况提醒:`}),Er.map(e=>(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,q.jsx)(`div`,{className:`text-sm`,children:e.label}),(0,q.jsx)(J,{checked:i[e.key],disabled:!i.enabled,onCheckedChange:t=>h(e.key,t),"aria-label":e.label})]},e.key))]}),f?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:f}):null]}):null]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`浏览器通知(本设备)`}),(0,q.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`text-sm font-medium`,children:`任务完成提醒`}),(0,q.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:`agent 任务在后台(标签页不可见或在看别的会话)完成时,通过浏览器通知提醒你。`})]}),(0,q.jsx)(J,{checked:e,onCheckedChange:()=>void g(),"aria-label":`任务完成提醒`,className:`mt-0.5`})]}),n===`denied`?(0,q.jsx)(`p`,{className:`mt-2 text-xs text-destructive`,children:`浏览器已拒绝通知权限,请在浏览器站点设置里允许。`}):n===`unsupported`?(0,q.jsx)(`p`,{className:`mt-2 text-xs text-muted-foreground`,children:`当前环境不支持通知。`}):null,e&&n===`granted`?(0,q.jsx)(s,{size:`sm`,variant:`secondary`,className:`mt-3`,onClick:()=>se(`Bodhi · 测试通知`,`通知工作正常 ✓`),children:`发送测试通知`}):null]}),(0,q.jsx)(Tr,{})]})}var Or=[`exact`,`regex`];function kr(){let[e,t]=(0,G.useState)([]),[n,r]=(0,G.useState)(!0),[i,a]=(0,G.useState)(``),[o,c]=(0,G.useState)(`exact`);(0,G.useEffect)(()=>{W.getKeywordMaskingConfig().then(e=>t(e.entries)).catch(()=>{}).finally(()=>r(!1))},[]);let l=async e=>{t(e);try{t((await W.updateKeywordMaskingConfig(e)).entries)}catch{}},u=()=>{i.trim()&&(l([...e,{pattern:i.trim(),match_type:o,enabled:!0}]),a(``))},[d,f]=(0,G.useState)(``),p=(0,G.useMemo)(()=>{let t=d;for(let n of e)if(!(!n.enabled||!n.pattern))try{t=n.match_type===`regex`?t.replace(new RegExp(n.pattern,`g`),`***`):t.split(n.pattern).join(`***`)}catch{}return t},[d,e]);return(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:`匹配的内容会在发往模型 / 日志前被掩码,避免密钥等敏感信息外泄。`}),(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`新增规则`}),(0,q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,q.jsx)(C,{className:`flex-1`,placeholder:`要掩码的内容 / 模式`,value:i,onChange:e=>a(e.target.value),onKeyDown:e=>{e.key===`Enter`&&u()}}),(0,q.jsxs)(Ce,{value:o,onValueChange:c,children:[(0,q.jsx)(de,{className:`w-28 shrink-0`,children:(0,q.jsx)(z,{})}),(0,q.jsx)(_e,{children:Or.map(e=>(0,q.jsx)(V,{value:e,children:e},e))})]}),(0,q.jsx)(s,{size:`sm`,onClick:u,disabled:!i.trim(),children:(0,q.jsx)(_,{className:`size-4`})})]})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:[`掩码规则 (`,e.length,`)`]}),n?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无`}):(0,q.jsx)(`ul`,{className:`space-y-1.5`,children:e.map((t,n)=>(0,q.jsxs)(`li`,{className:`flex items-center gap-2 rounded-md bg-muted/40 px-2.5 py-1.5`,children:[(0,q.jsx)(J,{checked:t.enabled,onCheckedChange:()=>void l(e.map((e,t)=>t===n?{...e,enabled:!e.enabled}:e)),"aria-label":`启用规则`}),(0,q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-xs`,children:t.pattern}),(0,q.jsx)(`span`,{className:`shrink-0 rounded bg-muted px-1 text-[10px] text-muted-foreground`,children:t.match_type}),(0,q.jsx)(`button`,{onClick:()=>void l(e.filter((e,t)=>t!==n)),"aria-label":`删除`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(v,{className:`size-3.5`})})]},`${t.pattern}-${n}`))})]}),(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`预览`}),(0,q.jsx)(he,{className:`min-h-16 resize-y rounded-md border px-2.5 py-1.5 text-sm`,placeholder:`输入一段文本,看看掩码后的效果…`,value:d,onChange:e=>f(e.target.value)}),d?(0,q.jsx)(`div`,{className:`rounded-md bg-muted/40 p-2.5 text-sm [overflow-wrap:anywhere]`,children:p}):null]})]})}function Ar({label:e,description:t,checked:n,onCheckedChange:r}){return(0,q.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,q.jsxs)(`div`,{className:`min-w-0`,children:[(0,q.jsx)(`div`,{className:`text-sm font-medium`,children:e}),t?(0,q.jsx)(`p`,{className:`mt-0.5 text-xs leading-relaxed text-muted-foreground`,children:t}):null]}),(0,q.jsx)(J,{checked:n,onCheckedChange:r,"aria-label":e,className:`mt-0.5 shrink-0`})]})}function jr(){let e=Se(e=>e.systemPrompts),t=Se(e=>e.addSystemPrompt),n=Se(e=>e.updateSystemPrompt),r=Se(e=>e.deleteSystemPrompt),i=U(e=>{let t=e.providerSnapshot?.defaults?.chat.provider;return t?e.getProviderType(t)===`copilot`:!1}),[a,o]=(0,G.useState)(!1),[c,u]=(0,G.useState)(null),[d,p]=(0,G.useState)(``),[h,g]=(0,G.useState)(``),[b,w]=(0,G.useState)(!1),[D,k]=(0,G.useState)(null),[A,j]=(0,G.useState)(null),P=e=>{u(e),p(e?.name??``),g(e?.content??``),k(null),o(!0)},F=()=>{o(!1),u(null),p(``),g(``),k(null)},ee=async()=>{if(!(!d.trim()||!h.trim())){w(!0),k(null);try{c?await n({...c,name:d.trim(),content:h}):await t({name:d.trim(),content:h}),F()}catch(e){k(S(e))}finally{w(!1)}}},I=async e=>{j(null);try{await r(e.id)}catch(t){j(`删除「${e.name}」失败:${S(t)}`)}},[L,te]=(0,G.useState)(()=>M()),[R,ne]=(0,G.useState)(!1),z=()=>{Te(L),ne(!0),setTimeout(()=>ne(!1),2e3)},[re,ie]=(0,G.useState)(()=>pe()),[ae,oe]=(0,G.useState)(()=>f()),[se,ce]=(0,G.useState)(()=>N());return(0,q.jsxs)(`div`,{className:`space-y-4`,children:[(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`mb-2 flex items-center justify-between`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`系统提示词预设`}),(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,onClick:()=>P(null),children:[(0,q.jsx)(_,{className:`size-4`}),` 新增`]})]}),A?(0,q.jsx)(`p`,{className:`mb-2 text-xs text-destructive`,children:A}):null,e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无预设`}):(0,q.jsx)(`ul`,{className:`space-y-2`,children:e.map(e=>(0,q.jsxs)(`li`,{className:`flex items-center gap-2 rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(`span`,{className:`truncate text-sm font-medium`,children:e.name}),e.isDefault?(0,q.jsx)(H,{variant:`secondary`,className:`shrink-0 text-[10px]`,children:`默认`}):null]}),(0,q.jsx)(`div`,{className:`truncate text-xs text-muted-foreground`,children:e.description||e.content.slice(0,120)})]}),e.isDefault?null:(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`button`,{onClick:()=>P(e),"aria-label":`编辑`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-foreground`,children:(0,q.jsx)(x,{className:`size-3.5`})}),(0,q.jsx)(`button`,{onClick:()=>void I(e),"aria-label":`删除`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(v,{className:`size-3.5`})})]})]},e.id))})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`提示词增强`}),(0,q.jsx)(`p`,{className:`mb-2 text-xs leading-relaxed text-muted-foreground`,children:`追加到系统提示词末尾的自定义内容,对所有会话生效。`}),(0,q.jsx)(he,{className:`min-h-24 resize-y text-sm`,placeholder:`输入要追加的增强内容…`,value:L,onChange:e=>te(e.target.value)}),(0,q.jsxs)(`div`,{className:`mt-2 flex items-center justify-end gap-2`,children:[R?(0,q.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`已保存`}):null,(0,q.jsx)(s,{size:`sm`,onClick:z,children:`保存`})]})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`增强开关`}),(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsx)(Ar,{label:`Mermaid 图表增强`,description:`引导模型在解释流程、架构时输出 Mermaid 图表。`,checked:re,onCheckedChange:e=>{ie(e),l(e)}}),(0,q.jsx)(Ar,{label:`任务列表规则`,description:`引导模型用 Task 工具管理多步任务进度。`,checked:ae,onCheckedChange:e=>{oe(e),E(e)}}),i?(0,q.jsx)(Ar,{label:`Copilot 结束前确认`,description:`要求 Copilot 会话结束前必须调用 conclusion_with_options 工具向你确认,否则视为未完成。`,checked:se,onCheckedChange:e=>{ce(e),m(e)}}):null]})]}),(0,q.jsx)(T,{open:a,onOpenChange:e=>{e||F()},children:(0,q.jsxs)(O,{className:`p-5 sm:max-w-lg`,children:[(0,q.jsx)(y,{children:c?`编辑预设`:`新增预设`}),(0,q.jsxs)(`div`,{className:`mt-3 space-y-2.5`,children:[(0,q.jsx)(C,{placeholder:`名称`,value:d,onChange:e=>p(e.target.value)}),(0,q.jsx)(he,{className:`min-h-40 resize-y text-sm`,placeholder:`提示词内容`,value:h,onChange:e=>g(e.target.value)}),D?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:D}):null,(0,q.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:F,children:`取消`}),(0,q.jsx)(s,{size:`sm`,onClick:()=>void ee(),disabled:b||!d.trim()||!h.trim(),children:b?`保存中…`:`保存`})]})]})]})})]})}function Mr(e){if(!e||e.trim()!==e||e.length>255||e.includes(`/`)||e.includes(`\\`)||e.includes(`..`))return!1;for(let t of e){let e=t.charCodeAt(0);if(e<32||e===127)return!1}return!0}function Nr(){let[e,t]=(0,G.useState)([]),[n,r]=(0,G.useState)(!0),[i,o]=(0,G.useState)(null),[c,l]=(0,G.useState)(null),[u,d]=(0,G.useState)(!1),[f,p]=(0,G.useState)(``),[m,h]=(0,G.useState)(``),[g,y]=(0,G.useState)(!1),b=(0,G.useRef)(0),[x,w]=(0,G.useState)(!1),[T,E]=(0,G.useState)(!1),[D,O]=(0,G.useState)(null),[k,A]=(0,G.useState)(!1),j=(0,G.useCallback)(async()=>{r(!0),o(null);try{let e=((await ie.listCommands()).commands??[]).filter(e=>e.type===`workflow`).sort((e,t)=>e.name.localeCompare(t.name));return t(e),e}catch(e){return o(`加载 workflow 列表失败:${S(e)}`),[]}finally{r(!1)}},[]);(0,G.useEffect)(()=>{j()},[j]);let M=()=>{l(null),d(!1),p(``),h(``),E(!1),O(null)},N=()=>{M(),d(!0)},P=async e=>{d(!1),l(e),p(e),h(``),E(!1),O(null),y(!0);let t=++b.current;try{let n=await ie.getWorkflowCommand(e);if(b.current!==t)return;h(n.content??``)}catch(e){if(b.current!==t)return;O(`加载内容失败:${S(e)}`)}finally{b.current===t&&y(!1)}},F=async()=>{let t=f.trim();if(O(null),!Mr(t)){O(`名称无效:不能为空,且不能包含 /、\\ 或 ..`);return}if(u&&e.some(e=>e.name===t)){O(`已存在同名 workflow「${t}」`);return}w(!0);try{await W.saveWorkflow(t,m),E(!1),d(!1),l(t),A(!0),setTimeout(()=>A(!1),2e3),await j()}catch(e){O(`保存失败:${S(e)}`)}finally{w(!1)}},ee=async e=>{o(null);try{await W.deleteWorkflow(e),c===e&&M(),await j()}catch(t){o(`删除「${e}」失败:${S(t)}`)}},I=u||c!==null;return(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Markdown workflow,可在聊天中以 /名称 调用。`}),(0,q.jsxs)(`div`,{className:`flex shrink-0 gap-1.5`,children:[(0,q.jsx)(s,{size:`sm`,variant:`ghost`,onClick:()=>void j(),"aria-label":`刷新`,children:(0,q.jsx)(Me,{className:a(`size-4`,n&&`animate-spin`)})}),(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,onClick:N,children:[(0,q.jsx)(_,{className:`size-4`}),` 新增`]})]})]}),i?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:i}):null,I?(0,q.jsxs)(`div`,{className:`space-y-2.5 rounded-lg border bg-muted/30 p-3`,children:[(0,q.jsx)(C,{placeholder:`名称(不含 .md 后缀)`,value:f,disabled:!u,onChange:e=>{p(e.target.value),E(!0)}}),(0,q.jsx)(he,{className:`min-h-48 resize-y font-mono text-xs`,placeholder:g?`加载中…`:`Markdown 内容`,value:m,disabled:g,onChange:e=>{h(e.target.value),E(!0)}}),D?(0,q.jsx)(`p`,{className:`text-xs text-destructive`,children:D}):null,(0,q.jsxs)(`div`,{className:`flex items-center justify-end gap-2`,children:[k?(0,q.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`已保存`}):null,(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:M,children:`关闭`}),(0,q.jsx)(s,{size:`sm`,onClick:()=>void F(),disabled:x||!T||!f.trim(),children:x?`保存中…`:`保存`})]})]}):null,n&&e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无 workflow`}):(0,q.jsx)(`ul`,{className:`space-y-2`,children:e.map(e=>{let t=typeof e.metadata?.filename==`string`?e.metadata.filename:`${e.name}.md`;return(0,q.jsxs)(`li`,{className:a(`flex cursor-pointer items-center gap-2 rounded-lg border p-3`,c===e.name&&`border-primary/50 bg-muted/40`),onClick:()=>void P(e.name),children:[(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsxs)(`div`,{className:`truncate text-sm font-medium`,children:[`/`,e.name]}),(0,q.jsx)(`div`,{className:`truncate text-xs text-muted-foreground`,children:t})]}),(0,q.jsx)(`button`,{onClick:t=>{t.stopPropagation(),ee(e.name)},"aria-label":`删除`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(v,{className:`size-3.5`})})]},e.id)})})]})}var Pr=`****...****`,Fr=3e4,Ir={not_deployed:{label:`未部署`,cls:`bg-muted text-muted-foreground`},deploying:{label:`部署中`,cls:`animate-pulse bg-blue-500/15 text-blue-600 dark:text-blue-400`},running:{label:`运行中`,cls:`bg-primary/15 text-primary`},unreachable:{label:`不可达`,cls:`bg-amber-500/15 text-amber-600 dark:text-amber-400`},stopped:{label:`已停止`,cls:`bg-muted text-muted-foreground`},failed:{label:`失败`,cls:`bg-destructive/15 text-destructive`}},Lr={test:`测试`,deploy:`部署`,stop:`停止`},Rr={test:`连接成功`,deploy:`部署已触发`,stop:`停止已触发`};function zr(e){if(!e)return``;let t=new Date(e).getTime();if(Number.isNaN(t))return``;let n=Math.max(0,Math.floor((Date.now()-t)/1e3));if(n<60)return`${n}秒前`;let r=Math.floor(n/60);if(r<60)return`${r}分钟前`;let i=Math.floor(r/60);return i<24?`${i}小时前`:`${Math.floor(i/24)}天前`}function Br(e,t){return e instanceof Error&&e.message?e.message:t}function Vr(e){return e.placement.type===`ssh`?`${e.placement.username}@${e.placement.host}:${e.placement.port}`:`本机`}var Hr={label:``,placementType:`ssh`,host:``,port:`22`,username:``,authMethod:`password`,password:``,privateKey:``,privateKeyPath:``,passphrase:``,trustLevel:`trusted`,artifactPath:``,remoteDir:``,defaultRole:``,model:``,workspace:``,autoRecover:!1,enabled:!0};function Ur(){let[e,t]=(0,G.useState)([]),[n,r]=(0,G.useState)([]),[i,o]=(0,G.useState)(!0),[l,u]=(0,G.useState)(null),[d,f]=(0,G.useState)(null),p=(0,G.useRef)(null),m=(0,G.useCallback)((e,t)=>{f({kind:e,text:t}),p.current&&window.clearTimeout(p.current),e===`ok`&&(p.current=window.setTimeout(()=>f(null),4e3))},[]);(0,G.useEffect)(()=>()=>{p.current&&window.clearTimeout(p.current)},[]);let[h,g]=(0,G.useState)(!1),[b,S]=(0,G.useState)(null),[w,E]=(0,G.useState)(Hr),[k,j]=(0,G.useState)(null),[M,N]=(0,G.useState)(!1),[P,I]=(0,G.useState)(!1),[L,te]=(0,G.useState)(null),[ne,re]=(0,G.useState)(``),[ie,ae]=(0,G.useState)(!1),[oe,se]=(0,G.useState)(!1),[ce,le]=(0,G.useState)(null),[ue,fe]=(0,G.useState)(``),[pe,me]=(0,G.useState)(``),[ge,ve]=(0,G.useState)([]),[ye,B]=(0,G.useState)(null),[xe,Se]=(0,G.useState)(!1),[we,Te]=(0,G.useState)(null),[U,Ee]=(0,G.useState)(null),[De,W]=(0,G.useState)(null),[Oe,ke]=(0,G.useState)(null),Ae=(0,G.useRef)(0),je=(0,G.useCallback)(async(e=!1)=>{let n=++Ae.current;e||o(!0);try{let e=await D.listNodes();if(n!==Ae.current)return;t(e.nodes??[]),r(e.clusters??[]),u(null)}catch(t){n===Ae.current&&!e&&u(Br(t,`加载集群配置失败`))}finally{e||o(!1)}},[]);(0,G.useEffect)(()=>{je()},[je]);let Ne=h||P||oe;(0,G.useEffect)(()=>{let e=()=>{document.visibilityState===`visible`&&!Ne&&je(!0)},t=window.setInterval(e,Fr);return document.addEventListener(`visibilitychange`,e),()=>{window.clearInterval(t),document.removeEventListener(`visibilitychange`,e)}},[je,Ne]);let Pe=(0,G.useMemo)(()=>{let e=new Map;for(let t of n)for(let n of t.node_ids)e.has(n)||e.set(n,t.name);return e},[n]),Fe=()=>{S(null),E({...Hr}),j(null),g(!0)},Ie=e=>{let t=e.placement.type===`ssh`?e.placement:void 0,n=t?.auth;S(e.id),E({label:e.label,placementType:e.placement.type,host:t?.host??``,port:String(t?.port??22),username:t?.username??``,authMethod:n?.method??`password`,password:``,privateKey:``,privateKeyPath:n?.method===`private_key`?n.private_key_path??``:``,passphrase:``,trustLevel:e.trust_level??`trusted`,artifactPath:e.deploy?.artifact_path??``,remoteDir:e.deploy?.remote_dir??``,defaultRole:e.deploy?.default_role??``,model:e.deploy?.model??``,workspace:e.deploy?.workspace??``,autoRecover:e.deploy?.auto_recover??!1,enabled:e.enabled}),j(null),g(!0)},Le=()=>{g(!1),S(null),j(null)},K=(e,t)=>E(n=>({...n,[e]:t})),Re=b?e.find(e=>e.id===b):void 0,ze=Re?.placement.type===`ssh`?Re.placement.auth:void 0,Be=e=>{if(!e.label.trim())return`名称不能为空`;if(e.placementType===`ssh`){if(!e.host.trim())return`主机不能为空`;if(!e.username.trim())return`用户名不能为空`;let t=Number(e.port);if(!Number.isInteger(t)||t<1||t>65535)return`端口必须是 1-65535`;if(e.authMethod===`password`){let t=ze?.method===`password`&&!!ze.password;if(!e.password&&!t)return`密码不能为空`}if(e.authMethod===`private_key`){let t=!!(e.privateKey.trim()||e.privateKeyPath.trim()),n=ze?.method===`private_key`&&!!(ze.private_key||ze.private_key_path);if(!t&&!n)return`需要提供私钥内容或私钥文件路径`}}return null},Ve=e=>{if(e.placementType===`local`)return{type:`local`};let t=ze,n=(e,t)=>!!e&&!t,r;if(e.authMethod===`system_ssh_config`)r={method:`system_ssh_config`};else if(e.authMethod===`private_key`){let i=t?.method===`private_key`?t.private_key:void 0,a=t?.method===`private_key`?t.passphrase:void 0;r={method:`private_key`,private_key:n(i,e.privateKey)?Pr:e.privateKey||void 0,private_key_path:e.privateKeyPath.trim()||void 0,passphrase:n(a,e.passphrase)?Pr:e.passphrase||void 0}}else r={method:`password`,password:n(t?.method===`password`?t.password:void 0,e.password)?Pr:e.password};return{type:`ssh`,host:e.host.trim(),port:Number(e.port)||22,username:e.username.trim(),auth:r}},He=async()=>{let e=Be(w);if(e){j(e);return}let t={label:w.label.trim(),placement:Ve(w),trust_level:w.trustLevel,enabled:w.enabled,deploy:{artifact_path:w.artifactPath.trim()||void 0,artifact_sha256:Re?.deploy?.artifact_sha256,remote_dir:w.remoteDir.trim()||void 0,default_role:w.defaultRole.trim()||void 0,model:w.model.trim()||void 0,workspace:w.workspace.trim()||void 0,auto_recover:w.autoRecover}};N(!0),j(null);try{b?await D.updateNode(b,t):await D.createNode(t),m(`ok`,b?`节点已更新`:`节点已创建`),Le(),je()}catch(e){j(Br(e,`保存节点失败`))}finally{N(!1)}},Ue=async e=>{Ee(e.id);try{await D.updateNode(e.id,{label:e.label,placement:e.placement,trust_level:e.trust_level,deploy:e.deploy,enabled:!e.enabled}),je(!0)}catch(e){m(`err`,`切换启用状态失败:${Br(e,`未知错误`)}`)}finally{Ee(null)}},We=async e=>{try{await D.deleteNode(e),m(`ok`,`节点已删除`),je(!0)}catch(e){m(`err`,`删除节点失败:${Br(e,`未知错误`)}`)}finally{W(null)}},Ge=async(e,t)=>{Te({id:e.id,action:t});try{let n=await D.nodeAction(e.id,t),r=t===`test`&&n&&typeof n==`object`&&`preflight`in n?String(n.preflight??``):``;m(`ok`,r?`连接成功:${r}`:Rr[t]),je(!0)}catch(e){m(`err`,`${Lr[t]}失败:${Br(e,`未知错误`)}`)}finally{Te(null)}},Ke=async e=>{te(e),I(!0),ae(!0),re(``);try{re((await D.nodeLogs(e.id,200)).logs||`(暂无日志输出)`)}catch(e){re(Br(e,`读取日志失败`))}finally{ae(!1)}},qe=()=>{le(null),fe(``),me(``),ve([]),B(null),se(!0)},Je=e=>{le(e.name),fe(e.name),me(e.description??``),ve([...e.node_ids]),B(null),se(!0)},Ye=()=>{se(!1),le(null),B(null)},Xe=e=>ve(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e]),Ze=async()=>{let e=ue.trim();if(!e){B(`集群名称不能为空`);return}Se(!0),B(null);try{let t={name:e,description:pe.trim()||void 0,node_ids:ge};ce?await D.updateCluster(ce,t):await D.createCluster(t),m(`ok`,`集群已保存`),Ye(),je()}catch(e){B(`保存集群失败(成员关系未生效):${Br(e,`未知错误`)}`)}finally{Se(!1)}},Qe=async e=>{try{await D.deleteCluster(e),m(`ok`,`集群已删除(成员节点保留)`),je(!0)}catch(e){m(`err`,`删除集群失败:${Br(e,`未知错误`)}`)}finally{ke(null)}},$e=w.placementType===`ssh`;return(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`注册本机或 SSH 远程机器,用于部署 worker 代理。SSH 凭据由后端加密存储,不会明文返回。`}),d?(0,q.jsxs)(`div`,{className:a(`flex items-start gap-2 rounded-md border px-3 py-2 text-xs`,d.kind===`err`?`border-destructive/30 bg-destructive/10 text-destructive`:`border-primary/30 bg-primary/10 text-primary`),children:[(0,q.jsx)(`span`,{className:`min-w-0 flex-1 [overflow-wrap:anywhere]`,children:d.text}),(0,q.jsx)(`button`,{onClick:()=>f(null),"aria-label":`关闭提示`,className:`shrink-0 opacity-70 hover:opacity-100`,children:(0,q.jsx)(ee,{className:`size-3.5`})})]}):null,l?(0,q.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive`,children:[(0,q.jsx)(c,{className:`size-3.5 shrink-0`}),(0,q.jsx)(`span`,{className:`min-w-0 flex-1`,children:l}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,className:`h-7 px-2 text-xs`,onClick:()=>void je(),children:`重试`})]}):null,(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`mb-2 flex items-center justify-between`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`节点`}),(0,q.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(s,{size:`sm`,variant:`ghost`,className:`h-7 px-2`,"aria-label":`刷新`,onClick:()=>void je(),children:(0,q.jsx)(Me,{className:a(`size-3.5`,i&&`animate-spin`)})}),(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,className:`h-7 px-2 text-xs`,onClick:Fe,children:[(0,q.jsx)(_,{className:`size-3.5`}),` 新增节点`]})]})]}),i&&e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无节点`}):(0,q.jsx)(`ul`,{className:`space-y-2`,children:e.map(e=>{let t=e.state?.status??`not_deployed`,n=Ir[t],r=e.state?.last_error,i=zr(e.state?.last_health),o=Pe.get(e.id),c=we?.id===e.id;return(0,q.jsxs)(`li`,{className:`space-y-1.5 rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[e.placement.type===`ssh`?(0,q.jsx)(F,{className:`size-3.5 shrink-0 text-muted-foreground`}):(0,q.jsx)(be,{className:`size-3.5 shrink-0 text-muted-foreground`}),(0,q.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-sm font-medium`,children:e.label}),(0,q.jsx)(H,{variant:`outline`,className:a(`border-transparent`,n.cls),title:r&&(t===`unreachable`||t===`failed`)?r:void 0,children:n.label}),(0,q.jsx)(J,{checked:e.enabled,disabled:U===e.id,onCheckedChange:()=>void Ue(e),"aria-label":e.enabled?`停用节点`:`启用节点`})]}),(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground`,children:[(0,q.jsx)(`span`,{className:`font-mono`,children:Vr(e)}),o?(0,q.jsx)(H,{variant:`outline`,className:`h-4 px-1.5 text-[10px]`,children:o}):null,e.trust_level===`untrusted`?(0,q.jsx)(H,{variant:`warning`,className:`h-4 px-1.5 text-[10px]`,children:`不受信任`}):null,e.enabled?null:(0,q.jsx)(`span`,{children:`已停用`}),i?(0,q.jsxs)(`span`,{children:[`活跃于 `,i]}):null]}),r&&(t===`unreachable`||t===`failed`)?(0,q.jsx)(`p`,{className:`truncate text-xs text-destructive`,title:r,children:r}):null,(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5 pt-0.5`,children:[[`test`,`deploy`,`stop`].map(t=>(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,className:`h-7 px-2 text-xs`,disabled:c,onClick:()=>void Ge(e,t),children:[c&&we?.action===t?(0,q.jsx)(A,{className:`size-3 animate-spin`}):null,Lr[t]]},t)),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,className:`h-7 px-2 text-xs`,onClick:()=>void Ke(e),children:`日志`}),(0,q.jsx)(`div`,{className:`ml-auto flex items-center gap-1`,children:De===e.id?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`span`,{className:`text-xs text-destructive`,children:`确认删除?`}),(0,q.jsx)(s,{size:`sm`,variant:`destructive`,className:`h-7 px-2 text-xs`,onClick:()=>void We(e.id),children:`删除`}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,className:`h-7 px-2 text-xs`,onClick:()=>W(null),children:`取消`})]}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`button`,{onClick:()=>Ie(e),"aria-label":`编辑节点`,className:`rounded p-1 text-muted-foreground hover:text-foreground`,children:(0,q.jsx)(x,{className:`size-3.5`})}),(0,q.jsx)(`button`,{onClick:()=>W(e.id),"aria-label":`删除节点`,className:`rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(v,{className:`size-3.5`})})]})})]})]},e.id)})})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`mb-2 flex items-center justify-between`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`集群`}),(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,className:`h-7 px-2 text-xs`,onClick:qe,children:[(0,q.jsx)(_,{className:`size-3.5`}),` 新增集群`]})]}),n.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无集群`}):(0,q.jsx)(`ul`,{className:`space-y-2`,children:n.map(t=>{let n=t.node_ids.map(t=>e.find(e=>e.id===t)?.label??t).join(`、`);return(0,q.jsxs)(`li`,{className:`flex items-center gap-2 rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsx)(`div`,{className:`truncate text-sm font-medium`,children:t.name}),(0,q.jsxs)(`div`,{className:`truncate text-xs text-muted-foreground`,children:[t.node_ids.length,` 个节点`,n?` · ${n}`:``,t.description?` · ${t.description}`:``]})]}),Oe===t.name?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`span`,{className:`shrink-0 text-xs text-destructive`,children:`确认删除?`}),(0,q.jsx)(s,{size:`sm`,variant:`destructive`,className:`h-7 shrink-0 px-2 text-xs`,onClick:()=>void Qe(t.name),children:`删除`}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,className:`h-7 shrink-0 px-2 text-xs`,onClick:()=>ke(null),children:`取消`})]}):(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`button`,{onClick:()=>Je(t),"aria-label":`编辑集群`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-foreground`,children:(0,q.jsx)(x,{className:`size-3.5`})}),(0,q.jsx)(`button`,{onClick:()=>ke(t.name),"aria-label":`删除集群`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(v,{className:`size-3.5`})})]})]},t.name)})})]}),(0,q.jsx)(T,{open:h,onOpenChange:e=>{e||Le()},children:(0,q.jsxs)(O,{className:`p-5 sm:max-w-lg`,children:[(0,q.jsx)(y,{children:b?`编辑节点`:`新增节点`}),(0,q.jsxs)(`div`,{className:`mt-3 min-h-0 flex-1 space-y-3 overflow-y-auto pr-1`,children:[(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`名称`}),(0,q.jsx)(C,{value:w.label,onChange:e=>K(`label`,e.target.value),placeholder:`gpu-1`})]}),(0,q.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`部署位置`}),(0,q.jsxs)(Ce,{value:w.placementType,onValueChange:e=>K(`placementType`,e),children:[(0,q.jsx)(de,{className:`w-full`,children:(0,q.jsx)(z,{})}),(0,q.jsxs)(_e,{children:[(0,q.jsx)(V,{value:`ssh`,children:`SSH(远程)`}),(0,q.jsx)(V,{value:`local`,children:`本机`})]})]})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`信任级别`}),(0,q.jsxs)(Ce,{value:w.trustLevel,onValueChange:e=>K(`trustLevel`,e),children:[(0,q.jsx)(de,{className:`w-full`,children:(0,q.jsx)(z,{})}),(0,q.jsxs)(_e,{children:[(0,q.jsx)(V,{value:`trusted`,children:`受信任`}),(0,q.jsx)(V,{value:`untrusted`,children:`不受信任`})]})]})]})]}),$e?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`div`,{className:`grid grid-cols-[1fr_6rem] gap-2`,children:[(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`主机`}),(0,q.jsx)(C,{value:w.host,onChange:e=>K(`host`,e.target.value),placeholder:`10.0.0.5`})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`端口`}),(0,q.jsx)(C,{inputMode:`numeric`,value:w.port,onChange:e=>K(`port`,e.target.value),placeholder:`22`})]})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`用户名`}),(0,q.jsx)(C,{value:w.username,onChange:e=>K(`username`,e.target.value),placeholder:`deploy`})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`认证方式`}),(0,q.jsxs)(Ce,{value:w.authMethod,onValueChange:e=>K(`authMethod`,e),children:[(0,q.jsx)(de,{className:`w-full`,children:(0,q.jsx)(z,{})}),(0,q.jsxs)(_e,{children:[(0,q.jsx)(V,{value:`password`,children:`密码`}),(0,q.jsx)(V,{value:`private_key`,children:`私钥`}),(0,q.jsx)(V,{value:`system_ssh_config`,children:`使用本机 SSH 配置`})]})]})]}),w.authMethod===`password`?(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`密码`}),(0,q.jsx)(C,{type:`password`,value:w.password,onChange:e=>K(`password`,e.target.value),placeholder:ze?.method===`password`?`留空保持原有密码`:void 0})]}):null,w.authMethod===`private_key`?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`私钥文件路径(本机)`}),(0,q.jsx)(C,{value:w.privateKeyPath,onChange:e=>K(`privateKeyPath`,e.target.value),placeholder:`~/.ssh/id_ed25519`})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`…或粘贴私钥(PEM)`}),(0,q.jsx)(he,{className:`min-h-16 resize-y font-mono text-xs`,value:w.privateKey,onChange:e=>K(`privateKey`,e.target.value),placeholder:ze?.method===`private_key`?`留空保持原有私钥`:`-----BEGIN OPENSSH PRIVATE KEY-----`})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`私钥口令(可选)`}),(0,q.jsx)(C,{type:`password`,value:w.passphrase,onChange:e=>K(`passphrase`,e.target.value),placeholder:ze?.method===`private_key`?`留空保持原有口令`:void 0})]})]}):null]}):null,(0,q.jsxs)(`div`,{className:`space-y-2.5 rounded-lg border bg-muted/30 p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`部署配置`}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`Artifact 路径(要上传的 bamboo 二进制)`}),(0,q.jsx)(C,{value:w.artifactPath,onChange:e=>K(`artifactPath`,e.target.value),placeholder:`/path/to/bamboo-linux-x64`})]}),(0,q.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`远程目录`}),(0,q.jsx)(C,{value:w.remoteDir,onChange:e=>K(`remoteDir`,e.target.value),placeholder:`~/.bamboo-worker`})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`默认角色`}),(0,q.jsx)(C,{value:w.defaultRole,onChange:e=>K(`defaultRole`,e.target.value),placeholder:`worker`})]})]}),(0,q.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`模型`}),(0,q.jsx)(C,{value:w.model,onChange:e=>K(`model`,e.target.value),placeholder:`默认`})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`工作目录`}),(0,q.jsx)(C,{value:w.workspace,onChange:e=>K(`workspace`,e.target.value),placeholder:`默认`})]})]}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`text-xs font-medium`,children:`自动恢复`}),(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`健康检查发现 worker 掉线时自动重新部署。`})]}),(0,q.jsx)(J,{checked:w.autoRecover,onCheckedChange:e=>K(`autoRecover`,e),"aria-label":`自动恢复`})]})]}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium`,children:`启用`}),(0,q.jsx)(J,{checked:w.enabled,onCheckedChange:e=>K(`enabled`,e),"aria-label":`启用节点`})]})]}),k?(0,q.jsx)(`p`,{className:`mt-2 text-xs text-destructive`,children:k}):null,(0,q.jsxs)(`div`,{className:`mt-4 flex justify-end gap-2`,children:[(0,q.jsx)(s,{variant:`secondary`,onClick:Le,children:`取消`}),(0,q.jsx)(s,{onClick:()=>void He(),disabled:M,children:M?`保存中…`:`保存`})]})]})}),(0,q.jsx)(T,{open:P,onOpenChange:e=>{e||I(!1)},children:(0,q.jsxs)(O,{className:`p-5 sm:max-w-2xl`,children:[(0,q.jsxs)(y,{children:[`日志 — `,L?.label??``]}),(0,q.jsx)(`div`,{className:`mt-3 max-h-[50vh] min-h-24 flex-1 overflow-auto rounded-md border bg-muted/30 p-2`,children:ie?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):(0,q.jsx)(`pre`,{className:`font-mono text-xs leading-relaxed whitespace-pre-wrap [overflow-wrap:anywhere]`,children:ne})}),(0,q.jsxs)(`div`,{className:`mt-3 flex justify-end gap-2`,children:[(0,q.jsx)(s,{variant:`secondary`,onClick:()=>I(!1),children:`关闭`}),(0,q.jsx)(s,{disabled:ie,onClick:()=>{L&&Ke(L)},children:`刷新`})]})]})}),(0,q.jsx)(T,{open:oe,onOpenChange:e=>{e||Ye()},children:(0,q.jsxs)(O,{className:`p-5`,children:[(0,q.jsx)(y,{children:ce?`编辑集群`:`新增集群`}),(0,q.jsxs)(`div`,{className:`mt-3 min-h-0 flex-1 space-y-3 overflow-y-auto pr-1`,children:[(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`名称`}),(0,q.jsx)(C,{value:ue,disabled:!!ce,onChange:e=>fe(e.target.value),placeholder:`gpu-pool`})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`描述(可选)`}),(0,q.jsx)(C,{value:pe,onChange:e=>me(e.target.value),placeholder:`用途说明`})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(X,{className:`text-xs`,children:`成员节点`}),e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无节点,请先新增节点`}):(0,q.jsx)(`div`,{className:`space-y-1.5`,children:e.map(e=>{let t=ge.includes(e.id);return(0,q.jsxs)(`button`,{type:`button`,onClick:()=>Xe(e.id),className:a(`flex w-full items-center gap-2 rounded-md border px-2.5 py-1.5 text-left text-sm transition-colors`,t?`border-primary/50 bg-primary/5`:`hover:bg-accent/50`),children:[(0,q.jsx)(`span`,{className:a(`flex size-4 shrink-0 items-center justify-center rounded border`,t?`border-primary bg-primary text-primary-foreground`:`border-muted-foreground/40`),children:t?(0,q.jsx)(R,{className:`size-3`}):null}),(0,q.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:e.label}),(0,q.jsx)(`span`,{className:`shrink-0 font-mono text-xs text-muted-foreground`,children:Vr(e)})]},e.id)})})]})]}),ye?(0,q.jsx)(`p`,{className:`mt-2 text-xs text-destructive`,children:ye}):null,(0,q.jsxs)(`div`,{className:`mt-4 flex justify-end gap-2`,children:[(0,q.jsx)(s,{variant:`secondary`,onClick:Ye,children:`取消`}),(0,q.jsx)(s,{onClick:()=>void Ze(),disabled:xe,children:xe?`保存中…`:`保存`})]})]})})]})}function Wr({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`skeleton`,className:a(`bg-accent animate-pulse rounded-md`,e),...t})}var Gr=new Intl.NumberFormat(`en`,{notation:`compact`,maximumFractionDigits:1}),Kr=new Intl.NumberFormat(`en-US`);function Z(e){return e==null||Number.isNaN(e)?`0`:Gr.format(e)}function Q(e){return e==null||Number.isNaN(e)?`0`:Kr.format(e)}function qr(e){return e==null||Number.isNaN(e)?`0%`:`${e.toFixed(1)}%`}function Jr(e){if(!e||e<=0)return`-`;let t=Math.floor(e/1e3),n=Math.floor(t/60),r=t%60;return n>=60?`${Math.floor(n/60)}h ${n%60}m`:n>0?`${n}m ${r}s`:`${r}s`}function Yr(e){if(!e)return`-`;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(`zh-CN`,{month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`})}function Xr(e){let t=/^\d{4}-(\d{2}-\d{2})$/.exec(e);return t?t[1]:e}function Zr(e){return String(e).padStart(2,`0`)}function Qr(e){return`${e.getFullYear()}-${Zr(e.getMonth()+1)}-${Zr(e.getDate())}`}function $r(){return Qr(new Date)}function ei(e,t){let[n,r,i]=e.split(`-`).map(Number),a=new Date(n,(r??1)-1,i??1);return a.setDate(a.getDate()+t),Qr(a)}function ti(e,t){let[n,r,i]=e.split(`-`).map(Number),[a,o,s]=t.split(`-`).map(Number),c=new Date(n,(r??1)-1,i??1),l=new Date(a,(o??1)-1,s??1),u=Math.round((l.getTime()-c.getTime())/864e5);return Math.max(1,u+1)}var ni={summary:null,timeline:[],models:[],usage:null,sessions:[],forwardEndpoints:[],forwardRequests:[],memoryTimeline:[]},ri=3e4,ii=50,ai=[`总览`,`趋势`,`模型分布`,`用量构成`,`会话列表`,`Forward 端点`,`Forward 请求`,`记忆趋势`];function oi(e){return e instanceof Error?e.message:String(e)}function si(e){let[t,n]=(0,G.useState)(ni),[r,i]=(0,G.useState)([]),[a,o]=(0,G.useState)(!0),[s,c]=(0,G.useState)(!1),[l,u]=(0,G.useState)(null),d=(0,G.useRef)(!1),f=(0,G.useRef)(0),p=(0,G.useRef)(!0),m=(0,G.useRef)(0);(0,G.useEffect)(()=>(p.current=!0,()=>{p.current=!1}),[]);let h=(0,G.useCallback)(async t=>{if(t?.skipIfBusy&&d.current)return;let r=++f.current;d.current=!0,c(!0);let a={startDate:e.startDate,endDate:e.endDate},s=await Promise.allSettled([ze.getUnifiedSummary(a),ze.getUnifiedTimeline({days:e.days,endDate:e.endDate}),ze.getByModel(a),ze.getUsageBreakdown(a),ze.getSessions({...a,limit:20}),ze.getForwardByEndpoint(a),ze.getForwardRequests({...a,limit:ii}),ze.getMemoryTimeline({days:e.days,endDate:e.endDate})]);if(r!==f.current||(d.current=!1,!p.current))return;let[l,h,g,_,v,y,b,x]=s;n(e=>({summary:l.status===`fulfilled`?l.value:e.summary,timeline:h.status===`fulfilled`?h.value:e.timeline,models:g.status===`fulfilled`?g.value:e.models,usage:_.status===`fulfilled`?_.value:e.usage,sessions:v.status===`fulfilled`?v.value:e.sessions,forwardEndpoints:y.status===`fulfilled`?y.value:e.forwardEndpoints,forwardRequests:b.status===`fulfilled`?b.value:e.forwardRequests,memoryTimeline:x.status===`fulfilled`?x.value:e.memoryTimeline})),i(s.flatMap((e,t)=>e.status===`rejected`?[`${ai[t]}: ${oi(e.reason)}`]:[])),m.current=Date.now(),u(m.current),o(!1),c(!1)},[e.startDate,e.endDate,e.days]);return(0,G.useEffect)(()=>{h();let e=setInterval(()=>{document.visibilityState===`visible`&&h({skipIfBusy:!0})},ri),t=()=>{document.visibilityState===`visible`&&Date.now()-m.current>ri&&h()};return document.addEventListener(`visibilitychange`,t),()=>{clearInterval(e),document.removeEventListener(`visibilitychange`,t)}},[h]),{data:t,errors:r,initialLoading:a,refreshing:s,lastUpdated:l,refresh:h}}var ci=`var(--mx-chat)`,li=`var(--mx-fwd)`,ui=140,di={top:8,right:12,bottom:20,left:40},fi=di.top+ui+di.bottom;function pi(){let e=(0,G.useRef)(null),[t,n]=(0,G.useState)(0);return(0,G.useEffect)(()=>{let t=e.current;if(!t)return;let r=new ResizeObserver(e=>{let t=e[0]?.contentRect.width;typeof t==`number`&&n(t)});return r.observe(t),n(t.clientWidth),()=>r.disconnect()},[]),{ref:e,width:t}}function mi(e){if(e<=0)return 1;let t=10**Math.floor(Math.log10(e));for(let n of[1,2,5,10])if(e<=n*t)return n*t;return 10*t}function hi(e,t){return e.map((e,n)=>`${n===0?`M`:`L`}${e.toFixed(1)} ${t[n].toFixed(1)}`).join(` `)}function gi(e,t,n){if(e.length===0)return``;let r=hi(e,t),i=e[e.length-1].toFixed(1),a=e[0].toFixed(1);return`${r} L${i} ${n.toFixed(1)} L${a} ${n.toFixed(1)} Z`}function _i({points:e}){let{ref:t,width:n}=pi(),[r,i]=(0,G.useState)(`chart`),[o,c]=(0,G.useState)(null),l=e.length,u=Math.max(0,n-di.left-di.right),d=di.top+ui,f=(0,G.useMemo)(()=>{if(l===0||u<=0)return null;let t=mi(e.reduce((e,t)=>Math.max(e,t.chat_tokens,t.forward_tokens),0)),n=e=>di.left+(l===1?u/2:e/(l-1)*u),r=e=>di.top+ui-e/t*ui;return{yMax:t,xs:e.map((e,t)=>n(t)),chatYs:e.map(e=>r(e.chat_tokens)),forwardYs:e.map(e=>r(e.forward_tokens))}},[e,l,u]),p=(0,G.useMemo)(()=>l===0?[]:l<=3?e.map((e,t)=>t):[...new Set([0,Math.floor((l-1)/2),l-1])],[l,e]),m=(e,t)=>{if(!f||l===0)return;let n=e-t.left,r=0,i=1/0;f.xs.forEach((e,t)=>{let a=Math.abs(e-n);a<i&&(i=a,r=t)}),c(r)};if(l===0)return(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无数据`});let h=o==null?null:e[o],g=o!=null&&f?f.xs[o]:null,_=g!=null&&n>0&&g>n*.55;return(0,q.jsxs)(`div`,{className:`space-y-2`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-3 text-xs text-muted-foreground`,children:[(0,q.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(`span`,{className:`h-0.5 w-3 rounded-full`,style:{background:ci}}),`会话 Tokens`]}),(0,q.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(`span`,{className:`h-0.5 w-3 rounded-full`,style:{background:li}}),`Forward Tokens`]})]}),(0,q.jsx)(`div`,{className:`flex gap-1`,children:[[`chart`,`图表`],[`table`,`表格`]].map(([e,t])=>(0,q.jsx)(s,{size:`sm`,variant:r===e?`secondary`:`ghost`,className:`h-6 px-2 text-xs`,onClick:()=>i(e),children:t},e))})]}),r===`table`?(0,q.jsx)(`div`,{className:`max-h-56 overflow-auto rounded-md border`,children:(0,q.jsxs)(`table`,{className:`w-full min-w-[420px] text-xs`,children:[(0,q.jsx)(`thead`,{className:`sticky top-0 bg-background text-muted-foreground`,children:(0,q.jsxs)(`tr`,{className:`[&>th]:px-2 [&>th]:py-1.5 [&>th]:font-medium`,children:[(0,q.jsx)(`th`,{className:`text-left`,children:`日期`}),(0,q.jsx)(`th`,{className:`text-right`,children:`会话 Tokens`}),(0,q.jsx)(`th`,{className:`text-right`,children:`Forward Tokens`}),(0,q.jsx)(`th`,{className:`text-right`,children:`会话数`}),(0,q.jsx)(`th`,{className:`text-right`,children:`转发数`})]})}),(0,q.jsx)(`tbody`,{children:e.map(e=>(0,q.jsxs)(`tr`,{className:`border-t [&>td]:px-2 [&>td]:py-1`,children:[(0,q.jsx)(`td`,{children:e.date}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Q(e.chat_tokens)}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Q(e.forward_tokens)}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Q(e.chat_sessions)}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Q(e.forward_requests)})]},e.date))})]})}):(0,q.jsx)(`div`,{ref:t,className:`relative w-full`,children:n>0&&f?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`svg`,{width:n,height:fi,role:`img`,"aria-label":`Token 趋势图`,tabIndex:0,className:`block outline-none focus-visible:ring-1 focus-visible:ring-ring`,onPointerMove:e=>m(e.clientX,e.currentTarget.getBoundingClientRect()),onPointerLeave:()=>c(null),onFocus:()=>c(e=>e??l-1),onBlur:()=>c(null),onKeyDown:e=>{if(e.key===`ArrowLeft`||e.key===`ArrowRight`){e.preventDefault();let t=e.key===`ArrowLeft`?-1:1;c(e=>Math.min(l-1,Math.max(0,(e??l-1)+t)))}},children:[[0,.5,1].map(e=>{let t=di.top+ui-e*ui;return(0,q.jsxs)(`g`,{children:[(0,q.jsx)(`line`,{x1:di.left,x2:n-di.right,y1:t,y2:t,stroke:`var(--border)`,strokeWidth:1}),(0,q.jsx)(`text`,{x:di.left-6,y:t+3,textAnchor:`end`,fontSize:10,className:`fill-muted-foreground tabular-nums`,children:Z(e*f.yMax)})]},e)}),(0,q.jsx)(`path`,{d:gi(f.xs,f.chatYs,d),fill:ci,fillOpacity:.1}),(0,q.jsx)(`path`,{d:gi(f.xs,f.forwardYs,d),fill:li,fillOpacity:.1}),l>1?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(`path`,{d:hi(f.xs,f.chatYs),fill:`none`,stroke:ci,strokeWidth:2,strokeLinejoin:`round`,strokeLinecap:`round`}),(0,q.jsx)(`path`,{d:hi(f.xs,f.forwardYs),fill:`none`,stroke:li,strokeWidth:2,strokeLinejoin:`round`,strokeLinecap:`round`})]}):null,(0,q.jsx)(`circle`,{cx:f.xs[l-1],cy:f.chatYs[l-1],r:4,fill:ci,stroke:`var(--background)`,strokeWidth:2}),(0,q.jsx)(`circle`,{cx:f.xs[l-1],cy:f.forwardYs[l-1],r:4,fill:li,stroke:`var(--background)`,strokeWidth:2}),g!=null&&o!=null?(0,q.jsxs)(`g`,{children:[(0,q.jsx)(`line`,{x1:g,x2:g,y1:di.top,y2:d,stroke:`var(--border)`,strokeWidth:1}),(0,q.jsx)(`circle`,{cx:g,cy:f.chatYs[o],r:3.5,fill:ci,stroke:`var(--background)`,strokeWidth:2}),(0,q.jsx)(`circle`,{cx:g,cy:f.forwardYs[o],r:3.5,fill:li,stroke:`var(--background)`,strokeWidth:2})]}):null,(0,q.jsx)(`line`,{x1:di.left,x2:n-di.right,y1:d,y2:d,stroke:`var(--border)`,strokeWidth:1}),p.map(t=>(0,q.jsx)(`text`,{x:f.xs[t],y:d+14,textAnchor:t===0?`start`:t===l-1?`end`:`middle`,fontSize:10,className:`fill-muted-foreground`,children:Xr(e[t].date)},t))]}),h&&g!=null?(0,q.jsxs)(`div`,{className:a(`pointer-events-none absolute top-1 z-10 rounded-md border bg-popover px-2.5 py-2 text-xs shadow-md`),style:_?{left:g-10,transform:`translateX(-100%)`}:{left:g+10},children:[(0,q.jsx)(`div`,{className:`mb-1 font-medium`,children:h.date}),(0,q.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(`span`,{className:`h-0.5 w-3 shrink-0 rounded-full`,style:{background:ci}}),(0,q.jsx)(`span`,{className:`font-semibold tabular-nums`,children:Q(h.chat_tokens)}),(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:`会话 Tokens`})]}),(0,q.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(`span`,{className:`h-0.5 w-3 shrink-0 rounded-full`,style:{background:li}}),(0,q.jsx)(`span`,{className:`font-semibold tabular-nums`,children:Q(h.forward_tokens)}),(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:`Forward Tokens`})]}),(0,q.jsxs)(`div`,{className:`mt-1 text-muted-foreground`,children:[Q(h.chat_sessions),` 会话 · `,Q(h.forward_requests),` 次转发`]})]}):null]}):(0,q.jsx)(`div`,{style:{height:fi}})})]})}function vi({items:e,color:t=`var(--mx-chat)`,emptyText:n=`暂无数据`,formatValue:r=Z}){if(e.length===0)return(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:n});let i=e.reduce((e,t)=>Math.max(e,t.value),0);return(0,q.jsx)(`ul`,{className:`space-y-2`,children:e.map(e=>(0,q.jsxs)(`li`,{title:`${e.label}: ${e.value.toLocaleString()}`,children:[(0,q.jsxs)(`div`,{className:`flex items-baseline justify-between gap-2`,children:[(0,q.jsxs)(`span`,{className:`min-w-0 truncate text-xs`,children:[e.label,e.meta?(0,q.jsx)(`span`,{className:`ml-1.5 text-muted-foreground`,children:e.meta}):null]}),(0,q.jsx)(`span`,{className:`shrink-0 text-xs font-medium tabular-nums`,children:r(e.value)})]}),(0,q.jsx)(`div`,{className:`mt-1 h-1.5 w-full rounded-full`,style:{background:`color-mix(in srgb, ${t} 14%, transparent)`},children:(0,q.jsx)(`div`,{className:`h-full rounded-full`,style:{width:`${i>0?Math.max(e.value/i*100,e.value>0?1.5:0):0}%`,background:t}})})]},e.key))})}var yi={running:{label:`进行中`,dotClass:`bg-[#2a78d6] dark:bg-[#3987e5]`},awaiting_response:{label:`待回应`,dotClass:`bg-amber-500`},completed:{label:`已完成`,dotClass:`bg-emerald-600 dark:bg-emerald-500`},error:{label:`出错`,dotClass:`bg-destructive`},cancelled:{label:`已取消`,dotClass:`bg-muted-foreground`}};function bi({status:e}){let t=yi[e]??{label:e,dotClass:`bg-muted-foreground`};return(0,q.jsxs)(`span`,{className:`flex items-center gap-1.5 whitespace-nowrap`,children:[(0,q.jsx)(`span`,{className:a(`inline-block size-1.5 shrink-0 rounded-full`,t.dotClass)}),t.label]})}function xi({sessions:e}){return e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无会话记录`}):(0,q.jsx)(`div`,{className:`max-h-72 overflow-auto rounded-md border`,children:(0,q.jsxs)(`table`,{className:`w-full min-w-[620px] text-xs`,children:[(0,q.jsx)(`thead`,{className:`sticky top-0 z-10 bg-background text-muted-foreground`,children:(0,q.jsxs)(`tr`,{className:`[&>th]:px-2 [&>th]:py-1.5 [&>th]:font-medium`,children:[(0,q.jsx)(`th`,{className:`text-left`,children:`会话`}),(0,q.jsx)(`th`,{className:`text-left`,children:`模型`}),(0,q.jsx)(`th`,{className:`text-left`,children:`状态`}),(0,q.jsx)(`th`,{className:`text-right`,children:`轮次`}),(0,q.jsx)(`th`,{className:`text-right`,children:`Tokens`}),(0,q.jsx)(`th`,{className:`text-right`,children:`工具`}),(0,q.jsx)(`th`,{className:`text-right`,children:`时长`}),(0,q.jsx)(`th`,{className:`text-right`,children:`开始时间`})]})}),(0,q.jsx)(`tbody`,{children:e.map(e=>(0,q.jsxs)(`tr`,{className:`border-t [&>td]:px-2 [&>td]:py-1.5`,children:[(0,q.jsx)(`td`,{className:`font-mono`,title:e.session_id,children:e.session_id.slice(0,8)}),(0,q.jsx)(`td`,{className:`max-w-40 truncate`,title:e.model,children:e.model||`-`}),(0,q.jsx)(`td`,{children:(0,q.jsx)(bi,{status:e.status})}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Q(e.total_rounds)}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,title:Q(e.total_token_usage.total_tokens),children:Z(e.total_token_usage.total_tokens)}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Q(e.tool_call_count)}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Jr(e.duration_ms)}),(0,q.jsx)(`td`,{className:`whitespace-nowrap text-right tabular-nums text-muted-foreground`,children:Yr(e.started_at)})]},e.session_id))})]})})}var Si=5;function Ci({usage:e}){let t=(0,G.useMemo)(()=>{let t=e.top_core_tools.slice(0,Si).map(e=>({key:`core:${e.name}`,category:`核心工具`,label:e.name,count:e.count})),n=e.top_skills.slice(0,Si).map(e=>({key:`skill:${e.skill_id}`,category:`技能`,label:e.skill_id,count:e.count})),r=e.top_mcp_tools.slice(0,Si).map(e=>({key:`mcp:${e.alias}`,category:`MCP`,label:e.tool_name,detail:e.server_id,count:e.count}));return[...t,...n,...r]},[e]),n=t.reduce((e,t)=>Math.max(e,t.count),0);return(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsx)(`div`,{className:`grid grid-cols-2 gap-2 sm:grid-cols-4`,children:[{label:`总工具调用`,value:e.total_tool_calls},{label:`核心工具`,value:e.core_tool_calls},{label:`技能加载`,value:e.skill_load_calls},{label:`MCP 调用`,value:e.mcp_calls}].map(e=>(0,q.jsxs)(`div`,{className:`rounded-md border p-2 text-center`,children:[(0,q.jsx)(`div`,{className:`text-sm font-semibold`,title:Q(e.value),children:Z(e.value)}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e.label})]},e.label))}),t.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`此范围内暂无工具/技能/MCP 使用记录`}):(0,q.jsx)(`div`,{className:`max-h-64 overflow-auto rounded-md border`,children:(0,q.jsxs)(`table`,{className:`w-full min-w-[440px] text-xs`,children:[(0,q.jsx)(`thead`,{className:`sticky top-0 z-10 bg-background text-muted-foreground`,children:(0,q.jsxs)(`tr`,{className:`[&>th]:px-2 [&>th]:py-1.5 [&>th]:font-medium`,children:[(0,q.jsx)(`th`,{className:`text-left`,children:`类别`}),(0,q.jsx)(`th`,{className:`text-left`,children:`名称`}),(0,q.jsx)(`th`,{className:`w-24 text-right`,children:`次数`}),(0,q.jsx)(`th`,{className:`w-28 text-left`,children:`占比`})]})}),(0,q.jsx)(`tbody`,{children:t.map(e=>(0,q.jsxs)(`tr`,{className:`border-t [&>td]:px-2 [&>td]:py-1.5`,children:[(0,q.jsx)(`td`,{children:(0,q.jsx)(H,{variant:`outline`,className:`px-1.5 py-0 text-[10px] font-normal`,children:e.category})}),(0,q.jsxs)(`td`,{className:`max-w-48 truncate`,title:e.detail?`${e.label} · ${e.detail}`:e.label,children:[e.label,e.detail?(0,q.jsxs)(`span`,{className:`ml-1 text-muted-foreground`,children:[`(`,e.detail,`)`]}):null]}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Q(e.count)}),(0,q.jsx)(`td`,{children:(0,q.jsx)(`div`,{className:`h-1.5 w-full rounded-full`,style:{background:`color-mix(in srgb, var(--mx-chat) 14%, transparent)`},children:(0,q.jsx)(`div`,{className:`h-full rounded-full`,style:{width:`${n>0?Math.max(e.count/n*100,1.5):0}%`,background:`var(--mx-chat)`}})})})]},e.key))})]})})]})}var wi=`var(--mx-ok)`,Ti=`var(--destructive)`;function Ei(e){return e.split(`.`).pop()||e}function Di({endpoints:e}){if(e.length===0)return(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`此范围内暂无 Forward 请求`});let t=[...e].sort((e,t)=>t.requests-e.requests),n=t.reduce((e,t)=>Math.max(e,t.requests),0);return(0,q.jsxs)(`div`,{className:`space-y-2`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-3 text-xs text-muted-foreground`,children:[(0,q.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(`span`,{className:`h-0.5 w-3 rounded-full`,style:{background:wi}}),`成功`]}),(0,q.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(`span`,{className:`h-0.5 w-3 rounded-full`,style:{background:Ti}}),`失败`]})]}),(0,q.jsx)(`ul`,{className:`space-y-2`,children:t.map(e=>{let t=n>0?e.successful/n*100:0,r=n>0?e.failed/n*100:0;return(0,q.jsxs)(`li`,{title:`${e.endpoint}: ${Q(e.requests)} 次请求(成功 ${Q(e.successful)} · 失败 ${Q(e.failed)})`,children:[(0,q.jsxs)(`div`,{className:`flex items-baseline justify-between gap-2`,children:[(0,q.jsxs)(`span`,{className:`min-w-0 truncate text-xs`,children:[Ei(e.endpoint),(0,q.jsxs)(`span`,{className:`ml-1.5 text-muted-foreground`,children:[`成功 `,Z(e.successful),` · 失败 `,Z(e.failed),e.avg_duration_ms!=null&&e.avg_duration_ms>0?` · 平均 ${Jr(e.avg_duration_ms)}`:``]})]}),(0,q.jsx)(`span`,{className:`shrink-0 text-xs font-medium tabular-nums`,children:Z(e.requests)})]}),(0,q.jsxs)(`div`,{className:`mt-1 flex h-1.5 w-full overflow-hidden rounded-full`,style:{background:`color-mix(in srgb, ${wi} 14%, transparent)`},children:[(0,q.jsx)(`div`,{className:`h-full`,style:{width:`${Math.max(t,e.successful>0?1.5:0)}%`,background:wi}}),(0,q.jsx)(`div`,{className:`h-full`,style:{width:`${Math.max(r,e.failed>0?1.5:0)}%`,background:Ti}})]})]},e.endpoint)})})]})}var Oi={pending:{label:`进行中`,dotClass:`bg-[var(--mx-chat)]`},success:{label:`成功`,dotClass:`bg-[var(--mx-ok)]`},error:{label:`失败`,dotClass:`bg-destructive`}};function ki({status:e,statusCode:t}){if(!e)return(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:`-`});let n=Oi[e]??{label:e,dotClass:`bg-muted-foreground`};return(0,q.jsxs)(`span`,{className:`flex items-center gap-1.5 whitespace-nowrap`,children:[(0,q.jsx)(`span`,{className:a(`inline-block size-1.5 shrink-0 rounded-full`,n.dotClass)}),n.label,t==null?null:(0,q.jsxs)(`span`,{className:`text-muted-foreground`,children:[`(`,t,`)`]})]})}function Ai(e){return e.split(`.`).pop()||e}function ji({requests:e}){return e.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`此范围内暂无 Forward 请求记录`}):(0,q.jsx)(`div`,{className:`max-h-72 overflow-auto rounded-md border`,children:(0,q.jsxs)(`table`,{className:`w-full min-w-[720px] text-xs`,children:[(0,q.jsx)(`thead`,{className:`sticky top-0 z-10 bg-background text-muted-foreground`,children:(0,q.jsxs)(`tr`,{className:`[&>th]:px-2 [&>th]:py-1.5 [&>th]:font-medium`,children:[(0,q.jsx)(`th`,{className:`text-left`,children:`请求`}),(0,q.jsx)(`th`,{className:`text-left`,children:`端点`}),(0,q.jsx)(`th`,{className:`text-left`,children:`模型`}),(0,q.jsx)(`th`,{className:`text-left`,children:`类型`}),(0,q.jsx)(`th`,{className:`text-left`,children:`状态`}),(0,q.jsx)(`th`,{className:`text-right`,children:`Tokens`}),(0,q.jsx)(`th`,{className:`text-right`,children:`耗时`}),(0,q.jsx)(`th`,{className:`text-right`,children:`开始时间`}),(0,q.jsx)(`th`,{className:`text-left`,children:`错误`})]})}),(0,q.jsx)(`tbody`,{children:e.map(e=>(0,q.jsxs)(`tr`,{className:`border-t [&>td]:px-2 [&>td]:py-1.5`,children:[(0,q.jsx)(`td`,{className:`font-mono`,title:e.forward_id,children:e.forward_id.slice(0,8)}),(0,q.jsx)(`td`,{title:e.endpoint,children:(0,q.jsx)(H,{variant:`outline`,className:`px-1.5 py-0 text-[10px] font-normal`,children:Ai(e.endpoint)})}),(0,q.jsx)(`td`,{className:`max-w-40 truncate`,title:e.model,children:e.model||`-`}),(0,q.jsx)(`td`,{className:`whitespace-nowrap`,children:e.is_stream?`流式`:`同步`}),(0,q.jsx)(`td`,{children:(0,q.jsx)(ki,{status:e.status,statusCode:e.status_code})}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,title:e.token_usage?Q(e.token_usage.total_tokens):void 0,children:e.token_usage?Z(e.token_usage.total_tokens):`-`}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Jr(e.duration_ms)}),(0,q.jsx)(`td`,{className:`whitespace-nowrap text-right tabular-nums text-muted-foreground`,children:Yr(e.started_at)}),(0,q.jsx)(`td`,{className:`max-w-48 truncate text-destructive`,title:e.error??void 0,children:e.error||(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:`-`})})]},e.forward_id))})]})})}var Mi={message_count_mismatch:`消息数量`,last_message_id_mismatch:`最后消息`,pending_question_mismatch:`待回应问题`,message_count:`消息数量`,last_message_id:`最后消息`,pending_question:`待回应问题`};function Ni(e){return Mi[e]?Mi[e]:e.split(`_`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}function Pi({breakdown:e}){return(0,q.jsx)(vi,{items:(0,G.useMemo)(()=>Object.entries(e??{}).map(([e,t])=>({key:e,label:Ni(e),value:t})).sort((e,t)=>t.value-e.value),[e]),color:`var(--destructive)`,emptyText:`此范围内暂无同步不一致记录`})}var Fi=`var(--mx-chat)`,Ii=[{key:`total_memories`,label:`记忆总量`,color:Fi},{key:`created_memories`,label:`新增记忆`,color:`var(--mx-fwd)`},{key:`updated_memories`,label:`更新记忆`,color:`var(--mx-mem)`}],Li=140,Ri={top:8,right:12,bottom:20,left:40},zi=Ri.top+Li+Ri.bottom;function Bi(){let e=(0,G.useRef)(null),[t,n]=(0,G.useState)(0);return{ref:(0,G.useCallback)(t=>{if(e.current?.disconnect(),e.current=null,!t)return;let r=new ResizeObserver(e=>{let t=e[0]?.contentRect.width;typeof t==`number`&&n(t)});r.observe(t),e.current=r,n(t.clientWidth)},[]),width:t}}function Vi(e){if(e<=0)return 1;let t=10**Math.floor(Math.log10(e));for(let n of[1,2,5,10])if(e<=n*t)return n*t;return 10*t}function Hi(e,t){return e.map((e,n)=>`${n===0?`M`:`L`}${e.toFixed(1)} ${t[n].toFixed(1)}`).join(` `)}function Ui(e,t,n){if(e.length===0)return``;let r=Hi(e,t),i=e[e.length-1].toFixed(1),a=e[0].toFixed(1);return`${r} L${i} ${n.toFixed(1)} L${a} ${n.toFixed(1)} Z`}function Wi({points:e}){let{ref:t,width:n}=Bi(),[r,i]=(0,G.useState)(`chart`),[o,c]=(0,G.useState)(null),l=e.length,u=Math.max(0,n-Ri.left-Ri.right),d=Ri.top+Li,f=(0,G.useMemo)(()=>{if(l===0||u<=0)return null;let t=Vi(e.reduce((e,t)=>Math.max(e,t.total_memories,t.created_memories,t.updated_memories),0)),n=e=>Ri.left+(l===1?u/2:e/(l-1)*u),r=e=>Ri.top+Li-e/t*Li;return{yMax:t,xs:e.map((e,t)=>n(t)),ysBySeries:Ii.map(t=>e.map(e=>r(e[t.key])))}},[e,l,u]),p=(0,G.useMemo)(()=>l===0?[]:l<=3?e.map((e,t)=>t):[...new Set([0,Math.floor((l-1)/2),l-1])],[l,e]),m=(e,t)=>{if(!f||l===0)return;let n=e-t.left,r=0,i=1/0;f.xs.forEach((e,t)=>{let a=Math.abs(e-n);a<i&&(i=a,r=t)}),c(r)};if(l===0)return(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无记忆趋势数据`});let h=o==null?null:e[o],g=o!=null&&f?f.xs[o]:null,_=g!=null&&n>0&&g>n*.55;return(0,q.jsxs)(`div`,{className:`space-y-2`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,q.jsx)(`div`,{className:`flex items-center gap-3 text-xs text-muted-foreground`,children:Ii.map(e=>(0,q.jsxs)(`span`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(`span`,{className:`h-0.5 w-3 rounded-full`,style:{background:e.color}}),e.label]},e.key))}),(0,q.jsx)(`div`,{className:`flex gap-1`,children:[[`chart`,`图表`],[`table`,`表格`]].map(([e,t])=>(0,q.jsx)(s,{size:`sm`,variant:r===e?`secondary`:`ghost`,className:`h-6 px-2 text-xs`,onClick:()=>i(e),children:t},e))})]}),r===`table`?(0,q.jsx)(`div`,{className:`max-h-56 overflow-auto rounded-md border`,children:(0,q.jsxs)(`table`,{className:`w-full min-w-[420px] text-xs`,children:[(0,q.jsx)(`thead`,{className:`sticky top-0 bg-background text-muted-foreground`,children:(0,q.jsxs)(`tr`,{className:`[&>th]:px-2 [&>th]:py-1.5 [&>th]:font-medium`,children:[(0,q.jsx)(`th`,{className:`text-left`,children:`日期`}),(0,q.jsx)(`th`,{className:`text-right`,children:`记忆总量`}),(0,q.jsx)(`th`,{className:`text-right`,children:`新增记忆`}),(0,q.jsx)(`th`,{className:`text-right`,children:`更新记忆`})]})}),(0,q.jsx)(`tbody`,{children:e.map(e=>(0,q.jsxs)(`tr`,{className:`border-t [&>td]:px-2 [&>td]:py-1`,children:[(0,q.jsx)(`td`,{children:e.label}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Q(e.total_memories)}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Q(e.created_memories)}),(0,q.jsx)(`td`,{className:`text-right tabular-nums`,children:Q(e.updated_memories)})]},e.label))})]})}):(0,q.jsx)(`div`,{ref:t,className:`relative w-full`,children:n>0&&f?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`svg`,{width:n,height:zi,role:`img`,"aria-label":`记忆趋势图`,tabIndex:0,className:`block outline-none focus-visible:ring-1 focus-visible:ring-ring`,onPointerMove:e=>m(e.clientX,e.currentTarget.getBoundingClientRect()),onPointerLeave:()=>c(null),onFocus:()=>c(e=>e??l-1),onBlur:()=>c(null),onKeyDown:e=>{if(e.key===`ArrowLeft`||e.key===`ArrowRight`){e.preventDefault();let t=e.key===`ArrowLeft`?-1:1;c(e=>Math.min(l-1,Math.max(0,(e??l-1)+t)))}},children:[[0,.5,1].map(e=>{let t=Ri.top+Li-e*Li;return(0,q.jsxs)(`g`,{children:[(0,q.jsx)(`line`,{x1:Ri.left,x2:n-Ri.right,y1:t,y2:t,stroke:`var(--border)`,strokeWidth:1}),(0,q.jsx)(`text`,{x:Ri.left-6,y:t+3,textAnchor:`end`,fontSize:10,className:`fill-muted-foreground tabular-nums`,children:Z(e*f.yMax)})]},e)}),(0,q.jsx)(`path`,{d:Ui(f.xs,f.ysBySeries[0],d),fill:Fi,fillOpacity:.1}),l>1?Ii.map((e,t)=>(0,q.jsx)(`path`,{d:Hi(f.xs,f.ysBySeries[t]),fill:`none`,stroke:e.color,strokeWidth:2,strokeLinejoin:`round`,strokeLinecap:`round`},e.key)):null,Ii.map((e,t)=>(0,q.jsx)(`circle`,{cx:f.xs[l-1],cy:f.ysBySeries[t][l-1],r:4,fill:e.color,stroke:`var(--background)`,strokeWidth:2},e.key)),g!=null&&o!=null?(0,q.jsxs)(`g`,{children:[(0,q.jsx)(`line`,{x1:g,x2:g,y1:Ri.top,y2:d,stroke:`var(--border)`,strokeWidth:1}),Ii.map((e,t)=>(0,q.jsx)(`circle`,{cx:g,cy:f.ysBySeries[t][o],r:3.5,fill:e.color,stroke:`var(--background)`,strokeWidth:2},e.key))]}):null,(0,q.jsx)(`line`,{x1:Ri.left,x2:n-Ri.right,y1:d,y2:d,stroke:`var(--border)`,strokeWidth:1}),p.map(t=>(0,q.jsx)(`text`,{x:f.xs[t],y:d+14,textAnchor:t===0?`start`:t===l-1?`end`:`middle`,fontSize:10,className:`fill-muted-foreground`,children:Xr(e[t].label)},t))]}),h&&g!=null?(0,q.jsxs)(`div`,{className:a(`pointer-events-none absolute top-1 z-10 rounded-md border bg-popover px-2.5 py-2 text-xs shadow-md`),style:_?{left:g-10,transform:`translateX(-100%)`}:{left:g+10},children:[(0,q.jsx)(`div`,{className:`mb-1 font-medium`,children:h.label}),Ii.map(e=>(0,q.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,q.jsx)(`span`,{className:`h-0.5 w-3 shrink-0 rounded-full`,style:{background:e.color}}),(0,q.jsx)(`span`,{className:`font-semibold tabular-nums`,children:Q(h[e.key])}),(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:e.label})]},e.key))]}):null]}):(0,q.jsx)(`div`,{style:{height:zi}})})]})}var Gi=[{id:`today`,label:`今天`,days:1},{id:`7d`,label:`7 天`,days:7},{id:`30d`,label:`30 天`,days:30}],Ki=`.lnx-metrics{--mx-chat:#2a78d6;--mx-fwd:#1baf7a;--mx-mem:#8a5cd8;--mx-ok:#059669}.dark .lnx-metrics{--mx-chat:#3987e5;--mx-fwd:#199e70;--mx-mem:#9a74e3;--mx-ok:#10b981}`;function qi({label:e,value:t,sub:n,title:r}){return(0,q.jsxs)(`div`,{className:`rounded-lg border p-2.5`,title:r,children:[(0,q.jsx)(`div`,{className:`text-lg font-semibold leading-tight`,children:t}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e}),n?(0,q.jsx)(`div`,{className:`mt-0.5 text-[11px] text-muted-foreground/80`,children:n}):null]})}function Ji(){let[e,t]=(0,G.useState)(`30d`),[n,r]=(0,G.useState)(()=>ei($r(),-29)),[i,o]=(0,G.useState)(()=>$r()),c=(e,n)=>{let i=$r();t(e),r(ei(i,-(n-1))),o(i)},l=(0,G.useMemo)(()=>n&&i?Math.min(ti(n,i),365):n?Math.min(ti(n,$r()),365):30,[n,i]),{data:u,errors:d,initialLoading:f,refreshing:p,lastUpdated:m,refresh:h}=si((0,G.useMemo)(()=>({startDate:n||void 0,endDate:i||void 0,days:l}),[n,i,l])),g=u.summary,_=(0,G.useMemo)(()=>{if(!g)return[];let{chat:e,forward:t,combined:n,memory:r}=g;return[{label:`总请求`,value:Z(n.total_requests),sub:`会话 ${Z(e.total_sessions)} · 转发 ${Z(t.total_requests)}`,title:Q(n.total_requests)},{label:`总 Tokens`,value:Z(n.total_tokens),title:Q(n.total_tokens)},{label:`成功率`,value:qr(n.success_rate),sub:`失败/取消 ${Z(n.total_errors)}`},{label:`进行中会话`,value:Z(e.active_sessions),sub:`已完成 ${Z(e.completed_sessions??0)}`,title:Q(e.active_sessions)},{label:`工具调用`,value:Z(e.total_tool_calls),title:Q(e.total_tool_calls)},{label:`压缩节省 Tokens`,value:Z(e.total_tokens_saved??0),sub:`压缩事件 ${Z(e.total_compression_events??0)}`,title:Q(e.total_tokens_saved??0)},{label:`Forward 请求`,value:Z(t.total_requests),sub:`失败 ${Z(t.failed_requests)}`,title:Q(t.total_requests)},{label:`记忆条目`,value:Z(r.total_memories),sub:`待清理 ${Z(r.stale_candidate_count)}`,title:Q(r.total_memories)}]},[g]),v=(0,G.useMemo)(()=>{let e=[...u.models].sort((e,t)=>t.tokens.total_tokens-e.tokens.total_tokens),t=e.slice(0,8),n=e.slice(8),r=t.map(e=>({key:e.model,label:e.model,value:e.tokens.total_tokens,meta:`${Q(e.sessions)} 会话`}));return n.length>0&&r.push({key:`__other__`,label:`其他(${n.length} 个模型)`,value:n.reduce((e,t)=>e+t.tokens.total_tokens,0),meta:`${Q(n.reduce((e,t)=>e+t.sessions,0))} 会话`}),r},[u.models]);return(0,q.jsxs)(`div`,{className:`lnx-metrics space-y-4`,children:[(0,q.jsx)(`style`,{children:Ki}),(0,q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[Gi.map(t=>(0,q.jsx)(s,{size:`sm`,variant:e===t.id?`default`:`secondary`,className:`h-7 px-2.5 text-xs`,onClick:()=>c(t.id,t.days),children:t.label},t.id)),(0,q.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,q.jsx)(C,{type:`date`,value:n,max:i||void 0,onChange:e=>{r(e.target.value),t(`custom`)},"aria-label":`开始日期`,className:`h-7 w-[8.75rem] px-2 text-xs`}),(0,q.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`至`}),(0,q.jsx)(C,{type:`date`,value:i,min:n||void 0,onChange:e=>{o(e.target.value),t(`custom`)},"aria-label":`结束日期`,className:`h-7 w-[8.75rem] px-2 text-xs`})]}),(0,q.jsx)(s,{size:`sm`,variant:`ghost`,className:`h-7 px-2`,onClick:()=>void h(),disabled:p,"aria-label":`刷新`,children:(0,q.jsx)(Me,{className:a(`size-3.5`,p&&`animate-spin`)})})]}),(0,q.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`面板可见时每 30 秒自动刷新`,m?` · 上次更新 ${new Date(m).toLocaleTimeString(`zh-CN`,{hour:`2-digit`,minute:`2-digit`,second:`2-digit`})}`:``]})]}),d.length>0?(0,q.jsxs)(`div`,{className:`space-y-1 rounded-lg border border-destructive/50 bg-destructive/10 p-2.5 text-xs text-destructive`,children:[d.map(e=>(0,q.jsxs)(`div`,{children:[`加载失败 — `,e]},e)),(0,q.jsx)(`button`,{className:`underline underline-offset-2`,onClick:()=>void h(),children:`重试`})]}):null,(0,q.jsxs)(`div`,{className:a(`space-y-4 transition-opacity duration-300`,p&&!f&&`opacity-60`),children:[(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`总览`}),f?(0,q.jsx)(`div`,{className:`grid grid-cols-2 gap-2 sm:grid-cols-4`,children:Array.from({length:8}).map((e,t)=>(0,q.jsx)(Wr,{className:`h-16 rounded-lg`},t))}):g?(0,q.jsx)(`div`,{className:`grid grid-cols-2 gap-2 sm:grid-cols-4`,children:_.map(e=>(0,q.jsx)(qi,{...e},e.label))}):(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无数据`})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:[`Token 趋势(近 `,l,` 天)`]}),f?(0,q.jsx)(Wr,{className:`h-40 rounded-lg`}):(0,q.jsx)(_i,{points:u.timeline})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`模型分布(按 Tokens)`}),f?(0,q.jsx)(Wr,{className:`h-24 rounded-lg`}):(0,q.jsx)(vi,{items:v,emptyText:`此范围内暂无模型用量`})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`用量构成`}),f?(0,q.jsx)(Wr,{className:`h-32 rounded-lg`}):u.usage?(0,q.jsx)(Ci,{usage:u.usage}):(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无数据`})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`Forward 端点分布(按请求数)`}),f?(0,q.jsx)(Wr,{className:`h-24 rounded-lg`}):(0,q.jsx)(Di,{endpoints:u.forwardEndpoints})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`同步不一致分布(按原因)`}),f?(0,q.jsx)(Wr,{className:`h-24 rounded-lg`}):(0,q.jsx)(Pi,{breakdown:g?.chat.sync_mismatch_breakdown})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:[`记忆趋势(近 `,l,` 天)`]}),f?(0,q.jsx)(Wr,{className:`h-40 rounded-lg`}):(0,q.jsx)(Wi,{points:u.memoryTimeline})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`最近会话(最多 20 条)`}),f?(0,q.jsx)(Wr,{className:`h-40 rounded-lg`}):(0,q.jsx)(xi,{sessions:u.sessions})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`最近 Forward 请求(最多 50 条)`}),f?(0,q.jsx)(Wr,{className:`h-40 rounded-lg`}):(0,q.jsx)(ji,{requests:u.forwardRequests})]})]})]})}function Yi(){let[e,t]=(0,G.useState)(null),[n,r]=(0,G.useState)(!0),[i,a]=(0,G.useState)(null),o=(0,G.useRef)(null),s=(0,G.useCallback)(async()=>{r(!0),a(null);try{let e=await w.get(`bamboo/config`);o.current=Array.isArray(e.model_limits)?e.model_limits:[],t(e)}catch(e){a(S(e))}finally{r(!1)}},[]);return(0,G.useEffect)(()=>{s()},[s]),{config:e,loading:n,loadError:i,reload:s,saveSection:(0,G.useCallback)(async e=>{let n={...e};n.model_limits===void 0&&o.current!==null&&(n.model_limits=o.current);let r=await W.validateBambooConfigPatch(n);if(!r.valid){let e=Object.values(r.errors??{}).flat().filter(Boolean)[0];throw Error(e?.message||`配置校验未通过`)}let i=await W.setBambooConfig(n);return o.current=Array.isArray(i.model_limits)?i.model_limits:[],t(i),i},[])}}function Xi({msg:e}){return e?(0,q.jsx)(`p`,{className:a(`text-xs`,e.kind===`error`?`text-destructive`:`text-muted-foreground`),children:e.text}):null}function Zi({config:e,saveSection:t}){let[n,r]=(0,G.useState)(()=>e.http_proxy??``),[i,a]=(0,G.useState)(()=>e.https_proxy??``),[o,c]=(0,G.useState)(!1),[l,u]=(0,G.useState)(null);return(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`代理`}),(0,q.jsxs)(`div`,{className:`space-y-2`,children:[(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`HTTP 代理`}),(0,q.jsx)(C,{placeholder:`http://proxy.example.com:8080`,value:n,onChange:e=>r(e.target.value)})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`HTTPS 代理`}),(0,q.jsx)(C,{placeholder:`https://proxy.example.com:8080`,value:i,onChange:e=>a(e.target.value)})]})]}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(Xi,{msg:l}),(0,q.jsx)(s,{size:`sm`,className:`ml-auto`,onClick:async()=>{c(!0),u(null);try{await t({http_proxy:n.trim(),https_proxy:i.trim()}),u({kind:`ok`,text:`已保存`})}catch(e){u({kind:`error`,text:S(e)})}finally{c(!1)}},disabled:o,children:o?`保存中…`:`保存`})]})]})}var Qi=1800;function $i({config:e,saveSection:t}){let[n,r]=(0,G.useState)(()=>e.memory?.auto_dream_enabled??!0),[i,a]=(0,G.useState)(()=>String(e.memory?.auto_dream_interval_secs??Qi)),[o,c]=(0,G.useState)(!1),[l,u]=(0,G.useState)(null);return(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`记忆`}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`text-sm`,children:`自动整理(auto-Dream)`}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`后台定期整理会话记忆`})]}),(0,q.jsx)(J,{checked:n,onCheckedChange:r})]}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(`div`,{className:`text-sm`,children:`整理间隔(秒)`}),(0,q.jsx)(C,{className:`w-28 text-right`,inputMode:`numeric`,placeholder:String(Qi),value:i,onChange:e=>a(e.target.value)})]}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(Xi,{msg:l}),(0,q.jsx)(s,{size:`sm`,className:`ml-auto`,onClick:async()=>{let e=Number(i);if(!Number.isInteger(e)||e<60){u({kind:`error`,text:`间隔需为不小于 60 的整数秒`});return}c(!0),u(null);try{await t({memory:{auto_dream_enabled:n,auto_dream_interval_secs:e}}),u({kind:`ok`,text:`已保存`})}catch(e){u({kind:`error`,text:S(e)})}finally{c(!1)}},disabled:o,children:o?`保存中…`:`保存`})]})]})}function ea({config:e,saveSection:t}){let[n,r]=(0,G.useState)(()=>{let t=e.subagents?.max_concurrent;return typeof t==`number`?String(t):``}),[i,a]=(0,G.useState)(!1),[o,c]=(0,G.useState)(null);return(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`子代理`}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`text-sm`,children:`最大并发数`}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`同时运行的子代理进程上限,留空使用默认(8)`})]}),(0,q.jsx)(C,{className:`w-24 text-right`,inputMode:`numeric`,placeholder:`8`,value:n,onChange:e=>r(e.target.value)})]}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(Xi,{msg:o}),(0,q.jsx)(s,{size:`sm`,className:`ml-auto`,onClick:async()=>{let e=n.trim(),r=null;if(e){let t=Number(e);if(!Number.isInteger(t)||t<1){c({kind:`error`,text:`并发上限需为不小于 1 的整数`});return}r=t}a(!0),c(null);try{await t({subagents:{max_concurrent:r}}),c({kind:`ok`,text:`已保存`})}catch(e){c({kind:`error`,text:S(e)})}finally{a(!1)}},disabled:i,children:i?`保存中…`:`保存`})]})]})}var ta=e=>[...new Set(e.map(e=>e.trim()).filter(Boolean))].sort();function na({config:e,saveSection:t}){let[n,r]=(0,G.useState)([]),[i,a]=(0,G.useState)(()=>ta((e.tools?.disabled??[]).filter(e=>typeof e==`string`))),[o,c]=(0,G.useState)(i),[l,u]=(0,G.useState)(!1),[d,f]=(0,G.useState)(null),[p,m]=(0,G.useState)(null),h=()=>{m(null),w.get(`bamboo/tools`).then(e=>r(ta(e.tools??[]))).catch(e=>m(S(e)))};(0,G.useEffect)(h,[]);let g=(0,G.useMemo)(()=>ta([...n,...i]),[n,i]),_=(0,G.useMemo)(()=>new Set(i),[i]),v=JSON.stringify(i)!==JSON.stringify(o),y=(e,t)=>{a(n=>{let r=new Set(n);return t?r.delete(e):r.add(e),ta([...r])})};return(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`工具`}),(0,q.jsx)(`button`,{onClick:h,"aria-label":`重新加载工具列表`,className:`rounded p-1 text-muted-foreground hover:text-foreground`,children:(0,q.jsx)(Me,{className:`size-3.5`})})]}),(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`关闭的工具将从模型可用工具中全局移除。`}),p?(0,q.jsxs)(`p`,{className:`text-xs text-destructive`,children:[`工具列表加载失败:`,p]}):null,g.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无工具`}):(0,q.jsx)(`ul`,{className:`max-h-56 space-y-1.5 overflow-y-auto pr-1`,children:g.map(e=>(0,q.jsxs)(`li`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(`code`,{className:`truncate font-mono text-xs`,children:e}),(0,q.jsx)(J,{checked:!_.has(e),onCheckedChange:t=>y(e,t),"aria-label":e})]},e))}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(Xi,{msg:d}),(0,q.jsx)(s,{size:`sm`,className:`ml-auto`,onClick:async()=>{u(!0),f(null);try{await t({tools:{disabled:i}}),c(i),f({kind:`ok`,text:`已保存`})}catch(e){f({kind:`error`,text:S(e)})}finally{u(!1)}},disabled:l||!v,children:l?`保存中…`:`保存`})]})]})}function ra({open:e,onOpenChange:t,title:n,description:r,confirmLabel:i=`确认`,destructive:a=!0,busy:o=!1,error:c,onConfirm:l}){return(0,q.jsx)(T,{open:e,onOpenChange:e=>o?void 0:t(e),children:(0,q.jsxs)(O,{className:`gap-0 p-4 sm:max-w-sm`,children:[(0,q.jsx)(y,{children:n}),(0,q.jsx)(g,{className:`mt-2 leading-relaxed`,children:r}),c?(0,q.jsx)(`p`,{className:`mt-2 text-xs text-destructive`,children:c}):null,(0,q.jsxs)(`div`,{className:`mt-4 flex justify-end gap-2`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,disabled:o,onClick:()=>t(!1),children:`取消`}),(0,q.jsx)(s,{size:`sm`,variant:a?`destructive`:`default`,disabled:o,onClick:l,children:o?`处理中…`:i})]})]})})}function ia({saveSection:e,configReady:t}){let[n,r]=(0,G.useState)(!0),[i,a]=(0,G.useState)(null),[o,c]=(0,G.useState)(!1),[l,u]=(0,G.useState)(!1),[d,f]=(0,G.useState)(``),[p,m]=(0,G.useState)(``),[h,g]=(0,G.useState)(``),[_,v]=(0,G.useState)(!1),[y,b]=(0,G.useState)(null),[x,w]=(0,G.useState)(!1),[T,E]=(0,G.useState)(!1),[D,O]=(0,G.useState)(null),k=o&&!l,A=(0,G.useCallback)(async()=>{r(!0),a(null);try{let e=await W.getAccessStatus();c(e.password_enabled),u(e.local_bypass)}catch(e){a(S(e))}finally{r(!1)}},[]);(0,G.useEffect)(()=>{A()},[A]);let j=async()=>{let e=p.trim();if(e.length<4){b({kind:`error`,text:`新密码至少 4 位`});return}if(e!==h.trim()){b({kind:`error`,text:`两次输入的密码不一致`});return}if(k&&!d.trim()){b({kind:`error`,text:`请输入当前密码`});return}v(!0),b(null);try{await W.updateAccessPassword({current_password:d.trim()||void 0,new_password:e}),f(``),m(``),g(``),b({kind:`ok`,text:o?`密码已更新`:`密码已启用`}),await A()}catch(e){b({kind:`error`,text:S(e)})}finally{v(!1)}},M=async()=>{E(!0),O(null);try{await e({access_control:{password_enabled:!1}}),w(!1),b({kind:`ok`,text:`访问密码已关闭`}),await A()}catch(e){O(S(e))}finally{E(!1)}};return(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`访问密码`}),n?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`}):i?(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsxs)(`p`,{className:`text-xs text-destructive`,children:[`状态加载失败:`,i]}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:()=>void A(),children:`重试`})]}):(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:o?l?`已启用。当前为本机/局域网访问,无需输入密码。`:`已启用。远程访问需要输入密码。`:`未启用。远程访问当前不需要密码,建议设置。`}),(0,q.jsxs)(`div`,{className:`space-y-2`,children:[k?(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`当前密码`}),(0,q.jsx)(C,{type:`password`,autoComplete:`current-password`,value:d,onChange:e=>f(e.target.value)})]}):null,(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:o?`新密码(至少 4 位)`:`设置密码(至少 4 位)`}),(0,q.jsx)(C,{type:`password`,autoComplete:`new-password`,value:p,onChange:e=>m(e.target.value)})]}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`确认密码`}),(0,q.jsx)(C,{type:`password`,autoComplete:`new-password`,value:h,onChange:e=>g(e.target.value)})]})]}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(Xi,{msg:y}),(0,q.jsxs)(`div`,{className:`ml-auto flex gap-2`,children:[o?(0,q.jsx)(s,{size:`sm`,variant:`secondary`,disabled:!t||_,onClick:()=>{O(null),w(!0)},children:`关闭密码`}):null,(0,q.jsx)(s,{size:`sm`,onClick:j,disabled:_||!p.trim(),children:_?`保存中…`:o?`更新密码`:`启用密码`})]})]}),(0,q.jsx)(ra,{open:x,onOpenChange:w,title:`关闭访问密码?`,description:`关闭后,远程访问将不再需要密码验证,立即生效。已配对设备的令牌不受影响。`,confirmLabel:`关闭密码`,busy:T,error:D,onConfirm:()=>void M()})]})}var aa={max_context_tokens:1e6,max_output_tokens:128e3,safety_margin:1e4},oa=0,sa=()=>`row-${oa++}`;function ca(e){return{id:sa(),model_pattern:e.model_pattern,max_context_tokens:String(e.max_context_tokens),max_output_tokens:e.max_output_tokens==null?``:String(e.max_output_tokens),safety_margin:e.safety_margin==null?``:String(e.safety_margin)}}function la(e){let t=e.trim();if(!t)return null;let n=Number(t);return Number.isInteger(n)?n:null}function ua(e){let t=new Set,n=[];for(let r of e){let e=r.model_pattern.trim();if(!e)return{error:`模型匹配串不能为空`};let i=e.toLowerCase();if(t.has(i))return{error:`模型 "${e}" 重复`};t.add(i);let a=la(r.max_context_tokens);if(a===null||a<1e3)return{error:`"${e}" 的上下文窗口需为不小于 1000 的整数`};let o=la(r.max_output_tokens);if(o===null||o<1)return{error:`"${e}" 的最大输出需为不小于 1 的整数`};if(o>a)return{error:`"${e}" 的最大输出不能超过上下文窗口`};let s;if(r.safety_margin.trim()){let t=la(r.safety_margin);if(t===null||t<0)return{error:`"${e}" 的安全余量需为非负整数`};if(t>=a)return{error:`"${e}" 的安全余量必须小于上下文窗口`};s=t}n.push({model_pattern:e,max_context_tokens:a,max_output_tokens:o,...s===void 0?{}:{safety_margin:s}})}return{overrides:n}}function da({config:e,saveSection:t}){let[n,r]=(0,G.useState)(aa),[i,a]=(0,G.useState)(()=>(e.model_limits??[]).map(ca)),[o,c]=(0,G.useState)(!1),[l,u]=(0,G.useState)(null),[d,f]=(0,G.useState)(!1),[p,m]=(0,G.useState)(null);(0,G.useEffect)(()=>{W.getModelLimitDefaults().then(e=>{let t=e.model_limits?.[0];t&&r({max_context_tokens:t.max_context_tokens||aa.max_context_tokens,max_output_tokens:t.max_output_tokens||aa.max_output_tokens,safety_margin:t.safety_margin||aa.safety_margin})}).catch(()=>{})},[]);let h=(e,t)=>{a(n=>n.map(n=>n.id===e?{...n,...t}:n))},g=()=>{a(e=>[...e,{id:sa(),model_pattern:``,max_context_tokens:String(n.max_context_tokens),max_output_tokens:String(n.max_output_tokens),safety_margin:``}])},y=async()=>{let e=ua(i);if(`error`in e){u({kind:`error`,text:e.error});return}c(!0),u(null);try{a(((await t({model_limits:e.overrides})).model_limits??[]).map(ca)),u({kind:`ok`,text:`已保存`})}catch(e){u({kind:`error`,text:S(e)})}finally{c(!1)}},b=async()=>{c(!0),m(null);try{await t({model_limits:[]}),a([]),f(!1),u({kind:`ok`,text:`已恢复为全局默认`})}catch(e){m(S(e))}finally{c(!1)}};return(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`模型限额`}),(0,q.jsxs)(s,{size:`sm`,variant:`secondary`,onClick:g,children:[(0,q.jsx)(_,{className:`size-4`}),` 新增`]})]}),(0,q.jsxs)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:[`按模型覆盖 token 预算;未覆盖的模型使用全局默认:上下文`,` `,n.max_context_tokens.toLocaleString(),` / 输出`,` `,n.max_output_tokens.toLocaleString(),` / 安全余量`,` `,n.safety_margin.toLocaleString(),`。`]}),i.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无覆盖,全部模型使用全局默认。`}):(0,q.jsx)(`ul`,{className:`space-y-2`,children:i.map(e=>(0,q.jsxs)(`li`,{className:`space-y-1.5 rounded-md border bg-muted/30 p-2`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,q.jsx)(C,{className:`flex-1 font-mono text-xs`,placeholder:`模型匹配串(如 gpt-4o)`,value:e.model_pattern,onChange:t=>h(e.id,{model_pattern:t.target.value})}),(0,q.jsx)(`button`,{onClick:()=>a(t=>t.filter(t=>t.id!==e.id)),"aria-label":`删除`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(v,{className:`size-3.5`})})]}),(0,q.jsxs)(`div`,{className:`grid grid-cols-3 gap-2`,children:[(0,q.jsxs)(`div`,{className:`space-y-0.5`,children:[(0,q.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,children:`上下文窗口`}),(0,q.jsx)(C,{inputMode:`numeric`,value:e.max_context_tokens,onChange:t=>h(e.id,{max_context_tokens:t.target.value})})]}),(0,q.jsxs)(`div`,{className:`space-y-0.5`,children:[(0,q.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,children:`最大输出`}),(0,q.jsx)(C,{inputMode:`numeric`,value:e.max_output_tokens,onChange:t=>h(e.id,{max_output_tokens:t.target.value})})]}),(0,q.jsxs)(`div`,{className:`space-y-0.5`,children:[(0,q.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,children:`安全余量(可选)`}),(0,q.jsx)(C,{inputMode:`numeric`,placeholder:String(n.safety_margin),value:e.safety_margin,onChange:t=>h(e.id,{safety_margin:t.target.value})})]})]})]},e.id))}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(Xi,{msg:l}),(0,q.jsxs)(`div`,{className:`ml-auto flex gap-2`,children:[(0,q.jsx)(s,{size:`sm`,variant:`secondary`,disabled:o,onClick:()=>{m(null),f(!0)},children:`全部恢复默认`}),(0,q.jsx)(s,{size:`sm`,onClick:y,disabled:o,children:o?`保存中…`:`保存`})]})]}),(0,q.jsx)(ra,{open:d,onOpenChange:f,title:`清除全部模型限额?`,description:`将删除所有按模型的覆盖,全部模型恢复为全局默认限额。`,confirmLabel:`清除`,busy:o,error:p,onConfirm:()=>void b()})]})}var fa=[{value:`placeholder`,label:`占位文本替换`},{value:`error`,label:`直接报错`},{value:`ocr`,label:`OCR 提取文本`}];function pa(e){let t=String(e??`placeholder`).trim().toLowerCase();return t===`error`||t===`ocr`?t:`placeholder`}function ma({config:e,saveSection:t}){let[n,r]=(0,G.useState)(()=>e.hooks?.image_fallback?.enabled===!0),[i,a]=(0,G.useState)(()=>pa(e.hooks?.image_fallback?.mode)),[o,s]=(0,G.useState)(!1),[c,l]=(0,G.useState)(null),u=async(e,o)=>{let c={enabled:n,mode:i};r(e),a(o),s(!0),l(null);try{await t({hooks:{image_fallback:{enabled:e,mode:o}}}),l({kind:`ok`,text:`已保存`})}catch(e){r(c.enabled),a(c.mode),l({kind:`error`,text:S(e)})}finally{s(!1)}};return(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`Hooks`}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`div`,{className:`text-sm`,children:`图片预检回退`}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`当模型不支持图片输入时,按所选方式处理图片内容`})]}),(0,q.jsx)(J,{checked:n,disabled:o,onCheckedChange:e=>void u(e,i)})]}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(`div`,{className:`text-sm`,children:`回退方式`}),(0,q.jsxs)(Ce,{value:i,disabled:!n||o,onValueChange:e=>void u(n,e),children:[(0,q.jsx)(de,{className:`w-44`,size:`sm`,children:(0,q.jsx)(z,{})}),(0,q.jsx)(_e,{children:fa.map(e=>(0,q.jsx)(V,{value:e.value,children:e.label},e.value))})]})]}),(0,q.jsx)(Xi,{msg:c})]})}var ha={all:`删除全部会话`,empty:`删除空会话`,children:`删除子会话`};function ga(){let e=Se(e=>e.chats),t=Se(e=>e.currentSessionId),n=Se(e=>e.loadChats),r=Se(e=>e.refreshChats),i=Se(e=>e.loadChatHistory),[a,o]=(0,G.useState)(!0),[c,l]=(0,G.useState)(null),[u,d]=(0,G.useState)(!1),[f,p]=(0,G.useState)(null),[m,h]=(0,G.useState)(null),g=(0,G.useMemo)(()=>t?e.find(e=>e.id===t)??null:null,[e,t]),_=e=>{switch(e.type){case`clear-current`:return{title:`清空当前会话消息?`,description:`将删除当前会话的全部消息与事件记录,会话本身保留。此操作不可撤销。`,label:`清空`};case`cleanup`:{let t=e.mode===`all`?`全部会话`:e.mode===`empty`?`所有空会话`:`所有子会话`;return{title:`${ha[e.mode]}?`,description:`将删除${t}${a?`(已置顶的会话会保留)`:`(包括已置顶的会话)`}。此操作不可撤销。`,label:`删除`}}case`dev-reset`:return{title:`重置会话存储?`,description:`开发用途:删除后端全部会话数据并重建索引。此操作不可撤销。`,label:`重置`}}},v=async()=>{if(c){d(!0),p(null);try{c.type===`clear-current`?(await me.clearSession(c.sessionId),await i(c.sessionId),await r(),h({kind:`ok`,text:`当前会话已清空`})):c.type===`cleanup`?(await me.cleanupSessions(c.mode,a),await n(),h({kind:`ok`,text:`清理完成`})):(await me.devResetSessions(),await n(),h({kind:`ok`,text:`会话存储已重置`})),l(null)}catch(e){p(S(e))}finally{d(!1)}}},y=e=>{p(null),h(null),l(e)},b=c?_(c):null;return(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`会话维护`}),(0,q.jsxs)(`div`,{className:`space-y-1`,children:[(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`当前会话`}),g?(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsxs)(`div`,{className:`min-w-0`,children:[(0,q.jsx)(`div`,{className:`truncate text-sm`,children:g.title||g.id}),(0,q.jsxs)(`div`,{className:`truncate text-xs text-muted-foreground`,children:[g.kind===`child`?`子会话`:`根会话`,` · `,g.id]})]}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:()=>y({type:`clear-current`,sessionId:g.id}),children:`清空消息`})]}):(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`暂无活动会话`})]}),(0,q.jsxs)(`div`,{className:`space-y-2 border-t pt-2`,children:[(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,q.jsx)(`div`,{className:`text-sm`,children:`批量清理时保留已置顶`}),(0,q.jsx)(J,{checked:a,onCheckedChange:o})]}),(0,q.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:[`all`,`empty`,`children`].map(e=>(0,q.jsx)(s,{size:`sm`,variant:`destructive`,onClick:()=>y({type:`cleanup`,mode:e}),children:ha[e]},e))})]}),(0,q.jsxs)(`div`,{className:`space-y-1 border-t pt-2`,children:[(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`开发重置:删除后端全部会话数据并重建索引`}),(0,q.jsx)(s,{size:`sm`,variant:`destructive`,onClick:()=>y({type:`dev-reset`}),children:`重置会话存储`})]}),(0,q.jsx)(Xi,{msg:m}),c&&b?(0,q.jsx)(ra,{open:!0,onOpenChange:e=>{e||l(null)},title:b.title,description:b.description,confirmLabel:b.label,busy:u,error:f,onConfirm:()=>void v()}):null]})}var{artifact:_a,publicMetadata:va}=r();function ya(){let[e,t]=(0,G.useState)(null),[n,r]=(0,G.useState)(!1),[i,a]=(0,G.useState)(null),[o,c]=(0,G.useState)(null),[l,u]=(0,G.useState)(De());(0,G.useEffect)(()=>re(()=>u(De())),[]);let d=e=>{u(e),Ee(e),window.dispatchEvent(new Event(we))},f=()=>{localStorage.clear(),t(null),c({kind:`ok`,text:`本地缓存已清除,即将刷新…`}),window.setTimeout(()=>window.location.reload(),600)},p=async()=>{r(!0),a(null);try{await me.cleanupSessions(`all`,!1),await W.resetSetupStatus(),await W.resetBambooConfig(),localStorage.clear(),t(null),c({kind:`ok`,text:`已重置,即将刷新…`}),window.setTimeout(()=>window.location.reload(),1200)}catch(e){a(S(e)),r(!1)}};return(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:`应用`}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between text-sm`,children:[(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:`前端版本`}),(0,q.jsxs)(`span`,{className:`font-mono text-xs`,children:[`v`,_a.version,va.development?` (dev)`:``]})]}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-3 border-t pt-2`,children:[(0,q.jsxs)(`div`,{className:`min-w-0 space-y-0.5`,children:[(0,q.jsx)(`div`,{className:`text-sm`,children:`图形兼容模式`}),(0,q.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:`禁用模糊与玻璃效果,适用于虚拟桌面(VDI)、远程或图形受限环境。`})]}),(0,q.jsx)(J,{checked:l,onCheckedChange:d})]}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between gap-2 border-t pt-2`,children:[(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`清除浏览器本地缓存并刷新页面`}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:()=>t(`clear-storage`),children:`清除本地缓存`})]}),(0,q.jsxs)(`div`,{className:`space-y-1.5 border-t pt-2`,children:[(0,q.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs font-medium text-destructive`,children:[(0,q.jsx)(ke,{className:`size-3.5`}),` 危险区`]}),(0,q.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:`完全重置:删除全部会话(含置顶)、重置后端配置、清除本地缓存,并重新进入初始化流程。`}),(0,q.jsx)(s,{size:`sm`,variant:`destructive`,onClick:()=>t(`reset-app`),children:`重置应用`})]}),(0,q.jsx)(Xi,{msg:o}),(0,q.jsx)(ra,{open:e===`clear-storage`,onOpenChange:e=>{e||t(null)},title:`清除本地缓存?`,description:`将清空浏览器 localStorage(界面偏好等本地状态)并刷新页面,后端数据不受影响。`,confirmLabel:`清除并刷新`,onConfirm:f}),(0,q.jsx)(ra,{open:e===`reset-app`,onOpenChange:e=>{!e&&!n&&t(null)},title:`重置整个应用?`,description:`将删除全部会话(包括已置顶)、重置后端 config.json、清除本地缓存,并在刷新后重新进入初始化流程。此操作不可撤销。`,confirmLabel:`确认重置`,busy:n,error:i,onConfirm:()=>void p()})]})}function ba(){let{config:e,loading:t,loadError:n,reload:r,saveSection:i}=Yi(),a=K(e=>e.isAdvanced);return(0,q.jsxs)(`div`,{className:`space-y-3`,children:[t?(0,q.jsxs)(`div`,{className:`space-y-3`,children:[(0,q.jsx)(Wr,{className:`h-24 w-full rounded-lg`}),(0,q.jsx)(Wr,{className:`h-24 w-full rounded-lg`}),(0,q.jsx)(Wr,{className:`h-24 w-full rounded-lg`})]}):n?(0,q.jsxs)(`section`,{className:`space-y-2 rounded-lg border p-3`,children:[(0,q.jsxs)(`p`,{className:`text-xs text-destructive`,children:[`配置加载失败:`,n]}),(0,q.jsx)(s,{size:`sm`,variant:`secondary`,onClick:()=>void r(),children:`重试`})]}):e?(0,q.jsxs)(q.Fragment,{children:[a?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(Zi,{config:e,saveSection:i}),(0,q.jsx)($i,{config:e,saveSection:i}),(0,q.jsx)(ea,{config:e,saveSection:i}),(0,q.jsx)(na,{config:e,saveSection:i})]}):null,(0,q.jsx)(da,{config:e,saveSection:i}),a?(0,q.jsx)(ma,{config:e,saveSection:i}):null]}):null,a?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(ia,{saveSection:i,configReady:!!e}),(0,q.jsx)(ga,{})]}):null,(0,q.jsx)(ya,{})]})}var xa=[`user`,`feedback`,`project`,`reference`],Sa=[`active`,`stale`,`superseded`,`contradicted`,`archived`],Ca=[`day`,`week`,`month`,`quarter`,`year`],wa={queryChars:512,pageSize:20,titleChars:160,bodyChars:4e3,tags:32,tagChars:64,keywords:32,entities:16,retrievalTermChars:96,detailChars:6e3},Ta=class extends Error{code;constructor(e){super(e),this.code=e,this.name=`JianduMemoryApiError`}},Ea=e=>typeof e==`object`&&!!e&&!Array.isArray(e),$=e=>{throw new Ta(e)},Da=e=>Ea(e)?e:$(`malformed_response`),Oa=(e,t)=>{let n=e[t];return typeof n==`string`&&n.length>0?n:$(`malformed_response`)},ka=(e,t)=>{let n=e[t];if(n!=null)return typeof n==`string`&&n.length>0?n:$(`malformed_response`)},Aa=(e,t)=>typeof e[t]==`boolean`?e[t]:$(`malformed_response`),ja=(e,t)=>{let n=e[t];return typeof n==`number`&&Number.isInteger(n)&&n>=0?n:$(`malformed_response`)},Ma=e=>e===void 0?[]:!Array.isArray(e)||!e.every(e=>typeof e==`string`)?$(`malformed_response`):e,Na=(e,t)=>typeof e==`string`&&t.includes(e)?e:$(`malformed_response`),Pa=e=>{try{return Da(JSON.parse(e))}catch(e){if(e instanceof Ta)throw e;return $(`malformed_response`)}},Fa=(e,t)=>{if(j(e)){if(e.status===401||e.status===403)return $(`access_denied`);if(t&&e.status===404)return $(`context_unavailable`);if(!t)return $(`action_rejected`)}return $(`request_failed`)},Ia=(e,t)=>{let n=Da(Da(e).session),r=Oa(n,`id`);if(r!==t)return $(`malformed_response`);let i=Na(n.kind,[`root`,`child`]),a=Oa(n,`root_session_id`),o=n.project_id;return{id:r,kind:i,rootSessionId:a,projectId:o==null?void 0:typeof o==`string`&&o.trim().length>0?o.trim():$(`malformed_response`),title:Oa(n,`title`)}},La=e=>{(!e.activeSessionId.trim()||!e.authoritySessionId.trim()||!e.projectId.trim())&&$(`context_unavailable`)},Ra=(e,t)=>{if(e.scope!==`project`)return $(`malformed_response`);let n=e.project_key;n!=null&&n!==t.projectId&&$(`malformed_response`)},za=(e,t)=>{let n=Da(e);Ra(n,t);let r=ka(n,`granularity`);return{id:Oa(n,`id`),title:Oa(n,`title`),type:Na(n.type,xa),status:Na(n.status,Sa),summary:typeof n.summary==`string`?n.summary:$(`malformed_response`),tags:Ma(n.tags),...r?{granularity:Na(r,Ca)}:{}}},Ba=(e,t,n)=>{let r=[...new Set((e??[]).map(e=>e.trim()).filter(Boolean))];return r.length>t||r.some(e=>[...e].length>n)?$(`invalid_input`):r},Va=e=>{let t=e.title.trim(),n=e.content.trim();return!t||!n||[...t].length>wa.titleChars||[...n].length>wa.bodyChars||!xa.includes(e.type)||e.granularity!==void 0&&!Ca.includes(e.granularity)?$(`invalid_input`):{title:t,content:n,type:e.type,tags:Ba(e.tags,wa.tags,wa.tagChars),keywords:Ba(e.keywords,wa.keywords,wa.retrievalTermChars),entities:Ba(e.entities,wa.entities,wa.retrievalTermChars),...e.granularity?{granularity:e.granularity}:{}}},Ha=e=>{let t=Va(e);return Array.from([t.title,...t.keywords,...t.entities].join(` `)).slice(0,wa.queryChars).join(``)},Ua=(e,t)=>({name:e,value:JSON.stringify(t)}),Wa=class{async getSession(e){try{return Ia(await w.get(`sessions/${encodeURIComponent(e)}`),e)}catch(e){if(e instanceof Ta)throw e;return Fa(e,!0)}}async resolveProjectContext(e){let t=e.trim();if(!t)return $(`context_unavailable`);let n=await this.getSession(t),r=n.kind===`child`?await this.getSession(n.rootSessionId):n;return r.kind!==`root`||r.rootSessionId!==r.id||!r.projectId||n.projectId!==r.projectId?$(`context_unavailable`):{activeSessionId:n.id,activeSessionTitle:n.title,authoritySessionId:r.id,authoritySessionTitle:r.title,projectId:r.projectId}}async execute(e,t,n){La(e);try{let r=Pa(Oa(Da(await w.post(`tools/execute`,{tool_name:`memory`,session_id:e.authoritySessionId,parameters:[[`action`,t],...n].map(([e,t])=>Ua(e,t))})),`result`));if(r.tool_name!==`memory`||typeof r.display_preference!=`string`)return $(`malformed_response`);if(r.success!==!0)return $(`action_rejected`);let i=Pa(Oa(r,`result`));return i.action===t?i:$(`malformed_response`)}catch(e){if(e instanceof Ta)throw e;return Fa(e,!1)}}async queryProjectMemories(e,t={}){let n=t.query?.trim()??``,r=t.limit??wa.pageSize;if([...n].length>wa.queryChars||!Number.isInteger(r)||r<1||r>wa.pageSize)return $(`invalid_input`);let i=t.filters?{type:Ga(t.filters.type,xa),status:Ga(t.filters.status,Sa),granularity:Ga(t.filters.granularity,Ca)}:void 0,a=t.cursor?.trim();if(t.cursor!==void 0&&(!a||a.length>2048))return $(`invalid_input`);let o={limit:r,...a?{cursor:a}:{}},s=await this.execute(e,`query`,[[`scope`,`project`],[`query`,n],...i?[[`filters`,i]]:[],[`options`,o]]);if(s.success!==!0)return $(`action_rejected`);let c=Da(s.data);if(!Array.isArray(c.items))return $(`malformed_response`);let l=c.items.map(t=>za(t,e)),u=ja(c,`returned_count`),d=ja(c,`matched_count`),f=ja(c,`remaining_count`);if(u!==l.length||u>d)return $(`malformed_response`);let p=ka(c,`next_cursor`);return{items:l,returnedCount:u,matchedCount:d,remainingCount:f,truncated:Aa(c,`truncated`),...p?{nextCursor:p}:{}}}async getProjectMemory(e,t){let n=Ka(t),r=await this.execute(e,`get`,[[`id`,n],[`options`,{max_chars:wa.detailChars}]]);if(Oa(r,`id`)!==n)return $(`malformed_response`);let i=Da(r.memory),a=Da(i.frontmatter);if(Oa(a,`id`)!==n)return $(`malformed_response`);Ra(a,e);let o=Da(a.retrieval),s=ka(a,`granularity`);return{id:n,title:Oa(a,`title`),type:Na(a.type,xa),status:Na(a.status,Sa),summary:``,tags:Ma(a.tags),...s?{granularity:Na(s,Ca)}:{},body:typeof i.body==`string`?i.body:$(`malformed_response`),bodyTruncated:Aa(i,`body_truncated`),retrievalMetadataTruncated:Aa(i,`retrieval_metadata_truncated`),createdAt:Oa(a,`created_at`),updatedAt:Oa(a,`updated_at`),keywords:Ma(o.keywords),entities:Ma(o.entities)}}async createProjectMemory(e,t){let n=Va(t),r=[[`scope`,`project`],[`type`,n.type],[`title`,n.title],[`content`,n.content],[`tags`,n.tags],[`keywords`,n.keywords],[`entities`,n.entities]];n.granularity&&r.push([`granularity`,n.granularity]),r.push([`options`,{allow_merge_if_similar:!1}]);let i=Da((await this.execute(e,`write`,r)).memory);Ra(i,e);let a=Na(i.status,Sa),o=Oa(i,`title`),s=Na(i.type,xa);return a!==`active`||o!==n.title||s!==n.type?$(`malformed_response`):{id:Oa(i,`id`),title:o,type:s,status:a}}async archiveProjectMemory(e,t){let n=Ka(t),r=await this.execute(e,`purge`,[[`id`,n],[`mode`,`archived`]]);if(Oa(r,`id`)!==n||r.status!==`archived`)return $(`malformed_response`)}},Ga=(e,t)=>{let n=e??[];return n.every(e=>t.includes(e))?n:$(`invalid_input`)},Ka=e=>{let t=e.trim();return!t||[...t].length>128?$(`invalid_input`):t},qa=(e,t)=>e.activeSessionId===t.activeSessionId&&e.authoritySessionId===t.authoritySessionId&&e.projectId===t.projectId,Ja=new Wa,Ya={title:``,type:`project`,content:``,tags:``,keywords:``,entities:``,granularity:``},Xa=e=>{if(!(e instanceof Ta))return`unavailable`;switch(e.code){case`invalid_input`:return`invalid`;case`context_unavailable`:return`context`;case`access_denied`:return`denied`;case`action_rejected`:return`rejected`;case`malformed_response`:return`malformed`;case`request_failed`:return`unavailable`}},Za=e=>e.split(`,`).map(e=>e.trim()).filter(Boolean),Qa=e=>({title:e.title,type:e.type,content:e.content,tags:Za(e.tags),keywords:Za(e.keywords),entities:Za(e.entities),...e.granularity?{granularity:e.granularity}:{}}),$a=(e,t)=>{let n=new Map(e.map(e=>[e.id,e]));return t.forEach(e=>n.set(e.id,e)),[...n.values()]};function eo({api:e=Ja}){let{t}=d(),n=Se(e=>e.currentSessionId),r=(0,G.useRef)(n);r.current=n;let i=(0,G.useRef)(0),a=(0,G.useRef)(0),o=(0,G.useRef)(0),c=(0,G.useRef)(0),l=(0,G.useRef)(0),[u,f]=(0,G.useState)(0),[p,m]=(0,G.useState)(null),[h,_]=(0,G.useState)(!1),[v,b]=(0,G.useState)(null),[x,S]=(0,G.useState)(``),[w,E]=(0,G.useState)(``),[D,k]=(0,G.useState)(`active`),[A,j]=(0,G.useState)(`active`),[M,N]=(0,G.useState)([]),[P,F]=(0,G.useState)(null),[ee,I]=(0,G.useState)(!1),[L,te]=(0,G.useState)(null),[R,ne]=(0,G.useState)(null),[re,ie]=(0,G.useState)(null),[ae,oe]=(0,G.useState)(null),[se,ce]=(0,G.useState)(!1),[le,ue]=(0,G.useState)(Ya),[fe,pe]=(0,G.useState)(null),[me,ge]=(0,G.useState)(!1),[ve,ye]=(0,G.useState)(null),[B,be]=(0,G.useState)(null),[xe,we]=(0,G.useState)(null),[Te,U]=(0,G.useState)(null),[Ee,De]=(0,G.useState)(null),W=(0,G.useCallback)(async(t,n,r,o,s,c)=>{let l=++a.current;I(!0),te(null);try{let u=await e.queryProjectMemories(t,{query:n,filters:{status:[r]},...o?{cursor:o}:{}});return i.current!==c||a.current!==l?`stale`:(N(e=>s?$a(e,u.items):u.items),F(u),`ok`)}catch(e){return i.current!==c||a.current!==l?`stale`:(te(Xa(e)),s||(N([]),F(null)),`failed`)}finally{i.current===c&&a.current===l&&I(!1)}},[e]),Oe=(0,G.useCallback)(e=>{let t=i.current;t===e&&(i.current=t+1)},[]);(0,G.useEffect)(()=>{let t=++i.current;if(++a.current,++o.current,++c.current,++l.current,m(null),b(null),_(!!n),S(``),E(``),k(`active`),j(`active`),N([]),F(null),te(null),I(!1),ne(null),ie(null),oe(null),ce(!1),ue(Ya),pe(null),ge(!1),ye(null),be(null),we(null),U(null),De(null),!n){b(`context`);return}return e.resolveProjectContext(n).then(e=>{i.current!==t||r.current!==n||(m(e),_(!1),W(e,``,`active`,void 0,!1,t))}).catch(e=>{i.current!==t||r.current!==n||(_(!1),b(Xa(e)))}),()=>Oe(t)},[e,n,Oe,W,u]);let ke=(0,G.useCallback)(e=>{++i.current,++a.current,++o.current,++c.current,++l.current,m(null),S(``),E(``),k(`active`),j(`active`),N([]),F(null),I(!1),te(null),ne(null),ie(null),oe(null),ce(!1),ue(Ya),pe(null),ge(!1),ye(null),be(null),we(null),U(null),De(null),b(e),_(!1)},[]),Ae=(0,G.useCallback)(async(t,n)=>{let a=r.current;if(!a||i.current!==n)return null;try{let o=await e.resolveProjectContext(a);return i.current!==n||r.current!==a?null:qa(t,o)?o:(ke(`context`),null)}catch(e){return i.current===n&&ke(Xa(e)),null}},[e,ke]),je=()=>{if(!p)return;let e=x.trim(),t=D;E(e),j(t),De(null),W(p,e,t,void 0,!1,i.current)},Me=async t=>{if(!p)return;let n=++o.current,r=i.current;ne(null),oe(null),ie(t.id);try{let a=await e.getProjectMemory(p,t.id);if(i.current!==r||o.current!==n)return;ne(a)}catch(e){i.current===r&&o.current===n&&oe(Xa(e))}finally{i.current===r&&o.current===n&&ie(null)}},Ne=()=>{++o.current,ne(null),oe(null),ie(null),we(null),U(null)},Pe=(0,G.useMemo)(()=>JSON.stringify(le),[le]),Fe=(e,t)=>{++c.current,ue(n=>({...n,[e]:t})),pe(null),ge(!1),ye(null)},Ie=()=>{ue(Ya),pe(null),ye(null),ce(!0)},Le=()=>{B!==`create`&&(++c.current,ce(!1),ue(Ya),pe(null),ye(null))},K=async()=>{if(!p||me||B)return;let t=Qa(le);try{Va(t)}catch(e){ye(Xa(e));return}let n=Pe,r=++c.current,a=i.current;ge(!0),pe(null),ye(null);try{let o=await e.queryProjectMemories(p,{query:``,limit:1});if(i.current!==a||c.current!==r)return;let s=o.matchedCount===0?o:await e.queryProjectMemories(p,{query:Ha(t),limit:5});if(i.current!==a||c.current!==r)return;pe({fingerprint:n,items:s.items,truncated:s.truncated})}catch(e){i.current===a&&c.current===r&&ye(Xa(e))}finally{i.current===a&&c.current===r&&ge(!1)}},Re=async()=>{if(!p||B||!fe||fe.fingerprint!==Pe)return;let t=Qa(le);try{Va(t)}catch(e){ye(Xa(e));return}let n=i.current,r=++l.current;be(`create`),ye(null);let a=await Ae(p,n);if(!a||i.current!==n||l.current!==r){l.current===r&&be(null);return}try{let o=await e.createProjectMemory(a,t);if(i.current!==n||l.current!==r)return;ce(!1),pe(null),De({kind:`created`,title:o.title}),await W(a,w,A,void 0,!1,n)===`failed`&&l.current===r&&De({kind:`createdRefreshFailed`,title:o.title})}catch(e){i.current===n&&l.current===r&&ye(Xa(e))}finally{i.current===n&&l.current===r&&be(null)}},ze=async()=>{let t=xe;if(!p||!t||B)return;let n=i.current,r=++l.current;be(`archive`),U(null);let a=await Ae(p,n);if(!a||i.current!==n||l.current!==r){l.current===r&&be(null);return}try{if(await e.archiveProjectMemory(a,t.id),i.current!==n||l.current!==r)return;we(null),Ne(),De({kind:`archived`,title:t.title}),await W(a,w,A,void 0,!1,n)===`failed`&&l.current===r&&De({kind:`archivedRefreshFailed`,title:t.title})}catch(e){i.current===n&&l.current===r&&U(Xa(e))}finally{i.current===n&&l.current===r&&be(null)}},Be=e=>t(`settings.jiandu.errors.${e}`),Ve=e=>t(`settings.jiandu.types.${e}`),He=e=>t(`settings.jiandu.statuses.${e}`);return(0,q.jsxs)(`div`,{className:`mx-auto max-w-3xl space-y-4`,children:[(0,q.jsx)(`header`,{className:`space-y-1`,children:(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`h2`,{className:`text-lg font-semibold`,children:t(`settings.jiandu.title`)}),(0,q.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:t(`settings.jiandu.description`)})]}),(0,q.jsx)(s,{onClick:Ie,disabled:!p||h,children:t(`settings.jiandu.create.open`)})]})}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,"aria-label":t(`settings.jiandu.context.label`),children:[(0,q.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:t(`settings.jiandu.context.label`)}),h?(0,q.jsx)(`p`,{className:`mt-1 text-sm`,children:t(`settings.jiandu.context.loading`)}):p?(0,q.jsxs)(`dl`,{className:`mt-2 grid gap-2 text-sm sm:grid-cols-2`,children:[(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`dt`,{className:`text-xs text-muted-foreground`,children:t(`settings.jiandu.context.session`)}),(0,q.jsx)(`dd`,{className:`break-words font-medium`,children:p.activeSessionTitle})]}),(0,q.jsxs)(`div`,{children:[(0,q.jsx)(`dt`,{className:`text-xs text-muted-foreground`,children:t(`settings.jiandu.context.project`)}),(0,q.jsx)(`dd`,{className:`break-all font-mono text-xs`,children:p.projectId})]}),p.activeSessionId===p.authoritySessionId?null:(0,q.jsxs)(`div`,{className:`sm:col-span-2`,children:[(0,q.jsx)(`dt`,{className:`text-xs text-muted-foreground`,children:t(`settings.jiandu.context.rootSession`)}),(0,q.jsx)(`dd`,{children:p.authoritySessionTitle})]})]}):(0,q.jsxs)(`div`,{className:`mt-2 space-y-2`,children:[(0,q.jsx)(`p`,{role:`alert`,className:`text-sm text-destructive`,children:Be(v??`context`)}),n?(0,q.jsx)(s,{variant:`outline`,size:`sm`,onClick:()=>f(e=>e+1),children:t(`settings.jiandu.context.retry`)}):null]})]}),Ee?(0,q.jsx)(`p`,{role:`status`,className:`rounded-lg border border-primary/30 bg-primary/5 p-3 text-sm`,children:t(`settings.jiandu.notices.${Ee.kind}`,{title:Ee.title})}):null,p?(0,q.jsxs)(q.Fragment,{children:[(0,q.jsxs)(`form`,{className:`flex flex-col gap-2 sm:flex-row`,onSubmit:e=>{e.preventDefault(),je()},children:[(0,q.jsx)(C,{"aria-label":t(`settings.jiandu.search.label`),value:x,maxLength:wa.queryChars,onChange:e=>S(e.target.value),placeholder:t(`settings.jiandu.search.placeholder`)}),(0,q.jsxs)(Ce,{value:D,disabled:ee,onValueChange:e=>k(e),children:[(0,q.jsx)(de,{className:`w-full sm:w-36`,"aria-label":t(`settings.jiandu.search.statusLabel`),children:(0,q.jsx)(z,{})}),(0,q.jsxs)(_e,{className:`z-[150]`,children:[(0,q.jsx)(V,{value:`active`,children:He(`active`)}),(0,q.jsx)(V,{value:`archived`,children:He(`archived`)})]})]}),(0,q.jsx)(s,{type:`submit`,disabled:ee,children:t(`settings.jiandu.search.action`)}),(0,q.jsx)(s,{type:`button`,variant:`outline`,disabled:ee,onClick:()=>void W(p,w,A,void 0,!1,i.current),children:t(`settings.jiandu.search.refresh`)})]}),L?(0,q.jsx)(`p`,{role:`alert`,className:`rounded-lg border border-destructive/40 p-3 text-sm text-destructive`,children:Be(L)}):null,P?(0,q.jsxs)(`div`,{className:`flex flex-wrap gap-x-4 gap-y-1 text-xs text-muted-foreground`,children:[(0,q.jsx)(`span`,{children:t(`settings.jiandu.list.count`,{visible:M.length,matched:P.matchedCount})}),P.truncated?(0,q.jsx)(`span`,{children:t(`settings.jiandu.list.truncated`)}):null,P.remainingCount>0?(0,q.jsx)(`span`,{children:t(`settings.jiandu.list.remaining`,{count:P.remainingCount})}):null]}):null,M.length>0?(0,q.jsx)(`ul`,{className:`space-y-2`,"aria-label":t(`settings.jiandu.list.label`),children:M.map(e=>(0,q.jsxs)(`li`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`button`,{type:`button`,className:`max-w-full break-words text-left text-sm font-semibold hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring`,disabled:re===e.id,onClick:()=>void Me(e),children:e.title}),(0,q.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-1.5`,children:[(0,q.jsx)(H,{variant:`outline`,children:Ve(e.type)}),(0,q.jsx)(H,{variant:e.status===`archived`?`secondary`:`outline`,children:He(e.status)}),e.granularity?(0,q.jsx)(H,{variant:`outline`,children:e.granularity}):null]}),(0,q.jsx)(`p`,{className:`mt-2 whitespace-pre-wrap break-words text-sm text-muted-foreground`,children:e.summary})]},e.id))}):P&&!ee?(0,q.jsx)(`p`,{className:`rounded-lg border p-4 text-sm text-muted-foreground`,children:t(`settings.jiandu.list.empty`)}):null,ee?(0,q.jsx)(`p`,{role:`status`,children:t(`settings.jiandu.list.loading`)}):null,P?.nextCursor?(0,q.jsx)(s,{variant:`outline`,className:`w-full`,disabled:ee,onClick:()=>void W(p,w,A,P.nextCursor,!0,i.current),children:t(`settings.jiandu.list.more`)}):null]}):null,(0,q.jsx)(T,{open:!!(R||re||ae),onOpenChange:e=>e?null:Ne(),children:(0,q.jsxs)(O,{showCloseButton:!1,className:`gap-4 p-5 sm:max-w-2xl`,children:[(0,q.jsx)(y,{children:R?.title??t(`settings.jiandu.detail.title`)}),re?(0,q.jsx)(`p`,{role:`status`,children:t(`settings.jiandu.detail.loading`)}):null,ae?(0,q.jsx)(`p`,{role:`alert`,className:`text-sm text-destructive`,children:Be(ae)}):null,R?(0,q.jsxs)(`div`,{className:`min-h-0 space-y-3 overflow-y-auto`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap gap-1.5`,children:[(0,q.jsx)(H,{variant:`outline`,children:Ve(R.type)}),(0,q.jsx)(H,{variant:R.status===`archived`?`secondary`:`outline`,children:He(R.status)})]}),R.bodyTruncated||R.retrievalMetadataTruncated?(0,q.jsx)(`p`,{role:`status`,className:`text-xs text-amber-600 dark:text-amber-400`,children:R.bodyTruncated?t(`settings.jiandu.detail.bodyTruncated`):t(`settings.jiandu.detail.metadataTruncated`)}):null,(0,q.jsx)(`pre`,{className:`max-h-[50dvh] overflow-auto whitespace-pre-wrap break-words rounded-lg bg-muted p-3 font-sans text-sm`,children:R.body})]}):null,(0,q.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[R&&R.status!==`archived`?(0,q.jsx)(s,{variant:`destructive`,onClick:()=>{U(null),we(R)},children:t(`settings.jiandu.archive.open`)}):null,(0,q.jsx)(s,{variant:`outline`,onClick:Ne,children:t(`settings.jiandu.detail.close`)})]})]})}),(0,q.jsx)(T,{open:se,onOpenChange:e=>e?null:Le(),children:(0,q.jsxs)(O,{showCloseButton:!1,dismissable:B!==`create`,className:`gap-4 p-5 sm:max-w-2xl`,children:[(0,q.jsx)(y,{children:t(`settings.jiandu.create.title`)}),(0,q.jsx)(g,{children:t(`settings.jiandu.create.description`)}),(0,q.jsxs)(`div`,{className:`min-h-0 space-y-3 overflow-y-auto pr-1`,children:[(0,q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,q.jsx)(X,{htmlFor:`jiandu-title`,children:t(`settings.jiandu.create.titleLabel`)}),(0,q.jsx)(C,{id:`jiandu-title`,value:le.title,maxLength:wa.titleChars,disabled:!!B,onChange:e=>Fe(`title`,e.target.value)})]}),(0,q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,q.jsx)(X,{children:t(`settings.jiandu.create.typeLabel`)}),(0,q.jsxs)(Ce,{value:le.type,disabled:!!B,onValueChange:e=>Fe(`type`,e),children:[(0,q.jsx)(de,{className:`w-full`,"aria-label":t(`settings.jiandu.create.typeLabel`),children:(0,q.jsx)(z,{})}),(0,q.jsx)(_e,{className:`z-[150]`,children:xa.map(e=>(0,q.jsx)(V,{value:e,children:Ve(e)},e))})]})]}),(0,q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,q.jsx)(X,{htmlFor:`jiandu-body`,children:t(`settings.jiandu.create.bodyLabel`)}),(0,q.jsx)(he,{id:`jiandu-body`,rows:7,value:le.content,maxLength:wa.bodyChars,disabled:!!B,onChange:e=>Fe(`content`,e.target.value)})]}),(0,q.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[[`tags`,`keywords`,`entities`].map(e=>(0,q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,q.jsx)(X,{htmlFor:`jiandu-${e}`,children:t(`settings.jiandu.create.${e}Label`)}),(0,q.jsx)(C,{id:`jiandu-${e}`,value:le[e],disabled:!!B,onChange:t=>Fe(e,t.target.value),placeholder:t(`settings.jiandu.create.csvHint`)})]},e)),(0,q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,q.jsx)(X,{children:t(`settings.jiandu.create.granularityLabel`)}),(0,q.jsxs)(Ce,{value:le.granularity||`none`,disabled:!!B,onValueChange:e=>Fe(`granularity`,e===`none`?``:e),children:[(0,q.jsx)(de,{className:`w-full`,"aria-label":t(`settings.jiandu.create.granularityLabel`),children:(0,q.jsx)(z,{})}),(0,q.jsxs)(_e,{className:`z-[150]`,children:[(0,q.jsx)(V,{value:`none`,children:t(`settings.jiandu.create.noGranularity`)}),Ca.map(e=>(0,q.jsx)(V,{value:e,children:e},e))]})]})]})]}),ve?(0,q.jsx)(`p`,{role:`alert`,className:`text-sm text-destructive`,children:Be(ve)}):null,fe?(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,"aria-label":t(`settings.jiandu.create.matchesLabel`),children:[(0,q.jsx)(`h3`,{className:`text-sm font-medium`,children:fe.items.length>0?t(`settings.jiandu.create.matches`):t(`settings.jiandu.create.noMatches`)}),fe.items.length>0?(0,q.jsx)(`ul`,{className:`mt-2 space-y-1 text-sm`,children:fe.items.map(e=>(0,q.jsxs)(`li`,{children:[e.title,` · `,He(e.status)]},e.id))}):null,fe.truncated?(0,q.jsx)(`p`,{className:`mt-2 text-xs text-muted-foreground`,children:t(`settings.jiandu.create.matchesTruncated`)}):null]}):null]}),(0,q.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-2`,children:[(0,q.jsx)(s,{variant:`outline`,disabled:B===`create`,onClick:Le,children:t(`settings.jiandu.create.close`)}),(0,q.jsx)(s,{variant:`secondary`,disabled:me||!!B,onClick:()=>void K(),children:t(me?`settings.jiandu.create.lookingUp`:`settings.jiandu.create.lookup`)}),(0,q.jsx)(s,{disabled:B===`create`||!fe||fe.fingerprint!==Pe,onClick:()=>void Re(),children:t(B===`create`?`settings.jiandu.create.creating`:`settings.jiandu.create.confirm`)})]})]})}),(0,q.jsx)(T,{open:!!xe,onOpenChange:e=>{!e&&B!==`archive`&&(we(null),U(null))},children:(0,q.jsxs)(O,{showCloseButton:!1,dismissable:B!==`archive`,className:`gap-4 p-5`,children:[(0,q.jsx)(y,{children:t(`settings.jiandu.archive.title`,{title:xe?.title??``})}),(0,q.jsx)(g,{children:t(`settings.jiandu.archive.description`)}),Te?(0,q.jsx)(`p`,{role:`alert`,className:`text-sm text-destructive`,children:Be(Te)}):null,(0,q.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,q.jsx)(s,{variant:`outline`,disabled:B===`archive`,onClick:()=>{we(null),U(null)},children:t(`settings.jiandu.archive.cancel`)}),(0,q.jsx)(s,{variant:`destructive`,disabled:B===`archive`,onClick:()=>void ze(),children:t(B===`archive`?`settings.jiandu.archive.archiving`:`settings.jiandu.archive.confirm`)})]})]})})]})}function to({label:e,value:t}){return(0,q.jsxs)(`div`,{className:`rounded-lg border p-2.5 text-center`,children:[(0,q.jsx)(`div`,{className:`text-lg font-semibold`,children:t??0}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e})]})}function no(){let e=fe(e=>e.themePreference),t=fe(e=>e.setThemePreference),n=K(e=>e.mode),r=K(e=>e.setMode),i=Se(u(e=>e.models)),a=Se(e=>e.selectedModel),o=Se(e=>e.setSelectedModel),c=U(e=>e.providerSnapshot?.defaults?.chat?.model),l=a||c||``,[d,f]=(0,G.useState)(null);return(0,G.useEffect)(()=>{ze.getSummary().then(f).catch(()=>f(null))},[]),(0,q.jsxs)(`div`,{className:`space-y-4`,children:[(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`外观`}),(0,q.jsx)(`div`,{className:`flex gap-2`,children:[`light`,`dark`,`system`].map(n=>(0,q.jsx)(s,{variant:e===n?`default`:`secondary`,className:`flex-1`,onClick:()=>t(n),children:n===`light`?`浅色`:n===`dark`?`深色`:`跟随系统`},n))})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`体验模式`}),(0,q.jsx)(`div`,{className:`flex gap-2`,children:[`simple`,`advanced`].map(e=>(0,q.jsx)(s,{variant:n===e?`default`:`secondary`,className:`flex-1`,onClick:()=>r(e),children:e===`simple`?`简洁`:`高级`},e))}),(0,q.jsx)(`p`,{className:`mt-2 text-xs leading-relaxed text-muted-foreground`,children:`简洁模式隐藏高级设置(技能、环境变量、关键词掩码、集群、指标等),适合日常使用。`})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`默认模型`}),i.length===0?(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`模型列表加载中或为空`}):(0,q.jsxs)(Ce,{value:l,onValueChange:o,children:[(0,q.jsx)(de,{className:`w-full`,children:(0,q.jsx)(z,{placeholder:`选择模型`})}),(0,q.jsxs)(_e,{children:[l&&!i.includes(l)?(0,q.jsx)(V,{value:l,children:l}):null,i.map(e=>(0,q.jsx)(V,{value:e,children:e},e))]})]})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`用量统计`}),d?(0,q.jsxs)(`div`,{className:`grid grid-cols-3 gap-2`,children:[(0,q.jsx)(to,{label:`总会话`,value:d.total_sessions}),(0,q.jsx)(to,{label:`进行中`,value:d.active_sessions}),(0,q.jsx)(to,{label:`已完成`,value:d.completed_sessions}),(0,q.jsx)(to,{label:`工具调用`,value:d.total_tool_calls}),(0,q.jsx)(to,{label:`出错`,value:d.error_sessions}),(0,q.jsx)(to,{label:`压缩节省`,value:d.total_tokens_saved})]}):(0,q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`加载中…`})]}),(0,q.jsxs)(`section`,{className:`rounded-lg border p-3`,children:[(0,q.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground`,children:`关于`}),(0,q.jsxs)(`div`,{className:`flex items-center justify-between text-sm`,children:[(0,q.jsx)(`span`,{className:`text-muted-foreground`,children:`应用`}),(0,q.jsx)(`span`,{className:`font-medium`,children:`Bodhi · lotus-next`})]})]})]})}var ro=[{id:`general`,label:`通用`,render:()=>(0,q.jsx)(no,{})},{id:`providers`,label:`提供方`,render:()=>(0,q.jsx)(Et,{})},{id:`mcp`,label:`MCP`,render:()=>(0,q.jsx)(bn,{})},{id:`plugins`,label:`插件`,render:()=>(0,q.jsx)(Nn,{})},{id:`skills`,label:`技能`,render:()=>(0,q.jsx)(Pn,{})},{id:`permissions`,label:`权限`,render:()=>(0,q.jsx)(Fn,{})},{id:`env`,label:`环境变量`,render:()=>(0,q.jsx)(zn,{})},{id:`schedules`,label:`定时任务`,render:()=>(0,q.jsx)(hr,{})},{id:`notifications`,label:`通知`,render:()=>(0,q.jsx)(Dr,{})},{id:`masking`,label:`关键词掩码`,render:()=>(0,q.jsx)(kr,{})},{id:`prompts`,label:`提示词`,render:()=>(0,q.jsx)(jr,{})},{id:`workflows`,label:`工作流`,render:()=>(0,q.jsx)(Nr,{})},{id:`clusters`,label:`集群`,render:()=>(0,q.jsx)(Ur,{})},{id:`metrics`,label:`指标`,render:()=>(0,q.jsx)(Ji,{})},{id:`jiandu`,label:`Jiandu 记忆`,render:()=>(0,q.jsx)(eo,{})},{id:`system`,label:`系统`,render:()=>(0,q.jsx)(ba,{})}];function io({tab:e,onTabChange:t}){let n=K(e=>e.isAdvanced)?ro:ro.filter(e=>!Ie.has(e.id)),r=n.find(t=>t.id===e)??ro[0];return(0,q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col md:flex-row`,children:[(0,q.jsx)(`div`,{className:`flex shrink-0 gap-1 overflow-x-auto border-b p-2 md:w-40 md:flex-col md:overflow-y-auto md:border-b-0 md:border-r`,children:n.map(e=>(0,q.jsx)(`button`,{onClick:()=>t(e.id),className:a(`shrink-0 whitespace-nowrap rounded-lg px-3 py-2 text-left text-sm transition-colors md:w-full`,r.id===e.id?`bg-accent font-medium text-foreground`:`text-muted-foreground hover:bg-accent/60`),children:e.label},e.id))}),(0,q.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-4`,children:r.render()})]})}export{io as SettingsContent};
|