Skip to content

Commit 2401379

Browse files
Copilotsawka
andcommitted
Fix Gemini schema validation by cleaning unsupported JSON Schema fields
Gemini's API uses a strict subset of JSON Schema and rejects: - $schema field - units (custom property field) - title field - definitions field - $ref field - other non-standard fields Added cleanSchemaForGemini() function that filters the schema to only include fields that Gemini accepts (type, properties, required, description, items, enum, format, minimum, maximum, pattern, default). This fixes the "Invalid JSON payload received. Unknown name" errors when using tools with the --gemini flag in main-testai.go. Co-authored-by: sawka <2722291+sawka@users.noreply.github.com>
1 parent f6452f1 commit 2401379

1 file changed

Lines changed: 60 additions & 1 deletion

File tree

pkg/aiusechat/gemini/gemini-convertmessage.go

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,71 @@ import (
1515
"github.com/wavetermdev/waveterm/pkg/aiusechat/uctypes"
1616
)
1717

18+
// cleanSchemaForGemini removes fields from JSON Schema that Gemini doesn't accept
19+
// Gemini uses a strict subset of JSON Schema and rejects fields like $schema, units, title, etc.
20+
func cleanSchemaForGemini(schema map[string]any) map[string]any {
21+
if schema == nil {
22+
return nil
23+
}
24+
25+
cleaned := make(map[string]any)
26+
27+
// Fields that Gemini accepts in the root schema
28+
allowedRootFields := map[string]bool{
29+
"type": true,
30+
"properties": true,
31+
"required": true,
32+
"description": true,
33+
"items": true,
34+
"enum": true,
35+
"format": true,
36+
"minimum": true,
37+
"maximum": true,
38+
"pattern": true,
39+
"default": true,
40+
}
41+
42+
for key, value := range schema {
43+
if !allowedRootFields[key] {
44+
// Skip fields like $schema, title, units, definitions, $ref, etc.
45+
continue
46+
}
47+
48+
// Recursively clean nested schemas
49+
switch key {
50+
case "properties":
51+
if props, ok := value.(map[string]any); ok {
52+
cleanedProps := make(map[string]any)
53+
for propName, propValue := range props {
54+
if propSchema, ok := propValue.(map[string]any); ok {
55+
cleanedProps[propName] = cleanSchemaForGemini(propSchema)
56+
}
57+
}
58+
cleaned[key] = cleanedProps
59+
}
60+
case "items":
61+
if items, ok := value.(map[string]any); ok {
62+
cleaned[key] = cleanSchemaForGemini(items)
63+
} else {
64+
cleaned[key] = value
65+
}
66+
default:
67+
cleaned[key] = value
68+
}
69+
}
70+
71+
return cleaned
72+
}
73+
1874
// ConvertToolDefinitionToGemini converts a Wave ToolDefinition to Gemini format
1975
func ConvertToolDefinitionToGemini(tool uctypes.ToolDefinition) GeminiFunctionDeclaration {
76+
// Clean the schema to remove fields that Gemini doesn't accept
77+
cleanedSchema := cleanSchemaForGemini(tool.InputSchema)
78+
2079
return GeminiFunctionDeclaration{
2180
Name: tool.Name,
2281
Description: tool.Description,
23-
Parameters: tool.InputSchema,
82+
Parameters: cleanedSchema,
2483
}
2584
}
2685

0 commit comments

Comments
 (0)