fix(bridge): emit empty content delta as heartbeat; preserve user provider fields on reinstall
OpenClaw's LLM idle watchdog (default 120s) fires on lack of *model
progress*, not lack of bytes — an SSE comment frame (": keepalive\n\n")
keeps the TCP socket alive but isn't recognized as progress, so a long
quiet tool-call phase still idles out. When that happens OpenClaw falls
back to re-sending the prior turn's assistant text (pi-embedded:1308
fallbackAnswerText), producing duplicate-Discord-message symptoms.
Heartbeat now emits a real chat.completion.chunk with an empty content
delta every 30s. Clients drop empty deltas; the upstream idle watchdog
should count it as model progress because it's a real event on the
canonical streaming channel.
scripts/install.mjs now spreads the existing provider entry before
overriding script-managed fields, so user-added fields like
timeoutSeconds survive reinstall.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -67,10 +67,15 @@ function install() {
|
||||
// 3. Update openclaw.json
|
||||
const cfg = readConfig();
|
||||
|
||||
// Add provider
|
||||
// Add provider — spread existing first so user-added fields
|
||||
// (e.g. timeoutSeconds, extraHeaders) survive reinstall. Script-managed
|
||||
// fields (baseUrl/apiKey/api/models) are then overridden authoritatively
|
||||
// since they're tied to the constants and model catalog above.
|
||||
cfg.models = cfg.models ?? {};
|
||||
cfg.models.providers = cfg.models.providers ?? {};
|
||||
const existingProvider = cfg.models.providers[PLUGIN_ID] ?? {};
|
||||
cfg.models.providers[PLUGIN_ID] = {
|
||||
...existingProvider,
|
||||
baseUrl: `http://127.0.0.1:${BRIDGE_PORT}/v1`,
|
||||
apiKey: BRIDGE_API_KEY,
|
||||
api: "openai-completions",
|
||||
|
||||
Reference in New Issue
Block a user