@xopcai/xopc 0.0.22 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/agents-CiZMJZRp.js +216 -0
- package/dist/gateway/static/root/assets/agents-CiZMJZRp.js.map +1 -0
- package/dist/gateway/static/root/assets/apps-page-tZz69XM3.js +2 -0
- package/dist/gateway/static/root/assets/apps-page-tZz69XM3.js.map +1 -0
- package/dist/gateway/static/root/assets/{attachment-preview-renderer-CebH7fCz.js → attachment-preview-renderer-CxMJMbD2.js} +4 -4
- package/dist/gateway/static/root/assets/{attachment-preview-renderer-CebH7fCz.js.map → attachment-preview-renderer-CxMJMbD2.js.map} +1 -1
- package/dist/gateway/static/root/assets/{attachment-process-heavy-Dbf1--O6.js → attachment-process-heavy-EFXPGfWk.js} +6 -6
- package/dist/gateway/static/root/assets/{attachment-process-heavy-Dbf1--O6.js.map → attachment-process-heavy-EFXPGfWk.js.map} +1 -1
- package/dist/gateway/static/root/assets/{attachment-utils-core-Dt6UxMPV.js → attachment-utils-core-ECbeoa9H.js} +1 -1
- package/dist/gateway/static/root/assets/attachment-utils-core-ECbeoa9H.js.map +1 -0
- package/dist/gateway/static/root/assets/channels-settings-BAvk9-aK.js +9 -0
- package/dist/gateway/static/root/assets/{channels-settings-BGueHxMv.js.map → channels-settings-BAvk9-aK.js.map} +1 -1
- package/dist/gateway/static/root/assets/cn-BMCV0OMB.js +2 -0
- package/dist/gateway/static/root/assets/cn-BMCV0OMB.js.map +1 -0
- package/dist/gateway/static/root/assets/cron-page-CANqvhK7.js +2 -0
- package/dist/gateway/static/root/assets/{cron-page-DsVZzPqv.js.map → cron-page-CANqvhK7.js.map} +1 -1
- package/dist/gateway/static/root/assets/cron-utils-DyOO6TdN.js +3 -0
- package/dist/gateway/static/root/assets/{cron-utils-zbRs2yND.js.map → cron-utils-DyOO6TdN.js.map} +1 -1
- package/dist/gateway/static/root/assets/dist-Brod9LF3.js +2 -0
- package/dist/gateway/static/root/assets/{dist-CDA7gR_M.js.map → dist-Brod9LF3.js.map} +1 -1
- package/dist/gateway/static/root/assets/{docx-preview-DxcHM3sR.js → docx-preview-F-jKDMNv.js} +2 -2
- package/dist/gateway/static/root/assets/{docx-preview-DxcHM3sR.js.map → docx-preview-F-jKDMNv.js.map} +1 -1
- package/dist/gateway/static/root/assets/{excel-worksheet-utils-Dk66snKA.js → excel-worksheet-utils-DPfAinZn.js} +1 -1
- package/dist/gateway/static/root/assets/{excel-worksheet-utils-Dk66snKA.js.map → excel-worksheet-utils-DPfAinZn.js.map} +1 -1
- package/dist/gateway/static/root/assets/extension-debug-page-CDD7ozsC.js +2 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-CDLp4DAs.js.map → extension-debug-page-CDD7ozsC.js.map} +1 -1
- package/dist/gateway/static/root/assets/extension-page-UUFMjoWf.js +2 -0
- package/dist/gateway/static/root/assets/{extension-page-DwSCjzHO.js.map → extension-page-UUFMjoWf.js.map} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CP9JNc4m.js +2 -0
- package/dist/gateway/static/root/assets/extension-settings-page-CP9JNc4m.js.map +1 -0
- package/dist/gateway/static/root/assets/index-BZvlG48D.js +150 -0
- package/dist/gateway/static/root/assets/index-BZvlG48D.js.map +1 -0
- package/dist/gateway/static/root/assets/index-DxkgyT8R.css +1 -0
- package/dist/gateway/static/root/assets/{jszip.min-DVUfmhpE.js → jszip.min-CL3dfyxs.js} +1 -1
- package/dist/gateway/static/root/assets/{jszip.min-DVUfmhpE.js.map → jszip.min-CL3dfyxs.js.map} +1 -1
- package/dist/gateway/static/root/assets/logs-page-Cr0eCGb4.js +2 -0
- package/dist/gateway/static/root/assets/{logs-page-ChJ0nsPh.js.map → logs-page-Cr0eCGb4.js.map} +1 -1
- package/dist/gateway/static/root/assets/{pdf--jE7rvON.js → pdf-CX6ji-QC.js} +1 -1
- package/dist/gateway/static/root/assets/{pdf--jE7rvON.js.map → pdf-CX6ji-QC.js.map} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DwLHN5GJ.js +2 -0
- package/dist/gateway/static/root/assets/{sessions-page-Cle4fPla.js.map → sessions-page-DwLHN5GJ.js.map} +1 -1
- package/dist/gateway/static/root/assets/settings-page-B3O3R0E4.js +2 -0
- package/dist/gateway/static/root/assets/settings-page-B3O3R0E4.js.map +1 -0
- package/dist/gateway/static/root/assets/skills-page-DgBYvH6B.js +3 -0
- package/dist/gateway/static/root/assets/{skills-page-B-smhcB2.js.map → skills-page-DgBYvH6B.js.map} +1 -1
- package/dist/gateway/static/root/assets/vendor-swr-B5fPo7KK.js +2 -0
- package/dist/gateway/static/root/assets/{vendor-swr-Dp4nzp5h.js.map → vendor-swr-B5fPo7KK.js.map} +1 -1
- package/dist/gateway/static/root/assets/{xlsx-DVk38js7.js → xlsx-CPtvfmVF.js} +1 -1
- package/dist/gateway/static/root/assets/{xlsx-DVk38js7.js.map → xlsx-CPtvfmVF.js.map} +1 -1
- package/dist/gateway/static/root/index.html +5 -4
- package/dist/package.js +1 -1
- package/dist/src/agent/image/tool-model-config.js +2 -2
- package/dist/src/agent/image/tool-model-config.js.map +1 -1
- package/dist/src/agent/tools/execute-code-tool.js +1 -1
- package/dist/src/agent/tools/execute-code-tool.js.map +1 -1
- package/dist/src/cli/commands/extension-dev.d.ts +2 -0
- package/dist/src/cli/commands/extension-dev.js +196 -0
- package/dist/src/cli/commands/extension-dev.js.map +1 -0
- package/dist/src/cli/commands/extension-marketplace.d.ts +4 -0
- package/dist/src/cli/commands/extension-marketplace.js +145 -0
- package/dist/src/cli/commands/extension-marketplace.js.map +1 -0
- package/dist/src/cli/commands/extension-pack.d.ts +2 -0
- package/dist/src/cli/commands/extension-pack.js +242 -0
- package/dist/src/cli/commands/extension-pack.js.map +1 -0
- package/dist/src/cli/commands/extension.js +13 -0
- package/dist/src/cli/commands/extension.js.map +1 -1
- package/dist/src/cli/index.js +5 -1
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/config/schema.js +1 -1
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/extensions/api.d.ts +6 -1
- package/dist/src/extensions/api.js +30 -0
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/engine-check.d.ts +14 -0
- package/dist/src/extensions/engine-check.js +148 -0
- package/dist/src/extensions/engine-check.js.map +1 -0
- package/dist/src/extensions/loader.js +23 -0
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/marketplace.d.ts +24 -0
- package/dist/src/extensions/marketplace.js +98 -0
- package/dist/src/extensions/marketplace.js.map +1 -0
- package/dist/src/extensions/normalize-manifest.js +16 -4
- package/dist/src/extensions/normalize-manifest.js.map +1 -1
- package/dist/src/extensions/sdk/index.d.ts +2 -0
- package/dist/src/extensions/sdk/index.js +2 -1
- package/dist/src/extensions/sdk/index.js.map +1 -1
- package/dist/src/extensions/sdk/testing.d.ts +49 -3
- package/dist/src/extensions/sdk/testing.js +174 -5
- package/dist/src/extensions/sdk/testing.js.map +1 -1
- package/dist/src/extensions/types/core.d.ts +5 -0
- package/dist/src/extensions/types/manifest.d.ts +17 -0
- package/dist/src/extensions/when-context.d.ts +6 -0
- package/dist/src/extensions/when-context.js +28 -0
- package/dist/src/extensions/when-context.js.map +1 -0
- package/dist/src/extensions/when-expression.d.ts +11 -0
- package/dist/src/extensions/when-expression.js +215 -0
- package/dist/src/extensions/when-expression.js.map +1 -0
- package/dist/src/gateway/hono/app.js +1 -1
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +28 -0
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js.map +1 -1
- package/dist/src/providers/index.d.ts +6 -3
- package/dist/src/providers/index.js +12 -23
- package/dist/src/providers/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/gateway/static/root/assets/agents-BcLv59-r.js +0 -71
- package/dist/gateway/static/root/assets/agents-BcLv59-r.js.map +0 -1
- package/dist/gateway/static/root/assets/apps-page-Bl-yxbQo.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-Bl-yxbQo.js.map +0 -1
- package/dist/gateway/static/root/assets/attachment-utils-core-Dt6UxMPV.js.map +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BGueHxMv.js +0 -9
- package/dist/gateway/static/root/assets/cron-page-DsVZzPqv.js +0 -2
- package/dist/gateway/static/root/assets/cron-utils-zbRs2yND.js +0 -3
- package/dist/gateway/static/root/assets/dist-CDA7gR_M.js +0 -2
- package/dist/gateway/static/root/assets/extension-debug-page-CDLp4DAs.js +0 -2
- package/dist/gateway/static/root/assets/extension-page-DwSCjzHO.js +0 -2
- package/dist/gateway/static/root/assets/extension-settings-page-Rdmxe24_.js +0 -2
- package/dist/gateway/static/root/assets/extension-settings-page-Rdmxe24_.js.map +0 -1
- package/dist/gateway/static/root/assets/index-D9Wmfh2f.css +0 -1
- package/dist/gateway/static/root/assets/index-DG8WvMbu.js +0 -150
- package/dist/gateway/static/root/assets/index-DG8WvMbu.js.map +0 -1
- package/dist/gateway/static/root/assets/logs-page-ChJ0nsPh.js +0 -2
- package/dist/gateway/static/root/assets/sessions-page-Cle4fPla.js +0 -2
- package/dist/gateway/static/root/assets/settings-page-Dyo2NYdy.js +0 -2
- package/dist/gateway/static/root/assets/settings-page-Dyo2NYdy.js.map +0 -1
- package/dist/gateway/static/root/assets/skills-page-B-smhcB2.js +0 -3
- package/dist/gateway/static/root/assets/vendor-swr-Dp4nzp5h.js +0 -2
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{i as t,t as n}from"./vendor-react-DbimaAId.js";import{t as r}from"./cn-BMCV0OMB.js";import{$ as i,$n as a,B as o,Br as s,Hn as c,J as l,K as u,Ln as d,Q as f,Qn as p,Qt as ee,Rn as m,V as h,X as g,Y as te,Z as ne,Zn as re,_n as _,_r as v,at as ie,ct as ae,dn as oe,dt as se,et as ce,it as le,kn as ue,lt as y,on as de,ot as b,q as fe,qr as pe,qt as me,rt as he,sn as x,sr as ge,un as S,ut as _e,wr as ve,zr as ye}from"./index-BZvlG48D.js";var C=e(t(),1),w=n();function T(e){let t=new Date(e),n=Math.floor((new Date().getTime()-t.getTime())/(1e3*60*60*24));return n===0?t.toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):n===1?`Yesterday`:n<7?t.toLocaleDateString([],{weekday:`short`}):t.toLocaleDateString([],{month:`short`,day:`numeric`})}function E(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function be({session:e,variant:t,labels:n,onOpen:i,onAction:a}){let l=e.name?.trim()||n.unnamedSession,u=!!e.name?.trim(),f=e.status===`archived`,p=e.status===`pinned`;return(0,w.jsxs)(`div`,{role:`button`,tabIndex:0,className:r(`group flex min-w-0 w-full max-w-full cursor-pointer flex-col rounded-xl bg-surface-base text-left transition-colors duration-150 ease-out`,`hover:bg-surface-hover active:scale-[0.99]`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel`,t===`list`&&`sm:flex-row sm:items-center sm:gap-4`),onClick:i,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),i())},children:[(0,w.jsxs)(`div`,{className:r(`flex min-w-0 items-start justify-between gap-2 bg-surface-hover/35 px-3 py-2 dark:bg-surface-hover/25`,t===`list`&&`sm:py-3`),children:[(0,w.jsx)(`div`,{className:`flex min-w-0 items-center gap-2`,children:(0,w.jsx)(`span`,{className:`truncate text-[11px] font-medium uppercase tracking-wide text-fg-subtle`,children:e.sourceChannel})}),(0,w.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1.5 text-xs text-fg-muted`,children:[p?(0,w.jsx)(d,{className:`size-3.5 text-accent-fg`,strokeWidth:1.75,"aria-hidden":!0}):null,(0,w.jsx)(`span`,{children:T(e.updatedAt)})]})]}),(0,w.jsxs)(`div`,{className:r(`min-w-0 flex-1 px-3 py-2`,t===`list`&&`sm:py-3`),children:[(0,w.jsx)(`div`,{className:`min-w-0 max-w-full truncate text-sm font-semibold text-fg`,title:l,children:l}),u?(0,w.jsx)(`div`,{className:`mt-0.5 min-w-0 max-w-full truncate font-mono text-[11px] text-fg-subtle`,title:e.key,children:e.key}):null,(0,w.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-3 text-xs text-fg-muted`,children:[(0,w.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,w.jsx)(c,{className:`size-3.5`,strokeWidth:1.75,"aria-hidden":!0}),e.messageCount]}),(0,w.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,w.jsx)(S,{className:`size-3.5`,strokeWidth:1.75,"aria-hidden":!0}),E(e.estimatedTokens)]})]}),e.tags.length>0?(0,w.jsxs)(`div`,{className:`mt-2 flex flex-wrap gap-1`,children:[e.tags.slice(0,3).map(e=>(0,w.jsx)(`span`,{className:`max-w-full break-words rounded-md bg-surface-hover px-1.5 py-0.5 text-[11px] text-fg-muted`,children:e},e)),e.tags.length>3?(0,w.jsxs)(`span`,{className:`text-[11px] text-fg-disabled`,children:[`+`,e.tags.length-3]}):null]}):null]}),(0,w.jsxs)(`div`,{className:`flex flex-wrap items-center gap-0.5 border-t border-edge-subtle/80 bg-surface-hover/25 px-2 py-2 dark:border-edge-subtle`,onClick:e=>e.stopPropagation(),onKeyDown:e=>e.stopPropagation(),children:[(0,w.jsx)(`button`,{type:`button`,className:o,title:n.continueChat,"aria-label":n.continueChat,onClick:()=>a(`continue`),children:(0,w.jsx)(c,{className:`size-4`,strokeWidth:1.75})}),f?(0,w.jsx)(`button`,{type:`button`,className:o,title:n.unarchive,"aria-label":n.unarchive,onClick:()=>a(`unarchive`),children:(0,w.jsx)(s,{className:`size-4`,strokeWidth:1.75})}):(0,w.jsx)(`button`,{type:`button`,className:o,title:n.archive,"aria-label":n.archive,onClick:()=>a(`archive`),children:(0,w.jsx)(ye,{className:`size-4`,strokeWidth:1.75})}),p?(0,w.jsx)(`button`,{type:`button`,className:o,title:n.unpin,"aria-label":n.unpin,onClick:()=>a(`unpin`),children:(0,w.jsx)(m,{className:`size-4`,strokeWidth:1.75})}):(0,w.jsx)(`button`,{type:`button`,className:o,title:n.pin,"aria-label":n.pin,onClick:()=>a(`pin`),children:(0,w.jsx)(d,{className:`size-4`,strokeWidth:1.75})}),(0,w.jsx)(`button`,{type:`button`,className:o,title:n.export,"aria-label":n.export,onClick:()=>a(`export`),children:(0,w.jsx)(v,{className:`size-4`,strokeWidth:1.75})}),(0,w.jsx)(`button`,{type:`button`,className:r(o,`text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950/40`),title:n.delete,"aria-label":n.delete,onClick:()=>a(`delete`),children:(0,w.jsx)(_,{className:`size-4`,strokeWidth:1.75})})]})]})}function D(e){if(typeof e==`string`)return e.length>2e3?`${e.slice(0,2e3)}…`:e;try{let t=JSON.stringify(e,null,2);return t.length>2e3?`${t.slice(0,2e3)}…`:t}catch{return String(e)}}function xe({open:e,loading:t,session:n,labels:i,onClose:a,onArchive:o,onUnarchive:s,onPin:c,onUnpin:l,onExport:u,onDelete:d}){let f=n?.status===`archived`,p=n?.status===`pinned`;return(0,w.jsx)(_e,{open:e,onOpenChange:e=>!e&&a(),children:(0,w.jsxs)(y,{children:[(0,w.jsx)(ae,{className:`xopc-dialog-overlay fixed inset-0 z-50 bg-scrim`}),(0,w.jsxs)(b,{className:r(`xopc-drawer-right fixed right-0 top-0 z-50 flex h-full w-full max-w-lg flex-col border-l border-edge bg-surface-panel shadow-popover outline-none`,`dark:border-edge`),"aria-describedby":void 0,children:[(0,w.jsxs)(`div`,{className:`flex min-w-0 shrink-0 items-center justify-between gap-2 border-b border-edge px-4 py-3 dark:border-edge`,children:[(0,w.jsx)(se,{className:`min-w-0 flex-1 truncate text-base font-semibold tracking-tight text-fg`,children:n?.name?.trim()||i.unnamedSession}),(0,w.jsx)(ie,{asChild:!0,children:(0,w.jsx)(x,{type:`button`,variant:`ghost`,className:`h-9 w-9 shrink-0 p-0`,"aria-label":i.close,children:(0,w.jsx)(oe,{className:`size-5`,strokeWidth:1.75})})})]}),(0,w.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-4 py-3`,children:t?(0,w.jsx)(`p`,{className:`text-sm text-fg-muted`,children:i.detailLoading}):n?(0,w.jsxs)(w.Fragment,{children:[(0,w.jsxs)(`dl`,{className:`mb-4 grid gap-2 text-xs text-fg-muted`,children:[(0,w.jsxs)(`div`,{children:[(0,w.jsx)(`dt`,{className:`text-fg-disabled`,children:`Key`}),(0,w.jsx)(`dd`,{className:`mt-0.5 break-all font-mono text-fg`,children:n.key})]}),(0,w.jsx)(`div`,{className:`flex flex-wrap gap-4`,children:(0,w.jsxs)(`span`,{children:[n.messageCount,` msgs · `,n.estimatedTokens,` tok`]})})]}),(0,w.jsx)(`h3`,{className:`mb-2 text-xs font-medium uppercase tracking-wide text-fg-subtle`,children:i.detailMessages}),(0,w.jsx)(`ul`,{className:`space-y-3`,children:n.messages.map((e,t)=>(0,w.jsxs)(`li`,{className:`rounded-lg border border-edge-subtle bg-surface-hover/50 p-2 dark:border-edge`,children:[(0,w.jsx)(`div`,{className:`mb-1 text-[10px] font-medium uppercase text-fg-subtle`,children:e.role}),(0,w.jsx)(`pre`,{className:`max-h-40 overflow-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-relaxed text-fg-muted`,children:D(e.content)})]},`${e.timestamp??t}-${t}`))})]}):null}),(0,w.jsx)(`div`,{className:`shrink-0 border-t border-edge px-4 py-3 dark:border-edge`,children:(0,w.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,w.jsx)(x,{type:`button`,variant:`secondary`,className:`text-sm`,onClick:u,children:i.detailExport}),f?(0,w.jsx)(x,{type:`button`,variant:`secondary`,className:`text-sm`,onClick:s,children:i.unarchive}):(0,w.jsx)(x,{type:`button`,variant:`secondary`,className:`text-sm`,onClick:o,children:i.archive}),p?(0,w.jsx)(x,{type:`button`,variant:`secondary`,className:`text-sm`,onClick:l,children:i.unpin}):(0,w.jsx)(x,{type:`button`,variant:`secondary`,className:`text-sm`,onClick:c,children:i.pin}),(0,w.jsx)(x,{type:`button`,variant:`secondary`,className:`text-sm text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950/40`,onClick:d,children:i.delete})]})})]})]})})}var O=20;function k(e,t){return e.replace(/\{\{(\w+)\}\}/g,(e,n)=>String(t[n]??``))}var A=new Set([`all`,`active`,`pinned`,`archived`]),j=new Set([`grid`,`list`]);function M(){let e=de(ee(e=>e.language)),t=e.sessions,n=!!me(e=>e.token),[o,s]=pe(),c=o.get(`q`)??``,m=o.get(`status`),_=o.get(`view`),v=o.get(`channel`)??``,ie=A.has(m)?m:`all`,oe=j.has(_)?_:`grid`,[S,T]=(0,C.useState)(c),[E,D]=(0,C.useState)(c.trim()),[M,N]=(0,C.useState)(ie),[P,F]=(0,C.useState)(oe),[I,L]=(0,C.useState)(v.trim()),[R,z]=(0,C.useState)([]),[B,V]=(0,C.useState)(!1),[Se,H]=(0,C.useState)(null),[U,Ce]=(0,C.useState)(!1),[W,G]=(0,C.useState)(null),[we,K]=(0,C.useState)(!1),[Te,Ee]=(0,C.useState)(!1),[q,J]=(0,C.useState)(null),[De,Y]=(0,C.useState)(!1),[X,Z]=(0,C.useState)(null);(0,C.useEffect)(()=>{let e=setTimeout(()=>D(S.trim()),300);return()=>clearTimeout(e)},[S]),(0,C.useEffect)(()=>{let e=o.get(`q`)??``,t=o.get(`status`),n=o.get(`view`),r=(o.get(`channel`)??``).trim(),i=A.has(t)?t:`all`,a=j.has(n)?n:`grid`,s=e.trim();T(t=>t===e?t:e),D(e=>e===s?e:s),N(e=>e===i?e:i),F(e=>e===a?e:a),L(e=>e===r?e:r)},[o]),(0,C.useEffect)(()=>{let e=new URLSearchParams(o),t=E.trim();t?e.set(`q`,t):e.delete(`q`),M===`all`?e.delete(`status`):e.set(`status`,M),P===`grid`?e.delete(`view`):e.set(`view`,P),I?e.set(`channel`,I):e.delete(`channel`),e.toString()!==o.toString()&&s(e,{replace:!0})},[E,o,s,M,P,I]),(0,C.useEffect)(()=>{if(!n)return;let e=!1;return(async()=>{V(!0),H(null);try{let t=await ne({limit:O,offset:0,...E?{search:E}:{},...M===`all`?{}:{status:M},...I?{channel:I}:{}});if(e)return;z(t.items),Ce(t.hasMore)}catch(n){e||H(n instanceof Error?n.message:t.loadError)}finally{e||V(!1)}})(),()=>{e=!0}},[n,E,M,t.loadError]),(0,C.useEffect)(()=>{n&&g().then(G).catch(()=>{})},[n]),(0,C.useEffect)(()=>{if(!n)return;let e=e=>{let t=e.detail;!t?.key||t.name===void 0||(z(e=>e.map(e=>e.key===t.key?{...e,name:t.name}:e)),J(e=>e&&e.key===t.key?{...e,name:t.name}:e))};return window.addEventListener(`session-updated`,e),()=>{window.removeEventListener(`session-updated`,e)}},[n]);let Oe=(0,C.useCallback)(async()=>{if(!(!n||B||!U)){V(!0),H(null);try{let e=await ne({limit:O,offset:R.length,...E?{search:E}:{},...M===`all`?{}:{status:M},...I?{channel:I}:{}});z(t=>[...t,...e.items]),Ce(e.hasMore)}catch(e){H(e instanceof Error?e.message:t.loadError)}finally{V(!1)}}},[n,B,U,R.length,E,M,I,t.loadError]),Q=(0,C.useCallback)((e,t)=>{z(n=>n.map(n=>n.key===e?{...n,status:t}:n)),J(n=>n&&n.key===e?{...n,status:t}:n)},[]),ke=(0,C.useCallback)(async e=>{K(!0),Ee(!0),J(null);try{J(await te(e))}catch{K(!1)}finally{Ee(!1)}},[]),Ae=e=>{ke(e)},$=async(e,t)=>{if(t===`continue`){window.dispatchEvent(new CustomEvent(`navigate-to-chat`,{detail:{sessionKey:e},bubbles:!0}));return}if(t===`delete`){Z(e),Y(!0);return}try{switch(t){case`archive`:await u(e),Q(e,`archived`);break;case`unarchive`:await i(e),Q(e,`active`);break;case`pin`:await f(e),Q(e,`pinned`);break;case`unpin`:await ce(e),Q(e,`active`);break;case`export`:{let t=await l(e),n=new Blob([t],{type:`application/json`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`session-${e.replace(/[^a-z0-9]/gi,`_`)}.json`,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(r);break}default:break}g().then(G).catch(()=>{})}catch{}},je=async e=>{try{await fe(e),z(t=>t.filter(t=>t.key!==e)),J(t=>t?.key===e?null:t),q?.key===e&&K(!1),g().then(G).catch(()=>{})}catch{}},Me={continueChat:t.continueChat,archive:t.archive,unarchive:t.unarchive,pin:t.pin,unpin:t.unpin,export:t.export,delete:t.delete,unnamedSession:e.chat.newSession},Ne={close:t.close,detailLoading:t.detailLoading,detailMessages:t.detailMessages,detailExport:t.detailExport,archive:t.archive,unarchive:t.unarchive,pin:t.pin,unpin:t.unpin,delete:t.delete,unnamedSession:e.chat.newSession},Pe=[{key:`all`,label:t.filterAll,icon:a},{key:`active`,label:t.filterActive,icon:ve},{key:`pinned`,label:t.filterPinned,icon:d},{key:`archived`,label:t.filterArchived,icon:ye}],Fe=(()=>{let e=Object.entries(W?.byChannel??{}).sort((e,t)=>t[1]-e[1]).slice(0,6).map(([e])=>e);for(let t of[`telegram`,`weixin`,`feishu`])e.includes(t)||e.push(t);return e.slice(0,8)})();return n?(0,w.jsxs)(`div`,{className:`flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto overflow-x-hidden bg-surface-panel`,children:[(0,w.jsxs)(`div`,{className:`mx-auto flex w-full min-w-0 max-w-2xl flex-col gap-4 px-4 py-6 sm:px-6 lg:max-w-app-main lg:px-8`,children:[(0,w.jsxs)(`header`,{className:`flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between`,children:[(0,w.jsxs)(`h1`,{className:`flex items-center gap-2 text-xl font-semibold tracking-tight text-fg`,children:[(0,w.jsx)(ge,{className:`size-5 shrink-0 text-fg-muted`,strokeWidth:1.75,"aria-hidden":!0}),t.title]}),(0,w.jsxs)(`div`,{className:`flex w-full min-w-0 items-center gap-2 rounded-xl bg-surface-base px-3 py-2 transition-colors sm:max-w-md dark:bg-surface-hover/40`,children:[(0,w.jsx)(ue,{className:`size-4 shrink-0 text-fg-disabled`,strokeWidth:1.75,"aria-hidden":!0}),(0,w.jsx)(`input`,{type:`search`,value:S,onChange:e=>T(e.target.value),placeholder:t.searchPlaceholder,className:`min-w-0 flex-1 border-0 bg-transparent text-sm text-fg placeholder:text-fg-disabled focus:outline-none focus:ring-0`})]})]}),(0,w.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:Pe.map(({key:e,label:t,icon:n})=>(0,w.jsxs)(`button`,{type:`button`,"aria-pressed":M===e,onClick:()=>N(e),className:r(`inline-flex items-center gap-1.5 rounded-xl px-3 py-2 text-sm font-medium`,h.transition,h.focusRingPanel,M===e?`bg-accent-soft text-accent-fg`:`bg-surface-base text-fg-muted hover:bg-surface-hover hover:text-fg dark:bg-surface-hover/35`),children:[(0,w.jsx)(n,{className:`size-4`,strokeWidth:1.75,"aria-hidden":!0}),t]},e))}),(0,w.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,w.jsx)(`span`,{className:`text-xs font-medium text-fg-subtle`,children:t.filterChannelLabel}),(0,w.jsx)(`button`,{type:`button`,"aria-pressed":!I,onClick:()=>L(``),className:r(`inline-flex items-center rounded-xl px-3 py-2 text-sm font-medium`,h.transition,h.focusRingPanel,I?`bg-surface-base text-fg-muted hover:bg-surface-hover hover:text-fg dark:bg-surface-hover/35`:`bg-accent-soft text-accent-fg`),children:t.filterChannelAll}),Fe.map(e=>(0,w.jsxs)(`button`,{type:`button`,"aria-pressed":I===e,onClick:()=>L(e),className:r(`inline-flex items-center rounded-xl px-3 py-2 text-sm font-medium`,h.transition,h.focusRingPanel,I===e?`bg-accent-soft text-accent-fg`:`bg-surface-base text-fg-muted hover:bg-surface-hover hover:text-fg dark:bg-surface-hover/35`),children:[e,W?.byChannel?.[e]==null?null:(0,w.jsx)(`span`,{className:`ml-2 rounded-full bg-surface-hover px-2 py-0.5 text-[11px] text-fg-subtle`,children:W.byChannel[e]})]},e))]}),W?(0,w.jsx)(`div`,{className:`grid grid-cols-2 gap-3 sm:grid-cols-4`,children:[[W.totalSessions,t.totalSessions],[W.activeSessions,t.activeSessions],[W.pinnedSessions,t.pinnedSessions],[W.archivedSessions,t.archivedSessions]].map(([e,t])=>(0,w.jsxs)(`div`,{className:`rounded-xl bg-surface-base px-3 py-3 dark:bg-surface-hover/30`,children:[(0,w.jsx)(`div`,{className:`text-lg font-semibold tabular-nums text-fg`,children:e}),(0,w.jsx)(`div`,{className:`text-xs text-fg-muted`,children:t})]},t))}):null,Se?(0,w.jsx)(`div`,{className:`rounded-lg border border-edge bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-edge dark:bg-red-950/40 dark:text-red-300`,children:Se}):null,(0,w.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,w.jsx)(`p`,{className:`text-xs text-fg-muted`,children:k(t.sessionCount,{count:R.length})}),(0,w.jsxs)(`div`,{className:le,role:`group`,"aria-label":t.layoutToggleGroup,children:[(0,w.jsx)(x,{type:`button`,variant:`segmented`,title:t.gridView,"aria-pressed":P===`grid`,onClick:()=>F(`grid`),className:r(he,`size-7 p-0`,P===`grid`&&`bg-surface-panel shadow-sm dark:bg-surface-panel dark:shadow-sm dark:ring-1 dark:ring-edge-strong/40`,P===`grid`&&`text-accent-fg`),children:(0,w.jsx)(p,{className:`size-3.5`,strokeWidth:1.5})}),(0,w.jsx)(x,{type:`button`,variant:`segmented`,title:t.listView,"aria-pressed":P===`list`,onClick:()=>F(`list`),className:r(he,`size-9 p-0`,P===`list`&&`bg-surface-panel shadow-sm dark:bg-surface-panel dark:shadow-sm dark:ring-1 dark:ring-edge-strong/40`,P===`list`&&`text-accent-fg`),children:(0,w.jsx)(re,{className:`size-3.5`,strokeWidth:1.5})})]})]}),B&&R.length===0?(0,w.jsx)(`div`,{className:`grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3`,children:Array.from({length:6}).map((e,t)=>(0,w.jsx)(`div`,{className:`h-40 animate-pulse rounded-xl bg-surface-hover/60 dark:bg-surface-hover/40`},t))}):R.length===0?(0,w.jsxs)(`div`,{className:`flex flex-col items-center justify-center rounded-2xl bg-surface-base py-16 text-center dark:bg-surface-hover/25`,children:[(0,w.jsx)(ge,{className:`mb-3 size-12 text-fg-disabled`,strokeWidth:1.25,"aria-hidden":!0}),(0,w.jsx)(`p`,{className:`text-base font-semibold text-fg`,children:t.noSessions}),(0,w.jsx)(`p`,{className:`mt-1 max-w-sm text-sm text-fg-muted`,children:t.noSessionsDescription}),(0,w.jsx)(x,{variant:`primary`,className:`mt-6`,onClick:()=>{window.dispatchEvent(new CustomEvent(`navigate-to-chat`,{detail:{sessionKey:``},bubbles:!0}))},children:t.startNewChat})]}):(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(`div`,{className:r(`grid min-w-0 gap-3`,P===`grid`?`sm:grid-cols-2 lg:grid-cols-3`:`grid-cols-1`),children:R.map(e=>(0,w.jsx)(be,{session:e,variant:P,labels:Me,onOpen:()=>Ae(e.key),onAction:t=>void $(e.key,t)},e.key))}),U?(0,w.jsx)(`div`,{className:`flex justify-center pt-2`,children:(0,w.jsx)(x,{type:`button`,variant:`secondary`,disabled:B,onClick:()=>void Oe(),children:t.loadMore})}):null]})]}),(0,w.jsx)(xe,{open:we,loading:Te,session:q,labels:Ne,onClose:()=>{K(!1),J(null)},onArchive:()=>q&&void $(q.key,`archive`),onUnarchive:()=>q&&void $(q.key,`unarchive`),onPin:()=>q&&void $(q.key,`pin`),onUnpin:()=>q&&void $(q.key,`unpin`),onExport:()=>q&&void $(q.key,`export`),onDelete:()=>q&&(Z(q.key),Y(!0))}),(0,w.jsx)(_e,{open:De,onOpenChange:Y,children:(0,w.jsxs)(y,{children:[(0,w.jsx)(ae,{className:`xopc-dialog-overlay fixed inset-0 z-[60] bg-scrim`}),(0,w.jsxs)(b,{className:`xopc-dialog-content fixed left-1/2 top-1/2 z-[60] w-[min(100%-2rem,24rem)] -translate-x-1/2 -translate-y-1/2 rounded-xl border border-edge bg-surface-panel p-4 shadow-popover dark:border-edge`,children:[(0,w.jsx)(se,{className:`text-base font-semibold text-fg`,children:t.deleteSessionTitle}),(0,w.jsx)(`p`,{className:`mt-2 text-sm text-fg-muted`,children:X?k(t.deleteSessionMessage,{name:R.find(e=>e.key===X)?.name?.trim()||e.chat.newSession}):``}),(0,w.jsxs)(`div`,{className:`mt-4 flex justify-end gap-2`,children:[(0,w.jsx)(x,{type:`button`,variant:`secondary`,onClick:()=>Y(!1),children:t.cancel}),(0,w.jsx)(x,{type:`button`,variant:`primary`,className:`bg-red-600 hover:bg-red-700`,onClick:()=>{X&&je(X),Y(!1),Z(null)},children:t.delete})]})]})]})})]}):(0,w.jsx)(`div`,{className:`mx-auto w-full max-w-2xl px-4 py-16 text-center text-sm text-fg-muted sm:px-8 lg:max-w-app-main`,children:t.needToken})}export{M as SessionsPage};
|
|
2
|
+
//# sourceMappingURL=sessions-page-DwLHN5GJ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions-page-Cle4fPla.js","names":[],"sources":["../../../../../web/src/features/sessions/session-card.tsx","../../../../../web/src/features/sessions/session-detail-drawer.tsx","../../../../../web/src/features/sessions/sessions-page.tsx"],"sourcesContent":["import {\n Archive,\n ArchiveRestore,\n Download,\n MessageSquare,\n Pin,\n PinOff,\n Trash2,\n Zap,\n} from 'lucide-react';\n\nimport type { SessionMetadata } from '@/features/sessions/session.types';\nimport { ghostIconButton } from '@/lib/interaction';\nimport { cn } from '@/lib/cn';\n\nexport type SessionCardAction =\n | 'continue'\n | 'delete'\n | 'archive'\n | 'unarchive'\n | 'pin'\n | 'unpin'\n | 'export';\n\nfunction formatRelativeDate(dateStr: string): string {\n const date = new Date(dateStr);\n const now = new Date();\n const diffDays = Math.floor((now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24));\n if (diffDays === 0) {\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n }\n if (diffDays === 1) return 'Yesterday';\n if (diffDays < 7) return date.toLocaleDateString([], { weekday: 'short' });\n return date.toLocaleDateString([], { month: 'short', day: 'numeric' });\n}\n\nfunction formatTokens(tokens: number): string {\n if (tokens >= 1000) return `${(tokens / 1000).toFixed(1)}k`;\n return String(tokens);\n}\n\nexport function SessionCard({\n session,\n variant,\n labels,\n onOpen,\n onAction,\n}: {\n session: SessionMetadata;\n variant: 'grid' | 'list';\n labels: {\n continueChat: string;\n archive: string;\n unarchive: string;\n pin: string;\n unpin: string;\n export: string;\n delete: string;\n /** Shown when `session.name` is empty (e.g. new chat before auto-title). */\n unnamedSession: string;\n };\n onOpen: () => void;\n onAction: (action: SessionCardAction) => void;\n}) {\n const displayName = session.name?.trim() || labels.unnamedSession;\n const showKeySubtitle = Boolean(session.name?.trim());\n const isArchived = session.status === 'archived';\n const isPinned = session.status === 'pinned';\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n className={cn(\n // min-w-0: grid/flex children default to min-width:auto — long unbroken titles (URLs) otherwise expand the track\n 'group flex min-w-0 w-full max-w-full cursor-pointer flex-col rounded-xl bg-surface-base text-left transition-colors duration-150 ease-out',\n 'hover:bg-surface-hover active:scale-[0.99]',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel',\n variant === 'list' && 'sm:flex-row sm:items-center sm:gap-4',\n )}\n onClick={onOpen}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onOpen();\n }\n }}\n >\n <div\n className={cn(\n 'flex min-w-0 items-start justify-between gap-2 bg-surface-hover/35 px-3 py-2 dark:bg-surface-hover/25',\n variant === 'list' && 'sm:py-3',\n )}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"truncate text-[11px] font-medium uppercase tracking-wide text-fg-subtle\">\n {session.sourceChannel}\n </span>\n </div>\n <div className=\"flex shrink-0 items-center gap-1.5 text-xs text-fg-muted\">\n {isPinned ? <Pin className=\"size-3.5 text-accent-fg\" strokeWidth={1.75} aria-hidden /> : null}\n <span>{formatRelativeDate(session.updatedAt)}</span>\n </div>\n </div>\n\n <div className={cn('min-w-0 flex-1 px-3 py-2', variant === 'list' && 'sm:py-3')}>\n <div className=\"min-w-0 max-w-full truncate text-sm font-semibold text-fg\" title={displayName}>\n {displayName}\n </div>\n {showKeySubtitle ? (\n <div\n className=\"mt-0.5 min-w-0 max-w-full truncate font-mono text-[11px] text-fg-subtle\"\n title={session.key}\n >\n {session.key}\n </div>\n ) : null}\n <div className=\"mt-2 flex flex-wrap items-center gap-3 text-xs text-fg-muted\">\n <span className=\"inline-flex items-center gap-1\">\n <MessageSquare className=\"size-3.5\" strokeWidth={1.75} aria-hidden />\n {session.messageCount}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <Zap className=\"size-3.5\" strokeWidth={1.75} aria-hidden />\n {formatTokens(session.estimatedTokens)}\n </span>\n </div>\n {session.tags.length > 0 ? (\n <div className=\"mt-2 flex flex-wrap gap-1\">\n {session.tags.slice(0, 3).map((tag) => (\n <span\n key={tag}\n className=\"max-w-full break-words rounded-md bg-surface-hover px-1.5 py-0.5 text-[11px] text-fg-muted\"\n >\n {tag}\n </span>\n ))}\n {session.tags.length > 3 ? (\n <span className=\"text-[11px] text-fg-disabled\">+{session.tags.length - 3}</span>\n ) : null}\n </div>\n ) : null}\n </div>\n\n <div\n className=\"flex flex-wrap items-center gap-0.5 border-t border-edge-subtle/80 bg-surface-hover/25 px-2 py-2 dark:border-edge-subtle\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.continueChat}\n aria-label={labels.continueChat}\n onClick={() => onAction('continue')}\n >\n <MessageSquare className=\"size-4\" strokeWidth={1.75} />\n </button>\n {isArchived ? (\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.unarchive}\n aria-label={labels.unarchive}\n onClick={() => onAction('unarchive')}\n >\n <ArchiveRestore className=\"size-4\" strokeWidth={1.75} />\n </button>\n ) : (\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.archive}\n aria-label={labels.archive}\n onClick={() => onAction('archive')}\n >\n <Archive className=\"size-4\" strokeWidth={1.75} />\n </button>\n )}\n {isPinned ? (\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.unpin}\n aria-label={labels.unpin}\n onClick={() => onAction('unpin')}\n >\n <PinOff className=\"size-4\" strokeWidth={1.75} />\n </button>\n ) : (\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.pin}\n aria-label={labels.pin}\n onClick={() => onAction('pin')}\n >\n <Pin className=\"size-4\" strokeWidth={1.75} />\n </button>\n )}\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.export}\n aria-label={labels.export}\n onClick={() => onAction('export')}\n >\n <Download className=\"size-4\" strokeWidth={1.75} />\n </button>\n <button\n type=\"button\"\n className={cn(\n ghostIconButton,\n 'text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950/40',\n )}\n title={labels.delete}\n aria-label={labels.delete}\n onClick={() => onAction('delete')}\n >\n <Trash2 className=\"size-4\" strokeWidth={1.75} />\n </button>\n </div>\n </div>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\n\nimport type { SessionDetail } from '@/features/sessions/session.types';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\n\nfunction previewContent(content: string | unknown[]): string {\n if (typeof content === 'string') {\n return content.length > 2000 ? `${content.slice(0, 2000)}…` : content;\n }\n try {\n const s = JSON.stringify(content, null, 2);\n return s.length > 2000 ? `${s.slice(0, 2000)}…` : s;\n } catch {\n return String(content);\n }\n}\n\nexport function SessionDetailDrawer({\n open,\n loading,\n session,\n labels,\n onClose,\n onArchive,\n onUnarchive,\n onPin,\n onUnpin,\n onExport,\n onDelete,\n}: {\n open: boolean;\n loading: boolean;\n session: SessionDetail | null;\n labels: {\n close: string;\n detailLoading: string;\n detailMessages: string;\n detailExport: string;\n archive: string;\n unarchive: string;\n pin: string;\n unpin: string;\n delete: string;\n unnamedSession: string;\n };\n onClose: () => void;\n onArchive: () => void;\n onUnarchive: () => void;\n onPin: () => void;\n onUnpin: () => void;\n onExport: () => void;\n onDelete: () => void;\n}) {\n const isArchived = session?.status === 'archived';\n const isPinned = session?.status === 'pinned';\n\n return (\n <Dialog.Root open={open} onOpenChange={(v) => !v && onClose()}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-50 bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-drawer-right fixed right-0 top-0 z-50 flex h-full w-full max-w-lg flex-col border-l border-edge bg-surface-panel shadow-popover outline-none',\n 'dark:border-edge',\n )}\n aria-describedby={undefined}\n >\n <div className=\"flex min-w-0 shrink-0 items-center justify-between gap-2 border-b border-edge px-4 py-3 dark:border-edge\">\n <Dialog.Title className=\"min-w-0 flex-1 truncate text-base font-semibold tracking-tight text-fg\">\n {session?.name?.trim() || labels.unnamedSession}\n </Dialog.Title>\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"ghost\" className=\"h-9 w-9 shrink-0 p-0\" aria-label={labels.close}>\n <X className=\"size-5\" strokeWidth={1.75} />\n </Button>\n </Dialog.Close>\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto px-4 py-3\">\n {loading ? (\n <p className=\"text-sm text-fg-muted\">{labels.detailLoading}</p>\n ) : session ? (\n <>\n <dl className=\"mb-4 grid gap-2 text-xs text-fg-muted\">\n <div>\n <dt className=\"text-fg-disabled\">Key</dt>\n <dd className=\"mt-0.5 break-all font-mono text-fg\">{session.key}</dd>\n </div>\n <div className=\"flex flex-wrap gap-4\">\n <span>\n {session.messageCount} msgs · {session.estimatedTokens} tok\n </span>\n </div>\n </dl>\n <h3 className=\"mb-2 text-xs font-medium uppercase tracking-wide text-fg-subtle\">\n {labels.detailMessages}\n </h3>\n <ul className=\"space-y-3\">\n {session.messages.map((msg, i) => (\n <li\n key={`${msg.timestamp ?? i}-${i}`}\n className=\"rounded-lg border border-edge-subtle bg-surface-hover/50 p-2 dark:border-edge\"\n >\n <div className=\"mb-1 text-[10px] font-medium uppercase text-fg-subtle\">{msg.role}</div>\n <pre className=\"max-h-40 overflow-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-relaxed text-fg-muted\">\n {previewContent(msg.content)}\n </pre>\n </li>\n ))}\n </ul>\n </>\n ) : null}\n </div>\n\n <div className=\"shrink-0 border-t border-edge px-4 py-3 dark:border-edge\">\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={onExport}>\n {labels.detailExport}\n </Button>\n {isArchived ? (\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={onUnarchive}>\n {labels.unarchive}\n </Button>\n ) : (\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={onArchive}>\n {labels.archive}\n </Button>\n )}\n {isPinned ? (\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={onUnpin}>\n {labels.unpin}\n </Button>\n ) : (\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={onPin}>\n {labels.pin}\n </Button>\n )}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"text-sm text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950/40\"\n onClick={onDelete}\n >\n {labels.delete}\n </Button>\n </div>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport {\n Archive,\n Circle,\n FolderOpen,\n Layers,\n LayoutGrid,\n LayoutList,\n Pin,\n Search,\n} from 'lucide-react';\nimport { useCallback, useEffect, useState } from 'react';\nimport { useSearchParams } from 'react-router-dom';\n\nimport { SessionCard, type SessionCardAction } from '@/features/sessions/session-card';\nimport { SessionDetailDrawer } from '@/features/sessions/session-detail-drawer';\nimport {\n archiveSession,\n deleteSession,\n exportSessionJson,\n getSessionDetail,\n getSessionStats,\n listSessions,\n pinSession,\n unarchiveSession,\n unpinSession,\n} from '@/features/sessions/session-api';\nimport type { SessionDetail, SessionMetadata, SessionStats } from '@/features/sessions/session.types';\nimport { Button } from '@/components/ui/button';\nimport {\n segmentedThumbActiveClassName,\n segmentedThumbBaseClassName,\n segmentedTrackClassName,\n} from '@/components/ui/segmented-styles';\nimport { cn } from '@/lib/cn';\nimport { interaction } from '@/lib/interaction';\nimport { messages } from '@/i18n/messages';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nconst PAGE_LIMIT = 20;\n\nfunction interpolate(template: string, params: Record<string, string | number>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => String(params[key] ?? ''));\n}\n\ntype StatusFilter = 'all' | 'active' | 'pinned' | 'archived';\ntype SessionsViewMode = 'grid' | 'list';\n\nconst SESSION_STATUS_FILTER_SET = new Set<StatusFilter>(['all', 'active', 'pinned', 'archived']);\nconst SESSION_VIEW_MODE_SET = new Set<SessionsViewMode>(['grid', 'list']);\n\nexport function SessionsPage() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const s = m.sessions;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n const [searchParams, setSearchParams] = useSearchParams();\n\n const initialSearch = searchParams.get('q') ?? '';\n const initialStatus = searchParams.get('status');\n const initialView = searchParams.get('view');\n const initialChannel = searchParams.get('channel') ?? '';\n const initialStatusFilter: StatusFilter = SESSION_STATUS_FILTER_SET.has(initialStatus as StatusFilter)\n ? (initialStatus as StatusFilter)\n : 'all';\n const initialViewMode: SessionsViewMode = SESSION_VIEW_MODE_SET.has(initialView as SessionsViewMode)\n ? (initialView as SessionsViewMode)\n : 'grid';\n\n const [searchInput, setSearchInput] = useState(initialSearch);\n const [debouncedSearch, setDebouncedSearch] = useState(initialSearch.trim());\n const [statusFilter, setStatusFilter] = useState<StatusFilter>(initialStatusFilter);\n const [viewMode, setViewMode] = useState<SessionsViewMode>(initialViewMode);\n const [channelFilter, setChannelFilter] = useState(initialChannel.trim());\n\n const [sessions, setSessions] = useState<SessionMetadata[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [hasMore, setHasMore] = useState(false);\n const [stats, setStats] = useState<SessionStats | null>(null);\n\n const [detailOpen, setDetailOpen] = useState(false);\n const [detailLoading, setDetailLoading] = useState(false);\n const [detailSession, setDetailSession] = useState<SessionDetail | null>(null);\n\n const [confirmOpen, setConfirmOpen] = useState(false);\n const [confirmKey, setConfirmKey] = useState<string | null>(null);\n\n useEffect(() => {\n const t = setTimeout(() => setDebouncedSearch(searchInput.trim()), 300);\n return () => clearTimeout(t);\n }, [searchInput]);\n\n useEffect(() => {\n const nextQ = searchParams.get('q') ?? '';\n const nextStatusRaw = searchParams.get('status');\n const nextViewRaw = searchParams.get('view');\n const nextChannel = (searchParams.get('channel') ?? '').trim();\n const nextStatus: StatusFilter = SESSION_STATUS_FILTER_SET.has(nextStatusRaw as StatusFilter)\n ? (nextStatusRaw as StatusFilter)\n : 'all';\n const nextView: SessionsViewMode = SESSION_VIEW_MODE_SET.has(nextViewRaw as SessionsViewMode)\n ? (nextViewRaw as SessionsViewMode)\n : 'grid';\n const nextDebouncedQ = nextQ.trim();\n\n setSearchInput((prev) => (prev === nextQ ? prev : nextQ));\n setDebouncedSearch((prev) => (prev === nextDebouncedQ ? prev : nextDebouncedQ));\n setStatusFilter((prev) => (prev === nextStatus ? prev : nextStatus));\n setViewMode((prev) => (prev === nextView ? prev : nextView));\n setChannelFilter((prev) => (prev === nextChannel ? prev : nextChannel));\n }, [searchParams]);\n\n useEffect(() => {\n const params = new URLSearchParams(searchParams);\n const nextQ = debouncedSearch.trim();\n if (nextQ) params.set('q', nextQ);\n else params.delete('q');\n if (statusFilter !== 'all') params.set('status', statusFilter);\n else params.delete('status');\n if (viewMode !== 'grid') params.set('view', viewMode);\n else params.delete('view');\n if (channelFilter) params.set('channel', channelFilter);\n else params.delete('channel');\n const next = params.toString();\n if (next !== searchParams.toString()) {\n setSearchParams(params, { replace: true });\n }\n }, [debouncedSearch, searchParams, setSearchParams, statusFilter, viewMode, channelFilter]);\n\n useEffect(() => {\n if (!hasToken) return;\n let cancelled = false;\n (async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await listSessions({\n limit: PAGE_LIMIT,\n offset: 0,\n ...(debouncedSearch ? { search: debouncedSearch } : {}),\n ...(statusFilter !== 'all' ? { status: statusFilter } : {}),\n ...(channelFilter ? { channel: channelFilter } : {}),\n });\n if (cancelled) return;\n setSessions(result.items);\n setHasMore(result.hasMore);\n } catch (e) {\n if (!cancelled) setError(e instanceof Error ? e.message : s.loadError);\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [hasToken, debouncedSearch, statusFilter, s.loadError]);\n\n useEffect(() => {\n if (!hasToken) return;\n void getSessionStats()\n .then(setStats)\n .catch(() => {});\n }, [hasToken]);\n\n useEffect(() => {\n if (!hasToken) return;\n const handler = (e: Event) => {\n const detail = (e as CustomEvent<{ key?: string; name?: string }>).detail;\n if (!detail?.key || detail.name === undefined) return;\n setSessions((prev) =>\n prev.map((row) => (row.key === detail.key ? { ...row, name: detail.name } : row)),\n );\n setDetailSession((prev) =>\n prev && prev.key === detail.key ? { ...prev, name: detail.name } : prev,\n );\n };\n window.addEventListener('session-updated', handler);\n return () => {\n window.removeEventListener('session-updated', handler);\n };\n }, [hasToken]);\n\n const loadMore = useCallback(async () => {\n if (!hasToken || loading || !hasMore) return;\n setLoading(true);\n setError(null);\n try {\n const result = await listSessions({\n limit: PAGE_LIMIT,\n offset: sessions.length,\n ...(debouncedSearch ? { search: debouncedSearch } : {}),\n ...(statusFilter !== 'all' ? { status: statusFilter } : {}),\n ...(channelFilter ? { channel: channelFilter } : {}),\n });\n setSessions((prev) => [...prev, ...result.items]);\n setHasMore(result.hasMore);\n } catch (e) {\n setError(e instanceof Error ? e.message : s.loadError);\n } finally {\n setLoading(false);\n }\n }, [\n hasToken,\n loading,\n hasMore,\n sessions.length,\n debouncedSearch,\n statusFilter,\n channelFilter,\n s.loadError,\n ]);\n\n const updateSessionStatus = useCallback((key: string, status: SessionMetadata['status']) => {\n setSessions((prev) => prev.map((row) => (row.key === key ? { ...row, status } : row)));\n setDetailSession((prev) => (prev && prev.key === key ? { ...prev, status } : prev));\n }, []);\n\n const openDetail = useCallback(async (key: string) => {\n setDetailOpen(true);\n setDetailLoading(true);\n setDetailSession(null);\n try {\n const session = await getSessionDetail(key);\n setDetailSession(session);\n } catch {\n setDetailOpen(false);\n } finally {\n setDetailLoading(false);\n }\n }, []);\n\n const handleCardOpen = (key: string) => {\n void openDetail(key);\n };\n\n const handleCardAction = async (key: string, action: SessionCardAction) => {\n if (action === 'continue') {\n window.dispatchEvent(\n new CustomEvent('navigate-to-chat', { detail: { sessionKey: key }, bubbles: true }),\n );\n return;\n }\n if (action === 'delete') {\n setConfirmKey(key);\n setConfirmOpen(true);\n return;\n }\n try {\n switch (action) {\n case 'archive':\n await archiveSession(key);\n updateSessionStatus(key, 'archived');\n break;\n case 'unarchive':\n await unarchiveSession(key);\n updateSessionStatus(key, 'active');\n break;\n case 'pin':\n await pinSession(key);\n updateSessionStatus(key, 'pinned');\n break;\n case 'unpin':\n await unpinSession(key);\n updateSessionStatus(key, 'active');\n break;\n case 'export': {\n const content = await exportSessionJson(key);\n const blob = new Blob([content], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `session-${key.replace(/[^a-z0-9]/gi, '_')}.json`;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n break;\n }\n default:\n break;\n }\n void getSessionStats().then(setStats).catch(() => {});\n } catch {\n /* toast optional */\n }\n };\n\n const runDelete = async (key: string) => {\n try {\n await deleteSession(key);\n setSessions((prev) => prev.filter((row) => row.key !== key));\n setDetailSession((prev) => (prev?.key === key ? null : prev));\n if (detailSession?.key === key) setDetailOpen(false);\n void getSessionStats().then(setStats).catch(() => {});\n } catch {\n /* ignore */\n }\n };\n\n const cardLabels = {\n continueChat: s.continueChat,\n archive: s.archive,\n unarchive: s.unarchive,\n pin: s.pin,\n unpin: s.unpin,\n export: s.export,\n delete: s.delete,\n unnamedSession: m.chat.newSession,\n };\n\n const detailLabels = {\n close: s.close,\n detailLoading: s.detailLoading,\n detailMessages: s.detailMessages,\n detailExport: s.detailExport,\n archive: s.archive,\n unarchive: s.unarchive,\n pin: s.pin,\n unpin: s.unpin,\n delete: s.delete,\n unnamedSession: m.chat.newSession,\n };\n\n const filters: { key: StatusFilter; label: string; icon: typeof Layers }[] = [\n { key: 'all', label: s.filterAll, icon: Layers },\n { key: 'active', label: s.filterActive, icon: Circle },\n { key: 'pinned', label: s.filterPinned, icon: Pin },\n { key: 'archived', label: s.filterArchived, icon: Archive },\n ];\n\n const channelChips = (() => {\n const entries = Object.entries(stats?.byChannel ?? {}).sort((a, b) => b[1] - a[1]);\n const top = entries.slice(0, 6).map(([id]) => id);\n // Keep a few common channels visible even if no stats yet.\n for (const c of ['telegram', 'weixin', 'feishu']) {\n if (!top.includes(c)) top.push(c);\n }\n return top.slice(0, 8);\n })();\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto w-full max-w-2xl px-4 py-16 text-center text-sm text-fg-muted sm:px-8 lg:max-w-app-main\">\n {s.needToken}\n </div>\n );\n }\n\n return (\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto overflow-x-hidden bg-surface-panel\">\n <div className=\"mx-auto flex w-full min-w-0 max-w-2xl flex-col gap-4 px-4 py-6 sm:px-6 lg:max-w-app-main lg:px-8\">\n <header className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <h1 className=\"flex items-center gap-2 text-xl font-semibold tracking-tight text-fg\">\n <FolderOpen className=\"size-5 shrink-0 text-fg-muted\" strokeWidth={1.75} aria-hidden />\n {s.title}\n </h1>\n <div className=\"flex w-full min-w-0 items-center gap-2 rounded-xl bg-surface-base px-3 py-2 transition-colors sm:max-w-md dark:bg-surface-hover/40\">\n <Search className=\"size-4 shrink-0 text-fg-disabled\" strokeWidth={1.75} aria-hidden />\n <input\n type=\"search\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n placeholder={s.searchPlaceholder}\n className=\"min-w-0 flex-1 border-0 bg-transparent text-sm text-fg placeholder:text-fg-disabled focus:outline-none focus:ring-0\"\n />\n </div>\n </header>\n\n <div className=\"flex flex-wrap gap-2\">\n {filters.map(({ key, label, icon: Icon }) => (\n <button\n key={key}\n type=\"button\"\n aria-pressed={statusFilter === key}\n onClick={() => setStatusFilter(key)}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-xl px-3 py-2 text-sm font-medium',\n interaction.transition,\n /* Filter chips (selection): no press scale. */\n interaction.focusRingPanel,\n statusFilter === key\n ? 'bg-accent-soft text-accent-fg'\n : 'bg-surface-base text-fg-muted hover:bg-surface-hover hover:text-fg dark:bg-surface-hover/35',\n )}\n >\n <Icon className=\"size-4\" strokeWidth={1.75} aria-hidden />\n {label}\n </button>\n ))}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-xs font-medium text-fg-subtle\">{s.filterChannelLabel}</span>\n <button\n type=\"button\"\n aria-pressed={!channelFilter}\n onClick={() => setChannelFilter('')}\n className={cn(\n 'inline-flex items-center rounded-xl px-3 py-2 text-sm font-medium',\n interaction.transition,\n interaction.focusRingPanel,\n !channelFilter\n ? 'bg-accent-soft text-accent-fg'\n : 'bg-surface-base text-fg-muted hover:bg-surface-hover hover:text-fg dark:bg-surface-hover/35',\n )}\n >\n {s.filterChannelAll}\n </button>\n {channelChips.map((chId) => (\n <button\n key={chId}\n type=\"button\"\n aria-pressed={channelFilter === chId}\n onClick={() => setChannelFilter(chId)}\n className={cn(\n 'inline-flex items-center rounded-xl px-3 py-2 text-sm font-medium',\n interaction.transition,\n interaction.focusRingPanel,\n channelFilter === chId\n ? 'bg-accent-soft text-accent-fg'\n : 'bg-surface-base text-fg-muted hover:bg-surface-hover hover:text-fg dark:bg-surface-hover/35',\n )}\n >\n {chId}\n {stats?.byChannel?.[chId] != null ? (\n <span className=\"ml-2 rounded-full bg-surface-hover px-2 py-0.5 text-[11px] text-fg-subtle\">\n {stats.byChannel[chId]}\n </span>\n ) : null}\n </button>\n ))}\n </div>\n\n {stats ? (\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n {[\n [stats.totalSessions, s.totalSessions],\n [stats.activeSessions, s.activeSessions],\n [stats.pinnedSessions, s.pinnedSessions],\n [stats.archivedSessions, s.archivedSessions],\n ].map(([value, label]) => (\n <div\n key={label}\n className=\"rounded-xl bg-surface-base px-3 py-3 dark:bg-surface-hover/30\"\n >\n <div className=\"text-lg font-semibold tabular-nums text-fg\">{value}</div>\n <div className=\"text-xs text-fg-muted\">{label}</div>\n </div>\n ))}\n </div>\n ) : null}\n\n {error ? (\n <div className=\"rounded-lg border border-edge bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-edge dark:bg-red-950/40 dark:text-red-300\">\n {error}\n </div>\n ) : null}\n\n <div className=\"flex items-center justify-between gap-2\">\n <p className=\"text-xs text-fg-muted\">{interpolate(s.sessionCount, { count: sessions.length })}</p>\n <div className={segmentedTrackClassName} role=\"group\" aria-label={s.layoutToggleGroup}>\n <Button\n type=\"button\"\n variant=\"segmented\"\n title={s.gridView}\n aria-pressed={viewMode === 'grid'}\n onClick={() => setViewMode('grid')}\n className={cn(\n segmentedThumbBaseClassName,\n 'size-7 p-0',\n viewMode === 'grid' && segmentedThumbActiveClassName,\n viewMode === 'grid' && 'text-accent-fg',\n )}\n >\n <LayoutGrid className=\"size-3.5\" strokeWidth={1.5} />\n </Button>\n <Button\n type=\"button\"\n variant=\"segmented\"\n title={s.listView}\n aria-pressed={viewMode === 'list'}\n onClick={() => setViewMode('list')}\n className={cn(\n segmentedThumbBaseClassName,\n 'size-9 p-0',\n viewMode === 'list' && segmentedThumbActiveClassName,\n viewMode === 'list' && 'text-accent-fg',\n )}\n >\n <LayoutList className=\"size-3.5\" strokeWidth={1.5} />\n </Button>\n </div>\n </div>\n\n {loading && sessions.length === 0 ? (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div\n key={i}\n className=\"h-40 animate-pulse rounded-xl bg-surface-hover/60 dark:bg-surface-hover/40\"\n />\n ))}\n </div>\n ) : sessions.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center rounded-2xl bg-surface-base py-16 text-center dark:bg-surface-hover/25\">\n <FolderOpen className=\"mb-3 size-12 text-fg-disabled\" strokeWidth={1.25} aria-hidden />\n <p className=\"text-base font-semibold text-fg\">{s.noSessions}</p>\n <p className=\"mt-1 max-w-sm text-sm text-fg-muted\">{s.noSessionsDescription}</p>\n <Button\n variant=\"primary\"\n className=\"mt-6\"\n onClick={() => {\n window.dispatchEvent(new CustomEvent('navigate-to-chat', { detail: { sessionKey: '' }, bubbles: true }));\n }}\n >\n {s.startNewChat}\n </Button>\n </div>\n ) : (\n <>\n <div\n className={cn(\n 'grid min-w-0 gap-3',\n viewMode === 'grid' ? 'sm:grid-cols-2 lg:grid-cols-3' : 'grid-cols-1',\n )}\n >\n {sessions.map((session) => (\n <SessionCard\n key={session.key}\n session={session}\n variant={viewMode}\n labels={cardLabels}\n onOpen={() => handleCardOpen(session.key)}\n onAction={(action) => void handleCardAction(session.key, action)}\n />\n ))}\n </div>\n {hasMore ? (\n <div className=\"flex justify-center pt-2\">\n <Button type=\"button\" variant=\"secondary\" disabled={loading} onClick={() => void loadMore()}>\n {s.loadMore}\n </Button>\n </div>\n ) : null}\n </>\n )}\n </div>\n\n <SessionDetailDrawer\n open={detailOpen}\n loading={detailLoading}\n session={detailSession}\n labels={detailLabels}\n onClose={() => {\n setDetailOpen(false);\n setDetailSession(null);\n }}\n onArchive={() => detailSession && void handleCardAction(detailSession.key, 'archive')}\n onUnarchive={() => detailSession && void handleCardAction(detailSession.key, 'unarchive')}\n onPin={() => detailSession && void handleCardAction(detailSession.key, 'pin')}\n onUnpin={() => detailSession && void handleCardAction(detailSession.key, 'unpin')}\n onExport={() => detailSession && void handleCardAction(detailSession.key, 'export')}\n onDelete={() => detailSession && (setConfirmKey(detailSession.key), setConfirmOpen(true))}\n />\n\n <Dialog.Root open={confirmOpen} onOpenChange={setConfirmOpen}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[60] bg-scrim\" />\n <Dialog.Content className=\"xopc-dialog-content fixed left-1/2 top-1/2 z-[60] w-[min(100%-2rem,24rem)] -translate-x-1/2 -translate-y-1/2 rounded-xl border border-edge bg-surface-panel p-4 shadow-popover dark:border-edge\">\n <Dialog.Title className=\"text-base font-semibold text-fg\">{s.deleteSessionTitle}</Dialog.Title>\n <p className=\"mt-2 text-sm text-fg-muted\">\n {confirmKey\n ? interpolate(s.deleteSessionMessage, {\n name:\n sessions.find((x) => x.key === confirmKey)?.name?.trim() || m.chat.newSession,\n })\n : ''}\n </p>\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button type=\"button\" variant=\"secondary\" onClick={() => setConfirmOpen(false)}>\n {s.cancel}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n className=\"bg-red-600 hover:bg-red-700\"\n onClick={() => {\n if (confirmKey) void runDelete(confirmKey);\n setConfirmOpen(false);\n setConfirmKey(null);\n }}\n >\n {s.delete}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sessions-page-DwLHN5GJ.js","names":[],"sources":["../../../../../web/src/features/sessions/session-card.tsx","../../../../../web/src/features/sessions/session-detail-drawer.tsx","../../../../../web/src/features/sessions/sessions-page.tsx"],"sourcesContent":["import {\n Archive,\n ArchiveRestore,\n Download,\n MessageSquare,\n Pin,\n PinOff,\n Trash2,\n Zap,\n} from 'lucide-react';\n\nimport type { SessionMetadata } from '@/features/sessions/session.types';\nimport { ghostIconButton } from '@/lib/interaction';\nimport { cn } from '@/lib/cn';\n\nexport type SessionCardAction =\n | 'continue'\n | 'delete'\n | 'archive'\n | 'unarchive'\n | 'pin'\n | 'unpin'\n | 'export';\n\nfunction formatRelativeDate(dateStr: string): string {\n const date = new Date(dateStr);\n const now = new Date();\n const diffDays = Math.floor((now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24));\n if (diffDays === 0) {\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n }\n if (diffDays === 1) return 'Yesterday';\n if (diffDays < 7) return date.toLocaleDateString([], { weekday: 'short' });\n return date.toLocaleDateString([], { month: 'short', day: 'numeric' });\n}\n\nfunction formatTokens(tokens: number): string {\n if (tokens >= 1000) return `${(tokens / 1000).toFixed(1)}k`;\n return String(tokens);\n}\n\nexport function SessionCard({\n session,\n variant,\n labels,\n onOpen,\n onAction,\n}: {\n session: SessionMetadata;\n variant: 'grid' | 'list';\n labels: {\n continueChat: string;\n archive: string;\n unarchive: string;\n pin: string;\n unpin: string;\n export: string;\n delete: string;\n /** Shown when `session.name` is empty (e.g. new chat before auto-title). */\n unnamedSession: string;\n };\n onOpen: () => void;\n onAction: (action: SessionCardAction) => void;\n}) {\n const displayName = session.name?.trim() || labels.unnamedSession;\n const showKeySubtitle = Boolean(session.name?.trim());\n const isArchived = session.status === 'archived';\n const isPinned = session.status === 'pinned';\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n className={cn(\n // min-w-0: grid/flex children default to min-width:auto — long unbroken titles (URLs) otherwise expand the track\n 'group flex min-w-0 w-full max-w-full cursor-pointer flex-col rounded-xl bg-surface-base text-left transition-colors duration-150 ease-out',\n 'hover:bg-surface-hover active:scale-[0.99]',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-surface-panel',\n variant === 'list' && 'sm:flex-row sm:items-center sm:gap-4',\n )}\n onClick={onOpen}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onOpen();\n }\n }}\n >\n <div\n className={cn(\n 'flex min-w-0 items-start justify-between gap-2 bg-surface-hover/35 px-3 py-2 dark:bg-surface-hover/25',\n variant === 'list' && 'sm:py-3',\n )}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"truncate text-[11px] font-medium uppercase tracking-wide text-fg-subtle\">\n {session.sourceChannel}\n </span>\n </div>\n <div className=\"flex shrink-0 items-center gap-1.5 text-xs text-fg-muted\">\n {isPinned ? <Pin className=\"size-3.5 text-accent-fg\" strokeWidth={1.75} aria-hidden /> : null}\n <span>{formatRelativeDate(session.updatedAt)}</span>\n </div>\n </div>\n\n <div className={cn('min-w-0 flex-1 px-3 py-2', variant === 'list' && 'sm:py-3')}>\n <div className=\"min-w-0 max-w-full truncate text-sm font-semibold text-fg\" title={displayName}>\n {displayName}\n </div>\n {showKeySubtitle ? (\n <div\n className=\"mt-0.5 min-w-0 max-w-full truncate font-mono text-[11px] text-fg-subtle\"\n title={session.key}\n >\n {session.key}\n </div>\n ) : null}\n <div className=\"mt-2 flex flex-wrap items-center gap-3 text-xs text-fg-muted\">\n <span className=\"inline-flex items-center gap-1\">\n <MessageSquare className=\"size-3.5\" strokeWidth={1.75} aria-hidden />\n {session.messageCount}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <Zap className=\"size-3.5\" strokeWidth={1.75} aria-hidden />\n {formatTokens(session.estimatedTokens)}\n </span>\n </div>\n {session.tags.length > 0 ? (\n <div className=\"mt-2 flex flex-wrap gap-1\">\n {session.tags.slice(0, 3).map((tag) => (\n <span\n key={tag}\n className=\"max-w-full break-words rounded-md bg-surface-hover px-1.5 py-0.5 text-[11px] text-fg-muted\"\n >\n {tag}\n </span>\n ))}\n {session.tags.length > 3 ? (\n <span className=\"text-[11px] text-fg-disabled\">+{session.tags.length - 3}</span>\n ) : null}\n </div>\n ) : null}\n </div>\n\n <div\n className=\"flex flex-wrap items-center gap-0.5 border-t border-edge-subtle/80 bg-surface-hover/25 px-2 py-2 dark:border-edge-subtle\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.continueChat}\n aria-label={labels.continueChat}\n onClick={() => onAction('continue')}\n >\n <MessageSquare className=\"size-4\" strokeWidth={1.75} />\n </button>\n {isArchived ? (\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.unarchive}\n aria-label={labels.unarchive}\n onClick={() => onAction('unarchive')}\n >\n <ArchiveRestore className=\"size-4\" strokeWidth={1.75} />\n </button>\n ) : (\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.archive}\n aria-label={labels.archive}\n onClick={() => onAction('archive')}\n >\n <Archive className=\"size-4\" strokeWidth={1.75} />\n </button>\n )}\n {isPinned ? (\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.unpin}\n aria-label={labels.unpin}\n onClick={() => onAction('unpin')}\n >\n <PinOff className=\"size-4\" strokeWidth={1.75} />\n </button>\n ) : (\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.pin}\n aria-label={labels.pin}\n onClick={() => onAction('pin')}\n >\n <Pin className=\"size-4\" strokeWidth={1.75} />\n </button>\n )}\n <button\n type=\"button\"\n className={ghostIconButton}\n title={labels.export}\n aria-label={labels.export}\n onClick={() => onAction('export')}\n >\n <Download className=\"size-4\" strokeWidth={1.75} />\n </button>\n <button\n type=\"button\"\n className={cn(\n ghostIconButton,\n 'text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950/40',\n )}\n title={labels.delete}\n aria-label={labels.delete}\n onClick={() => onAction('delete')}\n >\n <Trash2 className=\"size-4\" strokeWidth={1.75} />\n </button>\n </div>\n </div>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\n\nimport type { SessionDetail } from '@/features/sessions/session.types';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\n\nfunction previewContent(content: string | unknown[]): string {\n if (typeof content === 'string') {\n return content.length > 2000 ? `${content.slice(0, 2000)}…` : content;\n }\n try {\n const s = JSON.stringify(content, null, 2);\n return s.length > 2000 ? `${s.slice(0, 2000)}…` : s;\n } catch {\n return String(content);\n }\n}\n\nexport function SessionDetailDrawer({\n open,\n loading,\n session,\n labels,\n onClose,\n onArchive,\n onUnarchive,\n onPin,\n onUnpin,\n onExport,\n onDelete,\n}: {\n open: boolean;\n loading: boolean;\n session: SessionDetail | null;\n labels: {\n close: string;\n detailLoading: string;\n detailMessages: string;\n detailExport: string;\n archive: string;\n unarchive: string;\n pin: string;\n unpin: string;\n delete: string;\n unnamedSession: string;\n };\n onClose: () => void;\n onArchive: () => void;\n onUnarchive: () => void;\n onPin: () => void;\n onUnpin: () => void;\n onExport: () => void;\n onDelete: () => void;\n}) {\n const isArchived = session?.status === 'archived';\n const isPinned = session?.status === 'pinned';\n\n return (\n <Dialog.Root open={open} onOpenChange={(v) => !v && onClose()}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-50 bg-scrim\" />\n <Dialog.Content\n className={cn(\n 'xopc-drawer-right fixed right-0 top-0 z-50 flex h-full w-full max-w-lg flex-col border-l border-edge bg-surface-panel shadow-popover outline-none',\n 'dark:border-edge',\n )}\n aria-describedby={undefined}\n >\n <div className=\"flex min-w-0 shrink-0 items-center justify-between gap-2 border-b border-edge px-4 py-3 dark:border-edge\">\n <Dialog.Title className=\"min-w-0 flex-1 truncate text-base font-semibold tracking-tight text-fg\">\n {session?.name?.trim() || labels.unnamedSession}\n </Dialog.Title>\n <Dialog.Close asChild>\n <Button type=\"button\" variant=\"ghost\" className=\"h-9 w-9 shrink-0 p-0\" aria-label={labels.close}>\n <X className=\"size-5\" strokeWidth={1.75} />\n </Button>\n </Dialog.Close>\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto px-4 py-3\">\n {loading ? (\n <p className=\"text-sm text-fg-muted\">{labels.detailLoading}</p>\n ) : session ? (\n <>\n <dl className=\"mb-4 grid gap-2 text-xs text-fg-muted\">\n <div>\n <dt className=\"text-fg-disabled\">Key</dt>\n <dd className=\"mt-0.5 break-all font-mono text-fg\">{session.key}</dd>\n </div>\n <div className=\"flex flex-wrap gap-4\">\n <span>\n {session.messageCount} msgs · {session.estimatedTokens} tok\n </span>\n </div>\n </dl>\n <h3 className=\"mb-2 text-xs font-medium uppercase tracking-wide text-fg-subtle\">\n {labels.detailMessages}\n </h3>\n <ul className=\"space-y-3\">\n {session.messages.map((msg, i) => (\n <li\n key={`${msg.timestamp ?? i}-${i}`}\n className=\"rounded-lg border border-edge-subtle bg-surface-hover/50 p-2 dark:border-edge\"\n >\n <div className=\"mb-1 text-[10px] font-medium uppercase text-fg-subtle\">{msg.role}</div>\n <pre className=\"max-h-40 overflow-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-relaxed text-fg-muted\">\n {previewContent(msg.content)}\n </pre>\n </li>\n ))}\n </ul>\n </>\n ) : null}\n </div>\n\n <div className=\"shrink-0 border-t border-edge px-4 py-3 dark:border-edge\">\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={onExport}>\n {labels.detailExport}\n </Button>\n {isArchived ? (\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={onUnarchive}>\n {labels.unarchive}\n </Button>\n ) : (\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={onArchive}>\n {labels.archive}\n </Button>\n )}\n {isPinned ? (\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={onUnpin}>\n {labels.unpin}\n </Button>\n ) : (\n <Button type=\"button\" variant=\"secondary\" className=\"text-sm\" onClick={onPin}>\n {labels.pin}\n </Button>\n )}\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"text-sm text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-950/40\"\n onClick={onDelete}\n >\n {labels.delete}\n </Button>\n </div>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n );\n}\n","import * as Dialog from '@radix-ui/react-dialog';\nimport {\n Archive,\n Circle,\n FolderOpen,\n Layers,\n LayoutGrid,\n LayoutList,\n Pin,\n Search,\n} from 'lucide-react';\nimport { useCallback, useEffect, useState } from 'react';\nimport { useSearchParams } from 'react-router-dom';\n\nimport { SessionCard, type SessionCardAction } from '@/features/sessions/session-card';\nimport { SessionDetailDrawer } from '@/features/sessions/session-detail-drawer';\nimport {\n archiveSession,\n deleteSession,\n exportSessionJson,\n getSessionDetail,\n getSessionStats,\n listSessions,\n pinSession,\n unarchiveSession,\n unpinSession,\n} from '@/features/sessions/session-api';\nimport type { SessionDetail, SessionMetadata, SessionStats } from '@/features/sessions/session.types';\nimport { Button } from '@/components/ui/button';\nimport {\n segmentedThumbActiveClassName,\n segmentedThumbBaseClassName,\n segmentedTrackClassName,\n} from '@/components/ui/segmented-styles';\nimport { cn } from '@/lib/cn';\nimport { interaction } from '@/lib/interaction';\nimport { messages } from '@/i18n/messages';\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { useLocaleStore } from '@/stores/locale-store';\n\nconst PAGE_LIMIT = 20;\n\nfunction interpolate(template: string, params: Record<string, string | number>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => String(params[key] ?? ''));\n}\n\ntype StatusFilter = 'all' | 'active' | 'pinned' | 'archived';\ntype SessionsViewMode = 'grid' | 'list';\n\nconst SESSION_STATUS_FILTER_SET = new Set<StatusFilter>(['all', 'active', 'pinned', 'archived']);\nconst SESSION_VIEW_MODE_SET = new Set<SessionsViewMode>(['grid', 'list']);\n\nexport function SessionsPage() {\n const language = useLocaleStore((s) => s.language);\n const m = messages(language);\n const s = m.sessions;\n const token = useGatewayStore((st) => st.token);\n const hasToken = Boolean(token);\n const [searchParams, setSearchParams] = useSearchParams();\n\n const initialSearch = searchParams.get('q') ?? '';\n const initialStatus = searchParams.get('status');\n const initialView = searchParams.get('view');\n const initialChannel = searchParams.get('channel') ?? '';\n const initialStatusFilter: StatusFilter = SESSION_STATUS_FILTER_SET.has(initialStatus as StatusFilter)\n ? (initialStatus as StatusFilter)\n : 'all';\n const initialViewMode: SessionsViewMode = SESSION_VIEW_MODE_SET.has(initialView as SessionsViewMode)\n ? (initialView as SessionsViewMode)\n : 'grid';\n\n const [searchInput, setSearchInput] = useState(initialSearch);\n const [debouncedSearch, setDebouncedSearch] = useState(initialSearch.trim());\n const [statusFilter, setStatusFilter] = useState<StatusFilter>(initialStatusFilter);\n const [viewMode, setViewMode] = useState<SessionsViewMode>(initialViewMode);\n const [channelFilter, setChannelFilter] = useState(initialChannel.trim());\n\n const [sessions, setSessions] = useState<SessionMetadata[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [hasMore, setHasMore] = useState(false);\n const [stats, setStats] = useState<SessionStats | null>(null);\n\n const [detailOpen, setDetailOpen] = useState(false);\n const [detailLoading, setDetailLoading] = useState(false);\n const [detailSession, setDetailSession] = useState<SessionDetail | null>(null);\n\n const [confirmOpen, setConfirmOpen] = useState(false);\n const [confirmKey, setConfirmKey] = useState<string | null>(null);\n\n useEffect(() => {\n const t = setTimeout(() => setDebouncedSearch(searchInput.trim()), 300);\n return () => clearTimeout(t);\n }, [searchInput]);\n\n useEffect(() => {\n const nextQ = searchParams.get('q') ?? '';\n const nextStatusRaw = searchParams.get('status');\n const nextViewRaw = searchParams.get('view');\n const nextChannel = (searchParams.get('channel') ?? '').trim();\n const nextStatus: StatusFilter = SESSION_STATUS_FILTER_SET.has(nextStatusRaw as StatusFilter)\n ? (nextStatusRaw as StatusFilter)\n : 'all';\n const nextView: SessionsViewMode = SESSION_VIEW_MODE_SET.has(nextViewRaw as SessionsViewMode)\n ? (nextViewRaw as SessionsViewMode)\n : 'grid';\n const nextDebouncedQ = nextQ.trim();\n\n setSearchInput((prev) => (prev === nextQ ? prev : nextQ));\n setDebouncedSearch((prev) => (prev === nextDebouncedQ ? prev : nextDebouncedQ));\n setStatusFilter((prev) => (prev === nextStatus ? prev : nextStatus));\n setViewMode((prev) => (prev === nextView ? prev : nextView));\n setChannelFilter((prev) => (prev === nextChannel ? prev : nextChannel));\n }, [searchParams]);\n\n useEffect(() => {\n const params = new URLSearchParams(searchParams);\n const nextQ = debouncedSearch.trim();\n if (nextQ) params.set('q', nextQ);\n else params.delete('q');\n if (statusFilter !== 'all') params.set('status', statusFilter);\n else params.delete('status');\n if (viewMode !== 'grid') params.set('view', viewMode);\n else params.delete('view');\n if (channelFilter) params.set('channel', channelFilter);\n else params.delete('channel');\n const next = params.toString();\n if (next !== searchParams.toString()) {\n setSearchParams(params, { replace: true });\n }\n }, [debouncedSearch, searchParams, setSearchParams, statusFilter, viewMode, channelFilter]);\n\n useEffect(() => {\n if (!hasToken) return;\n let cancelled = false;\n (async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await listSessions({\n limit: PAGE_LIMIT,\n offset: 0,\n ...(debouncedSearch ? { search: debouncedSearch } : {}),\n ...(statusFilter !== 'all' ? { status: statusFilter } : {}),\n ...(channelFilter ? { channel: channelFilter } : {}),\n });\n if (cancelled) return;\n setSessions(result.items);\n setHasMore(result.hasMore);\n } catch (e) {\n if (!cancelled) setError(e instanceof Error ? e.message : s.loadError);\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [hasToken, debouncedSearch, statusFilter, s.loadError]);\n\n useEffect(() => {\n if (!hasToken) return;\n void getSessionStats()\n .then(setStats)\n .catch(() => {});\n }, [hasToken]);\n\n useEffect(() => {\n if (!hasToken) return;\n const handler = (e: Event) => {\n const detail = (e as CustomEvent<{ key?: string; name?: string }>).detail;\n if (!detail?.key || detail.name === undefined) return;\n setSessions((prev) =>\n prev.map((row) => (row.key === detail.key ? { ...row, name: detail.name } : row)),\n );\n setDetailSession((prev) =>\n prev && prev.key === detail.key ? { ...prev, name: detail.name } : prev,\n );\n };\n window.addEventListener('session-updated', handler);\n return () => {\n window.removeEventListener('session-updated', handler);\n };\n }, [hasToken]);\n\n const loadMore = useCallback(async () => {\n if (!hasToken || loading || !hasMore) return;\n setLoading(true);\n setError(null);\n try {\n const result = await listSessions({\n limit: PAGE_LIMIT,\n offset: sessions.length,\n ...(debouncedSearch ? { search: debouncedSearch } : {}),\n ...(statusFilter !== 'all' ? { status: statusFilter } : {}),\n ...(channelFilter ? { channel: channelFilter } : {}),\n });\n setSessions((prev) => [...prev, ...result.items]);\n setHasMore(result.hasMore);\n } catch (e) {\n setError(e instanceof Error ? e.message : s.loadError);\n } finally {\n setLoading(false);\n }\n }, [\n hasToken,\n loading,\n hasMore,\n sessions.length,\n debouncedSearch,\n statusFilter,\n channelFilter,\n s.loadError,\n ]);\n\n const updateSessionStatus = useCallback((key: string, status: SessionMetadata['status']) => {\n setSessions((prev) => prev.map((row) => (row.key === key ? { ...row, status } : row)));\n setDetailSession((prev) => (prev && prev.key === key ? { ...prev, status } : prev));\n }, []);\n\n const openDetail = useCallback(async (key: string) => {\n setDetailOpen(true);\n setDetailLoading(true);\n setDetailSession(null);\n try {\n const session = await getSessionDetail(key);\n setDetailSession(session);\n } catch {\n setDetailOpen(false);\n } finally {\n setDetailLoading(false);\n }\n }, []);\n\n const handleCardOpen = (key: string) => {\n void openDetail(key);\n };\n\n const handleCardAction = async (key: string, action: SessionCardAction) => {\n if (action === 'continue') {\n window.dispatchEvent(\n new CustomEvent('navigate-to-chat', { detail: { sessionKey: key }, bubbles: true }),\n );\n return;\n }\n if (action === 'delete') {\n setConfirmKey(key);\n setConfirmOpen(true);\n return;\n }\n try {\n switch (action) {\n case 'archive':\n await archiveSession(key);\n updateSessionStatus(key, 'archived');\n break;\n case 'unarchive':\n await unarchiveSession(key);\n updateSessionStatus(key, 'active');\n break;\n case 'pin':\n await pinSession(key);\n updateSessionStatus(key, 'pinned');\n break;\n case 'unpin':\n await unpinSession(key);\n updateSessionStatus(key, 'active');\n break;\n case 'export': {\n const content = await exportSessionJson(key);\n const blob = new Blob([content], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `session-${key.replace(/[^a-z0-9]/gi, '_')}.json`;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n break;\n }\n default:\n break;\n }\n void getSessionStats().then(setStats).catch(() => {});\n } catch {\n /* toast optional */\n }\n };\n\n const runDelete = async (key: string) => {\n try {\n await deleteSession(key);\n setSessions((prev) => prev.filter((row) => row.key !== key));\n setDetailSession((prev) => (prev?.key === key ? null : prev));\n if (detailSession?.key === key) setDetailOpen(false);\n void getSessionStats().then(setStats).catch(() => {});\n } catch {\n /* ignore */\n }\n };\n\n const cardLabels = {\n continueChat: s.continueChat,\n archive: s.archive,\n unarchive: s.unarchive,\n pin: s.pin,\n unpin: s.unpin,\n export: s.export,\n delete: s.delete,\n unnamedSession: m.chat.newSession,\n };\n\n const detailLabels = {\n close: s.close,\n detailLoading: s.detailLoading,\n detailMessages: s.detailMessages,\n detailExport: s.detailExport,\n archive: s.archive,\n unarchive: s.unarchive,\n pin: s.pin,\n unpin: s.unpin,\n delete: s.delete,\n unnamedSession: m.chat.newSession,\n };\n\n const filters: { key: StatusFilter; label: string; icon: typeof Layers }[] = [\n { key: 'all', label: s.filterAll, icon: Layers },\n { key: 'active', label: s.filterActive, icon: Circle },\n { key: 'pinned', label: s.filterPinned, icon: Pin },\n { key: 'archived', label: s.filterArchived, icon: Archive },\n ];\n\n const channelChips = (() => {\n const entries = Object.entries(stats?.byChannel ?? {}).sort((a, b) => b[1] - a[1]);\n const top = entries.slice(0, 6).map(([id]) => id);\n // Keep a few common channels visible even if no stats yet.\n for (const c of ['telegram', 'weixin', 'feishu']) {\n if (!top.includes(c)) top.push(c);\n }\n return top.slice(0, 8);\n })();\n\n if (!hasToken) {\n return (\n <div className=\"mx-auto w-full max-w-2xl px-4 py-16 text-center text-sm text-fg-muted sm:px-8 lg:max-w-app-main\">\n {s.needToken}\n </div>\n );\n }\n\n return (\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto overflow-x-hidden bg-surface-panel\">\n <div className=\"mx-auto flex w-full min-w-0 max-w-2xl flex-col gap-4 px-4 py-6 sm:px-6 lg:max-w-app-main lg:px-8\">\n <header className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <h1 className=\"flex items-center gap-2 text-xl font-semibold tracking-tight text-fg\">\n <FolderOpen className=\"size-5 shrink-0 text-fg-muted\" strokeWidth={1.75} aria-hidden />\n {s.title}\n </h1>\n <div className=\"flex w-full min-w-0 items-center gap-2 rounded-xl bg-surface-base px-3 py-2 transition-colors sm:max-w-md dark:bg-surface-hover/40\">\n <Search className=\"size-4 shrink-0 text-fg-disabled\" strokeWidth={1.75} aria-hidden />\n <input\n type=\"search\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n placeholder={s.searchPlaceholder}\n className=\"min-w-0 flex-1 border-0 bg-transparent text-sm text-fg placeholder:text-fg-disabled focus:outline-none focus:ring-0\"\n />\n </div>\n </header>\n\n <div className=\"flex flex-wrap gap-2\">\n {filters.map(({ key, label, icon: Icon }) => (\n <button\n key={key}\n type=\"button\"\n aria-pressed={statusFilter === key}\n onClick={() => setStatusFilter(key)}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-xl px-3 py-2 text-sm font-medium',\n interaction.transition,\n /* Filter chips (selection): no press scale. */\n interaction.focusRingPanel,\n statusFilter === key\n ? 'bg-accent-soft text-accent-fg'\n : 'bg-surface-base text-fg-muted hover:bg-surface-hover hover:text-fg dark:bg-surface-hover/35',\n )}\n >\n <Icon className=\"size-4\" strokeWidth={1.75} aria-hidden />\n {label}\n </button>\n ))}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-xs font-medium text-fg-subtle\">{s.filterChannelLabel}</span>\n <button\n type=\"button\"\n aria-pressed={!channelFilter}\n onClick={() => setChannelFilter('')}\n className={cn(\n 'inline-flex items-center rounded-xl px-3 py-2 text-sm font-medium',\n interaction.transition,\n interaction.focusRingPanel,\n !channelFilter\n ? 'bg-accent-soft text-accent-fg'\n : 'bg-surface-base text-fg-muted hover:bg-surface-hover hover:text-fg dark:bg-surface-hover/35',\n )}\n >\n {s.filterChannelAll}\n </button>\n {channelChips.map((chId) => (\n <button\n key={chId}\n type=\"button\"\n aria-pressed={channelFilter === chId}\n onClick={() => setChannelFilter(chId)}\n className={cn(\n 'inline-flex items-center rounded-xl px-3 py-2 text-sm font-medium',\n interaction.transition,\n interaction.focusRingPanel,\n channelFilter === chId\n ? 'bg-accent-soft text-accent-fg'\n : 'bg-surface-base text-fg-muted hover:bg-surface-hover hover:text-fg dark:bg-surface-hover/35',\n )}\n >\n {chId}\n {stats?.byChannel?.[chId] != null ? (\n <span className=\"ml-2 rounded-full bg-surface-hover px-2 py-0.5 text-[11px] text-fg-subtle\">\n {stats.byChannel[chId]}\n </span>\n ) : null}\n </button>\n ))}\n </div>\n\n {stats ? (\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n {[\n [stats.totalSessions, s.totalSessions],\n [stats.activeSessions, s.activeSessions],\n [stats.pinnedSessions, s.pinnedSessions],\n [stats.archivedSessions, s.archivedSessions],\n ].map(([value, label]) => (\n <div\n key={label}\n className=\"rounded-xl bg-surface-base px-3 py-3 dark:bg-surface-hover/30\"\n >\n <div className=\"text-lg font-semibold tabular-nums text-fg\">{value}</div>\n <div className=\"text-xs text-fg-muted\">{label}</div>\n </div>\n ))}\n </div>\n ) : null}\n\n {error ? (\n <div className=\"rounded-lg border border-edge bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-edge dark:bg-red-950/40 dark:text-red-300\">\n {error}\n </div>\n ) : null}\n\n <div className=\"flex items-center justify-between gap-2\">\n <p className=\"text-xs text-fg-muted\">{interpolate(s.sessionCount, { count: sessions.length })}</p>\n <div className={segmentedTrackClassName} role=\"group\" aria-label={s.layoutToggleGroup}>\n <Button\n type=\"button\"\n variant=\"segmented\"\n title={s.gridView}\n aria-pressed={viewMode === 'grid'}\n onClick={() => setViewMode('grid')}\n className={cn(\n segmentedThumbBaseClassName,\n 'size-7 p-0',\n viewMode === 'grid' && segmentedThumbActiveClassName,\n viewMode === 'grid' && 'text-accent-fg',\n )}\n >\n <LayoutGrid className=\"size-3.5\" strokeWidth={1.5} />\n </Button>\n <Button\n type=\"button\"\n variant=\"segmented\"\n title={s.listView}\n aria-pressed={viewMode === 'list'}\n onClick={() => setViewMode('list')}\n className={cn(\n segmentedThumbBaseClassName,\n 'size-9 p-0',\n viewMode === 'list' && segmentedThumbActiveClassName,\n viewMode === 'list' && 'text-accent-fg',\n )}\n >\n <LayoutList className=\"size-3.5\" strokeWidth={1.5} />\n </Button>\n </div>\n </div>\n\n {loading && sessions.length === 0 ? (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div\n key={i}\n className=\"h-40 animate-pulse rounded-xl bg-surface-hover/60 dark:bg-surface-hover/40\"\n />\n ))}\n </div>\n ) : sessions.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center rounded-2xl bg-surface-base py-16 text-center dark:bg-surface-hover/25\">\n <FolderOpen className=\"mb-3 size-12 text-fg-disabled\" strokeWidth={1.25} aria-hidden />\n <p className=\"text-base font-semibold text-fg\">{s.noSessions}</p>\n <p className=\"mt-1 max-w-sm text-sm text-fg-muted\">{s.noSessionsDescription}</p>\n <Button\n variant=\"primary\"\n className=\"mt-6\"\n onClick={() => {\n window.dispatchEvent(new CustomEvent('navigate-to-chat', { detail: { sessionKey: '' }, bubbles: true }));\n }}\n >\n {s.startNewChat}\n </Button>\n </div>\n ) : (\n <>\n <div\n className={cn(\n 'grid min-w-0 gap-3',\n viewMode === 'grid' ? 'sm:grid-cols-2 lg:grid-cols-3' : 'grid-cols-1',\n )}\n >\n {sessions.map((session) => (\n <SessionCard\n key={session.key}\n session={session}\n variant={viewMode}\n labels={cardLabels}\n onOpen={() => handleCardOpen(session.key)}\n onAction={(action) => void handleCardAction(session.key, action)}\n />\n ))}\n </div>\n {hasMore ? (\n <div className=\"flex justify-center pt-2\">\n <Button type=\"button\" variant=\"secondary\" disabled={loading} onClick={() => void loadMore()}>\n {s.loadMore}\n </Button>\n </div>\n ) : null}\n </>\n )}\n </div>\n\n <SessionDetailDrawer\n open={detailOpen}\n loading={detailLoading}\n session={detailSession}\n labels={detailLabels}\n onClose={() => {\n setDetailOpen(false);\n setDetailSession(null);\n }}\n onArchive={() => detailSession && void handleCardAction(detailSession.key, 'archive')}\n onUnarchive={() => detailSession && void handleCardAction(detailSession.key, 'unarchive')}\n onPin={() => detailSession && void handleCardAction(detailSession.key, 'pin')}\n onUnpin={() => detailSession && void handleCardAction(detailSession.key, 'unpin')}\n onExport={() => detailSession && void handleCardAction(detailSession.key, 'export')}\n onDelete={() => detailSession && (setConfirmKey(detailSession.key), setConfirmOpen(true))}\n />\n\n <Dialog.Root open={confirmOpen} onOpenChange={setConfirmOpen}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"xopc-dialog-overlay fixed inset-0 z-[60] bg-scrim\" />\n <Dialog.Content className=\"xopc-dialog-content fixed left-1/2 top-1/2 z-[60] w-[min(100%-2rem,24rem)] -translate-x-1/2 -translate-y-1/2 rounded-xl border border-edge bg-surface-panel p-4 shadow-popover dark:border-edge\">\n <Dialog.Title className=\"text-base font-semibold text-fg\">{s.deleteSessionTitle}</Dialog.Title>\n <p className=\"mt-2 text-sm text-fg-muted\">\n {confirmKey\n ? interpolate(s.deleteSessionMessage, {\n name:\n sessions.find((x) => x.key === confirmKey)?.name?.trim() || m.chat.newSession,\n })\n : ''}\n </p>\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button type=\"button\" variant=\"secondary\" onClick={() => setConfirmOpen(false)}>\n {s.cancel}\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n className=\"bg-red-600 hover:bg-red-700\"\n onClick={() => {\n if (confirmKey) void runDelete(confirmKey);\n setConfirmOpen(false);\n setConfirmKey(null);\n }}\n >\n {s.delete}\n </Button>\n </div>\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{i as t,t as n}from"./vendor-react-DbimaAId.js";import{i as r,o as i}from"./vendor-swr-B5fPo7KK.js";import{t as a}from"./cn-BMCV0OMB.js";import{A as o,Ar as s,Dn as c,Er as l,Fr as u,Gn as d,Gt as f,Hr as p,In as m,Jt as h,Kn as g,Kr as _,Mr as v,Nr as y,Or as b,Pn as x,Qt as S,Tn as C,Ur as w,Ut as T,V as E,Vn as D,W as O,Wn as k,Wt as A,Xt as j,Zt as M,_n as N,_t as P,a as F,an as I,at as L,c as ee,ct as R,dn as z,dt as B,f as te,fr as ne,ft as V,gt as H,ht as re,i as ie,in as U,jn as ae,k as W,kn as oe,lt as G,mr as K,mt as se,n as ce,nn as le,nr as ue,o as de,on as q,ot as fe,p as pe,pn as me,pr as he,pt as ge,qt as _e,r as ve,rr as ye,s as be,sn as J,t as xe,tr as Se,un as Ce,ut as we,vr as Te,yr as Ee,zn as De}from"./index-BZvlG48D.js";import{a as Oe,p as ke,v as Ae}from"./cron-utils-DyOO6TdN.js";import{i as je,n as Me,r as Ne,t as Pe}from"./agents-CiZMJZRp.js";var Y=n();function Fe(){return a(`rounded-xl border border-edge-subtle bg-surface-base px-4 py-1 sm:px-5`)}function Ie({scheme:e}){return e===`emerald`?(0,Y.jsxs)(`div`,{className:`flex h-10 w-full overflow-hidden rounded-md border border-edge-subtle`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-1 flex-col gap-1 bg-[#0a0a0a] p-1.5`,children:[(0,Y.jsx)(`div`,{className:`h-1 w-8 rounded-full bg-[#134e2a]`}),(0,Y.jsx)(`div`,{className:`h-1 w-5 rounded-full bg-[#134e2a]`})]}),(0,Y.jsx)(`div`,{className:`w-1.5 bg-[#10b981]`}),(0,Y.jsxs)(`div`,{className:`flex flex-1 flex-col gap-1 bg-[#000000] p-1.5`,children:[(0,Y.jsx)(`div`,{className:`h-1 w-6 rounded-full bg-[#34d399]`}),(0,Y.jsx)(`div`,{className:`h-1 w-9 rounded-full bg-[#065f46]`}),(0,Y.jsx)(`div`,{className:`h-1 w-4 rounded-full bg-[#065f46]`})]})]}):(0,Y.jsxs)(`div`,{className:`flex h-10 w-full overflow-hidden rounded-md border border-edge-subtle`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-1 flex-col gap-1 bg-[#f5f5f7] p-1.5`,children:[(0,Y.jsx)(`div`,{className:`h-1 w-8 rounded-full bg-[#d2d2d7]`}),(0,Y.jsx)(`div`,{className:`h-1 w-5 rounded-full bg-[#d2d2d7]`})]}),(0,Y.jsx)(`div`,{className:`w-1.5 bg-[#2563eb]`}),(0,Y.jsxs)(`div`,{className:`flex flex-1 flex-col gap-1 bg-[#ffffff] p-1.5`,children:[(0,Y.jsx)(`div`,{className:`h-1 w-6 rounded-full bg-[#1d1d1f]`}),(0,Y.jsx)(`div`,{className:`h-1 w-9 rounded-full bg-[#d2d2d7]`}),(0,Y.jsx)(`div`,{className:`h-1 w-4 rounded-full bg-[#d2d2d7]`})]})]})}var Le=[{value:`default`,labelKey:`colorSchemeDefault`},{value:`emerald`,labelKey:`colorSchemeLightGreen`}];function Re(){let e=q(S(e=>e.language)).appearanceSettings,t=M(e=>e.colorScheme),n=M(e=>e.setColorScheme);return(0,Y.jsxs)(`div`,{className:`flex flex-col gap-2 border-b border-edge-subtle py-3.5 last:border-b-0 sm:py-4`,children:[(0,Y.jsxs)(`div`,{className:`min-w-0`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-semibold text-fg`,children:e.colorSchemeTitle}),(0,Y.jsx)(`p`,{className:`mt-0.5 text-xs text-fg-muted`,children:e.colorSchemeDescription})]}),(0,Y.jsx)(`div`,{className:`grid grid-cols-2 gap-3 sm:grid-cols-3`,children:Le.map(({value:r,labelKey:i})=>{let o=t===r;return(0,Y.jsxs)(`button`,{type:`button`,"aria-pressed":o,onClick:()=>n(r),className:a(`flex flex-col gap-2 rounded-xl border-2 p-2.5 text-left transition-[border-color,box-shadow] duration-150`,o?`border-accent shadow-[0_0_0_1px_var(--color-accent)]`:`border-edge-subtle hover:border-edge`),children:[(0,Y.jsx)(Ie,{scheme:r}),(0,Y.jsx)(`span`,{className:a(`text-xs font-medium leading-none`,o?`text-accent-fg`:`text-fg-muted`),children:e[i]})]},r)})})]})}function ze(){let e=q(S(e=>e.language)).appearanceSettings;return(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6`,children:[(0,Y.jsxs)(`header`,{className:`flex flex-col gap-1`,children:[(0,Y.jsx)(`h1`,{className:`text-xl font-semibold tracking-tight text-fg`,children:e.pageTitle}),(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:e.subtitle})]}),(0,Y.jsxs)(`section`,{className:Fe(),"aria-labelledby":`pref-language-heading`,children:[(0,Y.jsx)(`h2`,{id:`pref-language-heading`,className:`sr-only`,children:e.languageTitle}),(0,Y.jsx)(j,{variant:`page`,sections:[`language`]})]}),(0,Y.jsxs)(`section`,{className:Fe(),"aria-labelledby":`pref-appearance-heading`,children:[(0,Y.jsx)(`h2`,{id:`pref-appearance-heading`,className:`sr-only`,children:e.themeTitle}),(0,Y.jsx)(j,{variant:`page`,sections:[`theme`,`font`]}),(0,Y.jsx)(Re,{})]})]})}var X=e(t(),1);function Be(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ve(e){let t=Be(e)?e:{},n=Be(t.gateway)?t.gateway:{},r=Be(n.auth)?n.auth:{},i=r.mode===`none`||r.mode===`token`?r.mode:`token`,a=(Be(t.update)?t.update:{}).channel,o=a===`beta`||a===`dev`||a===`stable`?a:`stable`;return{host:typeof n.host==`string`?n.host:``,port:typeof n.port==`number`?n.port:void 0,auth:{mode:i,token:typeof r.token==`string`?r.token:``},updateChannel:o}}async function He(e){let t=e.auth.token.trim().length>0?{mode:e.auth.mode,token:e.auth.token}:{mode:e.auth.mode};await f(T(`/api/config`),{method:`PATCH`,body:JSON.stringify({gateway:{auth:t},update:{channel:e.updateChannel}})}),W()}function Ue(){return a(`w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg`,`placeholder:text-fg-subtle`,I,`dark:border-edge`)}function We(){let e=S(e=>e.language),t=q(e),n=t.gatewaySettings,r=_e(e=>e.token),i=_e(e=>e.tokenExpired),a=_e(e=>e.openTokenDialog),s=!!r,[l,u]=(0,X.useState)(null),[d,f]=(0,X.useState)(null),[p,m]=(0,X.useState)(!1),[_,v]=(0,X.useState)(null),[y,x]=(0,X.useState)(!1),[C,w]=(0,X.useState)(!1),[T,E]=(0,X.useState)(!1),D=(0,X.useRef)(!1),{data:O,error:k,isLoading:A,mutate:j}=o(s),M=(0,X.useMemo)(()=>O?.payload?.config===void 0?null:structuredClone(Ve(O.payload.config)),[O]);(0,X.useEffect)(()=>{if(!s){u(null),f(null),D.current=!1;return}M!==null&&(D.current||(u(M),f(structuredClone(M)),x(!1)))},[s,M]);let N=!!(s&&A&&O===void 0&&!k),P=k instanceof Error?k.message:k?String(k):null,F=(0,X.useMemo)(()=>!l||!d?!1:JSON.stringify(l)!==JSON.stringify(d),[l,d]),I=(0,X.useCallback)(e=>{D.current=!0,u(t=>t?{...t,auth:{...t.auth,...e}}:null)},[]),L=(0,X.useCallback)(e=>{D.current=!0,u(t=>t?{...t,updateChannel:e}:null)},[]),ee=(0,X.useCallback)(async()=>{if(!(!l||p)){m(!0),v(null),x(!1);try{await He(l),D.current=!1,f(structuredClone(l)),x(!0),window.setTimeout(()=>x(!1),2500)}catch(e){v(e instanceof Error?e.message:n.saveError)}finally{m(!1)}}},[l,p,n.saveError]),R=(0,X.useCallback)(async()=>{let e=l?.auth.token;e&&(await navigator.clipboard.writeText(e).catch(()=>{}),E(!0),window.setTimeout(()=>E(!1),2e3))},[l?.auth.token]);return s?N?(0,Y.jsx)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-fg-muted`,children:[(0,Y.jsx)(g,{className:`size-4 animate-spin`}),n.loading]})}):l?(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6`,children:[(0,Y.jsxs)(`header`,{className:`flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold tracking-tight text-fg`,children:t.settingsSections.gateway}),(0,Y.jsx)(`p`,{className:`mt-1 text-sm text-fg-muted`,children:n.subtitle}),(0,Y.jsxs)(`a`,{href:h(e,`gateway`),target:`_blank`,rel:`noreferrer`,className:`mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40`,children:[n.docsLink,(0,Y.jsx)(K,{className:`size-3.5`})]})]}),(0,Y.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[y?(0,Y.jsx)(`span`,{className:`text-sm text-fg-muted`,children:n.saved}):null,(0,Y.jsx)(J,{type:`button`,variant:`primary`,disabled:!F||p,onClick:()=>void ee(),children:p?n.saving:n.save})]})]}),i?(0,Y.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-lg border border-red-200 bg-red-50 px-4 py-3 dark:border-red-900/50 dark:bg-red-950/40`,role:`alert`,children:[(0,Y.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,Y.jsx)(b,{className:`mt-0.5 size-4 shrink-0 text-red-600 dark:text-red-400`}),(0,Y.jsx)(`p`,{className:`text-sm text-red-900 dark:text-red-100`,children:n.tokenExpired})]}),(0,Y.jsx)(`div`,{children:(0,Y.jsx)(J,{type:`button`,variant:`secondary`,className:`text-sm`,onClick:()=>a(),children:n.updateToken})})]}):null,F?(0,Y.jsx)(`p`,{className:`text-xs text-amber-800 dark:text-amber-200`,children:n.unsavedHint}):null,_?(0,Y.jsx)(`p`,{className:`text-sm text-red-600 dark:text-red-400`,children:_}):null,l.auth.mode===`none`?(0,Y.jsx)(`p`,{className:`rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-950 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100`,children:n.authModeNone}):null,(0,Y.jsxs)(`section`,{className:`rounded-2xl bg-surface-base px-4 py-5 sm:px-5`,children:[(0,Y.jsxs)(`div`,{className:`mb-5 flex items-center gap-2 text-sm font-semibold text-fg`,children:[(0,Y.jsx)(c,{className:`size-4 text-accent`,strokeWidth:1.75}),t.settingsSections.gateway]}),(0,Y.jsxs)(`div`,{className:`space-y-4`,children:[(l.host||l.port!=null)&&(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`mb-1 text-sm font-medium text-fg`,children:n.listenHost}),(0,Y.jsx)(`div`,{className:`rounded-lg bg-surface-hover/80 px-3 py-2 font-mono text-xs text-fg-muted dark:bg-surface-hover/50`,children:l.host||`—`})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`mb-1 text-sm font-medium text-fg`,children:n.listenPort}),(0,Y.jsx)(`div`,{className:`rounded-lg bg-surface-hover/80 px-3 py-2 font-mono text-xs text-fg-muted dark:bg-surface-hover/50`,children:l.port==null?`—`:String(l.port)})]}),(0,Y.jsx)(`p`,{className:`sm:col-span-2 text-xs text-fg-subtle`,children:n.listenHint})]}),(0,Y.jsx)(Ge,{g:n,value:l.auth.token,show:C,copied:T,onToggleShow:()=>w(e=>!e),onCopy:()=>void R(),onChange:e=>I({token:e})}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,className:`w-full sm:w-auto`,onClick:()=>a(),children:n.changeToken}),(0,Y.jsxs)(`div`,{className:`space-y-2 border-t border-edge pt-4`,children:[(0,Y.jsx)(`label`,{className:`text-sm font-medium text-fg`,htmlFor:`gateway-update-channel`,children:n.updateChannel}),(0,Y.jsxs)(`select`,{id:`gateway-update-channel`,value:l.updateChannel,onChange:e=>L(e.target.value),className:Ue(),children:[(0,Y.jsx)(`option`,{value:`stable`,children:n.channelStable}),(0,Y.jsx)(`option`,{value:`beta`,children:n.channelBeta}),(0,Y.jsx)(`option`,{value:`dev`,children:n.channelDev})]}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-subtle`,children:n.updateChannelHint})]})]})]})]}):(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:_??P??n.loadError}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,onClick:()=>void j(),children:n.retry})]}):(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold text-fg`,children:t.settingsSections.gateway}),(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:n.needToken})]})}function Ge({g:e,value:t,show:n,copied:r,onToggleShow:i,onCopy:o,onChange:s}){return(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:e.accessToken}),(0,Y.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,Y.jsx)(`input`,{className:a(Ue(),`min-w-0 flex-1 font-mono text-xs`),type:n?`text`:`password`,autoComplete:`off`,value:t,onChange:e=>s(e.target.value),placeholder:e.tokenPlaceholder}),t?(0,Y.jsxs)(J,{type:`button`,variant:`secondary`,className:`px-2 py-1 text-xs`,onClick:o,children:[r?(0,Y.jsx)(y,{className:`size-3.5`}):(0,Y.jsx)(Ee,{className:`size-3.5`}),r?e.copied:e.copy]}):null,(0,Y.jsxs)(J,{type:`button`,variant:`secondary`,className:`px-2 py-1 text-xs`,onClick:i,children:[n?(0,Y.jsx)(he,{className:`size-3.5`}):(0,Y.jsx)(ne,{className:`size-3.5`}),n?e.hide:e.show]})]}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-subtle`,children:e.tokenHelp})]})}function Ke(){return T(`/api/channels/status`)}var qe=ke;function Je(){return T(`/api/workspace/heartbeat-md`)}async function Ye(){let e=await f(Je());return typeof e.payload?.content==`string`?e.payload.content:``}function Xe(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ze(e){let t=Xe(e)?e:{},n=Xe(t.gateway)?t.gateway:{},r=Xe(n.heartbeat)?n.heartbeat:{},i=r.activeHours,a=Xe(i)?i:null,o=a&&typeof a.start==`string`&&typeof a.end==`string`&&a.start&&a.end?{start:a.start,end:a.end,timezone:typeof a.timezone==`string`?a.timezone:``}:null;return{enabled:!!(r.enabled??!0),intervalMs:typeof r.intervalMs==`number`&&Number.isFinite(r.intervalMs)?r.intervalMs:18e5,target:typeof r.target==`string`?r.target:``,targetChatId:typeof r.targetChatId==`string`?r.targetChatId:``,prompt:typeof r.prompt==`string`?r.prompt:``,ackMaxChars:typeof r.ackMaxChars==`number`&&Number.isFinite(r.ackMaxChars)?r.ackMaxChars:``,isolatedSession:!!r.isolatedSession,activeHours:o}}function Qe(e){let t={enabled:e.enabled,intervalMs:e.intervalMs};return e.target.trim()?t.target=e.target.trim():t.target=null,e.targetChatId.trim()?t.targetChatId=e.targetChatId.trim():t.targetChatId=null,e.prompt.trim()?t.prompt=e.prompt.trim():t.prompt=null,e.ackMaxChars===``||e.ackMaxChars===void 0?t.ackMaxChars=null:t.ackMaxChars=e.ackMaxChars,e.isolatedSession?t.isolatedSession=!0:t.isolatedSession=null,e.activeHours?.start?.trim()&&e.activeHours?.end?.trim()?t.activeHours={start:e.activeHours.start.trim(),end:e.activeHours.end.trim(),...e.activeHours.timezone.trim()?{timezone:e.activeHours.timezone.trim()}:{}}:t.activeHours=null,t}async function $e(e){await f(T(`/api/config`),{method:`PATCH`,body:JSON.stringify({gateway:{heartbeat:Qe(e)}})}),W()}async function et(e){await f(T(`/api/workspace/heartbeat-md`),{method:`PUT`,body:JSON.stringify({content:e})}),i(Je())}async function tt(e){await f(T(`/api/heartbeat/trigger`),{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e?{reason:e}:{})})}var nt=[3e4,6e4,3e5,6e5,9e5,18e5,36e5,72e5],rt=new Set(nt);function it(){return a(`w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg`,`placeholder:text-fg-subtle`,I,`dark:border-edge`)}function at(){return a(U,le)}function ot(e){if(!e||typeof e!=`object`||Array.isArray(e))return``;let t=e.agents;if(!t||typeof t!=`object`||Array.isArray(t))return``;let n=t.defaults;if(!n||typeof n!=`object`||Array.isArray(n))return``;let r=n.workspace;return typeof r==`string`?r:``}function st(e,t){switch(e){case 3e4:return t.every30s;case 6e4:return t.every1min;case 3e5:return t.every5min;case 6e5:return t.every10min;case 9e5:return t.every15min;case 18e5:return t.every30min;case 36e5:return t.every1h;case 72e5:return t.every2h;default:return String(e)}}function ct(){let e=S(e=>e.language),t=q(e),n=t.heartbeatSettings,i=!!_e(e=>e.token),[s,c]=(0,X.useState)(null),[l,u]=(0,X.useState)(null),[d,f]=(0,X.useState)(``),[p,_]=(0,X.useState)(``),[v,y]=(0,X.useState)(!1),[b,x]=(0,X.useState)(!1),[C,w]=(0,X.useState)(null),[T,E]=(0,X.useState)(!1),[D,O]=(0,X.useState)(!1),[k,A]=(0,X.useState)(!1),[j,M]=(0,X.useState)(!1),[N,P]=(0,X.useState)(null),[F,I]=(0,X.useState)([]),{data:L,error:ee,isLoading:R,mutate:z}=o(i),{data:B,error:te,isLoading:ne,mutate:V}=r(i?Je():null,Ye,{revalidateOnFocus:!1}),{data:H=[]}=r(i?Ke():null,qe,{revalidateOnFocus:!1}),re=(0,X.useMemo)(()=>ot(L?.payload?.config),[L]),ie=(0,X.useMemo)(()=>Ze(L?.payload?.config??{}),[L]),U=(0,X.useMemo)(()=>!s||!l?!1:JSON.stringify(s)!==JSON.stringify(l),[s,l]),ae=(0,X.useMemo)(()=>d!==p,[d,p]);(0,X.useEffect)(()=>{if(!i){c(null),u(null);return}if(L!==void 0&&!U){let e=structuredClone(ie);c(e),u(e),E(!1)}},[i,L,ie,U]),(0,X.useEffect)(()=>{!i||B===void 0||ae||(f(B),_(B),O(!1))},[i,B,ae]);let W=ee instanceof Error?ee.message:ee?String(ee):te instanceof Error?te.message:te?String(te):null,oe=!!(i&&(L===void 0||B===void 0)&&!W&&(R||ne));(0,X.useEffect)(()=>{if(!i||!s){I([]);return}let e=s.target.trim();if(!e){I([]);return}let t=!1;return Ae(e).then(e=>{t||I(e)}),()=>{t=!0}},[i,s?.target]);let G=(0,X.useCallback)(()=>{let e=s?.target?.trim();e&&Ae(e).then(I)},[s?.target]),se=(0,X.useCallback)(async()=>{A(!0),M(!1),P(null);try{await tt(),M(!0),window.setTimeout(()=>M(!1),3e3)}catch(e){P(e instanceof Error?e.message:n.triggerError)}finally{A(!1)}},[n.triggerError]),ce=(0,X.useCallback)(e=>{c(t=>t?{...t,...e}:null)},[]),le=(0,X.useCallback)(async()=>{if(!(!s||v)){y(!0),w(null),E(!1);try{await $e(s),u(structuredClone(s)),E(!0),window.setTimeout(()=>E(!1),2500)}catch(e){w(e instanceof Error?e.message:n.saveConfigError)}finally{y(!1)}}},[s,v,n.saveConfigError]),ue=(0,X.useCallback)(async()=>{if(!b){x(!0),w(null),O(!1);try{await et(d),_(d),O(!0),window.setTimeout(()=>O(!1),2500)}catch(e){w(e instanceof Error?e.message:n.saveDocError)}finally{x(!1)}}},[d,b,n.saveDocError]);return i?oe?(0,Y.jsx)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-fg-muted`,children:[(0,Y.jsx)(g,{className:`size-4 animate-spin`}),n.loading]})}):s?(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6`,children:[(0,Y.jsx)(`header`,{className:`flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between`,children:(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold tracking-tight text-fg`,children:t.settingsSections.heartbeat}),(0,Y.jsx)(`p`,{className:`mt-1 text-sm text-fg-muted`,children:n.subtitle}),(0,Y.jsxs)(`a`,{href:h(e,`heartbeat`),target:`_blank`,rel:`noreferrer`,className:`mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40`,children:[n.docsLink,(0,Y.jsx)(K,{className:`size-3.5`})]})]})}),re?(0,Y.jsxs)(`p`,{className:`text-xs text-fg-subtle`,children:[n.workspaceLabel,`: `,(0,Y.jsx)(`span`,{className:`font-mono text-fg-muted`,children:re})]}):null,C?(0,Y.jsx)(`p`,{className:`text-sm text-red-600 dark:text-red-400`,children:C}):null,(0,Y.jsxs)(Me,{children:[(0,Y.jsxs)(`div`,{className:`mb-2 flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-sm font-semibold text-fg`,children:[(0,Y.jsx)(ye,{className:`size-4 text-accent`,strokeWidth:1.75}),n.configSection]}),(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Y.jsxs)(J,{type:`button`,variant:`secondary`,className:`inline-flex items-center gap-2`,disabled:k,onClick:()=>void se(),children:[k?(0,Y.jsx)(g,{className:`size-4 animate-spin`,"aria-hidden":!0}):(0,Y.jsx)(m,{className:`size-4`,strokeWidth:1.75,"aria-hidden":!0}),k?n.triggering:n.triggerNow]}),j?(0,Y.jsx)(`span`,{className:`text-sm text-fg-muted`,children:n.triggered}):null]})]}),(0,Y.jsx)(`p`,{className:`mb-4 text-xs text-fg-subtle`,children:n.triggerHint}),N?(0,Y.jsx)(`p`,{className:`mb-3 text-sm text-red-600 dark:text-red-400`,children:N}):null,(0,Y.jsx)(lt,{h:n,cron:t.cron,form:s,channels:H,sessionChatIds:F,onRefreshChatIds:G,update:ce,inputClassName:it,selectClassName:at}),(0,Y.jsxs)(`div`,{className:`mt-4 flex flex-wrap items-center gap-2`,children:[T?(0,Y.jsx)(`span`,{className:`text-sm text-fg-muted`,children:n.savedConfig}):null,(0,Y.jsx)(J,{type:`button`,variant:`primary`,disabled:!U||v,onClick:()=>void le(),children:v?n.savingConfig:n.saveConfig}),U?(0,Y.jsx)(`span`,{className:`text-xs text-amber-800 dark:text-amber-200`,children:n.unsavedConfig}):null]})]}),(0,Y.jsxs)(Me,{children:[(0,Y.jsx)(`div`,{className:`mb-2 text-sm font-semibold text-fg`,children:n.docSection}),(0,Y.jsx)(`p`,{className:`mb-3 text-xs text-fg-subtle`,children:n.docHint}),(0,Y.jsx)(`textarea`,{className:a(it(),`min-h-[12rem] resize-y font-mono text-xs leading-relaxed`),value:d,onChange:e=>f(e.target.value),spellCheck:!1,"aria-label":n.docSection}),(0,Y.jsxs)(`div`,{className:`mt-4 flex flex-wrap items-center gap-2`,children:[D?(0,Y.jsx)(`span`,{className:`text-sm text-fg-muted`,children:n.savedDoc}):null,(0,Y.jsx)(J,{type:`button`,variant:`primary`,disabled:!ae||b,onClick:()=>void ue(),children:b?n.savingDoc:n.saveDoc}),ae?(0,Y.jsx)(`span`,{className:`text-xs text-amber-800 dark:text-amber-200`,children:n.unsavedDoc}):null]})]})]}):(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:C??W??n.loadError}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,onClick:()=>{z(),V()},children:n.retry})]}):(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold text-fg`,children:t.settingsSections.heartbeat}),(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:n.needToken})]})}function lt({h:e,cron:t,form:n,channels:r,sessionChatIds:i,onRefreshChatIds:o,update:s,inputClassName:c,selectClassName:l}){let u=(0,X.useMemo)(()=>new Set(r.map(e=>e.name)),[r]),d=n.target.trim(),f=!!(d&&!u.has(d)),p=(0,X.useMemo)(()=>rt.has(n.intervalMs)?String(n.intervalMs):``,[n.intervalMs]),[m,h]=(0,X.useState)(null),g=Math.max(1,Math.round(n.intervalMs/1e3)),_=m===null?String(g):m;return(0,X.useEffect)(()=>{h(null)},[n.intervalMs]),(0,Y.jsxs)(`div`,{className:`space-y-4`,children:[(0,Y.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-sm text-fg`,children:[(0,Y.jsx)(`input`,{type:`checkbox`,className:`ui-checkbox`,checked:n.enabled,onChange:e=>s({enabled:e.target.checked})}),e.enable]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:e.interval}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,Y.jsx)(`span`,{className:`text-xs font-medium text-fg-muted`,children:e.intervalSecondsLabel}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsx)(`input`,{type:`number`,min:1,step:1,className:a(c(),`min-w-0 flex-1`),value:_,onChange:e=>{let t=e.target.value;h(t);let n=parseInt(t,10);Number.isFinite(n)&&n>=1&&s({intervalMs:n*1e3})},onBlur:()=>{if(m===null)return;let e=parseInt(m,10);s(!Number.isFinite(e)||e<1?{intervalMs:1e3}:{intervalMs:e*1e3}),h(null)}}),(0,Y.jsxs)(`select`,{className:a(l(),`max-w-[11rem] shrink-0 text-xs`),value:p,onChange:e=>{let t=e.target.value;t&&(s({intervalMs:parseInt(t,10)}),h(null))},children:[(0,Y.jsx)(`option`,{value:``,children:e.intervalPresets.custom}),nt.map(t=>(0,Y.jsx)(`option`,{value:String(t),children:st(t,e.intervalPresets)},t))]})]})]}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-muted`,children:e.intervalHintPreset}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-subtle`,children:e.intervalHint})]}),(0,Y.jsxs)(`div`,{className:`border-t border-edge-subtle pt-4`,children:[(0,Y.jsx)(`div`,{className:`mb-2 text-sm font-medium text-fg`,children:e.deliveryTitle}),(0,Y.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,Y.jsx)(`span`,{className:`text-xs font-medium text-fg-muted`,children:t.channel}),(0,Y.jsxs)(`select`,{className:l(),value:d,onChange:e=>{s({target:e.target.value.trim(),targetChatId:``})},children:[(0,Y.jsx)(`option`,{value:``,children:e.channelNone}),f?(0,Y.jsxs)(`option`,{value:d,children:[d,` (`,e.customChannelSuffix,`)`]}):null,r.map(e=>(0,Y.jsxs)(`option`,{value:e.name,disabled:!e.enabled,children:[e.name,` `,e.enabled?``:`(disabled)`]},e.name))]})]}),d?(0,Y.jsxs)(`div`,{className:`mt-3 flex flex-col gap-1`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,Y.jsx)(`span`,{className:`text-xs font-medium text-fg-muted`,children:t.recipient}),(0,Y.jsxs)(J,{type:`button`,variant:`ghost`,className:`h-7 gap-1 px-2 text-xs`,title:t.refreshRecipientHint,onClick:o,children:[(0,Y.jsx)(ae,{className:`size-3.5`,strokeWidth:1.75,"aria-hidden":!0}),t.refreshList]})]}),(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsx)(`input`,{type:`text`,className:a(c(),`min-w-0 flex-1`),value:n.targetChatId,onChange:e=>s({targetChatId:e.target.value}),placeholder:t.recipientPlaceholder,autoComplete:`off`}),(0,Y.jsxs)(`select`,{className:a(l(),`max-w-[10rem] shrink-0 text-xs`),value:n.targetChatId,onChange:e=>{let t=e.target.value;t&&s({targetChatId:t})},children:[(0,Y.jsx)(`option`,{value:``,children:t.selectRecipient}),i.length>0?i.map(e=>(0,Y.jsx)(`option`,{value:e.chatId,children:Oe(e,t.lastActiveLabels)},`${e.channel}-${e.chatId}`)):(0,Y.jsx)(`option`,{value:``,disabled:!0,children:t.noRecentChatsOption})]})]}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-muted`,children:i.length>0?t.enterManuallyOrSelect:t.noRecentChats})]}):null,(0,Y.jsx)(`p`,{className:`mt-2 text-xs text-fg-subtle`,children:e.deliveryHint})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`mb-1 text-sm font-medium text-fg`,children:e.prompt}),(0,Y.jsx)(`textarea`,{className:a(c(),`min-h-[4.5rem] resize-y font-mono text-xs`),value:n.prompt,onChange:e=>s({prompt:e.target.value}),placeholder:e.promptPlaceholder}),(0,Y.jsx)(`p`,{className:`mt-1 text-xs text-fg-subtle`,children:e.promptHint})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`mb-1 text-sm font-medium text-fg`,children:e.ackMaxChars}),(0,Y.jsx)(`input`,{type:`number`,min:1,className:c(),value:n.ackMaxChars===``?``:n.ackMaxChars,onChange:e=>{let t=e.target.value;if(t===``)s({ackMaxChars:``});else{let e=parseInt(t,10);s({ackMaxChars:Number.isFinite(e)?e:``})}},placeholder:e.ackDefaultPlaceholder}),(0,Y.jsx)(`p`,{className:`mt-1 text-xs text-fg-subtle`,children:e.ackMaxCharsHint})]}),(0,Y.jsxs)(`label`,{className:`flex cursor-pointer items-start gap-2 text-sm text-fg`,children:[(0,Y.jsx)(`input`,{type:`checkbox`,className:`ui-checkbox mt-0.5`,checked:n.isolatedSession,onChange:e=>s({isolatedSession:e.target.checked})}),(0,Y.jsxs)(`span`,{children:[e.isolatedSession,(0,Y.jsx)(`span`,{className:`mt-1 block text-xs text-fg-subtle`,children:e.isolatedSessionHint})]})]}),(0,Y.jsxs)(`div`,{className:`border-t border-edge-subtle pt-4`,children:[(0,Y.jsx)(`div`,{className:`mb-2 text-sm font-medium text-fg`,children:e.activeHoursTitle}),n.activeHours?(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`mb-1 text-xs text-fg`,children:e.activeStart}),(0,Y.jsx)(`input`,{className:c(),value:n.activeHours.start,onChange:e=>s({activeHours:{...n.activeHours,start:e.target.value}}),placeholder:`09:00`})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`mb-1 text-xs text-fg`,children:e.activeEnd}),(0,Y.jsx)(`input`,{className:c(),value:n.activeHours.end,onChange:e=>s({activeHours:{...n.activeHours,end:e.target.value}}),placeholder:`22:00`})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`mb-1 text-xs text-fg`,children:e.activeTimezone}),(0,Y.jsx)(`input`,{className:c(),value:n.activeHours.timezone,onChange:e=>s({activeHours:{...n.activeHours,timezone:e.target.value}}),placeholder:`Asia/Shanghai`})]})]}):(0,Y.jsx)(J,{type:`button`,variant:`secondary`,className:`text-sm`,onClick:()=>s({activeHours:{start:`09:00`,end:`22:00`,timezone:``}}),children:e.addActiveHours}),n.activeHours?(0,Y.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-2`,children:(0,Y.jsx)(J,{type:`button`,variant:`secondary`,className:`text-xs`,onClick:()=>s({activeHours:null}),children:e.clearActiveHours})}):null,(0,Y.jsx)(`p`,{className:`mt-2 text-xs text-fg-subtle`,children:e.activeHoursHint})]})]})}var ut=[{value:`openai-completions`,label:`OpenAI Completions`},{value:`openai-responses`,label:`OpenAI Responses`},{value:`anthropic-messages`,label:`Anthropic Messages`},{value:`google-generative-ai`,label:`Google Generative AI`},{value:`azure-openai-responses`,label:`Azure OpenAI`},{value:`bedrock-converse-stream`,label:`AWS Bedrock`},{value:`openai-codex-responses`,label:`OpenAI Codex`},{value:`google-gemini-cli`,label:`Google Gemini CLI`},{value:`google-vertex`,label:`Google Vertex AI`}];function dt(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.error==`string`)return t.error;if(t.error&&typeof t.error==`object`&&`message`in t.error){let e=t.error.message;return typeof e==`string`?e:void 0}}function ft(e){if(!e||typeof e!=`object`)return{providers:{}};let t=e,n=t.providers;return n&&typeof n==`object`&&!Array.isArray(n)?e:{...t,providers:{}}}async function pt(){let e=await A(T(`/api/models-json`)),t=await e.json().catch(()=>({}));if(!e.ok||!t.ok||!t.payload)throw Error(dt(t)||`HTTP ${e.status}`);return{...t.payload,config:ft(t.payload.config)}}async function mt(e){let t=await A(T(`/api/models-json/validate`),{method:`POST`,body:JSON.stringify({config:e})}),n=await t.json().catch(()=>({}));if(!t.ok||!n.ok||!n.payload)throw Error(dt(n)||`HTTP ${t.status}`);return n.payload}async function ht(e){let t=await A(T(`/api/models-json`),{method:`PATCH`,body:JSON.stringify({config:e})}),n=await t.json().catch(()=>({}));if(!t.ok||!n.ok||!n.payload)throw Error(dt(n)||`HTTP ${t.status}`);return n.payload}async function gt(){let e=await A(T(`/api/models-json/reload`),{method:`POST`}),t=await e.json().catch(()=>({}));if(!e.ok||!t.ok||!t.payload)throw Error(dt(t)||`HTTP ${e.status}`);return t.payload}async function _t(e){let t=await A(T(`/api/models-json/test-api-key`),{method:`POST`,body:JSON.stringify({value:e})}),n=await t.json().catch(()=>({}));if(!t.ok||!n.ok||!n.payload)throw Error(dt(n)||`HTTP ${t.status}`);return n.payload}function vt(e,t,n){return{id:e,name:t||e,input:[`text`],contextWindow:128e3,maxTokens:16384,cost:{input:0,output:0,cacheRead:0,cacheWrite:0},...n}}function yt(e){return e.startsWith(`!`)}function bt(e){return/^[A-Z][A-Z0-9_]*$/.test(e)}function xt(e){return yt(e)?`shell`:bt(e)?`env`:`literal`}function St(e){return e?e.length<=8?`••••`:`${e.slice(0,4)}••••${e.slice(-4)}`:``}var Ct={ollama:{baseUrl:`http://localhost:11434/v1`,api:`openai-completions`,apiKey:`ollama`},lmstudio:{baseUrl:`http://localhost:1234/v1`,api:`openai-completions`,apiKey:`lmstudio`},openrouter:{baseUrl:`https://openrouter.ai/api/v1`,api:`openai-completions`,apiKey:``},zhipuCn:{baseUrl:`https://open.bigmodel.cn/api/coding/paas/v4`,api:`openai-completions`,apiKey:`ZHIPU_API_KEY`},zaiGeneral:{baseUrl:`https://api.z.ai/api/paas/v4`,api:`openai-completions`,apiKey:`ZAI_API_KEY`}};function wt(e){return e===`openrouter`?`openrouter`:e===`zhipuCn`?`zhipu-cn`:e===`zaiGeneral`?`zai`:e}var Tt=[{value:`text`,labelKey:`inputTextOnly`},{value:`text,image`,labelKey:`inputTextVision`}];function Z(){return a(`w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg`,`placeholder:text-fg-subtle`,I,`dark:border-edge`)}function Et(){return a(U,le)}function Dt(e){return(e.input||[`text`]).includes(`image`)?`text,image`:`text`}function Ot(e){return e===`text,image`?[`text`,`image`]:[`text`]}function kt(e,t,n){return{...e,providers:{...e.providers,[t]:{...e.providers[t],...n}}}}function At(e,t){let n={...e.providers};return delete n[t],{...e,providers:n}}function jt(e,t,n){return{...e,providers:{...e.providers,[t]:n}}}function Mt({open:e,onOpenChange:t,presetKey:n,onConfirm:r,m:i}){let[o,s]=(0,X.useState)(``),[c,l]=(0,X.useState)(`custom`),[u,d]=(0,X.useState)(``),[f,p]=(0,X.useState)(`openai-completions`),[m,h]=(0,X.useState)(``),[g,_]=(0,X.useState)(null);(0,X.useEffect)(()=>{if(!e)return;_(null);let t=n||null;if(t&&Ct[t]){let e=Ct[t];l(t),d(e.baseUrl||``),p(e.api||`openai-completions`),h(e.apiKey??``),s(wt(t))}else l(`custom`),s(``),d(``),p(`openai-completions`),h(``)},[e,n]);let v=e=>{if(l(e),e===`custom`)return;let t=Ct[e];t&&(d(t.baseUrl||``),p(t.api||`openai-completions`),h(t.apiKey??``),s(wt(e)))};return(0,Y.jsx)(we,{open:e,onOpenChange:t,children:(0,Y.jsxs)(G,{children:[(0,Y.jsx)(R,{className:`xopc-dialog-overlay fixed inset-0 z-50 bg-scrim`}),(0,Y.jsxs)(fe,{className:a(`xopc-dialog-content fixed left-1/2 top-1/2 z-50 max-h-[min(90vh,640px)] w-[min(100%-2rem,32rem)] -translate-x-1/2 -translate-y-1/2`,`overflow-y-auto rounded-xl border border-edge bg-surface-panel p-4 shadow-popover dark:border-edge`),onOpenAutoFocus:e=>e.preventDefault(),children:[(0,Y.jsxs)(`div`,{className:`mb-3 flex items-start justify-between gap-2`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(B,{className:`text-base font-semibold text-fg`,children:i.addProviderTitle}),(0,Y.jsx)(`p`,{className:`mt-0.5 text-xs text-fg-muted`,children:i.addProviderSubtitle})]}),(0,Y.jsx)(L,{asChild:!0,children:(0,Y.jsx)(`button`,{type:`button`,className:`rounded-lg p-1.5 text-fg-muted hover:bg-surface-base hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40`,"aria-label":i.close,children:(0,Y.jsx)(z,{className:`size-4`})})})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs font-medium text-fg-muted`,children:i.presetLabel}),(0,Y.jsxs)(`select`,{className:Et(),value:c,onChange:e=>v(e.target.value),children:[(0,Y.jsx)(`option`,{value:`custom`,children:i.presetCustom}),(0,Y.jsx)(`option`,{value:`ollama`,children:i.presetOllama}),(0,Y.jsx)(`option`,{value:`lmstudio`,children:i.presetLmStudio}),(0,Y.jsx)(`option`,{value:`openrouter`,children:i.presetOpenRouter}),(0,Y.jsx)(`option`,{value:`zhipuCn`,children:i.presetZhipuCn}),(0,Y.jsx)(`option`,{value:`zaiGeneral`,children:i.presetZaiGeneral})]})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsxs)(`label`,{className:`mb-1 block text-xs font-medium text-fg`,children:[i.providerIdLabel,(0,Y.jsx)(`span`,{className:`text-red-600 dark:text-red-400`,children:` *`})]}),(0,Y.jsx)(`input`,{className:Z(),value:o,onChange:e=>s(e.target.value),placeholder:i.providerIdPlaceholder})]}),(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs font-medium text-fg-muted`,children:i.baseUrl}),(0,Y.jsx)(`input`,{className:Z(),value:u,onChange:e=>d(e.target.value),placeholder:`https://…`})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs font-medium text-fg-muted`,children:i.apiType}),(0,Y.jsx)(`select`,{className:Et(),value:f,onChange:e=>p(e.target.value),children:ut.map(e=>(0,Y.jsx)(`option`,{value:e.value,children:e.label},e.value))})]})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs font-medium text-fg-muted`,children:i.apiKey}),(0,Y.jsx)(`input`,{className:Z(),value:m,onChange:e=>h(e.target.value),placeholder:i.apiKeyPlaceholder})]}),g?(0,Y.jsxs)(`p`,{className:`flex items-center gap-1 text-xs text-red-600 dark:text-red-400`,children:[(0,Y.jsx)(b,{className:`size-3.5 shrink-0`}),g]}):null]}),(0,Y.jsxs)(`div`,{className:`mt-4 flex justify-end gap-2 border-t border-edge-subtle pt-3 dark:border-edge`,children:[(0,Y.jsx)(L,{asChild:!0,children:(0,Y.jsx)(J,{type:`button`,variant:`secondary`,children:i.cancel})}),(0,Y.jsx)(J,{type:`button`,className:`bg-accent text-white hover:bg-accent/90`,onClick:()=>{let e=o.trim();if(!e){_(i.providerIdRequired);return}_(null),r(e,{baseUrl:u.trim()||void 0,api:f,apiKey:m.trim()||void 0,models:[]}),t(!1)},children:i.addProviderConfirm})]})]})]})})}function Nt({open:e,onOpenChange:t,providerId:n,model:r,isNew:i,onSave:o,m:s}){let[c,l]=(0,X.useState)(()=>vt(``)),[u,d]=(0,X.useState)(()=>new Map);(0,X.useEffect)(()=>{e&&(d(new Map),l(r?{...r}:vt(``)))},[e,r]);let f=(e,t)=>{l(n=>({...n,[e]:t})),d(t=>{let n=new Map(t);return n.delete(e),n})},p=()=>{let e=new Map;return(c.id||``).trim()||e.set(`id`,s.modelIdRequired),c.contextWindow!==void 0&&c.contextWindow<=0&&e.set(`contextWindow`,s.mustBePositive),c.maxTokens!==void 0&&c.maxTokens<=0&&e.set(`maxTokens`,s.mustBePositive),d(e),e.size===0},m=()=>{if(!p())return;let e=(c.id||``).trim();o({...c,id:e,name:c.name?.trim()||e,reasoning:c.reasoning||!1,input:c.input||[`text`],contextWindow:c.contextWindow??128e3,maxTokens:c.maxTokens??16384,cost:{input:c.cost?.input??0,output:c.cost?.output??0,cacheRead:c.cost?.cacheRead??0,cacheWrite:c.cost?.cacheWrite??0}}),t(!1)},h=Dt(c);return(0,Y.jsx)(we,{open:e,onOpenChange:t,children:(0,Y.jsxs)(G,{children:[(0,Y.jsx)(R,{className:`xopc-dialog-overlay fixed inset-0 z-50 bg-scrim`}),(0,Y.jsxs)(fe,{className:a(`xopc-dialog-content fixed left-1/2 top-1/2 z-50 max-h-[min(90vh,720px)] w-[min(100%-2rem,28rem)] -translate-x-1/2 -translate-y-1/2`,`overflow-y-auto rounded-xl border border-edge bg-surface-panel p-4 shadow-popover dark:border-edge`),onOpenAutoFocus:e=>e.preventDefault(),children:[(0,Y.jsxs)(`div`,{className:`mb-3 flex items-start justify-between gap-2`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(B,{className:`text-base font-semibold text-fg`,children:i?s.addModelTitle:s.editModelTitle}),n?(0,Y.jsxs)(`p`,{className:`mt-0.5 text-xs text-fg-muted`,children:[s.modelProviderLabel,`: `,n]}):null]}),(0,Y.jsx)(L,{asChild:!0,children:(0,Y.jsx)(`button`,{type:`button`,className:`rounded-lg p-1.5 text-fg-muted hover:bg-surface-base hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40`,"aria-label":s.close,children:(0,Y.jsx)(z,{className:`size-4`})})})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsxs)(`label`,{className:`mb-1 block text-xs font-medium text-fg`,children:[s.modelId,(0,Y.jsx)(`span`,{className:`text-red-600 dark:text-red-400`,children:` *`})]}),(0,Y.jsx)(`input`,{className:a(Z(),u.has(`id`)&&`border-red-500`),value:c.id||``,onChange:e=>f(`id`,e.target.value),placeholder:`e.g. llama3.1:8b`,disabled:!i}),u.has(`id`)?(0,Y.jsx)(`p`,{className:`mt-1 text-xs text-red-600 dark:text-red-400`,children:u.get(`id`)}):null]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs font-medium text-fg-muted`,children:s.displayName}),(0,Y.jsx)(`input`,{className:Z(),value:c.name||``,onChange:e=>f(`name`,e.target.value)})]}),(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs font-medium text-fg-muted`,children:s.inputTypes}),(0,Y.jsx)(`select`,{className:Et(),value:h,onChange:e=>f(`input`,Ot(e.target.value)),children:Tt.map(e=>(0,Y.jsx)(`option`,{value:e.value,children:s[e.labelKey]},e.value))})]}),(0,Y.jsxs)(`label`,{className:`mt-6 flex cursor-pointer items-center gap-2 text-sm text-fg`,children:[(0,Y.jsx)(`input`,{type:`checkbox`,className:`ui-checkbox`,checked:c.reasoning||!1,onChange:e=>f(`reasoning`,e.target.checked)}),s.reasoning]})]}),(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs font-medium text-fg-muted`,children:s.contextWindow}),(0,Y.jsx)(`input`,{type:`number`,min:1,className:a(Z(),u.has(`contextWindow`)&&`border-red-500`),value:c.contextWindow??128e3,onChange:e=>f(`contextWindow`,parseInt(e.target.value,10)||0)}),u.has(`contextWindow`)?(0,Y.jsx)(`p`,{className:`mt-1 text-xs text-red-600 dark:text-red-400`,children:u.get(`contextWindow`)}):null]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs font-medium text-fg-muted`,children:s.maxOutputTokens}),(0,Y.jsx)(`input`,{type:`number`,min:1,className:a(Z(),u.has(`maxTokens`)&&`border-red-500`),value:c.maxTokens??16384,onChange:e=>f(`maxTokens`,parseInt(e.target.value,10)||0)}),u.has(`maxTokens`)?(0,Y.jsx)(`p`,{className:`mt-1 text-xs text-red-600 dark:text-red-400`,children:u.get(`maxTokens`)}):null]})]}),(0,Y.jsxs)(`div`,{className:`border-t border-edge-subtle pt-2 dark:border-edge`,children:[(0,Y.jsx)(`p`,{className:`mb-2 text-xs font-semibold text-fg`,children:s.costSection}),(0,Y.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs text-fg-muted`,children:s.costInput}),(0,Y.jsx)(`input`,{type:`number`,step:`any`,min:0,className:Z(),value:c.cost?.input??0,onChange:e=>f(`cost`,{...c.cost,input:parseFloat(e.target.value)||0,output:c.cost?.output??0,cacheRead:c.cost?.cacheRead??0,cacheWrite:c.cost?.cacheWrite??0})})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs text-fg-muted`,children:s.costOutput}),(0,Y.jsx)(`input`,{type:`number`,step:`any`,min:0,className:Z(),value:c.cost?.output??0,onChange:e=>f(`cost`,{...c.cost,input:c.cost?.input??0,output:parseFloat(e.target.value)||0,cacheRead:c.cost?.cacheRead??0,cacheWrite:c.cost?.cacheWrite??0})})]})]})]})]}),(0,Y.jsxs)(`div`,{className:`mt-4 flex justify-end gap-2 border-t border-edge-subtle pt-3 dark:border-edge`,children:[(0,Y.jsx)(L,{asChild:!0,children:(0,Y.jsx)(J,{type:`button`,variant:`secondary`,children:s.cancel})}),(0,Y.jsx)(J,{type:`button`,className:`bg-accent text-white hover:bg-accent/90`,onClick:m,children:i?s.addModelConfirm:s.saveModelConfirm})]})]})]})})}function Pt(){let e=S(e=>e.language),t=q(e),n=t.modelsSettings,r=!!_e(e=>e.token),[i,o]=(0,X.useState)({providers:{}}),[c,l]=(0,X.useState)({providers:{}}),[d,f]=(0,X.useState)(``),[p,m]=(0,X.useState)(),[_,y]=(0,X.useState)(!0),[C,w]=(0,X.useState)(!1),[T,D]=(0,X.useState)(!1),[O,k]=(0,X.useState)(!1),[A,j]=(0,X.useState)(null),[M,P]=(0,X.useState)(!1),[F,I]=(0,X.useState)(null),[L,ee]=(0,X.useState)(()=>new Set),[R,z]=(0,X.useState)(!1),[B,te]=(0,X.useState)(``),[V,H]=(0,X.useState)(null),[re,ie]=(0,X.useState)(()=>new Set),[U,W]=(0,X.useState)(()=>new Map),[oe,G]=(0,X.useState)(!1),[se,ce]=(0,X.useState)(null),[le,ue]=(0,X.useState)(!1),[de,fe]=(0,X.useState)(null),pe=(0,X.useCallback)(async e=>{let t=!e?.skipFullPageLoading;t&&y(!0),j(null);try{let e=await pt(),t=ft(e.config);o(t),l(structuredClone(t)),f(e.path),m(e.loadError),I(null),P(!1)}catch(e){j(e instanceof Error?e.message:n.loadError),o({providers:{}}),l({providers:{}})}finally{t&&y(!1)}},[n.loadError]);(0,X.useEffect)(()=>{if(!r){y(!1);return}pe()},[r,pe]);let me=(0,X.useMemo)(()=>JSON.stringify(i)!==JSON.stringify(c),[i,c]),ge=(0,X.useMemo)(()=>{let e=Object.keys(i.providers),t=0;for(let e of Object.values(i.providers))t+=e.models?.length??0;return{providers:e.length,models:t}},[i.providers]),ve=e=>{ee(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},ye=e=>{ie(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},be=(0,X.useCallback)(()=>{te(JSON.stringify(i,null,2)),H(null)},[i]);(0,X.useEffect)(()=>{R&&be()},[R,be]);let xe=()=>{try{o(ft(JSON.parse(B))),H(null)}catch{H(n.jsonParseError)}},Se=async()=>{D(!0),j(null);try{I(await mt(i))}catch(e){j(e instanceof Error?e.message:n.validateError)}finally{D(!1)}},we=async()=>{if(!C){w(!0),j(null),P(!1);try{await ht(i),l(structuredClone(i)),P(!0),I(null)}catch(e){j(e instanceof Error?e.message:n.saveError)}finally{w(!1)}}},Ee=async()=>{k(!0),j(null);try{await gt(),await pe({skipFullPageLoading:!0})}catch(e){j(e instanceof Error?e.message:n.reloadError)}finally{k(!1)}},Oe=async(e,t)=>{try{let n=await _t(t);W(t=>{let r=new Map(t);return r.set(e,n),r})}catch(t){W(n=>{let r=new Map(n);return r.set(e,{type:`error`,error:t instanceof Error?t.message:`Error`}),r})}},ke=(e=null)=>{ce(e),G(!0)},Ae=(e,t)=>{o(n=>jt(n,e,t)),ee(t=>new Set(t).add(e))},je=e=>{window.confirm(n.removeProviderConfirm.replace(`{{id}}`,e))&&(o(t=>At(t,e)),W(t=>{let n=new Map(t);return n.delete(e),n}))},Me=(e,t,n)=>{fe({providerId:e,model:t,isNew:n}),ue(!0)};return r?(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-4 px-4 py-8`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold text-fg`,children:t.settingsSections.models}),(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:n.subtitle}),(0,Y.jsxs)(`a`,{href:h(e,`models`),target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40`,children:[n.docsLink,(0,Y.jsx)(K,{className:`size-3.5`})]})]}),p?(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100`,role:`status`,children:[(0,Y.jsx)(b,{className:`mt-0.5 size-4 shrink-0`}),(0,Y.jsxs)(`span`,{children:[n.loadFileWarning,`: `,p]})]}):null,d?(0,Y.jsxs)(`p`,{className:`text-xs text-fg-subtle`,children:[n.filePath,`: `,(0,Y.jsx)(`code`,{className:`rounded bg-surface-base px-1 py-0.5 font-mono text-fg-muted`,children:d})]}):null,(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Y.jsxs)(J,{type:`button`,className:`bg-accent text-white hover:bg-accent/90`,onClick:()=>ke(null),disabled:_,children:[(0,Y.jsx)(x,{className:`mr-1 size-4`}),n.addProvider]}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,className:`inline-flex min-h-9 min-w-[7.5rem] justify-center`,onClick:Se,disabled:_||T,children:T?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(g,{className:`mr-1 size-4 animate-spin`}),n.validating]}):n.validate}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,className:`inline-flex min-h-9 min-w-[7.5rem] justify-center`,onClick:we,disabled:_||C||!me,children:C?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(g,{className:`mr-1 size-4 animate-spin`}),n.saving]}):n.save}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,className:`inline-flex min-h-9 min-w-[8.5rem] justify-center`,onClick:Ee,disabled:_||O,children:O?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(g,{className:`mr-1 size-4 animate-spin`}),n.reloading]}):(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(ae,{className:`mr-1 size-4`}),n.reload]})}),(0,Y.jsx)(J,{type:`button`,variant:`ghost`,className:`text-fg-muted`,onClick:()=>{z(e=>!e),H(null)},children:R?n.hideJson:n.showJson}),(0,Y.jsxs)(`div`,{className:`ml-auto flex items-center gap-2 rounded-lg border border-edge-subtle bg-surface-panel px-3 py-1.5 text-sm dark:border-edge`,children:[(0,Y.jsx)(`span`,{className:`text-fg-muted`,children:n.statsProviders.replace(`{{count}}`,String(ge.providers))}),(0,Y.jsx)(`span`,{className:`text-fg-subtle`,children:`|`}),(0,Y.jsx)(`span`,{className:`text-fg-muted`,children:n.statsModels.replace(`{{count}}`,String(ge.models))})]})]}),me?(0,Y.jsx)(`p`,{className:`text-xs text-amber-800 dark:text-amber-200`,children:n.unsavedHint}):null,M?(0,Y.jsx)(`p`,{className:`text-xs text-emerald-700 dark:text-emerald-400`,role:`status`,children:n.saved}):null,A?(0,Y.jsxs)(`p`,{className:`flex items-center gap-1 text-sm text-red-600 dark:text-red-400`,role:`alert`,children:[(0,Y.jsx)(b,{className:`size-4 shrink-0`}),A]}):null,F&&F.errors.length>0?(0,Y.jsxs)(`div`,{className:`rounded-lg border border-amber-200 bg-amber-50/80 px-3 py-2 dark:border-amber-800 dark:bg-amber-950/30`,role:`status`,children:[(0,Y.jsx)(`p`,{className:`mb-1 text-sm font-medium text-amber-950 dark:text-amber-100`,children:F.valid?n.validationWarnings:n.validationErrors}),(0,Y.jsx)(`ul`,{className:`list-inside list-disc space-y-0.5 text-xs text-amber-900 dark:text-amber-200`,children:F.errors.map((e,t)=>(0,Y.jsxs)(`li`,{children:[e.path,`: `,e.message,` (`,e.severity,`)`]},`${e.path}-${t}`))})]}):null,_?(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-fg-muted`,children:[(0,Y.jsx)(g,{className:`size-4 animate-spin`}),n.loading]}):R?(0,Y.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,Y.jsx)(`textarea`,{className:a(Z(),`min-h-[320px] resize-y font-mono text-xs leading-relaxed`),value:B,onChange:e=>te(e.target.value),spellCheck:!1}),V?(0,Y.jsx)(`p`,{className:`text-xs text-red-600 dark:text-red-400`,children:V}):null,(0,Y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Y.jsx)(J,{type:`button`,variant:`secondary`,onClick:be,children:n.jsonReset}),(0,Y.jsx)(J,{type:`button`,className:`bg-accent text-white hover:bg-accent/90`,onClick:xe,children:n.jsonApply})]})]}):Object.keys(i.providers).length===0?(0,Y.jsxs)(`div`,{className:`flex flex-col items-center rounded-xl border-2 border-dashed border-edge-subtle bg-surface-panel px-6 py-12 text-center dark:border-edge`,children:[(0,Y.jsx)(`div`,{className:`mb-4 flex size-14 items-center justify-center rounded-full border border-edge bg-surface-base dark:border-edge`,children:(0,Y.jsx)(Te,{className:`size-7 text-accent`,strokeWidth:1.5})}),(0,Y.jsx)(`h2`,{className:`mb-1 text-base font-semibold text-fg`,children:n.emptyTitle}),(0,Y.jsx)(`p`,{className:`mb-6 max-w-md text-sm text-fg-muted`,children:n.emptyDesc}),(0,Y.jsxs)(J,{type:`button`,className:`mb-6 bg-accent text-white hover:bg-accent/90`,onClick:()=>ke(null),children:[(0,Y.jsx)(x,{className:`mr-1 size-4`}),n.emptyCta]}),(0,Y.jsxs)(`div`,{className:`flex flex-wrap justify-center gap-2`,children:[(0,Y.jsxs)(`button`,{type:`button`,className:a(`inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge`,E.transition,E.focusRingBase),onClick:()=>ke(`ollama`),children:[(0,Y.jsx)(Ce,{className:`size-3.5`,"aria-hidden":!0}),n.presetOllama]}),(0,Y.jsxs)(`button`,{type:`button`,className:a(`inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge`,E.transition,E.focusRingBase),onClick:()=>ke(`openrouter`),children:[(0,Y.jsx)(u,{className:`size-3.5`,"aria-hidden":!0}),n.presetOpenRouter]}),(0,Y.jsxs)(`button`,{type:`button`,className:a(`inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge`,E.transition,E.focusRingBase),onClick:()=>ke(`lmstudio`),children:[(0,Y.jsx)(Te,{className:`size-3.5`,"aria-hidden":!0}),n.presetLmStudio]}),(0,Y.jsxs)(`button`,{type:`button`,className:a(`inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge`,E.transition,E.focusRingBase),onClick:()=>ke(`zhipuCn`),children:[(0,Y.jsx)(Ce,{className:`size-3.5`,"aria-hidden":!0}),n.presetZhipuCn]}),(0,Y.jsxs)(`button`,{type:`button`,className:a(`inline-flex items-center gap-1.5 rounded-full border border-edge bg-surface-base px-3 py-1.5 text-xs text-fg hover:border-accent hover:text-accent dark:border-edge`,E.transition,E.focusRingBase),onClick:()=>ke(`zaiGeneral`),children:[(0,Y.jsx)(u,{className:`size-3.5`,"aria-hidden":!0}),n.presetZaiGeneral]})]})]}):(0,Y.jsx)(`div`,{className:`flex flex-col gap-3`,children:Object.entries(i.providers).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>{let r=L.has(e),i=t.models?.length??0,c=t.apiKey?xt(t.apiKey):null,l=U.get(e),u=re.has(e);return(0,Y.jsxs)(`section`,{className:`overflow-hidden rounded-2xl bg-surface-base`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2 border-b border-edge-subtle bg-surface-hover/35 px-3 py-2 dark:border-edge-subtle`,children:[(0,Y.jsxs)(`button`,{type:`button`,className:`flex min-w-0 flex-1 items-center gap-2 text-left text-sm font-semibold text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40`,onClick:()=>ve(e),children:[r?(0,Y.jsx)(v,{className:`size-4 shrink-0 text-fg-muted`}):(0,Y.jsx)(s,{className:`size-4 shrink-0 text-fg-muted`}),(0,Y.jsx)(`span`,{className:`truncate`,children:e}),i>0?(0,Y.jsx)(`span`,{className:`shrink-0 rounded-full bg-accent px-2 py-0.5 text-[10px] font-medium text-white`,children:i}):null,c?(0,Y.jsx)(`span`,{className:a(`shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium`,c===`shell`&&`bg-blue-100 text-blue-800 dark:bg-blue-950 dark:text-blue-200`,c===`env`&&`bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200`,c===`literal`&&`bg-surface-hover text-fg-muted dark:bg-surface-active`),children:c===`shell`?n.badgeShell:c===`env`?n.badgeEnv:n.badgeLiteral}):null]}),(0,Y.jsx)(`button`,{type:`button`,className:`rounded-lg p-1.5 text-fg-muted hover:bg-surface-base hover:text-red-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40 dark:hover:text-red-400`,onClick:()=>je(e),"aria-label":n.removeProvider,children:(0,Y.jsx)(N,{className:`size-4`})})]}),r?(0,Y.jsxs)(`div`,{className:`space-y-4 px-3 py-3`,children:[(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs font-medium text-fg-muted`,children:n.baseUrl}),(0,Y.jsx)(`input`,{className:Z(),value:t.baseUrl||``,onChange:t=>o(n=>kt(n,e,{baseUrl:t.target.value}))})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs font-medium text-fg-muted`,children:n.apiType}),(0,Y.jsx)(`select`,{className:Et(),value:t.api||`openai-completions`,onChange:t=>o(n=>kt(n,e,{api:t.target.value})),children:ut.map(e=>(0,Y.jsx)(`option`,{value:e.value,children:e.label},e.value))})]})]}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`label`,{className:`mb-1 block text-xs font-medium text-fg-muted`,children:n.apiKey}),(0,Y.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,Y.jsx)(`input`,{className:a(Z(),`min-w-0 flex-1`),type:u?`text`:`password`,autoComplete:`off`,value:t.apiKey||``,onChange:t=>{let n=t.target.value;o(t=>kt(t,e,{apiKey:n})),W(t=>{let n=new Map(t);return n.delete(e),n})},placeholder:n.apiKeyPlaceholder}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,className:`px-2 py-1 text-xs`,onClick:()=>ye(e),children:u?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(he,{className:`mr-1 size-3.5`}),n.hide]}):(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(ne,{className:`mr-1 size-3.5`}),n.show]})}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,className:`px-2 py-1 text-xs`,onClick:()=>Oe(e,t.apiKey||``),children:n.testKey})]}),l?(0,Y.jsx)(`p`,{className:a(`mt-1 text-xs`,l.error?`text-red-600 dark:text-red-400`:`text-emerald-700 dark:text-emerald-400`),children:l.error?`${n.testError}: ${l.error}`:`${n.testOk} (${l.type}): ${St(l.resolved||``)}`}):null,(0,Y.jsx)(`p`,{className:`mt-1 text-xs text-fg-subtle`,children:n.apiKeyHint})]}),(0,Y.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-sm text-fg`,children:[(0,Y.jsx)(`input`,{type:`checkbox`,className:`ui-checkbox`,checked:t.authHeader||!1,onChange:t=>o(n=>kt(n,e,{authHeader:t.target.checked}))}),n.authHeader]}),(0,Y.jsxs)(`div`,{className:`border-t border-edge-subtle pt-3 dark:border-edge`,children:[(0,Y.jsxs)(`div`,{className:`mb-2 flex items-center justify-between gap-2`,children:[(0,Y.jsx)(`span`,{className:`text-sm font-semibold text-fg`,children:n.modelsSection}),(0,Y.jsxs)(J,{type:`button`,variant:`primary`,className:`px-2 py-1 text-xs`,onClick:()=>Me(e,null,!0),children:[(0,Y.jsx)(x,{className:`mr-1 size-3.5`}),n.addModel]})]}),(t.models||[]).length===0?(0,Y.jsx)(`p`,{className:`text-xs text-fg-muted`,children:n.modelsEmpty}):(0,Y.jsx)(`ul`,{className:`space-y-2`,children:(t.models||[]).map(t=>(0,Y.jsxs)(`li`,{className:`flex items-center justify-between gap-2 rounded-lg border border-edge-subtle bg-surface-base px-3 py-2 dark:border-edge`,children:[(0,Y.jsxs)(`div`,{className:`min-w-0`,children:[(0,Y.jsx)(`div`,{className:`truncate text-sm font-medium text-fg`,children:t.id}),t.name&&t.name!==t.id?(0,Y.jsx)(`div`,{className:`truncate text-xs text-fg-muted`,children:t.name}):null]}),(0,Y.jsxs)(`div`,{className:`flex shrink-0 gap-1`,children:[(0,Y.jsx)(`button`,{type:`button`,className:`rounded-lg p-1.5 text-fg-muted hover:bg-surface-panel hover:text-fg`,onClick:()=>Me(e,t,!1),"aria-label":n.editModel,children:(0,Y.jsx)(De,{className:`size-4`})}),(0,Y.jsx)(`button`,{type:`button`,className:`rounded-lg p-1.5 text-fg-muted hover:bg-surface-panel hover:text-red-600 dark:hover:text-red-400`,onClick:()=>{window.confirm(n.removeModelConfirm.replace(`{{id}}`,t.id))&&o(n=>{let r=n.providers[e];return r?kt(n,e,{models:(r.models||[]).filter(e=>e.id!==t.id)}):n})},"aria-label":n.removeModel,children:(0,Y.jsx)(N,{className:`size-4`})})]})]},t.id))})]})]}):null]},e)})}),(0,Y.jsx)(Mt,{open:oe,onOpenChange:G,presetKey:se,onConfirm:Ae,m:n}),(0,Y.jsx)(Nt,{open:le,onOpenChange:e=>{ue(e),e||fe(null)},providerId:de?.providerId??null,model:de?.model??null,isNew:de?.isNew??!1,onSave:e=>{if(!de)return;let{providerId:t,isNew:n}=de;o(r=>{let i=r.providers[t];if(!i)return r;let a=i.models||[];return n?kt(r,t,{models:[...a,e]}):kt(r,t,{models:a.map(t=>t.id===e.id?e:t)})})},m:n})]}):(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold text-fg`,children:t.settingsSections.models}),(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:n.needToken})]})}function Ft(){return{enabled:!1,provider:`alibaba`,alibaba:{model:`paraformer-v2`},openai:{model:`whisper-1`},fallback:{enabled:!0,order:[`alibaba`,`openai`]}}}function It(){return{enabled:!1,provider:`openai`,trigger:`always`,maxTextLength:4096,timeoutMs:3e4,alibaba:{model:`qwen-tts`,voice:`Cherry`},openai:{model:`tts-1`,voice:`alloy`},edge:{voice:`zh-CN-XiaoxiaoNeural`},minimax:{model:`speech-2.8-hd`,voice:`male-qn-qingse`}}}function Lt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Rt(e){let t=Ft();if(!Lt(e))return t;let n=e.provider===`openai`?`openai`:`alibaba`,r=Lt(e.alibaba)?{...t.alibaba,...e.alibaba}:t.alibaba,i=Lt(e.openai)?{...t.openai,...e.openai}:t.openai,a=t.fallback??{enabled:!0,order:[`alibaba`,`openai`]};if(Lt(e.fallback)){let t=Array.isArray(e.fallback.order)?e.fallback.order.filter(e=>e===`alibaba`||e===`openai`):a.order;a={enabled:typeof e.fallback.enabled==`boolean`?e.fallback.enabled:a.enabled,order:t.length?t:a.order}}return{enabled:!!e.enabled,provider:n,alibaba:r,openai:i,fallback:a}}function zt(e){return e===`openai`||e===`alibaba`||e===`edge`||e===`minimax`}function Bt(e){let t=It();if(!Lt(e))return t;let n=zt(e.provider)?e.provider:`openai`,r=e.trigger===`off`||e.trigger===`always`||e.trigger===`inbound`||e.trigger===`tagged`?e.trigger:`always`;return{enabled:!!e.enabled,provider:n,trigger:r,maxTextLength:typeof e.maxTextLength==`number`&&Number.isFinite(e.maxTextLength)?e.maxTextLength:t.maxTextLength,timeoutMs:typeof e.timeoutMs==`number`&&Number.isFinite(e.timeoutMs)?e.timeoutMs:t.timeoutMs,alibaba:Lt(e.alibaba)?{...t.alibaba,...e.alibaba}:t.alibaba,openai:Lt(e.openai)?{...t.openai,...e.openai}:t.openai,edge:Lt(e.edge)?{...t.edge,...e.edge}:t.edge,minimax:Lt(e.minimax)?{...t.minimax,...e.minimax}:t.minimax}}function Vt(e){let t=Lt(e)?e:{};return{stt:Rt(t.stt),tts:Bt(t.tts)}}async function Ht(e){await f(T(`/api/config`),{method:`PATCH`,body:JSON.stringify({stt:e.stt,tts:e.tts})}),W()}async function Ut(){let e=await f(T(`/api/voice/models`));if(!e.payload?.models)throw Error(`Missing voice models payload`);return e.payload.models}function Wt(){return a(`w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg`,`placeholder:text-fg-subtle`,I,`dark:border-edge`)}function Q(){return a(U,le)}var Gt=[{id:`paraformer-v2`,name:`Paraformer v2`},{id:`paraformer-v1`,name:`Paraformer v1`}],Kt=[{id:`whisper-1`,name:`Whisper-1`}],qt=[{id:`tts-1`,name:`TTS-1`},{id:`tts-1-hd`,name:`TTS-1 HD`}],Jt=[{id:`alloy`,name:`Alloy`},{id:`echo`,name:`Echo`}],Yt=[{id:`qwen-tts`,name:`Qwen TTS`},{id:`qwen3-tts-flash`,name:`Qwen3 TTS Flash`}],Xt=[{id:`Cherry`,name:`Cherry`},{id:`longxiaochun`,name:`Long Xiao Chun`}],Zt=[{id:`en-US-MichelleNeural`,name:`Michelle (US English)`},{id:`zh-CN-XiaoxiaoNeural`,name:`Xiaoxiao (Chinese)`}],Qt=[{id:`speech-2.8-hd`,name:`Speech 2.8 HD (Recommended)`},{id:`speech-2.8-turbo`,name:`Speech 2.8 Turbo (Fast)`}],$t=[{id:`male-qn-qingse`,name:`Male Qingse (青涩男声)`},{id:`female-shaonv`,name:`Female Shaonv (少女音)`}];function en(){let e=S(e=>e.language),t=q(e),n=t.voiceSettings,i=!!_e(e=>e.token),[a,s]=(0,X.useState)(null),[c,l]=(0,X.useState)(null),[u,d]=(0,X.useState)(null),[f,p]=(0,X.useState)(!1),[m,_]=(0,X.useState)(null),[v,y]=(0,X.useState)(!1),{data:b,error:x,isLoading:C,mutate:w}=o(i),{data:E,error:D,isLoading:O,mutate:k}=r(i?T(`/api/voice/models`):null,Ut,{revalidateOnFocus:!1}),A=(0,X.useMemo)(()=>b?.payload?.config===void 0?null:Vt(b.payload.config),[b]),j=(0,X.useMemo)(()=>!a||!c?!1:JSON.stringify(a)!==JSON.stringify(c),[a,c]);(0,X.useEffect)(()=>{if(!i){s(null),l(null),d(null);return}A===null||E===void 0||j||(s(structuredClone(A)),l(structuredClone(A)),d(E),y(!1))},[i,A,E,j]);let M=!!(i&&(A===null||E===void 0)&&(C||O)),N=x instanceof Error?x.message:x?String(x):D instanceof Error?D.message:D?String(D):null,P=(0,X.useCallback)(e=>{s(t=>t?{...t,stt:{...t.stt,...e}}:null)},[]),F=(0,X.useCallback)(e=>{s(t=>t?{...t,stt:{...t.stt,alibaba:{...t.stt.alibaba,...e}}}:null)},[]),I=(0,X.useCallback)(e=>{s(t=>t?{...t,stt:{...t.stt,openai:{...t.stt.openai,...e}}}:null)},[]),L=(0,X.useCallback)(e=>{s(t=>{if(!t)return null;let n=t.stt.fallback??{enabled:!0,order:[`alibaba`,`openai`]};return{...t,stt:{...t.stt,fallback:{...n,...e}}}})},[]),ee=(0,X.useCallback)(e=>{s(t=>t?{...t,tts:{...t.tts,...e}}:null)},[]),R=(0,X.useCallback)(e=>{s(t=>t?{...t,tts:{...t.tts,alibaba:{...t.tts.alibaba,...e}}}:null)},[]),z=(0,X.useCallback)(e=>{s(t=>t?{...t,tts:{...t.tts,openai:{...t.tts.openai,...e}}}:null)},[]),B=(0,X.useCallback)(e=>{s(t=>t?{...t,tts:{...t.tts,edge:{...t.tts.edge,...e}}}:null)},[]),te=(0,X.useCallback)(e=>{s(t=>t?{...t,tts:{...t.tts,minimax:{...t.tts.minimax,...e}}}:null)},[]),ne=(0,X.useCallback)(async()=>{if(!(!a||f)){p(!0),_(null),y(!1);try{await Ht(a);let e=structuredClone(a);l(e),s(e),y(!0),window.setTimeout(()=>y(!1),2500)}catch(e){_(e instanceof Error?e.message:n.saveError)}finally{p(!1)}}},[a,f,n.saveError]);if(!i)return(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold text-fg`,children:t.settingsSections.voice}),(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:n.needToken})]});if(M)return(0,Y.jsx)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-fg-muted`,children:[(0,Y.jsx)(g,{className:`size-4 animate-spin`}),n.loading]})});if(!a||u===null)return(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:m??N??n.loadError}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,onClick:()=>{w(),k()},children:n.retry})]});let V=a.stt,H=a.tts;return(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6`,children:[(0,Y.jsxs)(`header`,{className:`flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold tracking-tight text-fg`,children:t.settingsSections.voice}),(0,Y.jsx)(`p`,{className:`mt-1 text-sm text-fg-muted`,children:n.subtitle}),(0,Y.jsxs)(`a`,{href:h(e,`voice`),target:`_blank`,rel:`noreferrer`,className:`mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40`,children:[n.docsLink,(0,Y.jsx)(K,{className:`size-3.5`})]})]}),(0,Y.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[v?(0,Y.jsx)(`span`,{className:`text-sm text-fg-muted`,children:n.saved}):null,(0,Y.jsx)(J,{type:`button`,variant:`primary`,disabled:!j||f,onClick:()=>void ne(),children:f?n.saving:n.save})]})]}),j?(0,Y.jsx)(`p`,{className:`text-xs text-amber-800 dark:text-amber-200`,children:n.unsavedHint}):null,m?(0,Y.jsx)(`p`,{className:`text-sm text-red-600 dark:text-red-400`,children:m}):null,(0,Y.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,Y.jsx)(tn,{v:n,stt:V,models:u,updateStt:P,updateSttAlibaba:F,updateSttOpenai:I,updateSttFallback:L}),(0,Y.jsx)(nn,{v:n,tts:H,models:u,updateTts:ee,updateTtsAlibaba:R,updateTtsOpenai:z,updateTtsEdge:B,updateTtsMinimax:te})]}),(0,Y.jsxs)(`div`,{className:`rounded-xl border border-accent/25 bg-accent/5 px-4 py-3 dark:border-accent/30 dark:bg-accent/10`,children:[(0,Y.jsxs)(`p`,{className:`text-sm text-fg`,children:[(0,Y.jsx)(`strong`,{className:`text-accent`,children:n.notes.title}),` `,n.notes.duration]}),(0,Y.jsx)(`p`,{className:`mt-2 text-xs text-fg-muted`,children:n.notes.envVars})]})]})}function tn({v:e,stt:t,models:n,updateStt:r,updateSttAlibaba:i,updateSttOpenai:o,updateSttFallback:s}){let c=n?.stt?.alibaba?.length?n.stt.alibaba:Gt,l=n?.stt?.openai?.length?n.stt.openai:Kt;return(0,Y.jsxs)(`section`,{className:`rounded-2xl bg-surface-base px-4 py-5 sm:px-5`,children:[(0,Y.jsxs)(`div`,{className:`mb-4`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-sm font-semibold text-fg`,children:[(0,Y.jsx)(D,{className:`size-4 text-accent`,strokeWidth:1.75}),e.stt.title]}),(0,Y.jsx)(`p`,{className:`mt-1 text-xs text-fg-muted`,children:e.stt.description})]}),(0,Y.jsxs)(`div`,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:e.stt.enable}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-muted`,children:e.stt.enableDesc})]}),(0,Y.jsx)(`input`,{type:`checkbox`,className:`ui-checkbox`,checked:t.enabled,onChange:e=>r({enabled:e.target.checked})})]}),t.enabled?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.stt.provider}),(0,Y.jsxs)(`select`,{className:Q(),value:t.provider,onChange:e=>r({provider:e.target.value}),children:[(0,Y.jsx)(`option`,{value:`alibaba`,children:e.stt.alibaba}),(0,Y.jsx)(`option`,{value:`openai`,children:e.stt.openai})]})]})}),t.provider===`alibaba`?(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.stt.apiKey}),(0,Y.jsx)(`input`,{className:a(Wt(),`font-mono text-xs`),type:`password`,autoComplete:`off`,value:t.alibaba?.apiKey??``,onChange:e=>i({apiKey:e.target.value}),placeholder:`sk-...`}),(0,Y.jsxs)(`p`,{className:`text-xs text-fg-subtle`,children:[e.stt.apiKeyDesc,` (DASHSCOPE_API_KEY)`]})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.stt.model}),(0,Y.jsx)(`select`,{className:Q(),value:t.alibaba?.model??``,onChange:e=>i({model:e.target.value}),children:c.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.name},e.id))})]})]}):(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.stt.apiKey}),(0,Y.jsx)(`input`,{className:a(Wt(),`font-mono text-xs`),type:`password`,autoComplete:`off`,value:t.openai?.apiKey??``,onChange:e=>o({apiKey:e.target.value}),placeholder:`sk-...`}),(0,Y.jsxs)(`p`,{className:`text-xs text-fg-subtle`,children:[e.stt.apiKeyDesc,` (OPENAI_API_KEY)`]})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.stt.model}),(0,Y.jsx)(`select`,{className:Q(),value:t.openai?.model??``,onChange:e=>o({model:e.target.value}),children:l.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.name},e.id))})]})]}),(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:e.stt.fallback}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-muted`,children:e.stt.fallbackDesc})]}),(0,Y.jsx)(`input`,{type:`checkbox`,className:`ui-checkbox`,checked:t.fallback?.enabled??!0,onChange:e=>s({enabled:e.target.checked})})]})]}):null]})]})}function nn({v:e,tts:t,models:n,updateTts:r,updateTtsAlibaba:i,updateTtsOpenai:o,updateTtsEdge:s,updateTtsMinimax:c}){let l=t=>t===`off`?e.tts.triggerDescOff:t===`always`?e.tts.triggerDescAlways:t===`inbound`?e.tts.triggerDescInbound:t===`tagged`?e.tts.triggerDescTagged:``,u=n?.tts?.openai?.length?n.tts.openai:qt,d=n?.ttsVoices?.openai?.length?n.ttsVoices.openai:Jt,f=n?.tts?.alibaba?.length?n.tts.alibaba:Yt,p=n?.ttsVoices?.alibaba?.length?n.ttsVoices.alibaba:Xt,m=n?.ttsVoices?.edge?.length?n.ttsVoices.edge:Zt,h=n?.tts?.minimax?.length?n.tts.minimax:Qt,g=n?.ttsVoices?.minimax?.length?n.ttsVoices.minimax:$t;return(0,Y.jsxs)(`section`,{className:`rounded-2xl bg-surface-base px-4 py-5 sm:px-5`,children:[(0,Y.jsxs)(`div`,{className:`mb-4`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-sm font-semibold text-fg`,children:[(0,Y.jsx)(me,{className:`size-4 text-accent`,strokeWidth:1.75}),e.tts.title]}),(0,Y.jsx)(`p`,{className:`mt-1 text-xs text-fg-muted`,children:e.tts.description})]}),(0,Y.jsxs)(`div`,{className:`space-y-4`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:e.tts.enable}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-muted`,children:e.tts.enableDesc})]}),(0,Y.jsx)(`input`,{type:`checkbox`,className:`ui-checkbox`,checked:t.enabled,onChange:e=>r({enabled:e.target.checked})})]}),t.enabled?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.tts.trigger}),(0,Y.jsxs)(`select`,{className:Q(),value:t.trigger,onChange:e=>r({trigger:e.target.value}),children:[(0,Y.jsx)(`option`,{value:`off`,children:e.tts.triggerOff}),(0,Y.jsx)(`option`,{value:`always`,children:e.tts.triggerAlways}),(0,Y.jsx)(`option`,{value:`inbound`,children:e.tts.triggerInbound}),(0,Y.jsx)(`option`,{value:`tagged`,children:e.tts.triggerTagged})]}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-subtle`,children:l(t.trigger)})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.tts.provider}),(0,Y.jsxs)(`select`,{className:Q(),value:t.provider,onChange:e=>r({provider:e.target.value}),children:[(0,Y.jsx)(`option`,{value:`openai`,children:e.tts.providerOpenai}),(0,Y.jsx)(`option`,{value:`alibaba`,children:e.stt.alibaba}),(0,Y.jsx)(`option`,{value:`minimax`,children:`MiniMax`}),(0,Y.jsx)(`option`,{value:`edge`,children:e.tts.providerEdge})]})]})]}),t.provider===`openai`?(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5 sm:col-span-2`,children:[(0,Y.jsx)($,{children:e.stt.apiKey}),(0,Y.jsx)(`input`,{className:a(Wt(),`font-mono text-xs`),type:`password`,autoComplete:`off`,value:t.openai?.apiKey??``,onChange:e=>o({apiKey:e.target.value}),placeholder:`sk-...`}),(0,Y.jsxs)(`p`,{className:`text-xs text-fg-subtle`,children:[e.stt.apiKeyDesc,` (OPENAI_API_KEY)`]})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.stt.model}),(0,Y.jsx)(`select`,{className:Q(),value:t.openai?.model??``,onChange:e=>o({model:e.target.value}),children:u.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.name},e.id))})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.tts.voice}),(0,Y.jsx)(`select`,{className:Q(),value:t.openai?.voice??``,onChange:e=>o({voice:e.target.value}),children:d.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.name},e.id))})]})]}):null,t.provider===`alibaba`?(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5 sm:col-span-2`,children:[(0,Y.jsx)($,{children:e.stt.apiKey}),(0,Y.jsx)(`input`,{className:a(Wt(),`font-mono text-xs`),type:`password`,autoComplete:`off`,value:t.alibaba?.apiKey??``,onChange:e=>i({apiKey:e.target.value}),placeholder:`sk-...`}),(0,Y.jsxs)(`p`,{className:`text-xs text-fg-subtle`,children:[e.stt.apiKeyDesc,` (DASHSCOPE_API_KEY)`]})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.stt.model}),(0,Y.jsx)(`select`,{className:Q(),value:t.alibaba?.model??``,onChange:e=>i({model:e.target.value}),children:f.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.name},e.id))})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.tts.voice}),(0,Y.jsx)(`select`,{className:Q(),value:t.alibaba?.voice??``,onChange:e=>i({voice:e.target.value}),children:p.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.name},e.id))})]})]}):null,t.provider===`minimax`?(0,Y.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5 sm:col-span-2`,children:[(0,Y.jsx)($,{children:e.stt.apiKey}),(0,Y.jsx)(`input`,{className:a(Wt(),`font-mono text-xs`),type:`password`,autoComplete:`off`,value:t.minimax?.apiKey??``,onChange:e=>c({apiKey:e.target.value}),placeholder:`eyJ...`}),(0,Y.jsxs)(`p`,{className:`text-xs text-fg-subtle`,children:[e.stt.apiKeyDesc,` (MINIMAX_API_KEY)`]})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.stt.model}),(0,Y.jsx)(`select`,{className:Q(),value:t.minimax?.model??``,onChange:e=>c({model:e.target.value}),children:h.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.name},e.id))})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.tts.voice}),(0,Y.jsx)(`select`,{className:Q(),value:t.minimax?.voice??``,onChange:e=>c({voice:e.target.value}),children:g.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.name},e.id))})]})]}):null,t.provider===`edge`?(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)($,{children:e.tts.voice}),(0,Y.jsx)(`select`,{className:Q(),value:t.edge?.voice??``,onChange:e=>s({voice:e.target.value}),children:m.map(e=>(0,Y.jsx)(`option`,{value:e.id,children:e.name},e.id))}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-subtle`,children:e.tts.edgeHint})]}):null]}):null]})]})}function $({children:e}){return(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:e})}function rn(e){let t=e&&typeof e==`object`&&`tools`in e?e.tools:void 0,n=t&&typeof t==`object`&&`web`in t?t.web:void 0,r=n&&typeof n==`object`&&`region`in n?n.region:void 0,i=r===`cn`||r===`global`?r:`auto`,a=n&&typeof n==`object`&&`search`in n?n.search:void 0,o=a&&typeof a==`object`?a:{},s=typeof o.maxResults==`number`&&Number.isFinite(o.maxResults)?Math.floor(o.maxResults):5,c=o.providers;return{regionMode:i,maxResults:s,providers:Array.isArray(c)?c.map(e=>{let t=e&&typeof e==`object`?e:{},n=t.type;return{type:n===`brave`||n===`tavily`||n===`bing`||n===`searxng`?n:`brave`,apiKey:typeof t.apiKey==`string`?t.apiKey:``,url:typeof t.url==`string`?t.url:``,disabled:t.disabled===!0}}):[]}}async function an(e){let t=e.regionMode===`auto`?`auto`:e.regionMode===`cn`?`cn`:`global`,n={maxResults:e.maxResults,providers:e.providers.map(e=>{let t={type:e.type,apiKey:e.apiKey};return e.type===`searxng`&&e.url.trim()&&(t.url=e.url.trim().replace(/\/+$/,``)),e.disabled&&(t.disabled=!0),t})};await f(T(`/api/config`),{method:`PATCH`,body:JSON.stringify({tools:{web:{region:t,search:n}}})}),W()}function on({label:e,description:t,children:n}){return(0,Y.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:e}),n,(0,Y.jsx)(`p`,{className:`text-xs leading-relaxed text-fg-subtle`,children:t})]})}function sn(){return a(`w-full rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg`,`placeholder:text-fg-subtle`,I,`dark:border-edge`)}function cn(){return a(U,le)}var ln=[`brave`,`tavily`,`bing`,`searxng`];function un(){return{type:`brave`,apiKey:``,url:``,disabled:!1}}function dn(){let e=S(e=>e.language),t=q(e),n=t.webSearchSettings,r=t.logs,i=!!_e(e=>e.token),[a,s]=(0,X.useState)(null),[c,l]=(0,X.useState)(null),[u,d]=(0,X.useState)(!1),[f,p]=(0,X.useState)(null),[m,_]=(0,X.useState)(!1),v=(0,X.useRef)(!1),{data:y,error:b,isLoading:C,mutate:w}=o(i),T=(0,X.useMemo)(()=>y?.payload?.config===void 0?null:rn(y.payload.config),[y]);(0,X.useEffect)(()=>{if(!i){s(null),l(null),v.current=!1;return}T!==null&&(v.current||(s(T),l(T)))},[i,T]);let E=!!(i&&C&&y===void 0&&!b),D=b instanceof Error?b.message:b?String(b):null,O=(0,X.useMemo)(()=>!a||!c?!1:JSON.stringify(a)!==JSON.stringify(c),[a,c]),k=(0,X.useCallback)(e=>{v.current=!0,s(t=>t?{...t,...e}:null)},[]),A=(0,X.useCallback)(async()=>{if(!(!a||u)){d(!0),p(null),_(!1);try{await an(a),v.current=!1,_(!0),window.setTimeout(()=>_(!1),2500)}catch(e){p(e instanceof Error?e.message:n.saveError)}finally{d(!1)}}},[a,u,n.saveError]);return i?E?(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col items-center gap-3 px-4 py-8`,children:[(0,Y.jsx)(g,{className:`size-8 animate-spin text-fg-muted`,"aria-hidden":!0}),(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:n.loading})]}):a?(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6`,children:[(0,Y.jsxs)(`header`,{className:`flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold tracking-tight text-fg`,children:n.title}),(0,Y.jsx)(`p`,{className:`mt-1 text-sm text-fg-muted`,children:n.subtitle}),(0,Y.jsxs)(`a`,{href:h(e,`gateway`),target:`_blank`,rel:`noreferrer`,className:`mt-1 inline-flex items-center gap-1 text-sm text-accent hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40`,children:[n.docsLink,(0,Y.jsx)(K,{className:`size-3.5`})]})]}),(0,Y.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[m?(0,Y.jsx)(`span`,{className:`text-sm text-fg-muted`,children:n.saved}):null,(0,Y.jsx)(J,{type:`button`,variant:`primary`,disabled:!O||u,onClick:()=>void A(),children:u?n.saving:n.save})]})]}),O?(0,Y.jsx)(`p`,{className:`text-xs text-amber-800 dark:text-amber-200`,children:n.unsavedHint}):null,f?(0,Y.jsx)(`p`,{className:`text-sm text-red-600 dark:text-red-400`,children:f}):null,(0,Y.jsxs)(Me,{children:[(0,Y.jsx)(Ne,{icon:oe,title:n.sectionRegion,subtitle:n.sectionRegionHint}),(0,Y.jsx)(`div`,{className:`flex max-w-md flex-col gap-4`,children:(0,Y.jsx)(on,{label:n.regionLabel,description:n.regionDesc,children:(0,Y.jsxs)(`select`,{className:cn(),value:a.regionMode,onChange:e=>k({regionMode:e.target.value}),children:[(0,Y.jsx)(`option`,{value:`auto`,children:n.regionAuto}),(0,Y.jsx)(`option`,{value:`cn`,children:n.regionCn}),(0,Y.jsx)(`option`,{value:`global`,children:n.regionGlobal})]})})})]}),(0,Y.jsxs)(Me,{children:[(0,Y.jsx)(Ne,{icon:oe,title:n.sectionSearch,subtitle:n.sectionSearchHint}),(0,Y.jsxs)(`div`,{className:`flex max-w-xl flex-col gap-6`,children:[(0,Y.jsx)(on,{label:n.maxResultsLabel,description:n.maxResultsDesc,children:(0,Y.jsx)(`input`,{type:`number`,min:1,max:50,className:sn(),value:a.maxResults,onChange:e=>k({maxResults:Math.max(1,Math.min(50,Number(e.target.value)||5))})})}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:n.providersTitle}),a.providers.map((e,t)=>(0,Y.jsx)(fn,{row:e,labels:n,onChange:e=>{let n=[...a.providers];n[t]=e,k({providers:n})},onRemove:()=>{k({providers:a.providers.filter((e,n)=>n!==t)})}},t)),(0,Y.jsxs)(J,{type:`button`,variant:`secondary`,className:`w-fit gap-1.5 text-sm`,onClick:()=>k({providers:[...a.providers,un()]}),children:[(0,Y.jsx)(x,{className:`size-4`}),n.addProvider]})]})]})]}),(0,Y.jsx)(`p`,{className:`text-xs leading-relaxed text-fg-subtle`,children:n.footerHint})]}):(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:f??D??n.loadError}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,onClick:()=>void w(),children:r.refresh})]}):(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-4 px-4 py-6`,children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold text-fg`,children:n.title}),(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:n.needToken})]})}function fn({row:e,labels:t,onChange:n,onRemove:r}){return(0,Y.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-xl border border-edge-subtle bg-surface-panel/60 p-4 dark:border-edge-subtle`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Y.jsx)(`select`,{className:a(cn(),`min-w-[8rem]`),value:e.type,onChange:t=>n({...e,type:t.target.value,url:t.target.value===`searxng`?e.url:``}),children:ln.map(e=>(0,Y.jsx)(`option`,{value:e,children:t.providerTypes[e]},e))}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Y.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-1.5 text-xs text-fg-muted`,children:[(0,Y.jsx)(`input`,{type:`checkbox`,className:`size-3.5 rounded border-edge`,checked:e.disabled,onChange:t=>n({...e,disabled:t.target.checked})}),t.disabled]}),(0,Y.jsx)(J,{type:`button`,variant:`ghost`,className:`h-8 px-2 text-fg-muted`,onClick:r,children:(0,Y.jsx)(N,{className:`size-4`})})]})]}),e.type===`searxng`?(0,Y.jsx)(on,{label:t.urlLabel,description:t.urlDesc,children:(0,Y.jsx)(`input`,{type:`url`,className:sn(),value:e.url,placeholder:`http://localhost:8080`,onChange:t=>n({...e,url:t.target.value})})}):null,(0,Y.jsx)(on,{label:t.apiKeyLabel,description:t.apiKeyDesc,children:(0,Y.jsx)(`input`,{type:`password`,autoComplete:`off`,className:sn(),value:xe(e.apiKey)?``:e.apiKey,placeholder:xe(e.apiKey)?t.keyPlaceholderMasked:t.keyPlaceholder,onChange:t=>n({...e,apiKey:t.target.value})})})]})}var pn=[{key:`fullDisk`,pane:`fullDisk`},{key:`screen`,pane:`screen`},{key:`microphone`,pane:`microphone`},{key:`accessibility`,pane:`accessibility`},{key:`automation`,pane:`automation`},{key:`notifications`,pane:`notifications`},{key:`location`,pane:`location`}];function mn(e,t){let n=q(e).systemSettings.status;return t===`granted`?{label:n.granted,className:`text-emerald-600 dark:text-emerald-400`}:t===`denied`?{label:n.denied,className:`text-amber-600 dark:text-amber-400`}:{label:n.unknown,className:`text-fg-muted`}}function hn(){let e=S(e=>e.language),t=q(e).systemSettings,[n,r]=(0,X.useState)(null),[i,a]=(0,X.useState)(null),[o,s]=(0,X.useState)(null),c=typeof window<`u`?window.electronAPI?.system:void 0,l=(0,X.useCallback)(async()=>{if(c){s(null);try{r(await c.getBehavior()),a(await c.getPermissions())}catch(e){s(e instanceof Error?e.message:String(e))}}},[c]);if((0,X.useEffect)(()=>{O()&&c&&l()},[c,l]),!O()||!c)return(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold text-fg`,children:t.title}),(0,Y.jsxs)(`div`,{className:je(),children:[(0,Y.jsx)(`p`,{className:`text-sm font-medium text-fg`,children:t.desktopOnlyTitle}),(0,Y.jsx)(`p`,{className:`mt-1 text-sm text-fg-muted`,children:t.desktopOnlyBody})]})]});let u=async e=>{try{let{behavior:t}=await c.setBehavior(e);r(t)}catch(e){s(e instanceof Error?e.message:String(e))}},d=async e=>{try{(await c.openPrivacy(e)).ok||s(`open_privacy failed`)}catch(e){s(e instanceof Error?e.message:String(e))}},f=n?n.platform===`win32`?t.permissionsHintWin:n.platform===`linux`?t.permissionsHintLinux:n.platform===`darwin`?t.permissionsHintDarwin:t.permissionsHint:t.permissionsHint;return(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-8`,children:[(0,Y.jsx)(`div`,{children:(0,Y.jsx)(`h1`,{className:`text-lg font-semibold text-fg`,children:t.title})}),o?(0,Y.jsx)(`p`,{className:`text-sm text-amber-600 dark:text-amber-400`,role:`alert`,children:o}):null,(0,Y.jsxs)(Me,{children:[(0,Y.jsxs)(`div`,{className:`mb-4 flex items-center gap-2 text-sm font-semibold text-fg`,children:[(0,Y.jsx)(C,{className:`size-4 text-accent`,strokeWidth:1.75}),t.behaviorGroup]}),(0,Y.jsxs)(`div`,{className:`space-y-2`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:t.toggles.openAtLogin}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-muted`,children:t.toggles.openAtLoginDesc})]}),(0,Y.jsx)(`input`,{type:`checkbox`,className:`ui-checkbox`,disabled:!n,checked:!!n?.openAtLogin,onChange:e=>{u({openAtLogin:e.target.checked})}})]}),(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:t.toggles.keepAwake}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-muted`,children:t.toggles.keepAwakeDesc})]}),(0,Y.jsx)(`input`,{type:`checkbox`,className:`ui-checkbox`,disabled:!n,checked:!!n?.keepAwakePreferred,onChange:e=>{u({keepAwakePreferred:e.target.checked})}})]}),(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:t.toggles.notifyDesktop}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-muted`,children:t.toggles.notifyDesktopDesc})]}),(0,Y.jsx)(`input`,{type:`checkbox`,className:`ui-checkbox`,disabled:!n,checked:!!n?.notifyEnabled,onChange:e=>{u({notifyEnabled:e.target.checked})}})]}),(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-xl bg-surface-hover/50 px-3 py-2.5 dark:bg-surface-hover/35`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:t.toggles.notifySound}),(0,Y.jsx)(`p`,{className:`text-xs text-fg-muted`,children:t.toggles.notifySoundDesc})]}),(0,Y.jsx)(`input`,{type:`checkbox`,className:`ui-checkbox`,disabled:!n,checked:!!n?.notifySoundEnabled,onChange:e=>{u({notifySoundEnabled:e.target.checked})}})]})]})]}),n&&i?(0,Y.jsxs)(`section`,{className:je(),children:[(0,Y.jsxs)(`div`,{className:`mb-4 flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between`,children:[(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h2`,{className:`text-sm font-semibold text-fg`,children:t.permissionsTitle}),(0,Y.jsx)(`p`,{className:`mt-0.5 text-xs text-fg-muted`,children:f})]}),(0,Y.jsx)(`button`,{type:`button`,className:`mt-2 inline-flex max-w-full items-center justify-center rounded-lg border border-edge bg-surface-panel px-3 py-1.5 text-sm font-medium text-fg transition-colors hover:bg-surface-hover sm:mt-0`,onClick:()=>void l(),children:t.refresh})]}),(0,Y.jsx)(`ul`,{className:`space-y-3`,children:pn.map(({key:r,pane:o})=>{let l=mn(e,i[r]),u=t.perm[r];return u?(0,Y.jsxs)(`li`,{className:`flex flex-col gap-2 rounded-xl border border-edge-subtle bg-surface-panel/60 px-3 py-3 sm:flex-row sm:items-center sm:justify-between`,children:[(0,Y.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Y.jsx)(`div`,{className:`text-sm font-medium text-fg`,children:u.title}),(0,Y.jsx)(`p`,{className:`mt-0.5 text-xs text-fg-muted`,children:u.desc}),(0,Y.jsx)(`p`,{className:`mt-1 text-xs font-medium ${l.className}`,children:l.label})]}),(0,Y.jsxs)(`div`,{className:`flex shrink-0 flex-wrap items-center gap-2`,children:[r===`microphone`&&n?.platform===`darwin`?(0,Y.jsx)(`button`,{type:`button`,className:`inline-flex items-center gap-1 rounded-lg border border-edge bg-surface-base px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-hover`,onClick:()=>{(async()=>{try{await c.requestMicrophone(),a(await c.getPermissions())}catch(e){s(e instanceof Error?e.message:String(e))}})()},children:e===`zh`?`请求访问`:`Request`}):null,(0,Y.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1.5 rounded-lg border border-edge bg-surface-base px-2.5 py-1.5 text-xs font-medium text-fg hover:bg-surface-hover`,onClick:()=>void d(o),children:[t.openSettings,(0,Y.jsx)(K,{className:`size-3.5`,strokeWidth:1.75,"aria-hidden":!0})]})]})]},r):null})})]}):null]})}async function gn(e){let t=await A(T(`/api/auth/oauth-async/start`),{method:`POST`,body:JSON.stringify({provider:e})});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error||`OAuth start failed: ${t.status}`)}return(await t.json()).payload}async function _n(e){let t=await A(T(`/api/auth/oauth-async/${encodeURIComponent(e)}/status`));if(!t.ok)throw Error(`OAuth status: ${t.status}`);return(await t.json()).payload}async function vn(e,t){let n=await A(T(`/api/auth/oauth-async/${encodeURIComponent(e)}/code`),{method:`POST`,body:JSON.stringify({code:t})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error||`Submit code failed: ${n.status}`)}}async function yn(e){let t=await A(T(`/api/auth/oauth-async/${encodeURIComponent(e)}/cancel`),{method:`POST`});if(!t.ok)throw Error(`Cancel OAuth failed: ${t.status}`)}async function bn(e){let t=await A(T(`/api/auth/oauth-async/${encodeURIComponent(e)}`),{method:`DELETE`});if(!t.ok)throw Error(`Cleanup session failed: ${t.status}`)}async function xn(e){let t=await A(T(`/api/auth/oauth/${encodeURIComponent(e)}`),{method:`DELETE`});if(!t.ok)throw Error(`Revoke OAuth failed: ${t.status}`)}function Sn({providerId:e,language:t}){let n=de[e];if(!n)return null;let r=t===`zh`,i=r&&n.descriptionZh?n.descriptionZh:n.description;return i?(0,Y.jsxs)(H,{children:[(0,Y.jsx)(P,{asChild:!0,children:(0,Y.jsx)(`button`,{type:`button`,className:`rounded p-0.5 text-fg-subtle hover:bg-surface-hover hover:text-fg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,"aria-label":r?`${e} 详情`:`${e} info`,children:(0,Y.jsx)(ue,{className:`size-3.5`,"aria-hidden":!0})})}),(0,Y.jsx)(re,{children:(0,Y.jsxs)(se,{side:`right`,align:`start`,sideOffset:6,className:a(`z-50 w-64 rounded-xl border border-edge bg-surface-panel p-3 shadow-md`,`data-[state=open]:animate-in data-[state=closed]:animate-out`,`data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0`,`data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95`),children:[(0,Y.jsxs)(`div`,{className:`flex items-start justify-between gap-2`,children:[(0,Y.jsx)(`p`,{className:`text-xs font-semibold text-fg`,children:e}),(0,Y.jsx)(ge,{asChild:!0,children:(0,Y.jsx)(`button`,{type:`button`,className:`shrink-0 rounded p-0.5 text-fg-subtle hover:bg-surface-hover hover:text-fg`,"aria-label":r?`关闭`:`Close`,children:(0,Y.jsx)(z,{className:`size-3.5`,"aria-hidden":!0})})})]}),(0,Y.jsx)(`p`,{className:`mt-1.5 text-xs leading-relaxed text-fg-muted`,children:i}),n.bestFor&&n.bestFor.length>0?(0,Y.jsxs)(`div`,{className:`mt-2`,children:[(0,Y.jsx)(`p`,{className:`text-[10px] font-medium uppercase tracking-wide text-fg-subtle`,children:r?`适合场景`:`Best for`}),(0,Y.jsx)(`div`,{className:`mt-1 flex flex-wrap gap-1`,children:n.bestFor.map(e=>(0,Y.jsx)(`span`,{className:`rounded bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium text-fg-muted`,children:e},e))})]}):null,n.freeTier===void 0?null:(0,Y.jsxs)(`div`,{className:`mt-2`,children:[(0,Y.jsx)(`p`,{className:`text-[10px] font-medium uppercase tracking-wide text-fg-subtle`,children:r?`免费额度`:`Free tier`}),(0,Y.jsx)(`p`,{className:`mt-0.5 text-xs text-fg-muted`,children:n.freeTier?n.freeTierNote??(r?`有免费额度`:`Available`):r?`无免费额度(按量付费)`:`None (pay-as-you-go)`})]}),n.pricingUrl||n.docsUrl?(0,Y.jsxs)(`div`,{className:`mt-2.5 flex gap-3`,children:[n.pricingUrl?(0,Y.jsxs)(`a`,{href:n.pricingUrl,target:`_blank`,rel:`noopener noreferrer`,className:`inline-flex items-center gap-0.5 text-xs text-accent-fg hover:underline`,children:[r?`定价`:`Pricing`,(0,Y.jsx)(K,{className:`size-3`,"aria-hidden":!0})]}):null,n.docsUrl?(0,Y.jsxs)(`a`,{href:n.docsUrl,target:`_blank`,rel:`noopener noreferrer`,className:`inline-flex items-center gap-0.5 text-xs text-accent-fg hover:underline`,children:[r?`文档`:`Docs`,(0,Y.jsx)(K,{className:`size-3`,"aria-hidden":!0})]}):null]}):null,(0,Y.jsx)(V,{className:`fill-edge`})]})})]}):null}var Cn=[`common`,`specialty`,`enterprise`,`oauth`,`extension`];function wn(e){let t=new Map;for(let e of Cn)t.set(e,[]);for(let n of e){let e=n.category||`specialty`,r=t.get(e)??[];r.push(n),t.set(e,r)}return t}function Tn(e,t){return e.replace(/\{\{(\w+)\}\}/g,(e,n)=>String(t[n]??``))}function En(e,t){switch(t){case`agent`:return e.sourceAgent;case`gateway`:return e.sourceGateway;case`oauth`:return e.sourceOauth;case`env`:return e.sourceEnv;case`models_json`:return e.sourceModelsJson;case`extension`:return e.sourceExtension;default:return e.sourceNone}}function Dn(){let e=S(e=>e.language),t=q(e),n=t.providersSettings,i=!!_e(e=>e.token),[s,c]=(0,X.useState)({}),[u,d]=(0,X.useState)({}),[m,g]=(0,X.useState)(!1),[_,y]=(0,X.useState)(null),[b,x]=(0,X.useState)(null),[C,w]=(0,X.useState)(()=>new Set([`common`])),[E,D]=(0,X.useState)(``),[O,k]=(0,X.useState)(!1),[A,j]=(0,X.useState)(()=>new Set),M=(0,X.useRef)(``),N=T(`/api/providers/meta`),P=(0,X.useCallback)(async e=>(await f(e)).payload?.providers??[],[]),{data:F,error:L,isLoading:ee,mutate:R}=o(i),{data:z,error:B,isLoading:ne,mutate:V}=r(i?N:null,P,{revalidateOnFocus:!1}),{data:H,mutate:re}=r(i?te:null,()=>pe(),{revalidateOnFocus:!1}),U=(0,X.useMemo)(()=>!z||F===void 0?null:ce(z,ie(F.payload?.config),H??[]),[z,F,H]),ae=L instanceof Error?L.message:L?String(L):B instanceof Error?B.message:B?String(B):null,W=!!(i&&U===null&&(ee||ne)&&!ae),G=(0,X.useMemo)(()=>JSON.stringify(s)!==JSON.stringify(u),[s,u]);(0,X.useEffect)(()=>{if(!G)return;let e=e=>{e.preventDefault(),e.returnValue=``};return window.addEventListener(`beforeunload`,e),()=>window.removeEventListener(`beforeunload`,e)},[G]),(0,X.useEffect)(()=>{if(!(!i||U===null)&&!G){let e={};for(let t of U)e[t.id]=t.apiKey;c(e),d({...e})}},[i,U,G]);let K=U??[],se=(0,X.useMemo)(()=>{let e=K,t=E.trim().toLowerCase();return t&&(e=e.filter(e=>{let n=de[e.id]?.aliases??[];return e.id.toLowerCase().includes(t)||e.name.toLowerCase().includes(t)||n.some(e=>e.toLowerCase().includes(t))})),O&&(e=e.filter(e=>!e.configured)),e},[K,E,O]),le=(0,X.useMemo)(()=>wn(se),[se]);(0,X.useEffect)(()=>{let e=M.current;if(M.current=E,E.trim()){let e=new Set;for(let t of Cn)(le.get(t)??[]).length>0&&e.add(t);w(e);return}e.trim()&&w(new Set([`common`]))},[E,le]);let ue=(0,X.useCallback)(async()=>{if(m)return;let e={};for(let t of Object.keys(s)){let n=s[t]?.trim()??``;!n||xe(n)||(e[t]=n)}if(Object.keys(e).length===0){d({...s}),x(`noChanges`),window.setTimeout(()=>x(null),2500);return}g(!0),y(null),x(null);try{await ve(e),j(new Set(Object.keys(e)));let t=await re(pe(!0))??H??[],[n,r]=await Promise.all([R(),V()]),i=Array.isArray(r)?r:z??[],a=n??F;if(a?.payload){let e=ce(i,ie(a.payload.config),t),n={};for(let t of e)n[t.id]=t.apiKey;c(n),d({...n})}x(`saved`),window.setTimeout(()=>x(null),2500)}catch(e){y(e instanceof Error?e.message:n.saveError)}finally{g(!1)}},[F,s,z,H,R,V,re,n.saveError,m]),fe=(0,X.useCallback)(()=>{c({...u}),y(null),x(null),j(new Set)},[u]),me=e=>{w(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},he=(0,X.useCallback)(()=>{R(),V()},[R,V]),ge=!!(E.trim()||O);return i?W?(0,Y.jsxs)(`div`,{className:`mx-auto w-full max-w-app-main px-4 py-8`,children:[(0,Y.jsx)(`div`,{className:`h-8 w-48 animate-pulse rounded bg-surface-hover`}),(0,Y.jsx)(`div`,{className:`mt-6 h-32 animate-pulse rounded-xl bg-surface-hover`}),(0,Y.jsx)(`p`,{className:`mt-4 text-sm text-fg-muted`,children:t.logs.loading})]}):K.length===0?(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-10`,children:[(0,Y.jsxs)(`div`,{className:`rounded-xl border border-edge-subtle bg-surface-base px-4 py-3`,children:[(0,Y.jsx)(`p`,{className:`text-sm font-medium text-fg`,children:n.loadError}),(0,Y.jsx)(`p`,{className:`mt-1 text-sm text-fg-muted`,children:_??ae??n.empty})]}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,onClick:()=>{R(),V()},children:t.logs.refresh})]}):(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-6 px-4 py-6`,children:[(0,Y.jsxs)(`header`,{className:`flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between`,children:[(0,Y.jsxs)(`div`,{className:`min-w-0`,children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold tracking-tight text-fg`,children:t.settingsSections.providers}),(0,Y.jsx)(`p`,{className:`mt-1 text-sm text-fg-muted`,children:n.subtitle}),(0,Y.jsx)(`p`,{className:`mt-2 text-xs text-fg-subtle`,children:n.rotateHint})]}),(0,Y.jsxs)(`div`,{className:`flex shrink-0 flex-wrap items-center gap-2`,children:[b===`saved`?(0,Y.jsx)(`span`,{className:`text-sm text-fg-muted`,children:n.saved}):null,b===`noChanges`?(0,Y.jsx)(`span`,{className:`text-sm text-fg-muted`,children:n.noChangesSaved}):null,(0,Y.jsx)(J,{type:`button`,variant:`secondary`,disabled:!G||m,onClick:fe,children:n.discard}),(0,Y.jsx)(J,{type:`button`,variant:`primary`,disabled:!G||m,onClick:()=>void ue(),children:m?n.saving:n.save})]})]}),G?(0,Y.jsx)(`p`,{className:`text-xs text-amber-800 dark:text-amber-200`,children:n.unsavedHint}):null,(0,Y.jsxs)(`p`,{className:`text-sm leading-relaxed text-fg-muted`,children:[n.intro,` `,(0,Y.jsx)(`a`,{href:h(e,`models`),target:`_blank`,rel:`noopener noreferrer`,className:`font-medium text-accent-fg hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,children:n.docsLink}),` · `,(0,Y.jsx)(p,{to:`/settings/models`,className:`font-medium text-accent-fg hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,children:n.modelsLink})]}),(0,Y.jsxs)(`div`,{className:`flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center`,children:[(0,Y.jsxs)(`div`,{className:`relative min-w-0 flex-1 sm:max-w-md`,children:[(0,Y.jsx)(oe,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-fg-subtle`,strokeWidth:1.75,"aria-hidden":!0}),(0,Y.jsx)(`input`,{type:`search`,value:E,onChange:e=>D(e.target.value),placeholder:n.searchPlaceholder,autoComplete:`off`,className:a(`w-full rounded-lg border border-edge bg-surface-panel py-2 pl-10 pr-3 text-sm text-fg placeholder:text-fg-subtle`,I,`dark:border-edge`),"aria-label":n.searchPlaceholder})]}),(0,Y.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 text-sm text-fg-muted`,children:[(0,Y.jsx)(`input`,{type:`checkbox`,checked:O,onChange:e=>k(e.target.checked),className:`size-4 rounded border-edge text-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`}),n.unconfiguredOnly]}),ge?(0,Y.jsx)(J,{type:`button`,variant:`ghost`,className:`h-9 w-fit self-start text-fg-muted`,onClick:()=>{D(``),k(!1)},children:n.clearFilters}):null]}),_?(0,Y.jsx)(`div`,{className:`rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-400`,role:`alert`,children:_}):null,se.length===0?(0,Y.jsxs)(`div`,{className:`rounded-xl border border-dashed border-edge-subtle bg-surface-base px-4 py-8 text-center text-sm text-fg-muted`,children:[(0,Y.jsx)(`p`,{children:n.noMatches}),(0,Y.jsx)(J,{type:`button`,variant:`secondary`,className:`mt-4`,onClick:()=>{D(``),k(!1)},children:n.clearFilters})]}):(0,Y.jsx)(`div`,{className:`flex flex-col gap-3`,children:Cn.map(t=>{let r=le.get(t)??[];if(r.length===0)return null;let i=C.has(t),o=r.filter(e=>e.configured).length,d=`providers-cat-${t}`;return(0,Y.jsxs)(`section`,{className:`overflow-hidden rounded-2xl bg-surface-base`,children:[(0,Y.jsxs)(`button`,{type:`button`,id:`${d}-trigger`,"aria-expanded":i,"aria-controls":d,className:`flex w-full items-center justify-between gap-2 border-b border-edge-subtle px-4 py-3 text-left transition-colors hover:bg-surface-hover/60 dark:border-edge-subtle`,onClick:()=>me(t),children:[(0,Y.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2 text-sm font-semibold text-fg`,children:[(0,Y.jsx)(`span`,{className:`truncate`,children:n.categories[t]}),(0,Y.jsx)(`span`,{className:`shrink-0 rounded bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-subtle`,children:r.length})]}),(0,Y.jsxs)(`span`,{className:`flex shrink-0 items-center gap-2`,children:[o>0?(0,Y.jsxs)(`span`,{className:`flex items-center gap-1 text-xs text-fg-subtle`,children:[(0,Y.jsx)(l,{className:`size-3.5 text-emerald-600 dark:text-emerald-400`,"aria-hidden":!0}),Tn(n.configuredCount,{count:String(o)})]}):null,(0,Y.jsx)(v,{className:a(`size-4 text-fg-subtle transition-transform`,i&&`rotate-180`),"aria-hidden":!0})]})]}),i?(0,Y.jsx)(`div`,{id:d,role:`region`,"aria-labelledby":`${d}-trigger`,className:`divide-y divide-edge-subtle`,children:r.map(t=>(0,Y.jsx)(`div`,{id:`provider-row-${t.id}`,children:(0,Y.jsx)(kn,{row:t,value:s[t.id]??``,rowDirty:(s[t.id]??``)!==(u[t.id]??``),labels:n,language:e,onChange:(e,t)=>c(n=>({...n,[e]:t})),onReload:he,justSaved:A.has(t.id),availableModels:H??[]})},t.id))}):null]},t)})})]}):(0,Y.jsx)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-10`,children:(0,Y.jsxs)(`div`,{className:`flex items-start gap-3 rounded-2xl bg-surface-base p-6`,children:[(0,Y.jsx)(Se,{className:`mt-0.5 size-5 shrink-0 text-fg-subtle`,strokeWidth:1.75}),(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(`h1`,{className:`text-base font-semibold text-fg`,children:t.settingsSections.providers}),(0,Y.jsx)(`p`,{className:`mt-1 text-sm text-fg-muted`,children:n.needToken})]})]})})}function On({envVar:e,labels:t}){let[n,r]=(0,X.useState)(!1),i=async()=>{try{await navigator.clipboard.writeText(e),r(!0),window.setTimeout(()=>r(!1),2e3)}catch{}};return(0,Y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Y.jsx)(`code`,{className:`rounded bg-surface-hover px-1.5 py-0.5 font-mono text-[11px] text-fg-muted`,children:e}),(0,Y.jsx)(`button`,{type:`button`,onClick:()=>void i(),className:`rounded p-0.5 text-fg-subtle hover:bg-surface-hover hover:text-fg`,title:n?t.copied:t.copy,"aria-label":n?t.copied:t.copy,children:n?(0,Y.jsx)(l,{className:`size-3.5 text-emerald-600 dark:text-emerald-400`,"aria-hidden":!0}):(0,Y.jsx)(Ee,{className:`size-3.5`,"aria-hidden":!0})})]})}function kn({row:e,value:t,rowDirty:n,labels:r,language:i,onChange:o,onReload:s,justSaved:c,availableModels:u}){let[f,p]=(0,X.useState)(!1),[m,h]=(0,X.useState)(!1),[_,y]=(0,X.useState)(!1),[x,S]=(0,X.useState)(null),C=xe(t),w=C&&!m?``:t,T=e.configured&&!C&&!!t,[D,O]=(0,X.useState)(!1),[A,j]=(0,X.useState)(),[M,N]=(0,X.useState)(),[P,L]=(0,X.useState)(),[R,B]=(0,X.useState)(),[te,V]=(0,X.useState)(),[H,re]=(0,X.useState)(``),[ie,U]=(0,X.useState)(!1),[ae,W]=(0,X.useState)(null),[oe,G]=(0,X.useState)(null),se=e.activeKeySource??`none`,ce=(0,X.useMemo)(()=>be(e.id,i),[e.id,i]);(0,X.useEffect)(()=>()=>{A&&bn(A).catch(()=>{})},[A]),(0,X.useEffect)(()=>{if(!A||!D)return;let e=window.setInterval(()=>{(async()=>{try{let t=await _n(A);L(t.message),B(t.authUrl),V(t.instructions),t.status===`waiting_auth`||t.status===`waiting_code`?N(t.status===`waiting_code`?`waiting_code`:`waiting`):t.status===`completed`?(window.clearInterval(e),O(!1),N(`success`),L(t.message),window.setTimeout(()=>s(),800)):(t.status===`failed`||t.status===`cancelled`)&&(window.clearInterval(e),O(!1),N(`error`),L(t.error||t.message||`OAuth failed`))}catch{}})()},1e3);return()=>window.clearInterval(e)},[A,D,s]);let le=async()=>{O(!0),N(`waiting`),L(r.oauthStarting),j(void 0),B(void 0),V(void 0);try{j((await gn(e.id)).sessionId)}catch(e){N(`error`),L(e instanceof Error?e.message:`OAuth failed`),O(!1)}},q=async()=>{if(A){try{await yn(A)}catch{}j(void 0),O(!1),N(`idle`),L(void 0)}},fe=async()=>{if(!(!A||!H.trim()))try{await vn(A,H.trim()),re(``),L(r.oauthProcessingCode)}catch(e){N(`error`),L(e instanceof Error?e.message:`Failed`)}},pe=()=>{window.confirm(Tn(r.revokeConfirm,{name:e.name}))&&(S(null),xn(e.id).then(()=>s()).catch(e=>S(e instanceof Error?e.message:r.revokeFailed)))},me=async()=>{if(!(!t||C))try{await navigator.clipboard.writeText(t),y(!0),window.setTimeout(()=>y(!1),2e3)}catch{}},ge=async()=>{let e=t.trim();if(!(!e||xe(e))){U(!0),W(null),G(null);try{let t=await F(e);if(t.error){G(!1),W(`${r.testFailed} ${t.error}`);return}G(!0),t.type===`env`?W(r.testOkEnv):t.type===`command`?W(r.testOkCommand):W(r.testOkLiteral)}catch(e){G(!1),W(e instanceof Error?e.message:r.testFailed)}finally{U(!1)}}},_e=n?r.metaWillSave:e.configured?C?`${r.metaMasked} · ${r.runtimeLabelPrefix} ${En(r,se)}`:`${r.runtimeLabelPrefix} ${En(r,se)}`:r.metaNotConfigured,ve=`provider-details-${e.id}`;return(0,Y.jsxs)(`div`,{className:`bg-surface-panel`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-3 px-3 py-3 sm:px-4`,children:[(0,Y.jsx)(`div`,{className:`flex size-8 shrink-0 items-center justify-center rounded-md bg-surface-hover/80 dark:bg-surface-hover/50`,"aria-hidden":!0,children:e.configured?(0,Y.jsx)(l,{className:`size-4 text-emerald-600 dark:text-emerald-400`}):(0,Y.jsx)(Se,{className:`size-4 text-fg-subtle`,strokeWidth:1.75})}),(0,Y.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Y.jsx)(`span`,{className:`text-sm font-semibold text-fg`,children:e.name}),(0,Y.jsx)(Sn,{providerId:e.id,language:i}),(0,Y.jsx)(`span`,{className:`rounded bg-surface-hover px-1.5 py-0.5 font-mono text-[10px] font-medium uppercase tracking-wide text-fg-subtle`,children:e.id}),(0,Y.jsx)(`span`,{className:`rounded bg-surface-hover px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-fg-subtle`,children:e.category})]}),(0,Y.jsx)(`p`,{className:`mt-0.5 text-xs text-fg-muted`,children:_e})]}),(0,Y.jsx)(J,{type:`button`,variant:`ghost`,className:`h-9 w-9 shrink-0 p-0`,"aria-expanded":f,"aria-controls":ve,"aria-label":r.expandRowDetails,onClick:()=>p(e=>!e),children:(0,Y.jsx)(v,{className:a(`size-4 transition-transform`,f&&`rotate-180`),"aria-hidden":!0})})]}),f?(0,Y.jsxs)(`div`,{id:ve,role:`region`,className:`space-y-3 border-t border-edge-subtle bg-surface-base/40 px-3 py-3 dark:bg-surface-base/20 sm:px-4`,children:[e.supportsApiKey===!1?null:(0,Y.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,Y.jsxs)(`div`,{className:`relative flex flex-col gap-2 sm:flex-row sm:gap-2`,children:[(0,Y.jsxs)(`div`,{className:`relative min-w-0 flex-1`,children:[(0,Y.jsx)(`input`,{type:m||!C?`text`:`password`,className:a(`w-full rounded-lg border border-edge bg-surface-panel py-2 pl-3 pr-20 font-mono text-sm text-fg`,`placeholder:text-fg-subtle`,I,`dark:border-edge`),value:w,placeholder:C?r.placeholderOverride:e.configured?r.placeholderKeep:r.placeholderKey,disabled:D,onChange:t=>o(e.id,t.target.value),autoComplete:`off`,spellCheck:!1}),(0,Y.jsxs)(`div`,{className:`absolute right-1 top-1/2 flex -translate-y-1/2 gap-0.5`,children:[t&&!C?(0,Y.jsx)(`button`,{type:`button`,className:a(`rounded p-1.5 text-fg-subtle hover:bg-surface-hover hover:text-fg`,E.transition,E.press,E.focusRingPanel),title:_?r.copied:r.copy,"aria-label":_?r.copied:r.copy,onClick:()=>void me(),children:_?(0,Y.jsx)(l,{className:`size-4`}):(0,Y.jsx)(Ee,{className:`size-4`})}):null,(0,Y.jsx)(`button`,{type:`button`,className:a(`rounded p-1.5 text-fg-subtle hover:bg-surface-hover hover:text-fg disabled:opacity-40`,E.transition,E.press,E.focusRingPanel),title:m?r.hide:r.show,"aria-label":m?r.hide:r.show,disabled:C,onClick:()=>h(e=>!e),children:m?(0,Y.jsx)(he,{className:`size-4`}):(0,Y.jsx)(ne,{className:`size-4`})})]})]}),(0,Y.jsxs)(`div`,{className:`flex flex-wrap gap-2 sm:shrink-0`,children:[(0,Y.jsxs)(J,{type:`button`,variant:`secondary`,className:`gap-1`,disabled:D||ie||!t.trim()||xe(t),onClick:()=>void ge(),children:[ie?(0,Y.jsx)(g,{className:`size-4 animate-spin`,"aria-hidden":!0}):null,ie?r.testingKey:r.testKey]}),e.supportsOAuth?T?(0,Y.jsxs)(J,{type:`button`,variant:`secondary`,className:`gap-1 text-red-600 dark:text-red-400`,onClick:pe,children:[(0,Y.jsx)(k,{className:`size-4`,"aria-hidden":!0}),r.revoke]}):(0,Y.jsxs)(J,{type:`button`,variant:`secondary`,className:`gap-1`,disabled:D,onClick:()=>void le(),children:[D?(0,Y.jsx)(g,{className:`size-4 animate-spin`,"aria-hidden":!0}):(0,Y.jsx)(d,{className:`size-4`,"aria-hidden":!0}),r.oauth]}):null]})]}),ae?(0,Y.jsx)(`p`,{className:a(`text-xs`,oe===!1?`text-red-600 dark:text-red-400`:`text-fg-muted`),role:`status`,children:ae}):null,ce.length>0?(0,Y.jsx)(`div`,{className:`flex flex-col gap-1`,children:ce.map(e=>(0,Y.jsxs)(`a`,{href:e.href,target:`_blank`,rel:`noopener noreferrer`,className:`inline-flex w-fit items-center gap-1 text-xs font-medium text-accent-fg hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent`,children:[ee(e.kind,r),(0,Y.jsx)(K,{className:`size-3`,"aria-hidden":!0})]},`${e.kind}-${e.href}`))}):null]}),P?(0,Y.jsxs)(`div`,{className:a(`flex gap-2 rounded-md px-3 py-2 text-xs`,M===`error`?`border border-red-200 bg-red-50 text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-400`:`bg-surface-base text-fg-muted`),children:[M===`error`?(0,Y.jsx)(b,{className:`mt-0.5 size-4 shrink-0`,"aria-hidden":!0}):M===`success`?(0,Y.jsx)(l,{className:`mt-0.5 size-4 shrink-0 text-emerald-600`,"aria-hidden":!0}):(0,Y.jsx)(ue,{className:`mt-0.5 size-4 shrink-0`,"aria-hidden":!0}),(0,Y.jsx)(`span`,{children:P})]}):null,x?(0,Y.jsxs)(`div`,{className:`flex gap-2 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-400`,role:`alert`,children:[(0,Y.jsx)(b,{className:`mt-0.5 size-4 shrink-0`,"aria-hidden":!0}),(0,Y.jsx)(`span`,{children:x})]}):null,(M===`waiting`||M===`waiting_code`)&&(0,Y.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[R?(0,Y.jsxs)(`a`,{href:R,target:`_blank`,rel:`noopener noreferrer`,className:`inline-flex items-center gap-1.5 rounded-md bg-accent px-3 py-2 text-sm font-medium text-white hover:bg-accent-hover`,children:[(0,Y.jsx)(K,{className:`size-4`,"aria-hidden":!0}),r.openAuthPage]}):null,(0,Y.jsxs)(J,{type:`button`,variant:`secondary`,className:`gap-1`,onClick:()=>void q(),children:[(0,Y.jsx)(z,{className:`size-4`,"aria-hidden":!0}),r.cancelOAuth]})]}),te?(0,Y.jsxs)(`div`,{className:`flex gap-2 rounded-md bg-surface-hover/60 px-3 py-2 text-xs text-fg-muted dark:bg-surface-hover/40`,children:[(0,Y.jsx)(ue,{className:`mt-0.5 size-4 shrink-0`,"aria-hidden":!0}),(0,Y.jsx)(`span`,{children:te})]}):null,M===`waiting_code`?(0,Y.jsxs)(`div`,{className:`flex flex-col gap-2 sm:flex-row`,children:[(0,Y.jsx)(`input`,{type:`text`,className:a(`min-w-0 flex-1 rounded-lg border border-edge bg-surface-panel px-3 py-2 text-sm text-fg`,I,`dark:border-edge`),value:H,placeholder:r.pasteRedirectUrl,onChange:e=>re(e.target.value),onKeyDown:e=>e.key===`Enter`&&void fe()}),(0,Y.jsx)(J,{type:`button`,variant:`primary`,className:`shrink-0`,onClick:()=>void fe(),children:r.submitCode})]}):null,C?(0,Y.jsxs)(`div`,{className:`flex gap-2 rounded-md bg-surface-hover/60 px-3 py-2 text-xs text-fg-muted dark:bg-surface-hover/40`,children:[(0,Y.jsx)(ue,{className:`mt-0.5 size-4 shrink-0`,"aria-hidden":!0}),(0,Y.jsx)(`span`,{children:se===`env`?r.envHint:r.maskedStoredHint})]}):null,e.supportsOAuth&&!C&&!T?(0,Y.jsx)(`p`,{className:`text-xs text-fg-subtle`,children:r.oauthHint}):null,c?(0,Y.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md bg-surface-hover/60 px-3 py-2 text-xs text-fg-muted dark:bg-surface-hover/40`,children:[(0,Y.jsx)(l,{className:`mt-0.5 size-3.5 shrink-0 text-emerald-600 dark:text-emerald-400`,"aria-hidden":!0}),(0,Y.jsx)(`span`,{children:(()=>{let t=u.filter(t=>t.provider===e.id);if(t.length===0)return r.savedNoModels;let n=t.slice(0,3).map(e=>e.name||e.id).join(`, `),i=t.length>3?`… (+${t.length-3})`:``;return`${t.length} ${r.savedModelsAvailable}: ${n}${i}`})()})]}):null,(de[e.id]?.envVars??[]).length>0?(0,Y.jsxs)(`details`,{children:[(0,Y.jsx)(`summary`,{className:`cursor-pointer select-none list-none text-xs text-fg-subtle hover:text-fg-muted`,children:r.envVarAlt}),(0,Y.jsx)(`div`,{className:`mt-1.5 flex flex-col gap-1`,children:(de[e.id]?.envVars??[]).map(e=>(0,Y.jsx)(On,{envVar:e,labels:r},e))})]}):null]}):null]})}var An=[`appearance`,`system`,`agent-defaults`,`providers`,`models`,`voice`,`gateway`,`heartbeat`,`search`];function jn(){let{section:e}=_(),t=S(e=>e.language),n=q(t);if(e===`agent`||e===`agents`)return(0,Y.jsx)(w,{to:`/agents`,replace:!0});if(!e||!An.includes(e))return(0,Y.jsx)(w,{to:`/settings/appearance`,replace:!0});let r=e,i=n.settingsSections[r];return r===`appearance`?(0,Y.jsx)(ze,{}):r===`system`?(0,Y.jsx)(hn,{}):r===`agent-defaults`?(0,Y.jsx)(Pe,{}):r===`providers`?(0,Y.jsx)(Dn,{}):r===`models`?(0,Y.jsx)(Pt,{}):r===`voice`?(0,Y.jsx)(en,{}):r===`gateway`?(0,Y.jsx)(We,{}):r===`heartbeat`?(0,Y.jsx)(ct,{}):r===`search`?(0,Y.jsx)(dn,{}):(0,Y.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,Y.jsx)(`h1`,{className:`text-lg font-semibold text-fg`,children:i}),(0,Y.jsx)(`p`,{className:`text-sm text-fg-muted`,children:t===`zh`?`设置 · ${i}(即将推出)。`:`Settings · ${i} (coming soon).`})]})}export{jn as SettingsPage};
|
|
2
|
+
//# sourceMappingURL=settings-page-B3O3R0E4.js.map
|