@@ -17,42 +17,60 @@ function convertBuffersToObjects (chunks) {
17
17
}
18
18
19
19
/**
20
- * Constructs the entire response from a stream of OpenAI completion chunks,
21
- * mainly combining the text choices of each chunk into a single string per choice.
20
+ * Common function for combining chunks with n choices into a single response body.
21
+ * The shared logic will add a new choice index entry if it doesn't exist, and otherwise
22
+ * hand off to a onChoice handler to add that choice to the previously stored choice.
23
+ *
22
24
* @param {Array<Record<string, any>> } chunks
23
- * @param {number } n the number of choices to expect in the response
25
+ * @param {number } n
26
+ * @param {function(Record<string, any>, Record<string, any>): void } onChoice
24
27
* @returns {Record<string, any> }
25
28
*/
26
- function constructCompletionResponseFromStreamedChunks ( chunks , n ) {
29
+ function constructResponseFromStreamedChunks ( chunks , n , onChoice ) {
27
30
const body = { ...chunks [ 0 ] , choices : Array . from ( { length : n } ) }
28
31
29
32
for ( const chunk of chunks ) {
30
33
body . usage = chunk . usage
31
34
for ( const choice of chunk . choices ) {
32
35
const choiceIdx = choice . index
33
36
const oldChoice = body . choices . find ( choice => choice ?. index === choiceIdx )
34
- if ( oldChoice ) {
35
- if ( ! oldChoice . finish_reason ) {
36
- oldChoice . finish_reason = choice . finish_reason
37
- }
38
37
39
- const text = choice . text
40
- if ( text ) {
41
- if ( oldChoice . text ) {
42
- oldChoice . text += text
43
- } else {
44
- oldChoice . text = text
45
- }
46
- }
47
- } else {
38
+ if ( ! oldChoice ) {
48
39
body . choices [ choiceIdx ] = choice
40
+ continue
49
41
}
42
+
43
+ if ( ! oldChoice . finish_reason ) {
44
+ oldChoice . finish_reason = choice . finish_reason
45
+ }
46
+
47
+ onChoice ( choice , oldChoice )
50
48
}
51
49
}
52
50
53
51
return body
54
52
}
55
53
54
+ /**
55
+ * Constructs the entire response from a stream of OpenAI completion chunks,
56
+ * mainly combining the text choices of each chunk into a single string per choice.
57
+ * @param {Array<Record<string, any>> } chunks
58
+ * @param {number } n the number of choices to expect in the response
59
+ * @returns {Record<string, any> }
60
+ */
61
+ function constructCompletionResponseFromStreamedChunks ( chunks , n ) {
62
+ return constructResponseFromStreamedChunks ( chunks , n , ( choice , oldChoice ) => {
63
+ const text = choice . text
64
+ if ( text ) {
65
+ if ( oldChoice . text ) {
66
+ oldChoice . text += text
67
+ } else {
68
+ oldChoice . text = text
69
+ }
70
+ }
71
+ } )
72
+ }
73
+
56
74
/**
57
75
* Constructs the entire response from a stream of OpenAI chat completion chunks,
58
76
* mainly combining the text choices of each chunk into a single string per choice.
@@ -61,49 +79,32 @@ function constructCompletionResponseFromStreamedChunks (chunks, n) {
61
79
* @returns {Record<string, any> }
62
80
*/
63
81
function constructChatCompletionResponseFromStreamedChunks ( chunks , n ) {
64
- const body = { ...chunks [ 0 ] , choices : Array . from ( { length : n } ) }
65
-
66
- for ( const chunk of chunks ) {
67
- body . usage = chunk . usage
68
- for ( const choice of chunk . choices ) {
69
- const choiceIdx = choice . index
70
- const oldChoice = body . choices . find ( choice => choice ?. index === choiceIdx )
71
- if ( oldChoice ) {
72
- if ( ! oldChoice . finish_reason ) {
73
- oldChoice . finish_reason = choice . finish_reason
74
- }
75
-
76
- const delta = choice . delta
77
- if ( ! delta ) continue
82
+ return constructResponseFromStreamedChunks ( chunks , n , ( choice , oldChoice ) => {
83
+ const delta = choice . delta
84
+ if ( ! delta ) return
78
85
79
- const content = delta . content
80
- if ( content ) {
81
- if ( oldChoice . delta . content ) {
82
- oldChoice . delta . content += content
83
- } else {
84
- oldChoice . delta . content = content
85
- }
86
- }
87
-
88
- const tools = choice . delta . tool_calls
89
- if ( ! tools ) continue
90
-
91
- oldChoice . delta . tool_calls = tools . map ( ( newTool , toolIdx ) => {
92
- const oldTool = oldChoice . delta . tool_calls ?. [ toolIdx ]
93
- if ( oldTool ) {
94
- oldTool . function . arguments += newTool . function . arguments
95
- return oldTool
96
- }
97
-
98
- return newTool
99
- } )
86
+ const content = delta . content
87
+ if ( content ) {
88
+ if ( oldChoice . delta . content ) {
89
+ oldChoice . delta . content += content
100
90
} else {
101
- body . choices [ choiceIdx ] = choice
91
+ oldChoice . delta . content = content
102
92
}
103
93
}
104
- }
105
94
106
- return body
95
+ const tools = delta . tool_calls
96
+ if ( ! tools ) return
97
+
98
+ oldChoice . delta . tool_calls = tools . map ( ( newTool , toolIdx ) => {
99
+ const oldTool = oldChoice . delta . tool_calls ?. [ toolIdx ]
100
+ if ( oldTool ) {
101
+ oldTool . function . arguments += newTool . function . arguments
102
+ return oldTool
103
+ }
104
+
105
+ return newTool
106
+ } )
107
+ } )
107
108
}
108
109
109
110
module . exports = {
0 commit comments