mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-18 20:30:51 +08:00
115 lines
5.0 KiB
Go
115 lines
5.0 KiB
Go
// Package code provides request translation functionality for Claude API.
|
|
// It handles parsing and transforming Claude API requests into the internal client format,
|
|
// extracting model information, system instructions, message contents, and tool declarations.
|
|
// The package also performs JSON data cleaning and transformation to ensure compatibility
|
|
// between Claude API format and the internal client's expected format.
|
|
package code
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/luispater/CLIProxyAPI/internal/misc"
|
|
"github.com/tidwall/gjson"
|
|
"github.com/tidwall/sjson"
|
|
)
|
|
|
|
// PrepareClaudeRequest parses and transforms a Claude API request into internal client format.
|
|
// 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 ConvertClaudeCodeRequestToCodex(rawJSON []byte) string {
|
|
template := `{"model":"","instructions":"","input":[]}`
|
|
|
|
instructions := misc.CodexInstructions
|
|
template, _ = sjson.SetRaw(template, "instructions", instructions)
|
|
|
|
rootResult := gjson.ParseBytes(rawJSON)
|
|
modelResult := rootResult.Get("model")
|
|
template, _ = sjson.Set(template, "model", modelResult.String())
|
|
|
|
systemsResult := rootResult.Get("system")
|
|
if systemsResult.IsArray() {
|
|
systemResults := systemsResult.Array()
|
|
message := `{"type":"message","role":"user","content":[]}`
|
|
for i := 0; i < len(systemResults); i++ {
|
|
systemResult := systemResults[i]
|
|
systemTypeResult := systemResult.Get("type")
|
|
if systemTypeResult.String() == "text" {
|
|
message, _ = sjson.Set(message, fmt.Sprintf("content.%d.type", i), "input_text")
|
|
message, _ = sjson.Set(message, fmt.Sprintf("content.%d.text", i), systemResult.Get("text").String())
|
|
}
|
|
}
|
|
template, _ = sjson.SetRaw(template, "input.-1", message)
|
|
}
|
|
|
|
messagesResult := rootResult.Get("messages")
|
|
if messagesResult.IsArray() {
|
|
messageResults := messagesResult.Array()
|
|
|
|
for i := 0; i < len(messageResults); i++ {
|
|
messageResult := messageResults[i]
|
|
|
|
messageContentsResult := messageResult.Get("content")
|
|
if messageContentsResult.IsArray() {
|
|
messageContentResults := messageContentsResult.Array()
|
|
for j := 0; j < len(messageContentResults); j++ {
|
|
messageContentResult := messageContentResults[j]
|
|
messageContentTypeResult := messageContentResult.Get("type")
|
|
if messageContentTypeResult.String() == "text" {
|
|
message := `{"type": "message","role":"","content":[]}`
|
|
messageRole := messageResult.Get("role").String()
|
|
message, _ = sjson.Set(message, "role", messageRole)
|
|
|
|
partType := "input_text"
|
|
if messageRole == "assistant" {
|
|
partType = "output_text"
|
|
}
|
|
|
|
currentIndex := len(gjson.Get(message, "content").Array())
|
|
message, _ = sjson.Set(message, fmt.Sprintf("content.%d.type", currentIndex), partType)
|
|
message, _ = sjson.Set(message, fmt.Sprintf("content.%d.text", currentIndex), messageContentResult.Get("text").String())
|
|
template, _ = sjson.SetRaw(template, "input.-1", message)
|
|
} else if messageContentTypeResult.String() == "tool_use" {
|
|
functionCallMessage := `{"type":"function_call"}`
|
|
functionCallMessage, _ = sjson.Set(functionCallMessage, "call_id", messageContentResult.Get("id").String())
|
|
functionCallMessage, _ = sjson.Set(functionCallMessage, "name", messageContentResult.Get("name").String())
|
|
functionCallMessage, _ = sjson.Set(functionCallMessage, "arguments", messageContentResult.Get("input").Raw)
|
|
template, _ = sjson.SetRaw(template, "input.-1", functionCallMessage)
|
|
} else if messageContentTypeResult.String() == "tool_result" {
|
|
functionCallOutputMessage := `{"type":"function_call_output"}`
|
|
functionCallOutputMessage, _ = sjson.Set(functionCallOutputMessage, "call_id", messageContentResult.Get("tool_use_id").String())
|
|
functionCallOutputMessage, _ = sjson.Set(functionCallOutputMessage, "output", messageContentResult.Get("content").String())
|
|
template, _ = sjson.SetRaw(template, "input.-1", functionCallOutputMessage)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
toolsResult := rootResult.Get("tools")
|
|
if toolsResult.IsArray() {
|
|
template, _ = sjson.SetRaw(template, "tools", `[]`)
|
|
template, _ = sjson.Set(template, "tool_choice", `auto`)
|
|
toolResults := toolsResult.Array()
|
|
for i := 0; i < len(toolResults); i++ {
|
|
toolResult := toolResults[i]
|
|
tool := toolResult.Raw
|
|
tool, _ = sjson.Set(tool, "type", "function")
|
|
tool, _ = sjson.SetRaw(tool, "parameters", toolResult.Get("input_schema").Raw)
|
|
tool, _ = sjson.Delete(tool, "input_schema")
|
|
tool, _ = sjson.Delete(tool, "parameters.$schema")
|
|
tool, _ = sjson.Set(tool, "strict", false)
|
|
template, _ = sjson.SetRaw(template, "tools.-1", tool)
|
|
}
|
|
}
|
|
|
|
template, _ = sjson.Set(template, "parallel_tool_calls", true)
|
|
template, _ = sjson.Set(template, "reasoning.effort", "low")
|
|
template, _ = sjson.Set(template, "reasoning.summary", "auto")
|
|
template, _ = sjson.Set(template, "stream", true)
|
|
template, _ = sjson.Set(template, "store", false)
|
|
template, _ = sjson.Set(template, "include", []string{"reasoning.encrypted_content"})
|
|
|
|
return template
|
|
}
|