Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions pkg/session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,17 @@ func (s *Session) IsSubSession() bool {
return s.ParentID != ""
}

// MessageCount returns the number of items that contain a message.
func (s *Session) MessageCount() int {
n := 0
for _, item := range s.Messages {
if item.IsMessage() {
n++
}
}
return n
}

// New creates a new agent session
func New(opts ...Opt) *Session {
sessionID := uuid.New().String()
Expand Down
12 changes: 10 additions & 2 deletions pkg/session/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ type Summary struct {
CreatedAt time.Time
Starred bool
BranchParentSessionID string
NumMessages int
}

// Store defines the interface for session storage
Expand Down Expand Up @@ -164,6 +165,7 @@ func (s *InMemorySessionStore) GetSessionSummaries(_ context.Context) ([]Summary
CreatedAt: value.CreatedAt,
Starred: value.Starred,
BranchParentSessionID: value.BranchParentSessionID,
NumMessages: value.MessageCount(),
})
return true
})
Expand Down Expand Up @@ -878,7 +880,11 @@ func (s *SQLiteSessionStore) GetSessions(ctx context.Context) ([]*Session, error
// This is much faster than GetSessions as it doesn't load message content.
func (s *SQLiteSessionStore) GetSessionSummaries(ctx context.Context) ([]Summary, error) {
rows, err := s.db.QueryContext(ctx,
"SELECT id, title, created_at, starred, branch_parent_session_id FROM sessions WHERE parent_id IS NULL OR parent_id = '' ORDER BY created_at DESC")
`SELECT s.id, s.title, s.created_at, s.starred, s.branch_parent_session_id,
(SELECT COUNT(*) FROM session_items si WHERE si.session_id = s.id AND si.item_type = 'message')
FROM sessions s
WHERE s.parent_id IS NULL OR s.parent_id = ''
ORDER BY s.created_at DESC`)
if err != nil {
return nil, err
}
Expand All @@ -888,7 +894,8 @@ func (s *SQLiteSessionStore) GetSessionSummaries(ctx context.Context) ([]Summary
for rows.Next() {
var id, title, createdAtStr, starredStr string
var branchParentID sql.NullString
if err := rows.Scan(&id, &title, &createdAtStr, &starredStr, &branchParentID); err != nil {
var numMessages int
if err := rows.Scan(&id, &title, &createdAtStr, &starredStr, &branchParentID, &numMessages); err != nil {
return nil, err
}
createdAt, err := time.Parse(time.RFC3339, createdAtStr)
Expand All @@ -905,6 +912,7 @@ func (s *SQLiteSessionStore) GetSessionSummaries(ctx context.Context) ([]Summary
CreatedAt: createdAt,
Starred: starred,
BranchParentSessionID: branchParentID.String,
NumMessages: numMessages,
})
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/session/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,12 @@ func TestGetSessionSummaries(t *testing.T) {
assert.Equal(t, "session-2", summaries[0].ID)
assert.Equal(t, "Second Session", summaries[0].Title)
assert.Equal(t, session2Time, summaries[0].CreatedAt)
assert.Equal(t, 1, summaries[0].NumMessages)

assert.Equal(t, "session-1", summaries[1].ID)
assert.Equal(t, "First Session", summaries[1].Title)
assert.Equal(t, session1Time, summaries[1].CreatedAt)
assert.Equal(t, 1, summaries[1].NumMessages)
}

func TestBranchSessionCopiesPrefix(t *testing.T) {
Expand Down
6 changes: 4 additions & 2 deletions pkg/tui/dialog/session_browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,13 +317,15 @@ func (d *sessionBrowserDialog) renderSession(sess session.Summary, selected bool
title = "Untitled"
}

suffix := fmt.Sprintf(" (%d) • %s", sess.NumMessages, d.timeAgo(sess.CreatedAt))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Casual Greeting (2) is not really telling what the number means

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll improve that


starWidth := 3
maxTitleLen := maxWidth - 25 - starWidth
maxTitleLen := max(1, maxWidth-len(suffix)-starWidth)
if len(title) > maxTitleLen {
title = title[:maxTitleLen-1] + "…"
}

return styles.StarIndicator(sess.Starred) + titleStyle.Render(title) + timeStyle.Render(" • "+d.timeAgo(sess.CreatedAt))
return styles.StarIndicator(sess.Starred) + titleStyle.Render(title) + timeStyle.Render(suffix)
}

func (d *sessionBrowserDialog) timeAgo(t time.Time) string {
Expand Down