feat: RequestOpenAI2ClaudeMessage add more parms map
This commit is contained in:
@@ -17,6 +17,12 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
WebSearchMaxUsesLow = 1
|
||||
WebSearchMaxUsesMedium = 5
|
||||
WebSearchMaxUsesHigh = 10
|
||||
)
|
||||
|
||||
func stopReasonClaude2OpenAI(reason string) string {
|
||||
switch reason {
|
||||
case "stop_sequence":
|
||||
@@ -64,7 +70,7 @@ func RequestOpenAI2ClaudeComplete(textRequest dto.GeneralOpenAIRequest) *dto.Cla
|
||||
}
|
||||
|
||||
func RequestOpenAI2ClaudeMessage(textRequest dto.GeneralOpenAIRequest) (*dto.ClaudeRequest, error) {
|
||||
claudeTools := make([]dto.Tool, 0, len(textRequest.Tools))
|
||||
claudeTools := make([]any, 0, len(textRequest.Tools))
|
||||
|
||||
for _, tool := range textRequest.Tools {
|
||||
if params, ok := tool.Function.Parameters.(map[string]any); ok {
|
||||
@@ -84,10 +90,62 @@ func RequestOpenAI2ClaudeMessage(textRequest dto.GeneralOpenAIRequest) (*dto.Cla
|
||||
}
|
||||
claudeTool.InputSchema[s] = a
|
||||
}
|
||||
claudeTools = append(claudeTools, claudeTool)
|
||||
claudeTools = append(claudeTools, &claudeTool)
|
||||
}
|
||||
}
|
||||
|
||||
// Web search tool
|
||||
// https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool
|
||||
if textRequest.WebSearchOptions != nil {
|
||||
webSearchTool := dto.ClaudeWebSearchTool{
|
||||
Type: "web_search_20250305",
|
||||
Name: "web_search",
|
||||
}
|
||||
|
||||
// 处理 user_location
|
||||
if textRequest.WebSearchOptions.UserLocation != nil {
|
||||
anthropicUserLocation := &dto.ClaudeWebSearchUserLocation{
|
||||
Type: "approximate", // 固定为 "approximate"
|
||||
}
|
||||
|
||||
// 解析 UserLocation JSON
|
||||
var userLocationMap map[string]interface{}
|
||||
if err := json.Unmarshal(textRequest.WebSearchOptions.UserLocation, &userLocationMap); err == nil {
|
||||
// 检查是否有 approximate 字段
|
||||
if approximateData, ok := userLocationMap["approximate"].(map[string]interface{}); ok {
|
||||
if timezone, ok := approximateData["timezone"].(string); ok && timezone != "" {
|
||||
anthropicUserLocation.Timezone = timezone
|
||||
}
|
||||
if country, ok := approximateData["country"].(string); ok && country != "" {
|
||||
anthropicUserLocation.Country = country
|
||||
}
|
||||
if region, ok := approximateData["region"].(string); ok && region != "" {
|
||||
anthropicUserLocation.Region = region
|
||||
}
|
||||
if city, ok := approximateData["city"].(string); ok && city != "" {
|
||||
anthropicUserLocation.City = city
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
webSearchTool.UserLocation = anthropicUserLocation
|
||||
}
|
||||
|
||||
// 处理 search_context_size 转换为 max_uses
|
||||
if textRequest.WebSearchOptions.SearchContextSize != "" {
|
||||
switch textRequest.WebSearchOptions.SearchContextSize {
|
||||
case "low":
|
||||
webSearchTool.MaxUses = WebSearchMaxUsesLow
|
||||
case "medium":
|
||||
webSearchTool.MaxUses = WebSearchMaxUsesMedium
|
||||
case "high":
|
||||
webSearchTool.MaxUses = WebSearchMaxUsesHigh
|
||||
}
|
||||
}
|
||||
|
||||
claudeTools = append(claudeTools, &webSearchTool)
|
||||
}
|
||||
|
||||
claudeRequest := dto.ClaudeRequest{
|
||||
Model: textRequest.Model,
|
||||
MaxTokens: textRequest.MaxTokens,
|
||||
@@ -99,6 +157,14 @@ func RequestOpenAI2ClaudeMessage(textRequest dto.GeneralOpenAIRequest) (*dto.Cla
|
||||
Tools: claudeTools,
|
||||
}
|
||||
|
||||
// 处理 tool_choice 和 parallel_tool_calls
|
||||
if textRequest.ToolChoice != nil || textRequest.ParallelTooCalls != nil {
|
||||
claudeToolChoice := mapToolChoice(textRequest.ToolChoice, textRequest.ParallelTooCalls)
|
||||
if claudeToolChoice != nil {
|
||||
claudeRequest.ToolChoice = claudeToolChoice
|
||||
}
|
||||
}
|
||||
|
||||
if claudeRequest.MaxTokens == 0 {
|
||||
claudeRequest.MaxTokens = uint(model_setting.GetClaudeSettings().GetDefaultMaxTokens(textRequest.Model))
|
||||
}
|
||||
@@ -123,6 +189,27 @@ func RequestOpenAI2ClaudeMessage(textRequest dto.GeneralOpenAIRequest) (*dto.Cla
|
||||
claudeRequest.Model = strings.TrimSuffix(textRequest.Model, "-thinking")
|
||||
}
|
||||
|
||||
if textRequest.ReasoningEffort != "" {
|
||||
switch textRequest.ReasoningEffort {
|
||||
case "low":
|
||||
claudeRequest.Thinking = &dto.Thinking{
|
||||
Type: "enabled",
|
||||
BudgetTokens: common.GetPointer[int](1280),
|
||||
}
|
||||
case "medium":
|
||||
claudeRequest.Thinking = &dto.Thinking{
|
||||
Type: "enabled",
|
||||
BudgetTokens: common.GetPointer[int](2048),
|
||||
}
|
||||
case "high":
|
||||
claudeRequest.Thinking = &dto.Thinking{
|
||||
Type: "enabled",
|
||||
BudgetTokens: common.GetPointer[int](4096),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 指定了 reasoning 参数,覆盖 budgetTokens
|
||||
if textRequest.Reasoning != nil {
|
||||
var reasoning openrouter.RequestReasoning
|
||||
if err := common.UnmarshalJson(textRequest.Reasoning, &reasoning); err != nil {
|
||||
@@ -685,3 +772,51 @@ func ClaudeHandler(c *gin.Context, resp *http.Response, requestMode int, info *r
|
||||
}
|
||||
return nil, claudeInfo.Usage
|
||||
}
|
||||
|
||||
func mapToolChoice(toolChoice any, parallelToolCalls *bool) *dto.ClaudeToolChoice {
|
||||
var claudeToolChoice *dto.ClaudeToolChoice
|
||||
|
||||
// 处理 tool_choice 字符串值
|
||||
if toolChoiceStr, ok := toolChoice.(string); ok {
|
||||
switch toolChoiceStr {
|
||||
case "auto":
|
||||
claudeToolChoice = &dto.ClaudeToolChoice{
|
||||
Type: "auto",
|
||||
}
|
||||
case "required":
|
||||
claudeToolChoice = &dto.ClaudeToolChoice{
|
||||
Type: "any",
|
||||
}
|
||||
case "none":
|
||||
claudeToolChoice = &dto.ClaudeToolChoice{
|
||||
Type: "none",
|
||||
}
|
||||
}
|
||||
} else if toolChoiceMap, ok := toolChoice.(map[string]interface{}); ok {
|
||||
// 处理 tool_choice 对象值
|
||||
if function, ok := toolChoiceMap["function"].(map[string]interface{}); ok {
|
||||
if toolName, ok := function["name"].(string); ok {
|
||||
claudeToolChoice = &dto.ClaudeToolChoice{
|
||||
Type: "tool",
|
||||
Name: toolName,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理 parallel_tool_calls
|
||||
if parallelToolCalls != nil {
|
||||
if claudeToolChoice == nil {
|
||||
// 如果没有 tool_choice,但有 parallel_tool_calls,创建默认的 auto 类型
|
||||
claudeToolChoice = &dto.ClaudeToolChoice{
|
||||
Type: "auto",
|
||||
}
|
||||
}
|
||||
|
||||
// 设置 disable_parallel_tool_use
|
||||
// 如果 parallel_tool_calls 为 true,则 disable_parallel_tool_use 为 false
|
||||
claudeToolChoice.DisableParallelToolUse = !*parallelToolCalls
|
||||
}
|
||||
|
||||
return claudeToolChoice
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user