|
19 | 19 | import java.io.IOException; |
20 | 20 | import java.util.List; |
21 | 21 |
|
| 22 | +import static org.hamcrest.Matchers.is; |
| 23 | + |
22 | 24 | public class OpenAiUnifiedStreamingProcessorTests extends ESTestCase { |
23 | 25 |
|
24 | 26 | public void testJsonLiteral() { |
@@ -182,6 +184,73 @@ public void testJsonLiteralCornerCases() { |
182 | 184 | } |
183 | 185 | } |
184 | 186 |
|
| 187 | + public void testJsonNullFunctionName() throws IOException { |
| 188 | + String json = """ |
| 189 | + { |
| 190 | + "object": "chat.completion.chunk", |
| 191 | + "id": "", |
| 192 | + "created": 1746800254, |
| 193 | + "model": "/repository", |
| 194 | + "system_fingerprint": "3.2.3-sha-a1f3ebe", |
| 195 | + "choices": [ |
| 196 | + { |
| 197 | + "index": 0, |
| 198 | + "delta": { |
| 199 | + "role": "assistant", |
| 200 | + "tool_calls": [ |
| 201 | + { |
| 202 | + "index": 0, |
| 203 | + "id": "8f7c27be-6803-48e6-bba4-8cdcbcd2ff9a", |
| 204 | + "type": "function", |
| 205 | + "function": { |
| 206 | + "name": null, |
| 207 | + "arguments": " \\\"" |
| 208 | + } |
| 209 | + } |
| 210 | + ] |
| 211 | + }, |
| 212 | + "logprobs": null, |
| 213 | + "finish_reason": null |
| 214 | + } |
| 215 | + ], |
| 216 | + "usage": null |
| 217 | + } |
| 218 | + """; |
| 219 | + |
| 220 | + try (XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(XContentParserConfiguration.EMPTY, json)) { |
| 221 | + StreamingUnifiedChatCompletionResults.ChatCompletionChunk chunk = OpenAiUnifiedStreamingProcessor.ChatCompletionChunkParser |
| 222 | + .parse(parser); |
| 223 | + |
| 224 | + // Assertions to verify the parsed object |
| 225 | + assertThat(chunk.id(), is("")); |
| 226 | + assertThat(chunk.model(), is("/repository")); |
| 227 | + assertThat(chunk.object(), is("chat.completion.chunk")); |
| 228 | + assertNull(chunk.usage()); |
| 229 | + |
| 230 | + List<StreamingUnifiedChatCompletionResults.ChatCompletionChunk.Choice> choices = chunk.choices(); |
| 231 | + assertThat(choices.size(), is(1)); |
| 232 | + |
| 233 | + // First choice assertions |
| 234 | + StreamingUnifiedChatCompletionResults.ChatCompletionChunk.Choice firstChoice = choices.get(0); |
| 235 | + assertNull(firstChoice.delta().content()); |
| 236 | + assertNull(firstChoice.delta().refusal()); |
| 237 | + assertThat(firstChoice.delta().role(), is("assistant")); |
| 238 | + assertNull(firstChoice.finishReason()); |
| 239 | + assertThat(firstChoice.index(), is(0)); |
| 240 | + |
| 241 | + List<StreamingUnifiedChatCompletionResults.ChatCompletionChunk.Choice.Delta.ToolCall> toolCalls = firstChoice.delta() |
| 242 | + .toolCalls(); |
| 243 | + assertThat(toolCalls.size(), is(1)); |
| 244 | + |
| 245 | + StreamingUnifiedChatCompletionResults.ChatCompletionChunk.Choice.Delta.ToolCall toolCall = toolCalls.get(0); |
| 246 | + assertThat(toolCall.index(), is(0)); |
| 247 | + assertThat(toolCall.id(), is("8f7c27be-6803-48e6-bba4-8cdcbcd2ff9a")); |
| 248 | + assertThat(toolCall.type(), is("function")); |
| 249 | + assertNull(toolCall.function().name()); |
| 250 | + assertThat(toolCall.function().arguments(), is(" \"")); |
| 251 | + } |
| 252 | + } |
| 253 | + |
185 | 254 | public void testOpenAiUnifiedStreamingProcessorParsing() throws IOException { |
186 | 255 | // Generate random values for the JSON fields |
187 | 256 | int toolCallIndex = randomIntBetween(0, 10); |
|
0 commit comments