@xiaozhi-client/config 1.9.7-beta.2 → 1.9.7-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +12 -14
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/adapter.test.ts +30 -44
- package/src/adapter.ts +104 -126
- package/src/manager.ts +8 -4
package/dist/index.d.ts
CHANGED
|
@@ -8,12 +8,14 @@ interface SSEMCPServerConfig {
|
|
|
8
8
|
url: string;
|
|
9
9
|
headers?: Record<string, string>;
|
|
10
10
|
}
|
|
11
|
-
interface
|
|
12
|
-
type?: "streamable-http";
|
|
11
|
+
interface HTTPMCPServerConfig {
|
|
12
|
+
type?: "http" | "streamable-http";
|
|
13
13
|
url: string;
|
|
14
14
|
headers?: Record<string, string>;
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
/** @deprecated 使用 HTTPMCPServerConfig 代替 */
|
|
17
|
+
type StreamableHTTPMCPServerConfig = HTTPMCPServerConfig;
|
|
18
|
+
type MCPServerConfig = LocalMCPServerConfig | SSEMCPServerConfig | HTTPMCPServerConfig;
|
|
17
19
|
interface MCPToolConfig {
|
|
18
20
|
description?: string;
|
|
19
21
|
enable: boolean;
|
|
@@ -550,33 +552,29 @@ declare const configManager: ConfigManager;
|
|
|
550
552
|
* 配置验证错误类
|
|
551
553
|
*/
|
|
552
554
|
declare class ConfigValidationError extends Error {
|
|
553
|
-
|
|
554
|
-
constructor(message: string, configName?: string | undefined);
|
|
555
|
+
constructor(message: string);
|
|
555
556
|
}
|
|
556
557
|
declare enum MCPTransportType {
|
|
557
558
|
STDIO = "stdio",
|
|
558
559
|
SSE = "sse",
|
|
559
|
-
|
|
560
|
+
HTTP = "http"
|
|
560
561
|
}
|
|
561
562
|
interface MCPServiceConfig {
|
|
562
|
-
name: string;
|
|
563
563
|
type: MCPTransportType;
|
|
564
564
|
command?: string;
|
|
565
565
|
args?: string[];
|
|
566
566
|
env?: Record<string, string>;
|
|
567
567
|
url?: string;
|
|
568
|
-
timeout?: number;
|
|
569
568
|
headers?: Record<string, string>;
|
|
570
|
-
modelScopeAuth?: boolean;
|
|
571
569
|
}
|
|
572
570
|
/**
|
|
573
|
-
*
|
|
571
|
+
* 将各种配置格式标准化为统一的服务配置格式
|
|
574
572
|
*/
|
|
575
|
-
declare function
|
|
573
|
+
declare function normalizeServiceConfig(config: MCPServerConfig): MCPServiceConfig;
|
|
576
574
|
/**
|
|
577
|
-
*
|
|
575
|
+
* 批量标准化配置
|
|
578
576
|
*/
|
|
579
|
-
declare function
|
|
577
|
+
declare function normalizeServiceConfigBatch(legacyConfigs: Record<string, MCPServerConfig>): Record<string, MCPServiceConfig>;
|
|
580
578
|
/**
|
|
581
579
|
* 检查是否为 ModelScope URL
|
|
582
580
|
* 使用 URL hostname 检查而非简单的字符串包含检查,防止安全绕过
|
|
@@ -661,4 +659,4 @@ declare class ConfigInitializer {
|
|
|
661
659
|
private static getDefaultTemplateDir;
|
|
662
660
|
}
|
|
663
661
|
|
|
664
|
-
export { type AppConfig, type ChainHandlerConfig, ConfigInitializer, ConfigManager, ConfigResolver, ConfigValidationError, type ConnectionConfig, type CozePlatformConfig, type CustomMCPConfig, type CustomMCPTool, type FunctionHandlerConfig, type HandlerConfig, type HttpHandlerConfig, type LocalMCPServerConfig, type MCPHandlerConfig, type MCPServerConfig, type MCPServerToolsConfig, type MCPServiceConfig, type MCPToolConfig, MCPTransportType, type ModelScopeConfig, type PlatformConfig, type PlatformsConfig, type ProxyHandlerConfig, type SSEMCPServerConfig, type ScriptHandlerConfig, type StreamableHTTPMCPServerConfig, type ToolCallLogConfig, type WebServerInstance, type WebUIConfig, configManager,
|
|
662
|
+
export { type AppConfig, type ChainHandlerConfig, ConfigInitializer, ConfigManager, ConfigResolver, ConfigValidationError, type ConnectionConfig, type CozePlatformConfig, type CustomMCPConfig, type CustomMCPTool, type FunctionHandlerConfig, type HTTPMCPServerConfig, type HandlerConfig, type HttpHandlerConfig, type LocalMCPServerConfig, type MCPHandlerConfig, type MCPServerConfig, type MCPServerToolsConfig, type MCPServiceConfig, type MCPToolConfig, MCPTransportType, type ModelScopeConfig, type PlatformConfig, type PlatformsConfig, type ProxyHandlerConfig, type SSEMCPServerConfig, type ScriptHandlerConfig, type StreamableHTTPMCPServerConfig, type ToolCallLogConfig, type WebServerInstance, type WebUIConfig, configManager, getConfigTypeDescription, isModelScopeURL, normalizeServiceConfig, normalizeServiceConfigBatch };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var z=Object.defineProperty;var a=(r,e)=>z(r,"name",{value:e,configurable:!0});import{copyFileSync as $,existsSync as U,readFileSync as J,writeFileSync as B}from"fs";import{dirname as G,resolve as u}from"path";import{fileURLToPath as Y}from"url";import*as m from"comment-json";import j from"dayjs";import*as C from"comment-json";function x(r){let e=C.parse(r);return{write(t){e&&typeof e=="object"&&t&&Object.assign(e,t)},toSource(){return C.stringify(e,null,2)}}}a(x,"createJson5Writer");function k(r){return C.parse(r)}a(k,"parseJson5");import P from"path";import{existsSync as W}from"fs";var f=class{static{a(this,"ConfigResolver")}static resolveConfigPath(){if(process.env.XIAOZHI_CONFIG_DIR){let o=this.findConfigInDir(process.env.XIAOZHI_CONFIG_DIR);if(o)return o}let e=this.findConfigInDir(process.cwd());if(e)return e;let t=process.env.HOME||process.env.USERPROFILE;if(t){let o=P.join(t,".xiaozhi-client"),n=this.findConfigInDir(o);if(n)return n}return null}static findConfigInDir(e){let t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let o of t){let n=P.join(e,o);if(W(n))return n}return null}static getDefaultConfigDir(){let e=process.env.HOME||process.env.USERPROFILE;return e?P.join(e,".xiaozhi-client"):null}};var H=G(Y(import.meta.url)),b={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},S=class r{static{a(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;statsUpdateLocks=new Map;statsUpdateLockTimeouts=new Map;STATS_UPDATE_TIMEOUT=5e3;eventCallbacks=new Map;constructor(){let e=[u(H,"templates","default","xiaozhi.config.json"),u(H,"..","templates","default","xiaozhi.config.json"),u(process.cwd(),"templates","default","xiaozhi.config.json")];this.defaultConfigPath=e.find(t=>U(t))||e[0]}on(e,t){this.eventCallbacks.has(e)||this.eventCallbacks.set(e,[]),this.eventCallbacks.get(e)?.push(t)}emitEvent(e,t){let o=this.eventCallbacks.get(e);if(o)for(let n of o)try{n(t)}catch{}}getConfigFilePath(){let e=f.resolveConfigPath();if(e)return e;let t=f.getDefaultConfigDir();if(t)return u(t,"xiaozhi.config.json");let o=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return u(o,"xiaozhi.config.json")}getConfigFileFormat(e){return e.endsWith(".json5")?"json5":e.endsWith(".jsonc")?"jsonc":"json"}static getInstance(){return r.instance||(r.instance=new r),r.instance}configExists(){return f.resolveConfigPath()!==null}initConfig(e="json"){if(!U(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(),o=`xiaozhi.config.${e}`,n=u(t,o);$(this.defaultConfigPath,n),this.config=null,this.json5Writer=null}loadConfig(){if(!this.configExists()){let e=new Error("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C xiaozhi init \u521D\u59CB\u5316\u914D\u7F6E");throw this.emitEvent("config:error",{error:e,operation:"loadConfig"}),e}try{let e=this.getConfigFilePath();this.currentConfigPath=e;let t=this.getConfigFileFormat(e),n=J(e,"utf8").replace(/^\uFEFF/,""),i;switch(t){case"json5":i=k(n),this.json5Writer=x(n);break;case"jsonc":i=m.parse(n);break;default:i=JSON.parse(n);break}return this.validateConfig(i),i}catch(e){throw this.emitEvent("config:error",{error:e instanceof Error?e:new Error(String(e)),operation:"loadConfig"}),e instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${e.message}`):e}}validateConfig(e){if(!e||typeof e!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let t=e;if(t.mcpEndpoint===void 0||t.mcpEndpoint===null)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(typeof t.mcpEndpoint!="string")if(Array.isArray(t.mcpEndpoint)){for(let o of t.mcpEndpoint)if(typeof o!="string"||o.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[o,n]of Object.entries(t.mcpServers))if(!n||typeof n!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${o} \u65E0\u6548`)}getConfig(){return this.config=this.loadConfig(),JSON.parse(JSON.stringify(this.config))}getMutableConfig(){return this.config||(this.config=this.loadConfig()),this.config}getMcpEndpoint(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?e.mcpEndpoint[0]||"":e.mcpEndpoint}getMcpEndpoints(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?[...e.mcpEndpoint]:e.mcpEndpoint?[e.mcpEndpoint]:[]}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(e){return this.getMcpServerConfig()[e]?.tools||{}}isToolEnabled(e,t){return this.getServerToolsConfig(e)[t]?.enable!==!1}updateMcpEndpoint(e){if(Array.isArray(e)){for(let o of e)if(!o||typeof o!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}let t=this.getMutableConfig();t.mcpEndpoint=e,this.saveConfig(t),this.emitEvent("config:updated",{type:"endpoint",timestamp:new Date})}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(),o=this.getMcpEndpoints();if(o.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let n=[...o,e];t.mcpEndpoint=n,this.saveConfig(t)}removeMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),o=this.getMcpEndpoints();if(o.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);let i=o.filter(s=>s!==e);t.mcpEndpoint=i,this.saveConfig(t)}updateMcpServer(e,t){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let o=this.getMutableConfig();o.mcpServers[e]=t,this.saveConfig(o)}removeMcpServer(e){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig();if(!t.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);if(delete t.mcpServers[e],t.mcpServerConfig?.[e]&&delete t.mcpServerConfig[e],t.customMCP?.tools){let o=t.customMCP.tools.filter(n=>n.handler?.type==="mcp"&&n.handler.config?.serviceName===e);for(let n of o){let i=t.customMCP.tools.findIndex(s=>s.name===n.name);i!==-1&&t.customMCP.tools.splice(i,1)}t.customMCP.tools.length===0&&(t.customMCP=void 0)}this.saveConfig(t),this.emitEvent("config:updated",{type:"customMCP",timestamp:new Date})}updateConfig(e){let t=this.getMutableConfig();if(e.mcpEndpoint!==void 0&&(t.mcpEndpoint=e.mcpEndpoint),e.mcpServers){let o={...t.mcpServers};for(let[n,i]of Object.entries(e.mcpServers))t.mcpServers[n]=i;for(let n of Object.keys(o))n in e.mcpServers||(delete t.mcpServers[n],t.mcpServerConfig?.[n]&&delete t.mcpServerConfig[n])}if(e.connection&&(t.connection||(t.connection={}),Object.assign(t.connection,e.connection)),e.modelscope&&(t.modelscope||(t.modelscope={}),Object.assign(t.modelscope,e.modelscope)),e.webUI&&(t.webUI||(t.webUI={}),Object.assign(t.webUI,e.webUI)),e.mcpServerConfig)for(let[o,n]of Object.entries(e.mcpServerConfig))t.mcpServerConfig?.[o]&&(t.mcpServerConfig[o]=n);if(e.platforms)for(let[o,n]of Object.entries(e.platforms))t.platforms||(t.platforms={}),t.platforms[o]=n;this.saveConfig(t),this.emitEvent("config:updated",{type:"config",timestamp:new Date})}updateServerToolsConfig(e,t){let o=this.getMutableConfig();o.mcpServerConfig||(o.mcpServerConfig={}),Object.keys(t).length===0?delete o.mcpServerConfig[e]:o.mcpServerConfig[e]={tools:t},this.saveConfig(o),this.emitEvent("config:updated",{type:"serverTools",serviceName:e,timestamp:new Date})}removeServerToolsConfig(e){let o={...this.getConfig()};o.mcpServerConfig&&(delete o.mcpServerConfig[e],this.saveConfig(o))}cleanupInvalidServerToolsConfig(){let e=this.getMutableConfig();if(!e.mcpServerConfig)return;let t=Object.keys(e.mcpServers),n=Object.keys(e.mcpServerConfig).filter(i=>!t.includes(i));if(n.length>0){for(let i of n)delete e.mcpServerConfig[i];this.saveConfig(e)}}setToolEnabled(e,t,o,n){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:o,...n&&{description:n}},this.saveConfig(i)}saveConfig(e){try{this.validateConfig(e);let t;this.currentConfigPath?t=this.currentConfigPath:(t=this.getConfigFilePath(),this.currentConfigPath=t);let o=this.getConfigFileFormat(t),n;switch(o){case"json5":try{this.json5Writer?(this.json5Writer.write(e),n=this.json5Writer.toSource()):n=m.stringify(e,null,2)}catch{n=m.stringify(e,null,2)}break;case"jsonc":try{n=m.stringify(e,null,2)}catch{n=JSON.stringify(e,null,2)}break;default:n=JSON.stringify(e,null,2);break}B(t,n,"utf8"),this.config=e,this.notifyConfigUpdate(e)}catch(t){throw this.emitEvent("config:error",{error:t instanceof Error?t:new Error(String(t)),operation:"saveConfig"}),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??b.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??b.heartbeatTimeout,reconnectInterval:t.reconnectInterval??b.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),this.emitEvent("config:updated",{type:"connection",timestamp:new Date})}async updateToolUsageStats(e,t,o){try{if(typeof t=="string"&&o){let n=e,i=t,s=o;await Promise.all([this._updateMCPServerToolStats(n,i,s),this.updateCustomMCPToolStats(n,i,s)])}else{let n=e,i=t,s=new Date().toISOString();await this.updateCustomMCPToolStats(n,s,i)}}catch{if(typeof t=="string"&&o){let i=e,s=t}else{let i=e}}}async updateMCPServerToolStats(e,t,o,n=!0){await this._updateMCPServerToolStats(e,t,o,n)}setHeartbeatInterval(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:e})}setHeartbeatTimeout(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:e})}setReconnectInterval(e){if(e<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:e})}getModelScopeConfig(){return this.getConfig().modelscope||{}}getModelScopeApiKey(){return this.getModelScopeConfig().apiKey||process.env.MODELSCOPE_API_TOKEN}updateModelScopeConfig(e){let t=this.getMutableConfig();t.modelscope||(t.modelscope={}),Object.assign(t.modelscope,e),this.saveConfig(t),this.emitEvent("config:updated",{type:"modelscope",timestamp:new Date})}setModelScopeApiKey(e){if(!e||typeof e!="string")throw new Error("API Key \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");this.updateModelScopeConfig({apiKey:e})}getCustomMCPConfig(){return this.getConfig().customMCP||null}getCustomMCPTools(){let e=this.getCustomMCPConfig();return!e||!e.tools?[]:e.tools}validateCustomMCPTools(e){if(!Array.isArray(e))return!1;for(let t of e)if(!t.name||typeof t.name!="string"||!t.description||typeof t.description!="string"||!t.inputSchema||typeof t.inputSchema!="object"||!t.handler||typeof t.handler!="object"||!["proxy","function","http","script","chain","mcp"].includes(t.handler.type)||!this.validateHandlerConfig(t.name,t.handler))return!1;return!0}validateHandlerConfig(e,t){switch(t.type){case"proxy":return this.validateProxyHandler(e,t);case"http":return this.validateHttpHandler(e,t);case"function":return this.validateFunctionHandler(e,t);case"script":return this.validateScriptHandler(e,t);case"chain":return this.validateChainHandler(e,t);case"mcp":return this.validateMCPHandler(e,t);default:return!1}}validateProxyHandler(e,t){return!(!t.platform||!["coze","openai","anthropic","custom"].includes(t.platform)||!t.config||typeof t.config!="object"||t.platform==="coze"&&!t.config.workflow_id&&!t.config.bot_id)}validateHttpHandler(e,t){if(!t.url||typeof t.url!="string")return!1;try{new URL(t.url)}catch{return!1}return!(t.method&&!["GET","POST","PUT","DELETE","PATCH"].includes(t.method))}validateFunctionHandler(e,t){return!(!t.module||typeof t.module!="string"||!t.function||typeof t.function!="string")}validateScriptHandler(e,t){return!(!t.script||typeof t.script!="string"||t.interpreter&&!["node","python","bash"].includes(t.interpreter))}validateChainHandler(e,t){return!(!t.tools||!Array.isArray(t.tools)||t.tools.length===0||!["sequential","parallel"].includes(t.mode)||!["stop","continue","retry"].includes(t.error_handling))}validateMCPHandler(e,t){return!(!t.config||typeof t.config!="object"||!t.config.serviceName||typeof t.config.serviceName!="string"||!t.config.toolName||typeof t.config.toolName!="string")}hasValidCustomMCPTools(){try{let e=this.getCustomMCPTools();return e.length===0?!1:this.validateCustomMCPTools(e)}catch{return!1}}addCustomMCPTool(e){if(!e||typeof e!="object")throw new Error("\u5DE5\u5177\u914D\u7F6E\u4E0D\u80FD\u4E3A\u7A7A");let t=this.getMutableConfig();if(t.customMCP||(t.customMCP={tools:[]}),t.customMCP.tools.find(n=>n.name===e.name))throw new Error(`\u5DE5\u5177 "${e.name}" \u5DF2\u5B58\u5728`);if(!this.validateCustomMCPTools([e]))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");t.customMCP.tools.unshift(e),this.saveConfig(t)}async addCustomMCPTools(e){if(!Array.isArray(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u5FC5\u987B\u662F\u6570\u7EC4");if(e.length===0)return;let t=this.getMutableConfig();t.customMCP||(t.customMCP={tools:[]});let o=new Set(t.customMCP.tools.map(i=>i.name)),n=e.filter(i=>!o.has(i.name));if(n.length>0){if(!this.validateCustomMCPTools(n))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");t.customMCP.tools.push(...n),this.saveConfig(t),this.emitEvent("config:updated",{type:"customMCP",timestamp:new Date})}}removeCustomMCPTool(e){if(!e||typeof e!="string")throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");let t=this.getMutableConfig();if(!t.customMCP||!t.customMCP.tools)throw new Error("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177");let o=t.customMCP.tools.findIndex(n=>n.name===e);if(o===-1)throw new Error(`\u5DE5\u5177 "${e}" \u4E0D\u5B58\u5728`);t.customMCP.tools.splice(o,1),this.saveConfig(t)}updateCustomMCPTool(e,t){if(!e||typeof e!="string")throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");if(!t||typeof t!="object")throw new Error("\u66F4\u65B0\u540E\u7684\u5DE5\u5177\u914D\u7F6E\u4E0D\u80FD\u4E3A\u7A7A");let o=this.getMutableConfig();if(!o.customMCP||!o.customMCP.tools)throw new Error("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177");let n=o.customMCP.tools.findIndex(i=>i.name===e);if(n===-1)throw new Error(`\u5DE5\u5177 "${e}" \u4E0D\u5B58\u5728`);if(!this.validateCustomMCPTools([t]))throw new Error("\u66F4\u65B0\u540E\u7684\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");o.customMCP.tools[n]=t,this.saveConfig(o)}updateCustomMCPTools(e){if(!Array.isArray(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u5FC5\u987B\u662F\u6570\u7EC4");if(!this.validateCustomMCPTools(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let t=this.getMutableConfig();t.customMCP||(t.customMCP={tools:[]}),t.customMCP.tools=e,this.saveConfig(t),this.emitEvent("config:updated",{type:"customMCP",timestamp:new Date})}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)}catch{}}updateWebUIConfig(e){let t=this.getMutableConfig();t.webUI||(t.webUI={}),Object.assign(t.webUI,e),this.saveConfig(t),this.emitEvent("config:updated",{type:"webui",timestamp:new Date})}setWebUIPort(e){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error("\u7AEF\u53E3\u53F7\u5FC5\u987B\u662F 1-65535 \u4E4B\u95F4\u7684\u6574\u6570");this.updateWebUIConfig({port:e})}updatePlatformConfig(e,t){let o=this.getMutableConfig();o.platforms||(o.platforms={}),o.platforms[e]=t,this.saveConfig(o),this.emitEvent("config:updated",{type:"platform",platformName:e,timestamp:new Date})}getCozePlatformConfig(){let t=this.getConfig().platforms?.coze;return!t||!t.token?null:{token:t.token}}getCozeToken(){return this.getCozePlatformConfig()?.token||null}setCozePlatformConfig(e){if(!e.token||typeof e.token!="string"||e.token.trim()==="")throw new Error("\u6263\u5B50 API Token \u4E0D\u80FD\u4E3A\u7A7A");this.updatePlatformConfig("coze",{token:e.token.trim()})}isCozeConfigValid(){let e=this.getCozePlatformConfig();return e!==null&&typeof e.token=="string"&&e.token.trim()!==""}async _updateMCPServerToolStats(e,t,o,n=!0){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 s=i.mcpServerConfig[e].tools[t],l=s.usageCount||0,g=s.lastUsedTime;n&&(s.usageCount=l+1),(!g||new Date(o)>new Date(g))&&(s.lastUsedTime=j(o).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(i)}async updateCustomMCPToolStats(e,t,o){try{let n,i,s=!0,l;if(typeof o=="string"){let h=e;n=`${h}__${t}`,i=o,l=`${h}/${t}`}else n=e,i=t,s=o||!0,l=n;let g=this.getCustomMCPTools(),T=g.findIndex(h=>h.name===n);if(T===-1)return;let E=[...g],p=E[T];p.stats||(p.stats={});let F=p.stats.usageCount||0,I=p.stats.lastUsedTime;s&&(p.stats.usageCount=F+1),(!I||new Date(i)>new Date(I))&&(p.stats.lastUsedTime=j(i).format("YYYY-MM-DD HH:mm:ss")),await this.updateCustomMCPTools(E)}catch{if(typeof o=="string"){let i=e,s=t}else{let i=e}}}async acquireStatsUpdateLock(e){if(this.statsUpdateLocks.has(e))return!1;let t=new Promise(n=>{});this.statsUpdateLocks.set(e,t);let o=setTimeout(()=>{this.releaseStatsUpdateLock(e)},this.STATS_UPDATE_TIMEOUT);return this.statsUpdateLockTimeouts.set(e,o),!0}releaseStatsUpdateLock(e){this.statsUpdateLocks.delete(e);let t=this.statsUpdateLockTimeouts.get(e);t&&(clearTimeout(t),this.statsUpdateLockTimeouts.delete(e))}async updateToolUsageStatsWithLock(e,t=!0){let o=`custommcp_${e}`;if(await this.acquireStatsUpdateLock(o))try{await this.updateToolUsageStats(e,t)}catch(n){throw n}finally{this.releaseStatsUpdateLock(o)}}async updateMCPServerToolStatsWithLock(e,t,o,n=!0){let i=`mcpserver_${e}_${t}`;if(await this.acquireStatsUpdateLock(i))try{await this.updateMCPServerToolStats(e,t,o,n)}catch(s){throw s}finally{this.releaseStatsUpdateLock(i)}}clearAllStatsUpdateLocks(){let e=this.statsUpdateLocks.size;this.statsUpdateLocks.clear();for(let t of this.statsUpdateLockTimeouts.values())clearTimeout(t);this.statsUpdateLockTimeouts.clear(),e>0}getStatsUpdateLocks(){return Array.from(this.statsUpdateLocks.keys())}getToolCallLogConfig(){return this.getConfig().toolCallLog||{}}updateToolCallLogConfig(e){let t=this.getMutableConfig();t.toolCallLog||(t.toolCallLog={}),Object.assign(t.toolCallLog,e),this.saveConfig(t)}getConfigDir(){return process.env.XIAOZHI_CONFIG_DIR||process.cwd()}},be=S.getInstance();import{isAbsolute as q,resolve as X,dirname as Z}from"path";var c=class extends Error{constructor(t,o){super(t);this.configName=o;this.name="ConfigValidationError"}static{a(this,"ConfigValidationError")}},N=(o=>(o.STDIO="stdio",o.SSE="sse",o.STREAMABLE_HTTP="streamable-http",o))(N||{});function w(r){try{let t=new URL(r).pathname;return t.endsWith("/sse")?"sse":(t.endsWith("/mcp"),"streamable-http")}catch{return"streamable-http"}}a(w,"inferTransportTypeFromUrl");function K(r,e){try{if(!r||typeof r!="string")throw new c("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");if(!e||typeof e!="object")throw new c("\u914D\u7F6E\u5BF9\u8C61\u4E0D\u80FD\u4E3A\u7A7A",r);let t=V(r,e);return te(t),t}catch(t){throw t instanceof c?t:new c(`\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`,r)}}a(K,"convertLegacyToNew");function V(r,e){if(R(e))return Q(r,e);if("type"in e)switch(e.type){case"sse":return A(r,e);case"streamable-http":return D(r,e);default:throw new c(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${e.type}`,r)}if("url"in e){if(e.url===void 0||e.url===null)throw new c("\u7F51\u7EDC\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 url \u5B57\u6BB5",r);if(w(e.url||"")==="sse"){let n={...e,type:"sse"};return A(r,n)}let o={...e,type:"streamable-http"};return D(r,o)}throw new c("\u65E0\u6CD5\u8BC6\u522B\u7684\u914D\u7F6E\u7C7B\u578B",r)}a(V,"convertByConfigType");function Q(r,e){if(!e.command)throw new c("\u672C\u5730\u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5",r);let t;if(process.env.XIAOZHI_CONFIG_DIR)t=process.env.XIAOZHI_CONFIG_DIR;else{let n=f.resolveConfigPath();n?t=Z(n):t=process.cwd()}let o=(e.args||[]).map(n=>ee(n)?X(t,n):n);return{name:r,type:"stdio",command:e.command,args:o,env:e.env,timeout:3e4}}a(Q,"convertLocalConfig");function A(r,e){if(e.url===void 0||e.url===null)throw new c("SSE \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5",r);let t=e.type==="sse"?"sse":w(e.url||""),o=e.url?M(e.url):!1,n={name:r,type:t,url:e.url,timeout:3e4,headers:e.headers};return o&&(n.modelScopeAuth=!0),n}a(A,"convertSSEConfig");function D(r,e){if(e.url===void 0||e.url===null)throw new c("STREAMABLE_HTTP \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5",r);let t=e.url||"";return{name:r,type:"streamable-http",url:t,timeout:3e4,headers:e.headers}}a(D,"convertStreamableHTTPConfig");function Te(r){let e={},t=[];for(let[o,n]of Object.entries(r))try{e[o]=K(o,n)}catch(i){t.push({serviceName:o,error:i instanceof Error?i:new Error(String(i))})}if(t.length>0){let o=t.map(({serviceName:n,error:i})=>`${n}: ${i.message}`).join("; ");throw new c(`\u6279\u91CF\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${o}`)}return e}a(Te,"convertLegacyConfigBatch");function ee(r){return q(r)?!1:!!(r.startsWith("./")||r.startsWith("../")||/\.(js|py|ts|mjs|cjs)$/i.test(r))}a(ee,"isRelativePath");function R(r){return"command"in r&&typeof r.command=="string"}a(R,"isLocalConfig");function M(r){try{let t=new URL(r).hostname.toLowerCase();return t.endsWith(".modelscope.net")||t.endsWith(".modelscope.cn")||t==="modelscope.net"||t==="modelscope.cn"}catch{return!1}}a(M,"isModelScopeURL");function te(r){if(!r.name||typeof r.name!="string")throw new c("\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 name \u5B57\u6BB5");if(r.type&&!Object.values(N).includes(r.type))throw new c(`\u65E0\u6548\u7684\u4F20\u8F93\u7C7B\u578B: ${r.type}`);if(!r.type)throw new c("\u4F20\u8F93\u7C7B\u578B\u672A\u6307\u5B9A\uFF0C\u8BF7\u68C0\u67E5\u914D\u7F6E\u6216\u542F\u7528\u81EA\u52A8\u63A8\u65AD");switch(r.type){case"stdio":if(!r.command)throw new c("STDIO \u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5");break;case"sse":if(r.url===void 0||r.url===null)throw new c("SSE \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5");break;case"streamable-http":if(r.url===void 0||r.url===null)throw new c("STREAMABLE_HTTP \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5");break;default:throw new c(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${r.type}`)}}a(te,"validateNewConfig");function Ee(r){if(R(r))return`\u672C\u5730\u8FDB\u7A0B (${r.command})`;if("url"in r){if("type"in r&&r.type==="streamable-http")return`Streamable HTTP (${r.url})`;if("type"in r&&r.type==="sse")return`SSE${M(r.url)?" (ModelScope)":""} (${r.url})`;let e=w(r.url),t=M(r.url);return e==="sse"?`SSE${t?" (ModelScope)":""} (${r.url})`:`Streamable HTTP (${r.url})`}return"\u672A\u77E5\u7C7B\u578B"}a(Ee,"getConfigTypeDescription");import y from"path";import{mkdirSync as L,existsSync as _,readdirSync as oe,statSync as ne,copyFileSync as re}from"fs";import{dirname as ie,resolve as d}from"path";import{fileURLToPath as se}from"url";var v=ie(se(import.meta.url)),O=class{static{a(this,"ConfigInitializer")}static async initializeDefaultConfig(){let e=process.env.HOME||process.env.USERPROFILE;if(!e)throw new Error("\u65E0\u6CD5\u83B7\u53D6\u7528\u6237\u5BB6\u76EE\u5F55");let t=y.join(e,".xiaozhi-client");if(_(t))return t;L(t,{recursive:!0});let o=this.getDefaultTemplateDir();if(!o)throw new Error("\u9ED8\u8BA4\u914D\u7F6E\u6A21\u677F\u4E0D\u5B58\u5728\uFF0C\u8BF7\u68C0\u67E5\u9879\u76EE\u6A21\u677F\u6587\u4EF6\u662F\u5426\u5B58\u5728");return this.copyDirectoryRecursive(o,t,["template.json",".git","node_modules"]),t}static copyDirectoryRecursive(e,t,o=[]){let n=oe(e);for(let i of n){if(o.includes(i))continue;let s=y.join(e,i),l=y.join(t,i);ne(s).isDirectory()?(L(l,{recursive:!0}),this.copyDirectoryRecursive(s,l,o)):re(s,l)}}static getDefaultTemplateDir(){let e=[d(v,"templates","default"),d(v,"..","templates","default"),d(process.cwd(),"templates","default"),d(v,"..","..","..","templates","default"),d(v,"..","..","..","..","templates","default")];for(let t of e)if(_(t))return t;return null}};export{O as ConfigInitializer,S as ConfigManager,f as ConfigResolver,c as ConfigValidationError,N as MCPTransportType,be as configManager,Te as convertLegacyConfigBatch,K as convertLegacyToNew,Ee as getConfigTypeDescription,M as isModelScopeURL};
|
|
1
|
+
var $=Object.defineProperty;var a=(r,e)=>$(r,"name",{value:e,configurable:!0});import{copyFileSync as G,existsSync as j,readFileSync as Y,writeFileSync as q}from"fs";import{dirname as X,resolve as u}from"path";import{fileURLToPath as Z}from"url";import*as m from"comment-json";import H from"dayjs";import*as C from"comment-json";function k(r){let e=C.parse(r);return{write(t){e&&typeof e=="object"&&t&&Object.assign(e,t)},toSource(){return C.stringify(e,null,2)}}}a(k,"createJson5Writer");function U(r){return C.parse(r)}a(U,"parseJson5");import P from"path";import{existsSync as J}from"fs";var f=class{static{a(this,"ConfigResolver")}static resolveConfigPath(){if(process.env.XIAOZHI_CONFIG_DIR){let o=this.findConfigInDir(process.env.XIAOZHI_CONFIG_DIR);if(o)return o}let e=this.findConfigInDir(process.cwd());if(e)return e;let t=process.env.HOME||process.env.USERPROFILE;if(t){let o=P.join(t,".xiaozhi-client"),n=this.findConfigInDir(o);if(n)return n}return null}static findConfigInDir(e){let t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let o of t){let n=P.join(e,o);if(J(n))return n}return null}static getDefaultConfigDir(){let e=process.env.HOME||process.env.USERPROFILE;return e?P.join(e,".xiaozhi-client"):null}};var N=X(Z(import.meta.url)),b={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},S=class r{static{a(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;statsUpdateLocks=new Map;statsUpdateLockTimeouts=new Map;STATS_UPDATE_TIMEOUT=5e3;eventCallbacks=new Map;constructor(){let e=[u(N,"templates","default","xiaozhi.config.json"),u(N,"..","templates","default","xiaozhi.config.json"),u(process.cwd(),"templates","default","xiaozhi.config.json")];this.defaultConfigPath=e.find(t=>j(t))||e[0]}on(e,t){this.eventCallbacks.has(e)||this.eventCallbacks.set(e,[]),this.eventCallbacks.get(e)?.push(t)}emitEvent(e,t){let o=this.eventCallbacks.get(e);if(o)for(let n of o)try{n(t)}catch{}}getConfigFilePath(){let e=f.resolveConfigPath();if(e)return e;let t=f.getDefaultConfigDir();if(t)return u(t,"xiaozhi.config.json");let o=process.env.XIAOZHI_CONFIG_DIR||process.cwd();return u(o,"xiaozhi.config.json")}getConfigFileFormat(e){return e.endsWith(".json5")?"json5":e.endsWith(".jsonc")?"jsonc":"json"}static getInstance(){return r.instance||(r.instance=new r),r.instance}configExists(){return f.resolveConfigPath()!==null}initConfig(e="json"){if(!j(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(),o=`xiaozhi.config.${e}`,n=u(t,o);G(this.defaultConfigPath,n),this.config=null,this.json5Writer=null}loadConfig(){if(!this.configExists()){let e=new Error("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C xiaozhi init \u521D\u59CB\u5316\u914D\u7F6E");throw this.emitEvent("config:error",{error:e,operation:"loadConfig"}),e}try{let e=this.getConfigFilePath();this.currentConfigPath=e;let t=this.getConfigFileFormat(e),n=Y(e,"utf8").replace(/^\uFEFF/,""),i;switch(t){case"json5":i=U(n),this.json5Writer=k(n);break;case"jsonc":i=m.parse(n);break;default:i=JSON.parse(n);break}return this.validateConfig(i),i}catch(e){throw this.emitEvent("config:error",{error:e instanceof Error?e:new Error(String(e)),operation:"loadConfig"}),e instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${e.message}`):e}}validateConfig(e){if(!e||typeof e!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let t=e;if(t.mcpEndpoint===void 0||t.mcpEndpoint===null)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(typeof t.mcpEndpoint!="string")if(Array.isArray(t.mcpEndpoint)){for(let o of t.mcpEndpoint)if(typeof o!="string"||o.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[o,n]of Object.entries(t.mcpServers))if(!n||typeof n!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${o} \u65E0\u6548`)}getConfig(){return this.config=this.loadConfig(),JSON.parse(JSON.stringify(this.config))}getMutableConfig(){return this.config||(this.config=this.loadConfig()),this.config}getMcpEndpoint(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?e.mcpEndpoint[0]||"":e.mcpEndpoint}getMcpEndpoints(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?[...e.mcpEndpoint]:e.mcpEndpoint?[e.mcpEndpoint]:[]}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(e){return this.getMcpServerConfig()[e]?.tools||{}}isToolEnabled(e,t){return this.getServerToolsConfig(e)[t]?.enable!==!1}updateMcpEndpoint(e){if(Array.isArray(e)){for(let o of e)if(!o||typeof o!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}let t=this.getMutableConfig();t.mcpEndpoint=e,this.saveConfig(t),this.emitEvent("config:updated",{type:"endpoint",timestamp:new Date})}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(),o=this.getMcpEndpoints();if(o.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let n=[...o,e];t.mcpEndpoint=n,this.saveConfig(t)}removeMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),o=this.getMcpEndpoints();if(o.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);let i=o.filter(s=>s!==e);t.mcpEndpoint=i,this.saveConfig(t)}updateMcpServer(e,t){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let o=this.getMutableConfig();o.mcpServers[e]=t,this.saveConfig(o)}removeMcpServer(e){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig();if(!t.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);if(delete t.mcpServers[e],t.mcpServerConfig?.[e]&&delete t.mcpServerConfig[e],t.customMCP?.tools){let o=t.customMCP.tools.filter(n=>n.handler?.type==="mcp"&&n.handler.config?.serviceName===e);for(let n of o){let i=t.customMCP.tools.findIndex(s=>s.name===n.name);i!==-1&&t.customMCP.tools.splice(i,1)}t.customMCP.tools.length===0&&(t.customMCP=void 0)}this.saveConfig(t),this.emitEvent("config:updated",{type:"customMCP",timestamp:new Date})}updateConfig(e){let t=this.getMutableConfig();if(e.mcpEndpoint!==void 0&&(t.mcpEndpoint=e.mcpEndpoint),e.mcpServers){let o={...t.mcpServers};for(let[n,i]of Object.entries(e.mcpServers))t.mcpServers[n]=i;for(let n of Object.keys(o))n in e.mcpServers||(delete t.mcpServers[n],t.mcpServerConfig?.[n]&&delete t.mcpServerConfig[n])}if(e.connection&&(t.connection||(t.connection={}),Object.assign(t.connection,e.connection)),e.modelscope&&(t.modelscope||(t.modelscope={}),Object.assign(t.modelscope,e.modelscope)),e.webUI&&(t.webUI||(t.webUI={}),Object.assign(t.webUI,e.webUI)),e.mcpServerConfig)for(let[o,n]of Object.entries(e.mcpServerConfig))t.mcpServerConfig?.[o]&&(t.mcpServerConfig[o]=n);if(e.platforms)for(let[o,n]of Object.entries(e.platforms))t.platforms||(t.platforms={}),t.platforms[o]=n;this.saveConfig(t),this.emitEvent("config:updated",{type:"config",timestamp:new Date})}updateServerToolsConfig(e,t){let o=this.getMutableConfig();o.mcpServerConfig||(o.mcpServerConfig={}),Object.keys(t).length===0?delete o.mcpServerConfig[e]:o.mcpServerConfig[e]={tools:t},this.saveConfig(o),this.emitEvent("config:updated",{type:"serverTools",serviceName:e,timestamp:new Date})}removeServerToolsConfig(e){let o={...this.getConfig()};o.mcpServerConfig&&(delete o.mcpServerConfig[e],this.saveConfig(o))}cleanupInvalidServerToolsConfig(){let e=this.getMutableConfig();if(!e.mcpServerConfig)return;let t=Object.keys(e.mcpServers),n=Object.keys(e.mcpServerConfig).filter(i=>!t.includes(i));if(n.length>0){for(let i of n)delete e.mcpServerConfig[i];this.saveConfig(e)}}setToolEnabled(e,t,o,n){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:o,...n&&{description:n}},this.saveConfig(i)}saveConfig(e){try{this.validateConfig(e);let t;this.currentConfigPath?t=this.currentConfigPath:(t=this.getConfigFilePath(),this.currentConfigPath=t);let o=this.getConfigFileFormat(t),n;switch(o){case"json5":try{this.json5Writer?(this.json5Writer.write(e),n=this.json5Writer.toSource()):n=m.stringify(e,null,2)}catch{n=m.stringify(e,null,2)}break;case"jsonc":try{n=m.stringify(e,null,2)}catch{n=JSON.stringify(e,null,2)}break;default:n=JSON.stringify(e,null,2);break}q(t,n,"utf8"),this.config=e,this.notifyConfigUpdate(e)}catch(t){throw this.emitEvent("config:error",{error:t instanceof Error?t:new Error(String(t)),operation:"saveConfig"}),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??b.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??b.heartbeatTimeout,reconnectInterval:t.reconnectInterval??b.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),this.emitEvent("config:updated",{type:"connection",timestamp:new Date})}async updateToolUsageStats(e,t,o){try{if(typeof t=="string"&&o){let n=e,i=t,s=o;await Promise.all([this._updateMCPServerToolStats(n,i,s),this.updateCustomMCPToolStats(n,i,s)])}else{let n=e,i=t,s=new Date().toISOString();await this.updateCustomMCPToolStats(n,s,i)}}catch{if(typeof t=="string"&&o){let i=e,s=t}else{let i=e}}}async updateMCPServerToolStats(e,t,o,n=!0){await this._updateMCPServerToolStats(e,t,o,n)}setHeartbeatInterval(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:e})}setHeartbeatTimeout(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:e})}setReconnectInterval(e){if(e<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:e})}getModelScopeConfig(){return this.getConfig().modelscope||{}}getModelScopeApiKey(){return this.getModelScopeConfig().apiKey||process.env.MODELSCOPE_API_TOKEN}updateModelScopeConfig(e){let t=this.getMutableConfig();t.modelscope||(t.modelscope={}),Object.assign(t.modelscope,e),this.saveConfig(t),this.emitEvent("config:updated",{type:"modelscope",timestamp:new Date})}setModelScopeApiKey(e){if(!e||typeof e!="string")throw new Error("API Key \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");this.updateModelScopeConfig({apiKey:e})}getCustomMCPConfig(){return this.getConfig().customMCP||null}getCustomMCPTools(){let e=this.getCustomMCPConfig();return!e||!e.tools?[]:e.tools}validateCustomMCPTools(e){if(!Array.isArray(e))return!1;for(let t of e)if(!t.name||typeof t.name!="string"||!t.description||typeof t.description!="string"||!t.inputSchema||typeof t.inputSchema!="object"||!t.handler||typeof t.handler!="object"||!["proxy","function","http","script","chain","mcp"].includes(t.handler.type)||!this.validateHandlerConfig(t.name,t.handler))return!1;return!0}validateHandlerConfig(e,t){switch(t.type){case"proxy":return this.validateProxyHandler(e,t);case"http":return this.validateHttpHandler(e,t);case"function":return this.validateFunctionHandler(e,t);case"script":return this.validateScriptHandler(e,t);case"chain":return this.validateChainHandler(e,t);case"mcp":return this.validateMCPHandler(e,t);default:return!1}}validateProxyHandler(e,t){return!(!t.platform||!["coze","openai","anthropic","custom"].includes(t.platform)||!t.config||typeof t.config!="object"||t.platform==="coze"&&!t.config.workflow_id&&!t.config.bot_id)}validateHttpHandler(e,t){if(!t.url||typeof t.url!="string")return!1;try{new URL(t.url)}catch{return!1}return!(t.method&&!["GET","POST","PUT","DELETE","PATCH"].includes(t.method))}validateFunctionHandler(e,t){return!(!t.module||typeof t.module!="string"||!t.function||typeof t.function!="string")}validateScriptHandler(e,t){return!(!t.script||typeof t.script!="string"||t.interpreter&&!["node","python","bash"].includes(t.interpreter))}validateChainHandler(e,t){return!(!t.tools||!Array.isArray(t.tools)||t.tools.length===0||!["sequential","parallel"].includes(t.mode)||!["stop","continue","retry"].includes(t.error_handling))}validateMCPHandler(e,t){return!(!t.config||typeof t.config!="object"||!t.config.serviceName||typeof t.config.serviceName!="string"||!t.config.toolName||typeof t.config.toolName!="string")}hasValidCustomMCPTools(){try{let e=this.getCustomMCPTools();return e.length===0?!1:this.validateCustomMCPTools(e)}catch{return!1}}addCustomMCPTool(e){if(!e||typeof e!="object")throw new Error("\u5DE5\u5177\u914D\u7F6E\u4E0D\u80FD\u4E3A\u7A7A");let t=this.getMutableConfig();if(t.customMCP||(t.customMCP={tools:[]}),t.customMCP.tools.find(n=>n.name===e.name))throw new Error(`\u5DE5\u5177 "${e.name}" \u5DF2\u5B58\u5728`);if(!this.validateCustomMCPTools([e]))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");t.customMCP.tools.unshift(e),this.saveConfig(t)}async addCustomMCPTools(e){if(!Array.isArray(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u5FC5\u987B\u662F\u6570\u7EC4");if(e.length===0)return;let t=this.getMutableConfig();t.customMCP||(t.customMCP={tools:[]});let o=new Set(t.customMCP.tools.map(i=>i.name)),n=e.filter(i=>!o.has(i.name));if(n.length>0){if(!this.validateCustomMCPTools(n))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");t.customMCP.tools.push(...n),this.saveConfig(t),this.emitEvent("config:updated",{type:"customMCP",timestamp:new Date})}}removeCustomMCPTool(e){if(!e||typeof e!="string")throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");let t=this.getMutableConfig();if(!t.customMCP||!t.customMCP.tools)throw new Error("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177");let o=t.customMCP.tools.findIndex(n=>n.name===e);if(o===-1)throw new Error(`\u5DE5\u5177 "${e}" \u4E0D\u5B58\u5728`);t.customMCP.tools.splice(o,1),this.saveConfig(t)}updateCustomMCPTool(e,t){if(!e||typeof e!="string")throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");if(!t||typeof t!="object")throw new Error("\u66F4\u65B0\u540E\u7684\u5DE5\u5177\u914D\u7F6E\u4E0D\u80FD\u4E3A\u7A7A");let o=this.getMutableConfig();if(!o.customMCP||!o.customMCP.tools)throw new Error("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49 MCP \u5DE5\u5177");let n=o.customMCP.tools.findIndex(i=>i.name===e);if(n===-1)throw new Error(`\u5DE5\u5177 "${e}" \u4E0D\u5B58\u5728`);if(!this.validateCustomMCPTools([t]))throw new Error("\u66F4\u65B0\u540E\u7684\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");o.customMCP.tools[n]=t,this.saveConfig(o)}updateCustomMCPTools(e){if(!Array.isArray(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u5FC5\u987B\u662F\u6570\u7EC4");if(!this.validateCustomMCPTools(e))throw new Error("\u5DE5\u5177\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let t=this.getMutableConfig();t.customMCP||(t.customMCP={tools:[]}),t.customMCP.tools=e,this.saveConfig(t),this.emitEvent("config:updated",{type:"customMCP",timestamp:new Date})}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)}catch{}}updateWebUIConfig(e){let t=this.getMutableConfig();t.webUI||(t.webUI={}),Object.assign(t.webUI,e),this.saveConfig(t),this.emitEvent("config:updated",{type:"webui",timestamp:new Date})}setWebUIPort(e){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error("\u7AEF\u53E3\u53F7\u5FC5\u987B\u662F 1-65535 \u4E4B\u95F4\u7684\u6574\u6570");this.updateWebUIConfig({port:e})}updatePlatformConfig(e,t){let o=this.getMutableConfig();o.platforms||(o.platforms={}),o.platforms[e]=t,this.saveConfig(o),this.emitEvent("config:updated",{type:"platform",platformName:e,timestamp:new Date})}getCozePlatformConfig(){let t=this.getConfig().platforms?.coze;return!t||!t.token?null:{token:t.token}}getCozeToken(){return this.getCozePlatformConfig()?.token||null}setCozePlatformConfig(e){if(!e.token||typeof e.token!="string"||e.token.trim()==="")throw new Error("\u6263\u5B50 API Token \u4E0D\u80FD\u4E3A\u7A7A");this.updatePlatformConfig("coze",{token:e.token.trim()})}isCozeConfigValid(){let e=this.getCozePlatformConfig();return e!==null&&typeof e.token=="string"&&e.token.trim()!==""}async _updateMCPServerToolStats(e,t,o,n=!0){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 s=i.mcpServerConfig[e].tools[t],l=s.usageCount||0,g=s.lastUsedTime;n&&(s.usageCount=l+1),(!g||new Date(o)>new Date(g))&&(s.lastUsedTime=H(o).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(i)}async updateCustomMCPToolStats(e,t,o){try{let n,i,s=!0,l;if(typeof o=="string"){let h=e;n=`${h}__${t}`,i=o,l=`${h}/${t}`}else n=e,i=t,s=o||!0,l=n;let g=this.getCustomMCPTools(),E=g.findIndex(h=>h.name===n);if(E===-1)return;let I=[...g],p=I[E];p.stats||(p.stats={});let W=p.stats.usageCount||0,x=p.stats.lastUsedTime;s&&(p.stats.usageCount=W+1),(!x||new Date(i)>new Date(x))&&(p.stats.lastUsedTime=H(i).format("YYYY-MM-DD HH:mm:ss")),await this.updateCustomMCPTools(I)}catch{if(typeof o=="string"){let i=e,s=t}else{let i=e}}}async acquireStatsUpdateLock(e){if(this.statsUpdateLocks.has(e))return!1;let t=new Promise(n=>{});this.statsUpdateLocks.set(e,t);let o=setTimeout(()=>{this.releaseStatsUpdateLock(e)},this.STATS_UPDATE_TIMEOUT);return this.statsUpdateLockTimeouts.set(e,o),!0}releaseStatsUpdateLock(e){this.statsUpdateLocks.delete(e);let t=this.statsUpdateLockTimeouts.get(e);t&&(clearTimeout(t),this.statsUpdateLockTimeouts.delete(e))}async updateToolUsageStatsWithLock(e,t=!0){let o=`custommcp_${e}`;if(await this.acquireStatsUpdateLock(o))try{await this.updateToolUsageStats(e,t)}catch(n){throw n}finally{this.releaseStatsUpdateLock(o)}}async updateMCPServerToolStatsWithLock(e,t,o,n=!0){let i=`mcpserver_${e}_${t}`;if(await this.acquireStatsUpdateLock(i))try{await this.updateMCPServerToolStats(e,t,o,n)}catch(s){throw s}finally{this.releaseStatsUpdateLock(i)}}clearAllStatsUpdateLocks(){let e=this.statsUpdateLocks.size;this.statsUpdateLocks.clear();for(let t of this.statsUpdateLockTimeouts.values())clearTimeout(t);this.statsUpdateLockTimeouts.clear(),e>0}getStatsUpdateLocks(){return Array.from(this.statsUpdateLocks.keys())}getToolCallLogConfig(){return this.getConfig().toolCallLog||{}}updateToolCallLogConfig(e){let t=this.getMutableConfig();t.toolCallLog||(t.toolCallLog={}),Object.assign(t.toolCallLog,e),this.saveConfig(t)}getConfigDir(){return process.env.XIAOZHI_CONFIG_DIR||process.cwd()}},be=S.getInstance();import{isAbsolute as K,resolve as D,dirname as B}from"path";var c=class extends Error{static{a(this,"ConfigValidationError")}constructor(e){super(e),this.name="ConfigValidationError"}},L=(o=>(o.STDIO="stdio",o.SSE="sse",o.HTTP="http",o))(L||{});function w(r){try{let t=new URL(r).pathname;return t.endsWith("/sse")?"sse":(t.endsWith("/mcp"),"http")}catch{return"http"}}a(w,"inferTransportTypeFromUrl");function V(r){try{if(!r||typeof r!="object")throw new c("\u914D\u7F6E\u5BF9\u8C61\u4E0D\u80FD\u4E3A\u7A7A");let e=Q(r);return te(e),e}catch(e){throw e instanceof c?e:new c(`\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}a(V,"normalizeServiceConfig");function Q(r){if(M(r))return ee(r);if("type"in r)switch(r.type){case"sse":return O(r);case"http":case"streamable-http":return R(r);default:throw new c(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${r.type}`)}if("url"in r){if(r.url===void 0||r.url===null)throw new c("\u7F51\u7EDC\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 url \u5B57\u6BB5");if(w(r.url||"")==="sse"){let o={...r,type:"sse"};return O(o)}let t={...r,type:"http"};return R(t)}throw new c("\u65E0\u6CD5\u8BC6\u522B\u7684\u914D\u7F6E\u7C7B\u578B")}a(Q,"convertByConfigType");function ee(r){if(!M(r))throw new c("\u65E0\u6548\u7684\u672C\u5730\u914D\u7F6E\u7C7B\u578B");let{command:e,args:t,env:o}=r;if(!e)throw new c("\u672C\u5730\u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5");let n;if(process.env.XIAOZHI_CONFIG_DIR)n=process.env.XIAOZHI_CONFIG_DIR;else{let l=f.resolveConfigPath();l?n=B(l):n=process.cwd()}let i=e;_(e)&&(i=D(n,e));let s=(t||[]).map(l=>_(l)?D(n,l):l);return{type:"stdio",command:i,args:s,...o!==void 0&&{env:o}}}a(ee,"convertLocalConfig");function O(r){let e=r.url,t=r.type,o=r.headers;if(e==null)throw new c("SSE \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5");let n=t==="sse"?"sse":w(e||""),i=e?y(e):!1;return{type:n,url:e,headers:o}}a(O,"convertSSEConfig");function R(r){let e=r.url,t=r.headers;if(e==null)throw new c("HTTP \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5");return{type:"http",url:e||"",headers:t}}a(R,"convertHTTPConfig");function Te(r){let e={},t=[];for(let[o,n]of Object.entries(r))try{e[o]=V(n)}catch(i){t.push({error:i instanceof Error?i:new Error(String(i))})}if(t.length>0){let o=t.map(({error:n},i)=>`[${i}]: ${n.message}`).join("; ");throw new c(`\u6279\u91CF\u914D\u7F6E\u8F6C\u6362\u5931\u8D25: ${o}`)}return e}a(Te,"normalizeServiceConfigBatch");function _(r){return K(r)?!1:!!(r.startsWith("./")||r.startsWith("../")||/\.(js|py|ts|mjs|cjs)$/i.test(r))}a(_,"isRelativePath");function M(r){return"command"in r&&typeof r.command=="string"}a(M,"isLocalConfig");function y(r){try{let t=new URL(r).hostname.toLowerCase();return t.endsWith(".modelscope.net")||t.endsWith(".modelscope.cn")||t==="modelscope.net"||t==="modelscope.cn"}catch{return!1}}a(y,"isModelScopeURL");function te(r){if(r.type&&!Object.values(L).includes(r.type))throw new c(`\u65E0\u6548\u7684\u4F20\u8F93\u7C7B\u578B: ${r.type}`);if(!r.type)throw new c("\u4F20\u8F93\u7C7B\u578B\u672A\u6307\u5B9A\uFF0C\u8BF7\u68C0\u67E5\u914D\u7F6E\u6216\u542F\u7528\u81EA\u52A8\u63A8\u65AD");switch(r.type){case"stdio":if(!r.command)throw new c("STDIO \u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5");break;case"sse":if(r.url===void 0||r.url===null)throw new c("SSE \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5");break;case"http":if(r.url===void 0||r.url===null)throw new c("HTTP \u914D\u7F6E\u5FC5\u987B\u5305\u542B url \u5B57\u6BB5");break;default:throw new c(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${r.type}`)}}a(te,"validateNewConfig");function Ee(r){if(M(r))return`\u672C\u5730\u8FDB\u7A0B (${r.command})`;if("url"in r){if("type"in r&&(r.type==="http"||r.type==="streamable-http"))return`HTTP (${r.url})`;if("type"in r&&r.type==="sse")return`SSE${y(r.url)?" (ModelScope)":""} (${r.url})`;let e=w(r.url),t=y(r.url);return e==="sse"?`SSE${t?" (ModelScope)":""} (${r.url})`:`HTTP (${r.url})`}return"\u672A\u77E5\u7C7B\u578B"}a(Ee,"getConfigTypeDescription");import T from"path";import{mkdirSync as A,existsSync as F,readdirSync as oe,statSync as ne,copyFileSync as re}from"fs";import{dirname as ie,resolve as d}from"path";import{fileURLToPath as se}from"url";var v=ie(se(import.meta.url)),z=class{static{a(this,"ConfigInitializer")}static async initializeDefaultConfig(){let e=process.env.HOME||process.env.USERPROFILE;if(!e)throw new Error("\u65E0\u6CD5\u83B7\u53D6\u7528\u6237\u5BB6\u76EE\u5F55");let t=T.join(e,".xiaozhi-client");if(F(t))return t;A(t,{recursive:!0});let o=this.getDefaultTemplateDir();if(!o)throw new Error("\u9ED8\u8BA4\u914D\u7F6E\u6A21\u677F\u4E0D\u5B58\u5728\uFF0C\u8BF7\u68C0\u67E5\u9879\u76EE\u6A21\u677F\u6587\u4EF6\u662F\u5426\u5B58\u5728");return this.copyDirectoryRecursive(o,t,["template.json",".git","node_modules"]),t}static copyDirectoryRecursive(e,t,o=[]){let n=oe(e);for(let i of n){if(o.includes(i))continue;let s=T.join(e,i),l=T.join(t,i);ne(s).isDirectory()?(A(l,{recursive:!0}),this.copyDirectoryRecursive(s,l,o)):re(s,l)}}static getDefaultTemplateDir(){let e=[d(v,"templates","default"),d(v,"..","templates","default"),d(process.cwd(),"templates","default"),d(v,"..","..","..","templates","default"),d(v,"..","..","..","..","templates","default")];for(let t of e)if(F(t))return t;return null}};export{z as ConfigInitializer,S as ConfigManager,f as ConfigResolver,c as ConfigValidationError,L as MCPTransportType,be as configManager,Ee as getConfigTypeDescription,y as isModelScopeURL,V as normalizeServiceConfig,Te as normalizeServiceConfigBatch};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|