@@ -333,9 +333,10 @@ func (a *App) cmdModel(args []string) tea.Cmd {
333333
334334 return func () tea.Msg {
335335 return tui.CommandResultMsg {
336- Text : tui .SystemMsgStyle .Render (fmt .Sprintf ("Switched to model: %s" , resolved )),
337- NewProvider : a .Session .Provider (),
338- NewModel : a .Session .ModelName (),
336+ Text : tui .SystemMsgStyle .Render (fmt .Sprintf ("Switched to model: %s" , resolved )),
337+ NewProvider : a .Session .Provider (),
338+ NewModel : a .Session .ModelName (),
339+ NewContextWindow : a .Session .Settings ().ContextWindow ,
339340 }
340341 }
341342}
@@ -423,38 +424,19 @@ func (a *App) cmdSettings() tea.Cmd {
423424 if thinking == "" {
424425 thinking = "(unset)"
425426 }
426- apiKey := a .Session .APIKey ()
427- masked := maskKey (apiKey )
428427
429- labelStyle := lipgloss .NewStyle ().Foreground (tui .ColorMuted )
430- valueStyle := lipgloss .NewStyle ().Foreground (tui .ColorSoftText )
431- metaStyle := lipgloss .NewStyle ().Foreground (tui .ColorToken )
432-
433- var sb strings.Builder
434- renderRow := func (label , value string ) {
435- sb .WriteString (labelStyle .Render (fmt .Sprintf ("%-16s" , label )))
436- sb .WriteString (" " )
437- sb .WriteString (valueStyle .Render (value ))
438- sb .WriteString ("\n " )
439- }
440- renderMetaRow := func (label , value string ) {
441- sb .WriteString (labelStyle .Render (fmt .Sprintf ("%-16s" , label )))
442- sb .WriteString (" " )
443- sb .WriteString (metaStyle .Render (value ))
444- sb .WriteString ("\n " )
445- }
446-
447- renderRow ("Provider" , s .Provider )
448- renderRow ("Model" , a .Session .ModelName ())
449- renderRow ("API key" , masked )
450- renderRow ("Base URL" , baseURL )
451- sb .WriteString ("\n " )
452- renderRow ("Thinking" , thinking )
453- renderRow ("Context" , tui .FormatTokens (s .ContextWindow ))
454- renderRow ("Max turns" , fmt .Sprintf ("%d" , s .MaxTurns ))
455- renderMetaRow ("Config" , config .SettingsPath (a .Cwd ))
428+ p := tui .NewInfoPanel ("Settings" )
429+ p .Row ("Provider" , s .Provider )
430+ p .Row ("Model" , a .Session .ModelName ())
431+ p .Row ("API key" , maskKey (a .Session .APIKey ()))
432+ p .Row ("Base URL" , baseURL )
433+ p .Section ("Runtime" )
434+ p .Row ("Thinking" , thinking )
435+ p .Row ("Context" , tui .FormatTokens (s .ContextWindow ))
436+ p .Row ("Max turns" , fmt .Sprintf ("%d" , s .MaxTurns ))
437+ p .Hint ("Config" , config .SettingsPath (a .Cwd ))
456438
457- return tui .SendCommandResult (strings . TrimRight ( sb . String (), " \n " ))
439+ return tui .SendCommandResult (p . Render ( ))
458440}
459441
460442func maskKey (key string ) string {
@@ -1355,133 +1337,106 @@ func formatContextSnapshot(
13551337 lastCompaction agent.CompactionSnapshot ,
13561338 hasCompaction bool ,
13571339) string {
1358- labelStyle := lipgloss .NewStyle ().Foreground (tui .ColorMuted )
1359- valueStyle := lipgloss .NewStyle ().Foreground (tui .ColorSoftText )
1360- metaStyle := lipgloss .NewStyle ().Foreground (tui .ColorToken )
1361- warnStyle := lipgloss .NewStyle ().Foreground (tui .ColorAccent )
1362-
1363- var sb strings.Builder
1364- renderSection := func (title , meta string ) {
1365- if sb .Len () > 0 {
1366- sb .WriteString ("\n " )
1367- }
1368- sb .WriteString (title )
1369- sb .WriteString ("\n " )
1370- if meta != "" {
1371- sb .WriteString (metaStyle .Render (meta ))
1372- sb .WriteString ("\n " )
1373- }
1374- }
1375- renderRow := func (label , value string ) {
1376- sb .WriteString (labelStyle .Render (fmt .Sprintf ("%-20s" , label )))
1377- sb .WriteString (" " )
1378- sb .WriteString (valueStyle .Render (value ))
1379- sb .WriteString ("\n " )
1380- }
1381- renderMetaRow := func (label , value string ) {
1382- sb .WriteString (labelStyle .Render (fmt .Sprintf ("%-20s" , label )))
1383- sb .WriteString (" " )
1384- sb .WriteString (metaStyle .Render (value ))
1385- sb .WriteString ("\n " )
1386- }
1340+ p := tui .NewInfoPanel ("Context" )
13871341
1388- sb . WriteString ( "Context Snapshot \n " )
1389- renderSection ( "Live usage" , " " )
1342+ // Live usage
1343+ p . Section ( "Usage " )
13901344 usage := contextUsage
13911345 if ok && snapshot != nil && snapshot .Usage != nil {
13921346 usage = snapshot .Usage
13931347 }
13941348 if usage != nil {
1395- renderRow ( "Context used " , fmt .Sprintf ("%s (%.1f%%)" , tui .FormatTokens (usage .Tokens ), usage .Percent ))
1396- renderRow ( "Context window " , tui .FormatTokens (usage .ContextWindow ))
1397- renderMetaRow ( "Usage detail " , fmt .Sprintf ("usage=%s, trailing=%s" , tui .FormatTokens (usage .UsageTokens ), tui .FormatTokens (usage .TrailingTokens )))
1349+ p . Row ( "Used " , fmt .Sprintf ("%s (%.1f%%)" , tui .FormatTokens (usage .Tokens ), usage .Percent ))
1350+ p . Row ( "Window " , tui .FormatTokens (usage .ContextWindow ))
1351+ p . Hint ( "Detail " , fmt .Sprintf ("usage=%s, trailing=%s" , tui .FormatTokens (usage .UsageTokens ), tui .FormatTokens (usage .TrailingTokens )))
13981352 } else {
1399- renderMetaRow ( "Context used " , "(unavailable)" )
1353+ p . Hint ( "Used " , "(unavailable)" )
14001354 }
14011355
1402- // Token breakdown by category
1356+ // Token breakdown
14031357 if breakdown .Total > 0 {
1404- renderSection ("Token breakdown" , "Estimated token distribution by category." )
14051358 window := breakdown .ContextWindow
14061359 fmtPct := func (tokens int ) string {
14071360 if window <= 0 {
14081361 return tui .FormatTokens (tokens )
14091362 }
14101363 return fmt .Sprintf ("%s (%.0f%%)" , tui .FormatTokens (tokens ), float64 (tokens )/ float64 (window )* 100 )
14111364 }
1412- renderRow ("User text" , fmtPct (breakdown .UserText ))
1413- renderRow ("Assistant text" , fmtPct (breakdown .AssistantText ))
1414- renderRow ("Tool calls" , fmtPct (breakdown .ToolCalls ))
1415- renderRow ("Tool results" , fmtPct (breakdown .ToolResults ))
1365+ p .Section ("Breakdown" )
1366+ p .Row ("User text" , fmtPct (breakdown .UserText ))
1367+ p .Row ("Assistant text" , fmtPct (breakdown .AssistantText ))
1368+ p .Row ("Tool calls" , fmtPct (breakdown .ToolCalls ))
1369+ p .Row ("Tool results" , fmtPct (breakdown .ToolResults ))
14161370 if breakdown .Summaries > 0 {
1417- renderRow ("Summaries" , fmtPct (breakdown .Summaries ))
1371+ p . Row ("Summaries" , fmtPct (breakdown .Summaries ))
14181372 }
14191373 if breakdown .Images > 0 {
1420- renderRow ("Images" , fmtPct (breakdown .Images ))
1374+ p . Row ("Images" , fmtPct (breakdown .Images ))
14211375 }
14221376
14231377 if len (breakdown .TopTools ) > 0 {
1424- renderSection ("Top tools" , "Heaviest tools by token consumption. " )
1378+ p . Section ("Top tools" )
14251379 for _ , t := range breakdown .TopTools {
1426- detail := fmt .Sprintf ("calls=%s, results=%s" , tui .FormatTokens (t .CallTokens ), tui .FormatTokens (t .ResultTokens ))
1427- renderRow (t .Name , fmt .Sprintf ("%s %s" , fmtPct (t .Total ), metaStyle .Render (detail )))
1380+ p .Row (t .Name , fmt .Sprintf ("%s calls=%s results=%s" , fmtPct (t .Total ), tui .FormatTokens (t .CallTokens ), tui .FormatTokens (t .ResultTokens )))
14281381 }
14291382 }
14301383 }
14311384
1385+ // Composition
14321386 if ok && snapshot != nil {
1433- renderSection ("Composition" , " " )
1434- renderRow ( "Active scope " , formatContextScope (snapshot .Scope ))
1387+ p . Section ("Composition" )
1388+ p . Row ( "Scope " , formatContextScope (snapshot .Scope ))
14351389 if snapshot .TranscriptMessages != snapshot .ActiveMessages {
1436- renderRow ("Messages" , fmt .Sprintf ("%d active / %d transcript" , snapshot .ActiveMessages , snapshot .TranscriptMessages ))
1390+ p . Row ("Messages" , fmt .Sprintf ("%d active / %d transcript" , snapshot .ActiveMessages , snapshot .TranscriptMessages ))
14371391 } else {
1438- renderRow ("Messages" , fmt .Sprintf ("%d" , snapshot .ActiveMessages ))
1392+ p . Row ("Messages" , fmt .Sprintf ("%d" , snapshot .ActiveMessages ))
14391393 }
1440- renderRow ("Summary checkpoints" , fmt .Sprintf ("%d" , snapshot .SummaryMessages ))
1441- renderRow ("Tool result msgs" , fmt .Sprintf ("%d" , snapshot .ToolMessages ))
1442- renderRow ("Cleared results" , fmt .Sprintf ("%d" , snapshot .ClearedToolResults ))
1443- renderRow ("Trimmed blocks" , fmt .Sprintf ("%d" , snapshot .TrimmedTextBlocks ))
1394+ p .Row ("Summaries" , fmt .Sprintf ("%d" , snapshot .SummaryMessages ))
1395+ p .Row ("Cleared results" , fmt .Sprintf ("%d" , snapshot .ClearedToolResults ))
1396+ p .Row ("Trimmed blocks" , fmt .Sprintf ("%d" , snapshot .TrimmedTextBlocks ))
14441397
1445- renderSection ("Last rewrite" , " " )
1398+ p . Section ("Last rewrite" )
14461399 strategy := prettyCompactionStrategy (snapshot .LastStrategy )
14471400 if strategy == "" {
14481401 strategy = "(none)"
14491402 }
1450- renderMetaRow ("Strategy" , strategy )
1451- renderRow ("Changed" , formatBool (snapshot .LastChanged ))
1452- renderMetaRow ("Details" , formatContextRewriteDetails (snapshot ))
1403+ p . Hint ("Strategy" , strategy )
1404+ p . Row ("Changed" , formatBool (snapshot .LastChanged ))
1405+ p . Hint ("Details" , formatContextRewriteDetails (snapshot ))
14531406 } else {
1454- renderSection ("Composition" , " " )
1455- renderMetaRow ("Snapshot" , "(unavailable)" )
1407+ p . Section ("Composition" )
1408+ p . Hint ("Snapshot" , "(unavailable)" )
14561409 }
14571410
1458- renderSection ("Compaction totals" , "" )
1459- renderRow ("Compactions total" , fmt .Sprintf ("%d" , metrics .CompactionTotal ))
1460- renderRow ("Compactions changed" , fmt .Sprintf ("%d" , metrics .CompactionChanged ))
1461- renderRow ("Compaction saved" , tui .FormatTokens (metrics .CompactionSaved ))
1462- renderMetaRow ("By kind" , formatCompactionCounts (metrics .CompactionByKind ))
1463- renderMetaRow ("Last compaction" , formatLastCompaction (lastCompaction , hasCompaction ))
1411+ // Compaction totals
1412+ p .Section ("Compaction" )
1413+ p .Row ("Total" , fmt .Sprintf ("%d" , metrics .CompactionTotal ))
1414+ p .Row ("Changed" , fmt .Sprintf ("%d" , metrics .CompactionChanged ))
1415+ p .Row ("Saved" , tui .FormatTokens (metrics .CompactionSaved ))
1416+ p .Hint ("By kind" , formatCompactionCounts (metrics .CompactionByKind ))
1417+ p .Hint ("Last" , formatLastCompaction (lastCompaction , hasCompaction ))
14641418
14651419 // Suggestions
14661420 if len (suggestions ) > 0 {
1467- renderSection ("Suggestions" , " " )
1421+ p . Section ("Suggestions" )
14681422 for _ , s := range suggestions {
1469- prefix := "i"
1470- style := metaStyle
14711423 if s .Severity == "warning" {
1472- prefix = "!"
1473- style = warnStyle
1474- }
1475- line := fmt .Sprintf ("[%s] %s" , prefix , s .Message )
1476- if s .Savings > 0 {
1477- line += fmt .Sprintf (" (~%s saveable)" , tui .FormatTokens (s .Savings ))
1424+ msg := s .Message
1425+ if s .Savings > 0 {
1426+ msg += fmt .Sprintf (" (~%s saveable)" , tui .FormatTokens (s .Savings ))
1427+ }
1428+ p .Warn ("!" , msg )
1429+ } else {
1430+ msg := s .Message
1431+ if s .Savings > 0 {
1432+ msg += fmt .Sprintf (" (~%s saveable)" , tui .FormatTokens (s .Savings ))
1433+ }
1434+ p .Hint ("i" , msg )
14781435 }
1479- sb .WriteString (style .Render (line ))
1480- sb .WriteString ("\n " )
14811436 }
14821437 }
14831438
1484- return strings . TrimRight ( sb . String (), " \n " )
1439+ return p . Render ( )
14851440}
14861441
14871442func formatRunSummary (summary agentcore.RunSummary , ok bool ) string {
0 commit comments