mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-19 21:00:52 +08:00
feat: introduce custom provider example and remove redundant debug logs
- Added `examples/custom-provider/main.go` showcasing custom executor and translator integration using the SDK. - Removed redundant debug logs from translator modules to enhance code cleanliness. - Updated SDK documentation with new usage and advanced examples. - Expanded the management API with new endpoints, including request logging and GPT-5 Codex features.
This commit is contained in:
@@ -12,7 +12,6 @@ import (
|
||||
|
||||
client "github.com/router-for-me/CLIProxyAPI/v6/internal/interfaces"
|
||||
"github.com/router-for-me/CLIProxyAPI/v6/internal/util"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
)
|
||||
@@ -29,7 +28,6 @@ import (
|
||||
// Returns:
|
||||
// - []byte: The transformed request in Gemini CLI format.
|
||||
func ConvertClaudeRequestToGemini(modelName string, inputRawJSON []byte, _ bool) []byte {
|
||||
log.Debug("ConvertClaudeRequestToGemini")
|
||||
rawJSON := bytes.Clone(inputRawJSON)
|
||||
var pathsToDelete []string
|
||||
root := gjson.ParseBytes(rawJSON)
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
)
|
||||
@@ -42,7 +41,6 @@ type Params struct {
|
||||
// Returns:
|
||||
// - []string: A slice of strings, each containing a Claude-compatible JSON response.
|
||||
func ConvertGeminiResponseToClaude(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string {
|
||||
log.Debug("ConvertGeminiResponseToClaude")
|
||||
if *param == nil {
|
||||
*param = &Params{
|
||||
IsGlAPIKey: false,
|
||||
@@ -248,6 +246,5 @@ func ConvertGeminiResponseToClaude(_ context.Context, _ string, originalRequestR
|
||||
// Returns:
|
||||
// - string: A Claude-compatible JSON response.
|
||||
func ConvertGeminiResponseToClaudeNonStream(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, _ []byte, _ *any) string {
|
||||
log.Debug("ConvertGeminiResponseToClaudeNonStream")
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ import (
|
||||
// It extracts the model name, system instruction, message contents, and tool declarations
|
||||
// from the raw JSON request and returns them in the format expected by the internal client.
|
||||
func ConvertGeminiCLIRequestToGemini(_ string, inputRawJSON []byte, _ bool) []byte {
|
||||
log.Debug("ConvertGeminiCLIRequestToGemini")
|
||||
rawJSON := bytes.Clone(inputRawJSON)
|
||||
modelResult := gjson.GetBytes(rawJSON, "model")
|
||||
rawJSON = []byte(gjson.GetBytes(rawJSON, "request").Raw)
|
||||
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
// Returns:
|
||||
// - []string: A slice of strings, each containing a Gemini CLI-compatible JSON response.
|
||||
func ConvertGeminiResponseToGeminiCLI(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, _ *any) []string {
|
||||
log.Debug("ConvertGeminiResponseToGeminiCLI")
|
||||
if bytes.Equal(rawJSON, []byte("[DONE]")) {
|
||||
return []string{}
|
||||
}
|
||||
@@ -46,7 +45,6 @@ func ConvertGeminiResponseToGeminiCLI(_ context.Context, _ string, originalReque
|
||||
// Returns:
|
||||
// - string: A Gemini CLI-compatible JSON response.
|
||||
func ConvertGeminiResponseToGeminiCLINonStream(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, _ *any) string {
|
||||
log.Debug("ConvertGeminiResponseToGeminiCLINonStream")
|
||||
json := `{"response": {}}`
|
||||
rawJSON, _ = sjson.SetRawBytes([]byte(json), "response", rawJSON)
|
||||
return string(rawJSON)
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
//
|
||||
// It keeps the payload otherwise unchanged.
|
||||
func ConvertGeminiRequestToGemini(_ string, inputRawJSON []byte, _ bool) []byte {
|
||||
log.Debug("ConvertClaudeRequestToGemini")
|
||||
rawJSON := bytes.Clone(inputRawJSON)
|
||||
// Fast path: if no contents field, return as-is
|
||||
contents := gjson.GetBytes(rawJSON, "contents")
|
||||
|
||||
@@ -9,8 +9,6 @@ import (
|
||||
|
||||
// PassthroughGeminiResponseStream forwards Gemini responses unchanged.
|
||||
func PassthroughGeminiResponseStream(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, _ *any) []string {
|
||||
log.Debug("PassthroughGeminiResponseStream")
|
||||
|
||||
if bytes.HasPrefix(rawJSON, []byte("data:")) {
|
||||
rawJSON = bytes.TrimSpace(rawJSON[5:])
|
||||
}
|
||||
@@ -24,6 +22,5 @@ func PassthroughGeminiResponseStream(_ context.Context, _ string, originalReques
|
||||
|
||||
// PassthroughGeminiResponseNonStream forwards Gemini responses unchanged.
|
||||
func PassthroughGeminiResponseNonStream(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, _ *any) string {
|
||||
log.Debug("PassthroughGeminiResponseNonStream")
|
||||
return string(rawJSON)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
// Returns:
|
||||
// - []byte: The transformed request data in Gemini API format
|
||||
func ConvertOpenAIRequestToGemini(modelName string, inputRawJSON []byte, _ bool) []byte {
|
||||
log.Debug("ConvertOpenAIRequestToGemini")
|
||||
rawJSON := bytes.Clone(inputRawJSON)
|
||||
// Base envelope
|
||||
out := []byte(`{"contents":[],"generationConfig":{"thinkingConfig":{"include_thoughts":true}}}`)
|
||||
|
||||
@@ -37,7 +37,6 @@ type convertGeminiResponseToOpenAIChatParams struct {
|
||||
// Returns:
|
||||
// - []string: A slice of strings, each containing an OpenAI-compatible JSON response
|
||||
func ConvertGeminiResponseToOpenAI(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string {
|
||||
log.Debug("ConvertGeminiResponseToOpenAI")
|
||||
if *param == nil {
|
||||
*param = &convertGeminiResponseToOpenAIChatParams{
|
||||
UnixTimestamp: 0,
|
||||
@@ -180,7 +179,6 @@ func ConvertGeminiResponseToOpenAI(_ context.Context, _ string, originalRequestR
|
||||
// Returns:
|
||||
// - string: An OpenAI-compatible JSON response containing all message content and metadata
|
||||
func ConvertGeminiResponseToOpenAINonStream(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, _ *any) string {
|
||||
log.Debug("ConvertGeminiResponseToOpenAINonStream")
|
||||
var unixTimestamp int64
|
||||
template := `{"id":"","object":"chat.completion","created":123456,"model":"model","choices":[{"index":0,"message":{"role":"assistant","content":null,"reasoning_content":null,"tool_calls":null},"finish_reason":null,"native_finish_reason":null}]}`
|
||||
if modelVersionResult := gjson.GetBytes(rawJSON, "modelVersion"); modelVersionResult.Exists() {
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
)
|
||||
|
||||
func ConvertOpenAIResponsesRequestToGemini(modelName string, inputRawJSON []byte, stream bool) []byte {
|
||||
log.Debug("ConvertOpenAIResponsesRequestToGemini")
|
||||
rawJSON := bytes.Clone(inputRawJSON)
|
||||
|
||||
// Note: modelName and stream parameters are part of the fixed method signature
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
)
|
||||
@@ -44,7 +43,6 @@ func emitEvent(event string, payload string) string {
|
||||
|
||||
// ConvertGeminiResponseToOpenAIResponses converts Gemini SSE chunks into OpenAI Responses SSE events.
|
||||
func ConvertGeminiResponseToOpenAIResponses(_ context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string {
|
||||
log.Debug("ConvertGeminiResponseToOpenAIResponses")
|
||||
if *param == nil {
|
||||
*param = &geminiToResponsesState{
|
||||
FuncArgsBuf: make(map[int]*strings.Builder),
|
||||
@@ -424,7 +422,6 @@ func ConvertGeminiResponseToOpenAIResponses(_ context.Context, modelName string,
|
||||
|
||||
// ConvertGeminiResponseToOpenAIResponsesNonStream aggregates Gemini response JSON into a single OpenAI Responses JSON object.
|
||||
func ConvertGeminiResponseToOpenAIResponsesNonStream(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, _ *any) string {
|
||||
log.Debug("ConvertGeminiResponseToOpenAIResponsesNonStream")
|
||||
root := gjson.ParseBytes(rawJSON)
|
||||
|
||||
// Base response scaffold
|
||||
|
||||
Reference in New Issue
Block a user