| @@ -41,6 +41,23 @@ func TestConvertClaudeRequestToGemini_ToolChoice_SpecificTool(t *testing.T) { · 40 unmodified lines |
| 41 | 41 | } |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | +func TestConvertClaudeRequestToGemini_StringSystemInstruction(t *testing.T) { |
| 45 | + inputJSON := []byte(`{ |
| 46 | + "model": "gemini-3-flash-preview", |
| 47 | + "system": "Be concise", |
| 48 | + "messages": [{"role": "user", "content": "Hello"}] |
| 49 | + }`) |
| 50 | + |
| 51 | + output := ConvertClaudeRequestToGemini("gemini-3-flash-preview", inputJSON, false) |
| 52 | + |
| 53 | + if got := gjson.GetBytes(output, "systemInstruction.parts.0.text").String(); got != "Be concise" { |
| 54 | + t.Fatalf("Expected systemInstruction text %q, got %q", "Be concise", got) |
| 55 | + } |
| 56 | + if gjson.GetBytes(output, "system_instruction").Exists() { |
| 57 | + t.Fatalf("Legacy system_instruction field should not be emitted: %s", output) |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 44 | 61 | func TestConvertClaudeRequestToGemini_ImageContent(t *testing.T) { |
| 45 | 62 | inputJSON := []byte(`{ |
| 46 | 63 | "model": "gemini-3-flash-preview", |
| @@ -92,9 +109,9 @@ func TestConvertClaudeRequestToGemini_StripsClaudeCodeAttribution(t *testing.T) · 45 unmodified lines |
| 92 | 109 | |
| 93 | 110 | output := ConvertClaudeRequestToGemini("gemini-3-flash-preview", inputJSON, false) |
| 94 | 111 | |
| 95 | | − parts := gjson.GetBytes(output, "system_instruction.parts").Array() |
| 112 | + parts := gjson.GetBytes(output, "systemInstruction.parts").Array() |
| 96 | 113 | if len(parts) != 2 { |
| 97 | | − t.Fatalf("Expected 2 system parts after attribution strip, got %d: %s", len(parts), gjson.GetBytes(output, "system_instruction.parts").Raw) |
| 114 | + t.Fatalf("Expected 2 system parts after attribution strip, got %d: %s", len(parts), gjson.GetBytes(output, "systemInstruction.parts").Raw) |
| 98 | 115 | } |
| 99 | 116 | if got := parts[0].Get("text").String(); got != "You are a Claude agent, built on Anthropic's Claude Agent SDK." { |
| 100 | 117 | t.Fatalf("Unexpected first system part: %q", got) |
| @@ -102,8 +119,8 @@ func TestConvertClaudeRequestToGemini_StripsClaudeCodeAttribution(t *testing.T) · 1 unmodified line |
| 102 | 119 | if got := parts[1].Get("text").String(); got != "User system prompt" { |
| 103 | 120 | t.Fatalf("Unexpected second system part: %q", got) |
| 104 | 121 | } |
| 105 | | − if gjson.GetBytes(output, `system_instruction.parts.#(text%"x-anthropic-billing-header:*")`).Exists() { |
| 106 | | − t.Fatalf("Claude Code attribution block was forwarded: %s", gjson.GetBytes(output, "system_instruction.parts").Raw) |
| 122 | + if gjson.GetBytes(output, `systemInstruction.parts.#(text%"x-anthropic-billing-header:*")`).Exists() { |
| 123 | + t.Fatalf("Claude Code attribution block was forwarded: %s", gjson.GetBytes(output, "systemInstruction.parts").Raw) |
| 107 | 124 | } |
| 108 | 125 | } |
| 109 | 126 | |
| @@ -144,9 +161,9 @@ func TestConvertClaudeRequestToGemini_ConvertsMessageSystemRoleToUserContent(t * · 34 unmodified lines |
| 144 | 161 | t.Fatalf("Unexpected array message-level system content text: %q", got) |
| 145 | 162 | } |
| 146 | 163 | |
| 147 | | − parts := gjson.GetBytes(output, "system_instruction.parts").Array() |
| 164 | + parts := gjson.GetBytes(output, "systemInstruction.parts").Array() |
| 148 | 165 | if len(parts) != 1 { |
| 149 | | − t.Fatalf("Expected only top-level system parts, got %d: %s", len(parts), gjson.GetBytes(output, "system_instruction.parts").Raw) |
| 166 | + t.Fatalf("Expected only top-level system parts, got %d: %s", len(parts), gjson.GetBytes(output, "systemInstruction.parts").Raw) |
| 150 | 167 | } |
| 151 | 168 | if got := parts[0].Get("text").String(); got != "Top-level rules" { |
| 152 | 169 | t.Fatalf("Unexpected first system part: %q", got) |