94 lines
1.8 KiB
Go
94 lines
1.8 KiB
Go
package openai
|
|
|
|
func schemaObjectProperties(schema any) map[string]any {
|
|
m, ok := schema.(map[string]any)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
props, _ := m["properties"].(map[string]any)
|
|
if len(props) > 0 {
|
|
return props
|
|
}
|
|
for _, key := range []string{"oneOf", "anyOf", "allOf"} {
|
|
for _, branch := range schemaBranches(m[key]) {
|
|
if branchProps := schemaObjectProperties(branch); len(branchProps) > 0 {
|
|
if props == nil {
|
|
props = map[string]any{}
|
|
}
|
|
for propKey, propValue := range branchProps {
|
|
props[propKey] = propValue
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return props
|
|
}
|
|
|
|
func schemaArrayItemSchema(schema any) any {
|
|
m, ok := schema.(map[string]any)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
if items, ok := m["items"]; ok {
|
|
return items
|
|
}
|
|
for _, key := range []string{"oneOf", "anyOf", "allOf"} {
|
|
for _, branch := range schemaBranches(m[key]) {
|
|
if item := schemaArrayItemSchema(branch); item != nil {
|
|
return item
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func schemaAllowsType(schema any, want string) bool {
|
|
if schema == nil {
|
|
return false
|
|
}
|
|
m, ok := schema.(map[string]any)
|
|
if !ok {
|
|
return false
|
|
}
|
|
switch t := m["type"].(type) {
|
|
case string:
|
|
if t == want {
|
|
return true
|
|
}
|
|
case []any:
|
|
for _, item := range t {
|
|
if item == want {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
if want == "object" && len(schemaObjectProperties(schema)) > 0 {
|
|
return true
|
|
}
|
|
if want == "array" && schemaArrayItemSchema(schema) != nil {
|
|
return true
|
|
}
|
|
for _, key := range []string{"oneOf", "anyOf"} {
|
|
for _, branch := range schemaBranches(m[key]) {
|
|
if schemaAllowsType(branch, want) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
if branches := schemaBranches(m["allOf"]); len(branches) > 0 {
|
|
for _, branch := range branches {
|
|
if schemaAllowsType(branch, want) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func schemaBranches(value any) []any {
|
|
raw, ok := value.([]any)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
return raw
|
|
}
|