@@ -250,7 +250,7 @@ export default () => {
250250 } ) ,
251251 } ) ,
252252 signal : controller . signal ,
253- headers : { authorization : `Bearer ${ localStorage . getItem ( 'apiKey' ) } ` } ,
253+ headers : localStorage . getItem ( 'apiKey' ) ? { authorization : `Bearer ${ localStorage . getItem ( 'apiKey' ) } ` } : { } ,
254254 } )
255255 if ( ! response . ok ) {
256256 const error = await response . json ( )
@@ -266,25 +266,73 @@ export default () => {
266266 const decoder = new TextDecoder ( 'utf-8' )
267267 let done = false
268268
269+ let realValue = ''
270+ let displayValue = ''
271+ let lastTime = Date . now ( )
272+ const intervals = [ 0 ]
273+
274+ const N = 5
275+ const MAX = 500
276+ const FACTOR = 50
277+
278+ const getProperInterval = ( ) => {
279+ const slidingWindowMean = intervals . slice ( - N ) . reduce ( ( a , b ) => a + b , 0 ) / Math . min ( intervals . length , N )
280+ return Math . min ( slidingWindowMean , MAX / ( realValue . length - displayValue . length ) )
281+ }
282+
283+ const update = async ( ) => {
284+ if ( ! streaming ( ) ) return fastForward ( )
285+
286+ const distance = realValue . length - displayValue . length
287+ if ( ! done ) {
288+ const num = Math . round ( distance / FACTOR ) || 1
289+ displayValue = realValue . slice ( 0 , displayValue . length + num )
290+ setCurrentAssistantMessage ( displayValue )
291+ //
292+ realValue !== displayValue ? setTimeout ( update , Math . round ( getProperInterval ( ) ) ) : requestAnimationFrame ( update )
293+ }
294+ }
295+
296+ const fastForward = ( ) => {
297+ const distance = realValue . length - displayValue . length
298+ if ( distance ) {
299+ const num = Math . round ( distance / FACTOR ) || 1
300+ displayValue = realValue . slice ( 0 , displayValue . length + num )
301+ setCurrentAssistantMessage ( displayValue )
302+ //
303+ if ( realValue === displayValue ) return archiveCurrentMessage ( )
304+
305+ const interval = Math . floor ( 10 / ( realValue . length - displayValue . length ) )
306+
307+ interval ? setTimeout ( fastForward , interval ) : requestAnimationFrame ( fastForward )
308+ } else {
309+ return archiveCurrentMessage ( )
310+ }
311+ }
312+
313+ update ( )
314+
269315 while ( ! done ) {
270316 const { value, done : readerDone } = await reader . read ( )
271317 if ( value ) {
272318 const char = decoder . decode ( value )
273319 if ( char === '\n' && currentAssistantMessage ( ) . endsWith ( '\n' ) )
274320 continue
275321
276- if ( char )
277- setCurrentAssistantMessage ( currentAssistantMessage ( ) + char )
322+ if ( char ) {
323+ realValue += char
324+ intervals . push ( Date . now ( ) - lastTime )
325+ lastTime = Date . now ( )
326+ }
278327 }
279328 done = readerDone
329+ done && fastForward ( )
280330 }
281331 } catch ( e ) {
282332 console . error ( e )
283333 setStreaming ( false )
284334 setController ( null )
285- return
286335 }
287- archiveCurrentMessage ( )
288336 }
289337
290338 const archiveCurrentMessage = ( ) => {
@@ -317,7 +365,7 @@ export default () => {
317365 const stopStreamFetch = ( ) => {
318366 if ( controller ( ) ) {
319367 controller ( ) ! . abort ( )
320- archiveCurrentMessage ( )
368+ setStreaming ( false )
321369 }
322370 }
323371
0 commit comments