mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-16 14:57:36 +08:00
Merge pull request #7635 from wucm667/fix/issue-7629-responses-message-type
fix(apicompat): mark converted Chat role items as Responses messages
This commit is contained in:
@@ -92,6 +92,56 @@ func TestChatCompletionsToResponses_SystemMessage(t *testing.T) {
|
||||
assert.Equal(t, "user", items[1].Role)
|
||||
}
|
||||
|
||||
func TestChatCompletionsToResponses_MessageTypesWithReasoningAndTools(t *testing.T) {
|
||||
req := &ChatCompletionsRequest{
|
||||
Model: "step-5-preview",
|
||||
Messages: []ChatMessage{
|
||||
{Role: "system", Content: json.RawMessage(`"You are helpful."`)},
|
||||
{Role: "user", Content: json.RawMessage(`"Check the directory"`)},
|
||||
{
|
||||
Role: "assistant",
|
||||
Content: json.RawMessage(`"I will check."`),
|
||||
ReasoningContent: "Need to inspect the directory.",
|
||||
ToolCalls: []ChatToolCall{{
|
||||
ID: "call_1", Type: "function",
|
||||
Function: ChatFunctionCall{Name: "bash", Arguments: `{"cmd":"pwd"}`},
|
||||
}},
|
||||
},
|
||||
{Role: "tool", ToolCallID: "call_1", Content: json.RawMessage(`"/tmp"`)},
|
||||
{Role: "assistant", ReasoningContent: "The tool returned /tmp."},
|
||||
{Role: "user", Content: json.RawMessage(`"Continue"`)},
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := ChatCompletionsToResponses(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
var items []ResponsesInputItem
|
||||
require.NoError(t, json.Unmarshal(resp.Input, &items))
|
||||
require.Len(t, items, 7)
|
||||
for i, want := range []struct{ typ, role string }{
|
||||
{"message", "system"},
|
||||
{"message", "user"},
|
||||
{"message", "assistant"},
|
||||
{"function_call", ""},
|
||||
{"function_call_output", ""},
|
||||
{"message", "assistant"},
|
||||
{"message", "user"},
|
||||
} {
|
||||
assert.Equal(t, want.typ, items[i].Type, "input item %d type", i)
|
||||
assert.Equal(t, want.role, items[i].Role, "input item %d role", i)
|
||||
}
|
||||
var assistantContent, reasoningOnlyContent []ResponsesContentPart
|
||||
require.NoError(t, json.Unmarshal(items[2].Content, &assistantContent))
|
||||
require.NoError(t, json.Unmarshal(items[5].Content, &reasoningOnlyContent))
|
||||
require.Len(t, assistantContent, 1)
|
||||
require.Len(t, reasoningOnlyContent, 1)
|
||||
assert.Equal(t, "<thinking>Need to inspect the directory.</thinking>\nI will check.", assistantContent[0].Text)
|
||||
assert.Equal(t, "<thinking>The tool returned /tmp.</thinking>", reasoningOnlyContent[0].Text)
|
||||
assert.Equal(t, "call_1", items[3].CallID)
|
||||
assert.Equal(t, "call_1", items[4].CallID)
|
||||
}
|
||||
|
||||
func TestChatCompletionsToResponses_ToolCalls(t *testing.T) {
|
||||
req := &ChatCompletionsRequest{
|
||||
Model: "gpt-4o",
|
||||
|
||||
@@ -143,7 +143,7 @@ func chatSystemToResponses(m ChatMessage) ([]ResponsesInputItem, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []ResponsesInputItem{{Role: "system", Content: content}}, nil
|
||||
return []ResponsesInputItem{{Type: "message", Role: "system", Content: content}}, nil
|
||||
}
|
||||
|
||||
// chatUserToResponses converts a user message, handling both plain strings and
|
||||
@@ -157,7 +157,7 @@ func chatUserToResponses(m ChatMessage) ([]ResponsesInputItem, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []ResponsesInputItem{{Role: "user", Content: content}}, nil
|
||||
return []ResponsesInputItem{{Type: "message", Role: "user", Content: content}}, nil
|
||||
}
|
||||
|
||||
// chatAssistantToResponses converts an assistant message. If there is both
|
||||
@@ -192,7 +192,7 @@ func chatAssistantToResponses(m ChatMessage) ([]ResponsesInputItem, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, ResponsesInputItem{Role: "assistant", Content: partsJSON})
|
||||
items = append(items, ResponsesInputItem{Type: "message", Role: "assistant", Content: partsJSON})
|
||||
}
|
||||
|
||||
// Emit one function_call item per tool_call.
|
||||
|
||||
@@ -263,7 +263,7 @@ type ResponsesText struct {
|
||||
// The Type field determines which other fields are populated.
|
||||
type ResponsesInputItem struct {
|
||||
// Common
|
||||
Type string `json:"type,omitempty"` // "" for role-based messages
|
||||
Type string `json:"type,omitempty"` // "message" for role-based messages
|
||||
|
||||
// Role-based messages (developer/system/user/assistant)
|
||||
Role string `json:"role,omitempty"`
|
||||
|
||||
Reference in New Issue
Block a user