|
12 | 12 | import jakarta.ws.rs.Consumes; |
13 | 13 | import jakarta.ws.rs.POST; |
14 | 14 | import jakarta.ws.rs.Path; |
| 15 | +import jakarta.ws.rs.ProcessingException; |
15 | 16 | import jakarta.ws.rs.Produces; |
16 | 17 | import jakarta.ws.rs.WebApplicationException; |
17 | 18 | import jakarta.ws.rs.client.ClientRequestContext; |
@@ -85,40 +86,43 @@ class OllamaRestApiReaderInterceptor implements ReaderInterceptor { |
85 | 86 | public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException { |
86 | 87 | try { |
87 | 88 | return context.proceed(); |
88 | | - } catch (ClientWebApplicationException e) { |
89 | | - Throwable cause = e.getCause(); |
90 | | - if ((cause instanceof JsonParseException) || (cause instanceof MismatchedInputException)) { |
91 | | - if (e.getResponse().getStatus() == 200) { |
92 | | - Object invokedMethod = context.getProperty("org.eclipse.microprofile.rest.client.invokedMethod"); |
93 | | - if ((invokedMethod != null) && invokedMethod.toString().contains("OllamaRestApi.streamingChat")) { |
94 | | - InputStream is = context.getInputStream(); |
95 | | - if (is instanceof ByteArrayInputStream bis) { |
96 | | - bis.reset(); |
97 | | - String chunk = new String(bis.readAllBytes()); |
98 | | - final var ctx = Vertx.currentContext(); |
99 | | - if (ctx == null) { |
100 | | - throw e; |
101 | | - } |
| 89 | + } catch (ClientWebApplicationException | ProcessingException e) { |
| 90 | + // Depending on the Quarkus version MismatchedInputException could be wrapped in ProcessingException |
| 91 | + // or in WebApplicationException with Status 400. |
| 92 | + if ((e instanceof ProcessingException pe && pe.getCause() instanceof MismatchedInputException) || |
| 93 | + (e instanceof WebApplicationException wae |
| 94 | + && ((wae.getCause() instanceof JsonParseException && wae.getResponse().getStatus() == 200) || |
| 95 | + (wae.getCause() instanceof MismatchedInputException |
| 96 | + && wae.getResponse().getStatus() == 400)))) { |
| 97 | + Object invokedMethod = context.getProperty("org.eclipse.microprofile.rest.client.invokedMethod"); |
| 98 | + if ((invokedMethod != null) && invokedMethod.toString().contains("OllamaRestApi.streamingChat")) { |
| 99 | + InputStream is = context.getInputStream(); |
| 100 | + if (is instanceof ByteArrayInputStream bis) { |
| 101 | + bis.reset(); |
| 102 | + String chunk = new String(bis.readAllBytes()); |
| 103 | + final var ctx = Vertx.currentContext(); |
| 104 | + if (ctx == null) { |
| 105 | + throw e; |
| 106 | + } |
102 | 107 |
|
103 | | - // This piece of code deals with is the case where a message from Ollama is not received as an entire line |
104 | | - // but in pieces (my guess is that it is a Vertx bug). |
105 | | - // There is nothing we can do in this case except for returning empty responses and in the meantime buffer the pieces |
106 | | - // by storing them in the Vertx Duplicated Context |
107 | | - String existingBuffer = ctx.getLocal("buffer"); |
108 | | - if ((existingBuffer != null) && !existingBuffer.isEmpty()) { |
109 | | - if (chunk.endsWith("}")) { |
110 | | - ctx.putLocal("buffer", ""); |
111 | | - String entireLine = existingBuffer + chunk; |
112 | | - return QuarkusJsonCodecFactory.SnakeCaseObjectMapperHolder.MAPPER.readValue(entireLine, |
113 | | - ChatResponse.class); |
114 | | - } else { |
115 | | - ctx.putLocal("buffer", existingBuffer + chunk); |
116 | | - return ChatResponse.emptyNotDone(); |
117 | | - } |
| 108 | + // This piece of code deals with is the case where a message from Ollama is not received as an entire line |
| 109 | + // but in pieces (my guess is that it is a Vertx bug). |
| 110 | + // There is nothing we can do in this case except for returning empty responses and in the meantime buffer the pieces |
| 111 | + // by storing them in the Vertx Duplicated Context |
| 112 | + String existingBuffer = ctx.getLocal("buffer"); |
| 113 | + if ((existingBuffer != null) && !existingBuffer.isEmpty()) { |
| 114 | + if (chunk.endsWith("}")) { |
| 115 | + ctx.putLocal("buffer", ""); |
| 116 | + String entireLine = existingBuffer + chunk; |
| 117 | + return QuarkusJsonCodecFactory.SnakeCaseObjectMapperHolder.MAPPER.readValue(entireLine, |
| 118 | + ChatResponse.class); |
118 | 119 | } else { |
119 | | - ctx.putLocal("buffer", chunk); |
| 120 | + ctx.putLocal("buffer", existingBuffer + chunk); |
120 | 121 | return ChatResponse.emptyNotDone(); |
121 | 122 | } |
| 123 | + } else { |
| 124 | + ctx.putLocal("buffer", chunk); |
| 125 | + return ChatResponse.emptyNotDone(); |
122 | 126 | } |
123 | 127 | } |
124 | 128 | } |
|
0 commit comments