fix(monitors): send explicit user role in Gemini monitor probes

The Antigravity native Gemini route (generateContent) expects each
contents entry to carry an explicit "user" role, matching the request
shape used by the established Antigravity account-test flow. Without it
the probe body is rejected with 400 INVALID_ARGUMENT, so Gemini channel
monitors report false failures.

Add the explicit role to the Gemini provider adapter body and cover it
with a regression test that parses the generated request body.
This commit is contained in:
TT
2026-09-05 23:30:45 +08:00
parent ab99d56e96
commit c7343d2aa2
2 changed files with 24 additions and 1 deletions
@@ -198,7 +198,7 @@ var providerAdapters = map[string]providerAdapter{
buildBody: func(_, prompt string) ([]byte, error) {
return json.Marshal(map[string]any{
"contents": []map[string]any{
{"parts": []map[string]any{{"text": prompt}}},
{"role": "user", "parts": []map[string]any{{"text": prompt}}},
},
"generationConfig": map[string]any{"maxOutputTokens": monitorChallengeMaxTokens},
})
@@ -498,3 +498,26 @@ func TestValidateChallenge_AnthropicTextAfterThinking(t *testing.T) {
t.Fatalf("validateChallenge(%q, %q) = false, want true", respText, "2")
}
}
func TestGeminiMonitorBodyIncludesExplicitUserRole(t *testing.T) {
adapter := providerAdapters[MonitorProviderGemini]
body, err := adapter.buildBody("gemini-3.6-flash", "Reply with only 7.")
if err != nil {
t.Fatalf("buildBody() error = %v", err)
}
var payload struct {
Contents []struct {
Role string `json:"role"`
} `json:"contents"`
}
if err := json.Unmarshal(body, &payload); err != nil {
t.Fatalf("Unmarshal() error = %v", err)
}
if len(payload.Contents) != 1 {
t.Fatalf("contents length = %d, want 1", len(payload.Contents))
}
if payload.Contents[0].Role != "user" {
t.Fatalf("contents[0].role = %q, want user", payload.Contents[0].Role)
}
}