22
33import com .fasterxml .jackson .core .JsonParser ;
44import com .fasterxml .jackson .databind .DeserializationContext ;
5- import com .fasterxml .jackson .databind .JavaType ;
6- import com .fasterxml .jackson .databind .JsonNode ;
75import com .fasterxml .jackson .databind .ObjectMapper ;
86import com .fasterxml .jackson .databind .deser .std .StdDeserializer ;
97import com .sap .ai .sdk .orchestration .client .model .LLMModuleResult ;
10- import com .sap .ai .sdk .orchestration .client .model .LLMModuleResultStreaming ;
118import com .sap .ai .sdk .orchestration .client .model .LLMModuleResultSynchronous ;
129import java .io .IOException ;
1310import java .io .Serial ;
@@ -28,13 +25,7 @@ class LLMModuleResultDeserializer extends StdDeserializer<LLMModuleResult> {
2825 }
2926
3027 /**
31- * Deserialize the JSON object into one of the subtypes of the base type.
32- *
33- * <ul>
34- * <li>If elements of "choices" array contains "delta", deserialize into {@link
35- * LLMModuleResultStreaming}.
36- * <li>Otherwise, deserialize into {@link LLMModuleResultSynchronous}.
37- * </ul>
28+ * Always deserialize into {@link LLMModuleResultSynchronous} since streaming isn't supported yet.
3829 *
3930 * @param parser The JSON parser.
4031 * @param context The deserialization context.
@@ -46,50 +37,9 @@ class LLMModuleResultDeserializer extends StdDeserializer<LLMModuleResult> {
4637 public LLMModuleResult deserialize (
4738 @ Nonnull final JsonParser parser , @ Nonnull final DeserializationContext context )
4839 throws IOException {
49-
50- // Check if the target type is a concrete class
51- val targetType = context .getContextualType ();
52- if (targetType != null && !LLMModuleResult .class .equals (targetType .getRawClass ())) {
53- return delegateToDefaultDeserializer (parser , context , targetType );
54- }
55-
56- // Custom deserialization logic for LLMModuleResult interface
5740 val mapper = (ObjectMapper ) parser .getCodec ();
5841 val rootNode = mapper .readTree (parser );
59- Class <? extends LLMModuleResult > concreteClass = LLMModuleResultSynchronous .class ;
60-
61- // Inspect the "choices" field
62- val choicesNode = rootNode .get ("choices" );
63- if (choicesNode != null && choicesNode .isArray ()) {
64- val firstChoice = (JsonNode ) choicesNode .get (0 );
65- if (firstChoice != null && firstChoice .has ("delta" )) {
66- concreteClass = LLMModuleResultStreaming .class ;
67- }
68- }
6942
70- // Create a new parser for the root node
71- val rootParser = rootNode .traverse (mapper );
72- rootParser .nextToken (); // Advance to the first token
73-
74- // Use the default deserializer for the concrete class
75- return delegateToDefaultDeserializer (rootParser , context , mapper .constructType (concreteClass ));
76- }
77-
78- /**
79- * Delegate deserialization to the default deserializer for the given concrete type.
80- *
81- * @param parser The JSON parser.
82- * @param context The deserialization context.
83- * @param concreteType The concrete type to deserialize into.
84- * @return The deserialized object.
85- * @throws IOException If an I/O error occurs.
86- */
87- private LLMModuleResult delegateToDefaultDeserializer (
88- @ Nonnull final JsonParser parser ,
89- @ Nonnull final DeserializationContext context ,
90- @ Nonnull final JavaType concreteType )
91- throws IOException {
92- val defaultDeserializer = context .findRootValueDeserializer (concreteType );
93- return (LLMModuleResult ) defaultDeserializer .deserialize (parser , context );
43+ return mapper .readValue (rootNode .toString (), LLMModuleResultSynchronous .class );
9444 }
9545}
0 commit comments