| @@ -135,3 +135,71 @@ func TestConvertOpenAIRequestToClaude_ToolResultURLImageOnly(t *testing.T) { · 134 unmodified lines |
| 135 | t.Fatalf("Unexpected image URL: %q", got) | 135 | t.Fatalf("Unexpected image URL: %q", got) |
| 136 | } | 136 | } |
| 137 | } | 137 | } |
| | 138 | |
| | 139 | func TestConvertOpenAIRequestToClaude_SystemRoleBecomesTopLevelSystem(t *testing.T) { |
| | 140 | inputJSON := `{ |
| | 141 | "model": "gpt-4.1", |
| | 142 | "messages": [ |
| | 143 | {"role": "system", "content": "You are a helpful assistant."}, |
| | 144 | {"role": "user", "content": "Hello"} |
| | 145 | ] |
| | 146 | }` |
| | 147 | |
| | 148 | result := ConvertOpenAIRequestToClaude("claude-sonnet-4-5", []byte(inputJSON), false) |
| | 149 | resultJSON := gjson.ParseBytes(result) |
| | 150 | |
| | 151 | system := resultJSON.Get("system") |
| | 152 | if !system.IsArray() { |
| | 153 | t.Fatalf("Expected top-level system array, got %s", system.Raw) |
| | 154 | } |
| | 155 | if len(system.Array()) != 1 { |
| | 156 | t.Fatalf("Expected 1 system block, got %d. System: %s", len(system.Array()), system.Raw) |
| | 157 | } |
| | 158 | if got := system.Get("0.type").String(); got != "text" { |
| | 159 | t.Fatalf("Expected system block type %q, got %q", "text", got) |
| | 160 | } |
| | 161 | if got := system.Get("0.text").String(); got != "You are a helpful assistant." { |
| | 162 | t.Fatalf("Expected system text %q, got %q", "You are a helpful assistant.", got) |
| | 163 | } |
| | 164 | |
| | 165 | messages := resultJSON.Get("messages").Array() |
| | 166 | if len(messages) != 1 { |
| | 167 | t.Fatalf("Expected 1 non-system message, got %d. Messages: %s", len(messages), resultJSON.Get("messages").Raw) |
| | 168 | } |
| | 169 | if got := messages[0].Get("role").String(); got != "user" { |
| | 170 | t.Fatalf("Expected remaining message role %q, got %q", "user", got) |
| | 171 | } |
| | 172 | if got := messages[0].Get("content.0.text").String(); got != "Hello" { |
| | 173 | t.Fatalf("Expected user text %q, got %q", "Hello", got) |
| | 174 | } |
| | 175 | } |
| | 176 | |
| | 177 | func TestConvertOpenAIRequestToClaude_MultipleSystemMessagesMergedIntoTopLevelSystem(t *testing.T) { |
| | 178 | inputJSON := `{ |
| | 179 | "model": "gpt-4.1", |
| | 180 | "messages": [ |
| | 181 | {"role": "system", "content": "Rule 1"}, |
| | 182 | {"role": "system", "content": [{"type": "text", "text": "Rule 2"}]}, |
| | 183 | {"role": "user", "content": "Hello"} |
| | 184 | ] |
| | 185 | }` |
| | 186 | |
| | 187 | result := ConvertOpenAIRequestToClaude("claude-sonnet-4-5", []byte(inputJSON), false) |
| | 188 | resultJSON := gjson.ParseBytes(result) |
| | 189 | |
| | 190 | system := resultJSON.Get("system").Array() |
| | 191 | if len(system) != 2 { |
| | 192 | t.Fatalf("Expected 2 system blocks, got %d. System: %s", len(system), resultJSON.Get("system").Raw) |
| | 193 | } |
| | 194 | if got := system[0].Get("text").String(); got != "Rule 1" { |
| | 195 | t.Fatalf("Expected first system text %q, got %q", "Rule 1", got) |
| | 196 | } |
| | 197 | if got := system[1].Get("text").String(); got != "Rule 2" { |
| | 198 | t.Fatalf("Expected second system text %q, got %q", "Rule 2", got) |
| | 199 | } |
| | 200 | |
| | 201 | messages := resultJSON.Get("messages").Array() |
| | 202 | if len(messages) != 1 { |
| | 203 | t.Fatalf("Expected 1 non-system message, got %d. Messages: %s", len(messages), resultJSON.Get("messages").Raw) |
| | 204 | } |
| | 205 | } |