@@ -6,7 +6,7 @@ use agent2::HistoryStore;
66use collections:: HashMap ;
77use editor:: { Editor , EditorMode , MinimapVisibility } ;
88use gpui:: {
9- AnyEntity , App , AppContext as _, Entity , EntityId , EventEmitter , Focusable ,
9+ AnyEntity , App , AppContext as _, Entity , EntityId , EventEmitter , Focusable , ScrollHandle ,
1010 TextStyleRefinement , WeakEntity , Window ,
1111} ;
1212use language:: language_settings:: SoftWrap ;
@@ -154,10 +154,22 @@ impl EntryViewState {
154154 } ) ;
155155 }
156156 }
157- AgentThreadEntry :: AssistantMessage ( _) => {
158- if index == self . entries . len ( ) {
159- self . entries . push ( Entry :: empty ( ) )
160- }
157+ AgentThreadEntry :: AssistantMessage ( message) => {
158+ let entry = if let Some ( Entry :: AssistantMessage ( entry) ) =
159+ self . entries . get_mut ( index)
160+ {
161+ entry
162+ } else {
163+ self . set_entry (
164+ index,
165+ Entry :: AssistantMessage ( AssistantMessageEntry :: default ( ) ) ,
166+ ) ;
167+ let Some ( Entry :: AssistantMessage ( entry) ) = self . entries . get_mut ( index) else {
168+ unreachable ! ( )
169+ } ;
170+ entry
171+ } ;
172+ entry. sync ( message) ;
161173 }
162174 } ;
163175 }
@@ -177,7 +189,7 @@ impl EntryViewState {
177189 pub fn settings_changed ( & mut self , cx : & mut App ) {
178190 for entry in self . entries . iter ( ) {
179191 match entry {
180- Entry :: UserMessage { .. } => { }
192+ Entry :: UserMessage { .. } | Entry :: AssistantMessage { .. } => { }
181193 Entry :: Content ( response_views) => {
182194 for view in response_views. values ( ) {
183195 if let Ok ( diff_editor) = view. clone ( ) . downcast :: < Editor > ( ) {
@@ -208,17 +220,37 @@ pub enum ViewEvent {
208220 MessageEditorEvent ( Entity < MessageEditor > , MessageEditorEvent ) ,
209221}
210222
223+ #[ derive( Default , Debug ) ]
224+ pub struct AssistantMessageEntry {
225+ scroll_handles_by_chunk_index : HashMap < usize , ScrollHandle > ,
226+ }
227+
228+ impl AssistantMessageEntry {
229+ pub fn scroll_handle_for_chunk ( & self , ix : usize ) -> Option < ScrollHandle > {
230+ self . scroll_handles_by_chunk_index . get ( & ix) . cloned ( )
231+ }
232+
233+ pub fn sync ( & mut self , message : & acp_thread:: AssistantMessage ) {
234+ if let Some ( acp_thread:: AssistantMessageChunk :: Thought { .. } ) = message. chunks . last ( ) {
235+ let ix = message. chunks . len ( ) - 1 ;
236+ let handle = self . scroll_handles_by_chunk_index . entry ( ix) . or_default ( ) ;
237+ handle. scroll_to_bottom ( ) ;
238+ }
239+ }
240+ }
241+
211242#[ derive( Debug ) ]
212243pub enum Entry {
213244 UserMessage ( Entity < MessageEditor > ) ,
245+ AssistantMessage ( AssistantMessageEntry ) ,
214246 Content ( HashMap < EntityId , AnyEntity > ) ,
215247}
216248
217249impl Entry {
218250 pub fn message_editor ( & self ) -> Option < & Entity < MessageEditor > > {
219251 match self {
220252 Self :: UserMessage ( editor) => Some ( editor) ,
221- Entry :: Content ( _) => None ,
253+ Self :: AssistantMessage ( _ ) | Self :: Content ( _) => None ,
222254 }
223255 }
224256
@@ -239,6 +271,16 @@ impl Entry {
239271 . map ( |entity| entity. downcast :: < TerminalView > ( ) . unwrap ( ) )
240272 }
241273
274+ pub fn scroll_handle_for_assistant_message_chunk (
275+ & self ,
276+ chunk_ix : usize ,
277+ ) -> Option < ScrollHandle > {
278+ match self {
279+ Self :: AssistantMessage ( message) => message. scroll_handle_for_chunk ( chunk_ix) ,
280+ Self :: UserMessage ( _) | Self :: Content ( _) => None ,
281+ }
282+ }
283+
242284 fn content_map ( & self ) -> Option < & HashMap < EntityId , AnyEntity > > {
243285 match self {
244286 Self :: Content ( map) => Some ( map) ,
@@ -254,7 +296,7 @@ impl Entry {
254296 pub fn has_content ( & self ) -> bool {
255297 match self {
256298 Self :: Content ( map) => !map. is_empty ( ) ,
257- Self :: UserMessage ( _) => false ,
299+ Self :: UserMessage ( _) | Self :: AssistantMessage ( _ ) => false ,
258300 }
259301 }
260302}
0 commit comments