Description
Bug
When ToolChoiceNone is set, the Anthropic provider's toTools function returns nil for anthropicToolChoice instead of setting OfNone on the ToolChoiceUnionParam. The caller checks if toolChoice != nil before assigning to params.ToolChoice, so tool_choice: {type: "none"} is never included in the API request. The Anthropic API defaults to auto, meaning the model may still call tools — the opposite of the intended behavior.
Where
providers/anthropic/anthropic.go, in the toTools method:
case fantasy.ToolChoiceNone:
return anthropicTools, anthropicToolChoice, warnings // anthropicToolChoice is nil
The caller at the prepareParams level:
if toolChoice != nil {
params.ToolChoice = *toolChoice
}
Since toolChoice is nil, params.ToolChoice is never set.
Expected
The ToolChoiceNone case should set OfNone using the SDK's constructor:
case fantasy.ToolChoiceNone:
none := anthropic.NewToolChoiceNoneParam()
anthropicToolChoice = &anthropic.ToolChoiceUnionParam{
OfNone: &none,
}
The Anthropic Go SDK already supports ToolChoiceNoneParam — it just isn't wired up.
How we found it
We're building logos, a Bash-only reasoning engine on top of fantasy. LLMs think in plain text and act with ! rg main.go commands — no tool call at all. Since logos intentionally has no tools, we use ToolChoiceNone to explicitly enforce that the model never attempts tool calls. We discovered the model was still making tool calls on the Anthropic provider despite ToolChoiceNone being set, and traced it to this nil return.
Other providers
- OpenAI provider handles this correctly — sets
OfAuto with value "none"
- Google provider handles this correctly
- Anthropic provider is the only one that returns nil for
ToolChoiceNone
Version
v0.14.0
Environment
linux, macos
Description
Bug
When
ToolChoiceNoneis set, the Anthropic provider'stoToolsfunction returnsnilforanthropicToolChoiceinstead of settingOfNoneon theToolChoiceUnionParam. The caller checksif toolChoice != nilbefore assigning toparams.ToolChoice, sotool_choice: {type: "none"}is never included in the API request. The Anthropic API defaults toauto, meaning the model may still call tools — the opposite of the intended behavior.Where
providers/anthropic/anthropic.go, in thetoToolsmethod:The caller at the
prepareParamslevel:Since
toolChoiceisnil,params.ToolChoiceis never set.Expected
The
ToolChoiceNonecase should setOfNoneusing the SDK's constructor:The Anthropic Go SDK already supports
ToolChoiceNoneParam— it just isn't wired up.How we found it
We're building logos, a Bash-only reasoning engine on top of fantasy. LLMs think in plain text and act with
! rg main.gocommands — no tool call at all. Since logos intentionally has no tools, we useToolChoiceNoneto explicitly enforce that the model never attempts tool calls. We discovered the model was still making tool calls on the Anthropic provider despiteToolChoiceNonebeing set, and traced it to this nil return.Other providers
OfAutowith value"none"ToolChoiceNoneVersion
v0.14.0
Environment
linux, macos