mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-10-17 04:55:19 +08:00
75 lines
3.8 KiB
Go
75 lines
3.8 KiB
Go
package helps_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/router-for-me/CLIProxyAPI/v8/internal/registry"
|
|
helps "github.com/router-for-me/CLIProxyAPI/v8/internal/runtime/executor/helps"
|
|
_ "github.com/router-for-me/CLIProxyAPI/v8/internal/thinking/provider/claude"
|
|
_ "github.com/router-for-me/CLIProxyAPI/v8/internal/thinking/provider/codex"
|
|
_ "github.com/router-for-me/CLIProxyAPI/v8/internal/translator"
|
|
cliproxyexecutor "github.com/router-for-me/CLIProxyAPI/v8/sdk/cliproxy/executor"
|
|
sdktranslator "github.com/router-for-me/CLIProxyAPI/v8/sdk/translator"
|
|
"github.com/tidwall/gjson"
|
|
"github.com/tidwall/sjson"
|
|
)
|
|
|
|
type editUpdatePluginHooks struct {
|
|
summaryRemovingPluginHooks
|
|
effort string
|
|
}
|
|
|
|
func (h *editUpdatePluginHooks) NormalizeRequest(_ context.Context, _, _ sdktranslator.Format, _ string, body []byte, _ bool) []byte {
|
|
if h.effort == "" {
|
|
out, _ := sjson.DeleteBytes(body, "input.0")
|
|
return out
|
|
}
|
|
out, _ := sjson.SetBytes(body, "input.0.reasoning.effort", h.effort)
|
|
return out
|
|
}
|
|
|
|
func TestPluginConfigurationUpdateNormalizationIsAuthoritative(t *testing.T) {
|
|
const source = `{"reasoning":{"effort":"medium"},"input":[{"type":"configuration_update","reasoning":{"effort":"low"}},{"role":"user","content":"hi"}]}`
|
|
for _, tc := range []struct{ name, edit, want string }{
|
|
{name: "delete", want: "medium"},
|
|
{name: "rewrite", edit: "high", want: "high"},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
sdktranslator.SetPluginHooks(&editUpdatePluginHooks{effort: tc.edit})
|
|
t.Cleanup(func() { sdktranslator.SetPluginHooks(nil) })
|
|
translated := sdktranslator.TranslateRequestEnvelope(t.Context(), sdktranslator.FormatOpenAIResponse, sdktranslator.FormatCodex, sdktranslator.RequestEnvelope{Model: "opaque-route", Body: []byte(source)})
|
|
if !translated.ConfigurationUpdatesChanged {
|
|
t.Fatal("plugin update edit not reported by translator")
|
|
}
|
|
req := cliproxyexecutor.Request{Model: "opaque-route", Payload: []byte(source), Metadata: map[string]any{"cliproxy.resolved_api_key_model_info": ®istry.ModelInfo{ID: "opaque-route", Thinking: ®istry.ThinkingSupport{Levels: []string{"low", "medium", "high"}}}}}
|
|
body, errApply := helps.ApplyRequestThinking(translated.Body, req, cliproxyexecutor.Options{}, "openai-response", "codex", "codex", translated.ConfigurationUpdatesChanged)
|
|
if errApply != nil {
|
|
t.Fatal(errApply)
|
|
}
|
|
if got := gjson.GetBytes(body, "reasoning.effort").String(); got != tc.want {
|
|
t.Fatalf("effort = %q, want %q; body=%s", got, tc.want, body)
|
|
}
|
|
if len(gjson.GetBytes(body, "input").Array()) != 1 {
|
|
t.Fatalf("unexpected input: %s", body)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNativeCrossProtocolTranslationWithoutPluginRetainsSourceUpdate(t *testing.T) {
|
|
const source = `{"model":"private-chat","reasoning":{"effort":"medium"},"input":[{"type":"configuration_update","reasoning":{"effort":"high"}},{"role":"user","content":"hi"}]}`
|
|
translated := sdktranslator.TranslateRequestEnvelope(t.Context(), sdktranslator.FormatOpenAIResponse, sdktranslator.FormatOpenAI, sdktranslator.RequestEnvelope{Model: "private-chat", Body: []byte(source)})
|
|
if translated.ConfigurationUpdatesChanged {
|
|
t.Fatal("native translation was incorrectly reported as a plugin edit")
|
|
}
|
|
req := cliproxyexecutor.Request{Model: "private-chat", Payload: []byte(source), Metadata: map[string]any{"cliproxy.resolved_api_key_model_info": ®istry.ModelInfo{ID: "private-chat", Thinking: ®istry.ThinkingSupport{Levels: []string{"low", "medium", "high"}}}}}
|
|
body, errApply := helps.ApplyRequestThinking(translated.Body, req, cliproxyexecutor.Options{}, "openai-response", "openai", "openai", translated.ConfigurationUpdatesChanged)
|
|
if errApply != nil {
|
|
t.Fatal(errApply)
|
|
}
|
|
if got := gjson.GetBytes(body, "reasoning_effort").String(); got != "high" {
|
|
t.Fatalf("cross-protocol effort = %q, want high; body=%s", got, body)
|
|
}
|
|
}
|