on main help sign in
Merge pull request #242 from charmbracelet/conditional-header

chore: conditionally add thinking header

commit913b91e495d9d04433a6b04cc7296faf388f7dea authorKujtim Hoxha <kujtimii.h@gmail.com> dateTue 22 Jul 2025, 12:55 (1 year ago) parentda0c30a078a62c
2 files changed+22−3
internal/llm/provider/anthropic.go+21−2 internal/tui/components/chat/messages/messages.go+1−1
internal/llm/provider/anthropic.go+21−2
@@ -163,6 +163,15 @@ func (a *anthropicClient) finishReason(reason string) message.FinishReason {
163163 }
164164}
165165
166+func (a *anthropicClient) isThinkingEnabled() bool {
167+ cfg := config.Get()
168+ modelConfig := cfg.Models[config.SelectedModelTypeLarge]
169+ if a.providerOptions.modelType == config.SelectedModelTypeSmall {
170+ modelConfig = cfg.Models[config.SelectedModelTypeSmall]
171+ }
172+ return a.Model().CanReason && modelConfig.Think
173+}
174+
166175func (a *anthropicClient) preparedMessages(messages []anthropic.MessageParam, tools []anthropic.ToolUnionParam) anthropic.MessageNewParams {
167176 model := a.providerOptions.model(a.providerOptions.modelType)
168177 var thinkingParam anthropic.ThinkingConfigParamUnion
@@ -177,7 +186,7 @@ func (a *anthropicClient) preparedMessages(messages []anthropic.MessageParam, to
177186 if modelConfig.MaxTokens > 0 {
178187 maxTokens = modelConfig.MaxTokens
179188 }
180− if a.Model().CanReason && modelConfig.Think {
189+ if a.isThinkingEnabled() {
181190 thinkingParam = anthropic.ThinkingConfigParamOfEnabled(int64(float64(maxTokens) * 0.8))
182191 temperature = anthropic.Float(1)
183192 }
@@ -222,9 +231,14 @@ func (a *anthropicClient) send(ctx context.Context, messages []message.Message,
222231 slog.Debug("Prepared messages", "messages", string(jsonData))
223232 }
224233
234+ var opts []option.RequestOption
235+ if a.isThinkingEnabled() {
236+ opts = append(opts, option.WithHeaderAdd("anthropic-beta", "interleaved-thinking-2025-05-14"))
237+ }
225238 anthropicResponse, err := a.client.Messages.New(
226239 ctx,
227240 preparedMessages,
241+ opts...,
228242 )
229243 // If there is an error we are going to see if we can retry the call
230244 if err != nil {
@@ -274,10 +288,15 @@ func (a *anthropicClient) stream(ctx context.Context, messages []message.Message
274288 slog.Debug("Prepared messages", "messages", string(jsonData))
275289 }
276290
291+ var opts []option.RequestOption
292+ if a.isThinkingEnabled() {
293+ opts = append(opts, option.WithHeaderAdd("anthropic-beta", "interleaved-thinking-2025-05-14"))
294+ }
295+
277296 anthropicStream := a.client.Messages.NewStreaming(
278297 ctx,
279298 preparedMessages,
280− option.WithHeaderAdd("anthropic-beta", "interleaved-thinking-2025-05-14"),
299+ opts...,
281300 )
282301 accumulatedMessage := anthropic.Message{}
283302
internal/tui/components/chat/messages/messages.go+1−1
@@ -266,7 +266,7 @@ func (m *messageCmp) renderThinkingContent() string {
266266 Description: duration.String(),
267267 NoIcon: true,
268268 }
269− footer = t.S().Base.PaddingLeft(1).Render(core.Status(opts, m.textWidth()-1))
269+ return t.S().Base.PaddingLeft(1).Render(core.Status(opts, m.textWidth()-1))
270270 } else if finishReason != nil && finishReason.Reason == message.FinishReasonCanceled {
271271 footer = t.S().Base.PaddingLeft(1).Render(m.toMarkdown("*Canceled*"))
272272 } else {