diff --git a/lib/openclaw-provider.js b/lib/openclaw-provider.js index f4ca00d..511e652 100644 --- a/lib/openclaw-provider.js +++ b/lib/openclaw-provider.js @@ -5,6 +5,7 @@ const path = require('path'); const http = require('http'); const https = require('https'); const crypto = require('crypto'); +const { exec } = require('child_process'); const log = require('./logger'); const { resolveOpenclawConfigFile } = require('./frpc'); @@ -83,6 +84,23 @@ function writeJsonFile(filePath, obj) { fs.writeFileSync(filePath, `${JSON.stringify(obj, null, 2)}\n`, 'utf8'); } +/** + * 终止 openclaw-gateway 进程,由 systemd --user 自动重新拉起以读取新配置。 + * 每次写盘 openclaw.json 成功后应调用一次。 + * 使用异步 exec,不阻塞 Node.js 事件循环,避免干扰 LED / VFD 等后续操作。 + */ +function restartGateway() { + exec('pkill -9 -x openclaw-gateway', (err) => { + if (err && err.code !== 1) { + log.warn('openclaw-provider', `restartGateway: ${err.message}`); + } else if (!err) { + log.info('openclaw-provider', 'openclaw-gateway 已终止,等待自动重启'); + } else { + log.info('openclaw-provider', 'openclaw-gateway 进程不存在,无需终止'); + } + }); +} + /** * 同步:从 openclaw.json 删除指定 provider(解绑)。 * 若 primary 指向该 provider,先置为空串。 @@ -126,6 +144,7 @@ function removeProviderByName(providerId) { } writeJsonFile(configFile, config); + restartGateway(); log.info('openclaw-provider', `provider 已移除: ${providerId}`); } @@ -252,6 +271,7 @@ function addProviderSync(configFile, providerId, baseUrl, apiKey, models, defaul ensureWebSearchConfig(configFile, config); writeJsonFile(configFile, config); + restartGateway(); log.info('openclaw-provider', `provider 已写入: ${providerId}(${models.length} 个模型)`); } @@ -300,6 +320,7 @@ function applyFullProviderFromVps(provider, onDone) { // provider 无变化,但仍检查 web search 配置 if (ensureWebSearchConfig(configFile, existing)) { writeJsonFile(configFile, existing); + restartGateway(); log.info('openclaw-provider', 'web search config applied (provider unchanged)'); } else { log.info('openclaw-provider', `provider 无变化(apiKey + 模型列表相同),跳过写盘`); @@ -375,6 +396,7 @@ function refreshModelsIfChanged(onDone) { try { if (ensureWebSearchConfig(configFile, config)) { writeJsonFile(configFile, config); + restartGateway(); log.info('openclaw-provider', 'web search config applied (no provider)'); } } catch (_) {} @@ -405,6 +427,7 @@ function refreshModelsIfChanged(onDone) { const cfg = readJsonFile(configFile); if (ensureWebSearchConfig(configFile, cfg)) { writeJsonFile(configFile, cfg); + restartGateway(); log.info('openclaw-provider', 'web search config repaired'); } else { log.info('openclaw-provider', `模型列表未变化(${newModels.length} 个),跳过更新`); diff --git a/package.json b/package.json index c05dd49..02c4fce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clawd", - "version": "1.3.6", + "version": "1.3.7", "description": "Claw Box daemon - connects local Linux box to claw.cutos.ai via WebSocket", "main": "lib/client.js", "bin": {