xiaozhi-client 1.7.12-beta.0 → 1.7.12-beta.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xiaozhi-client",
3
- "version": "1.7.12-beta.0",
3
+ "version": "1.7.12-beta.1",
4
4
  "description": "小智 AI 客户端 命令行工具",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
@@ -47,7 +47,7 @@
47
47
  "websocket",
48
48
  "ai"
49
49
  ],
50
- "author": "shenjingnan(sjn.code@gmail.com)",
50
+ "author": "shenjingnan <sjn.code@gmail.com>",
51
51
  "license": "MIT",
52
52
  "dependencies": {
53
53
  "@hono/node-server": "^1.17.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xiaozhi-client",
3
- "version": "1.7.12-beta.0",
3
+ "version": "1.7.12-beta.1",
4
4
  "description": "小智 AI 客户端 命令行工具",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
@@ -47,7 +47,7 @@
47
47
  "websocket",
48
48
  "ai"
49
49
  ],
50
- "author": "shenjingnan(sjn.code@gmail.com)",
50
+ "author": "shenjingnan <sjn.code@gmail.com>",
51
51
  "license": "MIT",
52
52
  "dependencies": {
53
53
  "@hono/node-server": "^1.17.1",
@@ -27,8 +27,8 @@ var gr=Object.defineProperty;var xr=(r,t,s)=>t in r?gr(r,t,{enumerable:!0,config
27
27
  "url": "https://example.com/mcp"
28
28
  }
29
29
  }
30
- }`,...h})}),e.jsx(ee,{})]})})}),e.jsxs(xe,{className:"mt-4",children:[e.jsx(rt,{asChild:!0,children:e.jsx(C,{variant:"outline",disabled:s,children:"取消"})}),e.jsx(C,{type:"submit",disabled:s,children:s?"保存中...":"保存"})]})]})})})]})}class un{constructor(t){V(this,"baseUrl");if(t)this.baseUrl=t;else{const s=window.location.protocol,a=window.location.hostname,n=window.location.port;this.baseUrl=`${s}//${a}${n?`:${n}`:""}`}}async request(t,s={}){var c;const a=`${this.baseUrl}${t}`,n={headers:{"Content-Type":"application/json",...s.headers}},i=await fetch(a,{...n,...s});if(!i.ok){let m=`HTTP ${i.status}: ${i.statusText}`;try{m=((c=(await i.json()).error)==null?void 0:c.message)||m}catch{}throw new Error(m)}return i.json()}async fetchWorkspaces(){try{const t=await this.request("/api/coze/workspaces");if(!t.success||!t.data)throw new Error(t.message||"获取工作空间列表失败");return t.data}catch(t){throw console.error("获取工作空间列表失败:",t),t}}async fetchWorkflows(t){try{const s=new URLSearchParams;s.append("workspace_id",t.workspace_id),t.page_num!==void 0&&s.append("page_num",t.page_num.toString()),t.page_size!==void 0&&s.append("page_size",t.page_size.toString());const a=await this.request(`/api/coze/workflows?${s.toString()}`);if(!a.success||!a.data)throw new Error(a.message||"获取工作流列表失败");return a.data}catch(s){throw console.error("获取工作流列表失败:",s),s}}async clearCache(){try{const t=await this.request("/api/coze/cache/clear",{method:"POST"});if(!t.success)throw new Error(t.message||"清除缓存失败")}catch(t){throw console.error("清除缓存失败:",t),t}}async getCacheStats(){try{const t=await this.request("/api/coze/cache/stats");if(!t.success||!t.data)throw new Error(t.message||"获取缓存统计失败");return t.data}catch(t){throw console.error("获取缓存统计失败:",t),t}}}const He=new un;function mn(r={}){const{autoLoadWorkspaces:t=!0,autoLoadWorkflows:s=!0,defaultPageSize:a=20,initialWorkspaceId:n}=r,[i,c]=o.useState([]),[m,g]=o.useState([]),[h,f]=o.useState(n||null),[x,d]=o.useState({selectedWorkspaceId:n||null,workspacesLoading:!1,workflowsLoading:!1,workspacesError:null,workflowsError:null}),[l,b]=o.useState(1),[j,p]=o.useState(a),[S,E]=o.useState(!1),N=o.useMemo(()=>i&&Array.isArray(i)&&i.find(A=>A.id===h)||null,[i,h]),U=o.useCallback(async()=>{d(A=>({...A,workspacesLoading:!0,workspacesError:null}));try{const A=await He.fetchWorkspaces();c(A.workspaces),d(u=>({...u,workspacesLoading:!1}))}catch(A){const u=A instanceof Error?A.message:"加载工作空间失败";d(I=>({...I,workspacesLoading:!1,workspacesError:u})),console.error("加载工作空间失败:",A)}},[]),R=o.useCallback(async(A={})=>{const u=A.workspace_id||h;if(!u){console.warn("无法加载工作流:未选择工作空间");return}d(I=>({...I,workflowsLoading:!0,workflowsError:null}));try{const I={workspace_id:u,page_num:A.page_num||l,page_size:A.page_size||j},P=await He.fetchWorkflows(I);g(P.items),E(P.hasMore),d(M=>({...M,workflowsLoading:!1}))}catch(I){const P=I instanceof Error?I.message:"加载工作流失败";d(M=>({...M,workflowsLoading:!1,workflowsError:P})),console.error("加载工作流失败:",I)}},[h,l,j]),O=o.useCallback(A=>{f(A),d(u=>({...u,selectedWorkspaceId:A})),g([]),b(1),E(!1),s&&A&&R({workspace_id:A,page_num:1})},[s,R]),F=o.useCallback(async()=>{await U()},[U]),Z=o.useCallback(async()=>{h&&await R({workspace_id:h,page_num:l})},[R,h,l]),le=o.useCallback(async()=>{try{await He.clearCache(),t&&await U(),s&&h&&await R({workspace_id:h,page_num:1})}catch(A){throw console.error("清除缓存失败:",A),A}},[t,s,h,U,R]),fe=o.useCallback(A=>{b(A),h&&R({workspace_id:h,page_num:A})},[h,R]),he=o.useCallback(A=>{p(A),b(1),h&&R({workspace_id:h,page_num:1,page_size:A})},[h,R]);return o.useEffect(()=>{t&&U()},[t,U]),o.useEffect(()=>{s&&h&&(async()=>{d(u=>({...u,workflowsLoading:!0,workflowsError:null}));try{const u={workspace_id:h,page_num:1,page_size:j},I=await He.fetchWorkflows(u);g(I.items),E(I.hasMore),d(P=>({...P,workflowsLoading:!1}))}catch(u){const I=u instanceof Error?u.message:"加载工作流失败";d(P=>({...P,workflowsLoading:!1,workflowsError:I})),console.error("加载工作流失败:",u)}})()},[s,h,j]),{workspaces:i,workflows:m,selectedWorkspace:N,workspacesLoading:x.workspacesLoading,workflowsLoading:x.workflowsLoading,workspacesError:x.workspacesError,workflowsError:x.workflowsError,hasMoreWorkflows:S,selectWorkspace:O,loadWorkflows:R,refreshWorkspaces:F,refreshWorkflows:Z,clearCache:le,setWorkflows:g,currentPage:l,pageSize:j,setPage:fe,setPageSize:he}}function fn({onToolAdded:r}){var Wt;const[t,s]=o.useState(!1),[a,n]=o.useState(!1),[i,c]=o.useState({open:!1,action:"add"}),[m,g]=o.useState({open:!1}),[h,f]=o.useState(navigator.onLine),[x,d]=o.useState(new Set),[l,b]=o.useState(!1),{workspaces:j,workflows:p,selectedWorkspace:S,workspacesLoading:E,workflowsLoading:N,workspacesError:U,workflowsError:R,hasMoreWorkflows:O,currentPage:F,selectWorkspace:Z,refreshWorkflows:le,setPage:fe,setWorkflows:he}=mn({autoLoadWorkspaces:!0,autoLoadWorkflows:!0});o.useEffect(()=>{const T=()=>f(!0),B=()=>f(!1);return window.addEventListener("online",T),window.addEventListener("offline",B),()=>{window.removeEventListener("online",T),window.removeEventListener("offline",B)}},[]),o.useEffect(()=>{if(!E&&j.length>0&&!S&&!l){const T=j[0];console.log(`自动选择第一个工作空间: ${T.name}`),Z(T.id),b(!0)}E&&l&&b(!1)},[j,E,S,l,Z]);const A=T=>{b(!0),Z(T)},u=T=>{if(!h){y.error("网络连接已断开,请检查网络后重试");return}const B=`add_${T.workflow_id}`;if(x.has(B)){y.warning("该工作流正在添加中,请勿重复操作");return}g({open:!0,workflow:T})},I=async(T,B)=>{const _=`add_${T.workflow_id}`;n(!0),d(D=>new Set(D).add(_));try{if(!T.workflow_id||!T.workflow_name||!T.app_id)throw new Error("工作流数据不完整,缺少必要字段");if(!h)throw new Error("网络连接已断开,请检查网络后重试");const D=B.length>0?{parameters:B}:void 0,K={type:"coze",data:{workflow:T,customName:void 0,customDescription:void 0,parameterConfig:D}},be=await $.addCustomTool(K);y.success(`已添加工作流 "${T.workflow_name}" 为 MCP 工具 "${be.name}"${B.length>0?`,配置了 ${B.length} 个参数`:""}`),he(pr=>pr.map(ot=>ot.workflow_id===T.workflow_id?{...ot,isAddedAsTool:!0,toolName:be.name}:ot)),r==null||r(),await le()}catch(D){console.error("添加工作流失败:",D);let K="添加工作流失败,请重试";D instanceof Error&&(D.message.includes("已存在")||D.message.includes("冲突")?K=`工作流 "${T.workflow_name}" 已存在,请勿重复添加`:D.message.includes("配置")||D.message.includes("token")?K="系统配置错误,请检查扣子API配置":D.message.includes("验证失败")||D.message.includes("格式")?K="工作流数据格式错误,请联系管理员":D.message.includes("网络")||D.message.includes("超时")||D.message.includes("连接")?K="网络连接失败,请检查网络后重试":D.message.includes("权限")?K="权限不足,请检查API权限配置":D.message.includes("频繁")?K="操作过于频繁,请稍后重试":K=D.message),y.error(K)}finally{n(!1),d(D=>{const K=new Set(D);return K.delete(_),K}),g({open:!1})}},P=()=>{g({open:!1})},M=async T=>{const B=`add_${T.workflow_id}`;n(!0),d(_=>new Set(_).add(B));try{if(!T.workflow_id||!T.workflow_name||!T.app_id)throw new Error("工作流数据不完整,缺少必要字段");if(!h)throw new Error("网络连接已断开,请检查网络后重试");const _={type:"coze",data:{workflow:T,customName:void 0,customDescription:void 0,parameterConfig:void 0}},D=await $.addCustomTool(_);y.success(`已添加工作流 "${T.workflow_name}" 为 MCP 工具 "${D.name}"`),he(K=>K.map(be=>be.workflow_id===T.workflow_id?{...be,isAddedAsTool:!0,toolName:D.name}:be)),r==null||r(),await le()}catch(_){console.error("添加工作流失败:",_);let D="添加工作流失败,请重试";_ instanceof Error&&(_.message.includes("已存在")||_.message.includes("冲突")?D=`工作流 "${T.workflow_name}" 已存在,请勿重复添加`:_.message.includes("配置")||_.message.includes("token")?D="系统配置错误,请检查扣子API配置":_.message.includes("验证失败")||_.message.includes("格式")?D="工作流数据格式错误,请联系管理员":_.message.includes("网络")||_.message.includes("超时")||_.message.includes("连接")?D="网络连接失败,请检查网络后重试":_.message.includes("权限")?D="权限不足,请检查API权限配置":_.message.includes("频繁")?D="操作过于频繁,请稍后重试":D=_.message),y.error(D)}finally{n(!1),d(_=>{const D=new Set(_);return D.delete(B),D}),c({open:!1,action:"add"})}},v=()=>{F>1&&fe(F-1)},k=()=>{O&&fe(F+1)},z=()=>{S&&le()},W=()=>e.jsx("div",{className:"space-y-2",children:U?e.jsxs("div",{className:"flex items-center gap-2 p-3 text-sm text-red-600 bg-red-50 rounded-md",children:[e.jsx(Je,{className:"h-4 w-4"}),e.jsxs("span",{children:["加载工作空间失败: ",U]})]}):e.jsxs(Ge,{value:(S==null?void 0:S.id)||"",onValueChange:A,disabled:E,children:[e.jsx(Te,{children:e.jsx(Qe,{placeholder:E?"加载中...":"请选择工作空间"})}),e.jsx(Re,{children:j.map(T=>e.jsx(ue,{value:T.id,children:e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("span",{children:T.name})})},T.id))})]})}),nt=()=>S?R?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Je,{className:"h-12 w-12 text-red-500 mb-4"}),e.jsx("h3",{className:"text-lg font-medium mb-2",children:"加载工作流失败"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:R}),e.jsxs(C,{onClick:z,variant:"outline",children:[e.jsx(bs,{className:"h-4 w-4 mr-2"}),"重试"]})]}):N?e.jsx("div",{className:"space-y-3",children:Array.from({length:3},(T,B)=>B).map(T=>e.jsxs("div",{className:"flex items-center gap-4 p-4 border rounded-lg",children:[e.jsx(we,{className:"w-10 h-10 rounded-lg","data-testid":"skeleton"}),e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsx(we,{className:"h-4 w-1/3","data-testid":"skeleton"}),e.jsx(we,{className:"h-3 w-2/3","data-testid":"skeleton"})]}),e.jsx(we,{className:"w-16 h-8","data-testid":"skeleton"})]},`skeleton-${T}`))}):p.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Ne,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-medium mb-2",children:"暂无工作流"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"当前工作空间下没有可用的工作流"})]}):e.jsx("div",{className:"space-y-3 max-h-[500px] overflow-auto",children:p.map(T=>e.jsxs("div",{className:"flex items-center gap-4 p-4 border rounded-lg hover:bg-slate-50 transition-colors",children:[e.jsx("div",{className:"flex-shrink-0 w-10 h-10 bg-green-100 rounded-lg flex items-center justify-center text-lg",children:e.jsx(Ne,{className:"h-5 w-5 text-green-600"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("h4",{className:"font-medium text-sm truncate",children:T.workflow_name}),e.jsx(se,{variant:"secondary",className:"text-xs",children:"工作流"})]}),e.jsx("p",{className:"text-sm text-muted-foreground line-clamp-2",children:T.description||"暂无描述"})]}),e.jsx("div",{className:"flex-shrink-0",children:T.isAddedAsTool?e.jsx(se,{variant:"secondary",className:"text-xs bg-green-100 text-green-800",children:"已添加"}):e.jsxs(C,{size:"sm",onClick:()=>u(T),disabled:a,children:[a?e.jsx(Ce,{className:"h-4 w-4 animate-spin","data-testid":"loader"}):e.jsx(Me,{className:"h-4 w-4"}),"添加"]})})]},T.workflow_id))}):e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Ne,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-medium mb-2",children:"请先选择工作空间"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"选择一个工作空间后,将显示该空间下的工作流列表"})]}),hr=()=>!S||p.length===0?null:e.jsx("div",{className:"flex items-center justify-end",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(C,{variant:"link",size:"sm",onClick:v,disabled:F===1,className:"text-muted-foreground",children:e.jsx(Vr,{className:"h-4 w-4"})}),e.jsx("div",{className:"flex items-center gap-1",children:e.jsx("span",{className:"text-sm",children:F})}),e.jsx(C,{variant:"link",size:"sm",onClick:k,disabled:!O,className:"text-muted-foreground",children:e.jsx(qr,{className:"h-4 w-4"})})]})});return e.jsxs(e.Fragment,{children:[e.jsxs(me,{open:t,onOpenChange:s,children:[e.jsx(Se,{asChild:!0,children:e.jsxs(C,{variant:"outline",className:"w-full",children:[e.jsx(Ne,{className:"h-4 w-4 mr-2"}),"工作流集成"]})}),e.jsxs(oe,{className:"flex flex-col max-w-full w-[1000px]",children:[e.jsx(ie,{className:"flex-shrink-0",children:e.jsxs(ce,{className:"flex items-center gap-2",children:[e.jsx(Ne,{className:"h-5 w-5"}),"工作流集成"]})}),e.jsx("div",{className:"w-[120px]",children:W()}),e.jsx("div",{className:"flex-1 pr-2 w-full",children:nt()}),hr()]})]}),m.workflow&&e.jsx(sr,{open:m.open,onOpenChange:T=>g(B=>({...B,open:T})),workflow:m.workflow,onConfirm:I,onCancel:P,title:"配置工作流参数"}),e.jsx(st,{open:i.open,onOpenChange:T=>c(B=>({...B,open:T})),children:e.jsxs(De,{children:[e.jsxs($e,{children:[e.jsx(Le,{children:"确认添加工作流"}),e.jsxs(Oe,{children:['确定要将工作流 "',(Wt=i.workflow)==null?void 0:Wt.workflow_name,'" 添加为 MCP 工具吗?']})]}),e.jsxs(Ae,{children:[e.jsx(_e,{children:"取消"}),e.jsx(Ue,{onClick:()=>{i.workflow&&M(i.workflow)},children:"添加"})]})]})})]})}const hn=J.object({config:J.string().min(2,{message:"配置不能为空"})});function pn({mcpServer:r,mcpServerName:t}){const[s,a]=o.useState(!1),[n,i]=o.useState(!1),c=ye(),{updateConfig:m}=Zs(),g=ze({resolver:We(hn),defaultValues:{config:JSON.stringify(r,null,2)}});async function h(f){if(!c){y.error("配置数据未加载,请稍后重试");return}i(!0);try{let x;try{x=JSON.parse(f.config)}catch{y.error("JSON格式错误,请检查配置格式");return}if(!x||typeof x!="object"){y.error("配置格式无效");return}const d={...c,mcpServers:{...c.mcpServers,[t]:x}};await m(d),y.success("MCP服务器配置已更新"),a(!1)}catch(x){console.error("更新配置失败:",x),y.error(x instanceof Error?x.message:"更新配置失败")}finally{i(!1)}}return e.jsxs(me,{open:s,onOpenChange:a,children:[e.jsx(Se,{asChild:!0,children:e.jsx(C,{variant:"secondary",size:"icon",className:"size-8",children:e.jsx(Ie,{className:"h-4 w-4"})})}),e.jsx(oe,{className:"sm:max-w-[500px]",children:e.jsx(Ve,{...g,children:e.jsxs("form",{onSubmit:g.handleSubmit(h),children:[e.jsxs(ie,{className:"mb-4",children:[e.jsxs(ce,{children:["配置 ",t," MCP"]}),e.jsx(pe,{children:"点击保存后,需要重启服务才会生效。"})]}),e.jsx("div",{className:"grid gap-4",children:e.jsx(X,{control:g.control,name:"config",render:({field:f})=>e.jsxs(Q,{children:[e.jsx(Y,{children:e.jsx(It,{placeholder:"MCP服务配置",className:"resize-none h-[300px] font-mono text-sm",disabled:n,...f})}),e.jsx(ee,{})]})})}),e.jsxs(xe,{className:"mt-4",children:[e.jsx(rt,{asChild:!0,children:e.jsx(C,{variant:"outline",disabled:n,children:"取消"})}),e.jsx(C,{type:"submit",disabled:n,children:n?"保存中...":"保存"})]})]})})})]})}function gn({mcpServerName:r,onRemoveSuccess:t,disabled:s=!1}){const[a,n]=o.useState(!1),i=async()=>{try{if(n(!0),!await ut.removeServer(r))throw new Error("删除服务器失败");y.success(`MCP 服务 "${r}" 已删除`),t&&await t()}catch(c){console.error("删除 MCP 服务失败:",c),y.error(`删除 MCP 服务失败: ${c instanceof Error?c.message:"未知错误"}`)}finally{n(!1)}};return e.jsxs(st,{children:[e.jsx(qa,{asChild:!0,children:e.jsx(C,{variant:"destructive",size:"icon",className:"size-8",disabled:s||a,children:e.jsx(os,{className:"h-4 w-4"})})}),e.jsxs(De,{children:[e.jsxs($e,{children:[e.jsxs(Le,{children:["确定要删除这个(",r,")MCP服务吗?"]}),e.jsx(Oe,{children:"删除后,对应的工具列表也会移除。"})]}),e.jsxs(Ae,{children:[e.jsx(_e,{children:"取消"}),e.jsx(Ue,{onClick:i,disabled:s||a,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:a?"删除中...":"确定"})]})]})]})}function rr({disabled:r=!1,variant:t="outline",className:s="",restartingText:a="重启中...",defaultText:n="重启服务"}){const{loading:{isRestarting:i},restartService:c}=ae(),m=ks(),g=async()=>{try{await c()}catch(f){console.error("[RestartButton] 重启失败:",f)}},h=()=>i?m.enabled&&m.startTime?"重连中...":a:n;return e.jsxs(C,{type:"button",onClick:g,variant:t,disabled:i||r,className:ys("flex items-center gap-2 w-[120px]",s),children:[i?e.jsx(Ce,{className:"size-4 animate-spin"}):e.jsx(Br,{className:"size-4"}),h()]})}function xn({updateConfig:r}){const t=Ha(),s=Hs(),{refreshConfig:a}=Rt(),[n,i]=o.useState([]),[c,m]=o.useState([]),[g,h]=o.useState(!1),[f,x]=o.useState(null),d=o.useCallback((u,I)=>{var v,k;const{serviceName:P,toolName:M}=(()=>{var z,W;return!u||!u.handler?{serviceName:"unknown",toolName:(u==null?void 0:u.name)||"unknown"}:u.handler.type==="mcp"?{serviceName:((z=u.handler.config)==null?void 0:z.serviceName)||"unknown",toolName:((W=u.handler.config)==null?void 0:W.toolName)||u.name}:u.handler.type==="proxy"&&u.handler.platform==="coze"?{serviceName:"coze",toolName:u.name}:{serviceName:"custom",toolName:u.name}})();return{serverName:P,toolName:M,enable:I,name:u.name,description:u.description,usageCount:(v=u.stats)==null?void 0:v.usageCount,lastUsedTime:(k=u.stats)==null?void 0:k.lastUsedTime,inputSchema:u.inputSchema}},[]),l=o.useCallback(async()=>{h(!0),x(null);try{const[u,I]=await Promise.all([$.getToolsList("enabled"),$.getToolsList("disabled")]),P=u.map(v=>d(v,!0)),M=I.map(v=>d(v,!1));i(P),m(M)}catch(u){console.error("获取工具列表失败:",u);const I=u instanceof Error?u.message:"获取工具列表失败";if(x(I),y.error(I),t){const P=Object.entries(t).flatMap(([k,z])=>Object.entries((z==null?void 0:z.tools)||{}).map(([W,nt])=>({serverName:k,toolName:W,...nt}))),M=P.filter(k=>k.enable!==!1),v=P.filter(k=>k.enable===!1);i(M),m(v)}}finally{h(!1)}},[t,d]),[b,j]=o.useState(!1),p=o.useCallback(async()=>{if(!b)try{j(!0),await Promise.all([a(),l()])}catch(u){console.error("刷新数据失败:",u),y.error("刷新数据失败")}finally{j(!1)}},[a,l,b]),S=o.useCallback(async()=>{try{const[u,I]=await Promise.all([$.getToolsList("enabled"),$.getToolsList("disabled")]),P=u.map(v=>d(v,!0)),M=I.map(v=>d(v,!1));i(P),m(M)}catch(u){console.error("刷新工具列表失败:",u),y.error("刷新工具列表失败")}},[d]);o.useEffect(()=>{l()},[l]);const[E,N]=o.useState(null),[U,R]=o.useState({open:!1}),O=async(u,I)=>{try{if(I){const P=[...n,...c].find(M=>M.name===u);if(!P){y.error("找不到对应的工具信息");return}if(P.serverName==="coze"){N(u);return}await $.removeCustomTool(u),y.success(`删除工具 ${u} 成功`)}else{const P=[...n,...c].find(M=>M.name===u);if(!P){y.error("找不到对应的工具信息");return}P.serverName==="coze"?await $.addCustomTool({workflow_id:"",workflow_name:u,description:P.description||"",icon_url:"",app_id:""},u,P.description||""):await $.addCustomTool({type:"mcp",data:{serviceName:P.serverName,toolName:P.toolName,customName:u,customDescription:P.description||""}}),y.success(`添加工具 ${u} 成功`)}await S()}catch(P){console.error("切换工具状态失败:",P),y.error(P instanceof Error?P.message:"切换工具状态失败")}},F=async()=>{if(E)try{await $.removeCustomTool(E),y.success(`删除工具 ${E} 成功`),await S()}catch(u){console.error("删除 Coze 工具失败:",u),y.error(u instanceof Error?u.message:"删除 Coze 工具失败")}finally{N(null)}},Z=()=>{N(null)},le=u=>{u.serverName==="coze"&&R({open:!0,tool:u})},fe=u=>{var I,P,M;return u.serverName==="coze"&&((I=u.handler)==null?void 0:I.type)==="proxy"?{workflow_id:((P=u.handler.config)==null?void 0:P.workflow_id)||"",workflow_name:u.toolName,description:u.description||"",icon_url:"",app_id:((M=u.handler.config)==null?void 0:M.app_id)||"",creator:{id:"",name:""},created_at:0,updated_at:0,isAddedAsTool:!0,toolName:u.name,inputSchema:u.inputSchema}:{workflow_id:"",workflow_name:u.toolName,description:u.description||"",icon_url:"",app_id:"",creator:{id:"",name:""},created_at:0,updated_at:0,isAddedAsTool:!0,toolName:u.name,inputSchema:u.inputSchema}},he=async(u,I)=>{if(U.tool)try{const P=I.length>0?{parameters:I}:void 0,M=fe(U.tool);u.workflow_id&&(M.workflow_id=u.workflow_id),u.app_id&&(M.app_id=u.app_id);const v={type:"coze",data:{workflow:M,customName:void 0,customDescription:void 0,parameterConfig:P}};await $.updateCustomTool(U.tool.name,v),y.success(`工具 "${M.workflow_name}" 参数配置更新成功`),await S()}catch(P){console.error("更新工具参数配置失败:",P);let M="更新工具参数配置失败,请重试";P instanceof Error&&(M=P.message),y.error(M)}finally{R({open:!1})}},A=()=>{R({open:!1})};return!s||Object.keys(s).length===0?e.jsx("div",{className:"@container/main flex flex-1 flex-col gap-2",children:e.jsxs("div",{className:"flex flex-col gap-4 py-4 md:gap-6 md:py-6",children:[e.jsx("div",{className:"flex items-center justify-between px-4 lg:px-6",children:e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold",children:"你的聚合 MCP 服务"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"在这里管理你的 MCP 服务器和工具。"})]})}),e.jsx("div",{className:"px-4 lg:px-6",children:e.jsx(de,{className:"border-dashed",children:e.jsxs(ve,{className:"flex flex-col items-center justify-center py-12",children:[e.jsx(At,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"还没有 MCP 服务"}),e.jsx("p",{className:"text-sm text-muted-foreground text-center mb-4",children:"添加你的第一个 MCP 服务器来开始使用强大的工具集成功能。"}),e.jsx(Ht,{})]})})})]})}):e.jsxs("div",{className:"flex flex-col gap-4 px-4 lg:px-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold",children:"你的聚合 MCP 服务"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"你可以在这里管理你的 MCP 服务,包括启用/禁用工具,以及查看工具的详细信息。"})]}),b&&e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx("div",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-primary"}),"刷新中..."]})]}),e.jsxs("div",{className:"*:data-[slot=card]:shadow-xs @xl/main:grid-cols-8 @5xl/main:grid-cols-8 grid grid-cols-1 gap-4 *:data-[slot=card]:bg-gradient-to-t *:data-[slot=card]:from-primary/5 *:data-[slot=card]:to-card dark:*:data-[slot=card]:bg-card",children:[e.jsx(de,{className:"transition-all duration-200 col-span-3",children:e.jsx(ve,{className:"p-4",children:e.jsxs("div",{className:"flex-col",children:[e.jsxs("h4",{className:"text-sm font-medium mb-3 flex items-center gap-2",children:[e.jsx(Lt,{className:"h-4 w-4"}),"使用中的工具 (",n.length,")",g&&e.jsx("span",{className:"text-xs text-muted-foreground",children:"(加载中...)"})]}),e.jsx("div",{className:"flex-1 space-y-2",children:g?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx("div",{className:"text-sm text-muted-foreground",children:"加载工具列表中..."})}):f?e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 px-4",children:[e.jsx("div",{className:"text-sm text-red-500 mb-2",children:f}),e.jsx(C,{variant:"outline",size:"sm",onClick:l,children:"重试"})]}):n.map(u=>e.jsxs("div",{className:"flex items-start justify-between p-4 bg-slate-50 rounded-md font-mono",children:[e.jsxs("div",{className:"text-md flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 justify-start",children:[e.jsx(se,{variant:"secondary",className:"rounded-md",children:u.serverName}),e.jsx("span",{children:u.toolName})]}),e.jsx("p",{className:"text-sm text-muted-foreground my-2",children:u.description}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[e.jsx("span",{className:"text-muted-foreground",children:"使用次数:"})," ",e.jsx("span",{className:"text-primary font-bold",children:u.usageCount||0})]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[e.jsx("span",{className:"text-muted-foreground",children:"最后使用:"})," ",e.jsx("span",{className:"text-primary font-bold",children:u.lastUsedTime||"-"})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 ml-4",children:[u.serverName==="coze"&&e.jsx(C,{variant:"secondary",size:"icon",className:"size-8 hover:bg-blue-500 hover:text-white",onClick:()=>le(u),title:"配置参数",children:e.jsx(Ie,{size:16})}),e.jsx(C,{variant:"secondary",size:"icon",className:"size-8 hover:bg-red-500 hover:text-white",onClick:()=>O(u.name,!0),children:e.jsx(Fr,{size:18})})]})]},u.toolName))})]})})}),e.jsx(de,{className:"transition-all duration-200 col-span-3",children:e.jsx(ve,{className:"p-4",children:e.jsxs("div",{className:"flex-col",children:[e.jsxs("h4",{className:"text-sm font-medium mb-3 flex items-center gap-2",children:[e.jsx(Lt,{className:"h-4 w-4"}),"未使用的工具 (",c.length,")",g&&e.jsx("span",{className:"text-xs text-muted-foreground",children:"(加载中...)"})]}),e.jsx("div",{className:"flex-1 space-y-2",children:g?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx("div",{className:"text-sm text-muted-foreground",children:"加载工具列表中..."})}):f?e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 px-4",children:[e.jsx("div",{className:"text-sm text-red-500 mb-2",children:f}),e.jsx(C,{variant:"outline",size:"sm",onClick:l,children:"重试"})]}):c.length===0?e.jsxs("div",{className:"flex-1 flex flex-col items-center gap-4 py-20 px-4 bg-slate-50 rounded-md font-mono h-full",children:[e.jsx(At,{strokeWidth:1.5,size:48,className:"text-muted-foreground"}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"全部工具都已经启用"})]}):c.map(u=>e.jsxs("div",{className:"flex items-start justify-between p-4 bg-slate-50 rounded-md font-mono",children:[e.jsxs("div",{className:"text-md flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 justify-start",children:[e.jsx(se,{variant:"secondary",className:"rounded-md",children:u.serverName}),e.jsx("span",{children:u.toolName})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:u.description}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[e.jsx("span",{className:"text-muted-foreground",children:"使用次数:"})," ",e.jsx("span",{className:"text-primary font-bold",children:u.usageCount||0})]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[e.jsx("span",{className:"text-muted-foreground",children:"最后使用:"})," ",e.jsx("span",{className:"text-primary font-bold",children:u.lastUsedTime||"-"})]})]})]}),e.jsx("div",{className:"flex items-center gap-2 ml-4",children:e.jsx(C,{variant:"secondary",size:"icon",className:"size-8 hover:bg-green-500 hover:text-white",onClick:()=>O(u.name,!1),children:e.jsx(Me,{className:"h-4 w-4"})})})]},u.toolName))})]})})}),e.jsxs("div",{className:"transition-all duration-200 gap-4 flex flex-col col-span-2",children:[e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ht,{}),e.jsx(rr,{})]}),e.jsx(fn,{onToolAdded:S})]}),Object.entries(s||{}).map(([u,I])=>e.jsxs(de,{className:"transition-all duration-200",children:[e.jsx(ve,{className:"p-0",children:e.jsx("div",{className:"p-4 pb-2",children:e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsx("div",{className:"flex items-start gap-4 flex-1",children:e.jsx("div",{className:"flex-1",children:e.jsx("div",{className:"flex items-center gap-2 mb-2",children:e.jsx("h3",{className:"text-lg font-semibold",children:u})})})}),e.jsxs("div",{className:"flex items-center gap-2 ml-4",children:[e.jsx(pn,{mcpServerName:u,mcpServer:I}),e.jsx(gn,{mcpServerName:u,onRemoveSuccess:p,disabled:b})]})]})})}),e.jsx(Ke,{className:"p-4 pt-2",children:e.jsx(se,{variant:"outline",className:"text-xs",children:ft(I)})})]},u))]})]}),e.jsx(st,{open:E!==null,onOpenChange:u=>!u&&N(null),children:e.jsxs(De,{children:[e.jsxs($e,{children:[e.jsx(Le,{children:"确认移除 Coze 工作流工具"}),e.jsxs(Oe,{children:['移除后需要通过【工作流集成】重新添加并配置入参,确定要移除工具 "',E,'" 吗?']})]}),e.jsxs(Ae,{children:[e.jsx(_e,{onClick:Z,children:"取消"}),e.jsx(Ue,{onClick:F,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"确认移除"})]})]})}),U.tool&&e.jsx(sr,{open:U.open,onOpenChange:u=>R(I=>({...I,open:u})),workflow:U.tool,onConfirm:he,onCancel:A,title:"配置工作流参数"})]})}const bn=({size:r=24,color:t="currentColor",...s})=>e.jsx("svg",{width:r,height:r,viewBox:"0 0 1024 1024",fill:"none",stroke:t,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...s,children:e.jsx("path",{d:"M980.79827 694.105946c-21.144216-122.796973-109.844757-203.250162-109.844757-203.250162 12.647784-111.477622-33.792-131.26573-33.792-131.26573C827.392 14.668108 530.985514 20.67373 524.730811 20.839784 518.476108 20.67373 222.01427 14.668108 212.300108 359.590054c0 0-46.467459 19.788108-33.819676 131.26573 0 0-88.700541 80.453189-109.817081 203.250162 0 0-11.291676 207.484541 101.403676 25.40627 0 0 25.350919 69.161514 71.790703 131.26573 0 0-83.082378 28.256865-75.997405 101.625081 0 0-2.87827 81.836973 177.401081 76.218811 0 0 126.699243-9.852541 164.753297-63.515676l16.605405 0 0.276757 0 16.633081 0c38.026378 53.635459 164.725622 63.515676 164.725622 63.515676 180.224 5.618162 177.401081-76.218811 177.401081-76.218811 7.029622-73.368216-75.997405-101.625081-75.997405-101.625081 46.439784-62.104216 71.790703-131.26573 71.790703-131.26573C992.034595 901.590486 980.79827 694.105946 980.79827 694.105946z"})}),wn=({size:r=24,color:t="currentColor",...s})=>e.jsx("svg",{width:r,height:r,viewBox:"0 0 1024 1024",fill:"none",stroke:t,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...s,children:e.jsx("path",{d:"M0 524.992q0 166.016 95.488 298.496t247.488 185.504q6.016 0.992 10.016 0.992t6.496-1.504 4-3.008 2.016-4.992 0.512-4.992v-100.512q-36.992 4-66.016-0.512t-45.504-14.016-28.992-23.488-16.992-25.504-8.992-24-5.504-14.496q-8.992-15.008-27.008-27.488t-27.008-20-2.016-14.496q50.016-26.016 112.992 66.016 34.016 51.008 119.008 30.016 10.016-40.992 40-70.016Q293.984 736 237.984 670.976t-56-158.016q0-87.008 55.008-151.008-22.016-64.992 6.016-136.992 28.992-2.016 64.992 11.488t50.496 23.008 25.504 17.504q56.992-16 128.512-16t129.504 16q12.992-8.992 28.992-19.008t48.992-21.504 60.992-9.504q27.008 71.008 7.008 135.008 56 64 56 151.008 0 92.992-56.992 158.496t-172 85.504q43.008 43.008 43.008 104v128.992q0 0.992 0.992 3.008 0 6.016 0.512 8.992t4.512 6.016 12 3.008q152.992-52 250.496-185.504t97.504-300.512q0-104-40.512-199.008t-108.992-163.488-163.488-108.992T512.032 12.96 313.024 53.472 149.536 162.464t-108.992 163.488-40.512 199.008z","p-id":"4674"})});function ar(){const[r,t]=o.useState({status:"idle",logs:[]});o.useEffect(()=>{const g=L.subscribe("data:npmInstallStarted",d=>{console.log("[useNPMInstall] 安装开始:",d),t({status:"installing",version:d.version,installId:d.installId,logs:[]})}),h=L.subscribe("data:npmInstallLog",d=>{console.log("[useNPMInstall] 收到日志:",d),t(l=>l.installId===d.installId?{...l,logs:[...l.logs,{type:d.type,message:d.message,timestamp:d.timestamp}]}:l)}),f=L.subscribe("data:npmInstallCompleted",d=>{console.log("[useNPMInstall] 安装完成:",d),t(l=>l.installId===d.installId?{...l,status:"completed",duration:d.duration}:l)}),x=L.subscribe("data:npmInstallFailed",d=>{console.log("[useNPMInstall] 安装失败:",d),t(l=>l.installId===d.installId?{...l,status:"failed",error:d.error,duration:d.duration}:l)});return()=>{g(),h(),f(),x()}},[]);const s=o.useCallback(async g=>{var h;try{console.log("[useNPMInstall] 开始安装版本:",g);const x=await(await fetch("/api/update",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({version:g})})).json();if(!x.success)throw new Error(((h=x.error)==null?void 0:h.message)||"安装请求失败");return console.log("[useNPMInstall] 安装请求已接受:",x),x}catch(f){throw console.error("[useNPMInstall] 安装请求失败:",f),t(x=>({...x,status:"failed",error:f instanceof Error?f.message:"未知错误"})),f}},[]),a=o.useCallback(()=>{console.log("[useNPMInstall] 清除安装状态"),t({status:"idle",logs:[]})},[]),n=o.useCallback(()=>{switch(r.status){case"installing":return`正在安装 xiaozhi-client@${r.version}...`;case"completed":return"安装完成!";case"failed":return`安装失败: ${r.error}`;default:return""}},[r]),i=o.useCallback(()=>{switch(r.status){case"installing":return"text-blue-600";case"completed":return"text-green-600";case"failed":return"text-red-600";default:return"text-gray-600"}},[r]),c=o.useCallback(()=>r.status==="installing",[r.status]),m=o.useCallback(()=>r.status!=="installing",[r.status]);return{installStatus:r,startInstall:s,clearStatus:a,getStatusText:n,getStatusColor:i,isInstalling:c,canCloseDialog:m}}const nr=o.forwardRef(({className:r,value:t,status:s="idle",...a},n)=>{const i=()=>{switch(s){case"installing":return"bg-blue-500";case"completed":return"bg-green-500";case"failed":return"bg-red-500";default:return"bg-gray-300"}};return e.jsx("div",{ref:n,className:w("relative h-4 w-full overflow-hidden rounded-full bg-gray-200 dark:bg-gray-800",r),...a,children:e.jsx("div",{className:w("h-full transition-all duration-300 ease-in-out",i()),style:{width:`${t||0}%`}})})});nr.displayName="Progress";const or=o.forwardRef(({className:r,children:t,...s},a)=>e.jsx("div",{ref:a,className:w("relative overflow-auto",r),...s,children:t}));or.displayName="ScrollArea";const vn=o.forwardRef(({className:r,orientation:t="vertical",...s},a)=>e.jsx("div",{ref:a,className:w("flex touch-none select-none transition-colors",t==="vertical"&&"h-full w-2.5 border-l border-l-transparent p-[1px]",t==="horizontal"&&"h-2.5 w-full border-t border-t-transparent p-[1px]",r),...s,children:e.jsx("div",{className:"relative flex-1 rounded-full bg-border"})}));vn.displayName="ScrollBar";const jn=je("relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",{variants:{variant:{default:"bg-background text-foreground",destructive:"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive"}},defaultVariants:{variant:"default"}}),Mt=o.forwardRef(({className:r,variant:t,...s},a)=>e.jsx("div",{ref:a,role:"alert",className:w(jn({variant:t}),r),...s}));Mt.displayName="Alert";const ir=o.forwardRef(({className:r,...t},s)=>e.jsx("h5",{ref:s,className:w("mb-1 font-medium leading-none tracking-tight",r),...t}));ir.displayName="AlertTitle";const zt=o.forwardRef(({className:r,...t},s)=>e.jsx("div",{ref:s,className:w("text-sm [&_p]:leading-relaxed",r),...t}));zt.displayName="AlertDescription";function cr({isOpen:r,onClose:t,version:s}){const{installStatus:a,startInstall:n,clearStatus:i,isInstalling:c,canCloseDialog:m}=ar(),g=o.useRef(null),[h,f]=o.useState(!1);o.useEffect(()=>{r&&s&&(console.log("[InstallLogDialog] 对话框打开,开始安装版本:",s),i(),n(s).catch(N=>{console.error("[InstallLogDialog] 启动安装失败:",N)}))},[r,s,n,i]),o.useEffect(()=>{const N=setTimeout(()=>{g.current&&(g.current.scrollTop=g.current.scrollHeight)},100);return()=>clearTimeout(N)});const x=()=>{switch(a.status){case"idle":return 0;case"installing":return Math.min(90,a.logs.length*2);case"completed":return 100;case"failed":return 100;default:return 0}},d=()=>{switch(a.status){case"installing":return"正在安装...";case"completed":return"安装完成";case"failed":return"安装失败";default:return"准备安装"}},l=()=>{switch(a.status){case"installing":return e.jsx(Ot,{className:"h-4 w-4 animate-pulse"});case"completed":return e.jsx(dt,{className:"h-4 w-4 text-green-600"});case"failed":return e.jsx(Hr,{className:"h-4 w-4 text-red-600"});default:return null}},b=()=>{switch(a.status){case"installing":return"default";case"completed":return"secondary";case"failed":return"destructive";default:return"outline"}},j=N=>{let U=N;const R=[/\[0m/g,/\[31m/g,/\[32m/g,/\[33m/g,/\[34m/g,/\[35m/g,/\[36m/g,/\[37m/g,/\[90m/g,/\[91m/g,/\[92m/g,/\[93m/g,/\[94m/g,/\[95m/g,/\[96m/g,/\[97m/g];for(const O of R)U=U.replace(O,"");return U.split(`
31
- `).filter(O=>O.trim()).map((O,F)=>e.jsx("div",{className:"leading-relaxed",children:O},`${O.slice(0,20)}-${F}`))},p=()=>{m()&&(i(),t())},S=N=>{N.key==="Escape"&&m()&&p()},E=()=>{f(!h)};return e.jsx(me,{open:r,onOpenChange:p,children:e.jsxs(oe,{className:"max-w-2xl max-h-[80vh] flex flex-col",onKeyDown:S,children:[e.jsxs(ie,{className:"flex flex-row items-center justify-between space-y-0 pb-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(ce,{className:"text-lg font-semibold",children:"正在安装 xiaozhi-client"}),a.status!=="idle"&&e.jsxs(se,{variant:b(),className:"flex items-center gap-1",children:[l(),d()]})]}),e.jsx(C,{variant:"ghost",size:"icon",onClick:p,disabled:!m(),className:"h-6 w-6",children:e.jsx(vt,{className:"h-4 w-4"})})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{className:"font-medium",children:"安装进度"}),a.version&&e.jsxs(se,{variant:"outline",className:"text-xs",children:["v",a.version]})]}),e.jsx(nr,{value:x(),status:a.status,className:"w-full h-2"}),e.jsxs("div",{className:"flex items-center justify-between text-xs text-muted-foreground",children:[e.jsx("span",{children:d()}),a.duration&&e.jsxs("span",{children:["耗时: ",(a.duration/1e3).toFixed(1),"s"]})]})]}),a.status==="failed"&&e.jsx(Mt,{variant:"destructive",children:e.jsx(zt,{children:"安装失败,请查看详细日志了解具体原因。"})}),e.jsxs("div",{children:[e.jsxs("button",{type:"button",onClick:E,className:"flex w-full items-center justify-between h-auto p-0 gap-0 hover:bg-none bg-none text-sm mb-2",children:[e.jsx("h4",{className:"font-medium",children:"安装日志"}),e.jsx("div",{className:"flex items-center gap-1",children:h?e.jsxs(e.Fragment,{children:["收起 ",e.jsx(ms,{className:"h-4 w-4"})]}):e.jsxs(e.Fragment,{children:["展开 ",e.jsx(jt,{className:"h-4 w-4"})]})})]}),h&&e.jsx(or,{ref:g,className:"h-[300px] w-full rounded-md border bg-background",children:e.jsx("div",{className:"p-4 font-mono text-xs",children:a.logs.length===0?e.jsxs("div",{className:"text-muted-foreground flex items-center gap-2",children:[e.jsx(Ot,{className:"h-4 w-4 animate-pulse"}),"等待日志输出..."]}):e.jsx("div",{className:"space-y-1",children:a.logs.map(N=>e.jsx("div",{className:`${N.type==="stderr"?"text-orange-600":"text-foreground"} break-words`,children:j(N.message)},`${N.timestamp}-${N.message.slice(0,50)}`))})})})]})]}),e.jsx(xe,{className:"flex items-center justify-between pt-4 border-t",children:e.jsxs("div",{className:"flex gap-2",children:[a.status==="completed"&&e.jsxs(C,{variant:"outline",onClick:()=>window.location.reload(),className:"flex items-center gap-2",children:[e.jsx(dt,{className:"h-4 w-4"}),"重启应用"]}),e.jsx(C,{onClick:p,disabled:!m(),variant:a.status==="failed"?"destructive":"default",children:c()?"安装中...":a.status==="completed"?"完成":(a.status==="failed","关闭")})]})})]})})}const Sn=[{value:"stable",label:"正式版"},{value:"rc",label:"预览版"},{value:"beta",label:"测试版"},{value:"all",label:"全部版本"}];function Jt({children:r,defaultSelectedVersion:t}){const[s,a]=o.useState(!1),[n,i]=o.useState(""),[c,m]=o.useState("stable"),[g,h]=o.useState(!1),[f,x]=o.useState([]),[d,l]=o.useState(!1),{startInstall:b}=ar(),j=o.useCallback(async R=>{try{l(!0);const O=await $.getAvailableVersions(R),F=O.versions.map(Z=>({value:Z,label:`v${Z}`}));x(F),console.log(`[VersionUpgradeDialog] 获取到 ${O.total} 个${R}版本`),t&&O.versions.includes(t||"")&&i(t||"")}catch(O){console.error("[VersionUpgradeDialog] 获取版本列表失败:",O),x([])}finally{l(!1)}},[t]);o.useEffect(()=>{s&&j(c)},[s,c,j]);const p=R=>{m(R),i("")},S=R=>{i(R)},E=async()=>{if(n)try{console.log("[VersionUpgradeDialog] 开始安装版本:",n),a(!1),h(!0),await b(n)}catch(R){console.error("[VersionUpgradeDialog] 安装失败:",R),h(!1)}},N=()=>{h(!1),i("")},U=R=>{R||(i(""),m("stable")),a(R)};return e.jsxs(e.Fragment,{children:[e.jsxs(me,{open:s,onOpenChange:U,children:[e.jsx(Se,{asChild:!0,children:r||e.jsxs(C,{className:"flex items-center gap-2",children:[e.jsx(ws,{className:"h-4 w-4"}),"升级版本"]})}),e.jsxs(oe,{className:"sm:max-w-md",children:[e.jsxs(ie,{children:[e.jsx(ce,{children:"选择安装版本"}),e.jsx(pe,{children:"请选择要安装的 xiaozhi-client 版本"})]}),e.jsx("div",{className:"space-y-4 py-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{htmlFor:"version-select",className:"text-sm font-medium",children:"版本选择"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(Ge,{value:c,onValueChange:p,children:[e.jsx(Te,{id:"version-type-select",className:"w-[150px]",children:e.jsx(Qe,{placeholder:"请选择版本类型"})}),e.jsx(Re,{children:Sn.map(R=>e.jsx(ue,{value:R.value,children:R.label},R.value))})]}),e.jsxs(Ge,{value:n,onValueChange:S,disabled:d,children:[e.jsx(Te,{id:"version-select",children:e.jsx(Qe,{placeholder:d?"正在获取版本列表...":"请选择版本"})}),e.jsx(Re,{children:d?e.jsx(ue,{value:"loading",disabled:!0,children:"正在获取版本列表..."}):f.length===0?e.jsx(ue,{value:"empty",disabled:!0,children:"暂无可用版本"}):f.map(R=>e.jsx(ue,{value:R.value,children:R.label},R.value))})]})]}),!d&&f.length===0&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"当前版本类型暂无可用版本"}),n&&da.lt(n,"1.8.0")&&e.jsxs(Mt,{variant:"destructive",children:[e.jsx(Jr,{size:18}),e.jsx(ir,{children:"重要提醒"}),e.jsx(zt,{children:"指定版本低于1.8.0,安装后无法再使用Web界面重装,需手动通过命令操作,请谨慎操作!"})]})]})}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(C,{variant:"outline",onClick:()=>a(!1),children:"取消"}),e.jsx(C,{onClick:E,disabled:!n||d,children:"确定安装"})]})]})]}),e.jsx(cr,{isOpen:g,onClose:N,version:n})]})}function lr({className:r}){const[t,s]=o.useState(null),[a,n]=o.useState(null),[i,c]=o.useState(!0),[m,g]=o.useState(!0),[h,f]=o.useState(null),[x,d]=o.useState(!1);o.useEffect(()=>{(async()=>{try{c(!0),f(null);const S=await $.getVersion();s(S)}catch(S){f(S instanceof Error?S.message:"获取版本信息失败"),console.error("获取版本信息失败:",S)}finally{c(!1)}})()},[]),o.useEffect(()=>{t&&(async()=>{try{g(!0);const S=await $.getLatestVersion();n(S)}catch(S){console.error("检查更新失败:",S),n({currentVersion:(t==null?void 0:t.version)||"unknown",latestVersion:null,hasUpdate:!1,error:S instanceof Error?S.message:"检查更新失败"})}finally{g(!1)}})()},[t]);const l=async()=>{if(t!=null&&t.version)try{await navigator.clipboard.writeText(t.version),d(!0),setTimeout(()=>d(!1),2e3)}catch(p){console.error("复制版本号失败:",p)}};if(i)return e.jsx(se,{variant:"outline",className:r,children:e.jsx("span",{className:"text-xs",children:"加载中..."})});if(h||!t)return e.jsx(se,{variant:"outline",className:r,children:e.jsx("span",{className:"text-xs text-muted-foreground",children:"版本未知"})});const b=e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Kr,{className:"h-3 w-3"}),e.jsx("span",{className:"font-semibold",children:"版本详情"})]}),e.jsxs("div",{className:"text-xs space-y-0.5",children:[e.jsxs("div",{children:[e.jsx("strong",{children:"名称:"})," ",t.name]}),e.jsxs("div",{children:[e.jsx("strong",{children:"版本:"})," ",t.version]}),a&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("strong",{children:"最新版本:"})," ",a.latestVersion||"未知"]}),e.jsxs("div",{children:[e.jsx("strong",{children:"状态:"}),m?"检查中...":a.hasUpdate?"有新版本":"已是最新"]})]}),e.jsxs("div",{children:[e.jsx("strong",{children:"描述:"})," ",t.description]}),e.jsxs("div",{children:[e.jsx("strong",{children:"作者:"})," ",t.author]})]}),e.jsx("div",{className:"pt-1 border-t",children:e.jsxs("button",{type:"button",onClick:l,className:"text-xs text-primary hover:underline flex items-center gap-1",children:[e.jsx(ns,{className:"h-3 w-3"}),x?"已复制!":"复制版本号"]})})]}),j=()=>m?null:a!=null&&a.hasUpdate&&a.latestVersion?e.jsx(Jt,{defaultSelectedVersion:a.latestVersion,children:e.jsxs(C,{variant:"link",className:"p-0 gap-1",children:[e.jsx(Gr,{}),"升级版本"]})}):e.jsx(Jt,{defaultSelectedVersion:t.version,children:e.jsx(C,{variant:"link",className:"p-0 gap-1",children:"切换版本"})});return e.jsx(Ms,{children:e.jsxs("div",{className:"flex items-center gap-2",children:[j(),e.jsxs(zs,{children:[e.jsx(Ws,{asChild:!0,children:e.jsxs("span",{className:"text-sm cursor-help",children:["v",t.version]})}),e.jsx(Nt,{children:b})]})]})})}function dr({title:r}){return e.jsxs("header",{className:"group-has-data-[collapsible=icon]/sidebar-wrapper:h-12 flex h-12 shrink-0 items-center gap-2 border-b transition-[width,height] ease-linear pr-4",children:[e.jsxs("div",{className:"flex w-full items-center gap-2 px-4 box-border",children:[e.jsx(As,{className:"-ml-1"}),e.jsx(yt,{orientation:"vertical",className:"mx-2 data-[orientation=vertical]:h-4"}),e.jsx("h1",{className:"text-base font-medium",children:r})]}),e.jsxs("div",{className:"flex w-full justify-end items-center gap-4 box-border",children:[e.jsx(lr,{}),e.jsx("a",{href:"https://img.shields.io/badge/Join-QQ%20Group-5865F2?style=flat&logo=qq&logoColor=white)](https://qun.qq.com/universal-share/share?ac=1&authKey=c08PvS2zvAF1NN%2F%2BuaOi0ze1AElTIsvFBLwbWUMFc2ixjaZYxqZTUQHzipwd8Kka&busi_data=eyJncm91cENvZGUiOiIxMDU0ODg4NDczIiwidG9rZW4iOiJuSmJUN2cyUEVkNEQ5WXovM3RQbFVNcDluMGVibUNZTUQvL1RuQnFJRjBkZmRZQnRBRTdwU0szL3V2Y0dLc1ZmIiwidWluIjoiMzkxMTcyMDYwMCJ9&data=9cH6_zEC-sN3xYlwzKEWiYF71RLY9CId5taN-gy6XZo7axSlSWDpd1Ojui5hYMQKIgEJYSPw59XYgF5vH2wLog&svctype=4&tempid=h5_group_info",target:"_blank",rel:"noopener noreferrer",children:e.jsx(bn,{size:24,className:"text-slate-800",fill:"currentColor"})}),e.jsx("a",{href:"https://github.com/shenjingnan/xiaozhi-client",target:"_blank",rel:"noopener noreferrer",children:e.jsx(wn,{size:24,className:"text-slate-800",fill:"currentColor"})})]})]})}class yn{constructor(){V(this,"apiClient");V(this,"webSocketManager");V(this,"initialized",!1);this.apiClient=$,this.webSocketManager=L}async initialize(){this.initialized||(console.log("[NetworkService] 初始化网络服务"),this.webSocketManager.connect(),this.initialized=!0,console.log("[NetworkService] 网络服务初始化完成"))}destroy(){console.log("[NetworkService] 销毁网络服务"),this.webSocketManager.disconnect(),this.initialized=!1}async getConfig(){return this.apiClient.getConfig()}async updateConfig(t){return this.apiClient.updateConfig(t)}async getStatus(){return this.apiClient.getStatus()}async getClientStatus(){return this.apiClient.getClientStatus()}async restartService(){return this.apiClient.restartService()}async stopService(){return this.apiClient.stopService()}async startService(){return this.apiClient.startService()}async getServiceStatus(){return this.apiClient.getServiceStatus()}async getServiceHealth(){return this.apiClient.getServiceHealth()}async getMcpEndpoint(){return this.apiClient.getMcpEndpoint()}async getMcpEndpoints(){return this.apiClient.getMcpEndpoints()}async getMcpServers(){return this.apiClient.getMcpServers()}async getConnectionConfig(){return this.apiClient.getConnectionConfig()}async reloadConfig(){return this.apiClient.reloadConfig()}async getConfigPath(){return this.apiClient.getConfigPath()}async checkConfigExists(){return this.apiClient.checkConfigExists()}async getRestartStatus(){return this.apiClient.getRestartStatus()}async checkClientConnected(){return this.apiClient.checkClientConnected()}async getLastHeartbeat(){return this.apiClient.getLastHeartbeat()}async getActiveMCPServers(){return this.apiClient.getActiveMCPServers()}async updateClientStatus(t){return this.apiClient.updateClientStatus(t)}async setActiveMCPServers(t){return this.apiClient.setActiveMCPServers(t)}async resetStatus(){return this.apiClient.resetStatus()}getWebSocketState(){return this.webSocketManager.getState()}isWebSocketConnected(){return this.webSocketManager.isConnected()}setWebSocketUrl(t){this.webSocketManager.setUrl(t)}onWebSocketEvent(t,s){this.webSocketManager.on(t,s)}offWebSocketEvent(t){this.webSocketManager.off(t)}reconnectWebSocket(){this.webSocketManager.disconnect(),setTimeout(()=>{this.webSocketManager.connect()},1e3)}async getFullAppState(){const[t,s]=await Promise.all([this.getConfig(),this.getStatus()]);return{config:t,status:s,webSocketConnected:this.isWebSocketConnected()}}async updateConfigWithNotification(t,s=5e3){return new Promise((a,n)=>{const i=setTimeout(()=>{this.webSocketManager.off("configUpdate"),n(new Error("等待配置更新通知超时"))},s);this.webSocketManager.on("configUpdate",()=>{clearTimeout(i),this.webSocketManager.off("configUpdate"),a()}),this.updateConfig(t).catch(c=>{clearTimeout(i),this.webSocketManager.off("configUpdate"),n(c)})})}async restartServiceWithNotification(t=3e4){return new Promise((s,a)=>{const n=setTimeout(()=>{this.webSocketManager.off("restartStatus"),a(new Error("等待重启状态通知超时"))},t);this.webSocketManager.on("restartStatus",i=>{i.status==="completed"?(clearTimeout(n),this.webSocketManager.off("restartStatus"),s()):i.status==="failed"&&(clearTimeout(n),this.webSocketManager.off("restartStatus"),a(new Error(i.error||"服务重启失败")))}),this.restartService().catch(i=>{clearTimeout(n),this.webSocketManager.off("restartStatus"),a(i)})})}}const q=new yn;function Nn(){const r=Ys(),t=o.useRef(!1);o.useEffect(()=>{if(!t.current)return console.log("[NetworkService] 初始化网络服务"),t.current=!0,q.initialize().catch(l=>{console.error("[NetworkService] 初始化失败:",l)}),q.onWebSocketEvent("connected",()=>{console.log("[NetworkService] WebSocket 已连接"),r.setConnectionState(G.CONNECTED),s()}),q.onWebSocketEvent("disconnected",()=>{console.log("[NetworkService] WebSocket 已断开"),r.setConnectionState(G.DISCONNECTED)}),q.onWebSocketEvent("configUpdate",l=>{console.log("[NetworkService] 收到配置更新通知"),ne.getState().setConfig(l,"websocket")}),q.onWebSocketEvent("statusUpdate",l=>{console.log("[NetworkService] 收到状态更新通知"),ae.getState().setClientStatus(l,"websocket")}),q.onWebSocketEvent("restartStatus",l=>{console.log("[NetworkService] 收到重启状态通知:",l),ae.getState().setRestartStatus(l,"websocket")}),q.onWebSocketEvent("error",l=>{console.error("[NetworkService] WebSocket 错误:",l)}),()=>{console.log("[NetworkService] 清理网络服务"),q.destroy(),t.current=!1}},[r]);const s=o.useCallback(async()=>{try{console.log("[NetworkService] 加载初始数据");const[l,b]=await Promise.all([q.getConfig(),q.getClientStatus()]);console.log("[NetworkService] 初始数据加载成功"),ne.getState().setConfig(l,"http"),ae.getState().setClientStatus(b,"http")}catch(l){console.error("[NetworkService] 加载初始数据失败:",l)}},[]),a=o.useCallback(async()=>{try{const l=await q.getConfig();return ne.getState().setConfig(l,"http"),l}catch(l){throw console.error("[NetworkService] 获取配置失败:",l),l}},[]),n=o.useCallback(async l=>{try{console.log("[NetworkService] 更新配置"),await q.updateConfig(l),ne.getState().setConfig(l,"http"),console.log("[NetworkService] 配置更新成功")}catch(b){throw console.error("[NetworkService] 配置更新失败:",b),b}},[]),i=o.useCallback(async()=>{try{const l=await q.getStatus();return ae.getState().setClientStatus(l.client,"http"),l}catch(l){throw console.error("[NetworkService] 获取状态失败:",l),l}},[]),c=o.useCallback(async()=>{try{await i()}catch(l){console.error("[NetworkService] 刷新状态失败:",l)}},[i]),m=o.useCallback(async()=>{try{console.log("[NetworkService] 重启服务"),await q.restartService(),console.log("[NetworkService] 重启请求已发送")}catch(l){throw console.error("[NetworkService] 重启服务失败:",l),l}},[]),g=o.useCallback(async(l=3e4)=>{try{console.log("[NetworkService] 重启服务并等待通知"),await q.restartServiceWithNotification(l),console.log("[NetworkService] 服务重启完成")}catch(b){throw console.error("[NetworkService] 重启服务失败:",b),b}},[]),h=o.useCallback(async(l,b=5e3)=>{try{console.log("[NetworkService] 更新配置并等待通知"),await q.updateConfigWithNotification(l,b),console.log("[NetworkService] 配置更新完成")}catch(j){throw console.error("[NetworkService] 配置更新失败:",j),j}},[]),f=o.useCallback(l=>{console.log("[NetworkService] 设置自定义 WebSocket URL:",l),q.setWebSocketUrl(l),r.setWsUrl(l)},[r]),x=o.useCallback(async l=>{try{console.log(`[NetworkService] 切换到端口 ${l}`),r.setPortChangeStatus({status:"checking",targetPort:l,timestamp:Date.now()});const b=window.location.protocol==="https:"?"wss:":"ws:",j=window.location.hostname,p=`${b}//${j}:${l}`;await m(),await new Promise(S=>setTimeout(S,5e3)),f(p),window.location.reload()}catch(b){throw console.error("[NetworkService] 端口切换失败:",b),r.setPortChangeStatus({status:"failed",targetPort:l,error:b instanceof Error?b.message:"端口切换失败",timestamp:Date.now()}),b}},[r,m,f]),d=o.useCallback(()=>{const l=localStorage.getItem("xiaozhi-ws-url");if(l)return l;const b=window.location.protocol==="https:"?"wss:":"ws:",j=window.location.hostname,p=window.location.port;return`${b}//${j}${p?`:${p}`:""}`},[]);return{getConfig:a,updateConfig:n,getStatus:i,refreshStatus:c,restartService:m,updateConfigWithNotification:h,restartServiceWithNotification:g,setCustomWsUrl:f,getWebSocketUrl:d,changePort:x,loadInitialData:s,isWebSocketConnected:()=>q.isWebSocketConnected(),getWebSocketState:()=>q.getWebSocketState()}}async function Cn(){console.log("[Stores] 开始初始化所有 stores");try{console.log("[Stores] 初始化 WebSocket store"),qe.getState().initialize(),console.log("[Stores] 初始化配置 store"),await ne.getState().initialize(),console.log("[Stores] 初始化状态 store"),await ae.getState().initialize(),console.log("[Stores] 所有 stores 初始化完成")}catch(r){throw console.error("[Stores] Stores 初始化失败:",r),r}}const ur=o.createContext(null);function kn({children:r}){const t=Nn(),[s,a]=o.useState(!1);return o.useEffect(()=>{let n=!0;return(async()=>{try{console.log("[WebSocketProvider] 开始初始化 stores"),await Cn(),n&&(a(!0),console.log("[WebSocketProvider] Stores 初始化完成"))}catch(c){console.error("[WebSocketProvider] Stores 初始化失败:",c),n&&a(!0)}})(),()=>{n=!1}},[]),s?e.jsx(ur.Provider,{value:t,children:r}):e.jsx("div",{className:"flex items-center justify-center min-h-screen",children:e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-2"}),e.jsx("p",{className:"text-sm text-gray-600",children:"正在初始化应用..."})]})})}function En(){const r=o.useContext(ur);if(!r)throw new Error("useNetworkServiceActions must be used within a NetworkServiceProvider");return r}const Pn=kn,mr=En;function Tn(){const{updateConfig:r}=mr();return e.jsxs(Ct,{children:[e.jsx(Vs,{variant:"inset"}),e.jsxs(kt,{children:[e.jsx(dr,{title:"看板"}),e.jsx("div",{className:"flex flex-1 flex-col",children:e.jsx("div",{className:"@container/main flex flex-1 flex-col gap-2",children:e.jsxs("div",{className:"flex flex-col gap-4 py-4 md:gap-6 md:py-6",children:[e.jsx(rn,{}),e.jsx(xn,{updateConfig:r})]})})})]})]})}function Rn(){const[r,t]=o.useState(null),[s,a]=o.useState(null),[n,i]=o.useState(!1),[c,m]=o.useState(null),[g,h]=o.useState(!1),[f,x]=o.useState(""),d=o.useCallback(async()=>{try{m(null);const p=await $.getVersion();t(p),console.log("[VersionManager] 当前版本信息:",p)}catch(p){const S=p instanceof Error?p.message:"获取版本信息失败";m(S),console.error("[VersionManager] 获取版本信息失败:",p)}},[]),l=async()=>{if(r)try{i(!0),m(null),console.log("[VersionManager] 检查更新..."),await new Promise(S=>setTimeout(S,1e3));const p={currentVersion:r.version,latestVersion:"1.8.0",updateAvailable:!0,releaseNotes:`• 修复了若干 bug
30
+ }`,...h})}),e.jsx(ee,{})]})})}),e.jsxs(xe,{className:"mt-4",children:[e.jsx(rt,{asChild:!0,children:e.jsx(C,{variant:"outline",disabled:s,children:"取消"})}),e.jsx(C,{type:"submit",disabled:s,children:s?"保存中...":"保存"})]})]})})})]})}class un{constructor(t){V(this,"baseUrl");if(t)this.baseUrl=t;else{const s=window.location.protocol,a=window.location.hostname,n=window.location.port;this.baseUrl=`${s}//${a}${n?`:${n}`:""}`}}async request(t,s={}){var c;const a=`${this.baseUrl}${t}`,n={headers:{"Content-Type":"application/json",...s.headers}},i=await fetch(a,{...n,...s});if(!i.ok){let m=`HTTP ${i.status}: ${i.statusText}`;try{m=((c=(await i.json()).error)==null?void 0:c.message)||m}catch{}throw new Error(m)}return i.json()}async fetchWorkspaces(){try{const t=await this.request("/api/coze/workspaces");if(!t.success||!t.data)throw new Error(t.message||"获取工作空间列表失败");return t.data}catch(t){throw console.error("获取工作空间列表失败:",t),t}}async fetchWorkflows(t){try{const s=new URLSearchParams;s.append("workspace_id",t.workspace_id),t.page_num!==void 0&&s.append("page_num",t.page_num.toString()),t.page_size!==void 0&&s.append("page_size",t.page_size.toString());const a=await this.request(`/api/coze/workflows?${s.toString()}`);if(!a.success||!a.data)throw new Error(a.message||"获取工作流列表失败");return a.data}catch(s){throw console.error("获取工作流列表失败:",s),s}}async clearCache(){try{const t=await this.request("/api/coze/cache/clear",{method:"POST"});if(!t.success)throw new Error(t.message||"清除缓存失败")}catch(t){throw console.error("清除缓存失败:",t),t}}async getCacheStats(){try{const t=await this.request("/api/coze/cache/stats");if(!t.success||!t.data)throw new Error(t.message||"获取缓存统计失败");return t.data}catch(t){throw console.error("获取缓存统计失败:",t),t}}}const He=new un;function mn(r={}){const{autoLoadWorkspaces:t=!0,autoLoadWorkflows:s=!0,defaultPageSize:a=20,initialWorkspaceId:n}=r,[i,c]=o.useState([]),[m,g]=o.useState([]),[h,f]=o.useState(n||null),[x,d]=o.useState({selectedWorkspaceId:n||null,workspacesLoading:!1,workflowsLoading:!1,workspacesError:null,workflowsError:null}),[l,b]=o.useState(1),[j,p]=o.useState(a),[S,E]=o.useState(!1),N=o.useMemo(()=>i&&Array.isArray(i)&&i.find(A=>A.id===h)||null,[i,h]),U=o.useCallback(async()=>{d(A=>({...A,workspacesLoading:!0,workspacesError:null}));try{const A=await He.fetchWorkspaces();c(A.workspaces),d(u=>({...u,workspacesLoading:!1}))}catch(A){const u=A instanceof Error?A.message:"加载工作空间失败";d(I=>({...I,workspacesLoading:!1,workspacesError:u})),console.error("加载工作空间失败:",A)}},[]),R=o.useCallback(async(A={})=>{const u=A.workspace_id||h;if(!u){console.warn("无法加载工作流:未选择工作空间");return}d(I=>({...I,workflowsLoading:!0,workflowsError:null}));try{const I={workspace_id:u,page_num:A.page_num||l,page_size:A.page_size||j},P=await He.fetchWorkflows(I);g(P.items),E(P.hasMore),d(M=>({...M,workflowsLoading:!1}))}catch(I){const P=I instanceof Error?I.message:"加载工作流失败";d(M=>({...M,workflowsLoading:!1,workflowsError:P})),console.error("加载工作流失败:",I)}},[h,l,j]),O=o.useCallback(A=>{f(A),d(u=>({...u,selectedWorkspaceId:A})),g([]),b(1),E(!1),s&&A&&R({workspace_id:A,page_num:1})},[s,R]),F=o.useCallback(async()=>{await U()},[U]),Z=o.useCallback(async()=>{h&&await R({workspace_id:h,page_num:l})},[R,h,l]),le=o.useCallback(async()=>{try{await He.clearCache(),t&&await U(),s&&h&&await R({workspace_id:h,page_num:1})}catch(A){throw console.error("清除缓存失败:",A),A}},[t,s,h,U,R]),fe=o.useCallback(A=>{b(A),h&&R({workspace_id:h,page_num:A})},[h,R]),he=o.useCallback(A=>{p(A),b(1),h&&R({workspace_id:h,page_num:1,page_size:A})},[h,R]);return o.useEffect(()=>{t&&U()},[t,U]),o.useEffect(()=>{s&&h&&(async()=>{d(u=>({...u,workflowsLoading:!0,workflowsError:null}));try{const u={workspace_id:h,page_num:1,page_size:j},I=await He.fetchWorkflows(u);g(I.items),E(I.hasMore),d(P=>({...P,workflowsLoading:!1}))}catch(u){const I=u instanceof Error?u.message:"加载工作流失败";d(P=>({...P,workflowsLoading:!1,workflowsError:I})),console.error("加载工作流失败:",u)}})()},[s,h,j]),{workspaces:i,workflows:m,selectedWorkspace:N,workspacesLoading:x.workspacesLoading,workflowsLoading:x.workflowsLoading,workspacesError:x.workspacesError,workflowsError:x.workflowsError,hasMoreWorkflows:S,selectWorkspace:O,loadWorkflows:R,refreshWorkspaces:F,refreshWorkflows:Z,clearCache:le,setWorkflows:g,currentPage:l,pageSize:j,setPage:fe,setPageSize:he}}function fn({onToolAdded:r}){var Wt;const[t,s]=o.useState(!1),[a,n]=o.useState(!1),[i,c]=o.useState({open:!1,action:"add"}),[m,g]=o.useState({open:!1}),[h,f]=o.useState(navigator.onLine),[x,d]=o.useState(new Set),[l,b]=o.useState(!1),{workspaces:j,workflows:p,selectedWorkspace:S,workspacesLoading:E,workflowsLoading:N,workspacesError:U,workflowsError:R,hasMoreWorkflows:O,currentPage:F,selectWorkspace:Z,refreshWorkflows:le,setPage:fe,setWorkflows:he}=mn({autoLoadWorkspaces:!0,autoLoadWorkflows:!0});o.useEffect(()=>{const T=()=>f(!0),B=()=>f(!1);return window.addEventListener("online",T),window.addEventListener("offline",B),()=>{window.removeEventListener("online",T),window.removeEventListener("offline",B)}},[]),o.useEffect(()=>{if(!E&&j.length>0&&!S&&!l){const T=j[0];console.log(`自动选择第一个工作空间: ${T.name}`),Z(T.id),b(!0)}E&&l&&b(!1)},[j,E,S,l,Z]);const A=T=>{b(!0),Z(T)},u=T=>{if(!h){y.error("网络连接已断开,请检查网络后重试");return}const B=`add_${T.workflow_id}`;if(x.has(B)){y.warning("该工作流正在添加中,请勿重复操作");return}g({open:!0,workflow:T})},I=async(T,B)=>{const _=`add_${T.workflow_id}`;n(!0),d(D=>new Set(D).add(_));try{if(!T.workflow_id||!T.workflow_name||!T.app_id)throw new Error("工作流数据不完整,缺少必要字段");if(!h)throw new Error("网络连接已断开,请检查网络后重试");const D=B.length>0?{parameters:B}:void 0,K={type:"coze",data:{workflow:T,customName:void 0,customDescription:void 0,parameterConfig:D}},be=await $.addCustomTool(K);y.success(`已添加工作流 "${T.workflow_name}" 为 MCP 工具 "${be.name}"${B.length>0?`,配置了 ${B.length} 个参数`:""}`),he(pr=>pr.map(ot=>ot.workflow_id===T.workflow_id?{...ot,isAddedAsTool:!0,toolName:be.name}:ot)),r==null||r(),await le()}catch(D){console.error("添加工作流失败:",D);let K="添加工作流失败,请重试";D instanceof Error&&(D.message.includes("已存在")||D.message.includes("冲突")?K=`工作流 "${T.workflow_name}" 已存在,请勿重复添加`:D.message.includes("配置")||D.message.includes("token")?K="系统配置错误,请检查扣子API配置":D.message.includes("验证失败")||D.message.includes("格式")?K="工作流数据格式错误,请联系管理员":D.message.includes("网络")||D.message.includes("超时")||D.message.includes("连接")?K="网络连接失败,请检查网络后重试":D.message.includes("权限")?K="权限不足,请检查API权限配置":D.message.includes("频繁")?K="操作过于频繁,请稍后重试":K=D.message),y.error(K)}finally{n(!1),d(D=>{const K=new Set(D);return K.delete(_),K}),g({open:!1})}},P=()=>{g({open:!1})},M=async T=>{const B=`add_${T.workflow_id}`;n(!0),d(_=>new Set(_).add(B));try{if(!T.workflow_id||!T.workflow_name||!T.app_id)throw new Error("工作流数据不完整,缺少必要字段");if(!h)throw new Error("网络连接已断开,请检查网络后重试");const _={type:"coze",data:{workflow:T,customName:void 0,customDescription:void 0,parameterConfig:void 0}},D=await $.addCustomTool(_);y.success(`已添加工作流 "${T.workflow_name}" 为 MCP 工具 "${D.name}"`),he(K=>K.map(be=>be.workflow_id===T.workflow_id?{...be,isAddedAsTool:!0,toolName:D.name}:be)),r==null||r(),await le()}catch(_){console.error("添加工作流失败:",_);let D="添加工作流失败,请重试";_ instanceof Error&&(_.message.includes("已存在")||_.message.includes("冲突")?D=`工作流 "${T.workflow_name}" 已存在,请勿重复添加`:_.message.includes("配置")||_.message.includes("token")?D="系统配置错误,请检查扣子API配置":_.message.includes("验证失败")||_.message.includes("格式")?D="工作流数据格式错误,请联系管理员":_.message.includes("网络")||_.message.includes("超时")||_.message.includes("连接")?D="网络连接失败,请检查网络后重试":_.message.includes("权限")?D="权限不足,请检查API权限配置":_.message.includes("频繁")?D="操作过于频繁,请稍后重试":D=_.message),y.error(D)}finally{n(!1),d(_=>{const D=new Set(_);return D.delete(B),D}),c({open:!1,action:"add"})}},v=()=>{F>1&&fe(F-1)},k=()=>{O&&fe(F+1)},z=()=>{S&&le()},W=()=>e.jsx("div",{className:"space-y-2",children:U?e.jsxs("div",{className:"flex items-center gap-2 p-3 text-sm text-red-600 bg-red-50 rounded-md",children:[e.jsx(Je,{className:"h-4 w-4"}),e.jsxs("span",{children:["加载工作空间失败: ",U]})]}):e.jsxs(Ge,{value:(S==null?void 0:S.id)||"",onValueChange:A,disabled:E,children:[e.jsx(Te,{children:e.jsx(Qe,{placeholder:E?"加载中...":"请选择工作空间"})}),e.jsx(Re,{children:j.map(T=>e.jsx(ue,{value:T.id,children:e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("span",{children:T.name})})},T.id))})]})}),nt=()=>S?R?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Je,{className:"h-12 w-12 text-red-500 mb-4"}),e.jsx("h3",{className:"text-lg font-medium mb-2",children:"加载工作流失败"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:R}),e.jsxs(C,{onClick:z,variant:"outline",children:[e.jsx(bs,{className:"h-4 w-4 mr-2"}),"重试"]})]}):N?e.jsx("div",{className:"space-y-3",children:Array.from({length:3},(T,B)=>B).map(T=>e.jsxs("div",{className:"flex items-center gap-4 p-4 border rounded-lg",children:[e.jsx(we,{className:"w-10 h-10 rounded-lg","data-testid":"skeleton"}),e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsx(we,{className:"h-4 w-1/3","data-testid":"skeleton"}),e.jsx(we,{className:"h-3 w-2/3","data-testid":"skeleton"})]}),e.jsx(we,{className:"w-16 h-8","data-testid":"skeleton"})]},`skeleton-${T}`))}):p.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Ne,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-medium mb-2",children:"暂无工作流"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"当前工作空间下没有可用的工作流"})]}):e.jsx("div",{className:"space-y-3 max-h-[500px] overflow-auto",children:p.map(T=>e.jsxs("div",{className:"flex items-center gap-4 p-4 border rounded-lg hover:bg-slate-50 transition-colors",children:[e.jsx("div",{className:"flex-shrink-0 w-10 h-10 bg-green-100 rounded-lg flex items-center justify-center text-lg",children:e.jsx(Ne,{className:"h-5 w-5 text-green-600"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("h4",{className:"font-medium text-sm truncate",children:T.workflow_name}),e.jsx(se,{variant:"secondary",className:"text-xs",children:"工作流"})]}),e.jsx("p",{className:"text-sm text-muted-foreground line-clamp-2",children:T.description||"暂无描述"})]}),e.jsx("div",{className:"flex-shrink-0",children:T.isAddedAsTool?e.jsx(se,{variant:"secondary",className:"text-xs bg-green-100 text-green-800",children:"已添加"}):e.jsxs(C,{size:"sm",onClick:()=>u(T),disabled:a,children:[a?e.jsx(Ce,{className:"h-4 w-4 animate-spin","data-testid":"loader"}):e.jsx(Me,{className:"h-4 w-4"}),"添加"]})})]},T.workflow_id))}):e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Ne,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-medium mb-2",children:"请先选择工作空间"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"选择一个工作空间后,将显示该空间下的工作流列表"})]}),hr=()=>!S||p.length===0?null:e.jsx("div",{className:"flex items-center justify-end",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(C,{variant:"link",size:"sm",onClick:v,disabled:F===1,className:"text-muted-foreground",children:e.jsx(Vr,{className:"h-4 w-4"})}),e.jsx("div",{className:"flex items-center gap-1",children:e.jsx("span",{className:"text-sm",children:F})}),e.jsx(C,{variant:"link",size:"sm",onClick:k,disabled:!O,className:"text-muted-foreground",children:e.jsx(qr,{className:"h-4 w-4"})})]})});return e.jsxs(e.Fragment,{children:[e.jsxs(me,{open:t,onOpenChange:s,children:[e.jsx(Se,{asChild:!0,children:e.jsxs(C,{variant:"outline",className:"w-full",children:[e.jsx(Ne,{className:"h-4 w-4 mr-2"}),"工作流集成"]})}),e.jsxs(oe,{className:"flex flex-col max-w-full w-[1000px]",children:[e.jsx(ie,{className:"flex-shrink-0",children:e.jsxs(ce,{className:"flex items-center gap-2",children:[e.jsx(Ne,{className:"h-5 w-5"}),"工作流集成"]})}),e.jsx("div",{className:"w-[120px]",children:W()}),e.jsx("div",{className:"flex-1 pr-2 w-full",children:nt()}),hr()]})]}),m.workflow&&e.jsx(sr,{open:m.open,onOpenChange:T=>g(B=>({...B,open:T})),workflow:m.workflow,onConfirm:I,onCancel:P,title:"配置工作流参数"}),e.jsx(st,{open:i.open,onOpenChange:T=>c(B=>({...B,open:T})),children:e.jsxs(De,{children:[e.jsxs($e,{children:[e.jsx(Le,{children:"确认添加工作流"}),e.jsxs(Oe,{children:['确定要将工作流 "',(Wt=i.workflow)==null?void 0:Wt.workflow_name,'" 添加为 MCP 工具吗?']})]}),e.jsxs(Ae,{children:[e.jsx(_e,{children:"取消"}),e.jsx(Ue,{onClick:()=>{i.workflow&&M(i.workflow)},children:"添加"})]})]})})]})}const hn=J.object({config:J.string().min(2,{message:"配置不能为空"})});function pn({mcpServer:r,mcpServerName:t}){const[s,a]=o.useState(!1),[n,i]=o.useState(!1),c=ye(),{updateConfig:m}=Zs(),g=ze({resolver:We(hn),defaultValues:{config:JSON.stringify(r,null,2)}});async function h(f){if(!c){y.error("配置数据未加载,请稍后重试");return}i(!0);try{let x;try{x=JSON.parse(f.config)}catch{y.error("JSON格式错误,请检查配置格式");return}if(!x||typeof x!="object"){y.error("配置格式无效");return}const d={...c,mcpServers:{...c.mcpServers,[t]:x}};await m(d),y.success("MCP服务器配置已更新"),a(!1)}catch(x){console.error("更新配置失败:",x),y.error(x instanceof Error?x.message:"更新配置失败")}finally{i(!1)}}return e.jsxs(me,{open:s,onOpenChange:a,children:[e.jsx(Se,{asChild:!0,children:e.jsx(C,{variant:"secondary",size:"icon",className:"size-8",children:e.jsx(Ie,{className:"h-4 w-4"})})}),e.jsx(oe,{className:"sm:max-w-[500px]",children:e.jsx(Ve,{...g,children:e.jsxs("form",{onSubmit:g.handleSubmit(h),children:[e.jsxs(ie,{className:"mb-4",children:[e.jsxs(ce,{children:["配置 ",t," MCP"]}),e.jsx(pe,{children:"点击保存后,需要重启服务才会生效。"})]}),e.jsx("div",{className:"grid gap-4",children:e.jsx(X,{control:g.control,name:"config",render:({field:f})=>e.jsxs(Q,{children:[e.jsx(Y,{children:e.jsx(It,{placeholder:"MCP服务配置",className:"resize-none h-[300px] font-mono text-sm",disabled:n,...f})}),e.jsx(ee,{})]})})}),e.jsxs(xe,{className:"mt-4",children:[e.jsx(rt,{asChild:!0,children:e.jsx(C,{variant:"outline",disabled:n,children:"取消"})}),e.jsx(C,{type:"submit",disabled:n,children:n?"保存中...":"保存"})]})]})})})]})}function gn({mcpServerName:r,onRemoveSuccess:t,disabled:s=!1}){const[a,n]=o.useState(!1),i=async()=>{try{if(n(!0),!await ut.removeServer(r))throw new Error("删除服务器失败");y.success(`MCP 服务 "${r}" 已删除`),t&&await t()}catch(c){console.error("删除 MCP 服务失败:",c),y.error(`删除 MCP 服务失败: ${c instanceof Error?c.message:"未知错误"}`)}finally{n(!1)}};return e.jsxs(st,{children:[e.jsx(qa,{asChild:!0,children:e.jsx(C,{variant:"destructive",size:"icon",className:"size-8",disabled:s||a,children:e.jsx(os,{className:"h-4 w-4"})})}),e.jsxs(De,{children:[e.jsxs($e,{children:[e.jsxs(Le,{children:["确定要删除这个(",r,")MCP服务吗?"]}),e.jsx(Oe,{children:"删除后,对应的工具列表也会移除。"})]}),e.jsxs(Ae,{children:[e.jsx(_e,{children:"取消"}),e.jsx(Ue,{onClick:i,disabled:s||a,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:a?"删除中...":"确定"})]})]})]})}function rr({disabled:r=!1,variant:t="outline",className:s="",restartingText:a="重启中...",defaultText:n="重启服务"}){const{loading:{isRestarting:i},restartService:c}=ae(),m=ks(),g=async()=>{try{await c()}catch(f){console.error("[RestartButton] 重启失败:",f)}},h=()=>i?m.enabled&&m.startTime?"重连中...":a:n;return e.jsxs(C,{type:"button",onClick:g,variant:t,disabled:i||r,className:ys("flex items-center gap-2 w-[120px]",s),children:[i?e.jsx(Ce,{className:"size-4 animate-spin"}):e.jsx(Br,{className:"size-4"}),h()]})}function xn({updateConfig:r}){const t=Ha(),s=Hs(),{refreshConfig:a}=Rt(),[n,i]=o.useState([]),[c,m]=o.useState([]),[g,h]=o.useState(!1),[f,x]=o.useState(null),d=o.useCallback((u,I)=>{var v,k;const{serviceName:P,toolName:M}=(()=>{var z,W;return!u||!u.handler?{serviceName:"unknown",toolName:(u==null?void 0:u.name)||"unknown"}:u.handler.type==="mcp"?{serviceName:((z=u.handler.config)==null?void 0:z.serviceName)||"unknown",toolName:((W=u.handler.config)==null?void 0:W.toolName)||u.name}:u.handler.type==="proxy"&&u.handler.platform==="coze"?{serviceName:"coze",toolName:u.name}:{serviceName:"custom",toolName:u.name}})();return{serverName:P,toolName:M,enable:I,name:u.name,description:u.description,usageCount:(v=u.stats)==null?void 0:v.usageCount,lastUsedTime:(k=u.stats)==null?void 0:k.lastUsedTime,inputSchema:u.inputSchema}},[]),l=o.useCallback(async()=>{h(!0),x(null);try{const[u,I]=await Promise.all([$.getToolsList("enabled"),$.getToolsList("disabled")]),P=u.map(v=>d(v,!0)),M=I.map(v=>d(v,!1));i(P),m(M)}catch(u){console.error("获取工具列表失败:",u);const I=u instanceof Error?u.message:"获取工具列表失败";if(x(I),y.error(I),t){const P=Object.entries(t).flatMap(([k,z])=>Object.entries((z==null?void 0:z.tools)||{}).map(([W,nt])=>({serverName:k,toolName:W,...nt}))),M=P.filter(k=>k.enable!==!1),v=P.filter(k=>k.enable===!1);i(M),m(v)}}finally{h(!1)}},[t,d]),[b,j]=o.useState(!1),p=o.useCallback(async()=>{if(!b)try{j(!0),await Promise.all([a(),l()])}catch(u){console.error("刷新数据失败:",u),y.error("刷新数据失败")}finally{j(!1)}},[a,l,b]),S=o.useCallback(async()=>{try{const[u,I]=await Promise.all([$.getToolsList("enabled"),$.getToolsList("disabled")]),P=u.map(v=>d(v,!0)),M=I.map(v=>d(v,!1));i(P),m(M)}catch(u){console.error("刷新工具列表失败:",u),y.error("刷新工具列表失败")}},[d]);o.useEffect(()=>{l()},[l]);const[E,N]=o.useState(null),[U,R]=o.useState({open:!1}),O=async(u,I)=>{try{if(I){const P=[...n,...c].find(M=>M.name===u);if(!P){y.error("找不到对应的工具信息");return}if(P.serverName==="coze"){N(u);return}await $.removeCustomTool(u),y.success(`删除工具 ${u} 成功`)}else{const P=[...n,...c].find(M=>M.name===u);if(!P){y.error("找不到对应的工具信息");return}P.serverName==="coze"?await $.addCustomTool({workflow_id:"",workflow_name:u,description:P.description||"",icon_url:"",app_id:""},u,P.description||""):await $.addCustomTool({type:"mcp",data:{serviceName:P.serverName,toolName:P.toolName,customName:u,customDescription:P.description||""}}),y.success(`添加工具 ${u} 成功`)}await S()}catch(P){console.error("切换工具状态失败:",P),y.error(P instanceof Error?P.message:"切换工具状态失败")}},F=async()=>{if(E)try{await $.removeCustomTool(E),y.success(`删除工具 ${E} 成功`),await S()}catch(u){console.error("删除 Coze 工具失败:",u),y.error(u instanceof Error?u.message:"删除 Coze 工具失败")}finally{N(null)}},Z=()=>{N(null)},le=u=>{u.serverName==="coze"&&R({open:!0,tool:u})},fe=u=>{var I,P,M;return u.serverName==="coze"&&((I=u.handler)==null?void 0:I.type)==="proxy"?{workflow_id:((P=u.handler.config)==null?void 0:P.workflow_id)||"",workflow_name:u.toolName,description:u.description||"",icon_url:"",app_id:((M=u.handler.config)==null?void 0:M.app_id)||"",creator:{id:"",name:""},created_at:0,updated_at:0,isAddedAsTool:!0,toolName:u.name,inputSchema:u.inputSchema}:{workflow_id:"",workflow_name:u.toolName,description:u.description||"",icon_url:"",app_id:"",creator:{id:"",name:""},created_at:0,updated_at:0,isAddedAsTool:!0,toolName:u.name,inputSchema:u.inputSchema}},he=async(u,I)=>{if(U.tool)try{const P=I.length>0?{parameters:I}:void 0,M=fe(U.tool);u.workflow_id&&(M.workflow_id=u.workflow_id),u.app_id&&(M.app_id=u.app_id);const v={type:"coze",data:{workflow:M,customName:void 0,customDescription:void 0,parameterConfig:P}};await $.updateCustomTool(U.tool.name,v),y.success(`工具 "${M.workflow_name}" 参数配置更新成功`),await S()}catch(P){console.error("更新工具参数配置失败:",P);let M="更新工具参数配置失败,请重试";P instanceof Error&&(M=P.message),y.error(M)}finally{R({open:!1})}},A=()=>{R({open:!1})};return!s||Object.keys(s).length===0?e.jsx("div",{className:"@container/main flex flex-1 flex-col gap-2",children:e.jsxs("div",{className:"flex flex-col gap-4 py-4 md:gap-6 md:py-6",children:[e.jsx("div",{className:"flex items-center justify-between px-4 lg:px-6",children:e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-semibold",children:"你的聚合 MCP 服务"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"在这里管理你的 MCP 服务器和工具。"})]})}),e.jsx("div",{className:"px-4 lg:px-6",children:e.jsx(de,{className:"border-dashed",children:e.jsxs(ve,{className:"flex flex-col items-center justify-center py-12",children:[e.jsx(At,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"还没有 MCP 服务"}),e.jsx("p",{className:"text-sm text-muted-foreground text-center mb-4",children:"添加你的第一个 MCP 服务器来开始使用强大的工具集成功能。"}),e.jsx(Ht,{})]})})})]})}):e.jsxs("div",{className:"flex flex-col gap-4 px-4 lg:px-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold",children:"你的聚合 MCP 服务"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"你可以在这里管理你的 MCP 服务,包括启用/禁用工具,以及查看工具的详细信息。"})]}),b&&e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx("div",{className:"animate-spin rounded-full h-4 w-4 border-b-2 border-primary"}),"刷新中..."]})]}),e.jsxs("div",{className:"*:data-[slot=card]:shadow-xs @xl/main:grid-cols-8 @5xl/main:grid-cols-8 grid grid-cols-1 gap-4 *:data-[slot=card]:bg-gradient-to-t *:data-[slot=card]:from-primary/5 *:data-[slot=card]:to-card dark:*:data-[slot=card]:bg-card",children:[e.jsx(de,{className:"transition-all duration-200 col-span-3",children:e.jsx(ve,{className:"p-4",children:e.jsxs("div",{className:"flex-col",children:[e.jsxs("h4",{className:"text-sm font-medium mb-3 flex items-center gap-2",children:[e.jsx(Lt,{className:"h-4 w-4"}),"使用中的工具 (",n.length,")",g&&e.jsx("span",{className:"text-xs text-muted-foreground",children:"(加载中...)"})]}),e.jsx("div",{className:"flex-1 space-y-2",children:g?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx("div",{className:"text-sm text-muted-foreground",children:"加载工具列表中..."})}):f?e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 px-4",children:[e.jsx("div",{className:"text-sm text-red-500 mb-2",children:f}),e.jsx(C,{variant:"outline",size:"sm",onClick:l,children:"重试"})]}):n.map(u=>e.jsxs("div",{className:"flex items-start justify-between p-4 bg-slate-50 rounded-md font-mono",children:[e.jsxs("div",{className:"text-md flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 justify-start",children:[e.jsx(se,{variant:"secondary",className:"rounded-md",children:u.serverName}),e.jsx("span",{children:u.toolName})]}),e.jsx("p",{className:"text-sm text-muted-foreground my-2",children:u.description}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[e.jsx("span",{className:"text-muted-foreground",children:"使用次数:"})," ",e.jsx("span",{className:"text-primary font-bold",children:u.usageCount||0})]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[e.jsx("span",{className:"text-muted-foreground",children:"最后使用:"})," ",e.jsx("span",{className:"text-primary font-bold",children:u.lastUsedTime||"-"})]})]})]}),e.jsxs("div",{className:"flex items-center gap-2 ml-4",children:[u.serverName==="coze"&&e.jsx(C,{variant:"secondary",size:"icon",className:"size-8 hover:bg-blue-500 hover:text-white",onClick:()=>le(u),title:"配置参数",children:e.jsx(Ie,{size:16})}),e.jsx(C,{variant:"secondary",size:"icon",className:"size-8 hover:bg-red-500 hover:text-white",onClick:()=>O(u.name,!0),children:e.jsx(Fr,{size:18})})]})]},u.toolName))})]})})}),e.jsx(de,{className:"transition-all duration-200 col-span-3",children:e.jsx(ve,{className:"p-4",children:e.jsxs("div",{className:"flex-col",children:[e.jsxs("h4",{className:"text-sm font-medium mb-3 flex items-center gap-2",children:[e.jsx(Lt,{className:"h-4 w-4"}),"未使用的工具 (",c.length,")",g&&e.jsx("span",{className:"text-xs text-muted-foreground",children:"(加载中...)"})]}),e.jsx("div",{className:"flex-1 space-y-2",children:g?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx("div",{className:"text-sm text-muted-foreground",children:"加载工具列表中..."})}):f?e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 px-4",children:[e.jsx("div",{className:"text-sm text-red-500 mb-2",children:f}),e.jsx(C,{variant:"outline",size:"sm",onClick:l,children:"重试"})]}):c.length===0?e.jsxs("div",{className:"flex-1 flex flex-col items-center gap-4 py-20 px-4 bg-slate-50 rounded-md font-mono h-full",children:[e.jsx(At,{strokeWidth:1.5,size:48,className:"text-muted-foreground"}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"全部工具都已经启用"})]}):c.map(u=>e.jsxs("div",{className:"flex items-start justify-between p-4 bg-slate-50 rounded-md font-mono",children:[e.jsxs("div",{className:"text-md flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 justify-start",children:[e.jsx(se,{variant:"secondary",className:"rounded-md",children:u.serverName}),e.jsx("span",{children:u.toolName})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:u.description}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[e.jsx("span",{className:"text-muted-foreground",children:"使用次数:"})," ",e.jsx("span",{className:"text-primary font-bold",children:u.usageCount||0})]}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[e.jsx("span",{className:"text-muted-foreground",children:"最后使用:"})," ",e.jsx("span",{className:"text-primary font-bold",children:u.lastUsedTime||"-"})]})]})]}),e.jsx("div",{className:"flex items-center gap-2 ml-4",children:e.jsx(C,{variant:"secondary",size:"icon",className:"size-8 hover:bg-green-500 hover:text-white",onClick:()=>O(u.name,!1),children:e.jsx(Me,{className:"h-4 w-4"})})})]},u.toolName))})]})})}),e.jsxs("div",{className:"transition-all duration-200 gap-4 flex flex-col col-span-2",children:[e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ht,{}),e.jsx(rr,{})]}),e.jsx(fn,{onToolAdded:S})]}),Object.entries(s||{}).map(([u,I])=>e.jsxs(de,{className:"transition-all duration-200",children:[e.jsx(ve,{className:"p-0",children:e.jsx("div",{className:"p-4 pb-2",children:e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsx("div",{className:"flex items-start gap-4 flex-1",children:e.jsx("div",{className:"flex-1",children:e.jsx("div",{className:"flex items-center gap-2 mb-2",children:e.jsx("h3",{className:"text-lg font-semibold",children:u})})})}),e.jsxs("div",{className:"flex items-center gap-2 ml-4",children:[e.jsx(pn,{mcpServerName:u,mcpServer:I}),e.jsx(gn,{mcpServerName:u,onRemoveSuccess:p,disabled:b})]})]})})}),e.jsx(Ke,{className:"p-4 pt-2",children:e.jsx(se,{variant:"outline",className:"text-xs",children:ft(I)})})]},u))]})]}),e.jsx(st,{open:E!==null,onOpenChange:u=>!u&&N(null),children:e.jsxs(De,{children:[e.jsxs($e,{children:[e.jsx(Le,{children:"确认移除 Coze 工作流工具"}),e.jsxs(Oe,{children:['移除后需要通过【工作流集成】重新添加并配置入参,确定要移除工具 "',E,'" 吗?']})]}),e.jsxs(Ae,{children:[e.jsx(_e,{onClick:Z,children:"取消"}),e.jsx(Ue,{onClick:F,className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"确认移除"})]})]})}),U.tool&&e.jsx(sr,{open:U.open,onOpenChange:u=>R(I=>({...I,open:u})),workflow:U.tool,onConfirm:he,onCancel:A,title:"配置工作流参数"})]})}const bn=({size:r=24,color:t="currentColor",...s})=>e.jsx("svg",{width:r,height:r,viewBox:"0 0 1024 1024",fill:"none",stroke:t,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...s,children:e.jsx("path",{d:"M980.79827 694.105946c-21.144216-122.796973-109.844757-203.250162-109.844757-203.250162 12.647784-111.477622-33.792-131.26573-33.792-131.26573C827.392 14.668108 530.985514 20.67373 524.730811 20.839784 518.476108 20.67373 222.01427 14.668108 212.300108 359.590054c0 0-46.467459 19.788108-33.819676 131.26573 0 0-88.700541 80.453189-109.817081 203.250162 0 0-11.291676 207.484541 101.403676 25.40627 0 0 25.350919 69.161514 71.790703 131.26573 0 0-83.082378 28.256865-75.997405 101.625081 0 0-2.87827 81.836973 177.401081 76.218811 0 0 126.699243-9.852541 164.753297-63.515676l16.605405 0 0.276757 0 16.633081 0c38.026378 53.635459 164.725622 63.515676 164.725622 63.515676 180.224 5.618162 177.401081-76.218811 177.401081-76.218811 7.029622-73.368216-75.997405-101.625081-75.997405-101.625081 46.439784-62.104216 71.790703-131.26573 71.790703-131.26573C992.034595 901.590486 980.79827 694.105946 980.79827 694.105946z"})}),wn=({size:r=24,color:t="currentColor",...s})=>e.jsx("svg",{width:r,height:r,viewBox:"0 0 1024 1024",fill:"none",stroke:t,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...s,children:e.jsx("path",{d:"M0 524.992q0 166.016 95.488 298.496t247.488 185.504q6.016 0.992 10.016 0.992t6.496-1.504 4-3.008 2.016-4.992 0.512-4.992v-100.512q-36.992 4-66.016-0.512t-45.504-14.016-28.992-23.488-16.992-25.504-8.992-24-5.504-14.496q-8.992-15.008-27.008-27.488t-27.008-20-2.016-14.496q50.016-26.016 112.992 66.016 34.016 51.008 119.008 30.016 10.016-40.992 40-70.016Q293.984 736 237.984 670.976t-56-158.016q0-87.008 55.008-151.008-22.016-64.992 6.016-136.992 28.992-2.016 64.992 11.488t50.496 23.008 25.504 17.504q56.992-16 128.512-16t129.504 16q12.992-8.992 28.992-19.008t48.992-21.504 60.992-9.504q27.008 71.008 7.008 135.008 56 64 56 151.008 0 92.992-56.992 158.496t-172 85.504q43.008 43.008 43.008 104v128.992q0 0.992 0.992 3.008 0 6.016 0.512 8.992t4.512 6.016 12 3.008q152.992-52 250.496-185.504t97.504-300.512q0-104-40.512-199.008t-108.992-163.488-163.488-108.992T512.032 12.96 313.024 53.472 149.536 162.464t-108.992 163.488-40.512 199.008z","p-id":"4674"})});function ar(){const[r,t]=o.useState({status:"idle",logs:[]});o.useEffect(()=>{const g=L.subscribe("data:npmInstallStarted",d=>{console.log("[useNPMInstall] 安装开始:",d),t({status:"installing",version:d.version,installId:d.installId,logs:[]})}),h=L.subscribe("data:npmInstallLog",d=>{console.log("[useNPMInstall] 收到日志:",d),t(l=>l.installId===d.installId?{...l,logs:[...l.logs,{type:d.type,message:d.message,timestamp:d.timestamp}]}:l)}),f=L.subscribe("data:npmInstallCompleted",d=>{console.log("[useNPMInstall] 安装完成:",d),t(l=>l.installId===d.installId?{...l,status:"completed",duration:d.duration}:l)}),x=L.subscribe("data:npmInstallFailed",d=>{console.log("[useNPMInstall] 安装失败:",d),t(l=>l.installId===d.installId?{...l,status:"failed",error:d.error,duration:d.duration}:l)});return()=>{g(),h(),f(),x()}},[]);const s=o.useCallback(async g=>{var h;try{console.log("[useNPMInstall] 开始安装版本:",g);const x=await(await fetch("/api/update",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({version:g})})).json();if(!x.success)throw new Error(((h=x.error)==null?void 0:h.message)||"安装请求失败");return console.log("[useNPMInstall] 安装请求已接受:",x),x}catch(f){throw console.error("[useNPMInstall] 安装请求失败:",f),t(x=>({...x,status:"failed",error:f instanceof Error?f.message:"未知错误"})),f}},[]),a=o.useCallback(()=>{console.log("[useNPMInstall] 清除安装状态"),t({status:"idle",logs:[]})},[]),n=o.useCallback(()=>{switch(r.status){case"installing":return`正在安装 xiaozhi-client@${r.version}...`;case"completed":return"安装完成!";case"failed":return`安装失败: ${r.error}`;default:return""}},[r]),i=o.useCallback(()=>{switch(r.status){case"installing":return"text-blue-600";case"completed":return"text-green-600";case"failed":return"text-red-600";default:return"text-gray-600"}},[r]),c=o.useCallback(()=>r.status==="installing",[r.status]),m=o.useCallback(()=>r.status!=="installing",[r.status]);return{installStatus:r,startInstall:s,clearStatus:a,getStatusText:n,getStatusColor:i,isInstalling:c,canCloseDialog:m}}const vn=je("relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",{variants:{variant:{default:"bg-background text-foreground",destructive:"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive"}},defaultVariants:{variant:"default"}}),Mt=o.forwardRef(({className:r,variant:t,...s},a)=>e.jsx("div",{ref:a,role:"alert",className:w(vn({variant:t}),r),...s}));Mt.displayName="Alert";const nr=o.forwardRef(({className:r,...t},s)=>e.jsx("h5",{ref:s,className:w("mb-1 font-medium leading-none tracking-tight",r),...t}));nr.displayName="AlertTitle";const zt=o.forwardRef(({className:r,...t},s)=>e.jsx("div",{ref:s,className:w("text-sm [&_p]:leading-relaxed",r),...t}));zt.displayName="AlertDescription";const or=o.forwardRef(({className:r,value:t,status:s="idle",...a},n)=>{const i=()=>{switch(s){case"installing":return"bg-blue-500";case"completed":return"bg-green-500";case"failed":return"bg-red-500";default:return"bg-gray-300"}};return e.jsx("div",{ref:n,className:w("relative h-4 w-full overflow-hidden rounded-full bg-gray-200 dark:bg-gray-800",r),...a,children:e.jsx("div",{className:w("h-full transition-all duration-300 ease-in-out",i()),style:{width:`${t||0}%`}})})});or.displayName="Progress";const ir=o.forwardRef(({className:r,children:t,...s},a)=>e.jsx("div",{ref:a,className:w("relative overflow-auto",r),...s,children:t}));ir.displayName="ScrollArea";const jn=o.forwardRef(({className:r,orientation:t="vertical",...s},a)=>e.jsx("div",{ref:a,className:w("flex touch-none select-none transition-colors",t==="vertical"&&"h-full w-2.5 border-l border-l-transparent p-[1px]",t==="horizontal"&&"h-2.5 w-full border-t border-t-transparent p-[1px]",r),...s,children:e.jsx("div",{className:"relative flex-1 rounded-full bg-border"})}));jn.displayName="ScrollBar";function cr({isOpen:r,onClose:t,version:s}){const{installStatus:a,startInstall:n,clearStatus:i,isInstalling:c,canCloseDialog:m}=ar(),g=o.useRef(null),[h,f]=o.useState(!1);o.useEffect(()=>{r&&s&&(console.log("[InstallLogDialog] 对话框打开,开始安装版本:",s),i(),n(s).catch(N=>{console.error("[InstallLogDialog] 启动安装失败:",N)}))},[r,s,n,i]),o.useEffect(()=>{const N=setTimeout(()=>{g.current&&(g.current.scrollTop=g.current.scrollHeight)},100);return()=>clearTimeout(N)});const x=()=>{switch(a.status){case"idle":return 0;case"installing":return Math.min(90,a.logs.length*2);case"completed":return 100;case"failed":return 100;default:return 0}},d=()=>{switch(a.status){case"installing":return"正在安装...";case"completed":return"安装完成";case"failed":return"安装失败";default:return"准备安装"}},l=()=>{switch(a.status){case"installing":return e.jsx(Ot,{className:"h-4 w-4 animate-pulse"});case"completed":return e.jsx(dt,{className:"h-4 w-4 text-green-600"});case"failed":return e.jsx(Hr,{className:"h-4 w-4 text-red-600"});default:return null}},b=()=>{switch(a.status){case"installing":return"default";case"completed":return"secondary";case"failed":return"destructive";default:return"outline"}},j=N=>{let U=N;const R=[/\[0m/g,/\[31m/g,/\[32m/g,/\[33m/g,/\[34m/g,/\[35m/g,/\[36m/g,/\[37m/g,/\[90m/g,/\[91m/g,/\[92m/g,/\[93m/g,/\[94m/g,/\[95m/g,/\[96m/g,/\[97m/g];for(const O of R)U=U.replace(O,"");return U.split(`
31
+ `).filter(O=>O.trim()).map((O,F)=>e.jsx("div",{className:"leading-relaxed",children:O},`${O.slice(0,20)}-${F}`))},p=()=>{m()&&(i(),t())},S=N=>{N.key==="Escape"&&m()&&p()},E=()=>{f(!h)};return e.jsx(me,{open:r,onOpenChange:p,children:e.jsxs(oe,{className:"max-w-2xl max-h-[80vh] flex flex-col",onKeyDown:S,children:[e.jsxs(ie,{className:"flex flex-row items-center justify-between space-y-0 pb-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(ce,{className:"text-lg font-semibold",children:"正在安装 xiaozhi-client"}),a.status!=="idle"&&e.jsxs(se,{variant:b(),className:"flex items-center gap-1",children:[l(),d()]})]}),e.jsx(C,{variant:"ghost",size:"icon",onClick:p,disabled:!m(),className:"h-6 w-6",children:e.jsx(vt,{className:"h-4 w-4"})})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{className:"font-medium",children:"安装进度"}),a.version&&e.jsxs(se,{variant:"outline",className:"text-xs",children:["v",a.version]})]}),e.jsx(or,{value:x(),status:a.status,className:"w-full h-2"}),e.jsxs("div",{className:"flex items-center justify-between text-xs text-muted-foreground",children:[e.jsx("span",{children:d()}),a.duration&&e.jsxs("span",{children:["耗时: ",(a.duration/1e3).toFixed(1),"s"]})]})]}),a.status==="failed"&&e.jsx(Mt,{variant:"destructive",children:e.jsx(zt,{children:"安装失败,请查看详细日志了解具体原因。"})}),e.jsxs("div",{children:[e.jsxs("button",{type:"button",onClick:E,className:"flex w-full items-center justify-between h-auto p-0 gap-0 hover:bg-none bg-none text-sm mb-2",children:[e.jsx("h4",{className:"font-medium",children:"安装日志"}),e.jsx("div",{className:"flex items-center gap-1",children:h?e.jsxs(e.Fragment,{children:["收起 ",e.jsx(ms,{className:"h-4 w-4"})]}):e.jsxs(e.Fragment,{children:["展开 ",e.jsx(jt,{className:"h-4 w-4"})]})})]}),h&&e.jsx(ir,{ref:g,className:"h-[300px] w-full rounded-md border bg-background",children:e.jsx("div",{className:"p-4 font-mono text-xs",children:a.logs.length===0?e.jsxs("div",{className:"text-muted-foreground flex items-center gap-2",children:[e.jsx(Ot,{className:"h-4 w-4 animate-pulse"}),"等待日志输出..."]}):e.jsx("div",{className:"space-y-1",children:a.logs.map(N=>e.jsx("div",{className:`${N.type==="stderr"?"text-orange-600":"text-foreground"} break-words`,children:j(N.message)},`${N.timestamp}-${N.message.slice(0,50)}`))})})})]})]}),e.jsx(xe,{className:"flex items-center justify-between pt-4 border-t",children:e.jsxs("div",{className:"flex gap-2",children:[a.status==="completed"&&e.jsxs(C,{variant:"outline",onClick:()=>window.location.reload(),className:"flex items-center gap-2",children:[e.jsx(dt,{className:"h-4 w-4"}),"重启应用"]}),e.jsx(C,{onClick:p,disabled:!m(),variant:a.status==="failed"?"destructive":"default",children:c()?"安装中...":a.status==="completed"?"完成":(a.status==="failed","关闭")})]})})]})})}const Sn=[{value:"stable",label:"正式版"},{value:"rc",label:"预览版"},{value:"beta",label:"测试版"},{value:"all",label:"全部版本"}];function Jt({children:r,defaultSelectedVersion:t}){const[s,a]=o.useState(!1),[n,i]=o.useState(""),[c,m]=o.useState("stable"),[g,h]=o.useState(!1),[f,x]=o.useState([]),[d,l]=o.useState(!1),{startInstall:b}=ar(),j=o.useCallback(async R=>{try{l(!0);const O=await $.getAvailableVersions(R),F=O.versions.map(Z=>({value:Z,label:`v${Z}`}));x(F),console.log(`[VersionUpgradeDialog] 获取到 ${O.total} 个${R}版本`),t&&O.versions.includes(t||"")&&i(t||"")}catch(O){console.error("[VersionUpgradeDialog] 获取版本列表失败:",O),x([])}finally{l(!1)}},[t]);o.useEffect(()=>{s&&j(c)},[s,c,j]);const p=R=>{m(R),i("")},S=R=>{i(R)},E=async()=>{if(n)try{console.log("[VersionUpgradeDialog] 开始安装版本:",n),a(!1),h(!0),await b(n)}catch(R){console.error("[VersionUpgradeDialog] 安装失败:",R),h(!1)}},N=()=>{h(!1),i("")},U=R=>{R||(i(""),m("stable")),a(R)};return e.jsxs(e.Fragment,{children:[e.jsxs(me,{open:s,onOpenChange:U,children:[e.jsx(Se,{asChild:!0,children:r||e.jsxs(C,{className:"flex items-center gap-2",children:[e.jsx(ws,{className:"h-4 w-4"}),"升级版本"]})}),e.jsxs(oe,{className:"sm:max-w-md",children:[e.jsxs(ie,{children:[e.jsx(ce,{children:"选择安装版本"}),e.jsx(pe,{children:"请选择要安装的 xiaozhi-client 版本"})]}),e.jsx("div",{className:"space-y-4 py-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{htmlFor:"version-select",className:"text-sm font-medium",children:"版本选择"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(Ge,{value:c,onValueChange:p,children:[e.jsx(Te,{id:"version-type-select",className:"w-[150px]",children:e.jsx(Qe,{placeholder:"请选择版本类型"})}),e.jsx(Re,{children:Sn.map(R=>e.jsx(ue,{value:R.value,children:R.label},R.value))})]}),e.jsxs(Ge,{value:n,onValueChange:S,disabled:d,children:[e.jsx(Te,{id:"version-select",children:e.jsx(Qe,{placeholder:d?"正在获取版本列表...":"请选择版本"})}),e.jsx(Re,{children:d?e.jsx(ue,{value:"loading",disabled:!0,children:"正在获取版本列表..."}):f.length===0?e.jsx(ue,{value:"empty",disabled:!0,children:"暂无可用版本"}):f.map(R=>e.jsx(ue,{value:R.value,children:R.label},R.value))})]})]}),!d&&f.length===0&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"当前版本类型暂无可用版本"}),n&&da.lt(n,"1.8.0")&&e.jsxs(Mt,{variant:"destructive",children:[e.jsx(Jr,{size:18}),e.jsx(nr,{children:"重要提醒"}),e.jsx(zt,{children:"指定版本低于1.8.0,安装后无法再使用Web界面重装,需手动通过命令操作,请谨慎操作!"})]})]})}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(C,{variant:"outline",onClick:()=>a(!1),children:"取消"}),e.jsx(C,{onClick:E,disabled:!n||d,children:"确定安装"})]})]})]}),e.jsx(cr,{isOpen:g,onClose:N,version:n})]})}function lr({className:r}){const[t,s]=o.useState(null),[a,n]=o.useState(null),[i,c]=o.useState(!0),[m,g]=o.useState(!0),[h,f]=o.useState(null),[x,d]=o.useState(!1);o.useEffect(()=>{(async()=>{try{c(!0),f(null);const S=await $.getVersion();s(S)}catch(S){f(S instanceof Error?S.message:"获取版本信息失败"),console.error("获取版本信息失败:",S)}finally{c(!1)}})()},[]),o.useEffect(()=>{t&&(async()=>{try{g(!0);const S=await $.getLatestVersion();n(S)}catch(S){console.error("检查更新失败:",S),n({currentVersion:(t==null?void 0:t.version)||"unknown",latestVersion:null,hasUpdate:!1,error:S instanceof Error?S.message:"检查更新失败"})}finally{g(!1)}})()},[t]);const l=async()=>{if(t!=null&&t.version)try{await navigator.clipboard.writeText(t.version),d(!0),setTimeout(()=>d(!1),2e3)}catch(p){console.error("复制版本号失败:",p)}};if(i)return e.jsx(se,{variant:"outline",className:r,children:e.jsx("span",{className:"text-xs",children:"加载中..."})});if(h||!t)return e.jsx(se,{variant:"outline",className:r,children:e.jsx("span",{className:"text-xs text-muted-foreground",children:"版本未知"})});const b=e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Kr,{className:"h-3 w-3"}),e.jsx("span",{className:"font-semibold",children:"版本详情"})]}),e.jsxs("div",{className:"text-xs space-y-0.5",children:[e.jsxs("div",{children:[e.jsx("strong",{children:"名称:"})," ",t.name]}),e.jsxs("div",{children:[e.jsx("strong",{children:"版本:"})," ",t.version]}),a&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("strong",{children:"最新版本:"})," ",a.latestVersion||"未知"]}),e.jsxs("div",{children:[e.jsx("strong",{children:"状态:"}),m?"检查中...":a.hasUpdate?"有新版本":"已是最新"]})]}),e.jsxs("div",{children:[e.jsx("strong",{children:"描述:"})," ",t.description]}),e.jsxs("div",{children:[e.jsx("strong",{children:"作者:"})," ",t.author]})]}),e.jsx("div",{className:"pt-1 border-t",children:e.jsxs("button",{type:"button",onClick:l,className:"text-xs text-primary hover:underline flex items-center gap-1",children:[e.jsx(ns,{className:"h-3 w-3"}),x?"已复制!":"复制版本号"]})})]}),j=()=>m?null:a!=null&&a.hasUpdate&&a.latestVersion?e.jsx(Jt,{defaultSelectedVersion:a.latestVersion,children:e.jsxs(C,{variant:"link",className:"p-0 gap-1",children:[e.jsx(Gr,{}),"升级版本"]})}):e.jsx(Jt,{defaultSelectedVersion:t.version,children:e.jsx(C,{variant:"link",className:"p-0 gap-1",children:"切换版本"})});return e.jsx(Ms,{children:e.jsxs("div",{className:"flex items-center gap-2",children:[j(),e.jsxs(zs,{children:[e.jsx(Ws,{asChild:!0,children:e.jsxs("span",{className:"text-sm cursor-help",children:["v",t.version]})}),e.jsx(Nt,{children:b})]})]})})}function dr({title:r}){return e.jsxs("header",{className:"group-has-data-[collapsible=icon]/sidebar-wrapper:h-12 flex h-12 shrink-0 items-center gap-2 border-b transition-[width,height] ease-linear pr-4",children:[e.jsxs("div",{className:"flex w-full items-center gap-2 px-4 box-border",children:[e.jsx(As,{className:"-ml-1"}),e.jsx(yt,{orientation:"vertical",className:"mx-2 data-[orientation=vertical]:h-4"}),e.jsx("h1",{className:"text-base font-medium",children:r})]}),e.jsxs("div",{className:"flex w-full justify-end items-center gap-4 box-border",children:[e.jsx(lr,{}),e.jsx("a",{href:"https://img.shields.io/badge/Join-QQ%20Group-5865F2?style=flat&logo=qq&logoColor=white)](https://qun.qq.com/universal-share/share?ac=1&authKey=c08PvS2zvAF1NN%2F%2BuaOi0ze1AElTIsvFBLwbWUMFc2ixjaZYxqZTUQHzipwd8Kka&busi_data=eyJncm91cENvZGUiOiIxMDU0ODg4NDczIiwidG9rZW4iOiJuSmJUN2cyUEVkNEQ5WXovM3RQbFVNcDluMGVibUNZTUQvL1RuQnFJRjBkZmRZQnRBRTdwU0szL3V2Y0dLc1ZmIiwidWluIjoiMzkxMTcyMDYwMCJ9&data=9cH6_zEC-sN3xYlwzKEWiYF71RLY9CId5taN-gy6XZo7axSlSWDpd1Ojui5hYMQKIgEJYSPw59XYgF5vH2wLog&svctype=4&tempid=h5_group_info",target:"_blank",rel:"noopener noreferrer",children:e.jsx(bn,{size:24,className:"text-slate-800",fill:"currentColor"})}),e.jsx("a",{href:"https://github.com/shenjingnan/xiaozhi-client",target:"_blank",rel:"noopener noreferrer",children:e.jsx(wn,{size:24,className:"text-slate-800",fill:"currentColor"})})]})]})}class yn{constructor(){V(this,"apiClient");V(this,"webSocketManager");V(this,"initialized",!1);this.apiClient=$,this.webSocketManager=L}async initialize(){this.initialized||(console.log("[NetworkService] 初始化网络服务"),this.webSocketManager.connect(),this.initialized=!0,console.log("[NetworkService] 网络服务初始化完成"))}destroy(){console.log("[NetworkService] 销毁网络服务"),this.webSocketManager.disconnect(),this.initialized=!1}async getConfig(){return this.apiClient.getConfig()}async updateConfig(t){return this.apiClient.updateConfig(t)}async getStatus(){return this.apiClient.getStatus()}async getClientStatus(){return this.apiClient.getClientStatus()}async restartService(){return this.apiClient.restartService()}async stopService(){return this.apiClient.stopService()}async startService(){return this.apiClient.startService()}async getServiceStatus(){return this.apiClient.getServiceStatus()}async getServiceHealth(){return this.apiClient.getServiceHealth()}async getMcpEndpoint(){return this.apiClient.getMcpEndpoint()}async getMcpEndpoints(){return this.apiClient.getMcpEndpoints()}async getMcpServers(){return this.apiClient.getMcpServers()}async getConnectionConfig(){return this.apiClient.getConnectionConfig()}async reloadConfig(){return this.apiClient.reloadConfig()}async getConfigPath(){return this.apiClient.getConfigPath()}async checkConfigExists(){return this.apiClient.checkConfigExists()}async getRestartStatus(){return this.apiClient.getRestartStatus()}async checkClientConnected(){return this.apiClient.checkClientConnected()}async getLastHeartbeat(){return this.apiClient.getLastHeartbeat()}async getActiveMCPServers(){return this.apiClient.getActiveMCPServers()}async updateClientStatus(t){return this.apiClient.updateClientStatus(t)}async setActiveMCPServers(t){return this.apiClient.setActiveMCPServers(t)}async resetStatus(){return this.apiClient.resetStatus()}getWebSocketState(){return this.webSocketManager.getState()}isWebSocketConnected(){return this.webSocketManager.isConnected()}setWebSocketUrl(t){this.webSocketManager.setUrl(t)}onWebSocketEvent(t,s){this.webSocketManager.on(t,s)}offWebSocketEvent(t){this.webSocketManager.off(t)}reconnectWebSocket(){this.webSocketManager.disconnect(),setTimeout(()=>{this.webSocketManager.connect()},1e3)}async getFullAppState(){const[t,s]=await Promise.all([this.getConfig(),this.getStatus()]);return{config:t,status:s,webSocketConnected:this.isWebSocketConnected()}}async updateConfigWithNotification(t,s=5e3){return new Promise((a,n)=>{const i=setTimeout(()=>{this.webSocketManager.off("configUpdate"),n(new Error("等待配置更新通知超时"))},s);this.webSocketManager.on("configUpdate",()=>{clearTimeout(i),this.webSocketManager.off("configUpdate"),a()}),this.updateConfig(t).catch(c=>{clearTimeout(i),this.webSocketManager.off("configUpdate"),n(c)})})}async restartServiceWithNotification(t=3e4){return new Promise((s,a)=>{const n=setTimeout(()=>{this.webSocketManager.off("restartStatus"),a(new Error("等待重启状态通知超时"))},t);this.webSocketManager.on("restartStatus",i=>{i.status==="completed"?(clearTimeout(n),this.webSocketManager.off("restartStatus"),s()):i.status==="failed"&&(clearTimeout(n),this.webSocketManager.off("restartStatus"),a(new Error(i.error||"服务重启失败")))}),this.restartService().catch(i=>{clearTimeout(n),this.webSocketManager.off("restartStatus"),a(i)})})}}const q=new yn;function Nn(){const r=Ys(),t=o.useRef(!1);o.useEffect(()=>{if(!t.current)return console.log("[NetworkService] 初始化网络服务"),t.current=!0,q.initialize().catch(l=>{console.error("[NetworkService] 初始化失败:",l)}),q.onWebSocketEvent("connected",()=>{console.log("[NetworkService] WebSocket 已连接"),r.setConnectionState(G.CONNECTED),s()}),q.onWebSocketEvent("disconnected",()=>{console.log("[NetworkService] WebSocket 已断开"),r.setConnectionState(G.DISCONNECTED)}),q.onWebSocketEvent("configUpdate",l=>{console.log("[NetworkService] 收到配置更新通知"),ne.getState().setConfig(l,"websocket")}),q.onWebSocketEvent("statusUpdate",l=>{console.log("[NetworkService] 收到状态更新通知"),ae.getState().setClientStatus(l,"websocket")}),q.onWebSocketEvent("restartStatus",l=>{console.log("[NetworkService] 收到重启状态通知:",l),ae.getState().setRestartStatus(l,"websocket")}),q.onWebSocketEvent("error",l=>{console.error("[NetworkService] WebSocket 错误:",l)}),()=>{console.log("[NetworkService] 清理网络服务"),q.destroy(),t.current=!1}},[r]);const s=o.useCallback(async()=>{try{console.log("[NetworkService] 加载初始数据");const[l,b]=await Promise.all([q.getConfig(),q.getClientStatus()]);console.log("[NetworkService] 初始数据加载成功"),ne.getState().setConfig(l,"http"),ae.getState().setClientStatus(b,"http")}catch(l){console.error("[NetworkService] 加载初始数据失败:",l)}},[]),a=o.useCallback(async()=>{try{const l=await q.getConfig();return ne.getState().setConfig(l,"http"),l}catch(l){throw console.error("[NetworkService] 获取配置失败:",l),l}},[]),n=o.useCallback(async l=>{try{console.log("[NetworkService] 更新配置"),await q.updateConfig(l),ne.getState().setConfig(l,"http"),console.log("[NetworkService] 配置更新成功")}catch(b){throw console.error("[NetworkService] 配置更新失败:",b),b}},[]),i=o.useCallback(async()=>{try{const l=await q.getStatus();return ae.getState().setClientStatus(l.client,"http"),l}catch(l){throw console.error("[NetworkService] 获取状态失败:",l),l}},[]),c=o.useCallback(async()=>{try{await i()}catch(l){console.error("[NetworkService] 刷新状态失败:",l)}},[i]),m=o.useCallback(async()=>{try{console.log("[NetworkService] 重启服务"),await q.restartService(),console.log("[NetworkService] 重启请求已发送")}catch(l){throw console.error("[NetworkService] 重启服务失败:",l),l}},[]),g=o.useCallback(async(l=3e4)=>{try{console.log("[NetworkService] 重启服务并等待通知"),await q.restartServiceWithNotification(l),console.log("[NetworkService] 服务重启完成")}catch(b){throw console.error("[NetworkService] 重启服务失败:",b),b}},[]),h=o.useCallback(async(l,b=5e3)=>{try{console.log("[NetworkService] 更新配置并等待通知"),await q.updateConfigWithNotification(l,b),console.log("[NetworkService] 配置更新完成")}catch(j){throw console.error("[NetworkService] 配置更新失败:",j),j}},[]),f=o.useCallback(l=>{console.log("[NetworkService] 设置自定义 WebSocket URL:",l),q.setWebSocketUrl(l),r.setWsUrl(l)},[r]),x=o.useCallback(async l=>{try{console.log(`[NetworkService] 切换到端口 ${l}`),r.setPortChangeStatus({status:"checking",targetPort:l,timestamp:Date.now()});const b=window.location.protocol==="https:"?"wss:":"ws:",j=window.location.hostname,p=`${b}//${j}:${l}`;await m(),await new Promise(S=>setTimeout(S,5e3)),f(p),window.location.reload()}catch(b){throw console.error("[NetworkService] 端口切换失败:",b),r.setPortChangeStatus({status:"failed",targetPort:l,error:b instanceof Error?b.message:"端口切换失败",timestamp:Date.now()}),b}},[r,m,f]),d=o.useCallback(()=>{const l=localStorage.getItem("xiaozhi-ws-url");if(l)return l;const b=window.location.protocol==="https:"?"wss:":"ws:",j=window.location.hostname,p=window.location.port;return`${b}//${j}${p?`:${p}`:""}`},[]);return{getConfig:a,updateConfig:n,getStatus:i,refreshStatus:c,restartService:m,updateConfigWithNotification:h,restartServiceWithNotification:g,setCustomWsUrl:f,getWebSocketUrl:d,changePort:x,loadInitialData:s,isWebSocketConnected:()=>q.isWebSocketConnected(),getWebSocketState:()=>q.getWebSocketState()}}async function Cn(){console.log("[Stores] 开始初始化所有 stores");try{console.log("[Stores] 初始化 WebSocket store"),qe.getState().initialize(),console.log("[Stores] 初始化配置 store"),await ne.getState().initialize(),console.log("[Stores] 初始化状态 store"),await ae.getState().initialize(),console.log("[Stores] 所有 stores 初始化完成")}catch(r){throw console.error("[Stores] Stores 初始化失败:",r),r}}const ur=o.createContext(null);function kn({children:r}){const t=Nn(),[s,a]=o.useState(!1);return o.useEffect(()=>{let n=!0;return(async()=>{try{console.log("[WebSocketProvider] 开始初始化 stores"),await Cn(),n&&(a(!0),console.log("[WebSocketProvider] Stores 初始化完成"))}catch(c){console.error("[WebSocketProvider] Stores 初始化失败:",c),n&&a(!0)}})(),()=>{n=!1}},[]),s?e.jsx(ur.Provider,{value:t,children:r}):e.jsx("div",{className:"flex items-center justify-center min-h-screen",children:e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-2"}),e.jsx("p",{className:"text-sm text-gray-600",children:"正在初始化应用..."})]})})}function En(){const r=o.useContext(ur);if(!r)throw new Error("useNetworkServiceActions must be used within a NetworkServiceProvider");return r}const Pn=kn,mr=En;function Tn(){const{updateConfig:r}=mr();return e.jsxs(Ct,{children:[e.jsx(Vs,{variant:"inset"}),e.jsxs(kt,{children:[e.jsx(dr,{title:"看板"}),e.jsx("div",{className:"flex flex-1 flex-col",children:e.jsx("div",{className:"@container/main flex flex-1 flex-col gap-2",children:e.jsxs("div",{className:"flex flex-col gap-4 py-4 md:gap-6 md:py-6",children:[e.jsx(rn,{}),e.jsx(xn,{updateConfig:r})]})})})]})]})}function Rn(){const[r,t]=o.useState(null),[s,a]=o.useState(null),[n,i]=o.useState(!1),[c,m]=o.useState(null),[g,h]=o.useState(!1),[f,x]=o.useState(""),d=o.useCallback(async()=>{try{m(null);const p=await $.getVersion();t(p),console.log("[VersionManager] 当前版本信息:",p)}catch(p){const S=p instanceof Error?p.message:"获取版本信息失败";m(S),console.error("[VersionManager] 获取版本信息失败:",p)}},[]),l=async()=>{if(r)try{i(!0),m(null),console.log("[VersionManager] 检查更新..."),await new Promise(S=>setTimeout(S,1e3));const p={currentVersion:r.version,latestVersion:"1.8.0",updateAvailable:!0,releaseNotes:`• 修复了若干 bug
32
32
  • 新增实时日志功能
33
33
  • 性能优化`,publishDate:new Date().toISOString()};a(p),console.log("[VersionManager] 更新检查结果:",p)}catch(p){const S=p instanceof Error?p.message:"检查更新失败";m(S),console.error("[VersionManager] 检查更新失败:",p)}finally{i(!1)}},b=p=>{console.log("[VersionManager] 开始更新到版本:",p),x(p),h(!0)},j=()=>{h(!1),x(""),setTimeout(()=>{d()},1e3)};return o.useEffect(()=>{d()},[d]),e.jsxs(de,{className:"w-full max-w-2xl",children:[e.jsx(ke,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs(Ee,{className:"flex items-center gap-2",children:[e.jsx(Qr,{className:"h-5 w-5"}),"版本管理"]}),e.jsx(Pe,{children:"管理应用版本和更新"})]}),e.jsx(lr,{})]})}),e.jsxs(ve,{className:"space-y-6",children:[c&&e.jsxs("div",{className:"flex items-center gap-2 p-3 bg-destructive/10 border border-destructive/20 rounded-md",children:[e.jsx(Je,{className:"h-4 w-4 text-destructive"}),e.jsx("span",{className:"text-sm text-destructive",children:c})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("h3",{className:"text-lg font-medium",children:"当前版本"}),r?e.jsxs("div",{className:"p-4 bg-muted/50 rounded-md space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"font-medium",children:["版本 ",r.version]}),e.jsx(se,{variant:"secondary",children:r.name})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:r.description}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["作者: ",r.author]})]}):e.jsx("div",{className:"p-4 bg-muted/50 rounded-md",children:e.jsx("span",{className:"text-muted-foreground",children:"加载中..."})})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-lg font-medium",children:"更新检查"}),e.jsxs(C,{variant:"outline",size:"sm",onClick:l,disabled:n||!r,className:"flex items-center gap-2",children:[e.jsx(bs,{className:`h-4 w-4 ${n?"animate-spin":""}`}),n?"检查中...":"检查更新"]})]}),s&&e.jsx("div",{className:"p-4 border rounded-md space-y-3",children:s.updateAvailable?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Je,{className:"h-4 w-4 text-blue-600"}),e.jsxs("span",{className:"font-medium text-blue-600",children:["发现新版本 ",s.latestVersion]})]}),s.publishDate&&e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(Yr,{className:"h-3 w-3"}),"发布日期:"," ",new Date(s.publishDate).toLocaleDateString()]}),s.releaseNotes&&e.jsxs("div",{className:"mt-3",children:[e.jsx("h4",{className:"text-sm font-medium mb-2",children:"更新内容:"}),e.jsx("div",{className:"text-sm text-muted-foreground whitespace-pre-line bg-muted/30 p-2 rounded",children:s.releaseNotes})]}),e.jsxs("div",{className:"flex gap-2 pt-2",children:[e.jsxs(C,{onClick:()=>b(s.latestVersion),className:"flex items-center gap-2",children:[e.jsx(ws,{className:"h-4 w-4"}),"更新到 ",s.latestVersion]}),e.jsx(C,{variant:"outline",size:"sm",asChild:!0,children:e.jsxs("a",{href:"https://github.com/shenjingnan/xiaozhi-client/releases",target:"_blank",rel:"noopener noreferrer",className:"flex items-center gap-1",children:[e.jsx(Zr,{className:"h-3 w-3"}),"查看详情"]})})]})]}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(dt,{className:"h-4 w-4 text-green-600"}),e.jsxs("span",{className:"text-green-600",children:["当前版本 ",s.currentVersion," 是最新版本"]})]})})]})]}),e.jsx(cr,{isOpen:g,onClose:j,version:f})]})}const In=Xr,fr=o.forwardRef(({className:r,...t},s)=>e.jsx(vs,{ref:s,className:w("inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",r),...t}));fr.displayName=vs.displayName;const ht=o.forwardRef(({className:r,...t},s)=>e.jsx(js,{ref:s,className:w("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",r),...t}));ht.displayName=js.displayName;const pt=o.forwardRef(({className:r,...t},s)=>e.jsx(Ss,{ref:s,className:w("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",r),...t}));pt.displayName=Ss.displayName;const Mn=J.object({modelscope:J.object({apiKey:J.string().optional()}),platforms:J.object({coze:J.object({token:J.string().optional()})}),connection:J.object({heartbeatInterval:J.number().min(1e3,{message:"心跳间隔不能小于1000毫秒"}),heartbeatTimeout:J.number().min(1e3,{message:"心跳超时不能小于1000毫秒"}),reconnectInterval:J.number().min(1e3,{message:"重连间隔不能小于1000毫秒"})})});function zn(){var c,m,g,h,f,x;const r=ye(),{updateConfig:t}=mr(),[s,a]=o.useState(!1),n=ze({resolver:We(Mn),defaultValues:{platforms:{coze:{token:((m=(c=r==null?void 0:r.platforms)==null?void 0:c.coze)==null?void 0:m.token)||""}},modelscope:{apiKey:((g=r==null?void 0:r.modelscope)==null?void 0:g.apiKey)||""},connection:{heartbeatInterval:((h=r==null?void 0:r.connection)==null?void 0:h.heartbeatInterval)||3e4,heartbeatTimeout:((f=r==null?void 0:r.connection)==null?void 0:f.heartbeatTimeout)||1e4,reconnectInterval:((x=r==null?void 0:r.connection)==null?void 0:x.reconnectInterval)||5e3}}});o.useEffect(()=>{var d,l,b,j;n.reset({modelscope:{apiKey:((d=r==null?void 0:r.modelscope)==null?void 0:d.apiKey)||""},connection:{heartbeatInterval:((l=r==null?void 0:r.connection)==null?void 0:l.heartbeatInterval)||3e4,heartbeatTimeout:((b=r==null?void 0:r.connection)==null?void 0:b.heartbeatTimeout)||1e4,reconnectInterval:((j=r==null?void 0:r.connection)==null?void 0:j.reconnectInterval)||5e3}})},[r,n.reset]);async function i(d){var l;if(!r){y.error("配置数据未加载,请稍后重试");return}a(!0);try{const b={...r,modelscope:{apiKey:d.modelscope.apiKey},connection:{heartbeatInterval:d.connection.heartbeatInterval,heartbeatTimeout:d.connection.heartbeatTimeout,reconnectInterval:d.connection.reconnectInterval},platforms:{...(r==null?void 0:r.platforms)??{},coze:{...((l=r==null?void 0:r.platforms)==null?void 0:l.coze)??{},token:d.platforms.coze.token}}};await t(b),y.success("配置已更新")}catch(b){console.error("更新配置失败:",b),y.error(b instanceof Error?b.message:"更新配置失败")}finally{a(!1)}}return e.jsxs(Ct,{children:[e.jsx(Vs,{variant:"inset"}),e.jsxs(kt,{children:[e.jsx(dr,{title:"设置"}),e.jsx("div",{className:"flex flex-1 flex-col p-4",children:e.jsx("div",{className:"@container/main flex flex-1 flex-col gap-2 items-center",children:e.jsx("div",{className:"flex flex-col gap-4 py-4 md:gap-6 md:py-6 w-full max-w-4xl",children:e.jsxs(In,{defaultValue:"general",className:"w-full",children:[e.jsxs(fr,{className:"grid w-full grid-cols-2",children:[e.jsx(ht,{value:"general",children:"常规设置"}),e.jsx(ht,{value:"version",children:"版本管理"})]}),e.jsx(pt,{value:"general",className:"mt-6",children:e.jsx("div",{className:"w-[600px] mx-auto",children:e.jsx(Ve,{...n,children:e.jsx("form",{onSubmit:n.handleSubmit(i),children:e.jsxs("div",{className:"grid gap-4",children:[e.jsx(X,{control:n.control,name:"modelscope.apiKey",render:({field:d})=>e.jsxs(Q,{children:[e.jsx(re,{children:"魔搭社区 API Key"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Y,{children:e.jsx(te,{placeholder:"魔搭社区 API Key",className:"font-mono text-sm",type:"password",disabled:s,autoComplete:"off","data-1p-ignore":!0,...d})}),e.jsx(C,{variant:"outline",onClick:()=>{window.open("https://www.modelscope.cn/my/myaccesstoken","_blank")},children:"打开魔搭社区"})]}),e.jsx(ee,{})]})}),e.jsx(X,{control:n.control,name:"platforms.coze.token",render:({field:d})=>e.jsxs(Q,{children:[e.jsx(re,{children:"扣子身份凭证"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Y,{children:e.jsx(te,{placeholder:"扣子身份凭证",className:"font-mono text-sm",type:"password",autoComplete:"off","data-1p-ignore":!0,disabled:s,...d})}),e.jsx(C,{variant:"outline",onClick:()=>{window.open("https://www.coze.cn/open/oauth/sats","_blank")},children:"打开扣子平台"})]}),e.jsx(ee,{})]})}),e.jsx(X,{control:n.control,name:"connection.heartbeatInterval",render:({field:d})=>e.jsxs(Q,{children:[e.jsx(re,{children:"心跳间隔(毫秒)"}),e.jsxs("div",{className:"flex gap-2 items-center",children:[e.jsx(Y,{children:e.jsx(te,{placeholder:"心跳间隔(毫秒)",className:"font-mono text-sm",type:"number",disabled:s,...d,value:d.value||"",onChange:l=>{const b=l.target.value;d.onChange(b===""?"":Number(b))}})}),e.jsx("span",{className:"text-sm text-muted-foreground w-[50px]",children:"毫秒"})]}),e.jsx(ee,{})]})}),e.jsx(X,{control:n.control,name:"connection.heartbeatTimeout",render:({field:d})=>e.jsxs(Q,{children:[e.jsx(re,{children:"心跳超时(毫秒)"}),e.jsxs("div",{className:"flex gap-2 items-center",children:[e.jsx(Y,{children:e.jsx(te,{placeholder:"心跳超时(毫秒)",className:"font-mono text-sm",type:"number",disabled:s,...d,value:d.value||"",onChange:l=>{const b=l.target.value;d.onChange(b===""?"":Number(b))}})}),e.jsx("span",{className:"text-sm text-muted-foreground w-[50px]",children:"毫秒"})]}),e.jsx(ee,{})]})}),e.jsx(X,{control:n.control,name:"connection.reconnectInterval",render:({field:d})=>e.jsxs(Q,{children:[e.jsx(re,{children:"重连间隔(毫秒)"}),e.jsxs("div",{className:"flex gap-2 items-center",children:[e.jsx(Y,{children:e.jsx(te,{placeholder:"重连间隔(毫秒)",className:"font-mono text-sm",type:"number",disabled:s,...d,value:d.value||"",onChange:l=>{const b=l.target.value;d.onChange(b===""?"":Number(b))}})}),e.jsx("span",{className:"text-sm text-muted-foreground w-[50px]",children:"毫秒"})]}),e.jsx(ee,{})]})}),e.jsxs("div",{className:"flex gap-2 justify-end",children:[e.jsx(C,{type:"submit",disabled:s,className:"flex-1",children:s?"保存中...":"保存"}),e.jsx(rr,{})]})]})})})})}),e.jsx(pt,{value:"version",className:"mt-6",children:e.jsx("div",{className:"w-[600px] mx-auto",children:e.jsx(Rn,{})})})]})})})})]})]})}function Wn(){return e.jsxs(Pn,{children:[e.jsx(ga,{}),e.jsxs(ea,{children:[e.jsx(it,{path:"/",element:e.jsx(ta,{to:"/dashboard"})}),e.jsx(it,{path:"/dashboard",element:e.jsx(Tn,{})}),e.jsx(it,{path:"/settings",element:e.jsx(zn,{})})]}),e.jsx(oa,{richColors:!0,toastOptions:{classNames:{description:"group-[.toast]:text-muted-foreground",actionButton:"group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",cancelButton:"group-[.toast]:bg-white group-[.toast]:text-black",error:"group toast group-[.toaster]:bg-red group-[.toaster]:text-red-600 dark:group-[.toaster]:text-foreground group-[.toaster]:shadow-lg",success:"group toast group-[.toaster]:bg-green group-[.toaster]:text-green-600 dark:group-[.toaster]:text-foreground group-[.toaster]:shadow-lg",warning:"group toast group-[.toaster]:bg-yellow group-[.toaster]:text-yellow-600 dark:group-[.toaster]:text-foreground group-[.toaster]:shadow-lg",info:"group toast group-[.toaster]:bg-blue group-[.toaster]:text-blue-600 dark:group-[.toaster]:text-foreground group-[.toaster]:shadow-lg"}}})]})}sa.createRoot(document.getElementById("root")).render(e.jsx(ra.StrictMode,{children:e.jsx(aa,{children:e.jsx(Wn,{})})}));
34
- //# sourceMappingURL=index-DWHqhA0I.js.map
34
+ //# sourceMappingURL=index-Cb1nqXtT.js.map