@@ -10,26 +10,43 @@ import com.google.gson.stream.JsonReader
10
10
import com.google.gson.stream.JsonToken
11
11
import com.google.gson.stream.JsonWriter
12
12
13
+ /* *
14
+ * A Gson TypeAdapter for serializing and deserializing the `ChatChoiceChunk`
15
+ * data class to and from JSON. This adapter handles the `delta` field of the
16
+ * `ChatChoiceChunk` class, which can be either a string or an object.
17
+ */
13
18
class ChatChoiceChunkAdapter : TypeAdapter <ChatChoiceChunk ?>() {
14
19
20
+ /* *
21
+ * Serializes a `ChatChoiceChunk` object to JSON.
22
+ * If the provided value is null, it is serialized to a JSON null value.
23
+ *
24
+ * @param writer The JsonWriter to which the value should be written.
25
+ * @param value The value to be serialized.
26
+ */
15
27
override fun write (writer : JsonWriter , value : ChatChoiceChunk ? ) {
16
- if (value == null ) {
28
+ writer.beginObject()
29
+ writer.name(" index" ).value(value!! .index)
30
+ writer.name(" message" ).jsonValue(GsonBuilder ().create().toJson(value.message))
31
+ writer.name(" delta" ).value(value.delta)
32
+ writer.name(" finish_reason" )
33
+
34
+ // in general, it is bad practice to save a message in progress (but yes... you can do it)
35
+ if (value.finishReason == null ) {
17
36
writer.nullValue()
18
37
} else {
19
- writer.beginObject()
20
- writer.name(" index" ).value(value.index)
21
- writer.name(" message" ).jsonValue(GsonBuilder ().create().toJson(value.message))
22
- writer.name(" delta" ).value(value.delta)
23
- writer.name(" finish_reason" )
24
- if (value.finishReason == null ) {
25
- writer.nullValue()
26
- } else {
27
- writer.value(value.finishReason!! .name.lowercase())
28
- }
29
- writer.endObject()
38
+ writer.value(value.finishReason!! .name.lowercase())
30
39
}
40
+ writer.endObject()
31
41
}
32
42
43
+ /* *
44
+ * Deserializes a JSON string to a `ChatChoiceChunk` object.
45
+ *
46
+ * @param reader The JsonReader from which the value should be read.
47
+ * @return The deserialized `ChatChoiceChunk` object, or null if the JSON value is null.
48
+ * @throws IllegalArgumentException if the provided string cannot be parsed to a valid `ChatChoiceChunk` object.
49
+ */
33
50
override fun read (reader : JsonReader ): ChatChoiceChunk ? {
34
51
var index: Int = - 1
35
52
var message: ChatMessage ? = null
@@ -47,6 +64,8 @@ class ChatChoiceChunkAdapter : TypeAdapter<ChatChoiceChunk?>() {
47
64
}
48
65
}
49
66
" delta" -> {
67
+ // delta -> map when returned from OpenAI (we can ignore it since we use #update(json)).
68
+ // delta -> string when we store it as json.
50
69
when (reader.peek()) {
51
70
JsonToken .BEGIN_OBJECT -> reader.skipValue()
52
71
else -> delta = reader.nextString()
@@ -63,6 +82,9 @@ class ChatChoiceChunkAdapter : TypeAdapter<ChatChoiceChunk?>() {
63
82
}
64
83
reader.endObject()
65
84
85
+ // when message == null, that means that a message has not been
86
+ // provided yet. This means it is the first json message from OpenAI.
87
+ // In this case, ChatUser is always assistant.
66
88
return ChatChoiceChunk (index, message ? : ChatMessage (ChatUser .ASSISTANT , " " ), delta ? : " " , finishReason)
67
89
}
68
90
}
0 commit comments