@@ -5,14 +5,16 @@ import {
55 ChatMessageRole ,
66 StreamRequestType ,
77 type AssistantChatMessage ,
8+ type ChatMessageContext ,
89 type CompletedStreamResponse ,
910 type ErrorStreamResponse ,
11+ type QueuedMessage ,
1012 type RateLimitedStreamResponse ,
1113} from '@onlook/models/chat' ;
1214import { MainChannels } from '@onlook/models/constants' ;
1315import type { ParsedError } from '@onlook/utility' ;
1416import type { CoreMessage } from 'ai' ;
15- import { makeAutoObservable } from 'mobx' ;
17+ import { makeAutoObservable , runInAction } from 'mobx' ;
1618import { nanoid } from 'nanoid/non-secure' ;
1719import type { EditorEngine } from '..' ;
1820import { ChatCodeManager } from './code' ;
@@ -31,13 +33,17 @@ export class ChatManager {
3133 context : ChatContext ;
3234 stream : StreamResolver ;
3335 suggestions : SuggestionManager ;
36+ messageQueue : QueuedMessage [ ] = [ ] ;
37+ private maxQueueSize = 5 ;
3438
3539 constructor (
3640 private editorEngine : EditorEngine ,
3741 private projectsManager : ProjectsManager ,
3842 private userManager : UserManager ,
3943 ) {
40- makeAutoObservable ( this ) ;
44+ makeAutoObservable ( this , {
45+ messageQueue : true ,
46+ } ) ;
4147 this . context = new ChatContext ( this . editorEngine , this . projectsManager ) ;
4248 this . conversation = new ConversationManager ( this . editorEngine , this . projectsManager ) ;
4349 this . stream = new StreamResolver ( ) ;
@@ -49,14 +55,38 @@ export class ChatManager {
4955 window . dispatchEvent ( new Event ( FOCUS_CHAT_INPUT_EVENT ) ) ;
5056 }
5157
52- async sendNewMessage ( content : string ) : Promise < void > {
58+ get queueSize ( ) : number {
59+ return this . messageQueue . length ;
60+ }
61+
62+ async processMessageQueue ( ) {
63+ if ( this . messageQueue . length === 0 || this . isWaiting ) {
64+ return ;
65+ }
66+ const nextMessage = this . messageQueue . shift ( ) ! ;
67+ await this . processMessage ( nextMessage . content , nextMessage . context ) ;
68+
69+ if ( this . messageQueue . length > 0 ) {
70+ await this . processMessageQueue ( ) ;
71+ }
72+ }
73+
74+ private async processMessage ( content : string , context ?: ChatMessageContext [ ] ) {
5375 if ( ! this . conversation . current ) {
5476 console . error ( 'No conversation found' ) ;
5577 return ;
5678 }
5779
58- const context = await this . context . getChatContext ( ) ;
59- const userMessage = this . conversation . addUserMessage ( content , context ) ;
80+ if ( this . isWaiting ) {
81+ this . messageQueue . push ( { content, context } ) ;
82+ if ( this . messageQueue . length > this . maxQueueSize ) {
83+ this . messageQueue . shift ( ) ;
84+ }
85+ return ;
86+ }
87+
88+ const messageContext = context ?? ( await this . context . getChatContext ( ) ) ;
89+ const userMessage = this . conversation . addUserMessage ( content , messageContext ) ;
6090 this . conversation . current . updateName ( content ) ;
6191 if ( ! userMessage ) {
6292 console . error ( 'Failed to add user message' ) ;
@@ -68,6 +98,29 @@ export class ChatManager {
6898 await this . sendChatToAi ( StreamRequestType . CHAT , content ) ;
6999 }
70100
101+ async sendNewMessage ( content : string ) : Promise < void > {
102+ if ( ! this . conversation . current ) {
103+ console . error ( 'No conversation found' ) ;
104+ return ;
105+ }
106+
107+ if ( this . isWaiting ) {
108+ if ( this . messageQueue . length >= this . maxQueueSize ) {
109+ console . warn ( 'Message queue is full' ) ;
110+ return ;
111+ }
112+ runInAction ( ( ) => {
113+ this . messageQueue . push ( { content } ) ;
114+ } ) ;
115+
116+ console . log ( `Message queued. Queue size: ${ this . messageQueue . length } ` ) ;
117+ return ;
118+ }
119+
120+ await this . processMessage ( content ) ;
121+ this . processMessageQueue ( ) ;
122+ }
123+
71124 async sendFixErrorToAi ( errors : ParsedError [ ] ) : Promise < boolean > {
72125 if ( ! this . conversation . current ) {
73126 console . error ( 'No conversation found' ) ;
@@ -77,6 +130,22 @@ export class ChatManager {
77130 const prompt = `How can I resolve these errors? If you propose a fix, please make it concise.` ;
78131 const errorContexts = this . context . getMessageContext ( errors ) ;
79132 const projectContexts = this . context . getProjectContext ( ) ;
133+
134+ if ( this . isWaiting ) {
135+ if ( this . messageQueue . length >= this . maxQueueSize ) {
136+ console . warn ( 'Message queue is full' ) ;
137+ return false ;
138+ }
139+ runInAction ( ( ) => {
140+ this . messageQueue . push ( {
141+ content : prompt ,
142+ context : [ ...errorContexts , ...projectContexts ] ,
143+ } ) ;
144+ } ) ;
145+ console . log ( `Error-fix message queued. Queue size: ${ this . messageQueue . length } ` ) ;
146+ return true ;
147+ }
148+
80149 const userMessage = this . conversation . addUserMessage ( prompt , [
81150 ...errorContexts ,
82151 ...projectContexts ,
@@ -139,6 +208,10 @@ export class ChatManager {
139208 invokeMainChannel ( MainChannels . SEND_STOP_STREAM_REQUEST , {
140209 requestId,
141210 } ) ;
211+
212+ runInAction ( ( ) => {
213+ this . messageQueue = [ ] ;
214+ } ) ;
142215 sendAnalytics ( 'stop chat stream' ) ;
143216 }
144217
@@ -204,6 +277,8 @@ export class ChatManager {
204277 }
205278
206279 this . context . clearAttachments ( ) ;
280+
281+ await this . processMessageQueue ( ) ;
207282 }
208283
209284 handleNewCoreMessages ( messages : CoreMessage [ ] ) {
0 commit comments