ezllm 0.0.34 → 0.0.36

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.
Files changed (34) hide show
  1. package/dist/cpa.js +15 -0
  2. package/dist/daemon.js +8 -8
  3. package/dist/server.js +77 -77
  4. package/dist/web-ui/assets/DashboardView-4pju0xUn.js +1 -0
  5. package/dist/web-ui/assets/{LayoutView-DWg8yVra.js → LayoutView-DjpChErJ.js} +1 -1
  6. package/dist/web-ui/assets/{LoginView-Hrm8Vnje.js → LoginView-Dh-JvmGC.js} +1 -1
  7. package/dist/web-ui/assets/LogsView-BLOCTdb6.js +5 -0
  8. package/dist/web-ui/assets/{ManagedServicesView-CyEGu6c8.js → ManagedServicesView-C5ZROVtT.js} +2 -2
  9. package/dist/web-ui/assets/{ProvidersView-DIlimMSR.css → ProvidersView-BpBOF4eX.css} +1 -1
  10. package/dist/web-ui/assets/{ProvidersView-C8CfibS_.js → ProvidersView-Dwc7I6G0.js} +3 -3
  11. package/dist/web-ui/assets/ServiceStatusView-fiaEQZNp.js +2 -0
  12. package/dist/web-ui/assets/SettingsView-DygfiGG8.css +1 -0
  13. package/dist/web-ui/assets/SettingsView-MrcC_nr9.js +1 -0
  14. package/dist/web-ui/assets/{SetupView-B1Mz6mzJ.js → SetupView-vTCaewVk.js} +1 -1
  15. package/dist/web-ui/assets/{config-BU1w8kdn.js → config-DXHhKDw-.js} +1 -1
  16. package/dist/web-ui/assets/format-DbT9vkcP.js +1 -0
  17. package/dist/web-ui/assets/{index-CREDEMKs.js → index-BKnCp9qM.js} +1 -1
  18. package/dist/web-ui/assets/{message-DPoeboTE.js → message-C1fkA9sE.js} +1 -1
  19. package/dist/web-ui/assets/{providers-DQ4Op0Nb.js → providers-BHK2eZZc.js} +1 -1
  20. package/dist/web-ui/assets/{router-CHObBy9_.js → router-DI9ZLaCn.js} +2 -2
  21. package/dist/web-ui/assets/useManagerApi-l9V9LoLa.js +1 -0
  22. package/dist/web-ui/assets/{useQuickRangeFilter-D2Kl9eRA.js → useQuickRangeFilter-Crb6MDvU.js} +1 -1
  23. package/dist/web-ui/assets/useToast-PFDoTWpf.js +1 -0
  24. package/dist/web-ui/index.html +3 -3
  25. package/package.json +2 -2
  26. package/dist/web-ui/assets/DashboardView-DB3iKQCS.js +0 -1
  27. package/dist/web-ui/assets/LogsView-D33M-JJ7.js +0 -5
  28. package/dist/web-ui/assets/ServiceStatusView-BctoPehE.js +0 -2
  29. package/dist/web-ui/assets/SettingsView-3gy8wT-p.js +0 -1
  30. package/dist/web-ui/assets/SettingsView-PV2z7fD7.css +0 -1
  31. package/dist/web-ui/assets/format-Z1cpFfkW.js +0 -1
  32. package/dist/web-ui/assets/useCopyToast-pgRyL4NF.js +0 -1
  33. package/dist/web-ui/assets/useManagerApi-DIMNWza9.js +0 -1
  34. package/dist/web-ui/assets/useToast-CmSnOJzB.js +0 -1
@@ -1,5 +0,0 @@
1
- import{A as e,Ct as t,F as n,I as r,M as i,O as a,P as o,Pt as s,S as c,Tt as l,V as u,Wt as d,Z as f,a as p,at as ee,bt as m,et as h,fn as g,ft as _,ht as v,it as y,j as b,k as x,m as S,mt as C,nt as w,vt as T,w as E,x as D,xt as O}from"./router-CHObBy9_.js";import{R as k,S as te}from"./message-DPoeboTE.js";import{n as A,t as j}from"./index-CREDEMKs.js";import{t as M}from"./providers-DQ4Op0Nb.js";import{n as N,t as P}from"./useCopyToast-pgRyL4NF.js";import{t as F}from"./useToast-CmSnOJzB.js";import{n as I,t as ne}from"./useQuickRangeFilter-D2Kl9eRA.js";import{_ as L,a as R,c as z,d as B,f as V,g as H,i as re,l as U,n as ie,o as ae,r as oe,u as W}from"./format-Z1cpFfkW.js";u(),T(),d();var G={class:`detail-content`},se={key:0,class:`ip-link`},ce={class:`ip-pop`},K={class:`ip-pop-row`},le={key:0,class:`ip-pop-row`},q={key:1,class:`ip-pop-error`},J={key:2},Y=[`href`],ue={key:1},de={key:1},fe={class:`error-text`},X={class:`pane-bar`},pe={class:`json-block`},me={class:`pane-bar`},he={class:`json-block`},ge={class:`pane-bar`},_e={class:`json-block`},ve={class:`pane-bar`},Z={class:`json-block`},ye={class:`pane-bar`},Q={class:`json-block`},be={class:`pane-bar`},xe={class:`json-block`},$={class:`pane-bar`},Se={class:`json-block`},Ce={class:`pane-bar`},we={class:`json-block`},Te=j(r({__name:`LogDetailDialog`,setup(t,{expose:r}){let{copyWithToast:c}=P(),{loadError:u,run:d}=N(),f=l(!1),m=l(null),_=l(!1),S=l(`info`),w=l(!1),T=l(null),D=I(),k=e=>{T.value=e,f.value=!0,m.value=null,S.value=`info`;let t=D();_.value=!0,d(async()=>{try{let n=`?id=${String(e.id)}`,r=await p.get(`/api/logs/detail`+n);if(!t())return;if(r&&r.detail){let e={...r.detail,...r.meta};e.response&&=O(e.response),e.request&&=O(e.request),m.value=e}else m.value=r}catch(e){if(!t())return;throw e}finally{t()&&(_.value=!1)}})},te=()=>{T.value&&k(T.value)};r({open:k});let A=a(()=>U(m.value?.response?.inbound_request)),j=a(()=>U(m.value?.response?.upstream_request)),M=a(()=>B(m.value?.response?.upstream_response_text)),F=a(()=>(m.value?.response?.upstream_stream_frames||[]).join(`
2
-
3
- `)),ne=a(()=>U(m.value?.response?.client_response)),R=a(()=>(m.value?.response?.client_stream_frames||[]).join(`
4
-
5
- `)),V=a(()=>U(m.value?.request)),H=a(()=>U(m.value?.response)),re=async e=>{if(!(e._ipInfo||e._ipInfoError)){w.value=!0;try{let t=await p.get(`/api/logs/ipinfo?ip=${encodeURIComponent(e.ip)}`);t.error?e._ipInfoError=t.error:e._ipInfo=t}catch{e._ipInfoError=`查询失败`}finally{w.value=!1}}},oe=e=>[e.country,e.region,e.city].filter(Boolean).join(` · `)||`-`;return(t,r)=>{let a=y(`el-button`),l=y(`el-alert`),d=y(`el-descriptions-item`),p=y(`el-tag`),T=y(`el-divider`),D=y(`el-popover`),O=y(`el-descriptions`),k=y(`el-tab-pane`),N=y(`el-tabs`),P=y(`el-dialog`),I=ee(`loading`);return h(),e(P,{modelValue:f.value,"onUpdate:modelValue":r[11]||=e=>f.value=e,title:`日志详情`,width:`80%`,top:`5vh`,"destroy-on-close":``},{default:C(()=>[s(u)?(h(),e(l,{key:0,title:s(u),type:`error`,"show-icon":``,closable:!1,class:`mb-16`},{default:C(()=>[n(a,{size:`small`,onClick:te},{default:C(()=>[...r[12]||=[o(`重试`,-1)]]),_:1})]),_:1},8,[`title`])):b(``,!0),v((h(),i(`div`,G,[m.value?(h(),e(N,{key:0,modelValue:S.value,"onUpdate:modelValue":r[10]||=e=>S.value=e},{default:C(()=>[n(k,{lazy:``,label:`基本信息`,name:`info`},{default:C(()=>[n(O,{column:2,border:``},{default:C(()=>[n(d,{label:`时间`},{default:C(()=>[o(g(s(W)(m.value.time)),1)]),_:1}),n(d,{label:`模型`},{default:C(()=>[o(g(m.value.model),1)]),_:1}),n(d,{label:`方法`},{default:C(()=>[o(g(m.value.method),1)]),_:1}),n(d,{label:`路径`},{default:C(()=>[o(g(m.value.path),1)]),_:1}),n(d,{label:`状态码`},{default:C(()=>[o(g(m.value.status),1)]),_:1}),n(d,{label:`流式`},{default:C(()=>[n(p,{type:m.value.stream?`warning`:`info`},{default:C(()=>[o(g(m.value.stream?`是`:`否`),1)]),_:1},8,[`type`])]),_:1}),n(d,{label:`IP`},{default:C(()=>[m.value.ip?(h(),i(`span`,se,[n(D,{placement:`right`,width:`240`,trigger:`click`,onShow:r[0]||=e=>re(m.value)},{reference:C(()=>[x(`span`,null,g(m.value.ip),1)]),default:C(()=>[v((h(),i(`div`,ce,[m.value._ipInfo?(h(),i(E,{key:0},[x(`div`,K,[r[13]||=x(`span`,{class:`ip-pop-label`},`归属地`,-1),x(`span`,null,g(oe(m.value._ipInfo)),1)]),m.value._ipInfo.isp?(h(),i(`div`,le,[r[14]||=x(`span`,{class:`ip-pop-label`},`运营商`,-1),x(`span`,null,g(m.value._ipInfo.isp),1)])):b(``,!0)],64)):m.value._ipInfoError?(h(),i(`div`,q,g(m.value._ipInfoError),1)):(h(),i(`span`,J,`查询中...`)),n(T,{style:{margin:`8px 0`}}),x(`a`,{class:`ip-pop-link`,href:`https://m.ip138.com/iplookup.php?ip=${encodeURIComponent(m.value.ip)}`,target:`_blank`},`在 ip138 查看`,8,Y)])),[[I,w.value]])]),_:1})])):(h(),i(`span`,ue,`-`))]),_:1}),n(d,{label:`Session`},{default:C(()=>[o(g(m.value.session_id||`-`),1)]),_:1}),n(d,{label:`ID`},{default:C(()=>[m.value._id==null?(h(),i(`span`,de,`-`)):(h(),i(`span`,{key:0,class:`request-id`,title:`点击复制(日志 id 同时是响应头 x-request-id)`,onClick:r[1]||=e=>s(c)(String(m.value._id))},g(m.value._id),1))]),_:1}),n(d,{label:`输入 Token(含缓存读取)`},{default:C(()=>[o(g(s(z)(m.value.input_tokens??0)),1)]),_:1}),n(d,{label:`输出 Token`},{default:C(()=>[o(g(s(z)(m.value.output_tokens??0)),1)]),_:1}),n(d,{label:`缓存读取`},{default:C(()=>[o(g(s(z)(m.value.cache_read_tokens??0)),1)]),_:1}),n(d,{label:`请求耗时`},{default:C(()=>[o(g(s(ae)(m.value.duration)),1)]),_:1}),n(d,{label:`缓存命中率`},{default:C(()=>[o(g(s(ie)(m.value)),1)]),_:1}),m.value.error?(h(),e(d,{key:0,label:`错误`,span:2},{default:C(()=>[x(`span`,fe,g(m.value.error),1)]),_:1})):b(``,!0)]),_:1}),m.value.response?.truncated?(h(),e(l,{key:0,class:`mt-16`,type:`warning`,closable:!1,title:`内容超过单请求捕获上限,已截断`})):b(``,!0)]),_:1}),m.value.response?._capture?(h(),i(E,{key:0},[n(k,{lazy:``,label:`客户端请求`,name:`inbound`},{default:C(()=>[x(`div`,X,[n(a,{size:`small`,class:`copy-btn`,onClick:r[2]||=e=>s(c)(A.value)},{default:C(()=>[...r[15]||=[o(` 复制 `,-1)]]),_:1})]),x(`pre`,pe,g(s(L)(A.value)),1)]),_:1}),n(k,{lazy:``,label:`转发上游的请求`,name:`upstreamReq`},{default:C(()=>[x(`div`,me,[n(a,{size:`small`,class:`copy-btn`,onClick:r[3]||=e=>s(c)(j.value)},{default:C(()=>[...r[16]||=[o(` 复制 `,-1)]]),_:1})]),x(`pre`,he,g(s(L)(j.value)),1)]),_:1}),m.value.response.upstream_response_text?(h(),e(k,{key:0,lazy:``,label:`上游响应(原始)`,name:`upstreamRes`},{default:C(()=>[x(`div`,ge,[n(a,{size:`small`,class:`copy-btn`,onClick:r[4]||=e=>s(c)(m.value.response.upstream_response_text)},{default:C(()=>[...r[17]||=[o(` 复制 `,-1)]]),_:1})]),x(`pre`,_e,g(s(L)(M.value)),1)]),_:1})):m.value.response.upstream_stream_frames?.length?(h(),e(k,{key:1,lazy:``,label:`上游响应(原始流,${m.value.response.upstream_stream_frames.length} 帧)`,name:`upstreamStream`},{default:C(()=>[x(`div`,ve,[n(a,{size:`small`,class:`copy-btn`,onClick:r[5]||=e=>s(c)(F.value)},{default:C(()=>[...r[18]||=[o(` 复制 `,-1)]]),_:1})]),x(`pre`,Z,g(s(L)(F.value)),1)]),_:1},8,[`label`])):b(``,!0),m.value.response.client_response!==void 0&&m.value.response.client_response!==null?(h(),e(k,{key:2,lazy:``,label:`回写客户端(转换后)`,name:`clientRes`},{default:C(()=>[x(`div`,ye,[n(a,{size:`small`,class:`copy-btn`,onClick:r[6]||=e=>s(c)(ne.value)},{default:C(()=>[...r[19]||=[o(` 复制 `,-1)]]),_:1})]),x(`pre`,Q,g(s(L)(ne.value)),1)]),_:1})):m.value.response.client_stream_frames?.length?(h(),e(k,{key:3,lazy:``,label:`回写客户端(${m.value.response.client_stream_frames.length} 帧)`,name:`clientStream`},{default:C(()=>[x(`div`,be,[n(a,{size:`small`,class:`copy-btn`,onClick:r[7]||=e=>s(c)(R.value)},{default:C(()=>[...r[20]||=[o(` 复制 `,-1)]]),_:1})]),x(`pre`,xe,g(s(L)(R.value)),1)]),_:1},8,[`label`])):b(``,!0)],64)):(h(),i(E,{key:1},[n(k,{lazy:``,label:`请求体`,name:`request`},{default:C(()=>[x(`div`,$,[n(a,{size:`small`,class:`copy-btn`,onClick:r[8]||=e=>s(c)(V.value)},{default:C(()=>[...r[21]||=[o(` 复制 `,-1)]]),_:1})]),x(`pre`,Se,g(s(L)(V.value)),1)]),_:1}),n(k,{lazy:``,label:`响应体`,name:`response`},{default:C(()=>[x(`div`,Ce,[n(a,{size:`small`,class:`copy-btn`,onClick:r[9]||=e=>s(c)(H.value)},{default:C(()=>[...r[22]||=[o(` 复制 `,-1)]]),_:1})]),x(`pre`,we,g(s(L)(H.value)),1)]),_:1})],64))]),_:1},8,[`modelValue`])):b(``,!0)])),[[I,_.value]])]),_:1},8,[`modelValue`])}}}),[[`__scopeId`,`data-v-9c192d20`]]);u(),T(),d(),S();var Ee={class:`session-table`},De={class:`group-detail`},Oe=[`title`],ke={key:0,class:`detail-error`},Ae={class:`detail-footer`},je={class:`detail-count`},Me=[`title`,`onClick`],Ne=[`title`],Pe=[`title`],Fe=50,Ie=j(r({__name:`SessionGroupTable`,props:{groups:{},noSession:{},loading:{type:Boolean},filterParams:{}},emits:[`open-detail`],setup(r,{emit:u}){let d=r,f=u,{copyWithToast:m}=P(),S=a(()=>d.noSession?[...d.groups,d.noSession]:d.groups),w=e=>e.session_id||`__no_session__`,T=l(null),E=t(new Map),D={loading:!1,items:[],total:0,nextPage:1,error:null},O=e=>E.get(w(e))??D,k=async(e,t)=>{let n=(e=>(E.has(e)||E.set(e,{loading:!1,items:[],total:0,nextPage:1,error:null}),E.get(e)))(w(e));if(!n.loading){n.loading=!0,n.error=null;try{let r={...d.filterParams,sort:`time`,order:`desc`,page:String(t),pageSize:String(Fe)};e.session_id?r.sessionId=e.session_id:r.noSession=`1`;let i=await p.get(`/api/logs?`+new URLSearchParams(r).toString()),a=i.items||[];n.items=t===1?a:[...n.items,...a],n.total=i.total||0,n.nextPage=t+1}catch(e){n.error=e?.message||`加载失败`}finally{n.loading=!1}}},te=(e,t)=>{t.some(t=>w(t)===w(e))&&O(e).items.length===0&&k(e,1)},A=e=>{let t=O(e);t.loading||t.items.length>=t.total||k(e,t.nextPage)},j=e=>{T.value?.toggleRowExpansion(e)};return _(()=>S.value.map(w),e=>{let t=new Set(e);for(let e of[...E.keys()])t.has(e)||E.delete(e)}),(t,a)=>{let l=y(`el-table-column`),u=y(`el-tag`),d=y(`el-button`),p=y(`el-table`),_=y(`el-empty`),E=ee(`loading`);return h(),i(`div`,Ee,[S.value.length>0||r.loading?v((h(),e(p,{key:0,ref_key:`tableRef`,ref:T,data:S.value,height:`100%`,"row-key":w,stripe:``,onExpandChange:te,onRowClick:j},{default:C(()=>[n(l,{type:`expand`},{default:C(({row:t})=>[x(`div`,De,[v((h(),e(p,{data:O(t).items,size:`small`,stripe:``},{default:C(()=>[n(l,{label:`时间`,width:`165`},{default:C(({row:e})=>[o(g(s(W)(e.time)),1)]),_:1}),n(l,{prop:`model`,label:`模型`,"min-width":`150`}),n(l,{label:`客户端`,"min-width":`130`},{default:C(({row:e})=>[x(`span`,{title:e.user_agent||``},g(s(oe)(e)),9,Oe)]),_:1}),n(l,{label:`状态`,width:`80`,align:`center`},{default:C(({row:e})=>[n(u,{size:`small`,type:e.status>=400?`danger`:e.status>=300?`warning`:`success`},{default:C(()=>[o(g(e.status),1)]),_:2},1032,[`type`])]),_:1}),n(l,{label:`输入`,width:`100`,align:`center`},{default:C(({row:e})=>[o(g(s(z)(e.input_tokens??0)),1)]),_:1}),n(l,{label:`输出`,width:`100`,align:`center`},{default:C(({row:e})=>[o(g(s(z)(e.output_tokens??0)),1)]),_:1}),n(l,{label:`缓存读取`,width:`100`,align:`center`},{default:C(({row:e})=>[o(g(s(z)(e.cache_read_tokens??0)),1)]),_:1}),n(l,{label:`缓存命中率`,width:`105`,align:`center`},{default:C(({row:e})=>[o(g(s(ie)(e)),1)]),_:1}),n(l,{label:`请求耗时`,width:`90`,align:`center`},{default:C(({row:e})=>[o(g(s(ae)(e.duration)),1)]),_:1}),n(l,{label:`详情`,width:`70`,align:`center`},{default:C(({row:e})=>[n(d,{link:``,type:`primary`,onClick:t=>f(`open-detail`,e)},{default:C(()=>[...a[0]||=[o(`查看`,-1)]]),_:1},8,[`onClick`])]),_:1})]),_:1},8,[`data`])),[[E,O(t).loading]]),O(t).error?(h(),i(`div`,ke,[o(g(O(t).error)+` `,1),n(d,{link:``,type:`primary`,size:`small`,onClick:e=>k(t,1)},{default:C(()=>[...a[1]||=[o(`重试`,-1)]]),_:1},8,[`onClick`])])):b(``,!0),x(`div`,Ae,[x(`span`,je,`已显示 `+g(O(t).items.length)+` / `+g(O(t).total)+` 条`,1),O(t).items.length<O(t).total?(h(),e(d,{key:0,size:`small`,loading:O(t).loading,onClick:e=>A(t)},{default:C(()=>[...a[2]||=[o(` 加载更多 `,-1)]]),_:1},8,[`loading`,`onClick`])):b(``,!0)])])]),_:1}),n(l,{label:`Session`,width:`140`},{default:C(({row:t})=>[t.session_id?(h(),i(`span`,{key:0,class:`session-id`,title:`${t.session_id}(点击复制)`,onClick:c(e=>s(m)(t.session_id),[`stop`])},g(s(H)(t.session_id)),9,Me)):(h(),e(u,{key:1,size:`small`,type:`info`,title:`未携带会话标识的请求(NULL / 空串 session_id)`},{default:C(()=>[...a[3]||=[o(` 无 Session `,-1)]]),_:1}))]),_:1}),n(l,{label:`请求数`,width:`80`,align:`center`},{default:C(({row:e})=>[o(g(s(z)(e.calls)),1)]),_:1}),n(l,{label:`模型`,"min-width":`150`},{default:C(({row:e})=>[x(`span`,{title:e.models||``},g(s(V)(e.models)),9,Ne)]),_:1}),n(l,{label:`客户端`,"min-width":`140`},{default:C(({row:e})=>[x(`span`,{title:e.clients||``},g(s(R)(e.clients)),9,Pe)]),_:1}),n(l,{label:`输入`,width:`105`,align:`center`},{default:C(({row:e})=>[o(g(s(z)(e.input_tokens)),1)]),_:1}),n(l,{label:`输出`,width:`105`,align:`center`},{default:C(({row:e})=>[o(g(s(z)(e.output_tokens)),1)]),_:1}),n(l,{label:`缓存读取`,width:`120`,align:`center`},{default:C(({row:e})=>[o(g(s(z)(e.cache_read_tokens)),1)]),_:1}),n(l,{label:`首次请求`,width:`165`},{default:C(({row:e})=>[o(g(s(W)(e.first_time)),1)]),_:1}),n(l,{label:`最后请求`,width:`165`},{default:C(({row:e})=>[o(g(s(W)(e.last_time)),1)]),_:1})]),_:1},8,[`data`])),[[E,r.loading]]):(h(),e(_,{key:1,description:`当前筛选下没有日志`}))])}}}),[[`__scopeId`,`data-v-2ff0b8c0`]]);u(),T(),S(),d();var Le={class:`logs-page`},Re={class:`filter-bar`},ze={class:`table-wrap`},Be=[`onClick`],Ve={key:1},He=[`title`,`onClick`],Ue={key:1},We=[`title`,`onClick`],Ge={key:1},Ke={class:`pagination-bar`},qe=j(r({__name:`LogsView`,setup(t){let r=M(),{toast:c}=F(),{copyWithToast:u}=P(),{loadError:d,run:_}=N(),{rangeKey:S,dateRange:T,setRange:O,onRangeChange:j}=ne(()=>$()),L=l(`2xx`),R=l(``),B=l(``),V=l(``),U=l(`session`),G=l([]),se=l([]),ce=l(null),K=l(0),le=l(0),q=l(1),J=l(20),Y=l(!1),ue=l(null),de=e=>{ue.value?.open(e)},fe=a(()=>{let e=new Set;for(let t of r.suppliers)for(let n of t.models)e.add(n.modelName);for(let t of G.value)t.model&&e.add(t.model);return[...e].sort()}),X=l([]),pe=a(()=>{let e=new Set(X.value);for(let t of G.value)t.client&&e.add(t.client);return[...e].sort()}),me=async()=>{try{let e=await p.get(`/api/logs/clients`);X.value=e.clients||[]}catch{X.value=[]}},he=e=>{S.value=``,T.value=e||null,$()},ge=()=>{let e={};T.value&&T.value.length===2&&(e.startDate=T.value[0],e.endDate=T.value[1]),L.value&&(e.status=L.value),R.value&&(e.model=R.value),B.value&&(e.client=B.value);let t=V.value.trim();return t&&(e.sessionId=t),e},_e=a(()=>ge()),ve=I(),Z=()=>_(async()=>{let e=ve();Y.value=!0;try{let t={...ge(),page:String(q.value),pageSize:String(J.value)};if(U.value===`session`){let n=new URLSearchParams(t).toString(),r=await p.get(`/api/logs/sessions?`+n);if(!e())return;se.value=r.groups||[],ce.value=r.noSession??null,K.value=r.total||0,le.value=r.rowsTotal||0}else{let n=new URLSearchParams({...t,sort:`time`,order:`desc`}).toString(),r=await p.get(`/api/logs?`+n);if(!e())return;G.value=r.items||[],K.value=r.total||0}}catch(t){if(!e())return;throw t}finally{e()&&(Y.value=!1)}}),ye=e=>{U.value!==e&&(U.value=e,q.value=1,J.value=U.value===`session`?20:50,Z())},Q=l(!1),be=a(()=>U.value===`session`?le.value:K.value),xe=async()=>{if(Q.value||be.value===0)return;let e=U.value===`session`?`(按筛选行数计,含「无 Session」组)`:``;try{await A.confirm(`将永久清理当前筛选条件下的 ${be.value} 条日志${e},清理后不可恢复,请谨慎操作!`,`清理确认`,{confirmButtonText:`确认清理`,cancelButtonText:`取消`,type:`warning`})}catch{return}Q.value=!0;try{let e=new URLSearchParams(ge()).toString(),t=await p.post(`/api/logs/clear?`+e,{});c(`已清理 ${t.deleted??0} 条日志`,`success`),q.value>1&&(q.value=1),Z()}catch(e){c(e.message||`清理失败`,`error`)}finally{Q.value=!1}},$=()=>{q.value=1,me(),Z()},Se=()=>{S.value=`today`,T.value=null,L.value=`2xx`,R.value=``,B.value=``,V.value=``,q.value=1,J.value=U.value===`session`?20:50,O(`today`)};return f(()=>{r.loadProviders().catch(()=>{}),me(),O(`today`)}),(t,r)=>{let a=y(`el-button`),c=y(`el-alert`),l=y(`el-option`),f=y(`el-select`),p=y(`el-date-picker`),_=y(`el-input`),O=y(`el-tooltip`),A=y(`el-button-group`),M=y(`el-card`),N=y(`el-table-column`),P=y(`el-tag`),F=y(`el-table`),I=y(`el-pagination`),ne=ee(`loading`);return h(),i(`div`,Le,[s(d)?(h(),e(c,{key:0,title:s(d),type:`error`,"show-icon":``,closable:!1,class:`mb-16`},{default:C(()=>[n(a,{size:`small`,onClick:Z},{default:C(()=>[...r[10]||=[o(`重试`,-1)]]),_:1})]),_:1},8,[`title`])):b(``,!0),n(M,{shadow:`never`},{default:C(()=>[x(`div`,Re,[n(f,{modelValue:s(S),"onUpdate:modelValue":r[0]||=e=>m(S)?S.value=e:null,placeholder:`时间范围`,clearable:``,style:{width:`114px`},onChange:s(j)},{default:C(()=>[n(l,{label:`今天`,value:`today`}),n(l,{label:`昨天`,value:`yesterday`}),n(l,{label:`前天`,value:`beforeYesterday`}),n(l,{label:`近三天`,value:`last3days`}),n(l,{label:`本周`,value:`week`}),n(l,{label:`本月`,value:`month`})]),_:1},8,[`modelValue`,`onChange`]),n(p,{modelValue:s(T),"onUpdate:modelValue":r[1]||=e=>m(T)?T.value=e:null,type:`daterange`,"value-format":`YYYY-MM-DD`,"range-separator":`至`,"start-placeholder":`开始日期`,"end-placeholder":`结束日期`,style:{width:`240px`},onChange:he},null,8,[`modelValue`]),n(f,{modelValue:L.value,"onUpdate:modelValue":r[2]||=e=>L.value=e,placeholder:`全部状态`,clearable:``,style:{width:`106px`},onChange:$},{default:C(()=>[n(l,{label:`成功 (2xx)`,value:`2xx`}),n(l,{label:`3xx`,value:`3xx`}),n(l,{label:`4xx`,value:`4xx`}),n(l,{label:`5xx`,value:`5xx`}),n(l,{label:`错误 (4xx+)`,value:`err`})]),_:1},8,[`modelValue`]),n(f,{modelValue:R.value,"onUpdate:modelValue":r[3]||=e=>R.value=e,placeholder:`全部模型`,clearable:``,filterable:``,style:{width:`176px`},onChange:$},{default:C(()=>[(h(!0),i(E,null,w(fe.value,t=>(h(),e(l,{key:t,label:t,value:t},null,8,[`label`,`value`]))),128))]),_:1},8,[`modelValue`]),n(f,{modelValue:B.value,"onUpdate:modelValue":r[4]||=e=>B.value=e,placeholder:`全部客户端`,clearable:``,filterable:``,style:{width:`130px`},onChange:$},{default:C(()=>[(h(!0),i(E,null,w(pe.value,t=>(h(),e(l,{key:t,label:t,value:t},null,8,[`label`,`value`]))),128))]),_:1},8,[`modelValue`]),n(_,{modelValue:V.value,"onUpdate:modelValue":r[5]||=e=>V.value=e,class:`session-input`,placeholder:`Session ID(前缀匹配)`,clearable:``,onKeyup:D($,[`enter`])},null,8,[`modelValue`]),n(A,{class:`view-switch push-right`},{default:C(()=>[n(O,{content:`按会话分组`,placement:`top`,"show-after":300},{default:C(()=>[n(a,{type:U.value===`session`?`primary`:`default`,icon:s(te),"aria-label":`按会话分组`,onClick:r[6]||=e=>ye(`session`)},null,8,[`type`,`icon`])]),_:1}),n(O,{content:`列表`,placement:`top`,"show-after":300},{default:C(()=>[n(a,{type:U.value===`list`?`primary`:`default`,icon:s(k),"aria-label":`列表视图`,onClick:r[7]||=e=>ye(`list`)},null,8,[`type`,`icon`])]),_:1})]),_:1}),n(a,{type:`primary`,onClick:$},{default:C(()=>[...r[11]||=[o(`搜索`,-1)]]),_:1}),n(a,{onClick:Se},{default:C(()=>[...r[12]||=[o(`重置`,-1)]]),_:1})])]),_:1}),n(M,{shadow:`never`,class:`mt-16 table-card`},{default:C(()=>[x(`div`,ze,[U.value===`list`?v((h(),e(F,{key:0,data:G.value,stripe:``,height:`100%`},{default:C(()=>[n(N,{prop:`id`,label:`ID`,"min-width":`80`},{default:C(({row:e})=>[e.id==null?(h(),i(`span`,Ve,`-`)):(h(),i(`span`,{key:0,class:`request-id`,title:`点击复制(日志 id 同时是响应头 x-request-id,可用于关联控制台日志与检索)`,onClick:t=>s(u)(String(e.id))},g(e.id),9,Be))]),_:1}),n(N,{prop:`time`,label:`时间`,width:`180`},{default:C(({row:e})=>[o(g(s(W)(e.time)),1)]),_:1}),n(N,{prop:`model`,label:`模型`,"min-width":`180`}),n(N,{label:`客户端`,"min-width":`150`},{default:C(({row:e})=>[e.client||e.user_agent?(h(),i(`span`,{key:0,class:`request-id`,title:s(re)(e),onClick:t=>s(u)(e.user_agent||e.client)},g(s(oe)(e)),9,He)):(h(),i(`span`,Ue,`-`))]),_:1}),n(N,{label:`Session`,width:`140`},{default:C(({row:e})=>[e.session_id?(h(),i(`span`,{key:0,class:`request-id`,title:`${e.session_id}(点击复制)`,onClick:t=>s(u)(e.session_id)},g(s(H)(e.session_id)),9,We)):(h(),i(`span`,Ge,`-`))]),_:1}),n(N,{label:`输入`,"min-width":`110`,align:`center`},{default:C(({row:e})=>[o(g(s(z)(e.input_tokens??0)),1)]),_:1}),n(N,{label:`输出`,"min-width":`110`,align:`center`},{default:C(({row:e})=>[o(g(s(z)(e.output_tokens??0)),1)]),_:1}),n(N,{label:`缓存读取`,"min-width":`90`,align:`center`},{default:C(({row:e})=>[o(g(s(z)(e.cache_read_tokens??0)),1)]),_:1}),n(N,{label:`缓存命中率`,"min-width":`105`,align:`center`},{default:C(({row:e})=>[x(`span`,null,g(s(ie)(e)),1)]),_:1}),n(N,{label:`请求耗时`,"min-width":`90`,align:`center`},{default:C(({row:e})=>[o(g(s(ae)(e.duration)),1)]),_:1}),n(N,{prop:`status`,label:`状态`,width:`80`,align:`center`},{default:C(({row:e})=>[n(P,{size:`small`,type:e.status>=400?`danger`:e.status>=300?`warning`:`success`},{default:C(()=>[o(g(e.status),1)]),_:2},1032,[`type`])]),_:1}),n(N,{label:`详情`,width:`70`,align:`center`},{default:C(({row:e})=>[n(a,{link:``,type:`primary`,onClick:t=>de(e)},{default:C(()=>[...r[13]||=[o(`查看`,-1)]]),_:1},8,[`onClick`])]),_:1})]),_:1},8,[`data`])),[[ne,Y.value]]):b(``,!0),U.value===`session`?(h(),e(Ie,{key:1,groups:se.value,"no-session":ce.value,loading:Y.value,"filter-params":_e.value,onOpenDetail:de},null,8,[`groups`,`no-session`,`loading`,`filter-params`])):b(``,!0)]),x(`div`,Ke,[n(a,{type:`danger`,plain:``,size:`small`,loading:Q.value,disabled:be.value===0,onClick:xe},{default:C(()=>[...r[14]||=[o(`清理已筛选日志`,-1)]]),_:1},8,[`loading`,`disabled`]),n(I,{class:`push-right`,"current-page":q.value,"onUpdate:currentPage":r[8]||=e=>q.value=e,"page-size":J.value,"onUpdate:pageSize":r[9]||=e=>J.value=e,total:K.value,"page-sizes":[20,50,100,200],layout:`total, sizes, prev, pager, next`,onCurrentChange:Z,onSizeChange:Z},null,8,[`current-page`,`page-size`,`total`])])]),_:1}),n(Te,{ref_key:`logDetailRef`,ref:ue},null,512)])}}}),[[`__scopeId`,`data-v-9b1602a9`]]);export{qe as default};
@@ -1,2 +0,0 @@
1
- import{A as e,F as t,I as n,M as r,O as i,P as a,Pt as o,Q as s,Tt as c,V as l,Wt as u,Z as d,a as f,at as ee,et as p,fn as m,ht as h,it as g,j as _,k as v,ln as te,mt as y,nt as b,sn as ne,vt as x,w as S}from"./router-CHObBy9_.js";import{t as C}from"./index-CREDEMKs.js";import{n as w,t as re}from"./useCopyToast-pgRyL4NF.js";import{t as ie}from"./useToast-CmSnOJzB.js";import{p as T,s as E,u as ae}from"./format-Z1cpFfkW.js";l(),x(),u();var oe={class:`service-status-page`},se={class:`flex-between`},ce={class:`flex-gap-8`},D={class:`flex-gap-8`},O={class:`gantt-wrap`},k={key:0,class:`gantt`},le={class:`gantt-row gantt-head`},ue={class:`col-cells`},de=[`title`],fe={class:`cell-head-date`},pe={class:`col-name`},me=[`title`,`onClick`],he=[`title`],ge={class:`col-cells`},A=[`title`],j={key:1,class:`gantt-empty`},M=36e5,N=24,P=`#909399`,F=C(n({__name:`ServiceStatusView`,setup(n){let{toast:l}=ie(),{copyWithToast:u}=re(),{loadError:x,run:C}=w(`延迟数据加载失败,请重试`),F=c([]),I=c(!0),L=c(!1),R=c(null),z=c(!1),B=c(!1),V,H,U=c(G()),W=c(new Map);function G(){let e=new Date,t=new Date(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours()).getTime();return Array.from({length:N},(e,n)=>t-(23-n)*M)}let K=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?`-`:`${t.getFullYear()}-${T(t.getMonth()+1)}-${T(t.getDate())} ${T(t.getHours())}:00`},_e=i(()=>U.value.map(e=>{let t=new Date(e),n=T(t.getHours());return{start:e,dateLabel:`${T(t.getMonth()+1)}-${T(t.getDate())}`,hourLabel:n,fullLabel:`${K(e)} - ${n}:59`}})),ve=[103,194,58],q=[230,162,60],ye=[245,108,108],be=i(()=>{let e=[];for(let t of W.value.values())for(let n of t.values())n.avgLatencyMs!==null&&e.push(n.avgLatencyMs);if(e.length===0)return{min:0,max:0};let t=e[0],n=e[0];for(let r of e)r<t&&(t=r),r>n&&(n=r);return{min:t,max:n}}),J=e=>{let{min:t,max:n}=be.value,r=n===t?0:(e-t)/(n-t),[i,a]=r<=.5?[ve,q]:[q,ye],o=r<=.5?r*2:(r-.5)*2,s=i.map((e,t)=>Math.round(e+(a[t]-e)*o));return`rgba(${String(s[0])}, ${String(s[1])}, ${String(s[2])}, 0.9)`},Y=(e,t)=>{let n=`${K(t)} - ${T(new Date(t+M).getHours())}:00`;return e===void 0||e.total===0?`${n}\n无探测数据`:`${n}\n平均延迟 ${E(e.avgLatencyMs)}\n成功 ${String(e.success)} / 失败 ${String(e.failed)}`},X=i(()=>Se.value.map(e=>{let t=W.value.get(e.model),n=U.value.map(e=>{let n=t?.get(e);return n!==void 0&&n.failed>0?{start:e,className:`cell--down`,style:{backgroundColor:P},title:Y(n,e)}:n===void 0||n.avgLatencyMs===null?{start:e,className:`cell--empty`,style:{},title:Y(n,e)}:{start:e,className:``,style:{backgroundColor:J(n.avgLatencyMs)},title:Y(n,e)}});return{model:e.model,avg24h:e.avg24h,statusTitle:[e.avg24h===null?`最近 24 小时无成功探测记录`:`最近 24 小时成功探测平均延迟 ${E(e.avg24h)}`,e.lastLatencyMs==null?`最近一次探测:无成功延迟记录`:`最近一次探测延迟 ${E(e.lastLatencyMs)}`].join(`
2
- `),cells:n}})),xe=(e,t)=>e===null&&t===null?0:e===null?1:t===null?-1:e-t,Se=i(()=>[...F.value].sort((e,t)=>{let n=e.lastOk===!1;if(n!==(t.lastOk===!1))return n?1:-1;let r=xe(e.avg24h,t.avg24h);return r===0?e.model.localeCompare(t.model):r})),Z=async e=>{if(e.length===0){W.value=new Map;return}let t=await Promise.all(e.map(async e=>{try{let t=await f.get(`/api/latency/trend?model=${encodeURIComponent(e)}&granularity=hour`);return[e,new Map((t.buckets??[]).map(e=>[e.bucketStart,e]))]}catch{return[e,new Map]}}));W.value=new Map(t)},Q=async()=>{let e=await f.get(`/api/latency/history`);return F.value=e.models??[],L.value=e.running,R.value=e.lastRunAt,e},$=()=>C(async()=>{try{await Q(),U.value=G(),await Z(F.value.map(e=>e.model))}finally{I.value=!1}}),Ce=()=>$(),we=()=>{B.value?V=window.setInterval(()=>void $(),5e3):V!==void 0&&(window.clearInterval(V),V=void 0)},Te=async()=>{z.value=!0;try{await f.post(`/api/latency/run`)}catch(e){l(e.message,`error`),z.value=!1;return}H=window.setInterval(async()=>{try{(await Q()).running||(window.clearInterval(H),H=void 0,z.value=!1,U.value=G(),await Z(F.value.map(e=>e.model)))}catch{}},2e3)};return d(()=>{$()}),s(()=>{V!==void 0&&window.clearInterval(V),H!==void 0&&window.clearInterval(H)}),(n,i)=>{let s=g(`el-button`),c=g(`el-alert`),l=g(`el-tag`),d=g(`el-checkbox`),f=g(`el-empty`),C=g(`el-card`),w=ee(`loading`);return p(),r(`div`,oe,[o(x)?(p(),e(c,{key:0,title:o(x),type:`error`,"show-icon":``,closable:!1,class:`mb-16`},{default:y(()=>[t(s,{size:`small`,onClick:Ce},{default:y(()=>[...i[1]||=[a(`重试`,-1)]]),_:1})]),_:1},8,[`title`])):_(``,!0),t(C,{shadow:`never`,class:`main-card`},{header:y(()=>[v(`div`,se,[v(`div`,ce,[i[3]||=v(`span`,{class:`fw-600`},`服务状态`,-1),L.value?(p(),e(l,{key:0,type:`warning`,size:`small`},{default:y(()=>[...i[2]||=[a(`测试进行中`,-1)]]),_:1})):R.value?(p(),e(l,{key:1,type:`info`,size:`small`},{default:y(()=>[a(` 上次测试 `+m(o(ae)(R.value)),1)]),_:1})):_(``,!0)]),v(`div`,D,[t(d,{modelValue:B.value,"onUpdate:modelValue":i[0]||=e=>B.value=e,onChange:we},{default:y(()=>[...i[4]||=[a(` 自动刷新(5s) `,-1)]]),_:1},8,[`modelValue`]),t(s,{loading:z.value,onClick:Te},{default:y(()=>[...i[5]||=[a(` 延迟测试 `,-1)]]),_:1},8,[`loading`])])])]),default:y(()=>[i[9]||=v(`div`,{class:`legend`},[v(`span`,{class:`legend-text`},`延迟`),v(`span`,{class:`legend-text`},`低`),v(`span`,{class:`legend-gradient`}),v(`span`,{class:`legend-text`},`高`),v(`span`,{class:`legend-swatch legend-swatch--down`}),v(`span`,{class:`legend-text`},`该小时有失败探测`),v(`span`,{class:`legend-swatch legend-swatch--empty`}),v(`span`,{class:`legend-text`},`无探测数据`)],-1),h((p(),r(`div`,O,[i[8]||=v(`div`,{class:`muted-sm hint`},` 右侧 24 格为最近 24 小时(每格 1 小时,本地整点对齐,最右格为当前小时)。 格子底色为当小时成功探测的平均延迟,全表统一色标(本期最快→最慢 绿→红); 当小时存在失败探测即视为不可用,显示灰色。 行按 24h 平均延迟升序,最近一次探测失败的模型沉底。 `,-1),X.value.length>0?(p(),r(`div`,k,[v(`div`,le,[i[6]||=v(`div`,{class:`col-name`},`模型名称`,-1),i[7]||=v(`div`,{class:`col-status`},`状态`,-1),v(`div`,ue,[(p(!0),r(S,null,b(_e.value,e=>(p(),r(`div`,{key:e.start,class:`cell cell--head`,title:e.fullLabel},[v(`span`,fe,m(e.dateLabel),1),v(`span`,null,m(e.hourLabel),1)],8,de))),128))])]),(p(!0),r(S,null,b(X.value,e=>(p(),r(`div`,{key:e.model,class:`gantt-row`},[v(`div`,pe,[v(`span`,{class:`copy-text model-name`,title:e.model,onClick:t=>o(u)(e.model)},m(e.model),9,me)]),v(`div`,{class:`col-status`,title:e.statusTitle},m(o(E)(e.avg24h)),9,he),v(`div`,ge,[(p(!0),r(S,null,b(e.cells,e=>(p(),r(`div`,{key:e.start,class:ne([`cell`,e.className]),style:te(e.style),title:e.title},null,14,A))),128))])]))),128))])):(p(),r(`div`,j,[t(f,{description:`暂无延迟数据,点击「延迟测试」开始`,"image-size":80})]))])),[[w,I.value]])]),_:1})])}}}),[[`__scopeId`,`data-v-95ae284d`]]);export{F as default};
@@ -1 +0,0 @@
1
- import{A as e,F as t,I as n,M as r,O as i,P as a,Pt as o,Q as s,Tt as c,V as l,Wt as u,Z as d,a as f,at as p,et as m,fn as h,ht as g,it as _,j as v,k as y,mt as b,n as x,nt as S,vt as C,w}from"./router-CHObBy9_.js";import{n as T,t as E}from"./index-CREDEMKs.js";import{n as D,t as O}from"./useManagerApi-DIMNWza9.js";import{t as k}from"./config-BU1w8kdn.js";import{n as A,t as j}from"./useCopyToast-pgRyL4NF.js";import{t as M}from"./useToast-CmSnOJzB.js";import{n as N,t as P}from"./version-DegxwpkG.js";l(),u(),C();var F={class:`flex-between`},I={class:`muted-sm mb-8`},L={class:`switch-row`},R={class:`switch-info`},z={class:`switch-title`},B={class:`switch-row`},V={class:`switch-info`},H={class:`switch-title`},U={class:`switch-row`},W={class:`switch-info`},G={class:`switch-title`},K=E(n({__name:`HarnessSwitches`,setup(n){let{toast:i}=M(),o=c(!0),s=c(!1),l=c(null),u=c(null),f=c(null),x=c(null),S=c(`success`),C=async e=>{e||(l.value?s.value=!0:o.value=!0);try{l.value=await O.harness(),u.value=null}catch(t){e||(u.value=t.message)}finally{e||(o.value=!1,s.value=!1)}};d(()=>C(!1));let E={claudeCode:{label:`Claude Code`,file:`~/.claude/settings.json`,toggle:O.setClaudeCode},codex:{label:`Codex CLI`,file:`~/.codex/config.toml`,toggle:O.setCodex},dsh:{label:`DeepSeek Harness`,file:`~/.dsh/settings.yaml`,toggle:O.setDsh}},D=async(e,t)=>{if(!l.value||f.value)return;let n=E[e],r=t?`确定开启 ${n.label} 代理?将改写 ${n.file}(开启前自动备份,关闭时从备份还原)。`:`确定关闭 ${n.label} 代理?将从备份还原 ${n.file}(无备份时移除代理相关配置)。`;try{await T.confirm(r,t?`开启确认`:`关闭确认`,{confirmButtonText:t?`开启`:`关闭`,cancelButtonText:`取消`,type:`warning`})}catch{return}f.value=e;try{let e=await n.toggle(t);x.value=e.note??null,S.value=t?`success`:`info`,i(t?`已开启代理`:`已关闭代理`,`success`)}catch(e){i(e.message||`操作失败`,`error`)}finally{f.value=null,await C(!0)}};return(n,i)=>{let c=_(`el-button`),d=_(`el-alert`),T=_(`el-tag`),E=_(`el-switch`),O=_(`el-divider`),k=_(`el-empty`),A=_(`el-card`),j=p(`loading`);return g((m(),e(A,{shadow:`never`},{header:b(()=>[y(`div`,F,[i[7]||=y(`span`,{class:`fw-600`},`代理开关`,-1),t(c,{loading:s.value,onClick:i[0]||=e=>C(!1)},{default:b(()=>[...i[6]||=[a(`刷新`,-1)]]),_:1},8,[`loading`])])]),default:b(()=>[l.value?(m(),r(w,{key:0},[y(`div`,I,` 将本机 CLI 工具的流量一键指向本机网关(`+h(l.value.gatewayBase)+`)。 开启前自动备份原配置为 *.ellm-bak(保留最早的原始备份),关闭时从备份还原。 `,1),x.value?(m(),e(d,{key:0,title:x.value,type:S.value,"show-icon":``,class:`mb-8`,onClose:i[1]||=e=>x.value=null},null,8,[`title`,`type`])):v(``,!0),y(`div`,L,[y(`div`,R,[y(`div`,z,[i[8]||=a(` Claude Code `,-1),t(T,{type:l.value.claudeCode?`success`:`info`,size:`small`,"disable-transitions":``},{default:b(()=>[a(h(l.value.claudeCode?`已开启`:`未开启`),1)]),_:1},8,[`type`])]),i[9]||=y(`div`,{class:`switch-desc`},[a(` 写入 `),y(`code`,null,`~/.claude/settings.json`),a(` 的 env.ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN, 鉴权取网关配置的 masterKey(未设置将开启失败);其余字段原样保留,重启 Claude Code 会话后生效。 `)],-1)]),t(E,{"model-value":l.value.claudeCode,loading:f.value===`claudeCode`,onChange:i[2]||=e=>D(`claudeCode`,!!e)},null,8,[`model-value`,`loading`])]),t(O,{class:`switch-divider`}),y(`div`,B,[y(`div`,V,[y(`div`,H,[i[10]||=a(` Codex CLI `,-1),t(T,{type:l.value.codex?`success`:`info`,size:`small`,"disable-transitions":``},{default:b(()=>[a(h(l.value.codex?`已开启`:`未开启`),1)]),_:1},8,[`type`])]),i[11]||=y(`div`,{class:`switch-desc`},[a(` 写入 `),y(`code`,null,`~/.codex/config.toml`),a(` 的 model_provider 与 [model_providers.ellm-proxy] 段 (保留用户注释与排版);开启后需按提示设置环境变量 ELLM_PROXY_API_KEY 供 Codex 鉴权。 `)],-1)]),t(E,{"model-value":l.value.codex,loading:f.value===`codex`,onChange:i[3]||=e=>D(`codex`,!!e)},null,8,[`model-value`,`loading`])]),t(O,{class:`switch-divider`}),y(`div`,U,[y(`div`,W,[y(`div`,G,[i[12]||=a(` DeepSeek Harness `,-1),t(T,{type:l.value.dsh?`success`:`info`,size:`small`,"disable-transitions":``},{default:b(()=>[a(h(l.value.dsh?`已开启`:`未开启`),1)]),_:1},8,[`type`])]),i[13]||=y(`div`,{class:`switch-desc`},[a(` 写入 `),y(`code`,null,`~/.dsh/settings.yaml`),a(` 的 llm-deepseek.baseURL 与 `),y(`code`,null,`~/.dsh/.credentials.yaml`),a(` 的 DEEPSEEK_API_KEY(取网关 masterKey,未设置则写占位值);模型请在 dsh 内选择与网关部署名一致的模型。 dsh 为 developer preview,配置格式可能随版本变化。 `)],-1)]),t(E,{"model-value":l.value.dsh,loading:f.value===`dsh`,onChange:i[4]||=e=>D(`dsh`,!!e)},null,8,[`model-value`,`loading`])])],64)):(m(),e(k,{key:1,description:u.value||`暂无开关状态`},{default:b(()=>[t(c,{type:`primary`,onClick:i[5]||=e=>C(!1)},{default:b(()=>[...i[14]||=[a(`重试`,-1)]]),_:1})]),_:1},8,[`description`]))]),_:1})),[[j,o.value]])}}}),[[`__scopeId`,`data-v-fb084a91`]]);l(),u(),C();var q={class:`service-settings`},J={class:`flex-between`},Y={key:0,class:`switch-row`},ee={class:`switch-info`},te={class:`switch-title`},X={key:0,class:`switch-row`},Z={class:`switch-info`},ne={class:`switch-title`},re={class:`switch-desc`},ie={key:0,class:`version-block`},ae={class:`version-row`},oe={class:`muted-sm`},se={key:0,class:`muted-sm`},ce={key:1,class:`muted-sm`},le={class:`muted-sm`},ue={class:`version-actions`},Q=E(n({__name:`ServiceUpdateSettings`,setup(n){let{toast:o}=M(),l=c(!0),u=c(!1),f=c(null),x=c(null),S=c(null),C=c(null),E=c(null),k=c(!1),A=c(!1),j=c(null),F=null;s(()=>F?.abort());let I=async e=>{if(!e){if(u.value)return;u.value=!0}try{let[e,t]=await Promise.allSettled([O.autostart(),O.update()]);f.value=e.status===`fulfilled`?e.value:null,x.value=e.status===`rejected`?e.reason?.message:null,S.value=t.status===`fulfilled`?t.value:null,C.value=t.status===`rejected`?t.reason?.message:null}finally{l.value=!1,u.value=!1}};d(()=>I(!1));let L=e=>e?new Date(e).toLocaleString():``,R=i(()=>S.value?.lastCheck?.currentVersion??null),z=i(()=>P(R.value)),B=i(()=>S.value?.lastCheck?.latestVersion??null),V=i(()=>S.value?.lastCheck?.hasUpdate===!0),H=i(()=>{let e=S.value?.lastCheck?.checkedAt;return e?new Date(e).toLocaleString():null}),U=i(()=>{let e=S.value?.lastApply;if(!e)return null;let t=L(e.appliedAt);return`${e.fromVersion} → ${e.toVersion}${t?`(${t})`:``}`}),W=async e=>{if(!f.value||E.value)return;let t=e?`确定开启开机自启?将注册登录触发的自启项(登录时自动恢复服务)。`:`确定关闭开机自启?将移除自启项,且此后首次启动不再自动注册。`;try{await T.confirm(t,e?`开启确认`:`关闭确认`,{confirmButtonText:e?`开启`:`关闭`,cancelButtonText:`取消`,type:`warning`})}catch{return}E.value=`autostart`;try{let t=await O.setAutostart(e);t.note?o(t.note,`success`):o(e?`开机自启已开启`:`开机自启已关闭`,`success`)}catch(e){o(e.message||`操作失败`,`error`)}finally{E.value=null,await I(!0)}},G=async e=>{if(!S.value||E.value)return;let t=e?`确定开启自动更新?将每小时检查 npm 源,发现新版本自动安装并重启服务。`:`确定关闭自动更新?不再自动检查(手动检查更新不受影响)。`;try{await T.confirm(t,e?`开启确认`:`关闭确认`,{confirmButtonText:e?`开启`:`关闭`,cancelButtonText:`取消`,type:`warning`})}catch{return}E.value=`updateEnabled`;try{let t=await O.setUpdateEnabled(e);t.note&&o(t.note,`success`)}catch(e){o(e.message||`操作失败`,`error`)}finally{E.value=null,await I(!0)}},K=async()=>{k.value=!0;try{let e=await O.checkUpdate();j.value=e.hasUpdate?`发现新版本 ${e.latestVersion}(当前 ${e.currentVersion}):点击「立即更新」即可安装(服务自动重启,期间管理台短暂不可访问)`:`已是最新版本 ${e.currentVersion}(检查于 ${L(e.checkedAt)})`,await I(!0)}catch(e){o(e.message||`检查更新失败`,`error`)}finally{k.value=!1}},Q=async()=>{try{await T.confirm(`确定更新到 ${B.value}?服务会自动重启并在启动时安装新版本:重启期间管理台短暂不可访问(预计 1~3 分钟),更新完成后自动恢复。`,`更新确认`,{confirmButtonText:`立即更新`,cancelButtonText:`取消`,type:`warning`})}catch{return}A.value=!0;let e=new AbortController;F=e;try{let t=await O.update(),n=await O.applyUpdate();if(!n.updated){j.value=`已是最新版本 ${n.toVersion}`;return}j.value=`正在重启服务并安装 ${n.toVersion}(预计 1~3 分钟):重启期间管理台短暂不可访问,完成后这里会自动显示结果。`;let r=await D({targetVersion:n.toVersion,sinceAppliedAt:t.lastApply?.appliedAt??null,signal:e.signal});if(e.signal.aborted)return;r&&!r.error?(o(`已更新到 ${r.toVersion}`,`success`),j.value=`已更新 ${r.fromVersion} → ${r.toVersion},服务已在新版本上运行。`):r?.error?(o(`更新失败:${r.error}`,`error`),j.value=N(r.error)):j.value=`更新仍在进行(安装耗时较长):稍后刷新页面查看最新状态。`}catch(e){o(e.message||`更新失败`,`error`)}finally{A.value=!1,F===e&&(F=null),e.signal.aborted||await I(!0)}};return(n,i)=>{let o=_(`el-button`),s=_(`el-tag`),c=_(`el-switch`),d=_(`el-empty`),T=_(`el-card`),D=_(`el-link`),O=_(`el-alert`),M=p(`loading`);return g((m(),r(`div`,q,[t(T,{shadow:`never`,class:`mb-16`},{header:b(()=>[y(`div`,J,[i[7]||=y(`span`,{class:`fw-600`},`开机自启`,-1),t(o,{loading:u.value,onClick:i[0]||=e=>I(!1)},{default:b(()=>[...i[6]||=[a(`刷新`,-1)]]),_:1},8,[`loading`])])]),default:b(()=>[f.value?(m(),r(`div`,Y,[y(`div`,ee,[y(`div`,te,[i[8]||=a(` 登录时自动启动服务 `,-1),t(s,{type:f.value.enabled?`success`:`info`,size:`small`,"disable-transitions":``},{default:b(()=>[a(h(f.value.enabled?`已开启`:`未开启`),1)]),_:1},8,[`type`])]),i[9]||=y(`div`,{class:`switch-desc`},[a(` 登录操作系统时自动启动服务(无需管理员权限)。 关闭后首次启动 `),y(`code`,null,`ezllm`),a(` 也不会再自动注册,重新开启即可解除。 `)],-1)]),t(c,{"model-value":f.value.enabled,loading:E.value===`autostart`,onChange:i[1]||=e=>W(!!e)},null,8,[`model-value`,`loading`])])):(m(),e(d,{key:1,description:x.value||`暂无自启状态`},{default:b(()=>[t(o,{type:`primary`,onClick:i[2]||=e=>I(!1)},{default:b(()=>[...i[10]||=[a(`重试`,-1)]]),_:1})]),_:1},8,[`description`]))]),_:1}),t(T,{shadow:`never`,class:`mb-16`},{header:b(()=>[...i[11]||=[y(`div`,{class:`flex-between`},[y(`span`,{class:`fw-600`},`自动更新`)],-1)]]),default:b(()=>[S.value?(m(),r(`div`,X,[y(`div`,Z,[y(`div`,ne,[i[12]||=a(` 自动检查并安装新版本 `,-1),t(s,{type:S.value.enabled?`success`:`info`,size:`small`,"disable-transitions":``},{default:b(()=>[a(h(S.value.enabled?`已开启`:`未开启`),1)]),_:1},8,[`type`])]),y(`div`,re,[S.value.supported?(m(),r(w,{key:1},[a(` 每小时检查 npm 源,发现新版本自动重启服务并在启动时安装(更新期间服务短暂中断); 关闭后仍可在下方手动检查与更新。 `)],64)):(m(),r(w,{key:0},[a(` 当前为源码运行模式,更新功能不可用(仅 npm 全局安装的包支持自动更新)。 `)],64))])]),S.value.supported?(m(),e(c,{key:0,"model-value":S.value.enabled,loading:E.value===`updateEnabled`,onChange:i[3]||=e=>G(!!e)},null,8,[`model-value`,`loading`])):v(``,!0)])):(m(),e(d,{key:1,description:C.value||`暂无更新状态`},{default:b(()=>[t(o,{type:`primary`,onClick:i[4]||=e=>I(!1)},{default:b(()=>[...i[13]||=[a(`重试`,-1)]]),_:1})]),_:1},8,[`description`]))]),_:1}),t(T,{shadow:`never`},{header:b(()=>[...i[14]||=[y(`div`,{class:`flex-between`},[y(`span`,{class:`fw-600`},`版本信息`)],-1)]]),default:b(()=>[S.value?(m(),r(`div`,ie,[y(`div`,ae,[i[18]||=y(`span`,{class:`version-label`},`当前版本`,-1),t(s,{size:`small`},{default:b(()=>[a(h(R.value||`未知`),1)]),_:1}),z.value?(m(),e(s,{key:0,type:`warning`,size:`small`,"disable-transitions":``},{default:b(()=>[...i[15]||=[a(`本地构建`,-1)]]),_:1})):v(``,!0),B.value?(m(),r(w,{key:1},[i[17]||=y(`span`,{class:`version-label`},`最新版本`,-1),t(s,{type:V.value?`warning`:`success`,size:`small`,"disable-transitions":``},{default:b(()=>[a(h(B.value),1)]),_:1},8,[`type`]),V.value?(m(),e(s,{key:0,type:`warning`,size:`small`,"disable-transitions":``},{default:b(()=>[...i[16]||=[a(`发现新版本`,-1)]]),_:1})):v(``,!0)],64)):v(``,!0)]),y(`div`,oe,[a(` 上次检查:`+h(H.value||`尚未检查`)+` `,1),S.value.updating?(m(),r(w,{key:0},[a(` · 更新执行中...`)],64)):v(``,!0)]),S.value.supported?v(``,!0):(m(),r(`div`,se,`源码运行模式:手动检查与更新不可用。`)),U.value?(m(),r(`div`,ce,`上次更新:`+h(U.value),1)):v(``,!0),y(`div`,le,[i[20]||=a(` npm 包主页:`,-1),t(D,{type:`primary`,href:`https://www.npmjs.com/package/ezllm`,target:`_blank`},{default:b(()=>[...i[19]||=[a(`npmjs.com/package/ezllm`,-1)]]),_:1})]),y(`div`,ue,[t(o,{loading:k.value,disabled:!S.value.supported||S.value.updating,onClick:K},{default:b(()=>[a(h(k.value?`检查中...`:`检查更新`),1)]),_:1},8,[`loading`,`disabled`]),V.value&&S.value.supported?(m(),e(o,{key:0,type:`primary`,loading:A.value,disabled:S.value.updating,onClick:Q},{default:b(()=>[a(h(A.value?`更新中...`:`立即更新到 ${B.value}`),1)]),_:1},8,[`loading`,`disabled`])):v(``,!0)]),j.value?(m(),e(O,{key:2,title:j.value,type:`info`,"show-icon":``,class:`mt-8`,onClose:i[5]||=e=>j.value=null},null,8,[`title`])):v(``,!0)])):(m(),e(d,{key:1,description:`更新状态不可用`}))]),_:1})])),[[M,l.value]])}}}),[[`__scopeId`,`data-v-af77e8e0`]]);l(),C(),u();var de={class:`flex-col-gap`},fe={class:`flex-between`},$={class:`muted-sm`},pe={class:`login-row`},me={class:`muted-sm`},he={class:`flex-between`},ge={class:`monitor-row`},_e={class:`save-bar`},ve=E(n({__name:`SettingsView`,setup(n){let{toast:s}=M(),{copyWithToast:l}=j(),u=k(),C=c(`basic`),T=c(!0),E=c(!1),D=c(``),O=async()=>{D.value&&await l(D.value)},N=c(29770),P=c(null),F=c(!0),I=c(``),L=c(``),R=i(()=>D.value.trim()!==``||I.value!==``&&L.value!==``),z=c(!1),B=c(60),V=[{label:`10分钟`,value:10},{label:`30分钟`,value:30},{label:`1小时`,value:60},{label:`2小时`,value:120},{label:`5小时`,value:300},{label:`8小时`,value:480},{label:`12小时`,value:720},{label:`24小时`,value:1440}],{loadError:H,run:U}=A(`设置加载失败,请重试`),W=()=>U(async()=>{try{await u.load(),D.value=u.config.masterKey||``,N.value=u.config.port??29770;let e=u.config[`web-ui`]?.[`login-account`];I.value=e?.username||``,L.value=e?.password||``,F.value=u.config.allowLan!==!1;let t=u.config.latencyTest;z.value=t?.enabled===!0,B.value=t?.intervalMinutes??60;try{let e=await f.get(`/api/status`);P.value=e.listenPort}catch{P.value=null}}finally{T.value=!1}}),G=async()=>{if(I.value.trim()!==``||L.value!==``){if(I.value.trim()===``||L.value===``){s(`用户名和密码需同时填写`,`error`);return}if(L.value.length<6){s(`密码至少 6 位`,`error`);return}}E.value=!0;let e=z.value&&u.config.latencyTest?.enabled!==!0;try{let t=await u.update(e=>{e.masterKey=D.value.trim(),e.port=N.value,e.allowLan=F.value,e.latencyTest={enabled:z.value,intervalMinutes:B.value},e[`web-ui`]??={},e[`web-ui`][`login-account`]??={},e[`web-ui`][`login-account`].username=I.value.trim(),e[`web-ui`][`login-account`].password=L.value});await x(!0),s(`设置已保存并生效`,`success`),e&&s(`已开启自动测试:服务将定期直连所有上游发送探测请求,有少量 token 消耗`,`warning`),t.restartHint&&s(t.restartHint,`warning`)}catch(e){s(e.message,`error`)}finally{E.value=!1}};return d(W),(n,i)=>{let s=_(`el-button`),c=_(`el-alert`),l=_(`el-tag`),u=_(`el-input`),d=_(`el-form-item`),f=_(`el-input-number`),x=_(`el-form`),k=_(`el-card`),A=_(`el-switch`),j=_(`el-divider`),M=_(`el-option`),U=_(`el-select`),q=_(`el-tab-pane`),J=_(`el-tabs`),Y=p(`loading`);return m(),e(J,{modelValue:C.value,"onUpdate:modelValue":i[7]||=e=>C.value=e,class:`settings-tabs`},{default:b(()=>[t(q,{label:`基本设置`,name:`basic`},{default:b(()=>[g((m(),r(`div`,de,[o(H)?(m(),e(c,{key:0,title:o(H),type:`error`,"show-icon":``,closable:!1},{default:b(()=>[t(s,{size:`small`,onClick:W},{default:b(()=>[...i[8]||=[a(`重试`,-1)]]),_:1})]),_:1},8,[`title`])):v(``,!0),t(k,{shadow:`never`},{header:b(()=>[y(`div`,fe,[i[10]||=y(`span`,{class:`fw-600`},`网关访问`,-1),t(l,{type:`success`},{default:b(()=>[...i[9]||=[a(`运行中`,-1)]]),_:1})])]),default:b(()=>[t(x,{"label-position":`top`},{default:b(()=>[t(d,{label:`API 密钥 (masterKey)`},{default:b(()=>[t(u,{modelValue:D.value,"onUpdate:modelValue":i[0]||=e=>D.value=e,placeholder:`sk-1234`,clearable:``},{append:b(()=>[t(s,{onClick:O},{default:b(()=>[...i[11]||=[a(`复制`,-1)]]),_:1})]),_:1},8,[`modelValue`]),i[12]||=y(`div`,{class:`muted-sm`},`客户端请求 /v1/* 时的认证密钥(Bearer <masterKey>;留空 = 本地放行)`,-1)]),_:1}),t(d,{label:`监听端口 (port)`},{default:b(()=>[t(f,{modelValue:N.value,"onUpdate:modelValue":i[1]||=e=>N.value=e,min:1,max:65535,step:1,style:{width:`220px`}},null,8,[`modelValue`]),y(`div`,$,[i[14]||=a(` 网关与管理台 API 的监听端口,保存后重启生效 `,-1),P.value===null?v(``,!0):(m(),r(w,{key:0},[i[13]||=a(` ;服务上报的端口 `,-1),y(`b`,null,h(P.value),1)],64))])]),_:1})]),_:1})]),_:1}),t(k,{shadow:`never`},{header:b(()=>[...i[15]||=[y(`span`,{class:`fw-600`},`安全与登录`,-1)]]),default:b(()=>[t(x,{"label-position":`top`},{default:b(()=>[t(d,{label:`管理台登录账号`},{default:b(()=>[y(`div`,pe,[t(u,{modelValue:I.value,"onUpdate:modelValue":i[2]||=e=>I.value=e,placeholder:`用户名`,style:{width:`200px`}},null,8,[`modelValue`]),t(u,{modelValue:L.value,"onUpdate:modelValue":i[3]||=e=>L.value=e,type:`password`,placeholder:`密码(至少 6 位)`,"show-password":``,style:{width:`200px`}},null,8,[`modelValue`])]),i[16]||=y(`div`,{class:`muted-sm`},` 管理台登录凭证;留空 = 免登录直接访问(仅本机使用时推荐)。 修改后立即生效,需用新账号重新登录 `,-1)]),_:1}),t(d,{label:`允许局域网访问 (allowLan)`},{default:b(()=>[t(A,{modelValue:F.value,"onUpdate:modelValue":i[4]||=e=>F.value=e},null,8,[`modelValue`]),y(`div`,me,[i[17]||=a(` 开启 = 绑定全部网卡,局域网内设备可访问;关闭 = 仅本机 127.0.0.1。保存后需重启生效 `,-1),R.value?v(``,!0):(m(),r(w,{key:0},[a(` ;未设置任何凭据(密钥与登录账号皆无)时始终仅绑本机 `)],64))])]),_:1})]),_:1})]),_:1}),t(k,{shadow:`never`},{header:b(()=>[y(`div`,he,[i[18]||=y(`span`,{class:`fw-600`},`模型服务监控`,-1),t(l,{type:z.value?`success`:`info`,size:`small`,"disable-transitions":``},{default:b(()=>[a(h(z.value?`已开启`:`未开启`),1)]),_:1},8,[`type`])])]),default:b(()=>[y(`div`,ge,[i[19]||=y(`div`,{class:`monitor-info`},[y(`div`,{class:`monitor-title`},`自动测试模型服务状态`),y(`div`,{class:`muted-sm`},` 按设定间隔自动直连所有上游模型发送极小探测请求(max_tokens: 1,有少量 token 消耗); 测试结果展示在「服务状态」页面 `)],-1),t(A,{modelValue:z.value,"onUpdate:modelValue":i[5]||=e=>z.value=e},null,8,[`modelValue`])]),z.value?(m(),r(w,{key:0},[t(j,{style:{margin:`12px 0`}}),t(x,{"label-position":`top`},{default:b(()=>[t(d,{label:`测试间隔`,style:{"margin-bottom":`0`}},{default:b(()=>[t(U,{modelValue:B.value,"onUpdate:modelValue":i[6]||=e=>B.value=e,style:{width:`220px`}},{default:b(()=>[(m(),r(w,null,S(V,e=>t(M,{key:e.value,label:e.label,value:e.value},null,8,[`label`,`value`])),64))]),_:1},8,[`modelValue`]),i[20]||=y(`div`,{class:`muted-sm`},`自动测试的执行间隔,保存后即时生效(无需重启)`,-1)]),_:1})]),_:1})],64)):v(``,!0)]),_:1}),y(`div`,_e,[t(s,{type:`primary`,size:`large`,loading:E.value,disabled:E.value||o(H)!==null,onClick:G},{default:b(()=>[a(h(E.value?`保存中...`:`保存设置`),1)]),_:1},8,[`loading`,`disabled`])])])),[[Y,T.value]])]),_:1}),t(q,{label:`代理开关`,name:`harness`,lazy:``},{default:b(()=>[t(K)]),_:1}),t(q,{label:`服务与更新`,name:`service`,lazy:``},{default:b(()=>[t(Q)]),_:1})]),_:1},8,[`modelValue`])}}}),[[`__scopeId`,`data-v-e5f93ad5`]]);export{ve as default};
@@ -1 +0,0 @@
1
- .switch-divider[data-v-fb084a91]{margin:16px 0}.mb-16[data-v-af77e8e0]{margin-bottom:16px}.mt-8[data-v-af77e8e0]{margin-top:8px}.version-row[data-v-af77e8e0]{align-items:center;gap:8px;margin-bottom:8px;display:flex}.version-label[data-v-af77e8e0]{color:var(--el-text-color-secondary);font-size:13px}.version-actions[data-v-af77e8e0]{gap:8px;margin-top:12px;display:flex}.settings-tabs[data-v-e5f93ad5] .el-tabs__content{overflow:visible}.save-bar[data-v-e5f93ad5]{justify-content:center;padding:8px 0;display:flex;position:sticky;bottom:0}.login-row[data-v-e5f93ad5]{flex-wrap:wrap;gap:8px;display:flex}.monitor-row[data-v-e5f93ad5]{justify-content:space-between;align-items:center;gap:24px;display:flex}.monitor-title[data-v-e5f93ad5]{margin-bottom:4px;font-weight:600}
@@ -1 +0,0 @@
1
- var e=e=>String(e).padStart(2,`0`),t=t=>{let n=t=>`${t.getFullYear()}-${e(t.getMonth()+1)}-${e(t.getDate())}`,r=new Date,i=new Date(r),a=r;if(t!==`today`){if(t===`yesterday`)i.setDate(r.getDate()-1),a=i;else if(t===`beforeYesterday`)i.setDate(r.getDate()-2),a=i;else if(t===`last3days`)i.setDate(r.getDate()-2);else if(t===`week`)i.setDate(r.getDate()-(r.getDay()+6)%7);else if(t===`month`)i.setDate(1);else return null}return[n(i),n(a)]},n=e=>{if(e.name)return e.name;if(e.alias)return e.alias;let t=e.apiKey||``;if(!t)return`-`;if(t.length<=8)return t;let n=Math.min(6,Math.floor(t.length/4));return`${t.substring(0,n)}...${t.substring(t.length-n)}`},r=t=>{if(!t)return`-`;let n=new Date(t);return Number.isNaN(n.getTime())?`-`:`${n.getFullYear()}-${e(n.getMonth()+1)}-${e(n.getDate())} ${e(n.getHours())}:${e(n.getMinutes())}:${e(n.getSeconds())}`},i=e=>e?typeof e==`string`?e:JSON.stringify(e,null,2):`-`,a=e=>{if(!e)return`-`;try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}},o=e=>{let t=e??0;return(Number.isFinite(t)?t:0).toLocaleString()},s=({protocol:e,hostname:t,port:n})=>`${e===`https:`?`https:`:`http:`}//${t}${n?`:${n}`:``}`,c=e=>e==null||e<=0?`-`:e>=1e3?(e/1e3).toFixed(2)+`s`:Math.round(e)+`ms`,l=e=>e==null?`-`:e<1e3?`${String(e)}ms`:`${(e/1e3).toFixed(1)}s`,u=e=>{let t=e.input_tokens||0,n=e.cache_read_tokens||0;return t<=0?`-`:(n/t*100).toFixed(1)+`%`},d=(e,t=262144)=>{let n=e??``;return n.length<=t?n:`${n.slice(0,t)}\n\n…(已省略 ${(n.length-t).toLocaleString()} 字符以保持流畅,完整内容请点上方「复制」按钮)`},f=e=>{let t=(e||``).trim();return t?t.length>8?`${t.slice(0,8)}…`:t:`-`},p=e=>e.client||e.user_agent||`-`,m=e=>e.user_agent?`${e.user_agent}(点击复制)`:`${e.client??`-`}(点击复制)`,h=e=>{let t=(e||``).split(`,`).map(e=>e.trim()).filter(Boolean).sort();return t.length===0?`-`:t.length<=2?t.join(`, `):`${t.slice(0,2).join(`, `)} +${t.length-2}`},g=e=>h(e),_=e=>h(e);export{d as _,_ as a,o as c,a as d,g as f,f as g,t as h,m as i,i as l,n as m,u as n,c as o,e as p,p as r,l as s,s as t,r as u};
@@ -1 +0,0 @@
1
- import{Tt as e,vt as t}from"./router-CHObBy9_.js";import{t as n}from"./clipboard-JYWVdyjq.js";import{t as r}from"./useToast-CmSnOJzB.js";t();function i(t=`加载失败,请稍后重试`){let n=e(null);async function r(e){n.value=null;try{return await e(),!0}catch(e){return n.value=e?.message||t,!1}}return{loadError:n,run:r}}function a(){let{toast:e}=r();async function t(t,r=`已复制到剪贴板`){let i=await n(t);return i?e(r,`success`):e(`复制失败`,`error`),i}return{copyWithToast:t}}export{i as n,a as t};
@@ -1 +0,0 @@
1
- import{s as e}from"./router-CHObBy9_.js";var t=`/api/service`,n=`/api/harness`,r=`${t}/managed`,i={processes:()=>e.get(`${t}/processes`).then(e=>e.processes),autostart:()=>e.get(`${t}/autostart`),setAutostart:n=>e.post(`${t}/autostart`,{enabled:n}),update:()=>e.get(`${t}/update`),setUpdateEnabled:n=>e.post(`${t}/update/enabled`,{enabled:n}),checkUpdate:()=>e.post(`${t}/update/check`),applyUpdate:()=>e.post(`${t}/update/apply`),managedServices:()=>e.get(r),createManagedService:t=>e.post(r,t),updateManagedService:(t,n)=>e.put(`${r}/${encodeURIComponent(t)}`,n),removeManagedService:t=>e.del(`${r}/${encodeURIComponent(t)}`),startManagedService:t=>e.post(`${r}/${encodeURIComponent(t)}/start`),stopManagedService:t=>e.post(`${r}/${encodeURIComponent(t)}/stop`),restartManagedService:t=>e.post(`${r}/${encodeURIComponent(t)}/restart`),harness:()=>e.get(n),setClaudeCode:t=>e.post(`${n}/claude-code`,{enabled:t}),setCodex:t=>e.post(`${n}/codex`,{enabled:t}),setDsh:t=>e.post(`${n}/dsh`,{enabled:t})};async function a(e){let{targetVersion:t,sinceAppliedAt:n,timeoutMs:r=6e5,pollMs:a=3e3,signal:o}=e,s=Date.now()+r;for(;;){if(o?.aborted||Date.now()>=s||(await new Promise(e=>setTimeout(e,a)),o?.aborted))return null;let e=null;try{e=await i.update()}catch{continue}let r=e.lastApply;if(r&&r.toVersion===t&&(r.appliedAt??0)>(n??0))return r;if(Date.now()>=s)return null}}export{a as n,i as t};
@@ -1 +0,0 @@
1
- import{t as e}from"./message-DPoeboTE.js";function t(){function t(t,n=`success`){e({message:t,type:n,duration:n===`warning`?8e3:3e3})}return{toast:t}}export{t};