fix(grammars): handle empty parameters on object types (#6409)

fix: handle empty parameters on object types

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
Ettore Di Giacinto
2025-10-08 19:13:40 +02:00
committed by GitHub
parent 5e1d809904
commit df46a438b8
3 changed files with 45 additions and 1 deletions

View File

@@ -247,6 +247,8 @@ func ChatEndpoint(cl *config.ModelConfigLoader, ml *model.ModelLoader, evaluator
g, err := fs.Grammar(config.FunctionsConfig.GrammarOptions()...)
if err == nil {
input.Grammar = g
} else {
log.Error().Err(err).Msg("Failed generating grammar")
}
}
}
@@ -286,11 +288,15 @@ func ChatEndpoint(cl *config.ModelConfigLoader, ml *model.ModelLoader, evaluator
g, err := jsStruct.Grammar(config.FunctionsConfig.GrammarOptions()...)
if err == nil {
config.Grammar = g
} else {
log.Error().Err(err).Msg("Failed generating grammar")
}
case input.JSONFunctionGrammarObject != nil:
g, err := input.JSONFunctionGrammarObject.Grammar(config.FunctionsConfig.GrammarOptions()...)
if err == nil {
config.Grammar = g
} else {
log.Error().Err(err).Msg("Failed generating grammar")
}
default:
// Force picking one of the functions by the request

View File

@@ -171,10 +171,14 @@ func (sc *JSONSchemaConverter) visit(schema map[string]interface{}, name string,
}
rule := fmt.Sprintf(`"[" space (%s ("," space %s)*)? "]" space`, itemRuleName, itemRuleName)
return sc.addRule(ruleName, rule), nil
} else if properties, _ := schema["properties"].(map[string]interface{}); (schemaType == "object" || schemaType == "") && len(properties) == 0 {
// Handle empty object schema (no properties)
rule := `"{" space "}" space`
return sc.addRule(ruleName, rule), nil
} else {
primitiveRule, exists := PRIMITIVE_RULES[schemaType]
if !exists {
return "", fmt.Errorf("unrecognized schema: %v", schema)
return "", fmt.Errorf("unrecognized schema: %v (type: %s)", schema, schemaType)
}
if ruleName == "root" {
schemaType = "root"

View File

@@ -442,5 +442,39 @@ realvalue
}
}
})
It("handles empty object schema without properties", func() {
// Test case for the bug fix: schema with empty properties map
emptyObjectSchema := `{
"type": "object",
"properties": {}
}`
grammar, err := NewJSONSchemaConverter("").GrammarFromBytes([]byte(emptyObjectSchema))
Expect(err).To(BeNil())
Expect(grammar).To(ContainSubstring(`root ::= "{" space "}" space`))
})
It("handles object schema without properties field", func() {
// Test case for object schema without properties field at all
objectWithoutProperties := `{
"type": "object"
}`
grammar, err := NewJSONSchemaConverter("").GrammarFromBytes([]byte(objectWithoutProperties))
Expect(err).To(BeNil())
Expect(grammar).To(ContainSubstring(`root ::= "{" space "}" space`))
})
It("handles schema with properties but no type field", func() {
// Test case for the exact scenario causing the panic: schema with properties but no type
schemaWithPropertiesNoType := `{
"properties": {}
}`
grammar, err := NewJSONSchemaConverter("").GrammarFromBytes([]byte(schemaWithPropertiesNoType))
Expect(err).To(BeNil())
Expect(grammar).To(ContainSubstring(`root ::= "{" space "}" space`))
})
})
})