go-llm/schema/object.go

90 lines
1.9 KiB
Go

package schema
import (
"errors"
"reflect"
"github.com/google/generative-ai-go/genai"
"github.com/openai/openai-go"
)
type object struct {
basic
ref reflect.Type
fields map[string]Type
}
func (o object) OpenAIParameters() openai.FunctionParameters {
var properties = map[string]openai.FunctionParameters{}
for k, v := range o.fields {
properties[k] = v.OpenAIParameters()
}
return openai.FunctionParameters{
"type": "object",
"description": o.Description(),
"properties": properties,
}
}
func (o object) GoogleParameters() *genai.Schema {
var properties = map[string]*genai.Schema{}
for k, v := range o.fields {
properties[k] = v.GoogleParameters()
}
return &genai.Schema{
Type: genai.TypeObject,
Description: o.Description(),
Properties: properties,
}
}
func (o object) FromAny(val any) (reflect.Value, error) {
// if the value is nil, we can't do anything
if val == nil {
return reflect.Value{}, nil
}
// now make a new object of the type we're trying to parse
obj := reflect.New(o.ref).Elem()
// now we need to iterate over the fields and set the values
for k, v := range o.fields {
// get the field by name
field := obj.FieldByName(k)
if !field.IsValid() {
return reflect.Value{}, errors.New("field " + k + " not found")
}
// get the value from the map
val2, ok := val.(map[string]interface{})[k]
if !ok {
return reflect.Value{}, errors.New("field " + k + " not found in map")
}
// now we need to convert the value to the correct type
val3, err := v.FromAny(val2)
if err != nil {
return reflect.Value{}, err
}
// now we need to set the value on the field
v.SetValueOnField(field, val3)
}
return obj, nil
}
func (o object) SetValueOnField(obj reflect.Value, val reflect.Value) {
// if this basic type is not required that means it's a pointer type so we need to set the value to the address of the value
if !o.required {
val = val.Addr()
}
obj.Field(o.index).Set(val)
}