History

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

Luis Pater committed 11 months agov6.6.1-1

Commit ef0edbf1 parent 242b4d51 file · +49 −32Browse files

Unified · Split

internal/translator/gemini-cli/claude/gemini-cli_claude_response.go+49−32
@@ -69,12 +69,12 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque · 68 unmodified lines
69 69
70 // Track whether tools are being used in this response chunk70 // Track whether tools are being used in this response chunk
71 usedTool := false71 usedTool := false
72 var sb strings.Builder72 output := ""
73 73
74 // Initialize the streaming session with a message_start event74 // Initialize the streaming session with a message_start event
75 // This is only sent for the very first response chunk to establish the streaming session75 // This is only sent for the very first response chunk to establish the streaming session
76 if !(*param).(*Params).HasFirstResponse {76 if !(*param).(*Params).HasFirstResponse {
77 sb.WriteString("event: message_start\n")77 output = "event: message_start\n"
78 78
79 // Create the initial message structure with default values according to Claude Code API specification79 // Create the initial message structure with default values according to Claude Code API specification
80 // This follows the Claude Code API specification for streaming message initialization80 // This follows the Claude Code API specification for streaming message initialization
@@ -87,7 +87,7 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque · 6 unmodified lines
87 if responseIDResult := gjson.GetBytes(rawJSON, "response.responseId"); responseIDResult.Exists() {87 if responseIDResult := gjson.GetBytes(rawJSON, "response.responseId"); responseIDResult.Exists() {
88 messageStartTemplate, _ = sjson.Set(messageStartTemplate, "message.id", responseIDResult.String())88 messageStartTemplate, _ = sjson.Set(messageStartTemplate, "message.id", responseIDResult.String())
89 }89 }
90 sb.WriteString(fmt.Sprintf("data: %s\n\n\n", messageStartTemplate))90 output = output + fmt.Sprintf("data: %s\n\n\n", messageStartTemplate)
91 91
92 (*param).(*Params).HasFirstResponse = true92 (*param).(*Params).HasFirstResponse = true
93 }93 }
@@ -110,7 +110,7 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque · 16 unmodified lines
110 if partResult.Get("thought").Bool() {110 if partResult.Get("thought").Bool() {
111 // Continue existing thinking block if already in thinking state111 // Continue existing thinking block if already in thinking state
112 if (*param).(*Params).ResponseType == 2 {112 if (*param).(*Params).ResponseType == 2 {
113 sb.WriteString("event: content_block_delta\n")113 output = output + "event: content_block_delta\n"
114 data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"thinking_delta","thinking":""}}`, (*param).(*Params).ResponseIndex), "delta.thinking", partTextResult.String())114 data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"thinking_delta","thinking":""}}`, (*param).(*Params).ResponseIndex), "delta.thinking", partTextResult.String())
115 output = output + fmt.Sprintf("data: %s\n\n\n", data)115 output = output + fmt.Sprintf("data: %s\n\n\n", data)
116 (*param).(*Params).HasContent = true116 (*param).(*Params).HasContent = true
@@ -118,19 +118,24 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque · 1 unmodified line
118 // Transition from another state to thinking118 // Transition from another state to thinking
119 // First, close any existing content block119 // First, close any existing content block
120 if (*param).(*Params).ResponseType != 0 {120 if (*param).(*Params).ResponseType != 0 {
121 sb.WriteString("event: content_block_stop\n")121 if (*param).(*Params).ResponseType == 2 {
122 sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex))122 // output = output + "event: content_block_delta\n"
123 sb.WriteString("\n\n\n")123 // output = output + fmt.Sprintf(`data: {"type":"content_block_delta","index":%d,"delta":{"type":"signature_delta","signature":null}}`, (*param).(*Params).ResponseIndex)
124 // output = output + "\n\n\n"
125 }
126 output = output + "event: content_block_stop\n"
127 output = output + fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)
128 output = output + "\n\n\n"
124 (*param).(*Params).ResponseIndex++129 (*param).(*Params).ResponseIndex++
125 }130 }
126 131
127 // Start a new thinking content block132 // Start a new thinking content block
128 sb.WriteString("event: content_block_start\n")133 output = output + "event: content_block_start\n"
129 sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_start","index":%d,"content_block":{"type":"thinking","thinking":""}}`, (*param).(*Params).ResponseIndex))134 output = output + fmt.Sprintf(`data: {"type":"content_block_start","index":%d,"content_block":{"type":"thinking","thinking":""}}`, (*param).(*Params).ResponseIndex)
130 sb.WriteString("\n\n\n")135 output = output + "\n\n\n"
131 sb.WriteString("event: content_block_delta\n")136 output = output + "event: content_block_delta\n"
132 data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"thinking_delta","thinking":""}}`, (*param).(*Params).ResponseIndex), "delta.thinking", partTextResult.String())137 data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"thinking_delta","thinking":""}}`, (*param).(*Params).ResponseIndex), "delta.thinking", partTextResult.String())
133 sb.WriteString(fmt.Sprintf("data: %s\n\n\n", data))138 output = output + fmt.Sprintf("data: %s\n\n\n", data)
134 (*param).(*Params).ResponseType = 2 // Set state to thinking139 (*param).(*Params).ResponseType = 2 // Set state to thinking
135 (*param).(*Params).HasContent = true140 (*param).(*Params).HasContent = true
136 }141 }
@@ -138,7 +143,7 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque · 1 unmodified line
138 // Process regular text content (user-visible output)143 // Process regular text content (user-visible output)
139 // Continue existing text block if already in content state144 // Continue existing text block if already in content state
140 if (*param).(*Params).ResponseType == 1 {145 if (*param).(*Params).ResponseType == 1 {
141 sb.WriteString("event: content_block_delta\n")146 output = output + "event: content_block_delta\n"
142 data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"text_delta","text":""}}`, (*param).(*Params).ResponseIndex), "delta.text", partTextResult.String())147 data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"text_delta","text":""}}`, (*param).(*Params).ResponseIndex), "delta.text", partTextResult.String())
143 output = output + fmt.Sprintf("data: %s\n\n\n", data)148 output = output + fmt.Sprintf("data: %s\n\n\n", data)
144 (*param).(*Params).HasContent = true149 (*param).(*Params).HasContent = true
@@ -146,19 +151,24 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque · 1 unmodified line
146 // Transition from another state to text content151 // Transition from another state to text content
147 // First, close any existing content block152 // First, close any existing content block
148 if (*param).(*Params).ResponseType != 0 {153 if (*param).(*Params).ResponseType != 0 {
149 sb.WriteString("event: content_block_stop\n")154 if (*param).(*Params).ResponseType == 2 {
150 sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex))155 // output = output + "event: content_block_delta\n"
151 sb.WriteString("\n\n\n")156 // output = output + fmt.Sprintf(`data: {"type":"content_block_delta","index":%d,"delta":{"type":"signature_delta","signature":null}}`, (*param).(*Params).ResponseIndex)
157 // output = output + "\n\n\n"
158 }
159 output = output + "event: content_block_stop\n"
160 output = output + fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)
161 output = output + "\n\n\n"
152 (*param).(*Params).ResponseIndex++162 (*param).(*Params).ResponseIndex++
153 }163 }
154 164
155 // Start a new text content block165 // Start a new text content block
156 sb.WriteString("event: content_block_start\n")166 output = output + "event: content_block_start\n"
157 sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_start","index":%d,"content_block":{"type":"text","text":""}}`, (*param).(*Params).ResponseIndex))167 output = output + fmt.Sprintf(`data: {"type":"content_block_start","index":%d,"content_block":{"type":"text","text":""}}`, (*param).(*Params).ResponseIndex)
158 sb.WriteString("\n\n\n")168 output = output + "\n\n\n"
159 sb.WriteString("event: content_block_delta\n")169 output = output + "event: content_block_delta\n"
160 data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"text_delta","text":""}}`, (*param).(*Params).ResponseIndex), "delta.text", partTextResult.String())170 data, _ := sjson.Set(fmt.Sprintf(`{"type":"content_block_delta","index":%d,"delta":{"type":"text_delta","text":""}}`, (*param).(*Params).ResponseIndex), "delta.text", partTextResult.String())
161 sb.WriteString(fmt.Sprintf("data: %s\n\n\n", data))171 output = output + fmt.Sprintf("data: %s\n\n\n", data)
162 (*param).(*Params).ResponseType = 1 // Set state to content172 (*param).(*Params).ResponseType = 1 // Set state to content
163 (*param).(*Params).HasContent = true173 (*param).(*Params).HasContent = true
164 }174 }
@@ -172,35 +182,42 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque · 7 unmodified lines
172 // Handle state transitions when switching to function calls182 // Handle state transitions when switching to function calls
173 // Close any existing function call block first183 // Close any existing function call block first
174 if (*param).(*Params).ResponseType == 3 {184 if (*param).(*Params).ResponseType == 3 {
175 sb.WriteString("event: content_block_stop\n")185 output = output + "event: content_block_stop\n"
176 sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex))186 output = output + fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)
177 sb.WriteString("\n\n\n")187 output = output + "\n\n\n"
178 (*param).(*Params).ResponseIndex++188 (*param).(*Params).ResponseIndex++
179 (*param).(*Params).ResponseType = 0189 (*param).(*Params).ResponseType = 0
180 }190 }
181 191
192 // Special handling for thinking state transition
193 if (*param).(*Params).ResponseType == 2 {
194 // output = output + "event: content_block_delta\n"
195 // output = output + fmt.Sprintf(`data: {"type":"content_block_delta","index":%d,"delta":{"type":"signature_delta","signature":null}}`, (*param).(*Params).ResponseIndex)
196 // output = output + "\n\n\n"
197 }
198
182 // Close any other existing content block199 // Close any other existing content block
183 if (*param).(*Params).ResponseType != 0 {200 if (*param).(*Params).ResponseType != 0 {
184 sb.WriteString("event: content_block_stop\n")201 output = output + "event: content_block_stop\n"
185 sb.WriteString(fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex))202 output = output + fmt.Sprintf(`data: {"type":"content_block_stop","index":%d}`, (*param).(*Params).ResponseIndex)
186 sb.WriteString("\n\n\n")203 output = output + "\n\n\n"
187 (*param).(*Params).ResponseIndex++204 (*param).(*Params).ResponseIndex++
188 }205 }
189 206
190 // Start a new tool use content block207 // Start a new tool use content block
191 // This creates the structure for a function call in Claude Code format208 // This creates the structure for a function call in Claude Code format
192 sb.WriteString("event: content_block_start\n")209 output = output + "event: content_block_start\n"
193 210
194 // Create the tool use block with unique ID and function details211 // Create the tool use block with unique ID and function details
195 data := fmt.Sprintf(`{"type":"content_block_start","index":%d,"content_block":{"type":"tool_use","id":"","name":"","input":{}}}`, (*param).(*Params).ResponseIndex)212 data := fmt.Sprintf(`{"type":"content_block_start","index":%d,"content_block":{"type":"tool_use","id":"","name":"","input":{}}}`, (*param).(*Params).ResponseIndex)
196 data, _ = sjson.Set(data, "content_block.id", fmt.Sprintf("%s-%d-%d", fcName, time.Now().UnixNano(), atomic.AddUint64(&toolUseIDCounter, 1)))213 data, _ = sjson.Set(data, "content_block.id", fmt.Sprintf("%s-%d-%d", fcName, time.Now().UnixNano(), atomic.AddUint64(&toolUseIDCounter, 1)))
197 data, _ = sjson.Set(data, "content_block.name", fcName)214 data, _ = sjson.Set(data, "content_block.name", fcName)
198 sb.WriteString(fmt.Sprintf("data: %s\n\n\n", data))215 output = output + fmt.Sprintf("data: %s\n\n\n", data)
199 216
200 if fcArgsResult := functionCallResult.Get("args"); fcArgsResult.Exists() {217 if fcArgsResult := functionCallResult.Get("args"); fcArgsResult.Exists() {
201 sb.WriteString("event: content_block_delta\n")218 output = output + "event: content_block_delta\n"
202 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)219 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)
203 sb.WriteString(fmt.Sprintf("data: %s\n\n\n", data))220 output = output + fmt.Sprintf("data: %s\n\n\n", data)
204 }221 }
205 (*param).(*Params).ResponseType = 3222 (*param).(*Params).ResponseType = 3
206 (*param).(*Params).HasContent = true223 (*param).(*Params).HasContent = true
@@ -240,7 +257,7 @@ func ConvertGeminiCLIResponseToClaude(_ context.Context, _ string, originalReque · 33 unmodified lines
240 }257 }
241 }258 }
242 259
243 return []string{sb.String()}260 return []string{output}
244}261}
245 262
246// ConvertGeminiCLIResponseToClaudeNonStream converts a non-streaming Gemini CLI response to a non-streaming Claude response.263// ConvertGeminiCLIResponseToClaudeNonStream converts a non-streaming Gemini CLI response to a non-streaming Claude response.