@@ -227,7 +227,7 @@ export default () => {
227227 } ) ,
228228 } ) ,
229229 signal : controller . signal ,
230- headers : { authorization : `Bearer ${ localStorage . getItem ( 'apiKey' ) } ` } ,
230+ headers : localStorage . getItem ( 'apiKey' ) ? { authorization : `Bearer ${ localStorage . getItem ( 'apiKey' ) } ` } : { } ,
231231 } )
232232 if ( ! response . ok ) {
233233 const error = await response . json ( )
@@ -243,25 +243,73 @@ export default () => {
243243 const decoder = new TextDecoder ( 'utf-8' )
244244 let done = false
245245
246+ let realValue = ''
247+ let displayValue = ''
248+ let lastTime = Date . now ( )
249+ const intervals = [ 0 ]
250+
251+ const N = 5
252+ const MAX = 500
253+ const FACTOR = 50
254+
255+ const getProperInterval = ( ) => {
256+ const slidingWindowMean = intervals . slice ( - N ) . reduce ( ( a , b ) => a + b , 0 ) / Math . min ( intervals . length , N )
257+ return Math . min ( slidingWindowMean , MAX / ( realValue . length - displayValue . length ) )
258+ }
259+
260+ const update = async ( ) => {
261+ if ( ! streaming ( ) ) return fastForward ( )
262+
263+ const distance = realValue . length - displayValue . length
264+ if ( ! done ) {
265+ const num = Math . round ( distance / FACTOR ) || 1
266+ displayValue = realValue . slice ( 0 , displayValue . length + num )
267+ setCurrentAssistantMessage ( displayValue )
268+ //
269+ realValue !== displayValue ? setTimeout ( update , Math . round ( getProperInterval ( ) ) ) : requestAnimationFrame ( update )
270+ }
271+ }
272+
273+ const fastForward = ( ) => {
274+ const distance = realValue . length - displayValue . length
275+ if ( distance ) {
276+ const num = Math . round ( distance / FACTOR ) || 1
277+ displayValue = realValue . slice ( 0 , displayValue . length + num )
278+ setCurrentAssistantMessage ( displayValue )
279+ //
280+ if ( realValue === displayValue ) return archiveCurrentMessage ( )
281+
282+ const interval = Math . floor ( 10 / ( realValue . length - displayValue . length ) )
283+
284+ interval ? setTimeout ( fastForward , interval ) : requestAnimationFrame ( fastForward )
285+ } else {
286+ return archiveCurrentMessage ( )
287+ }
288+ }
289+
290+ update ( )
291+
246292 while ( ! done ) {
247293 const { value, done : readerDone } = await reader . read ( )
248294 if ( value ) {
249295 const char = decoder . decode ( value )
250296 if ( char === '\n' && currentAssistantMessage ( ) . endsWith ( '\n' ) )
251297 continue
252298
253- if ( char )
254- setCurrentAssistantMessage ( currentAssistantMessage ( ) + char )
299+ if ( char ) {
300+ realValue += char
301+ intervals . push ( Date . now ( ) - lastTime )
302+ lastTime = Date . now ( )
303+ }
255304 }
256305 done = readerDone
306+ done && fastForward ( )
257307 }
258308 } catch ( e ) {
259309 console . error ( e )
260310 setStreaming ( false )
261311 setController ( null )
262- return
263312 }
264- archiveCurrentMessage ( )
265313 }
266314
267315 const archiveCurrentMessage = ( ) => {
@@ -293,7 +341,7 @@ export default () => {
293341 const stopStreamFetch = ( ) => {
294342 if ( controller ( ) ) {
295343 controller ( ) ! . abort ( )
296- archiveCurrentMessage ( )
344+ setStreaming ( false )
297345 }
298346 }
299347
0 commit comments