Skip to content

Commit 54c610a

Browse files
authored
Merge pull request #31 from Geeks-Zone/fix/openclaw-bridge-ws-fallback
fix(openclaw): evitar fallback HTTP espurio e atrelar WS ao provider ativo
2 parents 28b961a + 5cf9dad commit 54c610a

2 files changed

Lines changed: 50 additions & 13 deletions

File tree

components/chat/chat-page.tsx

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ import { Skeleton } from "@/components/ui/skeleton";
7878

7979
import { apiFetch, apiJson, apiJsonRequest, testProviderCredentials } from "@/lib/api";
8080
import {
81+
isBridgeConnectionError,
8182
loadOpenClawBridgeSessionKey,
8283
OpenClawBridgeClient,
8384
type OpenClawBridgeEvent,
@@ -359,15 +360,11 @@ export function ChatPage() {
359360

360361
const getBridgeClient = useCallback(async () => {
361362
const baseUrl = normalizeGatewayBaseUrl(openclaw.bridgeSettings.baseUrl);
362-
const currentClient = bridgeClientRef.current;
363-
if (!currentClient || currentClient.baseUrl !== baseUrl) {
364-
currentClient?.disconnect();
365-
bridgeClientRef.current = new OpenClawBridgeClient(baseUrl);
366-
}
367-
368-
const client = bridgeClientRef.current;
369-
if (!client) {
370-
throw new Error("Bridge client unavailable.");
363+
let client = bridgeClientRef.current;
364+
if (!client || client.baseUrl !== baseUrl) {
365+
client?.disconnect();
366+
client = new OpenClawBridgeClient(baseUrl);
367+
bridgeClientRef.current = client;
371368
}
372369
await client.connect();
373370
return client;
@@ -418,11 +415,25 @@ export function ChatPage() {
418415
}, []);
419416

420417
useEffect(() => {
418+
const isOpenClawBridgeActive =
419+
selectedProviderId === OPENCLAW_PROVIDER_ID && openclaw.mode === "bridge";
420+
const baseUrl = openclaw.bridgeSettings.baseUrl.trim();
421+
421422
bridgeClientRef.current?.disconnect();
422423
bridgeClientRef.current = null;
423424
bridgeRunRef.current = null;
424425
setBridgeFallbackMode(false);
425-
}, [openclaw.bridgeSettings.baseUrl]);
426+
427+
if (!isOpenClawBridgeActive || !baseUrl) {
428+
return;
429+
}
430+
431+
const client = new OpenClawBridgeClient(normalizeGatewayBaseUrl(baseUrl));
432+
bridgeClientRef.current = client;
433+
void client.connect().catch(() => {
434+
// erros de conexão são reportados no envio/fluxo; aqui apenas garantimos que não propagam
435+
});
436+
}, [selectedProviderId, openclaw.mode, openclaw.bridgeSettings.baseUrl]);
426437

427438
// Smart auto-scroll: scroll to bottom only if user hasn't scrolled up
428439
useEffect(() => {
@@ -1150,6 +1161,9 @@ export function ChatPage() {
11501161
});
11511162
setBridgeFallbackMode(false);
11521163
} catch (bridgeError) {
1164+
if (!isBridgeConnectionError(bridgeError)) {
1165+
throw bridgeError;
1166+
}
11531167
setMessages((current) =>
11541168
current.map((message) =>
11551169
message.id === assistantMessageId

lib/openclaw-bridge-client.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,20 @@ function buildBridgeWebSocketUrl(baseUrl: string): string {
9595
return url.toString();
9696
}
9797

98+
const BRIDGE_CONNECTION_ERROR_MESSAGES = [
99+
"Bridge WS connection failed",
100+
"Bridge WS disconnected",
101+
"Bridge WS connection timed out",
102+
"Bridge WS not connected",
103+
];
104+
105+
export function isBridgeConnectionError(error: unknown): boolean {
106+
if (!(error instanceof Error)) {
107+
return false;
108+
}
109+
return BRIDGE_CONNECTION_ERROR_MESSAGES.some((prefix) => error.message.startsWith(prefix));
110+
}
111+
98112
export function loadOpenClawBridgeSessionKey(conversationId: string): string {
99113
if (typeof window === "undefined" || !conversationId) {
100114
return "";
@@ -291,12 +305,21 @@ export class OpenClawBridgeClient {
291305
}
292306

293307
const pending = this.#pendingRequests.get(requestId);
294-
if (!pending || !pending.types.has(event.type)) {
308+
if (!pending) {
295309
return;
296310
}
297311

298-
this.#pendingRequests.delete(requestId);
299-
pending.resolve(event);
312+
if (pending.types.has(event.type)) {
313+
this.#pendingRequests.delete(requestId);
314+
pending.resolve(event);
315+
return;
316+
}
317+
318+
if (event.type === "run.error") {
319+
this.#pendingRequests.delete(requestId);
320+
const message = "error" in event && event.error ? event.error : "bridge run.error";
321+
pending.reject(new Error(message));
322+
}
300323
}
301324

302325
#failPendingRequests(error: Error) {

0 commit comments

Comments
 (0)