Skip to content

Commit 735b213

Browse files
committed
refactor: simplify ConvertCodexResponseToClaudeNonStream by removing bufio.Scanner usage and restructuring response parsing logic
1 parent 9cdef93 commit 735b213

File tree

1 file changed

+118
-135
lines changed

1 file changed

+118
-135
lines changed

internal/translator/codex/claude/codex_claude_response.go

Lines changed: 118 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
package claude
88

99
import (
10-
"bufio"
1110
"bytes"
1211
"context"
1312
"encoding/json"
@@ -180,56 +179,58 @@ func ConvertCodexResponseToClaude(_ context.Context, _ string, originalRequestRa
180179
// Returns:
181180
// - string: A Claude Code-compatible JSON response containing all message content and metadata
182181
func ConvertCodexResponseToClaudeNonStream(_ context.Context, _ string, originalRequestRawJSON, _ []byte, rawJSON []byte, _ *any) string {
183-
scanner := bufio.NewScanner(bytes.NewReader(rawJSON))
184-
buffer := make([]byte, 20_971_520)
185-
scanner.Buffer(buffer, 20_971_520)
186182
revNames := buildReverseMapFromClaudeOriginalShortToOriginal(originalRequestRawJSON)
187183

188-
for scanner.Scan() {
189-
line := scanner.Bytes()
190-
if !bytes.HasPrefix(line, dataTag) {
191-
continue
192-
}
193-
payload := bytes.TrimSpace(line[len(dataTag):])
194-
if len(payload) == 0 {
195-
continue
196-
}
197-
198-
rootResult := gjson.ParseBytes(payload)
199-
if rootResult.Get("type").String() != "response.completed" {
200-
continue
201-
}
202-
203-
responseData := rootResult.Get("response")
204-
if !responseData.Exists() {
205-
continue
206-
}
184+
rootResult := gjson.ParseBytes(rawJSON)
185+
if rootResult.Get("type").String() != "response.completed" {
186+
return ""
187+
}
207188

208-
response := map[string]interface{}{
209-
"id": responseData.Get("id").String(),
210-
"type": "message",
211-
"role": "assistant",
212-
"model": responseData.Get("model").String(),
213-
"content": []interface{}{},
214-
"stop_reason": nil,
215-
"stop_sequence": nil,
216-
"usage": map[string]interface{}{
217-
"input_tokens": responseData.Get("usage.input_tokens").Int(),
218-
"output_tokens": responseData.Get("usage.output_tokens").Int(),
219-
},
220-
}
189+
responseData := rootResult.Get("response")
190+
if !responseData.Exists() {
191+
return ""
192+
}
221193

222-
var contentBlocks []interface{}
223-
hasToolCall := false
194+
response := map[string]interface{}{
195+
"id": responseData.Get("id").String(),
196+
"type": "message",
197+
"role": "assistant",
198+
"model": responseData.Get("model").String(),
199+
"content": []interface{}{},
200+
"stop_reason": nil,
201+
"stop_sequence": nil,
202+
"usage": map[string]interface{}{
203+
"input_tokens": responseData.Get("usage.input_tokens").Int(),
204+
"output_tokens": responseData.Get("usage.output_tokens").Int(),
205+
},
206+
}
224207

225-
if output := responseData.Get("output"); output.Exists() && output.IsArray() {
226-
output.ForEach(func(_, item gjson.Result) bool {
227-
switch item.Get("type").String() {
228-
case "reasoning":
229-
thinkingBuilder := strings.Builder{}
230-
if summary := item.Get("summary"); summary.Exists() {
231-
if summary.IsArray() {
232-
summary.ForEach(func(_, part gjson.Result) bool {
208+
var contentBlocks []interface{}
209+
hasToolCall := false
210+
211+
if output := responseData.Get("output"); output.Exists() && output.IsArray() {
212+
output.ForEach(func(_, item gjson.Result) bool {
213+
switch item.Get("type").String() {
214+
case "reasoning":
215+
thinkingBuilder := strings.Builder{}
216+
if summary := item.Get("summary"); summary.Exists() {
217+
if summary.IsArray() {
218+
summary.ForEach(func(_, part gjson.Result) bool {
219+
if txt := part.Get("text"); txt.Exists() {
220+
thinkingBuilder.WriteString(txt.String())
221+
} else {
222+
thinkingBuilder.WriteString(part.String())
223+
}
224+
return true
225+
})
226+
} else {
227+
thinkingBuilder.WriteString(summary.String())
228+
}
229+
}
230+
if thinkingBuilder.Len() == 0 {
231+
if content := item.Get("content"); content.Exists() {
232+
if content.IsArray() {
233+
content.ForEach(func(_, part gjson.Result) bool {
233234
if txt := part.Get("text"); txt.Exists() {
234235
thinkingBuilder.WriteString(txt.String())
235236
} else {
@@ -238,114 +239,96 @@ func ConvertCodexResponseToClaudeNonStream(_ context.Context, _ string, original
238239
return true
239240
})
240241
} else {
241-
thinkingBuilder.WriteString(summary.String())
242+
thinkingBuilder.WriteString(content.String())
242243
}
243244
}
244-
if thinkingBuilder.Len() == 0 {
245-
if content := item.Get("content"); content.Exists() {
246-
if content.IsArray() {
247-
content.ForEach(func(_, part gjson.Result) bool {
248-
if txt := part.Get("text"); txt.Exists() {
249-
thinkingBuilder.WriteString(txt.String())
250-
} else {
251-
thinkingBuilder.WriteString(part.String())
252-
}
253-
return true
254-
})
255-
} else {
256-
thinkingBuilder.WriteString(content.String())
245+
}
246+
if thinkingBuilder.Len() > 0 {
247+
contentBlocks = append(contentBlocks, map[string]interface{}{
248+
"type": "thinking",
249+
"thinking": thinkingBuilder.String(),
250+
})
251+
}
252+
case "message":
253+
if content := item.Get("content"); content.Exists() {
254+
if content.IsArray() {
255+
content.ForEach(func(_, part gjson.Result) bool {
256+
if part.Get("type").String() == "output_text" {
257+
text := part.Get("text").String()
258+
if text != "" {
259+
contentBlocks = append(contentBlocks, map[string]interface{}{
260+
"type": "text",
261+
"text": text,
262+
})
263+
}
257264
}
258-
}
259-
}
260-
if thinkingBuilder.Len() > 0 {
261-
contentBlocks = append(contentBlocks, map[string]interface{}{
262-
"type": "thinking",
263-
"thinking": thinkingBuilder.String(),
265+
return true
264266
})
265-
}
266-
case "message":
267-
if content := item.Get("content"); content.Exists() {
268-
if content.IsArray() {
269-
content.ForEach(func(_, part gjson.Result) bool {
270-
if part.Get("type").String() == "output_text" {
271-
text := part.Get("text").String()
272-
if text != "" {
273-
contentBlocks = append(contentBlocks, map[string]interface{}{
274-
"type": "text",
275-
"text": text,
276-
})
277-
}
278-
}
279-
return true
267+
} else {
268+
text := content.String()
269+
if text != "" {
270+
contentBlocks = append(contentBlocks, map[string]interface{}{
271+
"type": "text",
272+
"text": text,
280273
})
281-
} else {
282-
text := content.String()
283-
if text != "" {
284-
contentBlocks = append(contentBlocks, map[string]interface{}{
285-
"type": "text",
286-
"text": text,
287-
})
288-
}
289274
}
290275
}
291-
case "function_call":
292-
hasToolCall = true
293-
name := item.Get("name").String()
294-
if original, ok := revNames[name]; ok {
295-
name = original
296-
}
276+
}
277+
case "function_call":
278+
hasToolCall = true
279+
name := item.Get("name").String()
280+
if original, ok := revNames[name]; ok {
281+
name = original
282+
}
297283

298-
toolBlock := map[string]interface{}{
299-
"type": "tool_use",
300-
"id": item.Get("call_id").String(),
301-
"name": name,
302-
"input": map[string]interface{}{},
303-
}
284+
toolBlock := map[string]interface{}{
285+
"type": "tool_use",
286+
"id": item.Get("call_id").String(),
287+
"name": name,
288+
"input": map[string]interface{}{},
289+
}
304290

305-
if argsStr := item.Get("arguments").String(); argsStr != "" {
306-
var args interface{}
307-
if err := json.Unmarshal([]byte(argsStr), &args); err == nil {
308-
toolBlock["input"] = args
309-
}
291+
if argsStr := item.Get("arguments").String(); argsStr != "" {
292+
var args interface{}
293+
if err := json.Unmarshal([]byte(argsStr), &args); err == nil {
294+
toolBlock["input"] = args
310295
}
311-
312-
contentBlocks = append(contentBlocks, toolBlock)
313296
}
314-
return true
315-
})
316-
}
317297

318-
if len(contentBlocks) > 0 {
319-
response["content"] = contentBlocks
320-
}
298+
contentBlocks = append(contentBlocks, toolBlock)
299+
}
300+
return true
301+
})
302+
}
321303

322-
if stopReason := responseData.Get("stop_reason"); stopReason.Exists() && stopReason.String() != "" {
323-
response["stop_reason"] = stopReason.String()
324-
} else if hasToolCall {
325-
response["stop_reason"] = "tool_use"
326-
} else {
327-
response["stop_reason"] = "end_turn"
328-
}
304+
if len(contentBlocks) > 0 {
305+
response["content"] = contentBlocks
306+
}
329307

330-
if stopSequence := responseData.Get("stop_sequence"); stopSequence.Exists() && stopSequence.String() != "" {
331-
response["stop_sequence"] = stopSequence.Value()
332-
}
308+
if stopReason := responseData.Get("stop_reason"); stopReason.Exists() && stopReason.String() != "" {
309+
response["stop_reason"] = stopReason.String()
310+
} else if hasToolCall {
311+
response["stop_reason"] = "tool_use"
312+
} else {
313+
response["stop_reason"] = "end_turn"
314+
}
333315

334-
if responseData.Get("usage.input_tokens").Exists() || responseData.Get("usage.output_tokens").Exists() {
335-
response["usage"] = map[string]interface{}{
336-
"input_tokens": responseData.Get("usage.input_tokens").Int(),
337-
"output_tokens": responseData.Get("usage.output_tokens").Int(),
338-
}
339-
}
316+
if stopSequence := responseData.Get("stop_sequence"); stopSequence.Exists() && stopSequence.String() != "" {
317+
response["stop_sequence"] = stopSequence.Value()
318+
}
340319

341-
responseJSON, err := json.Marshal(response)
342-
if err != nil {
343-
return ""
320+
if responseData.Get("usage.input_tokens").Exists() || responseData.Get("usage.output_tokens").Exists() {
321+
response["usage"] = map[string]interface{}{
322+
"input_tokens": responseData.Get("usage.input_tokens").Int(),
323+
"output_tokens": responseData.Get("usage.output_tokens").Int(),
344324
}
345-
return string(responseJSON)
346325
}
347326

348-
return ""
327+
responseJSON, err := json.Marshal(response)
328+
if err != nil {
329+
return ""
330+
}
331+
return string(responseJSON)
349332
}
350333

351334
// buildReverseMapFromClaudeOriginalShortToOriginal builds a map[short]original from original Claude request tools.

0 commit comments

Comments
 (0)