mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-05-31 20:02:36 +08:00
feat(thinking): add xAI provider support with reasoning.effort implementation
- Implemented `xAI` provider for thinking configurations with support for reasoning.effort levels. - Registered `xAI` in available providers and updated relevant APIs for compatibility. - Added unit tests for `xAI` provider functionality, including fallback logic for unsupported levels. - Integrated `xAI` with executor handling and ensured conformance with OpenAI-compatible standards.
This commit is contained in:
@@ -8,4 +8,5 @@ import (
|
||||
_ "github.com/router-for-me/CLIProxyAPI/v7/internal/thinking/provider/geminicli"
|
||||
_ "github.com/router-for-me/CLIProxyAPI/v7/internal/thinking/provider/kimi"
|
||||
_ "github.com/router-for-me/CLIProxyAPI/v7/internal/thinking/provider/openai"
|
||||
_ "github.com/router-for-me/CLIProxyAPI/v7/internal/thinking/provider/xai"
|
||||
)
|
||||
|
||||
@@ -487,7 +487,7 @@ func (e *XAIExecutor) prepareResponsesRequest(ctx context.Context, req cliproxye
|
||||
body := sdktranslator.TranslateRequest(from, to, baseModel, bytes.Clone(req.Payload), stream)
|
||||
|
||||
var err error
|
||||
body, err = thinking.ApplyThinking(body, req.Model, from.String(), to.String(), e.Identifier())
|
||||
body, err = thinking.ApplyThinking(body, req.Model, from.String(), e.Identifier(), e.Identifier())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -196,6 +196,48 @@ func TestXAIExecutorOmitsUnsupportedReasoningEffort(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestXAIExecutorAppliesThinkingSuffix(t *testing.T) {
|
||||
var gotBody []byte
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var errRead error
|
||||
gotBody, errRead = io.ReadAll(r.Body)
|
||||
if errRead != nil {
|
||||
t.Fatalf("read body: %v", errRead)
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
_, _ = w.Write([]byte("data: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_1\",\"object\":\"response\",\"created_at\":0,\"status\":\"completed\",\"model\":\"grok-4.3\",\"output\":[{\"type\":\"message\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"ok\"}]}]}}\n\n"))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
exec := NewXAIExecutor(&config.Config{})
|
||||
auth := &cliproxyauth.Auth{
|
||||
Provider: "xai",
|
||||
Attributes: map[string]string{
|
||||
"base_url": server.URL,
|
||||
"auth_kind": "oauth",
|
||||
},
|
||||
Metadata: map[string]any{"access_token": "xai-token"},
|
||||
}
|
||||
|
||||
_, err := exec.Execute(context.Background(), auth, cliproxyexecutor.Request{
|
||||
Model: "grok-4.3(low)",
|
||||
Payload: []byte(`{"model":"grok-4.3","input":"hello"}`),
|
||||
}, cliproxyexecutor.Options{
|
||||
SourceFormat: sdktranslator.FormatOpenAIResponse,
|
||||
Stream: false,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Execute() error = %v", err)
|
||||
}
|
||||
|
||||
if got := gjson.GetBytes(gotBody, "model").String(); got != "grok-4.3" {
|
||||
t.Fatalf("model = %q, want grok-4.3; body=%s", got, string(gotBody))
|
||||
}
|
||||
if got := gjson.GetBytes(gotBody, "reasoning.effort").String(); got != "low" {
|
||||
t.Fatalf("reasoning.effort = %q, want low; body=%s", got, string(gotBody))
|
||||
}
|
||||
}
|
||||
|
||||
func TestXAIExecutorExecuteStreamFiltersToolSearchTool(t *testing.T) {
|
||||
var gotBody []byte
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user