@@ -55,6 +55,80 @@ func TestConvertOpenAIResponsesRequestToGemini_ReasoningSignatureCompatibility(t
5555 }
5656}
5757
58+ func TestConvertOpenAIResponsesRequestToGemini_SystemAndDeveloperRoles (t * testing.T ) {
59+ tests := []struct {
60+ name string
61+ role string
62+ wantText string
63+ }{
64+ {
65+ name : "system role" ,
66+ role : "system" ,
67+ wantText : "System message text" ,
68+ },
69+ {
70+ name : "developer role" ,
71+ role : "developer" ,
72+ wantText : "Developer message text" ,
73+ },
74+ }
75+
76+ for _ , tt := range tests {
77+ t .Run (tt .name , func (t * testing.T ) {
78+ input := []byte (`{
79+ "instructions": "Be a helpful assistant",
80+ "input": [
81+ {
82+ "type": "message",
83+ "role": "` + tt .role + `",
84+ "content": [
85+ {
86+ "type": "input_text",
87+ "text": "` + tt .wantText + `"
88+ }
89+ ]
90+ },
91+ {
92+ "type": "message",
93+ "role": "user",
94+ "content": [
95+ {
96+ "type": "input_text",
97+ "text": "Hello"
98+ }
99+ ]
100+ }
101+ ]
102+ }` )
103+
104+ output := ConvertOpenAIResponsesRequestToGemini ("gemini-3.5-flash" , input , false )
105+ result := gjson .ParseBytes (output )
106+
107+ systemInstruction := result .Get ("systemInstruction" )
108+ if ! systemInstruction .Exists () {
109+ t .Fatalf ("systemInstruction missing. Output: %s" , output )
110+ }
111+ parts := systemInstruction .Get ("parts" )
112+ if got := parts .Get ("#" ).Int (); got != 2 {
113+ t .Fatalf ("systemInstruction parts = %d, want 2. Output: %s" , got , output )
114+ }
115+ if got := parts .Get ("0.text" ).String (); got != "Be a helpful assistant" {
116+ t .Fatalf ("first systemInstruction part = %q, want %q. Output: %s" , got , "Be a helpful assistant" , output )
117+ }
118+ if got := parts .Get ("1.text" ).String (); got != tt .wantText {
119+ t .Fatalf ("second systemInstruction part = %q, want %q. Output: %s" , got , tt .wantText , output )
120+ }
121+
122+ result .Get ("contents" ).ForEach (func (_ , value gjson.Result ) bool {
123+ if role := value .Get ("role" ).String (); role == tt .role {
124+ t .Fatalf ("role %q leaked into contents array. Output: %s" , tt .role , output )
125+ }
126+ return true
127+ })
128+ })
129+ }
130+ }
131+
58132func validResponsesGPTReasoningSignature () string {
59133 raw := make ([]byte , 1 + 8 + 16 + 16 + 32 )
60134 raw [0 ] = 0x80
0 commit comments