xiaozhi-client 1.6.11 → 1.6.12-beta.0

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.
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- var re=Object.defineProperty;var s=(o,e)=>re(o,"name",{value:e,configurable:!0});import{dirname as Fe}from"path";import f from"process";import{fileURLToPath as ze}from"url";import*as g from"fs";import*as p from"path";import b from"chalk";import M from"pino";function se(o){let e=o.getFullYear(),t=String(o.getMonth()+1).padStart(2,"0"),n=String(o.getDate()).padStart(2,"0"),i=String(o.getHours()).padStart(2,"0"),r=String(o.getMinutes()).padStart(2,"0"),a=String(o.getSeconds()).padStart(2,"0");return`${e}-${t}-${n} ${i}:${r}:${a}`}s(se,"formatDateTime");var N=class{static{s(this,"Logger")}logFilePath=null;pinoInstance;isDaemonMode;maxLogFileSize=10*1024*1024;maxLogFiles=5;constructor(){this.isDaemonMode=process.env.XIAOZHI_DAEMON==="true",this.pinoInstance=this.createPinoInstance()}createPinoInstance(){let e=[];if(!this.isDaemonMode){let t=this.createOptimizedConsoleStream();e.push({level:"debug",stream:t})}return this.logFilePath&&e.push({level:"debug",stream:M.destination({dest:this.logFilePath,sync:!1,append:!0,mkdir:!0})}),e.length===0&&e.push({level:"debug",stream:M.destination({dest:"/dev/null"})}),M({level:"debug",timestamp:M.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:s((t,n)=>({level:n}),"level")},base:null,serializers:{err:M.stdSerializers?.err||(t=>t)}},M.multistream(e,{dedupe:!0}))}createOptimizedConsoleStream(){let e=new Map([[20,{name:"DEBUG",color:b.gray}],[30,{name:"INFO",color:b.blue}],[40,{name:"WARN",color:b.yellow}],[50,{name:"ERROR",color:b.red}],[60,{name:"FATAL",color:b.red}]]);return{write:s(t=>{try{let n=JSON.parse(t),i=this.formatConsoleMessageOptimized(n,e);this.safeWrite(`${i}
3
- `)}catch{this.safeWrite(t)}},"write")}}safeWrite(e){try{process.stderr&&typeof process.stderr.write=="function"?process.stderr.write(e):console&&typeof console.error=="function"&&console.error(e.trim())}catch{}}formatConsoleMessageOptimized(e,t){let n=se(new Date),i=t.get(e.level)||{name:"UNKNOWN",color:s(l=>l,"color")},r=i.color(`[${i.name}]`),a=e.msg;if(e.args&&Array.isArray(e.args)){let l=e.args.map(S=>typeof S=="object"?JSON.stringify(S):String(S)).join(" ");a=`${a} ${l}`}return`[${n}] ${r} ${a}`}initLogFile(e){this.logFilePath=p.join(e,"xiaozhi.log"),this.rotateLogFileIfNeeded(),g.existsSync(this.logFilePath)||g.writeFileSync(this.logFilePath,""),this.pinoInstance=this.createPinoInstance()}enableFileLogging(e){e&&this.logFilePath&&(this.pinoInstance=this.createPinoInstance())}info(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}success(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}warn(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.warn(e):this.pinoInstance.warn({args:t},e):this.pinoInstance.warn(e,t[0]||"")}error(e,...t){if(typeof e=="string")if(t.length===0)this.pinoInstance.error(e);else{let n=t.map(i=>i instanceof Error?{message:i.message,stack:i.stack,name:i.name,cause:i.cause}:i);this.pinoInstance.error({args:n},e)}else{let n=this.enhanceErrorObject(e);this.pinoInstance.error(n,t[0]||"")}}debug(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.debug(e):this.pinoInstance.debug({args:t},e):this.pinoInstance.debug(e,t[0]||"")}log(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}enhanceErrorObject(e){let t={...e};for(let[n,i]of Object.entries(t))i instanceof Error&&(t[n]={message:i.message,stack:i.stack,name:i.name,cause:i.cause});return t}rotateLogFileIfNeeded(){if(!(!this.logFilePath||!g.existsSync(this.logFilePath)))try{g.statSync(this.logFilePath).size>this.maxLogFileSize&&this.rotateLogFile()}catch{}}rotateLogFile(){if(this.logFilePath)try{let e=p.dirname(this.logFilePath),t=p.basename(this.logFilePath,".log");for(let i=this.maxLogFiles-1;i>=1;i--){let r=p.join(e,`${t}.${i}.log`),a=p.join(e,`${t}.${i+1}.log`);g.existsSync(r)&&(i===this.maxLogFiles-1?g.unlinkSync(r):g.renameSync(r,a))}let n=p.join(e,`${t}.1.log`);g.renameSync(this.logFilePath,n)}catch{}}cleanupOldLogs(){if(this.logFilePath)try{let e=p.dirname(this.logFilePath),t=p.basename(this.logFilePath,".log");for(let n=this.maxLogFiles+1;n<=this.maxLogFiles+10;n++){let i=p.join(e,`${t}.${n}.log`);g.existsSync(i)&&g.unlinkSync(i)}}catch{}}setLogFileOptions(e,t){this.maxLogFileSize=e,this.maxLogFiles=t}withTag(e){return this}close(){}},c=new N;import{copyFileSync as ce,existsSync as y,readFileSync as le,writeFileSync as ge}from"fs";import{dirname as he,resolve as C}from"path";import{fileURLToPath as pe}from"url";import*as w from"comment-json";import fe from"dayjs";import j from"json5";import*as G from"json5-writer";function ae(o){if(!o||typeof o!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u6709\u6548\u7684\u5BF9\u8C61");if("command"in o&&typeof o.command=="string")return"stdio";if("type"in o&&o.type==="sse")return"sse";if("type"in o&&o.type==="streamable-http"||"url"in o&&typeof o.url=="string")return"streamable-http";throw new Error("\u65E0\u6CD5\u8BC6\u522B\u7684 MCP \u670D\u52A1\u914D\u7F6E\u7C7B\u578B\u3002\u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5\uFF08stdio\uFF09\u3001type: 'sse' \u5B57\u6BB5\uFF08sse\uFF09\u6216 url \u5B57\u6BB5\uFF08streamable-http\uFF09")}s(ae,"getMcpServerCommunicationType");function k(o,e){if(!e||typeof e!="object")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61`};try{switch(ae(e)){case"stdio":if(!e.command||typeof e.command!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 command \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(!Array.isArray(e.args))return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4`};if(e.env&&typeof e.env!="object")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61`};break;case"sse":if(e.type!=="sse")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 type \u5B57\u6BB5\u5FC5\u987B\u662F "sse"`};if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};break;case"streamable-http":if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(e.type&&e.type!=="streamable-http")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 type \u5B57\u6BB5\u5982\u679C\u5B58\u5728\uFF0C\u5FC5\u987B\u662F "streamable-http"`};break;default:return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u7C7B\u578B\u65E0\u6CD5\u8BC6\u522B`}}return{valid:!0}}catch(t){return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u65E0\u6548: ${t instanceof Error?t.message:"\u672A\u77E5\u9519\u8BEF"}`}}}s(k,"validateMcpServerConfig");var K=he(pe(import.meta.url)),H={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},F=class o{static{s(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;constructor(){let e=[C(K,"templates","default","xiaozhi.config.json"),C(K,"..","templates","default","xiaozhi.config.json"),C(process.cwd(),"templates","default","xiaozhi.config.json")];this.defaultConfigPath=e.find(t=>y(t))||e[0]}getConfigFilePath(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let n of t){let i=C(e,n);if(y(i))return i}return C(e,"xiaozhi.config.json")}getConfigFileFormat(e){return e.endsWith(".json5")?"json5":e.endsWith(".jsonc")?"jsonc":"json"}static getInstance(){return o.instance||(o.instance=new o),o.instance}configExists(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let n of t){let i=C(e,n);if(y(i))return!0}return!1}initConfig(e="json"){if(!y(this.defaultConfigPath))throw new Error(`\u9ED8\u8BA4\u914D\u7F6E\u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728: ${this.defaultConfigPath}`);if(this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u521D\u59CB\u5316");let t=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),n=`xiaozhi.config.${e}`,i=C(t,n);ce(this.defaultConfigPath,i),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),i=le(e,"utf8").replace(/^\uFEFF/,""),r;switch(t){case"json5":r=j.parse(i),this.json5Writer=G.load(i);break;case"jsonc":r=w.parse(i);break;default:r=JSON.parse(i);break}return this.validateConfig(r),r}catch(e){throw e instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${e.message}`):e}}validateConfig(e){if(!e||typeof e!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let t=e;if(t.mcpEndpoint===void 0||t.mcpEndpoint===null)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(typeof t.mcpEndpoint!="string")if(Array.isArray(t.mcpEndpoint)){if(t.mcpEndpoint.length===0)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let n of t.mcpEndpoint)if(typeof n!="string"||n.trim()==="")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6216\u5B57\u7B26\u4E32\u6570\u7EC4");if(!t.mcpServers||typeof t.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[n,i]of Object.entries(t.mcpServers)){if(!i||typeof i!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${n} \u65E0\u6548`);let r=k(n,i);if(!r.valid)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A${r.error}`)}}getConfig(){return this.config=this.loadConfig(),JSON.parse(JSON.stringify(this.config))}getMutableConfig(){return this.config||(this.config=this.loadConfig()),this.config}getMcpEndpoint(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?e.mcpEndpoint[0]||"":e.mcpEndpoint}getMcpEndpoints(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?[...e.mcpEndpoint]:e.mcpEndpoint?[e.mcpEndpoint]:[]}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(e){return this.getMcpServerConfig()[e]?.tools||{}}isToolEnabled(e,t){return this.getServerToolsConfig(e)[t]?.enable!==!1}updateMcpEndpoint(e){if(Array.isArray(e)){if(e.length===0)throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let n of e)if(!n||typeof n!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig();t.mcpEndpoint=e,this.saveConfig(t)}addMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),n=this.getMcpEndpoints();if(n.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let i=[...n,e];t.mcpEndpoint=i,this.saveConfig(t)}removeMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),n=this.getMcpEndpoints();if(n.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);if(n.length===1)throw new Error("\u4E0D\u80FD\u5220\u9664\u6700\u540E\u4E00\u4E2A MCP \u7AEF\u70B9");let r=n.filter(a=>a!==e);t.mcpEndpoint=r,this.saveConfig(t)}updateMcpServer(e,t){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let n=k(e,t);if(!n.valid)throw new Error(n.error||"\u670D\u52A1\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let i=this.getMutableConfig();i.mcpServers[e]=t,this.saveConfig(i)}removeMcpServer(e){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getConfig();if(!t.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);let n={...t.mcpServers};delete n[e];let i={...t,mcpServers:n};this.saveConfig(i)}updateServerToolsConfig(e,t){let n=this.getMutableConfig();n.mcpServerConfig||(n.mcpServerConfig={}),Object.keys(t).length===0?delete n.mcpServerConfig[e]:n.mcpServerConfig[e]={tools:t},this.saveConfig(n)}removeServerToolsConfig(e){let n={...this.getConfig()};n.mcpServerConfig&&(delete n.mcpServerConfig[e],this.saveConfig(n))}cleanupInvalidServerToolsConfig(){let e=this.getMutableConfig();if(!e.mcpServerConfig)return;let t=Object.keys(e.mcpServers),i=Object.keys(e.mcpServerConfig).filter(r=>!t.includes(r));if(i.length>0){for(let r of i)delete e.mcpServerConfig[r];this.saveConfig(e),c.info(`\u5DF2\u6E05\u7406 ${i.length} \u4E2A\u65E0\u6548\u7684\u670D\u52A1\u5DE5\u5177\u914D\u7F6E: ${i.join(", ")}`)}}setToolEnabled(e,t,n,i){let r=this.getMutableConfig();r.mcpServerConfig||(r.mcpServerConfig={}),r.mcpServerConfig[e]||(r.mcpServerConfig[e]={tools:{}}),r.mcpServerConfig[e].tools[t]={...r.mcpServerConfig[e].tools[t],enable:n,...i&&{description:i}},this.saveConfig(r)}saveConfig(e){try{this.validateConfig(e);let t;this.currentConfigPath?t=this.currentConfigPath:(t=this.getConfigFilePath(),this.currentConfigPath=t);let n=this.getConfigFileFormat(t),i;switch(n){case"json5":try{this.json5Writer?(this.json5Writer.write(e),i=this.json5Writer.toSource()):(console.warn("\u6CA1\u6709 json5Writer \u5B9E\u4F8B\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F"),i=j.stringify(e,null,2))}catch(r){console.warn("\u4F7F\u7528 json5-writer \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F:",r),i=j.stringify(e,null,2)}break;case"jsonc":try{i=w.stringify(e,null,2)}catch(r){console.warn("\u4F7F\u7528 comment-json \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON \u683C\u5F0F:",r),i=JSON.stringify(e,null,2)}break;default:i=JSON.stringify(e,null,2);break}ge(t,i,"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??H.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??H.heartbeatTimeout,reconnectInterval:t.reconnectInterval??H.reconnectInterval}}getHeartbeatInterval(){return this.getConnectionConfig().heartbeatInterval}getHeartbeatTimeout(){return this.getConnectionConfig().heartbeatTimeout}getReconnectInterval(){return this.getConnectionConfig().reconnectInterval}updateConnectionConfig(e){let t=this.getMutableConfig();t.connection||(t.connection={}),Object.assign(t.connection,e),this.saveConfig(t)}async updateToolUsageStats(e,t,n){try{let i=this.getMutableConfig();i.mcpServerConfig||(i.mcpServerConfig={}),i.mcpServerConfig[e]||(i.mcpServerConfig[e]={tools:{}}),i.mcpServerConfig[e].tools[t]||(i.mcpServerConfig[e].tools[t]={enable:!0});let r=i.mcpServerConfig[e].tools[t],a=r.usageCount||0,l=r.lastUsedTime;r.usageCount=a+1,(!l||new Date(n)>new Date(l))&&(r.lastUsedTime=fe(n).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(i),c.debug(`\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${e}/${t}, \u4F7F\u7528\u6B21\u6570: ${r.usageCount}`)}catch(i){c.error(`\u66F4\u65B0\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5931\u8D25 (${e}/${t}): ${i instanceof Error?i.message:String(i)}`)}}setHeartbeatInterval(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:e})}setHeartbeatTimeout(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:e})}setReconnectInterval(e){if(e<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:e})}getModelScopeConfig(){return this.getConfig().modelscope||{}}getModelScopeApiKey(){return this.getModelScopeConfig().apiKey||process.env.MODELSCOPE_API_TOKEN}updateModelScopeConfig(e){let t=this.getMutableConfig();t.modelscope||(t.modelscope={}),Object.assign(t.modelscope,e),this.saveConfig(t)}setModelScopeApiKey(e){if(!e||typeof e!="string")throw new Error("API Key \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");this.updateModelScopeConfig({apiKey:e})}getWebUIConfig(){return this.getConfig().webUI||{}}getWebUIPort(){return this.getWebUIConfig().port??9999}notifyConfigUpdate(e){try{let t=global.__webServer;t&&typeof t.broadcastConfigUpdate=="function"&&(t.broadcastConfigUpdate(e),console.log("\u5DF2\u901A\u8FC7 WebSocket \u5E7F\u64AD\u914D\u7F6E\u66F4\u65B0"))}catch(t){console.warn("\u901A\u77E5 Web \u754C\u9762\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",t instanceof Error?t.message:String(t))}}updateWebUIConfig(e){let t=this.getMutableConfig();t.webUI||(t.webUI={}),Object.assign(t.webUI,e),this.saveConfig(t)}setWebUIPort(e){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error("\u7AEF\u53E3\u53F7\u5FC5\u987B\u662F 1-65535 \u4E4B\u95F4\u7684\u6574\u6570");this.updateWebUIConfig({port:e})}},d=F.getInstance();import{randomUUID as de}from"crypto";import z from"express";var u=class{static{s(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);this.logger.debug("\u53D1\u9001\u54CD\u5E94\u6D88\u606F:",t),await this.sendMessage(t)}catch(t){this.logger.error(`\u5904\u7406\u6D88\u606F\u65F6\u51FA\u9519: ${e.method}`,t);let n=this.createErrorResponse(t,e.id);await this.sendMessage(n)}}createErrorResponse(e,t){let n=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?n=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(n=-32602),{jsonrpc:"2.0",error:{code:n,message:e.message,data:{stack:e.stack}},id:t||null}}generateConnectionId(){let e=Date.now(),t=Math.random().toString(36).substr(2,9);return`${this.config.name}_${e}_${t}`}getConnectionId(){return this.connectionId}getState(){return this.state}setState(e){let t=this.state;this.state=e,t!==e&&(this.logger.info(`\u8FDE\u63A5\u72B6\u6001\u53D8\u66F4: ${t} -> ${e}`),this.onStateChange(t,e))}onStateChange(e,t){}getConfig(){return{...this.config}}getMessageHandler(){return this.messageHandler}parseMessage(e){try{let t=JSON.parse(e.trim());return!t.jsonrpc||t.jsonrpc!=="2.0"?(this.logger.warn("\u6536\u5230\u975E JSON-RPC 2.0 \u683C\u5F0F\u7684\u6D88\u606F",t),null):t.method?t:(this.logger.warn("\u6536\u5230\u6CA1\u6709 method \u5B57\u6BB5\u7684\u6D88\u606F",t),null)}catch(t){return this.logger.error("\u89E3\u6790 JSON \u6D88\u606F\u5931\u8D25",{data:e,error:t}),null}}serializeMessage(e){try{return JSON.stringify(e)}catch(t){this.logger.error("\u5E8F\u5217\u5316\u6D88\u606F\u5931\u8D25",{message:e,error:t});let n=t instanceof Error?t.message:String(t);throw new Error(`\u6D88\u606F\u5E8F\u5217\u5316\u5931\u8D25: ${n}`)}}validateMessage(e){return!(!e||typeof e!="object"||e.jsonrpc!=="2.0"||e.method&&typeof e.method!="string"||!e.method&&!e.result&&!e.error)}createTimeoutPromise(e,t){return Promise.race([e,new Promise((n,i)=>{setTimeout(()=>{i(new Error(`\u64CD\u4F5C\u8D85\u65F6: ${t}ms`))},t)})])}};var T=class extends u{static{s(this,"HTTPAdapter")}app;server=null;clients=new Map;port;host;enableSSE;enableRPC;corsOrigin;maxClients;constructor(e,t={name:"http"}){super(e,t),this.port=t.port||3e3,this.host=t.host||"0.0.0.0",this.enableSSE=t.enableSSE!==!1,this.enableRPC=t.enableRPC!==!1,this.corsOrigin=t.corsOrigin||"*",this.maxClients=t.maxClients!==void 0?t.maxClients:100,this.app=z(),this.setupMiddleware()}async initialize(){this.logger.info("\u521D\u59CB\u5316 HTTP \u9002\u914D\u5668");try{this.setupRoutes(),this.setState("connecting"),this.logger.info("HTTP \u9002\u914D\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("HTTP \u9002\u914D\u5668\u521D\u59CB\u5316\u5931\u8D25",e),this.setState("error"),e}}async start(){if(this.server){this.logger.warn("HTTP \u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C");return}return this.logger.info(`\u542F\u52A8 HTTP \u670D\u52A1\u5668\u5728 ${this.host}:${this.port}`),new Promise((e,t)=>{this.server=this.app.listen(this.port,this.host,()=>{this.setState("connected"),this.logger.info("HTTP \u9002\u914D\u5668\u542F\u52A8\u6210\u529F"),this.logger.info(`- RPC \u7AEF\u70B9: http://${this.host}:${this.port}/rpc`),this.enableSSE&&(this.logger.info(`- SSE \u7AEF\u70B9: http://${this.host}:${this.port}/sse`),this.logger.info(`- \u6D88\u606F\u7AEF\u70B9: http://${this.host}:${this.port}/messages`)),e()}),this.server?.on("error",n=>{this.logger.error("HTTP \u670D\u52A1\u5668\u9519\u8BEF",n),this.setState("error"),t(n)})})}async stop(){if(this.server)return this.logger.info("\u505C\u6B62 HTTP \u670D\u52A1\u5668"),new Promise(e=>{for(let t of this.clients.values())t.response.end();this.clients.clear(),this.server.close(()=>{this.server=null,this.setState("disconnected"),this.logger.info("HTTP \u670D\u52A1\u5668\u5DF2\u505C\u6B62"),e()})})}async sendMessage(e){this.clients.size>0&&this.broadcastToClients(e)}setupMiddleware(){this.app.use(z.json({limit:"10mb"})),this.app.use(z.urlencoded({extended:!0})),this.app.use((e,t,n)=>{t.header("Access-Control-Allow-Origin",this.corsOrigin),t.header("Access-Control-Allow-Methods","GET, POST, OPTIONS"),t.header("Access-Control-Allow-Headers","Content-Type, Accept"),t.header("Cache-Control","no-cache"),n()}),this.app.use((e,t,n)=>{this.logger.debug(`${e.method} ${e.path}`,{query:e.query,headers:e.headers}),n()})}setupRoutes(){this.enableSSE&&(this.app.get("/sse",this.handleSSE.bind(this)),this.app.post("/messages",this.handleMessages.bind(this))),this.enableRPC&&this.app.post("/rpc",this.handleRPC.bind(this)),this.app.get("/status",this.handleStatus.bind(this)),this.app.get("/health",this.handleHealth.bind(this))}handleSSE(e,t){if(this.clients.size>=this.maxClients){t.status(503).json({error:"\u670D\u52A1\u5668\u7E41\u5FD9\uFF0C\u5BA2\u6237\u7AEF\u8FDE\u63A5\u6570\u5DF2\u8FBE\u4E0A\u9650",maxClients:this.maxClients});return}let n=Date.now().toString(),i=de();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 r={id:n,sessionId:i,response:t,connectedAt:new Date};this.clients.set(i,r),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u8FDE\u63A5: ${n} (\u4F1A\u8BDD: ${i})`),t.write(`event: endpoint
2
+ var re=Object.defineProperty;var s=(o,e)=>re(o,"name",{value:e,configurable:!0});import{dirname as Le}from"path";import d from"process";import{fileURLToPath as We}from"url";import*as g from"fs";import*as p from"path";import b from"chalk";import M from"pino";function se(o){let e=o.getFullYear(),t=String(o.getMonth()+1).padStart(2,"0"),n=String(o.getDate()).padStart(2,"0"),i=String(o.getHours()).padStart(2,"0"),r=String(o.getMinutes()).padStart(2,"0"),a=String(o.getSeconds()).padStart(2,"0");return`${e}-${t}-${n} ${i}:${r}:${a}`}s(se,"formatDateTime");var N=class{static{s(this,"Logger")}logFilePath=null;pinoInstance;isDaemonMode;maxLogFileSize=10*1024*1024;maxLogFiles=5;constructor(){this.isDaemonMode=process.env.XIAOZHI_DAEMON==="true",this.pinoInstance=this.createPinoInstance()}createPinoInstance(){let e=[];if(!this.isDaemonMode){let t=this.createOptimizedConsoleStream();e.push({level:"debug",stream:t})}return this.logFilePath&&e.push({level:"debug",stream:M.destination({dest:this.logFilePath,sync:!1,append:!0,mkdir:!0})}),e.length===0&&e.push({level:"debug",stream:M.destination({dest:"/dev/null"})}),M({level:"debug",timestamp:M.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:s((t,n)=>({level:n}),"level")},base:null,serializers:{err:M.stdSerializers?.err||(t=>t)}},M.multistream(e,{dedupe:!0}))}createOptimizedConsoleStream(){let e=new Map([[20,{name:"DEBUG",color:b.gray}],[30,{name:"INFO",color:b.blue}],[40,{name:"WARN",color:b.yellow}],[50,{name:"ERROR",color:b.red}],[60,{name:"FATAL",color:b.red}]]);return{write:s(t=>{try{let n=JSON.parse(t),i=this.formatConsoleMessageOptimized(n,e);this.safeWrite(`${i}
3
+ `)}catch{this.safeWrite(t)}},"write")}}safeWrite(e){try{process.stderr&&typeof process.stderr.write=="function"?process.stderr.write(e):console&&typeof console.error=="function"&&console.error(e.trim())}catch{}}formatConsoleMessageOptimized(e,t){let n=se(new Date),i=t.get(e.level)||{name:"UNKNOWN",color:s(l=>l,"color")},r=i.color(`[${i.name}]`),a=e.msg;if(e.args&&Array.isArray(e.args)){let l=e.args.map(S=>typeof S=="object"?JSON.stringify(S):String(S)).join(" ");a=`${a} ${l}`}return`[${n}] ${r} ${a}`}initLogFile(e){this.logFilePath=p.join(e,"xiaozhi.log"),this.rotateLogFileIfNeeded(),g.existsSync(this.logFilePath)||g.writeFileSync(this.logFilePath,""),this.pinoInstance=this.createPinoInstance()}enableFileLogging(e){e&&this.logFilePath&&(this.pinoInstance=this.createPinoInstance())}info(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}success(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}warn(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.warn(e):this.pinoInstance.warn({args:t},e):this.pinoInstance.warn(e,t[0]||"")}error(e,...t){if(typeof e=="string")if(t.length===0)this.pinoInstance.error(e);else{let n=t.map(i=>i instanceof Error?{message:i.message,stack:i.stack,name:i.name,cause:i.cause}:i);this.pinoInstance.error({args:n},e)}else{let n=this.enhanceErrorObject(e);this.pinoInstance.error(n,t[0]||"")}}debug(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.debug(e):this.pinoInstance.debug({args:t},e):this.pinoInstance.debug(e,t[0]||"")}log(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}enhanceErrorObject(e){let t={...e};for(let[n,i]of Object.entries(t))i instanceof Error&&(t[n]={message:i.message,stack:i.stack,name:i.name,cause:i.cause});return t}rotateLogFileIfNeeded(){if(!(!this.logFilePath||!g.existsSync(this.logFilePath)))try{g.statSync(this.logFilePath).size>this.maxLogFileSize&&this.rotateLogFile()}catch{}}rotateLogFile(){if(this.logFilePath)try{let e=p.dirname(this.logFilePath),t=p.basename(this.logFilePath,".log");for(let i=this.maxLogFiles-1;i>=1;i--){let r=p.join(e,`${t}.${i}.log`),a=p.join(e,`${t}.${i+1}.log`);g.existsSync(r)&&(i===this.maxLogFiles-1?g.unlinkSync(r):g.renameSync(r,a))}let n=p.join(e,`${t}.1.log`);g.renameSync(this.logFilePath,n)}catch{}}cleanupOldLogs(){if(this.logFilePath)try{let e=p.dirname(this.logFilePath),t=p.basename(this.logFilePath,".log");for(let n=this.maxLogFiles+1;n<=this.maxLogFiles+10;n++){let i=p.join(e,`${t}.${n}.log`);g.existsSync(i)&&g.unlinkSync(i)}}catch{}}setLogFileOptions(e,t){this.maxLogFileSize=e,this.maxLogFiles=t}withTag(e){return this}close(){}},c=new N;import{copyFileSync as ce,existsSync as w,readFileSync as le,writeFileSync as ge}from"fs";import{dirname as he,resolve as C}from"path";import{fileURLToPath as pe}from"url";import*as T from"comment-json";import de from"dayjs";import j from"json5";import*as G from"json5-writer";function ae(o){if(!o||typeof o!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u6709\u6548\u7684\u5BF9\u8C61");if("command"in o&&typeof o.command=="string")return"stdio";if("type"in o&&o.type==="sse")return"sse";if("type"in o&&o.type==="streamable-http"||"url"in o&&typeof o.url=="string")return"streamable-http";throw new Error("\u65E0\u6CD5\u8BC6\u522B\u7684 MCP \u670D\u52A1\u914D\u7F6E\u7C7B\u578B\u3002\u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5\uFF08stdio\uFF09\u3001type: 'sse' \u5B57\u6BB5\uFF08sse\uFF09\u6216 url \u5B57\u6BB5\uFF08streamable-http\uFF09")}s(ae,"getMcpServerCommunicationType");function k(o,e){if(!e||typeof e!="object")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61`};try{switch(ae(e)){case"stdio":if(!e.command||typeof e.command!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 command \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(!Array.isArray(e.args))return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4`};if(e.env&&typeof e.env!="object")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61`};break;case"sse":if(e.type!=="sse")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 type \u5B57\u6BB5\u5FC5\u987B\u662F "sse"`};if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};break;case"streamable-http":if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(e.type&&e.type!=="streamable-http")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 type \u5B57\u6BB5\u5982\u679C\u5B58\u5728\uFF0C\u5FC5\u987B\u662F "streamable-http"`};break;default:return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u7C7B\u578B\u65E0\u6CD5\u8BC6\u522B`}}return{valid:!0}}catch(t){return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u65E0\u6548: ${t instanceof Error?t.message:"\u672A\u77E5\u9519\u8BEF"}`}}}s(k,"validateMcpServerConfig");var K=he(pe(import.meta.url)),H={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},F=class o{static{s(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;constructor(){let e=[C(K,"templates","default","xiaozhi.config.json"),C(K,"..","templates","default","xiaozhi.config.json"),C(process.cwd(),"templates","default","xiaozhi.config.json")];this.defaultConfigPath=e.find(t=>w(t))||e[0]}getConfigFilePath(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let n of t){let i=C(e,n);if(w(i))return i}return C(e,"xiaozhi.config.json")}getConfigFileFormat(e){return e.endsWith(".json5")?"json5":e.endsWith(".jsonc")?"jsonc":"json"}static getInstance(){return o.instance||(o.instance=new o),o.instance}configExists(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let n of t){let i=C(e,n);if(w(i))return!0}return!1}initConfig(e="json"){if(!w(this.defaultConfigPath))throw new Error(`\u9ED8\u8BA4\u914D\u7F6E\u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728: ${this.defaultConfigPath}`);if(this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u521D\u59CB\u5316");let t=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),n=`xiaozhi.config.${e}`,i=C(t,n);ce(this.defaultConfigPath,i),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),i=le(e,"utf8").replace(/^\uFEFF/,""),r;switch(t){case"json5":r=j.parse(i),this.json5Writer=G.load(i);break;case"jsonc":r=T.parse(i);break;default:r=JSON.parse(i);break}return this.validateConfig(r),r}catch(e){throw e instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${e.message}`):e}}validateConfig(e){if(!e||typeof e!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let t=e;if(t.mcpEndpoint===void 0||t.mcpEndpoint===null)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(typeof t.mcpEndpoint!="string")if(Array.isArray(t.mcpEndpoint)){if(t.mcpEndpoint.length===0)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let n of t.mcpEndpoint)if(typeof n!="string"||n.trim()==="")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6216\u5B57\u7B26\u4E32\u6570\u7EC4");if(!t.mcpServers||typeof t.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[n,i]of Object.entries(t.mcpServers)){if(!i||typeof i!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${n} \u65E0\u6548`);let r=k(n,i);if(!r.valid)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A${r.error}`)}}getConfig(){return this.config=this.loadConfig(),JSON.parse(JSON.stringify(this.config))}getMutableConfig(){return this.config||(this.config=this.loadConfig()),this.config}getMcpEndpoint(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?e.mcpEndpoint[0]||"":e.mcpEndpoint}getMcpEndpoints(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?[...e.mcpEndpoint]:e.mcpEndpoint?[e.mcpEndpoint]:[]}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(e){return this.getMcpServerConfig()[e]?.tools||{}}isToolEnabled(e,t){return this.getServerToolsConfig(e)[t]?.enable!==!1}updateMcpEndpoint(e){if(Array.isArray(e)){if(e.length===0)throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let n of e)if(!n||typeof n!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig();t.mcpEndpoint=e,this.saveConfig(t)}addMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),n=this.getMcpEndpoints();if(n.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let i=[...n,e];t.mcpEndpoint=i,this.saveConfig(t)}removeMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),n=this.getMcpEndpoints();if(n.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);if(n.length===1)throw new Error("\u4E0D\u80FD\u5220\u9664\u6700\u540E\u4E00\u4E2A MCP \u7AEF\u70B9");let r=n.filter(a=>a!==e);t.mcpEndpoint=r,this.saveConfig(t)}updateMcpServer(e,t){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let n=k(e,t);if(!n.valid)throw new Error(n.error||"\u670D\u52A1\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let i=this.getMutableConfig();i.mcpServers[e]=t,this.saveConfig(i)}removeMcpServer(e){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getConfig();if(!t.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);let n={...t.mcpServers};delete n[e];let i={...t,mcpServers:n};this.saveConfig(i)}updateServerToolsConfig(e,t){let n=this.getMutableConfig();n.mcpServerConfig||(n.mcpServerConfig={}),Object.keys(t).length===0?delete n.mcpServerConfig[e]:n.mcpServerConfig[e]={tools:t},this.saveConfig(n)}removeServerToolsConfig(e){let n={...this.getConfig()};n.mcpServerConfig&&(delete n.mcpServerConfig[e],this.saveConfig(n))}cleanupInvalidServerToolsConfig(){let e=this.getMutableConfig();if(!e.mcpServerConfig)return;let t=Object.keys(e.mcpServers),i=Object.keys(e.mcpServerConfig).filter(r=>!t.includes(r));if(i.length>0){for(let r of i)delete e.mcpServerConfig[r];this.saveConfig(e),c.info(`\u5DF2\u6E05\u7406 ${i.length} \u4E2A\u65E0\u6548\u7684\u670D\u52A1\u5DE5\u5177\u914D\u7F6E: ${i.join(", ")}`)}}setToolEnabled(e,t,n,i){let r=this.getMutableConfig();r.mcpServerConfig||(r.mcpServerConfig={}),r.mcpServerConfig[e]||(r.mcpServerConfig[e]={tools:{}}),r.mcpServerConfig[e].tools[t]={...r.mcpServerConfig[e].tools[t],enable:n,...i&&{description:i}},this.saveConfig(r)}saveConfig(e){try{this.validateConfig(e);let t;this.currentConfigPath?t=this.currentConfigPath:(t=this.getConfigFilePath(),this.currentConfigPath=t);let n=this.getConfigFileFormat(t),i;switch(n){case"json5":try{this.json5Writer?(this.json5Writer.write(e),i=this.json5Writer.toSource()):(console.warn("\u6CA1\u6709 json5Writer \u5B9E\u4F8B\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F"),i=j.stringify(e,null,2))}catch(r){console.warn("\u4F7F\u7528 json5-writer \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F:",r),i=j.stringify(e,null,2)}break;case"jsonc":try{i=T.stringify(e,null,2)}catch(r){console.warn("\u4F7F\u7528 comment-json \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON \u683C\u5F0F:",r),i=JSON.stringify(e,null,2)}break;default:i=JSON.stringify(e,null,2);break}ge(t,i,"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??H.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??H.heartbeatTimeout,reconnectInterval:t.reconnectInterval??H.reconnectInterval}}getHeartbeatInterval(){return this.getConnectionConfig().heartbeatInterval}getHeartbeatTimeout(){return this.getConnectionConfig().heartbeatTimeout}getReconnectInterval(){return this.getConnectionConfig().reconnectInterval}updateConnectionConfig(e){let t=this.getMutableConfig();t.connection||(t.connection={}),Object.assign(t.connection,e),this.saveConfig(t)}async updateToolUsageStats(e,t,n){try{let i=this.getMutableConfig();i.mcpServerConfig||(i.mcpServerConfig={}),i.mcpServerConfig[e]||(i.mcpServerConfig[e]={tools:{}}),i.mcpServerConfig[e].tools[t]||(i.mcpServerConfig[e].tools[t]={enable:!0});let r=i.mcpServerConfig[e].tools[t],a=r.usageCount||0,l=r.lastUsedTime;r.usageCount=a+1,(!l||new Date(n)>new Date(l))&&(r.lastUsedTime=de(n).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(i),c.debug(`\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${e}/${t}, \u4F7F\u7528\u6B21\u6570: ${r.usageCount}`)}catch(i){c.error(`\u66F4\u65B0\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5931\u8D25 (${e}/${t}): ${i instanceof Error?i.message:String(i)}`)}}setHeartbeatInterval(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:e})}setHeartbeatTimeout(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:e})}setReconnectInterval(e){if(e<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:e})}getModelScopeConfig(){return this.getConfig().modelscope||{}}getModelScopeApiKey(){return this.getModelScopeConfig().apiKey||process.env.MODELSCOPE_API_TOKEN}updateModelScopeConfig(e){let t=this.getMutableConfig();t.modelscope||(t.modelscope={}),Object.assign(t.modelscope,e),this.saveConfig(t)}setModelScopeApiKey(e){if(!e||typeof e!="string")throw new Error("API Key \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");this.updateModelScopeConfig({apiKey:e})}getWebUIConfig(){return this.getConfig().webUI||{}}getWebUIPort(){return this.getWebUIConfig().port??9999}notifyConfigUpdate(e){try{let t=global.__webServer;t&&typeof t.broadcastConfigUpdate=="function"&&(t.broadcastConfigUpdate(e),console.log("\u5DF2\u901A\u8FC7 WebSocket \u5E7F\u64AD\u914D\u7F6E\u66F4\u65B0"))}catch(t){console.warn("\u901A\u77E5 Web \u754C\u9762\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",t instanceof Error?t.message:String(t))}}updateWebUIConfig(e){let t=this.getMutableConfig();t.webUI||(t.webUI={}),Object.assign(t.webUI,e),this.saveConfig(t)}setWebUIPort(e){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error("\u7AEF\u53E3\u53F7\u5FC5\u987B\u662F 1-65535 \u4E4B\u95F4\u7684\u6574\u6570");this.updateWebUIConfig({port:e})}},f=F.getInstance();import{randomUUID as fe}from"crypto";import z from"express";var u=class{static{s(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 n=this.createErrorResponse(t,e.id);await this.sendMessage(n)}}createErrorResponse(e,t){let n=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?n=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(n=-32602),{jsonrpc:"2.0",error:{code:n,message:e.message,data:{stack:e.stack}},id:t||null}}generateConnectionId(){let e=Date.now(),t=Math.random().toString(36).substr(2,9);return`${this.config.name}_${e}_${t}`}getConnectionId(){return this.connectionId}getState(){return this.state}setState(e){let t=this.state;this.state=e,t!==e&&(this.logger.info(`\u8FDE\u63A5\u72B6\u6001\u53D8\u66F4: ${t} -> ${e}`),this.onStateChange(t,e))}onStateChange(e,t){}getConfig(){return{...this.config}}getMessageHandler(){return this.messageHandler}parseMessage(e){try{let t=JSON.parse(e.trim());return!t.jsonrpc||t.jsonrpc!=="2.0"?(this.logger.warn("\u6536\u5230\u975E JSON-RPC 2.0 \u683C\u5F0F\u7684\u6D88\u606F",t),null):t.method?t:(this.logger.warn("\u6536\u5230\u6CA1\u6709 method \u5B57\u6BB5\u7684\u6D88\u606F",t),null)}catch(t){return this.logger.error("\u89E3\u6790 JSON \u6D88\u606F\u5931\u8D25",{data:e,error:t}),null}}serializeMessage(e){try{return JSON.stringify(e)}catch(t){this.logger.error("\u5E8F\u5217\u5316\u6D88\u606F\u5931\u8D25",{message:e,error:t});let n=t instanceof Error?t.message:String(t);throw new Error(`\u6D88\u606F\u5E8F\u5217\u5316\u5931\u8D25: ${n}`)}}validateMessage(e){return!(!e||typeof e!="object"||e.jsonrpc!=="2.0"||e.method&&typeof e.method!="string"||!e.method&&!e.result&&!e.error)}createTimeoutPromise(e,t){return Promise.race([e,new Promise((n,i)=>{setTimeout(()=>{i(new Error(`\u64CD\u4F5C\u8D85\u65F6: ${t}ms`))},t)})])}};var E=class extends u{static{s(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=z(),this.setupMiddleware()}async initialize(){this.logger.info("\u521D\u59CB\u5316 HTTP \u9002\u914D\u5668");try{this.setupRoutes(),this.setState("connecting"),this.logger.info("HTTP \u9002\u914D\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("HTTP \u9002\u914D\u5668\u521D\u59CB\u5316\u5931\u8D25",e),this.setState("error"),e}}async start(){if(this.server){this.logger.warn("HTTP \u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C");return}return this.logger.info(`\u542F\u52A8 HTTP \u670D\u52A1\u5668\u5728 ${this.host}:${this.port}`),new Promise((e,t)=>{this.server=this.app.listen(this.port,this.host,()=>{this.setState("connected"),this.logger.info("HTTP \u9002\u914D\u5668\u542F\u52A8\u6210\u529F"),this.logger.info(`- RPC \u7AEF\u70B9: http://${this.host}:${this.port}/rpc`),this.enableSSE&&(this.logger.info(`- SSE \u7AEF\u70B9: http://${this.host}:${this.port}/sse`),this.logger.info(`- \u6D88\u606F\u7AEF\u70B9: http://${this.host}:${this.port}/messages`)),e()}),this.server?.on("error",n=>{this.logger.error("HTTP \u670D\u52A1\u5668\u9519\u8BEF",n),this.setState("error"),t(n)})})}async stop(){if(this.server)return this.logger.info("\u505C\u6B62 HTTP \u670D\u52A1\u5668"),new Promise(e=>{for(let t of this.clients.values())t.response.end();this.clients.clear(),this.server.close(()=>{this.server=null,this.setState("disconnected"),this.logger.info("HTTP \u670D\u52A1\u5668\u5DF2\u505C\u6B62"),e()})})}async sendMessage(e){this.clients.size>0&&this.broadcastToClients(e)}setupMiddleware(){this.app.use(z.json({limit:"10mb"})),this.app.use(z.urlencoded({extended:!0})),this.app.use((e,t,n)=>{t.header("Access-Control-Allow-Origin",this.corsOrigin),t.header("Access-Control-Allow-Methods","GET, POST, OPTIONS"),t.header("Access-Control-Allow-Headers","Content-Type, Accept"),t.header("Cache-Control","no-cache"),n()}),this.app.use((e,t,n)=>{this.logger.debug(`${e.method} ${e.path}`,{query:e.query,headers:e.headers}),n()})}setupRoutes(){this.enableSSE&&(this.app.get("/sse",this.handleSSE.bind(this)),this.app.post("/messages",this.handleMessages.bind(this))),this.enableRPC&&this.app.post("/rpc",this.handleRPC.bind(this)),this.app.get("/status",this.handleStatus.bind(this)),this.app.get("/health",this.handleHealth.bind(this))}handleSSE(e,t){if(this.clients.size>=this.maxClients){t.status(503).json({error:"\u670D\u52A1\u5668\u7E41\u5FD9\uFF0C\u5BA2\u6237\u7AEF\u8FDE\u63A5\u6570\u5DF2\u8FBE\u4E0A\u9650",maxClients:this.maxClients});return}let n=Date.now().toString(),i=fe();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 r={id:n,sessionId:i,response:t,connectedAt:new Date};this.clients.set(i,r),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u8FDE\u63A5: ${n} (\u4F1A\u8BDD: ${i})`),t.write(`event: endpoint
4
4
  data: /messages?sessionId=${i}
5
5
 
6
- `),e.on("close",()=>{this.clients.delete(i),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u65AD\u5F00\u8FDE\u63A5: ${n} (\u4F1A\u8BDD: ${i})`)}),e.on("error",a=>{this.logger.error(`SSE \u5BA2\u6237\u7AEF\u8FDE\u63A5\u9519\u8BEF: ${n}`,a),this.clients.delete(i)})}async handleMessages(e,t){try{let n=e.query.sessionId,i=e.body;if(this.logger.debug(`\u6536\u5230 SSE \u6D88\u606F (\u4F1A\u8BDD: ${n}):`,i),!n||!this.clients.has(n)){t.status(400).json({jsonrpc:"2.0",error:{code:-32600,message:"\u65E0\u6548\u6216\u7F3A\u5C11 sessionId"},id:i.id});return}let r=await this.messageHandler.handleMessage(i);this.logger.debug("SSE \u6D88\u606F\u5904\u7406\u54CD\u5E94:",r);let a=this.clients.get(n);a&&this.sendToClient(a,r),t.status(202).send()}catch(n){this.logger.error("\u5904\u7406 SSE \u6D88\u606F\u65F6\u51FA\u9519",n),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:n.message}})}}async handleRPC(e,t){try{let n=e.body;this.logger.debug("\u6536\u5230 RPC \u6D88\u606F:",n);let i=await this.messageHandler.handleMessage(n);t.json(i)}catch(n){this.logger.error("\u5904\u7406 RPC \u6D88\u606F\u65F6\u51FA\u9519",n),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:n.message},id:e.body?.id||null})}}handleStatus(e,t){t.json({status:"ok",mode:"mcp-server",serviceManager:"running",clients:this.clients.size,tools:0,maxClients:this.maxClients,enableSSE:this.enableSSE,enableRPC:this.enableRPC,uptime:process.uptime()})}handleHealth(e,t){t.json({status:"ok",mode:"mcp-server",timestamp:new Date().toISOString()})}sendToClient(e,t){try{let n=this.serializeMessage(t);e.response.write(`data: ${n}
6
+ `),e.on("close",()=>{this.clients.delete(i),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u65AD\u5F00\u8FDE\u63A5: ${n} (\u4F1A\u8BDD: ${i})`)}),e.on("error",a=>{this.logger.error(`SSE \u5BA2\u6237\u7AEF\u8FDE\u63A5\u9519\u8BEF: ${n}`,a),this.clients.delete(i)})}async handleMessages(e,t){try{let n=e.query.sessionId,i=e.body;if(this.logger.debug(`\u6536\u5230 SSE \u6D88\u606F (\u4F1A\u8BDD: ${n}):`,i),!n||!this.clients.has(n)){t.status(400).json({jsonrpc:"2.0",error:{code:-32600,message:"\u65E0\u6548\u6216\u7F3A\u5C11 sessionId"},id:i.id});return}let r=await this.messageHandler.handleMessage(i);this.logger.debug("SSE \u6D88\u606F\u5904\u7406\u54CD\u5E94:",r);let a=this.clients.get(n);a&&r!==null&&this.sendToClient(a,r),t.status(202).send()}catch(n){this.logger.error("\u5904\u7406 SSE \u6D88\u606F\u65F6\u51FA\u9519",n),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:n.message}})}}async handleRPC(e,t){try{let n=e.body;this.logger.debug("\u6536\u5230 RPC \u6D88\u606F:",n);let i=await this.messageHandler.handleMessage(n);t.json(i)}catch(n){this.logger.error("\u5904\u7406 RPC \u6D88\u606F\u65F6\u51FA\u9519",n),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:n.message},id:e.body?.id||null})}}handleStatus(e,t){t.json({status:"ok",mode:"mcp-server",serviceManager:"running",clients:this.clients.size,tools:0,maxClients:this.maxClients,enableSSE:this.enableSSE,enableRPC:this.enableRPC,uptime:process.uptime()})}handleHealth(e,t){t.json({status:"ok",mode:"mcp-server",timestamp:new Date().toISOString()})}sendToClient(e,t){try{let n=this.serializeMessage(t);e.response.write(`data: ${n}
7
7
 
8
- `),this.logger.debug(`\u6D88\u606F\u5DF2\u53D1\u9001\u5230\u5BA2\u6237\u7AEF ${e.id}`,{sessionId:e.sessionId,messageId:t.id})}catch(n){this.logger.error(`\u5411\u5BA2\u6237\u7AEF ${e.id} \u53D1\u9001\u6D88\u606F\u5931\u8D25`,n),this.clients.delete(e.sessionId)}}broadcastToClients(e){for(let t of this.clients.values())this.sendToClient(t,e)}getStatus(){return{isRunning:this.server!==null,port:this.port,host:this.host,clientCount:this.clients.size,maxClients:this.maxClients,enableSSE:this.enableSSE,enableRPC:this.enableRPC,connectionId:this.connectionId,state:this.state}}getClients(){return Array.from(this.clients.values()).map(e=>({id:e.id,sessionId:e.sessionId,connectedAt:e.connectedAt}))}};var E=class extends u{static{s(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}
8
+ `),this.logger.debug(`\u6D88\u606F\u5DF2\u53D1\u9001\u5230\u5BA2\u6237\u7AEF ${e.id}`,{sessionId:e.sessionId,messageId:t.id})}catch(n){this.logger.error(`\u5411\u5BA2\u6237\u7AEF ${e.id} \u53D1\u9001\u6D88\u606F\u5931\u8D25`,n),this.clients.delete(e.sessionId)}}broadcastToClients(e){for(let t of this.clients.values())this.sendToClient(t,e)}getStatus(){return{isRunning:this.server!==null,port:this.port,host:this.host,clientCount:this.clients.size,maxClients:this.maxClients,enableSSE:this.enableSSE,enableRPC:this.enableRPC,connectionId:this.connectionId,state:this.state}}getClients(){return Array.from(this.clients.values()).map(e=>({id:e.id,sessionId:e.sessionId,connectedAt:e.connectedAt}))}};var I=class extends u{static{s(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}
9
9
  `),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(`
10
- `);this.messageBuffer=t.pop()||"";for(let n of t){let i=n.trim();i&&await this.processMessageLine(i)}}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 n={jsonrpc:"2.0",error:{code:-32700,message:"\u89E3\u6790\u9519\u8BEF",data:{originalLine:e.substring(0,100)}},id:null};await this.sendMessage(n)}}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=s(()=>{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,n)=>{this.logger.error("\u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD",{reason:t,promise:n})})}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 J,{WebSocketServer as ue}from"ws";var I=class extends u{static{s(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 n=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(n),t(n)},this.reconnectOptions.timeout),this.ws=new J(this.endpointUrl),this.compression,this.ws.on("open",()=>{this.handleConnectionSuccess(),e()}),this.ws.on("message",n=>{this.handleIncomingData(n)}),this.ws.on("close",(n,i)=>{this.handleConnectionClose(n,i.toString())}),this.ws.on("error",n=>{this.handleConnectionError(n),t(n)})})}async initializeServer(){return new Promise((e,t)=>{try{let n=new URL(this.endpointUrl),i=Number.parseInt(n.port)||8080;this.wsServer=new ue({port:i,perMessageDeflate:this.compression}),this.wsServer.on("connection",(r,a)=>{this.handleNewConnection(r,a)}),this.wsServer.on("error",r=>{this.logger.error("WebSocket \u670D\u52A1\u5668\u9519\u8BEF",r),t(r)}),this.logger.info(`WebSocket \u670D\u52A1\u5668\u76D1\u542C\u7AEF\u53E3 ${i}`),e()}catch(n){t(n)}})}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 n of this.connections.values())n.readyState===J.OPEN&&n.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,n)=>{this.batchQueue.push({message:e,timestamp:Date.now(),resolve:t,reject:n}),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 n={jsonrpc:"2.0",method:"batch",params:{messages:e.map(i=>i.message)},id:`batch_${Date.now()}`};await this.sendMessageDirect(n);for(let i of e)i.resolve();this.logger.debug(`\u6279\u5904\u7406\u53D1\u9001 ${e.length} \u6761\u6D88\u606F`)}catch(t){for(let n of e)n.reject(t);this.logger.error("\u6279\u5904\u7406\u53D1\u9001\u5931\u8D25",t)}}async handleIncomingData(e){try{let t=e.toString(),n=this.parseMessage(t);if(n)if(n.method==="batch"&&n.params?.messages)for(let i of n.params.messages)await this.handleIncomingMessage(i);else await this.handleIncomingMessage(n)}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 n=`${this.getConnectionId()}_${this.connections.size}`;this.connections.set(n,e),this.logger.info(`\u65B0 WebSocket \u8FDE\u63A5: ${n}`),e.on("message",i=>{this.handleIncomingData(i)}),e.on("close",()=>{this.connections.delete(n),this.logger.info(`WebSocket \u8FDE\u63A5\u5DF2\u65AD\u5F00: ${n}`)}),e.on("error",i=>{this.logger.error(`WebSocket \u8FDE\u63A5\u9519\u8BEF ${n}:`,i),this.connections.delete(n)})}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:n,backoffMultiplier:i}=this.reconnectOptions,r=this.reconnectState.attempts,a;switch(e){case"linear":a=t+r*1e3;break;case"exponential":a=t*i**r;break;default:a=t;break}return Math.min(a,n)}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()}};import{EventEmitter as X}from"events";import{createHash as me}from"crypto";import{existsSync as R,readFileSync as q,renameSync as Ce,writeFileSync as Q}from"fs";import{resolve as Y}from"path";import Se from"dayjs";var $=class{static{s(this,"MCPCacheManager")}cachePath;logger;CACHE_VERSION="1.0.0";CACHE_ENTRY_VERSION="1.0.0";constructor(){this.logger=c,this.cachePath=this.getCacheFilePath()}formatTimestamp(){return Se().format("YYYY-MM-DD HH:mm:ss")}getCacheFilePath(){try{let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return Y(e,"xiaozhi.cache.json")}catch{let t=process.env.XIAOZHI_CONFIG_DIR||"/tmp";return Y(t,"xiaozhi.cache.json")}}async ensureCacheFile(){try{if(!R(this.cachePath)){this.logger.debug("[CacheManager] \u7F13\u5B58\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u521B\u5EFA\u521D\u59CB\u7F13\u5B58\u6587\u4EF6");let e=await this.createInitialCache();await this.saveCache(e),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,n){try{this.logger.debug(`[CacheManager] \u5F00\u59CB\u5199\u5165\u7F13\u5B58: ${e}`),await this.ensureCacheFile();let i=await this.loadExistingCache(),r=this.generateConfigHash(n),a={tools:t.map(l=>({name:l.name,description:l.description||"",inputSchema:l.inputSchema})),lastUpdated:this.formatTimestamp(),serverConfig:{...n},configHash:r,version:this.CACHE_ENTRY_VERSION};i.mcpServers[e]=a,i.metadata.lastGlobalUpdate=this.formatTimestamp(),i.metadata.totalWrites+=1,await this.saveCache(i),this.logger.info(`[CacheManager] \u7F13\u5B58\u5199\u5165\u6210\u529F: ${e}, \u5DE5\u5177\u6570\u91CF: ${t.length}`)}catch(i){this.logger.warn(`[CacheManager] \u7F13\u5B58\u5199\u5165\u5931\u8D25: ${e}, \u9519\u8BEF: ${i instanceof Error?i.message:String(i)}`)}}async loadExistingCache(){try{if(!R(this.cachePath))return await this.createInitialCache();let e=q(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 n=`${e}.tmp`;try{Q(n,t,"utf8"),Ce(n,e)}catch(i){try{R(n)&&Q(n,"","utf8")}catch{}throw i}}generateConfigHash(e){try{return me("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:R(this.cachePath)?q(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}};import{Client as Ne}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as V}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as ve}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as Me}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{EventSource as be}from"eventsource";typeof global<"u"&&!global.EventSource&&(global.EventSource=be);function Pe(){return c}s(Pe,"getLogger");function ye(o){switch(Pe().info(`[TransportFactory] \u521B\u5EFA ${o.type} transport for ${o.name}`),o.type){case"stdio":return we(o);case"sse":return Te(o);case"modelscope-sse":return Ee(o);case"streamable-http":return Ie(o);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${o.type}`)}}s(ye,"createTransport");function we(o){if(!o.command)throw new Error("stdio transport \u9700\u8981 command \u914D\u7F6E");return new ve({command:o.command,args:o.args||[],env:o.env})}s(we,"createStdioTransport");function Te(o){if(!o.url)throw new Error("SSE transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(o.url),t=Re(o);return new V(e,t)}s(Te,"createSSETransport");function Ee(o){if(!o.url)throw new Error("ModelScope SSE transport \u9700\u8981 URL \u914D\u7F6E");if(!o.apiKey)throw new Error("ModelScope SSE transport \u9700\u8981 apiKey \u914D\u7F6E");let e=new URL(o.url),t=$e(o);return new V(e,t)}s(Ee,"createModelScopeSSETransport");function Ie(o){if(!o.url)throw new Error("StreamableHTTP transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(o.url),t=Oe(o);return new Me(e,t)}s(Ie,"createStreamableHTTPTransport");function Re(o){let e={};return o.apiKey?e.headers={Authorization:`Bearer ${o.apiKey}`,...o.headers}:o.headers&&(e.headers=o.headers),e}s(Re,"createSSEOptions");function $e(o){let e=o.apiKey;return o.customSSEOptions?o.customSSEOptions:{eventSourceInit:{fetch:s(async(t,n)=>{let i={...n?.headers,Authorization:`Bearer ${e}`};return fetch(t,{...n,headers:i})},"fetch")},requestInit:{headers:{Authorization:`Bearer ${e}`,...o.headers}}}}s($e,"createModelScopeSSEOptions");function Oe(o){let e={};return o.apiKey?e.headers={Authorization:`Bearer ${o.apiKey}`,...o.headers}:o.headers&&(e.headers=o.headers),e}s(Oe,"createStreamableHTTPOptions");function xe(o){if(!o.name||typeof o.name!="string")throw new Error("\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 name \u5B57\u6BB5");if(!o.type)throw new Error("\u914D\u7F6E\u5FC5\u987B\u5305\u542B type \u5B57\u6BB5");switch(o.type){case"stdio":if(!o.command)throw new Error("stdio \u7C7B\u578B\u9700\u8981 command \u5B57\u6BB5");break;case"sse":case"streamable-http":if(!o.url)throw new Error(`${o.type} \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5`);break;case"modelscope-sse":if(!o.url)throw new Error("modelscope-sse \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5");if(!o.apiKey)throw new Error("modelscope-sse \u7C7B\u578B\u9700\u8981 apiKey \u5B57\u6BB5\u3002\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E modelscope.apiKey \u6216\u786E\u4FDD\u670D\u52A1\u914D\u7F6E\u5305\u542B apiKey");break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${o.type}`)}}s(xe,"validateConfig");function Ae(){return["stdio","sse","modelscope-sse","streamable-http"]}s(Ae,"getSupportedTypes");var L={create:ye,validateConfig:xe,getSupportedTypes:Ae};var O=class{static{s(this,"MCPService")}config;client=null;transport=null;tools=new Map;connectionState="disconnected";reconnectOptions;reconnectState;logger;connectionTimeout=null;initialized=!1;pingOptions;pingTimer=null;pingFailureCount=0;lastPingTime=null;isPinging=!1;constructor(e,t){this.config=e,this.logger=c,this.validateConfig(),this.reconnectOptions={enabled:!0,maxAttempts:10,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0,...t?.reconnect,...e.reconnect},this.pingOptions={enabled:!0,interval:3e4,timeout:5e3,maxFailures:3,startDelay:5e3,...e.ping},this.reconnectState={attempts:0,nextInterval:this.reconnectOptions.initialInterval,timer:null,lastError:null,isManualDisconnect:!1}}logWithTag(e,t,...n){let i=`[MCP-${this.config.name}] ${t}`;this.logger[e](i,...n)}validateConfig(){L.validateConfig(this.config)}async connect(){if(this.connectionState==="connecting")throw new Error("\u8FDE\u63A5\u6B63\u5728\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u8FDE\u63A5\u5B8C\u6210");return this.cleanupConnection(),this.reconnectState.isManualDisconnect=!1,this.attemptConnection()}async attemptConnection(){return this.connectionState="connecting",this.logWithTag("info",`\u6B63\u5728\u8FDE\u63A5 MCP \u670D\u52A1: ${this.config.name} (\u5C1D\u8BD5 ${this.reconnectState.attempts+1}/${this.reconnectOptions.maxAttempts})`),new Promise((e,t)=>{this.connectionTimeout=setTimeout(()=>{let n=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(n),t(n)},this.reconnectOptions.timeout);try{this.client=new Ne({name:`xiaozhi-${this.config.name}-client`,version:"1.0.0"},{capabilities:{tools:{}}}),this.transport=L.create(this.config),this.client.connect(this.transport).then(async()=>{this.handleConnectionSuccess(),await this.refreshTools(),e()}).catch(n=>{this.handleConnectionError(n),t(n)})}catch(n){this.handleConnectionError(n),t(n)}})}handleConnectionSuccess(){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.connectionState="connected",this.initialized=!0,this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.resetPingState(),this.logWithTag("info",`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u5DF2\u5EFA\u7ACB`),this.startPingMonitoring()}handleConnectionError(e){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.reconnectState.lastError=e,this.logger.error(`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u9519\u8BEF:`,e.message),this.cleanupConnection(),this.shouldReconnect()?this.scheduleReconnect():(this.connectionState="failed",this.logger.warn(`${this.config.name} \u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 (${this.reconnectOptions.maxAttempts})\uFF0C\u505C\u6B62\u91CD\u8FDE`))}shouldReconnect(){return this.reconnectOptions.enabled&&this.reconnectState.attempts<this.reconnectOptions.maxAttempts&&!this.reconnectState.isManualDisconnect}scheduleReconnect(){this.connectionState="reconnecting",this.reconnectState.attempts++,this.calculateNextInterval(),this.logger.info(`${this.config.name} \u5C06\u5728 ${this.reconnectState.nextInterval}ms \u540E\u8FDB\u884C\u7B2C ${this.reconnectState.attempts} \u6B21\u91CD\u8FDE`),this.reconnectState.timer&&clearTimeout(this.reconnectState.timer),this.reconnectState.timer=setTimeout(async()=>{try{await this.attemptConnection()}catch{}},this.reconnectState.nextInterval)}calculateNextInterval(){let e;switch(this.reconnectOptions.backoffStrategy){case"fixed":e=this.reconnectOptions.initialInterval;break;case"linear":e=this.reconnectOptions.initialInterval+this.reconnectState.attempts*this.reconnectOptions.backoffMultiplier*1e3;break;case"exponential":e=this.reconnectOptions.initialInterval*this.reconnectOptions.backoffMultiplier**(this.reconnectState.attempts-1);break;default:e=this.reconnectOptions.initialInterval}if(e=Math.min(e,this.reconnectOptions.maxInterval),this.reconnectOptions.jitter){let t=e*.1,n=(Math.random()-.5)*2*t;e+=n}this.reconnectState.nextInterval=Math.max(e,1e3)}cleanupConnection(){if(this.stopPingMonitoring(),this.client){try{this.client.close().catch(()=>{})}catch{}this.client=null}this.transport=null,this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.initialized=!1}stopReconnect(){this.reconnectState.timer&&(clearTimeout(this.reconnectState.timer),this.reconnectState.timer=null)}async refreshTools(){if(!this.client)throw new Error("\u5BA2\u6237\u7AEF\u672A\u521D\u59CB\u5316");try{let t=(await this.client.listTools()).tools||[];this.tools.clear();for(let n of t)this.tools.set(n.name,n);this.logger.info(`${this.config.name} \u670D\u52A1\u52A0\u8F7D\u4E86 ${t.length} \u4E2A\u5DE5\u5177: ${t.map(n=>n.name).join(", ")}`)}catch(e){throw this.logger.error(`${this.config.name} \u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25:`,e instanceof Error?e.message:String(e)),e}}async disconnect(){this.logger.info(`\u4E3B\u52A8\u65AD\u5F00 MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5`),this.reconnectState.isManualDisconnect=!0,this.stopPingMonitoring(),this.stopReconnect(),this.cleanupConnection(),this.connectionState="disconnected"}async reconnect(){this.logger.info(`\u624B\u52A8\u91CD\u8FDE MCP \u670D\u52A1 ${this.config.name}`),this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.isManualDisconnect=!1,this.cleanupConnection(),await this.connect()}getTools(){return Array.from(this.tools.values())}async callTool(e,t){if(!this.client)throw new Error(`\u670D\u52A1 ${this.config.name} \u672A\u8FDE\u63A5`);if(!this.tools.has(e))throw new Error(`\u5DE5\u5177 ${e} \u5728\u670D\u52A1 ${this.config.name} \u4E2D\u4E0D\u5B58\u5728`);this.logger.info(`\u8C03\u7528 ${this.config.name} \u670D\u52A1\u7684\u5DE5\u5177 ${e}\uFF0C\u53C2\u6570:`,JSON.stringify(t));try{let n=await this.client.callTool({name:e,arguments:t||{}});return this.logger.info(`\u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,`${JSON.stringify(n).substring(0,500)}...`),n}catch(n){throw this.logger.error(`\u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,n instanceof Error?n.message:String(n)),n}}getConfig(){return this.config}getStatus(){return{name:this.config.name,connected:this.connectionState==="connected",initialized:this.initialized,transportType:this.config.type,toolCount:this.tools.size,lastError:this.reconnectState.lastError?.message,reconnectAttempts:this.reconnectState.attempts,connectionState:this.connectionState,pingEnabled:this.pingOptions.enabled,lastPingTime:this.lastPingTime||void 0,pingFailureCount:this.pingFailureCount,isPinging:this.isPinging}}isConnected(){return this.connectionState==="connected"&&this.initialized}enableReconnect(){this.reconnectOptions.enabled=!0,this.logger.info(`${this.config.name} \u81EA\u52A8\u91CD\u8FDE\u5DF2\u542F\u7528`)}disableReconnect(){this.reconnectOptions.enabled=!1,this.stopReconnect(),this.logger.info(`${this.config.name} \u81EA\u52A8\u91CD\u8FDE\u5DF2\u7981\u7528`)}updateReconnectOptions(e){this.reconnectOptions={...this.reconnectOptions,...e},this.logger.info(`${this.config.name} \u91CD\u8FDE\u914D\u7F6E\u5DF2\u66F4\u65B0`,e)}getReconnectOptions(){return{...this.reconnectOptions}}resetReconnectState(){this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info(`${this.config.name} \u91CD\u8FDE\u72B6\u6001\u5DF2\u91CD\u7F6E`)}startPingMonitoring(){!this.pingOptions.enabled||this.pingTimer||!this.isConnected()||(this.logger.info(`${this.config.name} \u542F\u52A8ping\u76D1\u63A7\uFF0C\u95F4\u9694: ${this.pingOptions.interval}ms`),setTimeout(()=>{this.isConnected()&&!this.pingTimer&&(this.pingTimer=setInterval(()=>{this.performPing()},this.pingOptions.interval))},this.pingOptions.startDelay))}stopPingMonitoring(){this.pingTimer&&(clearInterval(this.pingTimer),this.pingTimer=null,this.logger.debug(`${this.config.name} \u505C\u6B62ping\u76D1\u63A7`))}async performPing(){if(!this.client||this.isPinging||!this.isConnected())return;this.isPinging=!0;let e=performance.now();try{this.logger.debug(`${this.config.name} \u53D1\u9001ping\u8BF7\u6C42\uFF08\u901A\u8FC7listTools\u68C0\u6D4B\u8FDE\u63A5\uFF09`);let t=this.client.listTools(),n=new Promise((r,a)=>{setTimeout(()=>{a(new Error(`Ping\u8D85\u65F6 (${this.pingOptions.timeout}ms)`))},this.pingOptions.timeout)});await Promise.race([t,n]);let i=performance.now()-e;this.handlePingSuccess(i)}catch(t){let n=performance.now()-e;this.handlePingFailure(t,n)}finally{this.isPinging=!1}}handlePingSuccess(e){this.pingFailureCount=0,this.lastPingTime=new Date,this.logger.debug(`${this.config.name} ping\u6210\u529F\uFF0C\u5EF6\u8FDF: ${e.toFixed(2)}ms`)}handlePingFailure(e,t){if(this.pingFailureCount++,this.logger.warn(`${this.config.name} ping\u5931\u8D25 (${this.pingFailureCount}/${this.pingOptions.maxFailures})\uFF0C\u5EF6\u8FDF: ${t.toFixed(2)}ms\uFF0C\u9519\u8BEF: ${e.message}`),this.pingFailureCount>=this.pingOptions.maxFailures){this.logger.error(`${this.config.name} \u8FDE\u7EEDping\u5931\u8D25\u8FBE\u5230\u9608\u503C\uFF0C\u89E6\u53D1\u91CD\u8FDE\u673A\u5236`),this.stopPingMonitoring();let n=new Error(`Ping\u68C0\u6D4B\u5931\u8D25\uFF0C\u8FDE\u7EED\u5931\u8D25${this.pingFailureCount}\u6B21\uFF0C\u8FDE\u63A5\u53EF\u80FD\u5DF2\u65AD\u5F00`);this.handleConnectionError(n)}}resetPingState(){this.pingFailureCount=0,this.lastPingTime=null,this.isPinging=!1}enablePing(){this.pingOptions.enabled=!0,this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u542F\u7528`),this.isConnected()&&this.startPingMonitoring()}disablePing(){this.pingOptions.enabled=!1,this.stopPingMonitoring(),this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u7981\u7528`)}updatePingOptions(e){let t=this.pingOptions.enabled;this.pingOptions={...this.pingOptions,...e},this.logger.info(`${this.config.name} ping\u914D\u7F6E\u5DF2\u66F4\u65B0`,e),t!==this.pingOptions.enabled&&(this.pingOptions.enabled&&this.isConnected()?this.startPingMonitoring():this.pingOptions.enabled||this.stopPingMonitoring())}getPingOptions(){return{...this.pingOptions}}};var x=class{static{s(this,"MCPServiceManager")}services=new Map;configs={};logger;tools=new Map;cacheManager;constructor(e){this.logger=c,this.configs=e||{},this.cacheManager=new $}async startAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u542F\u52A8\u6240\u6709 MCP \u670D\u52A1...");let e=Object.entries(this.configs);if(e.length===0){this.logger.warn("[MCPManager] \u6CA1\u6709\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1\uFF0C\u8BF7\u4F7F\u7528 addServiceConfig() \u6DFB\u52A0\u670D\u52A1\u914D\u7F6E");return}for(let[t]of e)await this.startService(t);this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u542F\u52A8\u5B8C\u6210")}async startService(e){this.logger.info(`[MCPManager] \u542F\u52A8 MCP \u670D\u52A1: ${e}`);let t=this.configs[e];if(!t)throw new Error(`\u672A\u627E\u5230\u670D\u52A1\u914D\u7F6E: ${e}`);try{this.services.has(e)&&await this.stopService(e);let n=new O(t);await n.connect(),this.services.set(e,n),await this.refreshToolsCache();let i=n.getTools();this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u542F\u52A8\u6210\u529F\uFF0C\u52A0\u8F7D\u4E86 ${i.length} \u4E2A\u5DE5\u5177:`,i.map(r=>r.name).join(", "))}catch(n){throw this.logger.error(`[MCPManager] \u542F\u52A8 ${e} \u670D\u52A1\u5931\u8D25:`,n.message),n}}async stopService(e){this.logger.info(`[MCPManager] \u505C\u6B62 MCP \u670D\u52A1: ${e}`);let t=this.services.get(e);if(!t){this.logger.warn(`[MCPManager] \u670D\u52A1 ${e} \u4E0D\u5B58\u5728\u6216\u672A\u542F\u52A8`);return}try{await t.disconnect(),this.services.delete(e),await this.refreshToolsCache(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(n){throw this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,n.message),n}}async refreshToolsCache(){this.tools.clear();for(let[e,t]of this.services)if(t.isConnected()){let n=t.getTools(),i=this.configs[e];i&&this.cacheManager.writeCacheEntry(e,n,i).then(()=>{this.logger.debug(`[MCPManager] \u5DF2\u5C06 ${e} \u5DE5\u5177\u5217\u8868\u5199\u5165\u7F13\u5B58`)}).catch(r=>{this.logger.warn(`[MCPManager] \u5199\u5165\u7F13\u5B58\u5931\u8D25: ${e}, \u9519\u8BEF: ${r instanceof Error?r.message:String(r)}`)});for(let r of n){let a=`${e}__${r.name}`;this.tools.set(a,{serviceName:e,originalName:r.name,tool:r})}}await this.syncToolsConfigToFile()}getAllTools(){let e=[];for(let[t,n]of this.tools)d.isToolEnabled(n.serviceName,n.originalName)&&e.push({name:t,description:n.tool.description||"",inputSchema:n.tool.inputSchema,serviceName:n.serviceName,originalName:n.originalName});return e}async callTool(e,t){this.logger.info(`[MCPManager] \u8C03\u7528\u5DE5\u5177: ${e}\uFF0C\u53C2\u6570:`,t);let n=this.tools.get(e);if(!n)throw new Error(`\u672A\u627E\u5230\u5DE5\u5177: ${e}`);let i=this.services.get(n.serviceName);if(!i)throw new Error(`\u670D\u52A1 ${n.serviceName} \u4E0D\u53EF\u7528`);if(!i.isConnected())throw new Error(`\u670D\u52A1 ${n.serviceName} \u672A\u8FDE\u63A5`);try{let r=await i.callTool(n.originalName,t||{});return this.logger.info(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,r),r}catch(r){throw this.logger.error(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,r.message),r}}async stopAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u505C\u6B62\u6240\u6709 MCP \u670D\u52A1...");for(let[e,t]of this.services)try{await t.disconnect(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(n){this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,n.message)}this.services.clear(),this.tools.clear(),this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u5DF2\u505C\u6B62")}getStatus(){let e={services:{},totalTools:this.tools.size,availableTools:Array.from(this.tools.keys())};for(let[t,n]of this.services){let i=n.getStatus();e.services[t]={connected:i.connected,clientName:`xiaozhi-${t}-client`}}return e}getService(e){return this.services.get(e)}getAllServices(){return new Map(this.services)}enhanceServiceConfig(e){let t={...e};try{if(e.type==="modelscope-sse"){let n=d.getModelScopeApiKey();if(n)t.apiKey=n,this.logger.info(`[MCPManager] \u4E3A ${e.name} \u670D\u52A1\u6DFB\u52A0 ModelScope API Key`);else throw this.logger.warn(`[MCPManager] ${e.name} \u670D\u52A1\u9700\u8981 ModelScope API Key\uFF0C\u4F46\u672A\u5728\u914D\u7F6E\u4E2D\u627E\u5230`),new Error(`ModelScope SSE \u670D\u52A1 ${e.name} \u9700\u8981 API Key\uFF0C\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E modelscope.apiKey`)}return t}catch(n){throw this.logger.error(`[MCPManager] \u914D\u7F6E\u589E\u5F3A\u5931\u8D25: ${e.name}`,n),n}}addServiceConfig(e,t){let n,i;if(typeof e=="string"&&t)i=e,n=t;else if(typeof e=="object")i=e.name,n=e;else throw new Error("Invalid arguments for addServiceConfig");let r=this.enhanceServiceConfig(n);this.configs[i]=r,this.logger.info(`[MCPManager] \u5DF2\u6DFB\u52A0\u670D\u52A1\u914D\u7F6E: ${i}`)}updateServiceConfig(e,t){let n=this.enhanceServiceConfig(t);this.configs[e]=n,this.logger.info(`[MCPManager] \u5DF2\u66F4\u65B0\u5E76\u589E\u5F3A\u670D\u52A1\u914D\u7F6E: ${e}`)}removeServiceConfig(e){delete this.configs[e],this.logger.info(`[MCPManager] \u5DF2\u79FB\u9664\u670D\u52A1\u914D\u7F6E: ${e}`)}async syncToolsConfigToFile(){try{this.logger.debug("[MCPManager] \u5F00\u59CB\u540C\u6B65\u5DE5\u5177\u914D\u7F6E\u5230\u914D\u7F6E\u6587\u4EF6");let e=d.getMcpServerConfig();for(let[t,n]of this.services){if(!n.isConnected())continue;let i=n.getTools();if(i.length===0)continue;let r=e[t]?.tools||{},a={};for(let h of i){let v=r[h.name];v?a[h.name]={...v,description:h.description||v.description||""}:a[h.name]={description:h.description||"",enable:!0}}let l=i.map(h=>h.name),m=Object.keys(r).filter(h=>!l.includes(h));if(m.length>0&&this.logger.info(`[MCPManager] \u68C0\u6D4B\u5230\u670D\u52A1 ${t} \u79FB\u9664\u4E86 ${m.length} \u4E2A\u5DE5\u5177: ${m.join(", ")}`),this.hasToolsConfigChanged(r,a)){d.updateServerToolsConfig(t,a);let h=Object.keys(a).filter(P=>!r[P]),v=Object.keys(a).filter(P=>{let B=r[P],oe=a[P];return B&&B.description!==oe.description});this.logger.info(`[MCPManager] \u5DF2\u540C\u6B65\u670D\u52A1 ${t} \u7684\u5DE5\u5177\u914D\u7F6E:`),h.length>0&&this.logger.info(` - \u65B0\u589E\u5DE5\u5177: ${h.join(", ")}`),v.length>0&&this.logger.info(` - \u66F4\u65B0\u5DE5\u5177: ${v.join(", ")}`),m.length>0&&this.logger.info(` - \u79FB\u9664\u5DE5\u5177: ${m.join(", ")}`)}}this.logger.debug("[MCPManager] \u5DE5\u5177\u914D\u7F6E\u540C\u6B65\u5B8C\u6210")}catch(e){this.logger.error("[MCPManager] \u540C\u6B65\u5DE5\u5177\u914D\u7F6E\u5230\u914D\u7F6E\u6587\u4EF6\u5931\u8D25:",e)}}hasToolsConfigChanged(e,t){let n=Object.keys(e),i=Object.keys(t);if(n.length!==i.length)return!0;let r=i.filter(l=>!n.includes(l)),a=n.filter(l=>!i.includes(l));if(r.length>0||a.length>0)return!0;for(let l of n){let S=e[l],m=t[l];if(S.description!==m.description)return!0}return!1}};var A=class{static{s(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{switch(e.method){case"initialize":return await this.handleInitialize(e.params,e.id);case"tools/list":return await this.handleToolsList(e.id);case"tools/call":return await this.handleToolCall(e.params,e.id);case"ping":return await this.handlePing(e.id);default:throw new Error(`\u672A\u77E5\u7684\u65B9\u6CD5: ${e.method}`)}}catch(t){return this.logger.error(`\u5904\u7406\u6D88\u606F\u65F6\u51FA\u9519: ${e.method}`,t),this.createErrorResponse(t,e.id)}}async handleInitialize(e,t){return this.logger.info("\u5904\u7406 initialize \u8BF7\u6C42",e),{jsonrpc:"2.0",result:{serverInfo:{name:"xiaozhi-mcp-server",version:"1.0.0"},capabilities:{tools:{},logging:{}},protocolVersion:"2024-11-05"},id:t||null}}async handleToolsList(e){this.logger.info("\u5904\u7406 tools/list \u8BF7\u6C42");try{let n=this.serviceManager.getAllTools().map(i=>({name:i.name,description:i.description,inputSchema:i.inputSchema}));return this.logger.info(`\u8FD4\u56DE ${n.length} \u4E2A\u5DE5\u5177`),{jsonrpc:"2.0",result:{tools:n},id:e||null}}catch(t){throw this.logger.error("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25",t),t}}async handleToolCall(e,t){this.logger.info(`\u5904\u7406 tools/call \u8BF7\u6C42: ${e.name}`,e);try{if(!e.name)throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");let n=await this.serviceManager.callTool(e.name,e.arguments||{});return this.logger.info(`\u5DE5\u5177 ${e.name} \u8C03\u7528\u6210\u529F`),{jsonrpc:"2.0",result:{content:n.content,isError:n.isError||!1},id:t||null}}catch(n){throw this.logger.error(`\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,n),n}}async handlePing(e){return this.logger.debug("\u5904\u7406 ping \u8BF7\u6C42"),{jsonrpc:"2.0",result:{status:"ok",timestamp:new Date().toISOString()},id:e||null}}createErrorResponse(e,t){let n=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?n=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(n=-32602),{jsonrpc:"2.0",error:{code:n,message:e.message,data:{stack:e.stack}},id:t||null}}getServiceManager(){return this.serviceManager}};var U=class{static{s(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(n=>n.name===e)||null}hasTool(e){return this.findTool(e)!==null}},_=class extends X{static{s(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,n){let i={id:e,transportName:t,state:n,connectedAt:new Date,lastActivity:new Date};this.connections.set(e,i),this.emit("connectionRegistered",i),this.logger.debug(`\u8FDE\u63A5\u5DF2\u6CE8\u518C: ${e} (${t})`)}updateConnectionState(e,t){let n=this.connections.get(e);n&&(n.state=t,n.lastActivity=new Date,this.emit("connectionStateChanged",n),this.logger.debug(`\u8FDE\u63A5\u72B6\u6001\u66F4\u65B0: ${e} -> ${t}`))}removeConnection(e){let t=this.connections.get(e);t&&(this.connections.delete(e),this.emit("connectionRemoved",t),this.logger.debug(`\u8FDE\u63A5\u5DF2\u79FB\u9664: ${e}`))}getAllConnections(){return Array.from(this.connections.values())}getActiveConnectionCount(){return Array.from(this.connections.values()).filter(e=>e.state==="connected").length}async closeAllConnections(){this.logger.info("\u5173\u95ED\u6240\u6709\u8FDE\u63A5"),this.connections.clear(),this.emit("allConnectionsClosed")}},D=class extends X{static{s(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 x,this.messageHandler=new A(this.serviceManager),this.toolRegistry=new U(this.serviceManager),this.connectionManager=new _,this.setupEventListeners()}setupEventListeners(){this.connectionManager.on("connectionRegistered",e=>{this.emit("connectionRegistered",e)}),this.connectionManager.on("connectionStateChanged",e=>{this.emit("connectionStateChanged",e)}),this.connectionManager.on("connectionRemoved",e=>{this.emit("connectionRemoved",e)})}async initialize(){this.logger.info("\u521D\u59CB\u5316\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{await this.serviceManager.startAllServices(),await this.toolRegistry.initialize(),await this.connectionManager.initialize(),this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210"),this.emit("initialized")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5931\u8D25",e),e}}async registerTransport(e,t){if(this.transportAdapters.has(e))throw new Error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5DF2\u5B58\u5728`);this.logger.info(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668: ${e}`);try{await t.initialize(),this.transportAdapters.set(e,t),this.connectionManager.registerConnection(t.getConnectionId(),e,t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u6CE8\u518C\u6210\u529F`),this.emit("transportRegistered",{name:e,adapter:t})}catch(n){throw this.logger.error(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5931\u8D25`,n),n}}async start(){if(this.isRunning)throw new Error("\u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C");this.logger.info("\u542F\u52A8\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{for(let[e,t]of this.transportAdapters)try{await t.start(),this.connectionManager.updateConnectionState(t.getConnectionId(),t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u542F\u52A8\u6210\u529F`)}catch(n){throw this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u542F\u52A8\u5931\u8D25`,n),n}this.isRunning=!0,this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u542F\u52A8\u6210\u529F"),this.emit("started")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25",e),e}}async stop(){if(this.isRunning){this.logger.info("\u505C\u6B62\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{for(let[e,t]of this.transportAdapters)try{await t.stop(),this.connectionManager.updateConnectionState(t.getConnectionId(),t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u6210\u529F`)}catch(n){this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u5931\u8D25`,n)}await this.connectionManager.closeAllConnections(),await this.serviceManager.stopAllServices(),this.isRunning=!1,this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u505C\u6B62\u6210\u529F"),this.emit("stopped")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u505C\u6B62\u5931\u8D25",e),e}}}getServiceManager(){return this.serviceManager}getToolRegistry(){return this.toolRegistry}getConnectionManager(){return this.connectionManager}getMessageHandler(){return this.messageHandler}getStatus(){return{isRunning:this.isRunning,transportCount:this.transportAdapters.size,activeConnections:this.connectionManager.getActiveConnectionCount(),toolCount:this.toolRegistry.getAllTools().length,config:this.config}}getTransportAdapters(){return new Map(this.transportAdapters)}isServerRunning(){return this.isRunning}};async function ne(o={}){c.info("[ServerFactory] \u5F00\u59CB\u521B\u5EFA MCP \u670D\u52A1\u5668",o);try{let e=await ke(o);c.info(`[ServerFactory] \u786E\u5B9A\u670D\u52A1\u5668\u6A21\u5F0F: ${e}`);let t=new D(o.serverConfig);return await t.initialize(),await He(t,e,o),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}}s(ne,"createServer");async function ke(o){if(o.mode&&o.mode!=="auto")return o.mode;let e=await je(o.autoDetect);return c.info("\u73AF\u5883\u68C0\u6D4B\u7ED3\u679C",e),e.suggestedMode}s(ke,"determineServerMode");async function je(o={}){let{checkStdin:e=!0,checkEnvironment:t=!0,defaultMode:n="http"}=o,i={hasStdin:!1,isInteractive:!1,hasPort:!1,suggestedMode:n,reasons:[]};e&&(i.hasStdin=!process.stdin.isTTY,i.isInteractive=process.stdin.isTTY||!1,i.hasStdin&&i.reasons.push("\u68C0\u6D4B\u5230\u6807\u51C6\u8F93\u5165\u6D41"),i.isInteractive&&i.reasons.push("\u68C0\u6D4B\u5230\u4EA4\u4E92\u5F0F\u7EC8\u7AEF"));let r=!1;if(t){let a=process.env.MCP_SERVER_MODE,l=process.env.PORT||process.env.MCP_PORT;a==="stdio"?(i.suggestedMode="stdio",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=stdio"),r=!0):a==="http"?(i.suggestedMode="http",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=http"),r=!0):a==="websocket"?(i.suggestedMode="websocket",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=websocket"),r=!0):a==="hybrid"&&(i.suggestedMode="hybrid",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=hybrid"),r=!0),l&&(i.hasPort=!0,i.reasons.push(`\u68C0\u6D4B\u5230\u7AEF\u53E3\u914D\u7F6E: ${l}`))}return!r&&i.suggestedMode===n&&(i.hasStdin&&!i.isInteractive?(i.suggestedMode="stdio",i.reasons.push("\u63A8\u65AD\uFF1A\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883\uFF0C\u9002\u5408 Stdio \u6A21\u5F0F")):(i.isInteractive||i.hasPort)&&(i.suggestedMode="http",i.reasons.push("\u63A8\u65AD\uFF1A\u4EA4\u4E92\u5F0F\u73AF\u5883\u6216\u6709\u7AEF\u53E3\u914D\u7F6E\uFF0C\u9002\u5408 HTTP \u6A21\u5F0F"))),i}s(je,"detectEnvironment");async function He(o,e,t){let n=o.getMessageHandler();switch(e){case"stdio":await Z(o,n,t.stdioConfig);break;case"http":await ee(o,n,t.httpConfig);break;case"websocket":await te(o,n,t.websocketConfig);break;case"hybrid":await Z(o,n,t.stdioConfig),await ee(o,n,t.httpConfig),t.websocketConfig&&await te(o,n,t.websocketConfig);break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u670D\u52A1\u5668\u6A21\u5F0F: ${e}`)}}s(He,"registerTransportsForMode");async function Z(o,e,t={name:"stdio"}){let n=new E(e,t);await o.registerTransport("stdio",n),c.info("Stdio \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F")}s(Z,"registerStdioTransport");async function ee(o,e,t={name:"http"}){let n={port:3e3,host:"0.0.0.0",...t};process.env.PORT?n.port=Number.parseInt(process.env.PORT,10):process.env.MCP_PORT&&(n.port=Number.parseInt(process.env.MCP_PORT,10));let i=new T(e,n);await o.registerTransport("http",i),c.info(`HTTP \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F (\u7AEF\u53E3: ${n.port})`)}s(ee,"registerHTTPTransport");async function te(o,e,t={name:"websocket",endpointUrl:"ws://localhost:8080"}){let n={mode:"client",compression:!0,batchSize:10,batchTimeout:100,maxConnections:100,...t};process.env.WEBSOCKET_URL?n.endpointUrl=process.env.WEBSOCKET_URL:process.env.MCP_WEBSOCKET_URL&&(n.endpointUrl=process.env.MCP_WEBSOCKET_URL);let i=new I(e,n);await o.registerTransport("websocket",i),c.info(`WebSocket \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F (\u7AEF\u70B9: ${n.endpointUrl})`)}s(te,"registerWebSocketTransport");var Cn=Fe(ze(import.meta.url)),ie=f.env.XIAOZHI_CONFIG_DIR||f.cwd();c.initLogFile(ie);c.enableFileLogging(!0);c.info(`\u65E5\u5FD7\u6587\u4EF6\u5DF2\u521D\u59CB\u5316: ${ie}/xiaozhi.log`);async function We(){try{c.info("\u542F\u52A8 MCP \u670D\u52A1\u5668\u4EE3\u7406"),await Le();let o=await ne({mode:"stdio",stdioConfig:{name:"mcp-proxy",encoding:"utf8"}});await o.start(),c.info("MCP \u670D\u52A1\u5668\u4EE3\u7406\u542F\u52A8\u6210\u529F"),f.on("SIGINT",async()=>{c.info("\u6536\u5230 SIGINT \u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668"),await o.stop(),f.exit(0)}),f.on("SIGTERM",async()=>{c.info("\u6536\u5230 SIGTERM \u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668"),await o.stop(),f.exit(0)})}catch(o){c.error("\u542F\u52A8 MCP \u670D\u52A1\u5668\u4EE3\u7406\u5931\u8D25:",o),f.exit(1)}}s(We,"main");async function Le(){try{if(c.info("\u52A0\u8F7D MCP \u670D\u52A1\u5668\u914D\u7F6E"),!d.configExists()){c.warn("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u5C06\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E");return}let o=d.getConfig();c.info(`\u5DF2\u52A0\u8F7D\u914D\u7F6E\uFF0C\u5305\u542B ${Object.keys(o.mcpServers||{}).length} \u4E2A MCP \u670D\u52A1\u5668`)}catch(o){throw c.error("\u52A0\u8F7D\u914D\u7F6E\u5931\u8D25:",o),o}}s(Le,"loadConfiguration");import.meta.url===`file://${f.argv[1]}`&&We().catch(o=>{c.error("MCP \u670D\u52A1\u5668\u4EE3\u7406\u542F\u52A8\u5931\u8D25:",o),f.exit(1)});export{We as main};
10
+ `);this.messageBuffer=t.pop()||"";for(let n of t){let i=n.trim();i&&await this.processMessageLine(i)}}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 n={jsonrpc:"2.0",error:{code:-32700,message:"\u89E3\u6790\u9519\u8BEF",data:{originalLine:e.substring(0,100)}},id:null};await this.sendMessage(n)}}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=s(()=>{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,n)=>{this.logger.error("\u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD",{reason:t,promise:n})})}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 J,{WebSocketServer as ue}from"ws";var R=class extends u{static{s(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 n=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(n),t(n)},this.reconnectOptions.timeout),this.ws=new J(this.endpointUrl),this.compression,this.ws.on("open",()=>{this.handleConnectionSuccess(),e()}),this.ws.on("message",n=>{this.handleIncomingData(n)}),this.ws.on("close",(n,i)=>{this.handleConnectionClose(n,i.toString())}),this.ws.on("error",n=>{this.handleConnectionError(n),t(n)})})}async initializeServer(){return new Promise((e,t)=>{try{let n=new URL(this.endpointUrl),i=Number.parseInt(n.port)||8080;this.wsServer=new ue({port:i,perMessageDeflate:this.compression}),this.wsServer.on("connection",(r,a)=>{this.handleNewConnection(r,a)}),this.wsServer.on("error",r=>{this.logger.error("WebSocket \u670D\u52A1\u5668\u9519\u8BEF",r),t(r)}),this.logger.info(`WebSocket \u670D\u52A1\u5668\u76D1\u542C\u7AEF\u53E3 ${i}`),e()}catch(n){t(n)}})}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 n of this.connections.values())n.readyState===J.OPEN&&n.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,n)=>{this.batchQueue.push({message:e,timestamp:Date.now(),resolve:t,reject:n}),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 n={jsonrpc:"2.0",method:"batch",params:{messages:e.map(i=>i.message)},id:`batch_${Date.now()}`};await this.sendMessageDirect(n);for(let i of e)i.resolve();this.logger.debug(`\u6279\u5904\u7406\u53D1\u9001 ${e.length} \u6761\u6D88\u606F`)}catch(t){for(let n of e)n.reject(t);this.logger.error("\u6279\u5904\u7406\u53D1\u9001\u5931\u8D25",t)}}async handleIncomingData(e){try{let t=e.toString(),n=this.parseMessage(t);if(n)if(n.method==="batch"&&n.params?.messages)for(let i of n.params.messages)await this.handleIncomingMessage(i);else await this.handleIncomingMessage(n)}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 n=`${this.getConnectionId()}_${this.connections.size}`;this.connections.set(n,e),this.logger.info(`\u65B0 WebSocket \u8FDE\u63A5: ${n}`),e.on("message",i=>{this.handleIncomingData(i)}),e.on("close",()=>{this.connections.delete(n),this.logger.info(`WebSocket \u8FDE\u63A5\u5DF2\u65AD\u5F00: ${n}`)}),e.on("error",i=>{this.logger.error(`WebSocket \u8FDE\u63A5\u9519\u8BEF ${n}:`,i),this.connections.delete(n)})}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:n,backoffMultiplier:i}=this.reconnectOptions,r=this.reconnectState.attempts,a;switch(e){case"linear":a=t+r*1e3;break;case"exponential":a=t*i**r;break;default:a=t;break}return Math.min(a,n)}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()}};import{EventEmitter as X}from"events";import{createHash as me}from"crypto";import{existsSync as P,mkdirSync as Ce,readFileSync as q,renameSync as Se,writeFileSync as V}from"fs";import{dirname as ve,resolve as Q}from"path";import Me from"dayjs";var $=class{static{s(this,"MCPCacheManager")}cachePath;logger;CACHE_VERSION="1.0.0";CACHE_ENTRY_VERSION="1.0.0";constructor(e){this.logger=c,this.cachePath=e||this.getCacheFilePath()}formatTimestamp(){return Me().format("YYYY-MM-DD HH:mm:ss")}getCacheFilePath(){try{let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return Q(e,"xiaozhi.cache.json")}catch{let t=process.env.XIAOZHI_CONFIG_DIR||"/tmp";return Q(t,"xiaozhi.cache.json")}}async ensureCacheFile(){try{if(!P(this.cachePath)){let e=ve(this.cachePath);P(e)||(Ce(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,n){try{this.logger.debug(`[CacheManager] \u5F00\u59CB\u5199\u5165\u7F13\u5B58: ${e}`),await this.ensureCacheFile();let i=await this.loadExistingCache(),r=this.generateConfigHash(n),a={tools:t.map(l=>({name:l.name,description:l.description||"",inputSchema:l.inputSchema})),lastUpdated:this.formatTimestamp(),serverConfig:{...n},configHash:r,version:this.CACHE_ENTRY_VERSION};i.mcpServers[e]=a,i.metadata.lastGlobalUpdate=this.formatTimestamp(),i.metadata.totalWrites+=1,await this.saveCache(i),this.logger.info(`[CacheManager] \u7F13\u5B58\u5199\u5165\u6210\u529F: ${e}, \u5DE5\u5177\u6570\u91CF: ${t.length}`)}catch(i){this.logger.warn(`[CacheManager] \u7F13\u5B58\u5199\u5165\u5931\u8D25: ${e}, \u9519\u8BEF: ${i instanceof Error?i.message:String(i)}`)}}async loadExistingCache(){try{if(!P(this.cachePath))return await this.createInitialCache();let e=q(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 n=`${e}.tmp`;try{V(n,t,"utf8"),Se(n,e)}catch(i){try{P(n)&&V(n,"","utf8")}catch{}throw i}}generateConfigHash(e){try{return me("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:P(this.cachePath)?q(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}};import{Client as je}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as Y}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as be}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as Pe}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{EventSource as ye}from"eventsource";typeof global<"u"&&!global.EventSource&&(global.EventSource=ye);function we(){return c}s(we,"getLogger");function Te(o){switch(we().info(`[TransportFactory] \u521B\u5EFA ${o.type} transport for ${o.name}`),o.type){case"stdio":return Ee(o);case"sse":return Ie(o);case"modelscope-sse":return Re(o);case"streamable-http":return $e(o);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${o.type}`)}}s(Te,"createTransport");function Ee(o){if(!o.command)throw new Error("stdio transport \u9700\u8981 command \u914D\u7F6E");return new be({command:o.command,args:o.args||[],env:o.env})}s(Ee,"createStdioTransport");function Ie(o){if(!o.url)throw new Error("SSE transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(o.url),t=Oe(o);return new Y(e,t)}s(Ie,"createSSETransport");function Re(o){if(!o.url)throw new Error("ModelScope SSE transport \u9700\u8981 URL \u914D\u7F6E");if(!o.apiKey)throw new Error("ModelScope SSE transport \u9700\u8981 apiKey \u914D\u7F6E");let e=new URL(o.url),t=xe(o);return new Y(e,t)}s(Re,"createModelScopeSSETransport");function $e(o){if(!o.url)throw new Error("StreamableHTTP transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(o.url),t=Ae(o);return new Pe(e,t)}s($e,"createStreamableHTTPTransport");function Oe(o){let e={};return o.apiKey?e.headers={Authorization:`Bearer ${o.apiKey}`,...o.headers}:o.headers&&(e.headers=o.headers),e}s(Oe,"createSSEOptions");function xe(o){let e=o.apiKey;return o.customSSEOptions?o.customSSEOptions:{eventSourceInit:{fetch:s(async(t,n)=>{let i={...n?.headers,Authorization:`Bearer ${e}`};return fetch(t,{...n,headers:i})},"fetch")},requestInit:{headers:{Authorization:`Bearer ${e}`,...o.headers}}}}s(xe,"createModelScopeSSEOptions");function Ae(o){let e={};return o.apiKey?e.headers={Authorization:`Bearer ${o.apiKey}`,...o.headers}:o.headers&&(e.headers=o.headers),e}s(Ae,"createStreamableHTTPOptions");function De(o){if(!o.name||typeof o.name!="string")throw new Error("\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 name \u5B57\u6BB5");if(!o.type)throw new Error("\u914D\u7F6E\u5FC5\u987B\u5305\u542B type \u5B57\u6BB5");switch(o.type){case"stdio":if(!o.command)throw new Error("stdio \u7C7B\u578B\u9700\u8981 command \u5B57\u6BB5");break;case"sse":case"streamable-http":if(!o.url)throw new Error(`${o.type} \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5`);break;case"modelscope-sse":if(!o.url)throw new Error("modelscope-sse \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5");if(!o.apiKey)throw new Error("modelscope-sse \u7C7B\u578B\u9700\u8981 apiKey \u5B57\u6BB5\u3002\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E modelscope.apiKey \u6216\u786E\u4FDD\u670D\u52A1\u914D\u7F6E\u5305\u542B apiKey");break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${o.type}`)}}s(De,"validateConfig");function Ne(){return["stdio","sse","modelscope-sse","streamable-http"]}s(Ne,"getSupportedTypes");var W={create:Te,validateConfig:De,getSupportedTypes:Ne};var O=class{static{s(this,"MCPService")}config;client=null;transport=null;tools=new Map;connectionState="disconnected";reconnectOptions;reconnectState;logger;connectionTimeout=null;initialized=!1;pingOptions;pingTimer=null;pingFailureCount=0;lastPingTime=null;isPinging=!1;constructor(e,t){this.config=e,this.logger=c,this.validateConfig(),this.reconnectOptions={enabled:!0,maxAttempts:10,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0,...t?.reconnect,...e.reconnect},this.pingOptions={enabled:!0,interval:3e4,timeout:5e3,maxFailures:3,startDelay:5e3,...e.ping},this.reconnectState={attempts:0,nextInterval:this.reconnectOptions.initialInterval,timer:null,lastError:null,isManualDisconnect:!1}}logWithTag(e,t,...n){let i=`[MCP-${this.config.name}] ${t}`;this.logger[e](i,...n)}validateConfig(){W.validateConfig(this.config)}async connect(){if(this.connectionState==="connecting")throw new Error("\u8FDE\u63A5\u6B63\u5728\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u8FDE\u63A5\u5B8C\u6210");return this.cleanupConnection(),this.reconnectState.isManualDisconnect=!1,this.attemptConnection()}async attemptConnection(){return this.connectionState="connecting",this.logWithTag("info",`\u6B63\u5728\u8FDE\u63A5 MCP \u670D\u52A1: ${this.config.name} (\u5C1D\u8BD5 ${this.reconnectState.attempts+1}/${this.reconnectOptions.maxAttempts})`),new Promise((e,t)=>{this.connectionTimeout=setTimeout(()=>{let n=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(n),t(n)},this.reconnectOptions.timeout);try{this.client=new je({name:`xiaozhi-${this.config.name}-client`,version:"1.0.0"},{capabilities:{tools:{}}}),this.transport=W.create(this.config),this.client.connect(this.transport).then(async()=>{this.handleConnectionSuccess(),await this.refreshTools(),e()}).catch(n=>{this.handleConnectionError(n),t(n)})}catch(n){this.handleConnectionError(n),t(n)}})}handleConnectionSuccess(){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.connectionState="connected",this.initialized=!0,this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.resetPingState(),this.logWithTag("info",`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u5DF2\u5EFA\u7ACB`),this.startPingMonitoring()}handleConnectionError(e){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.reconnectState.lastError=e,this.logger.error(`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u9519\u8BEF:`,e.message),this.cleanupConnection(),this.shouldReconnect()?this.scheduleReconnect():(this.connectionState="failed",this.logger.warn(`${this.config.name} \u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 (${this.reconnectOptions.maxAttempts})\uFF0C\u505C\u6B62\u91CD\u8FDE`))}shouldReconnect(){return this.reconnectOptions.enabled&&this.reconnectState.attempts<this.reconnectOptions.maxAttempts&&!this.reconnectState.isManualDisconnect}scheduleReconnect(){this.connectionState="reconnecting",this.reconnectState.attempts++,this.calculateNextInterval(),this.logger.info(`${this.config.name} \u5C06\u5728 ${this.reconnectState.nextInterval}ms \u540E\u8FDB\u884C\u7B2C ${this.reconnectState.attempts} \u6B21\u91CD\u8FDE`),this.reconnectState.timer&&clearTimeout(this.reconnectState.timer),this.reconnectState.timer=setTimeout(async()=>{try{await this.attemptConnection()}catch{}},this.reconnectState.nextInterval)}calculateNextInterval(){let e;switch(this.reconnectOptions.backoffStrategy){case"fixed":e=this.reconnectOptions.initialInterval;break;case"linear":e=this.reconnectOptions.initialInterval+this.reconnectState.attempts*this.reconnectOptions.backoffMultiplier*1e3;break;case"exponential":e=this.reconnectOptions.initialInterval*this.reconnectOptions.backoffMultiplier**(this.reconnectState.attempts-1);break;default:e=this.reconnectOptions.initialInterval}if(e=Math.min(e,this.reconnectOptions.maxInterval),this.reconnectOptions.jitter){let t=e*.1,n=(Math.random()-.5)*2*t;e+=n}this.reconnectState.nextInterval=Math.max(e,1e3)}cleanupConnection(){if(this.stopPingMonitoring(),this.client){try{this.client.close().catch(()=>{})}catch{}this.client=null}this.transport=null,this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.initialized=!1}stopReconnect(){this.reconnectState.timer&&(clearTimeout(this.reconnectState.timer),this.reconnectState.timer=null)}async refreshTools(){if(!this.client)throw new Error("\u5BA2\u6237\u7AEF\u672A\u521D\u59CB\u5316");try{let t=(await this.client.listTools()).tools||[];this.tools.clear();for(let n of t)this.tools.set(n.name,n);this.logger.info(`${this.config.name} \u670D\u52A1\u52A0\u8F7D\u4E86 ${t.length} \u4E2A\u5DE5\u5177: ${t.map(n=>n.name).join(", ")}`)}catch(e){throw this.logger.error(`${this.config.name} \u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25:`,e instanceof Error?e.message:String(e)),e}}async disconnect(){this.logger.info(`\u4E3B\u52A8\u65AD\u5F00 MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5`),this.reconnectState.isManualDisconnect=!0,this.stopPingMonitoring(),this.stopReconnect(),this.cleanupConnection(),this.connectionState="disconnected"}async reconnect(){this.logger.info(`\u624B\u52A8\u91CD\u8FDE MCP \u670D\u52A1 ${this.config.name}`),this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.isManualDisconnect=!1,this.cleanupConnection(),await this.connect()}getTools(){return Array.from(this.tools.values())}async callTool(e,t){if(!this.client)throw new Error(`\u670D\u52A1 ${this.config.name} \u672A\u8FDE\u63A5`);if(!this.tools.has(e))throw new Error(`\u5DE5\u5177 ${e} \u5728\u670D\u52A1 ${this.config.name} \u4E2D\u4E0D\u5B58\u5728`);this.logger.info(`\u8C03\u7528 ${this.config.name} \u670D\u52A1\u7684\u5DE5\u5177 ${e}\uFF0C\u53C2\u6570:`,JSON.stringify(t));try{let n=await this.client.callTool({name:e,arguments:t||{}});return this.logger.info(`\u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,`${JSON.stringify(n).substring(0,500)}...`),n}catch(n){throw this.logger.error(`\u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,n instanceof Error?n.message:String(n)),n}}getConfig(){return this.config}getStatus(){return{name:this.config.name,connected:this.connectionState==="connected",initialized:this.initialized,transportType:this.config.type,toolCount:this.tools.size,lastError:this.reconnectState.lastError?.message,reconnectAttempts:this.reconnectState.attempts,connectionState:this.connectionState,pingEnabled:this.pingOptions.enabled,lastPingTime:this.lastPingTime||void 0,pingFailureCount:this.pingFailureCount,isPinging:this.isPinging}}isConnected(){return this.connectionState==="connected"&&this.initialized}enableReconnect(){this.reconnectOptions.enabled=!0,this.logger.info(`${this.config.name} \u81EA\u52A8\u91CD\u8FDE\u5DF2\u542F\u7528`)}disableReconnect(){this.reconnectOptions.enabled=!1,this.stopReconnect(),this.logger.info(`${this.config.name} \u81EA\u52A8\u91CD\u8FDE\u5DF2\u7981\u7528`)}updateReconnectOptions(e){this.reconnectOptions={...this.reconnectOptions,...e},this.logger.info(`${this.config.name} \u91CD\u8FDE\u914D\u7F6E\u5DF2\u66F4\u65B0`,e)}getReconnectOptions(){return{...this.reconnectOptions}}resetReconnectState(){this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info(`${this.config.name} \u91CD\u8FDE\u72B6\u6001\u5DF2\u91CD\u7F6E`)}startPingMonitoring(){!this.pingOptions.enabled||this.pingTimer||!this.isConnected()||(this.logger.info(`${this.config.name} \u542F\u52A8ping\u76D1\u63A7\uFF0C\u95F4\u9694: ${this.pingOptions.interval}ms`),setTimeout(()=>{this.isConnected()&&!this.pingTimer&&(this.pingTimer=setInterval(()=>{this.performPing()},this.pingOptions.interval))},this.pingOptions.startDelay))}stopPingMonitoring(){this.pingTimer&&(clearInterval(this.pingTimer),this.pingTimer=null,this.logger.debug(`${this.config.name} \u505C\u6B62ping\u76D1\u63A7`))}async performPing(){if(!this.client||this.isPinging||!this.isConnected())return;this.isPinging=!0;let e=performance.now();try{this.logger.debug(`${this.config.name} \u53D1\u9001ping\u8BF7\u6C42\uFF08\u901A\u8FC7listTools\u68C0\u6D4B\u8FDE\u63A5\uFF09`);let t=this.client.listTools(),n=new Promise((r,a)=>{setTimeout(()=>{a(new Error(`Ping\u8D85\u65F6 (${this.pingOptions.timeout}ms)`))},this.pingOptions.timeout)});await Promise.race([t,n]);let i=performance.now()-e;this.handlePingSuccess(i)}catch(t){let n=performance.now()-e;this.handlePingFailure(t,n)}finally{this.isPinging=!1}}handlePingSuccess(e){this.pingFailureCount=0,this.lastPingTime=new Date,this.logger.debug(`${this.config.name} ping\u6210\u529F\uFF0C\u5EF6\u8FDF: ${e.toFixed(2)}ms`)}handlePingFailure(e,t){if(this.pingFailureCount++,this.logger.warn(`${this.config.name} ping\u5931\u8D25 (${this.pingFailureCount}/${this.pingOptions.maxFailures})\uFF0C\u5EF6\u8FDF: ${t.toFixed(2)}ms\uFF0C\u9519\u8BEF: ${e.message}`),this.pingFailureCount>=this.pingOptions.maxFailures){this.logger.error(`${this.config.name} \u8FDE\u7EEDping\u5931\u8D25\u8FBE\u5230\u9608\u503C\uFF0C\u89E6\u53D1\u91CD\u8FDE\u673A\u5236`),this.stopPingMonitoring();let n=new Error(`Ping\u68C0\u6D4B\u5931\u8D25\uFF0C\u8FDE\u7EED\u5931\u8D25${this.pingFailureCount}\u6B21\uFF0C\u8FDE\u63A5\u53EF\u80FD\u5DF2\u65AD\u5F00`);this.handleConnectionError(n)}}resetPingState(){this.pingFailureCount=0,this.lastPingTime=null,this.isPinging=!1}enablePing(){this.pingOptions.enabled=!0,this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u542F\u7528`),this.isConnected()&&this.startPingMonitoring()}disablePing(){this.pingOptions.enabled=!1,this.stopPingMonitoring(),this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u7981\u7528`)}updatePingOptions(e){let t=this.pingOptions.enabled;this.pingOptions={...this.pingOptions,...e},this.logger.info(`${this.config.name} ping\u914D\u7F6E\u5DF2\u66F4\u65B0`,e),t!==this.pingOptions.enabled&&(this.pingOptions.enabled&&this.isConnected()?this.startPingMonitoring():this.pingOptions.enabled||this.stopPingMonitoring())}getPingOptions(){return{...this.pingOptions}}};var x=class{static{s(this,"MCPServiceManager")}services=new Map;configs={};logger;tools=new Map;cacheManager;constructor(e){this.logger=c,this.configs=e||{};let n=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)}async startAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u542F\u52A8\u6240\u6709 MCP \u670D\u52A1...");let e=Object.entries(this.configs);if(e.length===0){this.logger.warn("[MCPManager] \u6CA1\u6709\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1\uFF0C\u8BF7\u4F7F\u7528 addServiceConfig() \u6DFB\u52A0\u670D\u52A1\u914D\u7F6E");return}for(let[t]of e)await this.startService(t);this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u542F\u52A8\u5B8C\u6210")}async startService(e){this.logger.info(`[MCPManager] \u542F\u52A8 MCP \u670D\u52A1: ${e}`);let t=this.configs[e];if(!t)throw new Error(`\u672A\u627E\u5230\u670D\u52A1\u914D\u7F6E: ${e}`);try{this.services.has(e)&&await this.stopService(e);let n=new O(t);await n.connect(),this.services.set(e,n),await this.refreshToolsCache();let i=n.getTools();this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u542F\u52A8\u6210\u529F\uFF0C\u52A0\u8F7D\u4E86 ${i.length} \u4E2A\u5DE5\u5177:`,i.map(r=>r.name).join(", "))}catch(n){throw this.logger.error(`[MCPManager] \u542F\u52A8 ${e} \u670D\u52A1\u5931\u8D25:`,n.message),n}}async stopService(e){this.logger.info(`[MCPManager] \u505C\u6B62 MCP \u670D\u52A1: ${e}`);let t=this.services.get(e);if(!t){this.logger.warn(`[MCPManager] \u670D\u52A1 ${e} \u4E0D\u5B58\u5728\u6216\u672A\u542F\u52A8`);return}try{await t.disconnect(),this.services.delete(e),await this.refreshToolsCache(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(n){throw this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,n.message),n}}async refreshToolsCache(){this.tools.clear();for(let[e,t]of this.services)if(t.isConnected()){let n=t.getTools(),i=this.configs[e];i&&this.cacheManager.writeCacheEntry(e,n,i).then(()=>{this.logger.debug(`[MCPManager] \u5DF2\u5C06 ${e} \u5DE5\u5177\u5217\u8868\u5199\u5165\u7F13\u5B58`)}).catch(r=>{this.logger.warn(`[MCPManager] \u5199\u5165\u7F13\u5B58\u5931\u8D25: ${e}, \u9519\u8BEF: ${r instanceof Error?r.message:String(r)}`)});for(let r of n){let a=`${e}__${r.name}`;this.tools.set(a,{serviceName:e,originalName:r.name,tool:r})}}await this.syncToolsConfigToFile()}getAllTools(){let e=[];for(let[t,n]of this.tools)f.isToolEnabled(n.serviceName,n.originalName)&&e.push({name:t,description:n.tool.description||"",inputSchema:n.tool.inputSchema,serviceName:n.serviceName,originalName:n.originalName});return e}async callTool(e,t){this.logger.info(`[MCPManager] \u8C03\u7528\u5DE5\u5177: ${e}\uFF0C\u53C2\u6570:`,t);let n=this.tools.get(e);if(!n)throw new Error(`\u672A\u627E\u5230\u5DE5\u5177: ${e}`);let i=this.services.get(n.serviceName);if(!i)throw new Error(`\u670D\u52A1 ${n.serviceName} \u4E0D\u53EF\u7528`);if(!i.isConnected())throw new Error(`\u670D\u52A1 ${n.serviceName} \u672A\u8FDE\u63A5`);try{let r=await i.callTool(n.originalName,t||{});return this.logger.info(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,r),r}catch(r){throw this.logger.error(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,r.message),r}}async stopAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u505C\u6B62\u6240\u6709 MCP \u670D\u52A1...");for(let[e,t]of this.services)try{await t.disconnect(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(n){this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,n.message)}this.services.clear(),this.tools.clear(),this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u5DF2\u505C\u6B62")}getStatus(){let e={services:{},totalTools:this.tools.size,availableTools:Array.from(this.tools.keys())};for(let[t,n]of this.services){let i=n.getStatus();e.services[t]={connected:i.connected,clientName:`xiaozhi-${t}-client`}}return e}getService(e){return this.services.get(e)}getAllServices(){return new Map(this.services)}enhanceServiceConfig(e){let t={...e};try{if(e.type==="modelscope-sse"){let n=f.getModelScopeApiKey();if(n)t.apiKey=n,this.logger.info(`[MCPManager] \u4E3A ${e.name} \u670D\u52A1\u6DFB\u52A0 ModelScope API Key`);else throw this.logger.warn(`[MCPManager] ${e.name} \u670D\u52A1\u9700\u8981 ModelScope API Key\uFF0C\u4F46\u672A\u5728\u914D\u7F6E\u4E2D\u627E\u5230`),new Error(`ModelScope SSE \u670D\u52A1 ${e.name} \u9700\u8981 API Key\uFF0C\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E modelscope.apiKey`)}return t}catch(n){throw this.logger.error(`[MCPManager] \u914D\u7F6E\u589E\u5F3A\u5931\u8D25: ${e.name}`,n),n}}addServiceConfig(e,t){let n,i;if(typeof e=="string"&&t)i=e,n=t;else if(typeof e=="object")i=e.name,n=e;else throw new Error("Invalid arguments for addServiceConfig");let r=this.enhanceServiceConfig(n);this.configs[i]=r,this.logger.info(`[MCPManager] \u5DF2\u6DFB\u52A0\u670D\u52A1\u914D\u7F6E: ${i}`)}updateServiceConfig(e,t){let n=this.enhanceServiceConfig(t);this.configs[e]=n,this.logger.info(`[MCPManager] \u5DF2\u66F4\u65B0\u5E76\u589E\u5F3A\u670D\u52A1\u914D\u7F6E: ${e}`)}removeServiceConfig(e){delete this.configs[e],this.logger.info(`[MCPManager] \u5DF2\u79FB\u9664\u670D\u52A1\u914D\u7F6E: ${e}`)}async syncToolsConfigToFile(){try{this.logger.debug("[MCPManager] \u5F00\u59CB\u540C\u6B65\u5DE5\u5177\u914D\u7F6E\u5230\u914D\u7F6E\u6587\u4EF6");let e=f.getMcpServerConfig();for(let[t,n]of this.services){if(!n.isConnected())continue;let i=n.getTools();if(i.length===0)continue;let r=e[t]?.tools||{},a={};for(let h of i){let v=r[h.name];v?a[h.name]={...v,description:h.description||v.description||""}:a[h.name]={description:h.description||"",enable:!0}}let l=i.map(h=>h.name),m=Object.keys(r).filter(h=>!l.includes(h));if(m.length>0&&this.logger.info(`[MCPManager] \u68C0\u6D4B\u5230\u670D\u52A1 ${t} \u79FB\u9664\u4E86 ${m.length} \u4E2A\u5DE5\u5177: ${m.join(", ")}`),this.hasToolsConfigChanged(r,a)){f.updateServerToolsConfig(t,a);let h=Object.keys(a).filter(y=>!r[y]),v=Object.keys(a).filter(y=>{let B=r[y],oe=a[y];return B&&B.description!==oe.description});this.logger.info(`[MCPManager] \u5DF2\u540C\u6B65\u670D\u52A1 ${t} \u7684\u5DE5\u5177\u914D\u7F6E:`),h.length>0&&this.logger.info(` - \u65B0\u589E\u5DE5\u5177: ${h.join(", ")}`),v.length>0&&this.logger.info(` - \u66F4\u65B0\u5DE5\u5177: ${v.join(", ")}`),m.length>0&&this.logger.info(` - \u79FB\u9664\u5DE5\u5177: ${m.join(", ")}`)}}this.logger.debug("[MCPManager] \u5DE5\u5177\u914D\u7F6E\u540C\u6B65\u5B8C\u6210")}catch(e){this.logger.error("[MCPManager] \u540C\u6B65\u5DE5\u5177\u914D\u7F6E\u5230\u914D\u7F6E\u6587\u4EF6\u5931\u8D25:",e)}}hasToolsConfigChanged(e,t){let n=Object.keys(e),i=Object.keys(t);if(n.length!==i.length)return!0;let r=i.filter(l=>!n.includes(l)),a=n.filter(l=>!i.includes(l));if(r.length>0||a.length>0)return!0;for(let l of n){let S=e[l],m=t[l];if(S.description!==m.description)return!0}return!1}};var A=class{static{s(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.info("\u5904\u7406 initialize \u8BF7\u6C42",e);let n=["2024-11-05","2025-06-18"],i=e.protocolVersion,r=n.includes(i)?i:"2024-11-05";return this.logger.info(`\u534F\u8BAE\u7248\u672C\u534F\u5546: \u5BA2\u6237\u7AEF=${i}, \u670D\u52A1\u5668\u54CD\u5E94=${r}`),{jsonrpc:"2.0",result:{serverInfo:{name:"xiaozhi-mcp-server",version:"1.0.0"},capabilities:{tools:{},logging:{}},protocolVersion:r},id:t!==void 0?t:1}}async handleInitializedNotification(e){return this.logger.info("\u6536\u5230 initialized \u901A\u77E5\uFF0C\u5BA2\u6237\u7AEF\u521D\u59CB\u5316\u5B8C\u6210",e),null}async handleToolsList(e){this.logger.info("\u5904\u7406 tools/list \u8BF7\u6C42");try{let n=this.serviceManager.getAllTools().map(i=>({name:i.name,description:i.description,inputSchema:i.inputSchema}));return this.logger.info(`\u8FD4\u56DE ${n.length} \u4E2A\u5DE5\u5177`),{jsonrpc:"2.0",result:{tools:n},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){this.logger.info(`\u5904\u7406 tools/call \u8BF7\u6C42: ${e.name}`,e);try{if(!e.name)throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");let n=await this.serviceManager.callTool(e.name,e.arguments||{});return this.logger.info(`\u5DE5\u5177 ${e.name} \u8C03\u7528\u6210\u529F`),{jsonrpc:"2.0",result:{content:n.content,isError:n.isError||!1},id:t!==void 0?t:1}}catch(n){throw this.logger.error(`\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,n),n}}async handlePing(e){return this.logger.debug("\u5904\u7406 ping \u8BF7\u6C42"),{jsonrpc:"2.0",result:{status:"ok",timestamp:new Date().toISOString()},id:e!==void 0?e:1}}async handleResourcesList(e){this.logger.info("\u5904\u7406 resources/list \u8BF7\u6C42");let t=[];return this.logger.info(`\u8FD4\u56DE ${t.length} \u4E2A\u8D44\u6E90`),{jsonrpc:"2.0",result:{resources:t},id:e!==void 0?e:1}}async handlePromptsList(e){this.logger.info("\u5904\u7406 prompts/list \u8BF7\u6C42");let t=[];return this.logger.info(`\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 n=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?n=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(n=-32602),{jsonrpc:"2.0",error:{code:n,message:e.message,data:{stack:e.stack}},id:t!==void 0?t:1}}getServiceManager(){return this.serviceManager}};var U=class{static{s(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(n=>n.name===e)||null}hasTool(e){return this.findTool(e)!==null}},_=class extends X{static{s(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,n){let i={id:e,transportName:t,state:n,connectedAt:new Date,lastActivity:new Date};this.connections.set(e,i),this.emit("connectionRegistered",i),this.logger.debug(`\u8FDE\u63A5\u5DF2\u6CE8\u518C: ${e} (${t})`)}updateConnectionState(e,t){let n=this.connections.get(e);n&&(n.state=t,n.lastActivity=new Date,this.emit("connectionStateChanged",n),this.logger.debug(`\u8FDE\u63A5\u72B6\u6001\u66F4\u65B0: ${e} -> ${t}`))}removeConnection(e){let t=this.connections.get(e);t&&(this.connections.delete(e),this.emit("connectionRemoved",t),this.logger.debug(`\u8FDE\u63A5\u5DF2\u79FB\u9664: ${e}`))}getAllConnections(){return Array.from(this.connections.values())}getActiveConnectionCount(){return Array.from(this.connections.values()).filter(e=>e.state==="connected").length}async closeAllConnections(){this.logger.info("\u5173\u95ED\u6240\u6709\u8FDE\u63A5"),this.connections.clear(),this.emit("allConnectionsClosed")}},D=class extends X{static{s(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 x,this.messageHandler=new A(this.serviceManager),this.toolRegistry=new U(this.serviceManager),this.connectionManager=new _,this.setupEventListeners()}setupEventListeners(){this.connectionManager.on("connectionRegistered",e=>{this.emit("connectionRegistered",e)}),this.connectionManager.on("connectionStateChanged",e=>{this.emit("connectionStateChanged",e)}),this.connectionManager.on("connectionRemoved",e=>{this.emit("connectionRemoved",e)})}async initialize(){this.logger.info("\u521D\u59CB\u5316\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{await this.serviceManager.startAllServices(),await this.toolRegistry.initialize(),await this.connectionManager.initialize(),this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210"),this.emit("initialized")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5931\u8D25",e),e}}async registerTransport(e,t){if(this.transportAdapters.has(e))throw new Error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5DF2\u5B58\u5728`);this.logger.info(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668: ${e}`);try{await t.initialize(),this.transportAdapters.set(e,t),this.connectionManager.registerConnection(t.getConnectionId(),e,t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u6CE8\u518C\u6210\u529F`),this.emit("transportRegistered",{name:e,adapter:t})}catch(n){throw this.logger.error(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5931\u8D25`,n),n}}async start(){if(this.isRunning)throw new Error("\u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C");this.logger.info("\u542F\u52A8\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{for(let[e,t]of this.transportAdapters)try{await t.start(),this.connectionManager.updateConnectionState(t.getConnectionId(),t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u542F\u52A8\u6210\u529F`)}catch(n){throw this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u542F\u52A8\u5931\u8D25`,n),n}this.isRunning=!0,this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u542F\u52A8\u6210\u529F"),this.emit("started")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25",e),e}}async stop(){if(this.isRunning){this.logger.info("\u505C\u6B62\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{for(let[e,t]of this.transportAdapters)try{await t.stop(),this.connectionManager.updateConnectionState(t.getConnectionId(),t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u6210\u529F`)}catch(n){this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u5931\u8D25`,n)}await this.connectionManager.closeAllConnections(),await this.serviceManager.stopAllServices(),this.isRunning=!1,this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u505C\u6B62\u6210\u529F"),this.emit("stopped")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u505C\u6B62\u5931\u8D25",e),e}}}getServiceManager(){return this.serviceManager}getToolRegistry(){return this.toolRegistry}getConnectionManager(){return this.connectionManager}getMessageHandler(){return this.messageHandler}getStatus(){return{isRunning:this.isRunning,transportCount:this.transportAdapters.size,activeConnections:this.connectionManager.getActiveConnectionCount(),toolCount:this.toolRegistry.getAllTools().length,config:this.config}}getTransportAdapters(){return new Map(this.transportAdapters)}isServerRunning(){return this.isRunning}};async function ne(o={}){c.info("[ServerFactory] \u5F00\u59CB\u521B\u5EFA MCP \u670D\u52A1\u5668",o);try{let e=await He(o);c.info(`[ServerFactory] \u786E\u5B9A\u670D\u52A1\u5668\u6A21\u5F0F: ${e}`);let t=new D(o.serverConfig);return await t.initialize(),await ze(t,e,o),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}}s(ne,"createServer");async function He(o){if(o.mode&&o.mode!=="auto")return o.mode;let e=await Fe(o.autoDetect);return c.info("\u73AF\u5883\u68C0\u6D4B\u7ED3\u679C",e),e.suggestedMode}s(He,"determineServerMode");async function Fe(o={}){let{checkStdin:e=!0,checkEnvironment:t=!0,defaultMode:n="http"}=o,i={hasStdin:!1,isInteractive:!1,hasPort:!1,suggestedMode:n,reasons:[]};e&&(i.hasStdin=!process.stdin.isTTY,i.isInteractive=process.stdin.isTTY||!1,i.hasStdin&&i.reasons.push("\u68C0\u6D4B\u5230\u6807\u51C6\u8F93\u5165\u6D41"),i.isInteractive&&i.reasons.push("\u68C0\u6D4B\u5230\u4EA4\u4E92\u5F0F\u7EC8\u7AEF"));let r=!1;if(t){let a=process.env.MCP_SERVER_MODE,l=process.env.PORT||process.env.MCP_PORT;a==="stdio"?(i.suggestedMode="stdio",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=stdio"),r=!0):a==="http"?(i.suggestedMode="http",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=http"),r=!0):a==="websocket"?(i.suggestedMode="websocket",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=websocket"),r=!0):a==="hybrid"&&(i.suggestedMode="hybrid",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=hybrid"),r=!0),l&&(i.hasPort=!0,i.reasons.push(`\u68C0\u6D4B\u5230\u7AEF\u53E3\u914D\u7F6E: ${l}`))}return!r&&i.suggestedMode===n&&(i.hasStdin&&!i.isInteractive?(i.suggestedMode="stdio",i.reasons.push("\u63A8\u65AD\uFF1A\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883\uFF0C\u9002\u5408 Stdio \u6A21\u5F0F")):(i.isInteractive||i.hasPort)&&(i.suggestedMode="http",i.reasons.push("\u63A8\u65AD\uFF1A\u4EA4\u4E92\u5F0F\u73AF\u5883\u6216\u6709\u7AEF\u53E3\u914D\u7F6E\uFF0C\u9002\u5408 HTTP \u6A21\u5F0F"))),i}s(Fe,"detectEnvironment");async function ze(o,e,t){let n=o.getMessageHandler();switch(e){case"stdio":await Z(o,n,t.stdioConfig);break;case"http":await ee(o,n,t.httpConfig);break;case"websocket":await te(o,n,t.websocketConfig);break;case"hybrid":await Z(o,n,t.stdioConfig),await ee(o,n,t.httpConfig),t.websocketConfig&&await te(o,n,t.websocketConfig);break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u670D\u52A1\u5668\u6A21\u5F0F: ${e}`)}}s(ze,"registerTransportsForMode");async function Z(o,e,t={name:"stdio"}){let n=new I(e,t);await o.registerTransport("stdio",n),c.info("Stdio \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F")}s(Z,"registerStdioTransport");async function ee(o,e,t={name:"http"}){let n={port:3e3,host:"0.0.0.0",...t};process.env.PORT?n.port=Number.parseInt(process.env.PORT,10):process.env.MCP_PORT&&(n.port=Number.parseInt(process.env.MCP_PORT,10));let i=new E(e,n);await o.registerTransport("http",i),c.info(`HTTP \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F (\u7AEF\u53E3: ${n.port})`)}s(ee,"registerHTTPTransport");async function te(o,e,t={name:"websocket",endpointUrl:"ws://localhost:8080"}){let n={mode:"client",compression:!0,batchSize:10,batchTimeout:100,maxConnections:100,...t};process.env.WEBSOCKET_URL?n.endpointUrl=process.env.WEBSOCKET_URL:process.env.MCP_WEBSOCKET_URL&&(n.endpointUrl=process.env.MCP_WEBSOCKET_URL);let i=new R(e,n);await o.registerTransport("websocket",i),c.info(`WebSocket \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F (\u7AEF\u70B9: ${n.endpointUrl})`)}s(te,"registerWebSocketTransport");var vn=Le(We(import.meta.url)),ie=d.env.XIAOZHI_CONFIG_DIR||d.cwd();c.initLogFile(ie);c.enableFileLogging(!0);c.info(`\u65E5\u5FD7\u6587\u4EF6\u5DF2\u521D\u59CB\u5316: ${ie}/xiaozhi.log`);async function Ue(){try{c.info("\u542F\u52A8 MCP \u670D\u52A1\u5668\u4EE3\u7406"),await _e();let o=await ne({mode:"stdio",stdioConfig:{name:"mcp-proxy",encoding:"utf8"}});await o.start(),c.info("MCP \u670D\u52A1\u5668\u4EE3\u7406\u542F\u52A8\u6210\u529F"),d.on("SIGINT",async()=>{c.info("\u6536\u5230 SIGINT \u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668"),await o.stop(),d.exit(0)}),d.on("SIGTERM",async()=>{c.info("\u6536\u5230 SIGTERM \u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668"),await o.stop(),d.exit(0)})}catch(o){c.error("\u542F\u52A8 MCP \u670D\u52A1\u5668\u4EE3\u7406\u5931\u8D25:",o),d.exit(1)}}s(Ue,"main");async function _e(){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 o=f.getConfig();c.info(`\u5DF2\u52A0\u8F7D\u914D\u7F6E\uFF0C\u5305\u542B ${Object.keys(o.mcpServers||{}).length} \u4E2A MCP \u670D\u52A1\u5668`)}catch(o){throw c.error("\u52A0\u8F7D\u914D\u7F6E\u5931\u8D25:",o),o}}s(_e,"loadConfiguration");import.meta.url===`file://${d.argv[1]}`&&Ue().catch(o=>{c.error("MCP \u670D\u52A1\u5668\u4EE3\u7406\u542F\u52A8\u5931\u8D25:",o),d.exit(1)});export{Ue as main};
11
11
  //# sourceMappingURL=mcpServerProxy.js.map