Refactor toolbox and function handling to support synthetic fields and improve type definitions

This commit is contained in:
2025-04-12 02:20:40 -04:00
parent 2ae583e9f3
commit 3093b988f8
13 changed files with 288 additions and 160 deletions

View File

@@ -8,15 +8,44 @@ import (
"github.com/openai/openai-go"
)
type object struct {
const (
// SyntheticFieldPrefix is any prefix that is added to any synthetic fields that are added to the object, to prevent
// collisions with the fields in the struct.
SyntheticFieldPrefix = "__"
)
type Object struct {
basic
ref reflect.Type
fields map[string]Type
// syntheticFields are fields that are not in the struct but are generated by a system.
synetheticFields map[string]Type
}
func (o object) OpenAIParameters() openai.FunctionParameters {
func (o Object) WithSyntheticField(name string, description string) Object {
if o.synetheticFields == nil {
o.synetheticFields = map[string]Type{}
}
o.synetheticFields[name] = basic{
DataType: TypeString,
typeName: "string",
index: -1,
required: false,
description: description,
}
return o
}
func (o Object) SyntheticFields() map[string]Type {
return o.synetheticFields
}
func (o Object) OpenAIParameters() openai.FunctionParameters {
var properties = map[string]openai.FunctionParameters{}
var required []string
for k, v := range o.fields {
@@ -26,6 +55,13 @@ func (o object) OpenAIParameters() openai.FunctionParameters {
}
}
for k, v := range o.synetheticFields {
properties[SyntheticFieldPrefix+k] = v.OpenAIParameters()
if v.Required() {
required = append(required, SyntheticFieldPrefix+k)
}
}
var res = openai.FunctionParameters{
"type": "object",
"description": o.Description(),
@@ -39,7 +75,7 @@ func (o object) OpenAIParameters() openai.FunctionParameters {
return res
}
func (o object) GoogleParameters() *genai.Schema {
func (o Object) GoogleParameters() *genai.Schema {
var properties = map[string]*genai.Schema{}
var required []string
for k, v := range o.fields {
@@ -62,7 +98,8 @@ func (o object) GoogleParameters() *genai.Schema {
return res
}
func (o object) FromAny(val any) (reflect.Value, error) {
// FromAny converts the value from any to the correct type, returning the value, and an error if any
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
@@ -99,7 +136,7 @@ func (o object) FromAny(val any) (reflect.Value, error) {
return obj, nil
}
func (o object) SetValueOnField(obj reflect.Value, val reflect.Value) {
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()