Files
wehub-resource-sync 770d92cb1f
Lint / lint (push) Has been cancelled
Build Docs / Deploy Docs (push) Has been cancelled
Windows CI / Windows (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:23:58 +08:00

290 lines
8.7 KiB
Swift

// Protocol definition of OpenAI API
import Foundation
// Protocols for v1/chat/completions
// API reference: https://platform.openai.com/docs/api-reference/chat/create
public struct TopLogProbs : Codable {
public var token: String
public var logprob: Float
public var bytes: Optional<[Int]>
}
public struct LogProbsContent : Codable {
public var token: String
public var logprob: Float
public var bytes: Optional<[Int]> = nil
public var top_logprobs: [TopLogProbs] = []
}
public struct LogProbs : Codable {
public var content: [LogProbsContent] = []
}
public struct ChatFunction : Codable {
public var name: String
public var description: Optional<String> = nil
public var parameters: [String: String]
public init(
name: String,
description: Optional<String> = nil,
parameters: [String : String]
) {
self.name = name
self.description = description
self.parameters = parameters
}
}
public struct ChatTool : Codable {
public var type: String = "function"
public let function: ChatFunction
public init(type: String, function: ChatFunction) {
self.type = type
self.function = function
}
}
public struct ChatFunctionCall : Codable {
public var name: String
// NOTE: arguments shold be dict str to any codable
// for now only allow string output due to typing issues
public var arguments: Optional<[String: String]> = nil
public init(name: String, arguments: Optional<[String : String]> = nil) {
self.name = name
self.arguments = arguments
}
}
public struct ChatToolCall : Codable {
public var id: String = UUID().uuidString
public var type: String = "function"
public var function: ChatFunctionCall
public init(
id: String = UUID().uuidString,
type: String = "function",
function: ChatFunctionCall
) {
self.id = id
self.type = type
self.function = function
}
}
public enum ChatCompletionRole: String, Codable {
case system = "system"
case user = "user"
case assistant = "assistant"
case tool = "tool"
}
public enum ChatCompletionMessageContent: Codable {
case text(String)
case parts([[String: String]])
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let text = try? container.decode(String.self) {
self = .text(text)
} else {
let parts = try container.decode([[String: String]].self)
self = .parts(parts)
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .text(let text): try container.encode(text)
case .parts(let parts): try container.encode(parts)
}
}
public func asText() -> String {
switch (self) {
case .text(let text): return text
case .parts(let parts):
var res = ""
for item in parts {
if item["type"]! == "text" {
res += item["text"]!
}
}
return res
}
}
}
public struct ChatCompletionMessage: Codable {
public var role: ChatCompletionRole
public var content: Optional<ChatCompletionMessageContent> = nil
public var name: Optional<String> = nil
public var tool_calls: Optional<[ChatToolCall]> = nil
public var tool_call_id: Optional<String> = nil
// more complicated content construction
public init(
role: ChatCompletionRole,
content: Optional<[[String : String]]> = nil,
name: Optional<String> = nil,
tool_calls: Optional<[ChatToolCall]> = nil,
tool_call_id: Optional<String> = nil
) {
self.role = role
if let cvalue = content {
self.content = .parts(cvalue)
} else {
self.content = nil
}
self.name = name
self.tool_calls = tool_calls
self.tool_call_id = tool_call_id
}
// convenient method to construct content from string
public init(
role: ChatCompletionRole,
content: String,
name: Optional<String> = nil,
tool_calls: Optional<[ChatToolCall]> = nil,
tool_call_id: Optional<String> = nil
) {
self.role = role
self.content = .text(content)
self.name = name
self.tool_calls = tool_calls
self.tool_call_id = tool_call_id
}
}
public struct ChatCompletionStreamResponseChoice: Codable {
public var finish_reason: Optional<String> = nil
public var index: Int
public var delta: ChatCompletionMessage
public var lobprobs: Optional<LogProbs> = nil
}
public struct CompletionUsageExtra: Codable {
public var prefill_tokens_per_s: Optional<Float> = nil
public var decode_tokens_per_s: Optional<Float> = nil
public var num_prefill_tokens: Optional<Int> = nil
public func asTextLabel() -> String {
var outputText = ""
if let prefill_tokens_per_s = self.prefill_tokens_per_s {
outputText += "prefill: "
outputText += String(format: "%.1f", prefill_tokens_per_s)
outputText += " tok/s"
}
if let decode_tokens_per_s = self.decode_tokens_per_s {
if !outputText.isEmpty {
outputText += ", "
}
outputText += "decode: "
outputText += String(format: "%.1f", decode_tokens_per_s)
outputText += " tok/s"
}
return outputText
}
}
public struct CompletionUsage: Codable {
public var prompt_tokens: Int
public var completion_tokens: Int
public var total_tokens: Int
public var extra: Optional<CompletionUsageExtra>
}
public struct ChatCompletionStreamResponse: Codable {
public var id : String
public var choices: [ChatCompletionStreamResponseChoice] = []
public var created: Optional<Int> = nil
public var model: Optional<String> = nil
public var system_fingerprint: String
public var object: Optional<String> = nil
public var usage: Optional<CompletionUsage> = nil
}
public struct ResponseFormat: Codable {
public var type: String
public var schema: Optional<String> = nil
public init(type: String, schema: Optional<String> = nil) {
self.type = type
self.schema = schema
}
}
public struct StreamOptions: Codable {
public var include_usage: Bool = false
public init(include_usage: Bool) {
self.include_usage = include_usage
}
}
public struct ChatCompletionRequest: Codable {
public var messages: [ChatCompletionMessage]
public var model: Optional<String> = nil
public var frequency_penalty: Optional<Float> = nil
public var presence_penalty: Optional<Float> = nil
public var logprobs: Bool = false
public var top_logprobs: Int = 0
public var logit_bias: Optional<[Int: Float]> = nil
public var max_tokens: Optional<Int> = nil
public var n: Int = 1
public var seed: Optional<Int> = nil
public var stop: Optional<[String]> = nil
public var stream: Bool = true
public var stream_options: Optional<StreamOptions> = nil
public var temperature: Optional<Float> = nil
public var top_p: Optional<Float> = nil
public var tools: Optional<[ChatTool]> = nil
public var user: Optional<String> = nil
public var response_format: Optional<ResponseFormat> = nil
public init(
messages: [ChatCompletionMessage],
model: Optional<String> = nil,
frequency_penalty: Optional<Float> = nil,
presence_penalty: Optional<Float> = nil,
logprobs: Bool = false,
top_logprobs: Int = 0,
logit_bias: Optional<[Int : Float]> = nil,
max_tokens: Optional<Int> = nil,
n: Int = 1,
seed: Optional<Int> = nil,
stop: Optional<[String]> = nil,
stream: Bool = true,
stream_options: Optional<StreamOptions> = nil,
temperature: Optional<Float> = nil,
top_p: Optional<Float> = nil,
tools: Optional<[ChatTool]> = nil,
user: Optional<String> = nil,
response_format: Optional<ResponseFormat> = nil
) {
self.messages = messages
self.model = model
self.frequency_penalty = frequency_penalty
self.presence_penalty = presence_penalty
self.logprobs = logprobs
self.top_logprobs = top_logprobs
self.logit_bias = logit_bias
self.max_tokens = max_tokens
self.n = n
self.seed = seed
self.stop = stop
self.stream = stream
self.stream_options = stream_options
self.temperature = temperature
self.top_p = top_p
self.tools = tools
self.user = user
self.response_format = response_format
}
}