From a628200127dc0ccaba09c20ebac671bdf792debd Mon Sep 17 00:00:00 2001 From: Haitao Pan Date: Fri, 8 May 2026 11:46:47 +0800 Subject: [PATCH] fix: use SSE for OpenClaw task submit --- lib/runtime/gateway_acp_client.dart | 10 +------ .../runtime/gateway_acp_client_auth_test.dart | 30 ++++++++++++------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/lib/runtime/gateway_acp_client.dart b/lib/runtime/gateway_acp_client.dart index 83d2327c..2077f7cf 100644 --- a/lib/runtime/gateway_acp_client.dart +++ b/lib/runtime/gateway_acp_client.dart @@ -572,7 +572,7 @@ class GatewayAcpClient { ); httpRequest.headers.set( HttpHeaders.acceptHeader, - _httpAcceptHeaderFor(endpoint, request.method), + 'text/event-stream, application/json', ); final authorization = await _resolveAuthorizationHeader( endpoint, @@ -1145,14 +1145,6 @@ bool _isOpenClawTaskSubmitMethod(String method) { return normalized == 'session.start' || normalized == 'session.message'; } -String _httpAcceptHeaderFor(Uri endpoint, String method) { - if (_isOpenClawTaskSubmitEndpoint(endpoint) && - _isOpenClawTaskSubmitMethod(method)) { - return 'application/json'; - } - return 'text/event-stream, application/json'; -} - Duration gatewayAcpHttpResponseTimeoutFor(Uri endpoint, String method) { if (_isOpenClawTaskSubmitEndpoint(endpoint) && _isOpenClawTaskSubmitMethod(method)) { diff --git a/test/runtime/gateway_acp_client_auth_test.dart b/test/runtime/gateway_acp_client_auth_test.dart index 29a8eb10..8e07a82c 100644 --- a/test/runtime/gateway_acp_client_auth_test.dart +++ b/test/runtime/gateway_acp_client_auth_test.dart @@ -781,6 +781,7 @@ void main() { 'desktop task execution routes OpenClaw through dedicated bridge gateway path', () async { final capture = await _startAcpHttpServer( + streamResponse: true, result: { 'success': true, 'status': 'completed', @@ -823,7 +824,7 @@ void main() { ); expect(capture.authorizationHeader, 'Bearer bridge-token'); - expect(capture.acceptHeader, 'application/json'); + expect(capture.acceptHeader, 'text/event-stream, application/json'); expect(capture.requestPath, '/gateway/openclaw'); expect(capture.requestPath, isNot(contains('/acp-server'))); expect(capture.requestPath, isNot(contains('/acp-server/gateway'))); @@ -885,7 +886,7 @@ void main() { onUpdate: (_) {}, ); - expect(capture.acceptHeader, 'application/json'); + expect(capture.acceptHeader, 'text/event-stream, application/json'); expect(capture.requestPath, '/gateway/openclaw'); expect(capture.requestBody, contains('"method":"session.message"')); }, @@ -1303,6 +1304,7 @@ GoTaskServiceRequest _taskRequest({ Future<_CapturedAcpHttpServer> _startAcpHttpServer({ Map result = const {'ok': true}, + bool streamResponse = false, }) async { final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0); final capture = _CapturedAcpHttpServer._( @@ -1319,14 +1321,22 @@ Future<_CapturedAcpHttpServer> _startAcpHttpServer({ capture.requestBody = body; capture.requestBodies.add(body); final id = _decodeRequestId(body); - request.response.headers.contentType = ContentType.json; - request.response.write( - jsonEncode({ - 'jsonrpc': '2.0', - 'id': id, - 'result': result, - }), - ); + final envelope = jsonEncode({ + 'jsonrpc': '2.0', + 'id': id, + 'result': result, + }); + if (streamResponse) { + request.response.headers.set( + HttpHeaders.contentTypeHeader, + 'text/event-stream', + ); + request.response.write('data: $envelope\n\n'); + request.response.write('data: [DONE]\n\n'); + } else { + request.response.headers.contentType = ContentType.json; + request.response.write(envelope); + } await request.response.close(); }); return capture;