Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ enum AssistantFunctionCallDefinition: String, CaseIterable {
switch self {
case .createImage:
return .init(type: .function, function: .init(
name: self.rawValue,
name: self.rawValue,
strict: nil,
description: "call this function if the request asks to generate an image",
parameters: .init(
type: .object,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum FunctionCallDefinition: String, CaseIterable {
case .createImage:
return .init(function: .init(
name: self.rawValue,
strict: nil,
description: "call this function if the request asks to generate an image",
parameters: .init(
type: .object,
Expand Down
162 changes: 6 additions & 156 deletions Sources/OpenAI/Public/Parameters/Chat/ChatCompletionParameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ public struct ChatCompletionParameters: Encodable {
}
}

/// [Documentation](https://platform.openai.com/docs/api-reference/chat/create#chat-create-tools)
public struct Tool: Encodable {

/// The type of the tool. Currently, only `function` is supported.
Expand All @@ -257,170 +258,19 @@ public struct ChatCompletionParameters: Encodable {
/// A description of what the function does, used by the model to choose when and how to call the function.
let description: String?
/// The parameters the functions accepts, described as a JSON Schema object. See the [guide](https://platform.openai.com/docs/guides/gpt/function-calling) for examples, and the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format.
/// To describe a function that accepts no parameters, provide the value `{"type": "object", "properties": {}}`.
/// Omitting parameters defines a function with an empty parameter list.
let parameters: JSONSchema?

public struct JSONSchema: Codable, Equatable {

public let type: JSONType
public let properties: [String: Property]?
public let required: [String]?
public let pattern: String?
public let const: String?
public let enumValues: [String]?
public let multipleOf: Int?
public let minimum: Int?
public let maximum: Int?

private enum CodingKeys: String, CodingKey {
case type, properties, required, pattern, const
case enumValues = "enum"
case multipleOf, minimum, maximum
}

public struct Property: Codable, Equatable {

public let type: JSONType
public let description: String?
public let format: String?
public let items: Items?
public let required: [String]?
public let pattern: String?
public let const: String?
public let enumValues: [String]?
public let multipleOf: Int?
public let minimum: Double?
public let maximum: Double?
public let minItems: Int?
public let maxItems: Int?
public let uniqueItems: Bool?

private enum CodingKeys: String, CodingKey {
case type, description, format, items, required, pattern, const
case enumValues = "enum"
case multipleOf, minimum, maximum
case minItems, maxItems, uniqueItems
}

public init(
type: JSONType,
description: String? = nil,
format: String? = nil,
items: Items? = nil,
required: [String]? = nil,
pattern: String? = nil,
const: String? = nil,
enumValues: [String]? = nil,
multipleOf: Int? = nil,
minimum: Double? = nil,
maximum: Double? = nil,
minItems: Int? = nil,
maxItems: Int? = nil,
uniqueItems: Bool? = nil)
{
self.type = type
self.description = description
self.format = format
self.items = items
self.required = required
self.pattern = pattern
self.const = const
self.enumValues = enumValues
self.multipleOf = multipleOf
self.minimum = minimum
self.maximum = maximum
self.minItems = minItems
self.maxItems = maxItems
self.uniqueItems = uniqueItems
}
}

public enum JSONType: String, Codable {
case integer = "integer"
case string = "string"
case boolean = "boolean"
case array = "array"
case object = "object"
case number = "number"
case `null` = "null"
}

public struct Items: Codable, Equatable {

public let type: JSONType
public let properties: [String: Property]?
public let pattern: String?
public let const: String?
public let enumValues: [String]?
public let multipleOf: Int?
public let minimum: Double?
public let maximum: Double?
public let minItems: Int?
public let maxItems: Int?
public let uniqueItems: Bool?

private enum CodingKeys: String, CodingKey {
case type, properties, pattern, const
case enumValues = "enum"
case multipleOf, minimum, maximum, minItems, maxItems, uniqueItems
}

public init(
type: JSONType,
properties: [String : Property]? = nil,
pattern: String? = nil,
const: String? = nil,
enumValues: [String]? = nil,
multipleOf: Int? = nil,
minimum: Double? = nil,
maximum: Double? = nil,
minItems: Int? = nil,
maxItems: Int? = nil,
uniqueItems: Bool? = nil)
{
self.type = type
self.properties = properties
self.pattern = pattern
self.const = const
self.enumValues = enumValues
self.multipleOf = multipleOf
self.minimum = minimum
self.maximum = maximum
self.minItems = minItems
self.maxItems = maxItems
self.uniqueItems = uniqueItems
}
}

public init(
type: JSONType,
properties: [String : Property]? = nil,
required: [String]? = nil,
pattern: String? = nil,
const: String? = nil,
enumValues: [String]? = nil,
multipleOf: Int? = nil,
minimum: Int? = nil,
maximum: Int? = nil)
{
self.type = type
self.properties = properties
self.required = required
self.pattern = pattern
self.const = const
self.enumValues = enumValues
self.multipleOf = multipleOf
self.minimum = minimum
self.maximum = maximum
}
}
/// Defaults to false, Whether to enable strict schema adherence when generating the function call. If set to true, the model will follow the exact schema defined in the parameters field. Only a subset of JSON Schema is supported when strict is true. Learn more about Structured Outputs in the [function calling guide].(https://platform.openai.com/docs/api-reference/chat/docs/guides/function-calling)
let strict: Bool?

public init(
name: String,
strict: Bool?,
description: String?,
parameters: JSONSchema?)
{
self.name = name
self.strict = strict
self.description = description
self.parameters = parameters
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public struct ChatCompletionObject: Decodable {
public let role: String
/// Provided by the Vision API.
public let finishDetails: FinishDetails?
/// The refusal message generated by the model.
public let refusal: String?

/// Provided by the Vision API.
public struct FinishDetails: Decodable {
Expand All @@ -62,6 +64,7 @@ public struct ChatCompletionObject: Decodable {
case functionCall = "function_call"
case role
case finishDetails = "finish_details"
case refusal
}
}

Expand Down
75 changes: 75 additions & 0 deletions Sources/OpenAI/Public/Shared/JSONSchema.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//
// JSONSchema.swift
//
//
// Created by James Rochabrun on 8/10/24.
//

import Foundation

// MARK: JSONSchemaType

/// Supported schemas
///
/// Structured Outputs supports a subset of the JSON Schema language.
///
/// Supported types
///
/// The following types are supported for Structured Outputs:
///
/// String
/// Number
/// Boolean
/// Object
/// Array
/// Enum
/// anyOf
public enum JSONSchemaType: String, Codable {
case string, integer, number, boolean, object, array, `enum`, anyOf
}

public class JSONSchema: Codable, Equatable {
public init(
type: JSONSchemaType,
description: String? = nil,
properties: [String: JSONSchema]? = nil,
items: JSONSchema? = nil,
required: [String]? = nil,
additionalProperties: Bool = false,
enum: [String]? = nil
) {
self.type = type
self.description = description
self.properties = properties
self.items = items
self.required = required
self.additionalProperties = additionalProperties
self.enum = `enum`
}

public static func == (lhs: JSONSchema, rhs: JSONSchema) -> Bool {
lhs.type == rhs.type &&
lhs.description == rhs.description &&
lhs.properties == rhs.properties &&
lhs.items == rhs.items &&
lhs.required == rhs.required &&
lhs.additionalProperties == rhs.additionalProperties &&
lhs.enum == rhs.enum
}

let type: JSONSchemaType
let description: String?
let properties: [String: JSONSchema]?
let items: JSONSchema?
/// To use Structured Outputs, all fields or function parameters [must be specified as required.](https://platform.openai.com/docs/guides/structured-outputs/all-fields-must-be-required)
/// Although all fields must be required (and the model will return a value for each parameter), it is possible to emulate an optional parameter by using a union type with null.
let required: [String]?
/// [additionalProperties](https://platform.openai.com/docs/guides/structured-outputs/additionalproperties-false-must-always-be-set-in-objects) controls whether it is allowable for an object to contain additional keys / values that were not defined in the JSON Schema.
/// Structured Outputs only supports generating specified keys / values, so we require developers to set additionalProperties: false to opt into Structured Outputs.
let additionalProperties: Bool?
let `enum`: [String]?

enum CodingKeys: String, CodingKey {
case type, description, properties, items, required, additionalProperties, `enum`
}
}
Loading