openai-kit icon indicating copy to clipboard operation
openai-kit copied to clipboard

Add basic support for functions

Open carlo- opened this issue 1 year ago • 2 comments

Hi all! I've started working on adding support for functions. I have a rather rough implementation ready, so I wanted to check in here. Function calls from the models are inherently "unsafe", so this clashes a bit with the strict type safety of Swift; I think making this work in a neat way is an interesting challenge. What are your thoughts?

Here's how you'd define a function with my implementation (this example function can be used to search a database of recipes):

struct FindRecipeFunction: Chat.Function {
    
    struct Call: Chat.FunctionCallWithArguments {
        var name: String
        var arguments: Arguments
        
        struct Arguments: Codable {
            let query: String
        }
    }
    
    struct Parameters: Encodable {
        let type = "object"
        let properties = Props()
        let required = ["query"]
        
        struct Props: Encodable {
            let query = Query()
            
            struct Query: Encodable {
                let type = "string"
                let description = "A human readable query to use when searching for a recipe."
            }
        }
    }
    
    let name: String = "findRecipe"
    
    let description: String? = "The `findRecipe` API can be used to search through a database of recipes."
    
    let parameters: Parameters? = Parameters()
}

You would then send a chat request as usual, passing in the functions and the function "mode" (called "function_call" in the docs):

let chat = try await client.chats.create(
    model: Model.GPT4.gpt40613,
    messages: ...,
    functions: [FindRecipeFunction()],
    functionMode: .auto
)
let message = chat.choices[0].message

And then try to extract any function calls with type safety:

if case let .assistantWithCall(_, call) = message,
    let call = try? call.structured(as: FindRecipeFunction.Call.self) {
    
    let recipeQuery = call.arguments.query
    // ...
}

carlo- avatar Jun 18 '23 13:06 carlo-