xiaozhi-client 1.6.3-beta.3 → 1.6.3-beta.4

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/WebServer.js CHANGED
@@ -1,17 +1,17 @@
1
- var ve=Object.defineProperty;var en=Object.getOwnPropertyDescriptor;var tn=Object.getOwnPropertyNames;var nn=Object.prototype.hasOwnProperty;var a=(i,e)=>ve(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)ve(i,t,{get:e[t],enumerable:!0})},rn=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of tn(e))!nn.call(i,r)&&r!==t&&ve(i,r,{get:()=>e[r],enumerable:!(n=en(e,r))||n.enumerable});return i};var ye=i=>rn(ve({},"__esModule",{value:!0}),i);import*as P from"fs";import*as N from"path";import ae from"chalk";import J from"pino";function on(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 ce,u,b=h(()=>{"use strict";a(on,"formatDateTime");ce=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:J.destination({dest:this.logFilePath,sync:!1,append:!0,mkdir:!0})}),e.length===0&&e.push({level:"debug",stream:J.destination({dest:"/dev/null"})}),J({level:"debug",timestamp:J.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:a((t,n)=>({level:n}),"level")},base:null,serializers:{err:J.stdSerializers?.err||(t=>t)}},J.multistream(e,{dedupe:!0}))}createOptimizedConsoleStream(){let e=new Map([[20,{name:"DEBUG",color:ae.gray}],[30,{name:"INFO",color:ae.blue}],[40,{name:"WARN",color:ae.yellow}],[50,{name:"ERROR",color:ae.red}],[60,{name:"FATAL",color:ae.red}]]);return{write:a(t=>{try{let n=JSON.parse(t),r=this.formatConsoleMessageOptimized(n,e);this.safeWrite(`${r}
2
- `)}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=on(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=N.join(e,"xiaozhi.log"),this.rotateLogFileIfNeeded(),P.existsSync(this.logFilePath)||P.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||!P.existsSync(this.logFilePath)))try{P.statSync(this.logFilePath).size>this.maxLogFileSize&&this.rotateLogFile()}catch{}}rotateLogFile(){if(this.logFilePath)try{let e=N.dirname(this.logFilePath),t=N.basename(this.logFilePath,".log");for(let r=this.maxLogFiles-1;r>=1;r--){let o=N.join(e,`${t}.${r}.log`),s=N.join(e,`${t}.${r+1}.log`);P.existsSync(o)&&(r===this.maxLogFiles-1?P.unlinkSync(o):P.renameSync(o,s))}let n=N.join(e,`${t}.1.log`);P.renameSync(this.logFilePath,n)}catch{}}cleanupOldLogs(){if(this.logFilePath)try{let e=N.dirname(this.logFilePath),t=N.basename(this.logFilePath,".log");for(let n=this.maxLogFiles+1;n<=this.maxLogFiles+10;n++){let r=N.join(e,`${t}.${n}.log`);P.existsSync(r)&&P.unlinkSync(r)}}catch{}}setLogFileOptions(e,t){this.maxLogFileSize=e,this.maxLogFiles=t}withTag(e){return this}close(){}},u=new ce});import L from"ws";var M,W,Me=h(()=>{"use strict";b();M=class extends Error{constructor(t,n,r){super(n);this.code=t;this.data=r;this.name="ToolCallError"}static{a(this,"ToolCallError")}},W=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=u,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 L(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===L.OPEN?this.ws.close(1e3,"Cleaning up connection"):this.ws.readyState===L.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===L.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===L.OPEN?"OPEN":this.ws?.readyState===L.CONNECTING?"CONNECTING":this.ws?.readyState===L.CLOSING?"CLOSING":this.ws?.readyState===L.CLOSED?"CLOSED":"UNKNOWN"}),(!this.isConnected||this.ws?.readyState!==L.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 M(-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 M(-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 M?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 M(-32602,"\u8BF7\u6C42\u53C2\u6570\u5FC5\u987B\u662F\u5BF9\u8C61");if(!e.name||typeof e.name!="string")throw new M(-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 M(-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 M?r=s:r=new M(-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 M(-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 M(-32601,`\u5DE5\u5177\u4E0D\u5B58\u5728: ${t}`)):l.message?.includes("\u670D\u52A1")&&l.message?.includes("\u4E0D\u53EF\u7528")?s(new M(-32001,l.message)):l.message?.includes("\u6682\u65F6\u4E0D\u53EF\u7528")?s(new M(-32001,l.message)):l.message?.includes("\u6301\u7EED\u4E0D\u53EF\u7528")?s(new M(-32001,l.message)):s(new M(-32e3,`\u5DE5\u5177\u6267\u884C\u5931\u8D25: ${l.message}`))})})}handleToolCallError(e,t,n){let r;e instanceof M?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===L.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()}}}});import{SSEClientTransport as st}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as sn}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as an}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{EventSource as cn}from"eventsource";function ln(){return u}function gn(i){switch(ln().info(`[TransportFactory] \u521B\u5EFA ${i.type} transport for ${i.name}`),i.type){case"stdio":return hn(i);case"sse":return pn(i);case"modelscope-sse":return un(i);case"streamable-http":return dn(i);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`)}}function hn(i){if(!i.command)throw new Error("stdio transport \u9700\u8981 command \u914D\u7F6E");return new sn({command:i.command,args:i.args||[]})}function pn(i){if(!i.url)throw new Error("SSE transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(i.url),t=mn(i);return new st(e,t)}function un(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=fn(i);return new st(e,t)}function dn(i){if(!i.url)throw new Error("StreamableHTTP transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(i.url),t=Sn(i);return new an(e,t)}function mn(i){let e={};return i.apiKey?e.headers={Authorization:`Bearer ${i.apiKey}`,...i.headers}:i.headers&&(e.headers=i.headers),e}function fn(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 Sn(i){let e={};return i.apiKey?e.headers={Authorization:`Bearer ${i.apiKey}`,...i.headers}:i.headers&&(e.headers=i.headers),e}function Cn(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 vn(){return["stdio","sse","modelscope-sse","streamable-http"]}var ke,at=h(()=>{"use strict";b();we();typeof global<"u"&&!global.EventSource&&(global.EventSource=cn);a(ln,"getLogger");a(gn,"createTransport");a(hn,"createStdioTransport");a(pn,"createSSETransport");a(un,"createModelScopeSSETransport");a(dn,"createStreamableHTTPTransport");a(mn,"createSSEOptions");a(fn,"createModelScopeSSEOptions");a(Sn,"createStreamableHTTPOptions");a(Cn,"validateConfig");a(vn,"getSupportedTypes");ke={create:gn,validateConfig:Cn,getSupportedTypes:vn}});import{Client as yn}from"@modelcontextprotocol/sdk/client/index.js";var le,Ee,we=h(()=>{"use strict";b();at();le=(r=>(r.STDIO="stdio",r.SSE="sse",r.STREAMABLE_HTTP="streamable-http",r.MODELSCOPE_SSE="modelscope-sse",r))(le||{}),Ee=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=u,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(){ke.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 yn({name:`xiaozhi-${this.config.name}-client`,version:"1.0.0"},{capabilities:{tools:{}}}),this.transport=ke.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}}}});function ct(i,e){Le.debug(`\u8F6C\u6362\u914D\u7F6E: ${i}`,e);try{if(!i||typeof i!="string")throw new T("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!e||typeof e!="object")throw new T("\u914D\u7F6E\u5BF9\u8C61\u4E0D\u80FD\u4E3A\u7A7A",i);let t=Mn(i,e);return On(t),Le.info(`\u914D\u7F6E\u8F6C\u6362\u6210\u529F: ${i} -> ${t.type}`),t}catch(t){throw Le.error(`\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${i}`,t),t instanceof T?t:new T(`\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`,i)}}function Mn(i,e){if(bn(e))return wn(i,e);if(Tn(e))return En(i,e);if(Rn(e))return Pn(i,e);throw new T("\u65E0\u6CD5\u8BC6\u522B\u7684\u914D\u7F6E\u7C7B\u578B",i)}function wn(i,e){if(!e.command)throw new T("\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 En(i,e){if(!e.url)throw new T("SSE \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5",i);let t=In(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 Pn(i,e){if(!e.url)throw new T("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 bn(i){return"command"in i&&typeof i.command=="string"}function Tn(i){return"type"in i&&i.type==="sse"&&"url"in i}function Rn(i){return"url"in i&&(!("type"in i)||i.type==="streamable-http")}function In(i){return i.includes("modelscope.net")||i.includes("modelscope.cn")}function On(i){if(!i.name||typeof i.name!="string")throw new T("\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 name \u5B57\u6BB5");if(!Object.values(le).includes(i.type))throw new T(`\u65E0\u6548\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`);switch(i.type){case"stdio":if(!i.command)throw new T("STDIO \u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5");break;case"sse":case"modelscope-sse":case"streamable-http":if(!i.url)throw new T(`${i.type} \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5`);break;default:throw new T(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`)}}var Le,T,lt=h(()=>{"use strict";b();we();Le=u.withTag("ConfigAdapter"),T=class extends Error{constructor(t,n){super(t);this.configName=n;this.name="ConfigValidationError"}static{a(this,"ConfigValidationError")}};a(ct,"convertLegacyToNew");a(Mn,"convertByConfigType");a(wn,"convertLocalConfig");a(En,"convertSSEConfig");a(Pn,"convertStreamableHTTPConfig");a(bn,"isLocalConfig");a(Tn,"isSSEConfig");a(Rn,"isStreamableHTTPConfig");a(In,"isModelScopeURL");a(On,"validateNewConfig")});function xn(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 ze(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(xn(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 gt=h(()=>{"use strict";a(xn,"getMcpServerCommunicationType");a(ze,"validateMcpServerConfig")});import{copyFileSync as $n,existsSync as Pe,readFileSync as Nn,writeFileSync as Dn}from"fs";import{dirname as An,resolve as V}from"path";import{fileURLToPath as Fn}from"url";import*as be from"comment-json";import kn from"dayjs";import je from"json5";import*as pt from"json5-writer";var ht,Ue,_e,d,ge=h(()=>{"use strict";b();gt();ht=An(Fn(import.meta.url)),Ue={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},_e=class i{static{a(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;constructor(){let e=[V(ht,"templates","default","xiaozhi.config.json"),V(ht,"..","templates","default","xiaozhi.config.json"),V(process.cwd(),"templates","default","xiaozhi.config.json")];this.defaultConfigPath=e.find(t=>Pe(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=V(e,n);if(Pe(r))return r}return V(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=V(e,n);if(Pe(r))return!0}return!1}initConfig(e="json"){if(!Pe(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=V(t,n);$n(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=Nn(e,"utf8").replace(/^\uFEFF/,""),o;switch(t){case"json5":o=je.parse(r),this.json5Writer=pt.load(r);break;case"jsonc":o=be.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=ze(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=ze(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=je.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=je.stringify(e,null,2)}break;case"jsonc":try{r=be.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}Dn(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??Ue.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??Ue.heartbeatTimeout,reconnectInterval:t.reconnectInterval??Ue.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=kn(n).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(r),u.debug(`\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${e}/${t}, \u4F7F\u7528\u6B21\u6570: ${o.usageCount}`)}catch(r){u.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})}},d=_e.getInstance()});var He,q,he,p,We,pe=h(()=>{"use strict";He={NAME:"xiaozhi-mcp-service",DEFAULT_PORT:3e3,DEFAULT_WEB_UI_PORT:9999,PID_FILE:"xiaozhi.pid",LOG_FILE:"xiaozhi.log"},q={FILE_NAMES:["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"],DEFAULT_FILE:"xiaozhi.config.default.json",DIR_ENV_VAR:"XIAOZHI_CONFIG_DIR"},he={WORK_DIR:".xiaozhi",TEMPLATES_DIR:"templates",LOGS_DIR:"logs"},p={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"},We={PROCESS_STOP:3e3,SERVICE_START:1e4,NETWORK_REQUEST:5e3,FILE_OPERATION:2e3}});var Ln,zn,Te,ut=h(()=>{"use strict";pe();Ln={[p.CONFIG_ERROR]:'\u8FD0\u884C "xiaozhi --help" \u67E5\u770B\u914D\u7F6E\u76F8\u5173\u547D\u4EE4',[p.SERVICE_ERROR]:'\u8FD0\u884C "xiaozhi status" \u68C0\u67E5\u670D\u52A1\u72B6\u6001',[p.VALIDATION_ERROR]:"\u68C0\u67E5\u8F93\u5165\u53C2\u6570\u662F\u5426\u6B63\u786E",[p.FILE_ERROR]:"\u68C0\u67E5\u6587\u4EF6\u8DEF\u5F84\u548C\u6743\u9650",[p.PROCESS_ERROR]:"\u68C0\u67E5\u8FDB\u7A0B\u72B6\u6001\u548C\u6743\u9650",[p.NETWORK_ERROR]:"\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u548C\u9632\u706B\u5899\u8BBE\u7F6E",[p.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"]},Te=class{static{a(this,"ERROR_MESSAGES")}static getHelpMessage(e){return Ln[e]}static getSolutions(e){return zn[e]||[]}static formatError(e,t){return`${t?`[${t}] `:""}${e.message}`}static getFriendlyMessage(e){return{[p.CONFIG_ERROR]:"\u914D\u7F6E\u6587\u4EF6\u76F8\u5173\u9519\u8BEF",[p.SERVICE_ERROR]:"\u670D\u52A1\u8FD0\u884C\u76F8\u5173\u9519\u8BEF",[p.VALIDATION_ERROR]:"\u8F93\u5165\u9A8C\u8BC1\u9519\u8BEF",[p.FILE_ERROR]:"\u6587\u4EF6\u64CD\u4F5C\u9519\u8BEF",[p.PROCESS_ERROR]:"\u8FDB\u7A0B\u7BA1\u7406\u9519\u8BEF",[p.NETWORK_ERROR]:"\u7F51\u7EDC\u8FDE\u63A5\u9519\u8BEF",[p.PERMISSION_ERROR]:"\u6743\u9650\u4E0D\u8DB3\u9519\u8BEF"}[e]||"\u672A\u77E5\u9519\u8BEF"}static isRecoverable(e){return[p.NETWORK_ERROR,p.FILE_ERROR,p.SERVICE_ERROR].includes(e)}static getSeverity(e){return{[p.VALIDATION_ERROR]:"low",[p.FILE_ERROR]:"medium",[p.CONFIG_ERROR]:"medium",[p.NETWORK_ERROR]:"medium",[p.SERVICE_ERROR]:"high",[p.PROCESS_ERROR]:"high",[p.PERMISSION_ERROR]:"critical"}[e]||"medium"}}});var R,X,v,m,g,H,z=h(()=>{"use strict";pe();R=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)}},X=class i extends R{static{a(this,"ConfigError")}constructor(e,t){super(e,p.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"])}},v=class i extends R{static{a(this,"ServiceError")}constructor(e,t){super(e,p.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"])}},m=class i extends R{static{a(this,"ValidationError")}constructor(e,t){super(`\u9A8C\u8BC1\u5931\u8D25: ${t} - ${e}`,p.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)}},g=class i extends R{static{a(this,"FileError")}constructor(e,t,n){let r=t?`${e}: ${t}`:e;super(r,p.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"])}},H=class i extends R{static{a(this,"ProcessError")}constructor(e,t,n){let r=t?`${e} (PID: ${t})`:e;super(r,p.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 I from"chalk";var Re,dt=h(()=>{"use strict";ut();z();Re=class i{static{a(this,"ErrorHandler")}static handle(e){e instanceof R?i.handleCLIError(e):i.handleUnknownError(e),process.exit(1)}static handleCLIError(e){if(console.error(I.red(`\u274C \u9519\u8BEF: ${e.message}`)),process.env.DEBUG&&console.error(I.gray(`\u9519\u8BEF\u7801: ${e.code}`)),e.suggestions&&e.suggestions.length>0){console.log(I.yellow("\u{1F4A1} \u5EFA\u8BAE:"));for(let n of e.suggestions)console.log(I.gray(` ${n}`))}let t=Te.getHelpMessage(e.code);t&&console.log(I.blue(`\u2139\uFE0F ${t}`))}static handleUnknownError(e){console.error(I.red(`\u274C \u672A\u77E5\u9519\u8BEF: ${e.message}`)),process.env.DEBUG||process.env.NODE_ENV==="development"?(console.error(I.gray("\u5806\u6808\u4FE1\u606F:")),console.error(I.gray(e.stack))):console.log(I.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 R?n:n instanceof Error?new R(`${t}\u5931\u8D25: ${n.message}`,"OPERATION_FAILED",1):new R(`${t}\u5931\u8D25: \u672A\u77E5\u9519\u8BEF`,"OPERATION_FAILED",1)}}static handleSync(e,t){try{return e()}catch(n){throw n instanceof R?n:n instanceof Error?new R(`${t}\u5931\u8D25: ${n.message}`,"OPERATION_FAILED",1):new R(`${t}\u5931\u8D25: \u672A\u77E5\u9519\u8BEF`,"OPERATION_FAILED",1)}}static warn(e,t){if(console.warn(I.yellow(`\u26A0\uFE0F \u8B66\u544A: ${e}`)),t&&t.length>0){console.log(I.yellow("\u{1F4A1} \u5EFA\u8BAE:"));for(let n of t)console.log(I.gray(` ${n}`))}}static info(e){console.log(I.blue(`\u2139\uFE0F ${e}`))}static success(e){console.log(I.green(`\u2705 ${e}`))}}});import w from"fs";import D from"path";var f,ue=h(()=>{"use strict";z();f=class i{static{a(this,"FileUtils")}static exists(e){try{return w.existsSync(e)}catch{return!1}}static ensureDir(e){try{w.existsSync(e)||w.mkdirSync(e,{recursive:!0})}catch{throw new g("\u65E0\u6CD5\u521B\u5EFA\u76EE\u5F55",e)}}static readFile(e,t="utf8"){try{if(!i.exists(e))throw g.notFound(e);return w.readFileSync(e,t)}catch(n){throw n instanceof g?n:new g("\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6",e)}}static writeFile(e,t,n){try{if(!n?.overwrite&&i.exists(e))throw g.alreadyExists(e);let r=D.dirname(e);i.ensureDir(r),w.writeFileSync(e,t,"utf8")}catch(r){throw r instanceof g?r:new g("\u65E0\u6CD5\u5199\u5165\u6587\u4EF6",e)}}static copyFile(e,t,n){try{if(!i.exists(e))throw g.notFound(e);if(!n?.overwrite&&i.exists(t))throw g.alreadyExists(t);let r=D.dirname(t);i.ensureDir(r),w.copyFileSync(e,t)}catch(r){throw r instanceof g?r:new g("\u65E0\u6CD5\u590D\u5236\u6587\u4EF6",e)}}static deleteFile(e){try{i.exists(e)&&w.unlinkSync(e)}catch{throw new g("\u65E0\u6CD5\u5220\u9664\u6587\u4EF6",e)}}static copyDirectory(e,t,n={}){try{if(!i.exists(e))throw g.notFound(e);i.ensureDir(t);let r=w.readdirSync(e);for(let o of r){if(n.exclude?.includes(o))continue;let s=D.join(e,o),c=D.join(t,o);w.statSync(s).isDirectory()?n.recursive!==!1&&i.copyDirectory(s,c,n):i.copyFile(s,c,{overwrite:n.overwrite})}}catch(r){throw r instanceof g?r:new g("\u65E0\u6CD5\u590D\u5236\u76EE\u5F55",e)}}static deleteDirectory(e,t={}){try{i.exists(e)&&w.rmSync(e,{recursive:t.recursive??!0,force:!0})}catch{throw new g("\u65E0\u6CD5\u5220\u9664\u76EE\u5F55",e)}}static getFileInfo(e){try{if(!i.exists(e))throw g.notFound(e);let t=w.statSync(e);return{size:t.size,isFile:t.isFile(),isDirectory:t.isDirectory(),mtime:t.mtime,ctime:t.ctime}}catch(t){throw t instanceof g?t:new g("\u65E0\u6CD5\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F",e)}}static listDirectory(e,t={}){try{if(!i.exists(e))throw g.notFound(e);let n=w.readdirSync(e),r=[];for(let o of n){if(!t.includeHidden&&o.startsWith("."))continue;let s=D.join(e,o);if(r.push(s),t.recursive&&w.statSync(s).isDirectory()){let c=i.listDirectory(s,t);r=r.concat(c)}}return r}catch(n){throw n instanceof g?n:new g("\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 D.join(n,s)}static checkPermissions(e,t=w.constants.R_OK|w.constants.W_OK){try{return w.accessSync(e,t),!0}catch{return!1}}static getExtension(e){return D.extname(e).toLowerCase()}static getBaseName(e){return D.basename(e,D.extname(e))}static normalizePath(e){return D.normalize(e)}static resolvePath(e,t){return t?D.resolve(t,e):D.resolve(e)}}});var Z,Be=h(()=>{"use strict";Z=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+=`
1
+ var ye=Object.defineProperty;var nn=Object.getOwnPropertyDescriptor;var rn=Object.getOwnPropertyNames;var on=Object.prototype.hasOwnProperty;var a=(i,e)=>ye(i,"name",{value:e,configurable:!0});var h=(i,e)=>()=>(i&&(e=i(i=0)),e);var Z=(i,e)=>{for(var t in e)ye(i,t,{get:e[t],enumerable:!0})},sn=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of rn(e))!on.call(i,r)&&r!==t&&ye(i,r,{get:()=>e[r],enumerable:!(n=nn(e,r))||n.enumerable});return i};var Me=i=>sn(ye({},"__esModule",{value:!0}),i);import*as b from"fs";import*as A from"path";import ce from"chalk";import Q from"pino";function an(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 le,u,T=h(()=>{"use strict";a(an,"formatDateTime");le=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:Q.destination({dest:this.logFilePath,sync:!1,append:!0,mkdir:!0})}),e.length===0&&e.push({level:"debug",stream:Q.destination({dest:"/dev/null"})}),Q({level:"debug",timestamp:Q.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:a((t,n)=>({level:n}),"level")},base:null,serializers:{err:Q.stdSerializers?.err||(t=>t)}},Q.multistream(e,{dedupe:!0}))}createOptimizedConsoleStream(){let e=new Map([[20,{name:"DEBUG",color:ce.gray}],[30,{name:"INFO",color:ce.blue}],[40,{name:"WARN",color:ce.yellow}],[50,{name:"ERROR",color:ce.red}],[60,{name:"FATAL",color:ce.red}]]);return{write:a(t=>{try{let n=JSON.parse(t),r=this.formatConsoleMessageOptimized(n,e);this.safeWrite(`${r}
2
+ `)}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=an(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=A.join(e,"xiaozhi.log"),this.rotateLogFileIfNeeded(),b.existsSync(this.logFilePath)||b.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||!b.existsSync(this.logFilePath)))try{b.statSync(this.logFilePath).size>this.maxLogFileSize&&this.rotateLogFile()}catch{}}rotateLogFile(){if(this.logFilePath)try{let e=A.dirname(this.logFilePath),t=A.basename(this.logFilePath,".log");for(let r=this.maxLogFiles-1;r>=1;r--){let o=A.join(e,`${t}.${r}.log`),s=A.join(e,`${t}.${r+1}.log`);b.existsSync(o)&&(r===this.maxLogFiles-1?b.unlinkSync(o):b.renameSync(o,s))}let n=A.join(e,`${t}.1.log`);b.renameSync(this.logFilePath,n)}catch{}}cleanupOldLogs(){if(this.logFilePath)try{let e=A.dirname(this.logFilePath),t=A.basename(this.logFilePath,".log");for(let n=this.maxLogFiles+1;n<=this.maxLogFiles+10;n++){let r=A.join(e,`${t}.${n}.log`);b.existsSync(r)&&b.unlinkSync(r)}}catch{}}setLogFileOptions(e,t){this.maxLogFileSize=e,this.maxLogFiles=t}withTag(e){return this}close(){}},u=new le});import j from"ws";var w,X,we=h(()=>{"use strict";T();w=class extends Error{constructor(t,n,r){super(n);this.code=t;this.data=r;this.name="ToolCallError"}static{a(this,"ToolCallError")}},X=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=u,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 j(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===j.OPEN?this.ws.close(1e3,"Cleaning up connection"):this.ws.readyState===j.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===j.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===j.OPEN?"OPEN":this.ws?.readyState===j.CONNECTING?"CONNECTING":this.ws?.readyState===j.CLOSING?"CLOSING":this.ws?.readyState===j.CLOSED?"CLOSED":"UNKNOWN"}),(!this.isConnected||this.ws?.readyState!==j.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 w(-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 w(-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 w?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 w(-32602,"\u8BF7\u6C42\u53C2\u6570\u5FC5\u987B\u662F\u5BF9\u8C61");if(!e.name||typeof e.name!="string")throw new w(-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 w(-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 w?r=s:r=new w(-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 w(-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 w(-32601,`\u5DE5\u5177\u4E0D\u5B58\u5728: ${t}`)):l.message?.includes("\u670D\u52A1")&&l.message?.includes("\u4E0D\u53EF\u7528")?s(new w(-32001,l.message)):l.message?.includes("\u6682\u65F6\u4E0D\u53EF\u7528")?s(new w(-32001,l.message)):l.message?.includes("\u6301\u7EED\u4E0D\u53EF\u7528")?s(new w(-32001,l.message)):s(new w(-32e3,`\u5DE5\u5177\u6267\u884C\u5931\u8D25: ${l.message}`))})})}handleToolCallError(e,t,n){let r;e instanceof w?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===j.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()}}}});import{SSEClientTransport as ct}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as cn}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as ln}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{EventSource as gn}from"eventsource";function hn(){return u}function pn(i){switch(hn().info(`[TransportFactory] \u521B\u5EFA ${i.type} transport for ${i.name}`),i.type){case"stdio":return un(i);case"sse":return dn(i);case"modelscope-sse":return fn(i);case"streamable-http":return mn(i);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`)}}function un(i){if(!i.command)throw new Error("stdio transport \u9700\u8981 command \u914D\u7F6E");return new cn({command:i.command,args:i.args||[]})}function dn(i){if(!i.url)throw new Error("SSE transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(i.url),t=Sn(i);return new ct(e,t)}function fn(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=Cn(i);return new ct(e,t)}function mn(i){if(!i.url)throw new Error("StreamableHTTP transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(i.url),t=vn(i);return new ln(e,t)}function Sn(i){let e={};return i.apiKey?e.headers={Authorization:`Bearer ${i.apiKey}`,...i.headers}:i.headers&&(e.headers=i.headers),e}function Cn(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 vn(i){let e={};return i.apiKey?e.headers={Authorization:`Bearer ${i.apiKey}`,...i.headers}:i.headers&&(e.headers=i.headers),e}function yn(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 Mn(){return["stdio","sse","modelscope-sse","streamable-http"]}var Le,lt=h(()=>{"use strict";T();Ee();typeof global<"u"&&!global.EventSource&&(global.EventSource=gn);a(hn,"getLogger");a(pn,"createTransport");a(un,"createStdioTransport");a(dn,"createSSETransport");a(fn,"createModelScopeSSETransport");a(mn,"createStreamableHTTPTransport");a(Sn,"createSSEOptions");a(Cn,"createModelScopeSSEOptions");a(vn,"createStreamableHTTPOptions");a(yn,"validateConfig");a(Mn,"getSupportedTypes");Le={create:pn,validateConfig:yn,getSupportedTypes:Mn}});import{Client as wn}from"@modelcontextprotocol/sdk/client/index.js";var ge,Pe,Ee=h(()=>{"use strict";T();lt();ge=(r=>(r.STDIO="stdio",r.SSE="sse",r.STREAMABLE_HTTP="streamable-http",r.MODELSCOPE_SSE="modelscope-sse",r))(ge||{}),Pe=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=u,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(){Le.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 wn({name:`xiaozhi-${this.config.name}-client`,version:"1.0.0"},{capabilities:{tools:{}}}),this.transport=Le.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}}}});function gt(i,e){ze.debug(`\u8F6C\u6362\u914D\u7F6E: ${i}`,e);try{if(!i||typeof i!="string")throw new R("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!e||typeof e!="object")throw new R("\u914D\u7F6E\u5BF9\u8C61\u4E0D\u80FD\u4E3A\u7A7A",i);let t=En(i,e);return $n(t),ze.info(`\u914D\u7F6E\u8F6C\u6362\u6210\u529F: ${i} -> ${t.type}`),t}catch(t){throw ze.error(`\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${i}`,t),t instanceof R?t:new R(`\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`,i)}}function En(i,e){if(Rn(e))return Pn(i,e);if(In(e))return bn(i,e);if(On(e))return Tn(i,e);throw new R("\u65E0\u6CD5\u8BC6\u522B\u7684\u914D\u7F6E\u7C7B\u578B",i)}function Pn(i,e){if(!e.command)throw new R("\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 bn(i,e){if(!e.url)throw new R("SSE \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5",i);let t=xn(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 Tn(i,e){if(!e.url)throw new R("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 Rn(i){return"command"in i&&typeof i.command=="string"}function In(i){return"type"in i&&i.type==="sse"&&"url"in i}function On(i){return"url"in i&&(!("type"in i)||i.type==="streamable-http")}function xn(i){return i.includes("modelscope.net")||i.includes("modelscope.cn")}function $n(i){if(!i.name||typeof i.name!="string")throw new R("\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 name \u5B57\u6BB5");if(!Object.values(ge).includes(i.type))throw new R(`\u65E0\u6548\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`);switch(i.type){case"stdio":if(!i.command)throw new R("STDIO \u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5");break;case"sse":case"modelscope-sse":case"streamable-http":if(!i.url)throw new R(`${i.type} \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5`);break;default:throw new R(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`)}}var ze,R,ht=h(()=>{"use strict";T();Ee();ze=u.withTag("ConfigAdapter"),R=class extends Error{constructor(t,n){super(t);this.configName=n;this.name="ConfigValidationError"}static{a(this,"ConfigValidationError")}};a(gt,"convertLegacyToNew");a(En,"convertByConfigType");a(Pn,"convertLocalConfig");a(bn,"convertSSEConfig");a(Tn,"convertStreamableHTTPConfig");a(Rn,"isLocalConfig");a(In,"isSSEConfig");a(On,"isStreamableHTTPConfig");a(xn,"isModelScopeURL");a($n,"validateNewConfig")});function Nn(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 je(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(Nn(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 pt=h(()=>{"use strict";a(Nn,"getMcpServerCommunicationType");a(je,"validateMcpServerConfig")});import{copyFileSync as Dn,existsSync as be,readFileSync as An,writeFileSync as Fn}from"fs";import{dirname as kn,resolve as G}from"path";import{fileURLToPath as Ln}from"url";import*as Te from"comment-json";import zn from"dayjs";import Ue from"json5";import*as dt from"json5-writer";var ut,_e,He,d,he=h(()=>{"use strict";T();pt();ut=kn(Ln(import.meta.url)),_e={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},He=class i{static{a(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;constructor(){let e=[G(ut,"templates","default","xiaozhi.config.json"),G(ut,"..","templates","default","xiaozhi.config.json"),G(process.cwd(),"templates","default","xiaozhi.config.json")];this.defaultConfigPath=e.find(t=>be(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=G(e,n);if(be(r))return r}return G(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=G(e,n);if(be(r))return!0}return!1}initConfig(e="json"){if(!be(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=G(t,n);Dn(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=An(e,"utf8").replace(/^\uFEFF/,""),o;switch(t){case"json5":o=Ue.parse(r),this.json5Writer=dt.load(r);break;case"jsonc":o=Te.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=je(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=je(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=Ue.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=Ue.stringify(e,null,2)}break;case"jsonc":try{r=Te.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}Fn(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??_e.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??_e.heartbeatTimeout,reconnectInterval:t.reconnectInterval??_e.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=zn(n).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(r),u.debug(`\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${e}/${t}, \u4F7F\u7528\u6B21\u6570: ${o.usageCount}`)}catch(r){u.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})}},d=He.getInstance()});var We,Y,pe,p,Be,ue=h(()=>{"use strict";We={NAME:"xiaozhi-mcp-service",DEFAULT_PORT:3e3,DEFAULT_WEB_UI_PORT:9999,PID_FILE:"xiaozhi.pid",LOG_FILE:"xiaozhi.log"},Y={FILE_NAMES:["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"],DEFAULT_FILE:"xiaozhi.config.default.json",DIR_ENV_VAR:"XIAOZHI_CONFIG_DIR"},pe={WORK_DIR:".xiaozhi",TEMPLATES_DIR:"templates",LOGS_DIR:"logs"},p={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"},Be={PROCESS_STOP:3e3,SERVICE_START:1e4,NETWORK_REQUEST:5e3,FILE_OPERATION:2e3}});var jn,Un,Re,ft=h(()=>{"use strict";ue();jn={[p.CONFIG_ERROR]:'\u8FD0\u884C "xiaozhi --help" \u67E5\u770B\u914D\u7F6E\u76F8\u5173\u547D\u4EE4',[p.SERVICE_ERROR]:'\u8FD0\u884C "xiaozhi status" \u68C0\u67E5\u670D\u52A1\u72B6\u6001',[p.VALIDATION_ERROR]:"\u68C0\u67E5\u8F93\u5165\u53C2\u6570\u662F\u5426\u6B63\u786E",[p.FILE_ERROR]:"\u68C0\u67E5\u6587\u4EF6\u8DEF\u5F84\u548C\u6743\u9650",[p.PROCESS_ERROR]:"\u68C0\u67E5\u8FDB\u7A0B\u72B6\u6001\u548C\u6743\u9650",[p.NETWORK_ERROR]:"\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u548C\u9632\u706B\u5899\u8BBE\u7F6E",[p.PERMISSION_ERROR]:"\u5C1D\u8BD5\u4F7F\u7528\u7BA1\u7406\u5458\u6743\u9650\u8FD0\u884C"},Un={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"]},Re=class{static{a(this,"ERROR_MESSAGES")}static getHelpMessage(e){return jn[e]}static getSolutions(e){return Un[e]||[]}static formatError(e,t){return`${t?`[${t}] `:""}${e.message}`}static getFriendlyMessage(e){return{[p.CONFIG_ERROR]:"\u914D\u7F6E\u6587\u4EF6\u76F8\u5173\u9519\u8BEF",[p.SERVICE_ERROR]:"\u670D\u52A1\u8FD0\u884C\u76F8\u5173\u9519\u8BEF",[p.VALIDATION_ERROR]:"\u8F93\u5165\u9A8C\u8BC1\u9519\u8BEF",[p.FILE_ERROR]:"\u6587\u4EF6\u64CD\u4F5C\u9519\u8BEF",[p.PROCESS_ERROR]:"\u8FDB\u7A0B\u7BA1\u7406\u9519\u8BEF",[p.NETWORK_ERROR]:"\u7F51\u7EDC\u8FDE\u63A5\u9519\u8BEF",[p.PERMISSION_ERROR]:"\u6743\u9650\u4E0D\u8DB3\u9519\u8BEF"}[e]||"\u672A\u77E5\u9519\u8BEF"}static isRecoverable(e){return[p.NETWORK_ERROR,p.FILE_ERROR,p.SERVICE_ERROR].includes(e)}static getSeverity(e){return{[p.VALIDATION_ERROR]:"low",[p.FILE_ERROR]:"medium",[p.CONFIG_ERROR]:"medium",[p.NETWORK_ERROR]:"medium",[p.SERVICE_ERROR]:"high",[p.PROCESS_ERROR]:"high",[p.PERMISSION_ERROR]:"critical"}[e]||"medium"}}});var I,K,y,f,g,B,U=h(()=>{"use strict";ue();I=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)}},K=class i extends I{static{a(this,"ConfigError")}constructor(e,t){super(e,p.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"])}},y=class i extends I{static{a(this,"ServiceError")}constructor(e,t){super(e,p.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"])}},f=class i extends I{static{a(this,"ValidationError")}constructor(e,t){super(`\u9A8C\u8BC1\u5931\u8D25: ${t} - ${e}`,p.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)}},g=class i extends I{static{a(this,"FileError")}constructor(e,t,n){let r=t?`${e}: ${t}`:e;super(r,p.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"])}},B=class i extends I{static{a(this,"ProcessError")}constructor(e,t,n){let r=t?`${e} (PID: ${t})`:e;super(r,p.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 O from"chalk";var Ie,mt=h(()=>{"use strict";ft();U();Ie=class i{static{a(this,"ErrorHandler")}static handle(e){e instanceof I?i.handleCLIError(e):i.handleUnknownError(e),process.exit(1)}static handleCLIError(e){if(console.error(O.red(`\u274C \u9519\u8BEF: ${e.message}`)),process.env.DEBUG&&console.error(O.gray(`\u9519\u8BEF\u7801: ${e.code}`)),e.suggestions&&e.suggestions.length>0){console.log(O.yellow("\u{1F4A1} \u5EFA\u8BAE:"));for(let n of e.suggestions)console.log(O.gray(` ${n}`))}let t=Re.getHelpMessage(e.code);t&&console.log(O.blue(`\u2139\uFE0F ${t}`))}static handleUnknownError(e){console.error(O.red(`\u274C \u672A\u77E5\u9519\u8BEF: ${e.message}`)),process.env.DEBUG||process.env.NODE_ENV==="development"?(console.error(O.gray("\u5806\u6808\u4FE1\u606F:")),console.error(O.gray(e.stack))):console.log(O.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 I?n:n instanceof Error?new I(`${t}\u5931\u8D25: ${n.message}`,"OPERATION_FAILED",1):new I(`${t}\u5931\u8D25: \u672A\u77E5\u9519\u8BEF`,"OPERATION_FAILED",1)}}static handleSync(e,t){try{return e()}catch(n){throw n instanceof I?n:n instanceof Error?new I(`${t}\u5931\u8D25: ${n.message}`,"OPERATION_FAILED",1):new I(`${t}\u5931\u8D25: \u672A\u77E5\u9519\u8BEF`,"OPERATION_FAILED",1)}}static warn(e,t){if(console.warn(O.yellow(`\u26A0\uFE0F \u8B66\u544A: ${e}`)),t&&t.length>0){console.log(O.yellow("\u{1F4A1} \u5EFA\u8BAE:"));for(let n of t)console.log(O.gray(` ${n}`))}}static info(e){console.log(O.blue(`\u2139\uFE0F ${e}`))}static success(e){console.log(O.green(`\u2705 ${e}`))}}});import E from"fs";import F from"path";var m,de=h(()=>{"use strict";U();m=class i{static{a(this,"FileUtils")}static exists(e){try{return E.existsSync(e)}catch{return!1}}static ensureDir(e){try{E.existsSync(e)||E.mkdirSync(e,{recursive:!0})}catch{throw new g("\u65E0\u6CD5\u521B\u5EFA\u76EE\u5F55",e)}}static readFile(e,t="utf8"){try{if(!i.exists(e))throw g.notFound(e);return E.readFileSync(e,t)}catch(n){throw n instanceof g?n:new g("\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6",e)}}static writeFile(e,t,n){try{if(!n?.overwrite&&i.exists(e))throw g.alreadyExists(e);let r=F.dirname(e);i.ensureDir(r),E.writeFileSync(e,t,"utf8")}catch(r){throw r instanceof g?r:new g("\u65E0\u6CD5\u5199\u5165\u6587\u4EF6",e)}}static copyFile(e,t,n){try{if(!i.exists(e))throw g.notFound(e);if(!n?.overwrite&&i.exists(t))throw g.alreadyExists(t);let r=F.dirname(t);i.ensureDir(r),E.copyFileSync(e,t)}catch(r){throw r instanceof g?r:new g("\u65E0\u6CD5\u590D\u5236\u6587\u4EF6",e)}}static deleteFile(e){try{i.exists(e)&&E.unlinkSync(e)}catch{throw new g("\u65E0\u6CD5\u5220\u9664\u6587\u4EF6",e)}}static copyDirectory(e,t,n={}){try{if(!i.exists(e))throw g.notFound(e);i.ensureDir(t);let r=E.readdirSync(e);for(let o of r){if(n.exclude?.includes(o))continue;let s=F.join(e,o),c=F.join(t,o);E.statSync(s).isDirectory()?n.recursive!==!1&&i.copyDirectory(s,c,n):i.copyFile(s,c,{overwrite:n.overwrite})}}catch(r){throw r instanceof g?r:new g("\u65E0\u6CD5\u590D\u5236\u76EE\u5F55",e)}}static deleteDirectory(e,t={}){try{i.exists(e)&&E.rmSync(e,{recursive:t.recursive??!0,force:!0})}catch{throw new g("\u65E0\u6CD5\u5220\u9664\u76EE\u5F55",e)}}static getFileInfo(e){try{if(!i.exists(e))throw g.notFound(e);let t=E.statSync(e);return{size:t.size,isFile:t.isFile(),isDirectory:t.isDirectory(),mtime:t.mtime,ctime:t.ctime}}catch(t){throw t instanceof g?t:new g("\u65E0\u6CD5\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F",e)}}static listDirectory(e,t={}){try{if(!i.exists(e))throw g.notFound(e);let n=E.readdirSync(e),r=[];for(let o of n){if(!t.includeHidden&&o.startsWith("."))continue;let s=F.join(e,o);if(r.push(s),t.recursive&&E.statSync(s).isDirectory()){let c=i.listDirectory(s,t);r=r.concat(c)}}return r}catch(n){throw n instanceof g?n:new g("\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 F.join(n,s)}static checkPermissions(e,t=E.constants.R_OK|E.constants.W_OK){try{return E.accessSync(e,t),!0}catch{return!1}}static getExtension(e){return F.extname(e).toLowerCase()}static getBaseName(e){return F.basename(e,F.extname(e))}static normalizePath(e){return F.normalize(e)}static resolvePath(e,t){return t?F.resolve(t,e):F.resolve(e)}}});var ee,Ve=h(()=>{"use strict";ee=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+=`
3
3
  \u5806\u6808\u4FE1\u606F:
4
4
  ${e.stack}`),n}static formatList(e,t="\u2022"){return e.map(n=>`${t} ${n}`).join(`
5
- `)}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,y)=>String(c[l]).padEnd(n[y])).join(" | "));return[r,o,...s].join(`
6
- `)}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 S from"path";import{fileURLToPath as mt}from"url";var C,Q=h(()=>{"use strict";pe();ue();C=class i{static{a(this,"PathUtils")}static getPidFile(){let e=process.env[q.DIR_ENV_VAR]||process.cwd();return S.join(e,`.${He.NAME}.pid`)}static getLogFile(e){let t=e||process.cwd();return S.join(t,He.LOG_FILE)}static getConfigDir(){return process.env[q.DIR_ENV_VAR]||process.cwd()}static getWorkDir(){let e=i.getConfigDir();return S.join(e,he.WORK_DIR)}static getTemplatesDir(){let e=mt(import.meta.url),t=S.dirname(e);return[S.join(t,he.TEMPLATES_DIR),S.join(t,"..","..","..",he.TEMPLATES_DIR),S.join(t,"..","..","..","..",he.TEMPLATES_DIR)]}static findTemplatesDir(){let e=i.getTemplatesDir();for(let t of e)if(f.exists(t))return t;return null}static getTemplatePath(e){let t=i.findTemplatesDir();if(!t)return null;let n=S.join(t,e);return f.exists(n)?n:null}static getScriptDir(){let e=mt(import.meta.url);return S.dirname(e)}static getProjectRoot(){let e=i.getScriptDir();return S.join(e,"..","..","..")}static getDistDir(){let e=i.getProjectRoot();return S.join(e,"dist")}static getRelativePath(e){let t=i.getProjectRoot();return S.relative(t,e)}static resolveConfigPath(e){let t=i.getConfigDir();if(e)return S.join(t,`xiaozhi.config.${e}`);for(let n of q.FILE_NAMES){let r=S.join(t,n);if(f.exists(r))return r}return S.join(t,q.FILE_NAMES[2])}static getDefaultConfigPath(){let e=i.getProjectRoot();return S.join(e,q.DEFAULT_FILE)}static validatePath(e){return!S.normalize(e).includes("..")}static ensurePathWithin(e,t){let n=S.resolve(t,e),r=S.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=S.dirname(t);return S.join(n,`${e}.js`)}static getMcpServerProxyPath(){return i.getExecutablePath("mcpServerProxy")}static getWebServerStandalonePath(){return i.getExecutablePath("WebServerStandalone")}static createSafePath(...e){let t=S.join(...e),n=S.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 ft}from"child_process";var $,de=h(()=>{"use strict";pe();z();$=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=ft(`tasklist /FI "PID eq ${e}" /FO CSV /NH`,{encoding:"utf8",timeout:We.PROCESS_STOP}).toLowerCase():t=ft(`ps -p ${e} -o comm=`,{encoding:"utf8",timeout:We.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 H(`\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 A,Ie=h(()=>{"use strict";z();A=class i{static{a(this,"Validation")}static validatePort(e){if(!Number.isInteger(e)||e<1||e>65535)throw m.invalidPort(e)}static validateConfigFormat(e){let t=["json","json5","jsonc"];if(!t.includes(e))throw new m(`\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 m.requiredField(t)}static validateStringLength(e,t,n={}){if(n.min!==void 0&&e.length<n.min)throw new m(`\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 m(`\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 m(`\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 m(`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 m(`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 m('\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u5305\u542B\u4EE5\u4E0B\u5B57\u7B26: < > : " / \\ | ? * \u4EE5\u53CA\u63A7\u5236\u5B57\u7B26',"projectName");if(e.startsWith("."))throw new m("\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 m("\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 m("\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 m(`\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 m(`\u503C\u4E0D\u80FD\u5C0F\u4E8E ${n.min}\uFF0C\u5F53\u524D\u503C: ${e}`,t);if(n.max!==void 0&&e>n.max)throw new m(`\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 m(`\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 m(`\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 m(`\u7F3A\u5C11\u5FC5\u9700\u7684\u5C5E\u6027: ${r}`,n)}static validateEnum(e,t,n){if(!t.includes(e))throw new m(`\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 m(`\u65E0\u6548\u7684\u6B63\u5219\u8868\u8FBE\u5F0F: ${n instanceof Error?n.message:String(n)}`,t)}}}});import Oe from"fs";import j from"path";import{fileURLToPath as St}from"url";var xe,Ct=h(()=>{"use strict";z();xe=class i{static{a(this,"VersionUtils")}static cachedVersion=null;static getVersion(){if(i.cachedVersion)return i.cachedVersion;try{let e=St(import.meta.url),t=j.dirname(e),n=[j.join(t,"package.json"),j.join(t,"..","package.json"),j.join(t,"..","..","..","package.json"),j.join(t,"..","..","..","..","package.json")];for(let r of n)if(Oe.existsSync(r)){let o=JSON.parse(Oe.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=St(import.meta.url),t=j.dirname(e),n=[j.join(t,"package.json"),j.join(t,"..","package.json"),j.join(t,"..","..","..","package.json"),j.join(t,"..","..","..","..","package.json")];for(let r of n)if(Oe.existsSync(r)){let o=JSON.parse(Oe.readFileSync(r,"utf8"));return{version:o.version||"unknown",name:o.name,description:o.description,author:o.author}}return{version:"unknown"}}catch{throw new g("\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 vt={};K(vt,{ProcessManagerImpl:()=>Ve});var Ve,yt=h(()=>{"use strict";z();ue();Be();Q();de();Ve=class{static{a(this,"ProcessManagerImpl")}getPidFilePath(){return C.getPidFile()}readPidFile(){try{let e=this.getPidFilePath();if(!f.exists(e))return null;let t=f.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();f.writeFile(r,n,{overwrite:!0})}catch{throw new g("\u65E0\u6CD5\u5199\u5165 PID \u6587\u4EF6",this.getPidFilePath())}}isXiaozhiProcess(e){return $.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=Z.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 $.killProcess(e)}catch(t){throw new H(`\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 H(`\u65E0\u6CD5\u505C\u6B62\u8FDB\u7A0B: ${t instanceof Error?t.message:String(t)}`,e)}}cleanupPidFile(){try{let e=this.getPidFilePath();f.exists(e)&&f.deleteFile(e)}catch(e){console.warn("\u6E05\u7406 PID \u6587\u4EF6\u5931\u8D25:",e)}}processExists(e){return $.processExists(e)}cleanupContainerState(){if($.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 wt={};K(wt,{DaemonManagerImpl:()=>Xe});import{spawn as Mt}from"child_process";import $e from"fs";var Xe,Et=h(()=>{"use strict";z();Q();de();Xe=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 v.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 v(`\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 v.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 v(`\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 v(`\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=C.getLogFile();if(!$e.existsSync(t))throw new v("\u65E5\u5FD7\u6587\u4EF6\u4E0D\u5B58\u5728");let{command:n,args:r}=$.getTailCommand(t),o=Mt(n,r,{stdio:"inherit"});process.on("SIGINT",()=>{console.log(`
7
- \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 v(`\u8FDE\u63A5\u65E5\u5FD7\u5931\u8D25: ${s.message}`)})}catch(t){throw new v(`\u8FDE\u63A5\u65E5\u5FD7\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}async spawnDaemonProcess(e,t){let r=[C.getWebServerStandalonePath()];t.openBrowser&&r.push("--open-browser");let o={...process.env,XIAOZHI_CONFIG_DIR:C.getConfigDir(),XIAOZHI_DAEMON:"true",...t.env},s=Mt("node",r,{detached:!0,stdio:["ignore","pipe","pipe"],env:o,cwd:t.cwd||process.cwd()});if(!s.pid)throw new H("\u65E0\u6CD5\u542F\u52A8\u5B88\u62A4\u8FDB\u7A0B",0);return s}async setupLogging(e,t){try{let n=C.getLogFile(),o=(await import("path")).dirname(n);$e.existsSync(o)||$e.mkdirSync(o,{recursive:!0});let s=$e.createWriteStream(n,{flags:"a"});e.stdout?.pipe(s),e.stderr?.pipe(s);let c=new Date().toISOString();s.write(`
5
+ `)}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,S)=>String(c[l]).padEnd(n[S])).join(" | "));return[r,o,...s].join(`
6
+ `)}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 C from"path";import{fileURLToPath as St}from"url";var v,te=h(()=>{"use strict";ue();de();v=class i{static{a(this,"PathUtils")}static getPidFile(){let e=process.env[Y.DIR_ENV_VAR]||process.cwd();return C.join(e,`.${We.NAME}.pid`)}static getLogFile(e){let t=e||process.cwd();return C.join(t,We.LOG_FILE)}static getConfigDir(){return process.env[Y.DIR_ENV_VAR]||process.cwd()}static getWorkDir(){let e=i.getConfigDir();return C.join(e,pe.WORK_DIR)}static getTemplatesDir(){let e=St(import.meta.url),t=C.dirname(e);return[C.join(t,pe.TEMPLATES_DIR),C.join(t,"..","..","..",pe.TEMPLATES_DIR),C.join(t,"..","..","..","..",pe.TEMPLATES_DIR)]}static findTemplatesDir(){let e=i.getTemplatesDir();for(let t of e)if(m.exists(t))return t;return null}static getTemplatePath(e){let t=i.findTemplatesDir();if(!t)return null;let n=C.join(t,e);return m.exists(n)?n:null}static getScriptDir(){let e=St(import.meta.url);return C.dirname(e)}static getProjectRoot(){let e=i.getScriptDir();return C.join(e,"..","..","..")}static getDistDir(){let e=i.getProjectRoot();return C.join(e,"dist")}static getRelativePath(e){let t=i.getProjectRoot();return C.relative(t,e)}static resolveConfigPath(e){let t=i.getConfigDir();if(e)return C.join(t,`xiaozhi.config.${e}`);for(let n of Y.FILE_NAMES){let r=C.join(t,n);if(m.exists(r))return r}return C.join(t,Y.FILE_NAMES[2])}static getDefaultConfigPath(){let e=i.getProjectRoot();return C.join(e,Y.DEFAULT_FILE)}static validatePath(e){return!C.normalize(e).includes("..")}static ensurePathWithin(e,t){let n=C.resolve(t,e),r=C.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=C.dirname(t);return C.join(n,`${e}.js`)}static getMcpServerProxyPath(){return i.getExecutablePath("mcpServerProxy")}static getWebServerStandalonePath(){return i.getExecutablePath("WebServerStandalone")}static createSafePath(...e){let t=C.join(...e),n=C.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 Ct}from"child_process";var N,fe=h(()=>{"use strict";ue();U();N=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=Ct(`tasklist /FI "PID eq ${e}" /FO CSV /NH`,{encoding:"utf8",timeout:Be.PROCESS_STOP}).toLowerCase():t=Ct(`ps -p ${e} -o comm=`,{encoding:"utf8",timeout:Be.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 B(`\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 k,Oe=h(()=>{"use strict";U();k=class i{static{a(this,"Validation")}static validatePort(e){if(!Number.isInteger(e)||e<1||e>65535)throw f.invalidPort(e)}static validateConfigFormat(e){let t=["json","json5","jsonc"];if(!t.includes(e))throw new f(`\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 f.requiredField(t)}static validateStringLength(e,t,n={}){if(n.min!==void 0&&e.length<n.min)throw new f(`\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 f(`\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 f(`\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 f(`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 f(`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 f('\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u5305\u542B\u4EE5\u4E0B\u5B57\u7B26: < > : " / \\ | ? * \u4EE5\u53CA\u63A7\u5236\u5B57\u7B26',"projectName");if(e.startsWith("."))throw new f("\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 f("\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 f("\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 f(`\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 f(`\u503C\u4E0D\u80FD\u5C0F\u4E8E ${n.min}\uFF0C\u5F53\u524D\u503C: ${e}`,t);if(n.max!==void 0&&e>n.max)throw new f(`\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 f(`\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 f(`\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 f(`\u7F3A\u5C11\u5FC5\u9700\u7684\u5C5E\u6027: ${r}`,n)}static validateEnum(e,t,n){if(!t.includes(e))throw new f(`\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 f(`\u65E0\u6548\u7684\u6B63\u5219\u8868\u8FBE\u5F0F: ${n instanceof Error?n.message:String(n)}`,t)}}}});import xe from"fs";import _ from"path";import{fileURLToPath as vt}from"url";var $e,yt=h(()=>{"use strict";U();$e=class i{static{a(this,"VersionUtils")}static cachedVersion=null;static getVersion(){if(i.cachedVersion)return i.cachedVersion;try{let e=vt(import.meta.url),t=_.dirname(e),n=[_.join(t,"package.json"),_.join(t,"..","package.json"),_.join(t,"..","..","..","package.json"),_.join(t,"..","..","..","..","package.json")];for(let r of n)if(xe.existsSync(r)){let o=JSON.parse(xe.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=vt(import.meta.url),t=_.dirname(e),n=[_.join(t,"package.json"),_.join(t,"..","package.json"),_.join(t,"..","..","..","package.json"),_.join(t,"..","..","..","..","package.json")];for(let r of n)if(xe.existsSync(r)){let o=JSON.parse(xe.readFileSync(r,"utf8"));return{version:o.version||"unknown",name:o.name,description:o.description,author:o.author}}return{version:"unknown"}}catch{throw new g("\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 Mt={};Z(Mt,{ProcessManagerImpl:()=>Xe});var Xe,wt=h(()=>{"use strict";U();de();Ve();te();fe();Xe=class{static{a(this,"ProcessManagerImpl")}getPidFilePath(){return v.getPidFile()}readPidFile(){try{let e=this.getPidFilePath();if(!m.exists(e))return null;let t=m.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();m.writeFile(r,n,{overwrite:!0})}catch{throw new g("\u65E0\u6CD5\u5199\u5165 PID \u6587\u4EF6",this.getPidFilePath())}}isXiaozhiProcess(e){return N.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=ee.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 N.killProcess(e)}catch(t){throw new B(`\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 B(`\u65E0\u6CD5\u505C\u6B62\u8FDB\u7A0B: ${t instanceof Error?t.message:String(t)}`,e)}}cleanupPidFile(){try{let e=this.getPidFilePath();m.exists(e)&&m.deleteFile(e)}catch(e){console.warn("\u6E05\u7406 PID \u6587\u4EF6\u5931\u8D25:",e)}}processExists(e){return N.processExists(e)}cleanupContainerState(){if(N.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 Pt={};Z(Pt,{DaemonManagerImpl:()=>Ge});import{spawn as Et}from"child_process";import Ne from"fs";var Ge,bt=h(()=>{"use strict";U();te();fe();Ge=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 y.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 y(`\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 y.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 y(`\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 y(`\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=v.getLogFile();if(!Ne.existsSync(t))throw new y("\u65E5\u5FD7\u6587\u4EF6\u4E0D\u5B58\u5728");let{command:n,args:r}=N.getTailCommand(t),o=Et(n,r,{stdio:"inherit"});process.on("SIGINT",()=>{console.log(`
7
+ \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 y(`\u8FDE\u63A5\u65E5\u5FD7\u5931\u8D25: ${s.message}`)})}catch(t){throw new y(`\u8FDE\u63A5\u65E5\u5FD7\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}async spawnDaemonProcess(e,t){let r=[v.getWebServerStandalonePath()];t.openBrowser&&r.push("--open-browser");let o={...process.env,XIAOZHI_CONFIG_DIR:v.getConfigDir(),XIAOZHI_DAEMON:"true",...t.env},s=Et("node",r,{detached:!0,stdio:["ignore","pipe","pipe"],env:o,cwd:t.cwd||process.cwd()});if(!s.pid)throw new B("\u65E0\u6CD5\u542F\u52A8\u5B88\u62A4\u8FDB\u7A0B",0);return s}async setupLogging(e,t){try{let n=v.getLogFile(),o=(await import("path")).dirname(n);Ne.existsSync(o)||Ne.mkdirSync(o,{recursive:!0});let s=Ne.createWriteStream(n,{flags:"a"});e.stdout?.pipe(s),e.stderr?.pipe(s);let c=new Date().toISOString();s.write(`
8
8
  [${c}] \u5B88\u62A4\u8FDB\u7A0B\u542F\u52A8 (PID: ${e.pid})
9
- `)}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}}}});var Y,me=h(()=>{"use strict";b();Y=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=u}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 jn}from"crypto";import Ge from"express";var Ne,Pt=h(()=>{"use strict";me();Ne=class extends Y{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=Ge(),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(Ge.json({limit:"10mb"})),this.app.use(Ge.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=jn();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
9
+ `)}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}}}});var ne,me=h(()=>{"use strict";T();ne=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=u}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 _n}from"crypto";import Ke from"express";var De,Tt=h(()=>{"use strict";me();De=class extends ne{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=Ke(),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(Ke.json({limit:"10mb"})),this.app.use(Ke.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=_n();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
10
10
  data: /messages?sessionId=${r}
11
11
 
12
12
  `),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}
13
13
 
14
- `),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 bt=h(()=>{"use strict";me()});import to,{WebSocketServer as no}from"ws";var Tt=h(()=>{"use strict";me()});var fe,Rt,Je=h(()=>{"use strict";b();ge();we();fe=class{static{a(this,"MCPServiceManager")}services=new Map;configs={};logger;tools=new Map;constructor(e){this.logger=u,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 Ee(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=d.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}`)}},Rt=fe});var De,It=h(()=>{"use strict";b();De=class{static{a(this,"MCPMessageHandler")}logger;serviceManager;constructor(e){this.serviceManager=e,this.logger=u}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 Ot}from"events";var qe,Ze,Ae,xt=h(()=>{"use strict";b();Je();me();It();qe=class{static{a(this,"ToolRegistry")}serviceManager;logger;constructor(e){this.serviceManager=e,this.logger=u}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}},Ze=class extends Ot{static{a(this,"ConnectionManager")}connections=new Map;logger;constructor(){super(),this.logger=u}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")}},Ae=class extends Ot{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=u,this.serviceManager=new fe,this.messageHandler=new De(this.serviceManager),this.toolRegistry=new qe(this.serviceManager),this.connectionManager=new Ze,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 $t(i={name:"http"}){u.info("\u521B\u5EFA HTTP \u6A21\u5F0F\u670D\u52A1\u5668");let e=new Ae;await e.initialize();let t=e.getMessageHandler(),n=new Ne(t,i);return await e.registerTransport("http",n),u.info("HTTP \u6A21\u5F0F\u670D\u52A1\u5668\u521B\u5EFA\u6210\u529F"),e}var Nt=h(()=>{"use strict";b();Pt();bt();Tt();xt();a($t,"createHTTPServer")});var Dt={};K(Dt,{MCPServer:()=>Qe});import{EventEmitter as Un}from"events";var E,Qe,At=h(()=>{"use strict";b();Me();ge();Nt();E=new ce,Qe=class extends Un{static{a(this,"MCPServer")}unifiedServer=null;proxyMCPServer=null;port;isStarted=!1;constructor(e=3e3){super(),this.port=e}async initializeUnifiedServer(){if(!this.unifiedServer){E.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 $t(e),this.unifiedServer.on("started",()=>this.emit("started")),this.unifiedServer.on("stopped",()=>this.emit("stopped")),this.unifiedServer.on("connectionRegistered",t=>{this.emit("connectionRegistered",t)}),E.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw E.error("\u521D\u59CB\u5316\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u5931\u8D25",e),e}}}async initializeMCPClient(){try{let e=null;try{d.configExists()&&(e=d.getMcpEndpoints().find(n=>n&&!n.includes("<\u8BF7\u586B\u5199"))||null)}catch(t){E.warn("\u4ECE\u914D\u7F6E\u4E2D\u8BFB\u53D6\u5C0F\u667A\u63A5\u5165\u70B9\u5931\u8D25:",t)}e?(this.proxyMCPServer=new W(e),this.unifiedServer&&this.proxyMCPServer.setServiceManager(this.unifiedServer.getServiceManager()),await this.proxyMCPServer.connect(),E.info("\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u6210\u529F")):E.info("\u672A\u914D\u7F6E\u6709\u6548\u7684\u5C0F\u667A\u63A5\u5165\u70B9\uFF0C\u8DF3\u8FC7\u8FDE\u63A5")}catch(e){E.error("\u521D\u59CB\u5316\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u5931\u8D25:",e)}}async start(){if(this.isStarted){E.warn("\u670D\u52A1\u5668\u5DF2\u542F\u52A8");return}try{E.info("\u542F\u52A8 MCP \u670D\u52A1\u5668"),await this.initializeUnifiedServer(),this.unifiedServer&&await this.unifiedServer.start(),this.initializeMCPClient().catch(e=>{E.error("\u521D\u59CB\u5316\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u5931\u8D25:",e)}),this.isStarted=!0,this.emit("started"),E.info("MCP \u670D\u52A1\u5668\u542F\u52A8\u6210\u529F")}catch(e){throw E.error("\u542F\u52A8 MCP \u670D\u52A1\u5668\u5931\u8D25:",e),e}}async stop(){if(!this.isStarted){E.warn("\u670D\u52A1\u5668\u672A\u542F\u52A8");return}try{E.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"),E.info("MCP \u670D\u52A1\u5668\u5DF2\u505C\u6B62")}catch(e){throw E.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)}}});var Ft={};K(Ft,{ServiceManagerImpl:()=>Ye});var Ye,kt=h(()=>{"use strict";z();Q();de();Ie();Ye=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 v.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 v?t:v.startFailed(t instanceof Error?t.message:String(t))}}async stop(){try{let e=this.getStatus();if(!e.running)throw v.notRunning();await this.processManager.gracefulKillProcess(e.pid),this.processManager.cleanupPidFile()}catch(e){throw e instanceof v?e:new v(`\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 v(`\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&&A.validatePort(e.port),e.mode&&!["normal","mcp-server","stdio"].includes(e.mode))throw new v(`\u65E0\u6548\u7684\u8FD0\u884C\u6A21\u5F0F: ${e.mode}`)}checkEnvironment(){if(!this.configManager.configExists())throw X.configNotFound();try{if(!this.configManager.getConfig())throw new X("\u914D\u7F6E\u6587\u4EF6\u65E0\u6548")}catch(e){throw e instanceof X?e:new X(`\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=C.getExecutablePath("cli"),o=n("node",[r,"start","--server",t.toString()],{detached:!0,stdio:["ignore","ignore","ignore"],env:{...process.env,XIAOZHI_CONFIG_DIR:C.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(()=>(At(),Dt)),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=C.getMcpServerProxyPath(),r=t("node",[n],{stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:C.getConfigDir()}});this.processManager.savePidInfo(r.pid,"foreground")}async startWebServerInDaemon(e){let{spawn:t}=await import("child_process"),n=C.getWebServerStandalonePath();if(!(await import("fs")).default.existsSync(n))throw new v(`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:C.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(()=>(zt(),Lt)),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=$.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 jt={};K(jt,{TemplateManagerImpl:()=>et});import _n from"fs";import G from"path";var et,Ut=h(()=>{"use strict";z();ue();Q();Ie();et=class{static{a(this,"TemplateManagerImpl")}templateCache=new Map;async getAvailableTemplates(){try{let e=C.findTemplatesDir();if(!e)return[];let t=[],n=_n.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 g("\u65E0\u6CD5\u8BFB\u53D6\u6A21\u677F\u76EE\u5F55",C.findTemplatesDir()||"")}}async getTemplateInfo(e){try{if(A.validateTemplateName(e),this.templateCache.has(e))return this.templateCache.get(e);let t=C.getTemplatePath(e);if(!t)return null;let n=G.join(t,"template.json"),r={};if(f.exists(n))try{let c=f.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 m?t:new g(`\u65E0\u6CD5\u83B7\u53D6\u6A21\u677F\u4FE1\u606F: ${e}`,"")}}async copyTemplate(e,t){await this.createProject({templateName:e,targetPath:t,projectName:G.basename(t)})}async createProject(e){try{this.validateCreateOptions(e);let t=e.templateName||"default",n=await this.getTemplateInfo(t);if(!n)throw new g(`\u6A21\u677F\u4E0D\u5B58\u5728: ${t}`,"");let r=G.resolve(e.targetPath);if(f.exists(r))throw g.alreadyExists(r);f.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 g||t instanceof m?t:new g(`\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=G.join(t.path,r);if(!f.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 f.listDirectory(e,{recursive:!0,includeHidden:!1}).filter(n=>{let r=G.relative(e,n);return!r.startsWith(".")&&r!=="template.json"&&!r.includes("node_modules")})}catch{return[]}}validateCreateOptions(e){A.validateRequired(e.targetPath,"targetPath"),A.validateRequired(e.projectName,"projectName"),A.validateProjectName(e.projectName),e.templateName&&A.validateTemplateName(e.templateName)}async copyTemplateFiles(e,t,n){try{f.copyDirectory(e.path,t,{exclude:["template.json",".git","node_modules"],overwrite:!1,recursive:!0})}catch(r){throw new g(`\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=G.join(e,t);return f.exists(o)?[o]:[]}let n=f.listDirectory(e,{recursive:!0}),r=new RegExp(t.replace(/\*\*/g,".*").replace(/\*/g,"[^/]*"));return n.filter(o=>{let s=G.relative(e,o);return r.test(s)})}catch{return[]}}async replaceVariablesInFile(e,t){try{let n=f.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&&f.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 _t(){return tt.create()}var tt,Ht=h(()=>{"use strict";b();ge();dt();ue();Be();Q();de();Ie();Ct();tt=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",()=>xe),e.registerSingleton("platformUtils",()=>$),e.registerSingleton("formatUtils",()=>Z),e.registerSingleton("fileUtils",()=>f),e.registerSingleton("pathUtils",()=>C),e.registerSingleton("validation",()=>A),e.registerSingleton("configManager",()=>d),e.registerSingleton("logger",()=>u),e.registerSingleton("errorHandler",()=>Re),e.registerSingleton("processManager",()=>{let t=(yt(),ye(vt));return new t.ProcessManagerImpl}),e.registerSingleton("daemonManager",()=>{let t=(Et(),ye(wt)),n=e.get("processManager"),r=e.get("logger");return new t.DaemonManagerImpl(n,r)}),e.registerSingleton("serviceManager",()=>{let t=(kt(),ye(Ft)),n=e.get("processManager"),r=e.get("configManager"),o=e.get("logger");return new t.ServiceManagerImpl(n,r,o)}),e.registerSingleton("templateManager",()=>{let t=(Ut(),ye(jt));return new t.TemplateManagerImpl}),e}};a(_t,"createContainer")});async function Hn(){return console.log("\u{1F680} \u6B63\u5728\u521D\u59CB\u5316 MCPServiceManager \u5355\u4F8B..."),new Rt}async function Wt(){if(U&&O==="initialized")return U;if(k&&O==="initializing")return k;O==="failed"&&nt(),O="initializing",k=Hn();try{return U=await k,O="initialized",ee=`mcp-manager-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,Se=null,console.log(`\u2705 MCPServiceManager \u5355\u4F8B\u521D\u59CB\u5316\u6210\u529F\uFF0C\u5B9E\u4F8BID: ${ee}`),U}catch(i){throw O="failed",Se=i,k=null,console.error("\u274C MCPServiceManager \u5355\u4F8B\u521D\u59CB\u5316\u5931\u8D25:",i.message),i}}async function Bt(){if(O==="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..."),O="cleanup";try{if(k){try{await(await k).stopAllServices()}catch(i){console.error("\u6E05\u7406\u521D\u59CB\u5316\u4E2D\u7684\u5B9E\u4F8B\u5931\u8D25:",i.message)}k=null}U&&(await U.stopAllServices(),U=null),O="not_initialized",Se=null,ee=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),nt(),i}}function nt(){console.log("\u{1F504} \u91CD\u7F6E MCPServiceManager \u5355\u4F8B\u72B6\u6001"),U=null,k=null,O="not_initialized",Se=null,ee=null}function Wn(){return O==="initialized"&&U!==null}function Bn(){return{state:O,initializationTime:ee?new Date:void 0,lastError:Se||void 0,instanceId:ee||void 0}}async function Vn(){return console.log("\u{1F504} \u5F3A\u5236\u91CD\u65B0\u521D\u59CB\u5316 MCPServiceManager \u5355\u4F8B..."),await Bt(),Wt()}function Xn(){return U}async function Gn(){if(O==="initialized")return!0;if(O==="initializing"&&k)try{return await k,!0}catch{return!1}return!1}var U,k,O,Se,ee,te,Vt=h(()=>{"use strict";Je();U=null,k=null,O="not_initialized",Se=null,ee=null;a(Hn,"createInstance");a(Wt,"getInstance");a(Bt,"cleanup");a(nt,"reset");a(Wn,"isInitialized");a(Bn,"getStatus");a(Vn,"forceReinitialize");a(Xn,"getCurrentInstance");a(Gn,"waitForInitialization");te={getInstance:Wt,cleanup:Bt,reset:nt,isInitialized:Wn,getStatus:Bn,forceReinitialize:Vn,getCurrentInstance:Xn,waitForInitialization:Gn};process.on("exit",()=>{te.isInitialized()&&(console.log("\u{1F504} \u8FDB\u7A0B\u9000\u51FA\uFF0C\u6B63\u5728\u6E05\u7406 MCPServiceManager \u5355\u4F8B..."),te.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 te.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 te.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}})});import{EventEmitter as Kn}from"events";var Xt,Jn,Fe,Gt=h(()=>{"use strict";b();Me();Xt=(r=>(r.EXPONENTIAL_BACKOFF="exponential_backoff",r.LINEAR_BACKOFF="linear_backoff",r.FIXED_INTERVAL="fixed_interval",r.ADAPTIVE="adaptive",r))(Xt||{}),Jn={healthCheckInterval:3e4,reconnectInterval:5e3,maxReconnectAttempts:10,loadBalanceStrategy:"round-robin",connectionTimeout:1e4,reconnectStrategy:"exponential_backoff",maxReconnectDelay:3e4,reconnectBackoffMultiplier:2,jitterEnabled:!0},Fe=class extends Kn{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=u,this.options={...Jn,...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(Xt);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(y=>!o.includes(y)),c=o.filter(y=>!n.includes(y)),l=o.filter(y=>n.includes(y));this.logger.info(`\u7AEF\u70B9\u53D8\u66F4 - \u6DFB\u52A0: ${s.length}, \u79FB\u9664: ${c.length}, \u4FDD\u6301: ${l.length}`);try{for(let B of c)await this.removeEndpoint(B);for(let B of s)await this.addEndpoint(B);let y={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",y),this.logger.info("\u7AEF\u70B9\u914D\u7F6E\u66F4\u65B0\u5B8C\u6210")}catch(y){throw this.logger.error("\u7AEF\u70B9\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",y),y}}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 W(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 qn(i){return console.log("\u{1F680} \u6B63\u5728\u521D\u59CB\u5316 XiaozhiConnectionManager \u5355\u4F8B..."),new Fe(i)}async function Kt(i){if(_&&x==="initialized")return _;if(F&&x==="initializing")return F;x==="failed"&&rt(),x="initializing",F=qn(i);try{return _=await F,x="initialized",ne=`xiaozhi-connection-manager-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,Ce=null,console.log(`\u2705 XiaozhiConnectionManager \u5355\u4F8B\u521D\u59CB\u5316\u6210\u529F\uFF0C\u5B9E\u4F8BID: ${ne}`),_}catch(e){throw x="failed",Ce=e,F=null,console.error("\u274C XiaozhiConnectionManager \u5355\u4F8B\u521D\u59CB\u5316\u5931\u8D25:",e.message),e}}async function Jt(){if(x==="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..."),x="cleanup";try{if(F){try{await(await F).cleanup()}catch(i){console.error("\u6E05\u7406\u521D\u59CB\u5316\u4E2D\u7684\u5B9E\u4F8B\u5931\u8D25:",i.message)}F=null}_&&(await _.cleanup(),_=null),x="not_initialized",Ce=null,ne=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),rt(),i}}function rt(){console.log("\u{1F504} \u91CD\u7F6E XiaozhiConnectionManager \u5355\u4F8B\u72B6\u6001..."),F&&(F=null),_=null,x="not_initialized",Ce=null,ne=null,console.log("\u2705 XiaozhiConnectionManager \u5355\u4F8B\u72B6\u6001\u5DF2\u91CD\u7F6E")}function Zn(){return x==="initialized"&&_!==null}function Qn(){return{state:x,initializationTime:ne?new Date:void 0,lastError:Ce||void 0,instanceId:ne||void 0}}async function Yn(i){return console.log("\u{1F504} \u5F3A\u5236\u91CD\u65B0\u521D\u59CB\u5316 XiaozhiConnectionManager \u5355\u4F8B..."),await Jt(),Kt(i)}function er(){return _}async function tr(){if(x==="initialized")return!0;if(x==="initializing"&&F)try{return await F,!0}catch{return!1}return!1}var _,F,x,Ce,ne,re,qt=h(()=>{"use strict";Gt();_=null,F=null,x="not_initialized",Ce=null,ne=null;a(qn,"createInstance");a(Kt,"getInstance");a(Jt,"cleanup");a(rt,"reset");a(Zn,"isInitialized");a(Qn,"getStatus");a(Yn,"forceReinitialize");a(er,"getCurrentInstance");a(tr,"waitForInitialization");re={getInstance:Kt,cleanup:Jt,reset:rt,isInitialized:Zn,getStatus:Qn,forceReinitialize:Yn,getCurrentInstance:er,waitForInitialization:tr};process.on("exit",()=>{re.isInitialized()&&(console.log("\u{1F504} \u8FDB\u7A0B\u9000\u51FA\uFF0C\u6B63\u5728\u6E05\u7406 XiaozhiConnectionManager \u5355\u4F8B..."),re.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 re.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 re.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}})});var Lt={};K(Lt,{WebServer:()=>ot});import{spawn as Zt}from"child_process";import{existsSync as it}from"fs";import{readFile as Qt}from"fs/promises";import{createServer as nr}from"http";import{dirname as rr,join as ie}from"path";import{fileURLToPath as ir}from"url";import{serve as or}from"@hono/node-server";import{Hono as sr}from"hono";import{cors as ar}from"hono/cors";import{WebSocketServer as cr}from"ws";var ot,zt=h(()=>{b();Me();lt();Ht();ge();Vt();qt();ot=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??d.getWebUIPort()??9999}catch{this.port=e??9999}this.logger=u,this.app=new sr,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 te.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(!d.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=d.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=ct(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 re.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 W(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(y){if(c=y,this.logger.warn(`${t} - \u8FDE\u63A5\u5931\u8D25:`,y),l<n){let B=Math.min(r*s**(l-1),o);this.logger.info(`${t} - ${B}ms \u540E\u91CD\u8BD5...`),await this.sleep(B)}}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("*",ar({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=d.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=rr(ir(import.meta.url)),o=[ie(n,"..","web","dist"),ie(n,"..","web"),ie(process.cwd(),"web","dist"),ie(process.cwd(),"web")].find(se=>it(se));if(!o)return e.html(`
14
+ `),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 Rt=h(()=>{"use strict";me()});import ro,{WebSocketServer as io}from"ws";var It=h(()=>{"use strict";me()});var Se,Ot,qe=h(()=>{"use strict";T();he();Ee();Se=class{static{a(this,"MCPServiceManager")}services=new Map;configs={};logger;tools=new Map;constructor(e){this.logger=u,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 Pe(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})}}await this.syncToolsConfigToFile()}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=d.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}`)}async syncToolsConfigToFile(){try{this.logger.debug("[MCPManager] \u5F00\u59CB\u540C\u6B65\u5DE5\u5177\u914D\u7F6E\u5230\u914D\u7F6E\u6587\u4EF6");let e=d.getMcpServerConfig();for(let[t,n]of this.services){if(!n.isConnected())continue;let r=n.getTools();if(r.length===0)continue;let o=e[t]?.tools||{},s={};for(let M of r){let D=o[M.name];D?s[M.name]={...D,description:M.description||D.description||""}:s[M.name]={description:M.description||"",enable:!0}}let c=r.map(M=>M.name),S=Object.keys(o).filter(M=>!c.includes(M));if(S.length>0&&this.logger.info(`[MCPManager] \u68C0\u6D4B\u5230\u670D\u52A1 ${t} \u79FB\u9664\u4E86 ${S.length} \u4E2A\u5DE5\u5177: ${S.join(", ")}`),this.hasToolsConfigChanged(o,s)){d.updateServerToolsConfig(t,s);let M=Object.keys(s).filter(q=>!o[q]),D=Object.keys(s).filter(q=>{let at=o[q],tn=s[q];return at&&at.description!==tn.description});this.logger.info(`[MCPManager] \u5DF2\u540C\u6B65\u670D\u52A1 ${t} \u7684\u5DE5\u5177\u914D\u7F6E:`),M.length>0&&this.logger.info(` - \u65B0\u589E\u5DE5\u5177: ${M.join(", ")}`),D.length>0&&this.logger.info(` - \u66F4\u65B0\u5DE5\u5177: ${D.join(", ")}`),S.length>0&&this.logger.info(` - \u79FB\u9664\u5DE5\u5177: ${S.join(", ")}`)}}this.logger.debug("[MCPManager] \u5DE5\u5177\u914D\u7F6E\u540C\u6B65\u5B8C\u6210")}catch(e){this.logger.error("[MCPManager] \u540C\u6B65\u5DE5\u5177\u914D\u7F6E\u5230\u914D\u7F6E\u6587\u4EF6\u5931\u8D25:",e)}}hasToolsConfigChanged(e,t){let n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!0;let o=r.filter(c=>!n.includes(c)),s=n.filter(c=>!r.includes(c));if(o.length>0||s.length>0)return!0;for(let c of n){let l=e[c],S=t[c];if(l.description!==S.description)return!0}return!1}},Ot=Se});var Ae,xt=h(()=>{"use strict";T();Ae=class{static{a(this,"MCPMessageHandler")}logger;serviceManager;constructor(e){this.serviceManager=e,this.logger=u}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 $t}from"events";var Ze,Qe,Fe,Nt=h(()=>{"use strict";T();qe();me();xt();Ze=class{static{a(this,"ToolRegistry")}serviceManager;logger;constructor(e){this.serviceManager=e,this.logger=u}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}},Qe=class extends $t{static{a(this,"ConnectionManager")}connections=new Map;logger;constructor(){super(),this.logger=u}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")}},Fe=class extends $t{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=u,this.serviceManager=new Se,this.messageHandler=new Ae(this.serviceManager),this.toolRegistry=new Ze(this.serviceManager),this.connectionManager=new Qe,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 Dt(i={name:"http"}){u.info("\u521B\u5EFA HTTP \u6A21\u5F0F\u670D\u52A1\u5668");let e=new Fe;await e.initialize();let t=e.getMessageHandler(),n=new De(t,i);return await e.registerTransport("http",n),u.info("HTTP \u6A21\u5F0F\u670D\u52A1\u5668\u521B\u5EFA\u6210\u529F"),e}var At=h(()=>{"use strict";T();Tt();Rt();It();Nt();a(Dt,"createHTTPServer")});var Ft={};Z(Ft,{MCPServer:()=>Ye});import{EventEmitter as Hn}from"events";var P,Ye,kt=h(()=>{"use strict";T();we();he();At();P=new le,Ye=class extends Hn{static{a(this,"MCPServer")}unifiedServer=null;proxyMCPServer=null;port;isStarted=!1;constructor(e=3e3){super(),this.port=e}async initializeUnifiedServer(){if(!this.unifiedServer){P.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 Dt(e),this.unifiedServer.on("started",()=>this.emit("started")),this.unifiedServer.on("stopped",()=>this.emit("stopped")),this.unifiedServer.on("connectionRegistered",t=>{this.emit("connectionRegistered",t)}),P.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw P.error("\u521D\u59CB\u5316\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u5931\u8D25",e),e}}}async initializeMCPClient(){try{let e=null;try{d.configExists()&&(e=d.getMcpEndpoints().find(n=>n&&!n.includes("<\u8BF7\u586B\u5199"))||null)}catch(t){P.warn("\u4ECE\u914D\u7F6E\u4E2D\u8BFB\u53D6\u5C0F\u667A\u63A5\u5165\u70B9\u5931\u8D25:",t)}e?(this.proxyMCPServer=new X(e),this.unifiedServer&&this.proxyMCPServer.setServiceManager(this.unifiedServer.getServiceManager()),await this.proxyMCPServer.connect(),P.info("\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u6210\u529F")):P.info("\u672A\u914D\u7F6E\u6709\u6548\u7684\u5C0F\u667A\u63A5\u5165\u70B9\uFF0C\u8DF3\u8FC7\u8FDE\u63A5")}catch(e){P.error("\u521D\u59CB\u5316\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u5931\u8D25:",e)}}async start(){if(this.isStarted){P.warn("\u670D\u52A1\u5668\u5DF2\u542F\u52A8");return}try{P.info("\u542F\u52A8 MCP \u670D\u52A1\u5668"),await this.initializeUnifiedServer(),this.unifiedServer&&await this.unifiedServer.start(),this.initializeMCPClient().catch(e=>{P.error("\u521D\u59CB\u5316\u5C0F\u667A\u63A5\u5165\u70B9\u8FDE\u63A5\u5931\u8D25:",e)}),this.isStarted=!0,this.emit("started"),P.info("MCP \u670D\u52A1\u5668\u542F\u52A8\u6210\u529F")}catch(e){throw P.error("\u542F\u52A8 MCP \u670D\u52A1\u5668\u5931\u8D25:",e),e}}async stop(){if(!this.isStarted){P.warn("\u670D\u52A1\u5668\u672A\u542F\u52A8");return}try{P.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"),P.info("MCP \u670D\u52A1\u5668\u5DF2\u505C\u6B62")}catch(e){throw P.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)}}});var Lt={};Z(Lt,{ServiceManagerImpl:()=>et});var et,zt=h(()=>{"use strict";U();te();fe();Oe();et=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 y.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 y?t:y.startFailed(t instanceof Error?t.message:String(t))}}async stop(){try{let e=this.getStatus();if(!e.running)throw y.notRunning();await this.processManager.gracefulKillProcess(e.pid),this.processManager.cleanupPidFile()}catch(e){throw e instanceof y?e:new y(`\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 y(`\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&&k.validatePort(e.port),e.mode&&!["normal","mcp-server","stdio"].includes(e.mode))throw new y(`\u65E0\u6548\u7684\u8FD0\u884C\u6A21\u5F0F: ${e.mode}`)}checkEnvironment(){if(!this.configManager.configExists())throw K.configNotFound();try{if(!this.configManager.getConfig())throw new K("\u914D\u7F6E\u6587\u4EF6\u65E0\u6548")}catch(e){throw e instanceof K?e:new K(`\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=v.getExecutablePath("cli"),o=n("node",[r,"start","--server",t.toString()],{detached:!0,stdio:["ignore","ignore","ignore"],env:{...process.env,XIAOZHI_CONFIG_DIR:v.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(()=>(kt(),Ft)),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=v.getMcpServerProxyPath(),r=t("node",[n],{stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:v.getConfigDir()}});this.processManager.savePidInfo(r.pid,"foreground")}async startWebServerInDaemon(e){let{spawn:t}=await import("child_process"),n=v.getWebServerStandalonePath();if(!(await import("fs")).default.existsSync(n))throw new y(`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:v.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(()=>(Ut(),jt)),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=N.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 _t={};Z(_t,{TemplateManagerImpl:()=>tt});import Wn from"fs";import J from"path";var tt,Ht=h(()=>{"use strict";U();de();te();Oe();tt=class{static{a(this,"TemplateManagerImpl")}templateCache=new Map;async getAvailableTemplates(){try{let e=v.findTemplatesDir();if(!e)return[];let t=[],n=Wn.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 g("\u65E0\u6CD5\u8BFB\u53D6\u6A21\u677F\u76EE\u5F55",v.findTemplatesDir()||"")}}async getTemplateInfo(e){try{if(k.validateTemplateName(e),this.templateCache.has(e))return this.templateCache.get(e);let t=v.getTemplatePath(e);if(!t)return null;let n=J.join(t,"template.json"),r={};if(m.exists(n))try{let c=m.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 f?t:new g(`\u65E0\u6CD5\u83B7\u53D6\u6A21\u677F\u4FE1\u606F: ${e}`,"")}}async copyTemplate(e,t){await this.createProject({templateName:e,targetPath:t,projectName:J.basename(t)})}async createProject(e){try{this.validateCreateOptions(e);let t=e.templateName||"default",n=await this.getTemplateInfo(t);if(!n)throw new g(`\u6A21\u677F\u4E0D\u5B58\u5728: ${t}`,"");let r=J.resolve(e.targetPath);if(m.exists(r))throw g.alreadyExists(r);m.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 g||t instanceof f?t:new g(`\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=J.join(t.path,r);if(!m.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 m.listDirectory(e,{recursive:!0,includeHidden:!1}).filter(n=>{let r=J.relative(e,n);return!r.startsWith(".")&&r!=="template.json"&&!r.includes("node_modules")})}catch{return[]}}validateCreateOptions(e){k.validateRequired(e.targetPath,"targetPath"),k.validateRequired(e.projectName,"projectName"),k.validateProjectName(e.projectName),e.templateName&&k.validateTemplateName(e.templateName)}async copyTemplateFiles(e,t,n){try{m.copyDirectory(e.path,t,{exclude:["template.json",".git","node_modules"],overwrite:!1,recursive:!0})}catch(r){throw new g(`\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=J.join(e,t);return m.exists(o)?[o]:[]}let n=m.listDirectory(e,{recursive:!0}),r=new RegExp(t.replace(/\*\*/g,".*").replace(/\*/g,"[^/]*"));return n.filter(o=>{let s=J.relative(e,o);return r.test(s)})}catch{return[]}}async replaceVariablesInFile(e,t){try{let n=m.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&&m.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 Wt(){return nt.create()}var nt,Bt=h(()=>{"use strict";T();he();mt();de();Ve();te();fe();Oe();yt();nt=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",()=>$e),e.registerSingleton("platformUtils",()=>N),e.registerSingleton("formatUtils",()=>ee),e.registerSingleton("fileUtils",()=>m),e.registerSingleton("pathUtils",()=>v),e.registerSingleton("validation",()=>k),e.registerSingleton("configManager",()=>d),e.registerSingleton("logger",()=>u),e.registerSingleton("errorHandler",()=>Ie),e.registerSingleton("processManager",()=>{let t=(wt(),Me(Mt));return new t.ProcessManagerImpl}),e.registerSingleton("daemonManager",()=>{let t=(bt(),Me(Pt)),n=e.get("processManager"),r=e.get("logger");return new t.DaemonManagerImpl(n,r)}),e.registerSingleton("serviceManager",()=>{let t=(zt(),Me(Lt)),n=e.get("processManager"),r=e.get("configManager"),o=e.get("logger");return new t.ServiceManagerImpl(n,r,o)}),e.registerSingleton("templateManager",()=>{let t=(Ht(),Me(_t));return new t.TemplateManagerImpl}),e}};a(Wt,"createContainer")});async function Bn(){return console.log("\u{1F680} \u6B63\u5728\u521D\u59CB\u5316 MCPServiceManager \u5355\u4F8B..."),new Ot}async function Vt(){if(H&&x==="initialized")return H;if(z&&x==="initializing")return z;x==="failed"&&rt(),x="initializing",z=Bn();try{return H=await z,x="initialized",re=`mcp-manager-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,Ce=null,console.log(`\u2705 MCPServiceManager \u5355\u4F8B\u521D\u59CB\u5316\u6210\u529F\uFF0C\u5B9E\u4F8BID: ${re}`),H}catch(i){throw x="failed",Ce=i,z=null,console.error("\u274C MCPServiceManager \u5355\u4F8B\u521D\u59CB\u5316\u5931\u8D25:",i.message),i}}async function Xt(){if(x==="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..."),x="cleanup";try{if(z){try{await(await z).stopAllServices()}catch(i){console.error("\u6E05\u7406\u521D\u59CB\u5316\u4E2D\u7684\u5B9E\u4F8B\u5931\u8D25:",i.message)}z=null}H&&(await H.stopAllServices(),H=null),x="not_initialized",Ce=null,re=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),rt(),i}}function rt(){console.log("\u{1F504} \u91CD\u7F6E MCPServiceManager \u5355\u4F8B\u72B6\u6001"),H=null,z=null,x="not_initialized",Ce=null,re=null}function Vn(){return x==="initialized"&&H!==null}function Xn(){return{state:x,initializationTime:re?new Date:void 0,lastError:Ce||void 0,instanceId:re||void 0}}async function Gn(){return console.log("\u{1F504} \u5F3A\u5236\u91CD\u65B0\u521D\u59CB\u5316 MCPServiceManager \u5355\u4F8B..."),await Xt(),Vt()}function Kn(){return H}async function Jn(){if(x==="initialized")return!0;if(x==="initializing"&&z)try{return await z,!0}catch{return!1}return!1}var H,z,x,Ce,re,ie,Gt=h(()=>{"use strict";qe();H=null,z=null,x="not_initialized",Ce=null,re=null;a(Bn,"createInstance");a(Vt,"getInstance");a(Xt,"cleanup");a(rt,"reset");a(Vn,"isInitialized");a(Xn,"getStatus");a(Gn,"forceReinitialize");a(Kn,"getCurrentInstance");a(Jn,"waitForInitialization");ie={getInstance:Vt,cleanup:Xt,reset:rt,isInitialized:Vn,getStatus:Xn,forceReinitialize:Gn,getCurrentInstance:Kn,waitForInitialization:Jn};process.on("exit",()=>{ie.isInitialized()&&(console.log("\u{1F504} \u8FDB\u7A0B\u9000\u51FA\uFF0C\u6B63\u5728\u6E05\u7406 MCPServiceManager \u5355\u4F8B..."),ie.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 ie.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 ie.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}})});import{EventEmitter as qn}from"events";var Kt,Zn,ke,Jt=h(()=>{"use strict";T();we();Kt=(r=>(r.EXPONENTIAL_BACKOFF="exponential_backoff",r.LINEAR_BACKOFF="linear_backoff",r.FIXED_INTERVAL="fixed_interval",r.ADAPTIVE="adaptive",r))(Kt||{}),Zn={healthCheckInterval:3e4,reconnectInterval:5e3,maxReconnectAttempts:10,loadBalanceStrategy:"round-robin",connectionTimeout:1e4,reconnectStrategy:"exponential_backoff",maxReconnectDelay:3e4,reconnectBackoffMultiplier:2,jitterEnabled:!0},ke=class extends qn{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=u,this.options={...Zn,...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(Kt);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(S=>!o.includes(S)),c=o.filter(S=>!n.includes(S)),l=o.filter(S=>n.includes(S));this.logger.info(`\u7AEF\u70B9\u53D8\u66F4 - \u6DFB\u52A0: ${s.length}, \u79FB\u9664: ${c.length}, \u4FDD\u6301: ${l.length}`);try{for(let V of c)await this.removeEndpoint(V);for(let V of s)await this.addEndpoint(V);let S={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",S),this.logger.info("\u7AEF\u70B9\u914D\u7F6E\u66F4\u65B0\u5B8C\u6210")}catch(S){throw this.logger.error("\u7AEF\u70B9\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",S),S}}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 X(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 Qn(i){return console.log("\u{1F680} \u6B63\u5728\u521D\u59CB\u5316 XiaozhiConnectionManager \u5355\u4F8B..."),new ke(i)}async function qt(i){if(W&&$==="initialized")return W;if(L&&$==="initializing")return L;$==="failed"&&it(),$="initializing",L=Qn(i);try{return W=await L,$="initialized",oe=`xiaozhi-connection-manager-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,ve=null,console.log(`\u2705 XiaozhiConnectionManager \u5355\u4F8B\u521D\u59CB\u5316\u6210\u529F\uFF0C\u5B9E\u4F8BID: ${oe}`),W}catch(e){throw $="failed",ve=e,L=null,console.error("\u274C XiaozhiConnectionManager \u5355\u4F8B\u521D\u59CB\u5316\u5931\u8D25:",e.message),e}}async function Zt(){if($==="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..."),$="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}W&&(await W.cleanup(),W=null),$="not_initialized",ve=null,oe=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),it(),i}}function it(){console.log("\u{1F504} \u91CD\u7F6E XiaozhiConnectionManager \u5355\u4F8B\u72B6\u6001..."),L&&(L=null),W=null,$="not_initialized",ve=null,oe=null,console.log("\u2705 XiaozhiConnectionManager \u5355\u4F8B\u72B6\u6001\u5DF2\u91CD\u7F6E")}function Yn(){return $==="initialized"&&W!==null}function er(){return{state:$,initializationTime:oe?new Date:void 0,lastError:ve||void 0,instanceId:oe||void 0}}async function tr(i){return console.log("\u{1F504} \u5F3A\u5236\u91CD\u65B0\u521D\u59CB\u5316 XiaozhiConnectionManager \u5355\u4F8B..."),await Zt(),qt(i)}function nr(){return W}async function rr(){if($==="initialized")return!0;if($==="initializing"&&L)try{return await L,!0}catch{return!1}return!1}var W,L,$,ve,oe,se,Qt=h(()=>{"use strict";Jt();W=null,L=null,$="not_initialized",ve=null,oe=null;a(Qn,"createInstance");a(qt,"getInstance");a(Zt,"cleanup");a(it,"reset");a(Yn,"isInitialized");a(er,"getStatus");a(tr,"forceReinitialize");a(nr,"getCurrentInstance");a(rr,"waitForInitialization");se={getInstance:qt,cleanup:Zt,reset:it,isInitialized:Yn,getStatus:er,forceReinitialize:tr,getCurrentInstance:nr,waitForInitialization:rr};process.on("exit",()=>{se.isInitialized()&&(console.log("\u{1F504} \u8FDB\u7A0B\u9000\u51FA\uFF0C\u6B63\u5728\u6E05\u7406 XiaozhiConnectionManager \u5355\u4F8B..."),se.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 se.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 se.cleanup()}catch(e){console.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",e)}})});var jt={};Z(jt,{WebServer:()=>st});import{spawn as Yt}from"child_process";import{existsSync as ot}from"fs";import{readFile as en}from"fs/promises";import{createServer as ir}from"http";import{dirname as or,join as ae}from"path";import{fileURLToPath as sr}from"url";import{serve as ar}from"@hono/node-server";import{Hono as cr}from"hono";import{cors as lr}from"hono/cors";import{WebSocketServer as gr}from"ws";var st,Ut=h(()=>{T();we();ht();Bt();he();Gt();Qt();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??d.getWebUIPort()??9999}catch{this.port=e??9999}this.logger=u,this.app=new cr,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 ie.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(!d.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=d.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=gt(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 se.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 X(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(S){if(c=S,this.logger.warn(`${t} - \u8FDE\u63A5\u5931\u8D25:`,S),l<n){let V=Math.min(r*s**(l-1),o);this.logger.info(`${t} - ${V}ms \u540E\u91CD\u8BD5...`),await this.sleep(V)}}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("*",lr({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=d.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=or(sr(import.meta.url)),o=[ae(n,"..","web","dist"),ae(n,"..","web"),ae(process.cwd(),"web","dist"),ae(process.cwd(),"web")].find(D=>ot(D));if(!o)return e.html(`
15
15
  <!DOCTYPE html>
16
16
  <html>
17
17
  <head>
@@ -31,5 +31,5 @@ data: /messages?sessionId=${r}
31
31
  </div>
32
32
  </body>
33
33
  </html>
34
- `);let s=t;if(s==="/"&&(s="/index.html"),s.includes(".."))return e.text("Forbidden",403);let c=ie(o,s);if(!it(c)){let se=ie(o,"index.html");if(it(se)){let Yt=await Qt(se);return e.html(Yt.toString())}return e.text("Not Found",404)}let l=await Qt(c),y=c.split(".").pop()?.toLowerCase(),oe={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"}[y||""]||"application/octet-stream";return oe.startsWith("text/")||oe.includes("javascript")||oe.includes("json")?e.text(l.toString(),200,{"Content-Type":oe}):e.body(l,200,{"Content-Type":oe})}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=d.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=d.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=d.getConfig();e.send(JSON.stringify({type:"config",data:t})),e.send(JSON.stringify({type:"status",data:this.clientInfo})),setTimeout(()=>{let n=d.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!==d.getMcpEndpoint()&&d.updateMcpEndpoint(e.mcpEndpoint);let t=d.getMcpServers();for(let[n,r]of Object.entries(e.mcpServers))JSON.stringify(t[n])!==JSON.stringify(r)&&d.updateMcpServer(n,r);for(let n of Object.keys(t))n in e.mcpServers||(d.removeMcpServer(n),d.removeServerToolsConfig(n));if(e.connection&&d.updateConnectionConfig(e.connection),e.modelscope&&d.updateModelScopeConfig(e.modelscope),e.webUI&&d.updateWebUIConfig(e.webUI),e.mcpServerConfig)for(let[n,r]of Object.entries(e.mcpServerConfig))for(let[o,s]of Object.entries(r.tools))d.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 _t()).get("serviceManager").getStatus();if(!n.running){this.logger.warn("MCP \u670D\u52A1\u672A\u8FD0\u884C\uFF0C\u5C1D\u8BD5\u542F\u52A8\u670D\u52A1"),Zt("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"),Zt("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=or({fetch:this.app.fetch,port:this.port,hostname:"0.0.0.0",createServer:nr});this.httpServer=e,this.wss=new cr({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()})}}});zt();export{ot as WebServer};
34
+ `);let s=t;if(s==="/"&&(s="/index.html"),s.includes(".."))return e.text("Forbidden",403);let c=ae(o,s);if(!ot(c)){let D=ae(o,"index.html");if(ot(D)){let q=await en(D);return e.html(q.toString())}return e.text("Not Found",404)}let l=await en(c),S=c.split(".").pop()?.toLowerCase(),M={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"}[S||""]||"application/octet-stream";return M.startsWith("text/")||M.includes("javascript")||M.includes("json")?e.text(l.toString(),200,{"Content-Type":M}):e.body(l,200,{"Content-Type":M})}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=d.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=d.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=d.getConfig();e.send(JSON.stringify({type:"config",data:t})),e.send(JSON.stringify({type:"status",data:this.clientInfo})),setTimeout(()=>{let n=d.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!==d.getMcpEndpoint()&&d.updateMcpEndpoint(e.mcpEndpoint);let t=d.getMcpServers();for(let[n,r]of Object.entries(e.mcpServers))JSON.stringify(t[n])!==JSON.stringify(r)&&d.updateMcpServer(n,r);for(let n of Object.keys(t))n in e.mcpServers||(d.removeMcpServer(n),d.removeServerToolsConfig(n));if(e.connection&&d.updateConnectionConfig(e.connection),e.modelscope&&d.updateModelScopeConfig(e.modelscope),e.webUI&&d.updateWebUIConfig(e.webUI),e.mcpServerConfig)for(let[n,r]of Object.entries(e.mcpServerConfig))for(let[o,s]of Object.entries(r.tools))d.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 Wt()).get("serviceManager").getStatus();if(!n.running){this.logger.warn("MCP \u670D\u52A1\u672A\u8FD0\u884C\uFF0C\u5C1D\u8BD5\u542F\u52A8\u670D\u52A1"),Yt("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"),Yt("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=ar({fetch:this.app.fetch,port:this.port,hostname:"0.0.0.0",createServer:ir});this.httpServer=e,this.wss=new gr({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()})}}});Ut();export{st as WebServer};
35
35
  //# sourceMappingURL=WebServer.js.map