Documentation
¶
Index ¶
- func RenderEmptyHistory(theme *ui.Theme) string
- func RenderScrollIndicator(offset int, theme *ui.Theme) string
- type BlockCache
- type ChatRenderer
- type FlushResult
- type InputState
- type MarkdownRenderer
- type MessageBlock
- type MessageBlockRenderer
- type RenderEvent
- func FromStreamEvent(ev ui.StreamEvent) RenderEvent
- func NewInvalidateCacheEvent() RenderEvent
- func NewMessageAddedEvent(id int64, role string, index int) RenderEvent
- func NewMessagesLoadedEvent(count int) RenderEvent
- func NewResizeEvent(width, height int) RenderEvent
- func NewScrollEvent(offset int) RenderEvent
- func NewStreamAskUserResultEvent(summary string) RenderEvent
- func NewStreamDiffEvent(path, old, new string, line int) RenderEvent
- func NewStreamEndEvent() RenderEvent
- func NewStreamErrorEvent(err error) RenderEvent
- func NewStreamImageEvent(path string) RenderEvent
- func NewStreamStartEvent() RenderEvent
- func NewStreamTextEvent(text string) RenderEvent
- func NewStreamToolEndEvent(callID, name, info string, success bool) RenderEvent
- func NewStreamToolStartEvent(callID, name, info string) RenderEvent
- type RenderEventType
- type RenderMode
- type RenderState
- type Renderer
- func (r *Renderer) ClearStreaming()
- func (r *Renderer) Flush() FlushResult
- func (r *Renderer) FlushAll() FlushResult
- func (r *Renderer) GetStreamingContent() string
- func (r *Renderer) HandleEvent(event RenderEvent) tea.Cmd
- func (r *Renderer) InvalidateCache()
- func (r *Renderer) Render(state RenderState) string
- func (r *Renderer) SetMarkdownRenderer(renderer MarkdownRenderer)
- func (r *Renderer) SetSize(width, height int)
- type StreamingBlock
- func (s *StreamingBlock) AddAskUserResult(summary string)
- func (s *StreamingBlock) AddDiff(path, old, new string, line int)
- func (s *StreamingBlock) AddImage(path string)
- func (s *StreamingBlock) AddText(text string)
- func (s *StreamingBlock) Complete()
- func (s *StreamingBlock) EndTool(callID string, success bool)
- func (s *StreamingBlock) Flush() FlushResult
- func (s *StreamingBlock) FlushAll() FlushResult
- func (s *StreamingBlock) GetCompletedContent() string
- func (s *StreamingBlock) GetTracker() *ui.ToolTracker
- func (s *StreamingBlock) HandleWavePause() tea.Cmd
- func (s *StreamingBlock) HandleWaveTick() tea.Cmd
- func (s *StreamingBlock) HasPendingTools() bool
- func (s *StreamingBlock) Render(wavePos int, pausedForUI bool, includeImages bool) string
- func (s *StreamingBlock) Resize(width int)
- func (s *StreamingBlock) SetError(err error)
- func (s *StreamingBlock) SetTracker(tracker *ui.ToolTracker)
- func (s *StreamingBlock) StartTool(callID, name, info string) bool
- func (s *StreamingBlock) StartWaveAnimation() tea.Cmd
- type StreamingState
- type ViewportInfo
- type ViewportState
- type VirtualViewport
- func (v *VirtualViewport) CalculateTotalHeight(heights []int) int
- func (v *VirtualViewport) EstimateMessageHeight(msg *session.Message) int
- func (v *VirtualViewport) GetViewportInfo(messages []session.Message, heights []int, scrollOffset int) ViewportInfo
- func (v *VirtualViewport) GetVisibleRange(messages []session.Message, scrollOffset int) (int, int)
- func (v *VirtualViewport) GetVisibleRangeWithHeights(messages []session.Message, heights []int, scrollOffset int) (int, int)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RenderEmptyHistory ¶
RenderEmptyHistory renders the "no messages" placeholder.
Types ¶
type BlockCache ¶
type BlockCache struct {
// contains filtered or unexported fields
}
BlockCache is an LRU cache for rendered MessageBlocks. It keeps memory bounded while avoiding re-rendering unchanged messages.
func NewBlockCache ¶
func NewBlockCache(maxSize int) *BlockCache
NewBlockCache creates a new block cache with the given maximum size.
func (*BlockCache) Clear ¶
func (c *BlockCache) Clear()
Clear removes all entries from the cache. Alias for InvalidateAll for semantic clarity.
func (*BlockCache) Get ¶
func (c *BlockCache) Get(key string) *MessageBlock
Get retrieves a block from the cache, returning nil if not found. Accessing a block moves it to the front of the LRU list.
func (*BlockCache) InvalidateAll ¶
func (c *BlockCache) InvalidateAll()
InvalidateAll clears the entire cache. Call this on terminal resize when all cached renders are invalid.
func (*BlockCache) Put ¶
func (c *BlockCache) Put(key string, block *MessageBlock)
Put adds a block to the cache, evicting the least recently used block if the cache is at capacity.
func (*BlockCache) Remove ¶
func (c *BlockCache) Remove(key string)
Remove removes a specific key from the cache.
func (*BlockCache) Size ¶
func (c *BlockCache) Size() int
Size returns the current number of cached blocks.
type ChatRenderer ¶
type ChatRenderer interface {
// Render returns the full view content for the current state.
// This is called by View() in the bubbletea model.
Render(state RenderState) string
// HandleEvent processes a render event and returns any commands
// that should be executed (e.g., starting animations).
HandleEvent(event RenderEvent) tea.Cmd
// SetSize updates the terminal dimensions.
// This invalidates caches as needed.
SetSize(width, height int)
// Flush returns content that should be printed to scrollback
// and clears it from the active view (inline mode only).
Flush() FlushResult
// FlushAll flushes all remaining content to scrollback.
// Called when streaming ends.
FlushAll() FlushResult
// InvalidateCache forces re-rendering of all cached content.
// Call this on terminal resize.
InvalidateCache()
// SetMarkdownRenderer sets the function used to render markdown.
SetMarkdownRenderer(renderer MarkdownRenderer)
}
ChatRenderer is the main interface for the chat rendering module. It provides a clean abstraction over the rendering logic, supporting both inline and alt-screen modes with virtualized rendering for large message histories.
type FlushResult ¶
type FlushResult struct {
// Content to print to scrollback (empty if nothing to flush)
Content string
}
FlushResult contains the result of flushing content to scrollback
type InputState ¶
type InputState struct {
Height int // Height of input area in lines
Focused bool // Whether input is focused
}
InputState tracks input area state for rendering
type MarkdownRenderer ¶
MarkdownRenderer is a function that renders markdown content
type MessageBlock ¶
type MessageBlock struct {
// MessageID is the unique identifier for this message
MessageID int64
// Rendered is the complete rendered output for this message
Rendered string
// Height is the number of lines in the rendered output
Height int
// Width is the terminal width when this block was rendered
// (used for cache invalidation on resize)
Width int
}
MessageBlock represents a pre-rendered, cacheable message. Once rendered, blocks are immutable and can be reused across frames.
type MessageBlockRenderer ¶
type MessageBlockRenderer struct {
// contains filtered or unexported fields
}
MessageBlockRenderer renders session messages to MessageBlocks.
func NewMessageBlockRenderer ¶
func NewMessageBlockRenderer(width int, mdRenderer MarkdownRenderer) *MessageBlockRenderer
NewMessageBlockRenderer creates a new renderer for message blocks.
func NewMessageBlockRendererWithContext ¶
func NewMessageBlockRendererWithContext(width int, mdRenderer MarkdownRenderer, messages []session.Message, index int) *MessageBlockRenderer
NewMessageBlockRendererWithContext creates a new renderer with message context for tool result lookup. This allows rendering diffs for edit_file tool calls by finding the corresponding tool result in subsequent messages.
func (*MessageBlockRenderer) Render ¶
func (r *MessageBlockRenderer) Render(msg *session.Message) *MessageBlock
Render converts a session.Message to a MessageBlock.
type RenderEvent ¶
type RenderEvent struct {
Type RenderEventType
// For RenderEventMessageAdded
MessageID int64
MessageRole string
MessageIndex int
// For RenderEventMessagesLoaded
MessageCount int
// For streaming text events
Text string
// For streaming tool events
ToolCallID string
ToolName string
ToolInfo string
ToolSuccess bool
// For streaming image/diff events
ImagePath string
DiffPath string
DiffOld string
DiffNew string
DiffLine int
// For ask user results
AskUserSummary string
// For resize events
Width int
Height int
// For scroll events
ScrollOffset int
// For error events
Err error
}
RenderEvent represents an event that affects rendering. The renderer processes these events to update its internal state and produce the appropriate output.
func FromStreamEvent ¶
func FromStreamEvent(ev ui.StreamEvent) RenderEvent
FromStreamEvent converts a ui.StreamEvent to a RenderEvent
func NewInvalidateCacheEvent ¶
func NewInvalidateCacheEvent() RenderEvent
NewInvalidateCacheEvent creates an event to force cache invalidation
func NewMessageAddedEvent ¶
func NewMessageAddedEvent(id int64, role string, index int) RenderEvent
NewMessageAddedEvent creates an event for when a message is added to history
func NewMessagesLoadedEvent ¶
func NewMessagesLoadedEvent(count int) RenderEvent
NewMessagesLoadedEvent creates an event for when messages are loaded from storage
func NewResizeEvent ¶
func NewResizeEvent(width, height int) RenderEvent
NewResizeEvent creates an event for terminal resize
func NewScrollEvent ¶
func NewScrollEvent(offset int) RenderEvent
NewScrollEvent creates an event for scroll changes
func NewStreamAskUserResultEvent ¶
func NewStreamAskUserResultEvent(summary string) RenderEvent
NewStreamAskUserResultEvent creates an event for ask_user results
func NewStreamDiffEvent ¶
func NewStreamDiffEvent(path, old, new string, line int) RenderEvent
NewStreamDiffEvent creates an event for when a diff is generated
func NewStreamEndEvent ¶
func NewStreamEndEvent() RenderEvent
NewStreamEndEvent creates an event for when streaming ends
func NewStreamErrorEvent ¶
func NewStreamErrorEvent(err error) RenderEvent
NewStreamErrorEvent creates an event for streaming errors
func NewStreamImageEvent ¶
func NewStreamImageEvent(path string) RenderEvent
NewStreamImageEvent creates an event for when an image is generated
func NewStreamStartEvent ¶
func NewStreamStartEvent() RenderEvent
NewStreamStartEvent creates an event for when streaming begins
func NewStreamTextEvent ¶
func NewStreamTextEvent(text string) RenderEvent
NewStreamTextEvent creates an event for streaming text content
func NewStreamToolEndEvent ¶
func NewStreamToolEndEvent(callID, name, info string, success bool) RenderEvent
NewStreamToolEndEvent creates an event for when a tool finishes executing
func NewStreamToolStartEvent ¶
func NewStreamToolStartEvent(callID, name, info string) RenderEvent
NewStreamToolStartEvent creates an event for when a tool starts executing
type RenderEventType ¶
type RenderEventType int
RenderEventType identifies the type of render event
const ( // Message events (historical) RenderEventMessageAdded RenderEventType = iota RenderEventMessagesLoaded RenderEventMessagesClear // Streaming events RenderEventStreamStart RenderEventStreamText RenderEventStreamToolStart RenderEventStreamToolEnd RenderEventStreamImage RenderEventStreamDiff RenderEventStreamAskUserResult RenderEventStreamEnd RenderEventStreamError // UI events RenderEventResize RenderEventScroll RenderEventInvalidateCache )
type RenderMode ¶
type RenderMode int
RenderMode determines how content is displayed
const ( RenderModeInline RenderMode = iota // Traditional inline mode with scrollback RenderModeAltScreen // Full-screen alternate screen mode )
type RenderState ¶
type RenderState struct {
Messages []session.Message
Streaming *StreamingState // nil if not streaming
Viewport ViewportState
Input InputState
Mode RenderMode
Width int
Height int
ShowStats bool
Error error // Display error if set
}
RenderState holds all state needed for rendering
type Renderer ¶
type Renderer struct {
// contains filtered or unexported fields
}
Renderer implements ChatRenderer with virtualized rendering and caching for performance.
func NewRenderer ¶
NewRenderer creates a new chat renderer with the given dimensions.
func (*Renderer) ClearStreaming ¶
func (r *Renderer) ClearStreaming()
ClearStreaming clears the streaming state without flushing. Call this when starting a new prompt.
func (*Renderer) Flush ¶
func (r *Renderer) Flush() FlushResult
Flush returns content that should be printed to scrollback.
func (*Renderer) FlushAll ¶
func (r *Renderer) FlushAll() FlushResult
FlushAll flushes all remaining content to scrollback.
func (*Renderer) GetStreamingContent ¶
GetStreamingContent returns the completed streaming content for caching. Used in alt-screen mode to preserve diffs/images after streaming ends.
func (*Renderer) HandleEvent ¶
func (r *Renderer) HandleEvent(event RenderEvent) tea.Cmd
HandleEvent processes a render event and returns any commands.
func (*Renderer) InvalidateCache ¶
func (r *Renderer) InvalidateCache()
InvalidateCache forces re-rendering of all cached content.
func (*Renderer) Render ¶
func (r *Renderer) Render(state RenderState) string
Render returns the full view content for the current state.
func (*Renderer) SetMarkdownRenderer ¶
func (r *Renderer) SetMarkdownRenderer(renderer MarkdownRenderer)
SetMarkdownRenderer sets the function used to render markdown.
type StreamingBlock ¶
type StreamingBlock struct {
// contains filtered or unexported fields
}
StreamingBlock handles rendering of the active streaming response. It manages segments (text, tools, images, diffs) and provides incremental flushing for inline mode.
func NewStreamingBlock ¶
func NewStreamingBlock(width int, mdRenderer MarkdownRenderer) *StreamingBlock
NewStreamingBlock creates a new streaming block.
func (*StreamingBlock) AddAskUserResult ¶
func (s *StreamingBlock) AddAskUserResult(summary string)
AddAskUserResult adds an ask_user result segment.
func (*StreamingBlock) AddDiff ¶
func (s *StreamingBlock) AddDiff(path, old, new string, line int)
AddDiff adds a diff segment.
func (*StreamingBlock) AddImage ¶
func (s *StreamingBlock) AddImage(path string)
AddImage adds an image segment.
func (*StreamingBlock) AddText ¶
func (s *StreamingBlock) AddText(text string)
AddText adds streaming text content.
func (*StreamingBlock) Complete ¶
func (s *StreamingBlock) Complete()
Complete marks the streaming as complete.
func (*StreamingBlock) EndTool ¶
func (s *StreamingBlock) EndTool(callID string, success bool)
EndTool updates the status of a pending tool.
func (*StreamingBlock) Flush ¶
func (s *StreamingBlock) Flush() FlushResult
Flush returns content to print to scrollback and marks it as flushed.
func (*StreamingBlock) FlushAll ¶
func (s *StreamingBlock) FlushAll() FlushResult
FlushAll flushes all remaining content.
func (*StreamingBlock) GetCompletedContent ¶
func (s *StreamingBlock) GetCompletedContent() string
GetCompletedContent returns the full rendered content for caching. Used to preserve images/diffs after streaming ends in alt-screen mode.
func (*StreamingBlock) GetTracker ¶
func (s *StreamingBlock) GetTracker() *ui.ToolTracker
GetTracker returns the underlying ToolTracker. This is used for compatibility with existing code during migration.
func (*StreamingBlock) HandleWavePause ¶
func (s *StreamingBlock) HandleWavePause() tea.Cmd
HandleWavePause handles wave animation pause end.
func (*StreamingBlock) HandleWaveTick ¶
func (s *StreamingBlock) HandleWaveTick() tea.Cmd
HandleWaveTick handles wave animation tick.
func (*StreamingBlock) HasPendingTools ¶
func (s *StreamingBlock) HasPendingTools() bool
HasPendingTools returns true if there are pending tools.
func (*StreamingBlock) Render ¶
func (s *StreamingBlock) Render(wavePos int, pausedForUI bool, includeImages bool) string
Render renders the streaming block content. wavePos is the wave animation position (-1 = paused). pausedForUI is true when paused for external UI (hide indicator). includeImages controls whether to render images inline.
func (*StreamingBlock) Resize ¶
func (s *StreamingBlock) Resize(width int)
Resize updates the width and invalidates cached renders.
func (*StreamingBlock) SetError ¶
func (s *StreamingBlock) SetError(err error)
SetError sets an error on the streaming block.
func (*StreamingBlock) SetTracker ¶
func (s *StreamingBlock) SetTracker(tracker *ui.ToolTracker)
SetTracker sets the underlying ToolTracker. This is used for compatibility with existing code during migration.
func (*StreamingBlock) StartTool ¶
func (s *StreamingBlock) StartTool(callID, name, info string) bool
StartTool adds a new pending tool segment. Returns true if a new segment was added (for starting wave animation).
func (*StreamingBlock) StartWaveAnimation ¶
func (s *StreamingBlock) StartWaveAnimation() tea.Cmd
StartWaveAnimation starts the wave animation for pending tools.
type StreamingState ¶
type StreamingState struct {
Phase string // Current phase ("Thinking", "Responding", etc.)
WavePos int // Wave animation position (-1 = paused)
SpinnerView string // Pre-rendered spinner string
RetryStatus string // Retry status message if any
PausedForUI bool // True when paused for external UI
ElapsedSecs float64 // Seconds since stream started
Tokens int // Current token count
ActiveTools []string // Names of currently executing tools
}
StreamingState represents the state of active streaming
type ViewportInfo ¶
type ViewportInfo struct {
StartMessage int // First visible message index
EndMessage int // Last visible message index (exclusive)
TotalHeight int // Total height of all messages
VisibleStart int // First visible line (from top of all content)
VisibleEnd int // Last visible line (from top of all content)
AtTop bool // True if showing the first message
AtBottom bool // True if showing the last message
}
ViewportInfo contains information about the current viewport state.
type ViewportState ¶
type ViewportState struct {
Height int // Visible height in lines
ScrollOffset int // Scroll offset from bottom (0 = bottom)
AtBottom bool
}
ViewportState tracks the viewport scroll position
type VirtualViewport ¶
type VirtualViewport struct {
// contains filtered or unexported fields
}
VirtualViewport handles virtualized rendering of message history. Instead of rendering all messages, it calculates which messages are visible in the viewport and only renders those.
func NewVirtualViewport ¶
func NewVirtualViewport(width, height int) *VirtualViewport
NewVirtualViewport creates a new virtual viewport.
func (*VirtualViewport) CalculateTotalHeight ¶
func (v *VirtualViewport) CalculateTotalHeight(heights []int) int
CalculateTotalHeight calculates the total height of all messages. This is used for scroll calculations.
func (*VirtualViewport) EstimateMessageHeight ¶
func (v *VirtualViewport) EstimateMessageHeight(msg *session.Message) int
EstimateMessageHeight gives a rough estimate of how many lines a message will take. This is used for initial viewport calculations before actual rendering.
func (*VirtualViewport) GetViewportInfo ¶
func (v *VirtualViewport) GetViewportInfo(messages []session.Message, heights []int, scrollOffset int) ViewportInfo
GetViewportInfo returns detailed information about the current viewport.
func (*VirtualViewport) GetVisibleRange ¶
GetVisibleRange returns the start and end indices (exclusive) of messages that should be rendered for the current viewport.
scrollOffset is the number of messages scrolled up from the bottom. Returns (start, end) where messages[start:end] should be rendered.
func (*VirtualViewport) GetVisibleRangeWithHeights ¶
func (v *VirtualViewport) GetVisibleRangeWithHeights(messages []session.Message, heights []int, scrollOffset int) (int, int)
GetVisibleRangeWithHeights returns the visible range using actual rendered heights. This is more accurate but requires heights to be known.