From 43960fdf15d7fff621b7c64d487fb1923281e4b8 Mon Sep 17 00:00:00 2001 From: Kujtim Hoxha Date: Fri, 18 Jul 2025 10:01:04 +0200 Subject: [PATCH 1/2] chore: conditionally add thinking header --- internal/llm/provider/anthropic.go | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/internal/llm/provider/anthropic.go b/internal/llm/provider/anthropic.go index a65f0b752367ca7b2e62f9dd263a7dd6e5ce7a53..9f39e16c21f3d02497458456be4c15e3acb53062 100644 --- a/internal/llm/provider/anthropic.go +++ b/internal/llm/provider/anthropic.go @@ -157,6 +157,15 @@ func (a *anthropicClient) finishReason(reason string) message.FinishReason { } } +func (a *anthropicClient) isThinkingEnabled() bool { + cfg := config.Get() + modelConfig := cfg.Models[config.SelectedModelTypeLarge] + if a.providerOptions.modelType == config.SelectedModelTypeSmall { + modelConfig = cfg.Models[config.SelectedModelTypeSmall] + } + return a.Model().CanReason && modelConfig.Think +} + func (a *anthropicClient) preparedMessages(messages []anthropic.MessageParam, tools []anthropic.ToolUnionParam) anthropic.MessageNewParams { model := a.providerOptions.model(a.providerOptions.modelType) var thinkingParam anthropic.ThinkingConfigParamUnion @@ -171,7 +180,7 @@ func (a *anthropicClient) preparedMessages(messages []anthropic.MessageParam, to if modelConfig.MaxTokens > 0 { maxTokens = modelConfig.MaxTokens } - if a.Model().CanReason && modelConfig.Think { + if a.isThinkingEnabled() { thinkingParam = anthropic.ThinkingConfigParamOfEnabled(int64(float64(maxTokens) * 0.8)) temperature = anthropic.Float(1) } @@ -216,9 +225,14 @@ func (a *anthropicClient) send(ctx context.Context, messages []message.Message, slog.Debug("Prepared messages", "messages", string(jsonData)) } + var opts []option.RequestOption + if a.isThinkingEnabled() { + opts = append(opts, option.WithHeaderAdd("anthropic-beta", "interleaved-thinking-2025-05-14")) + } anthropicResponse, err := a.client.Messages.New( ctx, preparedMessages, + opts..., ) // If there is an error we are going to see if we can retry the call if err != nil { @@ -268,10 +282,15 @@ func (a *anthropicClient) stream(ctx context.Context, messages []message.Message slog.Debug("Prepared messages", "messages", string(jsonData)) } + var opts []option.RequestOption + if a.isThinkingEnabled() { + opts = append(opts, option.WithHeaderAdd("anthropic-beta", "interleaved-thinking-2025-05-14")) + } + anthropicStream := a.client.Messages.NewStreaming( ctx, preparedMessages, - option.WithHeaderAdd("anthropic-beta", "interleaved-thinking-2025-05-14"), + opts..., ) accumulatedMessage := anthropic.Message{} From 078a62c2a73c6c71c55e3b6fcbf7d4174a32e318 Mon Sep 17 00:00:00 2001 From: Kujtim Hoxha Date: Sat, 19 Jul 2025 12:52:25 +0200 Subject: [PATCH 2/2] chore: remove thinking when done --- internal/tui/components/chat/messages/messages.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/tui/components/chat/messages/messages.go b/internal/tui/components/chat/messages/messages.go index bff149c72807f637a58a6d14878b3ac209f05541..ada7170e455e1a106b95d734f024164037ebd82f 100644 --- a/internal/tui/components/chat/messages/messages.go +++ b/internal/tui/components/chat/messages/messages.go @@ -263,7 +263,7 @@ func (m *messageCmp) renderThinkingContent() string { Description: duration.String(), NoIcon: true, } - footer = t.S().Base.PaddingLeft(1).Render(core.Status(opts, m.textWidth()-1)) + return 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 {