feat(translator): add user metadata generation for Claude transformation requests

- Introduced unique `user_id` metadata generation in OpenAI to Claude transformation functions.
- Utilized `uuid` and `sha256` for deterministic `account`, `session`, and `user` values.
- Embedded `user_id` into request payloads to enhance request tracking and identification.
This commit is contained in:
Luis Pater
2025-09-26 22:47:21 +08:00
parent 4fd95ead3b
commit 6d4b43dd7a
4 changed files with 77 additions and 5 deletions

File diff suppressed because one or more lines are too long

View File

@@ -8,15 +8,24 @@ package gemini
import ( import (
"bytes" "bytes"
"crypto/rand" "crypto/rand"
"crypto/sha256"
"encoding/hex"
"fmt" "fmt"
"math/big" "math/big"
"strings" "strings"
"github.com/google/uuid"
"github.com/router-for-me/CLIProxyAPI/v6/internal/util" "github.com/router-for-me/CLIProxyAPI/v6/internal/util"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
"github.com/tidwall/sjson" "github.com/tidwall/sjson"
) )
var (
user = ""
account = ""
session = ""
)
// ConvertGeminiRequestToClaude parses and transforms a Gemini API request into Claude Code API format. // ConvertGeminiRequestToClaude parses and transforms a Gemini API request into Claude Code API format.
// It extracts the model name, system instruction, message contents, and tool declarations // 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 Claude Code API. // from the raw JSON request and returns them in the format expected by the Claude Code API.
@@ -37,8 +46,23 @@ import (
// - []byte: The transformed request data in Claude Code API format // - []byte: The transformed request data in Claude Code API format
func ConvertGeminiRequestToClaude(modelName string, inputRawJSON []byte, stream bool) []byte { func ConvertGeminiRequestToClaude(modelName string, inputRawJSON []byte, stream bool) []byte {
rawJSON := bytes.Clone(inputRawJSON) rawJSON := bytes.Clone(inputRawJSON)
// Base Claude Code API template with default max_tokens value
out := `{"model":"","max_tokens":32000,"messages":[]}` if account == "" {
u, _ := uuid.NewRandom()
account = u.String()
}
if session == "" {
u, _ := uuid.NewRandom()
session = u.String()
}
if user == "" {
sum := sha256.Sum256([]byte(account + session))
user = hex.EncodeToString(sum[:])
}
userID := fmt.Sprintf("user_%s_account_%s_session_%s", user, account, session)
// Base Claude message payload
out := fmt.Sprintf(`{"model":"","max_tokens":32000,"messages":[],"metadata":{"user_id":"%s"}}`, userID)
root := gjson.ParseBytes(rawJSON) root := gjson.ParseBytes(rawJSON)

View File

@@ -8,14 +8,24 @@ package chat_completions
import ( import (
"bytes" "bytes"
"crypto/rand" "crypto/rand"
"crypto/sha256"
"encoding/hex"
"encoding/json" "encoding/json"
"fmt"
"math/big" "math/big"
"strings" "strings"
"github.com/google/uuid"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
"github.com/tidwall/sjson" "github.com/tidwall/sjson"
) )
var (
user = ""
account = ""
session = ""
)
// ConvertOpenAIRequestToClaude parses and transforms an OpenAI Chat Completions API request into Claude Code API format. // ConvertOpenAIRequestToClaude parses and transforms an OpenAI Chat Completions API request into Claude Code API format.
// It extracts the model name, system instruction, message contents, and tool declarations // 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 Claude Code API. // from the raw JSON request and returns them in the format expected by the Claude Code API.
@@ -36,8 +46,22 @@ import (
func ConvertOpenAIRequestToClaude(modelName string, inputRawJSON []byte, stream bool) []byte { func ConvertOpenAIRequestToClaude(modelName string, inputRawJSON []byte, stream bool) []byte {
rawJSON := bytes.Clone(inputRawJSON) rawJSON := bytes.Clone(inputRawJSON)
if account == "" {
u, _ := uuid.NewRandom()
account = u.String()
}
if session == "" {
u, _ := uuid.NewRandom()
session = u.String()
}
if user == "" {
sum := sha256.Sum256([]byte(account + session))
user = hex.EncodeToString(sum[:])
}
userID := fmt.Sprintf("user_%s_account_%s_session_%s", user, account, session)
// Base Claude Code API template with default max_tokens value // Base Claude Code API template with default max_tokens value
out := `{"model":"","max_tokens":32000,"messages":[]}` out := fmt.Sprintf(`{"model":"","max_tokens":32000,"messages":[],"metadata":{"user_id":"%s"}}`, userID)
root := gjson.ParseBytes(rawJSON) root := gjson.ParseBytes(rawJSON)

View File

@@ -3,13 +3,23 @@ package responses
import ( import (
"bytes" "bytes"
"crypto/rand" "crypto/rand"
"crypto/sha256"
"encoding/hex"
"fmt"
"math/big" "math/big"
"strings" "strings"
"github.com/google/uuid"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
"github.com/tidwall/sjson" "github.com/tidwall/sjson"
) )
var (
user = ""
account = ""
session = ""
)
// ConvertOpenAIResponsesRequestToClaude transforms an OpenAI Responses API request // ConvertOpenAIResponsesRequestToClaude transforms an OpenAI Responses API request
// into a Claude Messages API request using only gjson/sjson for JSON handling. // into a Claude Messages API request using only gjson/sjson for JSON handling.
// It supports: // It supports:
@@ -23,8 +33,22 @@ import (
func ConvertOpenAIResponsesRequestToClaude(modelName string, inputRawJSON []byte, stream bool) []byte { func ConvertOpenAIResponsesRequestToClaude(modelName string, inputRawJSON []byte, stream bool) []byte {
rawJSON := bytes.Clone(inputRawJSON) rawJSON := bytes.Clone(inputRawJSON)
if account == "" {
u, _ := uuid.NewRandom()
account = u.String()
}
if session == "" {
u, _ := uuid.NewRandom()
session = u.String()
}
if user == "" {
sum := sha256.Sum256([]byte(account + session))
user = hex.EncodeToString(sum[:])
}
userID := fmt.Sprintf("user_%s_account_%s_session_%s", user, account, session)
// Base Claude message payload // Base Claude message payload
out := `{"model":"","max_tokens":32000,"messages":[]}` out := fmt.Sprintf(`{"model":"","max_tokens":32000,"messages":[],"metadata":{"user_id":"%s"}}`, userID)
root := gjson.ParseBytes(rawJSON) root := gjson.ParseBytes(rawJSON)