Avoid repeated OpenClaw pairing fallback loops

This commit is contained in:
Haitao Pan 2026-03-12 19:52:13 +08:00
parent 15e98eb29e
commit 4a87f17564

View File

@ -161,6 +161,20 @@ export class OpenClawGatewayClient {
clientMode?: string
clientLabel?: string
}): Promise<{ mainSessionKey: string; deviceId: string }> {
return this.connectWithRetry(params, true)
}
private async connectWithRetry(
params: {
gatewayUrl: string
gatewayOrigin?: string
gatewayToken: string
clientId?: string
clientMode?: string
clientLabel?: string
},
allowSharedTokenFallback: boolean,
): Promise<{ mainSessionKey: string; deviceId: string }> {
const url = resolveGatewayUrl(params.gatewayUrl)
const origin = params.gatewayOrigin?.trim()
const socket = new WebSocket(url, {
@ -204,8 +218,8 @@ export class OpenClawGatewayClient {
role: 'operator',
})
const sharedGatewayToken = params.gatewayToken.trim()
const authToken = sharedGatewayToken || storedDeviceToken
const authDeviceToken = storedDeviceToken
const usingDeviceToken = Boolean(storedDeviceToken)
const authToken = usingDeviceToken ? storedDeviceToken : sharedGatewayToken
try {
const nonce = await this.waitForConnectChallenge(socket)
@ -245,11 +259,10 @@ export class OpenClawGatewayClient {
caps: ['tool-events'],
commands: [],
permissions: {},
...((authToken || authDeviceToken)
...(authToken
? {
auth: {
...(authToken ? { token: authToken } : {}),
...(authDeviceToken ? { deviceToken: authDeviceToken } : {}),
...(usingDeviceToken ? { deviceToken: authToken } : { token: authToken }),
},
}
: {}),
@ -287,13 +300,28 @@ export class OpenClawGatewayClient {
const gatewayError = error instanceof OpenClawGatewayError ? error : null
const detailCode = stringValue(asRecord(gatewayError?.details).code)
if (detailCode === 'AUTH_DEVICE_TOKEN_MISMATCH' && !sharedGatewayToken && authDeviceToken) {
if (storedDeviceToken && detailCode === 'AUTH_DEVICE_TOKEN_MISMATCH') {
await clearOpenClawDeviceToken({
deviceId: identity.deviceId,
role: 'operator',
})
}
const shouldRetryWithSharedToken =
allowSharedTokenFallback &&
Boolean(sharedGatewayToken) &&
Boolean(storedDeviceToken) &&
(detailCode === 'AUTH_DEVICE_TOKEN_MISMATCH' || detailCode === 'PAIRING_REQUIRED')
if (shouldRetryWithSharedToken) {
await clearOpenClawDeviceToken({
deviceId: identity.deviceId,
role: 'operator',
})
await this.close()
return this.connectWithRetry(params, false)
}
throw error
}
}