mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-09-08 10:46:58 +00:00
* feat(relaykit): preserve hosted tools across conversions - add protocol-neutral hosted-tool DTOs, conversion metadata, and loss policies - bridge citations, grounding metadata, and hosted-tool stream lifecycles - document the public conversion behavior and channel policy controls * refactor(relaykit): normalize reasoning and thinking intent - centralize provider-neutral reasoning intent, effort, and budget mappings - parse model suffixes at the host entry boundary while preserving provider-owned tails - keep adaptive Claude thinking and explicit zero-token compatibility consistent * fix(billing): preserve authoritative usage across relay hops - carry native BillingUsage sidecars through direct and streamed protocol bridges - merge partial and terminal usage monotonically with safe fallback settlement - retain cache metadata, penultimate usage, and per-call Gemini tool surcharges * feat(relay): bridge Responses with Claude and Gemini protocols - add direct request, response, and stream converters across supported relay formats - expose Claude count_tokens and Chat-to-Responses compatibility endpoints - carry conversion diagnostics through the host while retaining the curated public goldens * fix(relay): wire relaykit conversions into host channels - connect handlers, adaptors, and channel settings to the standalone conversion layer - keep model mapping, pricing identity, retries, and provider-specific suffix behavior aligned - ignore local audit artifacts and retain focused public regression coverage
126 lines
3.4 KiB
Go
126 lines
3.4 KiB
Go
package reasoning
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestMergeExplicitAndSuffix(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
budget1024 := 1024
|
|
budget2048 := 2048
|
|
|
|
tests := []struct {
|
|
name string
|
|
explicit Intent
|
|
suffix Intent
|
|
wantErr bool
|
|
wantMode Mode
|
|
wantEffort Effort
|
|
wantBudget *int
|
|
wantThoughts *bool
|
|
}{
|
|
{
|
|
name: "enabled plus matching effort merges",
|
|
explicit: Intent{Mode: ModeEnabled, Effort: EffortHigh},
|
|
suffix: Intent{Mode: ModeEnabled, Effort: EffortHigh, Source: SourceSuffix},
|
|
wantMode: ModeEnabled,
|
|
wantEffort: EffortHigh,
|
|
},
|
|
{
|
|
name: "enabled vs disabled conflict",
|
|
explicit: Intent{Mode: ModeEnabled, Effort: EffortHigh},
|
|
suffix: Intent{Mode: ModeDisabled, Effort: EffortNone, Source: SourceSuffix},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "different efforts conflict",
|
|
explicit: Intent{Mode: ModeEnabled, Effort: EffortLow},
|
|
suffix: Intent{Mode: ModeEnabled, Effort: EffortHigh, Source: SourceSuffix},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "different budgets conflict",
|
|
explicit: Intent{BudgetTokens: &budget1024},
|
|
suffix: Intent{BudgetTokens: &budget2048, Source: SourceSuffix, BudgetSource: SourceSuffix},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "effort versus exact suffix budget conflict",
|
|
explicit: Intent{Mode: ModeEnabled, Effort: EffortHigh},
|
|
suffix: Intent{BudgetTokens: &budget1024, Source: SourceSuffix, BudgetSource: SourceSuffix},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "suffix only is adopted",
|
|
suffix: Intent{Mode: ModeEnabled, Effort: EffortMedium, Source: SourceSuffix},
|
|
wantMode: ModeEnabled,
|
|
wantEffort: EffortMedium,
|
|
wantThoughts: nil,
|
|
},
|
|
{
|
|
name: "explicit include thoughts overlays empty suffix strength",
|
|
explicit: Intent{IncludeThoughts: boolPtr(false)},
|
|
suffix: Intent{Mode: ModeEnabled, Effort: EffortLow, Source: SourceSuffix},
|
|
wantMode: ModeEnabled,
|
|
wantEffort: EffortLow,
|
|
wantThoughts: boolPtr(false),
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
got, err := MergeExplicitAndSuffix(tt.explicit, tt.suffix, "claude-opus-4-8")
|
|
if tt.wantErr {
|
|
require.Error(t, err)
|
|
assert.ErrorIs(t, err, ErrEffortConflict)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.wantMode, got.Mode)
|
|
assert.Equal(t, tt.wantEffort, got.Effort)
|
|
if tt.wantBudget != nil {
|
|
require.NotNil(t, got.BudgetTokens)
|
|
assert.Equal(t, *tt.wantBudget, *got.BudgetTokens)
|
|
}
|
|
if tt.wantThoughts != nil {
|
|
require.NotNil(t, got.IncludeThoughts)
|
|
assert.Equal(t, *tt.wantThoughts, *got.IncludeThoughts)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIntentStateRoundTrip(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
budget := 4096
|
|
include := true
|
|
intent := Intent{
|
|
Mode: ModeEnabled,
|
|
Effort: EffortHigh,
|
|
BudgetTokens: &budget,
|
|
IncludeThoughts: &include,
|
|
}
|
|
|
|
state := StateFromIntent(intent)
|
|
require.NotNil(t, state)
|
|
got := IntentFromState(state)
|
|
assert.Equal(t, intent.Mode, got.Mode)
|
|
assert.Equal(t, intent.Effort, got.Effort)
|
|
require.NotNil(t, got.BudgetTokens)
|
|
assert.Equal(t, budget, *got.BudgetTokens)
|
|
require.NotNil(t, got.IncludeThoughts)
|
|
assert.True(t, *got.IncludeThoughts)
|
|
assert.True(t, IntentFromState(nil).IsEmpty())
|
|
assert.Nil(t, StateFromIntent(Intent{}))
|
|
}
|
|
|
|
func boolPtr(v bool) *bool {
|
|
return &v
|
|
}
|