refactor(claude): replace strings.Builder with simpler output string concatenation

This commit is contained in:
Luis Pater
2025-12-11 22:34:06 +08:00
parent 242b4d5754
commit ef0edbfe69
@@ -69,12 +69,12 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque
// Track whether tools are being used in this response chunk // Track whether tools are being used in this response chunk
usedTool := false usedTool := false
var sb strings.Builder output := ""
// Initialize the streaming session with a message_start event // Initialize the streaming session with a message_start event
// This is only sent for the very first response chunk to establish the streaming session // This is only sent for the very first response chunk to establish the streaming session
if !(*param).(*Params).HasFirstResponse { if !(*param).(*Params).HasFirstResponse {
sb.WriteString("event: message_start\n") output = "event: message_start\n"
// Create the initial message structure with default values according to Claude Code API specification // Create the initial message structure with default values according to Claude Code API specification
// This follows the Claude Code API specification for streaming message initialization // This follows the Claude Code API specification for streaming message initialization
@@ -87,7 +87,7 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque
if responseIDResult := gjson.GetBytes(rawJSON, "response.responseId"); responseIDResult.Exists() { if responseIDResult := gjson.GetBytes(rawJSON, "response.responseId"); responseIDResult.Exists() {
messageStartTemplate, _ = sjson.Set(messageStartTemplate, "message.id", responseIDResult.String()) messageStartTemplate, _ = sjson.Set(messageStartTemplate, "message.id", responseIDResult.String())
} }
sb.WriteString(fmt.Sprintf("data: %s\n\n\n", messageStartTemplate)) output = output + fmt.Sprintf("data: %s\n\n\n", messageStartTemplate)
(*param).(*Params).HasFirstResponse = true (*param).(*Params).HasFirstResponse = true
} }
@@ -110,7 +110,7 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque
if partResult.Get("thought").Bool() { if partResult.Get("thought").Bool() {
// Continue existing thinking block if already in thinking state // Continue existing thinking block if already in thinking state
if (*param).(*Params).ResponseType == 2 { if (*param).(*Params).ResponseType == 2 {
sb.WriteString("event: content_block_delta\n") output = output + "event: content_block_delta\n"
data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"thinking_delta","thinking":""}}`, (*param).(*Params).ResponseIndex), "delta.thinking", partTextResult.String()) data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"thinking_delta","thinking":""}}`, (*param).(*Params).ResponseIndex), "delta.thinking", partTextResult.String())
output = output + fmt.Sprintf("data: %s\n\n\n", data) output = output + fmt.Sprintf("data: %s\n\n\n", data)
(*param).(*Params).HasContent = true (*param).(*Params).HasContent = true
@@ -118,19 +118,24 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque
// Transition from another state to thinking // Transition from another state to thinking
// First, close any existing content block // First, close any existing content block
if (*param).(*Params).ResponseType != 0 { if (*param).(*Params).ResponseType != 0 {
sb.WriteString("event: content_block_stop\n") if (*param).(*Params).ResponseType == 2 {
sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)) // output = output + "event: content_block_delta\n"
sb.WriteString("\n\n\n") // output = output + fmt.Sprintf(`data: {"type":"content_block_delta","index":%d,"delta":{"type":"signature_delta","signature":null}}`, (*param).(*Params).ResponseIndex)
// output = output + "\n\n\n"
}
output = output + "event: content_block_stop\n"
output = output + fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)
output = output + "\n\n\n"
(*param).(*Params).ResponseIndex++ (*param).(*Params).ResponseIndex++
} }
// Start a new thinking content block // Start a new thinking content block
sb.WriteString("event: content_block_start\n") output = output + "event: content_block_start\n"
sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_start","index":%d,"content_block":{"type":"thinking","thinking":""}}`, (*param).(*Params).ResponseIndex)) output = output + fmt.Sprintf(`data: {"type":"content_block_start","index":%d,"content_block":{"type":"thinking","thinking":""}}`, (*param).(*Params).ResponseIndex)
sb.WriteString("\n\n\n") output = output + "\n\n\n"
sb.WriteString("event: content_block_delta\n") output = output + "event: content_block_delta\n"
data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"thinking_delta","thinking":""}}`, (*param).(*Params).ResponseIndex), "delta.thinking", partTextResult.String()) data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"thinking_delta","thinking":""}}`, (*param).(*Params).ResponseIndex), "delta.thinking", partTextResult.String())
sb.WriteString(fmt.Sprintf("data: %s\n\n\n", data)) output = output + fmt.Sprintf("data: %s\n\n\n", data)
(*param).(*Params).ResponseType = 2 // Set state to thinking (*param).(*Params).ResponseType = 2 // Set state to thinking
(*param).(*Params).HasContent = true (*param).(*Params).HasContent = true
} }
@@ -138,7 +143,7 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque
// Process regular text content (user-visible output) // Process regular text content (user-visible output)
// Continue existing text block if already in content state // Continue existing text block if already in content state
if (*param).(*Params).ResponseType == 1 { if (*param).(*Params).ResponseType == 1 {
sb.WriteString("event: content_block_delta\n") output = output + "event: content_block_delta\n"
data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"text_delta","text":""}}`, (*param).(*Params).ResponseIndex), "delta.text", partTextResult.String()) data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"text_delta","text":""}}`, (*param).(*Params).ResponseIndex), "delta.text", partTextResult.String())
output = output + fmt.Sprintf("data: %s\n\n\n", data) output = output + fmt.Sprintf("data: %s\n\n\n", data)
(*param).(*Params).HasContent = true (*param).(*Params).HasContent = true
@@ -146,19 +151,24 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque
// Transition from another state to text content // Transition from another state to text content
// First, close any existing content block // First, close any existing content block
if (*param).(*Params).ResponseType != 0 { if (*param).(*Params).ResponseType != 0 {
sb.WriteString("event: content_block_stop\n") if (*param).(*Params).ResponseType == 2 {
sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)) // output = output + "event: content_block_delta\n"
sb.WriteString("\n\n\n") // output = output + fmt.Sprintf(`data: {"type":"content_block_delta","index":%d,"delta":{"type":"signature_delta","signature":null}}`, (*param).(*Params).ResponseIndex)
// output = output + "\n\n\n"
}
output = output + "event: content_block_stop\n"
output = output + fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)
output = output + "\n\n\n"
(*param).(*Params).ResponseIndex++ (*param).(*Params).ResponseIndex++
} }
// Start a new text content block // Start a new text content block
sb.WriteString("event: content_block_start\n") output = output + "event: content_block_start\n"
sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_start","index":%d,"content_block":{"type":"text","text":""}}`, (*param).(*Params).ResponseIndex)) output = output + fmt.Sprintf(`data: {"type":"content_block_start","index":%d,"content_block":{"type":"text","text":""}}`, (*param).(*Params).ResponseIndex)
sb.WriteString("\n\n\n") output = output + "\n\n\n"
sb.WriteString("event: content_block_delta\n") output = output + "event: content_block_delta\n"
data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"text_delta","text":""}}`, (*param).(*Params).ResponseIndex), "delta.text", partTextResult.String()) data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"text_delta","text":""}}`, (*param).(*Params).ResponseIndex), "delta.text", partTextResult.String())
sb.WriteString(fmt.Sprintf("data: %s\n\n\n", data)) output = output + fmt.Sprintf("data: %s\n\n\n", data)
(*param).(*Params).ResponseType = 1 // Set state to content (*param).(*Params).ResponseType = 1 // Set state to content
(*param).(*Params).HasContent = true (*param).(*Params).HasContent = true
} }
@@ -172,35 +182,42 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque
// Handle state transitions when switching to function calls // Handle state transitions when switching to function calls
// Close any existing function call block first // Close any existing function call block first
if (*param).(*Params).ResponseType == 3 { if (*param).(*Params).ResponseType == 3 {
sb.WriteString("event: content_block_stop\n") output = output + "event: content_block_stop\n"
sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)) output = output + fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)
sb.WriteString("\n\n\n") output = output + "\n\n\n"
(*param).(*Params).ResponseIndex++ (*param).(*Params).ResponseIndex++
(*param).(*Params).ResponseType = 0 (*param).(*Params).ResponseType = 0
} }
// Special handling for thinking state transition
if (*param).(*Params).ResponseType == 2 {
// output = output + "event: content_block_delta\n"
// output = output + fmt.Sprintf(`data: {"type":"content_block_delta","index":%d,"delta":{"type":"signature_delta","signature":null}}`, (*param).(*Params).ResponseIndex)
// output = output + "\n\n\n"
}
// Close any other existing content block // Close any other existing content block
if (*param).(*Params).ResponseType != 0 { if (*param).(*Params).ResponseType != 0 {
sb.WriteString("event: content_block_stop\n") output = output + "event: content_block_stop\n"
sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)) output = output + fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)
sb.WriteString("\n\n\n") output = output + "\n\n\n"
(*param).(*Params).ResponseIndex++ (*param).(*Params).ResponseIndex++
} }
// Start a new tool use content block // Start a new tool use content block
// This creates the structure for a function call in Claude Code format // This creates the structure for a function call in Claude Code format
sb.WriteString("event: content_block_start\n") output = output + "event: content_block_start\n"
// Create the tool use block with unique ID and function details // Create the tool use block with unique ID and function details
data := fmt.Sprintf(`{"type":"content_block_start","index":%d,"content_block":{"type":"tool_use","id":"","name":"","input":{}}}`, (*param).(*Params).ResponseIndex) data := fmt.Sprintf(`{"type":"content_block_start","index":%d,"content_block":{"type":"tool_use","id":"","name":"","input":{}}}`, (*param).(*Params).ResponseIndex)
data, _ = sjson.Set(data, "content_block.id", fmt.Sprintf("%s-%d-%d", fcName, time.Now().UnixNano(), atomic.AddUint64(&toolUseIDCounter, 1))) data, _ = sjson.Set(data, "content_block.id", fmt.Sprintf("%s-%d-%d", fcName, time.Now().UnixNano(), atomic.AddUint64(&toolUseIDCounter, 1)))
data, _ = sjson.Set(data, "content_block.name", fcName) data, _ = sjson.Set(data, "content_block.name", fcName)
sb.WriteString(fmt.Sprintf("data: %s\n\n\n", data)) output = output + fmt.Sprintf("data: %s\n\n\n", data)
if fcArgsResult := functionCallResult.Get("args"); fcArgsResult.Exists() { if fcArgsResult := functionCallResult.Get("args"); fcArgsResult.Exists() {
sb.WriteString("event: content_block_delta\n") output = output + "event: content_block_delta\n"
data, _ = sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"input_json_delta","partial_json":""}}`, (*param).(*Params).ResponseIndex), "delta.partial_json", fcArgsResult.Raw) data, _ = sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"input_json_delta","partial_json":""}}`, (*param).(*Params).ResponseIndex), "delta.partial_json", fcArgsResult.Raw)
sb.WriteString(fmt.Sprintf("data: %s\n\n\n", data)) output = output + fmt.Sprintf("data: %s\n\n\n", data)
} }
(*param).(*Params).ResponseType = 3 (*param).(*Params).ResponseType = 3
(*param).(*Params).HasContent = true (*param).(*Params).HasContent = true
@@ -240,7 +257,7 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque
} }
} }
return []string{sb.String()} return []string{output}
} }
// ConvertGeminiCLIResponseToClaudeNonStream converts a non-streaming Gemini CLI response to a non-streaming Claude response. // ConvertGeminiCLIResponseToClaudeNonStream converts a non-streaming Gemini CLI response to a non-streaming Claude response.