11package sidebar
22
33import (
4+ "context"
45 "fmt"
56 "log/slog"
67 "maps"
@@ -11,6 +12,7 @@ import (
1112 tea "charm.land/bubbletea/v2"
1213 "charm.land/lipgloss/v2"
1314
15+ "github.com/docker/cagent/pkg/modelsdev"
1416 "github.com/docker/cagent/pkg/paths"
1517 "github.com/docker/cagent/pkg/runtime"
1618 "github.com/docker/cagent/pkg/session"
@@ -63,34 +65,35 @@ type ragIndexingState struct {
6365
6466// model implements Model
6567type model struct {
66- width int
67- height int
68- xPos int // absolute x position on screen
69- yPos int // absolute y position on screen
70- layoutCfg LayoutConfig // layout configuration for spacing
71- sessionUsage map [string ]* runtime.Usage // sessionID -> latest usage snapshot
72- sessionAgent map [string ]string // sessionID -> agent name
73- todoComp * todotool.SidebarComponent
74- mcpInit bool
75- ragIndexing map [string ]* ragIndexingState // strategy name -> indexing state
76- spinner spinner.Spinner
77- mode Mode
78- sessionTitle string
79- sessionStarred bool
80- sessionHasContent bool // true when session has been used (has messages)
81- currentAgent string
82- agentModel string
83- agentDescription string
84- availableAgents []runtime.AgentDetails
85- agentSwitching bool
86- availableTools int
87- toolsLoading bool // true when more tools may still be loading
88- sessionState * service.SessionState
89- workingAgent string // Name of the agent currently working (empty if none)
90- scrollbar * scrollbar.Model
91- workingDirectory string
92- queuedMessages []string // Truncated preview of queued messages
93- streamCancelled bool // true after ESC cancel until next StreamStartedEvent
68+ width int
69+ height int
70+ xPos int // absolute x position on screen
71+ yPos int // absolute y position on screen
72+ layoutCfg LayoutConfig // layout configuration for spacing
73+ sessionUsage map [string ]* runtime.Usage // sessionID -> latest usage snapshot
74+ sessionAgent map [string ]string // sessionID -> agent name
75+ todoComp * todotool.SidebarComponent
76+ mcpInit bool
77+ ragIndexing map [string ]* ragIndexingState // strategy name -> indexing state
78+ spinner spinner.Spinner
79+ mode Mode
80+ sessionTitle string
81+ sessionStarred bool
82+ sessionHasContent bool // true when session has been used (has messages)
83+ currentAgent string
84+ agentModel string
85+ agentDescription string
86+ availableAgents []runtime.AgentDetails
87+ agentSwitching bool
88+ availableTools int
89+ toolsLoading bool // true when more tools may still be loading
90+ sessionState * service.SessionState
91+ workingAgent string // Name of the agent currently working (empty if none)
92+ scrollbar * scrollbar.Model
93+ workingDirectory string
94+ queuedMessages []string // Truncated preview of queued messages
95+ streamCancelled bool // true after ESC cancel until next StreamStartedEvent
96+ reasoningSupported bool // true if current model supports reasoning (default: true / fail-open)
9497}
9598
9699// Option is a functional option for configuring the sidebar.
@@ -103,18 +106,19 @@ func WithLayoutConfig(cfg LayoutConfig) Option {
103106
104107func New (sessionState * service.SessionState , opts ... Option ) Model {
105108 m := & model {
106- width : 20 ,
107- layoutCfg : DefaultLayoutConfig (),
108- height : 24 ,
109- sessionUsage : make (map [string ]* runtime.Usage ),
110- sessionAgent : make (map [string ]string ),
111- todoComp : todotool .NewSidebarComponent (),
112- spinner : spinner .New (spinner .ModeSpinnerOnly , styles .SpinnerDotsHighlightStyle ),
113- sessionTitle : "New session" ,
114- ragIndexing : make (map [string ]* ragIndexingState ),
115- sessionState : sessionState ,
116- scrollbar : scrollbar .New (),
117- workingDirectory : getCurrentWorkingDirectory (),
109+ width : 20 ,
110+ layoutCfg : DefaultLayoutConfig (),
111+ height : 24 ,
112+ sessionUsage : make (map [string ]* runtime.Usage ),
113+ sessionAgent : make (map [string ]string ),
114+ todoComp : todotool .NewSidebarComponent (),
115+ spinner : spinner .New (spinner .ModeSpinnerOnly , styles .SpinnerDotsHighlightStyle ),
116+ sessionTitle : "New session" ,
117+ ragIndexing : make (map [string ]* ragIndexingState ),
118+ sessionState : sessionState ,
119+ scrollbar : scrollbar .New (),
120+ workingDirectory : getCurrentWorkingDirectory (),
121+ reasoningSupported : true , // Default to true (fail-open)
118122 }
119123 for _ , opt := range opts {
120124 opt (m )
@@ -145,16 +149,22 @@ func (m *model) SetTodos(result *tools.ToolCallResult) error {
145149}
146150
147151// SetAgentInfo sets the current agent information and updates the model in availableAgents
148- func (m * model ) SetAgentInfo (agentName , model , description string ) {
152+ func (m * model ) SetAgentInfo (agentName , modelID , description string ) {
149153 m .currentAgent = agentName
150- m .agentModel = model
154+ m .agentModel = modelID
151155 m .agentDescription = description
156+ m .reasoningSupported = modelsdev .ModelSupportsReasoning (context .Background (), modelID )
152157
153158 // Update the model in availableAgents for the current agent
154159 // This is important when model routing selects a different model than configured
160+ // Extract just the model name from "provider/model" format to match TeamInfoEvent format
155161 for i := range m .availableAgents {
156- if m .availableAgents [i ].Name == agentName && model != "" {
157- m .availableAgents [i ].Model = model
162+ if m .availableAgents [i ].Name == agentName && modelID != "" {
163+ modelName := modelID
164+ if idx := strings .LastIndex (modelName , "/" ); idx != - 1 {
165+ modelName = modelName [idx + 1 :]
166+ }
167+ m .availableAgents [i ].Model = modelName
158168 break
159169 }
160170 }
@@ -776,13 +786,14 @@ func (m *model) toolsetInfo(contentWidth int) string {
776786 lines = append (lines , m .renderToolsStatus ())
777787
778788 // Toggle indicators with shortcuts
789+ // Only show "Thinking enabled" if the model supports reasoning
779790 toggles := []struct {
780791 enabled bool
781792 label string
782793 shortcut string
783794 }{
784795 {m .sessionState .YoloMode , "YOLO mode enabled" , "^y" },
785- {m .sessionState .Thinking , "Thinking enabled" , "/think" },
796+ {m .sessionState .Thinking && m . reasoningSupported , "Thinking enabled" , "/think" },
786797 {m .sessionState .HideToolResults , "Tool output hidden" , "^o" },
787798 {m .sessionState .SplitDiffView , "Split Diff View enabled" , "^t" },
788799 }
0 commit comments