xiaozhi-client 1.6.3-beta.0 → 1.6.3-beta.2

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/cli.js CHANGED
@@ -1,11 +1,18 @@
1
1
  #!/usr/bin/env node
2
- var Ae=Object.defineProperty;var a=(o,e)=>Ae(o,"name",{value:e,configurable:!0});var v=(o,e)=>()=>(o&&(e=o(o=0)),e);var ft=(o,e)=>{for(var t in e)Ae(o,t,{get:e[t],enumerable:!0})};import*as y from"fs";import*as I from"path";import X from"chalk";import k from"pino";function dt(o){let e=o.getFullYear(),t=String(o.getMonth()+1).padStart(2,"0"),n=String(o.getDate()).padStart(2,"0"),r=String(o.getHours()).padStart(2,"0"),i=String(o.getMinutes()).padStart(2,"0"),s=String(o.getSeconds()).padStart(2,"0");return`${e}-${t}-${n} ${r}:${i}:${s}`}var G,d,M=v(()=>{"use strict";a(dt,"formatDateTime");G=class{static{a(this,"Logger")}logFilePath=null;pinoInstance;isDaemonMode;maxLogFileSize=10*1024*1024;maxLogFiles=5;constructor(){this.isDaemonMode=process.env.XIAOZHI_DAEMON==="true",this.pinoInstance=this.createPinoInstance()}createPinoInstance(){let e=[];if(!this.isDaemonMode){let t=this.createOptimizedConsoleStream();e.push({level:"debug",stream:t})}return this.logFilePath&&e.push({level:"debug",stream:k.destination({dest:this.logFilePath,sync:!1,append:!0,mkdir:!0})}),e.length===0&&e.push({level:"debug",stream:k.destination({dest:"/dev/null"})}),k({level:"debug",timestamp:k.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:a((t,n)=>({level:n}),"level")},base:null,serializers:{err:k.stdSerializers?.err||(t=>t)}},k.multistream(e,{dedupe:!0}))}createOptimizedConsoleStream(){let e=new Map([[20,{name:"DEBUG",color:X.gray}],[30,{name:"INFO",color:X.blue}],[40,{name:"WARN",color:X.yellow}],[50,{name:"ERROR",color:X.red}],[60,{name:"FATAL",color:X.red}]]);return{write:a(t=>{try{let n=JSON.parse(t),r=this.formatConsoleMessageOptimized(n,e);this.safeWrite(`${r}
3
- `)}catch{this.safeWrite(t)}},"write")}}safeWrite(e){try{process.stderr&&typeof process.stderr.write=="function"?process.stderr.write(e):console&&typeof console.error=="function"&&console.error(e.trim())}catch{}}formatConsoleMessageOptimized(e,t){let n=dt(new Date),r=t.get(e.level)||{name:"UNKNOWN",color:a(l=>l,"color")},i=r.color(`[${r.name}]`),s=e.msg;if(e.args&&Array.isArray(e.args)){let l=e.args.map(p=>typeof p=="object"?JSON.stringify(p):String(p)).join(" ");s=`${s} ${l}`}return`[${n}] ${i} ${s}`}initLogFile(e){this.logFilePath=I.join(e,"xiaozhi.log"),this.rotateLogFileIfNeeded(),y.existsSync(this.logFilePath)||y.writeFileSync(this.logFilePath,""),this.pinoInstance=this.createPinoInstance()}enableFileLogging(e){e&&this.logFilePath&&(this.pinoInstance=this.createPinoInstance())}info(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}success(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}warn(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.warn(e):this.pinoInstance.warn({args:t},e):this.pinoInstance.warn(e,t[0]||"")}error(e,...t){if(typeof e=="string")if(t.length===0)this.pinoInstance.error(e);else{let n=t.map(r=>r instanceof Error?{message:r.message,stack:r.stack,name:r.name,cause:r.cause}:r);this.pinoInstance.error({args:n},e)}else{let n=this.enhanceErrorObject(e);this.pinoInstance.error(n,t[0]||"")}}debug(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.debug(e):this.pinoInstance.debug({args:t},e):this.pinoInstance.debug(e,t[0]||"")}log(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}enhanceErrorObject(e){let t={...e};for(let[n,r]of Object.entries(t))r instanceof Error&&(t[n]={message:r.message,stack:r.stack,name:r.name,cause:r.cause});return t}rotateLogFileIfNeeded(){if(!(!this.logFilePath||!y.existsSync(this.logFilePath)))try{y.statSync(this.logFilePath).size>this.maxLogFileSize&&this.rotateLogFile()}catch{}}rotateLogFile(){if(this.logFilePath)try{let e=I.dirname(this.logFilePath),t=I.basename(this.logFilePath,".log");for(let r=this.maxLogFiles-1;r>=1;r--){let i=I.join(e,`${t}.${r}.log`),s=I.join(e,`${t}.${r+1}.log`);y.existsSync(i)&&(r===this.maxLogFiles-1?y.unlinkSync(i):y.renameSync(i,s))}let n=I.join(e,`${t}.1.log`);y.renameSync(this.logFilePath,n)}catch{}}cleanupOldLogs(){if(this.logFilePath)try{let e=I.dirname(this.logFilePath),t=I.basename(this.logFilePath,".log");for(let n=this.maxLogFiles+1;n<=this.maxLogFiles+10;n++){let r=I.join(e,`${t}.${n}.log`);y.existsSync(r)&&y.unlinkSync(r)}}catch{}}setLogFileOptions(e,t){this.maxLogFileSize=e,this.maxLogFiles=t}withTag(e){return this}close(){}},d=new G});import te from"ws";var D,ne=v(()=>{"use strict";M();D=class{static{a(this,"ProxyMCPServer")}endpointUrl;ws=null;logger;isConnected=!1;serverInitialized=!1;tools=new Map;connectionState="disconnected";reconnectOptions;reconnectState={attempts:0,nextInterval:0,timer:null,lastError:null,isManualDisconnect:!1};connectionTimeout=null;constructor(e,t){this.endpointUrl=e,this.logger=d,this.reconnectOptions={enabled:!0,maxAttempts:10,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0,...t?.reconnect},this.reconnectState.nextInterval=this.reconnectOptions.initialInterval}setServiceManager(e){this.serviceManager=e,this.logger.info("\u5DF2\u8BBE\u7F6E MCPServiceManager"),this.syncToolsFromServiceManager()}syncToolsFromServiceManager(){let e=this.serviceManager;if(!e){this.logger.debug("MCPServiceManager \u672A\u8BBE\u7F6E\uFF0C\u8DF3\u8FC7\u5DE5\u5177\u540C\u6B65");return}try{let t=e.getAllTools(),n=new Map;for(let r of t)n.set(r.name,{name:r.name,description:r.description,inputSchema:r.inputSchema});this.tools=n,this.logger.info(`\u5DF2\u4ECE MCPServiceManager \u540C\u6B65 ${this.tools.size} \u4E2A\u5DE5\u5177`)}catch(t){this.logger.error(`\u540C\u6B65\u5DE5\u5177\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}addTool(e,t){return this.validateTool(e,t),this.tools.set(e,t),this.logger.debug(`\u5DE5\u5177 '${e}' \u5DF2\u6DFB\u52A0`),this}addTools(e){for(let[t,n]of Object.entries(e))this.addTool(t,n);return this}removeTool(e){return this.tools.delete(e)?this.logger.debug(`\u5DE5\u5177 '${e}' \u5DF2\u79FB\u9664`):this.logger.warn(`\u5C1D\u8BD5\u79FB\u9664\u4E0D\u5B58\u5728\u7684\u5DE5\u5177: '${e}'`),this}getTools(){try{this.syncToolsFromServiceManager()}catch{}return Array.from(this.tools.values())}hasTool(e){return this.tools.has(e)}validateTool(e,t){if(!e||typeof e!="string"||e.trim()==="")throw new Error("\u5DE5\u5177\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(this.tools.has(e))throw new Error(`\u5DE5\u5177 '${e}' \u5DF2\u5B58\u5728`);if(!t||typeof t!="object")throw new Error("\u5DE5\u5177\u5FC5\u987B\u662F\u6709\u6548\u7684\u5BF9\u8C61");if(!t.name||typeof t.name!="string")throw new Error("\u5DE5\u5177\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 'name' \u5B57\u6BB5");if(!t.description||typeof t.description!="string")throw new Error("\u5DE5\u5177\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 'description' \u5B57\u6BB5");if(!t.inputSchema||typeof t.inputSchema!="object")throw new Error("\u5DE5\u5177\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 'inputSchema' \u5B57\u6BB5");if(!t.inputSchema.type||!t.inputSchema.properties)throw new Error("\u5DE5\u5177\u7684 inputSchema \u5FC5\u987B\u5305\u542B 'type' \u548C 'properties' \u5B57\u6BB5")}async connect(){if(this.tools.size===0)throw new Error("\u672A\u914D\u7F6E\u4EFB\u4F55\u5DE5\u5177\u3002\u8BF7\u5728\u8FDE\u63A5\u524D\u81F3\u5C11\u6DFB\u52A0\u4E00\u4E2A\u5DE5\u5177\u3002");if(this.connectionState==="connecting")throw new Error("\u8FDE\u63A5\u6B63\u5728\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u8FDE\u63A5\u5B8C\u6210");return this.cleanupConnection(),this.reconnectState.isManualDisconnect=!1,this.attemptConnection()}async attemptConnection(){return this.connectionState="connecting",this.logger.info(`\u6B63\u5728\u8FDE\u63A5 MCP \u63A5\u5165\u70B9: ${this.endpointUrl} (\u5C1D\u8BD5 ${this.reconnectState.attempts+1}/${this.reconnectOptions.maxAttempts})`),new Promise((e,t)=>{this.connectionTimeout=setTimeout(()=>{let n=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(n),t(n)},this.reconnectOptions.timeout),this.ws=new te(this.endpointUrl),this.ws.on("open",()=>{this.handleConnectionSuccess(),e()}),this.ws.on("message",n=>{try{let r=JSON.parse(n.toString());this.handleMessage(r)}catch(r){this.logger.error("MCP \u6D88\u606F\u89E3\u6790\u9519\u8BEF:",r)}}),this.ws.on("close",(n,r)=>{this.handleConnectionClose(n,r.toString())}),this.ws.on("error",n=>{this.handleConnectionError(n),t(n)})})}handleConnectionSuccess(){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=!0,this.connectionState="connected",this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info("MCP WebSocket \u8FDE\u63A5\u5DF2\u5EFA\u7ACB")}handleConnectionError(e){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.reconnectState.lastError=e,this.logger.error("MCP WebSocket \u9519\u8BEF:",e.message),this.cleanupConnection()}handleConnectionClose(e,t){if(this.isConnected=!1,this.serverInitialized=!1,this.logger.info(`MCP \u8FDE\u63A5\u5DF2\u5173\u95ED (\u4EE3\u7801: ${e}, \u539F\u56E0: ${t})`),this.reconnectState.isManualDisconnect){this.connectionState="disconnected";return}this.shouldReconnect()?this.scheduleReconnect():(this.connectionState="failed",this.logger.warn(`\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 (${this.reconnectOptions.maxAttempts})\uFF0C\u505C\u6B62\u91CD\u8FDE`))}shouldReconnect(){return this.reconnectOptions.enabled&&this.reconnectState.attempts<this.reconnectOptions.maxAttempts&&!this.reconnectState.isManualDisconnect}scheduleReconnect(){this.connectionState="reconnecting",this.reconnectState.attempts++,this.calculateNextInterval(),this.logger.info(`\u5C06\u5728 ${this.reconnectState.nextInterval}ms \u540E\u8FDB\u884C\u7B2C ${this.reconnectState.attempts} \u6B21\u91CD\u8FDE`),this.reconnectState.timer&&clearTimeout(this.reconnectState.timer),this.reconnectState.timer=setTimeout(async()=>{try{await this.attemptConnection()}catch{}},this.reconnectState.nextInterval)}calculateNextInterval(){let e;switch(this.reconnectOptions.backoffStrategy){case"fixed":e=this.reconnectOptions.initialInterval;break;case"linear":e=this.reconnectOptions.initialInterval+this.reconnectState.attempts*this.reconnectOptions.backoffMultiplier*1e3;break;case"exponential":e=this.reconnectOptions.initialInterval*this.reconnectOptions.backoffMultiplier**(this.reconnectState.attempts-1);break;default:e=this.reconnectOptions.initialInterval}if(e=Math.min(e,this.reconnectOptions.maxInterval),this.reconnectOptions.jitter){let t=e*.1,n=(Math.random()-.5)*2*t;e+=n}this.reconnectState.nextInterval=Math.max(e,1e3)}cleanupConnection(){if(this.ws){this.ws.removeAllListeners();try{this.ws.readyState===te.OPEN?this.ws.close(1e3,"Cleaning up connection"):this.ws.readyState===te.CONNECTING&&this.ws.terminate()}catch(e){this.logger.debug("WebSocket \u5173\u95ED\u65F6\u51FA\u73B0\u9519\u8BEF\uFF08\u5DF2\u5FFD\u7565\uFF09:",e)}this.ws=null}this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=!1,this.serverInitialized=!1}stopReconnect(){this.reconnectState.timer&&(clearTimeout(this.reconnectState.timer),this.reconnectState.timer=null)}handleMessage(e){this.logger.debug("\u6536\u5230 MCP \u6D88\u606F:",JSON.stringify(e,null,2)),e.method&&this.handleServerRequest(e)}handleServerRequest(e){switch(e.method){case"initialize":this.sendResponse(e.id,{protocolVersion:"2024-11-05",capabilities:{tools:{listChanged:!0},logging:{}},serverInfo:{name:"xiaozhi-mcp-server",version:"1.0.0"}}),this.serverInitialized=!0,this.logger.info("MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210");break;case"tools/list":{let t=this.getTools();this.sendResponse(e.id,{tools:t}),this.logger.info(`MCP \u5DE5\u5177\u5217\u8868\u5DF2\u53D1\u9001 (${t.length}\u4E2A\u5DE5\u5177)`);break}case"ping":this.sendResponse(e.id,{}),this.logger.debug("\u56DE\u5E94 MCP ping \u6D88\u606F");break;default:this.logger.warn(`\u672A\u77E5\u7684 MCP \u8BF7\u6C42: ${e.method}`)}}sendResponse(e,t){if(this.isConnected&&this.ws?.readyState===te.OPEN){let n={jsonrpc:"2.0",id:e,result:t};this.ws.send(JSON.stringify(n))}}getStatus(){return{connected:this.isConnected,initialized:this.serverInitialized,url:this.endpointUrl,availableTools:this.tools.size,connectionState:this.connectionState,reconnectAttempts:this.reconnectState.attempts,lastError:this.reconnectState.lastError?.message||null}}disconnect(){this.logger.info("\u4E3B\u52A8\u65AD\u5F00 MCP \u8FDE\u63A5"),this.reconnectState.isManualDisconnect=!0,this.stopReconnect(),this.cleanupConnection(),this.connectionState="disconnected"}async reconnect(){this.logger.info("\u624B\u52A8\u91CD\u8FDE MCP \u63A5\u5165\u70B9"),this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.isManualDisconnect=!1,this.cleanupConnection(),await this.connect()}enableReconnect(){this.reconnectOptions.enabled=!0,this.logger.info("\u81EA\u52A8\u91CD\u8FDE\u5DF2\u542F\u7528")}disableReconnect(){this.reconnectOptions.enabled=!1,this.stopReconnect(),this.logger.info("\u81EA\u52A8\u91CD\u8FDE\u5DF2\u7981\u7528")}updateReconnectOptions(e){this.reconnectOptions={...this.reconnectOptions,...e},this.logger.info("\u91CD\u8FDE\u914D\u7F6E\u5DF2\u66F4\u65B0",e)}getReconnectOptions(){return{...this.reconnectOptions}}resetReconnectState(){this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info("\u91CD\u8FDE\u72B6\u6001\u5DF2\u91CD\u7F6E")}}});import{SSEClientTransport as Ne}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as ut}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as mt}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{EventSource as St}from"eventsource";function Ct(){return d}function vt(o){switch(Ct().info(`[TransportFactory] \u521B\u5EFA ${o.type} transport for ${o.name}`),o.type){case"stdio":return yt(o);case"sse":return Mt(o);case"modelscope-sse":return bt(o);case"streamable-http":return Pt(o);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${o.type}`)}}function yt(o){if(!o.command)throw new Error("stdio transport \u9700\u8981 command \u914D\u7F6E");return new ut({command:o.command,args:o.args||[]})}function Mt(o){if(!o.url)throw new Error("SSE transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(o.url),t=wt(o);return new Ne(e,t)}function bt(o){if(!o.url)throw new Error("ModelScope SSE transport \u9700\u8981 URL \u914D\u7F6E");if(!o.apiKey)throw new Error("ModelScope SSE transport \u9700\u8981 apiKey \u914D\u7F6E");let e=new URL(o.url),t=Tt(o);return new Ne(e,t)}function Pt(o){if(!o.url)throw new Error("StreamableHTTP transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(o.url),t=Et(o);return new mt(e,t)}function wt(o){let e={};return o.apiKey?e.headers={Authorization:`Bearer ${o.apiKey}`,...o.headers}:o.headers&&(e.headers=o.headers),e}function Tt(o){let e=o.apiKey;return o.customSSEOptions?o.customSSEOptions:{eventSourceInit:{fetch:a(async(t,n)=>{let r={...n?.headers,Authorization:`Bearer ${e}`};return fetch(t,{...n,headers:r})},"fetch")},requestInit:{headers:{Authorization:`Bearer ${e}`,...o.headers}}}}function Et(o){let e={};return o.apiKey?e.headers={Authorization:`Bearer ${o.apiKey}`,...o.headers}:o.headers&&(e.headers=o.headers),e}function It(o){if(!o.name||typeof o.name!="string")throw new Error("\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 name \u5B57\u6BB5");if(!o.type)throw new Error("\u914D\u7F6E\u5FC5\u987B\u5305\u542B type \u5B57\u6BB5");switch(o.type){case"stdio":if(!o.command)throw new Error("stdio \u7C7B\u578B\u9700\u8981 command \u5B57\u6BB5");break;case"sse":case"streamable-http":if(!o.url)throw new Error(`${o.type} \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5`);break;case"modelscope-sse":if(!o.url)throw new Error("modelscope-sse \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5");if(!o.apiKey)throw new Error("modelscope-sse \u7C7B\u578B\u9700\u8981 apiKey \u5B57\u6BB5\u3002\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E modelscope.apiKey \u6216\u786E\u4FDD\u670D\u52A1\u914D\u7F6E\u5305\u542B apiKey");break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${o.type}`)}}function Rt(){return["stdio","sse","modelscope-sse","streamable-http"]}var pe,De=v(()=>{"use strict";M();oe();typeof global<"u"&&!global.EventSource&&(global.EventSource=St);a(Ct,"getLogger");a(vt,"createTransport");a(yt,"createStdioTransport");a(Mt,"createSSETransport");a(bt,"createModelScopeSSETransport");a(Pt,"createStreamableHTTPTransport");a(wt,"createSSEOptions");a(Tt,"createModelScopeSSEOptions");a(Et,"createStreamableHTTPOptions");a(It,"validateConfig");a(Rt,"getSupportedTypes");pe={create:vt,validateConfig:It,getSupportedTypes:Rt}});import{Client as xt}from"@modelcontextprotocol/sdk/client/index.js";var J,re,oe=v(()=>{"use strict";M();De();J=(r=>(r.STDIO="stdio",r.SSE="sse",r.STREAMABLE_HTTP="streamable-http",r.MODELSCOPE_SSE="modelscope-sse",r))(J||{}),re=class{static{a(this,"MCPService")}config;client=null;transport=null;tools=new Map;connectionState="disconnected";reconnectOptions;reconnectState;logger;connectionTimeout=null;initialized=!1;pingOptions;pingTimer=null;pingFailureCount=0;lastPingTime=null;isPinging=!1;constructor(e,t){this.config=e,this.logger=d,this.validateConfig(),this.reconnectOptions={enabled:!0,maxAttempts:10,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0,...t?.reconnect,...e.reconnect},this.pingOptions={enabled:!0,interval:3e4,timeout:5e3,maxFailures:3,startDelay:5e3,...e.ping},this.reconnectState={attempts:0,nextInterval:this.reconnectOptions.initialInterval,timer:null,lastError:null,isManualDisconnect:!1}}logWithTag(e,t,...n){let r=`[MCP-${this.config.name}] ${t}`;this.logger[e](r,...n)}validateConfig(){pe.validateConfig(this.config)}async connect(){if(this.connectionState==="connecting")throw new Error("\u8FDE\u63A5\u6B63\u5728\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u8FDE\u63A5\u5B8C\u6210");return this.cleanupConnection(),this.reconnectState.isManualDisconnect=!1,this.attemptConnection()}async attemptConnection(){return this.connectionState="connecting",this.logWithTag("info",`\u6B63\u5728\u8FDE\u63A5 MCP \u670D\u52A1: ${this.config.name} (\u5C1D\u8BD5 ${this.reconnectState.attempts+1}/${this.reconnectOptions.maxAttempts})`),new Promise((e,t)=>{this.connectionTimeout=setTimeout(()=>{let n=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(n),t(n)},this.reconnectOptions.timeout);try{this.client=new xt({name:`xiaozhi-${this.config.name}-client`,version:"1.0.0"},{capabilities:{tools:{}}}),this.transport=pe.create(this.config),this.client.connect(this.transport).then(async()=>{this.handleConnectionSuccess(),await this.refreshTools(),e()}).catch(n=>{this.handleConnectionError(n),t(n)})}catch(n){this.handleConnectionError(n),t(n)}})}handleConnectionSuccess(){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.connectionState="connected",this.initialized=!0,this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.resetPingState(),this.logWithTag("info",`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u5DF2\u5EFA\u7ACB`),this.startPingMonitoring()}handleConnectionError(e){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.reconnectState.lastError=e,this.logger.error(`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u9519\u8BEF:`,e.message),this.cleanupConnection(),this.shouldReconnect()?this.scheduleReconnect():(this.connectionState="failed",this.logger.warn(`${this.config.name} \u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 (${this.reconnectOptions.maxAttempts})\uFF0C\u505C\u6B62\u91CD\u8FDE`))}shouldReconnect(){return this.reconnectOptions.enabled&&this.reconnectState.attempts<this.reconnectOptions.maxAttempts&&!this.reconnectState.isManualDisconnect}scheduleReconnect(){this.connectionState="reconnecting",this.reconnectState.attempts++,this.calculateNextInterval(),this.logger.info(`${this.config.name} \u5C06\u5728 ${this.reconnectState.nextInterval}ms \u540E\u8FDB\u884C\u7B2C ${this.reconnectState.attempts} \u6B21\u91CD\u8FDE`),this.reconnectState.timer&&clearTimeout(this.reconnectState.timer),this.reconnectState.timer=setTimeout(async()=>{try{await this.attemptConnection()}catch{}},this.reconnectState.nextInterval)}calculateNextInterval(){let e;switch(this.reconnectOptions.backoffStrategy){case"fixed":e=this.reconnectOptions.initialInterval;break;case"linear":e=this.reconnectOptions.initialInterval+this.reconnectState.attempts*this.reconnectOptions.backoffMultiplier*1e3;break;case"exponential":e=this.reconnectOptions.initialInterval*this.reconnectOptions.backoffMultiplier**(this.reconnectState.attempts-1);break;default:e=this.reconnectOptions.initialInterval}if(e=Math.min(e,this.reconnectOptions.maxInterval),this.reconnectOptions.jitter){let t=e*.1,n=(Math.random()-.5)*2*t;e+=n}this.reconnectState.nextInterval=Math.max(e,1e3)}cleanupConnection(){if(this.stopPingMonitoring(),this.client){try{this.client.close().catch(()=>{})}catch{}this.client=null}this.transport=null,this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.initialized=!1}stopReconnect(){this.reconnectState.timer&&(clearTimeout(this.reconnectState.timer),this.reconnectState.timer=null)}async refreshTools(){if(!this.client)throw new Error("\u5BA2\u6237\u7AEF\u672A\u521D\u59CB\u5316");try{let t=(await this.client.listTools()).tools||[];this.tools.clear();for(let n of t)this.tools.set(n.name,n);this.logger.info(`${this.config.name} \u670D\u52A1\u52A0\u8F7D\u4E86 ${t.length} \u4E2A\u5DE5\u5177: ${t.map(n=>n.name).join(", ")}`)}catch(e){throw this.logger.error(`${this.config.name} \u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25:`,e instanceof Error?e.message:String(e)),e}}async disconnect(){this.logger.info(`\u4E3B\u52A8\u65AD\u5F00 MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5`),this.reconnectState.isManualDisconnect=!0,this.stopPingMonitoring(),this.stopReconnect(),this.cleanupConnection(),this.connectionState="disconnected"}async reconnect(){this.logger.info(`\u624B\u52A8\u91CD\u8FDE MCP \u670D\u52A1 ${this.config.name}`),this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.isManualDisconnect=!1,this.cleanupConnection(),await this.connect()}getTools(){return Array.from(this.tools.values())}async callTool(e,t){if(!this.client)throw new Error(`\u670D\u52A1 ${this.config.name} \u672A\u8FDE\u63A5`);if(!this.tools.has(e))throw new Error(`\u5DE5\u5177 ${e} \u5728\u670D\u52A1 ${this.config.name} \u4E2D\u4E0D\u5B58\u5728`);this.logger.info(`\u8C03\u7528 ${this.config.name} \u670D\u52A1\u7684\u5DE5\u5177 ${e}\uFF0C\u53C2\u6570:`,JSON.stringify(t));try{let n=await this.client.callTool({name:e,arguments:t||{}});return this.logger.info(`\u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,`${JSON.stringify(n).substring(0,500)}...`),n}catch(n){throw this.logger.error(`\u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,n instanceof Error?n.message:String(n)),n}}getConfig(){return this.config}getStatus(){return{name:this.config.name,connected:this.connectionState==="connected",initialized:this.initialized,transportType:this.config.type,toolCount:this.tools.size,lastError:this.reconnectState.lastError?.message,reconnectAttempts:this.reconnectState.attempts,connectionState:this.connectionState,pingEnabled:this.pingOptions.enabled,lastPingTime:this.lastPingTime||void 0,pingFailureCount:this.pingFailureCount,isPinging:this.isPinging}}isConnected(){return this.connectionState==="connected"&&this.initialized}enableReconnect(){this.reconnectOptions.enabled=!0,this.logger.info(`${this.config.name} \u81EA\u52A8\u91CD\u8FDE\u5DF2\u542F\u7528`)}disableReconnect(){this.reconnectOptions.enabled=!1,this.stopReconnect(),this.logger.info(`${this.config.name} \u81EA\u52A8\u91CD\u8FDE\u5DF2\u7981\u7528`)}updateReconnectOptions(e){this.reconnectOptions={...this.reconnectOptions,...e},this.logger.info(`${this.config.name} \u91CD\u8FDE\u914D\u7F6E\u5DF2\u66F4\u65B0`,e)}getReconnectOptions(){return{...this.reconnectOptions}}resetReconnectState(){this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info(`${this.config.name} \u91CD\u8FDE\u72B6\u6001\u5DF2\u91CD\u7F6E`)}startPingMonitoring(){!this.pingOptions.enabled||this.pingTimer||!this.isConnected()||(this.logger.info(`${this.config.name} \u542F\u52A8ping\u76D1\u63A7\uFF0C\u95F4\u9694: ${this.pingOptions.interval}ms`),setTimeout(()=>{this.isConnected()&&!this.pingTimer&&(this.pingTimer=setInterval(()=>{this.performPing()},this.pingOptions.interval))},this.pingOptions.startDelay))}stopPingMonitoring(){this.pingTimer&&(clearInterval(this.pingTimer),this.pingTimer=null,this.logger.debug(`${this.config.name} \u505C\u6B62ping\u76D1\u63A7`))}async performPing(){if(!this.client||this.isPinging||!this.isConnected())return;this.isPinging=!0;let e=performance.now();try{this.logger.debug(`${this.config.name} \u53D1\u9001ping\u8BF7\u6C42\uFF08\u901A\u8FC7listTools\u68C0\u6D4B\u8FDE\u63A5\uFF09`);let t=this.client.listTools(),n=new Promise((i,s)=>{setTimeout(()=>{s(new Error(`Ping\u8D85\u65F6 (${this.pingOptions.timeout}ms)`))},this.pingOptions.timeout)});await Promise.race([t,n]);let r=performance.now()-e;this.handlePingSuccess(r)}catch(t){let n=performance.now()-e;this.handlePingFailure(t,n)}finally{this.isPinging=!1}}handlePingSuccess(e){this.pingFailureCount=0,this.lastPingTime=new Date,this.logger.debug(`${this.config.name} ping\u6210\u529F\uFF0C\u5EF6\u8FDF: ${e.toFixed(2)}ms`)}handlePingFailure(e,t){if(this.pingFailureCount++,this.logger.warn(`${this.config.name} ping\u5931\u8D25 (${this.pingFailureCount}/${this.pingOptions.maxFailures})\uFF0C\u5EF6\u8FDF: ${t.toFixed(2)}ms\uFF0C\u9519\u8BEF: ${e.message}`),this.pingFailureCount>=this.pingOptions.maxFailures){this.logger.error(`${this.config.name} \u8FDE\u7EEDping\u5931\u8D25\u8FBE\u5230\u9608\u503C\uFF0C\u89E6\u53D1\u91CD\u8FDE\u673A\u5236`),this.stopPingMonitoring();let n=new Error(`Ping\u68C0\u6D4B\u5931\u8D25\uFF0C\u8FDE\u7EED\u5931\u8D25${this.pingFailureCount}\u6B21\uFF0C\u8FDE\u63A5\u53EF\u80FD\u5DF2\u65AD\u5F00`);this.handleConnectionError(n)}}resetPingState(){this.pingFailureCount=0,this.lastPingTime=null,this.isPinging=!1}enablePing(){this.pingOptions.enabled=!0,this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u542F\u7528`),this.isConnected()&&this.startPingMonitoring()}disablePing(){this.pingOptions.enabled=!1,this.stopPingMonitoring(),this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u7981\u7528`)}updatePingOptions(e){let t=this.pingOptions.enabled;this.pingOptions={...this.pingOptions,...e},this.logger.info(`${this.config.name} ping\u914D\u7F6E\u5DF2\u66F4\u65B0`,e),t!==this.pingOptions.enabled&&(this.pingOptions.enabled&&this.isConnected()?this.startPingMonitoring():this.pingOptions.enabled||this.stopPingMonitoring())}getPingOptions(){return{...this.pingOptions}}}});function Ft(o){if(!o||typeof o!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u6709\u6548\u7684\u5BF9\u8C61");if("command"in o&&typeof o.command=="string")return"stdio";if("type"in o&&o.type==="sse")return"sse";if("type"in o&&o.type==="streamable-http"||"url"in o&&typeof o.url=="string")return"streamable-http";throw new Error("\u65E0\u6CD5\u8BC6\u522B\u7684 MCP \u670D\u52A1\u914D\u7F6E\u7C7B\u578B\u3002\u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5\uFF08stdio\uFF09\u3001type: 'sse' \u5B57\u6BB5\uFF08sse\uFF09\u6216 url \u5B57\u6BB5\uFF08streamable-http\uFF09")}function de(o,e){if(!e||typeof e!="object")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61`};try{switch(Ft(e)){case"stdio":if(!e.command||typeof e.command!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 command \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(!Array.isArray(e.args))return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4`};if(e.env&&typeof e.env!="object")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61`};break;case"sse":if(e.type!=="sse")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 type \u5B57\u6BB5\u5FC5\u987B\u662F "sse"`};if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};break;case"streamable-http":if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(e.type&&e.type!=="streamable-http")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 type \u5B57\u6BB5\u5982\u679C\u5B58\u5728\uFF0C\u5FC5\u987B\u662F "streamable-http"`};break;default:return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u7C7B\u578B\u65E0\u6CD5\u8BC6\u522B`}}return{valid:!0}}catch(t){return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u65E0\u6548: ${t instanceof Error?t.message:"\u672A\u77E5\u9519\u8BEF"}`}}}var ze=v(()=>{"use strict";a(Ft,"getMcpServerCommunicationType");a(de,"validateMcpServerConfig")});import{copyFileSync as Lt,existsSync as ue,readFileSync as Ut,writeFileSync as Wt}from"fs";import{dirname as _t,resolve as K}from"path";import{fileURLToPath as Bt}from"url";import*as ie from"comment-json";import Xt from"dayjs";import me from"json5";import*as je from"json5-writer";var Gt,Se,Ce,g,z=v(()=>{"use strict";M();ze();Gt=_t(Bt(import.meta.url)),Se={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},Ce=class o{static{a(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;constructor(){this.defaultConfigPath=K(Gt,"xiaozhi.config.default.json")}getConfigFilePath(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let n of t){let r=K(e,n);if(ue(r))return r}return K(e,"xiaozhi.config.json")}getConfigFileFormat(e){return e.endsWith(".json5")?"json5":e.endsWith(".jsonc")?"jsonc":"json"}static getInstance(){return o.instance||(o.instance=new o),o.instance}configExists(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let n of t){let r=K(e,n);if(ue(r))return!0}return!1}initConfig(e="json"){if(!ue(this.defaultConfigPath))throw new Error("\u9ED8\u8BA4\u914D\u7F6E\u6587\u4EF6 xiaozhi.config.default.json \u4E0D\u5B58\u5728");if(this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u521D\u59CB\u5316");let t=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),n=`xiaozhi.config.${e}`,r=K(t,n);Lt(this.defaultConfigPath,r),this.config=null,this.json5Writer=null}loadConfig(){if(!this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C xiaozhi init \u521D\u59CB\u5316\u914D\u7F6E");try{let e=this.getConfigFilePath();this.currentConfigPath=e;let t=this.getConfigFileFormat(e),r=Ut(e,"utf8").replace(/^\uFEFF/,""),i;switch(t){case"json5":i=me.parse(r),this.json5Writer=je.load(r);break;case"jsonc":i=ie.parse(r);break;default:i=JSON.parse(r);break}return this.validateConfig(i),i}catch(e){throw e instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${e.message}`):e}}validateConfig(e){if(!e||typeof e!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let t=e;if(t.mcpEndpoint===void 0||t.mcpEndpoint===null)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(typeof t.mcpEndpoint!="string")if(Array.isArray(t.mcpEndpoint)){if(t.mcpEndpoint.length===0)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let n of t.mcpEndpoint)if(typeof n!="string"||n.trim()==="")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6216\u5B57\u7B26\u4E32\u6570\u7EC4");if(!t.mcpServers||typeof t.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[n,r]of Object.entries(t.mcpServers)){if(!r||typeof r!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${n} \u65E0\u6548`);let i=de(n,r);if(!i.valid)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A${i.error}`)}}getConfig(){return this.config=this.loadConfig(),JSON.parse(JSON.stringify(this.config))}getMutableConfig(){return this.config||(this.config=this.loadConfig()),this.config}getMcpEndpoint(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?e.mcpEndpoint[0]||"":e.mcpEndpoint}getMcpEndpoints(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?[...e.mcpEndpoint]:e.mcpEndpoint?[e.mcpEndpoint]:[]}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(e){return this.getMcpServerConfig()[e]?.tools||{}}isToolEnabled(e,t){return this.getServerToolsConfig(e)[t]?.enable!==!1}updateMcpEndpoint(e){if(Array.isArray(e)){if(e.length===0)throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let n of e)if(!n||typeof n!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig();t.mcpEndpoint=e,this.saveConfig(t)}addMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),n=this.getMcpEndpoints();if(n.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let r=[...n,e];t.mcpEndpoint=r,this.saveConfig(t)}removeMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),n=this.getMcpEndpoints();if(n.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);if(n.length===1)throw new Error("\u4E0D\u80FD\u5220\u9664\u6700\u540E\u4E00\u4E2A MCP \u7AEF\u70B9");let i=n.filter(s=>s!==e);t.mcpEndpoint=i,this.saveConfig(t)}updateMcpServer(e,t){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let n=de(e,t);if(!n.valid)throw new Error(n.error||"\u670D\u52A1\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let r=this.getMutableConfig();r.mcpServers[e]=t,this.saveConfig(r)}removeMcpServer(e){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getConfig();if(!t.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);let n={...t.mcpServers};delete n[e];let r={...t,mcpServers:n};this.saveConfig(r)}updateServerToolsConfig(e,t){let n=this.getMutableConfig();n.mcpServerConfig||(n.mcpServerConfig={}),Object.keys(t).length===0?delete n.mcpServerConfig[e]:n.mcpServerConfig[e]={tools:t},this.saveConfig(n)}removeServerToolsConfig(e){let n={...this.getConfig()};n.mcpServerConfig&&(delete n.mcpServerConfig[e],this.saveConfig(n))}setToolEnabled(e,t,n,r){let i=this.getMutableConfig();i.mcpServerConfig||(i.mcpServerConfig={}),i.mcpServerConfig[e]||(i.mcpServerConfig[e]={tools:{}}),i.mcpServerConfig[e].tools[t]={...i.mcpServerConfig[e].tools[t],enable:n,...r&&{description:r}},this.saveConfig(i)}saveConfig(e){try{this.validateConfig(e);let t;this.currentConfigPath?t=this.currentConfigPath:(t=this.getConfigFilePath(),this.currentConfigPath=t);let n=this.getConfigFileFormat(t),r;switch(n){case"json5":try{this.json5Writer?(this.json5Writer.write(e),r=this.json5Writer.toSource()):(console.warn("\u6CA1\u6709 json5Writer \u5B9E\u4F8B\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F"),r=me.stringify(e,null,2))}catch(i){console.warn("\u4F7F\u7528 json5-writer \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F:",i),r=me.stringify(e,null,2)}break;case"jsonc":try{r=ie.stringify(e,null,2)}catch(i){console.warn("\u4F7F\u7528 comment-json \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON \u683C\u5F0F:",i),r=JSON.stringify(e,null,2)}break;default:r=JSON.stringify(e,null,2);break}Wt(t,r,"utf8"),this.config=e,this.notifyConfigUpdate(e)}catch(t){throw new Error(`\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}reloadConfig(){this.config=null,this.currentConfigPath=null,this.json5Writer=null}getConfigPath(){return this.getConfigFilePath()}getDefaultConfigPath(){return this.defaultConfigPath}getConnectionConfig(){let t=this.getConfig().connection||{};return{heartbeatInterval:t.heartbeatInterval??Se.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??Se.heartbeatTimeout,reconnectInterval:t.reconnectInterval??Se.reconnectInterval}}getHeartbeatInterval(){return this.getConnectionConfig().heartbeatInterval}getHeartbeatTimeout(){return this.getConnectionConfig().heartbeatTimeout}getReconnectInterval(){return this.getConnectionConfig().reconnectInterval}updateConnectionConfig(e){let t=this.getMutableConfig();t.connection||(t.connection={}),Object.assign(t.connection,e),this.saveConfig(t)}async updateToolUsageStats(e,t,n){try{let r=this.getMutableConfig();r.mcpServerConfig||(r.mcpServerConfig={}),r.mcpServerConfig[e]||(r.mcpServerConfig[e]={tools:{}}),r.mcpServerConfig[e].tools[t]||(r.mcpServerConfig[e].tools[t]={enable:!0});let i=r.mcpServerConfig[e].tools[t],s=i.usageCount||0,l=i.lastUsedTime;i.usageCount=s+1,(!l||new Date(n)>new Date(l))&&(i.lastUsedTime=Xt(n).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(r),d.debug(`\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${e}/${t}, \u4F7F\u7528\u6B21\u6570: ${i.usageCount}`)}catch(r){d.error(`\u66F4\u65B0\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5931\u8D25 (${e}/${t}): ${r instanceof Error?r.message:String(r)}`)}}setHeartbeatInterval(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:e})}setHeartbeatTimeout(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:e})}setReconnectInterval(e){if(e<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:e})}getModelScopeConfig(){return this.getConfig().modelscope||{}}getModelScopeApiKey(){return this.getModelScopeConfig().apiKey||process.env.MODELSCOPE_API_TOKEN}updateModelScopeConfig(e){let t=this.getMutableConfig();t.modelscope||(t.modelscope={}),Object.assign(t.modelscope,e),this.saveConfig(t)}setModelScopeApiKey(e){if(!e||typeof e!="string")throw new Error("API Key \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");this.updateModelScopeConfig({apiKey:e})}getWebUIConfig(){return this.getConfig().webUI||{}}getWebUIPort(){return this.getWebUIConfig().port??9999}notifyConfigUpdate(e){try{let t=global.__webServer;t&&typeof t.broadcastConfigUpdate=="function"&&(t.broadcastConfigUpdate(e),console.log("\u5DF2\u901A\u8FC7 WebSocket \u5E7F\u64AD\u914D\u7F6E\u66F4\u65B0"))}catch(t){console.warn("\u901A\u77E5 Web \u754C\u9762\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",t instanceof Error?t.message:String(t))}}updateWebUIConfig(e){let t=this.getMutableConfig();t.webUI||(t.webUI={}),Object.assign(t.webUI,e),this.saveConfig(t)}setWebUIPort(e){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error("\u7AEF\u53E3\u53F7\u5FC5\u987B\u662F 1-65535 \u4E4B\u95F4\u7684\u6574\u6570");this.updateWebUIConfig({port:e})}},g=Ce.getInstance()});var q,He,ve=v(()=>{"use strict";M();z();oe();q=class{static{a(this,"MCPServiceManager")}services=new Map;configs={};logger;tools=new Map;constructor(e){this.logger=d,this.configs=e||{}}async startAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u542F\u52A8\u6240\u6709 MCP \u670D\u52A1...");let e=Object.entries(this.configs);if(e.length===0){this.logger.warn("[MCPManager] \u6CA1\u6709\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1\uFF0C\u8BF7\u4F7F\u7528 addServiceConfig() \u6DFB\u52A0\u670D\u52A1\u914D\u7F6E");return}for(let[t]of e)await this.startService(t);this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u542F\u52A8\u5B8C\u6210")}async startService(e){this.logger.info(`[MCPManager] \u542F\u52A8 MCP \u670D\u52A1: ${e}`);let t=this.configs[e];if(!t)throw new Error(`\u672A\u627E\u5230\u670D\u52A1\u914D\u7F6E: ${e}`);try{this.services.has(e)&&await this.stopService(e);let n=new re(t);await n.connect(),this.services.set(e,n),await this.refreshToolsCache();let r=n.getTools();this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u542F\u52A8\u6210\u529F\uFF0C\u52A0\u8F7D\u4E86 ${r.length} \u4E2A\u5DE5\u5177:`,r.map(i=>i.name).join(", "))}catch(n){throw this.logger.error(`[MCPManager] \u542F\u52A8 ${e} \u670D\u52A1\u5931\u8D25:`,n.message),n}}async stopService(e){this.logger.info(`[MCPManager] \u505C\u6B62 MCP \u670D\u52A1: ${e}`);let t=this.services.get(e);if(!t){this.logger.warn(`[MCPManager] \u670D\u52A1 ${e} \u4E0D\u5B58\u5728\u6216\u672A\u542F\u52A8`);return}try{await t.disconnect(),this.services.delete(e),await this.refreshToolsCache(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(n){throw this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,n.message),n}}async refreshToolsCache(){this.tools.clear();for(let[e,t]of this.services)if(t.isConnected()){let n=t.getTools();for(let r of n){let i=`${e}__${r.name}`;this.tools.set(i,{serviceName:e,originalName:r.name,tool:r})}}}getAllTools(){let e=[];for(let[t,n]of this.tools)e.push({name:t,description:n.tool.description||"",inputSchema:n.tool.inputSchema,serviceName:n.serviceName,originalName:n.originalName});return e}async callTool(e,t){this.logger.info(`[MCPManager] \u8C03\u7528\u5DE5\u5177: ${e}\uFF0C\u53C2\u6570:`,t);let n=this.tools.get(e);if(!n)throw new Error(`\u672A\u627E\u5230\u5DE5\u5177: ${e}`);let r=this.services.get(n.serviceName);if(!r)throw new Error(`\u670D\u52A1 ${n.serviceName} \u4E0D\u53EF\u7528`);if(!r.isConnected())throw new Error(`\u670D\u52A1 ${n.serviceName} \u672A\u8FDE\u63A5`);try{let i=await r.callTool(n.originalName,t||{});return this.logger.info(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,i),i}catch(i){throw this.logger.error(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,i.message),i}}async stopAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u505C\u6B62\u6240\u6709 MCP \u670D\u52A1...");for(let[e,t]of this.services)try{await t.disconnect(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(n){this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,n.message)}this.services.clear(),this.tools.clear(),this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u5DF2\u505C\u6B62")}getStatus(){let e={services:{},totalTools:this.tools.size,availableTools:Array.from(this.tools.keys())};for(let[t,n]of this.services){let r=n.getStatus();e.services[t]={connected:r.connected,clientName:`xiaozhi-${t}-client`}}return e}getService(e){return this.services.get(e)}getAllServices(){return new Map(this.services)}enhanceServiceConfig(e){let t={...e};try{if(e.type==="modelscope-sse"){let n=g.getModelScopeApiKey();if(n)t.apiKey=n,this.logger.info(`[MCPManager] \u4E3A ${e.name} \u670D\u52A1\u6DFB\u52A0 ModelScope API Key`);else throw this.logger.warn(`[MCPManager] ${e.name} \u670D\u52A1\u9700\u8981 ModelScope API Key\uFF0C\u4F46\u672A\u5728\u914D\u7F6E\u4E2D\u627E\u5230`),new Error(`ModelScope SSE \u670D\u52A1 ${e.name} \u9700\u8981 API Key\uFF0C\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E modelscope.apiKey`)}return t}catch(n){throw this.logger.error(`[MCPManager] \u914D\u7F6E\u589E\u5F3A\u5931\u8D25: ${e.name}`,n),n}}addServiceConfig(e,t){let n,r;if(typeof e=="string"&&t)r=e,n=t;else if(typeof e=="object")r=e.name,n=e;else throw new Error("Invalid arguments for addServiceConfig");let i=this.enhanceServiceConfig(n);this.configs[r]=i,this.logger.info(`[MCPManager] \u5DF2\u6DFB\u52A0\u670D\u52A1\u914D\u7F6E: ${r}`)}updateServiceConfig(e,t){let n=this.enhanceServiceConfig(t);this.configs[e]=n,this.logger.info(`[MCPManager] \u5DF2\u66F4\u65B0\u5E76\u589E\u5F3A\u670D\u52A1\u914D\u7F6E: ${e}`)}removeServiceConfig(e){delete this.configs[e],this.logger.info(`[MCPManager] \u5DF2\u79FB\u9664\u670D\u52A1\u914D\u7F6E: ${e}`)}},He=q});var _,Y=v(()=>{"use strict";M();_=class{static{a(this,"TransportAdapter")}logger;messageHandler;connectionId;config;state="disconnected";constructor(e,t){this.messageHandler=e,this.config=t,this.connectionId=this.generateConnectionId(),this.logger=d}async handleIncomingMessage(e){try{this.logger.debug(`\u5904\u7406\u63A5\u6536\u5230\u7684\u6D88\u606F: ${e.method}`,e);let t=await this.messageHandler.handleMessage(e);this.logger.debug("\u53D1\u9001\u54CD\u5E94\u6D88\u606F:",t),await this.sendMessage(t)}catch(t){this.logger.error(`\u5904\u7406\u6D88\u606F\u65F6\u51FA\u9519: ${e.method}`,t);let n=this.createErrorResponse(t,e.id);await this.sendMessage(n)}}createErrorResponse(e,t){let n=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?n=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(n=-32602),{jsonrpc:"2.0",error:{code:n,message:e.message,data:{stack:e.stack}},id:t||null}}generateConnectionId(){let e=Date.now(),t=Math.random().toString(36).substr(2,9);return`${this.config.name}_${e}_${t}`}getConnectionId(){return this.connectionId}getState(){return this.state}setState(e){let t=this.state;this.state=e,t!==e&&(this.logger.info(`\u8FDE\u63A5\u72B6\u6001\u53D8\u66F4: ${t} -> ${e}`),this.onStateChange(t,e))}onStateChange(e,t){}getConfig(){return{...this.config}}getMessageHandler(){return this.messageHandler}parseMessage(e){try{let t=JSON.parse(e.trim());return!t.jsonrpc||t.jsonrpc!=="2.0"?(this.logger.warn("\u6536\u5230\u975E JSON-RPC 2.0 \u683C\u5F0F\u7684\u6D88\u606F",t),null):t.method?t:(this.logger.warn("\u6536\u5230\u6CA1\u6709 method \u5B57\u6BB5\u7684\u6D88\u606F",t),null)}catch(t){return this.logger.error("\u89E3\u6790 JSON \u6D88\u606F\u5931\u8D25",{data:e,error:t}),null}}serializeMessage(e){try{return JSON.stringify(e)}catch(t){this.logger.error("\u5E8F\u5217\u5316\u6D88\u606F\u5931\u8D25",{message:e,error:t});let n=t instanceof Error?t.message:String(t);throw new Error(`\u6D88\u606F\u5E8F\u5217\u5316\u5931\u8D25: ${n}`)}}validateMessage(e){return!(!e||typeof e!="object"||e.jsonrpc!=="2.0"||e.method&&typeof e.method!="string"||!e.method&&!e.result&&!e.error)}createTimeoutPromise(e,t){return Promise.race([e,new Promise((n,r)=>{setTimeout(()=>{r(new Error(`\u64CD\u4F5C\u8D85\u65F6: ${t}ms`))},t)})])}}});import{randomUUID as un}from"crypto";import we from"express";var ae,Qe=v(()=>{"use strict";Y();ae=class extends _{static{a(this,"HTTPAdapter")}app;server=null;clients=new Map;port;host;enableSSE;enableRPC;corsOrigin;maxClients;constructor(e,t={name:"http"}){super(e,t),this.port=t.port||3e3,this.host=t.host||"0.0.0.0",this.enableSSE=t.enableSSE!==!1,this.enableRPC=t.enableRPC!==!1,this.corsOrigin=t.corsOrigin||"*",this.maxClients=t.maxClients!==void 0?t.maxClients:100,this.app=we(),this.setupMiddleware()}async initialize(){this.logger.info("\u521D\u59CB\u5316 HTTP \u9002\u914D\u5668");try{this.setupRoutes(),this.setState("connecting"),this.logger.info("HTTP \u9002\u914D\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("HTTP \u9002\u914D\u5668\u521D\u59CB\u5316\u5931\u8D25",e),this.setState("error"),e}}async start(){if(this.server){this.logger.warn("HTTP \u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C");return}return this.logger.info(`\u542F\u52A8 HTTP \u670D\u52A1\u5668\u5728 ${this.host}:${this.port}`),new Promise((e,t)=>{this.server=this.app.listen(this.port,this.host,()=>{this.setState("connected"),this.logger.info("HTTP \u9002\u914D\u5668\u542F\u52A8\u6210\u529F"),this.logger.info(`- RPC \u7AEF\u70B9: http://${this.host}:${this.port}/rpc`),this.enableSSE&&(this.logger.info(`- SSE \u7AEF\u70B9: http://${this.host}:${this.port}/sse`),this.logger.info(`- \u6D88\u606F\u7AEF\u70B9: http://${this.host}:${this.port}/messages`)),e()}),this.server?.on("error",n=>{this.logger.error("HTTP \u670D\u52A1\u5668\u9519\u8BEF",n),this.setState("error"),t(n)})})}async stop(){if(this.server)return this.logger.info("\u505C\u6B62 HTTP \u670D\u52A1\u5668"),new Promise(e=>{for(let t of this.clients.values())t.response.end();this.clients.clear(),this.server.close(()=>{this.server=null,this.setState("disconnected"),this.logger.info("HTTP \u670D\u52A1\u5668\u5DF2\u505C\u6B62"),e()})})}async sendMessage(e){this.clients.size>0&&this.broadcastToClients(e)}setupMiddleware(){this.app.use(we.json({limit:"10mb"})),this.app.use(we.urlencoded({extended:!0})),this.app.use((e,t,n)=>{t.header("Access-Control-Allow-Origin",this.corsOrigin),t.header("Access-Control-Allow-Methods","GET, POST, OPTIONS"),t.header("Access-Control-Allow-Headers","Content-Type, Accept"),t.header("Cache-Control","no-cache"),n()}),this.app.use((e,t,n)=>{this.logger.debug(`${e.method} ${e.path}`,{query:e.query,headers:e.headers}),n()})}setupRoutes(){this.enableSSE&&(this.app.get("/sse",this.handleSSE.bind(this)),this.app.post("/messages",this.handleMessages.bind(this))),this.enableRPC&&this.app.post("/rpc",this.handleRPC.bind(this)),this.app.get("/status",this.handleStatus.bind(this)),this.app.get("/health",this.handleHealth.bind(this))}handleSSE(e,t){if(this.clients.size>=this.maxClients){t.status(503).json({error:"\u670D\u52A1\u5668\u7E41\u5FD9\uFF0C\u5BA2\u6237\u7AEF\u8FDE\u63A5\u6570\u5DF2\u8FBE\u4E0A\u9650",maxClients:this.maxClients});return}let n=Date.now().toString(),r=un();t.setHeader("Content-Type","text/event-stream"),t.setHeader("Cache-Control","no-cache, no-transform"),t.setHeader("Connection","keep-alive"),t.setHeader("X-Accel-Buffering","no");let i={id:n,sessionId:r,response:t,connectedAt:new Date};this.clients.set(r,i),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u8FDE\u63A5: ${n} (\u4F1A\u8BDD: ${r})`),t.write(`event: endpoint
2
+ var Oe=Object.defineProperty;var jn=Object.getOwnPropertyDescriptor;var Hn=Object.getOwnPropertyNames;var Ln=Object.prototype.hasOwnProperty;var a=(i,e)=>Oe(i,"name",{value:e,configurable:!0});var h=(i,e)=>()=>(i&&(e=i(i=0)),e);var k=(i,e)=>{for(var t in e)Oe(i,t,{get:e[t],enumerable:!0})},Un=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Hn(e))!Ln.call(i,r)&&r!==t&&Oe(i,r,{get:()=>e[r],enumerable:!(n=jn(e,r))||n.enumerable});return i};var W=i=>Un(Oe({},"__esModule",{value:!0}),i);import*as I from"fs";import*as z from"path";import Se from"chalk";import se from"pino";function _n(i){let e=i.getFullYear(),t=String(i.getMonth()+1).padStart(2,"0"),n=String(i.getDate()).padStart(2,"0"),r=String(i.getHours()).padStart(2,"0"),o=String(i.getMinutes()).padStart(2,"0"),s=String(i.getSeconds()).padStart(2,"0");return`${e}-${t}-${n} ${r}:${o}:${s}`}var ye,f,R=h(()=>{"use strict";a(_n,"formatDateTime");ye=class{static{a(this,"Logger")}logFilePath=null;pinoInstance;isDaemonMode;maxLogFileSize=10*1024*1024;maxLogFiles=5;constructor(){this.isDaemonMode=process.env.XIAOZHI_DAEMON==="true",this.pinoInstance=this.createPinoInstance()}createPinoInstance(){let e=[];if(!this.isDaemonMode){let t=this.createOptimizedConsoleStream();e.push({level:"debug",stream:t})}return this.logFilePath&&e.push({level:"debug",stream:se.destination({dest:this.logFilePath,sync:!1,append:!0,mkdir:!0})}),e.length===0&&e.push({level:"debug",stream:se.destination({dest:"/dev/null"})}),se({level:"debug",timestamp:se.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:a((t,n)=>({level:n}),"level")},base:null,serializers:{err:se.stdSerializers?.err||(t=>t)}},se.multistream(e,{dedupe:!0}))}createOptimizedConsoleStream(){let e=new Map([[20,{name:"DEBUG",color:Se.gray}],[30,{name:"INFO",color:Se.blue}],[40,{name:"WARN",color:Se.yellow}],[50,{name:"ERROR",color:Se.red}],[60,{name:"FATAL",color:Se.red}]]);return{write:a(t=>{try{let n=JSON.parse(t),r=this.formatConsoleMessageOptimized(n,e);this.safeWrite(`${r}
3
+ `)}catch{this.safeWrite(t)}},"write")}}safeWrite(e){try{process.stderr&&typeof process.stderr.write=="function"?process.stderr.write(e):console&&typeof console.error=="function"&&console.error(e.trim())}catch{}}formatConsoleMessageOptimized(e,t){let n=_n(new Date),r=t.get(e.level)||{name:"UNKNOWN",color:a(c=>c,"color")},o=r.color(`[${r.name}]`),s=e.msg;if(e.args&&Array.isArray(e.args)){let c=e.args.map(l=>typeof l=="object"?JSON.stringify(l):String(l)).join(" ");s=`${s} ${c}`}return`[${n}] ${o} ${s}`}initLogFile(e){this.logFilePath=z.join(e,"xiaozhi.log"),this.rotateLogFileIfNeeded(),I.existsSync(this.logFilePath)||I.writeFileSync(this.logFilePath,""),this.pinoInstance=this.createPinoInstance()}enableFileLogging(e){e&&this.logFilePath&&(this.pinoInstance=this.createPinoInstance())}info(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}success(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}warn(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.warn(e):this.pinoInstance.warn({args:t},e):this.pinoInstance.warn(e,t[0]||"")}error(e,...t){if(typeof e=="string")if(t.length===0)this.pinoInstance.error(e);else{let n=t.map(r=>r instanceof Error?{message:r.message,stack:r.stack,name:r.name,cause:r.cause}:r);this.pinoInstance.error({args:n},e)}else{let n=this.enhanceErrorObject(e);this.pinoInstance.error(n,t[0]||"")}}debug(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.debug(e):this.pinoInstance.debug({args:t},e):this.pinoInstance.debug(e,t[0]||"")}log(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}enhanceErrorObject(e){let t={...e};for(let[n,r]of Object.entries(t))r instanceof Error&&(t[n]={message:r.message,stack:r.stack,name:r.name,cause:r.cause});return t}rotateLogFileIfNeeded(){if(!(!this.logFilePath||!I.existsSync(this.logFilePath)))try{I.statSync(this.logFilePath).size>this.maxLogFileSize&&this.rotateLogFile()}catch{}}rotateLogFile(){if(this.logFilePath)try{let e=z.dirname(this.logFilePath),t=z.basename(this.logFilePath,".log");for(let r=this.maxLogFiles-1;r>=1;r--){let o=z.join(e,`${t}.${r}.log`),s=z.join(e,`${t}.${r+1}.log`);I.existsSync(o)&&(r===this.maxLogFiles-1?I.unlinkSync(o):I.renameSync(o,s))}let n=z.join(e,`${t}.1.log`);I.renameSync(this.logFilePath,n)}catch{}}cleanupOldLogs(){if(this.logFilePath)try{let e=z.dirname(this.logFilePath),t=z.basename(this.logFilePath,".log");for(let n=this.maxLogFiles+1;n<=this.maxLogFiles+10;n++){let r=z.join(e,`${t}.${n}.log`);I.existsSync(r)&&I.unlinkSync(r)}}catch{}}setLogFileOptions(e,t){this.maxLogFileSize=e,this.maxLogFiles=t}withTag(e){return this}close(){}},f=new ye});function Wn(i){if(!i||typeof i!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u6709\u6548\u7684\u5BF9\u8C61");if("command"in i&&typeof i.command=="string")return"stdio";if("type"in i&&i.type==="sse")return"sse";if("type"in i&&i.type==="streamable-http"||"url"in i&&typeof i.url=="string")return"streamable-http";throw new Error("\u65E0\u6CD5\u8BC6\u522B\u7684 MCP \u670D\u52A1\u914D\u7F6E\u7C7B\u578B\u3002\u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5\uFF08stdio\uFF09\u3001type: 'sse' \u5B57\u6BB5\uFF08sse\uFF09\u6216 url \u5B57\u6BB5\uFF08streamable-http\uFF09")}function Qe(i,e){if(!e||typeof e!="object")return{valid:!1,error:`\u670D\u52A1 "${i}" \u7684\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61`};try{switch(Wn(e)){case"stdio":if(!e.command||typeof e.command!="string")return{valid:!1,error:`\u670D\u52A1 "${i}" \u7F3A\u5C11\u5FC5\u9700\u7684 command \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(!Array.isArray(e.args))return{valid:!1,error:`\u670D\u52A1 "${i}" \u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4`};if(e.env&&typeof e.env!="object")return{valid:!1,error:`\u670D\u52A1 "${i}" \u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61`};break;case"sse":if(e.type!=="sse")return{valid:!1,error:`\u670D\u52A1 "${i}" \u7684 type \u5B57\u6BB5\u5FC5\u987B\u662F "sse"`};if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${i}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};break;case"streamable-http":if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${i}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(e.type&&e.type!=="streamable-http")return{valid:!1,error:`\u670D\u52A1 "${i}" \u7684 type \u5B57\u6BB5\u5982\u679C\u5B58\u5728\uFF0C\u5FC5\u987B\u662F "streamable-http"`};break;default:return{valid:!1,error:`\u670D\u52A1 "${i}" \u7684\u914D\u7F6E\u7C7B\u578B\u65E0\u6CD5\u8BC6\u522B`}}return{valid:!0}}catch(t){return{valid:!1,error:`\u670D\u52A1 "${i}" \u7684\u914D\u7F6E\u65E0\u6548: ${t instanceof Error?t.message:"\u672A\u77E5\u9519\u8BEF"}`}}}var Ft=h(()=>{"use strict";a(Wn,"getMcpServerCommunicationType");a(Qe,"validateMcpServerConfig")});import{copyFileSync as Bn,existsSync as $e,readFileSync as Vn,writeFileSync as Xn}from"fs";import{dirname as Gn,resolve as te}from"path";import{fileURLToPath as Kn}from"url";import*as De from"comment-json";import Jn from"dayjs";import Ye from"json5";import*as jt from"json5-writer";var zt,et,tt,m,ae=h(()=>{"use strict";R();Ft();zt=Gn(Kn(import.meta.url)),et={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},tt=class i{static{a(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;constructor(){let e=[te(zt,"templates","default","xiaozhi.config.json"),te(zt,"..","templates","default","xiaozhi.config.json"),te(process.cwd(),"templates","default","xiaozhi.config.json")];this.defaultConfigPath=e.find(t=>$e(t))||e[0]}getConfigFilePath(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let n of t){let r=te(e,n);if($e(r))return r}return te(e,"xiaozhi.config.json")}getConfigFileFormat(e){return e.endsWith(".json5")?"json5":e.endsWith(".jsonc")?"jsonc":"json"}static getInstance(){return i.instance||(i.instance=new i),i.instance}configExists(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let n of t){let r=te(e,n);if($e(r))return!0}return!1}initConfig(e="json"){if(!$e(this.defaultConfigPath))throw new Error(`\u9ED8\u8BA4\u914D\u7F6E\u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728: ${this.defaultConfigPath}`);if(this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u521D\u59CB\u5316");let t=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),n=`xiaozhi.config.${e}`,r=te(t,n);Bn(this.defaultConfigPath,r),this.config=null,this.json5Writer=null}loadConfig(){if(!this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C xiaozhi init \u521D\u59CB\u5316\u914D\u7F6E");try{let e=this.getConfigFilePath();this.currentConfigPath=e;let t=this.getConfigFileFormat(e),r=Vn(e,"utf8").replace(/^\uFEFF/,""),o;switch(t){case"json5":o=Ye.parse(r),this.json5Writer=jt.load(r);break;case"jsonc":o=De.parse(r);break;default:o=JSON.parse(r);break}return this.validateConfig(o),o}catch(e){throw e instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${e.message}`):e}}validateConfig(e){if(!e||typeof e!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let t=e;if(t.mcpEndpoint===void 0||t.mcpEndpoint===null)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(typeof t.mcpEndpoint!="string")if(Array.isArray(t.mcpEndpoint)){if(t.mcpEndpoint.length===0)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let n of t.mcpEndpoint)if(typeof n!="string"||n.trim()==="")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6216\u5B57\u7B26\u4E32\u6570\u7EC4");if(!t.mcpServers||typeof t.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[n,r]of Object.entries(t.mcpServers)){if(!r||typeof r!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${n} \u65E0\u6548`);let o=Qe(n,r);if(!o.valid)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A${o.error}`)}}getConfig(){return this.config=this.loadConfig(),JSON.parse(JSON.stringify(this.config))}getMutableConfig(){return this.config||(this.config=this.loadConfig()),this.config}getMcpEndpoint(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?e.mcpEndpoint[0]||"":e.mcpEndpoint}getMcpEndpoints(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?[...e.mcpEndpoint]:e.mcpEndpoint?[e.mcpEndpoint]:[]}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(e){return this.getMcpServerConfig()[e]?.tools||{}}isToolEnabled(e,t){return this.getServerToolsConfig(e)[t]?.enable!==!1}updateMcpEndpoint(e){if(Array.isArray(e)){if(e.length===0)throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let n of e)if(!n||typeof n!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig();t.mcpEndpoint=e,this.saveConfig(t)}addMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),n=this.getMcpEndpoints();if(n.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let r=[...n,e];t.mcpEndpoint=r,this.saveConfig(t)}removeMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),n=this.getMcpEndpoints();if(n.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);if(n.length===1)throw new Error("\u4E0D\u80FD\u5220\u9664\u6700\u540E\u4E00\u4E2A MCP \u7AEF\u70B9");let o=n.filter(s=>s!==e);t.mcpEndpoint=o,this.saveConfig(t)}updateMcpServer(e,t){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let n=Qe(e,t);if(!n.valid)throw new Error(n.error||"\u670D\u52A1\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let r=this.getMutableConfig();r.mcpServers[e]=t,this.saveConfig(r)}removeMcpServer(e){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getConfig();if(!t.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);let n={...t.mcpServers};delete n[e];let r={...t,mcpServers:n};this.saveConfig(r)}updateServerToolsConfig(e,t){let n=this.getMutableConfig();n.mcpServerConfig||(n.mcpServerConfig={}),Object.keys(t).length===0?delete n.mcpServerConfig[e]:n.mcpServerConfig[e]={tools:t},this.saveConfig(n)}removeServerToolsConfig(e){let n={...this.getConfig()};n.mcpServerConfig&&(delete n.mcpServerConfig[e],this.saveConfig(n))}setToolEnabled(e,t,n,r){let o=this.getMutableConfig();o.mcpServerConfig||(o.mcpServerConfig={}),o.mcpServerConfig[e]||(o.mcpServerConfig[e]={tools:{}}),o.mcpServerConfig[e].tools[t]={...o.mcpServerConfig[e].tools[t],enable:n,...r&&{description:r}},this.saveConfig(o)}saveConfig(e){try{this.validateConfig(e);let t;this.currentConfigPath?t=this.currentConfigPath:(t=this.getConfigFilePath(),this.currentConfigPath=t);let n=this.getConfigFileFormat(t),r;switch(n){case"json5":try{this.json5Writer?(this.json5Writer.write(e),r=this.json5Writer.toSource()):(console.warn("\u6CA1\u6709 json5Writer \u5B9E\u4F8B\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F"),r=Ye.stringify(e,null,2))}catch(o){console.warn("\u4F7F\u7528 json5-writer \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F:",o),r=Ye.stringify(e,null,2)}break;case"jsonc":try{r=De.stringify(e,null,2)}catch(o){console.warn("\u4F7F\u7528 comment-json \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON \u683C\u5F0F:",o),r=JSON.stringify(e,null,2)}break;default:r=JSON.stringify(e,null,2);break}Xn(t,r,"utf8"),this.config=e,this.notifyConfigUpdate(e)}catch(t){throw new Error(`\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}reloadConfig(){this.config=null,this.currentConfigPath=null,this.json5Writer=null}getConfigPath(){return this.getConfigFilePath()}getDefaultConfigPath(){return this.defaultConfigPath}getConnectionConfig(){let t=this.getConfig().connection||{};return{heartbeatInterval:t.heartbeatInterval??et.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??et.heartbeatTimeout,reconnectInterval:t.reconnectInterval??et.reconnectInterval}}getHeartbeatInterval(){return this.getConnectionConfig().heartbeatInterval}getHeartbeatTimeout(){return this.getConnectionConfig().heartbeatTimeout}getReconnectInterval(){return this.getConnectionConfig().reconnectInterval}updateConnectionConfig(e){let t=this.getMutableConfig();t.connection||(t.connection={}),Object.assign(t.connection,e),this.saveConfig(t)}async updateToolUsageStats(e,t,n){try{let r=this.getMutableConfig();r.mcpServerConfig||(r.mcpServerConfig={}),r.mcpServerConfig[e]||(r.mcpServerConfig[e]={tools:{}}),r.mcpServerConfig[e].tools[t]||(r.mcpServerConfig[e].tools[t]={enable:!0});let o=r.mcpServerConfig[e].tools[t],s=o.usageCount||0,c=o.lastUsedTime;o.usageCount=s+1,(!c||new Date(n)>new Date(c))&&(o.lastUsedTime=Jn(n).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(r),f.debug(`\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${e}/${t}, \u4F7F\u7528\u6B21\u6570: ${o.usageCount}`)}catch(r){f.error(`\u66F4\u65B0\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5931\u8D25 (${e}/${t}): ${r instanceof Error?r.message:String(r)}`)}}setHeartbeatInterval(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:e})}setHeartbeatTimeout(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:e})}setReconnectInterval(e){if(e<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:e})}getModelScopeConfig(){return this.getConfig().modelscope||{}}getModelScopeApiKey(){return this.getModelScopeConfig().apiKey||process.env.MODELSCOPE_API_TOKEN}updateModelScopeConfig(e){let t=this.getMutableConfig();t.modelscope||(t.modelscope={}),Object.assign(t.modelscope,e),this.saveConfig(t)}setModelScopeApiKey(e){if(!e||typeof e!="string")throw new Error("API Key \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");this.updateModelScopeConfig({apiKey:e})}getWebUIConfig(){return this.getConfig().webUI||{}}getWebUIPort(){return this.getWebUIConfig().port??9999}notifyConfigUpdate(e){try{let t=global.__webServer;t&&typeof t.broadcastConfigUpdate=="function"&&(t.broadcastConfigUpdate(e),console.log("\u5DF2\u901A\u8FC7 WebSocket \u5E7F\u64AD\u914D\u7F6E\u66F4\u65B0"))}catch(t){console.warn("\u901A\u77E5 Web \u754C\u9762\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",t instanceof Error?t.message:String(t))}}updateWebUIConfig(e){let t=this.getMutableConfig();t.webUI||(t.webUI={}),Object.assign(t.webUI,e),this.saveConfig(t)}setWebUIPort(e){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error("\u7AEF\u53E3\u53F7\u5FC5\u987B\u662F 1-65535 \u4E4B\u95F4\u7684\u6574\u6570");this.updateWebUIConfig({port:e})}},m=tt.getInstance()});var nt,ce,we,u,rt,Me=h(()=>{"use strict";nt={NAME:"xiaozhi-mcp-service",DEFAULT_PORT:3e3,DEFAULT_WEB_UI_PORT:9999,PID_FILE:"xiaozhi.pid",LOG_FILE:"xiaozhi.log"},ce={FILE_NAMES:["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"],DEFAULT_FILE:"xiaozhi.config.default.json",DIR_ENV_VAR:"XIAOZHI_CONFIG_DIR"},we={WORK_DIR:".xiaozhi",TEMPLATES_DIR:"templates",LOGS_DIR:"logs"},u={GENERAL_ERROR:"GENERAL_ERROR",CONFIG_ERROR:"CONFIG_ERROR",SERVICE_ERROR:"SERVICE_ERROR",VALIDATION_ERROR:"VALIDATION_ERROR",FILE_ERROR:"FILE_ERROR",PROCESS_ERROR:"PROCESS_ERROR",NETWORK_ERROR:"NETWORK_ERROR",PERMISSION_ERROR:"PERMISSION_ERROR"},rt={PROCESS_STOP:3e3,SERVICE_START:1e4,NETWORK_REQUEST:5e3,FILE_OPERATION:2e3}});var qn,Zn,Ne,Ht=h(()=>{"use strict";Me();qn={[u.CONFIG_ERROR]:'\u8FD0\u884C "xiaozhi --help" \u67E5\u770B\u914D\u7F6E\u76F8\u5173\u547D\u4EE4',[u.SERVICE_ERROR]:'\u8FD0\u884C "xiaozhi status" \u68C0\u67E5\u670D\u52A1\u72B6\u6001',[u.VALIDATION_ERROR]:"\u68C0\u67E5\u8F93\u5165\u53C2\u6570\u662F\u5426\u6B63\u786E",[u.FILE_ERROR]:"\u68C0\u67E5\u6587\u4EF6\u8DEF\u5F84\u548C\u6743\u9650",[u.PROCESS_ERROR]:"\u68C0\u67E5\u8FDB\u7A0B\u72B6\u6001\u548C\u6743\u9650",[u.NETWORK_ERROR]:"\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u548C\u9632\u706B\u5899\u8BBE\u7F6E",[u.PERMISSION_ERROR]:"\u5C1D\u8BD5\u4F7F\u7528\u7BA1\u7406\u5458\u6743\u9650\u8FD0\u884C"},Zn={config_not_found:['\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6',"\u68C0\u67E5\u5F53\u524D\u76EE\u5F55\u662F\u5426\u4E3A\u9879\u76EE\u6839\u76EE\u5F55","\u8BBE\u7F6E XIAOZHI_CONFIG_DIR \u73AF\u5883\u53D8\u91CF\u6307\u5B9A\u914D\u7F6E\u76EE\u5F55"],service_port_occupied:["\u68C0\u67E5\u7AEF\u53E3\u662F\u5426\u88AB\u5176\u4ED6\u7A0B\u5E8F\u5360\u7528",'\u4F7F\u7528 "lsof -i :\u7AEF\u53E3\u53F7" \u67E5\u770B\u7AEF\u53E3\u4F7F\u7528\u60C5\u51B5',"\u66F4\u6539\u914D\u7F6E\u6587\u4EF6\u4E2D\u7684\u7AEF\u53E3\u8BBE\u7F6E"],permission_denied:["\u68C0\u67E5\u6587\u4EF6\u548C\u76EE\u5F55\u6743\u9650","\u4F7F\u7528 sudo \u6216\u7BA1\u7406\u5458\u6743\u9650\u8FD0\u884C","\u786E\u4FDD\u5F53\u524D\u7528\u6237\u6709\u8DB3\u591F\u7684\u6743\u9650"],service_start_failed:["\u68C0\u67E5\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u662F\u5426\u6B63\u786E","\u67E5\u770B\u65E5\u5FD7\u6587\u4EF6\u83B7\u53D6\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F","\u786E\u4FDD\u6240\u6709\u4F9D\u8D56\u670D\u52A1\u6B63\u5E38\u8FD0\u884C"]},Ne=class{static{a(this,"ERROR_MESSAGES")}static getHelpMessage(e){return qn[e]}static getSolutions(e){return Zn[e]||[]}static formatError(e,t){return`${t?`[${t}] `:""}${e.message}`}static getFriendlyMessage(e){return{[u.CONFIG_ERROR]:"\u914D\u7F6E\u6587\u4EF6\u76F8\u5173\u9519\u8BEF",[u.SERVICE_ERROR]:"\u670D\u52A1\u8FD0\u884C\u76F8\u5173\u9519\u8BEF",[u.VALIDATION_ERROR]:"\u8F93\u5165\u9A8C\u8BC1\u9519\u8BEF",[u.FILE_ERROR]:"\u6587\u4EF6\u64CD\u4F5C\u9519\u8BEF",[u.PROCESS_ERROR]:"\u8FDB\u7A0B\u7BA1\u7406\u9519\u8BEF",[u.NETWORK_ERROR]:"\u7F51\u7EDC\u8FDE\u63A5\u9519\u8BEF",[u.PERMISSION_ERROR]:"\u6743\u9650\u4E0D\u8DB3\u9519\u8BEF"}[e]||"\u672A\u77E5\u9519\u8BEF"}static isRecoverable(e){return[u.NETWORK_ERROR,u.FILE_ERROR,u.SERVICE_ERROR].includes(e)}static getSeverity(e){return{[u.VALIDATION_ERROR]:"low",[u.FILE_ERROR]:"medium",[u.CONFIG_ERROR]:"medium",[u.NETWORK_ERROR]:"medium",[u.SERVICE_ERROR]:"high",[u.PROCESS_ERROR]:"high",[u.PERMISSION_ERROR]:"critical"}[e]||"medium"}}});var x,ne,M,v,p,q,B=h(()=>{"use strict";Me();x=class i extends Error{constructor(t,n,r=1,o){super(t);this.code=n;this.exitCode=r;this.suggestions=o;this.name="CLIError",Error.captureStackTrace&&Error.captureStackTrace(this,i)}static{a(this,"CLIError")}static withSuggestions(t,n,r){return new i(t,n,1,r)}},ne=class i extends x{static{a(this,"ConfigError")}constructor(e,t){super(e,u.CONFIG_ERROR,1,t),this.name="ConfigError"}static configNotFound(){return new i("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728",['\u8BF7\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6'])}static invalidFormat(e){return new i(`\u65E0\u6548\u7684\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F: ${e}`,["\u652F\u6301\u7684\u683C\u5F0F: json, json5, jsonc"])}},M=class i extends x{static{a(this,"ServiceError")}constructor(e,t){super(e,u.SERVICE_ERROR,1,t),this.name="ServiceError"}static alreadyRunning(e){return new i(`\u670D\u52A1\u5DF2\u7ECF\u5728\u8FD0\u884C (PID: ${e})`,['\u8BF7\u5148\u8FD0\u884C "xiaozhi stop" \u505C\u6B62\u73B0\u6709\u670D\u52A1'])}static notRunning(){return new i("\u670D\u52A1\u672A\u8FD0\u884C",['\u8BF7\u8FD0\u884C "xiaozhi start" \u542F\u52A8\u670D\u52A1'])}static startFailed(e){return new i(`\u670D\u52A1\u542F\u52A8\u5931\u8D25: ${e}`,["\u68C0\u67E5\u914D\u7F6E\u6587\u4EF6\u662F\u5426\u6B63\u786E","\u786E\u4FDD\u7AEF\u53E3\u672A\u88AB\u5360\u7528","\u67E5\u770B\u65E5\u5FD7\u6587\u4EF6\u83B7\u53D6\u8BE6\u7EC6\u4FE1\u606F"])}},v=class i extends x{static{a(this,"ValidationError")}constructor(e,t){super(`\u9A8C\u8BC1\u5931\u8D25: ${t} - ${e}`,u.VALIDATION_ERROR,1),this.name="ValidationError"}static invalidPort(e){return new i(`\u7AEF\u53E3\u53F7\u5FC5\u987B\u5728 1-65535 \u8303\u56F4\u5185\uFF0C\u5F53\u524D\u503C: ${e}`,"port")}static requiredField(e){return new i("\u5FC5\u586B\u5B57\u6BB5\u4E0D\u80FD\u4E3A\u7A7A",e)}},p=class i extends x{static{a(this,"FileError")}constructor(e,t,n){let r=t?`${e}: ${t}`:e;super(r,u.FILE_ERROR,1,n),this.name="FileError"}static notFound(e){return new i("\u6587\u4EF6\u4E0D\u5B58\u5728",e,["\u68C0\u67E5\u6587\u4EF6\u8DEF\u5F84\u662F\u5426\u6B63\u786E"])}static permissionDenied(e){return new i("\u6743\u9650\u4E0D\u8DB3",e,["\u68C0\u67E5\u6587\u4EF6\u6743\u9650\u6216\u4F7F\u7528\u7BA1\u7406\u5458\u6743\u9650\u8FD0\u884C"])}static alreadyExists(e){return new i("\u6587\u4EF6\u5DF2\u5B58\u5728",e,["\u4F7F\u7528\u4E0D\u540C\u7684\u6587\u4EF6\u540D\u6216\u5220\u9664\u73B0\u6709\u6587\u4EF6"])}},q=class i extends x{static{a(this,"ProcessError")}constructor(e,t,n){let r=t?`${e} (PID: ${t})`:e;super(r,u.PROCESS_ERROR,1,n),this.name="ProcessError"}static killFailed(e){return new i("\u65E0\u6CD5\u7EC8\u6B62\u8FDB\u7A0B",e,["\u8FDB\u7A0B\u53EF\u80FD\u5DF2\u7ECF\u505C\u6B62\u6216\u6743\u9650\u4E0D\u8DB3"])}static notFound(e){return new i("\u8FDB\u7A0B\u4E0D\u5B58\u5728",e)}}});import $ from"chalk";var V,ot=h(()=>{"use strict";Ht();B();V=class i{static{a(this,"ErrorHandler")}static handle(e){e instanceof x?i.handleCLIError(e):i.handleUnknownError(e),process.exit(1)}static handleCLIError(e){if(console.error($.red(`\u274C \u9519\u8BEF: ${e.message}`)),process.env.DEBUG&&console.error($.gray(`\u9519\u8BEF\u7801: ${e.code}`)),e.suggestions&&e.suggestions.length>0){console.log($.yellow("\u{1F4A1} \u5EFA\u8BAE:"));for(let n of e.suggestions)console.log($.gray(` ${n}`))}let t=Ne.getHelpMessage(e.code);t&&console.log($.blue(`\u2139\uFE0F ${t}`))}static handleUnknownError(e){console.error($.red(`\u274C \u672A\u77E5\u9519\u8BEF: ${e.message}`)),process.env.DEBUG||process.env.NODE_ENV==="development"?(console.error($.gray("\u5806\u6808\u4FE1\u606F:")),console.error($.gray(e.stack))):console.log($.yellow("\u{1F4A1} \u63D0\u793A: \u8BBE\u7F6E DEBUG=1 \u73AF\u5883\u53D8\u91CF\u67E5\u770B\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F"))}static async handleAsync(e,t){try{return await e()}catch(n){throw n instanceof x?n:n instanceof Error?new x(`${t}\u5931\u8D25: ${n.message}`,"OPERATION_FAILED",1):new x(`${t}\u5931\u8D25: \u672A\u77E5\u9519\u8BEF`,"OPERATION_FAILED",1)}}static handleSync(e,t){try{return e()}catch(n){throw n instanceof x?n:n instanceof Error?new x(`${t}\u5931\u8D25: ${n.message}`,"OPERATION_FAILED",1):new x(`${t}\u5931\u8D25: \u672A\u77E5\u9519\u8BEF`,"OPERATION_FAILED",1)}}static warn(e,t){if(console.warn($.yellow(`\u26A0\uFE0F \u8B66\u544A: ${e}`)),t&&t.length>0){console.log($.yellow("\u{1F4A1} \u5EFA\u8BAE:"));for(let n of t)console.log($.gray(` ${n}`))}}static info(e){console.log($.blue(`\u2139\uFE0F ${e}`))}static success(e){console.log($.green(`\u2705 ${e}`))}}});import P from"fs";import j from"path";var C,be=h(()=>{"use strict";B();C=class i{static{a(this,"FileUtils")}static exists(e){try{return P.existsSync(e)}catch{return!1}}static ensureDir(e){try{P.existsSync(e)||P.mkdirSync(e,{recursive:!0})}catch{throw new p("\u65E0\u6CD5\u521B\u5EFA\u76EE\u5F55",e)}}static readFile(e,t="utf8"){try{if(!i.exists(e))throw p.notFound(e);return P.readFileSync(e,t)}catch(n){throw n instanceof p?n:new p("\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6",e)}}static writeFile(e,t,n){try{if(!n?.overwrite&&i.exists(e))throw p.alreadyExists(e);let r=j.dirname(e);i.ensureDir(r),P.writeFileSync(e,t,"utf8")}catch(r){throw r instanceof p?r:new p("\u65E0\u6CD5\u5199\u5165\u6587\u4EF6",e)}}static copyFile(e,t,n){try{if(!i.exists(e))throw p.notFound(e);if(!n?.overwrite&&i.exists(t))throw p.alreadyExists(t);let r=j.dirname(t);i.ensureDir(r),P.copyFileSync(e,t)}catch(r){throw r instanceof p?r:new p("\u65E0\u6CD5\u590D\u5236\u6587\u4EF6",e)}}static deleteFile(e){try{i.exists(e)&&P.unlinkSync(e)}catch{throw new p("\u65E0\u6CD5\u5220\u9664\u6587\u4EF6",e)}}static copyDirectory(e,t,n={}){try{if(!i.exists(e))throw p.notFound(e);i.ensureDir(t);let r=P.readdirSync(e);for(let o of r){if(n.exclude?.includes(o))continue;let s=j.join(e,o),c=j.join(t,o);P.statSync(s).isDirectory()?n.recursive!==!1&&i.copyDirectory(s,c,n):i.copyFile(s,c,{overwrite:n.overwrite})}}catch(r){throw r instanceof p?r:new p("\u65E0\u6CD5\u590D\u5236\u76EE\u5F55",e)}}static deleteDirectory(e,t={}){try{i.exists(e)&&P.rmSync(e,{recursive:t.recursive??!0,force:!0})}catch{throw new p("\u65E0\u6CD5\u5220\u9664\u76EE\u5F55",e)}}static getFileInfo(e){try{if(!i.exists(e))throw p.notFound(e);let t=P.statSync(e);return{size:t.size,isFile:t.isFile(),isDirectory:t.isDirectory(),mtime:t.mtime,ctime:t.ctime}}catch(t){throw t instanceof p?t:new p("\u65E0\u6CD5\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F",e)}}static listDirectory(e,t={}){try{if(!i.exists(e))throw p.notFound(e);let n=P.readdirSync(e),r=[];for(let o of n){if(!t.includeHidden&&o.startsWith("."))continue;let s=j.join(e,o);if(r.push(s),t.recursive&&P.statSync(s).isDirectory()){let c=i.listDirectory(s,t);r=r.concat(c)}}return r}catch(n){throw n instanceof p?n:new p("\u65E0\u6CD5\u5217\u51FA\u76EE\u5F55\u5185\u5BB9",e)}}static createTempFile(e="xiaozhi-",t=".tmp"){let n=process.env.TMPDIR||process.env.TEMP||"/tmp",r=Date.now(),o=Math.random().toString(36).substring(2),s=`${e}${r}-${o}${t}`;return j.join(n,s)}static checkPermissions(e,t=P.constants.R_OK|P.constants.W_OK){try{return P.accessSync(e,t),!0}catch{return!1}}static getExtension(e){return j.extname(e).toLowerCase()}static getBaseName(e){return j.basename(e,j.extname(e))}static normalizePath(e){return j.normalize(e)}static resolvePath(e,t){return t?j.resolve(t,e):j.resolve(e)}}});var le,it=h(()=>{"use strict";le=class{static{a(this,"FormatUtils")}static formatUptime(e){let t=Math.floor(e/1e3),n=Math.floor(t/60),r=Math.floor(n/60),o=Math.floor(r/24);return o>0?`${o}\u5929 ${r%24}\u5C0F\u65F6 ${n%60}\u5206\u949F`:r>0?`${r}\u5C0F\u65F6 ${n%60}\u5206\u949F`:n>0?`${n}\u5206\u949F ${t%60}\u79D2`:`${t}\u79D2`}static formatFileSize(e){let t=["B","KB","MB","GB","TB"],n=e,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r++;return`${n.toFixed(r===0?0:1)} ${t[r]}`}static formatTimestamp(e,t="full"){let n=new Date(e);switch(t){case"date":return n.toLocaleDateString("zh-CN");case"time":return n.toLocaleTimeString("zh-CN");default:return n.toLocaleString("zh-CN")}}static formatPid(e){return`PID: ${e}`}static formatPort(e){return`\u7AEF\u53E3: ${e}`}static formatUrl(e,t,n,r){let o=`${e}://${t}:${n}`;return r?`${o}${r}`:o}static formatConfigPair(e,t){return typeof t=="object"?`${e}: ${JSON.stringify(t,null,2)}`:`${e}: ${t}`}static formatError(e,t=!1){let n=`\u9519\u8BEF: ${e.message}`;return t&&e.stack&&(n+=`
4
+ \u5806\u6808\u4FE1\u606F:
5
+ ${e.stack}`),n}static formatList(e,t="\u2022"){return e.map(n=>`${t} ${n}`).join(`
6
+ `)}static formatTable(e){if(e.length===0)return"";let t=Object.keys(e[0]),n=t.map(c=>Math.max(c.length,...e.map(l=>String(l[c]).length))),r=t.map((c,l)=>c.padEnd(n[l])).join(" | "),o=n.map(c=>"-".repeat(c)).join("-|-"),s=e.map(c=>t.map((l,d)=>String(c[l]).padEnd(n[d])).join(" | "));return[r,o,...s].join(`
7
+ `)}static formatProgressBar(e,t,n=20){let r=Math.min(e/t,1),o=Math.floor(r*n),s=n-o,c="\u2588".repeat(o)+"\u2591".repeat(s),l=Math.floor(r*100);return`[${c}] ${l}% (${e}/${t})`}static formatCommandArgs(e,t){let n=t.map(r=>r.includes(" ")?`"${r}"`:r);return`${e} ${n.join(" ")}`}static truncateText(e,t,n="..."){return e.length<=t?e:e.substring(0,t-n.length)+n}static formatJson(e,t=2){try{return JSON.stringify(e,null,t)}catch{return String(e)}}static formatBoolean(e,t="\u662F",n="\u5426"){return e?t:n}}});import y from"path";import{fileURLToPath as Lt}from"url";var w,ge=h(()=>{"use strict";Me();be();w=class i{static{a(this,"PathUtils")}static getPidFile(){let e=process.env[ce.DIR_ENV_VAR]||process.cwd();return y.join(e,`.${nt.NAME}.pid`)}static getLogFile(e){let t=e||process.cwd();return y.join(t,nt.LOG_FILE)}static getConfigDir(){return process.env[ce.DIR_ENV_VAR]||process.cwd()}static getWorkDir(){let e=i.getConfigDir();return y.join(e,we.WORK_DIR)}static getTemplatesDir(){let e=Lt(import.meta.url),t=y.dirname(e);return[y.join(t,we.TEMPLATES_DIR),y.join(t,"..","..","..",we.TEMPLATES_DIR),y.join(t,"..","..","..","..",we.TEMPLATES_DIR)]}static findTemplatesDir(){let e=i.getTemplatesDir();for(let t of e)if(C.exists(t))return t;return null}static getTemplatePath(e){let t=i.findTemplatesDir();if(!t)return null;let n=y.join(t,e);return C.exists(n)?n:null}static getScriptDir(){let e=Lt(import.meta.url);return y.dirname(e)}static getProjectRoot(){let e=i.getScriptDir();return y.join(e,"..","..","..")}static getDistDir(){let e=i.getProjectRoot();return y.join(e,"dist")}static getRelativePath(e){let t=i.getProjectRoot();return y.relative(t,e)}static resolveConfigPath(e){let t=i.getConfigDir();if(e)return y.join(t,`xiaozhi.config.${e}`);for(let n of ce.FILE_NAMES){let r=y.join(t,n);if(C.exists(r))return r}return y.join(t,ce.FILE_NAMES[2])}static getDefaultConfigPath(){let e=i.getProjectRoot();return y.join(e,ce.DEFAULT_FILE)}static validatePath(e){return!y.normalize(e).includes("..")}static ensurePathWithin(e,t){let n=y.resolve(t,e),r=y.resolve(t);if(!n.startsWith(r))throw new Error(`\u8DEF\u5F84 ${e} \u8D85\u51FA\u4E86\u5141\u8BB8\u7684\u8303\u56F4`);return n}static getExecutablePath(e){let t=process.argv[1],n=y.dirname(t);return y.join(n,`${e}.js`)}static getMcpServerProxyPath(){return i.getExecutablePath("mcpServerProxy")}static getWebServerStandalonePath(){return i.getExecutablePath("WebServerStandalone")}static createSafePath(...e){let t=y.join(...e),n=y.normalize(t);if(n.includes("..")||n.includes("~"))throw new Error(`\u4E0D\u5B89\u5168\u7684\u8DEF\u5F84: ${n}`);return n}static getTempDir(){return process.env.TMPDIR||process.env.TEMP||"/tmp"}static getHomeDir(){return process.env.HOME||process.env.USERPROFILE||""}}});import{execSync as Ut}from"child_process";var F,Ee=h(()=>{"use strict";Me();B();F=class i{static{a(this,"PlatformUtils")}static getCurrentPlatform(){return process.platform}static isWindows(){return process.platform==="win32"}static isMacOS(){return process.platform==="darwin"}static isLinux(){return process.platform==="linux"}static isUnixLike(){return!i.isWindows()}static isXiaozhiProcess(e){try{if(process.env.XIAOZHI_CONTAINER==="true"||process.env.NODE_ENV==="test")return process.kill(e,0),!0;try{let t="";return i.isWindows()?t=Ut(`tasklist /FI "PID eq ${e}" /FO CSV /NH`,{encoding:"utf8",timeout:rt.PROCESS_STOP}).toLowerCase():t=Ut(`ps -p ${e} -o comm=`,{encoding:"utf8",timeout:rt.PROCESS_STOP}).toLowerCase(),t.includes("node")||t.includes("xiaozhi")}catch{return process.kill(e,0),!0}}catch{return!1}}static async killProcess(e,t="SIGTERM"){try{process.kill(e,t);let n=0,r=30;for(;n<r;){await new Promise(o=>setTimeout(o,100));try{process.kill(e,0),n++}catch{return}}try{process.kill(e,0),process.kill(e,"SIGKILL"),await new Promise(o=>setTimeout(o,500))}catch{}}catch(n){throw new q(`\u65E0\u6CD5\u7EC8\u6B62\u8FDB\u7A0B: ${n instanceof Error?n.message:String(n)}`,e)}}static processExists(e){try{return process.kill(e,0),!0}catch{return!1}}static getSystemInfo(){return{platform:i.getCurrentPlatform(),arch:process.arch,nodeVersion:process.version,isContainer:process.env.XIAOZHI_CONTAINER==="true"}}static getEnvVar(e,t){return process.env[e]||t}static setEnvVar(e,t){process.env[e]=t}static isContainerEnvironment(){return process.env.XIAOZHI_CONTAINER==="true"}static isTestEnvironment(){return process.env.NODE_ENV==="test"}static isDevelopmentEnvironment(){return process.env.NODE_ENV==="development"}static getTailCommand(e){return i.isWindows()?{command:"powershell",args:["-Command",`Get-Content -Path "${e}" -Wait`]}:{command:"tail",args:["-f",e]}}}});var H,Ae=h(()=>{"use strict";B();H=class i{static{a(this,"Validation")}static validatePort(e){if(!Number.isInteger(e)||e<1||e>65535)throw v.invalidPort(e)}static validateConfigFormat(e){let t=["json","json5","jsonc"];if(!t.includes(e))throw new v(`\u65E0\u6548\u7684\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F: ${e}\uFF0C\u652F\u6301\u7684\u683C\u5F0F: ${t.join(", ")}`,"format");return e}static validateRequired(e,t){if(e==null||e==="")throw v.requiredField(t)}static validateStringLength(e,t,n={}){if(n.min!==void 0&&e.length<n.min)throw new v(`\u957F\u5EA6\u4E0D\u80FD\u5C11\u4E8E ${n.min} \u4E2A\u5B57\u7B26\uFF0C\u5F53\u524D\u957F\u5EA6: ${e.length}`,t);if(n.max!==void 0&&e.length>n.max)throw new v(`\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7 ${n.max} \u4E2A\u5B57\u7B26\uFF0C\u5F53\u524D\u957F\u5EA6: ${e.length}`,t)}static validateUrl(e,t="url"){try{new URL(e)}catch{throw new v(`\u65E0\u6548\u7684 URL \u683C\u5F0F: ${e}`,t)}}static validateWebSocketUrl(e,t="websocket_url"){i.validateUrl(e,t);let n=new URL(e);if(!["ws:","wss:"].includes(n.protocol))throw new v(`WebSocket URL \u5FC5\u987B\u4F7F\u7528 ws:// \u6216 wss:// \u534F\u8BAE\uFF0C\u5F53\u524D\u534F\u8BAE: ${n.protocol}`,t)}static validateHttpUrl(e,t="http_url"){i.validateUrl(e,t);let n=new URL(e);if(!["http:","https:"].includes(n.protocol))throw new v(`HTTP URL \u5FC5\u987B\u4F7F\u7528 http:// \u6216 https:// \u534F\u8BAE\uFF0C\u5F53\u524D\u534F\u8BAE: ${n.protocol}`,t)}static validateProjectName(e){i.validateRequired(e,"projectName"),i.validateStringLength(e,"projectName",{min:1,max:100});let t=/[<>:"/\\|?*]/,n=e.split("").some(r=>r.charCodeAt(0)<32);if(t.test(e)||n)throw new v('\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u5305\u542B\u4EE5\u4E0B\u5B57\u7B26: < > : " / \\ | ? * \u4EE5\u53CA\u63A7\u5236\u5B57\u7B26',"projectName");if(e.startsWith("."))throw new v("\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u4EE5\u70B9\u5F00\u5934","projectName")}static validateTemplateName(e){if(i.validateRequired(e,"templateName"),i.validateStringLength(e,"templateName",{min:1,max:50}),!/^[a-zA-Z0-9_-]+$/.test(e))throw new v("\u6A21\u677F\u540D\u79F0\u53EA\u80FD\u5305\u542B\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u8FDE\u5B57\u7B26\u548C\u4E0B\u5212\u7EBF","templateName")}static validateEnvVarName(e){if(i.validateRequired(e,"envVarName"),!/^[A-Z_][A-Z0-9_]*$/.test(e))throw new v("\u73AF\u5883\u53D8\u91CF\u540D\u79F0\u53EA\u80FD\u5305\u542B\u5927\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u4E0B\u5212\u7EBF\uFF0C\u4E14\u4E0D\u80FD\u4EE5\u6570\u5B57\u5F00\u5934","envVarName")}static validateJson(e,t="json"){try{return JSON.parse(e)}catch(n){throw new v(`\u65E0\u6548\u7684 JSON \u683C\u5F0F: ${n instanceof Error?n.message:String(n)}`,t)}}static validateNumberRange(e,t,n={}){if(n.min!==void 0&&e<n.min)throw new v(`\u503C\u4E0D\u80FD\u5C0F\u4E8E ${n.min}\uFF0C\u5F53\u524D\u503C: ${e}`,t);if(n.max!==void 0&&e>n.max)throw new v(`\u503C\u4E0D\u80FD\u5927\u4E8E ${n.max}\uFF0C\u5F53\u524D\u503C: ${e}`,t)}static validateArrayLength(e,t,n={}){if(n.min!==void 0&&e.length<n.min)throw new v(`\u6570\u7EC4\u957F\u5EA6\u4E0D\u80FD\u5C11\u4E8E ${n.min}\uFF0C\u5F53\u524D\u957F\u5EA6: ${e.length}`,t);if(n.max!==void 0&&e.length>n.max)throw new v(`\u6570\u7EC4\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7 ${n.max}\uFF0C\u5F53\u524D\u957F\u5EA6: ${e.length}`,t)}static validateObjectProperties(e,t,n="object"){for(let r of t)if(!(r in e))throw new v(`\u7F3A\u5C11\u5FC5\u9700\u7684\u5C5E\u6027: ${r}`,n)}static validateEnum(e,t,n){if(!t.includes(e))throw new v(`\u65E0\u6548\u7684\u503C: ${e}\uFF0C\u6709\u6548\u503C: ${t.join(", ")}`,n);return e}static validateRegex(e,t="regex"){try{return new RegExp(e)}catch(n){throw new v(`\u65E0\u6548\u7684\u6B63\u5219\u8868\u8FBE\u5F0F: ${n instanceof Error?n.message:String(n)}`,t)}}}});import ke from"fs";import X from"path";import{fileURLToPath as _t}from"url";var Fe,Wt=h(()=>{"use strict";B();Fe=class i{static{a(this,"VersionUtils")}static cachedVersion=null;static getVersion(){if(i.cachedVersion)return i.cachedVersion;try{let e=_t(import.meta.url),t=X.dirname(e),n=[X.join(t,"package.json"),X.join(t,"..","package.json"),X.join(t,"..","..","..","package.json"),X.join(t,"..","..","..","..","package.json")];for(let r of n)if(ke.existsSync(r)){let o=JSON.parse(ke.readFileSync(r,"utf8"));if(o.version)return i.cachedVersion=o.version,o.version}return i.cachedVersion="unknown","unknown"}catch(e){return console.warn("\u65E0\u6CD5\u4ECE package.json \u8BFB\u53D6\u7248\u672C\u4FE1\u606F:",e),i.cachedVersion="unknown","unknown"}}static getVersionInfo(){try{let e=_t(import.meta.url),t=X.dirname(e),n=[X.join(t,"package.json"),X.join(t,"..","package.json"),X.join(t,"..","..","..","package.json"),X.join(t,"..","..","..","..","package.json")];for(let r of n)if(ke.existsSync(r)){let o=JSON.parse(ke.readFileSync(r,"utf8"));return{version:o.version||"unknown",name:o.name,description:o.description,author:o.author}}return{version:"unknown"}}catch{throw new p("\u65E0\u6CD5\u8BFB\u53D6\u7248\u672C\u4FE1\u606F","package.json")}}static compareVersions(e,t){let n=e.split(".").map(Number),r=t.split(".").map(Number),o=Math.max(n.length,r.length);for(let s=0;s<o;s++){let c=n[s]||0,l=r[s]||0;if(c>l)return 1;if(c<l)return-1}return 0}static isValidVersion(e){return/^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/.test(e)}static clearCache(){i.cachedVersion=null}}});var Bt={};k(Bt,{ProcessManagerImpl:()=>st});var st,Vt=h(()=>{"use strict";B();be();it();ge();Ee();st=class{static{a(this,"ProcessManagerImpl")}getPidFilePath(){return w.getPidFile()}readPidFile(){try{let e=this.getPidFilePath();if(!C.exists(e))return null;let t=C.readFile(e).trim(),[n,r,o]=t.split("|"),s=Number.parseInt(n),c=Number.parseInt(r);return Number.isNaN(s)||Number.isNaN(c)?(this.cleanupPidFile(),null):{pid:s,startTime:c,mode:o||"foreground"}}catch{return this.cleanupPidFile(),null}}writePidFile(e,t){try{let n=`${e}|${Date.now()}|${t}`,r=this.getPidFilePath();C.writeFile(r,n,{overwrite:!0})}catch{throw new p("\u65E0\u6CD5\u5199\u5165 PID \u6587\u4EF6",this.getPidFilePath())}}isXiaozhiProcess(e){return F.isXiaozhiProcess(e)}getServiceStatus(){try{let e=this.readPidFile();if(!e)return{running:!1};if(!this.isXiaozhiProcess(e.pid))return this.cleanupPidFile(),{running:!1};let t=le.formatUptime(Date.now()-e.startTime);return{running:!0,pid:e.pid,uptime:t,mode:e.mode}}catch{return{running:!1}}}savePidInfo(e,t){this.writePidFile(e,t)}async killProcess(e){try{await F.killProcess(e)}catch(t){throw new q(`\u65E0\u6CD5\u7EC8\u6B62\u8FDB\u7A0B: ${t instanceof Error?t.message:String(t)}`,e)}}async gracefulKillProcess(e){try{process.kill(e,"SIGTERM");let t=0,n=30;for(;t<n;){await new Promise(r=>setTimeout(r,100));try{process.kill(e,0),t++}catch{return}}try{process.kill(e,0),process.kill(e,"SIGKILL"),await new Promise(r=>setTimeout(r,500))}catch{}}catch(t){throw new q(`\u65E0\u6CD5\u505C\u6B62\u8FDB\u7A0B: ${t instanceof Error?t.message:String(t)}`,e)}}cleanupPidFile(){try{let e=this.getPidFilePath();C.exists(e)&&C.deleteFile(e)}catch(e){console.warn("\u6E05\u7406 PID \u6587\u4EF6\u5931\u8D25:",e)}}processExists(e){return F.processExists(e)}cleanupContainerState(){if(F.isContainerEnvironment())try{this.cleanupPidFile()}catch{}}getProcessInfo(e){let t=this.processExists(e),n=t?this.isXiaozhiProcess(e):!1;return{exists:t,isXiaozhi:n}}validatePidFile(){try{return this.readPidFile()!==null}catch{return!1}}}});var Gt={};k(Gt,{DaemonManagerImpl:()=>at});import{spawn as Xt}from"child_process";import ze from"fs";var at,Kt=h(()=>{"use strict";B();ge();Ee();at=class{constructor(e,t){this.processManager=e;this.logger=t}static{a(this,"DaemonManagerImpl")}currentDaemon=null;async startDaemon(e,t={}){try{let n=this.processManager.getServiceStatus();if(n.running)throw M.alreadyRunning(n.pid);let r=await this.spawnDaemonProcess(e,t);this.currentDaemon=r,this.processManager.savePidInfo(r.pid,"daemon"),await this.setupLogging(r,t.logFileName||"xiaozhi.log"),this.setupEventHandlers(r),r.unref(),this.logger.info(`\u5B88\u62A4\u8FDB\u7A0B\u5DF2\u542F\u52A8 (PID: ${r.pid})`)}catch(n){throw new M(`\u542F\u52A8\u5B88\u62A4\u8FDB\u7A0B\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}async stopDaemon(){try{let e=this.processManager.getServiceStatus();if(!e.running)throw M.notRunning();await this.processManager.gracefulKillProcess(e.pid),this.processManager.cleanupPidFile(),this.currentDaemon=null,this.logger.info("\u5B88\u62A4\u8FDB\u7A0B\u5DF2\u505C\u6B62")}catch(e){throw new M(`\u505C\u6B62\u5B88\u62A4\u8FDB\u7A0B\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}async restartDaemon(e,t={}){try{this.processManager.getServiceStatus().running&&(await this.stopDaemon(),await new Promise(r=>setTimeout(r,1e3))),await this.startDaemon(e,t)}catch(n){throw new M(`\u91CD\u542F\u5B88\u62A4\u8FDB\u7A0B\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}getDaemonStatus(){return this.processManager.getServiceStatus()}async attachToLogs(e="xiaozhi.log"){try{let t=w.getLogFile();if(!ze.existsSync(t))throw new M("\u65E5\u5FD7\u6587\u4EF6\u4E0D\u5B58\u5728");let{command:n,args:r}=F.getTailCommand(t),o=Xt(n,r,{stdio:"inherit"});process.on("SIGINT",()=>{console.log(`
8
+ \u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C`),o.kill(),process.exit(0)}),o.on("exit",()=>{process.exit(0)}),o.on("error",s=>{throw new M(`\u8FDE\u63A5\u65E5\u5FD7\u5931\u8D25: ${s.message}`)})}catch(t){throw new M(`\u8FDE\u63A5\u65E5\u5FD7\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}async spawnDaemonProcess(e,t){let r=[w.getWebServerStandalonePath()];t.openBrowser&&r.push("--open-browser");let o={...process.env,XIAOZHI_CONFIG_DIR:w.getConfigDir(),XIAOZHI_DAEMON:"true",...t.env},s=Xt("node",r,{detached:!0,stdio:["ignore","pipe","pipe"],env:o,cwd:t.cwd||process.cwd()});if(!s.pid)throw new q("\u65E0\u6CD5\u542F\u52A8\u5B88\u62A4\u8FDB\u7A0B",0);return s}async setupLogging(e,t){try{let n=w.getLogFile(),o=(await import("path")).dirname(n);ze.existsSync(o)||ze.mkdirSync(o,{recursive:!0});let s=ze.createWriteStream(n,{flags:"a"});e.stdout?.pipe(s),e.stderr?.pipe(s);let c=new Date().toISOString();s.write(`
9
+ [${c}] \u5B88\u62A4\u8FDB\u7A0B\u542F\u52A8 (PID: ${e.pid})
10
+ `)}catch(n){this.logger.warn(`\u8BBE\u7F6E\u65E5\u5FD7\u91CD\u5B9A\u5411\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}setupEventHandlers(e){e.on("exit",(t,n)=>{t!==0&&t!==null?this.logger.error(`\u5B88\u62A4\u8FDB\u7A0B\u5F02\u5E38\u9000\u51FA (\u4EE3\u7801: ${t}, \u4FE1\u53F7: ${n})`):this.logger.info("\u5B88\u62A4\u8FDB\u7A0B\u6B63\u5E38\u9000\u51FA"),this.processManager.cleanupPidFile(),this.currentDaemon=null}),e.on("error",t=>{this.logger.error(`\u5B88\u62A4\u8FDB\u7A0B\u9519\u8BEF: ${t.message}`),this.processManager.cleanupPidFile(),this.currentDaemon=null}),e.on("disconnect",()=>{this.logger.info("\u5B88\u62A4\u8FDB\u7A0B\u65AD\u5F00\u8FDE\u63A5")})}async checkHealth(){try{let e=this.getDaemonStatus();if(!e.running||!e.pid)return!1;let t=this.processManager.getProcessInfo(e.pid);return t.exists&&t.isXiaozhi}catch{return!1}}getCurrentDaemon(){return this.currentDaemon}cleanup(){if(this.currentDaemon){try{this.currentDaemon.kill("SIGTERM")}catch(e){this.logger.warn(`\u6E05\u7406\u5B88\u62A4\u8FDB\u7A0B\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}this.currentDaemon=null}}}});import G from"ws";var E,Y,je=h(()=>{"use strict";R();E=class extends Error{constructor(t,n,r){super(n);this.code=t;this.data=r;this.name="ToolCallError"}static{a(this,"ToolCallError")}},Y=class{static{a(this,"ProxyMCPServer")}endpointUrl;ws=null;logger;isConnected=!1;serverInitialized=!1;tools=new Map;connectionState="disconnected";reconnectOptions;reconnectState={attempts:0,nextInterval:0,timer:null,lastError:null,isManualDisconnect:!1};connectionTimeout=null;performanceMetrics={totalCalls:0,successfulCalls:0,failedCalls:0,averageResponseTime:0,minResponseTime:Number.MAX_VALUE,maxResponseTime:0,successRate:0,lastUpdated:new Date};callRecords=[];maxCallRecords=100;retryConfig={maxAttempts:3,initialDelay:1e3,maxDelay:1e4,backoffMultiplier:2,retryableErrors:[-32001,-32002]};toolCallConfig={timeout:3e4,retryAttempts:3,retryDelay:1e3};constructor(e,t){this.endpointUrl=e,this.logger=f,this.reconnectOptions={enabled:!0,maxAttempts:10,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0,...t?.reconnect},this.reconnectState.nextInterval=this.reconnectOptions.initialInterval}setServiceManager(e){this.serviceManager=e,this.logger.info("\u5DF2\u8BBE\u7F6E MCPServiceManager"),this.syncToolsFromServiceManager()}syncToolsFromServiceManager(){let e=this.serviceManager;if(!e){this.logger.debug("MCPServiceManager \u672A\u8BBE\u7F6E\uFF0C\u8DF3\u8FC7\u5DE5\u5177\u540C\u6B65");return}try{let t=e.getAllTools(),n=new Map;for(let r of t)n.set(r.name,{name:r.name,description:r.description,inputSchema:r.inputSchema});this.tools=n,this.logger.info(`\u5DF2\u4ECE MCPServiceManager \u540C\u6B65 ${this.tools.size} \u4E2A\u5DE5\u5177`)}catch(t){this.logger.error(`\u540C\u6B65\u5DE5\u5177\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}addTool(e,t){return this.validateTool(e,t),this.tools.set(e,t),this.logger.debug(`\u5DE5\u5177 '${e}' \u5DF2\u6DFB\u52A0`),this}addTools(e){for(let[t,n]of Object.entries(e))this.addTool(t,n);return this}removeTool(e){return this.tools.delete(e)?this.logger.debug(`\u5DE5\u5177 '${e}' \u5DF2\u79FB\u9664`):this.logger.warn(`\u5C1D\u8BD5\u79FB\u9664\u4E0D\u5B58\u5728\u7684\u5DE5\u5177: '${e}'`),this}getTools(){try{this.syncToolsFromServiceManager()}catch{}return Array.from(this.tools.values())}hasTool(e){return this.tools.has(e)}validateTool(e,t){if(!e||typeof e!="string"||e.trim()==="")throw new Error("\u5DE5\u5177\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(this.tools.has(e))throw new Error(`\u5DE5\u5177 '${e}' \u5DF2\u5B58\u5728`);if(!t||typeof t!="object")throw new Error("\u5DE5\u5177\u5FC5\u987B\u662F\u6709\u6548\u7684\u5BF9\u8C61");if(!t.name||typeof t.name!="string")throw new Error("\u5DE5\u5177\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 'name' \u5B57\u6BB5");if(!t.description||typeof t.description!="string")throw new Error("\u5DE5\u5177\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 'description' \u5B57\u6BB5");if(!t.inputSchema||typeof t.inputSchema!="object")throw new Error("\u5DE5\u5177\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 'inputSchema' \u5B57\u6BB5");if(!t.inputSchema.type||!t.inputSchema.properties)throw new Error("\u5DE5\u5177\u7684 inputSchema \u5FC5\u987B\u5305\u542B 'type' \u548C 'properties' \u5B57\u6BB5")}async connect(){if(this.tools.size===0)throw new Error("\u672A\u914D\u7F6E\u4EFB\u4F55\u5DE5\u5177\u3002\u8BF7\u5728\u8FDE\u63A5\u524D\u81F3\u5C11\u6DFB\u52A0\u4E00\u4E2A\u5DE5\u5177\u3002");if(this.connectionState==="connecting")throw new Error("\u8FDE\u63A5\u6B63\u5728\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u8FDE\u63A5\u5B8C\u6210");return this.cleanupConnection(),this.reconnectState.isManualDisconnect=!1,this.attemptConnection()}async attemptConnection(){return this.connectionState="connecting",this.logger.info(`\u6B63\u5728\u8FDE\u63A5 MCP \u63A5\u5165\u70B9: ${this.endpointUrl} (\u5C1D\u8BD5 ${this.reconnectState.attempts+1}/${this.reconnectOptions.maxAttempts})`),new Promise((e,t)=>{this.connectionTimeout=setTimeout(()=>{let n=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(n),t(n)},this.reconnectOptions.timeout),this.ws=new G(this.endpointUrl),this.ws.on("open",()=>{this.handleConnectionSuccess(),e()}),this.ws.on("message",n=>{try{let r=JSON.parse(n.toString());this.handleMessage(r)}catch(r){this.logger.error("MCP \u6D88\u606F\u89E3\u6790\u9519\u8BEF:",r)}}),this.ws.on("close",(n,r)=>{this.handleConnectionClose(n,r.toString())}),this.ws.on("error",n=>{this.handleConnectionError(n),t(n)})})}handleConnectionSuccess(){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=!0,this.connectionState="connected",this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info("MCP WebSocket \u8FDE\u63A5\u5DF2\u5EFA\u7ACB")}handleConnectionError(e){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.reconnectState.lastError=e,this.logger.error("MCP WebSocket \u9519\u8BEF:",e.message),this.cleanupConnection()}handleConnectionClose(e,t){if(this.isConnected=!1,this.serverInitialized=!1,this.logger.info(`MCP \u8FDE\u63A5\u5DF2\u5173\u95ED (\u4EE3\u7801: ${e}, \u539F\u56E0: ${t})`),this.reconnectState.isManualDisconnect){this.connectionState="disconnected";return}this.shouldReconnect()?this.scheduleReconnect():(this.connectionState="failed",this.logger.warn(`\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 (${this.reconnectOptions.maxAttempts})\uFF0C\u505C\u6B62\u91CD\u8FDE`))}shouldReconnect(){return this.reconnectOptions.enabled&&this.reconnectState.attempts<this.reconnectOptions.maxAttempts&&!this.reconnectState.isManualDisconnect}scheduleReconnect(){this.connectionState="reconnecting",this.reconnectState.attempts++,this.calculateNextInterval(),this.logger.info(`\u5C06\u5728 ${this.reconnectState.nextInterval}ms \u540E\u8FDB\u884C\u7B2C ${this.reconnectState.attempts} \u6B21\u91CD\u8FDE`),this.reconnectState.timer&&clearTimeout(this.reconnectState.timer),this.reconnectState.timer=setTimeout(async()=>{try{await this.attemptConnection()}catch{}},this.reconnectState.nextInterval)}calculateNextInterval(){let e;switch(this.reconnectOptions.backoffStrategy){case"fixed":e=this.reconnectOptions.initialInterval;break;case"linear":e=this.reconnectOptions.initialInterval+this.reconnectState.attempts*this.reconnectOptions.backoffMultiplier*1e3;break;case"exponential":e=this.reconnectOptions.initialInterval*this.reconnectOptions.backoffMultiplier**(this.reconnectState.attempts-1);break;default:e=this.reconnectOptions.initialInterval}if(e=Math.min(e,this.reconnectOptions.maxInterval),this.reconnectOptions.jitter){let t=e*.1,n=(Math.random()-.5)*2*t;e+=n}this.reconnectState.nextInterval=Math.max(e,1e3)}cleanupConnection(){if(this.ws){this.ws.removeAllListeners();try{this.ws.readyState===G.OPEN?this.ws.close(1e3,"Cleaning up connection"):this.ws.readyState===G.CONNECTING&&this.ws.terminate()}catch(e){this.logger.debug("WebSocket \u5173\u95ED\u65F6\u51FA\u73B0\u9519\u8BEF\uFF08\u5DF2\u5FFD\u7565\uFF09:",e)}this.ws=null}this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=!1,this.serverInitialized=!1}stopReconnect(){this.reconnectState.timer&&(clearTimeout(this.reconnectState.timer),this.reconnectState.timer=null)}handleMessage(e){this.logger.debug("\u6536\u5230 MCP \u6D88\u606F:",JSON.stringify(e,null,2)),e.method&&this.handleServerRequest(e)}handleServerRequest(e){switch(e.method){case"initialize":case"notifications/initialized":this.sendResponse(e.id,{protocolVersion:"2024-11-05",capabilities:{tools:{listChanged:!0},logging:{}},serverInfo:{name:"xiaozhi-mcp-server",version:"1.0.0"}}),this.serverInitialized=!0,this.logger.info("MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210");break;case"tools/list":{let t=this.getTools();this.sendResponse(e.id,{tools:t}),this.logger.info(`MCP \u5DE5\u5177\u5217\u8868\u5DF2\u53D1\u9001 (${t.length}\u4E2A\u5DE5\u5177)`);break}case"tools/call":{this.handleToolCall(e).catch(t=>{this.logger.error("\u5904\u7406\u5DE5\u5177\u8C03\u7528\u65F6\u53D1\u751F\u672A\u6355\u83B7\u9519\u8BEF:",t)});break}case"ping":this.sendResponse(e.id,{}),this.logger.debug("\u56DE\u5E94 MCP ping \u6D88\u606F");break;default:this.logger.warn(`\u672A\u77E5\u7684 MCP \u8BF7\u6C42: ${e.method}`)}}sendResponse(e,t){if(this.logger.debug(`\u5C1D\u8BD5\u53D1\u9001\u54CD\u5E94: id=${e}, isConnected=${this.isConnected}, wsReadyState=${this.ws?.readyState}`),this.isConnected&&this.ws?.readyState===G.OPEN){let n={jsonrpc:"2.0",id:e,result:t};try{this.ws.send(JSON.stringify(n)),this.logger.info(`\u54CD\u5E94\u5DF2\u53D1\u9001: id=${e}`,{responseSize:JSON.stringify(n).length})}catch(r){this.logger.error(`\u53D1\u9001\u54CD\u5E94\u5931\u8D25: id=${e}`,r)}}else this.logger.error(`\u65E0\u6CD5\u53D1\u9001\u54CD\u5E94: id=${e}, \u8FDE\u63A5\u72B6\u6001\u68C0\u67E5\u5931\u8D25`,{isConnected:this.isConnected,wsReadyState:this.ws?.readyState,wsReadyStateText:this.ws?.readyState===G.OPEN?"OPEN":this.ws?.readyState===G.CONNECTING?"CONNECTING":this.ws?.readyState===G.CLOSING?"CLOSING":this.ws?.readyState===G.CLOSED?"CLOSED":"UNKNOWN"}),(!this.isConnected||this.ws?.readyState!==G.OPEN)&&(this.logger.warn(`\u5C1D\u8BD5\u91CD\u65B0\u8FDE\u63A5\u4EE5\u53D1\u9001\u54CD\u5E94: id=${e}`),this.scheduleReconnect())}getStatus(){return{connected:this.isConnected,initialized:this.serverInitialized,url:this.endpointUrl,availableTools:this.tools.size,connectionState:this.connectionState,reconnectAttempts:this.reconnectState.attempts,lastError:this.reconnectState.lastError?.message||null}}disconnect(){this.logger.info("\u4E3B\u52A8\u65AD\u5F00 MCP \u8FDE\u63A5"),this.reconnectState.isManualDisconnect=!0,this.stopReconnect(),this.cleanupConnection(),this.connectionState="disconnected"}async reconnect(){this.logger.info("\u624B\u52A8\u91CD\u8FDE MCP \u63A5\u5165\u70B9"),this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.isManualDisconnect=!1,this.cleanupConnection(),await this.connect()}enableReconnect(){this.reconnectOptions.enabled=!0,this.logger.info("\u81EA\u52A8\u91CD\u8FDE\u5DF2\u542F\u7528")}disableReconnect(){this.reconnectOptions.enabled=!1,this.stopReconnect(),this.logger.info("\u81EA\u52A8\u91CD\u8FDE\u5DF2\u7981\u7528")}updateReconnectOptions(e){this.reconnectOptions={...this.reconnectOptions,...e},this.logger.info("\u91CD\u8FDE\u914D\u7F6E\u5DF2\u66F4\u65B0",e)}getReconnectOptions(){return{...this.reconnectOptions}}resetReconnectState(){this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info("\u91CD\u8FDE\u72B6\u6001\u5DF2\u91CD\u7F6E")}async handleToolCall(e){if(e.id===void 0||e.id===null)throw new E(-32602,"\u8BF7\u6C42 ID \u4E0D\u80FD\u4E3A\u7A7A");let t=e.id,n=null;try{let r=this.validateToolCallParams(e.params);n=this.recordCallStart(r.name,t),this.logger.info(`\u5F00\u59CB\u5904\u7406\u5DE5\u5177\u8C03\u7528: ${r.name}`,{requestId:t,toolName:r.name,hasArguments:!!r.arguments});let o=this.serviceManager;if(!o)throw new E(-32001,"MCPServiceManager \u672A\u8BBE\u7F6E");let s=await this.executeToolWithRetry(o,r.name,r.arguments||{});this.sendResponse(t,{content:s.content||[{type:"text",text:JSON.stringify(s)}],isError:s.isError||!1}),n&&this.recordCallEnd(n,!0),this.logger.info(`\u5DE5\u5177\u8C03\u7528\u6210\u529F: ${r.name}`,{requestId:t,duration:n?.duration?`${n.duration}ms`:"unknown"})}catch(r){if(n){let o=r instanceof E?r.code:-32e3,s=r instanceof Error?r.message:"\u672A\u77E5\u9519\u8BEF";this.recordCallEnd(n,!1,o,s)}this.handleToolCallError(r,t,n?.duration||0)}}validateToolCallParams(e){if(!e||typeof e!="object")throw new E(-32602,"\u8BF7\u6C42\u53C2\u6570\u5FC5\u987B\u662F\u5BF9\u8C61");if(!e.name||typeof e.name!="string")throw new E(-32602,"\u5DE5\u5177\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(e.arguments!==void 0&&(typeof e.arguments!="object"||Array.isArray(e.arguments)))throw new E(-32602,"\u5DE5\u5177\u53C2\u6570\u5FC5\u987B\u662F\u5BF9\u8C61");return{name:e.name,arguments:e.arguments}}async executeToolWithRetry(e,t,n){let r=null;for(let o=1;o<=this.retryConfig.maxAttempts;o++)try{return await this.executeToolWithTimeout(e,t,n,this.toolCallConfig.timeout)}catch(s){if(s instanceof E?r=s:r=new E(-32e3,s instanceof Error?s.message:"\u672A\u77E5\u9519\u8BEF"),this.retryConfig.retryableErrors.includes(r.code)&&o<this.retryConfig.maxAttempts){let c=Math.min(this.retryConfig.initialDelay*this.retryConfig.backoffMultiplier**(o-1),this.retryConfig.maxDelay);this.logger.warn(`\u5DE5\u5177\u8C03\u7528\u5931\u8D25\uFF0C\u5C06\u5728 ${c}ms \u540E\u91CD\u8BD5 (${o}/${this.retryConfig.maxAttempts})`,{toolName:t,error:r.message,attempt:o,delay:c}),await new Promise(l=>setTimeout(l,c));continue}break}throw r}async executeToolWithTimeout(e,t,n,r=3e4){return new Promise((o,s)=>{let c=setTimeout(()=>{s(new E(-32002,`\u5DE5\u5177\u8C03\u7528\u8D85\u65F6 (${r}ms): ${t}`))},r);e.callTool(t,n).then(l=>{clearTimeout(c),o(l)}).catch(l=>{clearTimeout(c),l.message?.includes("\u672A\u627E\u5230\u5DE5\u5177")?s(new E(-32601,`\u5DE5\u5177\u4E0D\u5B58\u5728: ${t}`)):l.message?.includes("\u670D\u52A1")&&l.message?.includes("\u4E0D\u53EF\u7528")?s(new E(-32001,l.message)):l.message?.includes("\u6682\u65F6\u4E0D\u53EF\u7528")?s(new E(-32001,l.message)):l.message?.includes("\u6301\u7EED\u4E0D\u53EF\u7528")?s(new E(-32001,l.message)):s(new E(-32e3,`\u5DE5\u5177\u6267\u884C\u5931\u8D25: ${l.message}`))})})}handleToolCallError(e,t,n){let r;e instanceof E?r={code:e.code,message:e.message,data:e.data}:r={code:-32e3,message:e?.message||"\u672A\u77E5\u9519\u8BEF",data:{originalError:e?.toString()||"null"}},this.sendErrorResponse(t,r),this.logger.error("\u5DE5\u5177\u8C03\u7528\u5931\u8D25",{requestId:t,duration:`${n}ms`,error:r})}sendErrorResponse(e,t){if(this.isConnected&&this.ws?.readyState===G.OPEN){let n={jsonrpc:"2.0",id:e,error:t};this.ws.send(JSON.stringify(n)),this.logger.debug("\u5DF2\u53D1\u9001\u9519\u8BEF\u54CD\u5E94:",n)}}recordCallStart(e,t){let n={id:String(t),toolName:e,startTime:new Date,success:!1};return this.callRecords.push(n),this.callRecords.length>this.maxCallRecords&&this.callRecords.shift(),n}recordCallEnd(e,t,n,r){e.endTime=new Date,e.duration=e.endTime.getTime()-e.startTime.getTime(),e.success=t,e.errorCode=n,e.errorMessage=r,this.updatePerformanceMetrics(e)}updatePerformanceMetrics(e){if(this.performanceMetrics.totalCalls++,e.success?this.performanceMetrics.successfulCalls++:this.performanceMetrics.failedCalls++,e.duration!==void 0){e.duration<this.performanceMetrics.minResponseTime&&(this.performanceMetrics.minResponseTime=e.duration),e.duration>this.performanceMetrics.maxResponseTime&&(this.performanceMetrics.maxResponseTime=e.duration);let t=this.callRecords.filter(r=>r.duration!==void 0).reduce((r,o)=>r+(o.duration||0),0),n=this.callRecords.filter(r=>r.duration!==void 0).length;this.performanceMetrics.averageResponseTime=n>0?t/n:0}this.performanceMetrics.successRate=this.performanceMetrics.totalCalls>0?this.performanceMetrics.successfulCalls/this.performanceMetrics.totalCalls*100:0,this.performanceMetrics.lastUpdated=new Date}getPerformanceMetrics(){return{...this.performanceMetrics}}getCallRecords(e){let t=[...this.callRecords].reverse();return e?t.slice(0,e):t}resetPerformanceMetrics(){this.performanceMetrics={totalCalls:0,successfulCalls:0,failedCalls:0,averageResponseTime:0,minResponseTime:Number.MAX_VALUE,maxResponseTime:0,successRate:0,lastUpdated:new Date},this.callRecords=[]}updateToolCallConfig(e){this.toolCallConfig={...this.toolCallConfig,...e},this.logger.info("\u5DE5\u5177\u8C03\u7528\u914D\u7F6E\u5DF2\u66F4\u65B0",this.toolCallConfig)}updateRetryConfig(e){this.retryConfig={...this.retryConfig,...e},this.logger.info("\u91CD\u8BD5\u914D\u7F6E\u5DF2\u66F4\u65B0",this.retryConfig)}getConfiguration(){return{toolCall:{...this.toolCallConfig},retry:{...this.retryConfig}}}getEnhancedStatus(){return{connected:this.isConnected,initialized:this.serverInitialized,url:this.endpointUrl,availableTools:this.tools.size,connectionState:this.connectionState,reconnectAttempts:this.reconnectState.attempts,lastError:this.reconnectState.lastError?.message||null,performance:this.getPerformanceMetrics(),configuration:this.getConfiguration()}}}});var he,Pe=h(()=>{"use strict";R();he=class{static{a(this,"TransportAdapter")}logger;messageHandler;connectionId;config;state="disconnected";constructor(e,t){this.messageHandler=e,this.config=t,this.connectionId=this.generateConnectionId(),this.logger=f}async handleIncomingMessage(e){try{this.logger.debug(`\u5904\u7406\u63A5\u6536\u5230\u7684\u6D88\u606F: ${e.method}`,e);let t=await this.messageHandler.handleMessage(e);this.logger.debug("\u53D1\u9001\u54CD\u5E94\u6D88\u606F:",t),await this.sendMessage(t)}catch(t){this.logger.error(`\u5904\u7406\u6D88\u606F\u65F6\u51FA\u9519: ${e.method}`,t);let n=this.createErrorResponse(t,e.id);await this.sendMessage(n)}}createErrorResponse(e,t){let n=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?n=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(n=-32602),{jsonrpc:"2.0",error:{code:n,message:e.message,data:{stack:e.stack}},id:t||null}}generateConnectionId(){let e=Date.now(),t=Math.random().toString(36).substr(2,9);return`${this.config.name}_${e}_${t}`}getConnectionId(){return this.connectionId}getState(){return this.state}setState(e){let t=this.state;this.state=e,t!==e&&(this.logger.info(`\u8FDE\u63A5\u72B6\u6001\u53D8\u66F4: ${t} -> ${e}`),this.onStateChange(t,e))}onStateChange(e,t){}getConfig(){return{...this.config}}getMessageHandler(){return this.messageHandler}parseMessage(e){try{let t=JSON.parse(e.trim());return!t.jsonrpc||t.jsonrpc!=="2.0"?(this.logger.warn("\u6536\u5230\u975E JSON-RPC 2.0 \u683C\u5F0F\u7684\u6D88\u606F",t),null):t.method?t:(this.logger.warn("\u6536\u5230\u6CA1\u6709 method \u5B57\u6BB5\u7684\u6D88\u606F",t),null)}catch(t){return this.logger.error("\u89E3\u6790 JSON \u6D88\u606F\u5931\u8D25",{data:e,error:t}),null}}serializeMessage(e){try{return JSON.stringify(e)}catch(t){this.logger.error("\u5E8F\u5217\u5316\u6D88\u606F\u5931\u8D25",{message:e,error:t});let n=t instanceof Error?t.message:String(t);throw new Error(`\u6D88\u606F\u5E8F\u5217\u5316\u5931\u8D25: ${n}`)}}validateMessage(e){return!(!e||typeof e!="object"||e.jsonrpc!=="2.0"||e.method&&typeof e.method!="string"||!e.method&&!e.result&&!e.error)}createTimeoutPromise(e,t){return Promise.race([e,new Promise((n,r)=>{setTimeout(()=>{r(new Error(`\u64CD\u4F5C\u8D85\u65F6: ${t}ms`))},t)})])}}});import{randomUUID as Qn}from"crypto";import ct from"express";var He,Jt=h(()=>{"use strict";Pe();He=class extends he{static{a(this,"HTTPAdapter")}app;server=null;clients=new Map;port;host;enableSSE;enableRPC;corsOrigin;maxClients;constructor(e,t={name:"http"}){super(e,t),this.port=t.port||3e3,this.host=t.host||"0.0.0.0",this.enableSSE=t.enableSSE!==!1,this.enableRPC=t.enableRPC!==!1,this.corsOrigin=t.corsOrigin||"*",this.maxClients=t.maxClients!==void 0?t.maxClients:100,this.app=ct(),this.setupMiddleware()}async initialize(){this.logger.info("\u521D\u59CB\u5316 HTTP \u9002\u914D\u5668");try{this.setupRoutes(),this.setState("connecting"),this.logger.info("HTTP \u9002\u914D\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("HTTP \u9002\u914D\u5668\u521D\u59CB\u5316\u5931\u8D25",e),this.setState("error"),e}}async start(){if(this.server){this.logger.warn("HTTP \u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C");return}return this.logger.info(`\u542F\u52A8 HTTP \u670D\u52A1\u5668\u5728 ${this.host}:${this.port}`),new Promise((e,t)=>{this.server=this.app.listen(this.port,this.host,()=>{this.setState("connected"),this.logger.info("HTTP \u9002\u914D\u5668\u542F\u52A8\u6210\u529F"),this.logger.info(`- RPC \u7AEF\u70B9: http://${this.host}:${this.port}/rpc`),this.enableSSE&&(this.logger.info(`- SSE \u7AEF\u70B9: http://${this.host}:${this.port}/sse`),this.logger.info(`- \u6D88\u606F\u7AEF\u70B9: http://${this.host}:${this.port}/messages`)),e()}),this.server?.on("error",n=>{this.logger.error("HTTP \u670D\u52A1\u5668\u9519\u8BEF",n),this.setState("error"),t(n)})})}async stop(){if(this.server)return this.logger.info("\u505C\u6B62 HTTP \u670D\u52A1\u5668"),new Promise(e=>{for(let t of this.clients.values())t.response.end();this.clients.clear(),this.server.close(()=>{this.server=null,this.setState("disconnected"),this.logger.info("HTTP \u670D\u52A1\u5668\u5DF2\u505C\u6B62"),e()})})}async sendMessage(e){this.clients.size>0&&this.broadcastToClients(e)}setupMiddleware(){this.app.use(ct.json({limit:"10mb"})),this.app.use(ct.urlencoded({extended:!0})),this.app.use((e,t,n)=>{t.header("Access-Control-Allow-Origin",this.corsOrigin),t.header("Access-Control-Allow-Methods","GET, POST, OPTIONS"),t.header("Access-Control-Allow-Headers","Content-Type, Accept"),t.header("Cache-Control","no-cache"),n()}),this.app.use((e,t,n)=>{this.logger.debug(`${e.method} ${e.path}`,{query:e.query,headers:e.headers}),n()})}setupRoutes(){this.enableSSE&&(this.app.get("/sse",this.handleSSE.bind(this)),this.app.post("/messages",this.handleMessages.bind(this))),this.enableRPC&&this.app.post("/rpc",this.handleRPC.bind(this)),this.app.get("/status",this.handleStatus.bind(this)),this.app.get("/health",this.handleHealth.bind(this))}handleSSE(e,t){if(this.clients.size>=this.maxClients){t.status(503).json({error:"\u670D\u52A1\u5668\u7E41\u5FD9\uFF0C\u5BA2\u6237\u7AEF\u8FDE\u63A5\u6570\u5DF2\u8FBE\u4E0A\u9650",maxClients:this.maxClients});return}let n=Date.now().toString(),r=Qn();t.setHeader("Content-Type","text/event-stream"),t.setHeader("Cache-Control","no-cache, no-transform"),t.setHeader("Connection","keep-alive"),t.setHeader("X-Accel-Buffering","no");let o={id:n,sessionId:r,response:t,connectedAt:new Date};this.clients.set(r,o),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u8FDE\u63A5: ${n} (\u4F1A\u8BDD: ${r})`),t.write(`event: endpoint
4
11
  data: /messages?sessionId=${r}
5
12
 
6
- `),e.on("close",()=>{this.clients.delete(r),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u65AD\u5F00\u8FDE\u63A5: ${n} (\u4F1A\u8BDD: ${r})`)}),e.on("error",s=>{this.logger.error(`SSE \u5BA2\u6237\u7AEF\u8FDE\u63A5\u9519\u8BEF: ${n}`,s),this.clients.delete(r)})}async handleMessages(e,t){try{let n=e.query.sessionId,r=e.body;if(this.logger.debug(`\u6536\u5230 SSE \u6D88\u606F (\u4F1A\u8BDD: ${n}):`,r),!n||!this.clients.has(n)){t.status(400).json({jsonrpc:"2.0",error:{code:-32600,message:"\u65E0\u6548\u6216\u7F3A\u5C11 sessionId"},id:r.id});return}let i=await this.messageHandler.handleMessage(r);this.logger.debug("SSE \u6D88\u606F\u5904\u7406\u54CD\u5E94:",i);let s=this.clients.get(n);s&&this.sendToClient(s,i),t.status(202).send()}catch(n){this.logger.error("\u5904\u7406 SSE \u6D88\u606F\u65F6\u51FA\u9519",n),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:n.message}})}}async handleRPC(e,t){try{let n=e.body;this.logger.debug("\u6536\u5230 RPC \u6D88\u606F:",n);let r=await this.messageHandler.handleMessage(n);t.json(r)}catch(n){this.logger.error("\u5904\u7406 RPC \u6D88\u606F\u65F6\u51FA\u9519",n),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:n.message},id:e.body?.id||null})}}handleStatus(e,t){t.json({status:"ok",mode:"mcp-server",serviceManager:"running",clients:this.clients.size,tools:0,maxClients:this.maxClients,enableSSE:this.enableSSE,enableRPC:this.enableRPC,uptime:process.uptime()})}handleHealth(e,t){t.json({status:"ok",mode:"mcp-server",timestamp:new Date().toISOString()})}sendToClient(e,t){try{let n=this.serializeMessage(t);e.response.write(`data: ${n}
13
+ `),e.on("close",()=>{this.clients.delete(r),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u65AD\u5F00\u8FDE\u63A5: ${n} (\u4F1A\u8BDD: ${r})`)}),e.on("error",s=>{this.logger.error(`SSE \u5BA2\u6237\u7AEF\u8FDE\u63A5\u9519\u8BEF: ${n}`,s),this.clients.delete(r)})}async handleMessages(e,t){try{let n=e.query.sessionId,r=e.body;if(this.logger.debug(`\u6536\u5230 SSE \u6D88\u606F (\u4F1A\u8BDD: ${n}):`,r),!n||!this.clients.has(n)){t.status(400).json({jsonrpc:"2.0",error:{code:-32600,message:"\u65E0\u6548\u6216\u7F3A\u5C11 sessionId"},id:r.id});return}let o=await this.messageHandler.handleMessage(r);this.logger.debug("SSE \u6D88\u606F\u5904\u7406\u54CD\u5E94:",o);let s=this.clients.get(n);s&&this.sendToClient(s,o),t.status(202).send()}catch(n){this.logger.error("\u5904\u7406 SSE \u6D88\u606F\u65F6\u51FA\u9519",n),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:n.message}})}}async handleRPC(e,t){try{let n=e.body;this.logger.debug("\u6536\u5230 RPC \u6D88\u606F:",n);let r=await this.messageHandler.handleMessage(n);t.json(r)}catch(n){this.logger.error("\u5904\u7406 RPC \u6D88\u606F\u65F6\u51FA\u9519",n),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:n.message},id:e.body?.id||null})}}handleStatus(e,t){t.json({status:"ok",mode:"mcp-server",serviceManager:"running",clients:this.clients.size,tools:0,maxClients:this.maxClients,enableSSE:this.enableSSE,enableRPC:this.enableRPC,uptime:process.uptime()})}handleHealth(e,t){t.json({status:"ok",mode:"mcp-server",timestamp:new Date().toISOString()})}sendToClient(e,t){try{let n=this.serializeMessage(t);e.response.write(`data: ${n}
7
14
 
8
- `),this.logger.debug(`\u6D88\u606F\u5DF2\u53D1\u9001\u5230\u5BA2\u6237\u7AEF ${e.id}`,{sessionId:e.sessionId,messageId:t.id})}catch(n){this.logger.error(`\u5411\u5BA2\u6237\u7AEF ${e.id} \u53D1\u9001\u6D88\u606F\u5931\u8D25`,n),this.clients.delete(e.sessionId)}}broadcastToClients(e){for(let t of this.clients.values())this.sendToClient(t,e)}getStatus(){return{isRunning:this.server!==null,port:this.port,host:this.host,clientCount:this.clients.size,maxClients:this.maxClients,enableSSE:this.enableSSE,enableRPC:this.enableRPC,connectionId:this.connectionId,state:this.state}}getClients(){return Array.from(this.clients.values()).map(e=>({id:e.id,sessionId:e.sessionId,connectedAt:e.connectedAt}))}}});var Ye=v(()=>{"use strict";Y()});import br,{WebSocketServer as Pr}from"ws";var et=v(()=>{"use strict";Y()});var ce,tt=v(()=>{"use strict";M();ce=class{static{a(this,"MCPMessageHandler")}logger;serviceManager;constructor(e){this.serviceManager=e,this.logger=d}async handleMessage(e){this.logger.debug(`\u5904\u7406 MCP \u6D88\u606F: ${e.method}`,e);try{switch(e.method){case"initialize":return await this.handleInitialize(e.params,e.id);case"tools/list":return await this.handleToolsList(e.id);case"tools/call":return await this.handleToolCall(e.params,e.id);case"ping":return await this.handlePing(e.id);default:throw new Error(`\u672A\u77E5\u7684\u65B9\u6CD5: ${e.method}`)}}catch(t){return this.logger.error(`\u5904\u7406\u6D88\u606F\u65F6\u51FA\u9519: ${e.method}`,t),this.createErrorResponse(t,e.id)}}async handleInitialize(e,t){return this.logger.info("\u5904\u7406 initialize \u8BF7\u6C42",e),{jsonrpc:"2.0",result:{serverInfo:{name:"xiaozhi-mcp-server",version:"1.0.0"},capabilities:{tools:{},logging:{}},protocolVersion:"2024-11-05"},id:t||null}}async handleToolsList(e){this.logger.info("\u5904\u7406 tools/list \u8BF7\u6C42");try{let n=this.serviceManager.getAllTools().map(r=>({name:r.name,description:r.description,inputSchema:r.inputSchema}));return this.logger.info(`\u8FD4\u56DE ${n.length} \u4E2A\u5DE5\u5177`),{jsonrpc:"2.0",result:{tools:n},id:e||null}}catch(t){throw this.logger.error("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25",t),t}}async handleToolCall(e,t){this.logger.info(`\u5904\u7406 tools/call \u8BF7\u6C42: ${e.name}`,e);try{if(!e.name)throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");let n=await this.serviceManager.callTool(e.name,e.arguments||{});return this.logger.info(`\u5DE5\u5177 ${e.name} \u8C03\u7528\u6210\u529F`),{jsonrpc:"2.0",result:{content:n.content,isError:n.isError||!1},id:t||null}}catch(n){throw this.logger.error(`\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,n),n}}async handlePing(e){return this.logger.debug("\u5904\u7406 ping \u8BF7\u6C42"),{jsonrpc:"2.0",result:{status:"ok",timestamp:new Date().toISOString()},id:e||null}}createErrorResponse(e,t){let n=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?n=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(n=-32602),{jsonrpc:"2.0",error:{code:n,message:e.message,data:{stack:e.stack}},id:t||null}}getServiceManager(){return this.serviceManager}}});import{EventEmitter as nt}from"events";var Ee,Ie,le,ot=v(()=>{"use strict";M();ve();Y();tt();Ee=class{static{a(this,"ToolRegistry")}serviceManager;logger;constructor(e){this.serviceManager=e,this.logger=d}async initialize(){this.logger.info("\u521D\u59CB\u5316\u5DE5\u5177\u6CE8\u518C\u8868")}getAllTools(){return this.serviceManager.getAllTools().map(e=>({name:e.name,description:e.description,inputSchema:e.inputSchema,serviceName:e.serviceName,originalName:e.originalName}))}findTool(e){return this.getAllTools().find(n=>n.name===e)||null}hasTool(e){return this.findTool(e)!==null}},Ie=class extends nt{static{a(this,"ConnectionManager")}connections=new Map;logger;constructor(){super(),this.logger=d}async initialize(){this.logger.info("\u521D\u59CB\u5316\u8FDE\u63A5\u7BA1\u7406\u5668")}registerConnection(e,t,n){let r={id:e,transportName:t,state:n,connectedAt:new Date,lastActivity:new Date};this.connections.set(e,r),this.emit("connectionRegistered",r),this.logger.debug(`\u8FDE\u63A5\u5DF2\u6CE8\u518C: ${e} (${t})`)}updateConnectionState(e,t){let n=this.connections.get(e);n&&(n.state=t,n.lastActivity=new Date,this.emit("connectionStateChanged",n),this.logger.debug(`\u8FDE\u63A5\u72B6\u6001\u66F4\u65B0: ${e} -> ${t}`))}removeConnection(e){let t=this.connections.get(e);t&&(this.connections.delete(e),this.emit("connectionRemoved",t),this.logger.debug(`\u8FDE\u63A5\u5DF2\u79FB\u9664: ${e}`))}getAllConnections(){return Array.from(this.connections.values())}getActiveConnectionCount(){return Array.from(this.connections.values()).filter(e=>e.state==="connected").length}async closeAllConnections(){this.logger.info("\u5173\u95ED\u6240\u6709\u8FDE\u63A5"),this.connections.clear(),this.emit("allConnectionsClosed")}},le=class extends nt{static{a(this,"UnifiedMCPServer")}serviceManager;messageHandler;transportAdapters=new Map;toolRegistry;connectionManager;isRunning=!1;logger;config;constructor(e={}){super(),this.config={name:"UnifiedMCPServer",enableLogging:!0,logLevel:"info",maxConnections:100,connectionTimeout:3e4,...e},this.logger=d,this.serviceManager=new q,this.messageHandler=new ce(this.serviceManager),this.toolRegistry=new Ee(this.serviceManager),this.connectionManager=new Ie,this.setupEventListeners()}setupEventListeners(){this.connectionManager.on("connectionRegistered",e=>{this.emit("connectionRegistered",e)}),this.connectionManager.on("connectionStateChanged",e=>{this.emit("connectionStateChanged",e)}),this.connectionManager.on("connectionRemoved",e=>{this.emit("connectionRemoved",e)})}async initialize(){this.logger.info("\u521D\u59CB\u5316\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{await this.serviceManager.startAllServices(),await this.toolRegistry.initialize(),await this.connectionManager.initialize(),this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210"),this.emit("initialized")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5931\u8D25",e),e}}async registerTransport(e,t){if(this.transportAdapters.has(e))throw new Error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5DF2\u5B58\u5728`);this.logger.info(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668: ${e}`);try{await t.initialize(),this.transportAdapters.set(e,t),this.connectionManager.registerConnection(t.getConnectionId(),e,t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u6CE8\u518C\u6210\u529F`),this.emit("transportRegistered",{name:e,adapter:t})}catch(n){throw this.logger.error(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5931\u8D25`,n),n}}async start(){if(this.isRunning)throw new Error("\u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C");this.logger.info("\u542F\u52A8\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{for(let[e,t]of this.transportAdapters)try{await t.start(),this.connectionManager.updateConnectionState(t.getConnectionId(),t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u542F\u52A8\u6210\u529F`)}catch(n){throw this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u542F\u52A8\u5931\u8D25`,n),n}this.isRunning=!0,this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u542F\u52A8\u6210\u529F"),this.emit("started")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25",e),e}}async stop(){if(this.isRunning){this.logger.info("\u505C\u6B62\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{for(let[e,t]of this.transportAdapters)try{await t.stop(),this.connectionManager.updateConnectionState(t.getConnectionId(),t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u6210\u529F`)}catch(n){this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u5931\u8D25`,n)}await this.connectionManager.closeAllConnections(),await this.serviceManager.stopAllServices(),this.isRunning=!1,this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u505C\u6B62\u6210\u529F"),this.emit("stopped")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u505C\u6B62\u5931\u8D25",e),e}}}getServiceManager(){return this.serviceManager}getToolRegistry(){return this.toolRegistry}getConnectionManager(){return this.connectionManager}getMessageHandler(){return this.messageHandler}getStatus(){return{isRunning:this.isRunning,transportCount:this.transportAdapters.size,activeConnections:this.connectionManager.getActiveConnectionCount(),toolCount:this.toolRegistry.getAllTools().length,config:this.config}}getTransportAdapters(){return new Map(this.transportAdapters)}isServerRunning(){return this.isRunning}}});async function rt(o={name:"http"}){d.info("\u521B\u5EFA HTTP \u6A21\u5F0F\u670D\u52A1\u5668");let e=new le;await e.initialize();let t=e.getMessageHandler(),n=new ae(t,o);return await e.registerTransport("http",n),d.info("HTTP \u6A21\u5F0F\u670D\u52A1\u5668\u521B\u5EFA\u6210\u529F"),e}var it=v(()=>{"use strict";M();Qe();Ye();et();ot();a(rt,"createHTTPServer")});var st={};ft(st,{MCPServer:()=>Re});import{EventEmitter as mn}from"events";var C,Re,at=v(()=>{"use strict";M();ne();z();it();C=new G,Re=class extends mn{static{a(this,"MCPServer")}unifiedServer=null;proxyMCPServer=null;port;isStarted=!1;constructor(e=3e3){super(),this.port=e}async initializeUnifiedServer(){if(!this.unifiedServer){C.info("\u521D\u59CB\u5316\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{let e={name:"http",port:this.port,host:"0.0.0.0",enableSSE:!0,enableRPC:!0};this.unifiedServer=await rt(e),this.unifiedServer.on("started",()=>this.emit("started")),this.unifiedServer.on("stopped",()=>this.emit("stopped")),this.unifiedServer.on("connectionRegistered",t=>{this.emit("connectionRegistered",t)}),C.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw C.error("\u521D\u59CB\u5316\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u5931\u8D25",e),e}}}async initializeMCPClient(){try{let e=null;try{g.configExists()&&(e=g.getMcpEndpoints().find(n=>n&&!n.includes("<\u8BF7\u586B\u5199"))||null)}catch(t){C.warn("\u4ECE\u914D\u7F6E\u4E2D\u8BFB\u53D6\u5C0F\u667A\u63A5\u5165\u70B9\u5931\u8D25:",t)}e?(this.proxyMCPServer=new D(e),this.unifiedServer&&this.proxyMCPServer.setServiceManager(this.unifiedServer.getServiceManager()),await this.proxyMCPServer.connect(),C.info("\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u6210\u529F")):C.info("\u672A\u914D\u7F6E\u6709\u6548\u7684\u5C0F\u667A\u63A5\u5165\u70B9\uFF0C\u8DF3\u8FC7\u8FDE\u63A5")}catch(e){C.error("\u521D\u59CB\u5316\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u5931\u8D25:",e)}}async start(){if(this.isStarted){C.warn("\u670D\u52A1\u5668\u5DF2\u542F\u52A8");return}try{C.info("\u542F\u52A8 MCP \u670D\u52A1\u5668"),await this.initializeUnifiedServer(),this.unifiedServer&&await this.unifiedServer.start(),this.initializeMCPClient().catch(e=>{C.error("\u521D\u59CB\u5316\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u5931\u8D25:",e)}),this.isStarted=!0,this.emit("started"),C.info("MCP \u670D\u52A1\u5668\u542F\u52A8\u6210\u529F")}catch(e){throw C.error("\u542F\u52A8 MCP \u670D\u52A1\u5668\u5931\u8D25:",e),e}}async stop(){if(!this.isStarted){C.warn("\u670D\u52A1\u5668\u672A\u542F\u52A8");return}try{C.info("\u505C\u6B62 MCP \u670D\u52A1\u5668"),this.unifiedServer&&await this.unifiedServer.stop(),this.proxyMCPServer&&(this.proxyMCPServer.disconnect(),this.proxyMCPServer=null),this.isStarted=!1,this.emit("stopped"),C.info("MCP \u670D\u52A1\u5668\u5DF2\u505C\u6B62")}catch(e){throw C.error("\u505C\u6B62 MCP \u670D\u52A1\u5668\u5931\u8D25:",e),e}}getServiceManager(){return this.unifiedServer?.getServiceManager()||null}getMessageHandler(){return this.unifiedServer?.getMessageHandler()||null}getStatus(){return this.unifiedServer?{...this.unifiedServer.getStatus(),port:this.port,mode:"mcp-server",proxyConnected:this.proxyMCPServer!==null}:{isRunning:!1,port:this.port,mode:"mcp-server"}}isRunning(){return this.isStarted&&(this.unifiedServer?.isServerRunning()||!1)}}});M();import{spawn as Sn}from"child_process";import m from"fs";import u from"path";import{fileURLToPath as B}from"url";import c from"chalk";import{Command as Cn}from"commander";import E from"ora";M();ne();import{spawn as Be}from"child_process";import{existsSync as be}from"fs";import{readFile as Xe}from"fs/promises";import{createServer as cn}from"http";import{dirname as ln,join as U}from"path";import{fileURLToPath as gn}from"url";import{serve as hn}from"@hono/node-server";import{Hono as pn}from"hono";import{cors as fn}from"hono/cors";import{WebSocketServer as dn}from"ws";M();oe();var fe=d.withTag("ConfigAdapter"),b=class extends Error{constructor(t,n){super(t);this.configName=n;this.name="ConfigValidationError"}static{a(this,"ConfigValidationError")}};function ke(o,e){fe.debug(`\u8F6C\u6362\u914D\u7F6E: ${o}`,e);try{if(!o||typeof o!="string")throw new b("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!e||typeof e!="object")throw new b("\u914D\u7F6E\u5BF9\u8C61\u4E0D\u80FD\u4E3A\u7A7A",o);let t=$t(o,e);return Ht(t),fe.info(`\u914D\u7F6E\u8F6C\u6362\u6210\u529F: ${o} -> ${t.type}`),t}catch(t){throw fe.error(`\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${o}`,t),t instanceof b?t:new b(`\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`,o)}}a(ke,"convertLegacyToNew");function $t(o,e){if(Dt(e))return Ot(o,e);if(kt(e))return At(o,e);if(zt(e))return Nt(o,e);throw new b("\u65E0\u6CD5\u8BC6\u522B\u7684\u914D\u7F6E\u7C7B\u578B",o)}a($t,"convertByConfigType");function Ot(o,e){if(!e.command)throw new b("\u672C\u5730\u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5",o);return{name:o,type:"stdio",command:e.command,args:e.args||[],reconnect:{enabled:!0,maxAttempts:5,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0},ping:{enabled:!0,interval:3e4,timeout:5e3,maxFailures:3,startDelay:5e3},timeout:3e4}}a(Ot,"convertLocalConfig");function At(o,e){if(!e.url)throw new b("SSE \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5",o);let t=jt(e.url),n={name:o,type:t?"modelscope-sse":"sse",url:e.url,reconnect:{enabled:!0,maxAttempts:10,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:15e3,jitter:!0},ping:{enabled:!0,interval:3e4,timeout:5e3,maxFailures:3,startDelay:5e3},timeout:3e4};return t&&(n.modelScopeAuth=!0),n}a(At,"convertSSEConfig");function Nt(o,e){if(!e.url)throw new b("Streamable HTTP \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5",o);return{name:o,type:"streamable-http",url:e.url,reconnect:{enabled:!0,maxAttempts:5,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:15e3,jitter:!0},ping:{enabled:!1,interval:6e4,timeout:1e4,maxFailures:3,startDelay:1e4},timeout:3e4}}a(Nt,"convertStreamableHTTPConfig");function Dt(o){return"command"in o&&typeof o.command=="string"}a(Dt,"isLocalConfig");function kt(o){return"type"in o&&o.type==="sse"&&"url"in o}a(kt,"isSSEConfig");function zt(o){return"url"in o&&(!("type"in o)||o.type==="streamable-http")}a(zt,"isStreamableHTTPConfig");function jt(o){return o.includes("modelscope.net")||o.includes("modelscope.cn")}a(jt,"isModelScopeURL");function Ht(o){if(!o.name||typeof o.name!="string")throw new b("\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 name \u5B57\u6BB5");if(!Object.values(J).includes(o.type))throw new b(`\u65E0\u6548\u7684\u4F20\u8F93\u7C7B\u578B: ${o.type}`);switch(o.type){case"stdio":if(!o.command)throw new b("STDIO \u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5");break;case"sse":case"modelscope-sse":case"streamable-http":if(!o.url)throw new b(`${o.type} \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5`);break;default:throw new b(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${o.type}`)}}a(Ht,"validateNewConfig");z();ve();var O=null,$=null,P="not_initialized",Z=null,j=null;async function Jt(){return console.log("\u{1F680} \u6B63\u5728\u521D\u59CB\u5316 MCPServiceManager \u5355\u4F8B..."),new He}a(Jt,"createInstance");async function Fe(){if(O&&P==="initialized")return O;if($&&P==="initializing")return $;P==="failed"&&ye(),P="initializing",$=Jt();try{return O=await $,P="initialized",j=`mcp-manager-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,Z=null,console.log(`\u2705 MCPServiceManager \u5355\u4F8B\u521D\u59CB\u5316\u6210\u529F\uFF0C\u5B9E\u4F8BID: ${j}`),O}catch(o){throw P="failed",Z=o,$=null,console.error("\u274C MCPServiceManager \u5355\u4F8B\u521D\u59CB\u5316\u5931\u8D25:",o.message),o}}a(Fe,"getInstance");async function Le(){if(P==="cleanup"){console.log("\u26A0\uFE0F MCPServiceManager \u5355\u4F8B\u5DF2\u5728\u6E05\u7406\u4E2D\uFF0C\u8DF3\u8FC7\u91CD\u590D\u6E05\u7406");return}console.log("\u{1F9F9} \u6B63\u5728\u6E05\u7406 MCPServiceManager \u5355\u4F8B\u8D44\u6E90..."),P="cleanup";try{if($){try{await(await $).stopAllServices()}catch(o){console.error("\u6E05\u7406\u521D\u59CB\u5316\u4E2D\u7684\u5B9E\u4F8B\u5931\u8D25:",o.message)}$=null}O&&(await O.stopAllServices(),O=null),P="not_initialized",Z=null,j=null,console.log("\u2705 MCPServiceManager \u5355\u4F8B\u8D44\u6E90\u6E05\u7406\u5B8C\u6210")}catch(o){throw console.error("\u274C MCPServiceManager \u5355\u4F8B\u6E05\u7406\u5931\u8D25:",o.message),ye(),o}}a(Le,"cleanup");function ye(){console.log("\u{1F504} \u91CD\u7F6E MCPServiceManager \u5355\u4F8B\u72B6\u6001"),O=null,$=null,P="not_initialized",Z=null,j=null}a(ye,"reset");function Kt(){return P==="initialized"&&O!==null}a(Kt,"isInitialized");function qt(){return{state:P,initializationTime:j?new Date:void 0,lastError:Z||void 0,instanceId:j||void 0}}a(qt,"getStatus");async function Zt(){return console.log("\u{1F504} \u5F3A\u5236\u91CD\u65B0\u521D\u59CB\u5316 MCPServiceManager \u5355\u4F8B..."),await Le(),Fe()}a(Zt,"forceReinitialize");function Vt(){return O}a(Vt,"getCurrentInstance");async function Qt(){if(P==="initialized")return!0;if(P==="initializing"&&$)try{return await $,!0}catch{return!1}return!1}a(Qt,"waitForInitialization");var H={getInstance:Fe,cleanup:Le,reset:ye,isInitialized:Kt,getStatus:qt,forceReinitialize:Zt,getCurrentInstance:Vt,waitForInitialization:Qt};process.on("exit",()=>{H.isInitialized()&&(console.log("\u{1F504} \u8FDB\u7A0B\u9000\u51FA\uFF0C\u6B63\u5728\u6E05\u7406 MCPServiceManager \u5355\u4F8B..."),H.reset())});process.on("uncaughtException",async o=>{console.error("\u{1F4A5} \u672A\u6355\u83B7\u7684\u5F02\u5E38\uFF0C\u6E05\u7406 MCPServiceManager \u5355\u4F8B:",o);try{await H.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}});process.on("unhandledRejection",async o=>{console.error("\u{1F4A5} \u672A\u5904\u7406\u7684Promise\u62D2\u7EDD\uFF0C\u6E05\u7406 MCPServiceManager \u5355\u4F8B:",o);try{await H.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}});M();ne();import{EventEmitter as Yt}from"events";var Ue=(r=>(r.EXPONENTIAL_BACKOFF="exponential_backoff",r.LINEAR_BACKOFF="linear_backoff",r.FIXED_INTERVAL="fixed_interval",r.ADAPTIVE="adaptive",r))(Ue||{});var en={healthCheckInterval:3e4,reconnectInterval:5e3,maxReconnectAttempts:10,loadBalanceStrategy:"round-robin",connectionTimeout:1e4,reconnectStrategy:"exponential_backoff",maxReconnectDelay:3e4,reconnectBackoffMultiplier:2,jitterEnabled:!0},se=class extends Yt{static{a(this,"XiaozhiConnectionManager")}connections=new Map;connectionStates=new Map;mcpServiceManager=null;logger;isInitialized=!1;isConnecting=!1;options;healthCheckInterval=null;reconnectTimers=new Map;roundRobinIndex=0;lastSelectedEndpoint=null;performanceMetrics={connectionStartTime:0,totalConnectionTime:0,averageConnectionTime:0,connectionCount:0,memoryUsage:{initial:0,current:0,peak:0},prewarmedConnections:new Set};constructor(e){super(),this.logger=d,this.options={...en,...e},this.logger.info("[XiaozhiConnectionManager] \u5B9E\u4F8B\u5DF2\u521B\u5EFA"),this.logger.debug("[XiaozhiConnectionManager] \u914D\u7F6E\u9009\u9879:",this.options)}async initialize(e,t){if(this.isInitialized){this.logger.warn("XiaozhiConnectionManager \u5DF2\u7ECF\u521D\u59CB\u5316\uFF0C\u8DF3\u8FC7\u91CD\u590D\u521D\u59CB\u5316");return}this.logger.info(`\u5F00\u59CB\u521D\u59CB\u5316 XiaozhiConnectionManager\uFF0C\u7AEF\u70B9\u6570\u91CF: ${e.length}`);try{this.validateInitializeParams(e,t),await this.cleanup();for(let n of e)await this.createConnection(n,t);this.isInitialized=!0,this.performanceMetrics.memoryUsage.initial=process.memoryUsage().heapUsed,this.performanceMetrics.memoryUsage.current=this.performanceMetrics.memoryUsage.initial,this.performanceMetrics.memoryUsage.peak=this.performanceMetrics.memoryUsage.initial,this.logger.info(`XiaozhiConnectionManager \u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u7BA1\u7406 ${this.connections.size} \u4E2A\u8FDE\u63A5`)}catch(n){throw this.logger.error("XiaozhiConnectionManager \u521D\u59CB\u5316\u5931\u8D25:",n),await this.cleanup(),n}}async connect(){if(!this.isInitialized)throw new Error("XiaozhiConnectionManager \u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u8C03\u7528 initialize()");if(this.isConnecting){this.logger.warn("\u8FDE\u63A5\u64CD\u4F5C\u6B63\u5728\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210");return}this.isConnecting=!0,this.performanceMetrics.connectionStartTime=Date.now(),this.logger.info(`\u5F00\u59CB\u8FDE\u63A5\u6240\u6709\u7AEF\u70B9\uFF0C\u603B\u6570: ${this.connections.size}`);try{let e=[];for(let[s,l]of this.connections)e.push(this.connectSingleEndpoint(s,l));let t=await Promise.allSettled(e),n=t.filter(s=>s.status==="fulfilled").length,r=t.length-n,i=Date.now()-this.performanceMetrics.connectionStartTime;if(this.performanceMetrics.totalConnectionTime+=i,this.performanceMetrics.connectionCount++,this.performanceMetrics.averageConnectionTime=this.performanceMetrics.totalConnectionTime/this.performanceMetrics.connectionCount,this.logger.info(`\u8FDE\u63A5\u5B8C\u6210 - \u6210\u529F: ${n}, \u5931\u8D25: ${r}, \u8017\u65F6: ${i}ms`),n===0)throw new Error("\u6240\u6709\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u5931\u8D25");this.startHealthCheck()}finally{this.isConnecting=!1}}async disconnect(){this.logger.info("\u5F00\u59CB\u65AD\u5F00\u6240\u6709\u8FDE\u63A5"),this.stopHealthCheck(),this.clearAllReconnectTimers();let e=[];for(let[t,n]of this.connections)e.push(this.disconnectSingleEndpoint(t,n));await Promise.allSettled(e),this.logger.info("\u6240\u6709\u8FDE\u63A5\u5DF2\u65AD\u5F00")}async addEndpoint(e){if(!this.isInitialized)throw new Error("XiaozhiConnectionManager \u672A\u521D\u59CB\u5316");if(this.connections.has(e)){this.logger.warn(`\u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\u6DFB\u52A0`);return}this.logger.info(`\u52A8\u6001\u6DFB\u52A0\u7AEF\u70B9: ${e}`);try{let t=this.getCurrentTools();if(await this.createConnection(e,t),this.isAnyConnected()){let n=this.connections.get(e);await this.connectSingleEndpoint(e,n)}this.logger.info(`\u7AEF\u70B9 ${e} \u6DFB\u52A0\u6210\u529F`)}catch(t){throw this.logger.error(`\u6DFB\u52A0\u7AEF\u70B9 ${e} \u5931\u8D25:`,t),this.connections.delete(e),this.connectionStates.delete(e),t}}async removeEndpoint(e){if(!this.connections.has(e)){this.logger.warn(`\u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u79FB\u9664`);return}this.logger.info(`\u52A8\u6001\u79FB\u9664\u7AEF\u70B9: ${e}`);try{let t=this.connections.get(e);await this.disconnectSingleEndpoint(e,t),this.connections.delete(e),this.connectionStates.delete(e);let n=this.reconnectTimers.get(e);n&&(clearTimeout(n),this.reconnectTimers.delete(e)),this.logger.info(`\u7AEF\u70B9 ${e} \u79FB\u9664\u6210\u529F`)}catch(t){throw this.logger.error(`\u79FB\u9664\u7AEF\u70B9 ${e} \u5931\u8D25:`,t),t}}getHealthyConnections(){let e=[];for(let[t,n]of this.connections){let r=this.connectionStates.get(t);r?.connected&&r.healthScore>50&&e.push(n)}return e}getConnectionStatus(){return Array.from(this.connectionStates.values())}isAnyConnected(){for(let e of this.connectionStates.values())if(e.connected)return!0;return!1}setServiceManager(e){this.mcpServiceManager=e,this.logger.info("\u5DF2\u8BBE\u7F6E MCPServiceManager"),this.connections.size>0&&this.syncToolsToAllConnections()}setHealthCheckEnabled(e,t){let n=this.connectionStates.get(e);n?(n.healthCheckEnabled=t,this.logger.info(`\u7AEF\u70B9 ${e} \u5065\u5EB7\u68C0\u67E5\u5DF2${t?"\u542F\u7528":"\u7981\u7528"}`)):this.logger.warn(`\u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728\uFF0C\u65E0\u6CD5\u8BBE\u7F6E\u5065\u5EB7\u68C0\u67E5\u72B6\u6001`)}getHealthCheckStats(){let e={};for(let[t,n]of this.connectionStates){let r=n.totalRequests>0?n.successfulRequests/n.totalRequests*100:0;e[t]={endpoint:t,healthScore:n.healthScore,successRate:Math.round(r*100)/100,averageResponseTime:n.responseTime||0,consecutiveFailures:n.consecutiveFailures,lastHealthCheck:n.lastHealthCheck,lastSuccessTime:n.lastSuccessTime}}return e}async triggerHealthCheck(){this.logger.info("\u624B\u52A8\u89E6\u53D1\u5065\u5EB7\u68C0\u67E5"),await this.performHealthCheck()}async triggerReconnect(e){let t=this.connectionStates.get(e);if(!t)throw new Error(`\u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);if(t.connected){this.logger.warn(`\u7AEF\u70B9 ${e} \u5DF2\u8FDE\u63A5\uFF0C\u65E0\u9700\u91CD\u8FDE`);return}this.logger.info(`\u624B\u52A8\u89E6\u53D1\u91CD\u8FDE: ${e}`);let n=this.reconnectTimers.get(e);n&&(clearTimeout(n),this.reconnectTimers.delete(e)),await this.performReconnect(e)}stopReconnect(e){let t=this.connectionStates.get(e);if(!t){this.logger.warn(`\u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);return}let n=this.reconnectTimers.get(e);n&&(clearTimeout(n),this.reconnectTimers.delete(e),t.isReconnecting=!1,t.nextReconnectTime=void 0,this.logger.info(`\u5DF2\u505C\u6B62\u7AEF\u70B9 ${e} \u7684\u91CD\u8FDE`))}stopAllReconnects(){this.logger.info("\u505C\u6B62\u6240\u6709\u7AEF\u70B9\u7684\u91CD\u8FDE");for(let[e]of this.reconnectTimers)this.stopReconnect(e)}getReconnectStats(){let e={};for(let[t,n]of this.connectionStates)e[t]={endpoint:t,reconnectAttempts:n.reconnectAttempts,isReconnecting:n.isReconnecting,nextReconnectTime:n.nextReconnectTime,lastReconnectAttempt:n.lastReconnectAttempt,reconnectDelay:n.reconnectDelay,errorType:n.errorType,recentReconnectHistory:n.reconnectHistory.slice(-5)};return e}validateEndpoints(e){let t=[],n=[];for(let r of e){if(!r||typeof r!="string"){n.push(r);continue}if(!r.startsWith("ws://")&&!r.startsWith("wss://")){n.push(r);continue}try{new URL(r),t.push(r)}catch{n.push(r)}}return{valid:t,invalid:n}}validateOptions(e){let t=[];if(e.healthCheckInterval!==void 0&&(typeof e.healthCheckInterval!="number"||e.healthCheckInterval<1e3)&&t.push("healthCheckInterval \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 1000 \u7684\u6570\u5B57"),e.reconnectInterval!==void 0&&(typeof e.reconnectInterval!="number"||e.reconnectInterval<100)&&t.push("reconnectInterval \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 100 \u7684\u6570\u5B57"),e.maxReconnectAttempts!==void 0&&(typeof e.maxReconnectAttempts!="number"||e.maxReconnectAttempts<0)&&t.push("maxReconnectAttempts \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 0 \u7684\u6570\u5B57"),e.connectionTimeout!==void 0&&(typeof e.connectionTimeout!="number"||e.connectionTimeout<1e3)&&t.push("connectionTimeout \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 1000 \u7684\u6570\u5B57"),e.maxReconnectDelay!==void 0&&(typeof e.maxReconnectDelay!="number"||e.maxReconnectDelay<1e3)&&t.push("maxReconnectDelay \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 1000 \u7684\u6570\u5B57"),e.reconnectBackoffMultiplier!==void 0&&(typeof e.reconnectBackoffMultiplier!="number"||e.reconnectBackoffMultiplier<1)&&t.push("reconnectBackoffMultiplier \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 1 \u7684\u6570\u5B57"),e.loadBalanceStrategy!==void 0){let n=["round-robin","random","health-based"];n.includes(e.loadBalanceStrategy)||t.push(`loadBalanceStrategy \u5FC5\u987B\u662F\u4EE5\u4E0B\u503C\u4E4B\u4E00: ${n.join(", ")}`)}if(e.reconnectStrategy!==void 0){let n=Object.values(Ue);n.includes(e.reconnectStrategy)||t.push(`reconnectStrategy \u5FC5\u987B\u662F\u4EE5\u4E0B\u503C\u4E4B\u4E00: ${n.join(", ")}`)}return{valid:t.length===0,errors:t}}async updateEndpoints(e,t=[]){if(!this.isInitialized)throw new Error("XiaozhiConnectionManager \u672A\u521D\u59CB\u5316");this.logger.info(`\u66F4\u65B0\u7AEF\u70B9\u914D\u7F6E\uFF0C\u65B0\u7AEF\u70B9\u6570\u91CF: ${e.length}`);let{valid:n,invalid:r}=this.validateEndpoints(e);if(r.length>0&&this.logger.warn(`\u53D1\u73B0\u65E0\u6548\u7AEF\u70B9: ${r.join(", ")}`),n.length===0)throw new Error("\u6CA1\u6709\u6709\u6548\u7684\u7AEF\u70B9");let i=Array.from(this.connections.keys()),s=n.filter(f=>!i.includes(f)),l=i.filter(f=>!n.includes(f)),p=i.filter(f=>n.includes(f));this.logger.info(`\u7AEF\u70B9\u53D8\u66F4 - \u6DFB\u52A0: ${s.length}, \u79FB\u9664: ${l.length}, \u4FDD\u6301: ${p.length}`);try{for(let S of l)await this.removeEndpoint(S);for(let S of s)await this.addEndpoint(S);let f={type:s.length>0&&l.length>0?"endpoints_updated":s.length>0?"endpoints_added":"endpoints_removed",data:{added:s.length>0?s:void 0,removed:l.length>0?l:void 0,updated:s.length>0&&l.length>0?n:void 0},timestamp:new Date};this.emit("configChange",f),this.logger.info("\u7AEF\u70B9\u914D\u7F6E\u66F4\u65B0\u5B8C\u6210")}catch(f){throw this.logger.error("\u7AEF\u70B9\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",f),f}}updateOptions(e){this.logger.info("\u66F4\u65B0\u8FDE\u63A5\u9009\u9879");let{valid:t,errors:n}=this.validateOptions(e);if(!t)throw new Error(`\u65E0\u6548\u7684\u8FDE\u63A5\u9009\u9879: ${n.join(", ")}`);let r={...this.options};this.options={...this.options,...e};let i={type:"options_updated",data:{oldOptions:r,newOptions:e},timestamp:new Date};this.emit("configChange",i),this.logger.info("\u8FDE\u63A5\u9009\u9879\u66F4\u65B0\u5B8C\u6210"),this.logger.debug("\u65B0\u7684\u914D\u7F6E\u9009\u9879:",this.options)}getCurrentConfig(){return{endpoints:Array.from(this.connections.keys()),options:{...this.options}}}async reloadConfig(e){this.logger.info("\u5F00\u59CB\u70ED\u91CD\u8F7D\u914D\u7F6E");try{e.options&&this.updateOptions(e.options),e.endpoints&&await this.updateEndpoints(e.endpoints,e.tools||[]),this.logger.info("\u914D\u7F6E\u70ED\u91CD\u8F7D\u5B8C\u6210")}catch(t){throw this.logger.error("\u914D\u7F6E\u70ED\u91CD\u8F7D\u5931\u8D25:",t),t}}selectBestConnection(e=[]){let t=this.getHealthyConnections();if(t.length===0)return this.logger.warn("\u6CA1\u6709\u5065\u5EB7\u7684\u8FDE\u63A5\u53EF\u7528"),null;let n=t.filter(i=>{let s=this.getEndpointByConnection(i);return s&&!e.includes(s)});if(n.length===0)return this.logger.warn("\u6CA1\u6709\u53EF\u7528\u7684\u8FDE\u63A5\uFF08\u6392\u9664\u6307\u5B9A\u7AEF\u70B9\u540E\uFF09"),null;let r;switch(this.options.loadBalanceStrategy){case"round-robin":r=this.selectRoundRobin(n);break;case"random":r=this.selectRandom(n);break;case"health-based":r=this.selectHealthBased(n);break;default:r=this.selectRoundRobin(n)}return this.lastSelectedEndpoint=this.getEndpointByConnection(r),r}selectRoundRobin(e){if(e.length===0)throw new Error("\u6CA1\u6709\u53EF\u7528\u7684\u8FDE\u63A5");let t=e[this.roundRobinIndex%e.length];return this.roundRobinIndex=(this.roundRobinIndex+1)%e.length,t}selectRandom(e){if(e.length===0)throw new Error("\u6CA1\u6709\u53EF\u7528\u7684\u8FDE\u63A5");let t=Math.floor(Math.random()*e.length);return e[t]}selectHealthBased(e){if(e.length===0)throw new Error("\u6CA1\u6709\u53EF\u7528\u7684\u8FDE\u63A5");let t=e.map(i=>{let s=this.getEndpointByConnection(i),l=s?this.connectionStates.get(s):null;return{connection:i,endpoint:s,healthScore:l?.healthScore||0,responseTime:l?.responseTime||Number.POSITIVE_INFINITY,successRate:l&&l.totalRequests>0?l.successfulRequests/l.totalRequests*100:0}});t.sort((i,s)=>i.healthScore!==s.healthScore?s.healthScore-i.healthScore:i.successRate!==s.successRate?s.successRate-i.successRate:i.responseTime-s.responseTime);let n=t.reduce((i,s)=>i+(s.healthScore+1),0),r=Math.random()*n;for(let i of t)if(r-=i.healthScore+1,r<=0)return i.connection;return t[0].connection}getEndpointByConnection(e){for(let[t,n]of this.connections)if(n===e)return t;return null}getLoadBalanceStats(){let e=this.getHealthyConnections(),t={};for(let[n,r]of this.connectionStates){let i=r.totalRequests>0?r.successfulRequests/r.totalRequests*100:0,s=r.healthScore+1;t[n]={healthScore:r.healthScore,responseTime:r.responseTime||0,successRate:Math.round(i*100)/100,weight:s}}return{strategy:this.options.loadBalanceStrategy,totalConnections:this.connections.size,healthyConnections:e.length,lastSelectedEndpoint:this.lastSelectedEndpoint,roundRobinIndex:this.roundRobinIndex,connectionWeights:t}}setLoadBalanceStrategy(e){let t=this.options.loadBalanceStrategy;this.options.loadBalanceStrategy=e,e==="round-robin"&&(this.roundRobinIndex=0),this.logger.info(`\u8D1F\u8F7D\u5747\u8861\u7B56\u7565\u5DF2\u4ECE ${t} \u5207\u6362\u5230 ${e}`);let n={type:"options_updated",data:{oldOptions:{loadBalanceStrategy:t},newOptions:{loadBalanceStrategy:e}},timestamp:new Date};this.emit("configChange",n)}async performFailover(e){this.logger.warn(`\u6267\u884C\u6545\u969C\u8F6C\u79FB\uFF0C\u5931\u8D25\u7AEF\u70B9: ${e}`);let t=this.selectBestConnection([e]);if(!t)return this.logger.error("\u6545\u969C\u8F6C\u79FB\u5931\u8D25\uFF1A\u6CA1\u6709\u53EF\u7528\u7684\u5907\u7528\u8FDE\u63A5"),null;let n=this.getEndpointByConnection(t);return this.logger.info(`\u6545\u969C\u8F6C\u79FB\u6210\u529F\uFF0C\u5207\u6362\u5230\u7AEF\u70B9: ${n}`),t}async prewarmConnections(e=[]){let t=e.length>0?e:Array.from(this.connections.keys());this.logger.info(`\u5F00\u59CB\u9884\u70ED\u8FDE\u63A5\uFF0C\u7AEF\u70B9\u6570\u91CF: ${t.length}`);let n=t.map(async r=>{if(this.performanceMetrics.prewarmedConnections.has(r)){this.logger.debug(`\u7AEF\u70B9 ${r} \u5DF2\u9884\u70ED\uFF0C\u8DF3\u8FC7`);return}try{this.connections.get(r)&&(await this.performHealthCheck(),this.performanceMetrics.prewarmedConnections.add(r),this.logger.debug(`\u7AEF\u70B9 ${r} \u9884\u70ED\u5B8C\u6210`))}catch(i){this.logger.warn(`\u7AEF\u70B9 ${r} \u9884\u70ED\u5931\u8D25:`,i)}});await Promise.all(n),this.logger.info(`\u8FDE\u63A5\u9884\u70ED\u5B8C\u6210\uFF0C\u6210\u529F\u9884\u70ED ${this.performanceMetrics.prewarmedConnections.size} \u4E2A\u7AEF\u70B9`)}updatePerformanceMetrics(){let e=process.memoryUsage().heapUsed;this.performanceMetrics.memoryUsage.current=e,e>this.performanceMetrics.memoryUsage.peak&&(this.performanceMetrics.memoryUsage.peak=e)}getPerformanceMetrics(){this.updatePerformanceMetrics();let e=this.performanceMetrics.memoryUsage.current-this.performanceMetrics.memoryUsage.initial,t=this.performanceMetrics.memoryUsage.initial>0?e/this.performanceMetrics.memoryUsage.initial*100:0;return{connectionTime:{total:this.performanceMetrics.totalConnectionTime,average:this.performanceMetrics.averageConnectionTime,count:this.performanceMetrics.connectionCount},memoryUsage:{initial:this.performanceMetrics.memoryUsage.initial,current:this.performanceMetrics.memoryUsage.current,peak:this.performanceMetrics.memoryUsage.peak,growth:e,growthPercentage:Math.round(t*100)/100},prewarmedConnections:this.performanceMetrics.prewarmedConnections.size,totalConnections:this.connections.size,healthyConnections:this.getHealthyConnections().length}}optimizeMemoryUsage(){this.logger.info("\u5F00\u59CB\u5185\u5B58\u4F18\u5316");for(let[,e]of this.connectionStates)if(e.reconnectHistory&&e.reconnectHistory.length>10&&(e.reconnectHistory=e.reconnectHistory.slice(-10)),e.totalRequests>1e4){let t=e.successfulRequests/e.totalRequests;e.totalRequests=1e3,e.successfulRequests=Math.round(t*1e3)}global.gc&&global.gc(),this.updatePerformanceMetrics(),this.logger.info("\u5185\u5B58\u4F18\u5316\u5B8C\u6210")}async cleanup(){this.logger.info("\u5F00\u59CB\u6E05\u7406 XiaozhiConnectionManager \u8D44\u6E90");try{await this.disconnect(),this.connections.clear(),this.connectionStates.clear(),this.isInitialized=!1,this.isConnecting=!1,this.roundRobinIndex=0,this.lastSelectedEndpoint=null,this.logger.info("XiaozhiConnectionManager \u8D44\u6E90\u6E05\u7406\u5B8C\u6210")}catch(e){throw this.logger.error("XiaozhiConnectionManager \u8D44\u6E90\u6E05\u7406\u5931\u8D25:",e),e}}validateInitializeParams(e,t){if(!Array.isArray(e)||e.length===0)throw new Error("\u7AEF\u70B9\u5217\u8868\u4E0D\u80FD\u4E3A\u7A7A");if(!Array.isArray(t))throw new Error("\u5DE5\u5177\u5217\u8868\u5FC5\u987B\u662F\u6570\u7EC4");for(let n of e){if(!n||typeof n!="string")throw new Error(`\u65E0\u6548\u7684\u7AEF\u70B9\u5730\u5740: ${n}`);if(!n.startsWith("ws://")&&!n.startsWith("wss://"))throw new Error(`\u7AEF\u70B9\u5730\u5740\u5FC5\u987B\u662F WebSocket URL: ${n}`)}}async createConnection(e,t){this.logger.debug(`\u521B\u5EFA\u8FDE\u63A5\u5B9E\u4F8B: ${e}`);try{let n=new D(e);this.mcpServiceManager&&n.setServiceManager(this.mcpServiceManager),this.connections.set(e,n),this.connectionStates.set(e,{endpoint:e,connected:!1,initialized:!1,reconnectAttempts:0,healthScore:100,consecutiveFailures:0,totalRequests:0,successfulRequests:0,healthCheckEnabled:!0,isReconnecting:!1,reconnectDelay:this.options.reconnectInterval,reconnectHistory:[]}),this.logger.debug(`\u8FDE\u63A5\u5B9E\u4F8B\u521B\u5EFA\u6210\u529F: ${e}`)}catch(n){throw this.logger.error(`\u521B\u5EFA\u8FDE\u63A5\u5B9E\u4F8B\u5931\u8D25 ${e}:`,n),n}}async connectSingleEndpoint(e,t){let n=this.connectionStates.get(e);if(!n)throw new Error(`\u7AEF\u70B9\u72B6\u6001\u4E0D\u5B58\u5728: ${e}`);this.logger.debug(`\u8FDE\u63A5\u7AEF\u70B9: ${e}`);try{n.connected=!1,n.initialized=!1,await t.connect(),n.connected=!0,n.initialized=!0,n.lastConnected=new Date,n.lastError=void 0,n.reconnectAttempts=0,n.healthScore=100,this.logger.info(`\u7AEF\u70B9\u8FDE\u63A5\u6210\u529F: ${e}`)}catch(r){throw n.connected=!1,n.initialized=!1,n.lastError=r instanceof Error?r.message:String(r),n.reconnectAttempts++,n.healthScore=Math.max(0,n.healthScore-20),this.logger.error(`\u7AEF\u70B9\u8FDE\u63A5\u5931\u8D25 ${e}:`,r),this.scheduleReconnect(e),r}}async disconnectSingleEndpoint(e,t){let n=this.connectionStates.get(e);if(n){this.logger.debug(`\u65AD\u5F00\u7AEF\u70B9: ${e}`);try{t.disconnect(),n.connected=!1,n.initialized=!1,this.logger.debug(`\u7AEF\u70B9\u65AD\u5F00\u6210\u529F: ${e}`)}catch(r){this.logger.error(`\u7AEF\u70B9\u65AD\u5F00\u5931\u8D25 ${e}:`,r),n.connected=!1,n.initialized=!1}}}getCurrentTools(){if(!this.mcpServiceManager)return[];try{return this.mcpServiceManager.getAllTools()}catch(e){return this.logger.error("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25:",e),[]}}syncToolsToAllConnections(){if(this.mcpServiceManager){this.logger.debug("\u540C\u6B65\u5DE5\u5177\u5230\u6240\u6709\u8FDE\u63A5");for(let[e,t]of this.connections)try{t.setServiceManager(this.mcpServiceManager),this.logger.debug(`\u5DE5\u5177\u540C\u6B65\u6210\u529F: ${e}`)}catch(n){this.logger.error(`\u5DE5\u5177\u540C\u6B65\u5931\u8D25 ${e}:`,n)}}}startHealthCheck(){this.healthCheckInterval||(this.logger.debug(`\u542F\u52A8\u5065\u5EB7\u68C0\u67E5\uFF0C\u95F4\u9694: ${this.options.healthCheckInterval}ms`),this.healthCheckInterval=setInterval(()=>{this.performHealthCheck()},this.options.healthCheckInterval))}stopHealthCheck(){this.healthCheckInterval&&(clearInterval(this.healthCheckInterval),this.healthCheckInterval=null,this.logger.debug("\u5065\u5EB7\u68C0\u67E5\u5DF2\u505C\u6B62"))}async performHealthCheck(){this.logger.debug("\u6267\u884C\u5065\u5EB7\u68C0\u67E5");let e=[];for(let[t,n]of this.connectionStates)n.healthCheckEnabled&&e.push(this.performSingleHealthCheck(t,n));await Promise.allSettled(e)}async performSingleHealthCheck(e,t){let n=Date.now();t.lastHealthCheck=new Date,t.totalRequests++;try{let r=this.connections.get(e);if(!r)throw new Error(`\u8FDE\u63A5\u5B9E\u4F8B\u4E0D\u5B58\u5728: ${e}`);await this.checkConnectionHealth(r,e);let i=Date.now()-n;this.handleHealthCheckSuccess(t,i)}catch(r){let i=Date.now()-n;this.handleHealthCheckFailure(t,r,i)}}async checkConnectionHealth(e,t){if(!e)throw new Error("\u8FDE\u63A5\u5B9E\u4F8B\u4E0D\u5B58\u5728");if(await new Promise(r=>setTimeout(r,10)),!this.connectionStates.get(t)?.connected)throw new Error("\u8FDE\u63A5\u5DF2\u65AD\u5F00")}handleHealthCheckSuccess(e,t){e.successfulRequests++,e.consecutiveFailures=0,e.responseTime=t,e.lastSuccessTime=new Date,this.updateHealthScore(e,!0,t),this.logger.debug(`\u5065\u5EB7\u68C0\u67E5\u6210\u529F: ${e.endpoint}, \u54CD\u5E94\u65F6\u95F4: ${t}ms, \u5065\u5EB7\u5EA6: ${e.healthScore}`)}handleHealthCheckFailure(e,t,n){e.consecutiveFailures++,e.responseTime=n,e.lastError=t.message,this.updateHealthScore(e,!1,n),this.logger.warn(`\u5065\u5EB7\u68C0\u67E5\u5931\u8D25: ${e.endpoint}, \u9519\u8BEF: ${t.message}, \u8FDE\u7EED\u5931\u8D25: ${e.consecutiveFailures}, \u5065\u5EB7\u5EA6: ${e.healthScore}`),e.consecutiveFailures>=3&&e.connected&&this.logger.warn(`\u7AEF\u70B9 ${e.endpoint} \u8FDE\u7EED\u5931\u8D25 ${e.consecutiveFailures} \u6B21\uFF0C\u53EF\u80FD\u9700\u8981\u91CD\u8FDE`)}updateHealthScore(e,t,n){let r=e.healthScore;if(t){let i=5;n<100?i=10:n<500?i=7:n<1e3?i=5:i=2,e.healthScore=Math.min(100,r+i)}else{let i=15;e.consecutiveFailures>=5?i=30:e.consecutiveFailures>=3&&(i=20),e.healthScore=Math.max(0,r-i)}if(e.totalRequests>0){let i=e.successfulRequests/e.totalRequests;i<.5?e.healthScore=Math.max(0,e.healthScore-10):i>.9&&(e.healthScore=Math.min(100,e.healthScore+5))}}classifyConnectionError(e){let t=e.message.toLowerCase();return t.includes("timeout")||t.includes("timed out")?"timeout_error":t.includes("network")||t.includes("connection refused")||t.includes("econnrefused")||t.includes("enotfound")?"network_error":t.includes("auth")||t.includes("unauthorized")||t.includes("forbidden")||t.includes("401")||t.includes("403")?"authentication_error":t.includes("server")||t.includes("500")||t.includes("502")||t.includes("503")||t.includes("504")?"server_error":"unknown_error"}calculateReconnectDelay(e){let t=this.options.reconnectInterval,n=this.options.maxReconnectDelay,r=this.options.reconnectBackoffMultiplier,i=e.reconnectAttempts,s;switch(this.options.reconnectStrategy){case"fixed_interval":s=t;break;case"linear_backoff":s=t*(i+1);break;case"exponential_backoff":s=t*r**i;break;case"adaptive":s=this.calculateAdaptiveDelay(e,t,r,i);break;default:s=t*r**i}if(s=Math.min(s,n),this.options.jitterEnabled){let l=s*.1*Math.random();s+=l}return Math.round(s)}calculateAdaptiveDelay(e,t,n,r){let i=t;switch(e.errorType){case"network_error":i=t*n**r;break;case"authentication_error":i=t*n**r*2;break;case"server_error":i=t*(1+r);break;case"timeout_error":i=t*(1+r*.5);break;default:i=t*n**r}if(e.reconnectHistory.length>0){let s=e.reconnectHistory.slice(-5),l=s.filter(p=>p.success).length/s.length;l<.2?i*=1.5:l>.8&&(i*=.8)}return i}shouldReconnect(e){return e.reconnectAttempts>=this.options.maxReconnectAttempts?(this.logger.warn(`\u7AEF\u70B9 ${e.endpoint} \u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 ${this.options.maxReconnectAttempts}`),!1):e.errorType==="authentication_error"&&e.reconnectAttempts>=3?(this.logger.warn(`\u7AEF\u70B9 ${e.endpoint} \u8BA4\u8BC1\u9519\u8BEF\uFF0C\u505C\u6B62\u91CD\u8FDE`),!1):e.consecutiveFailures>=10?(this.logger.warn(`\u7AEF\u70B9 ${e.endpoint} \u8FDE\u7EED\u5931\u8D25\u6B21\u6570\u8FC7\u591A\uFF0C\u505C\u6B62\u91CD\u8FDE`),!1):!0}scheduleReconnect(e){let t=this.connectionStates.get(e);if(!t)return;if(t.lastError&&(t.errorType=this.classifyConnectionError(new Error(t.lastError))),!this.shouldReconnect(t)){t.isReconnecting=!1;return}let n=this.reconnectTimers.get(e);n&&clearTimeout(n);let r=this.calculateReconnectDelay(t);t.reconnectDelay=r,t.isReconnecting=!0,t.nextReconnectTime=new Date(Date.now()+r),this.logger.info(`\u5B89\u6392\u91CD\u8FDE ${e}\uFF0C\u5EF6\u8FDF: ${r}ms\uFF0C\u5C1D\u8BD5\u6B21\u6570: ${t.reconnectAttempts+1}\uFF0C\u9519\u8BEF\u7C7B\u578B: ${t.errorType}`);let i=setTimeout(async()=>{this.reconnectTimers.delete(e),await this.performReconnect(e)},r);this.reconnectTimers.set(e,i)}async performReconnect(e){let t=this.connectionStates.get(e),n=this.connections.get(e);if(!(!t||!n)){t.lastReconnectAttempt=new Date,t.isReconnecting=!0,this.logger.info(`\u5F00\u59CB\u91CD\u8FDE ${e}\uFF0C\u7B2C ${t.reconnectAttempts+1} \u6B21\u5C1D\u8BD5`);try{await this.connectSingleEndpoint(e,n),t.isReconnecting=!1,t.reconnectHistory.push({timestamp:new Date,success:!0,delay:t.reconnectDelay}),this.logger.info(`\u91CD\u8FDE\u6210\u529F ${e}`)}catch(r){t.isReconnecting=!1,t.reconnectHistory.push({timestamp:new Date,success:!1,error:r instanceof Error?r.message:String(r),delay:t.reconnectDelay}),this.logger.error(`\u91CD\u8FDE\u5931\u8D25 ${e}:`,r),this.scheduleReconnect(e)}t.reconnectHistory.length>20&&(t.reconnectHistory=t.reconnectHistory.slice(-20))}}clearAllReconnectTimers(){for(let[,e]of this.reconnectTimers)clearTimeout(e);this.reconnectTimers.clear()}};var A=null,R=null,w="not_initialized",V=null,F=null;async function tn(o){return console.log("\u{1F680} \u6B63\u5728\u521D\u59CB\u5316 XiaozhiConnectionManager \u5355\u4F8B..."),new se(o)}a(tn,"createInstance");async function We(o){if(A&&w==="initialized")return A;if(R&&w==="initializing")return R;w==="failed"&&Me(),w="initializing",R=tn(o);try{return A=await R,w="initialized",F=`xiaozhi-connection-manager-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,V=null,console.log(`\u2705 XiaozhiConnectionManager \u5355\u4F8B\u521D\u59CB\u5316\u6210\u529F\uFF0C\u5B9E\u4F8BID: ${F}`),A}catch(e){throw w="failed",V=e,R=null,console.error("\u274C XiaozhiConnectionManager \u5355\u4F8B\u521D\u59CB\u5316\u5931\u8D25:",e.message),e}}a(We,"getInstance");async function _e(){if(w==="cleanup"){console.log("\u26A0\uFE0F XiaozhiConnectionManager \u5355\u4F8B\u5DF2\u5728\u6E05\u7406\u4E2D\uFF0C\u8DF3\u8FC7\u91CD\u590D\u6E05\u7406");return}console.log("\u{1F9F9} \u6B63\u5728\u6E05\u7406 XiaozhiConnectionManager \u5355\u4F8B\u8D44\u6E90..."),w="cleanup";try{if(R){try{await(await R).cleanup()}catch(o){console.error("\u6E05\u7406\u521D\u59CB\u5316\u4E2D\u7684\u5B9E\u4F8B\u5931\u8D25:",o.message)}R=null}A&&(await A.cleanup(),A=null),w="not_initialized",V=null,F=null,console.log("\u2705 XiaozhiConnectionManager \u5355\u4F8B\u8D44\u6E90\u6E05\u7406\u5B8C\u6210")}catch(o){throw console.error("\u274C XiaozhiConnectionManager \u5355\u4F8B\u6E05\u7406\u5931\u8D25:",o.message),Me(),o}}a(_e,"cleanup");function Me(){console.log("\u{1F504} \u91CD\u7F6E XiaozhiConnectionManager \u5355\u4F8B\u72B6\u6001..."),R&&(R=null),A=null,w="not_initialized",V=null,F=null,console.log("\u2705 XiaozhiConnectionManager \u5355\u4F8B\u72B6\u6001\u5DF2\u91CD\u7F6E")}a(Me,"reset");function nn(){return w==="initialized"&&A!==null}a(nn,"isInitialized");function on(){return{state:w,initializationTime:F?new Date:void 0,lastError:V||void 0,instanceId:F||void 0}}a(on,"getStatus");async function rn(o){return console.log("\u{1F504} \u5F3A\u5236\u91CD\u65B0\u521D\u59CB\u5316 XiaozhiConnectionManager \u5355\u4F8B..."),await _e(),We(o)}a(rn,"forceReinitialize");function sn(){return A}a(sn,"getCurrentInstance");async function an(){if(w==="initialized")return!0;if(w==="initializing"&&R)try{return await R,!0}catch{return!1}return!1}a(an,"waitForInitialization");var L={getInstance:We,cleanup:_e,reset:Me,isInitialized:nn,getStatus:on,forceReinitialize:rn,getCurrentInstance:sn,waitForInitialization:an};process.on("exit",()=>{L.isInitialized()&&(console.log("\u{1F504} \u8FDB\u7A0B\u9000\u51FA\uFF0C\u6B63\u5728\u6E05\u7406 XiaozhiConnectionManager \u5355\u4F8B..."),L.reset())});process.on("uncaughtException",async o=>{console.error("\u{1F4A5} \u672A\u6355\u83B7\u7684\u5F02\u5E38\uFF0C\u6E05\u7406 XiaozhiConnectionManager \u5355\u4F8B:",o);try{await L.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}});process.on("unhandledRejection",async o=>{console.error("\u{1F4A5} \u672A\u5904\u7406\u7684Promise\u62D2\u7EDD\uFF0C\u6E05\u7406 XiaozhiConnectionManager \u5355\u4F8B:",o);try{await L.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}});var Q=class{static{a(this,"WebServer")}app;httpServer=null;wss=null;logger;port;clientInfo={status:"disconnected",mcpEndpoint:"",activeMCPServers:[]};heartbeatTimeout;HEARTBEAT_TIMEOUT=35e3;proxyMCPServer;xiaozhiConnectionManager;mcpServiceManager;constructor(e){try{this.port=e??g.getWebUIPort()??9999}catch{this.port=e??9999}this.logger=d,this.app=new pn,this.setupMiddleware(),this.setupRoutes()}async initializeConnections(){try{this.logger.info("\u5F00\u59CB\u521D\u59CB\u5316\u8FDE\u63A5...");let e=await this.loadConfiguration();this.mcpServiceManager=await H.getInstance(),await this.loadMCPServicesFromConfig(e.mcpServers);let t=this.mcpServiceManager.getAllTools();this.logger.info(`\u5DF2\u52A0\u8F7D ${t.length} \u4E2A\u5DE5\u5177`),await this.initializeXiaozhiConnection(e.mcpEndpoint,t),this.logger.info("\u6240\u6709\u8FDE\u63A5\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("\u8FDE\u63A5\u521D\u59CB\u5316\u5931\u8D25:",e),e}}async loadConfiguration(){if(!g.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C 'xiaozhi init' \u521D\u59CB\u5316\u914D\u7F6E");let e=g.getConfig();return{mcpEndpoint:e.mcpEndpoint,mcpServers:e.mcpServers,webUIPort:e.webUI?.port??9999}}async loadMCPServicesFromConfig(e){if(!this.mcpServiceManager)throw new Error("MCPServiceManager \u672A\u521D\u59CB\u5316");for(let[t,n]of Object.entries(e)){this.logger.info(`\u6DFB\u52A0 MCP \u670D\u52A1\u914D\u7F6E: ${t}`);let r=ke(t,n);this.mcpServiceManager.addServiceConfig(t,r)}await this.mcpServiceManager.startAllServices(),this.logger.info("\u6240\u6709 MCP \u670D\u52A1\u5DF2\u542F\u52A8")}async initializeXiaozhiConnection(e,t){let r=(Array.isArray(e)?e:[e]).filter(i=>i&&!i.includes("<\u8BF7\u586B\u5199"));if(r.length===0){this.logger.warn("\u672A\u914D\u7F6E\u6709\u6548\u7684\u5C0F\u667A\u63A5\u5165\u70B9\uFF0C\u8DF3\u8FC7\u8FDE\u63A5");return}this.logger.info(`\u521D\u59CB\u5316\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u7BA1\u7406\u5668\uFF0C\u7AEF\u70B9\u6570\u91CF: ${r.length}`),this.logger.debug("\u6709\u6548\u7AEF\u70B9\u5217\u8868:",r);try{this.xiaozhiConnectionManager=await L.getInstance({healthCheckInterval:3e4,reconnectInterval:5e3,maxReconnectAttempts:10,loadBalanceStrategy:"round-robin",connectionTimeout:1e4}),this.mcpServiceManager&&this.xiaozhiConnectionManager.setServiceManager(this.mcpServiceManager),await this.xiaozhiConnectionManager.initialize(r,t),await this.xiaozhiConnectionManager.connect(),this.xiaozhiConnectionManager.on("configChange",i=>{this.logger.info(`\u5C0F\u667A\u8FDE\u63A5\u914D\u7F6E\u53D8\u66F4: ${i.type}`,i.data)}),this.logger.info(`\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u7BA1\u7406\u5668\u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u7BA1\u7406 ${r.length} \u4E2A\u7AEF\u70B9`)}catch(i){this.logger.error("\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u7BA1\u7406\u5668\u521D\u59CB\u5316\u5931\u8D25:",i),this.logger.warn("\u56DE\u9000\u5230\u5355\u8FDE\u63A5\u6A21\u5F0F");let s=r[0];this.logger.info(`\u521D\u59CB\u5316\u5355\u4E2A\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5: ${s}`),this.proxyMCPServer=new D(s),this.mcpServiceManager&&this.proxyMCPServer.setServiceManager(this.mcpServiceManager),await this.connectWithRetry(()=>this.proxyMCPServer.connect(),"\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5"),this.logger.info("\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u6210\u529F\uFF08\u5355\u8FDE\u63A5\u6A21\u5F0F\uFF09")}}getBestXiaozhiConnection(){return this.xiaozhiConnectionManager?this.xiaozhiConnectionManager.selectBestConnection():this.proxyMCPServer||null}getXiaozhiConnectionStatus(){return this.xiaozhiConnectionManager?{type:"multi-endpoint",manager:{healthyConnections:this.xiaozhiConnectionManager.getHealthyConnections().length,totalConnections:this.xiaozhiConnectionManager.getConnectionStatus().length,loadBalanceStats:this.xiaozhiConnectionManager.getLoadBalanceStats(),healthCheckStats:this.xiaozhiConnectionManager.getHealthCheckStats(),reconnectStats:this.xiaozhiConnectionManager.getReconnectStats()},connections:this.xiaozhiConnectionManager.getConnectionStatus()}:this.proxyMCPServer?{type:"single-endpoint",connected:!0,endpoint:"unknown"}:{type:"none",connected:!1}}async connectWithRetry(e,t,n=5,r=1e3,i=3e4,s=2){let l=null;for(let p=1;p<=n;p++)try{return this.logger.info(`${t} - \u5C1D\u8BD5\u8FDE\u63A5 (${p}/${n})`),await e()}catch(f){if(l=f,this.logger.warn(`${t} - \u8FDE\u63A5\u5931\u8D25:`,f),p<n){let S=Math.min(r*s**(p-1),i);this.logger.info(`${t} - ${S}ms \u540E\u91CD\u8BD5...`),await this.sleep(S)}}throw new Error(`${t} - \u8FDE\u63A5\u5931\u8D25\uFF0C\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570: ${l?.message}`)}sleep(e){return new Promise(t=>setTimeout(t,e))}setupMiddleware(){this.app?.use("*",fn({origin:"*",allowMethods:["GET","POST","PUT","OPTIONS"],allowHeaders:["Content-Type"]})),this.app?.onError((e,t)=>(this.logger.error("HTTP request error:",e),t.json({error:"Internal Server Error"},500)))}setupRoutes(){this.app?.get("/api/config",async e=>{let t=g.getConfig();return e.json(t)}),this.app?.put("/api/config",async e=>{try{let t=await e.req.json();return this.updateConfig(t),this.broadcastConfigUpdate(t),this.logger.info("\u914D\u7F6E\u5DF2\u66F4\u65B0"),e.json({success:!0})}catch(t){return e.json({error:t instanceof Error?t.message:String(t)},400)}}),this.app?.get("/api/status",async e=>{let t=this.proxyMCPServer?.getStatus();return e.json({...this.clientInfo,mcpConnection:t})}),this.app?.all("/api/*",async e=>e.text("Not Found",404)),this.app.get("*",async e=>this.serveStaticFile(e))}async serveStaticFile(e){let t=new URL(e.req.url).pathname;try{let n=ln(gn(import.meta.url)),i=[U(n,"..","web","dist"),U(n,"..","web"),U(process.cwd(),"web","dist"),U(process.cwd(),"web")].find(N=>be(N));if(!i)return e.html(`
15
+ `),this.logger.debug(`\u6D88\u606F\u5DF2\u53D1\u9001\u5230\u5BA2\u6237\u7AEF ${e.id}`,{sessionId:e.sessionId,messageId:t.id})}catch(n){this.logger.error(`\u5411\u5BA2\u6237\u7AEF ${e.id} \u53D1\u9001\u6D88\u606F\u5931\u8D25`,n),this.clients.delete(e.sessionId)}}broadcastToClients(e){for(let t of this.clients.values())this.sendToClient(t,e)}getStatus(){return{isRunning:this.server!==null,port:this.port,host:this.host,clientCount:this.clients.size,maxClients:this.maxClients,enableSSE:this.enableSSE,enableRPC:this.enableRPC,connectionId:this.connectionId,state:this.state}}getClients(){return Array.from(this.clients.values()).map(e=>({id:e.id,sessionId:e.sessionId,connectedAt:e.connectedAt}))}}});var qt=h(()=>{"use strict";Pe()});import Ai,{WebSocketServer as ki}from"ws";var Zt=h(()=>{"use strict";Pe()});import{SSEClientTransport as Qt}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as Yn}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as er}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{EventSource as tr}from"eventsource";function nr(){return f}function rr(i){switch(nr().info(`[TransportFactory] \u521B\u5EFA ${i.type} transport for ${i.name}`),i.type){case"stdio":return or(i);case"sse":return ir(i);case"modelscope-sse":return sr(i);case"streamable-http":return ar(i);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`)}}function or(i){if(!i.command)throw new Error("stdio transport \u9700\u8981 command \u914D\u7F6E");return new Yn({command:i.command,args:i.args||[]})}function ir(i){if(!i.url)throw new Error("SSE transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(i.url),t=cr(i);return new Qt(e,t)}function sr(i){if(!i.url)throw new Error("ModelScope SSE transport \u9700\u8981 URL \u914D\u7F6E");if(!i.apiKey)throw new Error("ModelScope SSE transport \u9700\u8981 apiKey \u914D\u7F6E");let e=new URL(i.url),t=lr(i);return new Qt(e,t)}function ar(i){if(!i.url)throw new Error("StreamableHTTP transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(i.url),t=gr(i);return new er(e,t)}function cr(i){let e={};return i.apiKey?e.headers={Authorization:`Bearer ${i.apiKey}`,...i.headers}:i.headers&&(e.headers=i.headers),e}function lr(i){let e=i.apiKey;return i.customSSEOptions?i.customSSEOptions:{eventSourceInit:{fetch:a(async(t,n)=>{let r={...n?.headers,Authorization:`Bearer ${e}`};return fetch(t,{...n,headers:r})},"fetch")},requestInit:{headers:{Authorization:`Bearer ${e}`,...i.headers}}}}function gr(i){let e={};return i.apiKey?e.headers={Authorization:`Bearer ${i.apiKey}`,...i.headers}:i.headers&&(e.headers=i.headers),e}function hr(i){if(!i.name||typeof i.name!="string")throw new Error("\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 name \u5B57\u6BB5");if(!i.type)throw new Error("\u914D\u7F6E\u5FC5\u987B\u5305\u542B type \u5B57\u6BB5");switch(i.type){case"stdio":if(!i.command)throw new Error("stdio \u7C7B\u578B\u9700\u8981 command \u5B57\u6BB5");break;case"sse":case"streamable-http":if(!i.url)throw new Error(`${i.type} \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5`);break;case"modelscope-sse":if(!i.url)throw new Error("modelscope-sse \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5");if(!i.apiKey)throw new Error("modelscope-sse \u7C7B\u578B\u9700\u8981 apiKey \u5B57\u6BB5\u3002\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E modelscope.apiKey \u6216\u786E\u4FDD\u670D\u52A1\u914D\u7F6E\u5305\u542B apiKey");break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`)}}function pr(){return["stdio","sse","modelscope-sse","streamable-http"]}var gt,Yt=h(()=>{"use strict";R();Le();typeof global<"u"&&!global.EventSource&&(global.EventSource=tr);a(nr,"getLogger");a(rr,"createTransport");a(or,"createStdioTransport");a(ir,"createSSETransport");a(sr,"createModelScopeSSETransport");a(ar,"createStreamableHTTPTransport");a(cr,"createSSEOptions");a(lr,"createModelScopeSSEOptions");a(gr,"createStreamableHTTPOptions");a(hr,"validateConfig");a(pr,"getSupportedTypes");gt={create:rr,validateConfig:hr,getSupportedTypes:pr}});import{Client as mr}from"@modelcontextprotocol/sdk/client/index.js";var Te,Ue,Le=h(()=>{"use strict";R();Yt();Te=(r=>(r.STDIO="stdio",r.SSE="sse",r.STREAMABLE_HTTP="streamable-http",r.MODELSCOPE_SSE="modelscope-sse",r))(Te||{}),Ue=class{static{a(this,"MCPService")}config;client=null;transport=null;tools=new Map;connectionState="disconnected";reconnectOptions;reconnectState;logger;connectionTimeout=null;initialized=!1;pingOptions;pingTimer=null;pingFailureCount=0;lastPingTime=null;isPinging=!1;constructor(e,t){this.config=e,this.logger=f,this.validateConfig(),this.reconnectOptions={enabled:!0,maxAttempts:10,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0,...t?.reconnect,...e.reconnect},this.pingOptions={enabled:!0,interval:3e4,timeout:5e3,maxFailures:3,startDelay:5e3,...e.ping},this.reconnectState={attempts:0,nextInterval:this.reconnectOptions.initialInterval,timer:null,lastError:null,isManualDisconnect:!1}}logWithTag(e,t,...n){let r=`[MCP-${this.config.name}] ${t}`;this.logger[e](r,...n)}validateConfig(){gt.validateConfig(this.config)}async connect(){if(this.connectionState==="connecting")throw new Error("\u8FDE\u63A5\u6B63\u5728\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u8FDE\u63A5\u5B8C\u6210");return this.cleanupConnection(),this.reconnectState.isManualDisconnect=!1,this.attemptConnection()}async attemptConnection(){return this.connectionState="connecting",this.logWithTag("info",`\u6B63\u5728\u8FDE\u63A5 MCP \u670D\u52A1: ${this.config.name} (\u5C1D\u8BD5 ${this.reconnectState.attempts+1}/${this.reconnectOptions.maxAttempts})`),new Promise((e,t)=>{this.connectionTimeout=setTimeout(()=>{let n=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(n),t(n)},this.reconnectOptions.timeout);try{this.client=new mr({name:`xiaozhi-${this.config.name}-client`,version:"1.0.0"},{capabilities:{tools:{}}}),this.transport=gt.create(this.config),this.client.connect(this.transport).then(async()=>{this.handleConnectionSuccess(),await this.refreshTools(),e()}).catch(n=>{this.handleConnectionError(n),t(n)})}catch(n){this.handleConnectionError(n),t(n)}})}handleConnectionSuccess(){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.connectionState="connected",this.initialized=!0,this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.resetPingState(),this.logWithTag("info",`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u5DF2\u5EFA\u7ACB`),this.startPingMonitoring()}handleConnectionError(e){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.reconnectState.lastError=e,this.logger.error(`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u9519\u8BEF:`,e.message),this.cleanupConnection(),this.shouldReconnect()?this.scheduleReconnect():(this.connectionState="failed",this.logger.warn(`${this.config.name} \u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 (${this.reconnectOptions.maxAttempts})\uFF0C\u505C\u6B62\u91CD\u8FDE`))}shouldReconnect(){return this.reconnectOptions.enabled&&this.reconnectState.attempts<this.reconnectOptions.maxAttempts&&!this.reconnectState.isManualDisconnect}scheduleReconnect(){this.connectionState="reconnecting",this.reconnectState.attempts++,this.calculateNextInterval(),this.logger.info(`${this.config.name} \u5C06\u5728 ${this.reconnectState.nextInterval}ms \u540E\u8FDB\u884C\u7B2C ${this.reconnectState.attempts} \u6B21\u91CD\u8FDE`),this.reconnectState.timer&&clearTimeout(this.reconnectState.timer),this.reconnectState.timer=setTimeout(async()=>{try{await this.attemptConnection()}catch{}},this.reconnectState.nextInterval)}calculateNextInterval(){let e;switch(this.reconnectOptions.backoffStrategy){case"fixed":e=this.reconnectOptions.initialInterval;break;case"linear":e=this.reconnectOptions.initialInterval+this.reconnectState.attempts*this.reconnectOptions.backoffMultiplier*1e3;break;case"exponential":e=this.reconnectOptions.initialInterval*this.reconnectOptions.backoffMultiplier**(this.reconnectState.attempts-1);break;default:e=this.reconnectOptions.initialInterval}if(e=Math.min(e,this.reconnectOptions.maxInterval),this.reconnectOptions.jitter){let t=e*.1,n=(Math.random()-.5)*2*t;e+=n}this.reconnectState.nextInterval=Math.max(e,1e3)}cleanupConnection(){if(this.stopPingMonitoring(),this.client){try{this.client.close().catch(()=>{})}catch{}this.client=null}this.transport=null,this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.initialized=!1}stopReconnect(){this.reconnectState.timer&&(clearTimeout(this.reconnectState.timer),this.reconnectState.timer=null)}async refreshTools(){if(!this.client)throw new Error("\u5BA2\u6237\u7AEF\u672A\u521D\u59CB\u5316");try{let t=(await this.client.listTools()).tools||[];this.tools.clear();for(let n of t)this.tools.set(n.name,n);this.logger.info(`${this.config.name} \u670D\u52A1\u52A0\u8F7D\u4E86 ${t.length} \u4E2A\u5DE5\u5177: ${t.map(n=>n.name).join(", ")}`)}catch(e){throw this.logger.error(`${this.config.name} \u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25:`,e instanceof Error?e.message:String(e)),e}}async disconnect(){this.logger.info(`\u4E3B\u52A8\u65AD\u5F00 MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5`),this.reconnectState.isManualDisconnect=!0,this.stopPingMonitoring(),this.stopReconnect(),this.cleanupConnection(),this.connectionState="disconnected"}async reconnect(){this.logger.info(`\u624B\u52A8\u91CD\u8FDE MCP \u670D\u52A1 ${this.config.name}`),this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.isManualDisconnect=!1,this.cleanupConnection(),await this.connect()}getTools(){return Array.from(this.tools.values())}async callTool(e,t){if(!this.client)throw new Error(`\u670D\u52A1 ${this.config.name} \u672A\u8FDE\u63A5`);if(!this.tools.has(e))throw new Error(`\u5DE5\u5177 ${e} \u5728\u670D\u52A1 ${this.config.name} \u4E2D\u4E0D\u5B58\u5728`);this.logger.info(`\u8C03\u7528 ${this.config.name} \u670D\u52A1\u7684\u5DE5\u5177 ${e}\uFF0C\u53C2\u6570:`,JSON.stringify(t));try{let n=await this.client.callTool({name:e,arguments:t||{}});return this.logger.info(`\u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,`${JSON.stringify(n).substring(0,500)}...`),n}catch(n){throw this.logger.error(`\u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,n instanceof Error?n.message:String(n)),n}}getConfig(){return this.config}getStatus(){return{name:this.config.name,connected:this.connectionState==="connected",initialized:this.initialized,transportType:this.config.type,toolCount:this.tools.size,lastError:this.reconnectState.lastError?.message,reconnectAttempts:this.reconnectState.attempts,connectionState:this.connectionState,pingEnabled:this.pingOptions.enabled,lastPingTime:this.lastPingTime||void 0,pingFailureCount:this.pingFailureCount,isPinging:this.isPinging}}isConnected(){return this.connectionState==="connected"&&this.initialized}enableReconnect(){this.reconnectOptions.enabled=!0,this.logger.info(`${this.config.name} \u81EA\u52A8\u91CD\u8FDE\u5DF2\u542F\u7528`)}disableReconnect(){this.reconnectOptions.enabled=!1,this.stopReconnect(),this.logger.info(`${this.config.name} \u81EA\u52A8\u91CD\u8FDE\u5DF2\u7981\u7528`)}updateReconnectOptions(e){this.reconnectOptions={...this.reconnectOptions,...e},this.logger.info(`${this.config.name} \u91CD\u8FDE\u914D\u7F6E\u5DF2\u66F4\u65B0`,e)}getReconnectOptions(){return{...this.reconnectOptions}}resetReconnectState(){this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info(`${this.config.name} \u91CD\u8FDE\u72B6\u6001\u5DF2\u91CD\u7F6E`)}startPingMonitoring(){!this.pingOptions.enabled||this.pingTimer||!this.isConnected()||(this.logger.info(`${this.config.name} \u542F\u52A8ping\u76D1\u63A7\uFF0C\u95F4\u9694: ${this.pingOptions.interval}ms`),setTimeout(()=>{this.isConnected()&&!this.pingTimer&&(this.pingTimer=setInterval(()=>{this.performPing()},this.pingOptions.interval))},this.pingOptions.startDelay))}stopPingMonitoring(){this.pingTimer&&(clearInterval(this.pingTimer),this.pingTimer=null,this.logger.debug(`${this.config.name} \u505C\u6B62ping\u76D1\u63A7`))}async performPing(){if(!this.client||this.isPinging||!this.isConnected())return;this.isPinging=!0;let e=performance.now();try{this.logger.debug(`${this.config.name} \u53D1\u9001ping\u8BF7\u6C42\uFF08\u901A\u8FC7listTools\u68C0\u6D4B\u8FDE\u63A5\uFF09`);let t=this.client.listTools(),n=new Promise((o,s)=>{setTimeout(()=>{s(new Error(`Ping\u8D85\u65F6 (${this.pingOptions.timeout}ms)`))},this.pingOptions.timeout)});await Promise.race([t,n]);let r=performance.now()-e;this.handlePingSuccess(r)}catch(t){let n=performance.now()-e;this.handlePingFailure(t,n)}finally{this.isPinging=!1}}handlePingSuccess(e){this.pingFailureCount=0,this.lastPingTime=new Date,this.logger.debug(`${this.config.name} ping\u6210\u529F\uFF0C\u5EF6\u8FDF: ${e.toFixed(2)}ms`)}handlePingFailure(e,t){if(this.pingFailureCount++,this.logger.warn(`${this.config.name} ping\u5931\u8D25 (${this.pingFailureCount}/${this.pingOptions.maxFailures})\uFF0C\u5EF6\u8FDF: ${t.toFixed(2)}ms\uFF0C\u9519\u8BEF: ${e.message}`),this.pingFailureCount>=this.pingOptions.maxFailures){this.logger.error(`${this.config.name} \u8FDE\u7EEDping\u5931\u8D25\u8FBE\u5230\u9608\u503C\uFF0C\u89E6\u53D1\u91CD\u8FDE\u673A\u5236`),this.stopPingMonitoring();let n=new Error(`Ping\u68C0\u6D4B\u5931\u8D25\uFF0C\u8FDE\u7EED\u5931\u8D25${this.pingFailureCount}\u6B21\uFF0C\u8FDE\u63A5\u53EF\u80FD\u5DF2\u65AD\u5F00`);this.handleConnectionError(n)}}resetPingState(){this.pingFailureCount=0,this.lastPingTime=null,this.isPinging=!1}enablePing(){this.pingOptions.enabled=!0,this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u542F\u7528`),this.isConnected()&&this.startPingMonitoring()}disablePing(){this.pingOptions.enabled=!1,this.stopPingMonitoring(),this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u7981\u7528`)}updatePingOptions(e){let t=this.pingOptions.enabled;this.pingOptions={...this.pingOptions,...e},this.logger.info(`${this.config.name} ping\u914D\u7F6E\u5DF2\u66F4\u65B0`,e),t!==this.pingOptions.enabled&&(this.pingOptions.enabled&&this.isConnected()?this.startPingMonitoring():this.pingOptions.enabled||this.stopPingMonitoring())}getPingOptions(){return{...this.pingOptions}}}});var Ie,en,ht=h(()=>{"use strict";R();ae();Le();Ie=class{static{a(this,"MCPServiceManager")}services=new Map;configs={};logger;tools=new Map;constructor(e){this.logger=f,this.configs=e||{}}async startAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u542F\u52A8\u6240\u6709 MCP \u670D\u52A1...");let e=Object.entries(this.configs);if(e.length===0){this.logger.warn("[MCPManager] \u6CA1\u6709\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1\uFF0C\u8BF7\u4F7F\u7528 addServiceConfig() \u6DFB\u52A0\u670D\u52A1\u914D\u7F6E");return}for(let[t]of e)await this.startService(t);this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u542F\u52A8\u5B8C\u6210")}async startService(e){this.logger.info(`[MCPManager] \u542F\u52A8 MCP \u670D\u52A1: ${e}`);let t=this.configs[e];if(!t)throw new Error(`\u672A\u627E\u5230\u670D\u52A1\u914D\u7F6E: ${e}`);try{this.services.has(e)&&await this.stopService(e);let n=new Ue(t);await n.connect(),this.services.set(e,n),await this.refreshToolsCache();let r=n.getTools();this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u542F\u52A8\u6210\u529F\uFF0C\u52A0\u8F7D\u4E86 ${r.length} \u4E2A\u5DE5\u5177:`,r.map(o=>o.name).join(", "))}catch(n){throw this.logger.error(`[MCPManager] \u542F\u52A8 ${e} \u670D\u52A1\u5931\u8D25:`,n.message),n}}async stopService(e){this.logger.info(`[MCPManager] \u505C\u6B62 MCP \u670D\u52A1: ${e}`);let t=this.services.get(e);if(!t){this.logger.warn(`[MCPManager] \u670D\u52A1 ${e} \u4E0D\u5B58\u5728\u6216\u672A\u542F\u52A8`);return}try{await t.disconnect(),this.services.delete(e),await this.refreshToolsCache(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(n){throw this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,n.message),n}}async refreshToolsCache(){this.tools.clear();for(let[e,t]of this.services)if(t.isConnected()){let n=t.getTools();for(let r of n){let o=`${e}__${r.name}`;this.tools.set(o,{serviceName:e,originalName:r.name,tool:r})}}}getAllTools(){let e=[];for(let[t,n]of this.tools)e.push({name:t,description:n.tool.description||"",inputSchema:n.tool.inputSchema,serviceName:n.serviceName,originalName:n.originalName});return e}async callTool(e,t){this.logger.info(`[MCPManager] \u8C03\u7528\u5DE5\u5177: ${e}\uFF0C\u53C2\u6570:`,t);let n=this.tools.get(e);if(!n)throw new Error(`\u672A\u627E\u5230\u5DE5\u5177: ${e}`);let r=this.services.get(n.serviceName);if(!r)throw new Error(`\u670D\u52A1 ${n.serviceName} \u4E0D\u53EF\u7528`);if(!r.isConnected())throw new Error(`\u670D\u52A1 ${n.serviceName} \u672A\u8FDE\u63A5`);try{let o=await r.callTool(n.originalName,t||{});return this.logger.info(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,o),o}catch(o){throw this.logger.error(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,o.message),o}}async stopAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u505C\u6B62\u6240\u6709 MCP \u670D\u52A1...");for(let[e,t]of this.services)try{await t.disconnect(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(n){this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,n.message)}this.services.clear(),this.tools.clear(),this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u5DF2\u505C\u6B62")}getStatus(){let e={services:{},totalTools:this.tools.size,availableTools:Array.from(this.tools.keys())};for(let[t,n]of this.services){let r=n.getStatus();e.services[t]={connected:r.connected,clientName:`xiaozhi-${t}-client`}}return e}getService(e){return this.services.get(e)}getAllServices(){return new Map(this.services)}enhanceServiceConfig(e){let t={...e};try{if(e.type==="modelscope-sse"){let n=m.getModelScopeApiKey();if(n)t.apiKey=n,this.logger.info(`[MCPManager] \u4E3A ${e.name} \u670D\u52A1\u6DFB\u52A0 ModelScope API Key`);else throw this.logger.warn(`[MCPManager] ${e.name} \u670D\u52A1\u9700\u8981 ModelScope API Key\uFF0C\u4F46\u672A\u5728\u914D\u7F6E\u4E2D\u627E\u5230`),new Error(`ModelScope SSE \u670D\u52A1 ${e.name} \u9700\u8981 API Key\uFF0C\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E modelscope.apiKey`)}return t}catch(n){throw this.logger.error(`[MCPManager] \u914D\u7F6E\u589E\u5F3A\u5931\u8D25: ${e.name}`,n),n}}addServiceConfig(e,t){let n,r;if(typeof e=="string"&&t)r=e,n=t;else if(typeof e=="object")r=e.name,n=e;else throw new Error("Invalid arguments for addServiceConfig");let o=this.enhanceServiceConfig(n);this.configs[r]=o,this.logger.info(`[MCPManager] \u5DF2\u6DFB\u52A0\u670D\u52A1\u914D\u7F6E: ${r}`)}updateServiceConfig(e,t){let n=this.enhanceServiceConfig(t);this.configs[e]=n,this.logger.info(`[MCPManager] \u5DF2\u66F4\u65B0\u5E76\u589E\u5F3A\u670D\u52A1\u914D\u7F6E: ${e}`)}removeServiceConfig(e){delete this.configs[e],this.logger.info(`[MCPManager] \u5DF2\u79FB\u9664\u670D\u52A1\u914D\u7F6E: ${e}`)}},en=Ie});var _e,tn=h(()=>{"use strict";R();_e=class{static{a(this,"MCPMessageHandler")}logger;serviceManager;constructor(e){this.serviceManager=e,this.logger=f}async handleMessage(e){this.logger.debug(`\u5904\u7406 MCP \u6D88\u606F: ${e.method}`,e);try{switch(e.method){case"initialize":return await this.handleInitialize(e.params,e.id);case"tools/list":return await this.handleToolsList(e.id);case"tools/call":return await this.handleToolCall(e.params,e.id);case"ping":return await this.handlePing(e.id);default:throw new Error(`\u672A\u77E5\u7684\u65B9\u6CD5: ${e.method}`)}}catch(t){return this.logger.error(`\u5904\u7406\u6D88\u606F\u65F6\u51FA\u9519: ${e.method}`,t),this.createErrorResponse(t,e.id)}}async handleInitialize(e,t){return this.logger.info("\u5904\u7406 initialize \u8BF7\u6C42",e),{jsonrpc:"2.0",result:{serverInfo:{name:"xiaozhi-mcp-server",version:"1.0.0"},capabilities:{tools:{},logging:{}},protocolVersion:"2024-11-05"},id:t||null}}async handleToolsList(e){this.logger.info("\u5904\u7406 tools/list \u8BF7\u6C42");try{let n=this.serviceManager.getAllTools().map(r=>({name:r.name,description:r.description,inputSchema:r.inputSchema}));return this.logger.info(`\u8FD4\u56DE ${n.length} \u4E2A\u5DE5\u5177`),{jsonrpc:"2.0",result:{tools:n},id:e||null}}catch(t){throw this.logger.error("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25",t),t}}async handleToolCall(e,t){this.logger.info(`\u5904\u7406 tools/call \u8BF7\u6C42: ${e.name}`,e);try{if(!e.name)throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");let n=await this.serviceManager.callTool(e.name,e.arguments||{});return this.logger.info(`\u5DE5\u5177 ${e.name} \u8C03\u7528\u6210\u529F`),{jsonrpc:"2.0",result:{content:n.content,isError:n.isError||!1},id:t||null}}catch(n){throw this.logger.error(`\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,n),n}}async handlePing(e){return this.logger.debug("\u5904\u7406 ping \u8BF7\u6C42"),{jsonrpc:"2.0",result:{status:"ok",timestamp:new Date().toISOString()},id:e||null}}createErrorResponse(e,t){let n=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?n=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(n=-32602),{jsonrpc:"2.0",error:{code:n,message:e.message,data:{stack:e.stack}},id:t||null}}getServiceManager(){return this.serviceManager}}});import{EventEmitter as nn}from"events";var pt,mt,We,rn=h(()=>{"use strict";R();ht();Pe();tn();pt=class{static{a(this,"ToolRegistry")}serviceManager;logger;constructor(e){this.serviceManager=e,this.logger=f}async initialize(){this.logger.info("\u521D\u59CB\u5316\u5DE5\u5177\u6CE8\u518C\u8868")}getAllTools(){return this.serviceManager.getAllTools().map(e=>({name:e.name,description:e.description,inputSchema:e.inputSchema,serviceName:e.serviceName,originalName:e.originalName}))}findTool(e){return this.getAllTools().find(n=>n.name===e)||null}hasTool(e){return this.findTool(e)!==null}},mt=class extends nn{static{a(this,"ConnectionManager")}connections=new Map;logger;constructor(){super(),this.logger=f}async initialize(){this.logger.info("\u521D\u59CB\u5316\u8FDE\u63A5\u7BA1\u7406\u5668")}registerConnection(e,t,n){let r={id:e,transportName:t,state:n,connectedAt:new Date,lastActivity:new Date};this.connections.set(e,r),this.emit("connectionRegistered",r),this.logger.debug(`\u8FDE\u63A5\u5DF2\u6CE8\u518C: ${e} (${t})`)}updateConnectionState(e,t){let n=this.connections.get(e);n&&(n.state=t,n.lastActivity=new Date,this.emit("connectionStateChanged",n),this.logger.debug(`\u8FDE\u63A5\u72B6\u6001\u66F4\u65B0: ${e} -> ${t}`))}removeConnection(e){let t=this.connections.get(e);t&&(this.connections.delete(e),this.emit("connectionRemoved",t),this.logger.debug(`\u8FDE\u63A5\u5DF2\u79FB\u9664: ${e}`))}getAllConnections(){return Array.from(this.connections.values())}getActiveConnectionCount(){return Array.from(this.connections.values()).filter(e=>e.state==="connected").length}async closeAllConnections(){this.logger.info("\u5173\u95ED\u6240\u6709\u8FDE\u63A5"),this.connections.clear(),this.emit("allConnectionsClosed")}},We=class extends nn{static{a(this,"UnifiedMCPServer")}serviceManager;messageHandler;transportAdapters=new Map;toolRegistry;connectionManager;isRunning=!1;logger;config;constructor(e={}){super(),this.config={name:"UnifiedMCPServer",enableLogging:!0,logLevel:"info",maxConnections:100,connectionTimeout:3e4,...e},this.logger=f,this.serviceManager=new Ie,this.messageHandler=new _e(this.serviceManager),this.toolRegistry=new pt(this.serviceManager),this.connectionManager=new mt,this.setupEventListeners()}setupEventListeners(){this.connectionManager.on("connectionRegistered",e=>{this.emit("connectionRegistered",e)}),this.connectionManager.on("connectionStateChanged",e=>{this.emit("connectionStateChanged",e)}),this.connectionManager.on("connectionRemoved",e=>{this.emit("connectionRemoved",e)})}async initialize(){this.logger.info("\u521D\u59CB\u5316\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{await this.serviceManager.startAllServices(),await this.toolRegistry.initialize(),await this.connectionManager.initialize(),this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210"),this.emit("initialized")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5931\u8D25",e),e}}async registerTransport(e,t){if(this.transportAdapters.has(e))throw new Error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5DF2\u5B58\u5728`);this.logger.info(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668: ${e}`);try{await t.initialize(),this.transportAdapters.set(e,t),this.connectionManager.registerConnection(t.getConnectionId(),e,t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u6CE8\u518C\u6210\u529F`),this.emit("transportRegistered",{name:e,adapter:t})}catch(n){throw this.logger.error(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5931\u8D25`,n),n}}async start(){if(this.isRunning)throw new Error("\u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C");this.logger.info("\u542F\u52A8\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{for(let[e,t]of this.transportAdapters)try{await t.start(),this.connectionManager.updateConnectionState(t.getConnectionId(),t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u542F\u52A8\u6210\u529F`)}catch(n){throw this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u542F\u52A8\u5931\u8D25`,n),n}this.isRunning=!0,this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u542F\u52A8\u6210\u529F"),this.emit("started")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25",e),e}}async stop(){if(this.isRunning){this.logger.info("\u505C\u6B62\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{for(let[e,t]of this.transportAdapters)try{await t.stop(),this.connectionManager.updateConnectionState(t.getConnectionId(),t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u6210\u529F`)}catch(n){this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u5931\u8D25`,n)}await this.connectionManager.closeAllConnections(),await this.serviceManager.stopAllServices(),this.isRunning=!1,this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u505C\u6B62\u6210\u529F"),this.emit("stopped")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u505C\u6B62\u5931\u8D25",e),e}}}getServiceManager(){return this.serviceManager}getToolRegistry(){return this.toolRegistry}getConnectionManager(){return this.connectionManager}getMessageHandler(){return this.messageHandler}getStatus(){return{isRunning:this.isRunning,transportCount:this.transportAdapters.size,activeConnections:this.connectionManager.getActiveConnectionCount(),toolCount:this.toolRegistry.getAllTools().length,config:this.config}}getTransportAdapters(){return new Map(this.transportAdapters)}isServerRunning(){return this.isRunning}}});async function on(i={name:"http"}){f.info("\u521B\u5EFA HTTP \u6A21\u5F0F\u670D\u52A1\u5668");let e=new We;await e.initialize();let t=e.getMessageHandler(),n=new He(t,i);return await e.registerTransport("http",n),f.info("HTTP \u6A21\u5F0F\u670D\u52A1\u5668\u521B\u5EFA\u6210\u529F"),e}var sn=h(()=>{"use strict";R();Jt();qt();Zt();rn();a(on,"createHTTPServer")});var an={};k(an,{MCPServer:()=>dt});import{EventEmitter as dr}from"events";var T,dt,cn=h(()=>{"use strict";R();je();ae();sn();T=new ye,dt=class extends dr{static{a(this,"MCPServer")}unifiedServer=null;proxyMCPServer=null;port;isStarted=!1;constructor(e=3e3){super(),this.port=e}async initializeUnifiedServer(){if(!this.unifiedServer){T.info("\u521D\u59CB\u5316\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{let e={name:"http",port:this.port,host:"0.0.0.0",enableSSE:!0,enableRPC:!0};this.unifiedServer=await on(e),this.unifiedServer.on("started",()=>this.emit("started")),this.unifiedServer.on("stopped",()=>this.emit("stopped")),this.unifiedServer.on("connectionRegistered",t=>{this.emit("connectionRegistered",t)}),T.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw T.error("\u521D\u59CB\u5316\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u5931\u8D25",e),e}}}async initializeMCPClient(){try{let e=null;try{m.configExists()&&(e=m.getMcpEndpoints().find(n=>n&&!n.includes("<\u8BF7\u586B\u5199"))||null)}catch(t){T.warn("\u4ECE\u914D\u7F6E\u4E2D\u8BFB\u53D6\u5C0F\u667A\u63A5\u5165\u70B9\u5931\u8D25:",t)}e?(this.proxyMCPServer=new Y(e),this.unifiedServer&&this.proxyMCPServer.setServiceManager(this.unifiedServer.getServiceManager()),await this.proxyMCPServer.connect(),T.info("\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u6210\u529F")):T.info("\u672A\u914D\u7F6E\u6709\u6548\u7684\u5C0F\u667A\u63A5\u5165\u70B9\uFF0C\u8DF3\u8FC7\u8FDE\u63A5")}catch(e){T.error("\u521D\u59CB\u5316\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u5931\u8D25:",e)}}async start(){if(this.isStarted){T.warn("\u670D\u52A1\u5668\u5DF2\u542F\u52A8");return}try{T.info("\u542F\u52A8 MCP \u670D\u52A1\u5668"),await this.initializeUnifiedServer(),this.unifiedServer&&await this.unifiedServer.start(),this.initializeMCPClient().catch(e=>{T.error("\u521D\u59CB\u5316\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u5931\u8D25:",e)}),this.isStarted=!0,this.emit("started"),T.info("MCP \u670D\u52A1\u5668\u542F\u52A8\u6210\u529F")}catch(e){throw T.error("\u542F\u52A8 MCP \u670D\u52A1\u5668\u5931\u8D25:",e),e}}async stop(){if(!this.isStarted){T.warn("\u670D\u52A1\u5668\u672A\u542F\u52A8");return}try{T.info("\u505C\u6B62 MCP \u670D\u52A1\u5668"),this.unifiedServer&&await this.unifiedServer.stop(),this.proxyMCPServer&&(this.proxyMCPServer.disconnect(),this.proxyMCPServer=null),this.isStarted=!1,this.emit("stopped"),T.info("MCP \u670D\u52A1\u5668\u5DF2\u505C\u6B62")}catch(e){throw T.error("\u505C\u6B62 MCP \u670D\u52A1\u5668\u5931\u8D25:",e),e}}getServiceManager(){return this.unifiedServer?.getServiceManager()||null}getMessageHandler(){return this.unifiedServer?.getMessageHandler()||null}getStatus(){return this.unifiedServer?{...this.unifiedServer.getStatus(),port:this.port,mode:"mcp-server",proxyConnected:this.proxyMCPServer!==null}:{isRunning:!1,port:this.port,mode:"mcp-server"}}isRunning(){return this.isStarted&&(this.unifiedServer?.isServerRunning()||!1)}}});function ln(i,e){ut.debug(`\u8F6C\u6362\u914D\u7F6E: ${i}`,e);try{if(!i||typeof i!="string")throw new O("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!e||typeof e!="object")throw new O("\u914D\u7F6E\u5BF9\u8C61\u4E0D\u80FD\u4E3A\u7A7A",i);let t=ur(i,e);return br(t),ut.info(`\u914D\u7F6E\u8F6C\u6362\u6210\u529F: ${i} -> ${t.type}`),t}catch(t){throw ut.error(`\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${i}`,t),t instanceof O?t:new O(`\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`,i)}}function ur(i,e){if(Sr(e))return fr(i,e);if(yr(e))return vr(i,e);if(wr(e))return Cr(i,e);throw new O("\u65E0\u6CD5\u8BC6\u522B\u7684\u914D\u7F6E\u7C7B\u578B",i)}function fr(i,e){if(!e.command)throw new O("\u672C\u5730\u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5",i);return{name:i,type:"stdio",command:e.command,args:e.args||[],reconnect:{enabled:!0,maxAttempts:5,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0},ping:{enabled:!0,interval:3e4,timeout:5e3,maxFailures:3,startDelay:5e3},timeout:3e4}}function vr(i,e){if(!e.url)throw new O("SSE \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5",i);let t=Mr(e.url),n={name:i,type:t?"modelscope-sse":"sse",url:e.url,reconnect:{enabled:!0,maxAttempts:10,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:15e3,jitter:!0},ping:{enabled:!0,interval:3e4,timeout:5e3,maxFailures:3,startDelay:5e3},timeout:3e4};return t&&(n.modelScopeAuth=!0),n}function Cr(i,e){if(!e.url)throw new O("Streamable HTTP \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5",i);return{name:i,type:"streamable-http",url:e.url,reconnect:{enabled:!0,maxAttempts:5,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:15e3,jitter:!0},ping:{enabled:!1,interval:6e4,timeout:1e4,maxFailures:3,startDelay:1e4},timeout:3e4}}function Sr(i){return"command"in i&&typeof i.command=="string"}function yr(i){return"type"in i&&i.type==="sse"&&"url"in i}function wr(i){return"url"in i&&(!("type"in i)||i.type==="streamable-http")}function Mr(i){return i.includes("modelscope.net")||i.includes("modelscope.cn")}function br(i){if(!i.name||typeof i.name!="string")throw new O("\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 name \u5B57\u6BB5");if(!Object.values(Te).includes(i.type))throw new O(`\u65E0\u6548\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`);switch(i.type){case"stdio":if(!i.command)throw new O("STDIO \u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5");break;case"sse":case"modelscope-sse":case"streamable-http":if(!i.url)throw new O(`${i.type} \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5`);break;default:throw new O(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`)}}var ut,O,gn=h(()=>{"use strict";R();Le();ut=f.withTag("ConfigAdapter"),O=class extends Error{constructor(t,n){super(t);this.configName=n;this.name="ConfigValidationError"}static{a(this,"ConfigValidationError")}};a(ln,"convertLegacyToNew");a(ur,"convertByConfigType");a(fr,"convertLocalConfig");a(vr,"convertSSEConfig");a(Cr,"convertStreamableHTTPConfig");a(Sr,"isLocalConfig");a(yr,"isSSEConfig");a(wr,"isStreamableHTTPConfig");a(Mr,"isModelScopeURL");a(br,"validateNewConfig")});async function Er(){return console.log("\u{1F680} \u6B63\u5728\u521D\u59CB\u5316 MCPServiceManager \u5355\u4F8B..."),new en}async function hn(){if(K&&D==="initialized")return K;if(_&&D==="initializing")return _;D==="failed"&&ft(),D="initializing",_=Er();try{return K=await _,D="initialized",pe=`mcp-manager-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,Re=null,console.log(`\u2705 MCPServiceManager \u5355\u4F8B\u521D\u59CB\u5316\u6210\u529F\uFF0C\u5B9E\u4F8BID: ${pe}`),K}catch(i){throw D="failed",Re=i,_=null,console.error("\u274C MCPServiceManager \u5355\u4F8B\u521D\u59CB\u5316\u5931\u8D25:",i.message),i}}async function pn(){if(D==="cleanup"){console.log("\u26A0\uFE0F MCPServiceManager \u5355\u4F8B\u5DF2\u5728\u6E05\u7406\u4E2D\uFF0C\u8DF3\u8FC7\u91CD\u590D\u6E05\u7406");return}console.log("\u{1F9F9} \u6B63\u5728\u6E05\u7406 MCPServiceManager \u5355\u4F8B\u8D44\u6E90..."),D="cleanup";try{if(_){try{await(await _).stopAllServices()}catch(i){console.error("\u6E05\u7406\u521D\u59CB\u5316\u4E2D\u7684\u5B9E\u4F8B\u5931\u8D25:",i.message)}_=null}K&&(await K.stopAllServices(),K=null),D="not_initialized",Re=null,pe=null,console.log("\u2705 MCPServiceManager \u5355\u4F8B\u8D44\u6E90\u6E05\u7406\u5B8C\u6210")}catch(i){throw console.error("\u274C MCPServiceManager \u5355\u4F8B\u6E05\u7406\u5931\u8D25:",i.message),ft(),i}}function ft(){console.log("\u{1F504} \u91CD\u7F6E MCPServiceManager \u5355\u4F8B\u72B6\u6001"),K=null,_=null,D="not_initialized",Re=null,pe=null}function Pr(){return D==="initialized"&&K!==null}function Tr(){return{state:D,initializationTime:pe?new Date:void 0,lastError:Re||void 0,instanceId:pe||void 0}}async function Ir(){return console.log("\u{1F504} \u5F3A\u5236\u91CD\u65B0\u521D\u59CB\u5316 MCPServiceManager \u5355\u4F8B..."),await pn(),hn()}function Rr(){return K}async function xr(){if(D==="initialized")return!0;if(D==="initializing"&&_)try{return await _,!0}catch{return!1}return!1}var K,_,D,Re,pe,me,mn=h(()=>{"use strict";ht();K=null,_=null,D="not_initialized",Re=null,pe=null;a(Er,"createInstance");a(hn,"getInstance");a(pn,"cleanup");a(ft,"reset");a(Pr,"isInitialized");a(Tr,"getStatus");a(Ir,"forceReinitialize");a(Rr,"getCurrentInstance");a(xr,"waitForInitialization");me={getInstance:hn,cleanup:pn,reset:ft,isInitialized:Pr,getStatus:Tr,forceReinitialize:Ir,getCurrentInstance:Rr,waitForInitialization:xr};process.on("exit",()=>{me.isInitialized()&&(console.log("\u{1F504} \u8FDB\u7A0B\u9000\u51FA\uFF0C\u6B63\u5728\u6E05\u7406 MCPServiceManager \u5355\u4F8B..."),me.reset())});process.on("uncaughtException",async i=>{console.error("\u{1F4A5} \u672A\u6355\u83B7\u7684\u5F02\u5E38\uFF0C\u6E05\u7406 MCPServiceManager \u5355\u4F8B:",i);try{await me.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}});process.on("unhandledRejection",async i=>{console.error("\u{1F4A5} \u672A\u5904\u7406\u7684Promise\u62D2\u7EDD\uFF0C\u6E05\u7406 MCPServiceManager \u5355\u4F8B:",i);try{await me.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}})});import{EventEmitter as Or}from"events";var dn,$r,Be,un=h(()=>{"use strict";R();je();dn=(r=>(r.EXPONENTIAL_BACKOFF="exponential_backoff",r.LINEAR_BACKOFF="linear_backoff",r.FIXED_INTERVAL="fixed_interval",r.ADAPTIVE="adaptive",r))(dn||{}),$r={healthCheckInterval:3e4,reconnectInterval:5e3,maxReconnectAttempts:10,loadBalanceStrategy:"round-robin",connectionTimeout:1e4,reconnectStrategy:"exponential_backoff",maxReconnectDelay:3e4,reconnectBackoffMultiplier:2,jitterEnabled:!0},Be=class extends Or{static{a(this,"XiaozhiConnectionManager")}connections=new Map;connectionStates=new Map;mcpServiceManager=null;logger;isInitialized=!1;isConnecting=!1;options;healthCheckInterval=null;reconnectTimers=new Map;roundRobinIndex=0;lastSelectedEndpoint=null;performanceMetrics={connectionStartTime:0,totalConnectionTime:0,averageConnectionTime:0,connectionCount:0,memoryUsage:{initial:0,current:0,peak:0},prewarmedConnections:new Set};constructor(e){super(),this.logger=f,this.options={...$r,...e},this.logger.info("[XiaozhiConnectionManager] \u5B9E\u4F8B\u5DF2\u521B\u5EFA"),this.logger.debug("[XiaozhiConnectionManager] \u914D\u7F6E\u9009\u9879:",this.options)}async initialize(e,t){if(this.isInitialized){this.logger.warn("XiaozhiConnectionManager \u5DF2\u7ECF\u521D\u59CB\u5316\uFF0C\u8DF3\u8FC7\u91CD\u590D\u521D\u59CB\u5316");return}this.logger.info(`\u5F00\u59CB\u521D\u59CB\u5316 XiaozhiConnectionManager\uFF0C\u7AEF\u70B9\u6570\u91CF: ${e.length}`);try{this.validateInitializeParams(e,t),await this.cleanup();for(let n of e)await this.createConnection(n,t);this.isInitialized=!0,this.performanceMetrics.memoryUsage.initial=process.memoryUsage().heapUsed,this.performanceMetrics.memoryUsage.current=this.performanceMetrics.memoryUsage.initial,this.performanceMetrics.memoryUsage.peak=this.performanceMetrics.memoryUsage.initial,this.logger.info(`XiaozhiConnectionManager \u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u7BA1\u7406 ${this.connections.size} \u4E2A\u8FDE\u63A5`)}catch(n){throw this.logger.error("XiaozhiConnectionManager \u521D\u59CB\u5316\u5931\u8D25:",n),await this.cleanup(),n}}async connect(){if(!this.isInitialized)throw new Error("XiaozhiConnectionManager \u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u8C03\u7528 initialize()");if(this.isConnecting){this.logger.warn("\u8FDE\u63A5\u64CD\u4F5C\u6B63\u5728\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210");return}this.isConnecting=!0,this.performanceMetrics.connectionStartTime=Date.now(),this.logger.info(`\u5F00\u59CB\u8FDE\u63A5\u6240\u6709\u7AEF\u70B9\uFF0C\u603B\u6570: ${this.connections.size}`);try{let e=[];for(let[s,c]of this.connections)e.push(this.connectSingleEndpoint(s,c));let t=await Promise.allSettled(e),n=t.filter(s=>s.status==="fulfilled").length,r=t.length-n,o=Date.now()-this.performanceMetrics.connectionStartTime;if(this.performanceMetrics.totalConnectionTime+=o,this.performanceMetrics.connectionCount++,this.performanceMetrics.averageConnectionTime=this.performanceMetrics.totalConnectionTime/this.performanceMetrics.connectionCount,this.logger.info(`\u8FDE\u63A5\u5B8C\u6210 - \u6210\u529F: ${n}, \u5931\u8D25: ${r}, \u8017\u65F6: ${o}ms`),n===0)throw new Error("\u6240\u6709\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u5931\u8D25");this.startHealthCheck()}finally{this.isConnecting=!1}}async disconnect(){this.logger.info("\u5F00\u59CB\u65AD\u5F00\u6240\u6709\u8FDE\u63A5"),this.stopHealthCheck(),this.clearAllReconnectTimers();let e=[];for(let[t,n]of this.connections)e.push(this.disconnectSingleEndpoint(t,n));await Promise.allSettled(e),this.logger.info("\u6240\u6709\u8FDE\u63A5\u5DF2\u65AD\u5F00")}async addEndpoint(e){if(!this.isInitialized)throw new Error("XiaozhiConnectionManager \u672A\u521D\u59CB\u5316");if(this.connections.has(e)){this.logger.warn(`\u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\u6DFB\u52A0`);return}this.logger.info(`\u52A8\u6001\u6DFB\u52A0\u7AEF\u70B9: ${e}`);try{let t=this.getCurrentTools();if(await this.createConnection(e,t),this.isAnyConnected()){let n=this.connections.get(e);await this.connectSingleEndpoint(e,n)}this.logger.info(`\u7AEF\u70B9 ${e} \u6DFB\u52A0\u6210\u529F`)}catch(t){throw this.logger.error(`\u6DFB\u52A0\u7AEF\u70B9 ${e} \u5931\u8D25:`,t),this.connections.delete(e),this.connectionStates.delete(e),t}}async removeEndpoint(e){if(!this.connections.has(e)){this.logger.warn(`\u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u79FB\u9664`);return}this.logger.info(`\u52A8\u6001\u79FB\u9664\u7AEF\u70B9: ${e}`);try{let t=this.connections.get(e);await this.disconnectSingleEndpoint(e,t),this.connections.delete(e),this.connectionStates.delete(e);let n=this.reconnectTimers.get(e);n&&(clearTimeout(n),this.reconnectTimers.delete(e)),this.logger.info(`\u7AEF\u70B9 ${e} \u79FB\u9664\u6210\u529F`)}catch(t){throw this.logger.error(`\u79FB\u9664\u7AEF\u70B9 ${e} \u5931\u8D25:`,t),t}}getHealthyConnections(){let e=[];for(let[t,n]of this.connections){let r=this.connectionStates.get(t);r?.connected&&r.healthScore>50&&e.push(n)}return e}getConnectionStatus(){return Array.from(this.connectionStates.values())}isAnyConnected(){for(let e of this.connectionStates.values())if(e.connected)return!0;return!1}setServiceManager(e){this.mcpServiceManager=e,this.logger.info("\u5DF2\u8BBE\u7F6E MCPServiceManager"),this.connections.size>0&&this.syncToolsToAllConnections()}setHealthCheckEnabled(e,t){let n=this.connectionStates.get(e);n?(n.healthCheckEnabled=t,this.logger.info(`\u7AEF\u70B9 ${e} \u5065\u5EB7\u68C0\u67E5\u5DF2${t?"\u542F\u7528":"\u7981\u7528"}`)):this.logger.warn(`\u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728\uFF0C\u65E0\u6CD5\u8BBE\u7F6E\u5065\u5EB7\u68C0\u67E5\u72B6\u6001`)}getHealthCheckStats(){let e={};for(let[t,n]of this.connectionStates){let r=n.totalRequests>0?n.successfulRequests/n.totalRequests*100:0;e[t]={endpoint:t,healthScore:n.healthScore,successRate:Math.round(r*100)/100,averageResponseTime:n.responseTime||0,consecutiveFailures:n.consecutiveFailures,lastHealthCheck:n.lastHealthCheck,lastSuccessTime:n.lastSuccessTime}}return e}async triggerHealthCheck(){this.logger.info("\u624B\u52A8\u89E6\u53D1\u5065\u5EB7\u68C0\u67E5"),await this.performHealthCheck()}async triggerReconnect(e){let t=this.connectionStates.get(e);if(!t)throw new Error(`\u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);if(t.connected){this.logger.warn(`\u7AEF\u70B9 ${e} \u5DF2\u8FDE\u63A5\uFF0C\u65E0\u9700\u91CD\u8FDE`);return}this.logger.info(`\u624B\u52A8\u89E6\u53D1\u91CD\u8FDE: ${e}`);let n=this.reconnectTimers.get(e);n&&(clearTimeout(n),this.reconnectTimers.delete(e)),await this.performReconnect(e)}stopReconnect(e){let t=this.connectionStates.get(e);if(!t){this.logger.warn(`\u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);return}let n=this.reconnectTimers.get(e);n&&(clearTimeout(n),this.reconnectTimers.delete(e),t.isReconnecting=!1,t.nextReconnectTime=void 0,this.logger.info(`\u5DF2\u505C\u6B62\u7AEF\u70B9 ${e} \u7684\u91CD\u8FDE`))}stopAllReconnects(){this.logger.info("\u505C\u6B62\u6240\u6709\u7AEF\u70B9\u7684\u91CD\u8FDE");for(let[e]of this.reconnectTimers)this.stopReconnect(e)}getReconnectStats(){let e={};for(let[t,n]of this.connectionStates)e[t]={endpoint:t,reconnectAttempts:n.reconnectAttempts,isReconnecting:n.isReconnecting,nextReconnectTime:n.nextReconnectTime,lastReconnectAttempt:n.lastReconnectAttempt,reconnectDelay:n.reconnectDelay,errorType:n.errorType,recentReconnectHistory:n.reconnectHistory.slice(-5)};return e}validateEndpoints(e){let t=[],n=[];for(let r of e){if(!r||typeof r!="string"){n.push(r);continue}if(!r.startsWith("ws://")&&!r.startsWith("wss://")){n.push(r);continue}try{new URL(r),t.push(r)}catch{n.push(r)}}return{valid:t,invalid:n}}validateOptions(e){let t=[];if(e.healthCheckInterval!==void 0&&(typeof e.healthCheckInterval!="number"||e.healthCheckInterval<1e3)&&t.push("healthCheckInterval \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 1000 \u7684\u6570\u5B57"),e.reconnectInterval!==void 0&&(typeof e.reconnectInterval!="number"||e.reconnectInterval<100)&&t.push("reconnectInterval \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 100 \u7684\u6570\u5B57"),e.maxReconnectAttempts!==void 0&&(typeof e.maxReconnectAttempts!="number"||e.maxReconnectAttempts<0)&&t.push("maxReconnectAttempts \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 0 \u7684\u6570\u5B57"),e.connectionTimeout!==void 0&&(typeof e.connectionTimeout!="number"||e.connectionTimeout<1e3)&&t.push("connectionTimeout \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 1000 \u7684\u6570\u5B57"),e.maxReconnectDelay!==void 0&&(typeof e.maxReconnectDelay!="number"||e.maxReconnectDelay<1e3)&&t.push("maxReconnectDelay \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 1000 \u7684\u6570\u5B57"),e.reconnectBackoffMultiplier!==void 0&&(typeof e.reconnectBackoffMultiplier!="number"||e.reconnectBackoffMultiplier<1)&&t.push("reconnectBackoffMultiplier \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 1 \u7684\u6570\u5B57"),e.loadBalanceStrategy!==void 0){let n=["round-robin","random","health-based"];n.includes(e.loadBalanceStrategy)||t.push(`loadBalanceStrategy \u5FC5\u987B\u662F\u4EE5\u4E0B\u503C\u4E4B\u4E00: ${n.join(", ")}`)}if(e.reconnectStrategy!==void 0){let n=Object.values(dn);n.includes(e.reconnectStrategy)||t.push(`reconnectStrategy \u5FC5\u987B\u662F\u4EE5\u4E0B\u503C\u4E4B\u4E00: ${n.join(", ")}`)}return{valid:t.length===0,errors:t}}async updateEndpoints(e,t=[]){if(!this.isInitialized)throw new Error("XiaozhiConnectionManager \u672A\u521D\u59CB\u5316");this.logger.info(`\u66F4\u65B0\u7AEF\u70B9\u914D\u7F6E\uFF0C\u65B0\u7AEF\u70B9\u6570\u91CF: ${e.length}`);let{valid:n,invalid:r}=this.validateEndpoints(e);if(r.length>0&&this.logger.warn(`\u53D1\u73B0\u65E0\u6548\u7AEF\u70B9: ${r.join(", ")}`),n.length===0)throw new Error("\u6CA1\u6709\u6709\u6548\u7684\u7AEF\u70B9");let o=Array.from(this.connections.keys()),s=n.filter(d=>!o.includes(d)),c=o.filter(d=>!n.includes(d)),l=o.filter(d=>n.includes(d));this.logger.info(`\u7AEF\u70B9\u53D8\u66F4 - \u6DFB\u52A0: ${s.length}, \u79FB\u9664: ${c.length}, \u4FDD\u6301: ${l.length}`);try{for(let U of c)await this.removeEndpoint(U);for(let U of s)await this.addEndpoint(U);let d={type:s.length>0&&c.length>0?"endpoints_updated":s.length>0?"endpoints_added":"endpoints_removed",data:{added:s.length>0?s:void 0,removed:c.length>0?c:void 0,updated:s.length>0&&c.length>0?n:void 0},timestamp:new Date};this.emit("configChange",d),this.logger.info("\u7AEF\u70B9\u914D\u7F6E\u66F4\u65B0\u5B8C\u6210")}catch(d){throw this.logger.error("\u7AEF\u70B9\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",d),d}}updateOptions(e){this.logger.info("\u66F4\u65B0\u8FDE\u63A5\u9009\u9879");let{valid:t,errors:n}=this.validateOptions(e);if(!t)throw new Error(`\u65E0\u6548\u7684\u8FDE\u63A5\u9009\u9879: ${n.join(", ")}`);let r={...this.options};this.options={...this.options,...e};let o={type:"options_updated",data:{oldOptions:r,newOptions:e},timestamp:new Date};this.emit("configChange",o),this.logger.info("\u8FDE\u63A5\u9009\u9879\u66F4\u65B0\u5B8C\u6210"),this.logger.debug("\u65B0\u7684\u914D\u7F6E\u9009\u9879:",this.options)}getCurrentConfig(){return{endpoints:Array.from(this.connections.keys()),options:{...this.options}}}async reloadConfig(e){this.logger.info("\u5F00\u59CB\u70ED\u91CD\u8F7D\u914D\u7F6E");try{e.options&&this.updateOptions(e.options),e.endpoints&&await this.updateEndpoints(e.endpoints,e.tools||[]),this.logger.info("\u914D\u7F6E\u70ED\u91CD\u8F7D\u5B8C\u6210")}catch(t){throw this.logger.error("\u914D\u7F6E\u70ED\u91CD\u8F7D\u5931\u8D25:",t),t}}selectBestConnection(e=[]){let t=this.getHealthyConnections();if(t.length===0)return this.logger.warn("\u6CA1\u6709\u5065\u5EB7\u7684\u8FDE\u63A5\u53EF\u7528"),null;let n=t.filter(o=>{let s=this.getEndpointByConnection(o);return s&&!e.includes(s)});if(n.length===0)return this.logger.warn("\u6CA1\u6709\u53EF\u7528\u7684\u8FDE\u63A5\uFF08\u6392\u9664\u6307\u5B9A\u7AEF\u70B9\u540E\uFF09"),null;let r;switch(this.options.loadBalanceStrategy){case"round-robin":r=this.selectRoundRobin(n);break;case"random":r=this.selectRandom(n);break;case"health-based":r=this.selectHealthBased(n);break;default:r=this.selectRoundRobin(n)}return this.lastSelectedEndpoint=this.getEndpointByConnection(r),r}selectRoundRobin(e){if(e.length===0)throw new Error("\u6CA1\u6709\u53EF\u7528\u7684\u8FDE\u63A5");let t=e[this.roundRobinIndex%e.length];return this.roundRobinIndex=(this.roundRobinIndex+1)%e.length,t}selectRandom(e){if(e.length===0)throw new Error("\u6CA1\u6709\u53EF\u7528\u7684\u8FDE\u63A5");let t=Math.floor(Math.random()*e.length);return e[t]}selectHealthBased(e){if(e.length===0)throw new Error("\u6CA1\u6709\u53EF\u7528\u7684\u8FDE\u63A5");let t=e.map(o=>{let s=this.getEndpointByConnection(o),c=s?this.connectionStates.get(s):null;return{connection:o,endpoint:s,healthScore:c?.healthScore||0,responseTime:c?.responseTime||Number.POSITIVE_INFINITY,successRate:c&&c.totalRequests>0?c.successfulRequests/c.totalRequests*100:0}});t.sort((o,s)=>o.healthScore!==s.healthScore?s.healthScore-o.healthScore:o.successRate!==s.successRate?s.successRate-o.successRate:o.responseTime-s.responseTime);let n=t.reduce((o,s)=>o+(s.healthScore+1),0),r=Math.random()*n;for(let o of t)if(r-=o.healthScore+1,r<=0)return o.connection;return t[0].connection}getEndpointByConnection(e){for(let[t,n]of this.connections)if(n===e)return t;return null}getLoadBalanceStats(){let e=this.getHealthyConnections(),t={};for(let[n,r]of this.connectionStates){let o=r.totalRequests>0?r.successfulRequests/r.totalRequests*100:0,s=r.healthScore+1;t[n]={healthScore:r.healthScore,responseTime:r.responseTime||0,successRate:Math.round(o*100)/100,weight:s}}return{strategy:this.options.loadBalanceStrategy,totalConnections:this.connections.size,healthyConnections:e.length,lastSelectedEndpoint:this.lastSelectedEndpoint,roundRobinIndex:this.roundRobinIndex,connectionWeights:t}}setLoadBalanceStrategy(e){let t=this.options.loadBalanceStrategy;this.options.loadBalanceStrategy=e,e==="round-robin"&&(this.roundRobinIndex=0),this.logger.info(`\u8D1F\u8F7D\u5747\u8861\u7B56\u7565\u5DF2\u4ECE ${t} \u5207\u6362\u5230 ${e}`);let n={type:"options_updated",data:{oldOptions:{loadBalanceStrategy:t},newOptions:{loadBalanceStrategy:e}},timestamp:new Date};this.emit("configChange",n)}async performFailover(e){this.logger.warn(`\u6267\u884C\u6545\u969C\u8F6C\u79FB\uFF0C\u5931\u8D25\u7AEF\u70B9: ${e}`);let t=this.selectBestConnection([e]);if(!t)return this.logger.error("\u6545\u969C\u8F6C\u79FB\u5931\u8D25\uFF1A\u6CA1\u6709\u53EF\u7528\u7684\u5907\u7528\u8FDE\u63A5"),null;let n=this.getEndpointByConnection(t);return this.logger.info(`\u6545\u969C\u8F6C\u79FB\u6210\u529F\uFF0C\u5207\u6362\u5230\u7AEF\u70B9: ${n}`),t}async prewarmConnections(e=[]){let t=e.length>0?e:Array.from(this.connections.keys());this.logger.info(`\u5F00\u59CB\u9884\u70ED\u8FDE\u63A5\uFF0C\u7AEF\u70B9\u6570\u91CF: ${t.length}`);let n=t.map(async r=>{if(this.performanceMetrics.prewarmedConnections.has(r)){this.logger.debug(`\u7AEF\u70B9 ${r} \u5DF2\u9884\u70ED\uFF0C\u8DF3\u8FC7`);return}try{this.connections.get(r)&&(await this.performHealthCheck(),this.performanceMetrics.prewarmedConnections.add(r),this.logger.debug(`\u7AEF\u70B9 ${r} \u9884\u70ED\u5B8C\u6210`))}catch(o){this.logger.warn(`\u7AEF\u70B9 ${r} \u9884\u70ED\u5931\u8D25:`,o)}});await Promise.all(n),this.logger.info(`\u8FDE\u63A5\u9884\u70ED\u5B8C\u6210\uFF0C\u6210\u529F\u9884\u70ED ${this.performanceMetrics.prewarmedConnections.size} \u4E2A\u7AEF\u70B9`)}updatePerformanceMetrics(){let e=process.memoryUsage().heapUsed;this.performanceMetrics.memoryUsage.current=e,e>this.performanceMetrics.memoryUsage.peak&&(this.performanceMetrics.memoryUsage.peak=e)}getPerformanceMetrics(){this.updatePerformanceMetrics();let e=this.performanceMetrics.memoryUsage.current-this.performanceMetrics.memoryUsage.initial,t=this.performanceMetrics.memoryUsage.initial>0?e/this.performanceMetrics.memoryUsage.initial*100:0;return{connectionTime:{total:this.performanceMetrics.totalConnectionTime,average:this.performanceMetrics.averageConnectionTime,count:this.performanceMetrics.connectionCount},memoryUsage:{initial:this.performanceMetrics.memoryUsage.initial,current:this.performanceMetrics.memoryUsage.current,peak:this.performanceMetrics.memoryUsage.peak,growth:e,growthPercentage:Math.round(t*100)/100},prewarmedConnections:this.performanceMetrics.prewarmedConnections.size,totalConnections:this.connections.size,healthyConnections:this.getHealthyConnections().length}}optimizeMemoryUsage(){this.logger.info("\u5F00\u59CB\u5185\u5B58\u4F18\u5316");for(let[,e]of this.connectionStates)if(e.reconnectHistory&&e.reconnectHistory.length>10&&(e.reconnectHistory=e.reconnectHistory.slice(-10)),e.totalRequests>1e4){let t=e.successfulRequests/e.totalRequests;e.totalRequests=1e3,e.successfulRequests=Math.round(t*1e3)}global.gc&&global.gc(),this.updatePerformanceMetrics(),this.logger.info("\u5185\u5B58\u4F18\u5316\u5B8C\u6210")}async cleanup(){this.logger.info("\u5F00\u59CB\u6E05\u7406 XiaozhiConnectionManager \u8D44\u6E90");try{await this.disconnect(),this.connections.clear(),this.connectionStates.clear(),this.isInitialized=!1,this.isConnecting=!1,this.roundRobinIndex=0,this.lastSelectedEndpoint=null,this.logger.info("XiaozhiConnectionManager \u8D44\u6E90\u6E05\u7406\u5B8C\u6210")}catch(e){throw this.logger.error("XiaozhiConnectionManager \u8D44\u6E90\u6E05\u7406\u5931\u8D25:",e),e}}validateInitializeParams(e,t){if(!Array.isArray(e)||e.length===0)throw new Error("\u7AEF\u70B9\u5217\u8868\u4E0D\u80FD\u4E3A\u7A7A");if(!Array.isArray(t))throw new Error("\u5DE5\u5177\u5217\u8868\u5FC5\u987B\u662F\u6570\u7EC4");for(let n of e){if(!n||typeof n!="string")throw new Error(`\u65E0\u6548\u7684\u7AEF\u70B9\u5730\u5740: ${n}`);if(!n.startsWith("ws://")&&!n.startsWith("wss://"))throw new Error(`\u7AEF\u70B9\u5730\u5740\u5FC5\u987B\u662F WebSocket URL: ${n}`)}}async createConnection(e,t){this.logger.debug(`\u521B\u5EFA\u8FDE\u63A5\u5B9E\u4F8B: ${e}`);try{let n=new Y(e);this.mcpServiceManager&&n.setServiceManager(this.mcpServiceManager),this.connections.set(e,n),this.connectionStates.set(e,{endpoint:e,connected:!1,initialized:!1,reconnectAttempts:0,healthScore:100,consecutiveFailures:0,totalRequests:0,successfulRequests:0,healthCheckEnabled:!0,isReconnecting:!1,reconnectDelay:this.options.reconnectInterval,reconnectHistory:[]}),this.logger.debug(`\u8FDE\u63A5\u5B9E\u4F8B\u521B\u5EFA\u6210\u529F: ${e}`)}catch(n){throw this.logger.error(`\u521B\u5EFA\u8FDE\u63A5\u5B9E\u4F8B\u5931\u8D25 ${e}:`,n),n}}async connectSingleEndpoint(e,t){let n=this.connectionStates.get(e);if(!n)throw new Error(`\u7AEF\u70B9\u72B6\u6001\u4E0D\u5B58\u5728: ${e}`);this.logger.debug(`\u8FDE\u63A5\u7AEF\u70B9: ${e}`);try{n.connected=!1,n.initialized=!1,await t.connect(),n.connected=!0,n.initialized=!0,n.lastConnected=new Date,n.lastError=void 0,n.reconnectAttempts=0,n.healthScore=100,this.logger.info(`\u7AEF\u70B9\u8FDE\u63A5\u6210\u529F: ${e}`)}catch(r){throw n.connected=!1,n.initialized=!1,n.lastError=r instanceof Error?r.message:String(r),n.reconnectAttempts++,n.healthScore=Math.max(0,n.healthScore-20),this.logger.error(`\u7AEF\u70B9\u8FDE\u63A5\u5931\u8D25 ${e}:`,r),this.scheduleReconnect(e),r}}async disconnectSingleEndpoint(e,t){let n=this.connectionStates.get(e);if(n){this.logger.debug(`\u65AD\u5F00\u7AEF\u70B9: ${e}`);try{t.disconnect(),n.connected=!1,n.initialized=!1,this.logger.debug(`\u7AEF\u70B9\u65AD\u5F00\u6210\u529F: ${e}`)}catch(r){this.logger.error(`\u7AEF\u70B9\u65AD\u5F00\u5931\u8D25 ${e}:`,r),n.connected=!1,n.initialized=!1}}}getCurrentTools(){if(!this.mcpServiceManager)return[];try{return this.mcpServiceManager.getAllTools()}catch(e){return this.logger.error("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25:",e),[]}}syncToolsToAllConnections(){if(this.mcpServiceManager){this.logger.debug("\u540C\u6B65\u5DE5\u5177\u5230\u6240\u6709\u8FDE\u63A5");for(let[e,t]of this.connections)try{t.setServiceManager(this.mcpServiceManager),this.logger.debug(`\u5DE5\u5177\u540C\u6B65\u6210\u529F: ${e}`)}catch(n){this.logger.error(`\u5DE5\u5177\u540C\u6B65\u5931\u8D25 ${e}:`,n)}}}startHealthCheck(){this.healthCheckInterval||(this.logger.debug(`\u542F\u52A8\u5065\u5EB7\u68C0\u67E5\uFF0C\u95F4\u9694: ${this.options.healthCheckInterval}ms`),this.healthCheckInterval=setInterval(()=>{this.performHealthCheck()},this.options.healthCheckInterval))}stopHealthCheck(){this.healthCheckInterval&&(clearInterval(this.healthCheckInterval),this.healthCheckInterval=null,this.logger.debug("\u5065\u5EB7\u68C0\u67E5\u5DF2\u505C\u6B62"))}async performHealthCheck(){this.logger.debug("\u6267\u884C\u5065\u5EB7\u68C0\u67E5");let e=[];for(let[t,n]of this.connectionStates)n.healthCheckEnabled&&e.push(this.performSingleHealthCheck(t,n));await Promise.allSettled(e)}async performSingleHealthCheck(e,t){let n=Date.now();t.lastHealthCheck=new Date,t.totalRequests++;try{let r=this.connections.get(e);if(!r)throw new Error(`\u8FDE\u63A5\u5B9E\u4F8B\u4E0D\u5B58\u5728: ${e}`);await this.checkConnectionHealth(r,e);let o=Date.now()-n;this.handleHealthCheckSuccess(t,o)}catch(r){let o=Date.now()-n;this.handleHealthCheckFailure(t,r,o)}}async checkConnectionHealth(e,t){if(!e)throw new Error("\u8FDE\u63A5\u5B9E\u4F8B\u4E0D\u5B58\u5728");if(await new Promise(r=>setTimeout(r,10)),!this.connectionStates.get(t)?.connected)throw new Error("\u8FDE\u63A5\u5DF2\u65AD\u5F00")}handleHealthCheckSuccess(e,t){e.successfulRequests++,e.consecutiveFailures=0,e.responseTime=t,e.lastSuccessTime=new Date,this.updateHealthScore(e,!0,t),this.logger.debug(`\u5065\u5EB7\u68C0\u67E5\u6210\u529F: ${e.endpoint}, \u54CD\u5E94\u65F6\u95F4: ${t}ms, \u5065\u5EB7\u5EA6: ${e.healthScore}`)}handleHealthCheckFailure(e,t,n){e.consecutiveFailures++,e.responseTime=n,e.lastError=t.message,this.updateHealthScore(e,!1,n),this.logger.warn(`\u5065\u5EB7\u68C0\u67E5\u5931\u8D25: ${e.endpoint}, \u9519\u8BEF: ${t.message}, \u8FDE\u7EED\u5931\u8D25: ${e.consecutiveFailures}, \u5065\u5EB7\u5EA6: ${e.healthScore}`),e.consecutiveFailures>=3&&e.connected&&this.logger.warn(`\u7AEF\u70B9 ${e.endpoint} \u8FDE\u7EED\u5931\u8D25 ${e.consecutiveFailures} \u6B21\uFF0C\u53EF\u80FD\u9700\u8981\u91CD\u8FDE`)}updateHealthScore(e,t,n){let r=e.healthScore;if(t){let o=5;n<100?o=10:n<500?o=7:n<1e3?o=5:o=2,e.healthScore=Math.min(100,r+o)}else{let o=15;e.consecutiveFailures>=5?o=30:e.consecutiveFailures>=3&&(o=20),e.healthScore=Math.max(0,r-o)}if(e.totalRequests>0){let o=e.successfulRequests/e.totalRequests;o<.5?e.healthScore=Math.max(0,e.healthScore-10):o>.9&&(e.healthScore=Math.min(100,e.healthScore+5))}}classifyConnectionError(e){let t=e.message.toLowerCase();return t.includes("timeout")||t.includes("timed out")?"timeout_error":t.includes("network")||t.includes("connection refused")||t.includes("econnrefused")||t.includes("enotfound")?"network_error":t.includes("auth")||t.includes("unauthorized")||t.includes("forbidden")||t.includes("401")||t.includes("403")?"authentication_error":t.includes("server")||t.includes("500")||t.includes("502")||t.includes("503")||t.includes("504")?"server_error":"unknown_error"}calculateReconnectDelay(e){let t=this.options.reconnectInterval,n=this.options.maxReconnectDelay,r=this.options.reconnectBackoffMultiplier,o=e.reconnectAttempts,s;switch(this.options.reconnectStrategy){case"fixed_interval":s=t;break;case"linear_backoff":s=t*(o+1);break;case"exponential_backoff":s=t*r**o;break;case"adaptive":s=this.calculateAdaptiveDelay(e,t,r,o);break;default:s=t*r**o}if(s=Math.min(s,n),this.options.jitterEnabled){let c=s*.1*Math.random();s+=c}return Math.round(s)}calculateAdaptiveDelay(e,t,n,r){let o=t;switch(e.errorType){case"network_error":o=t*n**r;break;case"authentication_error":o=t*n**r*2;break;case"server_error":o=t*(1+r);break;case"timeout_error":o=t*(1+r*.5);break;default:o=t*n**r}if(e.reconnectHistory.length>0){let s=e.reconnectHistory.slice(-5),c=s.filter(l=>l.success).length/s.length;c<.2?o*=1.5:c>.8&&(o*=.8)}return o}shouldReconnect(e){return e.reconnectAttempts>=this.options.maxReconnectAttempts?(this.logger.warn(`\u7AEF\u70B9 ${e.endpoint} \u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 ${this.options.maxReconnectAttempts}`),!1):e.errorType==="authentication_error"&&e.reconnectAttempts>=3?(this.logger.warn(`\u7AEF\u70B9 ${e.endpoint} \u8BA4\u8BC1\u9519\u8BEF\uFF0C\u505C\u6B62\u91CD\u8FDE`),!1):e.consecutiveFailures>=10?(this.logger.warn(`\u7AEF\u70B9 ${e.endpoint} \u8FDE\u7EED\u5931\u8D25\u6B21\u6570\u8FC7\u591A\uFF0C\u505C\u6B62\u91CD\u8FDE`),!1):!0}scheduleReconnect(e){let t=this.connectionStates.get(e);if(!t)return;if(t.lastError&&(t.errorType=this.classifyConnectionError(new Error(t.lastError))),!this.shouldReconnect(t)){t.isReconnecting=!1;return}let n=this.reconnectTimers.get(e);n&&clearTimeout(n);let r=this.calculateReconnectDelay(t);t.reconnectDelay=r,t.isReconnecting=!0,t.nextReconnectTime=new Date(Date.now()+r),this.logger.info(`\u5B89\u6392\u91CD\u8FDE ${e}\uFF0C\u5EF6\u8FDF: ${r}ms\uFF0C\u5C1D\u8BD5\u6B21\u6570: ${t.reconnectAttempts+1}\uFF0C\u9519\u8BEF\u7C7B\u578B: ${t.errorType}`);let o=setTimeout(async()=>{this.reconnectTimers.delete(e),await this.performReconnect(e)},r);this.reconnectTimers.set(e,o)}async performReconnect(e){let t=this.connectionStates.get(e),n=this.connections.get(e);if(!(!t||!n)){t.lastReconnectAttempt=new Date,t.isReconnecting=!0,this.logger.info(`\u5F00\u59CB\u91CD\u8FDE ${e}\uFF0C\u7B2C ${t.reconnectAttempts+1} \u6B21\u5C1D\u8BD5`);try{await this.connectSingleEndpoint(e,n),t.isReconnecting=!1,t.reconnectHistory.push({timestamp:new Date,success:!0,delay:t.reconnectDelay}),this.logger.info(`\u91CD\u8FDE\u6210\u529F ${e}`)}catch(r){t.isReconnecting=!1,t.reconnectHistory.push({timestamp:new Date,success:!1,error:r instanceof Error?r.message:String(r),delay:t.reconnectDelay}),this.logger.error(`\u91CD\u8FDE\u5931\u8D25 ${e}:`,r),this.scheduleReconnect(e)}t.reconnectHistory.length>20&&(t.reconnectHistory=t.reconnectHistory.slice(-20))}}clearAllReconnectTimers(){for(let[,e]of this.reconnectTimers)clearTimeout(e);this.reconnectTimers.clear()}}});async function Dr(i){return console.log("\u{1F680} \u6B63\u5728\u521D\u59CB\u5316 XiaozhiConnectionManager \u5355\u4F8B..."),new Be(i)}async function fn(i){if(J&&N==="initialized")return J;if(L&&N==="initializing")return L;N==="failed"&&vt(),N="initializing",L=Dr(i);try{return J=await L,N="initialized",de=`xiaozhi-connection-manager-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,xe=null,console.log(`\u2705 XiaozhiConnectionManager \u5355\u4F8B\u521D\u59CB\u5316\u6210\u529F\uFF0C\u5B9E\u4F8BID: ${de}`),J}catch(e){throw N="failed",xe=e,L=null,console.error("\u274C XiaozhiConnectionManager \u5355\u4F8B\u521D\u59CB\u5316\u5931\u8D25:",e.message),e}}async function vn(){if(N==="cleanup"){console.log("\u26A0\uFE0F XiaozhiConnectionManager \u5355\u4F8B\u5DF2\u5728\u6E05\u7406\u4E2D\uFF0C\u8DF3\u8FC7\u91CD\u590D\u6E05\u7406");return}console.log("\u{1F9F9} \u6B63\u5728\u6E05\u7406 XiaozhiConnectionManager \u5355\u4F8B\u8D44\u6E90..."),N="cleanup";try{if(L){try{await(await L).cleanup()}catch(i){console.error("\u6E05\u7406\u521D\u59CB\u5316\u4E2D\u7684\u5B9E\u4F8B\u5931\u8D25:",i.message)}L=null}J&&(await J.cleanup(),J=null),N="not_initialized",xe=null,de=null,console.log("\u2705 XiaozhiConnectionManager \u5355\u4F8B\u8D44\u6E90\u6E05\u7406\u5B8C\u6210")}catch(i){throw console.error("\u274C XiaozhiConnectionManager \u5355\u4F8B\u6E05\u7406\u5931\u8D25:",i.message),vt(),i}}function vt(){console.log("\u{1F504} \u91CD\u7F6E XiaozhiConnectionManager \u5355\u4F8B\u72B6\u6001..."),L&&(L=null),J=null,N="not_initialized",xe=null,de=null,console.log("\u2705 XiaozhiConnectionManager \u5355\u4F8B\u72B6\u6001\u5DF2\u91CD\u7F6E")}function Nr(){return N==="initialized"&&J!==null}function Ar(){return{state:N,initializationTime:de?new Date:void 0,lastError:xe||void 0,instanceId:de||void 0}}async function kr(i){return console.log("\u{1F504} \u5F3A\u5236\u91CD\u65B0\u521D\u59CB\u5316 XiaozhiConnectionManager \u5355\u4F8B..."),await vn(),fn(i)}function Fr(){return J}async function zr(){if(N==="initialized")return!0;if(N==="initializing"&&L)try{return await L,!0}catch{return!1}return!1}var J,L,N,xe,de,ue,Cn=h(()=>{"use strict";un();J=null,L=null,N="not_initialized",xe=null,de=null;a(Dr,"createInstance");a(fn,"getInstance");a(vn,"cleanup");a(vt,"reset");a(Nr,"isInitialized");a(Ar,"getStatus");a(kr,"forceReinitialize");a(Fr,"getCurrentInstance");a(zr,"waitForInitialization");ue={getInstance:fn,cleanup:vn,reset:vt,isInitialized:Nr,getStatus:Ar,forceReinitialize:kr,getCurrentInstance:Fr,waitForInitialization:zr};process.on("exit",()=>{ue.isInitialized()&&(console.log("\u{1F504} \u8FDB\u7A0B\u9000\u51FA\uFF0C\u6B63\u5728\u6E05\u7406 XiaozhiConnectionManager \u5355\u4F8B..."),ue.reset())});process.on("uncaughtException",async i=>{console.error("\u{1F4A5} \u672A\u6355\u83B7\u7684\u5F02\u5E38\uFF0C\u6E05\u7406 XiaozhiConnectionManager \u5355\u4F8B:",i);try{await ue.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}});process.on("unhandledRejection",async i=>{console.error("\u{1F4A5} \u672A\u5904\u7406\u7684Promise\u62D2\u7EDD\uFF0C\u6E05\u7406 XiaozhiConnectionManager \u5355\u4F8B:",i);try{await ue.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}})});var yt={};k(yt,{WebServer:()=>St});import{spawn as Sn}from"child_process";import{existsSync as Ct}from"fs";import{readFile as yn}from"fs/promises";import{createServer as jr}from"http";import{dirname as Hr,join as fe}from"path";import{fileURLToPath as Lr}from"url";import{serve as Ur}from"@hono/node-server";import{Hono as _r}from"hono";import{cors as Wr}from"hono/cors";import{WebSocketServer as Br}from"ws";var St,wt=h(()=>{"use strict";R();je();gn();Mt();ae();mn();Cn();St=class{static{a(this,"WebServer")}app;httpServer=null;wss=null;logger;port;clientInfo={status:"disconnected",mcpEndpoint:"",activeMCPServers:[]};heartbeatTimeout;HEARTBEAT_TIMEOUT=35e3;proxyMCPServer;xiaozhiConnectionManager;mcpServiceManager;constructor(e){try{this.port=e??m.getWebUIPort()??9999}catch{this.port=e??9999}this.logger=f,this.app=new _r,this.setupMiddleware(),this.setupRoutes()}async initializeConnections(){try{this.logger.info("\u5F00\u59CB\u521D\u59CB\u5316\u8FDE\u63A5...");let e=await this.loadConfiguration();this.mcpServiceManager=await me.getInstance(),await this.loadMCPServicesFromConfig(e.mcpServers);let t=this.mcpServiceManager.getAllTools();this.logger.info(`\u5DF2\u52A0\u8F7D ${t.length} \u4E2A\u5DE5\u5177`),await this.initializeXiaozhiConnection(e.mcpEndpoint,t),this.logger.info("\u6240\u6709\u8FDE\u63A5\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("\u8FDE\u63A5\u521D\u59CB\u5316\u5931\u8D25:",e),e}}async loadConfiguration(){if(!m.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C 'xiaozhi init' \u521D\u59CB\u5316\u914D\u7F6E");let e=m.getConfig();return{mcpEndpoint:e.mcpEndpoint,mcpServers:e.mcpServers,webUIPort:e.webUI?.port??9999}}async loadMCPServicesFromConfig(e){if(!this.mcpServiceManager)throw new Error("MCPServiceManager \u672A\u521D\u59CB\u5316");for(let[t,n]of Object.entries(e)){this.logger.info(`\u6DFB\u52A0 MCP \u670D\u52A1\u914D\u7F6E: ${t}`);let r=ln(t,n);this.mcpServiceManager.addServiceConfig(t,r)}await this.mcpServiceManager.startAllServices(),this.logger.info("\u6240\u6709 MCP \u670D\u52A1\u5DF2\u542F\u52A8")}async initializeXiaozhiConnection(e,t){let r=(Array.isArray(e)?e:[e]).filter(o=>o&&!o.includes("<\u8BF7\u586B\u5199"));if(r.length===0){this.logger.warn("\u672A\u914D\u7F6E\u6709\u6548\u7684\u5C0F\u667A\u63A5\u5165\u70B9\uFF0C\u8DF3\u8FC7\u8FDE\u63A5");return}this.logger.info(`\u521D\u59CB\u5316\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u7BA1\u7406\u5668\uFF0C\u7AEF\u70B9\u6570\u91CF: ${r.length}`),this.logger.debug("\u6709\u6548\u7AEF\u70B9\u5217\u8868:",r);try{this.xiaozhiConnectionManager=await ue.getInstance({healthCheckInterval:3e4,reconnectInterval:5e3,maxReconnectAttempts:10,loadBalanceStrategy:"round-robin",connectionTimeout:1e4}),this.mcpServiceManager&&this.xiaozhiConnectionManager.setServiceManager(this.mcpServiceManager),await this.xiaozhiConnectionManager.initialize(r,t),await this.xiaozhiConnectionManager.connect(),this.xiaozhiConnectionManager.on("configChange",o=>{this.logger.info(`\u5C0F\u667A\u8FDE\u63A5\u914D\u7F6E\u53D8\u66F4: ${o.type}`,o.data)}),this.logger.info(`\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u7BA1\u7406\u5668\u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u7BA1\u7406 ${r.length} \u4E2A\u7AEF\u70B9`)}catch(o){this.logger.error("\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u7BA1\u7406\u5668\u521D\u59CB\u5316\u5931\u8D25:",o),this.logger.warn("\u56DE\u9000\u5230\u5355\u8FDE\u63A5\u6A21\u5F0F");let s=r[0];this.logger.info(`\u521D\u59CB\u5316\u5355\u4E2A\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5: ${s}`),this.proxyMCPServer=new Y(s),this.mcpServiceManager&&this.proxyMCPServer.setServiceManager(this.mcpServiceManager),await this.connectWithRetry(()=>this.proxyMCPServer.connect(),"\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5"),this.logger.info("\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u6210\u529F\uFF08\u5355\u8FDE\u63A5\u6A21\u5F0F\uFF09")}}getBestXiaozhiConnection(){return this.xiaozhiConnectionManager?this.xiaozhiConnectionManager.selectBestConnection():this.proxyMCPServer||null}getXiaozhiConnectionStatus(){return this.xiaozhiConnectionManager?{type:"multi-endpoint",manager:{healthyConnections:this.xiaozhiConnectionManager.getHealthyConnections().length,totalConnections:this.xiaozhiConnectionManager.getConnectionStatus().length,loadBalanceStats:this.xiaozhiConnectionManager.getLoadBalanceStats(),healthCheckStats:this.xiaozhiConnectionManager.getHealthCheckStats(),reconnectStats:this.xiaozhiConnectionManager.getReconnectStats()},connections:this.xiaozhiConnectionManager.getConnectionStatus()}:this.proxyMCPServer?{type:"single-endpoint",connected:!0,endpoint:"unknown"}:{type:"none",connected:!1}}async connectWithRetry(e,t,n=5,r=1e3,o=3e4,s=2){let c=null;for(let l=1;l<=n;l++)try{return this.logger.info(`${t} - \u5C1D\u8BD5\u8FDE\u63A5 (${l}/${n})`),await e()}catch(d){if(c=d,this.logger.warn(`${t} - \u8FDE\u63A5\u5931\u8D25:`,d),l<n){let U=Math.min(r*s**(l-1),o);this.logger.info(`${t} - ${U}ms \u540E\u91CD\u8BD5...`),await this.sleep(U)}}throw new Error(`${t} - \u8FDE\u63A5\u5931\u8D25\uFF0C\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570: ${c?.message}`)}sleep(e){return new Promise(t=>setTimeout(t,e))}setupMiddleware(){this.app?.use("*",Wr({origin:"*",allowMethods:["GET","POST","PUT","OPTIONS"],allowHeaders:["Content-Type"]})),this.app?.onError((e,t)=>(this.logger.error("HTTP request error:",e),t.json({error:"Internal Server Error"},500)))}setupRoutes(){this.app?.get("/api/config",async e=>{let t=m.getConfig();return e.json(t)}),this.app?.put("/api/config",async e=>{try{let t=await e.req.json();return this.updateConfig(t),this.broadcastConfigUpdate(t),this.logger.info("\u914D\u7F6E\u5DF2\u66F4\u65B0"),e.json({success:!0})}catch(t){return e.json({error:t instanceof Error?t.message:String(t)},400)}}),this.app?.get("/api/status",async e=>{let t=this.proxyMCPServer?.getStatus();return e.json({...this.clientInfo,mcpConnection:t})}),this.app?.all("/api/*",async e=>e.text("Not Found",404)),this.app.get("*",async e=>this.serveStaticFile(e))}async serveStaticFile(e){let t=new URL(e.req.url).pathname;try{let n=Hr(Lr(import.meta.url)),o=[fe(n,"..","web","dist"),fe(n,"..","web"),fe(process.cwd(),"web","dist"),fe(process.cwd(),"web")].find(ee=>Ct(ee));if(!o)return e.html(`
9
16
  <!DOCTYPE html>
10
17
  <html>
11
18
  <head>
@@ -25,11 +32,37 @@ data: /messages?sessionId=${r}
25
32
  </div>
26
33
  </body>
27
34
  </html>
28
- `);let s=t;if(s==="/"&&(s="/index.html"),s.includes(".."))return e.text("Forbidden",403);let l=U(i,s);if(!be(l)){let N=U(i,"index.html");if(be(N)){let he=await Xe(N);return e.html(he.toString())}return e.text("Not Found",404)}let p=await Xe(l),f=l.split(".").pop()?.toLowerCase(),x={html:"text/html",js:"application/javascript",css:"text/css",json:"application/json",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",svg:"image/svg+xml",ico:"image/x-icon"}[f||""]||"application/octet-stream";return x.startsWith("text/")||x.includes("javascript")||x.includes("json")?e.text(p.toString(),200,{"Content-Type":x}):e.body(p,200,{"Content-Type":x})}catch(n){return this.logger.error("Serve static file error:",n),e.text("Internal Server Error",500)}}setupWebSocket(){this.wss&&this.wss.on("connection",e=>{this.logger.debug("WebSocket client connected"),e.on("message",async t=>{try{let n=JSON.parse(t.toString());await this.handleWebSocketMessage(e,n)}catch(n){this.logger.error("WebSocket message error:",n),e.send(JSON.stringify({type:"error",error:n instanceof Error?n.message:String(n)}))}}),e.on("close",()=>{this.logger.debug("WebSocket client disconnected")}),this.sendInitialData(e)})}async handleWebSocketMessage(e,t){switch(t.type){case"getConfig":{let n=g.getConfig();this.logger.debug("getConfig ws getConfig",n),e.send(JSON.stringify({type:"config",data:n}));break}case"updateConfig":this.updateConfig(t.config),this.broadcastConfigUpdate(t.config);break;case"getStatus":e.send(JSON.stringify({type:"status",data:this.clientInfo}));break;case"clientStatus":{this.updateClientInfo(t.data),this.broadcastStatusUpdate();let n=g.getConfig();e.send(JSON.stringify({type:"configUpdate",data:n}));break}case"restartService":this.logger.info("\u6536\u5230\u624B\u52A8\u91CD\u542F\u670D\u52A1\u8BF7\u6C42"),this.broadcastRestartStatus("restarting"),setTimeout(async()=>{try{await this.restartService(),setTimeout(()=>{this.broadcastRestartStatus("completed")},5e3)}catch(n){this.logger.error(`\u624B\u52A8\u91CD\u542F\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),this.broadcastRestartStatus("failed",n instanceof Error?n.message:"\u672A\u77E5\u9519\u8BEF")}},500);break}}async sendInitialData(e){let t=g.getConfig();e.send(JSON.stringify({type:"config",data:t})),e.send(JSON.stringify({type:"status",data:this.clientInfo})),setTimeout(()=>{let n=g.getConfig();e.send(JSON.stringify({type:"configUpdate",data:n}))},2e3)}broadcastConfigUpdate(e){if(!this.wss)return;let t=JSON.stringify({type:"configUpdate",data:e});for(let n of this.wss.clients)n.readyState===1&&n.send(t)}broadcastRestartStatus(e,t){if(!this.wss)return;let n=JSON.stringify({type:"restartStatus",data:{status:e,error:t,timestamp:Date.now()}});for(let r of this.wss.clients)r.readyState===1&&r.send(n)}broadcastStatusUpdate(){if(!this.wss)return;let e=JSON.stringify({type:"statusUpdate",data:this.clientInfo});for(let t of this.wss.clients)t.readyState===1&&t.send(e)}updateClientInfo(e){this.clientInfo={...this.clientInfo,...e},e.lastHeartbeat&&(this.clientInfo.lastHeartbeat=Date.now()),e.status==="connected"&&this.resetHeartbeatTimeout()}resetHeartbeatTimeout(){this.heartbeatTimeout&&clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=setTimeout(()=>{this.logger.warn("\u5BA2\u6237\u7AEF\u5FC3\u8DF3\u8D85\u65F6\uFF0C\u6807\u8BB0\u4E3A\u65AD\u5F00\u8FDE\u63A5"),this.updateClientInfo({status:"disconnected"}),this.broadcastStatusUpdate()},this.HEARTBEAT_TIMEOUT)}updateConfig(e){e.mcpEndpoint!==g.getMcpEndpoint()&&g.updateMcpEndpoint(e.mcpEndpoint);let t=g.getMcpServers();for(let[n,r]of Object.entries(e.mcpServers))JSON.stringify(t[n])!==JSON.stringify(r)&&g.updateMcpServer(n,r);for(let n of Object.keys(t))n in e.mcpServers||(g.removeMcpServer(n),g.removeServerToolsConfig(n));if(e.connection&&g.updateConnectionConfig(e.connection),e.modelscope&&g.updateModelScopeConfig(e.modelscope),e.webUI&&g.updateWebUIConfig(e.webUI),e.mcpServerConfig)for(let[n,r]of Object.entries(e.mcpServerConfig))for(let[i,s]of Object.entries(r.tools))g.setToolEnabled(n,i,s.enable)}async restartService(){this.logger.info("\u6B63\u5728\u91CD\u542F MCP \u670D\u52A1..."),this.heartbeatTimeout&&(clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=void 0);try{let e=W();if(!e.running){this.logger.warn("MCP \u670D\u52A1\u672A\u8FD0\u884C\uFF0C\u5C1D\u8BD5\u542F\u52A8\u670D\u52A1"),Be("xiaozhi",["start","--daemon"],{detached:!0,stdio:"ignore",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}}).unref(),this.logger.info("MCP \u670D\u52A1\u542F\u52A8\u547D\u4EE4\u5DF2\u53D1\u9001");return}let t=e.mode==="daemon",n=["restart"];t&&n.push("--daemon"),Be("xiaozhi",n,{detached:!0,stdio:"ignore",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}}).unref(),this.logger.info("MCP \u670D\u52A1\u91CD\u542F\u547D\u4EE4\u5DF2\u53D1\u9001"),this.resetHeartbeatTimeout()}catch(e){throw this.logger.error(`\u91CD\u542F\u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),this.resetHeartbeatTimeout(),e}}updateStatus(e){this.updateClientInfo(e),this.broadcastStatusUpdate()}async start(){if(this.httpServer){this.logger.warn("Web server is already running");return}let e=hn({fetch:this.app.fetch,port:this.port,hostname:"0.0.0.0",createServer:cn});this.httpServer=e,this.wss=new dn({server:this.httpServer}),this.setupWebSocket(),this.logger.info(`Web server listening on http://0.0.0.0:${this.port}`),this.logger.info(`Local access: http://localhost:${this.port}`);try{await this.initializeConnections(),this.logger.info("\u6240\u6709\u8FDE\u63A5\u521D\u59CB\u5316\u5B8C\u6210")}catch(t){this.logger.error("\u8FDE\u63A5\u521D\u59CB\u5316\u5931\u8D25\uFF0C\u4F46 Web \u670D\u52A1\u5668\u7EE7\u7EED\u8FD0\u884C:",t)}}stop(){return new Promise(e=>{let t=!1,n=a(()=>{t||(t=!0,e())},"doResolve");if(this.proxyMCPServer?.disconnect(),this.heartbeatTimeout&&(clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=void 0),this.wss){for(let r of this.wss.clients)r.terminate();this.wss.close(()=>{this.httpServer?this.httpServer.close(()=>{this.logger.info("Web server stopped"),n()}):(this.logger.info("Web server stopped"),n()),setTimeout(()=>{this.logger.info("Web server force stopped"),n()},2e3)})}else this.logger.info("Web server stopped"),n()})}};z();z();import h from"chalk";import Ge from"cli-table3";import Pe from"ora";function Je(o){let e=0;for(let t of o)/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(t)?e+=2:e+=1;return e}a(Je,"getDisplayWidth");function Ke(o,e){if(Je(o)<=e)return o;if(e<=3)return"";let t="",n=0,r=!1;for(let i of o){let s=/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(i)?2:1;if(n+s>e-3){if(!r)return"";t+="...";break}t+=i,n+=s,r=!0}return t}a(Ke,"truncateToWidth");async function qe(o={}){let e=Pe("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868...").start();try{let t=g.getMcpServers(),n=Object.keys(t);if(n.length===0){e.warn("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1"),console.log(h.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi config' \u547D\u4EE4\u914D\u7F6E MCP \u670D\u52A1"));return}if(e.succeed(`\u627E\u5230 ${n.length} \u4E2A MCP \u670D\u52A1`),o.tools){console.log(),console.log(h.bold("MCP \u670D\u52A1\u5DE5\u5177\u5217\u8868:")),console.log();let r=8,i=[];for(let l of n){let p=g.getServerToolsConfig(l),f=Object.keys(p);i.push(...f)}for(let l of i){let p=Je(l);p>r&&(r=p)}r=Math.max(10,Math.min(r+2,30));let s=new Ge({head:[h.bold("MCP"),h.bold("\u5DE5\u5177\u540D\u79F0"),h.bold("\u72B6\u6001"),h.bold("\u63CF\u8FF0")],colWidths:[15,r,8,40],wordWrap:!0,style:{head:[],border:[]}});for(let l of n){let p=g.getServerToolsConfig(l),f=Object.keys(p);if(f.length===0)s.push([h.gray(l),h.gray("-"),h.gray("-"),h.gray("\u6682\u672A\u8BC6\u522B\u5230\u76F8\u5173\u5DE5\u5177")]);else{s.length>0&&s.push([{colSpan:4,content:""}]);for(let S of f){let x=p[S],N=x.enable?h.green("\u542F\u7528"):h.red("\u7981\u7528"),he=Ke(x.description||"",32);s.push([l,S,N,he])}}}console.log(s.toString())}else{console.log(),console.log(h.bold("MCP \u670D\u52A1\u5217\u8868:")),console.log();for(let r of n){let i=t[r],s=g.getServerToolsConfig(r),l=Object.keys(s).length,p=Object.values(s).filter(f=>f.enable!==!1).length;console.log(`${h.cyan("\u2022")} ${h.bold(r)}`),"url"in i?("type"in i&&i.type==="sse"?console.log(` \u7C7B\u578B: ${h.gray("SSE")}`):console.log(` \u7C7B\u578B: ${h.gray("Streamable HTTP")}`),console.log(` URL: ${h.gray(i.url)}`)):console.log(` \u547D\u4EE4: ${h.gray(i.command)} ${h.gray(i.args.join(" "))}`),l>0?console.log(` \u5DE5\u5177: ${h.green(p)} \u542F\u7528 / ${h.yellow(l)} \u603B\u8BA1`):console.log(` \u5DE5\u5177: ${h.gray("\u672A\u626B\u63CF (\u8BF7\u5148\u542F\u52A8\u670D\u52A1)")}`),console.log()}}console.log(h.gray("\u{1F4A1} \u63D0\u793A:")),console.log(h.gray(" - \u4F7F\u7528 'xiaozhi mcp list --tools' \u67E5\u770B\u6240\u6709\u5DE5\u5177")),console.log(h.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> list' \u67E5\u770B\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177")),console.log(h.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> <\u5DE5\u5177\u540D> enable/disable' \u542F\u7528/\u7981\u7528\u5DE5\u5177"))}catch(t){e.fail("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868\u5931\u8D25"),console.error(h.red(`\u9519\u8BEF: ${t instanceof Error?t.message:String(t)}`)),process.exit(1)}}a(qe,"listMcpServers");async function Ze(o){let e=Pe(`\u83B7\u53D6 ${o} \u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868...`).start();try{if(!g.getMcpServers()[o]){e.fail(`\u670D\u52A1 '${o}' \u4E0D\u5B58\u5728`),console.log(h.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let n=g.getServerToolsConfig(o),r=Object.keys(n);if(r.length===0){e.warn(`\u670D\u52A1 '${o}' \u6682\u65E0\u5DE5\u5177\u4FE1\u606F`),console.log(h.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u542F\u52A8\u670D\u52A1\u4EE5\u626B\u63CF\u5DE5\u5177\u5217\u8868"));return}e.succeed(`\u670D\u52A1 '${o}' \u5171\u6709 ${r.length} \u4E2A\u5DE5\u5177`),console.log(),console.log(h.bold(`${o} \u670D\u52A1\u5DE5\u5177\u5217\u8868:`)),console.log();let i=new Ge({head:[h.bold("\u5DE5\u5177\u540D\u79F0"),h.bold("\u72B6\u6001"),h.bold("\u63CF\u8FF0")],colWidths:[30,8,50],wordWrap:!0,style:{head:[],border:[]}});for(let s of r){let l=n[s],p=l.enable?h.green("\u542F\u7528"):h.red("\u7981\u7528"),f=Ke(l.description||"",40);i.push([s,p,f])}console.log(i.toString()),console.log(),console.log(h.gray("\u{1F4A1} \u63D0\u793A:")),console.log(h.gray(` - \u4F7F\u7528 'xiaozhi mcp ${o} <\u5DE5\u5177\u540D> enable' \u542F\u7528\u5DE5\u5177`)),console.log(h.gray(` - \u4F7F\u7528 'xiaozhi mcp ${o} <\u5DE5\u5177\u540D> disable' \u7981\u7528\u5DE5\u5177`))}catch(t){e.fail("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25"),console.error(h.red(`\u9519\u8BEF: ${t instanceof Error?t.message:String(t)}`)),process.exit(1)}}a(Ze,"listServerTools");async function Ve(o,e,t){let n=t?"\u542F\u7528":"\u7981\u7528",r=Pe(`${n}\u5DE5\u5177 ${o}/${e}...`).start();try{if(!g.getMcpServers()[o]){r.fail(`\u670D\u52A1 '${o}' \u4E0D\u5B58\u5728`),console.log(h.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let s=g.getServerToolsConfig(o);if(!s[e]){r.fail(`\u5DE5\u5177 '${e}' \u5728\u670D\u52A1 '${o}' \u4E2D\u4E0D\u5B58\u5728`),console.log(h.yellow(`\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp ${o} list' \u67E5\u770B\u8BE5\u670D\u52A1\u7684\u6240\u6709\u5DE5\u5177`));return}g.setToolEnabled(o,e,t,s[e].description),r.succeed(`\u6210\u529F${n}\u5DE5\u5177 ${h.cyan(o)}/${h.cyan(e)}`),console.log(),console.log(h.gray("\u{1F4A1} \u63D0\u793A: \u5DE5\u5177\u72B6\u6001\u66F4\u6539\u5C06\u5728\u4E0B\u6B21\u542F\u52A8\u670D\u52A1\u65F6\u751F\u6548"))}catch(i){r.fail(`${n}\u5DE5\u5177\u5931\u8D25`),console.error(h.red(`\u9519\u8BEF: ${i instanceof Error?i.message:String(i)}`)),process.exit(1)}}a(Ve,"setToolEnabled");var T=new Cn,vn="xiaozhi-mcp-service";function lt(){try{let o=B(import.meta.url),e=u.dirname(o),t=[u.join(e,"..","package.json"),u.join(e,"..","package.json"),u.join(e,"..","..","package.json"),u.join(e,"package.json")];for(let n of t)if(m.existsSync(n)){let r=JSON.parse(m.readFileSync(n,"utf8"));if(r.version)return r.version}return"unknown"}catch(o){return console.warn("\u65E0\u6CD5\u4ECE package.json \u8BFB\u53D6\u7248\u672C\u4FE1\u606F:",o),"unknown"}}a(lt,"getVersion");var xe=a(()=>{let o=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return u.join(o,`.${vn}.pid`)},"getPidFile");function W(){try{let o=xe();if(!m.existsSync(o))return{running:!1};let e=m.readFileSync(o,"utf8").trim(),[t,n,r]=e.split("|"),i=Number.parseInt(t);if(Number.isNaN(i))return m.unlinkSync(o),{running:!1};try{process.kill(i,0);let s=Number.parseInt(n),l=yn(Date.now()-s);return{running:!0,pid:i,uptime:l,mode:r||"foreground"}}catch{return m.unlinkSync(o),{running:!1}}}catch{return{running:!1}}}a(W,"getServiceStatus");function yn(o){let e=Math.floor(o/1e3),t=Math.floor(e/60),n=Math.floor(t/60),r=Math.floor(n/24);return r>0?`${r}\u5929 ${n%24}\u5C0F\u65F6 ${t%60}\u5206\u949F`:n>0?`${n}\u5C0F\u65F6 ${t%60}\u5206\u949F`:t>0?`${t}\u5206\u949F ${e%60}\u79D2`:`${e}\u79D2`}a(yn,"formatUptime");function $e(o,e){let t=`${o}|${Date.now()}|${e}`;m.writeFileSync(xe(),t)}a($e,"savePidInfo");function ee(){try{let o=xe();m.existsSync(o)&&m.unlinkSync(o)}catch{}}a(ee,"cleanupPidFile");function Mn(){if(!g.configExists())return console.error(c.red("\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728")),console.log(c.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E')),!1;try{let e=g.getMcpEndpoints().filter(t=>t&&!t.includes("<\u8BF7\u586B\u5199"));return e.length===0?(console.log(c.yellow("\u26A0\uFE0F \u8B66\u544A: MCP \u7AEF\u70B9\u672A\u914D\u7F6E")),console.log(c.yellow('\u{1F4A1} \u63D0\u793A: \u670D\u52A1\u5C06\u542F\u52A8\u4F46\u65E0\u6CD5\u8FDE\u63A5\u5C0F\u667A\u670D\u52A1\u7AEF\uFF0C\u8BF7\u8FD0\u884C "xiaozhi config mcpEndpoint <your-endpoint-url>" \u8BBE\u7F6E\u7AEF\u70B9')),console.log(c.gray(" MCP \u670D\u52A1\u5668\u529F\u80FD\u4ECD\u7136\u53EF\u7528\uFF0C\u53EF\u901A\u8FC7 Web \u754C\u9762\u914D\u7F6E\u7AEF\u70B9\u540E\u91CD\u542F\u670D\u52A1"))):console.log(c.green(`\u2705 \u5DF2\u914D\u7F6E ${e.length} \u4E2A\u6709\u6548\u7684 MCP \u7AEF\u70B9`)),!0}catch(o){return console.error(c.red(`\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u65E0\u6548 - ${o instanceof Error?o.message:String(o)}`)),console.log(c.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u91CD\u65B0\u521D\u59CB\u5316\u914D\u7F6E')),!1}}a(Mn,"checkEnvironment");async function gt(o=!1,e=!1){let t=E("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let n=W();if(n.running){t.fail(`\u670D\u52A1\u5DF2\u7ECF\u5728\u8FD0\u884C (PID: ${n.pid})`);return}if(t.text="\u68C0\u67E5\u73AF\u5883\u914D\u7F6E...",!Mn()){t.fail("\u73AF\u5883\u914D\u7F6E\u68C0\u67E5\u5931\u8D25");return}t.text=`\u542F\u52A8\u670D\u52A1 (${o?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"})...`,o?(await bn(e),t.succeed("\u670D\u52A1\u5DF2\u5728\u540E\u53F0\u542F\u52A8")):(await Pn(e),t.succeed("\u670D\u52A1\u5DF2\u542F\u52A8"))}catch(n){t.fail(`\u542F\u52A8\u670D\u52A1\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}a(gt,"startService");async function bn(o=!1){let{spawn:e}=await import("child_process"),t=u.dirname(B(import.meta.url)),n="node",r=[u.join(t,"webServerStandalone.js"),o?"--open-browser":""].filter(Boolean),i=e(n,r,{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.FORCE_CONFIG_DIR||process.cwd(),XIAOZHI_DAEMON:"true"}});$e(i.pid,"daemon");let s=process.cwd();d.initLogFile(s),d.enableFileLogging(!0);let l=u.join(s,"xiaozhi.log"),p=m.createWriteStream(l,{flags:"a"});i.stdout?.pipe(p),i.stderr?.pipe(p),i.on("exit",(f,S)=>{f!==0&&f!==null&&d.error(`\u540E\u53F0\u670D\u52A1\u5F02\u5E38\u9000\u51FA (\u4EE3\u7801: ${f}, \u4FE1\u53F7: ${S})`),ee()}),i.on("error",f=>{throw d.error(`\u540E\u53F0\u670D\u52A1\u542F\u52A8\u9519\u8BEF: ${f.message}`),ee(),f}),i.unref(),console.log(c.green(`\u2705 \u670D\u52A1\u5DF2\u5728\u540E\u53F0\u542F\u52A8 (PID: ${i.pid})`)),console.log(c.gray(`\u65E5\u5FD7\u6587\u4EF6: ${l}`)),console.log(c.gray("\u4F7F\u7528 'xiaozhi attach' \u53EF\u4EE5\u67E5\u770B\u5B9E\u65F6\u65E5\u5FD7")),o&&console.log(c.green("\u{1F310} \u6D4F\u89C8\u5668\u5C06\u81EA\u52A8\u6253\u5F00"))}a(bn,"startWebServerInDaemon");async function Pn(o=!1){let e=new Q,t=a(async()=>{console.log(c.yellow(`
29
- \u6B63\u5728\u505C\u6B62\u670D\u52A1...`)),await e.stop(),ee(),process.exit(0)},"cleanup");if(process.on("SIGINT",t),process.on("SIGTERM",t),$e(process.pid,"foreground"),await e.start(),o){let r=`http://localhost:${g.getWebUIPort()}`;await wn(r)}}a(Pn,"startWebServerInForeground");async function wn(o){try{let{spawn:e}=await import("child_process"),t=process.platform,n,r;t==="darwin"?(n="open",r=[o]):t==="win32"?(n="start",r=["",o]):(n="xdg-open",r=[o]),e(n,r,{detached:!0,stdio:"ignore"}),console.log(c.green(`\u{1F310} \u5DF2\u5C1D\u8BD5\u6253\u5F00\u6D4F\u89C8\u5668: ${o}`))}catch{console.log(c.yellow(`\u26A0\uFE0F \u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u8BBF\u95EE: ${o}`))}}a(wn,"openBrowserUrl");async function ht(){let o=E("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let e=W();if(!e.running){o.warn("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}o.text=`\u505C\u6B62\u670D\u52A1 (PID: ${e.pid})...`;try{process.kill(e.pid,"SIGTERM");let t=0,n=30;for(;t<n;){await new Promise(r=>setTimeout(r,100));try{process.kill(e.pid,0),t++}catch{break}}try{process.kill(e.pid,0),o.text="\u5F3A\u5236\u505C\u6B62\u670D\u52A1...",process.kill(e.pid,"SIGKILL"),await new Promise(r=>setTimeout(r,500))}catch{}ee(),o.succeed("\u670D\u52A1\u5DF2\u505C\u6B62")}catch(t){ee(),o.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}catch(e){o.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}a(ht,"stopService");async function Tn(){let o=E("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let e=W();if(e.running){if(o.succeed("\u670D\u52A1\u72B6\u6001"),console.log(c.green("\u2705 \u670D\u52A1\u6B63\u5728\u8FD0\u884C")),console.log(c.gray(` PID: ${e.pid}`)),console.log(c.gray(` \u8FD0\u884C\u65F6\u95F4: ${e.uptime}`)),console.log(c.gray(` \u8FD0\u884C\u6A21\u5F0F: ${e.mode==="daemon"?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"}`)),e.mode==="daemon"){let t=u.join(process.cwd(),"xiaozhi.log");console.log(c.gray(` \u65E5\u5FD7\u6587\u4EF6: ${t}`))}}else o.succeed("\u670D\u52A1\u72B6\u6001"),console.log(c.red("\u274C \u670D\u52A1\u672A\u8FD0\u884C"))}catch(e){o.fail(`\u68C0\u67E5\u72B6\u6001\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}a(Tn,"checkStatus");async function En(){let o=E("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{let e=W();if(!e.running){o.fail("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}if(e.mode!=="daemon"){o.fail("\u670D\u52A1\u4E0D\u662F\u5728\u540E\u53F0\u6A21\u5F0F\u8FD0\u884C");return}o.succeed("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1..."),console.log(c.green(`\u5DF2\u8FDE\u63A5\u5230\u670D\u52A1 (PID: ${e.pid})`)),console.log(c.gray("\u6309 Ctrl+C \u53EF\u4EE5\u65AD\u5F00\u8FDE\u63A5\uFF08\u4E0D\u4F1A\u505C\u6B62\u670D\u52A1\uFF09")),console.log(c.gray("=".repeat(50)));let t=u.join(process.cwd(),"xiaozhi.log");if(m.existsSync(t))if(process.platform==="win32"){let{spawn:n}=await import("child_process"),r=n("powershell",["-Command",`Get-Content -Path "${t}" -Wait`],{stdio:"inherit"});process.on("SIGINT",()=>{console.log(c.yellow(`
30
- \u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C`)),r.kill(),process.exit(0)}),r.on("exit",()=>{process.exit(0)})}else{let{spawn:n}=await import("child_process"),r=n("tail",["-f",t],{stdio:"inherit"});process.on("SIGINT",()=>{console.log(c.yellow(`
31
- \u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C`)),r.kill(),process.exit(0)}),r.on("exit",()=>{process.exit(0)})}else console.log(c.yellow("\u65E5\u5FD7\u6587\u4EF6\u4E0D\u5B58\u5728"))}catch(e){o.fail(`\u8FDE\u63A5\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}a(En,"attachService");async function In(o=!1,e=!1){console.log(c.blue("\u{1F504} \u91CD\u542F\u670D\u52A1...")),await ht(),await new Promise(t=>setTimeout(t,1e3)),await gt(o,e)}a(In,"restartService");async function Rn(o,e=!1){let t=E("\u542F\u52A8 MCP Server \u6A21\u5F0F...").start();try{if(!g.configExists()){t.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(c.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}let{MCPServer:n}=await Promise.resolve().then(()=>(at(),st));if(e){let r=B(import.meta.url),i=u.dirname(r),s=Sn("node",[u.join(i,"cli.js"),"start","--server",o.toString()],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd(),XIAOZHI_DAEMON:"true",MCP_SERVER_MODE:"true"}});$e(s.pid,"daemon");let l=u.join(process.cwd(),"xiaozhi-mcp-server.log"),p=m.createWriteStream(l,{flags:"a"});s.stdout?.pipe(p),s.stderr?.pipe(p),s.unref(),t.succeed(`MCP Server \u5DF2\u5728\u540E\u53F0\u542F\u52A8 (PID: ${s.pid}, Port: ${o})`),console.log(c.gray(`\u65E5\u5FD7\u6587\u4EF6: ${l}`))}else{let r=new n(o),i=a(async()=>{console.log(c.yellow(`
32
- \u6B63\u5728\u505C\u6B62 MCP Server...`)),await r.stop(),process.exit(0)},"cleanup");process.on("SIGINT",i),process.on("SIGTERM",i),await r.start(),t.succeed("MCP Server \u5DF2\u542F\u52A8"),console.log(c.green("\u2705 MCP Server \u7AEF\u70B9\u5DF2\u542F\u52A8\uFF0C\u53EF\u901A\u8FC7\u4EE5\u4E0B\u5730\u5740\u8BBF\u95EE:")),console.log(c.green(` SSE endpoint: http://localhost:${o}/sse`)),console.log(c.green(` Messages endpoint: http://localhost:${o}/messages`)),console.log(c.green(` RPC endpoint: http://localhost:${o}/rpc`)),console.log(c.green(" \u7F51\u7EDC\u8BBF\u95EE: \u5C06 localhost \u66FF\u6362\u4E3A\u4F60\u7684IP\u5730\u5740")),console.log(c.yellow("\u{1F4A1} \u63D0\u793A: \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1"))}}catch(n){t.fail(`\u542F\u52A8 MCP Server \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}a(Rn,"startMCPServerMode");function xn(){let o=lt();console.log(c.blue(`xiaozhi v${o}`)),console.log(c.gray("MCP Calculator Service CLI Tool")),console.log(c.gray("Built with Node.js and TypeScript")),console.log(c.gray(`Node.js: ${process.version}`)),console.log(c.gray(`Platform: ${process.platform} ${process.arch}`))}a(xn,"showDetailedInfo");async function $n(o="json"){let e=E("\u521D\u59CB\u5316\u914D\u7F6E...").start();try{if(g.configExists()){e.warn("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728"),console.log(c.yellow("\u5982\u9700\u91CD\u65B0\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u5220\u9664\u73B0\u6709\u7684\u914D\u7F6E\u6587\u4EF6"));return}g.initConfig(o),e.succeed("\u914D\u7F6E\u6587\u4EF6\u521D\u59CB\u5316\u6210\u529F");let t=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),n=`xiaozhi.config.${o}`,r=u.join(t,n);console.log(c.green(`\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u521B\u5EFA: ${n}`)),console.log(c.yellow("\u{1F4DD} \u8BF7\u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9:")),console.log(c.gray(` \u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84: ${r}`)),console.log(c.yellow("\u{1F4A1} \u6216\u8005\u4F7F\u7528\u547D\u4EE4\u8BBE\u7F6E:")),console.log(c.gray(" xiaozhi config mcpEndpoint <your-endpoint-url>"))}catch(t){e.fail(`\u521D\u59CB\u5316\u914D\u7F6E\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}a($n,"initConfig");function On(){let o=u.dirname(B(import.meta.url)),t=[u.join(o,"..","templates"),u.join(o,"templates"),u.join(o,"..","..","templates")].find(n=>m.existsSync(n));return t?m.readdirSync(t).filter(n=>{let r=u.join(t,n);return m.statSync(r).isDirectory()}):[]}a(On,"getAvailableTemplates");function ct(o,e){let t=o.length,n=e.length,r=Array(t+1).fill(null).map(()=>Array(n+1).fill(0));for(let s=0;s<=t;s++)r[s][0]=s;for(let s=0;s<=n;s++)r[0][s]=s;for(let s=1;s<=t;s++)for(let l=1;l<=n;l++)o[s-1]===e[l-1]?r[s][l]=r[s-1][l-1]:r[s][l]=Math.min(r[s-1][l]+1,r[s][l-1]+1,r[s-1][l-1]+1);let i=Math.max(t,n);return i===0?1:(i-r[t][n])/i}a(ct,"calculateSimilarity");function An(o,e){if(e.length===0)return null;let t=e[0],n=ct(o.toLowerCase(),t.toLowerCase());for(let r of e.slice(1)){let i=ct(o.toLowerCase(),r.toLowerCase());i>n&&(n=i,t=r)}return n>.5?t:null}a(An,"findSimilarTemplate");async function Nn(o){if(!process.stdin.isTTY)return console.log("n (\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883)"),!1;let e=await import("readline");return new Promise(t=>{process.stdout.write(o);let n=e.createInterface({input:process.stdin,output:process.stdout}),r=a(i=>{let s=i.trim().toLowerCase();s==="y"||s==="yes"?(n.close(),t(!0)):s==="n"||s==="no"||s===""?(n.close(),t(!1)):process.stdout.write("\u8BF7\u8F93\u5165 y \u6216 n: ")},"handleInput");n.on("line",r),n.on("SIGINT",()=>{n.close(),t(!1)})})}a(Nn,"askUserConfirmation");function Dn(o){let e={mcpEndpoint:"<\u8BF7\u586B\u5199\u4F60\u7684\u63A5\u5165\u70B9\u5730\u5740\uFF08\u83B7\u53D6\u5730\u5740\u5728 xiaozhi.me\uFF09>",mcpServers:{}},t=u.join(o,"xiaozhi.config.json");m.writeFileSync(t,JSON.stringify(e,null,2),"utf8")}a(Dn,"createBasicConfig");async function kn(o,e){let t=E("\u521D\u59CB\u5316\u9879\u76EE...").start();try{let n=u.join(process.cwd(),o);if(m.existsSync(n)){t.fail(`\u76EE\u5F55 "${o}" \u5DF2\u5B58\u5728`),console.log(c.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u9009\u62E9\u4E0D\u540C\u7684\u9879\u76EE\u540D\u79F0\u6216\u5220\u9664\u73B0\u6709\u76EE\u5F55"));return}if(e.template){t.text="\u68C0\u67E5\u6A21\u677F...";let r=On();if(r.length===0){t.fail("\u627E\u4E0D\u5230 templates \u76EE\u5F55"),console.log(c.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u786E\u4FDD xiaozhi-client \u6B63\u786E\u5B89\u88C5"));return}if(!r.includes(e.template)){t.fail(`\u6A21\u677F "${e.template}" \u4E0D\u5B58\u5728`);let S=An(e.template,r);if(S)if(console.log(c.yellow(`\u{1F4A1} \u4F60\u662F\u60F3\u4F7F\u7528\u6A21\u677F "${S}" \u5417\uFF1F`)),await Nn(c.cyan("\u786E\u8BA4\u4F7F\u7528\u6B64\u6A21\u677F\uFF1F(y/n): ")))e.template=S;else{console.log(c.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(let N of r)console.log(c.gray(` - ${N}`));return}else{console.log(c.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(let x of r)console.log(c.gray(` - ${x}`));return}}let i=u.dirname(B(import.meta.url)),l=[u.join(i,"..","templates"),u.join(i,"templates"),u.join(i,"..","..","templates")].find(S=>m.existsSync(S)),p=u.join(l,e.template);t.text=`\u4ECE\u6A21\u677F "${e.template}" \u521B\u5EFA\u9879\u76EE "${o}"...`,pt(p,n,["node_modules",".pnpm-debug.log","pnpm-lock.yaml"]);let f=u.join(n,"xiaozhi.log");m.existsSync(f)||m.writeFileSync(f,"","utf8"),t.succeed(`\u9879\u76EE "${o}" \u521B\u5EFA\u6210\u529F`),console.log(c.green("\u2705 \u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(c.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(c.gray(` cd ${o}`)),console.log(c.gray(" pnpm install # \u5B89\u88C5\u4F9D\u8D56")),console.log(c.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9")),console.log(c.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1"))}else{t.text=`\u521B\u5EFA\u57FA\u672C\u9879\u76EE "${o}"...`,m.mkdirSync(n,{recursive:!0}),Dn(n);let r=u.join(n,"xiaozhi.log");m.writeFileSync(r,"","utf8"),t.succeed(`\u9879\u76EE "${o}" \u521B\u5EFA\u6210\u529F`),console.log(c.green("\u2705 \u57FA\u672C\u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(c.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(c.gray(` cd ${o}`)),console.log(c.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9\u548C\u670D\u52A1")),console.log(c.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1")),console.log(c.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 --template \u9009\u9879\u53EF\u4EE5\u4ECE\u6A21\u677F\u521B\u5EFA\u9879\u76EE"))}}catch(n){t.fail(`\u521B\u5EFA\u9879\u76EE\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}a(kn,"createProject");function pt(o,e,t=[]){m.existsSync(e)||m.mkdirSync(e,{recursive:!0});let n=m.readdirSync(o);for(let r of n){if(t.some(p=>r.includes(p)))continue;let i=u.join(o,r),s=u.join(e,r);m.statSync(i).isDirectory()?pt(i,s,t):m.copyFileSync(i,s)}}a(pt,"copyDirectory");async function zn(){let o=E("\u542F\u52A8 UI \u670D\u52A1...").start();try{if(!g.configExists()){o.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(c.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}let e=new Q;await e.start(),o.succeed("UI \u670D\u52A1\u5DF2\u542F\u52A8");let t=g.getWebUIPort();console.log(c.green("\u2705 \u914D\u7F6E\u7BA1\u7406\u7F51\u9875\u5DF2\u542F\u52A8\uFF0C\u53EF\u901A\u8FC7\u4EE5\u4E0B\u5730\u5740\u8BBF\u95EE:")),console.log(c.green(` \u672C\u5730\u8BBF\u95EE: http://localhost:${t}`)),console.log(c.green(` \u7F51\u7EDC\u8BBF\u95EE: http://<\u4F60\u7684IP\u5730\u5740>:${t}`)),console.log(c.yellow("\u{1F4A1} \u63D0\u793A: \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1"));let{spawn:n}=await import("child_process"),r=`http://localhost:${t}`;try{let s;process.platform==="darwin"?s=n("open",[r],{detached:!0,stdio:"ignore"}):process.platform==="win32"?s=n("cmd",["/c","start",r],{detached:!0,stdio:"ignore"}):s=n("xdg-open",[r],{detached:!0,stdio:"ignore"}),s.on("error",()=>{console.log(c.gray(`\u{1F4A1} \u63D0\u793A: \u65E0\u6CD5\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u624B\u52A8\u8BBF\u95EE: ${r}`))}),s.unref()}catch{console.log(c.gray(`\u{1F4A1} \u63D0\u793A: \u65E0\u6CD5\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u624B\u52A8\u8BBF\u95EE: ${r}`))}let i=!1;process.on("SIGINT",async()=>{i&&(console.log(c.red(`
33
- \u5F3A\u5236\u9000\u51FA...`)),process.exit(1)),i=!0,console.log(c.yellow(`
34
- \u6B63\u5728\u505C\u6B62 UI \u670D\u52A1...`));try{await e.stop(),console.log(c.green("UI \u670D\u52A1\u5DF2\u505C\u6B62"))}catch{console.log(c.red("\u505C\u6B62\u670D\u52A1\u65F6\u51FA\u9519\uFF0C\u5F3A\u5236\u9000\u51FA"))}process.exit(0)}),process.on("SIGTERM",async()=>{i=!0,await e.stop(),process.exit(0)})}catch(e){o.fail(`\u542F\u52A8 UI \u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}a(zn,"startUIService");async function jn(o,e){let t=E("\u66F4\u65B0\u914D\u7F6E...").start();try{if(!g.configExists()){t.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(c.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}if(e)switch(o){case"mcpEndpoint":g.updateMcpEndpoint(e),t.succeed(`MCP \u7AEF\u70B9\u5DF2\u66F4\u65B0\u4E3A: ${e}`);break;case"heartbeatInterval":{let n=Number.parseInt(e,10);if(Number.isNaN(n)||n<=0){t.fail("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}g.setHeartbeatInterval(n),t.succeed(`\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5DF2\u66F4\u65B0\u4E3A: ${n}ms`);break}case"heartbeatTimeout":{let n=Number.parseInt(e,10);if(Number.isNaN(n)||n<=0){t.fail("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}g.setHeartbeatTimeout(n),t.succeed(`\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5DF2\u66F4\u65B0\u4E3A: ${n}ms`);break}case"reconnectInterval":{let n=Number.parseInt(e,10);if(Number.isNaN(n)||n<=0){t.fail("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u662F\u5927\u4E8E0\u7684\u6570\u5B57\uFF08\u6BEB\u79D2\uFF09");return}g.setReconnectInterval(n),t.succeed(`\u91CD\u8FDE\u95F4\u9694\u5DF2\u66F4\u65B0\u4E3A: ${n}ms`);break}default:t.fail(`\u914D\u7F6E\u9879 ${o} \u4E0D\u652F\u6301\u901A\u8FC7\u547D\u4EE4\u884C\u8BBE\u7F6E`),console.log(c.yellow("\u652F\u6301\u8BBE\u7F6E\u7684\u914D\u7F6E\u9879: mcpEndpoint, heartbeatInterval, heartbeatTimeout, reconnectInterval"));return}else{t.text="\u8BFB\u53D6\u914D\u7F6E...";let n=g.getConfig();switch(o){case"mcpEndpoint":{t.succeed("\u914D\u7F6E\u4FE1\u606F");let r=g.getMcpEndpoints();r.length===0?console.log(c.yellow("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u7AEF\u70B9")):r.length===1?console.log(c.green(`MCP \u7AEF\u70B9: ${r[0]}`)):(console.log(c.green(`MCP \u7AEF\u70B9 (${r.length} \u4E2A):`)),r.forEach((i,s)=>{console.log(c.gray(` ${s+1}. ${i}`))}));break}case"mcpServers":t.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(c.green("MCP \u670D\u52A1:"));for(let[r,i]of Object.entries(n.mcpServers))"type"in i&&i.type==="sse"?console.log(c.gray(` ${r}: [SSE] ${i.url}`)):console.log(c.gray(` ${r}: ${i.command} ${i.args.join(" ")}`));break;case"connection":{t.succeed("\u914D\u7F6E\u4FE1\u606F");let r=g.getConnectionConfig();console.log(c.green("\u8FDE\u63A5\u914D\u7F6E:")),console.log(c.gray(` \u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694: ${r.heartbeatInterval}ms`)),console.log(c.gray(` \u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4: ${r.heartbeatTimeout}ms`)),console.log(c.gray(` \u91CD\u8FDE\u95F4\u9694: ${r.reconnectInterval}ms`));break}case"heartbeatInterval":t.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(c.green(`\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694: ${g.getHeartbeatInterval()}ms`));break;case"heartbeatTimeout":t.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(c.green(`\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4: ${g.getHeartbeatTimeout()}ms`));break;case"reconnectInterval":t.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(c.green(`\u91CD\u8FDE\u95F4\u9694: ${g.getReconnectInterval()}ms`));break;default:t.fail(`\u672A\u77E5\u7684\u914D\u7F6E\u9879: ${o}`),console.log(c.yellow("\u652F\u6301\u7684\u914D\u7F6E\u9879: mcpEndpoint, mcpServers, connection, heartbeatInterval, heartbeatTimeout, reconnectInterval"));return}}}catch(n){t.fail(`\u914D\u7F6E\u64CD\u4F5C\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}a(jn,"configCommand");function Hn(){console.log(c.blue.bold("xiaozhi - MCP Calculator Service CLI")),console.log(),console.log(c.yellow("\u4F7F\u7528\u65B9\u6CD5:")),console.log(" xiaozhi <command> [options]"),console.log(),console.log(c.yellow("\u547D\u4EE4:")),console.log(" create <projectName> \u521B\u5EFA\u9879\u76EE"),console.log(" init \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6"),console.log(" config <key> [value] \u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E"),console.log(" start [--daemon] [--ui] [--server] \u542F\u52A8\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C, --ui \u540C\u65F6\u542F\u52A8 Web UI, --server MCP Server \u6A21\u5F0F)"),console.log(" stop \u505C\u6B62\u670D\u52A1"),console.log(" status \u68C0\u67E5\u670D\u52A1\u72B6\u6001"),console.log(" attach \u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7"),console.log(" restart [--daemon] [--ui] \u91CD\u542F\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C, --ui \u540C\u65F6\u542F\u52A8 Web UI)"),console.log(" ui \u542F\u52A8\u914D\u7F6E\u7BA1\u7406\u7F51\u9875"),console.log(),console.log(c.yellow("\u9009\u9879:")),console.log(" -v, --version \u663E\u793A\u7248\u672C\u4FE1\u606F"),console.log(" -V \u663E\u793A\u8BE6\u7EC6\u4FE1\u606F"),console.log(" -h, --help \u663E\u793A\u5E2E\u52A9\u4FE1\u606F"),console.log(" -t, --template <name> \u6307\u5B9A\u6A21\u677F\u540D\u79F0\uFF08\u7528\u4E8E create \u547D\u4EE4\uFF09"),console.log(),console.log(c.yellow("\u9879\u76EE\u793A\u4F8B:")),console.log(" xiaozhi create my-app # \u521B\u5EFA\u57FA\u672C\u9879\u76EE"),console.log(" xiaozhi create my-app -t hello-world # \u4F7F\u7528 hello-world \u6A21\u677F"),console.log(" xiaozhi create my-app --template hello-world # \u540C\u4E0A\uFF0C\u5B8C\u6574\u9009\u9879\u540D"),console.log(),console.log(c.yellow("\u914D\u7F6E\u793A\u4F8B:")),console.log(" xiaozhi init # \u521D\u59CB\u5316\u914D\u7F6E"),console.log(" xiaozhi config mcpEndpoint # \u67E5\u770B MCP \u7AEF\u70B9"),console.log(" xiaozhi config mcpEndpoint wss://... # \u8BBE\u7F6E MCP \u7AEF\u70B9"),console.log(),console.log(c.yellow("\u670D\u52A1\u793A\u4F8B:")),console.log(" xiaozhi start # \u524D\u53F0\u542F\u52A8\u670D\u52A1"),console.log(" xiaozhi start --daemon # \u540E\u53F0\u542F\u52A8\u670D\u52A1"),console.log(" xiaozhi start --ui # \u542F\u52A8\u670D\u52A1\u5E76\u540C\u65F6\u542F\u52A8 Web UI"),console.log(" xiaozhi start -d -u # \u540E\u53F0\u542F\u52A8\u670D\u52A1\u5E76\u540C\u65F6\u542F\u52A8 Web UI"),console.log(" xiaozhi start --server # \u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8 (\u7AEF\u53E3 3000)"),console.log(" xiaozhi start -s 8080 # \u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8 (\u7AEF\u53E3 8080)"),console.log(" xiaozhi start -s -d # \u540E\u53F0\u8FD0\u884C MCP Server"),console.log(" xiaozhi status # \u68C0\u67E5\u670D\u52A1\u72B6\u6001"),console.log(" xiaozhi attach # \u67E5\u770B\u540E\u53F0\u670D\u52A1\u65E5\u5FD7"),console.log(" xiaozhi stop # \u505C\u6B62\u670D\u52A1"),console.log(),console.log(c.yellow("MCP \u7BA1\u7406\u793A\u4F8B:")),console.log(" xiaozhi mcp list # \u5217\u51FA\u6240\u6709 MCP \u670D\u52A1"),console.log(" xiaozhi mcp list --tools # \u5217\u51FA\u6240\u6709\u670D\u52A1\u7684\u5DE5\u5177"),console.log(" xiaozhi mcp server <name> # \u5217\u51FA\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177"),console.log(" xiaozhi mcp tool <server> <tool> enable # \u542F\u7528\u5DE5\u5177"),console.log(" xiaozhi mcp tool <server> <tool> disable # \u7981\u7528\u5DE5\u5177"),console.log()}a(Hn,"showHelp");T.name("xiaozhi").description("MCP Calculator Service CLI Tool").version(lt(),"-v, --version","\u663E\u793A\u7248\u672C\u4FE1\u606F").helpOption("-h, --help","\u663E\u793A\u5E2E\u52A9\u4FE1\u606F");T.command("create <projectName>").description("\u521B\u5EFA\u9879\u76EE").option("-t, --template <templateName>","\u4F7F\u7528\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u9879\u76EE").action(async(o,e)=>{await kn(o,e)});T.command("init").description("\u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6").option("-f, --format <format>","\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F (json, json5, jsonc)","json").action(async o=>{let e=o.format;e!=="json"&&e!=="json5"&&e!=="jsonc"&&(console.error(c.red("\u9519\u8BEF: \u683C\u5F0F\u5FC5\u987B\u662F json, json5 \u6216 jsonc")),process.exit(1)),await $n(e)});T.command("config <key> [value]").description("\u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E").action(async(o,e)=>{await jn(o,e)});T.command("start").description("\u542F\u52A8\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").option("-u, --ui","\u540C\u65F6\u542F\u52A8 Web UI \u670D\u52A1").option("-s, --server [port]","\u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8 (\u53EF\u9009\u6307\u5B9A\u7AEF\u53E3\uFF0C\u9ED8\u8BA4 3000)").option("--stdio","\u4EE5 stdio \u6A21\u5F0F\u8FD0\u884C MCP Server (\u7528\u4E8E Cursor \u7B49\u5BA2\u6237\u7AEF)").action(async o=>{if(o.stdio){let{spawn:e}=await import("child_process"),t=B(import.meta.url),n=u.dirname(t),r=u.join(n,"mcpServerProxy.js");e("node",[r],{stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}})}else if(o.server){let e=typeof o.server=="string"?Number.parseInt(o.server):3e3;await Rn(e,o.daemon)}else await gt(o.daemon,o.ui)});T.command("stop").description("\u505C\u6B62\u670D\u52A1").action(async()=>{await ht()});T.command("status").description("\u68C0\u67E5\u670D\u52A1\u72B6\u6001").action(async()=>{await Tn()});T.command("attach").description("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7").action(async()=>{await En()});T.command("restart").description("\u91CD\u542F\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").option("-u, --ui","\u540C\u65F6\u542F\u52A8 Web UI \u670D\u52A1").action(async o=>{await In(o.daemon,o.ui)});var Oe=T.command("mcp").description("MCP \u670D\u52A1\u548C\u5DE5\u5177\u7BA1\u7406");Oe.command("list").description("\u5217\u51FA MCP \u670D\u52A1").option("--tools","\u663E\u793A\u6240\u6709\u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868").action(async o=>{await qe(o)});Oe.command("server <serverName>").description("\u7BA1\u7406\u6307\u5B9A\u7684 MCP \u670D\u52A1").action(async o=>{await Ze(o)});Oe.command("tool <serverName> <toolName> <action>").description("\u542F\u7528\u6216\u7981\u7528\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177").action(async(o,e,t)=>{t!=="enable"&&t!=="disable"&&(console.error(c.red("\u9519\u8BEF: \u64CD\u4F5C\u5FC5\u987B\u662F 'enable' \u6216 'disable'")),process.exit(1)),await Ve(o,e,t==="enable")});var ge=T.command("endpoint").description("\u7BA1\u7406 MCP \u7AEF\u70B9");ge.command("list").description("\u5217\u51FA\u6240\u6709 MCP \u7AEF\u70B9").action(async()=>{let o=E("\u8BFB\u53D6\u7AEF\u70B9\u914D\u7F6E...").start();try{let e=g.getMcpEndpoints();o.succeed("\u7AEF\u70B9\u5217\u8868"),e.length===0?console.log(c.yellow("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u7AEF\u70B9")):(console.log(c.green(`\u5171 ${e.length} \u4E2A\u7AEF\u70B9:`)),e.forEach((t,n)=>{console.log(c.gray(` ${n+1}. ${t}`))}))}catch(e){o.fail(`\u8BFB\u53D6\u7AEF\u70B9\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}});ge.command("add <url>").description("\u6DFB\u52A0\u65B0\u7684 MCP \u7AEF\u70B9").action(async o=>{let e=E("\u6DFB\u52A0\u7AEF\u70B9...").start();try{g.addMcpEndpoint(o),e.succeed(`\u6210\u529F\u6DFB\u52A0\u7AEF\u70B9: ${o}`);let t=g.getMcpEndpoints();console.log(c.gray(`\u5F53\u524D\u5171 ${t.length} \u4E2A\u7AEF\u70B9`))}catch(t){e.fail(`\u6DFB\u52A0\u7AEF\u70B9\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}});ge.command("remove <url>").description("\u79FB\u9664\u6307\u5B9A\u7684 MCP \u7AEF\u70B9").action(async o=>{let e=E("\u79FB\u9664\u7AEF\u70B9...").start();try{g.removeMcpEndpoint(o),e.succeed(`\u6210\u529F\u79FB\u9664\u7AEF\u70B9: ${o}`);let t=g.getMcpEndpoints();console.log(c.gray(`\u5F53\u524D\u5269\u4F59 ${t.length} \u4E2A\u7AEF\u70B9`))}catch(t){e.fail(`\u79FB\u9664\u7AEF\u70B9\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}});ge.command("set <urls...>").description("\u8BBE\u7F6E MCP \u7AEF\u70B9\uFF08\u53EF\u4EE5\u662F\u5355\u4E2A\u6216\u591A\u4E2A\uFF09").action(async o=>{let e=E("\u8BBE\u7F6E\u7AEF\u70B9...").start();try{if(o.length===1)g.updateMcpEndpoint(o[0]),e.succeed(`\u6210\u529F\u8BBE\u7F6E\u7AEF\u70B9: ${o[0]}`);else{g.updateMcpEndpoint(o),e.succeed(`\u6210\u529F\u8BBE\u7F6E ${o.length} \u4E2A\u7AEF\u70B9`);for(let[t,n]of o.entries())console.log(c.gray(` ${t+1}. ${n}`))}}catch(t){e.fail(`\u8BBE\u7F6E\u7AEF\u70B9\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}});T.command("ui").description("\u542F\u52A8\u914D\u7F6E\u7BA1\u7406\u7F51\u9875").action(async()=>{await zn()});T.option("-V","\u663E\u793A\u8BE6\u7EC6\u4FE1\u606F").action(o=>{o.V&&(xn(),process.exit(0))});process.argv.length<=2&&(Hn(),process.exit(0));T.parse(process.argv);export{ct as calculateSimilarity,Mn as checkEnvironment,yn as formatUptime,W as getServiceStatus,lt as getVersion};
35
+ `);let s=t;if(s==="/"&&(s="/index.html"),s.includes(".."))return e.text("Forbidden",403);let c=fe(o,s);if(!Ct(c)){let ee=fe(o,"index.html");if(Ct(ee)){let Ze=await yn(ee);return e.html(Ze.toString())}return e.text("Not Found",404)}let l=await yn(c),d=c.split(".").pop()?.toLowerCase(),Q={html:"text/html",js:"application/javascript",css:"text/css",json:"application/json",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",svg:"image/svg+xml",ico:"image/x-icon"}[d||""]||"application/octet-stream";return Q.startsWith("text/")||Q.includes("javascript")||Q.includes("json")?e.text(l.toString(),200,{"Content-Type":Q}):e.body(l,200,{"Content-Type":Q})}catch(n){return this.logger.error("Serve static file error:",n),e.text("Internal Server Error",500)}}setupWebSocket(){this.wss&&this.wss.on("connection",e=>{this.logger.debug("WebSocket client connected"),e.on("message",async t=>{try{let n=JSON.parse(t.toString());await this.handleWebSocketMessage(e,n)}catch(n){this.logger.error("WebSocket message error:",n),e.send(JSON.stringify({type:"error",error:n instanceof Error?n.message:String(n)}))}}),e.on("close",()=>{this.logger.debug("WebSocket client disconnected")}),this.sendInitialData(e)})}async handleWebSocketMessage(e,t){switch(t.type){case"getConfig":{let n=m.getConfig();this.logger.debug("getConfig ws getConfig",n),e.send(JSON.stringify({type:"config",data:n}));break}case"updateConfig":this.updateConfig(t.config),this.broadcastConfigUpdate(t.config);break;case"getStatus":e.send(JSON.stringify({type:"status",data:this.clientInfo}));break;case"clientStatus":{this.updateClientInfo(t.data),this.broadcastStatusUpdate();let n=m.getConfig();e.send(JSON.stringify({type:"configUpdate",data:n}));break}case"restartService":this.logger.info("\u6536\u5230\u624B\u52A8\u91CD\u542F\u670D\u52A1\u8BF7\u6C42"),this.broadcastRestartStatus("restarting"),setTimeout(async()=>{try{await this.restartService(),setTimeout(()=>{this.broadcastRestartStatus("completed")},5e3)}catch(n){this.logger.error(`\u624B\u52A8\u91CD\u542F\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),this.broadcastRestartStatus("failed",n instanceof Error?n.message:"\u672A\u77E5\u9519\u8BEF")}},500);break}}async sendInitialData(e){let t=m.getConfig();e.send(JSON.stringify({type:"config",data:t})),e.send(JSON.stringify({type:"status",data:this.clientInfo})),setTimeout(()=>{let n=m.getConfig();e.send(JSON.stringify({type:"configUpdate",data:n}))},2e3)}broadcastConfigUpdate(e){if(!this.wss)return;let t=JSON.stringify({type:"configUpdate",data:e});for(let n of this.wss.clients)n.readyState===1&&n.send(t)}broadcastRestartStatus(e,t){if(!this.wss)return;let n=JSON.stringify({type:"restartStatus",data:{status:e,error:t,timestamp:Date.now()}});for(let r of this.wss.clients)r.readyState===1&&r.send(n)}broadcastStatusUpdate(){if(!this.wss)return;let e=JSON.stringify({type:"statusUpdate",data:this.clientInfo});for(let t of this.wss.clients)t.readyState===1&&t.send(e)}updateClientInfo(e){this.clientInfo={...this.clientInfo,...e},e.lastHeartbeat&&(this.clientInfo.lastHeartbeat=Date.now()),e.status==="connected"&&this.resetHeartbeatTimeout()}resetHeartbeatTimeout(){this.heartbeatTimeout&&clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=setTimeout(()=>{this.logger.warn("\u5BA2\u6237\u7AEF\u5FC3\u8DF3\u8D85\u65F6\uFF0C\u6807\u8BB0\u4E3A\u65AD\u5F00\u8FDE\u63A5"),this.updateClientInfo({status:"disconnected"}),this.broadcastStatusUpdate()},this.HEARTBEAT_TIMEOUT)}updateConfig(e){e.mcpEndpoint!==m.getMcpEndpoint()&&m.updateMcpEndpoint(e.mcpEndpoint);let t=m.getMcpServers();for(let[n,r]of Object.entries(e.mcpServers))JSON.stringify(t[n])!==JSON.stringify(r)&&m.updateMcpServer(n,r);for(let n of Object.keys(t))n in e.mcpServers||(m.removeMcpServer(n),m.removeServerToolsConfig(n));if(e.connection&&m.updateConnectionConfig(e.connection),e.modelscope&&m.updateModelScopeConfig(e.modelscope),e.webUI&&m.updateWebUIConfig(e.webUI),e.mcpServerConfig)for(let[n,r]of Object.entries(e.mcpServerConfig))for(let[o,s]of Object.entries(r.tools))m.setToolEnabled(n,o,s.enable)}async restartService(){this.logger.info("\u6B63\u5728\u91CD\u542F MCP \u670D\u52A1..."),this.heartbeatTimeout&&(clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=void 0);try{let n=await(await ve()).get("serviceManager").getStatus();if(!n.running){this.logger.warn("MCP \u670D\u52A1\u672A\u8FD0\u884C\uFF0C\u5C1D\u8BD5\u542F\u52A8\u670D\u52A1"),Sn("xiaozhi",["start","--daemon"],{detached:!0,stdio:"ignore",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}}).unref(),this.logger.info("MCP \u670D\u52A1\u542F\u52A8\u547D\u4EE4\u5DF2\u53D1\u9001");return}let r=n.mode==="daemon",o=["restart"];r&&o.push("--daemon"),Sn("xiaozhi",o,{detached:!0,stdio:"ignore",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}}).unref(),this.logger.info("MCP \u670D\u52A1\u91CD\u542F\u547D\u4EE4\u5DF2\u53D1\u9001"),this.resetHeartbeatTimeout()}catch(e){throw this.logger.error(`\u91CD\u542F\u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),this.resetHeartbeatTimeout(),e}}updateStatus(e){this.updateClientInfo(e),this.broadcastStatusUpdate()}async start(){if(this.httpServer){this.logger.warn("Web server is already running");return}let e=Ur({fetch:this.app.fetch,port:this.port,hostname:"0.0.0.0",createServer:jr});this.httpServer=e,this.wss=new Br({server:this.httpServer}),this.setupWebSocket(),this.logger.info(`Web server listening on http://0.0.0.0:${this.port}`),this.logger.info(`Local access: http://localhost:${this.port}`);try{await this.initializeConnections(),this.logger.info("\u6240\u6709\u8FDE\u63A5\u521D\u59CB\u5316\u5B8C\u6210")}catch(t){this.logger.error("\u8FDE\u63A5\u521D\u59CB\u5316\u5931\u8D25\uFF0C\u4F46 Web \u670D\u52A1\u5668\u7EE7\u7EED\u8FD0\u884C:",t)}}stop(){return new Promise(e=>{let t=!1,n=a(()=>{t||(t=!0,e())},"doResolve");if(this.proxyMCPServer?.disconnect(),this.heartbeatTimeout&&(clearTimeout(this.heartbeatTimeout),this.heartbeatTimeout=void 0),this.wss){for(let r of this.wss.clients)r.terminate();this.wss.close(()=>{this.httpServer?this.httpServer.close(()=>{this.logger.info("Web server stopped"),n()}):(this.logger.info("Web server stopped"),n()),setTimeout(()=>{this.logger.info("Web server force stopped"),n()},2e3)})}else this.logger.info("Web server stopped"),n()})}}});var wn={};k(wn,{ServiceManagerImpl:()=>bt});var bt,Mn=h(()=>{"use strict";B();ge();Ee();Ae();bt=class{constructor(e,t,n){this.processManager=e;this.configManager=t;this.logger=n}static{a(this,"ServiceManagerImpl")}async start(e){try{this.validateStartOptions(e),this.processManager.cleanupContainerState();let t=this.getStatus();if(t.running)throw M.alreadyRunning(t.pid);switch(this.checkEnvironment(),e.mode){case"mcp-server":await this.startMcpServerMode(e);break;case"stdio":await this.startStdioMode(e);break;case"normal":await this.startNormalMode(e);break;default:await this.startNormalMode(e);break}}catch(t){throw t instanceof M?t:M.startFailed(t instanceof Error?t.message:String(t))}}async stop(){try{let e=this.getStatus();if(!e.running)throw M.notRunning();await this.processManager.gracefulKillProcess(e.pid),this.processManager.cleanupPidFile()}catch(e){throw e instanceof M?e:new M(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}async restart(e){try{this.getStatus().running&&(await this.stop(),await new Promise(n=>setTimeout(n,1e3))),await this.start(e)}catch(t){throw new M(`\u91CD\u542F\u670D\u52A1\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}getStatus(){return this.processManager.getServiceStatus()}validateStartOptions(e){if(e.port!==void 0&&H.validatePort(e.port),e.mode&&!["normal","mcp-server","stdio"].includes(e.mode))throw new M(`\u65E0\u6548\u7684\u8FD0\u884C\u6A21\u5F0F: ${e.mode}`)}checkEnvironment(){if(!this.configManager.configExists())throw ne.configNotFound();try{if(!this.configManager.getConfig())throw new ne("\u914D\u7F6E\u6587\u4EF6\u65E0\u6548")}catch(e){throw e instanceof ne?e:new ne(`\u914D\u7F6E\u6587\u4EF6\u9519\u8BEF: ${e instanceof Error?e.message:String(e)}`)}}async startNormalMode(e){let{spawn:t}=await import("child_process");e.daemon?await this.startWebServerInDaemon(e.ui||!1):await this.startWebServerInForeground(e.ui||!1)}async startMcpServerMode(e){let t=e.port||3e3,{spawn:n}=await import("child_process");if(e.daemon){let r=w.getExecutablePath("cli"),o=n("node",[r,"start","--server",t.toString()],{detached:!0,stdio:["ignore","ignore","ignore"],env:{...process.env,XIAOZHI_CONFIG_DIR:w.getConfigDir(),XIAOZHI_DAEMON:"true",MCP_SERVER_MODE:"true"}});this.processManager.savePidInfo(o.pid,"daemon"),o.unref(),console.log(`\u2705 MCP Server \u5DF2\u5728\u540E\u53F0\u542F\u52A8 (PID: ${o.pid}, Port: ${t})`),console.log("\u{1F4A1} \u4F7F\u7528 'xiaozhi status' \u67E5\u770B\u72B6\u6001"),process.exit(0)}else{let{MCPServer:r}=await Promise.resolve().then(()=>(cn(),an)),o=new r(t),s=a(async()=>{await o.stop(),process.exit(0)},"cleanup");process.on("SIGINT",s),process.on("SIGTERM",s),await o.start()}}async startStdioMode(e){let{spawn:t}=await import("child_process"),n=w.getMcpServerProxyPath(),r=t("node",[n],{stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:w.getConfigDir()}});this.processManager.savePidInfo(r.pid,"foreground")}async startWebServerInDaemon(e){let{spawn:t}=await import("child_process"),n=w.getWebServerStandalonePath();if(!(await import("fs")).default.existsSync(n))throw new M(`WebServer \u6587\u4EF6\u4E0D\u5B58\u5728: ${n}`);let o=[n];e&&o.push("--open-browser");let s=t("node",o,{detached:!0,stdio:["ignore","ignore","ignore"],env:{...process.env,XIAOZHI_CONFIG_DIR:w.getConfigDir(),XIAOZHI_DAEMON:"true"}});this.processManager.savePidInfo(s.pid,"daemon"),s.unref(),console.log(`\u2705 \u540E\u53F0\u670D\u52A1\u5DF2\u542F\u52A8 (PID: ${s.pid})`),console.log("\u{1F4A1} \u4F7F\u7528 'xiaozhi status' \u67E5\u770B\u72B6\u6001"),console.log("\u{1F4A1} \u4F7F\u7528 'xiaozhi attach' \u67E5\u770B\u65E5\u5FD7"),process.exit(0)}async startWebServerInForeground(e){let{WebServer:t}=await Promise.resolve().then(()=>(wt(),yt)),n=new t,r=a(async()=>{await n.stop(),this.processManager.cleanupPidFile(),process.exit(0)},"cleanup");if(process.on("SIGINT",r),process.on("SIGTERM",r),this.processManager.savePidInfo(process.pid,"foreground"),await n.start(),e){let s=this.configManager.getConfig()?.webServer?.port||9999;await this.openBrowserUrl(`http://localhost:${s}`)}}async openBrowserUrl(e){try{let{spawn:t}=await import("child_process"),n=F.getCurrentPlatform(),r,o;n==="darwin"?(r="open",o=[e]):n==="win32"?(r="start",o=["",e]):(r="xdg-open",o=[e]),t(r,o,{detached:!0,stdio:"ignore"}),console.log(`\u{1F310} \u5DF2\u5C1D\u8BD5\u6253\u5F00\u6D4F\u89C8\u5668: ${e}`)}catch{console.log(`\u26A0\uFE0F \u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u8BBF\u95EE: ${e}`)}}}});var bn={};k(bn,{TemplateManagerImpl:()=>Et});import Vr from"fs";import re from"path";var Et,En=h(()=>{"use strict";B();be();ge();Ae();Et=class{static{a(this,"TemplateManagerImpl")}templateCache=new Map;async getAvailableTemplates(){try{let e=w.findTemplatesDir();if(!e)return[];let t=[],n=Vr.readdirSync(e,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name);for(let r of n)try{let o=await this.getTemplateInfo(r);o&&t.push(o)}catch{console.warn(`\u8DF3\u8FC7\u65E0\u6548\u6A21\u677F: ${r}`)}return t}catch{throw new p("\u65E0\u6CD5\u8BFB\u53D6\u6A21\u677F\u76EE\u5F55",w.findTemplatesDir()||"")}}async getTemplateInfo(e){try{if(H.validateTemplateName(e),this.templateCache.has(e))return this.templateCache.get(e);let t=w.getTemplatePath(e);if(!t)return null;let n=re.join(t,"template.json"),r={};if(C.exists(n))try{let c=C.readFile(n);r=JSON.parse(c)}catch{console.warn(`\u6A21\u677F\u914D\u7F6E\u6587\u4EF6\u89E3\u6790\u5931\u8D25: ${e}`)}let o=this.getTemplateFiles(t),s={name:e,path:t,description:r.description||`${e} \u6A21\u677F`,version:r.version||"1.0.0",author:r.author,files:o};return this.templateCache.set(e,s),s}catch(t){throw t instanceof v?t:new p(`\u65E0\u6CD5\u83B7\u53D6\u6A21\u677F\u4FE1\u606F: ${e}`,"")}}async copyTemplate(e,t){await this.createProject({templateName:e,targetPath:t,projectName:re.basename(t)})}async createProject(e){try{this.validateCreateOptions(e);let t=e.templateName||"default",n=await this.getTemplateInfo(t);if(!n)throw new p(`\u6A21\u677F\u4E0D\u5B58\u5728: ${t}`,"");let r=re.resolve(e.targetPath);if(C.exists(r))throw p.alreadyExists(r);C.ensureDir(r),await this.copyTemplateFiles(n,r,e),await this.processTemplateVariables(r,e),console.log(`\u2705 \u9879\u76EE\u521B\u5EFA\u6210\u529F: ${r}`)}catch(t){throw t instanceof p||t instanceof v?t:new p(`\u521B\u5EFA\u9879\u76EE\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`,e.targetPath)}}async validateTemplate(e){try{let t=await this.getTemplateInfo(e);if(!t)return!1;let n=["package.json"];for(let r of n){let o=re.join(t.path,r);if(!C.exists(o))return console.warn(`\u6A21\u677F\u7F3A\u5C11\u5FC5\u8981\u6587\u4EF6: ${r}`),!1}return!0}catch{return!1}}clearCache(){this.templateCache.clear()}getTemplateFiles(e){try{return C.listDirectory(e,{recursive:!0,includeHidden:!1}).filter(n=>{let r=re.relative(e,n);return!r.startsWith(".")&&r!=="template.json"&&!r.includes("node_modules")})}catch{return[]}}validateCreateOptions(e){H.validateRequired(e.targetPath,"targetPath"),H.validateRequired(e.projectName,"projectName"),H.validateProjectName(e.projectName),e.templateName&&H.validateTemplateName(e.templateName)}async copyTemplateFiles(e,t,n){try{C.copyDirectory(e.path,t,{exclude:["template.json",".git","node_modules"],overwrite:!1,recursive:!0})}catch(r){throw new p(`\u590D\u5236\u6A21\u677F\u6587\u4EF6\u5931\u8D25: ${r instanceof Error?r.message:String(r)}`,e.path)}}async processTemplateVariables(e,t){try{let n={PROJECT_NAME:t.projectName,PROJECT_NAME_LOWER:t.projectName.toLowerCase(),PROJECT_NAME_UPPER:t.projectName.toUpperCase(),...t.variables},r=["package.json","README.md","src/**/*.ts","src/**/*.js","src/**/*.json"];for(let o of r){let s=this.findFilesByPattern(e,o);for(let c of s)await this.replaceVariablesInFile(c,n)}}catch(n){console.warn(`\u5904\u7406\u6A21\u677F\u53D8\u91CF\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}findFilesByPattern(e,t){try{if(!t.includes("*")){let o=re.join(e,t);return C.exists(o)?[o]:[]}let n=C.listDirectory(e,{recursive:!0}),r=new RegExp(t.replace(/\*\*/g,".*").replace(/\*/g,"[^/]*"));return n.filter(o=>{let s=re.relative(e,o);return r.test(s)})}catch{return[]}}async replaceVariablesInFile(e,t){try{let n=C.readFile(e),r=!1;for(let[o,s]of Object.entries(t)){let c=new RegExp(`{{\\s*${o}\\s*}}`,"g");c.test(n)&&(n=n.replace(c,s),r=!0)}r&&C.writeFile(e,n,{overwrite:!0})}catch(n){console.warn(`\u66FF\u6362\u6587\u4EF6\u53D8\u91CF\u5931\u8D25 ${e}: ${n instanceof Error?n.message:String(n)}`)}}}});async function ve(){return Pt.create()}var Pt,Mt=h(()=>{"use strict";R();ae();ot();be();it();ge();Ee();Ae();Wt();Pt=class i{static{a(this,"DIContainer")}instances=new Map;factories=new Map;asyncFactories=new Map;singletons=new Set;register(e,t,n=!1){this.factories.set(e,t),n&&this.singletons.add(e)}registerSingleton(e,t){this.register(e,t,!0)}registerInstance(e,t){this.instances.set(e,t),this.singletons.add(e)}get(e){if(this.singletons.has(e)&&this.instances.has(e))return this.instances.get(e);let t=this.factories.get(e);if(!t)throw new Error(`Service ${e} not registered`);let n=t();return this.singletons.has(e)&&this.instances.set(e,n),n}has(e){return this.factories.has(e)||this.instances.has(e)}clear(){this.instances.clear(),this.factories.clear(),this.singletons.clear()}getRegisteredKeys(){let e=Array.from(this.factories.keys()),t=Array.from(this.instances.keys());return[...new Set([...e,...t])]}static create(){let e=new i;return e.registerSingleton("versionUtils",()=>Fe),e.registerSingleton("platformUtils",()=>F),e.registerSingleton("formatUtils",()=>le),e.registerSingleton("fileUtils",()=>C),e.registerSingleton("pathUtils",()=>w),e.registerSingleton("validation",()=>H),e.registerSingleton("configManager",()=>m),e.registerSingleton("logger",()=>f),e.registerSingleton("errorHandler",()=>V),e.registerSingleton("processManager",()=>{let t=(Vt(),W(Bt));return new t.ProcessManagerImpl}),e.registerSingleton("daemonManager",()=>{let t=(Kt(),W(Gt)),n=e.get("processManager"),r=e.get("logger");return new t.DaemonManagerImpl(n,r)}),e.registerSingleton("serviceManager",()=>{let t=(Mn(),W(wn)),n=e.get("processManager"),r=e.get("configManager"),o=e.get("logger");return new t.ServiceManagerImpl(n,r,o)}),e.registerSingleton("templateManager",()=>{let t=(En(),W(bn));return new t.TemplateManagerImpl}),e}};a(ve,"createContainer")});var A,oe=h(()=>{"use strict";A=class{constructor(e){this.container=e}static{a(this,"BaseCommandHandler")}options;subcommands;getService(e){return this.container.get(e)}handleError(e){this.getService("errorHandler").handle(e)}validateArgs(e,t){if(e.length<t)throw new Error(`\u547D\u4EE4\u9700\u8981\u81F3\u5C11 ${t} \u4E2A\u53C2\u6570\uFF0C\u4F46\u53EA\u63D0\u4F9B\u4E86 ${e.length} \u4E2A`)}}});var Pn={};k(Pn,{ServiceCommandHandler:()=>Tt});var Tt,Tn=h(()=>{"use strict";oe();Tt=class extends A{static{a(this,"ServiceCommandHandler")}name="service";description="\u670D\u52A1\u7BA1\u7406\u547D\u4EE4";subcommands=[{name:"start",description:"\u542F\u52A8\u670D\u52A1",options:[{flags:"-d, --daemon",description:"\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1"},{flags:"-u, --ui",description:"\u540C\u65F6\u542F\u52A8 Web UI \u670D\u52A1"},{flags:"-s, --server [port]",description:"\u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8 (\u53EF\u9009\u6307\u5B9A\u7AEF\u53E3\uFF0C\u9ED8\u8BA4 3000)"},{flags:"--stdio",description:"\u4EE5 stdio \u6A21\u5F0F\u8FD0\u884C MCP Server (\u7528\u4E8E Cursor \u7B49\u5BA2\u6237\u7AEF)"}],execute:a(async(e,t)=>{await this.handleStart(t)},"execute")},{name:"stop",description:"\u505C\u6B62\u670D\u52A1",execute:a(async(e,t)=>{await this.handleStop()},"execute")},{name:"status",description:"\u68C0\u67E5\u670D\u52A1\u72B6\u6001",execute:a(async(e,t)=>{await this.handleStatus()},"execute")},{name:"restart",description:"\u91CD\u542F\u670D\u52A1",options:[{flags:"-d, --daemon",description:"\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1"},{flags:"-u, --ui",description:"\u540C\u65F6\u542F\u52A8 Web UI \u670D\u52A1"}],execute:a(async(e,t)=>{await this.handleRestart(t)},"execute")},{name:"attach",description:"\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7",execute:a(async(e,t)=>{await this.handleAttach()},"execute")}];constructor(e){super(e)}async execute(e,t){console.log("\u670D\u52A1\u7BA1\u7406\u547D\u4EE4\u3002\u4F7F\u7528 --help \u67E5\u770B\u53EF\u7528\u7684\u5B50\u547D\u4EE4\u3002")}async handleStart(e){try{let t=this.getService("serviceManager");if(e.stdio)await this.startStdioMode();else if(e.server){let n=typeof e.server=="string"?Number.parseInt(e.server):3e3;await this.startMCPServerMode(n,e.daemon)}else await t.start({daemon:e.daemon||!1,ui:e.ui||!1})}catch(t){this.handleError(t)}}async handleStop(){try{await this.getService("serviceManager").stop()}catch(e){this.handleError(e)}}async handleStatus(){try{let t=await this.getService("serviceManager").getStatus();t.running?(console.log(`\u2705 \u670D\u52A1\u6B63\u5728\u8FD0\u884C (PID: ${t.pid})`),t.uptime&&console.log(`\u23F1\uFE0F \u8FD0\u884C\u65F6\u95F4: ${t.uptime}`),t.mode&&console.log(`\u{1F527} \u8FD0\u884C\u6A21\u5F0F: ${t.mode}`)):console.log("\u274C \u670D\u52A1\u672A\u8FD0\u884C")}catch(e){this.handleError(e)}}async handleRestart(e){try{await this.getService("serviceManager").restart({daemon:e.daemon||!1,ui:e.ui||!1})}catch(t){this.handleError(t)}}async handleAttach(){try{await this.getService("daemonManager").attachToLogs()}catch(e){this.handleError(e)}}async startStdioMode(){let{spawn:e}=await import("child_process"),{fileURLToPath:t}=await import("url"),n=await import("path"),r=t(import.meta.url),o=n.dirname(r),s=n.join(o,"mcpServerProxy.js");e("node",[s],{stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:process.env.XIAOZHI_CONFIG_DIR||process.cwd()}})}async startMCPServerMode(e,t){throw new Error("MCP Server \u6A21\u5F0F\u542F\u52A8\u903B\u8F91\u9700\u8981\u5B9E\u73B0")}}});var In={};k(In,{ConfigCommandHandler:()=>Rt});import Xr from"path";import S from"chalk";import It from"ora";var Rt,Rn=h(()=>{"use strict";oe();Rt=class extends A{static{a(this,"ConfigCommandHandler")}name="config";description="\u914D\u7F6E\u7BA1\u7406\u547D\u4EE4";subcommands=[{name:"init",description:"\u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6",options:[{flags:"-f, --format <format>",description:"\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F (json, json5, jsonc)",defaultValue:"json"}],execute:a(async(e,t)=>{await this.handleInit(t)},"execute")},{name:"get",description:"\u67E5\u770B\u914D\u7F6E\u503C",execute:a(async(e,t)=>{this.validateArgs(e,1),await this.handleGet(e[0])},"execute")},{name:"set",description:"\u8BBE\u7F6E\u914D\u7F6E\u503C",execute:a(async(e,t)=>{this.validateArgs(e,2),await this.handleSet(e[0],e[1])},"execute")}];constructor(e){super(e)}async execute(e,t){console.log("\u914D\u7F6E\u7BA1\u7406\u547D\u4EE4\u3002\u4F7F\u7528 --help \u67E5\u770B\u53EF\u7528\u7684\u5B50\u547D\u4EE4\u3002")}async handleInit(e){let t=It("\u521D\u59CB\u5316\u914D\u7F6E...").start();try{let n=e.format;if(n!=="json"&&n!=="json5"&&n!=="jsonc")throw new Error("\u683C\u5F0F\u5FC5\u987B\u662F json, json5 \u6216 jsonc");let r=this.getService("configManager");if(r.configExists()){t.warn("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728"),console.log(S.yellow("\u5982\u9700\u91CD\u65B0\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u5220\u9664\u73B0\u6709\u7684\u914D\u7F6E\u6587\u4EF6"));return}r.initConfig(n),t.succeed("\u914D\u7F6E\u6587\u4EF6\u521D\u59CB\u5316\u6210\u529F");let o=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),s=`xiaozhi.config.${n}`,c=Xr.join(o,s);console.log(S.green(`\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u521B\u5EFA: ${s}`)),console.log(S.yellow("\u{1F4DD} \u8BF7\u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9:")),console.log(S.gray(` \u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84: ${c}`)),console.log(S.yellow("\u{1F4A1} \u6216\u8005\u4F7F\u7528\u547D\u4EE4\u8BBE\u7F6E:")),console.log(S.gray(" xiaozhi config set mcpEndpoint <your-endpoint-url>"))}catch(n){t.fail(`\u521D\u59CB\u5316\u914D\u7F6E\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),this.handleError(n)}}async handleGet(e){let t=It("\u8BFB\u53D6\u914D\u7F6E...").start();try{let n=this.getService("configManager");if(!n.configExists()){t.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(S.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi config init" \u521D\u59CB\u5316\u914D\u7F6E'));return}let r=n.getConfig();switch(e){case"mcpEndpoint":{t.succeed("\u914D\u7F6E\u4FE1\u606F");let o=n.getMcpEndpoints();o.length===0?console.log(S.yellow("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u7AEF\u70B9")):o.length===1?console.log(S.green(`MCP \u7AEF\u70B9: ${o[0]}`)):(console.log(S.green(`MCP \u7AEF\u70B9 (${o.length} \u4E2A):`)),o.forEach((s,c)=>{console.log(S.gray(` ${c+1}. ${s}`))}));break}case"mcpServers":t.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(S.green("MCP \u670D\u52A1:"));for(let[o,s]of Object.entries(r.mcpServers)){let c=s;"type"in c&&c.type==="sse"?console.log(S.gray(` ${o}: [SSE] ${c.url}`)):console.log(S.gray(` ${o}: ${c.command} ${c.args.join(" ")}`))}break;case"connection":{t.succeed("\u914D\u7F6E\u4FE1\u606F");let o=n.getConnectionConfig();console.log(S.green("\u8FDE\u63A5\u914D\u7F6E:")),console.log(S.gray(` \u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694: ${o.heartbeatInterval}ms`)),console.log(S.gray(` \u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4: ${o.heartbeatTimeout}ms`)),console.log(S.gray(` \u91CD\u8FDE\u95F4\u9694: ${o.reconnectInterval}ms`));break}case"heartbeatInterval":t.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(S.green(`\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694: ${n.getHeartbeatInterval()}ms`));break;case"heartbeatTimeout":t.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(S.green(`\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4: ${n.getHeartbeatTimeout()}ms`));break;case"reconnectInterval":t.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(S.green(`\u91CD\u8FDE\u95F4\u9694: ${n.getReconnectInterval()}ms`));break;default:t.fail(`\u672A\u77E5\u7684\u914D\u7F6E\u9879: ${e}`),console.log(S.yellow("\u652F\u6301\u7684\u914D\u7F6E\u9879: mcpEndpoint, mcpServers, connection, heartbeatInterval, heartbeatTimeout, reconnectInterval"))}}catch(n){t.fail(`\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),this.handleError(n)}}async handleSet(e,t){let n=It("\u66F4\u65B0\u914D\u7F6E...").start();try{let r=this.getService("configManager");if(!r.configExists()){n.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(S.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi config init" \u521D\u59CB\u5316\u914D\u7F6E'));return}switch(e){case"mcpEndpoint":r.updateMcpEndpoint(t),n.succeed(`MCP \u7AEF\u70B9\u5DF2\u8BBE\u7F6E\u4E3A: ${t}`);break;case"heartbeatInterval":{let o=Number.parseInt(t);if(Number.isNaN(o)||o<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u662F\u6B63\u6574\u6570");r.updateHeartbeatInterval(o),n.succeed(`\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5DF2\u8BBE\u7F6E\u4E3A: ${o}ms`);break}case"heartbeatTimeout":{let o=Number.parseInt(t);if(Number.isNaN(o)||o<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u662F\u6B63\u6574\u6570");r.updateHeartbeatTimeout(o),n.succeed(`\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5DF2\u8BBE\u7F6E\u4E3A: ${o}ms`);break}case"reconnectInterval":{let o=Number.parseInt(t);if(Number.isNaN(o)||o<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u662F\u6B63\u6574\u6570");r.updateReconnectInterval(o),n.succeed(`\u91CD\u8FDE\u95F4\u9694\u5DF2\u8BBE\u7F6E\u4E3A: ${o}ms`);break}default:n.fail(`\u4E0D\u652F\u6301\u8BBE\u7F6E\u7684\u914D\u7F6E\u9879: ${e}`),console.log(S.yellow("\u652F\u6301\u8BBE\u7F6E\u7684\u914D\u7F6E\u9879: mcpEndpoint, heartbeatInterval, heartbeatTimeout, reconnectInterval"))}}catch(r){n.fail(`\u8BBE\u7F6E\u914D\u7F6E\u5931\u8D25: ${r instanceof Error?r.message:String(r)}`),this.handleError(r)}}}});var xn={};k(xn,{ProjectCommandHandler:()=>xt});import Gr from"path";import b from"chalk";import Kr from"ora";var xt,On=h(()=>{"use strict";oe();xt=class extends A{static{a(this,"ProjectCommandHandler")}name="create";description="\u521B\u5EFA\u9879\u76EE";options=[{flags:"-t, --template <templateName>",description:"\u4F7F\u7528\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u9879\u76EE"}];constructor(e){super(e)}async execute(e,t){this.validateArgs(e,1);let n=e[0];await this.handleCreate(n,t)}async handleCreate(e,t){let n=Kr("\u521D\u59CB\u5316\u9879\u76EE...").start();try{let r=this.getService("templateManager"),o=this.getService("fileUtils"),s=Gr.join(process.cwd(),e);if(await o.exists(s)){n.fail(`\u76EE\u5F55 "${e}" \u5DF2\u5B58\u5728`),console.log(b.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u9009\u62E9\u4E0D\u540C\u7684\u9879\u76EE\u540D\u79F0\u6216\u5220\u9664\u73B0\u6709\u76EE\u5F55"));return}t.template?await this.createFromTemplate(e,t.template,s,n,r):await this.createBasicProject(e,s,n,r)}catch(r){n.fail(`\u521B\u5EFA\u9879\u76EE\u5931\u8D25: ${r instanceof Error?r.message:String(r)}`),this.handleError(r)}}async createFromTemplate(e,t,n,r,o){r.text="\u68C0\u67E5\u6A21\u677F...";let s=await o.getAvailableTemplates();if(s.length===0){r.fail("\u627E\u4E0D\u5230\u53EF\u7528\u6A21\u677F"),console.log(b.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u786E\u4FDD xiaozhi-client \u6B63\u786E\u5B89\u88C5"));return}let c=t;if(!await o.validateTemplate(c)){r.fail(`\u6A21\u677F "${c}" \u4E0D\u5B58\u5728`);let d=this.findSimilarTemplate(c,s);if(d)if(console.log(b.yellow(`\u{1F4A1} \u4F60\u662F\u60F3\u4F7F\u7528\u6A21\u677F "${d}" \u5417\uFF1F`)),await this.askUserConfirmation(b.cyan("\u786E\u8BA4\u4F7F\u7528\u6B64\u6A21\u677F\uFF1F(y/n): ")))c=d;else{this.showAvailableTemplates(s);return}else{this.showAvailableTemplates(s);return}}r.text=`\u4ECE\u6A21\u677F "${c}" \u521B\u5EFA\u9879\u76EE "${e}"...`,await o.createProject({templateName:c,targetPath:n,projectName:e}),r.succeed(`\u9879\u76EE "${e}" \u521B\u5EFA\u6210\u529F`),console.log(b.green("\u2705 \u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(b.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(b.gray(` cd ${e}`)),console.log(b.gray(" pnpm install # \u5B89\u88C5\u4F9D\u8D56")),console.log(b.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9")),console.log(b.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1"))}async createBasicProject(e,t,n,r){n.text=`\u521B\u5EFA\u57FA\u672C\u9879\u76EE "${e}"...`,await r.createProject({templateName:null,targetPath:t,projectName:e}),n.succeed(`\u9879\u76EE "${e}" \u521B\u5EFA\u6210\u529F`),console.log(b.green("\u2705 \u57FA\u672C\u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(b.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(b.gray(` cd ${e}`)),console.log(b.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9\u548C\u670D\u52A1")),console.log(b.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1")),console.log(b.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 --template \u9009\u9879\u53EF\u4EE5\u4ECE\u6A21\u677F\u521B\u5EFA\u9879\u76EE"))}showAvailableTemplates(e){console.log(b.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(let t of e)console.log(b.gray(` - ${t}`))}findSimilarTemplate(e,t){let n=this.getService("formatUtils"),r=null,o=0;for(let s of t){let c=n.calculateSimilarity(e.toLowerCase(),s.toLowerCase());c>o&&c>.6&&(o=c,r=s)}return r}async askUserConfirmation(e){let n=(await import("readline")).createInterface({input:process.stdin,output:process.stdout});return new Promise(r=>{n.question(e,o=>{n.close(),r(o.toLowerCase().trim()==="y"||o.toLowerCase().trim()==="yes")})})}}});var Ve={};k(Ve,{getDisplayWidth:()=>$t,listMcpServers:()=>Jr,listServerTools:()=>qr,setToolEnabled:()=>Zr,truncateToWidth:()=>Dt});import g from"chalk";import $n from"cli-table3";import Ot from"ora";function $t(i){let e=0;for(let t of i)/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(t)?e+=2:e+=1;return e}function Dt(i,e){if($t(i)<=e)return i;if(e<=3)return"";let t="",n=0,r=!1;for(let o of i){let s=/[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef]/.test(o)?2:1;if(n+s>e-3){if(!r)return"";t+="...";break}t+=o,n+=s,r=!0}return t}async function Jr(i={}){let e=Ot("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868...").start();try{let t=m.getMcpServers(),n=Object.keys(t);if(n.length===0){e.warn("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1"),console.log(g.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi config' \u547D\u4EE4\u914D\u7F6E MCP \u670D\u52A1"));return}if(e.succeed(`\u627E\u5230 ${n.length} \u4E2A MCP \u670D\u52A1`),i.tools){console.log(),console.log(g.bold("MCP \u670D\u52A1\u5DE5\u5177\u5217\u8868:")),console.log();let r=8,o=[];for(let c of n){let l=m.getServerToolsConfig(c),d=Object.keys(l);o.push(...d)}for(let c of o){let l=$t(c);l>r&&(r=l)}r=Math.max(10,Math.min(r+2,30));let s=new $n({head:[g.bold("MCP"),g.bold("\u5DE5\u5177\u540D\u79F0"),g.bold("\u72B6\u6001"),g.bold("\u63CF\u8FF0")],colWidths:[15,r,8,40],wordWrap:!0,style:{head:[],border:[]}});for(let c of n){let l=m.getServerToolsConfig(c),d=Object.keys(l);if(d.length===0)s.push([g.gray(c),g.gray("-"),g.gray("-"),g.gray("\u6682\u672A\u8BC6\u522B\u5230\u76F8\u5173\u5DE5\u5177")]);else{s.length>0&&s.push([{colSpan:4,content:""}]);for(let U of d){let Q=l[U],ee=Q.enable?g.green("\u542F\u7528"):g.red("\u7981\u7528"),Ze=Dt(Q.description||"",32);s.push([c,U,ee,Ze])}}}console.log(s.toString())}else{console.log(),console.log(g.bold("MCP \u670D\u52A1\u5217\u8868:")),console.log();for(let r of n){let o=t[r],s=m.getServerToolsConfig(r),c=Object.keys(s).length,l=Object.values(s).filter(d=>d.enable!==!1).length;console.log(`${g.cyan("\u2022")} ${g.bold(r)}`),"url"in o?("type"in o&&o.type==="sse"?console.log(` \u7C7B\u578B: ${g.gray("SSE")}`):console.log(` \u7C7B\u578B: ${g.gray("Streamable HTTP")}`),console.log(` URL: ${g.gray(o.url)}`)):console.log(` \u547D\u4EE4: ${g.gray(o.command)} ${g.gray(o.args.join(" "))}`),c>0?console.log(` \u5DE5\u5177: ${g.green(l)} \u542F\u7528 / ${g.yellow(c)} \u603B\u8BA1`):console.log(` \u5DE5\u5177: ${g.gray("\u672A\u626B\u63CF (\u8BF7\u5148\u542F\u52A8\u670D\u52A1)")}`),console.log()}}console.log(g.gray("\u{1F4A1} \u63D0\u793A:")),console.log(g.gray(" - \u4F7F\u7528 'xiaozhi mcp list --tools' \u67E5\u770B\u6240\u6709\u5DE5\u5177")),console.log(g.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> list' \u67E5\u770B\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177")),console.log(g.gray(" - \u4F7F\u7528 'xiaozhi mcp <\u670D\u52A1\u540D> <\u5DE5\u5177\u540D> enable/disable' \u542F\u7528/\u7981\u7528\u5DE5\u5177"))}catch(t){e.fail("\u83B7\u53D6 MCP \u670D\u52A1\u5217\u8868\u5931\u8D25"),console.error(g.red(`\u9519\u8BEF: ${t instanceof Error?t.message:String(t)}`)),process.exit(1)}}async function qr(i){let e=Ot(`\u83B7\u53D6 ${i} \u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868...`).start();try{if(!m.getMcpServers()[i]){e.fail(`\u670D\u52A1 '${i}' \u4E0D\u5B58\u5728`),console.log(g.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let n=m.getServerToolsConfig(i),r=Object.keys(n);if(r.length===0){e.warn(`\u670D\u52A1 '${i}' \u6682\u65E0\u5DE5\u5177\u4FE1\u606F`),console.log(g.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u542F\u52A8\u670D\u52A1\u4EE5\u626B\u63CF\u5DE5\u5177\u5217\u8868"));return}e.succeed(`\u670D\u52A1 '${i}' \u5171\u6709 ${r.length} \u4E2A\u5DE5\u5177`),console.log(),console.log(g.bold(`${i} \u670D\u52A1\u5DE5\u5177\u5217\u8868:`)),console.log();let o=new $n({head:[g.bold("\u5DE5\u5177\u540D\u79F0"),g.bold("\u72B6\u6001"),g.bold("\u63CF\u8FF0")],colWidths:[30,8,50],wordWrap:!0,style:{head:[],border:[]}});for(let s of r){let c=n[s],l=c.enable?g.green("\u542F\u7528"):g.red("\u7981\u7528"),d=Dt(c.description||"",40);o.push([s,l,d])}console.log(o.toString()),console.log(),console.log(g.gray("\u{1F4A1} \u63D0\u793A:")),console.log(g.gray(` - \u4F7F\u7528 'xiaozhi mcp ${i} <\u5DE5\u5177\u540D> enable' \u542F\u7528\u5DE5\u5177`)),console.log(g.gray(` - \u4F7F\u7528 'xiaozhi mcp ${i} <\u5DE5\u5177\u540D> disable' \u7981\u7528\u5DE5\u5177`))}catch(t){e.fail("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25"),console.error(g.red(`\u9519\u8BEF: ${t instanceof Error?t.message:String(t)}`)),process.exit(1)}}async function Zr(i,e,t){let n=t?"\u542F\u7528":"\u7981\u7528",r=Ot(`${n}\u5DE5\u5177 ${i}/${e}...`).start();try{if(!m.getMcpServers()[i]){r.fail(`\u670D\u52A1 '${i}' \u4E0D\u5B58\u5728`),console.log(g.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp list' \u67E5\u770B\u6240\u6709\u53EF\u7528\u670D\u52A1"));return}let s=m.getServerToolsConfig(i);if(!s[e]){r.fail(`\u5DE5\u5177 '${e}' \u5728\u670D\u52A1 '${i}' \u4E2D\u4E0D\u5B58\u5728`),console.log(g.yellow(`\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 'xiaozhi mcp ${i} list' \u67E5\u770B\u8BE5\u670D\u52A1\u7684\u6240\u6709\u5DE5\u5177`));return}m.setToolEnabled(i,e,t,s[e].description),r.succeed(`\u6210\u529F${n}\u5DE5\u5177 ${g.cyan(i)}/${g.cyan(e)}`),console.log(),console.log(g.gray("\u{1F4A1} \u63D0\u793A: \u5DE5\u5177\u72B6\u6001\u66F4\u6539\u5C06\u5728\u4E0B\u6B21\u542F\u52A8\u670D\u52A1\u65F6\u751F\u6548"))}catch(o){r.fail(`${n}\u5DE5\u5177\u5931\u8D25`),console.error(g.red(`\u9519\u8BEF: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}var Xe=h(()=>{"use strict";ae();a($t,"getDisplayWidth");a(Dt,"truncateToWidth");a(Jr,"listMcpServers");a(qr,"listServerTools");a(Zr,"setToolEnabled")});var Dn={};k(Dn,{McpCommandHandler:()=>Nt});import Qr from"chalk";var Nt,Nn=h(()=>{"use strict";oe();Nt=class extends A{static{a(this,"McpCommandHandler")}name="mcp";description="MCP \u670D\u52A1\u548C\u5DE5\u5177\u7BA1\u7406";subcommands=[{name:"list",description:"\u5217\u51FA MCP \u670D\u52A1",options:[{flags:"--tools",description:"\u663E\u793A\u6240\u6709\u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868"}],execute:a(async(e,t)=>{await this.handleList(t)},"execute")},{name:"server",description:"\u7BA1\u7406\u6307\u5B9A\u7684 MCP \u670D\u52A1",execute:a(async(e,t)=>{this.validateArgs(e,1),await this.handleServer(e[0])},"execute")},{name:"tool",description:"\u542F\u7528\u6216\u7981\u7528\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177",execute:a(async(e,t)=>{this.validateArgs(e,3);let[n,r,o]=e;o!=="enable"&&o!=="disable"&&(console.error(Qr.red("\u9519\u8BEF: \u64CD\u4F5C\u5FC5\u987B\u662F 'enable' \u6216 'disable'")),process.exit(1));let s=o==="enable";await this.handleTool(n,r,s)},"execute")}];constructor(e){super(e)}async execute(e,t){console.log("MCP \u670D\u52A1\u548C\u5DE5\u5177\u7BA1\u7406\u547D\u4EE4\u3002\u4F7F\u7528 --help \u67E5\u770B\u53EF\u7528\u7684\u5B50\u547D\u4EE4\u3002")}async handleList(e){try{let{listMcpServers:t}=await Promise.resolve().then(()=>(Xe(),Ve));await t(e)}catch(t){this.handleError(t)}}async handleServer(e){try{let{listServerTools:t}=await Promise.resolve().then(()=>(Xe(),Ve));await t(e)}catch(t){this.handleError(t)}}async handleTool(e,t,n){try{let{setToolEnabled:r}=await Promise.resolve().then(()=>(Xe(),Ve));await r(e,t,n)}catch(r){this.handleError(r)}}}});var An={};k(An,{EndpointCommandHandler:()=>At});import Ce from"chalk";import Ge from"ora";var At,kn=h(()=>{"use strict";oe();At=class extends A{static{a(this,"EndpointCommandHandler")}name="endpoint";description="\u7BA1\u7406 MCP \u7AEF\u70B9";subcommands=[{name:"list",description:"\u5217\u51FA\u6240\u6709 MCP \u7AEF\u70B9",execute:a(async(e,t)=>{await this.handleList()},"execute")},{name:"add",description:"\u6DFB\u52A0\u65B0\u7684 MCP \u7AEF\u70B9",execute:a(async(e,t)=>{this.validateArgs(e,1),await this.handleAdd(e[0])},"execute")},{name:"remove",description:"\u79FB\u9664\u6307\u5B9A\u7684 MCP \u7AEF\u70B9",execute:a(async(e,t)=>{this.validateArgs(e,1),await this.handleRemove(e[0])},"execute")},{name:"set",description:"\u8BBE\u7F6E MCP \u7AEF\u70B9\uFF08\u53EF\u4EE5\u662F\u5355\u4E2A\u6216\u591A\u4E2A\uFF09",execute:a(async(e,t)=>{this.validateArgs(e,1),await this.handleSet(e)},"execute")}];constructor(e){super(e)}async execute(e,t){console.log("MCP \u7AEF\u70B9\u7BA1\u7406\u547D\u4EE4\u3002\u4F7F\u7528 --help \u67E5\u770B\u53EF\u7528\u7684\u5B50\u547D\u4EE4\u3002")}async handleList(){let e=Ge("\u8BFB\u53D6\u7AEF\u70B9\u914D\u7F6E...").start();try{let n=this.getService("configManager").getMcpEndpoints();e.succeed("\u7AEF\u70B9\u5217\u8868"),n.length===0?console.log(Ce.yellow("\u672A\u914D\u7F6E\u4EFB\u4F55 MCP \u7AEF\u70B9")):(console.log(Ce.green(`\u5171 ${n.length} \u4E2A\u7AEF\u70B9:`)),n.forEach((r,o)=>{console.log(Ce.gray(` ${o+1}. ${r}`))}))}catch(t){e.fail(`\u8BFB\u53D6\u7AEF\u70B9\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`),this.handleError(t)}}async handleAdd(e){let t=Ge("\u6DFB\u52A0\u7AEF\u70B9...").start();try{let n=this.getService("configManager");n.addMcpEndpoint(e),t.succeed(`\u6210\u529F\u6DFB\u52A0\u7AEF\u70B9: ${e}`);let r=n.getMcpEndpoints();console.log(Ce.gray(`\u5F53\u524D\u5171 ${r.length} \u4E2A\u7AEF\u70B9`))}catch(n){t.fail(`\u6DFB\u52A0\u7AEF\u70B9\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),this.handleError(n)}}async handleRemove(e){let t=Ge("\u79FB\u9664\u7AEF\u70B9...").start();try{let n=this.getService("configManager");n.removeMcpEndpoint(e),t.succeed(`\u6210\u529F\u79FB\u9664\u7AEF\u70B9: ${e}`);let r=n.getMcpEndpoints();console.log(Ce.gray(`\u5F53\u524D\u5269\u4F59 ${r.length} \u4E2A\u7AEF\u70B9`))}catch(n){t.fail(`\u79FB\u9664\u7AEF\u70B9\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),this.handleError(n)}}async handleSet(e){let t=Ge("\u8BBE\u7F6E\u7AEF\u70B9...").start();try{let n=this.getService("configManager");if(e.length===1)n.updateMcpEndpoint(e[0]),t.succeed(`\u6210\u529F\u8BBE\u7F6E\u7AEF\u70B9: ${e[0]}`);else{n.updateMcpEndpoint(e),t.succeed(`\u6210\u529F\u8BBE\u7F6E ${e.length} \u4E2A\u7AEF\u70B9`);for(let[r,o]of e.entries())console.log(Ce.gray(` ${r+1}. ${o}`))}}catch(n){t.fail(`\u8BBE\u7F6E\u7AEF\u70B9\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),this.handleError(n)}}}});var Fn={};k(Fn,{UICommandHandler:()=>kt});import ie from"chalk";import Yr from"ora";var kt,zn=h(()=>{"use strict";oe();kt=class extends A{static{a(this,"UICommandHandler")}name="ui";description="\u542F\u52A8\u914D\u7F6E\u7BA1\u7406\u7F51\u9875";constructor(e){super(e)}async execute(e,t){await this.handleUI()}async handleUI(){let e=Yr("\u542F\u52A8 UI \u670D\u52A1...").start();try{let t=this.getService("configManager");if(!t.configExists()){e.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(ie.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi config init" \u521D\u59CB\u5316\u914D\u7F6E'));return}let{WebServer:n}=await Promise.resolve().then(()=>(wt(),yt));await new n().start(),e.succeed("UI \u670D\u52A1\u5DF2\u542F\u52A8");let o=t.getWebUIPort();console.log(ie.green("\u2705 \u914D\u7F6E\u7BA1\u7406\u7F51\u9875\u5DF2\u542F\u52A8\uFF0C\u53EF\u901A\u8FC7\u4EE5\u4E0B\u5730\u5740\u8BBF\u95EE:")),console.log(ie.green(` \u672C\u5730\u8BBF\u95EE: http://localhost:${o}`)),console.log(ie.green(` \u7F51\u7EDC\u8BBF\u95EE: http://<\u4F60\u7684IP\u5730\u5740>:${o}`)),console.log(ie.yellow("\u{1F4A1} \u63D0\u793A: \u6309 Ctrl+C \u505C\u6B62\u670D\u52A1")),await this.openBrowser(`http://localhost:${o}`)}catch(t){e.fail(`\u542F\u52A8 UI \u670D\u52A1\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`),this.handleError(t)}}async openBrowser(e){try{let{spawn:t}=await import("child_process"),n;process.platform==="darwin"?n=t("open",[e],{detached:!0,stdio:"ignore"}):process.platform==="win32"?n=t("cmd",["/c","start",e],{detached:!0,stdio:"ignore"}):n=t("xdg-open",[e],{detached:!0,stdio:"ignore"}),n.on("error",()=>{console.log(ie.gray(`\u{1F4A1} \u63D0\u793A: \u65E0\u6CD5\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u624B\u52A8\u8BBF\u95EE: ${e}`))}),n.unref()}catch{console.log(ie.gray(`\u{1F4A1} \u63D0\u793A: \u65E0\u6CD5\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u624B\u52A8\u8BBF\u95EE: ${e}`))}}}});Mt();import Z from"chalk";import{Command as eo}from"commander";ot();var Ke=class{constructor(e){this.container=e}static{a(this,"CommandHandlerFactory")}createHandlers(){return[this.createHandler("service"),this.createHandler("config"),this.createHandler("project"),this.createHandler("mcp"),this.createHandler("endpoint"),this.createHandler("ui")]}createHandler(e){switch(e){case"service":return this.createServiceCommandHandler();case"config":return this.createConfigCommandHandler();case"project":return this.createProjectCommandHandler();case"mcp":return this.createMcpCommandHandler();case"endpoint":return this.createEndpointCommandHandler();case"ui":return this.createUICommandHandler();default:throw new Error(`\u672A\u77E5\u7684\u547D\u4EE4\u5904\u7406\u5668\u7C7B\u578B: ${e}`)}}createServiceCommandHandler(){let{ServiceCommandHandler:e}=(Tn(),W(Pn));return new e(this.container)}createConfigCommandHandler(){let{ConfigCommandHandler:e}=(Rn(),W(In));return new e(this.container)}createProjectCommandHandler(){let{ProjectCommandHandler:e}=(On(),W(xn));return new e(this.container)}createMcpCommandHandler(){let{McpCommandHandler:e}=(Nn(),W(Dn));return new e(this.container)}createEndpointCommandHandler(){let{EndpointCommandHandler:e}=(kn(),W(An));return new e(this.container)}createUICommandHandler(){let{UICommandHandler:e}=(zn(),W(Fn));return new e(this.container)}};var Je=class{constructor(e){this.container=e;this.handlerFactory=new Ke(e)}static{a(this,"CommandRegistry")}handlers=[];handlerFactory;async registerCommands(e){try{this.registerVersionCommand(e),this.registerHelpCommand(e);let t=this.handlerFactory.createHandlers();for(let n of t)this.registerHandler(n),this.registerCommand(e,n);this.registerLegacyServiceCommands(e,t)}catch(t){V.handle(t)}}registerHandler(e){this.handlers.push(e)}registerCommand(e,t){if(t.subcommands&&t.subcommands.length>0){let n=e.command(t.name).description(t.description);for(let r of t.subcommands){let o=r.name;r.name==="get"?o="get <key>":r.name==="set"&&(o="set <key> <value>");let s=n.command(o).description(r.description);if(r.options)for(let c of r.options)s.option(c.flags,c.description,c.defaultValue);s.action(async(...c)=>{try{let d=c[c.length-1].opts();await r.execute(c.slice(0,-1),d)}catch(l){V.handle(l)}})}n.action(async(...r)=>{try{let s=r[r.length-1].opts();await t.execute(r.slice(0,-1),s)}catch(o){V.handle(o)}})}else{let n=t.name;t.name==="create"&&(n="create <projectName>");let r=e.command(n).description(t.description);if(t.options)for(let o of t.options)r.option(o.flags,o.description,o.defaultValue);r.action(async(...o)=>{try{let c=o[o.length-1].opts();await t.execute(o.slice(0,-1),c)}catch(s){V.handle(s)}})}}registerVersionCommand(e){let t=this.container.get("versionUtils");e.version(t.getVersion(),"-v, --version","\u663E\u793A\u7248\u672C\u4FE1\u606F"),e.option("--info","\u663E\u793A\u8BE6\u7EC6\u4FE1\u606F"),e.option("--version-info","\u663E\u793A\u8BE6\u7EC6\u7248\u672C\u4FE1\u606F")}registerHelpCommand(e){e.helpOption("-h, --help","\u663E\u793A\u5E2E\u52A9\u4FE1\u606F").addHelpText("after",`
36
+ \u793A\u4F8B:
37
+ xiaozhi init # \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6
38
+ xiaozhi start # \u542F\u52A8\u670D\u52A1
39
+ xiaozhi start -d # \u540E\u53F0\u542F\u52A8\u670D\u52A1
40
+ xiaozhi start -u # \u542F\u52A8\u670D\u52A1\u5E76\u6253\u5F00 Web UI
41
+ xiaozhi start -s 3000 # \u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8
42
+ xiaozhi stop # \u505C\u6B62\u670D\u52A1
43
+ xiaozhi status # \u68C0\u67E5\u670D\u52A1\u72B6\u6001
44
+ xiaozhi restart -d # \u91CD\u542F\u670D\u52A1\uFF08\u540E\u53F0\u6A21\u5F0F\uFF09
45
+ xiaozhi config mcpEndpoint <url> # \u8BBE\u7F6E MCP \u7AEF\u70B9
46
+ xiaozhi create my-project # \u521B\u5EFA\u9879\u76EE
47
+ xiaozhi mcp list # \u5217\u51FA MCP \u670D\u52A1
48
+
49
+ \u66F4\u591A\u4FE1\u606F\u8BF7\u8BBF\u95EE: https://github.com/your-org/xiaozhi-client
50
+ `)}registerLegacyServiceCommands(e,t){let n=t.find(r=>r.name==="service");if(!(!n||!n.subcommands))for(let r of n.subcommands){let o=e.command(r.name).description(r.description);if(r.options)for(let s of r.options)o.option(s.flags,s.description,s.defaultValue);o.action(async(...s)=>{try{let l=s[s.length-1].opts();await r.execute(s.slice(0,-1),l)}catch(c){V.handle(c)}})}}};var qe=new eo;function to(){console.log(Z.blue("\u{1F916} \u5C0F\u667A MCP \u5BA2\u6237\u7AEF")),console.log(),console.log("\u4E00\u4E2A\u5F3A\u5927\u7684 MCP (Model Context Protocol) \u5BA2\u6237\u7AEF\uFF0C\u652F\u6301\u591A\u79CD\u8FDE\u63A5\u65B9\u5F0F\u548C\u670D\u52A1\u7BA1\u7406\u3002"),console.log(),console.log(Z.yellow("\u4E3B\u8981\u529F\u80FD:")),console.log(" \u2022 \u652F\u6301 WebSocket \u548C HTTP \u8FDE\u63A5"),console.log(" \u2022 \u591A MCP \u670D\u52A1\u7BA1\u7406"),console.log(" \u2022 \u5DE5\u5177\u8C03\u7528\u548C\u8D44\u6E90\u8BBF\u95EE"),console.log(" \u2022 \u914D\u7F6E\u7BA1\u7406\u548C\u6A21\u677F\u521B\u5EFA"),console.log(" \u2022 \u540E\u53F0\u670D\u52A1\u548C Web UI"),console.log(),console.log(Z.yellow("\u5FEB\u901F\u5F00\u59CB:")),console.log(" xiaozhi config init # \u521D\u59CB\u5316\u914D\u7F6E"),console.log(" xiaozhi start # \u542F\u52A8\u670D\u52A1"),console.log(" xiaozhi ui # \u542F\u52A8 Web UI"),console.log(),console.log("\u4F7F\u7528 'xiaozhi --help' \u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4")}a(to,"showHelp");function no(i){let e=i.get("versionUtils"),t=i.get("platformUtils"),n=e.getVersionInfo(),r=t.getSystemInfo();console.log(Z.blue("\u{1F916} \u5C0F\u667A MCP \u5BA2\u6237\u7AEF - \u8BE6\u7EC6\u4FE1\u606F")),console.log(),console.log(Z.green("\u7248\u672C\u4FE1\u606F:")),console.log(` \u540D\u79F0: ${n.name||"xiaozhi"}`),console.log(` \u7248\u672C: ${n.version}`),n.description&&console.log(` \u63CF\u8FF0: ${n.description}`),console.log(),console.log(Z.green("\u7CFB\u7EDF\u4FE1\u606F:")),console.log(` Node.js: ${r.nodeVersion}`),console.log(` \u5E73\u53F0: ${r.platform} ${r.arch}`),r.isContainer&&console.log(" \u73AF\u5883: Container"),console.log(),console.log(Z.green("\u914D\u7F6E\u4FE1\u606F:"));let o=i.get("configManager");if(o.configExists()){let s=o.getConfigPath();console.log(` \u914D\u7F6E\u6587\u4EF6: ${s}`);try{let c=o.getMcpEndpoints();console.log(` MCP \u7AEF\u70B9: ${c.length} \u4E2A`)}catch{console.log(" MCP \u7AEF\u70B9: \u8BFB\u53D6\u5931\u8D25")}}else console.log(" \u914D\u7F6E\u6587\u4EF6: \u672A\u521D\u59CB\u5316")}a(no,"showDetailedInfo");async function ro(){try{if(process.argv.includes("--info")){let t=await ve();no(t),process.exit(0)}if(process.argv.includes("--version-info")){let t=await ve(),n=t.get("versionUtils"),r=t.get("platformUtils"),o=n.getVersionInfo(),s=r.getSystemInfo();console.log(`${o.name||"xiaozhi"} v${o.version}`),o.description&&console.log(o.description),console.log(`Node.js: ${s.nodeVersion}`),console.log(`Platform: ${s.platform} ${s.arch}`),s.isContainer&&console.log("Environment: Container"),process.exit(0)}let i=await ve(),e=new Je(i);qe.name("xiaozhi").description("\u5C0F\u667A MCP \u5BA2\u6237\u7AEF - \u5F3A\u5927\u7684 Model Context Protocol \u5BA2\u6237\u7AEF"),await e.registerCommands(qe),qe.helpOption("-h, --help","\u663E\u793A\u5E2E\u52A9\u4FE1\u606F").addHelpText("after",`
51
+ \u793A\u4F8B:
52
+ xiaozhi config init # \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6
53
+ xiaozhi start # \u542F\u52A8\u670D\u52A1
54
+ xiaozhi start -d # \u540E\u53F0\u542F\u52A8\u670D\u52A1
55
+ xiaozhi start -u # \u542F\u52A8\u670D\u52A1\u5E76\u6253\u5F00 Web UI
56
+ xiaozhi start -s 3000 # \u4EE5 MCP Server \u6A21\u5F0F\u542F\u52A8
57
+ xiaozhi stop # \u505C\u6B62\u670D\u52A1
58
+ xiaozhi status # \u68C0\u67E5\u670D\u52A1\u72B6\u6001
59
+ xiaozhi restart -d # \u91CD\u542F\u670D\u52A1\uFF08\u540E\u53F0\u6A21\u5F0F\uFF09
60
+ xiaozhi config set mcpEndpoint <url> # \u8BBE\u7F6E MCP \u7AEF\u70B9
61
+ xiaozhi create my-project # \u521B\u5EFA\u9879\u76EE
62
+ xiaozhi mcp list # \u5217\u51FA MCP \u670D\u52A1
63
+ xiaozhi endpoint list # \u5217\u51FA MCP \u7AEF\u70B9
64
+ xiaozhi ui # \u542F\u52A8 Web UI
65
+
66
+ \u66F4\u591A\u4FE1\u606F\u8BF7\u8BBF\u95EE: https://github.com/your-org/xiaozhi-client
67
+ `),process.argv.length<=2&&(to(),process.exit(0)),await qe.parseAsync(process.argv)}catch(i){console.error(Z.red("\u7A0B\u5E8F\u542F\u52A8\u5931\u8D25:"),i instanceof Error?i.message:String(i)),process.exit(1)}}a(ro,"main");ro().catch(i=>{console.error(Z.red("\u7A0B\u5E8F\u6267\u884C\u5931\u8D25:"),i instanceof Error?i.message:String(i)),process.exit(1)});
35
68
  //# sourceMappingURL=cli.js.map