























@@ -4,6 +4,8 @@ import OpenClawIPC
44import OpenClawKit
5566actor MacNodeRuntime {
7+private static let maxGatewayPayloadBytes = 25 * 1024 * 1024
8+private static let maxScreenSnapshotRawBytesBeforeBase64 = (maxGatewayPayloadBytes / 4) * 3
79private let cameraCapture = CameraCaptureService()
810private let makeMainActorServices: () async -> any MacNodeRuntimeMainActorServices
911private let browserProxyRequest: @Sendable (String?) async throws -> String
@@ -363,15 +365,55 @@ actor MacNodeRuntime {
363365}
364366365367private func handleScreenSnapshotInvoke(_ req: BridgeInvokeRequest) async throws -> BridgeInvokeResponse {
366-let params = (try? Self.decodeParams(MacNodeScreenSnapshotParams.self, from: req.paramsJSON)) ??
367-MacNodeScreenSnapshotParams()
368+let params: MacNodeScreenSnapshotParams
369+if let paramsJSON = req.paramsJSON {
370+do {
371+ params = try Self.decodeParams(MacNodeScreenSnapshotParams.self, from: paramsJSON)
372+} catch {
373+return Self.errorResponse(
374+ req,
375+ code: .invalidRequest,
376+ message: "INVALID_REQUEST: invalid screen snapshot params")
377+}
378+} else {
379+ params = MacNodeScreenSnapshotParams()
380+}
368381let services = await self.mainActorServices()
369382let capturedAtMs = Int64(Date().timeIntervalSince1970 * 1000)
370-let res = try await services.snapshotScreen(
371- screenIndex: params.screenIndex,
372- maxWidth: params.maxWidth,
373- quality: params.quality,
374- format: params.format)
383+let res: (data: Data, format: OpenClawScreenSnapshotFormat, width: Int, height: Int)
384+do {
385+ res = try await services.snapshotScreen(
386+ screenIndex: params.screenIndex,
387+ maxWidth: params.maxWidth,
388+ quality: params.quality,
389+ format: params.format)
390+} catch let error as ScreenSnapshotService.ScreenSnapshotError {
391+switch error {
392+case .noDisplays:
393+return Self.errorResponse(
394+ req,
395+ code: .invalidRequest,
396+ message: "INVALID_REQUEST: no displays available for screen snapshot")
397+case let .invalidScreenIndex(idx):
398+return Self.errorResponse(
399+ req,
400+ code: .invalidRequest,
401+ message: "INVALID_REQUEST: invalid screen index \(idx)")
402+case .captureFailed, .encodeFailed:
403+return Self.errorResponse(
404+ req,
405+ code: .unavailable,
406+ message: "UNAVAILABLE: screen snapshot failed")
407+}
408+} catch {
409+return Self.errorResponse(
410+ req,
411+ code: .unavailable,
412+ message: "UNAVAILABLE: screen snapshot failed")
413+}
414+if res.data.count > Self.maxScreenSnapshotRawBytesBeforeBase64 {
415+return Self.screenSnapshotPayloadTooLarge(req)
416+}
375417struct ScreenSnapshotPayload: Encodable {
376418var format: String
377419var base64: String
@@ -387,6 +429,13 @@ actor MacNodeRuntime {
387429 height: res.height,
388430 screenIndex: params.screenIndex,
389431 capturedAtMs: capturedAtMs))
432+if try Self.projectedOuterFrameBytes(
433+ forPayloadJSON: payload,
434+ requestId: req.id,
435+ nodeId: req.nodeId) > Self.maxGatewayPayloadBytes
436+{
437+return Self.screenSnapshotPayloadTooLarge(req)
438+}
390439return BridgeInvokeResponse(id: req.id, ok: true, payloadJSON: payload)
391440}
392441@@ -1004,6 +1053,40 @@ extension MacNodeRuntime {
10041053return json
10051054}
100610551056+static func projectedOuterFrameBytes(
1057+ forPayloadJSON payloadJSON: String,
1058+ requestId: String,
1059+ nodeId: String?) throws -> Int
1060+{
1061+struct InvokeResultFrame: Encodable {
1062+let type = "req"
1063+let id = "00000000-0000-0000-0000-000000000000"
1064+let method = "node.invoke.result"
1065+let params: Params
1066+1067+struct Params: Encodable {
1068+let id: String
1069+let nodeId: String
1070+let ok: Bool
1071+let payloadJSON: String
1072+}
1073+}
1074+1075+let frame = InvokeResultFrame(params: InvokeResultFrame.Params(
1076+ id: requestId,
1077+ nodeId: nodeId ?? "",
1078+ ok: true,
1079+ payloadJSON: payloadJSON))
1080+return try JSONEncoder().encode(frame).count
1081+}
1082+1083+private static func screenSnapshotPayloadTooLarge(_ req: BridgeInvokeRequest) -> BridgeInvokeResponse {
1084+self.errorResponse(
1085+ req,
1086+ code: .unavailable,
1087+ message: "UNAVAILABLE: screen snapshot payload too large; reduce maxWidth or use jpeg")
1088+}
1089+10071090private nonisolated static func canvasEnabled() -> Bool {
10081091UserDefaults.standard.object(forKey: canvasEnabledKey) as? Bool ?? true
10091092}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。