diff --git a/apps/shared/ClawdbotKit/Sources/ClawdbotKit/GatewayChannel.swift b/apps/shared/ClawdbotKit/Sources/ClawdbotKit/GatewayChannel.swift index db2ffa36d..8ac3256f5 100644 --- a/apps/shared/ClawdbotKit/Sources/ClawdbotKit/GatewayChannel.swift +++ b/apps/shared/ClawdbotKit/Sources/ClawdbotKit/GatewayChannel.swift @@ -643,6 +643,52 @@ public actor GatewayChannelActor { return Data() // Should not happen, but tolerate empty payloads. } + public func send(method: String, params: [String: AnyCodable]?) async throws { + do { + try await self.connect() + } catch { + throw self.wrap(error, context: "gateway connect") + } + let id = UUID().uuidString + let paramsObject: ProtoAnyCodable? = params.map { entries in + let dict = entries.reduce(into: [String: ProtoAnyCodable]()) { dict, entry in + dict[entry.key] = ProtoAnyCodable(entry.value.value) + } + return ProtoAnyCodable(dict) + } + let frame = RequestFrame( + type: "req", + id: id, + method: method, + params: paramsObject) + let data: Data + do { + data = try self.encoder.encode(frame) + } catch { + self.logger.error( + "gateway send encode failed \(method, privacy: .public) error=\(error.localizedDescription, privacy: .public)") + throw error + } + guard let task = self.task else { + throw NSError( + domain: "Gateway", + code: 5, + userInfo: [NSLocalizedDescriptionKey: "gateway socket unavailable"]) + } + do { + try await task.send(.data(data)) + } catch { + let wrapped = self.wrap(error, context: "gateway send \(method)") + self.connected = false + self.task?.cancel(with: .goingAway, reason: nil) + Task { [weak self] in + guard let self else { return } + await self.scheduleReconnect() + } + throw wrapped + } + } + // Wrap low-level URLSession/WebSocket errors with context so UI can surface them. private func wrap(_ error: Error, context: String) -> Error { if let urlError = error as? URLError { diff --git a/apps/shared/ClawdbotKit/Sources/ClawdbotKit/GatewayNodeSession.swift b/apps/shared/ClawdbotKit/Sources/ClawdbotKit/GatewayNodeSession.swift index a2ac2ad6d..122231f02 100644 --- a/apps/shared/ClawdbotKit/Sources/ClawdbotKit/GatewayNodeSession.swift +++ b/apps/shared/ClawdbotKit/Sources/ClawdbotKit/GatewayNodeSession.swift @@ -143,7 +143,7 @@ public actor GatewayNodeSession { "payloadJSON": AnyCodable(payloadJSON ?? NSNull()), ] do { - _ = try await channel.request(method: "node.event", params: params, timeoutMs: 8000) + try await channel.send(method: "node.event", params: params) } catch { self.logger.error("node event failed: \(error.localizedDescription, privacy: .public)") } @@ -224,7 +224,7 @@ public actor GatewayNodeSession { ]) } do { - _ = try await channel.request(method: "node.invoke.result", params: params, timeoutMs: 15000) + try await channel.send(method: "node.invoke.result", params: params) } catch { self.logger.error("node invoke result failed: \(error.localizedDescription, privacy: .public)") }