feat: compact command with auto-compact

This commit is contained in:
adamdottv
2025-05-02 09:24:24 -05:00
committed by Adam
parent 364cf5b429
commit 49423da081
16 changed files with 507 additions and 73 deletions

View File

@@ -23,6 +23,8 @@ type SessionClearedMsg struct{}
type EditorFocusMsg bool
type CompactSessionMsg struct{}
func header(width int) string {
return lipgloss.JoinVertical(
lipgloss.Top,

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"math"
"time"
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/spinner"
@@ -450,8 +451,11 @@ func (m *messagesCmp) BindingKeys() []key.Binding {
}
func NewMessagesCmp(app *app.App) tea.Model {
s := spinner.New()
s.Spinner = spinner.Pulse
customSpinner := spinner.Spinner{
Frames: []string{" ", "┃"},
FPS: time.Second / 2, //nolint:gomnd
}
s := spinner.New(spinner.WithSpinner(customSpinner))
vp := viewport.New(0, 0)
vp.KeyMap.PageUp = messageKeys.PageUp
vp.KeyMap.PageDown = messageKeys.PageDown

View File

@@ -2,10 +2,12 @@ package page
import (
"context"
"fmt"
"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
"github.com/opencode-ai/opencode/internal/app"
"github.com/opencode-ai/opencode/internal/logging"
"github.com/opencode-ai/opencode/internal/session"
"github.com/opencode-ai/opencode/internal/tui/components/chat"
"github.com/opencode-ai/opencode/internal/tui/layout"
@@ -64,6 +66,22 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
}
p.session = msg
case chat.CompactSessionMsg:
if p.session.ID == "" {
return p, util.ReportWarn("No active session to compact.")
}
// Run compaction in background
go func(sessionID string) {
err := p.app.CoderAgent.CompactSession(context.Background(), sessionID)
if err != nil {
logging.ErrorPersist(fmt.Sprintf("Compaction failed: %v", err))
} else {
logging.InfoPersist("Conversation compacted successfully.")
}
}(p.session.ID)
return p, nil
case tea.KeyMsg:
switch {
case key.Matches(msg, keyMap.NewSession):

View File

@@ -723,5 +723,23 @@ If there are Cursor rules (in .cursor/rules/ or .cursorrules) or Copilot rules (
)
},
})
model.RegisterCommand(dialog.Command{
ID: "compact_conversation",
Title: "Compact Conversation",
Description: "Summarize the current session to save tokens",
Handler: func(cmd dialog.Command) tea.Cmd {
// Get the current session from the appModel
if model.currentPage != page.ChatPage {
return util.ReportWarn("Please navigate to a chat session first.")
}
// Return a message that will be handled by the chat page
return tea.Batch(
util.CmdHandler(chat.CompactSessionMsg{}),
util.ReportInfo("Compacting conversation..."))
},
})
return model
}