chore: sync dev branch proxy and workflow updates

This commit is contained in:
Quorinex
2026-05-10 18:57:40 +08:00
parent a063efd494
commit a24529d783
13 changed files with 1062 additions and 100 deletions

View File

@@ -23,7 +23,7 @@ var modelMapOrdered = []modelMapping{
{"claude-sonnet-4-6", "claude-sonnet-4.6"},
{"claude-sonnet-4.6", "claude-sonnet-4.6"},
{"claude-opus-4-7", "claude-opus-4-7"},
{"claude-opus-4.7", "claude-opus-4-7"},
{"claude-opus-4.7", "claude-opus-4-7"},
{"claude-haiku-4-5", "claude-haiku-4.5"},
{"claude-haiku-4.5", "claude-haiku-4.5"},
{"claude-opus-4-5", "claude-opus-4.5"},
@@ -46,6 +46,7 @@ const ThinkingModePrompt = `<thinking_mode>enabled</thinking_mode>
<max_thinking_length>200000</max_thinking_length>`
const minimalFallbackUserContent = "."
const toolResultsContinuationPrefix = "Tool results:"
// ParseModelAndThinking 解析模型名称,返回实际模型和是否启用 thinking
func ParseModelAndThinking(model string, thinkingSuffix string) (string, bool) {
@@ -134,9 +135,17 @@ type ClaudeResponse struct {
Usage ClaudeUsage `json:"usage"`
}
type ClaudeCacheCreationUsage struct {
Ephemeral5mInputTokens int `json:"ephemeral_5m_input_tokens,omitempty"`
Ephemeral1hInputTokens int `json:"ephemeral_1h_input_tokens,omitempty"`
}
type ClaudeUsage struct {
InputTokens int `json:"input_tokens"`
OutputTokens int `json:"output_tokens"`
InputTokens int `json:"input_tokens"`
OutputTokens int `json:"output_tokens"`
CacheCreationInputTokens int `json:"cache_creation_input_tokens,omitempty"`
CacheReadInputTokens int `json:"cache_read_input_tokens,omitempty"`
CacheCreation *ClaudeCacheCreationUsage `json:"cache_creation,omitempty"`
}
// ==================== Claude -> Kiro 转换 ====================
@@ -176,7 +185,7 @@ func ClaudeToKiro(req *ClaudeRequest, thinking bool) *KiroPayload {
userMsg := KiroUserInputMessage{
Content: content,
// ModelID: modelID,
Origin: origin,
Origin: origin,
}
if len(images) > 0 {
userMsg.Images = images
@@ -201,16 +210,7 @@ func ClaudeToKiro(req *ClaudeRequest, thinking bool) *KiroPayload {
}
}
// 确保 history 以 user 开始
if len(history) > 0 && history[0].AssistantResponseMessage != nil {
history = append([]KiroHistoryMessage{{
UserInputMessage: &KiroUserInputMessage{
Content: "Begin conversation",
// ModelID: modelID,
Origin: origin,
},
}}, history...)
}
history = trimLeadingAssistantHistory(history)
// 构建最终内容
finalContent := ""
@@ -237,8 +237,8 @@ func ClaudeToKiro(req *ClaudeRequest, thinking bool) *KiroPayload {
payload.ConversationState.CurrentMessage.UserInputMessage = KiroUserInputMessage{
Content: finalContent,
// ModelID: modelID,
Origin: origin,
Images: currentImages,
Origin: origin,
Images: currentImages,
}
if len(kiroTools) > 0 || len(currentToolResults) > 0 {
@@ -616,8 +616,8 @@ func OpenAIToKiro(req *OpenAIRequest, thinking bool) *KiroPayload {
UserInputMessage: &KiroUserInputMessage{
Content: content,
// ModelID: modelID,
Origin: origin,
Images: images,
Origin: origin,
Images: images,
},
})
}
@@ -662,7 +662,7 @@ func OpenAIToKiro(req *OpenAIRequest, thinking bool) *KiroPayload {
UserInputMessage: &KiroUserInputMessage{
Content: buildToolResultsContinuation(currentToolResults),
// ModelID: modelID,
Origin: origin,
Origin: origin,
UserInputMessageContext: &UserInputMessageContext{
ToolResults: currentToolResults,
},
@@ -699,8 +699,8 @@ func OpenAIToKiro(req *OpenAIRequest, thinking bool) *KiroPayload {
payload.ConversationState.CurrentMessage.UserInputMessage = KiroUserInputMessage{
Content: finalContent,
// ModelID: modelID,
Origin: origin,
Images: currentImages,
Origin: origin,
Images: currentImages,
}
if len(kiroTools) > 0 || len(currentToolResults) > 0 {
@@ -832,13 +832,27 @@ func buildToolResultsContinuation(toolResults []KiroToolResult) string {
return minimalFallbackUserContent
}
joined := strings.Join(parts, "\n\n")
joined := toolResultsContinuationPrefix + "\n\n" + strings.Join(parts, "\n\n")
if len(joined) > 4000 {
return joined[:4000]
}
return joined
}
func trimLeadingAssistantHistory(history []KiroHistoryMessage) []KiroHistoryMessage {
idx := 0
for idx < len(history) && history[idx].AssistantResponseMessage != nil {
idx++
}
if idx == 0 {
return history
}
if idx >= len(history) {
return nil
}
return history[idx:]
}
func firstClaudeConversationAnchor(messages []ClaudeMessage) string {
for _, msg := range messages {
if msg.Role != "user" {
@@ -849,15 +863,7 @@ func firstClaudeConversationAnchor(messages []ClaudeMessage) string {
return strings.TrimSpace(text)
}
if len(toolResults) > 0 {
return buildToolResultsContinuation(toolResults)
}
}
for _, msg := range messages {
if strings.TrimSpace(msg.Role) != "" {
if text := extractOpenAIMessageText(msg.Content); strings.TrimSpace(text) != "" {
return strings.TrimSpace(text)
}
continue
}
}
@@ -875,25 +881,32 @@ func firstOpenAIConversationAnchor(messages []OpenAIMessage) string {
}
}
for _, msg := range messages {
text := extractOpenAIMessageText(msg.Content)
if strings.TrimSpace(text) != "" {
return strings.TrimSpace(text)
}
}
return ""
}
func buildConversationID(modelID, systemPrompt, anchor string) string {
anchor = strings.TrimSpace(anchor)
if anchor == "" {
if isSyntheticConversationAnchor(anchor) {
return uuid.New().String()
}
seed := strings.Join([]string{modelID, strings.TrimSpace(systemPrompt), anchor}, "\n")
return uuid.NewSHA1(uuid.NameSpaceURL, []byte(seed)).String()
}
func isSyntheticConversationAnchor(anchor string) bool {
if strings.TrimSpace(anchor) == "" {
return true
}
normalized := strings.ToLower(strings.Join(strings.Fields(anchor), " "))
switch normalized {
case ".", "begin conversation", "please analyze the attached image.", strings.ToLower(minimalFallbackUserContent):
return true
default:
return false
}
}
func extractOpenAITextPart(part map[string]interface{}) (string, bool) {
partType, _ := part["type"].(string)
switch partType {