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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/apps/frontend/dist/assets/form-utils-h64o2Nyg.js +2 -0
  2. package/apps/frontend/dist/assets/form-utils-h64o2Nyg.js.map +1 -0
  3. package/apps/frontend/dist/assets/index-88NfCOo9.js +50 -0
  4. package/apps/frontend/dist/assets/index-88NfCOo9.js.map +1 -0
  5. package/apps/frontend/dist/assets/index-P6Zq3MZF.css +1 -0
  6. package/apps/frontend/dist/assets/radix-ui-BA32w1ww.js.map +1 -1
  7. package/apps/frontend/dist/assets/react-vendor-DrjkXih1.js +319 -0
  8. package/apps/frontend/dist/assets/react-vendor-DrjkXih1.js.map +1 -0
  9. package/apps/frontend/dist/assets/utils-CiPelQLP.js +2 -0
  10. package/apps/frontend/dist/assets/utils-CiPelQLP.js.map +1 -0
  11. package/apps/frontend/dist/assets/{vendor-DvFnRBMT.js → vendor-DK9yaMt3.js} +2 -2
  12. package/apps/frontend/dist/assets/vendor-DK9yaMt3.js.map +1 -0
  13. package/apps/frontend/dist/index.html +6 -6
  14. package/dist/WebServerStandalone.js +16 -21
  15. package/dist/WebServerStandalone.js.map +1 -1
  16. package/dist/cli.js +20 -28
  17. package/dist/cli.js.map +1 -1
  18. package/dist/mcpServerProxy.d.ts +1 -1
  19. package/dist/mcpServerProxy.js +13 -13
  20. package/dist/mcpServerProxy.js.map +1 -1
  21. package/dist/package.json +9 -4
  22. package/docs/changelog.mdx +628 -0
  23. package/docs/development/todo__release-guide.md +5 -5
  24. package/docs/docs.json +5 -1
  25. package/package.json +9 -4
  26. package/apps/frontend/dist/assets/form-utils-wyhL6gg0.js +0 -24
  27. package/apps/frontend/dist/assets/form-utils-wyhL6gg0.js.map +0 -1
  28. package/apps/frontend/dist/assets/index-COfJftUA.css +0 -1
  29. package/apps/frontend/dist/assets/index-ukaaLbQN.js +0 -50
  30. package/apps/frontend/dist/assets/index-ukaaLbQN.js.map +0 -1
  31. package/apps/frontend/dist/assets/react-vendor-B6Uf_8Kw.js +0 -319
  32. package/apps/frontend/dist/assets/react-vendor-B6Uf_8Kw.js.map +0 -1
  33. package/apps/frontend/dist/assets/utils-D0kRQKVW.js +0 -2
  34. package/apps/frontend/dist/assets/utils-D0kRQKVW.js.map +0 -1
  35. package/apps/frontend/dist/assets/vendor-DvFnRBMT.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- var We=Object.defineProperty;var l=(i,e)=>We(i,"name",{value:e,configurable:!0});import{dirname as It}from"path";import w from"process";import{fileURLToPath as kt}from"url";import{EventEmitter as He}from"events";import*as v from"fs";import*as M from"path";import z from"chalk";import A from"pino";import{z as Be}from"zod";var Ke=Be.enum(["fatal","error","warn","info","debug","trace"]);function Ve(i){let e=i.getFullYear(),t=String(i.getMonth()+1).padStart(2,"0"),r=String(i.getDate()).padStart(2,"0"),n=String(i.getHours()).padStart(2,"0"),s=String(i.getMinutes()).padStart(2,"0"),o=String(i.getSeconds()).padStart(2,"0");return`${e}-${t}-${r} ${n}:${s}:${o}`}l(Ve,"formatDateTime");var le=class{static{l(this,"Logger")}logFilePath=null;pinoInstance;isDaemonMode;logLevel;maxLogFileSize=10*1024*1024;maxLogFiles=5;constructor(e="info"){this.isDaemonMode=process.env.XIAOZHI_DAEMON==="true",this.logLevel=this.validateLogLevel(e),this.pinoInstance=this.createPinoInstance()}validateLogLevel(e){let t=e.toLowerCase(),r=Ke.safeParse(t);return r.success?r.data:"info"}createPinoInstance(){let e=[];if(!this.isDaemonMode){let t=this.createOptimizedConsoleStream();e.push({level:this.logLevel,stream:t})}return this.logFilePath&&e.push({level:this.logLevel,stream:A.destination({dest:this.logFilePath,sync:!1,append:!0,mkdir:!0})}),e.length===0&&e.push({level:this.logLevel,stream:A.destination({dest:"/dev/null"})}),A({level:this.logLevel,timestamp:A.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:l((t,r)=>({level:r}),"level")},base:null,serializers:{err:A.stdSerializers?.err||(t=>t)}},A.multistream(e,{dedupe:!0}))}createOptimizedConsoleStream(){let e=new Map([[20,{name:"DEBUG",color:z.gray}],[30,{name:"INFO",color:z.blue}],[40,{name:"WARN",color:z.yellow}],[50,{name:"ERROR",color:z.red}],[60,{name:"FATAL",color:z.red}]]);return{write:l(t=>{try{let r=JSON.parse(t),n=this.formatConsoleMessageOptimized(r,e);this.safeWrite(`${n}
3
- `)}catch{this.safeWrite(t)}},"write")}}safeWrite(e){try{process.stderr&&typeof process.stderr.write=="function"?process.stderr.write(e):console&&typeof console.error=="function"&&console.error(e.trim())}catch{}}formatConsoleMessageOptimized(e,t){let r=Ve(new Date),n=t.get(e.level)||{name:"UNKNOWN",color:l(a=>a,"color")},s=n.color(`[${n.name}]`),o=e.msg;if(e.args&&Array.isArray(e.args)){let a=e.args.map(g=>typeof g=="object"?JSON.stringify(g):String(g)).join(" ");o=`${o} ${a}`}return`[${r}] ${s} ${o}`}initLogFile(e){this.logFilePath=M.join(e,"xiaozhi.log"),this.rotateLogFileIfNeeded(),v.existsSync(this.logFilePath)||v.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 r=t.map(n=>n instanceof Error?this.pinoInstance.level==="debug"?n.message:{message:n.message,stack:n.stack,name:n.name,cause:n.cause}:n);this.pinoInstance.error({args:r},e)}else{let r=this.enhanceErrorObject(e);this.pinoInstance.error(r,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[r,n]of Object.entries(t))n instanceof Error&&(t[r]={message:n.message,stack:n.stack,name:n.name,cause:n.cause});return t}rotateLogFileIfNeeded(){if(!(!this.logFilePath||!v.existsSync(this.logFilePath)))try{v.statSync(this.logFilePath).size>this.maxLogFileSize&&this.rotateLogFile()}catch{}}rotateLogFile(){if(this.logFilePath)try{let e=M.dirname(this.logFilePath),t=M.basename(this.logFilePath,".log");for(let n=this.maxLogFiles-1;n>=1;n--){let s=M.join(e,`${t}.${n}.log`),o=M.join(e,`${t}.${n+1}.log`);v.existsSync(s)&&(n===this.maxLogFiles-1?v.unlinkSync(s):v.renameSync(s,o))}let r=M.join(e,`${t}.1.log`);v.renameSync(this.logFilePath,r)}catch{}}cleanupOldLogs(){if(this.logFilePath)try{let e=M.dirname(this.logFilePath),t=M.basename(this.logFilePath,".log");for(let r=this.maxLogFiles+1;r<=this.maxLogFiles+10;r++){let n=M.join(e,`${t}.${r}.log`);v.existsSync(n)&&v.unlinkSync(n)}}catch{}}setLogFileOptions(e,t){this.maxLogFileSize=e,this.maxLogFiles=t}withTag(e){return this}close(){}setLevel(e){this.logLevel=this.validateLogLevel(e),this.pinoInstance=this.createPinoInstance()}getLevel(){return this.logLevel}},ce=null,Ge="info";function Je(){return ce||(ce=new le(Ge)),ce}l(Je,"getLogger");var c=Je();var K=class{static{l(this,"MCPMessageHandler")}logger;serviceManager;constructor(e){this.serviceManager=e,this.logger=c}async handleMessage(e){this.logger.debug(`\u5904\u7406 MCP \u6D88\u606F: ${e.method}`,e);try{let t=e.id===void 0;switch(e.method){case"initialize":return await this.handleInitialize(e.params,e.id);case"notifications/initialized":return await this.handleInitializedNotification(e.params);case"tools/list":return await this.handleToolsList(e.id);case"tools/call":return await this.handleToolCall(e.params,e.id);case"resources/list":return await this.handleResourcesList(e.id);case"prompts/list":return await this.handlePromptsList(e.id);case"ping":return await this.handlePing(e.id);default:if(t)return this.logger.warn(`\u6536\u5230\u672A\u77E5\u7684\u901A\u77E5\u6D88\u606F: ${e.method}`,e),null;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),e.id===void 0?null:this.createErrorResponse(t,e.id)}}async handleInitialize(e,t){this.logger.debug("\u5904\u7406 initialize \u8BF7\u6C42",e);let r=["2024-11-05","2025-06-18"],n=e.protocolVersion,s=r.includes(n)?n:"2024-11-05";return this.logger.debug(`\u534F\u8BAE\u7248\u672C\u534F\u5546: \u5BA2\u6237\u7AEF=${n}, \u670D\u52A1\u5668\u54CD\u5E94=${s}`),{jsonrpc:"2.0",result:{serverInfo:{name:"xiaozhi-mcp-server",version:"1.0.0"},capabilities:{tools:{},logging:{}},protocolVersion:s},id:t!==void 0?t:1}}async handleInitializedNotification(e){return this.logger.debug("\u6536\u5230 initialized \u901A\u77E5\uFF0C\u5BA2\u6237\u7AEF\u521D\u59CB\u5316\u5B8C\u6210",e),null}async handleToolsList(e){this.logger.debug("\u5904\u7406 tools/list \u8BF7\u6C42");try{return{jsonrpc:"2.0",result:{tools:this.serviceManager.getAllTools().map(n=>({name:n.name,description:n.description,inputSchema:n.inputSchema}))},id:e!==void 0?e:1}}catch(t){throw this.logger.error("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25",t),t}}async handleToolCall(e,t){try{if(!e.name)throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");let r=await this.serviceManager.callTool(e.name,e.arguments||{});return{jsonrpc:"2.0",result:{content:r.content,isError:r.isError||!1},id:t!==void 0?t:1}}catch(r){throw this.logger.error(`\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,r),r}}async handlePing(e){return this.logger.debug("\u5904\u7406 ping \u8BF7\u6C42"),{jsonrpc:"2.0",result:{status:"ok",timestamp:new Date().toISOString()},id:e!==void 0?e:1}}async handleResourcesList(e){this.logger.debug("\u5904\u7406 resources/list \u8BF7\u6C42");let t=[];return this.logger.debug(`\u8FD4\u56DE ${t.length} \u4E2A\u8D44\u6E90`),{jsonrpc:"2.0",result:{resources:t},id:e!==void 0?e:1}}async handlePromptsList(e){this.logger.debug("\u5904\u7406 prompts/list \u8BF7\u6C42");let t=[];return this.logger.debug(`\u8FD4\u56DE ${t.length} \u4E2A\u63D0\u793A\u6A21\u677F`),{jsonrpc:"2.0",result:{prompts:t},id:e!==void 0?e:1}}createErrorResponse(e,t){let r=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?r=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(r=-32602),{jsonrpc:"2.0",error:{code:r,message:e.message,data:{stack:e.stack}},id:t!==void 0?t:1}}getServiceManager(){return this.serviceManager}};import{copyFileSync as Qe,existsSync as V,readFileSync as Xe,writeFileSync as Ze}from"fs";import{dirname as et,resolve as L}from"path";import{fileURLToPath as tt}from"url";import{EventEmitter as qe}from"events";var ue=class extends qe{static{l(this,"EventBus")}logger;eventStats=new Map;maxListeners=50;constructor(){super(),this.logger=c.withTag("EventBus"),this.setMaxListeners(this.maxListeners),this.setupErrorHandling()}setupErrorHandling(){this.on("error",e=>{this.logger.error("EventBus \u5185\u90E8\u9519\u8BEF:",e)}),this.on("newListener",e=>{let t=this.listenerCount(e);t>this.maxListeners*.8&&this.logger.warn(`\u4E8B\u4EF6 ${e} \u7684\u76D1\u542C\u5668\u6570\u91CF\u8FC7\u591A: ${t}`)})}emitEvent(e,t){try{return this.updateEventStats(e),this.logger.debug(`\u53D1\u5C04\u4E8B\u4EF6: ${e}`,t),super.emit(e,t)}catch(r){return this.logger.error(`\u53D1\u5C04\u4E8B\u4EF6\u5931\u8D25: ${e}`,r),r instanceof Error&&this.emit("error",r),!1}}onEvent(e,t){return this.logger.debug(`\u6DFB\u52A0\u4E8B\u4EF6\u76D1\u542C\u5668: ${e}`),this.on(e,t)}onceEvent(e,t){this.logger.debug(`\u6DFB\u52A0\u4E00\u6B21\u6027\u4E8B\u4EF6\u76D1\u542C\u5668: ${e}`);let r=l(n=>{try{t(n)}catch(s){throw this.emit("error",s),s}finally{this.offEvent(e,r)}},"onceListener");return this.on(e,r)}offEvent(e,t){return this.logger.debug(`\u79FB\u9664\u4E8B\u4EF6\u76D1\u542C\u5668: ${e}`),this.off(e,t)}updateEventStats(e){let t=this.eventStats.get(e)||{count:0,lastEmitted:new Date};t.count++,t.lastEmitted=new Date,this.eventStats.set(e,t)}getEventStats(){let e={};for(let[t,r]of this.eventStats)e[t]={...r};return e}getListenerStats(){let e={};for(let t of this.eventNames())e[t]=this.listenerCount(t);return e}clearEventStats(){this.eventStats.clear(),this.logger.info("\u4E8B\u4EF6\u7EDF\u8BA1\u5DF2\u6E05\u7406")}getStatus(){return{totalEvents:this.eventStats.size,totalListeners:Object.values(this.getListenerStats()).reduce((e,t)=>e+t,0),eventStats:this.getEventStats(),listenerStats:this.getListenerStats()}}destroy(){this.removeAllListeners(),this.eventStats.clear(),this.logger.info("EventBus \u5DF2\u9500\u6BC1")}},ge=null;function b(){return ge||(ge=new ue),ge}l(b,"getEventBus");function Ye(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")}l(Ye,"getMcpServerCommunicationType");function he(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(Ye(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"}`}}}l(he,"validateMcpServerConfig");import*as G from"comment-json";import Ee from"dayjs";import pe from"json5";import*as $e from"json5-writer";var Re=et(tt(import.meta.url)),me={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},de=class i{static{l(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;eventBus=b();statsUpdateLocks=new Map;statsUpdateLockTimeouts=new Map;STATS_UPDATE_TIMEOUT=5e3;constructor(){let e=[L(Re,"templates","default","xiaozhi.config.json"),L(Re,"..","templates","default","xiaozhi.config.json"),L(process.cwd(),"templates","default","xiaozhi.config.json")];this.defaultConfigPath=e.find(t=>V(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 r of t){let n=L(e,r);if(V(n))return n}return L(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 r of t){let n=L(e,r);if(V(n))return!0}return!1}initConfig(e="json"){if(!V(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(),r=`xiaozhi.config.${e}`,n=L(t,r);Qe(this.defaultConfigPath,n),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),n=Xe(e,"utf8").replace(/^\uFEFF/,""),s;switch(t){case"json5":s=pe.parse(n),this.json5Writer=$e.load(n);break;case"jsonc":s=G.parse(n);break;default:s=JSON.parse(n);break}return this.validateConfig(s),s}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)){for(let r of t.mcpEndpoint)if(typeof r!="string"||r.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[r,n]of Object.entries(t.mcpServers)){if(!n||typeof n!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${r} \u65E0\u6548`);let s=he(r,n);if(!s.valid)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A${s.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)){for(let r of e)if(!r||typeof r!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\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(),r=this.getMcpEndpoints();if(r.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let n=[...r,e];t.mcpEndpoint=n,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(),r=this.getMcpEndpoints();if(r.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);let s=r.filter(o=>o!==e);t.mcpEndpoint=s,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 r=he(e,t);if(!r.valid)throw new Error(r.error||"\u670D\u52A1\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let n=this.getMutableConfig();n.mcpServers[e]=t,this.saveConfig(n)}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.getMutableConfig();if(!t.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);if(delete t.mcpServers[e],t.mcpServerConfig?.[e]&&delete t.mcpServerConfig[e],t.customMCP?.tools){let r=t.customMCP.tools.filter(n=>n.handler?.type==="mcp"&&n.handler.config?.serviceName===e);for(let n of r){let s=t.customMCP.tools.findIndex(o=>o.name===n.name);s!==-1&&t.customMCP.tools.splice(s,1)}t.customMCP.tools.length===0&&(t.customMCP=void 0)}this.saveConfig(t),this.eventBus.emitEvent("config:updated",{type:"customMCP",timestamp:new Date}),c.info(`\u6210\u529F\u79FB\u9664 MCP \u670D\u52A1 ${e} \u53CA\u5176\u76F8\u5173\u914D\u7F6E`)}updateServerToolsConfig(e,t){let r=this.getMutableConfig();r.mcpServerConfig||(r.mcpServerConfig={}),Object.keys(t).length===0?delete r.mcpServerConfig[e]:r.mcpServerConfig[e]={tools:t},this.saveConfig(r),this.eventBus.emitEvent("config:updated",{type:"serverTools",serviceName:e,timestamp:new Date})}removeServerToolsConfig(e){let r={...this.getConfig()};r.mcpServerConfig&&(delete r.mcpServerConfig[e],this.saveConfig(r))}cleanupInvalidServerToolsConfig(){let e=this.getMutableConfig();if(!e.mcpServerConfig)return;let t=Object.keys(e.mcpServers),n=Object.keys(e.mcpServerConfig).filter(s=>!t.includes(s));if(n.length>0){for(let s of n)delete e.mcpServerConfig[s];this.saveConfig(e),c.info(`\u5DF2\u6E05\u7406 ${n.length} \u4E2A\u65E0\u6548\u7684\u670D\u52A1\u5DE5\u5177\u914D\u7F6E: ${n.join(", ")}`)}}setToolEnabled(e,t,r,n){let s=this.getMutableConfig();s.mcpServerConfig||(s.mcpServerConfig={}),s.mcpServerConfig[e]||(s.mcpServerConfig[e]={tools:{}}),s.mcpServerConfig[e].tools[t]={...s.mcpServerConfig[e].tools[t],enable:r,...n&&{description:n}},this.saveConfig(s)}saveConfig(e){try{this.validateConfig(e);let t;this.currentConfigPath?t=this.currentConfigPath:(t=this.getConfigFilePath(),this.currentConfigPath=t);let r=this.getConfigFileFormat(t),n;switch(r){case"json5":try{this.json5Writer?(this.json5Writer.write(e),n=this.json5Writer.toSource()):(console.warn("\u6CA1\u6709 json5Writer \u5B9E\u4F8B\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F"),n=pe.stringify(e,null,2))}catch(s){console.warn("\u4F7F\u7528 json5-writer \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F:",s),n=pe.stringify(e,null,2)}break;case"jsonc":try{n=G.stringify(e,null,2)}catch(s){console.warn("\u4F7F\u7528 comment-json \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON \u683C\u5F0F:",s),n=JSON.stringify(e,null,2)}break;default:n=JSON.stringify(e,null,2);break}Ze(t,n,"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??me.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??me.heartbeatTimeout,reconnectInterval:t.reconnectInterval??me.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,r){try{if(typeof t=="string"&&r){let n=e,s=t,o=r;await Promise.all([this._updateMCPServerToolStats(n,s,o),this.updateCustomMCPToolStats(n,s,o)]),c.debug(`\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${n}/${s}`)}else{let n=e,s=t,o=new Date().toISOString();await this.updateCustomMCPToolStats(n,o,s),c.debug(`CustomMCP \u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${n}`)}}catch(n){if(typeof t=="string"&&r){let s=e,o=t;c.error(`\u66F4\u65B0\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5931\u8D25 (${s}/${o}): ${n instanceof Error?n.message:String(n)}`)}else{let s=e;c.error(`\u66F4\u65B0 CustomMCP \u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5931\u8D25 (${s}): ${n instanceof Error?n.message:String(n)}`)}}}async updateMCPServerToolStats(e,t,r,n=!0){await this._updateMCPServerToolStats(e,t,r,n)}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})}getCustomMCPConfig(){return this.getConfig().customMCP||null}getCustomMCPTools(){let e=this.getCustomMCPConfig();return!e||!e.tools?[]:e.tools}validateCustomMCPTools(e){if(!Array.isArray(e))return!1;for(let t of e){if(!t.name||typeof t.name!="string")return c.warn(`CustomMCP \u5DE5\u5177\u7F3A\u5C11\u6709\u6548\u7684 name \u5B57\u6BB5: ${JSON.stringify(t)}`),!1;if(!t.description||typeof t.description!="string")return c.warn(`CustomMCP \u5DE5\u5177 ${t.name} \u7F3A\u5C11\u6709\u6548\u7684 description \u5B57\u6BB5`),!1;if(!t.inputSchema||typeof t.inputSchema!="object")return c.warn(`CustomMCP \u5DE5\u5177 ${t.name} \u7F3A\u5C11\u6709\u6548\u7684 inputSchema \u5B57\u6BB5`),!1;if(!t.handler||typeof t.handler!="object")return c.warn(`CustomMCP \u5DE5\u5177 ${t.name} \u7F3A\u5C11\u6709\u6548\u7684 handler \u5B57\u6BB5`),!1;if(!["proxy","function","http","script","chain","mcp"].includes(t.handler.type))return c.warn(`CustomMCP \u5DE5\u5177 ${t.name} \u7684 handler.type \u5FC5\u987B\u662F 'proxy', 'function', 'http', 'script', 'chain' \u6216 'mcp'`),!1;if(!this.validateHandlerConfig(t.name,t.handler))return!1}return!0}validateHandlerConfig(e,t){switch(t.type){case"proxy":return this.validateProxyHandler(e,t);case"http":return this.validateHttpHandler(e,t);case"function":return this.validateFunctionHandler(e,t);case"script":return this.validateScriptHandler(e,t);case"chain":return this.validateChainHandler(e,t);case"mcp":return this.validateMCPHandler(e,t);default:return c.warn(`CustomMCP \u5DE5\u5177 ${e} \u4F7F\u7528\u4E86\u672A\u77E5\u7684\u5904\u7406\u5668\u7C7B\u578B`),!1}}validateProxyHandler(e,t){return t.platform?["coze","openai","anthropic","custom"].includes(t.platform)?!t.config||typeof t.config!="object"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 proxy \u5904\u7406\u5668\u7F3A\u5C11 config \u5B57\u6BB5`),!1):t.platform==="coze"&&!t.config.workflow_id&&!t.config.bot_id?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 Coze \u5904\u7406\u5668\u5FC5\u987B\u63D0\u4F9B workflow_id \u6216 bot_id`),!1):!0:(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 proxy \u5904\u7406\u5668\u4F7F\u7528\u4E86\u4E0D\u652F\u6301\u7684\u5E73\u53F0: ${t.platform}`),!1):(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 proxy \u5904\u7406\u5668\u7F3A\u5C11 platform \u5B57\u6BB5`),!1)}validateHttpHandler(e,t){if(!t.url||typeof t.url!="string")return c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 http \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 url \u5B57\u6BB5`),!1;try{new URL(t.url)}catch{return c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 http \u5904\u7406\u5668 url \u683C\u5F0F\u65E0\u6548: ${t.url}`),!1}return t.method&&!["GET","POST","PUT","DELETE","PATCH"].includes(t.method)?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 http \u5904\u7406\u5668\u4F7F\u7528\u4E86\u4E0D\u652F\u6301\u7684 HTTP \u65B9\u6CD5: ${t.method}`),!1):!0}validateFunctionHandler(e,t){return!t.module||typeof t.module!="string"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 function \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 module \u5B57\u6BB5`),!1):!t.function||typeof t.function!="string"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 function \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 function \u5B57\u6BB5`),!1):!0}validateScriptHandler(e,t){return!t.script||typeof t.script!="string"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 script \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 script \u5B57\u6BB5`),!1):t.interpreter&&!["node","python","bash"].includes(t.interpreter)?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 script \u5904\u7406\u5668\u4F7F\u7528\u4E86\u4E0D\u652F\u6301\u7684\u89E3\u91CA\u5668: ${t.interpreter}`),!1):!0}validateChainHandler(e,t){return!t.tools||!Array.isArray(t.tools)||t.tools.length===0?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 chain \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 tools \u6570\u7EC4`),!1):["sequential","parallel"].includes(t.mode)?["stop","continue","retry"].includes(t.error_handling)?!0:(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 chain \u5904\u7406\u5668\u4F7F\u7528\u4E86\u4E0D\u652F\u6301\u7684\u9519\u8BEF\u5904\u7406\u7B56\u7565: ${t.error_handling}`),!1):(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 chain \u5904\u7406\u5668\u4F7F\u7528\u4E86\u4E0D\u652F\u6301\u7684\u6267\u884C\u6A21\u5F0F: ${t.mode}`),!1)}validateMCPHandler(e,t){return!t.config||typeof t.config!="object"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 mcp \u5904\u7406\u5668\u7F3A\u5C11 config \u5B57\u6BB5`),!1):!t.config.serviceName||typeof t.config.serviceName!="string"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 mcp \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 serviceName`),!1):!t.config.toolName||typeof t.config.toolName!="string"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 mcp \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 toolName`),!1):!0}hasValidCustomMCPTools(){try{let e=this.getCustomMCPTools();return e.length===0?!1:this.validateCustomMCPTools(e)}catch(e){return c.error("\u68C0\u67E5 customMCP \u5DE5\u5177\u914D\u7F6E\u65F6\u51FA\u9519:",e),!1}}addCustomMCPTool(e){if(!e||typeof e!="object")throw new Error("\u5DE5\u5177\u914D\u7F6E\u4E0D\u80FD\u4E3A\u7A7A");let t=this.getMutableConfig();if(t.customMCP||(t.customMCP={tools:[]}),t.customMCP.tools.find(n=>n.name===e.name))throw new Error(`\u5DE5\u5177 "${e.name}" \u5DF2\u5B58\u5728`);if(!this.validateCustomMCPTools([e]))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");t.customMCP.tools.unshift(e),this.saveConfig(t),c.info(`\u6210\u529F\u6DFB\u52A0\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177: ${e.name}`)}async addCustomMCPTools(e){if(!Array.isArray(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u5FC5\u987B\u662F\u6570\u7EC4");if(e.length===0)return;let t=this.getMutableConfig();t.customMCP||(t.customMCP={tools:[]});let r=new Set(t.customMCP.tools.map(s=>s.name)),n=e.filter(s=>!r.has(s.name));if(n.length>0){if(!this.validateCustomMCPTools(n))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");t.customMCP.tools.push(...n),this.saveConfig(t),this.eventBus.emitEvent("config:updated",{type:"customMCP",timestamp:new Date}),c.debug(`\u6210\u529F\u6279\u91CF\u6DFB\u52A0 ${n.length} \u4E2A\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177: ${n.map(s=>s.name).join(", ")}`)}}removeCustomMCPTool(e){if(!e||typeof e!="string")throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");let t=this.getMutableConfig();if(!t.customMCP||!t.customMCP.tools)throw new Error("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177");let r=t.customMCP.tools.findIndex(n=>n.name===e);if(r===-1)throw new Error(`\u5DE5\u5177 "${e}" \u4E0D\u5B58\u5728`);t.customMCP.tools.splice(r,1),this.saveConfig(t),c.info(`\u6210\u529F\u5220\u9664\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177: ${e}`)}updateCustomMCPTool(e,t){if(!e||typeof e!="string")throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");if(!t||typeof t!="object")throw new Error("\u66F4\u65B0\u540E\u7684\u5DE5\u5177\u914D\u7F6E\u4E0D\u80FD\u4E3A\u7A7A");let r=this.getMutableConfig();if(!r.customMCP||!r.customMCP.tools)throw new Error("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177");let n=r.customMCP.tools.findIndex(s=>s.name===e);if(n===-1)throw new Error(`\u5DE5\u5177 "${e}" \u4E0D\u5B58\u5728`);if(!this.validateCustomMCPTools([t]))throw new Error("\u66F4\u65B0\u540E\u7684\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");r.customMCP.tools[n]=t,this.saveConfig(r),c.debug(`\u6210\u529F\u66F4\u65B0\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177: ${e}`)}updateCustomMCPTools(e){if(!Array.isArray(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u5FC5\u987B\u662F\u6570\u7EC4");if(!this.validateCustomMCPTools(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let t=this.getMutableConfig();t.customMCP||(t.customMCP={tools:[]}),t.customMCP.tools=e,this.saveConfig(t),this.eventBus.emitEvent("config:updated",{type:"customMCP",timestamp:new Date}),c.debug(`\u6210\u529F\u66F4\u65B0\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177\u914D\u7F6E\uFF0C\u5171 ${e.length} \u4E2A\u5DE5\u5177`)}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})}updatePlatformConfig(e,t){let r=this.getMutableConfig();r.platforms||(r.platforms={}),r.platforms[e]=t,this.saveConfig(r)}getCozePlatformConfig(){let t=this.getConfig().platforms?.coze;return!t||!t.token?null:{token:t.token}}getCozeToken(){return this.getCozePlatformConfig()?.token||null}setCozePlatformConfig(e){if(!e.token||typeof e.token!="string"||e.token.trim()==="")throw new Error("\u6263\u5B50 API Token \u4E0D\u80FD\u4E3A\u7A7A");this.updatePlatformConfig("coze",{token:e.token.trim()})}isCozeConfigValid(){let e=this.getCozePlatformConfig();return e!==null&&typeof e.token=="string"&&e.token.trim()!==""}async _updateMCPServerToolStats(e,t,r,n=!0){let s=this.getMutableConfig();s.mcpServerConfig||(s.mcpServerConfig={}),s.mcpServerConfig[e]||(s.mcpServerConfig[e]={tools:{}}),s.mcpServerConfig[e].tools[t]||(s.mcpServerConfig[e].tools[t]={enable:!0});let o=s.mcpServerConfig[e].tools[t],a=o.usageCount||0,g=o.lastUsedTime;n&&(o.usageCount=a+1),(!g||new Date(r)>new Date(g))&&(o.lastUsedTime=Ee(r).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(s)}async updateCustomMCPToolStats(e,t,r){try{let n,s,o=!0,a;if(typeof r=="string"){let y=e;n=`${y}__${t}`,s=r,a=`${y}/${t}`}else n=e,s=t,o=r||!0,a=n;let g=this.getCustomMCPTools(),u=g.findIndex(y=>y.name===n);if(u===-1)return;let p=[...g],h=p[u];h.stats||(h.stats={});let S=h.stats.usageCount||0,T=h.stats.lastUsedTime;o&&(h.stats.usageCount=S+1),(!T||new Date(s)>new Date(T))&&(h.stats.lastUsedTime=Ee(s).format("YYYY-MM-DD HH:mm:ss")),await this.updateCustomMCPTools(p)}catch(n){if(typeof r=="string"){let s=e,o=t;c.error(`\u66F4\u65B0 customMCP \u5DE5\u5177\u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25 (${s}/${o}): ${n instanceof Error?n.message:String(n)}`)}else{let s=e;c.error(`\u66F4\u65B0 customMCP \u5DE5\u5177\u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25 (${s}): ${n instanceof Error?n.message:String(n)}`)}}}async acquireStatsUpdateLock(e){if(this.statsUpdateLocks.has(e))return c.debug(`\u5DE5\u5177 ${e} \u7684\u7EDF\u8BA1\u66F4\u65B0\u6B63\u5728\u8FDB\u884C\u4E2D\uFF0C\u8DF3\u8FC7\u672C\u6B21\u66F4\u65B0`),!1;let t=new Promise(n=>{});this.statsUpdateLocks.set(e,t);let r=setTimeout(()=>{this.releaseStatsUpdateLock(e)},this.STATS_UPDATE_TIMEOUT);return this.statsUpdateLockTimeouts.set(e,r),!0}releaseStatsUpdateLock(e){this.statsUpdateLocks.delete(e);let t=this.statsUpdateLockTimeouts.get(e);t&&(clearTimeout(t),this.statsUpdateLockTimeouts.delete(e)),c.debug(`\u5DF2\u91CA\u653E\u5DE5\u5177 ${e} \u7684\u7EDF\u8BA1\u66F4\u65B0\u9501`)}async updateToolUsageStatsWithLock(e,t=!0){let r=`custommcp_${e}`;if(await this.acquireStatsUpdateLock(r))try{await this.updateToolUsageStats(e,t),c.debug(`\u5DE5\u5177 ${e} \u7EDF\u8BA1\u66F4\u65B0\u5B8C\u6210`)}catch(n){throw c.error(`\u5DE5\u5177 ${e} \u7EDF\u8BA1\u66F4\u65B0\u5931\u8D25:`,n),n}finally{this.releaseStatsUpdateLock(r)}}async updateMCPServerToolStatsWithLock(e,t,r,n=!0){let s=`mcpserver_${e}_${t}`;if(await this.acquireStatsUpdateLock(s))try{await this.updateMCPServerToolStats(e,t,r,n),c.debug(`MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u7EDF\u8BA1\u66F4\u65B0\u5B8C\u6210`)}catch(o){throw c.error(`MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u7EDF\u8BA1\u66F4\u65B0\u5931\u8D25:`,o),o}finally{this.releaseStatsUpdateLock(s)}}clearAllStatsUpdateLocks(){let e=this.statsUpdateLocks.size;this.statsUpdateLocks.clear();for(let t of this.statsUpdateLockTimeouts.values())clearTimeout(t);this.statsUpdateLockTimeouts.clear(),e>0&&c.info(`\u5DF2\u6E05\u7406 ${e} \u4E2A\u7EDF\u8BA1\u66F4\u65B0\u9501`)}getStatsUpdateLocks(){return Array.from(this.statsUpdateLocks.keys())}getToolCallLogConfig(){return this.getConfig().toolCallLog||{}}updateToolCallLogConfig(e){let t=this.getMutableConfig();t.toolCallLog||(t.toolCallLog={}),Object.assign(t.toolCallLog,e),this.saveConfig(t)}getConfigDir(){return process.env.XIAOZHI_CONFIG_DIR||process.cwd()}},f=de.getInstance();import{createHash as rt}from"crypto";function R(i,e){let t=rt("md5").update(JSON.stringify(e||{})).digest("hex");return`${i}_${t}`}l(R,"generateCacheKey");function H(i,e){let t=new Date(i).getTime();return Date.now()-t>e}l(H,"isCacheExpired");function O(i){let e=Date.now(),t=new Date(i.timestamp).getTime();return!!(i.consumed&&e-t>6e4||e-t>i.ttl||i.status==="failed")}l(O,"shouldCleanupCache");var $={TIMEOUT:8e3,CACHE_TTL:3e5,CLEANUP_INTERVAL:6e4,MAX_CACHE_SIZE:1e3,ENABLE_ONE_TIME_CACHE:!0};var J=class{static{l(this,"CacheLifecycleManager")}logger;cleanupInterval;statistics;lastCleanupTime;constructor(e){this.logger=e,this.statistics=this.initializeStatistics(),this.lastCleanupTime=new Date().toISOString()}initializeStatistics(){return{totalEntries:0,pendingTasks:0,completedTasks:0,failedTasks:0,consumedEntries:0,cacheHitRate:0,lastCleanupTime:new Date().toISOString(),memoryUsage:0}}startAutoCleanup(){if(this.cleanupInterval){this.logger.warn("[CacheLifecycle] \u81EA\u52A8\u6E05\u7406\u5B9A\u65F6\u5668\u5DF2\u7ECF\u5728\u8FD0\u884C");return}this.cleanupInterval=setInterval(()=>{this.performCleanup().catch(e=>{this.logger.error(`[CacheLifecycle] \u81EA\u52A8\u6E05\u7406\u5931\u8D25: ${e}`)})},$.CLEANUP_INTERVAL),this.logger.debug(`[CacheLifecycle] \u542F\u52A8\u81EA\u52A8\u6E05\u7406\u5B9A\u65F6\u5668\uFF0C\u95F4\u9694: ${$.CLEANUP_INTERVAL}ms`)}stopAutoCleanup(){this.cleanupInterval&&(clearInterval(this.cleanupInterval),this.cleanupInterval=void 0,this.logger.info("[CacheLifecycle] \u505C\u6B62\u81EA\u52A8\u6E05\u7406\u5B9A\u65F6\u5668"))}createCacheEntry(e,t,r,n="pending",s){let o={result:r,timestamp:new Date().toISOString(),ttl:$.CACHE_TTL,status:n,consumed:!1,taskId:s,retryCount:0};return this.logger.debug(`[CacheLifecycle] \u521B\u5EFA\u7F13\u5B58\u6761\u76EE: ${e}, \u72B6\u6001: ${n}`),o}updateCacheStatus(e,t,r,n,s){if(!e.customMCPResults||!e.customMCPResults[t])return this.logger.warn(`[CacheLifecycle] \u7F13\u5B58\u6761\u76EE\u4E0D\u5B58\u5728: ${t}`),!1;let o=e.customMCPResults[t],a=o.status;return this.logStateTransition(t,a,r),o.status=r,o.timestamp=new Date().toISOString(),n&&(o.result=n),s&&r==="failed"&&(o.result={content:[{type:"text",text:`\u4EFB\u52A1\u5931\u8D25: ${s}`}]},o.consumed=!0),r==="completed"&&(o.consumed=!1),this.logger.debug(`[CacheLifecycle] \u66F4\u65B0\u7F13\u5B58\u72B6\u6001: ${t} ${a} -> ${r}`),!0}markAsConsumed(e,t){if(!e.customMCPResults||!e.customMCPResults[t])return!1;let r=e.customMCPResults[t];return r.consumed?(this.logger.debug(`[CacheLifecycle] \u7F13\u5B58\u5DF2\u6807\u8BB0\u4E3A\u6D88\u8D39: ${t}`),!0):(r.consumed=!0,r.timestamp=new Date().toISOString(),this.logStateTransition(t,r.status,"consumed"),this.logger.debug(`[CacheLifecycle] \u6807\u8BB0\u7F13\u5B58\u4E3A\u5DF2\u6D88\u8D39: ${t}`),!0)}isCacheAvailable(e,t){if(!e.customMCPResults||!e.customMCPResults[t])return!1;let r=e.customMCPResults[t];return H(r.timestamp,r.ttl)?(this.logger.debug(`[CacheLifecycle] \u7F13\u5B58\u5DF2\u8FC7\u671F: ${t}`),!1):r.consumed?(this.logger.debug(`[CacheLifecycle] \u7F13\u5B58\u5DF2\u6D88\u8D39: ${t}`),!1):r.status!=="completed"?(this.logger.debug(`[CacheLifecycle] \u7F13\u5B58\u72B6\u6001\u672A\u5B8C\u6210: ${t}, \u72B6\u6001: ${r.status}`),!1):!0}async performCleanup(){try{this.logger.debug("[CacheLifecycle] \u6267\u884C\u7F13\u5B58\u6E05\u7406"),this.lastCleanupTime=new Date().toISOString()}catch(e){throw this.logger.error(`[CacheLifecycle] \u6E05\u7406\u5931\u8D25: ${e}`),e}}cleanupCacheEntries(e,t){if(!e.customMCPResults)return{cleaned:0,total:0};let r=Object.entries(e.customMCPResults),n=0,s=t||r.map(([o])=>o);for(let o of s){let a=e.customMCPResults[o];a&&O(a)&&(delete e.customMCPResults[o],n++,this.logger.debug(`[CacheLifecycle] \u6E05\u7406\u7F13\u5B58\u6761\u76EE: ${o}`))}return this.logger.info(`[CacheLifecycle] \u6E05\u7406\u5B8C\u6210: ${n}/${s.length}`),{cleaned:n,total:s.length}}cleanupExpiredCache(e){if(!e.customMCPResults)return{cleaned:0,total:0};let t=Object.entries(e.customMCPResults),r=0;for(let[n,s]of t)H(s.timestamp,s.ttl)&&(delete e.customMCPResults[n],r++,this.logger.debug(`[CacheLifecycle] \u6E05\u7406\u8FC7\u671F\u7F13\u5B58: ${n}`));return r>0&&this.logger.info(`[CacheLifecycle] \u6E05\u7406\u8FC7\u671F\u7F13\u5B58: ${r}/${t.length}`),{cleaned:r,total:t.length}}cleanupConsumedCache(e){if(!e.customMCPResults)return{cleaned:0,total:0};let t=Object.entries(e.customMCPResults),r=0,n=Date.now();for(let[s,o]of t)if(o.consumed){let a=new Date(o.timestamp).getTime();n-a>6e4&&(delete e.customMCPResults[s],r++,this.logger.debug(`[CacheLifecycle] \u6E05\u7406\u5DF2\u6D88\u8D39\u7F13\u5B58: ${s}`))}return r>0&&this.logger.info(`[CacheLifecycle] \u6E05\u7406\u5DF2\u6D88\u8D39\u7F13\u5B58: ${r}/${t.length}`),{cleaned:r,total:t.length}}updateStatistics(e){if(!e.customMCPResults){this.statistics=this.initializeStatistics();return}let t=Object.values(e.customMCPResults);this.statistics.totalEntries=t.length,this.statistics.pendingTasks=t.filter(s=>s.status==="pending").length,this.statistics.completedTasks=t.filter(s=>s.status==="completed").length,this.statistics.failedTasks=t.filter(s=>s.status==="failed").length,this.statistics.consumedEntries=t.filter(s=>s.consumed).length;let r=this.statistics.completedTasks,n=this.statistics.consumedEntries;this.statistics.cacheHitRate=r>0?n/r*100:0,this.statistics.lastCleanupTime=this.lastCleanupTime,this.statistics.memoryUsage=JSON.stringify(e.customMCPResults).length}getStatistics(){return{...this.statistics}}validateCacheIntegrity(e){let t=[];if(!e.customMCPResults)return{isValid:!0,issues:[]};for(let[r,n]of Object.entries(e.customMCPResults))(!n.timestamp||!n.ttl||!n.status)&&t.push(`\u7F13\u5B58\u6761\u76EE\u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5: ${r}`),Number.isNaN(new Date(n.timestamp).getTime())&&t.push(`\u65E0\u6548\u7684\u65F6\u95F4\u6233\u683C\u5F0F: ${r}`),["pending","completed","failed"].includes(n.status)||t.push(`\u65E0\u6548\u7684\u72B6\u6001\u503C: ${r}, \u72B6\u6001: ${n.status}`),H(n.timestamp,n.ttl)&&t.push(`\u7F13\u5B58\u6761\u76EE\u5DF2\u8FC7\u671F: ${r}`);return{isValid:t.length===0,issues:t}}logStateTransition(e,t,r){let n={from:t,to:r,reason:this.getTransitionReason(t,r),timestamp:new Date().toISOString()};this.logger.debug(`[CacheLifecycle] \u72B6\u6001\u8F6C\u6362: ${e} ${t} -> ${r} (${n.reason})`)}getTransitionReason(e,t){return{"pending->completed":"\u4EFB\u52A1\u6267\u884C\u6210\u529F","pending->failed":"\u4EFB\u52A1\u6267\u884C\u5931\u8D25","completed->consumed":"\u7ED3\u679C\u88AB\u6D88\u8D39","failed->consumed":"\u5931\u8D25\u7ED3\u679C\u88AB\u5904\u7406","consumed->deleted":"\u7F13\u5B58\u88AB\u6E05\u7406"}[`${e}->${t}`]||"\u72B6\u6001\u66F4\u65B0"}cleanup(){this.stopAutoCleanup(),this.logger.info("[CacheLifecycle] \u6E05\u7406\u8D44\u6E90\u5B8C\u6210")}};var q=class{static{l(this,"TaskStateManager")}logger;activeTasks;taskHistory;constructor(e){this.logger=e,this.activeTasks=new Map,this.taskHistory=[]}generateTaskId(e,t){let r=Date.now(),n=Math.random().toString(36).substring(2,11),s=`${e}_${r}_${n}`;return this.logger.debug(`[TaskState] \u751F\u6210\u4EFB\u52A1ID: ${s}`),s}validateTaskId(e){let r=/^[a-zA-Z0-9_-]+_\d+_[a-zA-Z0-9]+$/.test(e);return r||this.logger.warn(`[TaskState] \u65E0\u6548\u7684\u4EFB\u52A1ID\u683C\u5F0F: ${e}`),r}extractToolName(e){if(!this.validateTaskId(e))return null;let t=e.split("_");if(t.length<3)return null;let r=t.findIndex(s=>/^\d+$/.test(s));return r<=0?null:t.slice(0,r).join("_")}createTask(e,t,r,n="pending"){if(this.activeTasks.has(e))throw new Error(`\u4EFB\u52A1\u5DF2\u5B58\u5728: ${e}`);let s={taskId:e,toolName:t,arguments:r,status:n,startTime:new Date().toISOString()};return this.activeTasks.set(e,s),this.recordStateTransition(e,"none",n,"\u521B\u5EFA\u65B0\u4EFB\u52A1"),this.logger.info(`[TaskState] \u521B\u5EFA\u4EFB\u52A1: ${e}, \u5DE5\u5177: ${t}, \u72B6\u6001: ${n}`),s}updateTaskStatus(e,t,r,n){let s=this.activeTasks.get(e);if(!s)return this.logger.warn(`[TaskState] \u4EFB\u52A1\u4E0D\u5B58\u5728: ${e}`),!1;let o=s.status;return s.status=t,(t==="completed"||t==="failed")&&(s.endTime=new Date().toISOString()),r&&(s.result=r),n&&(s.error=n),this.recordStateTransition(e,o,t,this.getStatusChangeReason(o,t,n)),this.logger.info(`[TaskState] \u66F4\u65B0\u4EFB\u52A1\u72B6\u6001: ${e} ${o} -> ${t}`),!0}markTaskAsPending(e,t,r){let n=this.activeTasks.get(e);return n?this.updateTaskStatus(e,"pending"):n=this.createTask(e,t,r,"pending"),n}markTaskAsCompleted(e,t){return this.updateTaskStatus(e,"completed",t)}markTaskAsFailed(e,t){return this.updateTaskStatus(e,"failed",void 0,t)}markTaskAsConsumed(e){return this.updateTaskStatus(e,"consumed")}getTask(e){return this.activeTasks.get(e)||null}hasTask(e){return this.activeTasks.has(e)}getTaskStatus(e){let t=this.activeTasks.get(e);return t?t.status:null}getTasksByStatus(e){return Array.from(this.activeTasks.values()).filter(t=>t.status===e)}getTasksByTool(e){return Array.from(this.activeTasks.values()).filter(t=>t.toolName===e)}getTaskExecutionTime(e){let t=this.activeTasks.get(e);if(!t||!t.endTime)return null;let r=new Date(t.startTime).getTime();return new Date(t.endTime).getTime()-r}isTaskTimeout(e,t=8e3){let r=this.activeTasks.get(e);if(!r)return!1;let n=new Date(r.startTime).getTime();return Date.now()-n>t}getTimeoutTasks(e=8e3){let t=Date.now();return Array.from(this.activeTasks.values()).filter(r=>{let n=new Date(r.startTime).getTime();return t-n>e&&r.status==="pending"})}removeTask(e){let t=this.activeTasks.get(e);return t?(this.recordStateTransition(e,t.status,"deleted","\u4EFB\u52A1\u88AB\u79FB\u9664"),this.activeTasks.delete(e),this.logger.info(`[TaskState] \u79FB\u9664\u4EFB\u52A1: ${e}`),!0):!1}cleanupCompletedTasks(e=3e5){let t=Date.now(),r=0;for(let[n,s]of this.activeTasks.entries())if(s.status==="completed"||s.status==="failed"){let o=s.endTime?new Date(s.endTime).getTime():t;t-o>e&&(this.removeTask(n),r++)}return r>0&&this.logger.info(`[TaskState] \u6E05\u7406\u5DF2\u5B8C\u6210\u4EFB\u52A1: ${r}\u4E2A`),r}getTaskStatistics(){let e=Array.from(this.activeTasks.values()),t=e.length,r=e.filter(u=>u.status==="pending").length,n=e.filter(u=>u.status==="completed").length,s=e.filter(u=>u.status==="failed").length,o=e.filter(u=>u.status==="consumed").length,a=e.filter(u=>u.status==="completed"&&u.endTime),g=a.length>0?a.reduce((u,p)=>{let h=this.getTaskExecutionTime(p.taskId)||0;return u+h},0)/a.length:0;return{total:t,pending:r,completed:n,failed:s,consumed:o,averageExecutionTime:g}}getTaskHistory(e){return e?this.taskHistory.filter(t=>t.taskId===e):[...this.taskHistory]}recordStateTransition(e,t,r,n){let s={from:t,to:r,reason:n,timestamp:new Date().toISOString(),taskId:e};this.taskHistory.push(s),this.taskHistory.length>1e3&&(this.taskHistory=this.taskHistory.slice(-500))}getStatusChangeReason(e,t,r){if(r)return`\u6267\u884C\u5931\u8D25: ${r}`;let n={"none->pending":"\u4EFB\u52A1\u5F00\u59CB\u6267\u884C","pending->completed":"\u4EFB\u52A1\u6267\u884C\u6210\u529F","pending->failed":"\u4EFB\u52A1\u6267\u884C\u5931\u8D25","completed->consumed":"\u7ED3\u679C\u88AB\u6D88\u8D39","failed->consumed":"\u5931\u8D25\u7ED3\u679C\u88AB\u5904\u7406","consumed->deleted":"\u4EFB\u52A1\u88AB\u6E05\u7406"},s=`${e}->${t}`;return n[s]||"\u72B6\u6001\u66F4\u65B0"}validateTaskIntegrity(){let e=[];for(let[t,r]of this.activeTasks.entries())(!r.taskId||!r.toolName||!r.status||!r.startTime)&&e.push(`\u4EFB\u52A1\u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5: ${t}`),Number.isNaN(new Date(r.startTime).getTime())&&e.push(`\u65E0\u6548\u7684\u5F00\u59CB\u65F6\u95F4: ${t}`),r.endTime&&Number.isNaN(new Date(r.endTime).getTime())&&e.push(`\u65E0\u6548\u7684\u7ED3\u675F\u65F6\u95F4: ${t}`),r.status==="completed"&&!r.endTime&&e.push(`\u5DF2\u5B8C\u6210\u4EFB\u52A1\u7F3A\u5C11\u7ED3\u675F\u65F6\u95F4: ${t}`),r.status==="failed"&&!r.error&&e.push(`\u5931\u8D25\u4EFB\u52A1\u7F3A\u5C11\u9519\u8BEF\u4FE1\u606F: ${t}`);return{isValid:e.length===0,issues:e}}restartStalledTasks(e=3e4){let t=this.getTimeoutTasks(e),r=0;for(let n of t){this.logger.warn(`[TaskState] \u68C0\u6D4B\u5230\u505C\u6EDE\u4EFB\u52A1: ${n.taskId}`),this.markTaskAsFailed(n.taskId,"\u4EFB\u52A1\u6267\u884C\u8D85\u65F6");let s=this.generateTaskId(n.toolName,n.arguments);this.createTask(s,n.toolName,n.arguments,"pending"),r++}return r>0&&this.logger.info(`[TaskState] \u91CD\u542F\u505C\u6EDE\u4EFB\u52A1: ${r}\u4E2A`),r}cleanup(){this.activeTasks.clear(),this.taskHistory=[],this.logger.info("[TaskState] \u6E05\u7406\u4EFB\u52A1\u72B6\u6001\u7BA1\u7406\u5668\u8D44\u6E90")}};var _=class i extends Error{static{l(this,"TimeoutError")}name="TimeoutError";constructor(e){super(e),this.name="TimeoutError",Error.captureStackTrace(this,i)}toJSON(){return{name:this.name,message:this.message,stack:this.stack}}};function xe(i,e){return{content:[{type:"text",text:e?nt(e,i):Ie(i)}],isError:!1,taskId:i,status:"timeout",message:"\u5DE5\u5177\u8C03\u7528\u8D85\u65F6\uFF0C\u6B63\u5728\u540E\u53F0\u5904\u7406\u4E2D",nextAction:"\u8BF7\u7A0D\u540E\u91CD\u8BD5\u6216\u7B49\u5F85\u4EFB\u52A1\u5B8C\u6210"}}l(xe,"createTimeoutResponse");function nt(i,e){let t={coze_workflow:`\u23F1\uFE0F \u6263\u5B50\u5DE5\u4F5C\u6D41\u6267\u884C\u8D85\u65F6\uFF0C\u6B63\u5728\u540E\u53F0\u5904\u7406\u4E2D...
2
+ var Fe=Object.defineProperty;var l=(i,e)=>Fe(i,"name",{value:e,configurable:!0});import{dirname as Rt}from"path";import R from"process";import{fileURLToPath as $t}from"url";import{EventEmitter as at}from"events";var _=(r=>(r.STDIO="stdio",r.SSE="sse",r.STREAMABLE_HTTP="streamable-http",r))(_||{});import*as v from"fs";import*as M from"path";import z from"chalk";import H from"pino";import{z as Ue}from"zod";var _e=Ue.enum(["fatal","error","warn","info","debug","trace"]);function ze(i){let e=i.getFullYear(),t=String(i.getMonth()+1).padStart(2,"0"),r=String(i.getDate()).padStart(2,"0"),s=String(i.getHours()).padStart(2,"0"),o=String(i.getMinutes()).padStart(2,"0"),n=String(i.getSeconds()).padStart(2,"0");return`${e}-${t}-${r} ${s}:${o}:${n}`}l(ze,"formatDateTime");var ce=class{static{l(this,"Logger")}logFilePath=null;pinoInstance;isDaemonMode;logLevel;maxLogFileSize=10*1024*1024;maxLogFiles=5;constructor(e="info"){this.isDaemonMode=process.env.XIAOZHI_DAEMON==="true",this.logLevel=this.validateLogLevel(e),this.pinoInstance=this.createPinoInstance()}validateLogLevel(e){let t=e.toLowerCase(),r=_e.safeParse(t);return r.success?r.data:"info"}createPinoInstance(){let e=[];if(!this.isDaemonMode){let t=this.createOptimizedConsoleStream();e.push({level:this.logLevel,stream:t})}return this.logFilePath&&e.push({level:this.logLevel,stream:H.destination({dest:this.logFilePath,sync:!1,append:!0,mkdir:!0})}),e.length===0&&e.push({level:this.logLevel,stream:H.destination({dest:"/dev/null"})}),H({level:this.logLevel,timestamp:H.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:l((t,r)=>({level:r}),"level")},base:null,serializers:{err:H.stdSerializers?.err||(t=>t)}},H.multistream(e,{dedupe:!0}))}createOptimizedConsoleStream(){let e=new Map([[20,{name:"DEBUG",color:z.gray}],[30,{name:"INFO",color:z.blue}],[40,{name:"WARN",color:z.yellow}],[50,{name:"ERROR",color:z.red}],[60,{name:"FATAL",color:z.red}]]);return{write:l(t=>{try{let r=JSON.parse(t),s=this.formatConsoleMessageOptimized(r,e);this.safeWrite(`${s}
3
+ `)}catch{this.safeWrite(t)}},"write")}}safeWrite(e){try{process.stderr&&typeof process.stderr.write=="function"?process.stderr.write(e):console&&typeof console.error=="function"&&console.error(e.trim())}catch{}}formatConsoleMessageOptimized(e,t){let r=ze(new Date),s=t.get(e.level)||{name:"UNKNOWN",color:l(a=>a,"color")},o=s.color(`[${s.name}]`),n=e.msg;if(e.args&&Array.isArray(e.args)){let a=e.args.map(g=>typeof g=="object"?JSON.stringify(g):String(g)).join(" ");n=`${n} ${a}`}return`[${r}] ${o} ${n}`}initLogFile(e){this.logFilePath=M.join(e,"xiaozhi.log"),this.rotateLogFileIfNeeded(),v.existsSync(this.logFilePath)||v.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 r=t.map(s=>s instanceof Error?this.pinoInstance.level==="debug"?s.message:{message:s.message,stack:s.stack,name:s.name,cause:s.cause}:s);this.pinoInstance.error({args:r},e)}else{let r=this.enhanceErrorObject(e);this.pinoInstance.error(r,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[r,s]of Object.entries(t))s instanceof Error&&(t[r]={message:s.message,stack:s.stack,name:s.name,cause:s.cause});return t}rotateLogFileIfNeeded(){if(!(!this.logFilePath||!v.existsSync(this.logFilePath)))try{v.statSync(this.logFilePath).size>this.maxLogFileSize&&this.rotateLogFile()}catch{}}rotateLogFile(){if(this.logFilePath)try{let e=M.dirname(this.logFilePath),t=M.basename(this.logFilePath,".log");for(let s=this.maxLogFiles-1;s>=1;s--){let o=M.join(e,`${t}.${s}.log`),n=M.join(e,`${t}.${s+1}.log`);v.existsSync(o)&&(s===this.maxLogFiles-1?v.unlinkSync(o):v.renameSync(o,n))}let r=M.join(e,`${t}.1.log`);v.renameSync(this.logFilePath,r)}catch{}}cleanupOldLogs(){if(this.logFilePath)try{let e=M.dirname(this.logFilePath),t=M.basename(this.logFilePath,".log");for(let r=this.maxLogFiles+1;r<=this.maxLogFiles+10;r++){let s=M.join(e,`${t}.${r}.log`);v.existsSync(s)&&v.unlinkSync(s)}}catch{}}setLogFileOptions(e,t){this.maxLogFileSize=e,this.maxLogFiles=t}withTag(e){return this}close(){}setLevel(e){this.logLevel=this.validateLogLevel(e),this.pinoInstance=this.createPinoInstance()}getLevel(){return this.logLevel}},ae=null,We="info";function Be(){return ae||(ae=new ce(We)),ae}l(Be,"getLogger");var c=Be();var K=class{static{l(this,"MCPMessageHandler")}logger;serviceManager;constructor(e){this.serviceManager=e,this.logger=c}async handleMessage(e){this.logger.debug(`\u5904\u7406 MCP \u6D88\u606F: ${e.method}`,e);try{let t=e.id===void 0;switch(e.method){case"initialize":return await this.handleInitialize(e.params,e.id);case"notifications/initialized":return await this.handleInitializedNotification(e.params);case"tools/list":return await this.handleToolsList(e.id);case"tools/call":return await this.handleToolCall(e.params,e.id);case"resources/list":return await this.handleResourcesList(e.id);case"prompts/list":return await this.handlePromptsList(e.id);case"ping":return await this.handlePing(e.id);default:if(t)return this.logger.warn(`\u6536\u5230\u672A\u77E5\u7684\u901A\u77E5\u6D88\u606F: ${e.method}`,e),null;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),e.id===void 0?null:this.createErrorResponse(t,e.id)}}async handleInitialize(e,t){this.logger.debug("\u5904\u7406 initialize \u8BF7\u6C42",e);let r=["2024-11-05","2025-06-18"],s=e.protocolVersion,o=r.includes(s)?s:"2024-11-05";return this.logger.debug(`\u534F\u8BAE\u7248\u672C\u534F\u5546: \u5BA2\u6237\u7AEF=${s}, \u670D\u52A1\u5668\u54CD\u5E94=${o}`),{jsonrpc:"2.0",result:{serverInfo:{name:"xiaozhi-mcp-server",version:"1.0.0"},capabilities:{tools:{},logging:{}},protocolVersion:o},id:t!==void 0?t:1}}async handleInitializedNotification(e){return this.logger.debug("\u6536\u5230 initialized \u901A\u77E5\uFF0C\u5BA2\u6237\u7AEF\u521D\u59CB\u5316\u5B8C\u6210",e),null}async handleToolsList(e){this.logger.debug("\u5904\u7406 tools/list \u8BF7\u6C42");try{return{jsonrpc:"2.0",result:{tools:this.serviceManager.getAllTools().map(s=>({name:s.name,description:s.description,inputSchema:s.inputSchema}))},id:e!==void 0?e:1}}catch(t){throw this.logger.error("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25",t),t}}async handleToolCall(e,t){try{if(!e.name)throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");let r=await this.serviceManager.callTool(e.name,e.arguments||{});return{jsonrpc:"2.0",result:{content:r.content,isError:r.isError||!1},id:t!==void 0?t:1}}catch(r){throw this.logger.error(`\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,r),r}}async handlePing(e){return this.logger.debug("\u5904\u7406 ping \u8BF7\u6C42"),{jsonrpc:"2.0",result:{status:"ok",timestamp:new Date().toISOString()},id:e!==void 0?e:1}}async handleResourcesList(e){this.logger.debug("\u5904\u7406 resources/list \u8BF7\u6C42");let t=[];return this.logger.debug(`\u8FD4\u56DE ${t.length} \u4E2A\u8D44\u6E90`),{jsonrpc:"2.0",result:{resources:t},id:e!==void 0?e:1}}async handlePromptsList(e){this.logger.debug("\u5904\u7406 prompts/list \u8BF7\u6C42");let t=[];return this.logger.debug(`\u8FD4\u56DE ${t.length} \u4E2A\u63D0\u793A\u6A21\u677F`),{jsonrpc:"2.0",result:{prompts:t},id:e!==void 0?e:1}}createErrorResponse(e,t){let r=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?r=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(r=-32602),{jsonrpc:"2.0",error:{code:r,message:e.message,data:{stack:e.stack}},id:t!==void 0?t:1}}getServiceManager(){return this.serviceManager}};import{copyFileSync as Ge,existsSync as G,readFileSync as Je,writeFileSync as qe}from"fs";import{dirname as Ye,resolve as A}from"path";import{fileURLToPath as Qe}from"url";import{EventEmitter as Ve}from"events";var ge=class extends Ve{static{l(this,"EventBus")}logger;eventStats=new Map;maxListeners=50;constructor(){super(),this.logger=c.withTag("EventBus"),this.setMaxListeners(this.maxListeners),this.setupErrorHandling()}setupErrorHandling(){this.on("error",e=>{this.logger.error("EventBus \u5185\u90E8\u9519\u8BEF:",e)}),this.on("newListener",e=>{let t=this.listenerCount(e);t>this.maxListeners*.8&&this.logger.warn(`\u4E8B\u4EF6 ${e} \u7684\u76D1\u542C\u5668\u6570\u91CF\u8FC7\u591A: ${t}`)})}emitEvent(e,t){try{return this.updateEventStats(e),this.logger.debug(`\u53D1\u5C04\u4E8B\u4EF6: ${e}`,t),super.emit(e,t)}catch(r){return this.logger.error(`\u53D1\u5C04\u4E8B\u4EF6\u5931\u8D25: ${e}`,r),r instanceof Error&&this.emit("error",r),!1}}onEvent(e,t){return this.logger.debug(`\u6DFB\u52A0\u4E8B\u4EF6\u76D1\u542C\u5668: ${e}`),this.on(e,t)}onceEvent(e,t){this.logger.debug(`\u6DFB\u52A0\u4E00\u6B21\u6027\u4E8B\u4EF6\u76D1\u542C\u5668: ${e}`);let r=l(s=>{try{t(s)}catch(o){throw this.emit("error",o),o}finally{this.offEvent(e,r)}},"onceListener");return this.on(e,r)}offEvent(e,t){return this.logger.debug(`\u79FB\u9664\u4E8B\u4EF6\u76D1\u542C\u5668: ${e}`),this.off(e,t)}updateEventStats(e){let t=this.eventStats.get(e)||{count:0,lastEmitted:new Date};t.count++,t.lastEmitted=new Date,this.eventStats.set(e,t)}getEventStats(){let e={};for(let[t,r]of this.eventStats)e[t]={...r};return e}getListenerStats(){let e={};for(let t of this.eventNames())e[t]=this.listenerCount(t);return e}clearEventStats(){this.eventStats.clear(),this.logger.info("\u4E8B\u4EF6\u7EDF\u8BA1\u5DF2\u6E05\u7406")}getStatus(){return{totalEvents:this.eventStats.size,totalListeners:Object.values(this.getListenerStats()).reduce((e,t)=>e+t,0),eventStats:this.getEventStats(),listenerStats:this.getListenerStats()}}destroy(){this.removeAllListeners(),this.eventStats.clear(),this.logger.info("EventBus \u5DF2\u9500\u6BC1")}},le=null;function b(){return le||(le=new ge),le}l(b,"getEventBus");function Ke(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")}l(Ke,"getMcpServerCommunicationType");function ue(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(Ke(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"}`}}}l(ue,"validateMcpServerConfig");import*as J from"comment-json";import ye from"dayjs";import he from"json5";import*as we from"json5-writer";var be=Ye(Qe(import.meta.url)),pe={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},me=class i{static{l(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;eventBus=b();statsUpdateLocks=new Map;statsUpdateLockTimeouts=new Map;STATS_UPDATE_TIMEOUT=5e3;constructor(){let e=[A(be,"templates","default","xiaozhi.config.json"),A(be,"..","templates","default","xiaozhi.config.json"),A(process.cwd(),"templates","default","xiaozhi.config.json")];this.defaultConfigPath=e.find(t=>G(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 r of t){let s=A(e,r);if(G(s))return s}return A(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 r of t){let s=A(e,r);if(G(s))return!0}return!1}initConfig(e="json"){if(!G(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(),r=`xiaozhi.config.${e}`,s=A(t,r);Ge(this.defaultConfigPath,s),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),s=Je(e,"utf8").replace(/^\uFEFF/,""),o;switch(t){case"json5":o=he.parse(s),this.json5Writer=we.load(s);break;case"jsonc":o=J.parse(s);break;default:o=JSON.parse(s);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)){for(let r of t.mcpEndpoint)if(typeof r!="string"||r.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[r,s]of Object.entries(t.mcpServers)){if(!s||typeof s!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${r} \u65E0\u6548`);let o=ue(r,s);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)){for(let r of e)if(!r||typeof r!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\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(),r=this.getMcpEndpoints();if(r.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let s=[...r,e];t.mcpEndpoint=s,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(),r=this.getMcpEndpoints();if(r.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);let o=r.filter(n=>n!==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 r=ue(e,t);if(!r.valid)throw new Error(r.error||"\u670D\u52A1\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let s=this.getMutableConfig();s.mcpServers[e]=t,this.saveConfig(s)}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.getMutableConfig();if(!t.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);if(delete t.mcpServers[e],t.mcpServerConfig?.[e]&&delete t.mcpServerConfig[e],t.customMCP?.tools){let r=t.customMCP.tools.filter(s=>s.handler?.type==="mcp"&&s.handler.config?.serviceName===e);for(let s of r){let o=t.customMCP.tools.findIndex(n=>n.name===s.name);o!==-1&&t.customMCP.tools.splice(o,1)}t.customMCP.tools.length===0&&(t.customMCP=void 0)}this.saveConfig(t),this.eventBus.emitEvent("config:updated",{type:"customMCP",timestamp:new Date}),c.info(`\u6210\u529F\u79FB\u9664 MCP \u670D\u52A1 ${e} \u53CA\u5176\u76F8\u5173\u914D\u7F6E`)}updateServerToolsConfig(e,t){let r=this.getMutableConfig();r.mcpServerConfig||(r.mcpServerConfig={}),Object.keys(t).length===0?delete r.mcpServerConfig[e]:r.mcpServerConfig[e]={tools:t},this.saveConfig(r),this.eventBus.emitEvent("config:updated",{type:"serverTools",serviceName:e,timestamp:new Date})}removeServerToolsConfig(e){let r={...this.getConfig()};r.mcpServerConfig&&(delete r.mcpServerConfig[e],this.saveConfig(r))}cleanupInvalidServerToolsConfig(){let e=this.getMutableConfig();if(!e.mcpServerConfig)return;let t=Object.keys(e.mcpServers),s=Object.keys(e.mcpServerConfig).filter(o=>!t.includes(o));if(s.length>0){for(let o of s)delete e.mcpServerConfig[o];this.saveConfig(e),c.info(`\u5DF2\u6E05\u7406 ${s.length} \u4E2A\u65E0\u6548\u7684\u670D\u52A1\u5DE5\u5177\u914D\u7F6E: ${s.join(", ")}`)}}setToolEnabled(e,t,r,s){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:r,...s&&{description:s}},this.saveConfig(o)}saveConfig(e){try{this.validateConfig(e);let t;this.currentConfigPath?t=this.currentConfigPath:(t=this.getConfigFilePath(),this.currentConfigPath=t);let r=this.getConfigFileFormat(t),s;switch(r){case"json5":try{this.json5Writer?(this.json5Writer.write(e),s=this.json5Writer.toSource()):(console.warn("\u6CA1\u6709 json5Writer \u5B9E\u4F8B\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F"),s=he.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),s=he.stringify(e,null,2)}break;case"jsonc":try{s=J.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),s=JSON.stringify(e,null,2)}break;default:s=JSON.stringify(e,null,2);break}qe(t,s,"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??pe.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??pe.heartbeatTimeout,reconnectInterval:t.reconnectInterval??pe.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,r){try{if(typeof t=="string"&&r){let s=e,o=t,n=r;await Promise.all([this._updateMCPServerToolStats(s,o,n),this.updateCustomMCPToolStats(s,o,n)]),c.debug(`\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${s}/${o}`)}else{let s=e,o=t,n=new Date().toISOString();await this.updateCustomMCPToolStats(s,n,o),c.debug(`CustomMCP \u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${s}`)}}catch(s){if(typeof t=="string"&&r){let o=e,n=t;c.error(`\u66F4\u65B0\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5931\u8D25 (${o}/${n}): ${s instanceof Error?s.message:String(s)}`)}else{let o=e;c.error(`\u66F4\u65B0 CustomMCP \u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5931\u8D25 (${o}): ${s instanceof Error?s.message:String(s)}`)}}}async updateMCPServerToolStats(e,t,r,s=!0){await this._updateMCPServerToolStats(e,t,r,s)}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})}getCustomMCPConfig(){return this.getConfig().customMCP||null}getCustomMCPTools(){let e=this.getCustomMCPConfig();return!e||!e.tools?[]:e.tools}validateCustomMCPTools(e){if(!Array.isArray(e))return!1;for(let t of e){if(!t.name||typeof t.name!="string")return c.warn(`CustomMCP \u5DE5\u5177\u7F3A\u5C11\u6709\u6548\u7684 name \u5B57\u6BB5: ${JSON.stringify(t)}`),!1;if(!t.description||typeof t.description!="string")return c.warn(`CustomMCP \u5DE5\u5177 ${t.name} \u7F3A\u5C11\u6709\u6548\u7684 description \u5B57\u6BB5`),!1;if(!t.inputSchema||typeof t.inputSchema!="object")return c.warn(`CustomMCP \u5DE5\u5177 ${t.name} \u7F3A\u5C11\u6709\u6548\u7684 inputSchema \u5B57\u6BB5`),!1;if(!t.handler||typeof t.handler!="object")return c.warn(`CustomMCP \u5DE5\u5177 ${t.name} \u7F3A\u5C11\u6709\u6548\u7684 handler \u5B57\u6BB5`),!1;if(!["proxy","function","http","script","chain","mcp"].includes(t.handler.type))return c.warn(`CustomMCP \u5DE5\u5177 ${t.name} \u7684 handler.type \u5FC5\u987B\u662F 'proxy', 'function', 'http', 'script', 'chain' \u6216 'mcp'`),!1;if(!this.validateHandlerConfig(t.name,t.handler))return!1}return!0}validateHandlerConfig(e,t){switch(t.type){case"proxy":return this.validateProxyHandler(e,t);case"http":return this.validateHttpHandler(e,t);case"function":return this.validateFunctionHandler(e,t);case"script":return this.validateScriptHandler(e,t);case"chain":return this.validateChainHandler(e,t);case"mcp":return this.validateMCPHandler(e,t);default:return c.warn(`CustomMCP \u5DE5\u5177 ${e} \u4F7F\u7528\u4E86\u672A\u77E5\u7684\u5904\u7406\u5668\u7C7B\u578B`),!1}}validateProxyHandler(e,t){return t.platform?["coze","openai","anthropic","custom"].includes(t.platform)?!t.config||typeof t.config!="object"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 proxy \u5904\u7406\u5668\u7F3A\u5C11 config \u5B57\u6BB5`),!1):t.platform==="coze"&&!t.config.workflow_id&&!t.config.bot_id?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 Coze \u5904\u7406\u5668\u5FC5\u987B\u63D0\u4F9B workflow_id \u6216 bot_id`),!1):!0:(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 proxy \u5904\u7406\u5668\u4F7F\u7528\u4E86\u4E0D\u652F\u6301\u7684\u5E73\u53F0: ${t.platform}`),!1):(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 proxy \u5904\u7406\u5668\u7F3A\u5C11 platform \u5B57\u6BB5`),!1)}validateHttpHandler(e,t){if(!t.url||typeof t.url!="string")return c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 http \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 url \u5B57\u6BB5`),!1;try{new URL(t.url)}catch{return c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 http \u5904\u7406\u5668 url \u683C\u5F0F\u65E0\u6548: ${t.url}`),!1}return t.method&&!["GET","POST","PUT","DELETE","PATCH"].includes(t.method)?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 http \u5904\u7406\u5668\u4F7F\u7528\u4E86\u4E0D\u652F\u6301\u7684 HTTP \u65B9\u6CD5: ${t.method}`),!1):!0}validateFunctionHandler(e,t){return!t.module||typeof t.module!="string"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 function \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 module \u5B57\u6BB5`),!1):!t.function||typeof t.function!="string"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 function \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 function \u5B57\u6BB5`),!1):!0}validateScriptHandler(e,t){return!t.script||typeof t.script!="string"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 script \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 script \u5B57\u6BB5`),!1):t.interpreter&&!["node","python","bash"].includes(t.interpreter)?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 script \u5904\u7406\u5668\u4F7F\u7528\u4E86\u4E0D\u652F\u6301\u7684\u89E3\u91CA\u5668: ${t.interpreter}`),!1):!0}validateChainHandler(e,t){return!t.tools||!Array.isArray(t.tools)||t.tools.length===0?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 chain \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 tools \u6570\u7EC4`),!1):["sequential","parallel"].includes(t.mode)?["stop","continue","retry"].includes(t.error_handling)?!0:(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 chain \u5904\u7406\u5668\u4F7F\u7528\u4E86\u4E0D\u652F\u6301\u7684\u9519\u8BEF\u5904\u7406\u7B56\u7565: ${t.error_handling}`),!1):(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 chain \u5904\u7406\u5668\u4F7F\u7528\u4E86\u4E0D\u652F\u6301\u7684\u6267\u884C\u6A21\u5F0F: ${t.mode}`),!1)}validateMCPHandler(e,t){return!t.config||typeof t.config!="object"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 mcp \u5904\u7406\u5668\u7F3A\u5C11 config \u5B57\u6BB5`),!1):!t.config.serviceName||typeof t.config.serviceName!="string"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 mcp \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 serviceName`),!1):!t.config.toolName||typeof t.config.toolName!="string"?(c.warn(`CustomMCP \u5DE5\u5177 ${e} \u7684 mcp \u5904\u7406\u5668\u7F3A\u5C11\u6709\u6548\u7684 toolName`),!1):!0}hasValidCustomMCPTools(){try{let e=this.getCustomMCPTools();return e.length===0?!1:this.validateCustomMCPTools(e)}catch(e){return c.error("\u68C0\u67E5 customMCP \u5DE5\u5177\u914D\u7F6E\u65F6\u51FA\u9519:",e),!1}}addCustomMCPTool(e){if(!e||typeof e!="object")throw new Error("\u5DE5\u5177\u914D\u7F6E\u4E0D\u80FD\u4E3A\u7A7A");let t=this.getMutableConfig();if(t.customMCP||(t.customMCP={tools:[]}),t.customMCP.tools.find(s=>s.name===e.name))throw new Error(`\u5DE5\u5177 "${e.name}" \u5DF2\u5B58\u5728`);if(!this.validateCustomMCPTools([e]))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");t.customMCP.tools.unshift(e),this.saveConfig(t),c.info(`\u6210\u529F\u6DFB\u52A0\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177: ${e.name}`)}async addCustomMCPTools(e){if(!Array.isArray(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u5FC5\u987B\u662F\u6570\u7EC4");if(e.length===0)return;let t=this.getMutableConfig();t.customMCP||(t.customMCP={tools:[]});let r=new Set(t.customMCP.tools.map(o=>o.name)),s=e.filter(o=>!r.has(o.name));if(s.length>0){if(!this.validateCustomMCPTools(s))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");t.customMCP.tools.push(...s),this.saveConfig(t),this.eventBus.emitEvent("config:updated",{type:"customMCP",timestamp:new Date}),c.debug(`\u6210\u529F\u6279\u91CF\u6DFB\u52A0 ${s.length} \u4E2A\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177: ${s.map(o=>o.name).join(", ")}`)}}removeCustomMCPTool(e){if(!e||typeof e!="string")throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");let t=this.getMutableConfig();if(!t.customMCP||!t.customMCP.tools)throw new Error("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177");let r=t.customMCP.tools.findIndex(s=>s.name===e);if(r===-1)throw new Error(`\u5DE5\u5177 "${e}" \u4E0D\u5B58\u5728`);t.customMCP.tools.splice(r,1),this.saveConfig(t),c.info(`\u6210\u529F\u5220\u9664\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177: ${e}`)}updateCustomMCPTool(e,t){if(!e||typeof e!="string")throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");if(!t||typeof t!="object")throw new Error("\u66F4\u65B0\u540E\u7684\u5DE5\u5177\u914D\u7F6E\u4E0D\u80FD\u4E3A\u7A7A");let r=this.getMutableConfig();if(!r.customMCP||!r.customMCP.tools)throw new Error("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177");let s=r.customMCP.tools.findIndex(o=>o.name===e);if(s===-1)throw new Error(`\u5DE5\u5177 "${e}" \u4E0D\u5B58\u5728`);if(!this.validateCustomMCPTools([t]))throw new Error("\u66F4\u65B0\u540E\u7684\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");r.customMCP.tools[s]=t,this.saveConfig(r),c.debug(`\u6210\u529F\u66F4\u65B0\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177: ${e}`)}updateCustomMCPTools(e){if(!Array.isArray(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u5FC5\u987B\u662F\u6570\u7EC4");if(!this.validateCustomMCPTools(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let t=this.getMutableConfig();t.customMCP||(t.customMCP={tools:[]}),t.customMCP.tools=e,this.saveConfig(t),this.eventBus.emitEvent("config:updated",{type:"customMCP",timestamp:new Date}),c.debug(`\u6210\u529F\u66F4\u65B0\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177\u914D\u7F6E\uFF0C\u5171 ${e.length} \u4E2A\u5DE5\u5177`)}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})}updatePlatformConfig(e,t){let r=this.getMutableConfig();r.platforms||(r.platforms={}),r.platforms[e]=t,this.saveConfig(r)}getCozePlatformConfig(){let t=this.getConfig().platforms?.coze;return!t||!t.token?null:{token:t.token}}getCozeToken(){return this.getCozePlatformConfig()?.token||null}setCozePlatformConfig(e){if(!e.token||typeof e.token!="string"||e.token.trim()==="")throw new Error("\u6263\u5B50 API Token \u4E0D\u80FD\u4E3A\u7A7A");this.updatePlatformConfig("coze",{token:e.token.trim()})}isCozeConfigValid(){let e=this.getCozePlatformConfig();return e!==null&&typeof e.token=="string"&&e.token.trim()!==""}async _updateMCPServerToolStats(e,t,r,s=!0){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:!0});let n=o.mcpServerConfig[e].tools[t],a=n.usageCount||0,g=n.lastUsedTime;s&&(n.usageCount=a+1),(!g||new Date(r)>new Date(g))&&(n.lastUsedTime=ye(r).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(o)}async updateCustomMCPToolStats(e,t,r){try{let s,o,n=!0,a;if(typeof r=="string"){let y=e;s=`${y}__${t}`,o=r,a=`${y}/${t}`}else s=e,o=t,n=r||!0,a=s;let g=this.getCustomMCPTools(),u=g.findIndex(y=>y.name===s);if(u===-1)return;let p=[...g],h=p[u];h.stats||(h.stats={});let T=h.stats.usageCount||0,S=h.stats.lastUsedTime;n&&(h.stats.usageCount=T+1),(!S||new Date(o)>new Date(S))&&(h.stats.lastUsedTime=ye(o).format("YYYY-MM-DD HH:mm:ss")),await this.updateCustomMCPTools(p)}catch(s){if(typeof r=="string"){let o=e,n=t;c.error(`\u66F4\u65B0 customMCP \u5DE5\u5177\u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25 (${o}/${n}): ${s instanceof Error?s.message:String(s)}`)}else{let o=e;c.error(`\u66F4\u65B0 customMCP \u5DE5\u5177\u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25 (${o}): ${s instanceof Error?s.message:String(s)}`)}}}async acquireStatsUpdateLock(e){if(this.statsUpdateLocks.has(e))return c.debug(`\u5DE5\u5177 ${e} \u7684\u7EDF\u8BA1\u66F4\u65B0\u6B63\u5728\u8FDB\u884C\u4E2D\uFF0C\u8DF3\u8FC7\u672C\u6B21\u66F4\u65B0`),!1;let t=new Promise(s=>{});this.statsUpdateLocks.set(e,t);let r=setTimeout(()=>{this.releaseStatsUpdateLock(e)},this.STATS_UPDATE_TIMEOUT);return this.statsUpdateLockTimeouts.set(e,r),!0}releaseStatsUpdateLock(e){this.statsUpdateLocks.delete(e);let t=this.statsUpdateLockTimeouts.get(e);t&&(clearTimeout(t),this.statsUpdateLockTimeouts.delete(e)),c.debug(`\u5DF2\u91CA\u653E\u5DE5\u5177 ${e} \u7684\u7EDF\u8BA1\u66F4\u65B0\u9501`)}async updateToolUsageStatsWithLock(e,t=!0){let r=`custommcp_${e}`;if(await this.acquireStatsUpdateLock(r))try{await this.updateToolUsageStats(e,t),c.debug(`\u5DE5\u5177 ${e} \u7EDF\u8BA1\u66F4\u65B0\u5B8C\u6210`)}catch(s){throw c.error(`\u5DE5\u5177 ${e} \u7EDF\u8BA1\u66F4\u65B0\u5931\u8D25:`,s),s}finally{this.releaseStatsUpdateLock(r)}}async updateMCPServerToolStatsWithLock(e,t,r,s=!0){let o=`mcpserver_${e}_${t}`;if(await this.acquireStatsUpdateLock(o))try{await this.updateMCPServerToolStats(e,t,r,s),c.debug(`MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u7EDF\u8BA1\u66F4\u65B0\u5B8C\u6210`)}catch(n){throw c.error(`MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u7EDF\u8BA1\u66F4\u65B0\u5931\u8D25:`,n),n}finally{this.releaseStatsUpdateLock(o)}}clearAllStatsUpdateLocks(){let e=this.statsUpdateLocks.size;this.statsUpdateLocks.clear();for(let t of this.statsUpdateLockTimeouts.values())clearTimeout(t);this.statsUpdateLockTimeouts.clear(),e>0&&c.info(`\u5DF2\u6E05\u7406 ${e} \u4E2A\u7EDF\u8BA1\u66F4\u65B0\u9501`)}getStatsUpdateLocks(){return Array.from(this.statsUpdateLocks.keys())}getToolCallLogConfig(){return this.getConfig().toolCallLog||{}}updateToolCallLogConfig(e){let t=this.getMutableConfig();t.toolCallLog||(t.toolCallLog={}),Object.assign(t.toolCallLog,e),this.saveConfig(t)}getConfigDir(){return process.env.XIAOZHI_CONFIG_DIR||process.cwd()}},f=me.getInstance();import{createHash as Xe}from"crypto";function w(i,e){let t=Xe("md5").update(JSON.stringify(e||{})).digest("hex");return`${i}_${t}`}l(w,"generateCacheKey");function D(i,e){let t=new Date(i).getTime();return Date.now()-t>e}l(D,"isCacheExpired");function x(i){let e=Date.now(),t=new Date(i.timestamp).getTime();return!!(i.consumed&&e-t>6e4||e-t>i.ttl||i.status==="failed")}l(x,"shouldCleanupCache");var E={TIMEOUT:8e3,CACHE_TTL:3e5,CLEANUP_INTERVAL:6e4,MAX_CACHE_SIZE:1e3,ENABLE_ONE_TIME_CACHE:!0};var q=class{static{l(this,"CacheLifecycleManager")}logger;cleanupInterval;statistics;lastCleanupTime;constructor(e){this.logger=e,this.statistics=this.initializeStatistics(),this.lastCleanupTime=new Date().toISOString()}initializeStatistics(){return{totalEntries:0,pendingTasks:0,completedTasks:0,failedTasks:0,consumedEntries:0,cacheHitRate:0,lastCleanupTime:new Date().toISOString(),memoryUsage:0}}startAutoCleanup(){if(this.cleanupInterval){this.logger.warn("[CacheLifecycle] \u81EA\u52A8\u6E05\u7406\u5B9A\u65F6\u5668\u5DF2\u7ECF\u5728\u8FD0\u884C");return}this.cleanupInterval=setInterval(()=>{this.performCleanup().catch(e=>{this.logger.error(`[CacheLifecycle] \u81EA\u52A8\u6E05\u7406\u5931\u8D25: ${e}`)})},E.CLEANUP_INTERVAL),this.logger.debug(`[CacheLifecycle] \u542F\u52A8\u81EA\u52A8\u6E05\u7406\u5B9A\u65F6\u5668\uFF0C\u95F4\u9694: ${E.CLEANUP_INTERVAL}ms`)}stopAutoCleanup(){this.cleanupInterval&&(clearInterval(this.cleanupInterval),this.cleanupInterval=void 0,this.logger.info("[CacheLifecycle] \u505C\u6B62\u81EA\u52A8\u6E05\u7406\u5B9A\u65F6\u5668"))}createCacheEntry(e,t,r,s="pending",o){let n={result:r,timestamp:new Date().toISOString(),ttl:E.CACHE_TTL,status:s,consumed:!1,taskId:o,retryCount:0};return this.logger.debug(`[CacheLifecycle] \u521B\u5EFA\u7F13\u5B58\u6761\u76EE: ${e}, \u72B6\u6001: ${s}`),n}updateCacheStatus(e,t,r,s,o){if(!e.customMCPResults||!e.customMCPResults[t])return this.logger.warn(`[CacheLifecycle] \u7F13\u5B58\u6761\u76EE\u4E0D\u5B58\u5728: ${t}`),!1;let n=e.customMCPResults[t],a=n.status;return this.logStateTransition(t,a,r),n.status=r,n.timestamp=new Date().toISOString(),s&&(n.result=s),o&&r==="failed"&&(n.result={content:[{type:"text",text:`\u4EFB\u52A1\u5931\u8D25: ${o}`}]},n.consumed=!0),r==="completed"&&(n.consumed=!1),this.logger.debug(`[CacheLifecycle] \u66F4\u65B0\u7F13\u5B58\u72B6\u6001: ${t} ${a} -> ${r}`),!0}markAsConsumed(e,t){if(!e.customMCPResults||!e.customMCPResults[t])return!1;let r=e.customMCPResults[t];return r.consumed?(this.logger.debug(`[CacheLifecycle] \u7F13\u5B58\u5DF2\u6807\u8BB0\u4E3A\u6D88\u8D39: ${t}`),!0):(r.consumed=!0,r.timestamp=new Date().toISOString(),this.logStateTransition(t,r.status,"consumed"),this.logger.debug(`[CacheLifecycle] \u6807\u8BB0\u7F13\u5B58\u4E3A\u5DF2\u6D88\u8D39: ${t}`),!0)}isCacheAvailable(e,t){if(!e.customMCPResults||!e.customMCPResults[t])return!1;let r=e.customMCPResults[t];return D(r.timestamp,r.ttl)?(this.logger.debug(`[CacheLifecycle] \u7F13\u5B58\u5DF2\u8FC7\u671F: ${t}`),!1):r.consumed?(this.logger.debug(`[CacheLifecycle] \u7F13\u5B58\u5DF2\u6D88\u8D39: ${t}`),!1):r.status!=="completed"?(this.logger.debug(`[CacheLifecycle] \u7F13\u5B58\u72B6\u6001\u672A\u5B8C\u6210: ${t}, \u72B6\u6001: ${r.status}`),!1):!0}async performCleanup(){try{this.logger.debug("[CacheLifecycle] \u6267\u884C\u7F13\u5B58\u6E05\u7406"),this.lastCleanupTime=new Date().toISOString()}catch(e){throw this.logger.error(`[CacheLifecycle] \u6E05\u7406\u5931\u8D25: ${e}`),e}}cleanupCacheEntries(e,t){if(!e.customMCPResults)return{cleaned:0,total:0};let r=Object.entries(e.customMCPResults),s=0,o=t||r.map(([n])=>n);for(let n of o){let a=e.customMCPResults[n];a&&x(a)&&(delete e.customMCPResults[n],s++,this.logger.debug(`[CacheLifecycle] \u6E05\u7406\u7F13\u5B58\u6761\u76EE: ${n}`))}return this.logger.info(`[CacheLifecycle] \u6E05\u7406\u5B8C\u6210: ${s}/${o.length}`),{cleaned:s,total:o.length}}cleanupExpiredCache(e){if(!e.customMCPResults)return{cleaned:0,total:0};let t=Object.entries(e.customMCPResults),r=0;for(let[s,o]of t)D(o.timestamp,o.ttl)&&(delete e.customMCPResults[s],r++,this.logger.debug(`[CacheLifecycle] \u6E05\u7406\u8FC7\u671F\u7F13\u5B58: ${s}`));return r>0&&this.logger.info(`[CacheLifecycle] \u6E05\u7406\u8FC7\u671F\u7F13\u5B58: ${r}/${t.length}`),{cleaned:r,total:t.length}}cleanupConsumedCache(e){if(!e.customMCPResults)return{cleaned:0,total:0};let t=Object.entries(e.customMCPResults),r=0,s=Date.now();for(let[o,n]of t)if(n.consumed){let a=new Date(n.timestamp).getTime();s-a>6e4&&(delete e.customMCPResults[o],r++,this.logger.debug(`[CacheLifecycle] \u6E05\u7406\u5DF2\u6D88\u8D39\u7F13\u5B58: ${o}`))}return r>0&&this.logger.info(`[CacheLifecycle] \u6E05\u7406\u5DF2\u6D88\u8D39\u7F13\u5B58: ${r}/${t.length}`),{cleaned:r,total:t.length}}updateStatistics(e){if(!e.customMCPResults){this.statistics=this.initializeStatistics();return}let t=Object.values(e.customMCPResults);this.statistics.totalEntries=t.length,this.statistics.pendingTasks=t.filter(o=>o.status==="pending").length,this.statistics.completedTasks=t.filter(o=>o.status==="completed").length,this.statistics.failedTasks=t.filter(o=>o.status==="failed").length,this.statistics.consumedEntries=t.filter(o=>o.consumed).length;let r=this.statistics.completedTasks,s=this.statistics.consumedEntries;this.statistics.cacheHitRate=r>0?s/r*100:0,this.statistics.lastCleanupTime=this.lastCleanupTime,this.statistics.memoryUsage=JSON.stringify(e.customMCPResults).length}getStatistics(){return{...this.statistics}}validateCacheIntegrity(e){let t=[];if(!e.customMCPResults)return{isValid:!0,issues:[]};for(let[r,s]of Object.entries(e.customMCPResults))(!s.timestamp||!s.ttl||!s.status)&&t.push(`\u7F13\u5B58\u6761\u76EE\u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5: ${r}`),Number.isNaN(new Date(s.timestamp).getTime())&&t.push(`\u65E0\u6548\u7684\u65F6\u95F4\u6233\u683C\u5F0F: ${r}`),["pending","completed","failed"].includes(s.status)||t.push(`\u65E0\u6548\u7684\u72B6\u6001\u503C: ${r}, \u72B6\u6001: ${s.status}`),D(s.timestamp,s.ttl)&&t.push(`\u7F13\u5B58\u6761\u76EE\u5DF2\u8FC7\u671F: ${r}`);return{isValid:t.length===0,issues:t}}logStateTransition(e,t,r){let s={from:t,to:r,reason:this.getTransitionReason(t,r),timestamp:new Date().toISOString()};this.logger.debug(`[CacheLifecycle] \u72B6\u6001\u8F6C\u6362: ${e} ${t} -> ${r} (${s.reason})`)}getTransitionReason(e,t){return{"pending->completed":"\u4EFB\u52A1\u6267\u884C\u6210\u529F","pending->failed":"\u4EFB\u52A1\u6267\u884C\u5931\u8D25","completed->consumed":"\u7ED3\u679C\u88AB\u6D88\u8D39","failed->consumed":"\u5931\u8D25\u7ED3\u679C\u88AB\u5904\u7406","consumed->deleted":"\u7F13\u5B58\u88AB\u6E05\u7406"}[`${e}->${t}`]||"\u72B6\u6001\u66F4\u65B0"}cleanup(){this.stopAutoCleanup(),this.logger.info("[CacheLifecycle] \u6E05\u7406\u8D44\u6E90\u5B8C\u6210")}};var Y=class{static{l(this,"TaskStateManager")}logger;activeTasks;taskHistory;constructor(e){this.logger=e,this.activeTasks=new Map,this.taskHistory=[]}generateTaskId(e,t){let r=Date.now(),s=Math.random().toString(36).substring(2,11),o=`${e}_${r}_${s}`;return this.logger.debug(`[TaskState] \u751F\u6210\u4EFB\u52A1ID: ${o}`),o}validateTaskId(e){let r=/^[a-zA-Z0-9_-]+_\d+_[a-zA-Z0-9]+$/.test(e);return r||this.logger.warn(`[TaskState] \u65E0\u6548\u7684\u4EFB\u52A1ID\u683C\u5F0F: ${e}`),r}extractToolName(e){if(!this.validateTaskId(e))return null;let t=e.split("_");if(t.length<3)return null;let r=t.findIndex(o=>/^\d+$/.test(o));return r<=0?null:t.slice(0,r).join("_")}createTask(e,t,r,s="pending"){if(this.activeTasks.has(e))throw new Error(`\u4EFB\u52A1\u5DF2\u5B58\u5728: ${e}`);let o={taskId:e,toolName:t,arguments:r,status:s,startTime:new Date().toISOString()};return this.activeTasks.set(e,o),this.recordStateTransition(e,"none",s,"\u521B\u5EFA\u65B0\u4EFB\u52A1"),this.logger.info(`[TaskState] \u521B\u5EFA\u4EFB\u52A1: ${e}, \u5DE5\u5177: ${t}, \u72B6\u6001: ${s}`),o}updateTaskStatus(e,t,r,s){let o=this.activeTasks.get(e);if(!o)return this.logger.warn(`[TaskState] \u4EFB\u52A1\u4E0D\u5B58\u5728: ${e}`),!1;let n=o.status;return o.status=t,(t==="completed"||t==="failed")&&(o.endTime=new Date().toISOString()),r&&(o.result=r),s&&(o.error=s),this.recordStateTransition(e,n,t,this.getStatusChangeReason(n,t,s)),this.logger.info(`[TaskState] \u66F4\u65B0\u4EFB\u52A1\u72B6\u6001: ${e} ${n} -> ${t}`),!0}markTaskAsPending(e,t,r){let s=this.activeTasks.get(e);return s?this.updateTaskStatus(e,"pending"):s=this.createTask(e,t,r,"pending"),s}markTaskAsCompleted(e,t){return this.updateTaskStatus(e,"completed",t)}markTaskAsFailed(e,t){return this.updateTaskStatus(e,"failed",void 0,t)}markTaskAsConsumed(e){return this.updateTaskStatus(e,"consumed")}getTask(e){return this.activeTasks.get(e)||null}hasTask(e){return this.activeTasks.has(e)}getTaskStatus(e){let t=this.activeTasks.get(e);return t?t.status:null}getTasksByStatus(e){return Array.from(this.activeTasks.values()).filter(t=>t.status===e)}getTasksByTool(e){return Array.from(this.activeTasks.values()).filter(t=>t.toolName===e)}getTaskExecutionTime(e){let t=this.activeTasks.get(e);if(!t||!t.endTime)return null;let r=new Date(t.startTime).getTime();return new Date(t.endTime).getTime()-r}isTaskTimeout(e,t=8e3){let r=this.activeTasks.get(e);if(!r)return!1;let s=new Date(r.startTime).getTime();return Date.now()-s>t}getTimeoutTasks(e=8e3){let t=Date.now();return Array.from(this.activeTasks.values()).filter(r=>{let s=new Date(r.startTime).getTime();return t-s>e&&r.status==="pending"})}removeTask(e){let t=this.activeTasks.get(e);return t?(this.recordStateTransition(e,t.status,"deleted","\u4EFB\u52A1\u88AB\u79FB\u9664"),this.activeTasks.delete(e),this.logger.info(`[TaskState] \u79FB\u9664\u4EFB\u52A1: ${e}`),!0):!1}cleanupCompletedTasks(e=3e5){let t=Date.now(),r=0;for(let[s,o]of this.activeTasks.entries())if(o.status==="completed"||o.status==="failed"){let n=o.endTime?new Date(o.endTime).getTime():t;t-n>e&&(this.removeTask(s),r++)}return r>0&&this.logger.info(`[TaskState] \u6E05\u7406\u5DF2\u5B8C\u6210\u4EFB\u52A1: ${r}\u4E2A`),r}getTaskStatistics(){let e=Array.from(this.activeTasks.values()),t=e.length,r=e.filter(u=>u.status==="pending").length,s=e.filter(u=>u.status==="completed").length,o=e.filter(u=>u.status==="failed").length,n=e.filter(u=>u.status==="consumed").length,a=e.filter(u=>u.status==="completed"&&u.endTime),g=a.length>0?a.reduce((u,p)=>{let h=this.getTaskExecutionTime(p.taskId)||0;return u+h},0)/a.length:0;return{total:t,pending:r,completed:s,failed:o,consumed:n,averageExecutionTime:g}}getTaskHistory(e){return e?this.taskHistory.filter(t=>t.taskId===e):[...this.taskHistory]}recordStateTransition(e,t,r,s){let o={from:t,to:r,reason:s,timestamp:new Date().toISOString(),taskId:e};this.taskHistory.push(o),this.taskHistory.length>1e3&&(this.taskHistory=this.taskHistory.slice(-500))}getStatusChangeReason(e,t,r){if(r)return`\u6267\u884C\u5931\u8D25: ${r}`;let s={"none->pending":"\u4EFB\u52A1\u5F00\u59CB\u6267\u884C","pending->completed":"\u4EFB\u52A1\u6267\u884C\u6210\u529F","pending->failed":"\u4EFB\u52A1\u6267\u884C\u5931\u8D25","completed->consumed":"\u7ED3\u679C\u88AB\u6D88\u8D39","failed->consumed":"\u5931\u8D25\u7ED3\u679C\u88AB\u5904\u7406","consumed->deleted":"\u4EFB\u52A1\u88AB\u6E05\u7406"},o=`${e}->${t}`;return s[o]||"\u72B6\u6001\u66F4\u65B0"}validateTaskIntegrity(){let e=[];for(let[t,r]of this.activeTasks.entries())(!r.taskId||!r.toolName||!r.status||!r.startTime)&&e.push(`\u4EFB\u52A1\u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5: ${t}`),Number.isNaN(new Date(r.startTime).getTime())&&e.push(`\u65E0\u6548\u7684\u5F00\u59CB\u65F6\u95F4: ${t}`),r.endTime&&Number.isNaN(new Date(r.endTime).getTime())&&e.push(`\u65E0\u6548\u7684\u7ED3\u675F\u65F6\u95F4: ${t}`),r.status==="completed"&&!r.endTime&&e.push(`\u5DF2\u5B8C\u6210\u4EFB\u52A1\u7F3A\u5C11\u7ED3\u675F\u65F6\u95F4: ${t}`),r.status==="failed"&&!r.error&&e.push(`\u5931\u8D25\u4EFB\u52A1\u7F3A\u5C11\u9519\u8BEF\u4FE1\u606F: ${t}`);return{isValid:e.length===0,issues:e}}restartStalledTasks(e=3e4){let t=this.getTimeoutTasks(e),r=0;for(let s of t){this.logger.warn(`[TaskState] \u68C0\u6D4B\u5230\u505C\u6EDE\u4EFB\u52A1: ${s.taskId}`),this.markTaskAsFailed(s.taskId,"\u4EFB\u52A1\u6267\u884C\u8D85\u65F6");let o=this.generateTaskId(s.toolName,s.arguments);this.createTask(o,s.toolName,s.arguments,"pending"),r++}return r>0&&this.logger.info(`[TaskState] \u91CD\u542F\u505C\u6EDE\u4EFB\u52A1: ${r}\u4E2A`),r}cleanup(){this.activeTasks.clear(),this.taskHistory=[],this.logger.info("[TaskState] \u6E05\u7406\u4EFB\u52A1\u72B6\u6001\u7BA1\u7406\u5668\u8D44\u6E90")}};var W=class i extends Error{static{l(this,"TimeoutError")}name="TimeoutError";constructor(e){super(e),this.name="TimeoutError",Error.captureStackTrace(this,i)}toJSON(){return{name:this.name,message:this.message,stack:this.stack}}};function Ee(i,e){return{content:[{type:"text",text:e?Ze(e,i):Re(i)}],isError:!1,taskId:i,status:"timeout",message:"\u5DE5\u5177\u8C03\u7528\u8D85\u65F6\uFF0C\u6B63\u5728\u540E\u53F0\u5904\u7406\u4E2D",nextAction:"\u8BF7\u7A0D\u540E\u91CD\u8BD5\u6216\u7B49\u5F85\u4EFB\u52A1\u5B8C\u6210"}}l(Ee,"createTimeoutResponse");function Ze(i,e){let t={coze_workflow:`\u23F1\uFE0F \u6263\u5B50\u5DE5\u4F5C\u6D41\u6267\u884C\u8D85\u65F6\uFF0C\u6B63\u5728\u540E\u53F0\u5904\u7406\u4E2D...
4
4
 
5
5
  \u{1F4CB} \u4EFB\u52A1\u4FE1\u606F\uFF1A
6
6
  - \u4EFB\u52A1ID: ${e}
@@ -11,7 +11,7 @@ var We=Object.defineProperty;var l=(i,e)=>We(i,"name",{value:e,configurable:!0})
11
11
  \u{1F504} \u540E\u7EED\u64CD\u4F5C\uFF1A
12
12
  1. \u4F7F\u7528\u76F8\u540C\u53C2\u6570\u91CD\u65B0\u8C03\u7528\u5DE5\u5177
13
13
  2. \u7CFB\u7EDF\u4F1A\u81EA\u52A8\u8FD4\u56DE\u5DF2\u5B8C\u6210\u7684\u4EFB\u52A1\u7ED3\u679C
14
- 3. \u590D\u6742\u5DE5\u4F5C\u6D41\u53EF\u80FD\u9700\u8981\u66F4\u957F\u65F6\u95F4\u5904\u7406`,default:Ie(e)};return t[i]||t.default}l(nt,"getToolSpecificTimeoutMessage");function Ie(i){return`\u23F1\uFE0F \u5DE5\u5177\u8C03\u7528\u8D85\u65F6\uFF0C\u6B63\u5728\u540E\u53F0\u5904\u7406\u4E2D...
14
+ 3. \u590D\u6742\u5DE5\u4F5C\u6D41\u53EF\u80FD\u9700\u8981\u66F4\u957F\u65F6\u95F4\u5904\u7406`,default:Re(e)};return t[i]||t.default}l(Ze,"getToolSpecificTimeoutMessage");function Re(i){return`\u23F1\uFE0F \u5DE5\u5177\u8C03\u7528\u8D85\u65F6\uFF0C\u6B63\u5728\u540E\u53F0\u5904\u7406\u4E2D...
15
15
 
16
16
  \u{1F4CB} \u4EFB\u52A1\u4FE1\u606F\uFF1A
17
17
  - \u4EFB\u52A1ID: ${i}
@@ -21,17 +21,17 @@ var We=Object.defineProperty;var l=(i,e)=>We(i,"name",{value:e,configurable:!0})
21
21
  \u{1F504} \u540E\u7EED\u64CD\u4F5C\uFF1A
22
22
  1. \u4F7F\u7528\u76F8\u540C\u7684\u53C2\u6570\u91CD\u65B0\u8C03\u7528\u5DE5\u5177
23
23
  2. \u7CFB\u7EDF\u4F1A\u81EA\u52A8\u8FD4\u56DE\u5DF2\u5B8C\u6210\u7684\u4EFB\u52A1\u7ED3\u679C
24
- 3. \u5982\u679C\u957F\u65F6\u95F4\u672A\u5B8C\u6210\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458`}l(Ie,"getDefaultTimeoutMessage");import{createHash as st}from"crypto";import{existsSync as W,mkdirSync as ot,readFileSync as ke,renameSync as it,writeFileSync as Le}from"fs";import{dirname as at,resolve as Oe}from"path";import ct from"dayjs";var N=class{static{l(this,"MCPCacheManager")}cachePath;logger;CACHE_VERSION="1.0.0";CACHE_ENTRY_VERSION="1.0.0";cleanupInterval;CLEANUP_INTERVAL=6e4;constructor(e){this.logger=c,this.cachePath=e||this.getCacheFilePath(),this.startCleanupTimer()}formatTimestamp(){return ct().format("YYYY-MM-DD HH:mm:ss")}getCacheFilePath(){try{let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return Oe(e,"xiaozhi.cache.json")}catch{let t=process.env.XIAOZHI_CONFIG_DIR||"/tmp";return Oe(t,"xiaozhi.cache.json")}}async ensureCacheFile(){try{if(!W(this.cachePath)){let e=at(this.cachePath);W(e)||(ot(e,{recursive:!0}),this.logger.debug(`[CacheManager] \u5DF2\u521B\u5EFA\u7F13\u5B58\u76EE\u5F55: ${e}`)),this.logger.debug("[CacheManager] \u7F13\u5B58\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u521B\u5EFA\u521D\u59CB\u7F13\u5B58\u6587\u4EF6");let t=await this.createInitialCache();await this.saveCache(t),this.logger.info(`[CacheManager] \u5DF2\u521B\u5EFA\u7F13\u5B58\u6587\u4EF6: ${this.cachePath}`)}}catch(e){this.logger.warn(`[CacheManager] \u521B\u5EFA\u7F13\u5B58\u6587\u4EF6\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}async createInitialCache(){let e=this.formatTimestamp();return{version:this.CACHE_VERSION,mcpServers:{},metadata:{lastGlobalUpdate:e,totalWrites:0,createdAt:e}}}async writeCacheEntry(e,t,r){try{this.logger.debug(`[CacheManager] \u5F00\u59CB\u5199\u5165\u7F13\u5B58: ${e}`),await this.ensureCacheFile();let n=await this.loadExistingCache(),s=this.generateConfigHash(r),o={tools:t.map(a=>({name:a.name,description:a.description||"",inputSchema:a.inputSchema})),lastUpdated:this.formatTimestamp(),serverConfig:{...r},configHash:s,version:this.CACHE_ENTRY_VERSION};n.mcpServers[e]=o,n.metadata.lastGlobalUpdate=this.formatTimestamp(),n.metadata.totalWrites+=1,await this.saveCache(n),this.logger.debug(`[CacheManager] \u7F13\u5B58\u5199\u5165\u6210\u529F: ${e}, \u5DE5\u5177\u6570\u91CF: ${t.length}`)}catch(n){this.logger.warn(`[CacheManager] \u7F13\u5B58\u5199\u5165\u5931\u8D25: ${e}, \u9519\u8BEF: ${n instanceof Error?n.message:String(n)}`)}}async loadExistingCache(){try{if(!W(this.cachePath))return await this.createInitialCache();let e=ke(this.cachePath,"utf8"),t=JSON.parse(e);return this.validateCacheStructure(t)?t:(this.logger.warn("[CacheManager] \u7F13\u5B58\u6587\u4EF6\u7ED3\u6784\u65E0\u6548\uFF0C\u91CD\u65B0\u521B\u5EFA"),await this.createInitialCache())}catch(e){return this.logger.warn(`[CacheManager] \u52A0\u8F7D\u7F13\u5B58\u5931\u8D25\uFF0C\u521B\u5EFA\u65B0\u7F13\u5B58: ${e instanceof Error?e.message:String(e)}`),await this.createInitialCache()}}async saveCache(e){let t=JSON.stringify(e,null,2);await this.atomicWrite(this.cachePath,t)}async atomicWrite(e,t){let r=`${e}.tmp`;try{Le(r,t,"utf8"),it(r,e)}catch(n){try{W(r)&&Le(r,"","utf8")}catch{}throw n}}generateConfigHash(e){try{return st("sha256").update(JSON.stringify(e)).digest("hex")}catch(t){return this.logger.warn(`[CacheManager] \u751F\u6210\u914D\u7F6E\u54C8\u5E0C\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`),""}}validateCacheStructure(e){try{return e&&typeof e=="object"&&typeof e.version=="string"&&typeof e.mcpServers=="object"&&e.metadata&&typeof e.metadata=="object"&&typeof e.metadata.lastGlobalUpdate=="string"&&typeof e.metadata.totalWrites=="number"&&typeof e.metadata.createdAt=="string"}catch{return!1}}async getStats(){try{let e=await this.loadExistingCache();return{totalWrites:e.metadata.totalWrites,lastUpdate:e.metadata.lastGlobalUpdate,serverCount:Object.keys(e.mcpServers).length,cacheFileSize:W(this.cachePath)?ke(this.cachePath,"utf8").length:0}}catch(e){return this.logger.warn(`[CacheManager] \u83B7\u53D6\u7F13\u5B58\u7EDF\u8BA1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),null}}getFilePath(){return this.cachePath}async getAllCachedTools(){try{let e=await this.loadExistingCache(),t=[];for(let[r,n]of Object.entries(e.mcpServers))for(let s of n.tools)t.push({...s,name:`${r}__${s.name}`});return this.logger.debug(`[CacheManager] \u83B7\u53D6\u5230\u6240\u6709\u7F13\u5B58\u5DE5\u5177\uFF0C\u5171 ${t.length} \u4E2A`),t}catch(e){return this.logger.warn(`[CacheManager] \u83B7\u53D6\u6240\u6709\u7F13\u5B58\u5DE5\u5177\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),[]}}async writeCustomMCPResult(e,t,r,n="completed",s,o=3e5){try{let a=await this.loadExtendedCache(),g=R(e,t),u={result:r,timestamp:new Date().toISOString(),ttl:o,status:n,consumed:!1,taskId:s,retryCount:0};a.customMCPResults||(a.customMCPResults={}),a.customMCPResults[g]=u,await this.saveExtendedCache(a),this.logger.debug(`[CacheManager] \u5199\u5165CustomMCP\u7ED3\u679C\u7F13\u5B58: ${e}, \u72B6\u6001: ${n}`)}catch(a){this.logger.warn(`[CacheManager] \u5199\u5165CustomMCP\u7ED3\u679C\u7F13\u5B58\u5931\u8D25: ${a instanceof Error?a.message:String(a)}`)}}async readCustomMCPResult(e,t){try{let r=await this.loadExtendedCache(),n=R(e,t);if(!r.customMCPResults||!r.customMCPResults[n])return null;let s=r.customMCPResults[n],o=Date.now(),a=new Date(s.timestamp).getTime();return o-a>s.ttl?(this.logger.debug(`[CacheManager] \u7F13\u5B58\u5DF2\u8FC7\u671F: ${e}`),null):s}catch(r){return this.logger.warn(`[CacheManager] \u8BFB\u53D6CustomMCP\u7ED3\u679C\u7F13\u5B58\u5931\u8D25: ${r instanceof Error?r.message:String(r)}`),null}}async updateCustomMCPStatus(e,t,r,n,s){try{let o=await this.loadExtendedCache(),a=R(e,t);if(!o.customMCPResults||!o.customMCPResults[a])return!1;let g=o.customMCPResults[a],u=g.status;return g.status=r,g.timestamp=new Date().toISOString(),n&&(g.result=n),s&&r==="failed"&&(g.result={content:[{type:"text",text:`\u4EFB\u52A1\u5931\u8D25: ${s}`}]},g.consumed=!0),r==="completed"&&(g.consumed=!1),await this.saveExtendedCache(o),this.logger.debug(`[CacheManager] \u66F4\u65B0\u7F13\u5B58\u72B6\u6001: ${e} ${u} -> ${r}`),!0}catch(o){return this.logger.warn(`[CacheManager] \u66F4\u65B0CustomMCP\u7F13\u5B58\u72B6\u6001\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`),!1}}async markCustomMCPAsConsumed(e,t){try{let r=await this.loadExtendedCache(),n=R(e,t);if(!r.customMCPResults||!r.customMCPResults[n])return!1;let s=r.customMCPResults[n];return s.consumed||(s.consumed=!0,s.timestamp=new Date().toISOString(),await this.saveExtendedCache(r),this.logger.debug(`[CacheManager] \u6807\u8BB0\u7F13\u5B58\u4E3A\u5DF2\u6D88\u8D39: ${e}`)),!0}catch(r){return this.logger.warn(`[CacheManager] \u6807\u8BB0CustomMCP\u7F13\u5B58\u4E3A\u5DF2\u6D88\u8D39\u5931\u8D25: ${r instanceof Error?r.message:String(r)}`),!1}}async deleteCustomMCPResult(e,t){try{let r=await this.loadExtendedCache(),n=R(e,t);return!r.customMCPResults||!r.customMCPResults[n]?!1:(delete r.customMCPResults[n],await this.saveExtendedCache(r),this.logger.debug(`[CacheManager] \u5220\u9664\u7F13\u5B58\u6761\u76EE: ${e}`),!0)}catch(r){return this.logger.warn(`[CacheManager] \u5220\u9664CustomMCP\u7F13\u5B58\u6761\u76EE\u5931\u8D25: ${r instanceof Error?r.message:String(r)}`),!1}}async cleanupCustomMCPResults(){try{let e=await this.loadExtendedCache();if(!e.customMCPResults)return{cleaned:0,total:0};let t=Object.entries(e.customMCPResults),r=0;for(let[n,s]of t)O(s)&&(delete e.customMCPResults[n],r++);return r>0&&(await this.saveExtendedCache(e),this.logger.info(`[CacheManager] \u6E05\u7406CustomMCP\u7F13\u5B58: ${r}/${t.length}`)),{cleaned:r,total:t.length}}catch(e){return this.logger.warn(`[CacheManager] \u6E05\u7406CustomMCP\u7F13\u5B58\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),{cleaned:0,total:0}}}async getCustomMCPStatistics(){try{let e=await this.loadExtendedCache();if(!e.customMCPResults)return{totalEntries:0,pendingTasks:0,completedTasks:0,failedTasks:0,consumedEntries:0,cacheHitRate:0,lastCleanupTime:new Date().toISOString(),memoryUsage:0};let t=Object.values(e.customMCPResults),r=t.length,n=t.filter(p=>p.status==="pending").length,s=t.filter(p=>p.status==="completed").length,o=t.filter(p=>p.status==="failed").length,a=t.filter(p=>p.consumed).length,g=s>0?a/s*100:0,u=JSON.stringify(e.customMCPResults).length;return{totalEntries:r,pendingTasks:n,completedTasks:s,failedTasks:o,consumedEntries:a,cacheHitRate:g,lastCleanupTime:new Date().toISOString(),memoryUsage:u}}catch(e){return this.logger.warn(`[CacheManager] \u83B7\u53D6CustomMCP\u7F13\u5B58\u7EDF\u8BA1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),{totalEntries:0,pendingTasks:0,completedTasks:0,failedTasks:0,consumedEntries:0,cacheHitRate:0,lastCleanupTime:new Date().toISOString(),memoryUsage:0}}}async loadExtendedCache(){try{return await this.loadExistingCache()}catch(e){return this.logger.warn(`[CacheManager] \u52A0\u8F7D\u6269\u5C55\u7F13\u5B58\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),{version:this.CACHE_VERSION,mcpServers:{},metadata:{lastGlobalUpdate:this.formatTimestamp(),totalWrites:0,createdAt:this.formatTimestamp()},customMCPResults:{}}}}async saveExtendedCache(e){await this.saveCache(e)}startCleanupTimer(){this.cleanupInterval=setInterval(()=>{this.cleanupCustomMCPResults().catch(e=>{this.logger.warn(`[CacheManager] \u81EA\u52A8\u6E05\u7406\u5931\u8D25: ${e}`)})},this.CLEANUP_INTERVAL),this.logger.debug(`[CacheManager] \u542F\u52A8\u6E05\u7406\u5B9A\u65F6\u5668\uFF0C\u95F4\u9694: ${this.CLEANUP_INTERVAL}ms`)}stopCleanupTimer(){this.cleanupInterval&&(clearInterval(this.cleanupInterval),this.cleanupInterval=void 0,this.logger.debug("[CacheManager] \u505C\u6B62\u6E05\u7406\u5B9A\u65F6\u5668"))}cleanup(){this.stopCleanupTimer(),this.logger.debug("[CacheManager] \u6E05\u7406\u8D44\u6E90\u5B8C\u6210")}};var Y=class{static{l(this,"CustomMCPHandler")}logger;tools=new Map;cacheManager;cacheLifecycleManager;taskStateManager;mcpServiceManager;TIMEOUT=$.TIMEOUT;CACHE_TTL=$.CACHE_TTL;CLEANUP_INTERVAL=$.CLEANUP_INTERVAL;cleanupTimer;activeTasks=new Map;eventBus=b();constructor(e,t){this.logger=c,this.cacheManager=e||new N,this.mcpServiceManager=t,this.cacheLifecycleManager=new J(this.logger),this.taskStateManager=new q(this.logger),this.startCleanupTimer(),this.cacheLifecycleManager.startAutoCleanup(),this.setupEventListeners()}setupEventListeners(){this.eventBus.onEvent("config:updated",async e=>{await this.handleConfigUpdated(e)})}async handleConfigUpdated(e){this.logger.debug("[CustomMCP] \u68C0\u6D4B\u5230\u914D\u7F6E\u66F4\u65B0\uFF0C\u68C0\u67E5\u662F\u5426\u9700\u8981\u91CD\u65B0\u521D\u59CB\u5316");try{e.type==="customMCP"?(this.logger.debug("[CustomMCP] customMCP \u914D\u7F6E\u5DF2\u66F4\u65B0\uFF0C\u91CD\u65B0\u521D\u59CB\u5316\u5904\u7406\u5668"),await this.reinitialize()):e.type==="serverTools"&&(this.logger.debug("[CustomMCP] serverTools \u914D\u7F6E\u5DF2\u66F4\u65B0\uFF0C\u91CD\u65B0\u521D\u59CB\u5316\u5904\u7406\u5668"),await this.reinitialize())}catch(t){this.logger.error("[CustomMCP] \u914D\u7F6E\u66F4\u65B0\u5904\u7406\u5931\u8D25:",t)}}async reinitialize(){try{this.logger.debug("[CustomMCP] \u5F00\u59CB\u91CD\u65B0\u521D\u59CB\u5316\u5904\u7406\u5668"),this.tools.clear();let e=f.getCustomMCPTools();for(let t of e)this.tools.set(t.name,t),this.logger.debug(`[CustomMCP] \u91CD\u65B0\u52A0\u8F7D\u5DE5\u5177: ${t.name} (${t.handler.type})`);this.logger.debug(`[CustomMCP] \u91CD\u65B0\u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u5171\u52A0\u8F7D ${this.tools.size} \u4E2A\u5DE5\u5177`)}catch(e){throw this.logger.error("[CustomMCP] \u91CD\u65B0\u521D\u59CB\u5316\u5931\u8D25:",e),e}}initialize(e){this.logger.debug("[CustomMCP] \u521D\u59CB\u5316 CustomMCP \u5904\u7406\u5668...");try{let t=e||f.getCustomMCPTools();this.tools.clear();for(let r of t)this.tools.set(r.name,r),this.logger.debug(`[CustomMCP] \u5DF2\u52A0\u8F7D\u5DE5\u5177: ${r.name} (${r.handler.type})`);this.logger.debug(`[CustomMCP] \u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u5171\u52A0\u8F7D ${this.tools.size} \u4E2A\u5DE5\u5177`)}catch(t){throw this.logger.error("[CustomMCP] \u521D\u59CB\u5316\u5931\u8D25:",t),t}}getTools(){return Array.from(this.tools.values()).map(e=>({name:e.name,description:e.description,inputSchema:e.inputSchema}))}hasTool(e){return this.tools.has(e)}getToolCount(){return this.tools.size}getToolNames(){return Array.from(this.tools.keys())}async callTool(e,t,r){if(!this.tools.get(e))throw new Error(`\u672A\u627E\u5230\u5DE5\u5177: ${e}`);let s=await this.getCompletedResult(e,t);if(s)return this.logger.debug(`[CustomMCP] \u8FD4\u56DE\u5DF2\u5B8C\u6210\u7684\u4EFB\u52A1\u7ED3\u679C: ${e}`),await this.clearConsumedCache(e,t),s;try{let o=await Promise.race([this.executeToolWithBackgroundProcessing(e,t),this.createTimeoutPromise(e,t)]);return await this.cacheResult(e,t,o),o}catch(o){if(o instanceof _){let a=await this.generateTaskId(e,t);return this.logger.info(`[CustomMCP] \u5DE5\u5177\u8D85\u65F6\uFF0C\u8FD4\u56DE\u53CB\u597D\u63D0\u793A: ${e}, taskId: ${a}`),xe(a,e)}throw o}}async executeToolWithBackgroundProcessing(e,t){let r=this.tools.get(e);if(!r)throw new Error(`\u5DE5\u5177\u4E0D\u5B58\u5728: ${e}`);let n=await this.generateTaskId(e,t);await this.markTaskAsPending(n,e,t);try{let s=await this.callToolByType(r,t);return await this.markTaskAsCompleted(n,s),s}catch(s){throw await this.markTaskAsFailed(n,s),s}}async createTimeoutPromise(e,t){return new Promise((r,n)=>{setTimeout(()=>{n(new _(`\u5DE5\u5177\u8C03\u7528\u8D85\u65F6: ${e}`))},this.TIMEOUT)})}async getCompletedResult(e,t){try{let r=this.generateCacheKey(e,t),n=await this.loadExtendedCache();if(!n.customMCPResults||!n.customMCPResults[r])return null;let s=n.customMCPResults[r];return s.status==="completed"&&!s.consumed&&!H(s.timestamp,s.ttl)?s.result:null}catch(r){return this.logger.warn(`[CustomMCP] \u83B7\u53D6\u7F13\u5B58\u5931\u8D25: ${r}`),null}}async callToolByType(e,t){switch(e.handler.type){case"proxy":return await this.callProxyTool(e,t);case"function":return await this.callFunctionTool(e,t);case"http":return await this.callHttpTool(e,t);case"script":return await this.callScriptTool(e,t);case"chain":return await this.callChainTool(e,t);case"mcp":try{return await this.forwardToMCPServiceManager(e,t)}catch(r){this.logger.error(`[CustomMCP] MCP \u7C7B\u578B\u5DE5\u5177\u8DEF\u7531\u5931\u8D25: ${e.name}`,r);let n=r instanceof Error?r.message:"MCP \u7C7B\u578B\u5DE5\u5177\u8DEF\u7531\u9519\u8BEF";return{content:[{type:"text",text:n.includes("MCPServiceManager \u672A\u521D\u59CB\u5316")?n:"\u5185\u90E8\u9519\u8BEF\uFF1AMCP \u7C7B\u578B\u5DE5\u5177\u8DEF\u7531\u9519\u8BEF"}],isError:!0}}default:throw new Error(`\u4E0D\u652F\u6301\u7684\u5904\u7406\u5668\u7C7B\u578B: ${e.handler.type}`)}}async forwardToMCPServiceManager(e,t){if(!this.mcpServiceManager)throw this.logger.error(`[CustomMCP] MCPServiceManager \u672A\u521D\u59CB\u5316\uFF0C\u65E0\u6CD5\u8F6C\u53D1\u5DE5\u5177 ${e.name} \u7684\u8C03\u7528`),new Error("MCPServiceManager \u672A\u521D\u59CB\u5316");let r=e.handler;this.logger.info(`[CustomMCP] \u8F6C\u53D1MCP\u5DE5\u5177\u8C03\u7528: ${e.name}`,{serviceName:r.config.serviceName,toolName:r.config.toolName});try{let n=await this.mcpServiceManager.callTool(r.config.toolName,t);return this.logger.info(`[CustomMCP] MCP\u5DE5\u5177\u8F6C\u53D1\u6210\u529F: ${e.name}`),n}catch(n){return this.logger.error(`[CustomMCP] MCP\u5DE5\u5177\u8F6C\u53D1\u5931\u8D25: ${e.name}`,n),{content:[{type:"text",text:`MCP\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`}],isError:!0}}}async callProxyTool(e,t){let r=e.handler;if(this.logger.info(`[CustomMCP] \u8C03\u7528\u4EE3\u7406\u5DE5\u5177: ${e.name}`,{platform:r.platform,config:r.config}),r.platform==="coze")return await this.callCozeWorkflow(e,t);throw new Error(`\u4E0D\u652F\u6301\u7684\u4EE3\u7406\u5E73\u53F0: ${r.platform}`)}async callCozeWorkflow(e,t){let n=e.handler.config;this.logger.info(`[CustomMCP] \u8C03\u7528 Coze \u5DE5\u4F5C\u6D41: ${e.name}`,{workflow_id:n.workflow_id,bot_id:n.bot_id});try{let s=this.buildCozeRequest(n,t),o=await this.sendCozeRequest(n,s);return this.logger.info(`[CustomMCP] Coze \u5DE5\u4F5C\u6D41\u8C03\u7528\u6210\u529F: ${e.name}`,{response:o}),this.processCozeResponse(e.name,o)}catch(s){return this.logger.error(`[CustomMCP] Coze \u5DE5\u4F5C\u6D41\u8C03\u7528\u5931\u8D25: ${e.name}`,s),{content:[{type:"text",text:`Coze \u5DE5\u4F5C\u6D41\u8C03\u7528\u5931\u8D25: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}}buildCozeRequest(e,t){return{workflow_id:e.workflow_id,parameters:{...t}}}async sendCozeRequest(e,t){let r=e.base_url||"https://api.coze.cn",n="",s=f.getConfig().platforms?.coze?.token;if(!s)throw new Error("Coze Token \u914D\u7F6E\u4E0D\u5B58\u5728");if(e.workflow_id)n="/v1/workflow/run",t.workflow_id=e.workflow_id;else if(e.bot_id)n="/v3/chat",t.bot_id=e.bot_id;else throw new Error("Coze \u914D\u7F6E\u5FC5\u987B\u63D0\u4F9B workflow_id \u6216 bot_id");let o=`${r}${n}`,a=e.timeout||3e5,g={"Content-Type":"application/json",Authorization:`Bearer ${s}`,...e.headers};this.logger.debug(`[CustomMCP] \u53D1\u9001 Coze \u8BF7\u6C42\u5230: ${o}`,{headers:{...g},body:t});let u=new AbortController,p=setTimeout(()=>u.abort(),a);try{let h=await fetch(o,{method:"POST",headers:g,body:JSON.stringify(t)});if(clearTimeout(p),!h.ok){let T=await h.text();throw new Error(`Coze API \u8BF7\u6C42\u5931\u8D25 (${h.status}): ${T}`)}let S=await h.json();return this.logger.debug("[CustomMCP] Coze API \u54CD\u5E94:",S),S}catch(h){throw clearTimeout(p),h instanceof Error&&h.name==="AbortError"?new Error(`Coze API \u8BF7\u6C42\u8D85\u65F6 (${a}ms)`):h}}processCozeResponse(e,t){try{return t.data?{content:[{type:"text",text:t.data}],isError:!1}:{content:[{type:"text",text:JSON.stringify(t,null,2)}],isError:!1}}catch(r){return this.logger.error(`[CustomMCP] \u5904\u7406 Coze \u54CD\u5E94\u5931\u8D25: ${e}`,r),{content:[{type:"text",text:`\u5904\u7406\u54CD\u5E94\u5931\u8D25: ${r instanceof Error?r.message:String(r)}`}],isError:!0}}}async callFunctionTool(e,t){let r=e.handler;this.logger.info(`[CustomMCP] \u8C03\u7528\u51FD\u6570\u5DE5\u5177: ${e.name}`,{module:r.module,function:r.function});try{let n=await this.loadModule(r.module),s=this.getFunction(n,r.function),o=await this.executeFunction(s,t,r);return{content:[{type:"text",text:typeof o=="string"?o:JSON.stringify(o,null,2)}],isError:!1}}catch(n){return this.logger.error(`[CustomMCP] \u51FD\u6570\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,n),{content:[{type:"text",text:`\u51FD\u6570\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`}],isError:!0}}}async loadModule(e){try{let t=e;return!e.startsWith("/")&&!e.startsWith("file://")&&(t=new URL(e,`file://${process.cwd()}/`).href),this.logger.debug(`[CustomMCP] \u52A0\u8F7D\u6A21\u5757: ${t}`),await import(t)}catch(t){throw new Error(`\u65E0\u6CD5\u52A0\u8F7D\u6A21\u5757 ${e}: ${t instanceof Error?t.message:String(t)}`)}}getFunction(e,t){let r;if(e.default&&typeof e.default=="function"&&(t==="default"?r=e.default:e.default[t]&&typeof e.default[t]=="function"&&(r=e.default[t])),!r&&e[t]&&typeof e[t]=="function"&&(r=e[t]),!r)throw new Error(`\u5728\u6A21\u5757\u4E2D\u627E\u4E0D\u5230\u51FD\u6570: ${t}`);return r}async executeFunction(e,t,r){let n=r.timeout||3e4,s={...r.context,logger:this.logger,arguments:t},o=Promise.resolve().then(()=>e.length>1?e(t,s):e(t)),a=new Promise((g,u)=>{setTimeout(()=>u(new Error(`\u51FD\u6570\u6267\u884C\u8D85\u65F6 (${n}ms)`)),n)});return Promise.race([o,a])}async callHttpTool(e,t){let r=e.handler;this.logger.info(`[CustomMCP] \u8C03\u7528 HTTP \u5DE5\u5177: ${e.name}`,{url:r.url,method:r.method||"POST"});try{let{url:n,requestOptions:s}=this.buildHttpRequest(r,t),o=await this.sendHttpRequest(n,s,r);return this.processHttpResponse(e.name,o,r)}catch(n){return this.logger.error(`[CustomMCP] HTTP \u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,n),{content:[{type:"text",text:`HTTP \u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`}],isError:!0}}}buildHttpRequest(e,t){let r=e.method||"POST",n={"Content-Type":"application/json","User-Agent":"xiaozhi-client/1.0",...e.headers};if(e.auth)switch(e.auth.type){case"bearer":e.auth.token&&(n.Authorization=`Bearer ${e.auth.token}`);break;case"basic":if(e.auth.username&&e.auth.password){let g=btoa(`${e.auth.username}:${e.auth.password}`);n.Authorization=`Basic ${g}`}break;case"api_key":e.auth.api_key&&e.auth.api_key_header&&(n[e.auth.api_key_header]=e.auth.api_key);break}let s,o=e.url;if(r!=="GET")e.body_template?s=this.replaceTemplateVariables(e.body_template,t):s=JSON.stringify(t);else{let g=new URLSearchParams;for(let[p,h]of Object.entries(t))h!=null&&g.append(p,String(h));let u=g.toString();u&&(o+=(o.includes("?")?"&":"?")+u)}return{url:o,requestOptions:{method:r,headers:n,body:s}}}async sendHttpRequest(e,t,r){let n=r.timeout||3e4,s=r.retry_count||0,o=r.retry_delay||1e3,a=null;for(let g=0;g<=s;g++){try{this.logger.debug(`[CustomMCP] \u53D1\u9001 HTTP \u8BF7\u6C42 (\u5C1D\u8BD5 ${g+1}/${s+1}): ${e}`,{method:t.method,headers:t.headers});let u=new AbortController,p=setTimeout(()=>u.abort(),n),h=await fetch(e,{...t,signal:u.signal});if(clearTimeout(p),h.ok||g===s)return h;this.logger.warn(`[CustomMCP] HTTP \u8BF7\u6C42\u5931\u8D25 (${h.status}), \u5C06\u5728 ${o}ms \u540E\u91CD\u8BD5`),a=new Error(`HTTP \u8BF7\u6C42\u5931\u8D25: ${h.status} ${h.statusText}`)}catch(u){if(a=u instanceof Error?u:new Error(String(u)),u instanceof Error&&u.name==="AbortError"&&(a=new Error(`HTTP \u8BF7\u6C42\u8D85\u65F6 (${n}ms)`)),this.logger.warn(`[CustomMCP] HTTP \u8BF7\u6C42\u5F02\u5E38 (\u5C1D\u8BD5 ${g+1}/${s+1}):`,a.message),g===s)throw a}g<s&&await new Promise(u=>setTimeout(u,o))}throw a||new Error("HTTP \u8BF7\u6C42\u5931\u8D25")}async processHttpResponse(e,t,r){try{let n=t.headers.get("content-type")||"",s;if(n.includes("application/json")?s=await t.json():s=await t.text(),!t.ok)return{content:[{type:"text",text:`HTTP \u8BF7\u6C42\u5931\u8D25 (${t.status}): ${typeof s=="string"?s:JSON.stringify(s)}`}],isError:!0};let o=s;return r.response_mapping&&(o=this.extractResponseData(s,r.response_mapping)),{content:[{type:"text",text:typeof o=="string"?o:JSON.stringify(o,null,2)}],isError:!1}}catch(n){return this.logger.error(`[CustomMCP] \u5904\u7406 HTTP \u54CD\u5E94\u5931\u8D25: ${e}`,n),{content:[{type:"text",text:`\u5904\u7406\u54CD\u5E94\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`}],isError:!0}}}replaceTemplateVariables(e,t){let r=e;for(let[n,s]of Object.entries(t)){let o=`{{${n}}}`,a=typeof s=="string"?s:JSON.stringify(s);r=r.replace(new RegExp(o.replace(/[{}]/g,"\\$&"),"g"),a)}return r}extractResponseData(e,t){if(!t)return e;let r=l((n,s)=>{if(!s)return n;let o=s.split("."),a=n;for(let g of o)if(a&&typeof a=="object"&&g in a)a=a[g];else return;return a},"extractByPath");if(t.success_path){let n=r(e,t.success_path);if(n!==void 0)return t.data_path?r(n,t.data_path):n}if(t.data_path){let n=r(e,t.data_path);if(n!==void 0)return n}return e}async callScriptTool(e,t){let r=e.handler;this.logger.info(`[CustomMCP] \u8C03\u7528\u811A\u672C\u5DE5\u5177: ${e.name}`,{script:r.script.substring(0,100)+(r.script.length>100?"...":""),interpreter:r.interpreter||"node"});try{let n=await this.executeScript(r,t);return{content:[{type:"text",text:typeof n=="string"?n:JSON.stringify(n,null,2)}],isError:!1}}catch(n){return this.logger.error(`[CustomMCP] \u811A\u672C\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,n),{content:[{type:"text",text:`\u811A\u672C\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`}],isError:!0}}}async executeScript(e,t){let{spawn:r}=await import("child_process"),{promisify:n}=await import("util"),s=await import("fs/promises"),o=await import("path"),a=await import("os"),g=e.timeout||3e4,u=e.interpreter||"node",p,h=!1;try{if(e.script.includes(`
25
- `)||e.script.length>200){let y=await s.mkdtemp(o.join(a.tmpdir(),"xiaozhi-script-")),I=this.getScriptExtension(u);p=o.join(y,`script${I}`),await s.writeFile(p,e.script,"utf8"),h=!0}else{p=e.script;try{await s.access(p)}catch{throw new Error(`\u811A\u672C\u6587\u4EF6\u4E0D\u5B58\u5728: ${p}`)}}let S={...process.env,...e.env,XIAOZHI_ARGUMENTS:JSON.stringify(t)},T=this.buildScriptCommand(u,p);return this.logger.debug(`[CustomMCP] \u6267\u884C\u811A\u672C\u547D\u4EE4: ${T.join(" ")}`),new Promise((y,I)=>{let k=r(T[0],T.slice(1),{env:S,stdio:["pipe","pipe","pipe"]}),ye="",be="";k.stdout?.on("data",E=>{ye+=E.toString()}),k.stderr?.on("data",E=>{be+=E.toString()});let we=setTimeout(()=>{k.kill("SIGTERM"),I(new Error(`\u811A\u672C\u6267\u884C\u8D85\u65F6 (${g}ms)`))},g);k.on("close",E=>{clearTimeout(we),E===0?y(ye.trim()):I(new Error(`\u811A\u672C\u6267\u884C\u5931\u8D25 (\u9000\u51FA\u7801: ${E}): ${be.trim()}`))}),k.on("error",E=>{clearTimeout(we),I(new Error(`\u811A\u672C\u6267\u884C\u9519\u8BEF: ${E.message}`))}),t&&Object.keys(t).length>0&&(k.stdin?.write(JSON.stringify(t)),k.stdin?.end())})}finally{if(h&&p)try{await s.unlink(p),await s.rmdir(o.dirname(p))}catch{}}}getScriptExtension(e){switch(e){case"node":return".js";case"python":return".py";case"bash":return".sh";default:return".txt"}}buildScriptCommand(e,t){switch(e){case"node":return["node",t];case"python":return["python3",t];case"bash":return["bash",t];default:throw new Error(`\u4E0D\u652F\u6301\u7684\u811A\u672C\u89E3\u91CA\u5668: ${e}`)}}async callChainTool(e,t){let r=e.handler;this.logger.info(`[CustomMCP] \u8C03\u7528\u94FE\u5F0F\u5DE5\u5177: ${e.name}`,{tools:r.tools,mode:r.mode,error_handling:r.error_handling});try{let n;r.mode==="sequential"?n=await this.executeSequentialChain(r,t):n=await this.executeParallelChain(r,t);let s=n.flatMap(a=>a.content),o=n.some(a=>a.isError);return{content:s,isError:o}}catch(n){return this.logger.error(`[CustomMCP] \u94FE\u5F0F\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,n),{content:[{type:"text",text:`\u94FE\u5F0F\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`}],isError:!0}}}delay(e){return new Promise(t=>setTimeout(t,e))}getToolInfo(e){return this.tools.get(e)}async executeSequentialChain(e,t){let r=[],n=t;for(let s of e.tools)try{this.logger.debug(`[CustomMCP] \u6267\u884C\u94FE\u5F0F\u5DE5\u5177\u4E2D\u7684: ${s}`);let o=await this.callToolRecursive(s,n);if(r.push(o),o.isError){if(e.error_handling==="stop")break;if(e.error_handling==="retry"){this.logger.warn(`[CustomMCP] \u5DE5\u5177 ${s} \u6267\u884C\u5931\u8D25\uFF0C\u5C1D\u8BD5\u91CD\u8BD5`);let a=await this.callToolRecursive(s,n);if(r[r.length-1]=a,a.isError)break}}if(!o.isError&&o.content.length>0){let a=o.content.filter(g=>g.type==="text").map(g=>g.text).join(`
26
- `);if(a)try{n=JSON.parse(a)}catch{n={input:a,...t}}}}catch(o){let a={content:[{type:"text",text:`\u5DE5\u5177 ${s} \u6267\u884C\u5F02\u5E38: ${o instanceof Error?o.message:String(o)}`}],isError:!0};if(r.push(a),e.error_handling==="stop")break}return r}async executeParallelChain(e,t){let r=e.tools.map(async n=>{try{return this.logger.debug(`[CustomMCP] \u5E76\u884C\u6267\u884C\u94FE\u5F0F\u5DE5\u5177\u4E2D\u7684: ${n}`),await this.callToolRecursive(n,t)}catch(s){return{content:[{type:"text",text:`\u5DE5\u5177 ${n} \u6267\u884C\u5F02\u5E38: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}});return Promise.all(r)}async callToolRecursive(e,t){if(this.tools.get(e))return this.callTool(e,t);throw new Error(`\u94FE\u5F0F\u5DE5\u5177\u4E2D\u5F15\u7528\u7684\u5DE5\u5177 ${e} \u4E0D\u5B58\u5728\u4E8E\u5F53\u524D CustomMCP \u5DE5\u5177\u96C6\u4E2D`)}async clearConsumedCache(e,t){try{let r=this.generateCacheKey(e,t),n=await this.loadExtendedCache();if(n.customMCPResults?.[r]){n.customMCPResults[r].consumed=!0;let s=n.customMCPResults[r];O(s)&&delete n.customMCPResults[r],await this.saveCache(n),this.logger.debug(`[CustomMCP] \u6E05\u7406\u5DF2\u6D88\u8D39\u7F13\u5B58: ${r}`)}}catch(r){this.logger.warn(`[CustomMCP] \u6E05\u7406\u7F13\u5B58\u5931\u8D25: ${r}`)}}async generateTaskId(e,t){return this.taskStateManager.generateTaskId(e,t)}async markTaskAsPending(e,t,r){try{let n=this.generateCacheKey(t,r),s={result:{content:[{type:"text",text:"\u5904\u7406\u4E2D..."}]},timestamp:new Date().toISOString(),ttl:this.CACHE_TTL,status:"pending",consumed:!1,taskId:e,retryCount:0};await this.updateCacheWithResult(n,s),this.taskStateManager.markTaskAsPending(e,t,r),this.activeTasks.set(e,{taskId:e,status:"pending",startTime:Date.now()}),this.logger.debug(`[CustomMCP] \u6807\u8BB0\u4EFB\u52A1\u4E3A\u5904\u7406\u4E2D: ${e}`)}catch(n){this.logger.warn(`[CustomMCP] \u6807\u8BB0\u4EFB\u52A1\u72B6\u6001\u5931\u8D25: ${n}`)}}async markTaskAsCompleted(e,t){try{let r=this.activeTasks.get(e);r&&(r.status="completed",r.endTime=new Date().toISOString(),r.result=t);let n=await this.loadExtendedCache();for(let[s,o]of Object.entries(n.customMCPResults||{}))if(o.taskId===e){o.status="completed",o.result=t,o.timestamp=new Date().toISOString(),o.consumed=!1;break}await this.saveCache(n),this.taskStateManager.markTaskAsCompleted(e,t),this.logger.debug(`[CustomMCP] \u6807\u8BB0\u4EFB\u52A1\u4E3A\u5DF2\u5B8C\u6210: ${e}`)}catch(r){this.logger.warn(`[CustomMCP] \u66F4\u65B0\u4EFB\u52A1\u72B6\u6001\u5931\u8D25: ${r}`)}}async markTaskAsFailed(e,t){try{let r=await this.loadExtendedCache();for(let[s,o]of Object.entries(r.customMCPResults||{}))if(o.taskId===e){o.status="failed",o.result={content:[{type:"text",text:`\u4EFB\u52A1\u5931\u8D25: ${t.message}`}]},o.timestamp=new Date().toISOString(),o.consumed=!0;break}await this.saveCache(r),this.taskStateManager.markTaskAsFailed(e,t.message);let n=this.activeTasks.get(e);n&&(n.status="failed",n.endTime=new Date().toISOString(),n.error=t.message),this.logger.debug(`[CustomMCP] \u6807\u8BB0\u4EFB\u52A1\u4E3A\u5931\u8D25: ${e}`)}catch(r){this.logger.warn(`[CustomMCP] \u66F4\u65B0\u4EFB\u52A1\u72B6\u6001\u5931\u8D25: ${r}`)}}startCleanupTimer(){this.cleanupTimer=setInterval(()=>{this.cleanupExpiredCache().catch(e=>{this.logger.warn(`[CustomMCP] \u7F13\u5B58\u6E05\u7406\u5931\u8D25: ${e}`)})},this.CLEANUP_INTERVAL),this.logger.debug(`[CustomMCP] \u542F\u52A8\u7F13\u5B58\u6E05\u7406\u5B9A\u65F6\u5668\uFF0C\u95F4\u9694: ${this.CLEANUP_INTERVAL}ms`)}async cleanupExpiredCache(){try{let e=await this.loadExtendedCache(),t=!1,r=0;for(let[n,s]of Object.entries(e.customMCPResults||{}))O(s)&&(e.customMCPResults?.[n]&&delete e.customMCPResults[n],t=!0,r++,s.taskId&&this.activeTasks.delete(s.taskId));t&&(await this.saveCache(e),this.logger.debug(`[CustomMCP] \u6E05\u7406\u8FC7\u671F\u7F13\u5B58\u5B8C\u6210\uFF0C\u6E05\u7406\u4E86 ${r} \u4E2A\u6761\u76EE`))}catch(e){this.logger.warn(`[CustomMCP] \u6E05\u7406\u8FC7\u671F\u7F13\u5B58\u5931\u8D25: ${e}`)}}generateCacheKey(e,t){return R(e,t)}async loadExtendedCache(){try{return await this.cacheManager.loadExistingCache()}catch{return{version:"1.0.0",mcpServers:{},metadata:{lastGlobalUpdate:new Date().toISOString(),totalWrites:0,createdAt:new Date().toISOString()},customMCPResults:{}}}}async updateCacheWithResult(e,t){try{let r=await this.loadExtendedCache();r.customMCPResults||(r.customMCPResults={}),r.customMCPResults[e]=t,await this.saveCache(r)}catch(r){this.logger.warn(`[CustomMCP] \u66F4\u65B0\u7F13\u5B58\u5931\u8D25: ${r}`)}}async cacheResult(e,t,r){try{let n=this.generateCacheKey(e,t),s={result:r,timestamp:new Date().toISOString(),ttl:this.CACHE_TTL,status:"completed",consumed:!1,retryCount:0};await this.updateCacheWithResult(n,s),this.logger.debug(`[CustomMCP] \u7F13\u5B58\u5DE5\u5177\u7ED3\u679C: ${e}`)}catch(n){this.logger.warn(`[CustomMCP] \u7F13\u5B58\u7ED3\u679C\u5931\u8D25: ${n}`)}}async saveCache(e){try{await this.cacheManager.saveCache(e)}catch(t){this.logger.warn(`[CustomMCP] \u4FDD\u5B58\u7F13\u5B58\u5931\u8D25: ${t}`)}}stopCleanupTimer(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=void 0,this.logger.info("[CustomMCP] \u505C\u6B62\u7F13\u5B58\u6E05\u7406\u5B9A\u65F6\u5668"))}cleanup(){this.logger.info("[CustomMCP] \u6E05\u7406 CustomMCP \u5904\u7406\u5668\u8D44\u6E90"),this.stopCleanupTimer(),this.cacheLifecycleManager.stopAutoCleanup(),this.cacheLifecycleManager.cleanup(),this.taskStateManager.cleanup(),this.cacheManager.cleanup(),this.tools.clear(),this.activeTasks.clear()}getCacheLifecycleManager(){return this.cacheLifecycleManager}getTaskStateManager(){return this.taskStateManager}async getCacheStatistics(){return this.cacheManager.getCustomMCPStatistics()}getTaskStatistics(){return this.taskStateManager.getTaskStatistics()}getTaskStatus(e){return this.taskStateManager.getTaskStatus(e)}validateTaskId(e){return this.taskStateManager.validateTaskId(e)}restartStalledTasks(e=3e4){return this.taskStateManager.restartStalledTasks(e)}async manualCleanupCache(){return this.cacheManager.cleanupCustomMCPResults()}async validateSystemIntegrity(){let e=await this.cacheManager.loadExtendedCache(),t=this.cacheLifecycleManager.validateCacheIntegrity(e),r=this.taskStateManager.validateTaskIntegrity();return{cacheValid:t.isValid,taskValid:r.isValid,issues:[...t.issues,...r.issues]}}};import{Client as Pt}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as lt}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as gt}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as ut}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{EventSource as ht}from"eventsource";typeof global<"u"&&!global.EventSource&&(global.EventSource=ht);function pt(){return c}l(pt,"getLogger");function mt(i){switch(pt().debug(`[TransportFactory] \u521B\u5EFA ${i.type} transport for ${i.name}`),i.type){case"stdio":return dt(i);case"sse":return ft(i);case"streamable-http":return Ct(i);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`)}}l(mt,"createTransport");function dt(i){if(!i.command)throw new Error("stdio transport \u9700\u8981 command \u914D\u7F6E");return new gt({command:i.command,args:i.args||[],env:i.env})}l(dt,"createStdioTransport");function ft(i){if(!i.url)throw new Error("SSE transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(i.url),t=vt(i);return new lt(e,t)}l(ft,"createSSETransport");function Ct(i){if(!i.url)throw new Error("StreamableHTTP transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(i.url),t=St(i);return new ut(e,t)}l(Ct,"createStreamableHTTPTransport");function vt(i){let e={};return i.apiKey?e.headers={Authorization:`Bearer ${i.apiKey}`,...i.headers}:i.headers&&(e.headers=i.headers),e}l(vt,"createSSEOptions");function St(i){let e={};return i.apiKey?e.headers={Authorization:`Bearer ${i.apiKey}`,...i.headers}:i.headers&&(e.headers=i.headers),e}l(St,"createStreamableHTTPOptions");function Tt(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&&!Object.values(Q).includes(i.type))throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`);if(!i.type)throw new Error("\u4F20\u8F93\u7C7B\u578B\u672A\u8BBE\u7F6E\uFF0C\u8FD9\u5E94\u8BE5\u5728 inferTransportType \u4E2D\u5904\u7406");switch(i.type){case"stdio":if(!i.command)throw new Error("stdio \u7C7B\u578B\u9700\u8981 command \u5B57\u6BB5");break;case"sse":if(i.url===void 0||i.url===null)throw new Error(`${i.type} \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5`);break;case"streamable-http":if(i.url===void 0||i.url===null)throw new Error(`${i.type} \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5`);break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`)}}l(Tt,"validateConfig");function Mt(){return["stdio","sse","streamable-http"]}l(Mt,"getSupportedTypes");var fe={create:mt,validateConfig:Tt,getSupportedTypes:Mt};var Q=(r=>(r.STDIO="stdio",r.SSE="sse",r.STREAMABLE_HTTP="streamable-http",r))(Q||{});var X=class{static{l(this,"MCPService")}config;client=null;transport=null;tools=new Map;connectionState="disconnected";reconnectOptions;reconnectState;logger;connectionTimeout=null;initialized=!1;eventBus=b();pingOptions;pingTimer=null;pingFailureCount=0;lastPingTime=null;isPinging=!1;constructor(e,t){this.logger=c;let r=this.inferTransportType(e);this.config=r,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,...r){let n=`[MCP-${this.config.name}] ${t}`;this.logger[e](n,...r)}inferTransportType(e){if(e.type)return e;this.logger.debug(`[MCP-${e.name}] \u81EA\u52A8\u63A8\u65AD\u4F20\u8F93\u7C7B\u578B...`);let t;if(e.command)t="stdio",this.logger.debug(`[MCP-${e.name}] \u68C0\u6D4B\u5230 command \u5B57\u6BB5\uFF0C\u63A8\u65AD\u4E3A stdio \u7C7B\u578B`);else if(e.url!==void 0&&e.url!==null)t=this.inferTransportTypeFromUrl(e.url,e.name);else throw new Error(`\u65E0\u6CD5\u4E3A\u670D\u52A1 ${e.name} \u63A8\u65AD\u4F20\u8F93\u7C7B\u578B\u3002\u8BF7\u663E\u5F0F\u6307\u5B9A type \u5B57\u6BB5\uFF0C\u6216\u63D0\u4F9B command/url \u914D\u7F6E`);return{type:t,...e}}inferTransportTypeFromUrl(e,t){try{let n=new URL(e).pathname;return n.endsWith("/sse")?(this.logger.info(`[MCP-${t}] \u68C0\u6D4B\u5230 URL \u8DEF\u5F84\u4EE5 /sse \u7ED3\u5C3E\uFF0C\u63A8\u65AD\u4E3A sse \u7C7B\u578B`),"sse"):n.endsWith("/mcp")?(this.logger.info(`[MCP-${t}] \u68C0\u6D4B\u5230 URL \u8DEF\u5F84\u4EE5 /mcp \u7ED3\u5C3E\uFF0C\u63A8\u65AD\u4E3A streamable-http \u7C7B\u578B`),"streamable-http"):(this.logger.info(`[MCP-${t}] URL \u8DEF\u5F84 ${n} \u4E0D\u5339\u914D\u7279\u5B9A\u89C4\u5219\uFF0C\u9ED8\u8BA4\u63A8\u65AD\u4E3A streamable-http \u7C7B\u578B`),"streamable-http")}catch(r){return this.logger.warn(`[MCP-${t}] URL \u89E3\u6790\u5931\u8D25\uFF0C\u9ED8\u8BA4\u63A8\u65AD\u4E3A streamable-http \u7C7B\u578B`,r),"streamable-http"}}validateConfig(){fe.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("debug",`\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 r=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(r),t(r)},this.reconnectOptions.timeout);try{this.client=new Pt({name:`xiaozhi-${this.config.name}-client`,version:"1.0.0"},{capabilities:{tools:{}}}),this.transport=fe.create(this.config),this.client.connect(this.transport).then(async()=>{this.handleConnectionSuccess(),await this.refreshTools(),this.eventBus.emitEvent("mcp:service:connected",{serviceName:this.config.name,tools:this.getTools(),connectionTime:new Date}),e()}).catch(r=>{this.handleConnectionError(r),t(r)})}catch(r){this.handleConnectionError(r),t(r)}})}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.connectionState="disconnected",this.initialized=!1,this.reconnectState.lastError=e,this.logger.debug(`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u9519\u8BEF:`,e.message),this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.cleanupConnection(),this.eventBus.emitEvent("mcp:service:connection:failed",{serviceName:this.config.name,error:e,attempt:this.reconnectState.attempts}),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.debug(`${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,r=(Math.random()-.5)*2*t;e+=r}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 r of t)this.tools.set(r.name,r);this.logger.debug(`${this.config.name} \u670D\u52A1\u52A0\u8F7D\u4E86 ${t.length} \u4E2A\u5DE5\u5177: ${t.map(r=>r.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",this.eventBus.emitEvent("mcp:service:disconnected",{serviceName:this.config.name,reason:"\u624B\u52A8\u65AD\u5F00",disconnectionTime:new Date})}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.debug(`\u8C03\u7528 ${this.config.name} \u670D\u52A1\u7684\u5DE5\u5177 ${e}\uFF0C\u53C2\u6570:`,JSON.stringify(t));try{let r=await this.client.callTool({name:e,arguments:t||{}});return this.logger.debug(`\u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,`${JSON.stringify(r).substring(0,500)}...`),r}catch(r){throw this.logger.error(`\u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,r instanceof Error?r.message:String(r)),r}}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.debug(`${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(),r=new Promise((s,o)=>{setTimeout(()=>{o(new Error(`Ping\u8D85\u65F6 (${this.pingOptions.timeout}ms)`))},this.pingOptions.timeout)});await Promise.race([t,r]);let n=performance.now()-e;this.handlePingSuccess(n)}catch(t){let r=performance.now()-e;this.handlePingFailure(t,r)}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 r=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(r)}}resetPingState(){this.pingFailureCount=0,this.lastPingTime=null,this.isPinging=!1}enablePing(){this.pingOptions.enabled=!0,this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u542F\u7528`),this.isConnected()&&this.startPingMonitoring()}disablePing(){this.pingOptions.enabled=!1,this.stopPingMonitoring(),this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u7981\u7528`)}updatePingOptions(e){let t=this.pingOptions.enabled;this.pingOptions={...this.pingOptions,...e},this.logger.info(`${this.config.name} ping\u914D\u7F6E\u5DF2\u66F4\u65B0`,e),t!==this.pingOptions.enabled&&(this.pingOptions.enabled&&this.isConnected()?this.startPingMonitoring():this.pingOptions.enabled||this.stopPingMonitoring())}getPingOptions(){return{...this.pingOptions}}};var Z=class{static{l(this,"ToolSyncManager")}configManager;logger;syncLocks=new Map;eventBus=b();constructor(e,t=c){this.configManager=e,this.logger=t.withTag("ToolSync"),this.setupEventListeners()}setupEventListeners(){this.eventBus.onEvent("config:updated",async e=>{await this.handleConfigUpdated(e)}),this.eventBus.onEvent("mcp:server:added",async e=>{await this.handleMCPServerAdded(e)}),this.eventBus.onEvent("mcp:server:removed",async e=>{await this.handleMCPServerRemoved(e)})}async handleConfigUpdated(e){this.logger.debug("\u68C0\u6D4B\u5230\u914D\u7F6E\u66F4\u65B0\uFF0C\u68C0\u67E5\u5DE5\u5177\u540C\u6B65\u72B6\u6001");try{e.type==="customMCP"?this.logger.debug("customMCP\u914D\u7F6E\u5DF2\u66F4\u65B0\uFF0CCustomMCPHandler\u5C06\u81EA\u52A8\u5904\u7406"):e.type==="serverTools"&&e.serviceName?await this.handleServerToolsConfigUpdated(e.serviceName):await this.handleGeneralConfigUpdated()}catch(t){this.logger.error("\u914D\u7F6E\u66F4\u65B0\u540E\u7684\u5DE5\u5177\u540C\u6B65\u5931\u8D25:",t)}}async handleServerToolsConfigUpdated(e){this.logger.debug(`\u5904\u7406\u670D\u52A1 ${e} \u7684serverTools\u914D\u7F6E\u66F4\u65B0`);try{this.eventBus.emitEvent("tool-sync:server-tools-updated",{serviceName:e,timestamp:new Date})}catch(t){this.logger.error(`\u5904\u7406\u670D\u52A1 ${e} \u914D\u7F6E\u66F4\u65B0\u5931\u8D25:`,t)}}async handleGeneralConfigUpdated(){this.logger.info("\u5904\u7406\u901A\u7528\u914D\u7F6E\u66F4\u65B0\uFF0C\u68C0\u67E5\u6240\u6709\u670D\u52A1\u540C\u6B65\u72B6\u6001");try{this.eventBus.emitEvent("tool-sync:general-config-updated",{timestamp:new Date})}catch(e){this.logger.error("\u5904\u7406\u901A\u7528\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",e)}}async handleMCPServerAdded(e){this.logger.info(`\u5904\u7406MCP\u670D\u52A1\u6DFB\u52A0\u4E8B\u4EF6: ${e.serverName}`);try{setTimeout(async()=>{await this.triggerServiceToolSync(e.serverName)},1e3)}catch(t){this.logger.error(`\u5904\u7406\u670D\u52A1 ${e.serverName} \u6DFB\u52A0\u4E8B\u4EF6\u5931\u8D25:`,t)}}async triggerServiceToolSync(e){this.logger.info(`\u89E6\u53D1\u670D\u52A1 ${e} \u7684\u5DE5\u5177\u540C\u6B65`);try{this.eventBus.emitEvent("tool-sync:request-service-tools",{serviceName:e,timestamp:new Date})}catch(t){this.logger.error(`\u89E6\u53D1\u670D\u52A1 ${e} \u5DE5\u5177\u540C\u6B65\u5931\u8D25:`,t)}}async handleMCPServerRemoved(e){this.logger.info(`\u5904\u7406MCP\u670D\u52A1\u79FB\u9664\u4E8B\u4EF6: ${e.serverName}`);try{await this.removeServiceToolsFromCustomMCP(e.serverName,e.affectedTools)}catch(t){this.logger.error(`\u5904\u7406\u670D\u52A1 ${e.serverName} \u79FB\u9664\u4E8B\u4EF6\u5931\u8D25:`,t)}}async removeServiceToolsFromCustomMCP(e,t){this.logger.info(`\u4ECEcustomMCP\u4E2D\u79FB\u9664\u670D\u52A1 ${e} \u7684\u5DE5\u5177`);try{let r=this.configManager.getCustomMCPTools(),n=r.filter(o=>!o.name.startsWith(`${e}__`));if(n.length===r.length){this.logger.debug(`\u670D\u52A1 ${e} \u7684\u5DE5\u5177\u4E0D\u5728customMCP\u4E2D\uFF0C\u65E0\u9700\u79FB\u9664`);return}await this.configManager.updateCustomMCPTools(n);let s=r.length-n.length;this.logger.info(`\u6210\u529F\u4ECEcustomMCP\u4E2D\u79FB\u9664\u670D\u52A1 ${e} \u7684 ${s} \u4E2A\u5DE5\u5177`),this.eventBus.emitEvent("tool-sync:service-tools-removed",{serviceName:e,removedCount:s,timestamp:new Date})}catch(r){throw this.logger.error(`\u79FB\u9664\u670D\u52A1 ${e} \u5DE5\u5177\u5931\u8D25:`,r),r}}async syncToolsAfterConnection(e,t){if(this.syncLocks.has(e)){this.logger.debug(`\u670D\u52A1 ${e} \u6B63\u5728\u540C\u6B65\u4E2D\uFF0C\u8DF3\u8FC7`);return}let r=this.doSyncTools(e,t).finally(()=>{this.syncLocks.delete(e)});this.syncLocks.set(e,r),await r}async doSyncTools(e,t){try{this.logger.info(`\u5F00\u59CB\u540C\u6B65\u670D\u52A1 ${e} \u7684\u5DE5\u5177`);let r=this.configManager.getServerToolsConfig(e);if(!r){this.logger.debug(`\u670D\u52A1 ${e} \u65E0 mcpServerConfig \u914D\u7F6E\uFF0C\u8DF3\u8FC7\u540C\u6B65`);return}let n=this.getEnabledTools(r,t);if(n.length===0){this.logger.debug(`\u670D\u52A1 ${e} \u65E0\u542F\u7528\u5DE5\u5177\uFF0C\u8DF3\u8FC7\u540C\u6B65`);return}let s=this.configManager.getCustomMCPTools(),o=new Set(s.map(g=>g.name)),a=n.filter(g=>!o.has(`${e}__${g.name}`));if(a.length===0){this.logger.info(`\u670D\u52A1 ${e} \u7684\u542F\u7528\u5DE5\u5177\u5DF2\u5B58\u5728\u4E8E customMCP \u4E2D\uFF0C\u8DF3\u8FC7\u540C\u6B65`);return}await this.addToolsToCustomMCP(e,a),this.logger.info(`\u6210\u529F\u540C\u6B65\u670D\u52A1 ${e} \u7684 ${a.length} \u4E2A\u5DE5\u5177\u5230 customMCP`)}catch(r){this.logger.error(`\u540C\u6B65\u670D\u52A1 ${e} \u5DE5\u5177\u5931\u8D25:`,r),this.recordSyncError(e,r)}}getEnabledTools(e,t){let r=[];for(let n of t){let s=e[n.name];s&&s.enable!==!1&&r.push(n)}return r}async addToolsToCustomMCP(e,t){let r=t.map(n=>({name:`${e}__${n.name}`,description:n.description||"",inputSchema:n.inputSchema||{},handler:{type:"mcp",config:{serviceName:e,toolName:n.name}}}));await this.configManager.addCustomMCPTools(r),await this.syncToolStats(e,t)}recordSyncError(e,t){let r={serviceName:e,error:t instanceof Error?t.message:String(t),timestamp:new Date().toISOString(),type:t instanceof Error?t.constructor.name:"UnknownError"};this.logger.error("\u540C\u6B65\u9519\u8BEF\u8BB0\u5F55:",r)}getSyncLocks(){return Array.from(this.syncLocks.keys())}clearSyncLocks(){this.syncLocks.clear(),this.logger.debug("\u5DF2\u6E05\u7406\u6240\u6709\u540C\u6B65\u9501")}async syncToolStats(e,t){try{let r=this.configManager.getServerToolsConfig(e);if(!r){this.logger.debug(`\u670D\u52A1 ${e} \u65E0 mcpServerConfig \u914D\u7F6E\uFF0C\u8DF3\u8FC7\u7EDF\u8BA1\u4FE1\u606F\u540C\u6B65`);return}let n=this.configManager.getCustomMCPTools(),s=new Map(n.map(o=>[o.name,o]));for(let o of t){let a=`${e}__${o.name}`,g=s.get(a),u=r[o.name];if(g&&u&&(!g.stats||!g.stats.usageCount&&!g.stats.lastUsedTime)){let p={};u.usageCount!==void 0&&(p.usageCount=u.usageCount),u.lastUsedTime&&(p.lastUsedTime=u.lastUsedTime),Object.keys(p).length>0&&(await this.updateCustomMCPToolStats(a,p),this.logger.debug(`\u5DF2\u540C\u6B65\u5DE5\u5177 ${a} \u7684\u7EDF\u8BA1\u4FE1\u606F: ${JSON.stringify(p)}`))}}}catch(r){this.logger.error(`\u540C\u6B65\u670D\u52A1 ${e} \u5DE5\u5177\u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25:`,r instanceof Error?r.message:String(r))}}async updateCustomMCPToolStats(e,t){try{let r=this.configManager.getCustomMCPTools(),n=r.findIndex(a=>a.name===e);if(n===-1){this.logger.warn(`\u5DE5\u5177 ${e} \u4E0D\u5B58\u5728\u4E8E customMCP \u4E2D`);return}let s=[...r],o=s[n];o.stats||(o.stats={}),t.usageCount!==void 0&&(o.stats.usageCount=t.usageCount),t.lastUsedTime!==void 0&&(o.stats.lastUsedTime=t.lastUsedTime),await this.configManager.updateCustomMCPTools(s)}catch(r){throw this.logger.error(`\u66F4\u65B0\u5DE5\u5177 ${e} \u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25:`,r instanceof Error?r.message:String(r)),r}}};import*as U from"fs";import*as D from"path";import{realpathSync as yt}from"fs";import{tmpdir as bt}from"os";import d from"path";import{fileURLToPath as Ae}from"url";var Ce={NAME:"xiaozhi-mcp-service",DEFAULT_PORT:3e3,DEFAULT_WEB_UI_PORT:9999,PID_FILE:"xiaozhi.pid",LOG_FILE:"xiaozhi.log"},F={FILE_NAMES:["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"],DEFAULT_FILE:"xiaozhi.config.default.json",DIR_ENV_VAR:"XIAOZHI_CONFIG_DIR"},B={WORK_DIR:".xiaozhi",TEMPLATES_DIR:"templates",LOGS_DIR:"logs"},De={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"};import C from"fs";import P from"path";var ve=class i extends Error{constructor(t,r,n=1,s){super(t);this.code=r;this.exitCode=n;this.suggestions=s;this.name="CLIError",Error.captureStackTrace&&Error.captureStackTrace(this,i)}static{l(this,"CLIError")}static withSuggestions(t,r,n){return new i(t,r,1,n)}};var m=class i extends ve{static{l(this,"FileError")}constructor(e,t,r){let n=t?`${e}: ${t}`:e;super(n,De.FILE_ERROR,1,r),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"])}};var j=class i{static{l(this,"FileUtils")}static exists(e){try{return C.existsSync(e)}catch{return!1}}static ensureDir(e){try{C.existsSync(e)||C.mkdirSync(e,{recursive:!0})}catch{throw new m("\u65E0\u6CD5\u521B\u5EFA\u76EE\u5F55",e)}}static readFile(e,t="utf8"){try{if(!i.exists(e))throw m.notFound(e);return C.readFileSync(e,t)}catch(r){throw r instanceof m?r:new m("\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6",e)}}static writeFile(e,t,r){try{if(!r?.overwrite&&i.exists(e))throw m.alreadyExists(e);let n=P.dirname(e);i.ensureDir(n),C.writeFileSync(e,t,"utf8")}catch(n){throw n instanceof m?n:new m("\u65E0\u6CD5\u5199\u5165\u6587\u4EF6",e)}}static copyFile(e,t,r){try{if(!i.exists(e))throw m.notFound(e);if(!r?.overwrite&&i.exists(t))throw m.alreadyExists(t);let n=P.dirname(t);i.ensureDir(n),C.copyFileSync(e,t)}catch(n){throw n instanceof m?n:new m("\u65E0\u6CD5\u590D\u5236\u6587\u4EF6",e)}}static deleteFile(e){try{i.exists(e)&&C.unlinkSync(e)}catch{throw new m("\u65E0\u6CD5\u5220\u9664\u6587\u4EF6",e)}}static copyDirectory(e,t,r={}){try{if(!i.exists(e))throw m.notFound(e);i.ensureDir(t);let n=C.readdirSync(e);for(let s of n){if(r.exclude?.includes(s))continue;let o=P.join(e,s),a=P.join(t,s);C.statSync(o).isDirectory()?r.recursive!==!1&&i.copyDirectory(o,a,r):i.copyFile(o,a,{overwrite:r.overwrite})}}catch(n){throw n instanceof m?n:new m("\u65E0\u6CD5\u590D\u5236\u76EE\u5F55",e)}}static deleteDirectory(e,t={}){try{i.exists(e)&&C.rmSync(e,{recursive:t.recursive??!0,force:!0})}catch{throw new m("\u65E0\u6CD5\u5220\u9664\u76EE\u5F55",e)}}static getFileInfo(e){try{if(!i.exists(e))throw m.notFound(e);let t=C.statSync(e);return{size:t.size,isFile:t.isFile(),isDirectory:t.isDirectory(),mtime:t.mtime,ctime:t.ctime}}catch(t){throw t instanceof m?t:new m("\u65E0\u6CD5\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F",e)}}static listDirectory(e,t={}){try{if(!i.exists(e))throw m.notFound(e);let r=C.readdirSync(e),n=[];for(let s of r){if(!t.includeHidden&&s.startsWith("."))continue;let o=P.join(e,s);if(n.push(o),t.recursive&&C.statSync(o).isDirectory()){let a=i.listDirectory(o,t);n=n.concat(a)}}return n}catch(r){throw r instanceof m?r:new m("\u65E0\u6CD5\u5217\u51FA\u76EE\u5F55\u5185\u5BB9",e)}}static createTempFile(e="xiaozhi-",t=".tmp"){let r=process.env.TMPDIR||process.env.TEMP||"/tmp",n=Date.now(),s=Math.random().toString(36).substring(2),o=`${e}${n}-${s}${t}`;return P.join(r,o)}static checkPermissions(e,t=C.constants.R_OK|C.constants.W_OK){try{return C.accessSync(e,t),!0}catch{return!1}}static getExtension(e){return P.extname(e).toLowerCase()}static getBaseName(e){return P.basename(e,P.extname(e))}static normalizePath(e){return P.normalize(e)}static resolvePath(e,t){return t?P.resolve(t,e):P.resolve(e)}};var ee=class i{static{l(this,"PathUtils")}static getPidFile(){let e=process.env[F.DIR_ENV_VAR]||process.cwd();return d.join(e,`.${Ce.NAME}.pid`)}static getLogFile(e){let t=e||process.cwd();return d.join(t,Ce.LOG_FILE)}static getConfigDir(){return process.env[F.DIR_ENV_VAR]||process.cwd()}static getWorkDir(){let e=i.getConfigDir();return d.join(e,B.WORK_DIR)}static getTemplatesDir(){let e=Ae(import.meta.url),t=d.dirname(e);return[d.join(t,B.TEMPLATES_DIR),d.join(t,"..","..","..",B.TEMPLATES_DIR),d.join(t,"..","..","..","..",B.TEMPLATES_DIR)]}static findTemplatesDir(){let e=i.getTemplatesDir();for(let t of e)if(j.exists(t))return t;return null}static getTemplatePath(e){let t=i.findTemplatesDir();if(!t)return null;let r=d.join(t,e);return j.exists(r)?r:null}static getScriptDir(){let e=Ae(import.meta.url);return d.dirname(e)}static getProjectRoot(){let e=i.getScriptDir();return d.join(e,"..","..","..")}static getDistDir(){let e=i.getProjectRoot();return d.join(e,"dist")}static getRelativePath(e){let t=i.getProjectRoot();return d.relative(t,e)}static resolveConfigPath(e){let t=i.getConfigDir();if(e)return d.join(t,`xiaozhi.config.${e}`);for(let r of F.FILE_NAMES){let n=d.join(t,r);if(j.exists(n))return n}return d.join(t,F.FILE_NAMES[2])}static getDefaultConfigPath(){let e=i.getProjectRoot();return d.join(e,F.DEFAULT_FILE)}static validatePath(e){return!d.normalize(e).includes("..")}static ensurePathWithin(e,t){let r=d.resolve(t,e),n=d.resolve(t);if(!r.startsWith(n))throw new Error(`\u8DEF\u5F84 ${e} \u8D85\u51FA\u4E86\u5141\u8BB8\u7684\u8303\u56F4`);return r}static getExecutablePath(e){let t=process.argv[1];if(!t)return d.join(process.cwd(),`${e}.js`);let r;try{r=yt(t)}catch{r=t}let n=d.dirname(r);return d.join(n,`${e}.js`)}static getMcpServerProxyPath(){return i.getExecutablePath("mcpServerProxy")}static getWebServerStandalonePath(){return i.getExecutablePath("WebServerStandalone")}static createSafePath(...e){let t=d.join(...e),r=d.normalize(t);if(r.includes("..")||r.includes("~"))throw new Error(`\u4E0D\u5B89\u5168\u7684\u8DEF\u5F84: ${r}`);return r}static getTempDir(){return process.env.TMPDIR||process.env.TEMP||bt()}static getHomeDir(){return process.env.HOME||process.env.USERPROFILE||""}};import te from"pino";var re=class{static{l(this,"ToolCallLogger")}pinoLogger;maxRecords;logFilePath;constructor(e,t){if(this.maxRecords=e.maxRecords??100,e.logFilePath)this.logFilePath=D.resolve(D.normalize(e.logFilePath));else{let r=t||ee.getTempDir();this.logFilePath=D.join(D.normalize(r),"tool-calls.jsonl")}this.pinoLogger=this.createPinoLogger(this.logFilePath),c.debug(`ToolCallLogger \u521D\u59CB\u5316: maxRecords=${this.maxRecords}, path=${this.logFilePath}`)}createPinoLogger(e){let t=[];t.push({level:"info",stream:{write:l(r=>{try{let n=JSON.parse(r),s=this.formatConsoleMessage(n);c.info(`[\u5DE5\u5177\u8C03\u7528] ${s}`)}catch{c.info(`[\u5DE5\u5177\u8C03\u7528] ${r.trim()}`)}},"write")}});try{t.push({level:"info",stream:te.destination({dest:e,sync:!0,append:!0,mkdir:!0})})}catch(r){c.error("\u65E0\u6CD5\u521B\u5EFA\u5DE5\u5177\u8C03\u7528\u65E5\u5FD7\u6587\u4EF6:",r)}return te({level:"info",timestamp:te.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:l((r,n)=>({level:n}),"level")},base:null},te.multistream(t,{dedupe:!0}))}formatConsoleMessage(e){let t=e.toolName||"\u672A\u77E5\u5DE5\u5177",r=e.success!==!1,n=e.duration?` (${e.duration}ms)`:"";return`${r?"\u2705":"\u274C"} ${t}${n}`}async cleanupOldRecords(){try{if(!U.existsSync(this.logFilePath))return;let t=U.readFileSync(this.logFilePath,"utf8").trim().split(`
27
- `).filter(o=>o.trim()!=="");if(t.length<=this.maxRecords)return;let r=t.length-this.maxRecords+1,n=t.slice(r),s=n.join(`
28
- `)+(n.length>0?`
29
- `:"");U.writeFileSync(this.logFilePath,s,"utf8"),c.debug(`\u5DF2\u6E05\u7406 ${r} \u6761\u65E7\u7684\u5DE5\u5177\u8C03\u7528\u8BB0\u5F55\uFF0C\u4FDD\u7559\u6700\u65B0 ${this.maxRecords} \u6761`)}catch(e){c.error("\u6E05\u7406\u65E7\u5DE5\u5177\u8C03\u7528\u8BB0\u5F55\u5931\u8D25:",e)}}async recordToolCall(e){try{await this.cleanupOldRecords(),this.pinoLogger.info(e,e.toolName)}catch(t){c.error("\u8BB0\u5F55\u5DE5\u5177\u8C03\u7528\u5931\u8D25:",t)}}getLogFilePath(){return this.logFilePath}getMaxRecords(){return this.maxRecords}};var ne=class{static{l(this,"MCPServiceManager")}services=new Map;configs={};logger;tools=new Map;customMCPHandler;cacheManager;toolSyncManager;eventBus=b();toolCallLogger;retryTimers=new Map;failedServices=new Set;constructor(e){this.logger=c,this.configs=e||{};let r=process.env.NODE_ENV==="test"||process.env.VITEST==="true"?`/tmp/xiaozhi-test-${Date.now()}-${Math.random().toString(36).substring(2,11)}/xiaozhi.cache.json`:void 0;this.cacheManager=new N(r),this.customMCPHandler=new Y,this.toolSyncManager=new Z(f,this.logger);let n=f.getToolCallLogConfig(),s=f.getConfigDir();this.toolCallLogger=new re(n,s),this.setupEventListeners()}setupEventListeners(){this.eventBus.onEvent("mcp:service:connected",async e=>{await this.handleServiceConnected(e)}),this.eventBus.onEvent("mcp:service:disconnected",async e=>{await this.handleServiceDisconnected(e)}),this.eventBus.onEvent("mcp:service:connection:failed",async e=>{await this.handleServiceConnectionFailed(e)}),this.eventBus.onEvent("tool-sync:server-tools-updated",async e=>{await this.handleServerToolsUpdated(e)}),this.eventBus.onEvent("tool-sync:general-config-updated",async e=>{await this.handleGeneralConfigUpdated(e)})}async handleServiceConnected(e){this.logger.debug(`\u670D\u52A1 ${e.serviceName} \u8FDE\u63A5\u6210\u529F\uFF0C\u5F00\u59CB\u5DE5\u5177\u540C\u6B65`);try{let t=this.services.get(e.serviceName);if(t){let r=t.getTools();this.toolSyncManager&&await this.toolSyncManager.syncToolsAfterConnection(e.serviceName,r),await this.refreshCustomMCPHandlerPublic(),this.logger.info(`\u670D\u52A1 ${e.serviceName} \u5DE5\u5177\u540C\u6B65\u5B8C\u6210`)}}catch(t){this.logger.error(`\u540C\u6B65\u670D\u52A1 ${e.serviceName} \u5DE5\u5177\u5931\u8D25:`,t)}}async handleServiceDisconnected(e){this.logger.info(`\u670D\u52A1 ${e.serviceName} \u65AD\u5F00\u8FDE\u63A5\uFF0C\u539F\u56E0: ${e.reason||"\u672A\u77E5"}`);try{await this.refreshToolsCache(),await this.refreshCustomMCPHandlerPublic(),this.logger.info(`\u670D\u52A1 ${e.serviceName} \u65AD\u5F00\u8FDE\u63A5\u5904\u7406\u5B8C\u6210`)}catch(t){this.logger.error(`\u670D\u52A1 ${e.serviceName} \u65AD\u5F00\u8FDE\u63A5\u5904\u7406\u5931\u8D25:`,t)}}async handleServiceConnectionFailed(e){try{await this.refreshCustomMCPHandlerPublic()}catch(t){this.logger.error("\u5237\u65B0CustomMCPHandler\u5931\u8D25:",t)}}async handleServerToolsUpdated(e){this.logger.debug(`\u5904\u7406\u670D\u52A1 ${e.serviceName} \u7684serverTools\u914D\u7F6E\u66F4\u65B0`);try{let t=this.services.get(e.serviceName);if(t?.isConnected()){let r=t.getTools();this.toolSyncManager&&await this.toolSyncManager.syncToolsAfterConnection(e.serviceName,r),await this.refreshCustomMCPHandlerPublic(),this.logger.info(`\u670D\u52A1 ${e.serviceName} \u914D\u7F6E\u66F4\u65B0\u540C\u6B65\u5B8C\u6210`)}}catch(t){this.logger.error(`\u5904\u7406\u670D\u52A1 ${e.serviceName} \u914D\u7F6E\u66F4\u65B0\u5931\u8D25:`,t)}}async handleGeneralConfigUpdated(e){this.logger.info("\u5904\u7406\u901A\u7528\u914D\u7F6E\u66F4\u65B0\uFF0C\u68C0\u67E5\u6240\u6709\u5DF2\u8FDE\u63A5\u670D\u52A1");try{for(let[t,r]of this.services)if(r.isConnected()){let n=r.getTools();this.toolSyncManager&&await this.toolSyncManager.syncToolsAfterConnection(t,n)}await this.refreshCustomMCPHandlerPublic(),this.logger.info("\u901A\u7528\u914D\u7F6E\u66F4\u65B0\u540C\u6B65\u5B8C\u6210")}catch(t){this.logger.error("\u5904\u7406\u901A\u7528\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",t)}}async startAllServices(){this.logger.debug("[MCPManager] \u6B63\u5728\u542F\u52A8\u6240\u6709 MCP \u670D\u52A1...");try{this.customMCPHandler.initialize(),this.logger.debug("[MCPManager] CustomMCP \u5904\u7406\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(a){this.logger.error("[MCPManager] CustomMCP \u5904\u7406\u5668\u521D\u59CB\u5316\u5931\u8D25:",a)}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}this.logger.info(`[MCPManager] \u5F00\u59CB\u5E76\u884C\u542F\u52A8 ${e.length} \u4E2A MCP \u670D\u52A1`);let t=e.map(async([a])=>{try{return await this.startService(a),{serviceName:a,success:!0,error:null}}catch(g){return{serviceName:a,success:!1,error:g instanceof Error?g.message:String(g)}}}),r=await Promise.allSettled(t),n=0,s=0,o=[];for(let a of r)a.status==="fulfilled"?a.value.success?n++:(s++,o.push(a.value.serviceName)):s++;this.logger.info(`[MCPManager] \u670D\u52A1\u542F\u52A8\u5B8C\u6210 - \u6210\u529F: ${n}, \u5931\u8D25: ${s}`),o.length>0&&(this.logger.warn(`[MCPManager] \u4EE5\u4E0B\u670D\u52A1\u542F\u52A8\u5931\u8D25: ${o.join(", ")}`),s===e.length&&this.logger.warn("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u542F\u52A8\u5931\u8D25\uFF0C\u4F46\u7CFB\u7EDF\u5C06\u7EE7\u7EED\u8FD0\u884C\u4EE5\u4FBF\u91CD\u8BD5")),o.length>0&&this.scheduleFailedServicesRetry(o)}async startService(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 r=new X(t);await r.connect(),this.services.set(e,r),await this.refreshToolsCache();let n=r.getTools();this.logger.debug(`[MCPManager] ${e} \u670D\u52A1\u542F\u52A8\u6210\u529F\uFF0C\u52A0\u8F7D\u4E86 ${n.length} \u4E2A\u5DE5\u5177:`,n.map(s=>s.name).join(", "))}catch(r){throw this.logger.error(`[MCPManager] \u542F\u52A8 ${e} \u670D\u52A1\u5931\u8D25:`,r.message),this.services.delete(e),r}}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(r){throw this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,r.message),r}}async refreshToolsCache(){this.tools.clear();for(let[e,t]of this.services)if(t.isConnected()){let r=t.getTools(),n=this.configs[e];n&&this.cacheManager.writeCacheEntry(e,r,n).then(()=>{this.logger.debug(`[MCPManager] \u5DF2\u5C06 ${e} \u5DE5\u5177\u5217\u8868\u5199\u5165\u7F13\u5B58`)}).catch(s=>{this.logger.warn(`[MCPManager] \u5199\u5165\u7F13\u5B58\u5931\u8D25: ${e}, \u9519\u8BEF: ${s instanceof Error?s.message:String(s)}`)});for(let s of r){let o=`${e}__${s.name}`;this.tools.set(o,{serviceName:e,originalName:s.name,tool:s})}}await this.syncToolsConfigToFile()}getAllTools(){let e=[];for(let[r,n]of this.services)try{if(n.isConnected()){let s=n.getTools();for(let o of s)try{if(!f.isToolEnabled(r,o.name))continue;let g=`${r}__${o.name}`;e.push({name:g,description:o.description||"",inputSchema:o.inputSchema,serviceName:r,originalName:o.name})}catch(a){this.logger.warn(`[MCPManager] \u68C0\u67E5\u5DE5\u5177 ${r}.${o.name} \u542F\u7528\u72B6\u6001\u5931\u8D25\uFF0C\u8DF3\u8FC7\u8BE5\u5DE5\u5177:`,a)}}}catch(s){this.logger.warn(`[MCPManager] \u83B7\u53D6\u670D\u52A1 ${r} \u7684\u5DE5\u5177\u5931\u8D25\uFF0C\u8DF3\u8FC7\u8BE5\u670D\u52A1:`,s)}let t=[];try{t=this.customMCPHandler.getTools(),this.logger.debug(`[MCPManager] \u6210\u529F\u83B7\u53D6 ${t.length} \u4E2A customMCP \u5DE5\u5177`)}catch(r){this.logger.warn("[MCPManager] \u83B7\u53D6 CustomMCP \u5DE5\u5177\u5931\u8D25\uFF0C\u5C06\u53EA\u8FD4\u56DE\u6807\u51C6 MCP \u5DE5\u5177:",r),t=[]}for(let r of t)try{e.push({name:r.name,description:r.description||"",inputSchema:r.inputSchema,serviceName:this.getServiceNameForTool(r),originalName:r.name})}catch(n){this.logger.warn(`[MCPManager] \u5904\u7406 CustomMCP \u5DE5\u5177 ${r.name} \u5931\u8D25\uFF0C\u8DF3\u8FC7\u8BE5\u5DE5\u5177:`,n)}return this.logger.debug(`[MCPManager] \u6210\u529F\u83B7\u53D6 ${e.length} \u4E2A\u53EF\u7528\u5DE5\u5177`),e}getServiceNameForTool(e){return e.handler?.type==="mcp"?e.handler.config.serviceName:"customMCP"}getLogServerName(e){if(!e?.handler)return"custom";switch(e.handler.type){case"mcp":return e.handler.config.serviceName;case"coze":return"coze";case"dify":return"dify";case"n8n":return"n8n";default:return"custom"}}getOriginalToolName(e,t,r){return t?t.handler?.type==="mcp"?t.handler.config.toolName:e:r?.originalName||e}async callTool(e,t){let r=Date.now(),n="unknown",s=e;try{let o;if(this.customMCPHandler.hasTool(e)){let a=this.customMCPHandler.getToolInfo(e);n=this.getLogServerName(a),s=this.getOriginalToolName(e,a),a?.handler?.type==="mcp"?(o=await this.callMCPTool(e,a.handler.config,t),this.updateToolStatsSafe(e,a.handler.config.serviceName,a.handler.config.toolName,!0)):(o=await this.customMCPHandler.callTool(e,t),this.logger.info(`[MCPManager] CustomMCP \u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F`),this.updateToolStatsSafe(e,"customMCP",e,!0))}else{let a=this.tools.get(e);if(!a)throw new Error(`\u672A\u627E\u5230\u5DE5\u5177: ${e}`);n=a.serviceName,s=a.originalName;let g=this.services.get(a.serviceName);if(!g)throw new Error(`\u670D\u52A1 ${a.serviceName} \u4E0D\u53EF\u7528`);if(!g.isConnected())throw new Error(`\u670D\u52A1 ${a.serviceName} \u672A\u8FDE\u63A5`);o=await g.callTool(a.originalName,t||{}),this.logger.debug(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,o),this.updateToolStatsSafe(e,a.serviceName,a.originalName,!0)}return this.toolCallLogger.recordToolCall({toolName:s,serverName:n,arguments:t,result:o,success:o.isError!==!0,duration:Date.now()-r}),o}catch(o){if(this.toolCallLogger.recordToolCall({toolName:s,serverName:n,arguments:t,result:null,success:!1,duration:Date.now()-r,error:o instanceof Error?o.message:String(o)}),this.customMCPHandler.hasTool(e)){let a=this.customMCPHandler.getToolInfo(e);a?.handler?.type==="mcp"?this.updateToolStatsSafe(e,a.handler.config.serviceName,a.handler.config.toolName,!1):(this.updateToolStatsSafe(e,"customMCP",e,!1),this.logger.error(`[MCPManager] CustomMCP \u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,o.message))}else{let a=this.tools.get(e);a&&(this.updateToolStatsSafe(e,a.serviceName,a.originalName,!1),this.logger.error(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,o.message))}throw o}}async updateToolStats(e,t,r,n){try{let s=new Date().toISOString();n?(await this.updateCustomMCPToolStats(e,s),t!=="customMCP"&&await this.updateMCPServerToolStats(t,r,s),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0\u5DE5\u5177 ${e} \u7684\u7EDF\u8BA1\u4FE1\u606F`)):(await this.updateCustomMCPToolLastUsedTime(e,s),t!=="customMCP"&&await this.updateMCPServerToolLastUsedTime(t,r,s),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0\u5DE5\u5177 ${e} \u7684\u5931\u8D25\u8C03\u7528\u7EDF\u8BA1\u4FE1\u606F`))}catch(s){throw this.logger.error(`[MCPManager] \u66F4\u65B0\u5DE5\u5177 ${e} \u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25:`,s),s}}async updateToolStatsSafe(e,t,r,n){try{await this.updateToolStats(e,t,r,n)}catch(s){let o=n?"\u7EDF\u8BA1\u4FE1\u606F":"\u5931\u8D25\u7EDF\u8BA1\u4FE1\u606F";this.logger.warn(`[MCPManager] \u66F4\u65B0\u5DE5\u5177 ${e} ${o}\u5931\u8D25:`,s)}}async updateCustomMCPToolStats(e,t){try{await f.updateToolUsageStatsWithLock(e,!0),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0 customMCP \u5DE5\u5177 ${e} \u4F7F\u7528\u7EDF\u8BA1`)}catch(r){throw this.logger.error(`[MCPManager] \u66F4\u65B0 customMCP \u5DE5\u5177 ${e} \u7EDF\u8BA1\u5931\u8D25:`,r),r}}async updateCustomMCPToolLastUsedTime(e,t){try{await f.updateToolUsageStatsWithLock(e,!1),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0 customMCP \u5DE5\u5177 ${e} \u6700\u540E\u4F7F\u7528\u65F6\u95F4`)}catch(r){throw this.logger.error(`[MCPManager] \u66F4\u65B0 customMCP \u5DE5\u5177 ${e} \u6700\u540E\u4F7F\u7528\u65F6\u95F4\u5931\u8D25:`,r),r}}async updateMCPServerToolStats(e,t,r){try{await f.updateMCPServerToolStatsWithLock(e,t,r,!0),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0 MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u7EDF\u8BA1`)}catch(n){throw this.logger.error(`[MCPManager] \u66F4\u65B0 MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u7EDF\u8BA1\u5931\u8D25:`,n),n}}async updateMCPServerToolLastUsedTime(e,t,r){try{await f.updateMCPServerToolStatsWithLock(e,t,r,!1),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0 MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u6700\u540E\u4F7F\u7528\u65F6\u95F4`)}catch(n){throw this.logger.error(`[MCPManager] \u66F4\u65B0 MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u6700\u540E\u4F7F\u7528\u65F6\u95F4\u5931\u8D25:`,n),n}}async callMCPTool(e,t,r){let{serviceName:n,toolName:s}=t;this.logger.debug(`[MCPManager] \u8C03\u7528 MCP \u540C\u6B65\u5DE5\u5177 ${e} -> ${n}.${s}`);let o=this.services.get(n);if(!o)throw new Error(`\u670D\u52A1 ${n} \u4E0D\u53EF\u7528`);if(!o.isConnected())throw new Error(`\u670D\u52A1 ${n} \u672A\u8FDE\u63A5`);try{let a=await o.callTool(s,r||{});return this.logger.debug(`[MCPManager] MCP \u540C\u6B65\u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F`),a}catch(a){throw this.logger.error(`[MCPManager] MCP \u540C\u6B65\u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,a.message),a}}hasTool(e){return this.customMCPHandler.hasTool(e)?!0:this.tools.has(e)}async stopAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u505C\u6B62\u6240\u6709 MCP \u670D\u52A1..."),this.stopAllServiceRetries();for(let[e,t]of this.services)try{await t.disconnect(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(r){this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,r.message)}try{this.customMCPHandler.cleanup(),this.logger.info("[MCPManager] CustomMCP \u5904\u7406\u5668\u5DF2\u6E05\u7406")}catch(e){this.logger.error("[MCPManager] CustomMCP \u5904\u7406\u5668\u6E05\u7406\u5931\u8D25:",e)}try{f.clearAllStatsUpdateLocks(),this.logger.info("[MCPManager] \u7EDF\u8BA1\u66F4\u65B0\u9501\u5DF2\u6E05\u7406")}catch(e){this.logger.error("[MCPManager] \u6E05\u7406\u7EDF\u8BA1\u66F4\u65B0\u9501\u5931\u8D25:",e)}this.services.clear(),this.tools.clear(),this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u5DF2\u505C\u6B62")}getStatus(){let e=0,t=[];try{e=this.customMCPHandler.getToolCount(),t=this.customMCPHandler.getToolNames(),this.logger.debug(`[MCPManager] \u6210\u529F\u83B7\u53D6 customMCP \u72B6\u6001: ${e} \u4E2A\u5DE5\u5177`)}catch(a){this.logger.warn("[MCPManager] \u83B7\u53D6 CustomMCP \u72B6\u6001\u5931\u8D25\uFF0C\u5C06\u53EA\u5305\u542B\u6807\u51C6 MCP \u5DE5\u5177:",a),e=0,t=[]}let r=this.tools.size+e,s=[...Array.from(this.tools.keys()),...t],o={services:{},totalTools:r,availableTools:s};for(let[a,g]of this.services){let u=g.getStatus();o.services[a]={connected:u.connected,clientName:`xiaozhi-${a}-client`}}return e>0&&(o.services.customMCP={connected:!0,clientName:"xiaozhi-customMCP-handler"}),o}getStatsUpdateInfo(){try{let e=f.getStatsUpdateLocks();return{activeLocks:e,totalLocks:e.length}}catch(e){return this.logger.warn("[MCPManager] \u83B7\u53D6\u7EDF\u8BA1\u66F4\u65B0\u76D1\u63A7\u4FE1\u606F\u5931\u8D25:",e),{activeLocks:[],totalLocks:0}}}getService(e){return this.services.get(e)}getConnectedServices(){let e=[];for(let[t,r]of this.services)r.isConnected()&&e.push(t);return e}async refreshCustomMCPHandler(){try{this.logger.debug("\u91CD\u65B0\u521D\u59CB\u5316CustomMCPHandler"),await this.customMCPHandler.reinitialize(),this.logger.debug("CustomMCPHandler\u91CD\u65B0\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("CustomMCPHandler\u91CD\u65B0\u521D\u59CB\u5316\u5931\u8D25:",e),e}}async refreshCustomMCPHandlerPublic(){return this.refreshCustomMCPHandler()}getAllServices(){return new Map(this.services)}getCustomMCPHandler(){return this.customMCPHandler}hasCustomMCPTool(e){try{return this.customMCPHandler.hasTool(e)}catch(t){return this.logger.warn(`[MCPManager] \u68C0\u67E5 CustomMCP \u5DE5\u5177 ${e} \u662F\u5426\u5B58\u5728\u5931\u8D25:`,t),!1}}getCustomMCPTools(){try{return this.customMCPHandler.getTools()}catch(e){return this.logger.warn("[MCPManager] \u83B7\u53D6 CustomMCP \u5DE5\u5177\u5217\u8868\u5931\u8D25\uFF0C\u8FD4\u56DE\u7A7A\u6570\u7EC4:",e),[]}}enhanceServiceConfig(e){let t={...e};try{if(e.type==="sse"&&e.url&&e.url.includes("modelscope")){let r=f.getModelScopeApiKey();if(r)t.apiKey=r,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(r){throw this.logger.error(`[MCPManager] \u914D\u7F6E\u589E\u5F3A\u5931\u8D25: ${e.name}`,r),r}}addServiceConfig(e,t){let r,n;if(typeof e=="string"&&t)n=e,r=t;else if(typeof e=="object")n=e.name,r=e;else throw new Error("Invalid arguments for addServiceConfig");let s=this.enhanceServiceConfig(r);this.configs[n]=s,this.logger.debug(`[MCPManager] \u5DF2\u6DFB\u52A0\u670D\u52A1\u914D\u7F6E: ${n}`)}updateServiceConfig(e,t){let r=this.enhanceServiceConfig(t);this.configs[e]=r,this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0\u5E76\u589E\u5F3A\u670D\u52A1\u914D\u7F6E: ${e}`)}removeServiceConfig(e){delete this.configs[e],this.logger.debug(`[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=f.getMcpServerConfig();for(let[t,r]of this.services){if(!r.isConnected())continue;let n=r.getTools();if(n.length===0)continue;let s=e[t]?.tools||{},o={};for(let h of n){let S=s[h.name];S?o[h.name]={...S,description:h.description||S.description||""}:o[h.name]={description:h.description||"",enable:!0}}let a=n.map(h=>h.name),u=Object.keys(s).filter(h=>!a.includes(h));if(u.length>0&&this.logger.info(`[MCPManager] \u68C0\u6D4B\u5230\u670D\u52A1 ${t} \u79FB\u9664\u4E86 ${u.length} \u4E2A\u5DE5\u5177: ${u.join(", ")}`),this.hasToolsConfigChanged(s,o)){f.updateServerToolsConfig(t,o);let h=Object.keys(o).filter(T=>!s[T]),S=Object.keys(o).filter(T=>{let y=s[T],I=o[T];return y&&y.description!==I.description});this.logger.debug(`[MCPManager] \u5DF2\u540C\u6B65\u670D\u52A1 ${t} \u7684\u5DE5\u5177\u914D\u7F6E:`),h.length>0&&this.logger.debug(` - \u65B0\u589E\u5DE5\u5177: ${h.join(", ")}`),S.length>0&&this.logger.debug(` - \u66F4\u65B0\u5DE5\u5177: ${S.join(", ")}`),u.length>0&&this.logger.debug(` - \u79FB\u9664\u5DE5\u5177: ${u.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 r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!0;let s=n.filter(a=>!r.includes(a)),o=r.filter(a=>!n.includes(a));if(s.length>0||o.length>0)return!0;for(let a of r){let g=e[a],u=t[a];if(g.description!==u.description)return!0}return!1}scheduleFailedServicesRetry(e){if(e.length===0)return;this.logger.info(`[MCPManager] \u5B89\u6392 ${e.length} \u4E2A\u5931\u8D25\u670D\u52A1\u7684\u91CD\u8BD5`);let t=3e4;for(let r of e)this.failedServices.add(r),this.scheduleServiceRetry(r,t)}scheduleServiceRetry(e,t){let r=this.retryTimers.get(e);r&&(clearTimeout(r),this.retryTimers.delete(e)),this.logger.debug(`[MCPManager] \u5B89\u6392\u670D\u52A1 ${e} \u5728 ${t}ms \u540E\u91CD\u8BD5`);let n=setTimeout(async()=>{this.retryTimers.delete(e),await this.retryFailedService(e)},t);this.retryTimers.set(e,n)}async retryFailedService(e){if(this.failedServices.has(e))try{await this.startService(e),this.failedServices.delete(e),this.logger.info(`[MCPManager] \u670D\u52A1 ${e} \u91CD\u8BD5\u542F\u52A8\u6210\u529F`);try{await this.refreshCustomMCPHandlerPublic()}catch(t){this.logger.error("[MCPManager] \u5237\u65B0CustomMCPHandler\u5931\u8D25:",t)}}catch(t){this.logger.error(`[MCPManager] \u670D\u52A1 ${e} \u91CD\u8BD5\u542F\u52A8\u5931\u8D25:`,t.message);let r=this.getRetryDelay(e),n=Math.min(r*2,3e5);this.logger.debug(`[MCPManager] \u670D\u52A1 ${e} \u4E0B\u6B21\u91CD\u8BD5\u5C06\u5728 ${n}ms \u540E\u8FDB\u884C`),this.scheduleServiceRetry(e,n)}}getRetryDelay(e){return 3e4+e.split("").reduce((r,n)=>r+n.charCodeAt(0),0)%6e4}stopServiceRetry(e){let t=this.retryTimers.get(e);t&&(clearTimeout(t),this.retryTimers.delete(e),this.logger.debug(`[MCPManager] \u5DF2\u505C\u6B62\u670D\u52A1 ${e} \u7684\u91CD\u8BD5`)),this.failedServices.delete(e)}stopAllServiceRetries(){this.logger.info("[MCPManager] \u505C\u6B62\u6240\u6709\u670D\u52A1\u91CD\u8BD5");for(let[e,t]of this.retryTimers)clearTimeout(t),this.logger.debug(`[MCPManager] \u5DF2\u505C\u6B62\u670D\u52A1 ${e} \u7684\u91CD\u8BD5`);this.retryTimers.clear(),this.failedServices.clear()}getFailedServices(){return Array.from(this.failedServices)}isServiceFailed(e){return this.failedServices.has(e)}getRetryStats(){return{failedServices:Array.from(this.failedServices),activeRetries:Array.from(this.retryTimers.keys()),totalFailed:this.failedServices.size,totalActiveRetries:this.retryTimers.size}}};var x=class{static{l(this,"TransportAdapter")}logger;messageHandler;connectionId;config;state="disconnected";constructor(e,t){this.messageHandler=e,this.config=t,this.connectionId=this.generateConnectionId(),this.logger=c}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);t!==null?(this.logger.debug("\u53D1\u9001\u54CD\u5E94\u6D88\u606F:",t),await this.sendMessage(t)):this.logger.debug("\u6536\u5230\u901A\u77E5\u6D88\u606F\uFF0C\u65E0\u9700\u54CD\u5E94")}catch(t){this.logger.error(`\u5904\u7406\u6D88\u606F\u65F6\u51FA\u9519: ${e.method}`,t);let r=this.createErrorResponse(t,e.id);await this.sendMessage(r)}}createErrorResponse(e,t){let r=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?r=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(r=-32602),{jsonrpc:"2.0",error:{code:r,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 r=t instanceof Error?t.message:String(t);throw new Error(`\u6D88\u606F\u5E8F\u5217\u5316\u5931\u8D25: ${r}`)}}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((r,n)=>{setTimeout(()=>{n(new Error(`\u64CD\u4F5C\u8D85\u65F6: ${t}ms`))},t)})])}};var Se=class{static{l(this,"ToolRegistry")}serviceManager;logger;constructor(e){this.serviceManager=e,this.logger=c}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(r=>r.name===e)||null}hasTool(e){return this.findTool(e)!==null}},Te=class extends He{static{l(this,"ConnectionManager")}connections=new Map;logger;constructor(){super(),this.logger=c}async initialize(){this.logger.info("\u521D\u59CB\u5316\u8FDE\u63A5\u7BA1\u7406\u5668")}registerConnection(e,t,r){let n={id:e,transportName:t,state:r,connectedAt:new Date,lastActivity:new Date};this.connections.set(e,n),this.emit("connectionRegistered",n),this.logger.debug(`\u8FDE\u63A5\u5DF2\u6CE8\u518C: ${e} (${t})`)}updateConnectionState(e,t){let r=this.connections.get(e);r&&(r.state=t,r.lastActivity=new Date,this.emit("connectionStateChanged",r),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")}},se=class extends He{static{l(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=c,this.serviceManager=new ne,this.messageHandler=new K(this.serviceManager),this.toolRegistry=new Se(this.serviceManager),this.connectionManager=new Te,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.debug("\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(r){throw this.logger.error(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5931\u8D25`,r),r}}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(r){throw this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u542F\u52A8\u5931\u8D25`,r),r}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(r){this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u5931\u8D25`,r)}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}};import{randomUUID as wt}from"crypto";import Pe from"express";var oe=class extends x{static{l(this,"HTTPAdapter")}app;server=null;clients=new Map;port;host;enableSSE;enableRPC;corsOrigin;maxClients;constructor(e,t={name:"http"}){super(e,t),console.warn("[\u5DF2\u5E9F\u5F03] HTTPAdapter \u5C06\u5728 v2.0.0 \u4E2D\u79FB\u9664\u3002\u8BF7\u4F7F\u7528 WebServer \u7684 /mcp \u7AEF\u70B9\u66FF\u4EE3\u3002"),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=Pe(),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",r=>{this.logger.error("HTTP \u670D\u52A1\u5668\u9519\u8BEF",r),this.setState("error"),t(r)})})}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(Pe.json({limit:"10mb"})),this.app.use(Pe.urlencoded({extended:!0})),this.app.use((e,t,r)=>{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"),r()}),this.app.use((e,t,r)=>{this.logger.debug(`${e.method} ${e.path}`,{query:e.query,headers:e.headers}),r()})}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 r=Date.now().toString(),n=wt();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 s={id:r,sessionId:n,response:t,connectedAt:new Date};this.clients.set(n,s),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u8FDE\u63A5: ${r} (\u4F1A\u8BDD: ${n})`),t.write(`event: endpoint
30
- data: /messages?sessionId=${n}
24
+ 3. \u5982\u679C\u957F\u65F6\u95F4\u672A\u5B8C\u6210\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458`}l(Re,"getDefaultTimeoutMessage");import{createHash as et}from"crypto";import{existsSync as B,mkdirSync as tt,readFileSync as $e,renameSync as rt,writeFileSync as xe}from"fs";import{dirname as st,resolve as ke}from"path";import{Hono as mr}from"hono";import ot from"dayjs";var N=class{static{l(this,"MCPCacheManager")}cachePath;logger;CACHE_VERSION="1.0.0";CACHE_ENTRY_VERSION="1.0.0";cleanupInterval;CLEANUP_INTERVAL=6e4;constructor(e){this.logger=c,this.cachePath=e||this.getCacheFilePath(),this.startCleanupTimer()}formatTimestamp(){return ot().format("YYYY-MM-DD HH:mm:ss")}getCacheFilePath(){try{let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return ke(e,"xiaozhi.cache.json")}catch{let t=process.env.XIAOZHI_CONFIG_DIR||"/tmp";return ke(t,"xiaozhi.cache.json")}}async ensureCacheFile(){try{if(!B(this.cachePath)){let e=st(this.cachePath);B(e)||(tt(e,{recursive:!0}),this.logger.debug(`[CacheManager] \u5DF2\u521B\u5EFA\u7F13\u5B58\u76EE\u5F55: ${e}`)),this.logger.debug("[CacheManager] \u7F13\u5B58\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u521B\u5EFA\u521D\u59CB\u7F13\u5B58\u6587\u4EF6");let t=await this.createInitialCache();await this.saveCache(t),this.logger.info(`[CacheManager] \u5DF2\u521B\u5EFA\u7F13\u5B58\u6587\u4EF6: ${this.cachePath}`)}}catch(e){this.logger.warn(`[CacheManager] \u521B\u5EFA\u7F13\u5B58\u6587\u4EF6\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}async createInitialCache(){let e=this.formatTimestamp();return{version:this.CACHE_VERSION,mcpServers:{},metadata:{lastGlobalUpdate:e,totalWrites:0,createdAt:e}}}async writeCacheEntry(e,t,r){try{this.logger.debug(`[CacheManager] \u5F00\u59CB\u5199\u5165\u7F13\u5B58: ${e}`),await this.ensureCacheFile();let s=await this.loadExistingCache(),o=this.generateConfigHash(r),n={tools:t.map(a=>({name:a.name,description:a.description||"",inputSchema:a.inputSchema})),lastUpdated:this.formatTimestamp(),serverConfig:{...r},configHash:o,version:this.CACHE_ENTRY_VERSION};s.mcpServers[e]=n,s.metadata.lastGlobalUpdate=this.formatTimestamp(),s.metadata.totalWrites+=1,await this.saveCache(s),this.logger.debug(`[CacheManager] \u7F13\u5B58\u5199\u5165\u6210\u529F: ${e}, \u5DE5\u5177\u6570\u91CF: ${t.length}`)}catch(s){this.logger.warn(`[CacheManager] \u7F13\u5B58\u5199\u5165\u5931\u8D25: ${e}, \u9519\u8BEF: ${s instanceof Error?s.message:String(s)}`)}}async loadExistingCache(){try{if(!B(this.cachePath))return await this.createInitialCache();let e=$e(this.cachePath,"utf8"),t=JSON.parse(e);return this.validateCacheStructure(t)?t:(this.logger.warn("[CacheManager] \u7F13\u5B58\u6587\u4EF6\u7ED3\u6784\u65E0\u6548\uFF0C\u91CD\u65B0\u521B\u5EFA"),await this.createInitialCache())}catch(e){return this.logger.warn(`[CacheManager] \u52A0\u8F7D\u7F13\u5B58\u5931\u8D25\uFF0C\u521B\u5EFA\u65B0\u7F13\u5B58: ${e instanceof Error?e.message:String(e)}`),await this.createInitialCache()}}async saveCache(e){let t=JSON.stringify(e,null,2);await this.atomicWrite(this.cachePath,t)}async atomicWrite(e,t){let r=`${e}.tmp`;try{xe(r,t,"utf8"),rt(r,e)}catch(s){try{B(r)&&xe(r,"","utf8")}catch{}throw s}}generateConfigHash(e){try{return et("sha256").update(JSON.stringify(e)).digest("hex")}catch(t){return this.logger.warn(`[CacheManager] \u751F\u6210\u914D\u7F6E\u54C8\u5E0C\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`),""}}validateCacheStructure(e){try{return e&&typeof e=="object"&&typeof e.version=="string"&&typeof e.mcpServers=="object"&&e.metadata&&typeof e.metadata=="object"&&typeof e.metadata.lastGlobalUpdate=="string"&&typeof e.metadata.totalWrites=="number"&&typeof e.metadata.createdAt=="string"}catch{return!1}}async getStats(){try{let e=await this.loadExistingCache();return{totalWrites:e.metadata.totalWrites,lastUpdate:e.metadata.lastGlobalUpdate,serverCount:Object.keys(e.mcpServers).length,cacheFileSize:B(this.cachePath)?$e(this.cachePath,"utf8").length:0}}catch(e){return this.logger.warn(`[CacheManager] \u83B7\u53D6\u7F13\u5B58\u7EDF\u8BA1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),null}}getFilePath(){return this.cachePath}async getAllCachedTools(){try{let e=await this.loadExistingCache(),t=[];for(let[r,s]of Object.entries(e.mcpServers))for(let o of s.tools)t.push({...o,name:`${r}__${o.name}`});return this.logger.debug(`[CacheManager] \u83B7\u53D6\u5230\u6240\u6709\u7F13\u5B58\u5DE5\u5177\uFF0C\u5171 ${t.length} \u4E2A`),t}catch(e){return this.logger.warn(`[CacheManager] \u83B7\u53D6\u6240\u6709\u7F13\u5B58\u5DE5\u5177\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),[]}}async writeCustomMCPResult(e,t,r,s="completed",o,n=3e5){try{let a=await this.loadExtendedCache(),g=w(e,t),u={result:r,timestamp:new Date().toISOString(),ttl:n,status:s,consumed:!1,taskId:o,retryCount:0};a.customMCPResults||(a.customMCPResults={}),a.customMCPResults[g]=u,await this.saveExtendedCache(a),this.logger.debug(`[CacheManager] \u5199\u5165CustomMCP\u7ED3\u679C\u7F13\u5B58: ${e}, \u72B6\u6001: ${s}`)}catch(a){this.logger.warn(`[CacheManager] \u5199\u5165CustomMCP\u7ED3\u679C\u7F13\u5B58\u5931\u8D25: ${a instanceof Error?a.message:String(a)}`)}}async readCustomMCPResult(e,t){try{let r=await this.loadExtendedCache(),s=w(e,t);if(!r.customMCPResults||!r.customMCPResults[s])return null;let o=r.customMCPResults[s],n=Date.now(),a=new Date(o.timestamp).getTime();return n-a>o.ttl?(this.logger.debug(`[CacheManager] \u7F13\u5B58\u5DF2\u8FC7\u671F: ${e}`),null):o}catch(r){return this.logger.warn(`[CacheManager] \u8BFB\u53D6CustomMCP\u7ED3\u679C\u7F13\u5B58\u5931\u8D25: ${r instanceof Error?r.message:String(r)}`),null}}async updateCustomMCPStatus(e,t,r,s,o){try{let n=await this.loadExtendedCache(),a=w(e,t);if(!n.customMCPResults||!n.customMCPResults[a])return!1;let g=n.customMCPResults[a],u=g.status;return g.status=r,g.timestamp=new Date().toISOString(),s&&(g.result=s),o&&r==="failed"&&(g.result={content:[{type:"text",text:`\u4EFB\u52A1\u5931\u8D25: ${o}`}]},g.consumed=!0),r==="completed"&&(g.consumed=!1),await this.saveExtendedCache(n),this.logger.debug(`[CacheManager] \u66F4\u65B0\u7F13\u5B58\u72B6\u6001: ${e} ${u} -> ${r}`),!0}catch(n){return this.logger.warn(`[CacheManager] \u66F4\u65B0CustomMCP\u7F13\u5B58\u72B6\u6001\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),!1}}async markCustomMCPAsConsumed(e,t){try{let r=await this.loadExtendedCache(),s=w(e,t);if(!r.customMCPResults||!r.customMCPResults[s])return!1;let o=r.customMCPResults[s];return o.consumed||(o.consumed=!0,o.timestamp=new Date().toISOString(),await this.saveExtendedCache(r),this.logger.debug(`[CacheManager] \u6807\u8BB0\u7F13\u5B58\u4E3A\u5DF2\u6D88\u8D39: ${e}`)),!0}catch(r){return this.logger.warn(`[CacheManager] \u6807\u8BB0CustomMCP\u7F13\u5B58\u4E3A\u5DF2\u6D88\u8D39\u5931\u8D25: ${r instanceof Error?r.message:String(r)}`),!1}}async deleteCustomMCPResult(e,t){try{let r=await this.loadExtendedCache(),s=w(e,t);return!r.customMCPResults||!r.customMCPResults[s]?!1:(delete r.customMCPResults[s],await this.saveExtendedCache(r),this.logger.debug(`[CacheManager] \u5220\u9664\u7F13\u5B58\u6761\u76EE: ${e}`),!0)}catch(r){return this.logger.warn(`[CacheManager] \u5220\u9664CustomMCP\u7F13\u5B58\u6761\u76EE\u5931\u8D25: ${r instanceof Error?r.message:String(r)}`),!1}}async cleanupCustomMCPResults(){try{let e=await this.loadExtendedCache();if(!e.customMCPResults)return{cleaned:0,total:0};let t=Object.entries(e.customMCPResults),r=0;for(let[s,o]of t)x(o)&&(delete e.customMCPResults[s],r++);return r>0&&(await this.saveExtendedCache(e),this.logger.info(`[CacheManager] \u6E05\u7406CustomMCP\u7F13\u5B58: ${r}/${t.length}`)),{cleaned:r,total:t.length}}catch(e){return this.logger.warn(`[CacheManager] \u6E05\u7406CustomMCP\u7F13\u5B58\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),{cleaned:0,total:0}}}async getCustomMCPStatistics(){try{let e=await this.loadExtendedCache();if(!e.customMCPResults)return{totalEntries:0,pendingTasks:0,completedTasks:0,failedTasks:0,consumedEntries:0,cacheHitRate:0,lastCleanupTime:new Date().toISOString(),memoryUsage:0};let t=Object.values(e.customMCPResults),r=t.length,s=t.filter(p=>p.status==="pending").length,o=t.filter(p=>p.status==="completed").length,n=t.filter(p=>p.status==="failed").length,a=t.filter(p=>p.consumed).length,g=o>0?a/o*100:0,u=JSON.stringify(e.customMCPResults).length;return{totalEntries:r,pendingTasks:s,completedTasks:o,failedTasks:n,consumedEntries:a,cacheHitRate:g,lastCleanupTime:new Date().toISOString(),memoryUsage:u}}catch(e){return this.logger.warn(`[CacheManager] \u83B7\u53D6CustomMCP\u7F13\u5B58\u7EDF\u8BA1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),{totalEntries:0,pendingTasks:0,completedTasks:0,failedTasks:0,consumedEntries:0,cacheHitRate:0,lastCleanupTime:new Date().toISOString(),memoryUsage:0}}}async loadExtendedCache(){try{return await this.loadExistingCache()}catch(e){return this.logger.warn(`[CacheManager] \u52A0\u8F7D\u6269\u5C55\u7F13\u5B58\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),{version:this.CACHE_VERSION,mcpServers:{},metadata:{lastGlobalUpdate:this.formatTimestamp(),totalWrites:0,createdAt:this.formatTimestamp()},customMCPResults:{}}}}async saveExtendedCache(e){await this.saveCache(e)}startCleanupTimer(){this.cleanupInterval=setInterval(()=>{this.cleanupCustomMCPResults().catch(e=>{this.logger.warn(`[CacheManager] \u81EA\u52A8\u6E05\u7406\u5931\u8D25: ${e}`)})},this.CLEANUP_INTERVAL),this.logger.debug(`[CacheManager] \u542F\u52A8\u6E05\u7406\u5B9A\u65F6\u5668\uFF0C\u95F4\u9694: ${this.CLEANUP_INTERVAL}ms`)}stopCleanupTimer(){this.cleanupInterval&&(clearInterval(this.cleanupInterval),this.cleanupInterval=void 0,this.logger.debug("[CacheManager] \u505C\u6B62\u6E05\u7406\u5B9A\u65F6\u5668"))}cleanup(){this.stopCleanupTimer(),this.logger.debug("[CacheManager] \u6E05\u7406\u8D44\u6E90\u5B8C\u6210")}};var Q=class{static{l(this,"CustomMCPHandler")}logger;tools=new Map;cacheManager;cacheLifecycleManager;taskStateManager;mcpServiceManager;TIMEOUT=E.TIMEOUT;CACHE_TTL=E.CACHE_TTL;CLEANUP_INTERVAL=E.CLEANUP_INTERVAL;cleanupTimer;activeTasks=new Map;eventBus=b();constructor(e,t){this.logger=c,this.cacheManager=e||new N,this.mcpServiceManager=t,this.cacheLifecycleManager=new q(this.logger),this.taskStateManager=new Y(this.logger),this.startCleanupTimer(),this.cacheLifecycleManager.startAutoCleanup(),this.setupEventListeners()}setupEventListeners(){this.eventBus.onEvent("config:updated",async e=>{await this.handleConfigUpdated(e)})}async handleConfigUpdated(e){this.logger.debug("[CustomMCP] \u68C0\u6D4B\u5230\u914D\u7F6E\u66F4\u65B0\uFF0C\u68C0\u67E5\u662F\u5426\u9700\u8981\u91CD\u65B0\u521D\u59CB\u5316");try{e.type==="customMCP"?(this.logger.debug("[CustomMCP] customMCP \u914D\u7F6E\u5DF2\u66F4\u65B0\uFF0C\u91CD\u65B0\u521D\u59CB\u5316\u5904\u7406\u5668"),await this.reinitialize()):e.type==="serverTools"&&(this.logger.debug("[CustomMCP] serverTools \u914D\u7F6E\u5DF2\u66F4\u65B0\uFF0C\u91CD\u65B0\u521D\u59CB\u5316\u5904\u7406\u5668"),await this.reinitialize())}catch(t){this.logger.error("[CustomMCP] \u914D\u7F6E\u66F4\u65B0\u5904\u7406\u5931\u8D25:",t)}}async reinitialize(){try{this.logger.debug("[CustomMCP] \u5F00\u59CB\u91CD\u65B0\u521D\u59CB\u5316\u5904\u7406\u5668"),this.tools.clear();let e=f.getCustomMCPTools();for(let t of e)this.tools.set(t.name,t),this.logger.debug(`[CustomMCP] \u91CD\u65B0\u52A0\u8F7D\u5DE5\u5177: ${t.name} (${t.handler.type})`);this.logger.debug(`[CustomMCP] \u91CD\u65B0\u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u5171\u52A0\u8F7D ${this.tools.size} \u4E2A\u5DE5\u5177`)}catch(e){throw this.logger.error("[CustomMCP] \u91CD\u65B0\u521D\u59CB\u5316\u5931\u8D25:",e),e}}initialize(e){this.logger.debug("[CustomMCP] \u521D\u59CB\u5316 CustomMCP \u5904\u7406\u5668...");try{let t=e||f.getCustomMCPTools();this.tools.clear();for(let r of t)this.tools.set(r.name,r),this.logger.debug(`[CustomMCP] \u5DF2\u52A0\u8F7D\u5DE5\u5177: ${r.name} (${r.handler.type})`);this.logger.debug(`[CustomMCP] \u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u5171\u52A0\u8F7D ${this.tools.size} \u4E2A\u5DE5\u5177`)}catch(t){throw this.logger.error("[CustomMCP] \u521D\u59CB\u5316\u5931\u8D25:",t),t}}getTools(){return Array.from(this.tools.values()).map(e=>({name:e.name,description:e.description,inputSchema:e.inputSchema}))}hasTool(e){return this.tools.has(e)}getToolCount(){return this.tools.size}getToolNames(){return Array.from(this.tools.keys())}async callTool(e,t,r){if(!this.tools.get(e))throw new Error(`\u672A\u627E\u5230\u5DE5\u5177: ${e}`);let o=await this.getCompletedResult(e,t);if(o)return this.logger.debug(`[CustomMCP] \u8FD4\u56DE\u5DF2\u5B8C\u6210\u7684\u4EFB\u52A1\u7ED3\u679C: ${e}`),await this.clearConsumedCache(e,t),o;try{let n=await Promise.race([this.executeToolWithBackgroundProcessing(e,t),this.createTimeoutPromise(e,t)]);return await this.cacheResult(e,t,n),n}catch(n){if(n instanceof W){let a=await this.generateTaskId(e,t);return this.logger.info(`[CustomMCP] \u5DE5\u5177\u8D85\u65F6\uFF0C\u8FD4\u56DE\u53CB\u597D\u63D0\u793A: ${e}, taskId: ${a}`),Ee(a,e)}throw n}}async executeToolWithBackgroundProcessing(e,t){let r=this.tools.get(e);if(!r)throw new Error(`\u5DE5\u5177\u4E0D\u5B58\u5728: ${e}`);let s=await this.generateTaskId(e,t);await this.markTaskAsPending(s,e,t);try{let o=await this.callToolByType(r,t);return await this.markTaskAsCompleted(s,o),o}catch(o){let n=o instanceof Error?o:new Error(String(o));throw await this.markTaskAsFailed(s,n),o}}async createTimeoutPromise(e,t){return new Promise((r,s)=>{setTimeout(()=>{s(new W(`\u5DE5\u5177\u8C03\u7528\u8D85\u65F6: ${e}`))},this.TIMEOUT)})}async getCompletedResult(e,t){try{let r=this.generateCacheKey(e,t),s=await this.loadExtendedCache();if(!s.customMCPResults||!s.customMCPResults[r])return null;let o=s.customMCPResults[r];return o.status==="completed"&&!o.consumed&&!D(o.timestamp,o.ttl)?o.result:null}catch(r){return this.logger.warn(`[CustomMCP] \u83B7\u53D6\u7F13\u5B58\u5931\u8D25: ${r}`),null}}async callToolByType(e,t){switch(e.handler.type){case"proxy":return await this.callProxyTool(e,t);case"function":return await this.callFunctionTool(e,t);case"http":return await this.callHttpTool(e,t);case"script":return await this.callScriptTool(e,t);case"chain":return await this.callChainTool(e,t);case"mcp":try{return await this.forwardToMCPServiceManager(e,t)}catch(r){this.logger.error(`[CustomMCP] MCP \u7C7B\u578B\u5DE5\u5177\u8DEF\u7531\u5931\u8D25: ${e.name}`,r);let s=r instanceof Error?r.message:"MCP \u7C7B\u578B\u5DE5\u5177\u8DEF\u7531\u9519\u8BEF";return{content:[{type:"text",text:s.includes("MCPServiceManager \u672A\u521D\u59CB\u5316")?s:"\u5185\u90E8\u9519\u8BEF\uFF1AMCP \u7C7B\u578B\u5DE5\u5177\u8DEF\u7531\u9519\u8BEF"}],isError:!0}}default:{let r=e.handler.type;throw new Error(`\u4E0D\u652F\u6301\u7684\u5904\u7406\u5668\u7C7B\u578B: ${r}`)}}}async forwardToMCPServiceManager(e,t){if(!this.mcpServiceManager)throw this.logger.error(`[CustomMCP] MCPServiceManager \u672A\u521D\u59CB\u5316\uFF0C\u65E0\u6CD5\u8F6C\u53D1\u5DE5\u5177 ${e.name} \u7684\u8C03\u7528`),new Error("MCPServiceManager \u672A\u521D\u59CB\u5316");let r=e.handler;this.logger.info(`[CustomMCP] \u8F6C\u53D1MCP\u5DE5\u5177\u8C03\u7528: ${e.name}`,{serviceName:r.config.serviceName,toolName:r.config.toolName});try{let s=await this.mcpServiceManager.callTool(r.config.toolName,t);return this.logger.info(`[CustomMCP] MCP\u5DE5\u5177\u8F6C\u53D1\u6210\u529F: ${e.name}`),s}catch(s){return this.logger.error(`[CustomMCP] MCP\u5DE5\u5177\u8F6C\u53D1\u5931\u8D25: ${e.name}`,s),{content:[{type:"text",text:`MCP\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}}async callProxyTool(e,t){let r=e.handler;if(this.logger.info(`[CustomMCP] \u8C03\u7528\u4EE3\u7406\u5DE5\u5177: ${e.name}`,{platform:r.platform,config:r.config}),r.platform==="coze")return await this.callCozeWorkflow(e,t);throw new Error(`\u4E0D\u652F\u6301\u7684\u4EE3\u7406\u5E73\u53F0: ${r.platform}`)}async callCozeWorkflow(e,t){let s=e.handler.config;this.logger.info(`[CustomMCP] \u8C03\u7528 Coze \u5DE5\u4F5C\u6D41: ${e.name}`,{workflow_id:s.workflow_id,bot_id:s.bot_id});try{let o=this.buildCozeRequest(s,t),n=await this.sendCozeRequest(s,o);return this.logger.info(`[CustomMCP] Coze \u5DE5\u4F5C\u6D41\u8C03\u7528\u6210\u529F: ${e.name}`,{response:n}),this.processCozeResponse(e.name,n)}catch(o){return this.logger.error(`[CustomMCP] Coze \u5DE5\u4F5C\u6D41\u8C03\u7528\u5931\u8D25: ${e.name}`,o),{content:[{type:"text",text:`Coze \u5DE5\u4F5C\u6D41\u8C03\u7528\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`}],isError:!0}}}buildCozeRequest(e,t){return{workflow_id:e.workflow_id,parameters:{...t}}}async sendCozeRequest(e,t){let r=e.base_url||"https://api.coze.cn",s="",o=f.getConfig().platforms?.coze?.token;if(!o)throw new Error("Coze Token \u914D\u7F6E\u4E0D\u5B58\u5728");if(e.workflow_id)s="/v1/workflow/run",t.workflow_id=e.workflow_id;else if(e.bot_id)s="/v3/chat",t.bot_id=e.bot_id;else throw new Error("Coze \u914D\u7F6E\u5FC5\u987B\u63D0\u4F9B workflow_id \u6216 bot_id");let n=`${r}${s}`,a=e.timeout||3e5,g={"Content-Type":"application/json",Authorization:`Bearer ${o}`,...e.headers};this.logger.debug(`[CustomMCP] \u53D1\u9001 Coze \u8BF7\u6C42\u5230: ${n}`,{headers:{...g},body:t});let u=new AbortController,p=setTimeout(()=>u.abort(),a);try{let h=await fetch(n,{method:"POST",headers:g,body:JSON.stringify(t)});if(clearTimeout(p),!h.ok){let S=await h.text();throw new Error(`Coze API \u8BF7\u6C42\u5931\u8D25 (${h.status}): ${S}`)}let T=await h.json();return this.logger.debug("[CustomMCP] Coze API \u54CD\u5E94:",T),T}catch(h){throw clearTimeout(p),h instanceof Error&&h.name==="AbortError"?new Error(`Coze API \u8BF7\u6C42\u8D85\u65F6 (${a}ms)`):h}}processCozeResponse(e,t){try{return t.data?{content:[{type:"text",text:t.data}],isError:!1}:{content:[{type:"text",text:JSON.stringify(t,null,2)}],isError:!1}}catch(r){return this.logger.error(`[CustomMCP] \u5904\u7406 Coze \u54CD\u5E94\u5931\u8D25: ${e}`,r),{content:[{type:"text",text:`\u5904\u7406\u54CD\u5E94\u5931\u8D25: ${r instanceof Error?r.message:String(r)}`}],isError:!0}}}async callFunctionTool(e,t){let r=e.handler;this.logger.info(`[CustomMCP] \u8C03\u7528\u51FD\u6570\u5DE5\u5177: ${e.name}`,{module:r.module,function:r.function});try{let s=await this.loadModule(r.module),o=this.getFunction(s,r.function),n=await this.executeFunction(o,t,r);return{content:[{type:"text",text:typeof n=="string"?n:JSON.stringify(n,null,2)}],isError:!1}}catch(s){return this.logger.error(`[CustomMCP] \u51FD\u6570\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,s),{content:[{type:"text",text:`\u51FD\u6570\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}}async loadModule(e){try{let t=e;return!e.startsWith("/")&&!e.startsWith("file://")&&(t=new URL(e,`file://${process.cwd()}/`).href),this.logger.debug(`[CustomMCP] \u52A0\u8F7D\u6A21\u5757: ${t}`),await import(t)}catch(t){throw new Error(`\u65E0\u6CD5\u52A0\u8F7D\u6A21\u5757 ${e}: ${t instanceof Error?t.message:String(t)}`)}}getFunction(e,t){let r;if(e.default&&typeof e.default=="function"){if(t==="default")r=e.default;else if(typeof e.default=="object"&&e.default!==null&&t in e.default){let s=e.default[t];typeof s=="function"&&(r=s)}}if(!r&&t in e&&typeof e[t]=="function"&&(r=e[t]),!r)throw new Error(`\u5728\u6A21\u5757\u4E2D\u627E\u4E0D\u5230\u51FD\u6570: ${t}`);return r}async executeFunction(e,t,r){let s=r.timeout||3e4,o={...r.context,logger:this.logger,arguments:t},n=Promise.resolve().then(()=>e.length>1?e(t,o):e(t)),a=new Promise((g,u)=>{setTimeout(()=>u(new Error(`\u51FD\u6570\u6267\u884C\u8D85\u65F6 (${s}ms)`)),s)});return Promise.race([n,a])}async callHttpTool(e,t){let r=e.handler;this.logger.info(`[CustomMCP] \u8C03\u7528 HTTP \u5DE5\u5177: ${e.name}`,{url:r.url,method:r.method||"POST"});try{let{url:s,requestOptions:o}=this.buildHttpRequest(r,t),n=await this.sendHttpRequest(s,o,r);return this.processHttpResponse(e.name,n,r)}catch(s){return this.logger.error(`[CustomMCP] HTTP \u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,s),{content:[{type:"text",text:`HTTP \u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}}buildHttpRequest(e,t){let r=e.method||"POST",s={"Content-Type":"application/json","User-Agent":"xiaozhi-client/1.0",...e.headers};if(e.auth)switch(e.auth.type){case"bearer":e.auth.token&&(s.Authorization=`Bearer ${e.auth.token}`);break;case"basic":if(e.auth.username&&e.auth.password){let g=btoa(`${e.auth.username}:${e.auth.password}`);s.Authorization=`Basic ${g}`}break;case"api_key":e.auth.api_key&&e.auth.api_key_header&&(s[e.auth.api_key_header]=e.auth.api_key);break}let o,n=e.url;if(r!=="GET")e.body_template?o=this.replaceTemplateVariables(e.body_template,t):o=JSON.stringify(t);else{let g=new URLSearchParams;for(let[p,h]of Object.entries(t))h!=null&&g.append(p,String(h));let u=g.toString();u&&(n+=(n.includes("?")?"&":"?")+u)}return{url:n,requestOptions:{method:r,headers:s,body:o}}}async sendHttpRequest(e,t,r){let s=r.timeout||3e4,o=r.retry_count||0,n=r.retry_delay||1e3,a=null;for(let g=0;g<=o;g++){try{this.logger.debug(`[CustomMCP] \u53D1\u9001 HTTP \u8BF7\u6C42 (\u5C1D\u8BD5 ${g+1}/${o+1}): ${e}`,{method:t.method,headers:t.headers});let u=new AbortController,p=setTimeout(()=>u.abort(),s),h=await fetch(e,{...t,signal:u.signal});if(clearTimeout(p),h.ok||g===o)return h;this.logger.warn(`[CustomMCP] HTTP \u8BF7\u6C42\u5931\u8D25 (${h.status}), \u5C06\u5728 ${n}ms \u540E\u91CD\u8BD5`),a=new Error(`HTTP \u8BF7\u6C42\u5931\u8D25: ${h.status} ${h.statusText}`)}catch(u){if(a=u instanceof Error?u:new Error(String(u)),u instanceof Error&&u.name==="AbortError"&&(a=new Error(`HTTP \u8BF7\u6C42\u8D85\u65F6 (${s}ms)`)),this.logger.warn(`[CustomMCP] HTTP \u8BF7\u6C42\u5F02\u5E38 (\u5C1D\u8BD5 ${g+1}/${o+1}):`,a.message),g===o)throw a}g<o&&await new Promise(u=>setTimeout(u,n))}throw a||new Error("HTTP \u8BF7\u6C42\u5931\u8D25")}async processHttpResponse(e,t,r){try{let s=t.headers.get("content-type")||"",o;if(s.includes("application/json")?o=await t.json():o=await t.text(),!t.ok)return{content:[{type:"text",text:`HTTP \u8BF7\u6C42\u5931\u8D25 (${t.status}): ${typeof o=="string"?o:JSON.stringify(o)}`}],isError:!0};let n=o;if(r.response_mapping){let a=this.extractResponseData(o,r.response_mapping);a!==void 0&&(n=a)}return{content:[{type:"text",text:typeof n=="string"?n:JSON.stringify(n,null,2)}],isError:!1}}catch(s){return this.logger.error(`[CustomMCP] \u5904\u7406 HTTP \u54CD\u5E94\u5931\u8D25: ${e}`,s),{content:[{type:"text",text:`\u5904\u7406\u54CD\u5E94\u5931\u8D25: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}}replaceTemplateVariables(e,t){let r=e;for(let[s,o]of Object.entries(t)){let n=`{{${s}}}`,a=typeof o=="string"?o:JSON.stringify(o);r=r.replace(new RegExp(n.replace(/[{}]/g,"\\$&"),"g"),a)}return r}extractResponseData(e,t){if(!t)return e;let r=l((s,o)=>{if(!o)return s;let n=o.split("."),a=s;for(let g of n)if(a&&typeof a=="object"&&a!==null&&g in a)a=a[g];else return;return a},"extractByPath");if(t.success_path){let s=r(e,t.success_path);if(s!==void 0)return t.data_path?r(s,t.data_path):s}if(t.data_path){let s=r(e,t.data_path);if(s!==void 0)return s}return e}async callScriptTool(e,t){let r=e.handler;this.logger.info(`[CustomMCP] \u8C03\u7528\u811A\u672C\u5DE5\u5177: ${e.name}`,{script:r.script.substring(0,100)+(r.script.length>100?"...":""),interpreter:r.interpreter||"node"});try{let s=await this.executeScript(r,t);return{content:[{type:"text",text:typeof s=="string"?s:JSON.stringify(s,null,2)}],isError:!1}}catch(s){return this.logger.error(`[CustomMCP] \u811A\u672C\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,s),{content:[{type:"text",text:`\u811A\u672C\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}}async executeScript(e,t){let{spawn:r}=await import("child_process"),{promisify:s}=await import("util"),o=await import("fs/promises"),n=await import("path"),a=await import("os"),g=e.timeout||3e4,u=e.interpreter||"node",p,h=!1;try{if(e.script.includes(`
25
+ `)||e.script.length>200){let y=await o.mkdtemp(n.join(a.tmpdir(),"xiaozhi-script-")),I=this.getScriptExtension(u);p=n.join(y,`script${I}`),await o.writeFile(p,e.script,"utf8"),h=!0}else{p=e.script;try{await o.access(p)}catch{throw new Error(`\u811A\u672C\u6587\u4EF6\u4E0D\u5B58\u5728: ${p}`)}}let T={...process.env,...e.env,XIAOZHI_ARGUMENTS:JSON.stringify(t)},S=this.buildScriptCommand(u,p);return this.logger.debug(`[CustomMCP] \u6267\u884C\u811A\u672C\u547D\u4EE4: ${S.join(" ")}`),new Promise((y,I)=>{let L=r(S[0],S.slice(1),{env:T,stdio:["pipe","pipe","pipe"]}),Se="",Me="";L.stdout?.on("data",$=>{Se+=$.toString()}),L.stderr?.on("data",$=>{Me+=$.toString()});let Pe=setTimeout(()=>{L.kill("SIGTERM"),I(new Error(`\u811A\u672C\u6267\u884C\u8D85\u65F6 (${g}ms)`))},g);L.on("close",$=>{clearTimeout(Pe),$===0?y(Se.trim()):I(new Error(`\u811A\u672C\u6267\u884C\u5931\u8D25 (\u9000\u51FA\u7801: ${$}): ${Me.trim()}`))}),L.on("error",$=>{clearTimeout(Pe),I(new Error(`\u811A\u672C\u6267\u884C\u9519\u8BEF: ${$.message}`))}),t&&Object.keys(t).length>0&&(L.stdin?.write(JSON.stringify(t)),L.stdin?.end())})}finally{if(h&&p)try{await o.unlink(p),await o.rmdir(n.dirname(p))}catch{}}}getScriptExtension(e){switch(e){case"node":return".js";case"python":return".py";case"bash":return".sh";default:return".txt"}}buildScriptCommand(e,t){switch(e){case"node":return["node",t];case"python":return["python3",t];case"bash":return["bash",t];default:throw new Error(`\u4E0D\u652F\u6301\u7684\u811A\u672C\u89E3\u91CA\u5668: ${e}`)}}async callChainTool(e,t){let r=e.handler;this.logger.info(`[CustomMCP] \u8C03\u7528\u94FE\u5F0F\u5DE5\u5177: ${e.name}`,{tools:r.tools,mode:r.mode,error_handling:r.error_handling});try{let s;r.mode==="sequential"?s=await this.executeSequentialChain(r,t):s=await this.executeParallelChain(r,t);let o=s.flatMap(a=>a.content),n=s.some(a=>a.isError);return{content:o,isError:n}}catch(s){return this.logger.error(`[CustomMCP] \u94FE\u5F0F\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,s),{content:[{type:"text",text:`\u94FE\u5F0F\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${s instanceof Error?s.message:String(s)}`}],isError:!0}}}delay(e){return new Promise(t=>setTimeout(t,e))}getToolInfo(e){return this.tools.get(e)}async executeSequentialChain(e,t){let r=[],s=t;for(let o of e.tools)try{this.logger.debug(`[CustomMCP] \u6267\u884C\u94FE\u5F0F\u5DE5\u5177\u4E2D\u7684: ${o}`);let n=await this.callToolRecursive(o,s);if(r.push(n),n.isError){if(e.error_handling==="stop")break;if(e.error_handling==="retry"){this.logger.warn(`[CustomMCP] \u5DE5\u5177 ${o} \u6267\u884C\u5931\u8D25\uFF0C\u5C1D\u8BD5\u91CD\u8BD5`);let a=await this.callToolRecursive(o,s);if(r[r.length-1]=a,a.isError)break}}if(!n.isError&&n.content.length>0){let a=n.content.filter(g=>g.type==="text").map(g=>g.text).join(`
26
+ `);if(a)try{s=JSON.parse(a)}catch{s={input:a,...t}}}}catch(n){let a={content:[{type:"text",text:`\u5DE5\u5177 ${o} \u6267\u884C\u5F02\u5E38: ${n instanceof Error?n.message:String(n)}`}],isError:!0};if(r.push(a),e.error_handling==="stop")break}return r}async executeParallelChain(e,t){let r=e.tools.map(async s=>{try{return this.logger.debug(`[CustomMCP] \u5E76\u884C\u6267\u884C\u94FE\u5F0F\u5DE5\u5177\u4E2D\u7684: ${s}`),await this.callToolRecursive(s,t)}catch(o){return{content:[{type:"text",text:`\u5DE5\u5177 ${s} \u6267\u884C\u5F02\u5E38: ${o instanceof Error?o.message:String(o)}`}],isError:!0}}});return Promise.all(r)}async callToolRecursive(e,t){if(this.tools.get(e))return this.callTool(e,t);throw new Error(`\u94FE\u5F0F\u5DE5\u5177\u4E2D\u5F15\u7528\u7684\u5DE5\u5177 ${e} \u4E0D\u5B58\u5728\u4E8E\u5F53\u524D CustomMCP \u5DE5\u5177\u96C6\u4E2D`)}async clearConsumedCache(e,t){try{let r=this.generateCacheKey(e,t),s=await this.loadExtendedCache();if(s.customMCPResults?.[r]){s.customMCPResults[r].consumed=!0;let o=s.customMCPResults[r];x(o)&&delete s.customMCPResults[r],await this.saveCache(s),this.logger.debug(`[CustomMCP] \u6E05\u7406\u5DF2\u6D88\u8D39\u7F13\u5B58: ${r}`)}}catch(r){this.logger.warn(`[CustomMCP] \u6E05\u7406\u7F13\u5B58\u5931\u8D25: ${r}`)}}async generateTaskId(e,t){return this.taskStateManager.generateTaskId(e,t)}async markTaskAsPending(e,t,r){try{let s=this.generateCacheKey(t,r),o={result:{content:[{type:"text",text:"\u5904\u7406\u4E2D..."}]},timestamp:new Date().toISOString(),ttl:this.CACHE_TTL,status:"pending",consumed:!1,taskId:e,retryCount:0};await this.updateCacheWithResult(s,o),this.taskStateManager.markTaskAsPending(e,t,r),this.activeTasks.set(e,{taskId:e,status:"pending",startTime:Date.now()}),this.logger.debug(`[CustomMCP] \u6807\u8BB0\u4EFB\u52A1\u4E3A\u5904\u7406\u4E2D: ${e}`)}catch(s){this.logger.warn(`[CustomMCP] \u6807\u8BB0\u4EFB\u52A1\u72B6\u6001\u5931\u8D25: ${s}`)}}async markTaskAsCompleted(e,t){try{let r=this.activeTasks.get(e);r&&(r.status="completed",r.endTime=new Date().toISOString(),r.result=t);let s=await this.loadExtendedCache();for(let[o,n]of Object.entries(s.customMCPResults||{})){let a=n;if(a.taskId===e){a.status="completed",a.result=t,a.timestamp=new Date().toISOString(),a.consumed=!1,(s.customMCPResults||{})[o]=a;break}}await this.saveCache(s),this.taskStateManager.markTaskAsCompleted(e,t),this.logger.debug(`[CustomMCP] \u6807\u8BB0\u4EFB\u52A1\u4E3A\u5DF2\u5B8C\u6210: ${e}`)}catch(r){this.logger.warn(`[CustomMCP] \u66F4\u65B0\u4EFB\u52A1\u72B6\u6001\u5931\u8D25: ${r}`)}}async markTaskAsFailed(e,t){try{let r=await this.loadExtendedCache();for(let[o,n]of Object.entries(r.customMCPResults||{})){let a=n;if(a.taskId===e){a.status="failed",a.result={content:[{type:"text",text:`\u4EFB\u52A1\u5931\u8D25: ${t.message}`}]},a.timestamp=new Date().toISOString(),a.consumed=!0,(r.customMCPResults||{})[o]=a;break}}await this.saveCache(r),this.taskStateManager.markTaskAsFailed(e,t.message);let s=this.activeTasks.get(e);s&&(s.status="failed",s.endTime=new Date().toISOString(),s.error=t.message),this.logger.debug(`[CustomMCP] \u6807\u8BB0\u4EFB\u52A1\u4E3A\u5931\u8D25: ${e}`)}catch(r){this.logger.warn(`[CustomMCP] \u66F4\u65B0\u4EFB\u52A1\u72B6\u6001\u5931\u8D25: ${r}`)}}startCleanupTimer(){this.cleanupTimer=setInterval(()=>{this.cleanupExpiredCache().catch(e=>{this.logger.warn(`[CustomMCP] \u7F13\u5B58\u6E05\u7406\u5931\u8D25: ${e}`)})},this.CLEANUP_INTERVAL),this.logger.debug(`[CustomMCP] \u542F\u52A8\u7F13\u5B58\u6E05\u7406\u5B9A\u65F6\u5668\uFF0C\u95F4\u9694: ${this.CLEANUP_INTERVAL}ms`)}async cleanupExpiredCache(){try{let e=await this.loadExtendedCache(),t=!1,r=0;for(let[s,o]of Object.entries(e.customMCPResults||{})){let n=o;x(n)&&(e.customMCPResults?.[s]&&delete e.customMCPResults[s],t=!0,r++,n.taskId&&this.activeTasks.delete(n.taskId))}t&&(await this.saveCache(e),this.logger.debug(`[CustomMCP] \u6E05\u7406\u8FC7\u671F\u7F13\u5B58\u5B8C\u6210\uFF0C\u6E05\u7406\u4E86 ${r} \u4E2A\u6761\u76EE`))}catch(e){this.logger.warn(`[CustomMCP] \u6E05\u7406\u8FC7\u671F\u7F13\u5B58\u5931\u8D25: ${e}`)}}generateCacheKey(e,t){return w(e,t)}async loadExtendedCache(){try{return await this.cacheManager.loadExistingCache()}catch{return{version:"1.0.0",mcpServers:{},metadata:{lastGlobalUpdate:new Date().toISOString(),totalWrites:0,createdAt:new Date().toISOString()},customMCPResults:{}}}}async updateCacheWithResult(e,t){try{let r=await this.loadExtendedCache();r.customMCPResults||(r.customMCPResults={}),r.customMCPResults[e]=t,await this.saveCache(r)}catch(r){this.logger.warn(`[CustomMCP] \u66F4\u65B0\u7F13\u5B58\u5931\u8D25: ${r}`)}}async cacheResult(e,t,r){try{let s=this.generateCacheKey(e,t),o={result:r,timestamp:new Date().toISOString(),ttl:this.CACHE_TTL,status:"completed",consumed:!1,retryCount:0};await this.updateCacheWithResult(s,o),this.logger.debug(`[CustomMCP] \u7F13\u5B58\u5DE5\u5177\u7ED3\u679C: ${e}`)}catch(s){this.logger.warn(`[CustomMCP] \u7F13\u5B58\u7ED3\u679C\u5931\u8D25: ${s}`)}}async saveCache(e){try{await this.cacheManager.saveCache(e)}catch(t){this.logger.warn(`[CustomMCP] \u4FDD\u5B58\u7F13\u5B58\u5931\u8D25: ${t}`)}}stopCleanupTimer(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=void 0,this.logger.info("[CustomMCP] \u505C\u6B62\u7F13\u5B58\u6E05\u7406\u5B9A\u65F6\u5668"))}cleanup(){this.logger.info("[CustomMCP] \u6E05\u7406 CustomMCP \u5904\u7406\u5668\u8D44\u6E90"),this.stopCleanupTimer(),this.cacheLifecycleManager.stopAutoCleanup(),this.cacheLifecycleManager.cleanup(),this.taskStateManager.cleanup(),this.cacheManager.cleanup(),this.tools.clear(),this.activeTasks.clear()}getCacheLifecycleManager(){return this.cacheLifecycleManager}getTaskStateManager(){return this.taskStateManager}async getCacheStatistics(){return this.cacheManager.getCustomMCPStatistics()}getTaskStatistics(){return this.taskStateManager.getTaskStatistics()}getTaskStatus(e){return this.taskStateManager.getTaskStatus(e)}validateTaskId(e){return this.taskStateManager.validateTaskId(e)}restartStalledTasks(e=3e4){return this.taskStateManager.restartStalledTasks(e)}async manualCleanupCache(){return this.cacheManager.cleanupCustomMCPResults()}async validateSystemIntegrity(){let e=await this.cacheManager.loadExtendedCache(),t=this.cacheLifecycleManager.validateCacheIntegrity(e),r=this.taskStateManager.validateTaskIntegrity();return{cacheValid:t.isValid,taskValid:r.isValid,issues:[...t.issues,...r.issues]}}};var X=class{static{l(this,"ToolSyncManager")}configManager;logger;syncLocks=new Map;eventBus=b();constructor(e,t=c){this.configManager=e,this.logger=t.withTag("ToolSync"),this.setupEventListeners()}setupEventListeners(){this.eventBus.onEvent("config:updated",async e=>{await this.handleConfigUpdated(e)}),this.eventBus.onEvent("mcp:server:added",async e=>{await this.handleMCPServerAdded(e)}),this.eventBus.onEvent("mcp:server:removed",async e=>{await this.handleMCPServerRemoved(e)})}async handleConfigUpdated(e){this.logger.debug("\u68C0\u6D4B\u5230\u914D\u7F6E\u66F4\u65B0\uFF0C\u68C0\u67E5\u5DE5\u5177\u540C\u6B65\u72B6\u6001");try{e.type==="customMCP"?this.logger.debug("customMCP\u914D\u7F6E\u5DF2\u66F4\u65B0\uFF0CCustomMCPHandler\u5C06\u81EA\u52A8\u5904\u7406"):e.type==="serverTools"&&e.serviceName?await this.handleServerToolsConfigUpdated(e.serviceName):await this.handleGeneralConfigUpdated()}catch(t){this.logger.error("\u914D\u7F6E\u66F4\u65B0\u540E\u7684\u5DE5\u5177\u540C\u6B65\u5931\u8D25:",t)}}async handleServerToolsConfigUpdated(e){this.logger.debug(`\u5904\u7406\u670D\u52A1 ${e} \u7684serverTools\u914D\u7F6E\u66F4\u65B0`);try{this.eventBus.emitEvent("tool-sync:server-tools-updated",{serviceName:e,timestamp:new Date})}catch(t){this.logger.error(`\u5904\u7406\u670D\u52A1 ${e} \u914D\u7F6E\u66F4\u65B0\u5931\u8D25:`,t)}}async handleGeneralConfigUpdated(){this.logger.info("\u5904\u7406\u901A\u7528\u914D\u7F6E\u66F4\u65B0\uFF0C\u68C0\u67E5\u6240\u6709\u670D\u52A1\u540C\u6B65\u72B6\u6001");try{this.eventBus.emitEvent("tool-sync:general-config-updated",{timestamp:new Date})}catch(e){this.logger.error("\u5904\u7406\u901A\u7528\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",e)}}async handleMCPServerAdded(e){this.logger.info(`\u5904\u7406MCP\u670D\u52A1\u6DFB\u52A0\u4E8B\u4EF6: ${e.serverName}`);try{setTimeout(async()=>{await this.triggerServiceToolSync(e.serverName)},1e3)}catch(t){this.logger.error(`\u5904\u7406\u670D\u52A1 ${e.serverName} \u6DFB\u52A0\u4E8B\u4EF6\u5931\u8D25:`,t)}}async triggerServiceToolSync(e){this.logger.info(`\u89E6\u53D1\u670D\u52A1 ${e} \u7684\u5DE5\u5177\u540C\u6B65`);try{this.eventBus.emitEvent("tool-sync:request-service-tools",{serviceName:e,timestamp:new Date})}catch(t){this.logger.error(`\u89E6\u53D1\u670D\u52A1 ${e} \u5DE5\u5177\u540C\u6B65\u5931\u8D25:`,t)}}async handleMCPServerRemoved(e){this.logger.info(`\u5904\u7406MCP\u670D\u52A1\u79FB\u9664\u4E8B\u4EF6: ${e.serverName}`);try{await this.removeServiceToolsFromCustomMCP(e.serverName,e.affectedTools)}catch(t){this.logger.error(`\u5904\u7406\u670D\u52A1 ${e.serverName} \u79FB\u9664\u4E8B\u4EF6\u5931\u8D25:`,t)}}async removeServiceToolsFromCustomMCP(e,t){this.logger.info(`\u4ECEcustomMCP\u4E2D\u79FB\u9664\u670D\u52A1 ${e} \u7684\u5DE5\u5177`);try{let r=this.configManager.getCustomMCPTools(),s=r.filter(n=>!n.name.startsWith(`${e}__`));if(s.length===r.length){this.logger.debug(`\u670D\u52A1 ${e} \u7684\u5DE5\u5177\u4E0D\u5728customMCP\u4E2D\uFF0C\u65E0\u9700\u79FB\u9664`);return}await this.configManager.updateCustomMCPTools(s);let o=r.length-s.length;this.logger.info(`\u6210\u529F\u4ECEcustomMCP\u4E2D\u79FB\u9664\u670D\u52A1 ${e} \u7684 ${o} \u4E2A\u5DE5\u5177`),this.eventBus.emitEvent("tool-sync:service-tools-removed",{serviceName:e,removedCount:o,timestamp:new Date})}catch(r){throw this.logger.error(`\u79FB\u9664\u670D\u52A1 ${e} \u5DE5\u5177\u5931\u8D25:`,r),r}}async syncToolsAfterConnection(e,t){if(this.syncLocks.has(e)){this.logger.debug(`\u670D\u52A1 ${e} \u6B63\u5728\u540C\u6B65\u4E2D\uFF0C\u8DF3\u8FC7`);return}let r=this.doSyncTools(e,t).finally(()=>{this.syncLocks.delete(e)});this.syncLocks.set(e,r),await r}async doSyncTools(e,t){try{this.logger.info(`\u5F00\u59CB\u540C\u6B65\u670D\u52A1 ${e} \u7684\u5DE5\u5177`);let r=this.configManager.getServerToolsConfig(e);if(!r){this.logger.debug(`\u670D\u52A1 ${e} \u65E0 mcpServerConfig \u914D\u7F6E\uFF0C\u8DF3\u8FC7\u540C\u6B65`);return}let s=this.getEnabledTools(r,t);if(s.length===0){this.logger.debug(`\u670D\u52A1 ${e} \u65E0\u542F\u7528\u5DE5\u5177\uFF0C\u8DF3\u8FC7\u540C\u6B65`);return}let o=this.configManager.getCustomMCPTools(),n=new Set(o.map(g=>g.name)),a=s.filter(g=>!n.has(`${e}__${g.name}`));if(a.length===0){this.logger.info(`\u670D\u52A1 ${e} \u7684\u542F\u7528\u5DE5\u5177\u5DF2\u5B58\u5728\u4E8E customMCP \u4E2D\uFF0C\u8DF3\u8FC7\u540C\u6B65`);return}await this.addToolsToCustomMCP(e,a),this.logger.info(`\u6210\u529F\u540C\u6B65\u670D\u52A1 ${e} \u7684 ${a.length} \u4E2A\u5DE5\u5177\u5230 customMCP`)}catch(r){this.logger.error(`\u540C\u6B65\u670D\u52A1 ${e} \u5DE5\u5177\u5931\u8D25:`,r),this.recordSyncError(e,r)}}getEnabledTools(e,t){let r=[];for(let s of t){let o=e[s.name];o&&o.enable!==!1&&r.push(s)}return r}async addToolsToCustomMCP(e,t){let r=t.map(s=>({name:`${e}__${s.name}`,description:s.description||"",inputSchema:s.inputSchema||{},handler:{type:"mcp",config:{serviceName:e,toolName:s.name}}}));await this.configManager.addCustomMCPTools(r),await this.syncToolStats(e,t)}recordSyncError(e,t){let r={serviceName:e,error:t instanceof Error?t.message:String(t),timestamp:new Date().toISOString(),type:t instanceof Error?t.constructor.name:"UnknownError"};this.logger.error("\u540C\u6B65\u9519\u8BEF\u8BB0\u5F55:",r)}getSyncLocks(){return Array.from(this.syncLocks.keys())}clearSyncLocks(){this.syncLocks.clear(),this.logger.debug("\u5DF2\u6E05\u7406\u6240\u6709\u540C\u6B65\u9501")}async syncToolStats(e,t){try{let r=this.configManager.getServerToolsConfig(e);if(!r){this.logger.debug(`\u670D\u52A1 ${e} \u65E0 mcpServerConfig \u914D\u7F6E\uFF0C\u8DF3\u8FC7\u7EDF\u8BA1\u4FE1\u606F\u540C\u6B65`);return}let s=this.configManager.getCustomMCPTools(),o=new Map(s.map(n=>[n.name,n]));for(let n of t){let a=`${e}__${n.name}`,g=o.get(a),u=r[n.name];if(g&&u&&(!g.stats||!g.stats.usageCount&&!g.stats.lastUsedTime)){let p={};u.usageCount!==void 0&&(p.usageCount=u.usageCount),u.lastUsedTime&&(p.lastUsedTime=u.lastUsedTime),Object.keys(p).length>0&&(await this.updateCustomMCPToolStats(a,p),this.logger.debug(`\u5DF2\u540C\u6B65\u5DE5\u5177 ${a} \u7684\u7EDF\u8BA1\u4FE1\u606F: ${JSON.stringify(p)}`))}}}catch(r){this.logger.error(`\u540C\u6B65\u670D\u52A1 ${e} \u5DE5\u5177\u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25:`,r instanceof Error?r.message:String(r))}}async updateCustomMCPToolStats(e,t){try{let r=this.configManager.getCustomMCPTools(),s=r.findIndex(a=>a.name===e);if(s===-1){this.logger.warn(`\u5DE5\u5177 ${e} \u4E0D\u5B58\u5728\u4E8E customMCP \u4E2D`);return}let o=[...r],n=o[s];n.stats||(n.stats={}),t.usageCount!==void 0&&(n.stats.usageCount=t.usageCount),t.lastUsedTime!==void 0&&(n.stats.lastUsedTime=t.lastUsedTime),await this.configManager.updateCustomMCPTools(o)}catch(r){throw this.logger.error(`\u66F4\u65B0\u5DE5\u5177 ${e} \u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25:`,r instanceof Error?r.message:String(r)),r}}};var k=class{static{l(this,"TransportAdapter")}logger;messageHandler;connectionId;config;state="disconnected";constructor(e,t){this.messageHandler=e,this.config=t,this.connectionId=this.generateConnectionId(),this.logger=c}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);t!==null?(this.logger.debug("\u53D1\u9001\u54CD\u5E94\u6D88\u606F:",t),await this.sendMessage(t)):this.logger.debug("\u6536\u5230\u901A\u77E5\u6D88\u606F\uFF0C\u65E0\u9700\u54CD\u5E94")}catch(t){this.logger.error(`\u5904\u7406\u6D88\u606F\u65F6\u51FA\u9519: ${e.method}`,t);let r=this.createErrorResponse(t,e.id);await this.sendMessage(r)}}createErrorResponse(e,t){let r=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?r=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(r=-32602),{jsonrpc:"2.0",error:{code:r,message:e.message,data:{stack:e.stack}},id:t}}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 r=t instanceof Error?t.message:String(t);throw new Error(`\u6D88\u606F\u5E8F\u5217\u5316\u5931\u8D25: ${r}`)}}validateMessage(e){if(!e||typeof e!="object")return!1;let t=e;return!(t.jsonrpc!=="2.0"||t.method&&typeof t.method!="string"||!t.method&&!t.result&&!t.error)}createTimeoutPromise(e,t){return Promise.race([e,new Promise((r,s)=>{setTimeout(()=>{s(new Error(`\u64CD\u4F5C\u8D85\u65F6: ${t}ms`))},t)})])}};import*as U from"fs";import*as O from"path";import{realpathSync as nt}from"fs";import{tmpdir as it}from"os";import d from"path";import{fileURLToPath as Le}from"url";var de={NAME:"xiaozhi-mcp-service",DEFAULT_PORT:3e3,DEFAULT_WEB_UI_PORT:9999,PID_FILE:"xiaozhi.pid",LOG_FILE:"xiaozhi.log"},j={FILE_NAMES:["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"],DEFAULT_FILE:"xiaozhi.config.default.json",DIR_ENV_VAR:"XIAOZHI_CONFIG_DIR"},V={WORK_DIR:".xiaozhi",TEMPLATES_DIR:"templates",LOGS_DIR:"logs"},Ie={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"};import C from"fs";import P from"path";var fe=class i extends Error{constructor(t,r,s=1,o){super(t);this.code=r;this.exitCode=s;this.suggestions=o;this.name="CLIError",Error.captureStackTrace&&Error.captureStackTrace(this,i)}static{l(this,"CLIError")}static withSuggestions(t,r,s){return new i(t,r,1,s)}};var m=class i extends fe{static{l(this,"FileError")}constructor(e,t,r){let s=t?`${e}: ${t}`:e;super(s,Ie.FILE_ERROR,1,r),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"])}};var F=class i{static{l(this,"FileUtils")}static exists(e){try{return C.existsSync(e)}catch{return!1}}static ensureDir(e){try{C.existsSync(e)||C.mkdirSync(e,{recursive:!0})}catch{throw new m("\u65E0\u6CD5\u521B\u5EFA\u76EE\u5F55",e)}}static readFile(e,t="utf8"){try{if(!i.exists(e))throw m.notFound(e);return C.readFileSync(e,t)}catch(r){throw r instanceof m?r:new m("\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6",e)}}static writeFile(e,t,r){try{if(!r?.overwrite&&i.exists(e))throw m.alreadyExists(e);let s=P.dirname(e);i.ensureDir(s),C.writeFileSync(e,t,"utf8")}catch(s){throw s instanceof m?s:new m("\u65E0\u6CD5\u5199\u5165\u6587\u4EF6",e)}}static copyFile(e,t,r){try{if(!i.exists(e))throw m.notFound(e);if(!r?.overwrite&&i.exists(t))throw m.alreadyExists(t);let s=P.dirname(t);i.ensureDir(s),C.copyFileSync(e,t)}catch(s){throw s instanceof m?s:new m("\u65E0\u6CD5\u590D\u5236\u6587\u4EF6",e)}}static deleteFile(e){try{i.exists(e)&&C.unlinkSync(e)}catch{throw new m("\u65E0\u6CD5\u5220\u9664\u6587\u4EF6",e)}}static copyDirectory(e,t,r={}){try{if(!i.exists(e))throw m.notFound(e);i.ensureDir(t);let s=C.readdirSync(e);for(let o of s){if(r.exclude?.includes(o))continue;let n=P.join(e,o),a=P.join(t,o);C.statSync(n).isDirectory()?r.recursive!==!1&&i.copyDirectory(n,a,r):i.copyFile(n,a,{overwrite:r.overwrite})}}catch(s){throw s instanceof m?s:new m("\u65E0\u6CD5\u590D\u5236\u76EE\u5F55",e)}}static deleteDirectory(e,t={}){try{i.exists(e)&&C.rmSync(e,{recursive:t.recursive??!0,force:!0})}catch{throw new m("\u65E0\u6CD5\u5220\u9664\u76EE\u5F55",e)}}static getFileInfo(e){try{if(!i.exists(e))throw m.notFound(e);let t=C.statSync(e);return{size:t.size,isFile:t.isFile(),isDirectory:t.isDirectory(),mtime:t.mtime,ctime:t.ctime}}catch(t){throw t instanceof m?t:new m("\u65E0\u6CD5\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F",e)}}static listDirectory(e,t={}){try{if(!i.exists(e))throw m.notFound(e);let r=C.readdirSync(e),s=[];for(let o of r){if(!t.includeHidden&&o.startsWith("."))continue;let n=P.join(e,o);if(s.push(n),t.recursive&&C.statSync(n).isDirectory()){let a=i.listDirectory(n,t);s=s.concat(a)}}return s}catch(r){throw r instanceof m?r:new m("\u65E0\u6CD5\u5217\u51FA\u76EE\u5F55\u5185\u5BB9",e)}}static createTempFile(e="xiaozhi-",t=".tmp"){let r=process.env.TMPDIR||process.env.TEMP||"/tmp",s=Date.now(),o=Math.random().toString(36).substring(2),n=`${e}${s}-${o}${t}`;return P.join(r,n)}static checkPermissions(e,t=C.constants.R_OK|C.constants.W_OK){try{return C.accessSync(e,t),!0}catch{return!1}}static getExtension(e){return P.extname(e).toLowerCase()}static getBaseName(e){return P.basename(e,P.extname(e))}static normalizePath(e){return P.normalize(e)}static resolvePath(e,t){return t?P.resolve(t,e):P.resolve(e)}};var Z=class i{static{l(this,"PathUtils")}static getPidFile(){let e=process.env[j.DIR_ENV_VAR]||process.cwd();return d.join(e,`.${de.NAME}.pid`)}static getLogFile(e){let t=e||process.cwd();return d.join(t,de.LOG_FILE)}static getConfigDir(){return process.env[j.DIR_ENV_VAR]||process.cwd()}static getWorkDir(){let e=i.getConfigDir();return d.join(e,V.WORK_DIR)}static getTemplatesDir(){let e=Le(import.meta.url),t=d.dirname(e);return[d.join(t,V.TEMPLATES_DIR),d.join(t,"..","..","..",V.TEMPLATES_DIR),d.join(t,"..","..","..","..",V.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 r=d.join(t,e);return F.exists(r)?r:null}static getScriptDir(){let e=Le(import.meta.url);return d.dirname(e)}static getProjectRoot(){let e=i.getScriptDir();return d.join(e,"..","..","..")}static getDistDir(){let e=i.getProjectRoot();return d.join(e,"dist")}static getRelativePath(e){let t=i.getProjectRoot();return d.relative(t,e)}static resolveConfigPath(e){let t=i.getConfigDir();if(e)return d.join(t,`xiaozhi.config.${e}`);for(let r of j.FILE_NAMES){let s=d.join(t,r);if(F.exists(s))return s}return d.join(t,j.FILE_NAMES[2])}static getDefaultConfigPath(){let e=i.getProjectRoot();return d.join(e,j.DEFAULT_FILE)}static validatePath(e){return!d.normalize(e).includes("..")}static ensurePathWithin(e,t){let r=d.resolve(t,e),s=d.resolve(t);if(!r.startsWith(s))throw new Error(`\u8DEF\u5F84 ${e} \u8D85\u51FA\u4E86\u5141\u8BB8\u7684\u8303\u56F4`);return r}static getExecutablePath(e){let t=process.argv[1];if(!t)return d.join(process.cwd(),`${e}.js`);let r;try{r=nt(t)}catch{r=t}let s=d.dirname(r);return d.join(s,`${e}.js`)}static getMcpServerProxyPath(){return i.getExecutablePath("mcpServerProxy")}static getWebServerStandalonePath(){return i.getExecutablePath("WebServerStandalone")}static createSafePath(...e){let t=d.join(...e),r=d.normalize(t);if(r.includes("..")||r.includes("~"))throw new Error(`\u4E0D\u5B89\u5168\u7684\u8DEF\u5F84: ${r}`);return r}static getTempDir(){return process.env.TMPDIR||process.env.TEMP||it()}static getHomeDir(){return process.env.HOME||process.env.USERPROFILE||""}};import ee from"pino";var te=class{static{l(this,"ToolCallLogger")}pinoLogger;maxRecords;logFilePath;constructor(e,t){if(this.maxRecords=e.maxRecords??100,e.logFilePath)this.logFilePath=O.resolve(O.normalize(e.logFilePath));else{let r=t||Z.getTempDir();this.logFilePath=O.join(O.normalize(r),"tool-calls.jsonl")}this.pinoLogger=this.createPinoLogger(this.logFilePath),c.debug(`ToolCallLogger \u521D\u59CB\u5316: maxRecords=${this.maxRecords}, path=${this.logFilePath}`)}createPinoLogger(e){let t=[];t.push({level:"info",stream:{write:l(r=>{try{let s=JSON.parse(r),o=this.formatConsoleMessage(s);c.info(`[\u5DE5\u5177\u8C03\u7528] ${o}`)}catch{c.info(`[\u5DE5\u5177\u8C03\u7528] ${r.trim()}`)}},"write")}});try{t.push({level:"info",stream:ee.destination({dest:e,sync:!0,append:!0,mkdir:!0})})}catch(r){c.error("\u65E0\u6CD5\u521B\u5EFA\u5DE5\u5177\u8C03\u7528\u65E5\u5FD7\u6587\u4EF6:",r)}return ee({level:"info",timestamp:ee.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:l((r,s)=>({level:s}),"level")},base:null},ee.multistream(t,{dedupe:!0}))}formatConsoleMessage(e){let t=e.toolName||"\u672A\u77E5\u5DE5\u5177",r=e.success!==!1,s=e.duration?` (${e.duration}ms)`:"";return`${r?"\u2705":"\u274C"} ${t}${s}`}async cleanupOldRecords(){try{if(!U.existsSync(this.logFilePath))return;let t=U.readFileSync(this.logFilePath,"utf8").trim().split(`
27
+ `).filter(n=>n.trim()!=="");if(t.length<=this.maxRecords)return;let r=t.length-this.maxRecords+1,s=t.slice(r),o=s.join(`
28
+ `)+(s.length>0?`
29
+ `:"");U.writeFileSync(this.logFilePath,o,"utf8"),c.debug(`\u5DF2\u6E05\u7406 ${r} \u6761\u65E7\u7684\u5DE5\u5177\u8C03\u7528\u8BB0\u5F55\uFF0C\u4FDD\u7559\u6700\u65B0 ${this.maxRecords} \u6761`)}catch(e){c.error("\u6E05\u7406\u65E7\u5DE5\u5177\u8C03\u7528\u8BB0\u5F55\u5931\u8D25:",e)}}async recordToolCall(e){try{await this.cleanupOldRecords(),this.pinoLogger.info(e,e.toolName)}catch(t){c.error("\u8BB0\u5F55\u5DE5\u5177\u8C03\u7528\u5931\u8D25:",t)}}getLogFilePath(){return this.logFilePath}getMaxRecords(){return this.maxRecords}};var re=class extends at{static{l(this,"MCPServiceManager")}services=new Map;configs={};logger;tools=new Map;customMCPHandler;cacheManager;toolSyncManager;eventBus=b();toolCallLogger;retryTimers=new Map;failedServices=new Set;transportAdapters=new Map;messageHandler;isRunning=!1;config;constructor(e,t){super(),this.logger=t||c,e&&this.isUnifiedServerConfig(e)?(this.config={name:"MCPServiceManager",enableLogging:!0,logLevel:"info",...e},this.configs=e.configs||{}):(this.config={name:"MCPServiceManager",enableLogging:!0,logLevel:"info"},this.configs=e||{});let s=process.env.NODE_ENV==="test"||process.env.VITEST==="true"?`/tmp/xiaozhi-test-${Date.now()}-${Math.random().toString(36).substring(2,11)}/xiaozhi.cache.json`:void 0;this.cacheManager=new N(s),this.customMCPHandler=new Q,this.toolSyncManager=new X(f,this.logger);let o=f.getToolCallLogConfig(),n=f.getConfigDir();this.toolCallLogger=new te(o,n),this.setupEventListeners(),this.messageHandler=new K(this)}setupEventListeners(){this.eventBus.onEvent("mcp:service:connected",async e=>{await this.handleServiceConnected(e)}),this.eventBus.onEvent("mcp:service:disconnected",async e=>{await this.handleServiceDisconnected(e)}),this.eventBus.onEvent("mcp:service:connection:failed",async e=>{await this.handleServiceConnectionFailed(e)}),this.eventBus.onEvent("tool-sync:server-tools-updated",async e=>{await this.handleServerToolsUpdated(e)}),this.eventBus.onEvent("tool-sync:general-config-updated",async e=>{await this.handleGeneralConfigUpdated(e)})}async handleServiceConnected(e){this.logger.debug(`\u670D\u52A1 ${e.serviceName} \u8FDE\u63A5\u6210\u529F\uFF0C\u5F00\u59CB\u5DE5\u5177\u540C\u6B65`);try{let t=this.services.get(e.serviceName);if(t){let r=t.getTools();this.toolSyncManager&&await this.toolSyncManager.syncToolsAfterConnection(e.serviceName,r),await this.refreshCustomMCPHandlerPublic(),this.logger.info(`\u670D\u52A1 ${e.serviceName} \u5DE5\u5177\u540C\u6B65\u5B8C\u6210`)}}catch(t){this.logger.error(`\u540C\u6B65\u670D\u52A1 ${e.serviceName} \u5DE5\u5177\u5931\u8D25:`,t)}}async handleServiceDisconnected(e){this.logger.info(`\u670D\u52A1 ${e.serviceName} \u65AD\u5F00\u8FDE\u63A5\uFF0C\u539F\u56E0: ${e.reason||"\u672A\u77E5"}`);try{await this.refreshToolsCache(),await this.refreshCustomMCPHandlerPublic(),this.logger.info(`\u670D\u52A1 ${e.serviceName} \u65AD\u5F00\u8FDE\u63A5\u5904\u7406\u5B8C\u6210`)}catch(t){this.logger.error(`\u670D\u52A1 ${e.serviceName} \u65AD\u5F00\u8FDE\u63A5\u5904\u7406\u5931\u8D25:`,t)}}async handleServiceConnectionFailed(e){try{await this.refreshCustomMCPHandlerPublic()}catch(t){this.logger.error("\u5237\u65B0CustomMCPHandler\u5931\u8D25:",t)}}async handleServerToolsUpdated(e){this.logger.debug(`\u5904\u7406\u670D\u52A1 ${e.serviceName} \u7684serverTools\u914D\u7F6E\u66F4\u65B0`);try{let t=this.services.get(e.serviceName);if(t?.isConnected()){let r=t.getTools();this.toolSyncManager&&await this.toolSyncManager.syncToolsAfterConnection(e.serviceName,r),await this.refreshCustomMCPHandlerPublic(),this.logger.info(`\u670D\u52A1 ${e.serviceName} \u914D\u7F6E\u66F4\u65B0\u540C\u6B65\u5B8C\u6210`)}}catch(t){this.logger.error(`\u5904\u7406\u670D\u52A1 ${e.serviceName} \u914D\u7F6E\u66F4\u65B0\u5931\u8D25:`,t)}}async handleGeneralConfigUpdated(e){this.logger.info("\u5904\u7406\u901A\u7528\u914D\u7F6E\u66F4\u65B0\uFF0C\u68C0\u67E5\u6240\u6709\u5DF2\u8FDE\u63A5\u670D\u52A1");try{for(let[t,r]of this.services)if(r.isConnected()){let s=r.getTools();this.toolSyncManager&&await this.toolSyncManager.syncToolsAfterConnection(t,s)}await this.refreshCustomMCPHandlerPublic(),this.logger.info("\u901A\u7528\u914D\u7F6E\u66F4\u65B0\u540C\u6B65\u5B8C\u6210")}catch(t){this.logger.error("\u5904\u7406\u901A\u7528\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",t)}}async startAllServices(){this.logger.debug("[MCPManager] \u6B63\u5728\u542F\u52A8\u6240\u6709 MCP \u670D\u52A1...");try{this.customMCPHandler.initialize(),this.logger.debug("[MCPManager] CustomMCP \u5904\u7406\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(a){this.logger.error("[MCPManager] CustomMCP \u5904\u7406\u5668\u521D\u59CB\u5316\u5931\u8D25:",a)}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}this.logger.info(`[MCPManager] \u5F00\u59CB\u5E76\u884C\u542F\u52A8 ${e.length} \u4E2A MCP \u670D\u52A1`);let t=e.map(async([a])=>{try{return await this.startService(a),{serviceName:a,success:!0,error:null}}catch(g){return{serviceName:a,success:!1,error:g instanceof Error?g.message:String(g)}}}),r=await Promise.allSettled(t),s=0,o=0,n=[];for(let a of r)a.status==="fulfilled"?a.value.success?s++:(o++,n.push(a.value.serviceName)):o++;this.logger.info(`[MCPManager] \u670D\u52A1\u542F\u52A8\u5B8C\u6210 - \u6210\u529F: ${s}, \u5931\u8D25: ${o}`),n.length>0&&(this.logger.warn(`[MCPManager] \u4EE5\u4E0B\u670D\u52A1\u542F\u52A8\u5931\u8D25: ${n.join(", ")}`),o===e.length&&this.logger.warn("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u542F\u52A8\u5931\u8D25\uFF0C\u4F46\u7CFB\u7EDF\u5C06\u7EE7\u7EED\u8FD0\u884C\u4EE5\u4FBF\u91CD\u8BD5")),n.length>0&&this.scheduleFailedServicesRetry(n)}async startService(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 r=new se(t,this.logger);await r.connect(),this.services.set(e,r),await this.refreshToolsCache();let s=r.getTools();this.logger.debug(`[MCPManager] ${e} \u670D\u52A1\u542F\u52A8\u6210\u529F\uFF0C\u52A0\u8F7D\u4E86 ${s.length} \u4E2A\u5DE5\u5177:`,s.map(o=>o.name).join(", "))}catch(r){throw this.logger.error(`[MCPManager] \u542F\u52A8 ${e} \u670D\u52A1\u5931\u8D25:`,r.message),this.services.delete(e),r}}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(r){throw this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,r.message),r}}async refreshToolsCache(){this.tools.clear();for(let[e,t]of this.services)if(t.isConnected()){let r=t.getTools(),s=this.configs[e];s&&this.cacheManager.writeCacheEntry(e,r,s).then(()=>{this.logger.debug(`[MCPManager] \u5DF2\u5C06 ${e} \u5DE5\u5177\u5217\u8868\u5199\u5165\u7F13\u5B58`)}).catch(o=>{this.logger.warn(`[MCPManager] \u5199\u5165\u7F13\u5B58\u5931\u8D25: ${e}, \u9519\u8BEF: ${o instanceof Error?o.message:String(o)}`)});for(let o of r){let n=`${e}__${o.name}`;this.tools.set(n,{serviceName:e,originalName:o.name,tool:o})}}await this.syncToolsConfigToFile()}getAllTools(){let e=[];for(let[r,s]of this.services)try{if(s.isConnected()){let o=s.getTools();for(let n of o)try{if(!f.isToolEnabled(r,n.name))continue;let g=`${r}__${n.name}`;e.push({name:g,description:n.description||"",inputSchema:n.inputSchema,serviceName:r,originalName:n.name})}catch(a){this.logger.warn(`[MCPManager] \u68C0\u67E5\u5DE5\u5177 ${r}.${n.name} \u542F\u7528\u72B6\u6001\u5931\u8D25\uFF0C\u8DF3\u8FC7\u8BE5\u5DE5\u5177:`,a)}}}catch(o){this.logger.warn(`[MCPManager] \u83B7\u53D6\u670D\u52A1 ${r} \u7684\u5DE5\u5177\u5931\u8D25\uFF0C\u8DF3\u8FC7\u8BE5\u670D\u52A1:`,o)}let t=[];try{t=this.customMCPHandler.getTools(),this.logger.debug(`[MCPManager] \u6210\u529F\u83B7\u53D6 ${t.length} \u4E2A customMCP \u5DE5\u5177`)}catch(r){this.logger.warn("[MCPManager] \u83B7\u53D6 CustomMCP \u5DE5\u5177\u5931\u8D25\uFF0C\u5C06\u53EA\u8FD4\u56DE\u6807\u51C6 MCP \u5DE5\u5177:",r),t=[]}for(let r of t)try{e.push({name:r.name,description:r.description||"",inputSchema:r.inputSchema,serviceName:this.getServiceNameForTool(r),originalName:r.name})}catch(s){this.logger.warn(`[MCPManager] \u5904\u7406 CustomMCP \u5DE5\u5177 ${r.name} \u5931\u8D25\uFF0C\u8DF3\u8FC7\u8BE5\u5DE5\u5177:`,s)}return this.logger.debug(`[MCPManager] \u6210\u529F\u83B7\u53D6 ${e.length} \u4E2A\u53EF\u7528\u5DE5\u5177`),e}getServiceNameForTool(e){return e.handler?.type==="mcp"&&e.handler.config?.serviceName||"customMCP"}getLogServerName(e){if(!e?.handler)return"custom";switch(e.handler.type){case"mcp":return e.handler.config?.serviceName||"customMCP";case"coze":return"coze";case"dify":return"dify";case"n8n":return"n8n";default:return"custom"}}getOriginalToolName(e,t,r){return t?t.handler?.type==="mcp"&&t.handler.config?.toolName||e:r?.originalName||e}async callTool(e,t){let r=Date.now(),s="unknown",o=e;try{let n;if(this.customMCPHandler.hasTool(e)){let a=this.customMCPHandler.getToolInfo(e);a&&(s=this.getLogServerName(a),o=this.getOriginalToolName(e,a)),a?.handler?.type==="mcp"?(n=await this.callMCPTool(e,a.handler.config,t),this.updateToolStatsSafe(e,a.handler.config.serviceName,a.handler.config.toolName,!0)):(n=await this.customMCPHandler.callTool(e,t),this.logger.info(`[MCPManager] CustomMCP \u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F`),this.updateToolStatsSafe(e,"customMCP",e,!0))}else{let a=this.tools.get(e);if(!a)throw new Error(`\u672A\u627E\u5230\u5DE5\u5177: ${e}`);s=a.serviceName,o=a.originalName;let g=this.services.get(a.serviceName);if(!g)throw new Error(`\u670D\u52A1 ${a.serviceName} \u4E0D\u53EF\u7528`);if(!g.isConnected())throw new Error(`\u670D\u52A1 ${a.serviceName} \u672A\u8FDE\u63A5`);n=await g.callTool(a.originalName,t||{}),this.logger.debug(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,n),this.updateToolStatsSafe(e,a.serviceName,a.originalName,!0)}return this.toolCallLogger.recordToolCall({toolName:o,serverName:s,arguments:t,result:n,success:n.isError!==!0,duration:Date.now()-r}),n}catch(n){if(this.toolCallLogger.recordToolCall({toolName:o,serverName:s,arguments:t,result:null,success:!1,duration:Date.now()-r,error:n instanceof Error?n.message:String(n)}),this.customMCPHandler.hasTool(e)){let a=this.customMCPHandler.getToolInfo(e);a?.handler?.type==="mcp"?this.updateToolStatsSafe(e,a.handler.config.serviceName,a.handler.config.toolName,!1):(this.updateToolStatsSafe(e,"customMCP",e,!1),this.logger.error(`[MCPManager] CustomMCP \u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,n.message))}else{let a=this.tools.get(e);a&&(this.updateToolStatsSafe(e,a.serviceName,a.originalName,!1),this.logger.error(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,n.message))}throw n}}async updateToolStats(e,t,r,s){try{let o=new Date().toISOString();s?(await this.updateCustomMCPToolStats(e,o),t!=="customMCP"&&await this.updateMCPServerToolStats(t,r,o),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0\u5DE5\u5177 ${e} \u7684\u7EDF\u8BA1\u4FE1\u606F`)):(await this.updateCustomMCPToolLastUsedTime(e,o),t!=="customMCP"&&await this.updateMCPServerToolLastUsedTime(t,r,o),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0\u5DE5\u5177 ${e} \u7684\u5931\u8D25\u8C03\u7528\u7EDF\u8BA1\u4FE1\u606F`))}catch(o){throw this.logger.error(`[MCPManager] \u66F4\u65B0\u5DE5\u5177 ${e} \u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25:`,o),o}}async updateToolStatsSafe(e,t,r,s){try{await this.updateToolStats(e,t,r,s)}catch(o){let n=s?"\u7EDF\u8BA1\u4FE1\u606F":"\u5931\u8D25\u7EDF\u8BA1\u4FE1\u606F";this.logger.warn(`[MCPManager] \u66F4\u65B0\u5DE5\u5177 ${e} ${n}\u5931\u8D25:`,o)}}async updateCustomMCPToolStats(e,t){try{await f.updateToolUsageStatsWithLock(e,!0),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0 customMCP \u5DE5\u5177 ${e} \u4F7F\u7528\u7EDF\u8BA1`)}catch(r){throw this.logger.error(`[MCPManager] \u66F4\u65B0 customMCP \u5DE5\u5177 ${e} \u7EDF\u8BA1\u5931\u8D25:`,r),r}}async updateCustomMCPToolLastUsedTime(e,t){try{await f.updateToolUsageStatsWithLock(e,!1),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0 customMCP \u5DE5\u5177 ${e} \u6700\u540E\u4F7F\u7528\u65F6\u95F4`)}catch(r){throw this.logger.error(`[MCPManager] \u66F4\u65B0 customMCP \u5DE5\u5177 ${e} \u6700\u540E\u4F7F\u7528\u65F6\u95F4\u5931\u8D25:`,r),r}}async updateMCPServerToolStats(e,t,r){try{await f.updateMCPServerToolStatsWithLock(e,t,r,!0),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0 MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u7EDF\u8BA1`)}catch(s){throw this.logger.error(`[MCPManager] \u66F4\u65B0 MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u7EDF\u8BA1\u5931\u8D25:`,s),s}}async updateMCPServerToolLastUsedTime(e,t,r){try{await f.updateMCPServerToolStatsWithLock(e,t,r,!1),this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0 MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u6700\u540E\u4F7F\u7528\u65F6\u95F4`)}catch(s){throw this.logger.error(`[MCPManager] \u66F4\u65B0 MCP \u670D\u52A1\u5DE5\u5177 ${e}/${t} \u6700\u540E\u4F7F\u7528\u65F6\u95F4\u5931\u8D25:`,s),s}}async callMCPTool(e,t,r){let{serviceName:s,toolName:o}=t;this.logger.debug(`[MCPManager] \u8C03\u7528 MCP \u540C\u6B65\u5DE5\u5177 ${e} -> ${s}.${o}`);let n=this.services.get(s);if(!n)throw new Error(`\u670D\u52A1 ${s} \u4E0D\u53EF\u7528`);if(!n.isConnected())throw new Error(`\u670D\u52A1 ${s} \u672A\u8FDE\u63A5`);try{let a=await n.callTool(o,r||{});return this.logger.debug(`[MCPManager] MCP \u540C\u6B65\u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F`),a}catch(a){throw this.logger.error(`[MCPManager] MCP \u540C\u6B65\u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,a.message),a}}hasTool(e){return this.customMCPHandler.hasTool(e)?!0:this.tools.has(e)}async stopAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u505C\u6B62\u6240\u6709 MCP \u670D\u52A1..."),this.stopAllServiceRetries();for(let[e,t]of this.services)try{await t.disconnect(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(r){this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,r.message)}try{this.customMCPHandler.cleanup(),this.logger.info("[MCPManager] CustomMCP \u5904\u7406\u5668\u5DF2\u6E05\u7406")}catch(e){this.logger.error("[MCPManager] CustomMCP \u5904\u7406\u5668\u6E05\u7406\u5931\u8D25:",e)}try{f.clearAllStatsUpdateLocks(),this.logger.info("[MCPManager] \u7EDF\u8BA1\u66F4\u65B0\u9501\u5DF2\u6E05\u7406")}catch(e){this.logger.error("[MCPManager] \u6E05\u7406\u7EDF\u8BA1\u66F4\u65B0\u9501\u5931\u8D25:",e)}this.services.clear(),this.tools.clear(),this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u5DF2\u505C\u6B62")}getStatus(){return this.getUnifiedStatus()}getStatsUpdateInfo(){try{let e=f.getStatsUpdateLocks();return{activeLocks:e,totalLocks:e.length}}catch(e){return this.logger.warn("[MCPManager] \u83B7\u53D6\u7EDF\u8BA1\u66F4\u65B0\u76D1\u63A7\u4FE1\u606F\u5931\u8D25:",e),{activeLocks:[],totalLocks:0}}}getService(e){return this.services.get(e)}getConnectedServices(){let e=[];for(let[t,r]of this.services)r.isConnected()&&e.push(t);return e}async refreshCustomMCPHandler(){try{this.logger.debug("\u91CD\u65B0\u521D\u59CB\u5316CustomMCPHandler"),await this.customMCPHandler.reinitialize(),this.logger.debug("CustomMCPHandler\u91CD\u65B0\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("CustomMCPHandler\u91CD\u65B0\u521D\u59CB\u5316\u5931\u8D25:",e),e}}async refreshCustomMCPHandlerPublic(){return this.refreshCustomMCPHandler()}getAllServices(){return new Map(this.services)}getCustomMCPHandler(){return this.customMCPHandler}hasCustomMCPTool(e){try{return this.customMCPHandler.hasTool(e)}catch(t){return this.logger.warn(`[MCPManager] \u68C0\u67E5 CustomMCP \u5DE5\u5177 ${e} \u662F\u5426\u5B58\u5728\u5931\u8D25:`,t),!1}}getCustomMCPTools(){try{return this.customMCPHandler.getTools()}catch(e){return this.logger.warn("[MCPManager] \u83B7\u53D6 CustomMCP \u5DE5\u5177\u5217\u8868\u5931\u8D25\uFF0C\u8FD4\u56DE\u7A7A\u6570\u7EC4:",e),[]}}enhanceServiceConfig(e){let t={...e};try{if(e.type==="sse"&&e.url&&e.url.includes("modelscope")){let r=f.getModelScopeApiKey();if(r)t.apiKey=r,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(r){throw this.logger.error(`[MCPManager] \u914D\u7F6E\u589E\u5F3A\u5931\u8D25: ${e.name}`,r),r}}addServiceConfig(e,t){let r,s;if(typeof e=="string"&&t)s=e,r=t;else if(typeof e=="object")s=e.name,r=e;else throw new Error("Invalid arguments for addServiceConfig");let o=this.enhanceServiceConfig(r);this.configs[s]=o,this.logger.debug(`[MCPManager] \u5DF2\u6DFB\u52A0\u670D\u52A1\u914D\u7F6E: ${s}`)}updateServiceConfig(e,t){let r=this.enhanceServiceConfig(t);this.configs[e]=r,this.logger.debug(`[MCPManager] \u5DF2\u66F4\u65B0\u5E76\u589E\u5F3A\u670D\u52A1\u914D\u7F6E: ${e}`)}removeServiceConfig(e){delete this.configs[e],this.logger.debug(`[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=f.getMcpServerConfig();for(let[t,r]of this.services){if(!r.isConnected())continue;let s=r.getTools();if(s.length===0)continue;let o=e[t]?.tools||{},n={};for(let h of s){let T=o[h.name];T?n[h.name]={...T,description:h.description||T.description||""}:n[h.name]={description:h.description||"",enable:!0}}let a=s.map(h=>h.name),u=Object.keys(o).filter(h=>!a.includes(h));if(u.length>0&&this.logger.info(`[MCPManager] \u68C0\u6D4B\u5230\u670D\u52A1 ${t} \u79FB\u9664\u4E86 ${u.length} \u4E2A\u5DE5\u5177: ${u.join(", ")}`),this.hasToolsConfigChanged(o,n)){f.updateServerToolsConfig(t,n);let h=Object.keys(n).filter(S=>!o[S]),T=Object.keys(n).filter(S=>{let y=o[S],I=n[S];return y&&y.description!==I.description});this.logger.debug(`[MCPManager] \u5DF2\u540C\u6B65\u670D\u52A1 ${t} \u7684\u5DE5\u5177\u914D\u7F6E:`),h.length>0&&this.logger.debug(` - \u65B0\u589E\u5DE5\u5177: ${h.join(", ")}`),T.length>0&&this.logger.debug(` - \u66F4\u65B0\u5DE5\u5177: ${T.join(", ")}`),u.length>0&&this.logger.debug(` - \u79FB\u9664\u5DE5\u5177: ${u.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 r=Object.keys(e),s=Object.keys(t);if(r.length!==s.length)return!0;let o=s.filter(a=>!r.includes(a)),n=r.filter(a=>!s.includes(a));if(o.length>0||n.length>0)return!0;for(let a of r){let g=e[a],u=t[a];if(g.description!==u.description)return!0}return!1}scheduleFailedServicesRetry(e){if(e.length===0)return;this.logger.info(`[MCPManager] \u5B89\u6392 ${e.length} \u4E2A\u5931\u8D25\u670D\u52A1\u7684\u91CD\u8BD5`);let t=3e4;for(let r of e)this.failedServices.add(r),this.scheduleServiceRetry(r,t)}scheduleServiceRetry(e,t){let r=this.retryTimers.get(e);r&&(clearTimeout(r),this.retryTimers.delete(e)),this.logger.debug(`[MCPManager] \u5B89\u6392\u670D\u52A1 ${e} \u5728 ${t}ms \u540E\u91CD\u8BD5`);let s=setTimeout(async()=>{this.retryTimers.delete(e),await this.retryFailedService(e)},t);this.retryTimers.set(e,s)}async retryFailedService(e){if(this.failedServices.has(e))try{await this.startService(e),this.failedServices.delete(e),this.logger.info(`[MCPManager] \u670D\u52A1 ${e} \u91CD\u8BD5\u542F\u52A8\u6210\u529F`);try{await this.refreshCustomMCPHandlerPublic()}catch(t){this.logger.error("[MCPManager] \u5237\u65B0CustomMCPHandler\u5931\u8D25:",t)}}catch(t){this.logger.error(`[MCPManager] \u670D\u52A1 ${e} \u91CD\u8BD5\u542F\u52A8\u5931\u8D25:`,t.message);let r=this.getRetryDelay(e),s=Math.min(r*2,3e5);this.logger.debug(`[MCPManager] \u670D\u52A1 ${e} \u4E0B\u6B21\u91CD\u8BD5\u5C06\u5728 ${s}ms \u540E\u8FDB\u884C`),this.scheduleServiceRetry(e,s)}}getRetryDelay(e){return 3e4+e.split("").reduce((r,s)=>r+s.charCodeAt(0),0)%6e4}stopServiceRetry(e){let t=this.retryTimers.get(e);t&&(clearTimeout(t),this.retryTimers.delete(e),this.logger.debug(`[MCPManager] \u5DF2\u505C\u6B62\u670D\u52A1 ${e} \u7684\u91CD\u8BD5`)),this.failedServices.delete(e)}stopAllServiceRetries(){this.logger.info("[MCPManager] \u505C\u6B62\u6240\u6709\u670D\u52A1\u91CD\u8BD5");for(let[e,t]of this.retryTimers)clearTimeout(t),this.logger.debug(`[MCPManager] \u5DF2\u505C\u6B62\u670D\u52A1 ${e} \u7684\u91CD\u8BD5`);this.retryTimers.clear(),this.failedServices.clear()}getFailedServices(){return Array.from(this.failedServices)}isServiceFailed(e){return this.failedServices.has(e)}getRetryStats(){return{failedServices:Array.from(this.failedServices),activeRetries:Array.from(this.retryTimers.keys()),totalFailed:this.failedServices.size,totalActiveRetries:this.retryTimers.size}}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.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u6CE8\u518C\u6210\u529F`),this.emit("transportRegistered",{name:e,adapter:t})}catch(r){throw this.logger.error(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5931\u8D25`,r),r}}async startTransports(){this.logger.info("\u542F\u52A8\u6240\u6709\u4F20\u8F93\u9002\u914D\u5668");let e=[],t=[];for(let[r,s]of this.transportAdapters)try{await s.start(),e.push(r),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${r} \u542F\u52A8\u6210\u529F`)}catch(o){t.push(r),this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${r} \u542F\u52A8\u5931\u8D25`,o)}if(e.length===0&&t.length>0){let r=`\u6240\u6709\u4F20\u8F93\u9002\u914D\u5668\u542F\u52A8\u5931\u8D25\uFF0C\u5931\u8D25\u7684\u9002\u914D\u5668: ${t.join(", ")}`;throw this.logger.error(r),new Error(r)}t.length>0&&this.logger.warn(`\u90E8\u5206\u4F20\u8F93\u9002\u914D\u5668\u542F\u52A8\u5931\u8D25\uFF0C\u6210\u529F: ${e.join(", ")}, \u5931\u8D25: ${t.join(", ")}`),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668\u542F\u52A8\u5B8C\u6210\uFF0C\u6210\u529F: ${e.length}, \u5931\u8D25: ${t.length}`)}async stopTransports(){this.logger.info("\u505C\u6B62\u6240\u6709\u4F20\u8F93\u9002\u914D\u5668");try{for(let[e,t]of this.transportAdapters)try{await t.stop(),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u6210\u529F`)}catch(r){this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u5931\u8D25`,r)}}catch(e){throw this.logger.error("\u4F20\u8F93\u9002\u914D\u5668\u505C\u6B62\u5931\u8D25",e),e}}getTransportAdapters(){return new Map(this.transportAdapters)}getMessageHandler(){return this.messageHandler}async start(){if(this.isRunning)throw new Error("\u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C");this.logger.info("\u542F\u52A8 MCP \u670D\u52A1\u7BA1\u7406\u5668");try{await this.startAllServices(),await this.startTransports(),this.isRunning=!0,this.logger.info("MCP \u670D\u52A1\u7BA1\u7406\u5668\u542F\u52A8\u6210\u529F"),this.emit("started")}catch(e){throw this.logger.error("MCP \u670D\u52A1\u7BA1\u7406\u5668\u542F\u52A8\u5931\u8D25",e),e}}async stop(){if(this.isRunning){this.logger.info("\u505C\u6B62 MCP \u670D\u52A1\u7BA1\u7406\u5668");try{await this.stopTransports(),await this.stopAllServices(),this.isRunning=!1,this.logger.info("MCP \u670D\u52A1\u7BA1\u7406\u5668\u505C\u6B62\u6210\u529F"),this.emit("stopped")}catch(e){throw this.logger.error("MCP \u670D\u52A1\u7BA1\u7406\u5668\u505C\u6B62\u5931\u8D25",e),e}}}getAllConnections(){let e=[];for(let[t,r]of this.services)r.isConnected()&&e.push({id:`service-${t}`,name:t,state:"connected"});for(let[t,r]of this.transportAdapters)e.push({id:r.getConnectionId(),name:t,state:r.getState()});return e}getActiveConnectionCount(){return this.getAllConnections().filter(e=>e.state==="connected").length}getUnifiedStatus(){let e=this.getServiceManagerStatus();return{isRunning:this.isRunning,serviceStatus:e,transportCount:this.getTransportAdapters().size,activeConnections:this.getActiveConnectionCount(),config:this.config,services:e.services,totalTools:e.totalTools,availableTools:e.availableTools}}getServiceManagerStatus(){let e=0,t=[];try{e=this.customMCPHandler.getToolCount(),t=this.customMCPHandler.getToolNames(),this.logger.debug(`[MCPManager] \u6210\u529F\u83B7\u53D6 customMCP \u72B6\u6001: ${e} \u4E2A\u5DE5\u5177`)}catch(a){this.logger.warn("[MCPManager] \u83B7\u53D6 CustomMCP \u72B6\u6001\u5931\u8D25\uFF0C\u5C06\u53EA\u5305\u542B\u6807\u51C6 MCP \u5DE5\u5177:",a),e=0,t=[]}let r=this.tools.size+e,o=[...Array.from(this.tools.keys()),...t],n={services:{},totalTools:r,availableTools:o};for(let[a,g]of this.services){let u=g.getStatus();n.services[a]={connected:u.connected,clientName:`xiaozhi-${a}-client`}}return e>0&&(n.services.customMCP={connected:!0,clientName:"xiaozhi-customMCP-handler"}),n}isServerRunning(){return this.isRunning}isUnifiedServerConfig(e){return e!==null&&typeof e=="object"&&"configs"in e}async routeMessage(e){let t=await this.messageHandler.handleMessage(e);return t===null?null:{jsonrpc:"2.0",method:"response",params:t,id:t.id}}async initialize(){await this.start()}getToolRegistry(){return this}getConnectionManager(){return this}setLogger(e){this.logger=e}getLogger(){return this.logger}};import{Client as Mt}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as ct}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as lt}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as gt}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{EventSource as ut}from"eventsource";typeof global<"u"&&!global.EventSource&&(global.EventSource=ut);function ht(){return c}l(ht,"getLogger");function pt(i){switch(ht().debug(`[TransportFactory] \u521B\u5EFA ${i.type} transport for ${i.name}`),i.type){case"stdio":return mt(i);case"sse":return dt(i);case"streamable-http":return ft(i);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`)}}l(pt,"createTransport");function mt(i){if(!i.command)throw new Error("stdio transport \u9700\u8981 command \u914D\u7F6E");return new lt({command:i.command,args:i.args||[],env:i.env})}l(mt,"createStdioTransport");function dt(i){if(!i.url)throw new Error("SSE transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(i.url),t=Ct(i);return new ct(e,t)}l(dt,"createSSETransport");function ft(i){if(!i.url)throw new Error("StreamableHTTP transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(i.url),t=vt(i);return new gt(e,t)}l(ft,"createStreamableHTTPTransport");function Ct(i){let e={};return i.apiKey?e.headers={Authorization:`Bearer ${i.apiKey}`,...i.headers}:i.headers&&(e.headers=i.headers),e}l(Ct,"createSSEOptions");function vt(i){let e={};return i.apiKey?e.headers={Authorization:`Bearer ${i.apiKey}`,...i.headers}:i.headers&&(e.headers=i.headers),e}l(vt,"createStreamableHTTPOptions");function Tt(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&&!Object.values(_).includes(i.type))throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`);if(!i.type)throw new Error("\u4F20\u8F93\u7C7B\u578B\u672A\u8BBE\u7F6E\uFF0C\u8FD9\u5E94\u8BE5\u5728 inferTransportType \u4E2D\u5904\u7406");switch(i.type){case"stdio":if(!i.command)throw new Error("stdio \u7C7B\u578B\u9700\u8981 command \u5B57\u6BB5");break;case"sse":if(i.url===void 0||i.url===null)throw new Error(`${i.type} \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5`);break;case"streamable-http":if(i.url===void 0||i.url===null)throw new Error(`${i.type} \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5`);break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${i.type}`)}}l(Tt,"validateConfig");function St(){return["stdio","sse","streamable-http"]}l(St,"getSupportedTypes");var ve={create:pt,validateConfig:Tt,getSupportedTypes:St};var se=class{static{l(this,"MCPService")}config;client=null;transport=null;tools=new Map;connectionState="disconnected";logger;connectionTimeout=null;initialized=!1;eventBus=b();constructor(e,t){if(this.logger=t,e.type)this.config=e;else if(e.command)this.config={...e,type:"stdio"};else if(e.url!==void 0&&e.url!==null){let r=this.inferTransportTypeFromUrl(e.url,e.name);this.config={...e,type:r}}else throw new Error(`\u65E0\u6CD5\u4E3A\u670D\u52A1 ${e.name} \u63A8\u65AD\u4F20\u8F93\u7C7B\u578B\u3002\u8BF7\u663E\u5F0F\u6307\u5B9A type \u5B57\u6BB5\uFF0C\u6216\u63D0\u4F9B command/url \u914D\u7F6E`);this.validateConfig()}inferTransportTypeFromUrl(e,t){try{let s=new URL(e).pathname;return s.endsWith("/sse")?"sse":s.endsWith("/mcp")?"streamable-http":(this.logger.info(`[MCP-${t}] URL \u8DEF\u5F84 ${s} \u4E0D\u5339\u914D\u7279\u5B9A\u89C4\u5219\uFF0C\u9ED8\u8BA4\u63A8\u65AD\u4E3A streamable-http \u7C7B\u578B`),"streamable-http")}catch(r){return this.logger.warn(`[MCP-${t}] URL \u89E3\u6790\u5931\u8D25\uFF0C\u9ED8\u8BA4\u63A8\u65AD\u4E3A streamable-http \u7C7B\u578B`,r),"streamable-http"}}validateConfig(){ve.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.attemptConnection()}async attemptConnection(){return this.connectionState="connecting",this.logger.debug(`[MCP-${this.config.name}] \u6B63\u5728\u8FDE\u63A5 MCP \u670D\u52A1: ${this.config.name}`),new Promise((e,t)=>{this.connectionTimeout=setTimeout(()=>{let r=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.config.timeout||1e4}ms)`);this.handleConnectionError(r),t(r)},this.config.timeout||1e4);try{this.client=new Mt({name:`xiaozhi-${this.config.name}-client`,version:"1.0.0"},{capabilities:{tools:{}}}),this.transport=ve.create(this.config),this.client.connect(this.transport).then(async()=>{this.handleConnectionSuccess(),await this.refreshTools(),this.eventBus.emitEvent("mcp:service:connected",{serviceName:this.config.name,tools:this.getTools(),connectionTime:new Date}),e()}).catch(r=>{this.handleConnectionError(r),t(r)})}catch(r){this.handleConnectionError(r),t(r)}})}handleConnectionSuccess(){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.connectionState="connected",this.initialized=!0,this.logger.info(`[MCP-${this.config.name}] MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u5DF2\u5EFA\u7ACB`)}handleConnectionError(e){this.connectionState="disconnected",this.initialized=!1,this.logger.debug(`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u9519\u8BEF:`,e.message),this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.cleanupConnection(),this.eventBus.emitEvent("mcp:service:connection:failed",{serviceName:this.config.name,error:e,attempt:0})}cleanupConnection(){if(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}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 r of t)this.tools.set(r.name,r);this.logger.debug(`${this.config.name} \u670D\u52A1\u52A0\u8F7D\u4E86 ${t.length} \u4E2A\u5DE5\u5177: ${t.map(r=>r.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.cleanupConnection(),this.connectionState="disconnected",this.eventBus.emitEvent("mcp:service:disconnected",{serviceName:this.config.name,reason:"\u624B\u52A8\u65AD\u5F00",disconnectionTime:new Date})}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.debug(`\u8C03\u7528 ${this.config.name} \u670D\u52A1\u7684\u5DE5\u5177 ${e}\uFF0C\u53C2\u6570:`,JSON.stringify(t));try{let r=await this.client.callTool({name:e,arguments:t||{}});return this.logger.debug(`\u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,`${JSON.stringify(r).substring(0,500)}...`),r}catch(r){throw this.logger.error(`\u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,r instanceof Error?r.message:String(r)),r}}getConfig(){return this.config}getStatus(){return{name:this.config.name,connected:this.connectionState==="connected",initialized:this.initialized,transportType:this.config.type||"streamable-http",toolCount:this.tools.size,connectionState:this.connectionState}}isConnected(){return this.connectionState==="connected"&&this.initialized}};import{randomUUID as Pt}from"crypto";import Te from"express";var oe=class extends k{static{l(this,"HTTPAdapter")}app;server=null;clients=new Map;port;host;enableSSE;enableRPC;corsOrigin;maxClients;constructor(e,t={name:"http"}){super(e,t),console.warn("[\u5DF2\u5E9F\u5F03] HTTPAdapter \u5C06\u5728 v2.0.0 \u4E2D\u79FB\u9664\u3002\u8BF7\u4F7F\u7528 WebServer \u7684 /mcp \u7AEF\u70B9\u66FF\u4EE3\u3002"),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=Te(),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",r=>{this.logger.error("HTTP \u670D\u52A1\u5668\u9519\u8BEF",r),this.setState("error"),t(r)})})}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(Te.json({limit:"10mb"})),this.app.use(Te.urlencoded({extended:!0})),this.app.use((e,t,r)=>{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"),r()}),this.app.use((e,t,r)=>{this.logger.debug(`${e.method} ${e.path}`,{query:e.query,headers:e.headers}),r()})}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 r=Date.now().toString(),s=Pt();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:r,sessionId:s,response:t,connectedAt:new Date};this.clients.set(s,o),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u8FDE\u63A5: ${r} (\u4F1A\u8BDD: ${s})`),t.write(`event: endpoint
30
+ data: /messages?sessionId=${s}
31
31
 
32
- `),e.on("close",()=>{this.clients.delete(n),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u65AD\u5F00\u8FDE\u63A5: ${r} (\u4F1A\u8BDD: ${n})`)}),e.on("error",o=>{this.logger.error(`SSE \u5BA2\u6237\u7AEF\u8FDE\u63A5\u9519\u8BEF: ${r}`,o),this.clients.delete(n)})}async handleMessages(e,t){try{let r=e.query.sessionId,n=e.body;if(this.logger.debug(`\u6536\u5230 SSE \u6D88\u606F (\u4F1A\u8BDD: ${r}):`,n),!r||!this.clients.has(r)){t.status(400).json({jsonrpc:"2.0",error:{code:-32600,message:"\u65E0\u6548\u6216\u7F3A\u5C11 sessionId"},id:n.id});return}let s=await this.messageHandler.handleMessage(n);this.logger.debug("SSE \u6D88\u606F\u5904\u7406\u54CD\u5E94:",s);let o=this.clients.get(r);o&&s!==null&&this.sendToClient(o,s),t.status(202).send()}catch(r){this.logger.error("\u5904\u7406 SSE \u6D88\u606F\u65F6\u51FA\u9519",r),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:r.message}})}}async handleRPC(e,t){try{let r=e.body;this.logger.debug("\u6536\u5230 RPC \u6D88\u606F:",r);let n=await this.messageHandler.handleMessage(r);t.json(n)}catch(r){this.logger.error("\u5904\u7406 RPC \u6D88\u606F\u65F6\u51FA\u9519",r),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:r.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 r=this.serializeMessage(t);e.response.write(`data: ${r}
32
+ `),e.on("close",()=>{this.clients.delete(s),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u65AD\u5F00\u8FDE\u63A5: ${r} (\u4F1A\u8BDD: ${s})`)}),e.on("error",n=>{this.logger.error(`SSE \u5BA2\u6237\u7AEF\u8FDE\u63A5\u9519\u8BEF: ${r}`,n),this.clients.delete(s)})}async handleMessages(e,t){try{let r=e.query.sessionId,s=e.body;if(this.logger.debug(`\u6536\u5230 SSE \u6D88\u606F (\u4F1A\u8BDD: ${r}):`,s),!r||!this.clients.has(r)){t.status(400).json({jsonrpc:"2.0",error:{code:-32600,message:"\u65E0\u6548\u6216\u7F3A\u5C11 sessionId"},id:s.id});return}let o=await this.messageHandler.handleMessage(s);this.logger.debug("SSE \u6D88\u606F\u5904\u7406\u54CD\u5E94:",o);let n=this.clients.get(r);n&&o!==null&&this.sendToClient(n,o),t.status(202).send()}catch(r){this.logger.error("\u5904\u7406 SSE \u6D88\u606F\u65F6\u51FA\u9519",r),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:r.message}})}}async handleRPC(e,t){try{let r=e.body;this.logger.debug("\u6536\u5230 RPC \u6D88\u606F:",r);let s=await this.messageHandler.handleMessage(r);t.json(s)}catch(r){this.logger.error("\u5904\u7406 RPC \u6D88\u606F\u65F6\u51FA\u9519",r),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:r.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 r=this.serializeMessage(t);e.response.write(`data: ${r}
33
33
 
34
- `),this.logger.debug(`\u6D88\u606F\u5DF2\u53D1\u9001\u5230\u5BA2\u6237\u7AEF ${e.id}`,{sessionId:e.sessionId,messageId:t.id})}catch(r){this.logger.error(`\u5411\u5BA2\u6237\u7AEF ${e.id} \u53D1\u9001\u6D88\u606F\u5931\u8D25`,r),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 ie=class extends x{static{l(this,"StdioAdapter")}messageBuffer="";isRunning=!1;encoding;bufferSize;constructor(e,t={name:"stdio"}){super(e,t),this.encoding=t.encoding||"utf8",this.bufferSize=t.bufferSize||1024*1024}async initialize(){this.logger.info("\u521D\u59CB\u5316 Stdio \u9002\u914D\u5668");try{process.stdin.setEncoding(this.encoding),this.setupProcessHandlers(),this.setState("connecting"),this.logger.info("Stdio \u9002\u914D\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("Stdio \u9002\u914D\u5668\u521D\u59CB\u5316\u5931\u8D25",e),this.setState("error"),e}}async start(){if(this.isRunning){this.logger.warn("Stdio \u9002\u914D\u5668\u5DF2\u5728\u8FD0\u884C");return}this.logger.info("\u542F\u52A8 Stdio \u9002\u914D\u5668");try{this.isRunning=!0,this.setupStdioHandlers(),this.setState("connected"),this.logger.info("Stdio \u9002\u914D\u5668\u542F\u52A8\u6210\u529F\uFF0C\u7B49\u5F85\u6D88\u606F...")}catch(e){throw this.logger.error("\u542F\u52A8 Stdio \u9002\u914D\u5668\u5931\u8D25",e),this.setState("error"),this.isRunning=!1,e}}async stop(){if(this.isRunning){this.logger.info("\u505C\u6B62 Stdio \u9002\u914D\u5668");try{this.isRunning=!1,this.removeStdioHandlers(),this.setState("disconnected"),this.logger.info("Stdio \u9002\u914D\u5668\u5DF2\u505C\u6B62")}catch(e){throw this.logger.error("\u505C\u6B62 Stdio \u9002\u914D\u5668\u65F6\u51FA\u9519",e),e}}}async sendMessage(e){try{let t=this.serializeMessage(e);process.stdout.write(`${t}
34
+ `),this.logger.debug(`\u6D88\u606F\u5DF2\u53D1\u9001\u5230\u5BA2\u6237\u7AEF ${e.id}`,{sessionId:e.sessionId,messageId:t.id})}catch(r){this.logger.error(`\u5411\u5BA2\u6237\u7AEF ${e.id} \u53D1\u9001\u6D88\u606F\u5931\u8D25`,r),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 ne=class extends k{static{l(this,"StdioAdapter")}messageBuffer="";isRunning=!1;encoding;bufferSize;constructor(e,t={name:"stdio"}){super(e,t),this.encoding=t.encoding||"utf8",this.bufferSize=t.bufferSize||1024*1024}async initialize(){this.logger.info("\u521D\u59CB\u5316 Stdio \u9002\u914D\u5668");try{process.stdin.setEncoding(this.encoding),this.setupProcessHandlers(),this.setState("connecting"),this.logger.info("Stdio \u9002\u914D\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("Stdio \u9002\u914D\u5668\u521D\u59CB\u5316\u5931\u8D25",e),this.setState("error"),e}}async start(){if(this.isRunning){this.logger.warn("Stdio \u9002\u914D\u5668\u5DF2\u5728\u8FD0\u884C");return}this.logger.info("\u542F\u52A8 Stdio \u9002\u914D\u5668");try{this.isRunning=!0,this.setupStdioHandlers(),this.setState("connected"),this.logger.info("Stdio \u9002\u914D\u5668\u542F\u52A8\u6210\u529F\uFF0C\u7B49\u5F85\u6D88\u606F...")}catch(e){throw this.logger.error("\u542F\u52A8 Stdio \u9002\u914D\u5668\u5931\u8D25",e),this.setState("error"),this.isRunning=!1,e}}async stop(){if(this.isRunning){this.logger.info("\u505C\u6B62 Stdio \u9002\u914D\u5668");try{this.isRunning=!1,this.removeStdioHandlers(),this.setState("disconnected"),this.logger.info("Stdio \u9002\u914D\u5668\u5DF2\u505C\u6B62")}catch(e){throw this.logger.error("\u505C\u6B62 Stdio \u9002\u914D\u5668\u65F6\u51FA\u9519",e),e}}}async sendMessage(e){try{let t=this.serializeMessage(e);process.stdout.write(`${t}
35
35
  `),this.logger.debug("\u6D88\u606F\u5DF2\u53D1\u9001\u5230 stdout",{messageId:e.id,method:"method"in e?e.method:"response"})}catch(t){throw this.logger.error("\u53D1\u9001\u6D88\u606F\u5931\u8D25",t),t}}setupStdioHandlers(){process.stdin.on("data",this.handleStdinData.bind(this)),process.stdin.on("end",this.handleStdinEnd.bind(this)),process.stdin.on("error",this.handleStdinError.bind(this))}removeStdioHandlers(){process.stdin.removeListener("data",this.handleStdinData.bind(this)),process.stdin.removeListener("end",this.handleStdinEnd.bind(this)),process.stdin.removeListener("error",this.handleStdinError.bind(this))}async handleStdinData(e){try{if(this.messageBuffer+=e.toString(),this.messageBuffer.length>this.bufferSize){this.logger.warn(`\u6D88\u606F\u7F13\u51B2\u533A\u8D85\u8FC7\u9650\u5236 (${this.bufferSize} bytes)\uFF0C\u6E05\u7A7A\u7F13\u51B2\u533A`),this.messageBuffer="";return}let t=this.messageBuffer.split(`
36
- `);this.messageBuffer=t.pop()||"";for(let r of t){let n=r.trim();n&&await this.processMessageLine(n)}}catch(t){this.logger.error("\u5904\u7406 stdin \u6570\u636E\u65F6\u51FA\u9519",t)}}async processMessageLine(e){try{this.logger.debug(`\u5904\u7406\u6D88\u606F\u884C: ${e.substring(0,200)}...`);let t=this.parseMessage(e);t&&await this.handleIncomingMessage(t)}catch(t){this.logger.error(`\u5904\u7406\u6D88\u606F\u884C\u5931\u8D25: ${e.substring(0,100)}...`,t);let r={jsonrpc:"2.0",error:{code:-32700,message:"\u89E3\u6790\u9519\u8BEF",data:{originalLine:e.substring(0,100)}},id:null};await this.sendMessage(r)}}handleStdinEnd(){this.logger.info("\u6807\u51C6\u8F93\u5165\u5DF2\u5173\u95ED\uFF0C\u505C\u6B62\u9002\u914D\u5668"),this.stop().catch(e=>{this.logger.error("\u505C\u6B62\u9002\u914D\u5668\u65F6\u51FA\u9519",e)})}handleStdinError(e){this.logger.error("\u6807\u51C6\u8F93\u5165\u9519\u8BEF",e),this.setState("error")}setupProcessHandlers(){let e=l(()=>{this.logger.info("\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6E05\u7406\u8D44\u6E90"),this.stop().finally(()=>{process.exit(0)})},"handleExit");process.on("SIGINT",e),process.on("SIGTERM",e),process.on("uncaughtException",t=>{this.logger.error("\u672A\u6355\u83B7\u7684\u5F02\u5E38",t),this.setState("error")}),process.on("unhandledRejection",(t,r)=>{this.logger.error("\u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD",{reason:t,promise:r})})}getStatus(){return{isRunning:this.isRunning,bufferSize:this.messageBuffer.length,encoding:this.encoding,connectionId:this.connectionId,state:this.state}}clearBuffer(){this.messageBuffer="",this.logger.debug("\u6D88\u606F\u7F13\u51B2\u533A\u5DF2\u6E05\u7A7A")}};import Ne,{WebSocketServer as Et}from"ws";var ae=class extends x{static{l(this,"WebSocketAdapter")}ws=null;wsServer=null;endpointUrl;mode;wsState="disconnected";reconnectOptions;reconnectState;connectionTimeout=null;compression;batchQueue=[];batchTimer=null;batchSize;batchTimeout;connections=new Map;maxConnections;constructor(e,t){super(e,t),this.endpointUrl=t.endpointUrl,this.mode=t.mode||"client",this.compression=t.compression||!1,this.batchSize=t.batchSize||10,this.batchTimeout=t.batchTimeout||100,this.maxConnections=t.maxConnections||100,this.reconnectOptions={enabled:!0,maxAttempts:5,initialInterval:1e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0,...t.reconnect},this.reconnectState={attempts:0,nextInterval:this.reconnectOptions.initialInterval,timer:null,lastError:null,isManualDisconnect:!1}}async initialize(){this.logger.info(`\u521D\u59CB\u5316 WebSocket \u9002\u914D\u5668 (${this.mode} \u6A21\u5F0F)`);try{this.setState("connecting"),this.wsState="connecting",this.mode==="client"?await this.initializeClient():await this.initializeServer(),this.logger.info("WebSocket \u9002\u914D\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("WebSocket \u9002\u914D\u5668\u521D\u59CB\u5316\u5931\u8D25",e),this.setState("error"),this.wsState="failed",e}}async initializeClient(){return new Promise((e,t)=>{this.connectionTimeout=setTimeout(()=>{let r=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(r),t(r)},this.reconnectOptions.timeout),this.ws=new Ne(this.endpointUrl),this.compression,this.ws.on("open",()=>{this.handleConnectionSuccess(),e()}),this.ws.on("message",r=>{this.handleIncomingData(r)}),this.ws.on("close",(r,n)=>{this.handleConnectionClose(r,n.toString())}),this.ws.on("error",r=>{this.handleConnectionError(r),t(r)})})}async initializeServer(){return new Promise((e,t)=>{try{let r=new URL(this.endpointUrl),n=Number.parseInt(r.port)||8080;this.wsServer=new Et({port:n,perMessageDeflate:this.compression}),this.wsServer.on("connection",(s,o)=>{this.handleNewConnection(s,o)}),this.wsServer.on("error",s=>{this.logger.error("WebSocket \u670D\u52A1\u5668\u9519\u8BEF",s),t(s)}),this.logger.info(`WebSocket \u670D\u52A1\u5668\u76D1\u542C\u7AEF\u53E3 ${n}`),e()}catch(r){t(r)}})}async start(){if(this.wsState==="connected"){this.logger.warn("WebSocket \u9002\u914D\u5668\u5DF2\u542F\u52A8");return}this.logger.info("\u542F\u52A8 WebSocket \u9002\u914D\u5668");try{this.setState("connected"),this.wsState="connected",this.logger.info("WebSocket \u9002\u914D\u5668\u542F\u52A8\u6210\u529F")}catch(e){throw this.logger.error("\u542F\u52A8 WebSocket \u9002\u914D\u5668\u5931\u8D25",e),this.setState("error"),this.wsState="failed",e}}async stop(){this.logger.info("\u505C\u6B62 WebSocket \u9002\u914D\u5668");try{this.reconnectState.isManualDisconnect=!0,this.reconnectState.timer&&(clearTimeout(this.reconnectState.timer),this.reconnectState.timer=null),this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),await this.flushBatchQueue(),this.ws&&(this.ws.close(),this.ws=null),this.wsServer&&(this.wsServer.close(),this.wsServer=null);for(let[e,t]of this.connections)t.close();this.connections.clear(),this.setState("disconnected"),this.wsState="disconnected",this.logger.info("WebSocket \u9002\u914D\u5668\u5DF2\u505C\u6B62")}catch(e){throw this.logger.error("\u505C\u6B62 WebSocket \u9002\u914D\u5668\u65F6\u51FA\u9519",e),e}}async sendMessage(e){if(this.wsState!=="connected")throw new Error(`WebSocket \u672A\u8FDE\u63A5 (\u72B6\u6001: ${this.wsState})`);return this.batchSize>1?this.addToBatchQueue(e):this.sendMessageDirect(e)}async sendMessageDirect(e){try{let t=this.serializeMessage(e);if(this.mode==="client"&&this.ws)this.ws.send(t);else if(this.mode==="server")for(let r of this.connections.values())r.readyState===Ne.OPEN&&r.send(t);this.logger.debug("\u6D88\u606F\u5DF2\u53D1\u9001",{messageId:e.id,method:"method"in e?e.method:"response"})}catch(t){throw this.logger.error("\u53D1\u9001\u6D88\u606F\u5931\u8D25",t),t}}async addToBatchQueue(e){return new Promise((t,r)=>{this.batchQueue.push({message:e,timestamp:Date.now(),resolve:t,reject:r}),this.batchQueue.length>=this.batchSize?this.flushBatchQueue():this.batchTimer||(this.batchTimer=setTimeout(()=>{this.flushBatchQueue()},this.batchTimeout))})}async flushBatchQueue(){if(this.batchQueue.length===0)return;this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null);let e=this.batchQueue.splice(0);try{let r={jsonrpc:"2.0",method:"batch",params:{messages:e.map(n=>n.message)},id:`batch_${Date.now()}`};await this.sendMessageDirect(r);for(let n of e)n.resolve();this.logger.debug(`\u6279\u5904\u7406\u53D1\u9001 ${e.length} \u6761\u6D88\u606F`)}catch(t){for(let r of e)r.reject(t);this.logger.error("\u6279\u5904\u7406\u53D1\u9001\u5931\u8D25",t)}}async handleIncomingData(e){try{let t=e.toString(),r=this.parseMessage(t);if(r)if(r.method==="batch"&&r.params?.messages)for(let n of r.params.messages)await this.handleIncomingMessage(n);else await this.handleIncomingMessage(r)}catch(t){this.logger.error("\u5904\u7406\u63A5\u6536\u6570\u636E\u5931\u8D25",t)}}handleConnectionSuccess(){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.setState("connected"),this.wsState="connected",this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info("WebSocket \u8FDE\u63A5\u5DF2\u5EFA\u7ACB")}handleConnectionError(e){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.reconnectState.lastError=e,this.logger.error("WebSocket \u8FDE\u63A5\u9519\u8BEF",e),this.setState("error"),this.wsState="failed",this.cleanupConnection()}handleConnectionClose(e,t){this.setState("disconnected"),this.wsState="disconnected",this.logger.info(`WebSocket \u8FDE\u63A5\u5DF2\u5173\u95ED (\u4EE3\u7801: ${e}, \u539F\u56E0: ${t})`),!this.reconnectState.isManualDisconnect&&(this.shouldReconnect()?this.scheduleReconnect():(this.wsState="failed",this.logger.warn(`\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 (${this.reconnectOptions.maxAttempts})\uFF0C\u505C\u6B62\u91CD\u8FDE`)))}handleNewConnection(e,t){if(this.connections.size>=this.maxConnections){this.logger.warn("\u8FBE\u5230\u6700\u5927\u8FDE\u63A5\u6570\u9650\u5236\uFF0C\u62D2\u7EDD\u65B0\u8FDE\u63A5"),e.close(1013,"\u670D\u52A1\u5668\u7E41\u5FD9");return}let r=`${this.getConnectionId()}_${this.connections.size}`;this.connections.set(r,e),this.logger.info(`\u65B0 WebSocket \u8FDE\u63A5: ${r}`),e.on("message",n=>{this.handleIncomingData(n)}),e.on("close",()=>{this.connections.delete(r),this.logger.info(`WebSocket \u8FDE\u63A5\u5DF2\u65AD\u5F00: ${r}`)}),e.on("error",n=>{this.logger.error(`WebSocket \u8FDE\u63A5\u9519\u8BEF ${r}:`,n),this.connections.delete(r)})}cleanupConnection(){this.ws&&(this.ws.removeAllListeners(),this.ws=null)}shouldReconnect(){return this.reconnectOptions.enabled&&this.reconnectState.attempts<this.reconnectOptions.maxAttempts&&!this.reconnectState.isManualDisconnect}scheduleReconnect(){this.wsState="reconnecting",this.reconnectState.attempts++;let e=this.calculateReconnectInterval();this.reconnectOptions.jitter&&(e+=Math.random()*1e3),this.logger.info(`\u5B89\u6392\u91CD\u8FDE (\u7B2C ${this.reconnectState.attempts} \u6B21\uFF0C${e}ms \u540E)`),this.reconnectState.timer=setTimeout(async()=>{try{await this.initializeClient()}catch(t){this.logger.error("\u91CD\u8FDE\u5931\u8D25",t),this.shouldReconnect()?this.scheduleReconnect():this.wsState="failed"}},e)}calculateReconnectInterval(){let{backoffStrategy:e,initialInterval:t,maxInterval:r,backoffMultiplier:n}=this.reconnectOptions,s=this.reconnectState.attempts,o;switch(e){case"linear":o=t+s*1e3;break;case"exponential":o=t*n**s;break;default:o=t;break}return Math.min(o,r)}getStatus(){return{wsState:this.wsState,connectionState:this.state,mode:this.mode,endpointUrl:this.endpointUrl,connectionCount:this.connections.size,reconnectAttempts:this.reconnectState.attempts,batchQueueSize:this.batchQueue.length,compression:this.compression}}async forceReconnect(){if(this.mode!=="client")throw new Error("\u53EA\u6709\u5BA2\u6237\u7AEF\u6A21\u5F0F\u652F\u6301\u91CD\u8FDE");this.logger.info("\u5F3A\u5236\u91CD\u8FDE"),this.reconnectState.attempts=0,this.reconnectState.isManualDisconnect=!1,this.ws&&this.ws.close(),await this.initializeClient()}};async function ze(i={}){c.info("[ServerFactory] \u5F00\u59CB\u521B\u5EFA MCP \u670D\u52A1\u5668",i);try{let e=await Rt(i);c.info(`[ServerFactory] \u786E\u5B9A\u670D\u52A1\u5668\u6A21\u5F0F: ${e}`);let t=new se(i.serverConfig);return await t.initialize(),await xt(t,e,i),c.info("[ServerFactory] MCP \u670D\u52A1\u5668\u521B\u5EFA\u6210\u529F"),t}catch(e){throw c.error("[ServerFactory] \u521B\u5EFA MCP \u670D\u52A1\u5668\u5931\u8D25",e),e}}l(ze,"createServer");async function Rt(i){if(i.mode&&i.mode!=="auto")return i.mode;let e=await $t(i.autoDetect);return c.info("\u73AF\u5883\u68C0\u6D4B\u7ED3\u679C",e),e.suggestedMode}l(Rt,"determineServerMode");async function $t(i={}){let{checkStdin:e=!0,checkEnvironment:t=!0,defaultMode:r="http"}=i,n={hasStdin:!1,isInteractive:!1,hasPort:!1,suggestedMode:r,reasons:[]};e&&(n.hasStdin=!process.stdin.isTTY,n.isInteractive=process.stdin.isTTY||!1,n.hasStdin&&n.reasons.push("\u68C0\u6D4B\u5230\u6807\u51C6\u8F93\u5165\u6D41"),n.isInteractive&&n.reasons.push("\u68C0\u6D4B\u5230\u4EA4\u4E92\u5F0F\u7EC8\u7AEF"));let s=!1;if(t){let o=process.env.MCP_SERVER_MODE,a=process.env.PORT||process.env.MCP_PORT;o==="stdio"?(n.suggestedMode="stdio",n.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=stdio"),s=!0):o==="http"?(n.suggestedMode="http",n.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=http"),s=!0):o==="websocket"?(n.suggestedMode="websocket",n.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=websocket"),s=!0):o==="hybrid"&&(n.suggestedMode="hybrid",n.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=hybrid"),s=!0),a&&(n.hasPort=!0,n.reasons.push(`\u68C0\u6D4B\u5230\u7AEF\u53E3\u914D\u7F6E: ${a}`))}return!s&&n.suggestedMode===r&&(n.hasStdin&&!n.isInteractive?(n.suggestedMode="stdio",n.reasons.push("\u63A8\u65AD\uFF1A\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883\uFF0C\u9002\u5408 Stdio \u6A21\u5F0F")):(n.isInteractive||n.hasPort)&&(n.suggestedMode="http",n.reasons.push("\u63A8\u65AD\uFF1A\u4EA4\u4E92\u5F0F\u73AF\u5883\u6216\u6709\u7AEF\u53E3\u914D\u7F6E\uFF0C\u9002\u5408 HTTP \u6A21\u5F0F"))),n}l($t,"detectEnvironment");async function xt(i,e,t){let r=i.getMessageHandler();switch(e){case"stdio":await Fe(i,r,t.stdioConfig);break;case"http":await je(i,r,t.httpConfig);break;case"websocket":await Ue(i,r,t.websocketConfig);break;case"hybrid":await Fe(i,r,t.stdioConfig),await je(i,r,t.httpConfig),t.websocketConfig&&await Ue(i,r,t.websocketConfig);break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u670D\u52A1\u5668\u6A21\u5F0F: ${e}`)}}l(xt,"registerTransportsForMode");async function Fe(i,e,t={name:"stdio"}){let r=new ie(e,t);await i.registerTransport("stdio",r),c.info("Stdio \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F")}l(Fe,"registerStdioTransport");async function je(i,e,t={name:"http"}){let r={port:3e3,host:"0.0.0.0",...t};process.env.PORT?r.port=Number.parseInt(process.env.PORT,10):process.env.MCP_PORT&&(r.port=Number.parseInt(process.env.MCP_PORT,10));let n=new oe(e,r);await i.registerTransport("http",n),c.info(`HTTP \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F (\u7AEF\u53E3: ${r.port})`)}l(je,"registerHTTPTransport");async function Ue(i,e,t={name:"websocket",endpointUrl:"ws://localhost:8080"}){let r={mode:"client",compression:!0,batchSize:10,batchTimeout:100,maxConnections:100,...t};process.env.WEBSOCKET_URL?r.endpointUrl=process.env.WEBSOCKET_URL:process.env.MCP_WEBSOCKET_URL&&(r.endpointUrl=process.env.MCP_WEBSOCKET_URL);let n=new ae(e,r);await i.registerTransport("websocket",n),c.info(`WebSocket \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F (\u7AEF\u70B9: ${r.endpointUrl})`)}l(Ue,"registerWebSocketTransport");var fs=It(kt(import.meta.url)),_e=w.env.XIAOZHI_CONFIG_DIR||w.cwd();c.initLogFile(_e);c.enableFileLogging(!0);c.info(`\u65E5\u5FD7\u6587\u4EF6\u5DF2\u521D\u59CB\u5316: ${_e}/xiaozhi.log`);async function Lt(){try{c.info("\u542F\u52A8 MCP \u670D\u52A1\u5668\u4EE3\u7406"),await Ot();let i=await ze({mode:"stdio",stdioConfig:{name:"mcp-proxy",encoding:"utf8"}});await i.start(),c.info("MCP \u670D\u52A1\u5668\u4EE3\u7406\u542F\u52A8\u6210\u529F"),w.on("SIGINT",async()=>{c.info("\u6536\u5230 SIGINT \u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668"),await i.stop(),w.exit(0)}),w.on("SIGTERM",async()=>{c.info("\u6536\u5230 SIGTERM \u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668"),await i.stop(),w.exit(0)})}catch(i){c.error("\u542F\u52A8 MCP \u670D\u52A1\u5668\u4EE3\u7406\u5931\u8D25:",i),w.exit(1)}}l(Lt,"main");async function Ot(){try{if(c.info("\u52A0\u8F7D MCP \u670D\u52A1\u5668\u914D\u7F6E"),!f.configExists()){c.warn("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u5C06\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E");return}let i=f.getConfig();c.info(`\u5DF2\u52A0\u8F7D\u914D\u7F6E\uFF0C\u5305\u542B ${Object.keys(i.mcpServers||{}).length} \u4E2A MCP \u670D\u52A1\u5668`)}catch(i){throw c.error("\u52A0\u8F7D\u914D\u7F6E\u5931\u8D25:",i),i}}l(Ot,"loadConfiguration");import.meta.url===`file://${w.argv[1]}`&&Lt().catch(i=>{c.error("MCP \u670D\u52A1\u5668\u4EE3\u7406\u542F\u52A8\u5931\u8D25:",i),w.exit(1)});export{Lt as main};
36
+ `);this.messageBuffer=t.pop()||"";for(let r of t){let s=r.trim();s&&await this.processMessageLine(s)}}catch(t){this.logger.error("\u5904\u7406 stdin \u6570\u636E\u65F6\u51FA\u9519",t)}}async processMessageLine(e){try{this.logger.debug(`\u5904\u7406\u6D88\u606F\u884C: ${e.substring(0,200)}...`);let t=this.parseMessage(e);t&&await this.handleIncomingMessage(t)}catch(t){this.logger.error(`\u5904\u7406\u6D88\u606F\u884C\u5931\u8D25: ${e.substring(0,100)}...`,t);let r=`parse-error-${Date.now()}`;try{let o=JSON.parse(e.trim());o&&(typeof o.id=="string"||typeof o.id=="number")&&(r=o.id)}catch{}let s={jsonrpc:"2.0",error:{code:-32700,message:"\u89E3\u6790\u9519\u8BEF",data:{originalLine:e.substring(0,100)}},id:r};await this.sendMessage(s)}}handleStdinEnd(){this.logger.info("\u6807\u51C6\u8F93\u5165\u5DF2\u5173\u95ED\uFF0C\u505C\u6B62\u9002\u914D\u5668"),this.stop().catch(e=>{this.logger.error("\u505C\u6B62\u9002\u914D\u5668\u65F6\u51FA\u9519",e)})}handleStdinError(e){this.logger.error("\u6807\u51C6\u8F93\u5165\u9519\u8BEF",e),this.setState("error")}setupProcessHandlers(){let e=l(()=>{this.logger.info("\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6E05\u7406\u8D44\u6E90"),this.stop().finally(()=>{process.exit(0)})},"handleExit");process.on("SIGINT",e),process.on("SIGTERM",e),process.on("uncaughtException",t=>{this.logger.error("\u672A\u6355\u83B7\u7684\u5F02\u5E38",t),this.setState("error")}),process.on("unhandledRejection",(t,r)=>{this.logger.error("\u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD",{reason:t,promise:r})})}getStatus(){return{isRunning:this.isRunning,bufferSize:this.messageBuffer.length,encoding:this.encoding,connectionId:this.connectionId,state:this.state}}clearBuffer(){this.messageBuffer="",this.logger.debug("\u6D88\u606F\u7F13\u51B2\u533A\u5DF2\u6E05\u7A7A")}};import Ae,{WebSocketServer as yt}from"ws";var ie=class extends k{static{l(this,"WebSocketAdapter")}ws=null;wsServer=null;endpointUrl;mode;wsState="disconnected";reconnectOptions;reconnectState;connectionTimeout=null;compression;batchQueue=[];batchTimer=null;batchSize;batchTimeout;connections=new Map;maxConnections;constructor(e,t){super(e,t),this.endpointUrl=t.endpointUrl,this.mode=t.mode||"client",this.compression=t.compression||!1,this.batchSize=t.batchSize||10,this.batchTimeout=t.batchTimeout||100,this.maxConnections=t.maxConnections||100,this.reconnectOptions={enabled:!0,maxAttempts:5,initialInterval:1e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0,...t.reconnect},this.reconnectState={attempts:0,nextInterval:this.reconnectOptions.initialInterval,timer:null,lastError:null,isManualDisconnect:!1}}async initialize(){this.logger.info(`\u521D\u59CB\u5316 WebSocket \u9002\u914D\u5668 (${this.mode} \u6A21\u5F0F)`);try{this.setState("connecting"),this.wsState="connecting",this.mode==="client"?await this.initializeClient():await this.initializeServer(),this.logger.info("WebSocket \u9002\u914D\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("WebSocket \u9002\u914D\u5668\u521D\u59CB\u5316\u5931\u8D25",e),this.setState("error"),this.wsState="failed",e}}async initializeClient(){return new Promise((e,t)=>{this.connectionTimeout=setTimeout(()=>{let r=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(r),t(r)},this.reconnectOptions.timeout),this.ws=new Ae(this.endpointUrl),this.compression,this.ws.on("open",()=>{this.handleConnectionSuccess(),e()}),this.ws.on("message",r=>{this.handleIncomingData(r)}),this.ws.on("close",(r,s)=>{this.handleConnectionClose(r,s.toString())}),this.ws.on("error",r=>{this.handleConnectionError(r),t(r)})})}async initializeServer(){return new Promise((e,t)=>{try{let r=new URL(this.endpointUrl),s=Number.parseInt(r.port)||8080;this.wsServer=new yt({port:s,perMessageDeflate:this.compression}),this.wsServer.on("connection",(o,n)=>{this.handleNewConnection(o,n)}),this.wsServer.on("error",o=>{this.logger.error("WebSocket \u670D\u52A1\u5668\u9519\u8BEF",o),t(o)}),this.logger.info(`WebSocket \u670D\u52A1\u5668\u76D1\u542C\u7AEF\u53E3 ${s}`),e()}catch(r){t(r)}})}async start(){if(this.wsState==="connected"){this.logger.warn("WebSocket \u9002\u914D\u5668\u5DF2\u542F\u52A8");return}this.logger.info("\u542F\u52A8 WebSocket \u9002\u914D\u5668");try{this.setState("connected"),this.wsState="connected",this.logger.info("WebSocket \u9002\u914D\u5668\u542F\u52A8\u6210\u529F")}catch(e){throw this.logger.error("\u542F\u52A8 WebSocket \u9002\u914D\u5668\u5931\u8D25",e),this.setState("error"),this.wsState="failed",e}}async stop(){this.logger.info("\u505C\u6B62 WebSocket \u9002\u914D\u5668");try{this.reconnectState.isManualDisconnect=!0,this.reconnectState.timer&&(clearTimeout(this.reconnectState.timer),this.reconnectState.timer=null),this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),await this.flushBatchQueue(),this.ws&&(this.ws.close(),this.ws=null),this.wsServer&&(this.wsServer.close(),this.wsServer=null);for(let[e,t]of this.connections)t.close();this.connections.clear(),this.setState("disconnected"),this.wsState="disconnected",this.logger.info("WebSocket \u9002\u914D\u5668\u5DF2\u505C\u6B62")}catch(e){throw this.logger.error("\u505C\u6B62 WebSocket \u9002\u914D\u5668\u65F6\u51FA\u9519",e),e}}async sendMessage(e){if(this.wsState!=="connected")throw new Error(`WebSocket \u672A\u8FDE\u63A5 (\u72B6\u6001: ${this.wsState})`);return this.batchSize>1?this.addToBatchQueue(e):this.sendMessageDirect(e)}async sendMessageDirect(e){try{let t=this.serializeMessage(e);if(this.mode==="client"&&this.ws)this.ws.send(t);else if(this.mode==="server")for(let r of this.connections.values())r.readyState===Ae.OPEN&&r.send(t);this.logger.debug("\u6D88\u606F\u5DF2\u53D1\u9001",{messageId:e.id,method:"method"in e?e.method:"response"})}catch(t){throw this.logger.error("\u53D1\u9001\u6D88\u606F\u5931\u8D25",t),t}}async addToBatchQueue(e){return new Promise((t,r)=>{this.batchQueue.push({message:e,timestamp:Date.now(),resolve:t,reject:r}),this.batchQueue.length>=this.batchSize?this.flushBatchQueue():this.batchTimer||(this.batchTimer=setTimeout(()=>{this.flushBatchQueue()},this.batchTimeout))})}async flushBatchQueue(){if(this.batchQueue.length===0)return;this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null);let e=this.batchQueue.splice(0);try{let r={jsonrpc:"2.0",method:"batch",params:{messages:e.map(s=>s.message)},id:`batch_${Date.now()}`};await this.sendMessageDirect(r);for(let s of e)s.resolve();this.logger.debug(`\u6279\u5904\u7406\u53D1\u9001 ${e.length} \u6761\u6D88\u606F`)}catch(t){for(let r of e)r.reject(t);this.logger.error("\u6279\u5904\u7406\u53D1\u9001\u5931\u8D25",t)}}async handleIncomingData(e){try{let t=e.toString(),r=this.parseMessage(t);if(r)if(r.method==="batch"&&r.params&&typeof r.params=="object"&&"messages"in r.params&&Array.isArray(r.params.messages)){let s=r.params.messages;for(let o of s)await this.handleIncomingMessage(o)}else await this.handleIncomingMessage(r)}catch(t){this.logger.error("\u5904\u7406\u63A5\u6536\u6570\u636E\u5931\u8D25",t)}}handleConnectionSuccess(){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.setState("connected"),this.wsState="connected",this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info("WebSocket \u8FDE\u63A5\u5DF2\u5EFA\u7ACB")}handleConnectionError(e){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.reconnectState.lastError=e,this.logger.error("WebSocket \u8FDE\u63A5\u9519\u8BEF",e),this.setState("error"),this.wsState="failed",this.cleanupConnection()}handleConnectionClose(e,t){this.setState("disconnected"),this.wsState="disconnected",this.logger.info(`WebSocket \u8FDE\u63A5\u5DF2\u5173\u95ED (\u4EE3\u7801: ${e}, \u539F\u56E0: ${t})`),!this.reconnectState.isManualDisconnect&&(this.shouldReconnect()?this.scheduleReconnect():(this.wsState="failed",this.logger.warn(`\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 (${this.reconnectOptions.maxAttempts})\uFF0C\u505C\u6B62\u91CD\u8FDE`)))}handleNewConnection(e,t){if(this.connections.size>=this.maxConnections){this.logger.warn("\u8FBE\u5230\u6700\u5927\u8FDE\u63A5\u6570\u9650\u5236\uFF0C\u62D2\u7EDD\u65B0\u8FDE\u63A5"),e.close(1013,"\u670D\u52A1\u5668\u7E41\u5FD9");return}let r=`${this.getConnectionId()}_${this.connections.size}`;this.connections.set(r,e),this.logger.info(`\u65B0 WebSocket \u8FDE\u63A5: ${r}`),e.on("message",s=>{this.handleIncomingData(s)}),e.on("close",()=>{this.connections.delete(r),this.logger.info(`WebSocket \u8FDE\u63A5\u5DF2\u65AD\u5F00: ${r}`)}),e.on("error",s=>{this.logger.error(`WebSocket \u8FDE\u63A5\u9519\u8BEF ${r}:`,s),this.connections.delete(r)})}cleanupConnection(){this.ws&&(this.ws.removeAllListeners(),this.ws=null)}shouldReconnect(){return this.reconnectOptions.enabled&&this.reconnectState.attempts<this.reconnectOptions.maxAttempts&&!this.reconnectState.isManualDisconnect}scheduleReconnect(){this.wsState="reconnecting",this.reconnectState.attempts++;let e=this.calculateReconnectInterval();this.reconnectOptions.jitter&&(e+=Math.random()*1e3),this.logger.info(`\u5B89\u6392\u91CD\u8FDE (\u7B2C ${this.reconnectState.attempts} \u6B21\uFF0C${e}ms \u540E)`),this.reconnectState.timer=setTimeout(async()=>{try{await this.initializeClient()}catch(t){this.logger.error("\u91CD\u8FDE\u5931\u8D25",t),this.shouldReconnect()?this.scheduleReconnect():this.wsState="failed"}},e)}calculateReconnectInterval(){let{backoffStrategy:e,initialInterval:t,maxInterval:r,backoffMultiplier:s}=this.reconnectOptions,o=this.reconnectState.attempts,n;switch(e){case"linear":n=t+o*1e3;break;case"exponential":n=t*s**o;break;default:n=t;break}return Math.min(n,r)}getStatus(){return{wsState:this.wsState,connectionState:this.state,mode:this.mode,endpointUrl:this.endpointUrl,connectionCount:this.connections.size,reconnectAttempts:this.reconnectState.attempts,batchQueueSize:this.batchQueue.length,compression:this.compression}}async forceReconnect(){if(this.mode!=="client")throw new Error("\u53EA\u6709\u5BA2\u6237\u7AEF\u6A21\u5F0F\u652F\u6301\u91CD\u8FDE");this.logger.info("\u5F3A\u5236\u91CD\u8FDE"),this.reconnectState.attempts=0,this.reconnectState.isManualDisconnect=!1,this.ws&&this.ws.close(),await this.initializeClient()}};async function Ne(i={}){c.info("[ServerFactory] \u5F00\u59CB\u521B\u5EFA MCP \u670D\u52A1\u5668",i);try{let e=await bt(i);c.info(`[ServerFactory] \u786E\u5B9A\u670D\u52A1\u5668\u6A21\u5F0F: ${e}`);let t=new re(i.serverConfig);return await t.start(),await Et(t,e,i),c.info("[ServerFactory] MCP \u670D\u52A1\u7BA1\u7406\u5668\u521B\u5EFA\u6210\u529F"),t}catch(e){throw c.error("[ServerFactory] \u521B\u5EFA MCP \u670D\u52A1\u7BA1\u7406\u5668\u5931\u8D25",e),e}}l(Ne,"createServer");async function bt(i){if(i.mode&&i.mode!=="auto")return i.mode;let e=await wt(i.autoDetect);return c.info("\u73AF\u5883\u68C0\u6D4B\u7ED3\u679C",e),e.suggestedMode}l(bt,"determineServerMode");async function wt(i={}){let{checkStdin:e=!0,checkEnvironment:t=!0,defaultMode:r="http"}=i,s={hasStdin:!1,isInteractive:!1,hasPort:!1,suggestedMode:r,reasons:[]};e&&(s.hasStdin=!process.stdin.isTTY,s.isInteractive=process.stdin.isTTY||!1,s.hasStdin&&s.reasons.push("\u68C0\u6D4B\u5230\u6807\u51C6\u8F93\u5165\u6D41"),s.isInteractive&&s.reasons.push("\u68C0\u6D4B\u5230\u4EA4\u4E92\u5F0F\u7EC8\u7AEF"));let o=!1;if(t){let n=process.env.MCP_SERVER_MODE,a=process.env.PORT||process.env.MCP_PORT;n==="stdio"?(s.suggestedMode="stdio",s.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=stdio"),o=!0):n==="http"?(s.suggestedMode="http",s.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=http"),o=!0):n==="websocket"?(s.suggestedMode="websocket",s.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=websocket"),o=!0):n==="hybrid"&&(s.suggestedMode="hybrid",s.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=hybrid"),o=!0),a&&(s.hasPort=!0,s.reasons.push(`\u68C0\u6D4B\u5230\u7AEF\u53E3\u914D\u7F6E: ${a}`))}return!o&&s.suggestedMode===r&&(s.hasStdin&&!s.isInteractive?(s.suggestedMode="stdio",s.reasons.push("\u63A8\u65AD\uFF1A\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883\uFF0C\u9002\u5408 Stdio \u6A21\u5F0F")):(s.isInteractive||s.hasPort)&&(s.suggestedMode="http",s.reasons.push("\u63A8\u65AD\uFF1A\u4EA4\u4E92\u5F0F\u73AF\u5883\u6216\u6709\u7AEF\u53E3\u914D\u7F6E\uFF0C\u9002\u5408 HTTP \u6A21\u5F0F"))),s}l(wt,"detectEnvironment");async function Et(i,e,t){let r=i.getMessageHandler();switch(e){case"stdio":await De(i,r,t.stdioConfig);break;case"http":await Oe(i,r,t.httpConfig);break;case"websocket":await He(i,r,t.websocketConfig);break;case"hybrid":await De(i,r,t.stdioConfig),await Oe(i,r,t.httpConfig),t.websocketConfig&&await He(i,r,t.websocketConfig);break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u670D\u52A1\u5668\u6A21\u5F0F: ${e}`)}}l(Et,"registerTransportsForMode");async function De(i,e,t={name:"stdio"}){let r=new ne(e,t);await i.registerTransport("stdio",r),c.info("Stdio \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F")}l(De,"registerStdioTransport");async function Oe(i,e,t={name:"http"}){let r;t.port?r=t.port:process.env.PORT?r=Number.parseInt(process.env.PORT,10):process.env.MCP_PORT?r=Number.parseInt(process.env.MCP_PORT,10):r=3e3;let s={...t,port:r,host:t.host||"0.0.0.0"},o=new oe(e,s);await i.registerTransport("http",o),c.info(`HTTP \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F (\u7AEF\u53E3: ${s.port})`)}l(Oe,"registerHTTPTransport");async function He(i,e,t={name:"websocket",endpointUrl:"ws://localhost:8080"}){let r={mode:"client",compression:!0,batchSize:10,batchTimeout:100,maxConnections:100,...t};process.env.WEBSOCKET_URL?r.endpointUrl=process.env.WEBSOCKET_URL:process.env.MCP_WEBSOCKET_URL&&(r.endpointUrl=process.env.MCP_WEBSOCKET_URL);let s=new ie(e,r);await i.registerTransport("websocket",s),c.info(`WebSocket \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F (\u7AEF\u70B9: ${r.endpointUrl})`)}l(He,"registerWebSocketTransport");var wo=Rt($t(import.meta.url)),je=R.env.XIAOZHI_CONFIG_DIR||R.cwd();c.initLogFile(je);c.enableFileLogging(!0);c.info(`\u65E5\u5FD7\u6587\u4EF6\u5DF2\u521D\u59CB\u5316: ${je}/xiaozhi.log`);async function xt(){try{c.info("\u542F\u52A8 MCP \u670D\u52A1\u5668\u4EE3\u7406"),await kt();let i=await Ne({mode:"stdio",stdioConfig:{name:"mcp-proxy",encoding:"utf8"}});c.info("MCP \u670D\u52A1\u5668\u4EE3\u7406\u542F\u52A8\u6210\u529F"),R.on("SIGINT",async()=>{c.info("\u6536\u5230 SIGINT \u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u7BA1\u7406\u5668"),await i.stop(),R.exit(0)}),R.on("SIGTERM",async()=>{c.info("\u6536\u5230 SIGTERM \u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u7BA1\u7406\u5668"),await i.stop(),R.exit(0)})}catch(i){c.error("\u542F\u52A8 MCP \u670D\u52A1\u5668\u4EE3\u7406\u5931\u8D25:",i),R.exit(1)}}l(xt,"main");async function kt(){try{if(c.info("\u52A0\u8F7D MCP \u670D\u52A1\u5668\u914D\u7F6E"),!f.configExists()){c.warn("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u5C06\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E");return}let i=f.getConfig();c.info(`\u5DF2\u52A0\u8F7D\u914D\u7F6E\uFF0C\u5305\u542B ${Object.keys(i.mcpServers||{}).length} \u4E2A MCP \u670D\u52A1\u5668`)}catch(i){throw c.error("\u52A0\u8F7D\u914D\u7F6E\u5931\u8D25:",i),i}}l(kt,"loadConfiguration");import.meta.url===`file://${R.argv[1]}`&&xt().catch(i=>{c.error("MCP \u670D\u52A1\u5668\u4EE3\u7406\u542F\u52A8\u5931\u8D25:",i),R.exit(1)});export{xt as main};
37
37
  //# sourceMappingURL=mcpServerProxy.js.map