feat: add Claude Sonnet 4.6 and Opus 4.6 to model list and mapping (#18)
- Add claude-sonnet-4.6 (dot and dash variants) to modelMap in translator.go - Add claude-sonnet-4.6 and claude-opus-4.6 (plus -thinking variants) to the static fallback model list in handler.go - Realign existing opus-4.6 entries for consistency
This commit is contained in:
102
proxy/handler.go
102
proxy/handler.go
@@ -259,6 +259,10 @@ func (h *Handler) handleModels(w http.ResponseWriter, r *http.Request) {
|
||||
} else {
|
||||
// fallback 静态列表
|
||||
models = []map[string]interface{}{
|
||||
{"id": "claude-sonnet-4.6", "object": "model", "owned_by": "anthropic"},
|
||||
{"id": "claude-sonnet-4.6" + thinkingSuffix, "object": "model", "owned_by": "anthropic"},
|
||||
{"id": "claude-opus-4.6", "object": "model", "owned_by": "anthropic"},
|
||||
{"id": "claude-opus-4.6" + thinkingSuffix, "object": "model", "owned_by": "anthropic"},
|
||||
{"id": "claude-sonnet-4.5", "object": "model", "owned_by": "anthropic"},
|
||||
{"id": "claude-sonnet-4.5" + thinkingSuffix, "object": "model", "owned_by": "anthropic"},
|
||||
{"id": "claude-sonnet-4", "object": "model", "owned_by": "anthropic"},
|
||||
@@ -1410,20 +1414,20 @@ func (h *Handler) apiGetAccounts(w http.ResponseWriter, r *http.Request) {
|
||||
"expiresAt": a.ExpiresAt,
|
||||
"hasToken": a.AccessToken != "",
|
||||
"machineId": a.MachineId,
|
||||
"subscriptionType": a.SubscriptionType,
|
||||
"subscriptionTitle": a.SubscriptionTitle,
|
||||
"daysRemaining": a.DaysRemaining,
|
||||
"usageCurrent": a.UsageCurrent,
|
||||
"usageLimit": a.UsageLimit,
|
||||
"usagePercent": a.UsagePercent,
|
||||
"nextResetDate": a.NextResetDate,
|
||||
"lastRefresh": a.LastRefresh,
|
||||
"trialUsageCurrent": a.TrialUsageCurrent,
|
||||
"trialUsageLimit": a.TrialUsageLimit,
|
||||
"trialUsagePercent": a.TrialUsagePercent,
|
||||
"trialStatus": a.TrialStatus,
|
||||
"trialExpiresAt": a.TrialExpiresAt,
|
||||
"requestCount": stats.RequestCount,
|
||||
"subscriptionType": a.SubscriptionType,
|
||||
"subscriptionTitle": a.SubscriptionTitle,
|
||||
"daysRemaining": a.DaysRemaining,
|
||||
"usageCurrent": a.UsageCurrent,
|
||||
"usageLimit": a.UsageLimit,
|
||||
"usagePercent": a.UsagePercent,
|
||||
"nextResetDate": a.NextResetDate,
|
||||
"lastRefresh": a.LastRefresh,
|
||||
"trialUsageCurrent": a.TrialUsageCurrent,
|
||||
"trialUsageLimit": a.TrialUsageLimit,
|
||||
"trialUsagePercent": a.TrialUsagePercent,
|
||||
"trialStatus": a.TrialStatus,
|
||||
"trialExpiresAt": a.TrialExpiresAt,
|
||||
"requestCount": stats.RequestCount,
|
||||
"errorCount": stats.ErrorCount,
|
||||
"totalTokens": stats.TotalTokens,
|
||||
"totalCredits": stats.TotalCredits,
|
||||
@@ -2080,41 +2084,41 @@ func (h *Handler) apiGetAccountFull(w http.ResponseWriter, r *http.Request, id s
|
||||
|
||||
// 返回完整账号信息(包含敏感字段)
|
||||
result := map[string]interface{}{
|
||||
"id": account.ID,
|
||||
"email": account.Email,
|
||||
"userId": account.UserId,
|
||||
"nickname": account.Nickname,
|
||||
"accessToken": account.AccessToken,
|
||||
"refreshToken": account.RefreshToken,
|
||||
"clientId": account.ClientID,
|
||||
"clientSecret": account.ClientSecret,
|
||||
"authMethod": account.AuthMethod,
|
||||
"provider": account.Provider,
|
||||
"region": account.Region,
|
||||
"expiresAt": account.ExpiresAt,
|
||||
"machineId": account.MachineId,
|
||||
"enabled": account.Enabled,
|
||||
"banStatus": account.BanStatus,
|
||||
"banReason": account.BanReason,
|
||||
"banTime": account.BanTime,
|
||||
"subscriptionType": account.SubscriptionType,
|
||||
"subscriptionTitle": account.SubscriptionTitle,
|
||||
"daysRemaining": account.DaysRemaining,
|
||||
"usageCurrent": account.UsageCurrent,
|
||||
"usageLimit": account.UsageLimit,
|
||||
"usagePercent": account.UsagePercent,
|
||||
"nextResetDate": account.NextResetDate,
|
||||
"lastRefresh": account.LastRefresh,
|
||||
"trialUsageCurrent": account.TrialUsageCurrent,
|
||||
"trialUsageLimit": account.TrialUsageLimit,
|
||||
"trialUsagePercent": account.TrialUsagePercent,
|
||||
"trialStatus": account.TrialStatus,
|
||||
"trialExpiresAt": account.TrialExpiresAt,
|
||||
"requestCount": stats.RequestCount,
|
||||
"errorCount": stats.ErrorCount,
|
||||
"totalTokens": stats.TotalTokens,
|
||||
"totalCredits": stats.TotalCredits,
|
||||
"lastUsed": stats.LastUsed,
|
||||
"id": account.ID,
|
||||
"email": account.Email,
|
||||
"userId": account.UserId,
|
||||
"nickname": account.Nickname,
|
||||
"accessToken": account.AccessToken,
|
||||
"refreshToken": account.RefreshToken,
|
||||
"clientId": account.ClientID,
|
||||
"clientSecret": account.ClientSecret,
|
||||
"authMethod": account.AuthMethod,
|
||||
"provider": account.Provider,
|
||||
"region": account.Region,
|
||||
"expiresAt": account.ExpiresAt,
|
||||
"machineId": account.MachineId,
|
||||
"enabled": account.Enabled,
|
||||
"banStatus": account.BanStatus,
|
||||
"banReason": account.BanReason,
|
||||
"banTime": account.BanTime,
|
||||
"subscriptionType": account.SubscriptionType,
|
||||
"subscriptionTitle": account.SubscriptionTitle,
|
||||
"daysRemaining": account.DaysRemaining,
|
||||
"usageCurrent": account.UsageCurrent,
|
||||
"usageLimit": account.UsageLimit,
|
||||
"usagePercent": account.UsagePercent,
|
||||
"nextResetDate": account.NextResetDate,
|
||||
"lastRefresh": account.LastRefresh,
|
||||
"trialUsageCurrent": account.TrialUsageCurrent,
|
||||
"trialUsageLimit": account.TrialUsageLimit,
|
||||
"trialUsagePercent": account.TrialUsagePercent,
|
||||
"trialStatus": account.TrialStatus,
|
||||
"trialExpiresAt": account.TrialExpiresAt,
|
||||
"requestCount": stats.RequestCount,
|
||||
"errorCount": stats.ErrorCount,
|
||||
"totalTokens": stats.TotalTokens,
|
||||
"totalCredits": stats.TotalCredits,
|
||||
"lastUsed": stats.LastUsed,
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(result)
|
||||
|
||||
@@ -16,8 +16,10 @@ var modelMap = map[string]string{
|
||||
"claude-sonnet-4.5": "claude-sonnet-4.5",
|
||||
"claude-haiku-4-5": "claude-haiku-4.5",
|
||||
"claude-haiku-4.5": "claude-haiku-4.5",
|
||||
"claude-opus-4-6": "claude-opus-4.6",
|
||||
"claude-opus-4.6": "claude-opus-4.6",
|
||||
"claude-sonnet-4-6": "claude-sonnet-4.6",
|
||||
"claude-sonnet-4.6": "claude-sonnet-4.6",
|
||||
"claude-opus-4-6": "claude-opus-4.6",
|
||||
"claude-opus-4.6": "claude-opus-4.6",
|
||||
"claude-opus-4-5": "claude-opus-4.5",
|
||||
"claude-opus-4.5": "claude-opus-4.5",
|
||||
"claude-sonnet-4": "claude-sonnet-4",
|
||||
@@ -40,7 +42,7 @@ const ThinkingModePrompt = `<thinking_mode>enabled</thinking_mode>
|
||||
func ParseModelAndThinking(model string, thinkingSuffix string) (string, bool) {
|
||||
lower := strings.ToLower(model)
|
||||
thinking := false
|
||||
|
||||
|
||||
// 使用配置的后缀检查
|
||||
suffixLower := strings.ToLower(thinkingSuffix)
|
||||
if strings.HasSuffix(lower, suffixLower) {
|
||||
@@ -48,19 +50,19 @@ func ParseModelAndThinking(model string, thinkingSuffix string) (string, bool) {
|
||||
model = model[:len(model)-len(thinkingSuffix)]
|
||||
lower = strings.ToLower(model)
|
||||
}
|
||||
|
||||
|
||||
// 映射模型
|
||||
for k, v := range modelMap {
|
||||
if strings.Contains(lower, k) {
|
||||
return v, thinking
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 如果已经是有效的 Kiro 模型,直接返回
|
||||
if strings.HasPrefix(lower, "claude-") {
|
||||
return model, thinking
|
||||
}
|
||||
|
||||
|
||||
return "claude-sonnet-4.5", thinking
|
||||
}
|
||||
|
||||
@@ -89,13 +91,13 @@ type ClaudeMessage struct {
|
||||
}
|
||||
|
||||
type ClaudeContentBlock struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Input interface{} `json:"input,omitempty"`
|
||||
ToolUseID string `json:"tool_use_id,omitempty"`
|
||||
Content interface{} `json:"content,omitempty"` // for tool_result
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Input interface{} `json:"input,omitempty"`
|
||||
ToolUseID string `json:"tool_use_id,omitempty"`
|
||||
Content interface{} `json:"content,omitempty"` // for tool_result
|
||||
Source *ImageSource `json:"source,omitempty"`
|
||||
}
|
||||
|
||||
@@ -137,12 +139,12 @@ func ClaudeToKiro(req *ClaudeRequest, thinking bool) *KiroPayload {
|
||||
|
||||
// 提取系统提示
|
||||
systemPrompt := extractSystemPrompt(req.System)
|
||||
|
||||
|
||||
// 如果启用 thinking 模式,注入 thinking 提示
|
||||
if thinking {
|
||||
systemPrompt = ThinkingModePrompt + "\n\n" + systemPrompt
|
||||
}
|
||||
|
||||
|
||||
// 注入时间戳
|
||||
timestamp := time.Now().Format(time.RFC3339)
|
||||
systemPrompt = "[Context: Current time is " + timestamp + "]\n\n" + systemPrompt
|
||||
@@ -172,7 +174,7 @@ func ClaudeToKiro(req *ClaudeRequest, thinking bool) *KiroPayload {
|
||||
|
||||
if msg.Role == "user" {
|
||||
content, images, toolResults := extractClaudeUserContent(msg.Content)
|
||||
|
||||
|
||||
if isLast {
|
||||
currentContent = content
|
||||
currentImages = images
|
||||
@@ -591,7 +593,7 @@ func OpenAIToKiro(req *OpenAIRequest, thinking bool) *KiroPayload {
|
||||
switch msg.Role {
|
||||
case "user":
|
||||
content, images := extractOpenAIUserContent(msg.Content)
|
||||
|
||||
|
||||
// 第一条 user 消息合并 system prompt
|
||||
if !systemMerged && systemPrompt != "" {
|
||||
content = systemPrompt + "\n" + content
|
||||
@@ -617,7 +619,7 @@ func OpenAIToKiro(req *OpenAIRequest, thinking bool) *KiroPayload {
|
||||
if content == "" && len(msg.ToolCalls) > 0 {
|
||||
content = "Using tools."
|
||||
}
|
||||
|
||||
|
||||
var toolUses []KiroToolUse
|
||||
for _, tc := range msg.ToolCalls {
|
||||
var input map[string]interface{}
|
||||
|
||||
Reference in New Issue
Block a user