malt666 commited on
Commit
184c400
·
verified ·
1 Parent(s): 2ef9a19

Upload main.go

Browse files
Files changed (1) hide show
  1. main.go +88 -12
main.go CHANGED
@@ -65,14 +65,7 @@ var modelRules = []ModelRule{
65
  Keywords: []string{"deepseek"},
66
  Target: "deepseek-v3",
67
  },
68
- {
69
- Keywords: []string{"claude", "3", "sonnet"},
70
- Target: "claude-3-sonnet-20240229",
71
- },
72
- {
73
- Keywords: []string{"claude", "3", "7"},
74
- Target: "claude-3-7-sonnet-latest",
75
- },
76
  {
77
  Keywords: []string{"claude", "3", "5", "sonnet"},
78
  Target: "claude-3-5-sonnet-latest",
@@ -81,6 +74,10 @@ var modelRules = []ModelRule{
81
  Keywords: []string{"claude", "3", "5", "haiku"},
82
  Target: "claude-3-5-haiku-latest",
83
  },
 
 
 
 
84
  {
85
  Keywords: []string{"claude", "3", "opus"},
86
  Target: "claude-3-opus-latest",
@@ -89,6 +86,11 @@ var modelRules = []ModelRule{
89
  Keywords: []string{"claude", "3", "haiku"},
90
  Target: "claude-3-haiku-20240307",
91
  },
 
 
 
 
 
92
  {
93
  Keywords: []string{"gemini", "2.0"},
94
  Target: "gemini-2.0-flash",
@@ -107,17 +109,43 @@ var modelRules = []ModelRule{
107
  func matchModelName(input string) string {
108
  // 转换为小写进行匹配
109
  input = strings.ToLower(input)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
  // 特殊规则:OpenAI GPT-4o
112
  if (strings.Contains(input, "gpt") && strings.Contains(input, "4o")) ||
113
  strings.Contains(input, "o1") ||
114
  strings.Contains(input, "o3") {
 
115
  return "gpt-4o"
116
  }
117
 
118
  // 特殊规则:OpenAI GPT-4
119
  if (strings.Contains(input, "gpt") && strings.Contains(input, "3") && strings.Contains(input, "5")) ||
120
  (strings.Contains(input, "gpt") && strings.Contains(input, "4") && !strings.Contains(input, "4o")) {
 
121
  return "gpt-4"
122
  }
123
 
@@ -131,11 +159,13 @@ func matchModelName(input string) string {
131
  }
132
  }
133
  if matches {
 
134
  return rule.Target
135
  }
136
  }
137
 
138
  // 如果没有匹配到,返回原始输入
 
139
  return input
140
  }
141
 
@@ -196,6 +226,16 @@ func countTokensWithClaude(req TokenCountRequest) (TokenCountResponse, error) {
196
  // 准备请求Anthropic API
197
  log.Printf("开始Claude API请求: 模型=%s, 消息数量=%d", req.Model, len(req.Messages))
198
 
 
 
 
 
 
 
 
 
 
 
199
  client := &http.Client{}
200
  data, err := json.Marshal(req)
201
  if err != nil {
@@ -230,9 +270,19 @@ func countTokensWithClaude(req TokenCountRequest) (TokenCountResponse, error) {
230
  errorBody, _ = io.ReadAll(response.Body)
231
  log.Printf("错误: Claude API返回非200状态码: %d, 响应体: %s", response.StatusCode, string(errorBody))
232
 
233
- if response.StatusCode == http.StatusUnauthorized {
234
- log.Printf("错误: Claude API密钥可能无效或过期")
 
 
235
  return TokenCountResponse{}, fmt.Errorf("Claude API验证失败,请检查API Key是否有效: %s", string(errorBody))
 
 
 
 
 
 
 
 
236
  }
237
 
238
  return TokenCountResponse{}, fmt.Errorf("Claude API返回错误状态码: %d, 响应: %s", response.StatusCode, string(errorBody))
@@ -529,8 +579,34 @@ func countTokens(c *gin.Context) {
529
 
530
  if err != nil {
531
  log.Printf("计算token失败: %v", err)
532
- c.JSON(http.StatusInternalServerError, ErrorResponse{Error: err.Error()})
533
- return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
534
  }
535
 
536
  // 返回结果
 
65
  Keywords: []string{"deepseek"},
66
  Target: "deepseek-v3",
67
  },
68
+ // 先放更具体的规则
 
 
 
 
 
 
 
69
  {
70
  Keywords: []string{"claude", "3", "5", "sonnet"},
71
  Target: "claude-3-5-sonnet-latest",
 
74
  Keywords: []string{"claude", "3", "5", "haiku"},
75
  Target: "claude-3-5-haiku-latest",
76
  },
77
+ {
78
+ Keywords: []string{"claude", "3", "7"},
79
+ Target: "claude-3-7-sonnet-latest",
80
+ },
81
  {
82
  Keywords: []string{"claude", "3", "opus"},
83
  Target: "claude-3-opus-latest",
 
86
  Keywords: []string{"claude", "3", "haiku"},
87
  Target: "claude-3-haiku-20240307",
88
  },
89
+ // 再放一般规则
90
+ {
91
+ Keywords: []string{"claude", "3", "sonnet"},
92
+ Target: "claude-3-sonnet-20240229",
93
+ },
94
  {
95
  Keywords: []string{"gemini", "2.0"},
96
  Target: "gemini-2.0-flash",
 
109
  func matchModelName(input string) string {
110
  // 转换为小写进行匹配
111
  input = strings.ToLower(input)
112
+ log.Printf("正在匹配模型名称: %s", input)
113
+
114
+ // 特殊处理 Claude 3.5 系列
115
+ if strings.Contains(input, "claude") && strings.Contains(input, "3.5") ||
116
+ strings.Contains(input, "claude") && strings.Contains(input, "3") && strings.Contains(input, "5") {
117
+ if strings.Contains(input, "sonnet") {
118
+ log.Printf("匹配到Claude 3.5 Sonnet")
119
+ return "claude-3-5-sonnet-latest"
120
+ } else if strings.Contains(input, "haiku") {
121
+ log.Printf("匹配到Claude 3.5 Haiku")
122
+ return "claude-3-5-haiku-latest"
123
+ } else {
124
+ // 默认为Sonnet
125
+ log.Printf("匹配到Claude 3.5 (默认使用Sonnet)")
126
+ return "claude-3-5-sonnet-latest"
127
+ }
128
+ }
129
+
130
+ // 特殊处理 Claude 3.7 系列
131
+ if strings.Contains(input, "claude") && strings.Contains(input, "3.7") ||
132
+ strings.Contains(input, "claude") && strings.Contains(input, "3") && strings.Contains(input, "7") {
133
+ log.Printf("匹配到Claude 3.7")
134
+ return "claude-3-7-sonnet-latest"
135
+ }
136
 
137
  // 特殊规则:OpenAI GPT-4o
138
  if (strings.Contains(input, "gpt") && strings.Contains(input, "4o")) ||
139
  strings.Contains(input, "o1") ||
140
  strings.Contains(input, "o3") {
141
+ log.Printf("匹配到GPT-4o")
142
  return "gpt-4o"
143
  }
144
 
145
  // 特殊规则:OpenAI GPT-4
146
  if (strings.Contains(input, "gpt") && strings.Contains(input, "3") && strings.Contains(input, "5")) ||
147
  (strings.Contains(input, "gpt") && strings.Contains(input, "4") && !strings.Contains(input, "4o")) {
148
+ log.Printf("匹配到GPT-4")
149
  return "gpt-4"
150
  }
151
 
 
159
  }
160
  }
161
  if matches {
162
+ log.Printf("通过规则匹配到: %s", rule.Target)
163
  return rule.Target
164
  }
165
  }
166
 
167
  // 如果没有匹配到,返回原始输入
168
+ log.Printf("没有匹配到任何规则,使用原始输入: %s", input)
169
  return input
170
  }
171
 
 
226
  // 准备请求Anthropic API
227
  log.Printf("开始Claude API请求: 模型=%s, 消息数量=%d", req.Model, len(req.Messages))
228
 
229
+ // 验证消息格式
230
+ for i, msg := range req.Messages {
231
+ if msg.Content == "" {
232
+ log.Printf("警告: 消息 #%d 内容为空,可能导致请求失败", i)
233
+ }
234
+ if msg.Role != "user" && msg.Role != "assistant" {
235
+ log.Printf("警告: 消息 #%d 角色'%s'不是标准角色(user/assistant),可能导致请求失败", i, msg.Role)
236
+ }
237
+ }
238
+
239
  client := &http.Client{}
240
  data, err := json.Marshal(req)
241
  if err != nil {
 
270
  errorBody, _ = io.ReadAll(response.Body)
271
  log.Printf("错误: Claude API返回非200状态码: %d, 响应体: %s", response.StatusCode, string(errorBody))
272
 
273
+ // 检查常见错误
274
+ errorStr := string(errorBody)
275
+ if response.StatusCode == http.StatusUnauthorized || strings.Contains(errorStr, "invalid_api_key") {
276
+ log.Printf("错误: Claude API密钥无效或过期")
277
  return TokenCountResponse{}, fmt.Errorf("Claude API验证失败,请检查API Key是否有效: %s", string(errorBody))
278
+ } else if response.StatusCode == http.StatusBadRequest {
279
+ if strings.Contains(errorStr, "empty content") {
280
+ log.Printf("错误: 请求包含空内容的消息")
281
+ return TokenCountResponse{}, fmt.Errorf("请求格式错误: 消息不能有空内容: %s", string(errorBody))
282
+ } else if strings.Contains(errorStr, "invalid_request_error") {
283
+ log.Printf("错误: 无效的请求格式")
284
+ return TokenCountResponse{}, fmt.Errorf("无效的请求格式: %s", string(errorBody))
285
+ }
286
  }
287
 
288
  return TokenCountResponse{}, fmt.Errorf("Claude API返回错误状态码: %d, 响应: %s", response.StatusCode, string(errorBody))
 
579
 
580
  if err != nil {
581
  log.Printf("计算token失败: %v", err)
582
+
583
+ // 对所有API调用失败的情况尝试使用GPT-4o估算
584
+ log.Printf("API调用失败,尝试使用GPT-4o估算: 原始模型=%s, 错误=%v", req.Model, err)
585
+
586
+ // 创建新的请求,使用GPT-4o
587
+ gptReq := req
588
+ gptReq.Model = "gpt-4o"
589
+
590
+ // 使用OpenAI API进行估算
591
+ estimatedResult, estimateErr := countTokensWithOpenAI(gptReq)
592
+
593
+ if estimateErr == nil {
594
+ log.Printf("使用GPT-4o估算成功: 模型=%s, 估算tokens=%d", originalModel, estimatedResult.InputTokens)
595
+
596
+ // 返回估算值,但添加警告信息和原始错误
597
+ c.JSON(http.StatusOK, gin.H{
598
+ "input_tokens": estimatedResult.InputTokens,
599
+ "warning": fmt.Sprintf("Token calculation for model '%s' failed. This is an estimation based on gpt-4o and may not be accurate.", originalModel),
600
+ "estimated_with": "gpt-4o",
601
+ "original_error": err.Error(),
602
+ })
603
+ return
604
+ } else {
605
+ log.Printf("使用GPT-4o估算也失败: %v", estimateErr)
606
+ // 如果GPT-4o估算也失败,返回原始错误
607
+ c.JSON(http.StatusInternalServerError, ErrorResponse{Error: err.Error()})
608
+ return
609
+ }
610
  }
611
 
612
  // 返回结果