@@ -10,8 +10,8 @@ use serde::{Deserialize, Serialize};
10
10
use anyhow:: { Result , anyhow} ;
11
11
use assistant_context_editor:: {
12
12
AgentPanelDelegate , AssistantContext , ConfigurationError , ContextEditor , ContextEvent ,
13
- SlashCommandCompletionProvider , humanize_token_count , make_lsp_adapter_delegate ,
14
- render_remaining_tokens,
13
+ ContextSummary , SlashCommandCompletionProvider , humanize_token_count ,
14
+ make_lsp_adapter_delegate , render_remaining_tokens,
15
15
} ;
16
16
use assistant_settings:: { AssistantDockPosition , AssistantSettings } ;
17
17
use assistant_slash_command:: SlashCommandWorkingSet ;
@@ -59,7 +59,7 @@ use crate::agent_configuration::{AgentConfiguration, AssistantConfigurationEvent
59
59
use crate :: agent_diff:: AgentDiff ;
60
60
use crate :: history_store:: { HistoryStore , RecentEntry } ;
61
61
use crate :: message_editor:: { MessageEditor , MessageEditorEvent } ;
62
- use crate :: thread:: { Thread , ThreadError , ThreadId , TokenUsageRatio } ;
62
+ use crate :: thread:: { Thread , ThreadError , ThreadId , ThreadSummary , TokenUsageRatio } ;
63
63
use crate :: thread_history:: { HistoryEntryElement , ThreadHistory } ;
64
64
use crate :: thread_store:: ThreadStore ;
65
65
use crate :: ui:: AgentOnboardingModal ;
@@ -196,7 +196,7 @@ impl ActiveView {
196
196
}
197
197
198
198
pub fn thread ( thread : Entity < Thread > , window : & mut Window , cx : & mut App ) -> Self {
199
- let summary = thread. read ( cx) . summary_or_default ( ) ;
199
+ let summary = thread. read ( cx) . summary ( ) . or_default ( ) ;
200
200
201
201
let editor = cx. new ( |cx| {
202
202
let mut editor = Editor :: single_line ( window, cx) ;
@@ -218,7 +218,7 @@ impl ActiveView {
218
218
}
219
219
EditorEvent :: Blurred => {
220
220
if editor. read( cx) . text( cx) . is_empty( ) {
221
- let summary = thread. read( cx) . summary_or_default ( ) ;
221
+ let summary = thread. read( cx) . summary ( ) . or_default ( ) ;
222
222
223
223
editor. update( cx, |editor, cx| {
224
224
editor. set_text( summary, window, cx) ;
@@ -233,7 +233,7 @@ impl ActiveView {
233
233
let editor = editor. clone( ) ;
234
234
move |thread, event, window, cx| match event {
235
235
ThreadEvent :: SummaryGenerated => {
236
- let summary = thread. read( cx) . summary_or_default ( ) ;
236
+ let summary = thread. read( cx) . summary ( ) . or_default ( ) ;
237
237
238
238
editor. update( cx, |editor, cx| {
239
239
editor. set_text( summary, window, cx) ;
@@ -296,7 +296,8 @@ impl ActiveView {
296
296
. read( cx)
297
297
. context( )
298
298
. read( cx)
299
- . summary_or_default( ) ;
299
+ . summary( )
300
+ . or_default( ) ;
300
301
301
302
editor. update( cx, |editor, cx| {
302
303
editor. set_text( summary, window, cx) ;
@@ -311,7 +312,7 @@ impl ActiveView {
311
312
let editor = editor. clone( ) ;
312
313
move |assistant_context, event, window, cx| match event {
313
314
ContextEvent :: SummaryGenerated => {
314
- let summary = assistant_context. read( cx) . summary_or_default ( ) ;
315
+ let summary = assistant_context. read( cx) . summary ( ) . or_default ( ) ;
315
316
316
317
editor. update( cx, |editor, cx| {
317
318
editor. set_text( summary, window, cx) ;
@@ -1452,38 +1453,59 @@ impl AgentPanel {
1452
1453
..
1453
1454
} => {
1454
1455
let active_thread = self . thread . read ( cx) ;
1455
- let is_empty = active_thread. is_empty ( ) ;
1456
-
1457
- let summary = active_thread. summary ( cx) ;
1456
+ let state = if active_thread. is_empty ( ) {
1457
+ & ThreadSummary :: Pending
1458
+ } else {
1459
+ active_thread. summary ( cx)
1460
+ } ;
1458
1461
1459
- if is_empty {
1460
- Label :: new ( Thread :: DEFAULT_SUMMARY . clone ( ) )
1462
+ match state {
1463
+ ThreadSummary :: Pending => Label :: new ( ThreadSummary :: DEFAULT . clone ( ) )
1461
1464
. truncate ( )
1462
- . into_any_element ( )
1463
- } else if summary. is_none ( ) {
1464
- Label :: new ( LOADING_SUMMARY_PLACEHOLDER )
1465
+ . into_any_element ( ) ,
1466
+ ThreadSummary :: Generating => Label :: new ( LOADING_SUMMARY_PLACEHOLDER )
1465
1467
. truncate ( )
1466
- . into_any_element ( )
1467
- } else {
1468
- div ( )
1468
+ . into_any_element ( ) ,
1469
+ ThreadSummary :: Ready ( _) => div ( )
1469
1470
. w_full ( )
1470
1471
. child ( change_title_editor. clone ( ) )
1471
- . into_any_element ( )
1472
+ . into_any_element ( ) ,
1473
+ ThreadSummary :: Error => h_flex ( )
1474
+ . w_full ( )
1475
+ . child ( change_title_editor. clone ( ) )
1476
+ . child (
1477
+ ui:: IconButton :: new ( "retry-summary-generation" , IconName :: RotateCcw )
1478
+ . on_click ( {
1479
+ let active_thread = self . thread . clone ( ) ;
1480
+ move |_, _window, cx| {
1481
+ active_thread. update ( cx, |thread, cx| {
1482
+ thread. regenerate_summary ( cx) ;
1483
+ } ) ;
1484
+ }
1485
+ } )
1486
+ . tooltip ( move |_window, cx| {
1487
+ cx. new ( |_| {
1488
+ Tooltip :: new ( "Failed to generate title" )
1489
+ . meta ( "Click to try again" )
1490
+ } )
1491
+ . into ( )
1492
+ } ) ,
1493
+ )
1494
+ . into_any_element ( ) ,
1472
1495
}
1473
1496
}
1474
1497
ActiveView :: PromptEditor {
1475
1498
title_editor,
1476
1499
context_editor,
1477
1500
..
1478
1501
} => {
1479
- let context_editor = context_editor. read ( cx) ;
1480
- let summary = context_editor. context ( ) . read ( cx) . summary ( ) ;
1502
+ let summary = context_editor. read ( cx) . context ( ) . read ( cx) . summary ( ) ;
1481
1503
1482
1504
match summary {
1483
- None => Label :: new ( AssistantContext :: DEFAULT_SUMMARY . clone ( ) )
1505
+ ContextSummary :: Pending => Label :: new ( ContextSummary :: DEFAULT )
1484
1506
. truncate ( )
1485
1507
. into_any_element ( ) ,
1486
- Some ( summary) => {
1508
+ ContextSummary :: Content ( summary) => {
1487
1509
if summary. done {
1488
1510
div ( )
1489
1511
. w_full ( )
@@ -1495,6 +1517,28 @@ impl AgentPanel {
1495
1517
. into_any_element ( )
1496
1518
}
1497
1519
}
1520
+ ContextSummary :: Error => h_flex ( )
1521
+ . w_full ( )
1522
+ . child ( title_editor. clone ( ) )
1523
+ . child (
1524
+ ui:: IconButton :: new ( "retry-summary-generation" , IconName :: RotateCcw )
1525
+ . on_click ( {
1526
+ let context_editor = context_editor. clone ( ) ;
1527
+ move |_, _window, cx| {
1528
+ context_editor. update ( cx, |context_editor, cx| {
1529
+ context_editor. regenerate_summary ( cx) ;
1530
+ } ) ;
1531
+ }
1532
+ } )
1533
+ . tooltip ( move |_window, cx| {
1534
+ cx. new ( |_| {
1535
+ Tooltip :: new ( "Failed to generate title" )
1536
+ . meta ( "Click to try again" )
1537
+ } )
1538
+ . into ( )
1539
+ } ) ,
1540
+ )
1541
+ . into_any_element ( ) ,
1498
1542
}
1499
1543
}
1500
1544
ActiveView :: History => Label :: new ( "History" ) . truncate ( ) . into_any_element ( ) ,
0 commit comments