//

//

// Those are the interface for all the atomic APIs.

// An example of a non atomic API call is sending a message with tool call:

//   User send message ->

//                  <- Assistant call tool

//   User send tool input ->

//                  <- Assistant send response

//

// Here the client sends two atomic API calls to the server.


import Foundation


// MARK: - Tool


/// A tool that can be called by the assistant.

public protocol Tool: Encodable, Sendable {

  /// Executes the tool with the provided input and returns the result

  /// - Parameter input: JSON data containing the tool's input parameters

  /// - Returns: JSON data containing the tool's output

  /// - Throws: Any errors that occur during tool execution

  func use(input: JSON) async throws -> JSON


  /// The name of the tool

  var name: String { get }


  /// A description of what the tool does and how to use it

  var description: String { get }


  /// JSON schema defining the structure and validation rules for the tool's input

  var inputSchema: JSON { get }

}


// MARK: - AIProviderModel


/// Represents a Large Language Model available for use in the application

public struct AIProviderModel: Hashable, Identifiable, CaseIterable, Sendable {

  /// All available LLM models in the application

  public static var allCases: [AIProviderModel] {

    [.claudeSonnet, .gpt4o, .gpt4o_mini, .o1]

  }


  /// The user-friendly display name of the model

  public let displayName: String


  /// The unique identifier for the model used in API requests

  public let id: String


  /// Claude 3.7 Sonnet model by Anthropic

  public static let claudeSonnet = AIProviderModel(displayName: "claude-3.7-sonnet", id: "claude-3-7-sonnet-latest")


  /// gpt-latest model by OpenAI

  public static let gpt4o = AIProviderModel(displayName: "gpt-latest", id: "gpt-latest")


  /// gpt-latest-mini model by OpenAI

  public static let gpt4o_mini = AIProviderModel(displayName: "gpt-latest-mini", id: "gpt-latest-mini")


  /// o1 preview model by Deepmind

  public static let o1 = AIProviderModel(displayName: "o1", id: "o1-preview")

}