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:
Luis Pater
2025-09-22 03:37:53 +08:00
parent d5ad5fab87
commit f81898c906
54 changed files with 907 additions and 101 deletions

View File

@@ -12,7 +12,6 @@ import (
"strings"
"github.com/router-for-me/CLIProxyAPI/v6/internal/misc"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
@@ -36,7 +35,6 @@ import (
// Returns:
// - []byte: The transformed request data in internal client format
func ConvertClaudeRequestToCodex(modelName string, inputRawJSON []byte, _ bool) []byte {
log.Debug("ConvertClaudeRequestToCodex")
rawJSON := bytes.Clone(inputRawJSON)
template := `{"model":"","instructions":"","input":[]}`

View File

@@ -11,7 +11,6 @@ import (
"context"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
@@ -37,7 +36,6 @@ var (
// Returns:
// - []string: A slice of strings, each containing a Claude Code-compatible JSON response
func ConvertCodexResponseToClaude(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string {
log.Debug("ConvertCodexResponseToClaude")
if *param == nil {
hasToolCall := false
*param = &hasToolCall
@@ -179,7 +177,6 @@ func ConvertCodexResponseToClaude(_ context.Context, _ string, originalRequestRa
// Returns:
// - string: A Claude Code-compatible JSON response containing all message content and metadata
func ConvertCodexResponseToClaudeNonStream(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, _ []byte, _ *any) string {
log.Debug("ConvertCodexResponseToClaudeNonStream")
return ""
}

View File

@@ -9,7 +9,6 @@ import (
"bytes"
. "github.com/router-for-me/CLIProxyAPI/v6/internal/translator/codex/gemini"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
@@ -31,7 +30,6 @@ import (
// Returns:
// - []byte: The transformed request data in Codex API format
func ConvertGeminiCLIRequestToCodex(modelName string, inputRawJSON []byte, stream bool) []byte {
log.Debug("ConvertGeminiRequestToCodex")
rawJSON := bytes.Clone(inputRawJSON)
rawJSON = []byte(gjson.GetBytes(rawJSON, "request").Raw)

View File

@@ -8,7 +8,6 @@ import (
"context"
. "github.com/router-for-me/CLIProxyAPI/v6/internal/translator/codex/gemini"
log "github.com/sirupsen/logrus"
"github.com/tidwall/sjson"
)
@@ -26,7 +25,6 @@ import (
// Returns:
// - []string: A slice of strings, each containing a Gemini-compatible JSON response wrapped in a response object
func ConvertCodexResponseToGeminiCLI(ctx context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string {
log.Debug("ConvertCodexResponseToGeminiCLI")
outputs := ConvertCodexResponseToGemini(ctx, modelName, originalRequestRawJSON, requestRawJSON, rawJSON, param)
newOutputs := make([]string, 0)
for i := 0; i < len(outputs); i++ {
@@ -50,7 +48,6 @@ func ConvertCodexResponseToGeminiCLI(ctx context.Context, modelName string, orig
// Returns:
// - string: A Gemini-compatible JSON response wrapped in a response object
func ConvertCodexResponseToGeminiCLINonStream(ctx context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) string {
log.Debug("ConvertCodexResponseToGeminiCLINonStream")
// log.Debug(string(rawJSON))
strJSON := ConvertCodexResponseToGeminiNonStream(ctx, modelName, originalRequestRawJSON, requestRawJSON, rawJSON, param)
json := `{"response": {}}`

View File

@@ -15,7 +15,6 @@ import (
"github.com/router-for-me/CLIProxyAPI/v6/internal/misc"
"github.com/router-for-me/CLIProxyAPI/v6/internal/util"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
@@ -38,7 +37,6 @@ import (
// Returns:
// - []byte: The transformed request data in Codex API format
func ConvertGeminiRequestToCodex(modelName string, inputRawJSON []byte, _ bool) []byte {
log.Debug("ConvertGeminiRequestToCodex")
rawJSON := bytes.Clone(inputRawJSON)
// Base template
out := `{"model":"","instructions":"","input":[]}`

View File

@@ -11,7 +11,6 @@ import (
"encoding/json"
"time"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
@@ -42,7 +41,6 @@ type ConvertCodexResponseToGeminiParams struct {
// Returns:
// - []string: A slice of strings, each containing a Gemini-compatible JSON response
func ConvertCodexResponseToGemini(_ context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string {
log.Debug("ConvertCodexResponseToGemini")
if *param == nil {
*param = &ConvertCodexResponseToGeminiParams{
Model: modelName,
@@ -154,7 +152,6 @@ func ConvertCodexResponseToGemini(_ context.Context, modelName string, originalR
// Returns:
// - string: A Gemini-compatible JSON response containing all message content and metadata
func ConvertCodexResponseToGeminiNonStream(_ context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, _ *any) string {
log.Debug("ConvertCodexResponseToGeminiNonStream")
scanner := bufio.NewScanner(bytes.NewReader(rawJSON))
buffer := make([]byte, 10240*1024)
scanner.Buffer(buffer, 10240*1024)

View File

@@ -13,7 +13,6 @@ import (
"strings"
"github.com/router-for-me/CLIProxyAPI/v6/internal/misc"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
@@ -31,7 +30,6 @@ import (
// Returns:
// - []byte: The transformed request data in OpenAI Responses API format
func ConvertOpenAIRequestToCodex(modelName string, inputRawJSON []byte, stream bool) []byte {
log.Debug("ConvertOpenAIRequestToCodex")
rawJSON := bytes.Clone(inputRawJSON)
// Start with empty JSON object
out := `{}`

View File

@@ -11,7 +11,6 @@ import (
"context"
"time"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
@@ -43,7 +42,6 @@ type ConvertCliToOpenAIParams struct {
// Returns:
// - []string: A slice of strings, each containing an OpenAI-compatible JSON response
func ConvertCodexResponseToOpenAI(_ context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string {
log.Debug("ConvertCodexResponseToOpenAI")
if *param == nil {
*param = &ConvertCliToOpenAIParams{
Model: modelName,
@@ -168,7 +166,6 @@ func ConvertCodexResponseToOpenAI(_ context.Context, modelName string, originalR
// Returns:
// - string: An OpenAI-compatible JSON response containing all message content and metadata
func ConvertCodexResponseToOpenAINonStream(_ context.Context, _ string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, _ *any) string {
log.Debug("ConvertCodexResponseToOpenAINonStream")
scanner := bufio.NewScanner(bytes.NewReader(rawJSON))
buffer := make([]byte, 10240*1024)
scanner.Buffer(buffer, 10240*1024)

View File

@@ -4,13 +4,11 @@ import (
"bytes"
"github.com/router-for-me/CLIProxyAPI/v6/internal/misc"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
func ConvertOpenAIResponsesRequestToCodex(modelName string, inputRawJSON []byte, _ bool) []byte {
log.Debug("ConvertOpenAIResponsesRequestToCodex")
rawJSON := bytes.Clone(inputRawJSON)
rawJSON, _ = sjson.SetBytes(rawJSON, "stream", true)

View File

@@ -6,7 +6,6 @@ import (
"context"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)
@@ -14,7 +13,6 @@ import (
// ConvertCodexResponseToOpenAIResponses converts OpenAI Chat Completions streaming chunks
// to OpenAI Responses SSE events (response.*).
func ConvertCodexResponseToOpenAIResponses(ctx context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string {
log.Debug("ConvertCodexResponseToOpenAIResponses")
if bytes.HasPrefix(rawJSON, []byte("data:")) {
rawJSON = bytes.TrimSpace(rawJSON[5:])
if typeResult := gjson.GetBytes(rawJSON, "type"); typeResult.Exists() {
@@ -31,7 +29,6 @@ func ConvertCodexResponseToOpenAIResponses(ctx context.Context, modelName string
// ConvertCodexResponseToOpenAIResponsesNonStream builds a single Responses JSON
// from a non-streaming OpenAI Chat Completions response.
func ConvertCodexResponseToOpenAIResponsesNonStream(_ context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, _ *any) string {
log.Debug("ConvertCodexResponseToOpenAIResponsesNonStream")
scanner := bufio.NewScanner(bytes.NewReader(rawJSON))
buffer := make([]byte, 10240*1024)
scanner.Buffer(buffer, 10240*1024)