iop/apps/edge/internal/openai/tool_schema.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
}