mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-06-21 23:52:50 +08:00
test(translator): add tests to validate omission of top-level output_text in OpenAI responses
- Added `TestConvertOpenAIChatCompletionsResponseToOpenAIResponses_CompletedOmitsTopLevelOutputText` to ensure `output_text` is excluded in streamed responses. - Added `TestConvertOpenAIChatCompletionsResponseToOpenAIResponses_ToolCallCompletedOmitsTopLevelOutputText` to validate behavior during tool call completions. - Introduced `TestConvertOpenAIChatCompletionsResponseToOpenAIResponsesNonStream_OmitsTopLevelOutputText` to confirm the omission of `output_text` in non-streamed responses. - Expanded test coverage to ensure consistency with native OpenAI responses.
This commit is contained in:
@@ -371,6 +371,72 @@ func TestConvertOpenAIChatCompletionsResponseToOpenAIResponses_MixedMessageAndTo
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertOpenAIChatCompletionsResponseToOpenAIResponses_CompletedOmitsTopLevelOutputText(t *testing.T) {
|
||||
in := []string{
|
||||
`data: {"id":"resp_output_text","object":"chat.completion.chunk","created":1773896263,"model":"model","choices":[{"index":0,"delta":{"role":"assistant","content":"hello ","reasoning_content":null,"tool_calls":null},"finish_reason":null}]}`,
|
||||
`data: {"id":"resp_output_text","object":"chat.completion.chunk","created":1773896263,"model":"model","choices":[{"index":0,"delta":{"role":null,"content":"world","reasoning_content":null,"tool_calls":null},"finish_reason":"stop"}],"usage":{"completion_tokens":2,"total_tokens":4,"prompt_tokens":2}}`,
|
||||
`data: [DONE]`,
|
||||
}
|
||||
|
||||
request := []byte(`{"model":"gpt-5.4"}`)
|
||||
|
||||
var param any
|
||||
var completed gjson.Result
|
||||
for _, line := range in {
|
||||
for _, chunk := range ConvertOpenAIChatCompletionsResponseToOpenAIResponses(context.Background(), "model", request, request, []byte(line), ¶m) {
|
||||
ev, data := parseOpenAIResponsesSSEEvent(t, chunk)
|
||||
if ev == "response.completed" {
|
||||
completed = data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !completed.Exists() {
|
||||
t.Fatal("expected response.completed event")
|
||||
}
|
||||
if completed.Get("response.output_text").Exists() {
|
||||
t.Fatalf("response.output_text should be omitted to match native Responses output: %s", completed.Get("response.output_text").Raw)
|
||||
}
|
||||
if got := completed.Get("response.output.0.content.0.text").String(); got != "hello world" {
|
||||
t.Fatalf("response.output text = %q, want %q", got, "hello world")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertOpenAIChatCompletionsResponseToOpenAIResponses_ToolCallCompletedOmitsTopLevelOutputText(t *testing.T) {
|
||||
in := []string{
|
||||
`data: {"id":"resp_tool_output_text","object":"chat.completion.chunk","created":1773896263,"model":"model","choices":[{"index":0,"delta":{"role":"assistant","content":"I will call the weather tool.","reasoning_content":null,"tool_calls":null},"finish_reason":null}]}`,
|
||||
`data: {"id":"resp_tool_output_text","object":"chat.completion.chunk","created":1773896263,"model":"model","choices":[{"index":0,"delta":{"role":"assistant","content":null,"reasoning_content":null,"tool_calls":[{"index":0,"id":"call_weather","type":"function","function":{"name":"get_weather","arguments":""}}]},"finish_reason":null}]}`,
|
||||
`data: {"id":"resp_tool_output_text","object":"chat.completion.chunk","created":1773896263,"model":"model","choices":[{"index":0,"delta":{"role":null,"content":null,"reasoning_content":null,"tool_calls":[{"index":0,"function":{"arguments":"{\"location\":\"北京\",\"unit\":\"celsius\"}"}}]},"finish_reason":"tool_calls"}],"usage":{"completion_tokens":10,"total_tokens":20,"prompt_tokens":10}}`,
|
||||
`data: [DONE]`,
|
||||
}
|
||||
|
||||
request := []byte(`{"model":"gpt-5.4","tool_choice":"auto","parallel_tool_calls":true}`)
|
||||
|
||||
var param any
|
||||
var completed gjson.Result
|
||||
for _, line := range in {
|
||||
for _, chunk := range ConvertOpenAIChatCompletionsResponseToOpenAIResponses(context.Background(), "model", request, request, []byte(line), ¶m) {
|
||||
ev, data := parseOpenAIResponsesSSEEvent(t, chunk)
|
||||
if ev == "response.completed" {
|
||||
completed = data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !completed.Exists() {
|
||||
t.Fatal("expected response.completed event")
|
||||
}
|
||||
if completed.Get("response.output_text").Exists() {
|
||||
t.Fatalf("response.output_text should be omitted to match native Responses output: %s", completed.Get("response.output_text").Raw)
|
||||
}
|
||||
if got := completed.Get("response.output.0.content.0.text").String(); got != "I will call the weather tool." {
|
||||
t.Fatalf("response output text = %q, want %q", got, "I will call the weather tool.")
|
||||
}
|
||||
if got := completed.Get("response.output.1.arguments").String(); !strings.Contains(got, "北京") {
|
||||
t.Fatalf("response function call arguments = %q, want Beijing argument", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertOpenAIChatCompletionsResponseToOpenAIResponses_FunctionCallDoneAndCompletedOutputStayAscending(t *testing.T) {
|
||||
in := []string{
|
||||
`data: {"id":"resp_order","object":"chat.completion.chunk","created":1773896263,"model":"model","choices":[{"index":0,"delta":{"role":"assistant","content":null,"reasoning_content":null,"tool_calls":[{"index":0,"id":"call_glob","type":"function","function":{"name":"glob","arguments":""}}]},"finish_reason":null}]}`,
|
||||
@@ -421,3 +487,18 @@ func TestConvertOpenAIChatCompletionsResponseToOpenAIResponses_FunctionCallDoneA
|
||||
t.Fatalf("unexpected completed function_call order: %v", completedOrder)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertOpenAIChatCompletionsResponseToOpenAIResponsesNonStream_OmitsTopLevelOutputText(t *testing.T) {
|
||||
request := []byte(`{"model":"gpt-5.4"}`)
|
||||
raw := []byte(`{"id":"chatcmpl_output_text","object":"chat.completion","created":1773896263,"model":"model","choices":[{"index":0,"message":{"role":"assistant","content":"ping"},"finish_reason":"stop"}],"usage":{"prompt_tokens":2,"completion_tokens":1,"total_tokens":3}}`)
|
||||
|
||||
resp := ConvertOpenAIChatCompletionsResponseToOpenAIResponsesNonStream(context.Background(), "model", request, request, raw, nil)
|
||||
data := gjson.ParseBytes(resp)
|
||||
|
||||
if data.Get("output_text").Exists() {
|
||||
t.Fatalf("output_text should be omitted to match native Responses output: %s", resp)
|
||||
}
|
||||
if got := data.Get("output.0.content.0.text").String(); got != "ping" {
|
||||
t.Fatalf("output text = %q, want %q; response=%s", got, "ping", resp)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user