Change summary
internal/tui/components/chat/messages/messages.go | 3 +
internal/tui/components/chat/sidebar/sidebar.go | 29 ++++++++++++++++
2 files changed, 31 insertions(+), 1 deletion(-)
Detailed changes
@@ -252,6 +252,7 @@ func (m *messageCmp) renderThinkingContent() string {
m.thinkingViewport.SetWidth(m.textWidth())
m.thinkingViewport.SetContent(fullContent)
m.thinkingViewport.GotoBottom()
+ finishReason := m.message.FinishPart()
var footer string
if reasoningContent.StartedAt > 0 {
duration := m.message.ThinkingDuration()
@@ -263,6 +264,8 @@ func (m *messageCmp) renderThinkingContent() string {
NoIcon: true,
}
footer = t.S().Base.PaddingLeft(1).Render(core.Status(opts, m.textWidth()-1))
+ } else if finishReason != nil && finishReason.Reason == message.FinishReasonCanceled {
+ footer = t.S().Base.PaddingLeft(1).Render(m.toMarkdown("*Canceled*"))
} else {
footer = m.anim.View()
}
@@ -12,6 +12,7 @@ import (
"github.com/charmbracelet/crush/internal/config"
"github.com/charmbracelet/crush/internal/diff"
"github.com/charmbracelet/crush/internal/fsext"
+ "github.com/charmbracelet/crush/internal/fur/provider"
"github.com/charmbracelet/crush/internal/history"
"github.com/charmbracelet/crush/internal/lsp"
"github.com/charmbracelet/crush/internal/lsp/protocol"
@@ -26,6 +27,8 @@ import (
"github.com/charmbracelet/crush/internal/version"
"github.com/charmbracelet/lipgloss/v2"
"github.com/charmbracelet/x/ansi"
+ "golang.org/x/text/cases"
+ "golang.org/x/text/language"
)
type FileHistory struct {
@@ -880,8 +883,13 @@ func formatTokensAndCost(tokens, contextWindow int64, cost float64) string {
}
func (s *sidebarCmp) currentModelBlock() string {
- agentCfg := config.Get().Agents["coder"]
+ cfg := config.Get()
+ agentCfg := cfg.Agents["coder"]
+
+ selectedModel := cfg.Models[agentCfg.Model]
+
model := config.Get().GetModelByType(agentCfg.Model)
+ modelProvider := config.Get().GetProviderForModel(agentCfg.Model)
t := styles.CurrentTheme()
@@ -891,6 +899,25 @@ func (s *sidebarCmp) currentModelBlock() string {
parts := []string{
modelInfo,
}
+ if model.CanReason {
+ reasoningInfoStyle := t.S().Subtle.PaddingLeft(2)
+ switch modelProvider.Type {
+ case provider.TypeOpenAI:
+ reasoningEffort := model.DefaultReasoningEffort
+ if selectedModel.ReasoningEffort != "" {
+ reasoningEffort = selectedModel.ReasoningEffort
+ }
+ formatter := cases.Title(language.English, cases.NoLower)
+ parts = append(parts, reasoningInfoStyle.Render(formatter.String(fmt.Sprintf("Reasoning %s", reasoningEffort))))
+ case provider.TypeAnthropic:
+ formatter := cases.Title(language.English, cases.NoLower)
+ if selectedModel.Think {
+ parts = append(parts, reasoningInfoStyle.Render(formatter.String("Thinking on")))
+ } else {
+ parts = append(parts, reasoningInfoStyle.Render(formatter.String("Thinking off")))
+ }
+ }
+ }
if s.session.ID != "" {
parts = append(
parts,