Add FunctionCallIndex to ConvertCliToOpenAIParams and enhance tool call handling

- Introduced `FunctionCallIndex` to track and manage function call indices within `ConvertCliToOpenAIParams`.
- Enhanced handling for `response.completed` and `response.output_item.done` data types to support tool call scenarios.
- Improved logic for restoring original tool names and setting function arguments during response parsing.
This commit is contained in:
Luis Pater
2025-09-05 09:02:24 +08:00
parent c62e45ee88
commit 54ffb52838

View File

@@ -21,9 +21,10 @@ var (
// ConvertCliToOpenAIParams holds parameters for response conversion. // ConvertCliToOpenAIParams holds parameters for response conversion.
type ConvertCliToOpenAIParams struct { type ConvertCliToOpenAIParams struct {
ResponseID string ResponseID string
CreatedAt int64 CreatedAt int64
Model string Model string
FunctionCallIndex int
} }
// ConvertCodexResponseToOpenAI translates a single chunk of a streaming response from the // ConvertCodexResponseToOpenAI translates a single chunk of a streaming response from the
@@ -43,9 +44,10 @@ type ConvertCliToOpenAIParams struct {
func ConvertCodexResponseToOpenAI(_ context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string { func ConvertCodexResponseToOpenAI(_ context.Context, modelName string, originalRequestRawJSON, requestRawJSON, rawJSON []byte, param *any) []string {
if *param == nil { if *param == nil {
*param = &ConvertCliToOpenAIParams{ *param = &ConvertCliToOpenAIParams{
Model: modelName, Model: modelName,
CreatedAt: 0, CreatedAt: 0,
ResponseID: "", ResponseID: "",
FunctionCallIndex: -1,
} }
} }
@@ -108,27 +110,36 @@ func ConvertCodexResponseToOpenAI(_ context.Context, modelName string, originalR
template, _ = sjson.Set(template, "choices.0.delta.content", deltaResult.String()) template, _ = sjson.Set(template, "choices.0.delta.content", deltaResult.String())
} }
} else if dataType == "response.completed" { } else if dataType == "response.completed" {
template, _ = sjson.Set(template, "choices.0.finish_reason", "stop") finishReason := "stop"
template, _ = sjson.Set(template, "choices.0.native_finish_reason", "stop") if (*param).(*ConvertCliToOpenAIParams).FunctionCallIndex != -1 {
finishReason = "tool_calls"
}
template, _ = sjson.Set(template, "choices.0.finish_reason", finishReason)
template, _ = sjson.Set(template, "choices.0.native_finish_reason", finishReason)
} else if dataType == "response.output_item.done" { } else if dataType == "response.output_item.done" {
functionCallItemTemplate := `{"id": "","type": "function","function": {"name": "","arguments": ""}}` functionCallItemTemplate := `{"index":0,"id":"","type":"function","function":{"name":"","arguments":""}}`
itemResult := rootResult.Get("item") itemResult := rootResult.Get("item")
if itemResult.Exists() { if itemResult.Exists() {
if itemResult.Get("type").String() != "function_call" { if itemResult.Get("type").String() != "function_call" {
return []string{} return []string{}
} }
// set the index
(*param).(*ConvertCliToOpenAIParams).FunctionCallIndex++
functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "index", (*param).(*ConvertCliToOpenAIParams).FunctionCallIndex)
template, _ = sjson.SetRaw(template, "choices.0.delta.tool_calls", `[]`) template, _ = sjson.SetRaw(template, "choices.0.delta.tool_calls", `[]`)
functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "id", itemResult.Get("call_id").String()) functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "id", itemResult.Get("call_id").String())
{
// Restore original tool name if it was shortened // Restore original tool name if it was shortened
name := itemResult.Get("name").String() name := itemResult.Get("name").String()
// Build reverse map on demand from original request tools // Build reverse map on demand from original request tools
rev := buildReverseMapFromOriginalOpenAI(originalRequestRawJSON) rev := buildReverseMapFromOriginalOpenAI(originalRequestRawJSON)
if orig, ok := rev[name]; ok { if orig, ok := rev[name]; ok {
name = orig name = orig
}
functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "function.name", name)
} }
functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "function.name", name)
functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "function.arguments", itemResult.Get("arguments").String()) functionCallItemTemplate, _ = sjson.Set(functionCallItemTemplate, "function.arguments", itemResult.Get("arguments").String())
template, _ = sjson.Set(template, "choices.0.delta.role", "assistant") template, _ = sjson.Set(template, "choices.0.delta.role", "assistant")
template, _ = sjson.SetRaw(template, "choices.0.delta.tool_calls.-1", functionCallItemTemplate) template, _ = sjson.SetRaw(template, "choices.0.delta.tool_calls.-1", functionCallItemTemplate)