Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
157 lines
4.4 KiB
Go
157 lines
4.4 KiB
Go
package apicompat
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestResponsesInputToChatMessages_DeveloperRoleMapsToSystem(t *testing.T) {
|
|
messages, err := responsesInputToChatMessages("", json.RawMessage(`[{"role":"developer","content":"follow project instructions"}]`))
|
|
require.NoError(t, err)
|
|
require.Len(t, messages, 1)
|
|
|
|
assert.Equal(t, "system", messages[0].Role)
|
|
assert.JSONEq(t, `"follow project instructions"`, string(messages[0].Content))
|
|
}
|
|
|
|
func TestResponsesInputToChatMessages_KeepsChatCompletionRoles(t *testing.T) {
|
|
input := json.RawMessage(`[
|
|
{"role":"system","content":"system message"},
|
|
{"role":"user","content":"user message"},
|
|
{"role":"assistant","content":"assistant message"},
|
|
{"role":"tool","content":"tool message"}
|
|
]`)
|
|
|
|
messages, err := responsesInputToChatMessages("", input)
|
|
require.NoError(t, err)
|
|
require.Len(t, messages, 4)
|
|
|
|
assert.Equal(t, []string{"system", "user", "assistant", "tool"}, chatMessageRoles(messages))
|
|
}
|
|
|
|
func TestResponsesInputToChatMessages_EmptyRoleFallsBackToUser(t *testing.T) {
|
|
messages, err := responsesInputToChatMessages("", json.RawMessage(`[{"role":"","content":"hello"}]`))
|
|
require.NoError(t, err)
|
|
require.Len(t, messages, 1)
|
|
|
|
assert.Equal(t, "user", messages[0].Role)
|
|
}
|
|
|
|
func TestResponsesInputToChatMessages_DeveloperRoleTrimAndCaseInsensitive(t *testing.T) {
|
|
input := json.RawMessage(`[
|
|
{"role":" Developer ","content":"one"},
|
|
{"role":"\tDEVELOPER\n","content":"two"}
|
|
]`)
|
|
|
|
messages, err := responsesInputToChatMessages("", input)
|
|
require.NoError(t, err)
|
|
require.Len(t, messages, 2)
|
|
|
|
assert.Equal(t, []string{"system", "system"}, chatMessageRoles(messages))
|
|
}
|
|
|
|
func TestResponsesToChatCompletionsRequest_InstructionsAndInputDeveloperRole(t *testing.T) {
|
|
req := &ResponsesRequest{
|
|
Model: "gpt-4o",
|
|
Instructions: "Use concise answers.",
|
|
Input: json.RawMessage(`[
|
|
{"role":"developer","content":[{"type":"input_text","text":"Prefer JSON."}]},
|
|
{"role":"user","content":"Hello"}
|
|
]`),
|
|
}
|
|
|
|
out, err := ResponsesToChatCompletionsRequest(req)
|
|
require.NoError(t, err)
|
|
require.Len(t, out.Messages, 3)
|
|
|
|
assert.Equal(t, []string{"system", "system", "user"}, chatMessageRoles(out.Messages))
|
|
assert.JSONEq(t, `"Use concise answers."`, string(out.Messages[0].Content))
|
|
assert.JSONEq(t, `"Prefer JSON."`, string(out.Messages[1].Content))
|
|
assert.JSONEq(t, `"Hello"`, string(out.Messages[2].Content))
|
|
}
|
|
|
|
func TestResponsesToChatCompletionsRequest_TextFormatJsonObject(t *testing.T) {
|
|
req := &ResponsesRequest{
|
|
Model: "gpt-4o",
|
|
Input: json.RawMessage(`[
|
|
{"role":"user","content":"Return JSON"}
|
|
]`),
|
|
Text: &ResponsesText{
|
|
Format: json.RawMessage(`{"type":"json_object"}`),
|
|
},
|
|
}
|
|
|
|
out, err := ResponsesToChatCompletionsRequest(req)
|
|
require.NoError(t, err)
|
|
assert.JSONEq(t, `{"type":"json_object"}`, string(out.ResponseFormat))
|
|
}
|
|
|
|
func TestResponsesToChatCompletionsRequest_TextFormatJsonSchema(t *testing.T) {
|
|
req := &ResponsesRequest{
|
|
Model: "gpt-4o",
|
|
Input: json.RawMessage(`[
|
|
{"role":"user","content":"Return structured JSON"}
|
|
]`),
|
|
Text: &ResponsesText{
|
|
Format: json.RawMessage(`{
|
|
"type":"json_schema",
|
|
"name":"answer",
|
|
"schema":{
|
|
"type":"object",
|
|
"properties":{"ok":{"type":"boolean"}},
|
|
"required":["ok"],
|
|
"additionalProperties":false
|
|
},
|
|
"strict":true
|
|
}`),
|
|
},
|
|
}
|
|
|
|
out, err := ResponsesToChatCompletionsRequest(req)
|
|
require.NoError(t, err)
|
|
assert.JSONEq(t, `{
|
|
"type":"json_schema",
|
|
"json_schema":{
|
|
"name":"answer",
|
|
"schema":{
|
|
"type":"object",
|
|
"properties":{"ok":{"type":"boolean"}},
|
|
"required":["ok"],
|
|
"additionalProperties":false
|
|
},
|
|
"strict":true
|
|
}
|
|
}`, string(out.ResponseFormat))
|
|
}
|
|
|
|
func TestResponsesToChatCompletionsRequest_ParallelToolCalls(t *testing.T) {
|
|
parallel := false
|
|
req := &ResponsesRequest{
|
|
Model: "gpt-4o",
|
|
Input: json.RawMessage(`[
|
|
{"role":"user","content":"Use tools"}
|
|
]`),
|
|
ParallelToolCalls: ¶llel,
|
|
}
|
|
|
|
out, err := ResponsesToChatCompletionsRequest(req)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, out.ParallelToolCalls)
|
|
assert.False(t, *out.ParallelToolCalls)
|
|
|
|
payload, err := json.Marshal(out)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, string(payload), `"parallel_tool_calls":false`)
|
|
}
|
|
|
|
func chatMessageRoles(messages []ChatMessage) []string {
|
|
roles := make([]string, 0, len(messages))
|
|
for _, message := range messages {
|
|
roles = append(roles, message.Role)
|
|
}
|
|
return roles
|
|
}
|