Feat: scroll to end toggle

This commit is contained in:
Grail Finder
2025-12-31 16:18:18 +03:00
parent 03e1f5dc6d
commit 5b8880ebc8
4 changed files with 39 additions and 7 deletions

14
bot.go
View File

@@ -674,7 +674,9 @@ out:
case chunk := <-chunkChan: case chunk := <-chunkChan:
fmt.Fprint(tv, chunk) fmt.Fprint(tv, chunk)
respText.WriteString(chunk) respText.WriteString(chunk)
tv.ScrollToEnd() if scrollToEndEnabled {
tv.ScrollToEnd()
}
// Send chunk to audio stream handler // Send chunk to audio stream handler
if cfg.TTS_ENABLED { if cfg.TTS_ENABLED {
extra.TTSTextChan <- chunk extra.TTSTextChan <- chunk
@@ -682,14 +684,18 @@ out:
case toolChunk := <-openAIToolChan: case toolChunk := <-openAIToolChan:
fmt.Fprint(tv, toolChunk) fmt.Fprint(tv, toolChunk)
toolResp.WriteString(toolChunk) toolResp.WriteString(toolChunk)
tv.ScrollToEnd() if scrollToEndEnabled {
tv.ScrollToEnd()
}
case <-streamDone: case <-streamDone:
// drain any remaining chunks from chunkChan before exiting // drain any remaining chunks from chunkChan before exiting
for len(chunkChan) > 0 { for len(chunkChan) > 0 {
chunk := <-chunkChan chunk := <-chunkChan
fmt.Fprint(tv, chunk) fmt.Fprint(tv, chunk)
respText.WriteString(chunk) respText.WriteString(chunk)
tv.ScrollToEnd() if scrollToEndEnabled {
tv.ScrollToEnd()
}
// Send chunk to audio stream handler // Send chunk to audio stream handler
if cfg.TTS_ENABLED { if cfg.TTS_ENABLED {
extra.TTSTextChan <- chunk extra.TTSTextChan <- chunk
@@ -1130,5 +1136,7 @@ func init() {
if cfg.STT_ENABLED { if cfg.STT_ENABLED {
asr = extra.NewSTT(logger, cfg) asr = extra.NewSTT(logger, cfg)
} }
// Initialize scrollToEndEnabled based on config
scrollToEndEnabled = cfg.AutoScrollEnabled
go updateModelLists() go updateModelLists()
} }

View File

@@ -18,6 +18,7 @@ ToolRole = "tool"
AssistantRole = "assistant" AssistantRole = "assistant"
SysDir = "sysprompts" SysDir = "sysprompts"
ChunkLimit = 100000 ChunkLimit = 100000
AutoScrollEnabled = true
# AutoCleanToolCallsFromCtx = false # AutoCleanToolCallsFromCtx = false
# rag settings # rag settings
RAGBatchSize = 1 RAGBatchSize = 1

View File

@@ -28,6 +28,7 @@ type Config struct {
AssistantRole string `toml:"AssistantRole"` AssistantRole string `toml:"AssistantRole"`
SysDir string `toml:"SysDir"` SysDir string `toml:"SysDir"`
ChunkLimit uint32 `toml:"ChunkLimit"` ChunkLimit uint32 `toml:"ChunkLimit"`
AutoScrollEnabled bool `toml:"AutoScrollEnabled"`
WriteNextMsgAs string WriteNextMsgAs string
WriteNextMsgAsCompletionAgent string WriteNextMsgAsCompletionAgent string
SkipLLMResp bool SkipLLMResp bool

30
tui.go
View File

@@ -36,6 +36,7 @@ var (
roleEditWindow *tview.InputField roleEditWindow *tview.InputField
fullscreenMode bool fullscreenMode bool
positionVisible bool = true positionVisible bool = true
scrollToEndEnabled bool = true
// pages // pages
historyPage = "historyPage" historyPage = "historyPage"
agentPage = "agentPage" agentPage = "agentPage"
@@ -88,6 +89,7 @@ var (
[yellow]Ctrl+q[white]: cycle through mentioned chars in chat, to pick persona to send next msg as [yellow]Ctrl+q[white]: cycle through mentioned chars in chat, to pick persona to send next msg as
[yellow]Ctrl+x[white]: cycle through mentioned chars in chat, to pick persona to send next msg as (for llm) [yellow]Ctrl+x[white]: cycle through mentioned chars in chat, to pick persona to send next msg as (for llm)
[yellow]Alt+1[white]: toggle shell mode (execute commands locally) [yellow]Alt+1[white]: toggle shell mode (execute commands locally)
[yellow]Alt+2[white]: toggle auto-scrolling (for reading while LLM types)
[yellow]Alt+3[white]: summarize chat history and start new chat with summary as tool response [yellow]Alt+3[white]: summarize chat history and start new chat with summary as tool response
[yellow]Alt+4[white]: edit msg role [yellow]Alt+4[white]: edit msg role
[yellow]Alt+5[white]: toggle system and tool messages display [yellow]Alt+5[white]: toggle system and tool messages display
@@ -203,7 +205,9 @@ func executeCommandAndDisplay(cmdText string) {
cmdParts := parseCommand(cmdText) cmdParts := parseCommand(cmdText)
if len(cmdParts) == 0 { if len(cmdParts) == 0 {
fmt.Fprintf(textView, "\n[red]Error: No command provided[-:-:-]\n") fmt.Fprintf(textView, "\n[red]Error: No command provided[-:-:-]\n")
textView.ScrollToEnd() if scrollToEndEnabled {
textView.ScrollToEnd()
}
colorText() colorText()
return return
} }
@@ -233,7 +237,9 @@ func executeCommandAndDisplay(cmdText string) {
} }
} }
// Scroll to end and update colors // Scroll to end and update colors
textView.ScrollToEnd() if scrollToEndEnabled {
textView.ScrollToEnd()
}
colorText() colorText()
} }
@@ -767,7 +773,9 @@ func init() {
updateStatusLine() updateStatusLine()
textView.SetText(chatToText(cfg.ShowSys)) textView.SetText(chatToText(cfg.ShowSys))
colorText() colorText()
textView.ScrollToEnd() if scrollToEndEnabled {
textView.ScrollToEnd()
}
// init sysmap // init sysmap
_, err := initSysCards() _, err := initSysCards()
if err != nil { if err != nil {
@@ -792,6 +800,18 @@ func init() {
positionVisible = !positionVisible positionVisible = !positionVisible
updateFlexLayout() updateFlexLayout()
} }
if event.Key() == tcell.KeyRune && event.Rune() == '2' && event.Modifiers()&tcell.ModAlt != 0 {
// toggle auto-scrolling
scrollToEndEnabled = !scrollToEndEnabled
status := "disabled"
if scrollToEndEnabled {
status = "enabled"
}
if err := notifyUser("autoscroll", "Auto-scrolling "+status); err != nil {
logger.Error("failed to send notification", "error", err)
}
updateStatusLine()
}
if event.Key() == tcell.KeyF1 { if event.Key() == tcell.KeyF1 {
// chatList, err := loadHistoryChats() // chatList, err := loadHistoryChats()
chatList, err := store.GetChatByChar(cfg.AssistantRole) chatList, err := store.GetChatByChar(cfg.AssistantRole)
@@ -1292,7 +1312,9 @@ func init() {
fmt.Fprintf(textView, "%s[-:-:b](%d) <%s>: [-:-:-]\n%s\n", fmt.Fprintf(textView, "%s[-:-:b](%d) <%s>: [-:-:-]\n%s\n",
nl, len(chatBody.Messages), persona, msgText) nl, len(chatBody.Messages), persona, msgText)
textArea.SetText("", true) textArea.SetText("", true)
textView.ScrollToEnd() if scrollToEndEnabled {
textView.ScrollToEnd()
}
colorText() colorText()
} }
go chatRound(msgText, persona, textView, false, false) go chatRound(msgText, persona, textView, false, false)