feat(providers): allow xhigh/max reasoning_effort on the OpenAI-compatible path

The per-agent options builder only emitted WithReasoning for low/medium/high,
and the langchaingo fork clamped xhigh/max to high in GetEffort (treating them
as adaptive-only). OpenAI GPT-5.5 and GLM-5.2 now expose xhigh/max as real
reasoning_effort levels, so that clamp encodes a stale invariant.

Extend the effort switch to pass xhigh/max through; the fork's GetEffort clamp
is removed in the local langchaingo (propagated via vendor) so the OpenAI
transport emits the real level. Adaptive (anthropic/bedrock) and budget paths
are unaffected — GetEffort is called only by the OpenAI transport. Validity is
gated per model by ModelReasoningInfo.Efforts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Sergey Kozyrenko
2026-06-26 02:18:57 +07:00
co-authored by Claude Sonnet 4.6
parent 40debd150d
commit a69e19f751
2 changed files with 38 additions and 1 deletions
+1 -1
View File
@@ -724,7 +724,7 @@ func (ac *AgentConfig) BuildOptions() []llms.CallOption {
}
default:
switch ac.Reasoning.Effort {
case llms.ReasoningLow, llms.ReasoningMedium, llms.ReasoningHigh:
case llms.ReasoningLow, llms.ReasoningMedium, llms.ReasoningHigh, llms.ReasoningXHigh, llms.ReasoningMax:
options = append(options, llms.WithReasoning(ac.Reasoning.Effort, 0))
}
}
@@ -0,0 +1,37 @@
package pconfig
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/vxcontrol/langchaingo/llms"
"gopkg.in/yaml.v3"
)
func TestReasoningConfig_GetEffortPreservesXHighAndMax(t *testing.T) {
for _, effort := range []llms.ReasoningEffort{llms.ReasoningXHigh, llms.ReasoningMax} {
rc := llms.ReasoningConfig{Effort: effort}
if got := rc.GetEffort(8192); got != effort {
t.Errorf("GetEffort(effort=%q) = %q, want %q: the xhigh/max clamp must stay removed so OpenAI-compatible reasoning_effort carries the real level", effort, got, effort)
}
}
}
func TestProviderConfig_EmitsTopReasoningEffortOnEffortPath(t *testing.T) {
for _, effort := range []string{"low", "medium", "high", "xhigh", "max"} {
t.Run(effort, func(t *testing.T) {
var ac AgentConfig
require.NoError(t, yaml.Unmarshal([]byte("model: gpt-5.5\nreasoning:\n effort: "+effort+"\n"), &ac))
pc := &ProviderConfig{Simple: &ac}
var applied llms.CallOptions
for _, opt := range pc.GetOptionsForType(OptionsTypeSimple) {
opt(&applied)
}
require.NotNil(t, applied.Reasoning, "effort %q must emit a reasoning option on the non-adaptive path", effort)
assert.Equal(t, llms.ReasoningEffort(effort), applied.Reasoning.Effort, "the configured effort must reach the call options unchanged")
})
}
}