MCPcopy Create free account
hub / github.com/MemTensor/MemOS / handleSaveConfig

Method handleSaveConfig

packages/memos-core/src/viewer/server.ts:3115–3253  ·  view source on GitHub ↗
(req: http.IncomingMessage, res: http.ServerResponse)

Source from the content-addressed store, hash-verified

3113 }
3114
3115 private handleSaveConfig(req: http.IncomingMessage, res: http.ServerResponse): void {
3116 this.readBody(req, async (body) => {
3117 try {
3118 const newCfg = JSON.parse(body);
3119 const cfgPath = this.getOpenClawConfigPath();
3120 let raw: Record<string, unknown> = {};
3121 if (fs.existsSync(cfgPath)) {
3122 raw = JSON.parse(fs.readFileSync(cfgPath, "utf-8"));
3123 }
3124
3125 if (!raw.plugins) raw.plugins = {};
3126 const plugins = raw.plugins as Record<string, unknown>;
3127 if (!plugins.entries) plugins.entries = {};
3128 const entries = plugins.entries as Record<string, unknown>;
3129 const entryKey = entries["memos-local-openclaw-plugin"] ? "memos-local-openclaw-plugin"
3130 : entries["memos-local"] ? "memos-local"
3131 : entries["memos-lite-openclaw-plugin"] ? "memos-lite-openclaw-plugin"
3132 : entries["memos-lite"] ? "memos-lite"
3133 : "memos-local-openclaw-plugin";
3134 if (!entries[entryKey]) entries[entryKey] = { enabled: true };
3135 const entry = entries[entryKey] as Record<string, unknown>;
3136 if (!entry.config) entry.config = {};
3137 const config = entry.config as Record<string, unknown>;
3138
3139 const oldSharing = config.sharing as Record<string, unknown> | undefined;
3140 const oldSharingRole = oldSharing?.role as string | undefined;
3141 const oldSharingEnabled = Boolean(oldSharing?.enabled);
3142 const oldClientHubAddress = String((oldSharing?.client as Record<string, unknown>)?.hubAddress || "");
3143
3144 if (newCfg.embedding) config.embedding = newCfg.embedding;
3145 if (newCfg.summarizer) config.summarizer = newCfg.summarizer;
3146 if (newCfg.skillEvolution) config.skillEvolution = newCfg.skillEvolution;
3147 if (newCfg.viewerPort) config.viewerPort = newCfg.viewerPort;
3148 if (newCfg.taskAutoFinalizeHours !== undefined) config.taskAutoFinalizeHours = newCfg.taskAutoFinalizeHours;
3149 if (newCfg.telemetry !== undefined) config.telemetry = newCfg.telemetry;
3150 if (newCfg.sharing !== undefined) {
3151 const existing = (config.sharing as Record<string, unknown>) || {};
3152 const merged = { ...existing, ...newCfg.sharing };
3153 if (newCfg.sharing.capabilities && existing.capabilities) {
3154 merged.capabilities = { ...(existing.capabilities as Record<string, unknown>), ...newCfg.sharing.capabilities };
3155 }
3156 if (merged.role === "client" && merged.client) {
3157 const clientCfg = merged.client as Record<string, unknown>;
3158 const addr = String(clientCfg.hubAddress || "");
3159 if (addr && oldSharingRole === "hub" && oldSharingEnabled) {
3160 const selfHubPort = (oldSharing?.hub as Record<string, unknown>)?.port ?? 18800;
3161 const localIPs = this.getLocalIPs();
3162 localIPs.push("127.0.0.1", "localhost", "0.0.0.0");
3163 try {
3164 const u = new URL(addr.startsWith("http") ? addr : `http://${addr}`);
3165 const targetPort = u.port || (u.protocol === "https:" ? "443" : "80");
3166 if (localIPs.includes(u.hostname) && targetPort === String(selfHubPort)) {
3167 res.writeHead(400, { "Content-Type": "application/json" });
3168 res.end(JSON.stringify({ error: "cannot_join_self" }));
3169 return;
3170 }
3171 } catch {}
3172 }

Callers 1

handleRequestMethod · 0.95

Calls 15

readBodyMethod · 0.95
getOpenClawConfigPathMethod · 0.95
getLocalIPsMethod · 0.95
notifyHubShutdownMethod · 0.95
stopHubHeartbeatMethod · 0.95
withdrawOrLeaveHubMethod · 0.95
notifyHubLeaveMethod · 0.95
autoJoinOnSaveMethod · 0.95
jsonResponseMethod · 0.95
normalizeHubUrlFunction · 0.90
endMethod · 0.80

Tested by

no test coverage detected