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
6 changes: 0 additions & 6 deletions Sources/AnyLanguageModel/Generable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@ public protocol Generable: ConvertibleFromGeneratedContent, ConvertibleToGenerat
static var generationSchema: GenerationSchema { get }
}

// MARK: - Error

/// Errors from converting generated content are ``GeneratedContentError``.
@available(*, deprecated, renamed: "GeneratedContentError")
public typealias GeneratedContentConversionError = GeneratedContentError

// MARK: - Macros

/// Conforms a type to ``Generable`` protocol.
Expand Down
94 changes: 4 additions & 90 deletions Sources/AnyLanguageModel/Models/GeminiLanguageModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,6 @@ public struct GeminiLanguageModel: LanguageModel {
}
}

/// Deprecated. Use ``CustomGenerationOptions/Thinking`` instead.
@available(*, deprecated, renamed: "CustomGenerationOptions.Thinking")
public typealias Thinking = CustomGenerationOptions.Thinking

/// Deprecated. Use ``CustomGenerationOptions/ServerTool`` instead.
@available(*, deprecated, renamed: "CustomGenerationOptions.ServerTool")
public typealias ServerTool = CustomGenerationOptions.ServerTool

public let baseURL: URL

private let tokenProvider: @Sendable () -> String
Expand All @@ -152,40 +144,6 @@ public struct GeminiLanguageModel: LanguageModel {

public let model: String

/// The thinking mode for this model.
///
/// - Important: This property is deprecated. Use ``GenerationOptions`` with
/// custom options instead:
/// ```swift
/// var options = GenerationOptions()
/// options[custom: GeminiLanguageModel.self] = .init(thinking: .dynamic)
/// ```
@available(*, deprecated, message: "Use GenerationOptions with custom options instead")
public var thinking: Thinking {
get { _thinking }
set { _thinking = newValue }
}

/// Internal storage for the deprecated thinking property.
internal var _thinking: CustomGenerationOptions.Thinking

/// Server-side tools enabled for this model.
///
/// - Important: This property is deprecated. Use ``GenerationOptions`` with
/// custom options instead:
/// ```swift
/// var options = GenerationOptions()
/// options[custom: GeminiLanguageModel.self] = .init(serverTools: [.googleSearch])
/// ```
@available(*, deprecated, message: "Use GenerationOptions with custom options instead")
public var serverTools: [CustomGenerationOptions.ServerTool] {
get { _serverTools }
set { _serverTools = newValue }
}

/// Internal storage for the deprecated serverTools property.
internal var _serverTools: [CustomGenerationOptions.ServerTool]

private let httpSession: HTTPSession

/// Creates a new Gemini language model.
Expand All @@ -212,50 +170,6 @@ public struct GeminiLanguageModel: LanguageModel {
self.tokenProvider = tokenProvider
self.apiVersion = apiVersion
self.model = model
self._thinking = .disabled
self._serverTools = []
self.httpSession = session
}

/// Creates a new Gemini language model with thinking and server tools configuration.
///
/// - Parameters:
/// - baseURL: The base URL for the Gemini API.
/// - tokenProvider: A closure that provides the API key.
/// - apiVersion: The API version to use.
/// - model: The model identifier.
/// - thinking: The thinking mode configuration.
/// - serverTools: Server-side tools to enable.
/// - session: The HTTP session or client used for network requests.
///
/// - Important: This initializer is deprecated. Use the initializer without
/// `thinking` and `serverTools` parameters, and pass these options through
/// ``GenerationOptions`` instead.
@available(
*,
deprecated,
message: "Use init without thinking/serverTools and pass them via GenerationOptions custom options"
)
public init(
baseURL: URL = defaultBaseURL,
apiKey tokenProvider: @escaping @autoclosure @Sendable () -> String,
apiVersion: String = defaultAPIVersion,
model: String,
thinking: CustomGenerationOptions.Thinking = .disabled,
serverTools: [CustomGenerationOptions.ServerTool] = [],
session: HTTPSession = makeDefaultSession(),
) {
var baseURL = baseURL
if !baseURL.path.hasSuffix("/") {
baseURL = baseURL.appendingPathComponent("")
}

self.baseURL = baseURL
self.tokenProvider = tokenProvider
self.apiVersion = apiVersion
self.model = model
self._thinking = thinking
self._serverTools = serverTools
self.httpSession = session
}

Expand Down Expand Up @@ -303,8 +217,8 @@ public struct GeminiLanguageModel: LanguageModel {
) async throws -> LanguageModelSession.Response<Content> where Content: Generable {
// Extract effective configuration from custom options or fall back to model defaults
let customOptions = options[custom: GeminiLanguageModel.self]
let effectiveThinking = customOptions?.thinking ?? _thinking
let effectiveServerTools = customOptions?.serverTools ?? _serverTools
let effectiveThinking = customOptions?.thinking ?? .disabled
let effectiveServerTools = customOptions?.serverTools ?? []
let effectiveJsonMode = customOptions?.jsonMode

let url =
Expand Down Expand Up @@ -469,8 +383,8 @@ public struct GeminiLanguageModel: LanguageModel {
) -> sending LanguageModelSession.ResponseStream<Content> where Content: Generable {
// Extract effective configuration from custom options or fall back to model defaults
let customOptions = options[custom: GeminiLanguageModel.self]
let effectiveThinking = customOptions?.thinking ?? _thinking
let effectiveServerTools = customOptions?.serverTools ?? _serverTools
let effectiveThinking = customOptions?.thinking ?? .disabled
let effectiveServerTools = customOptions?.serverTools ?? []
let effectiveJsonMode = customOptions?.jsonMode

var streamURL =
Expand Down
154 changes: 7 additions & 147 deletions Sources/AnyLanguageModel/Models/LlamaLanguageModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ import Foundation
/// Use this model to generate text using GGUF models running directly with llama.cpp.
///
/// ```swift
/// let model = LlamaLanguageModel(
/// modelPath: "/path/to/model.gguf",
/// contextSize: 2048
/// )
/// let model = LlamaLanguageModel(modelPath: "/path/to/model.gguf")
/// ```
public final class LlamaLanguageModel: LanguageModel, @unchecked Sendable {
/// The reason the model is unavailable.
Expand Down Expand Up @@ -227,109 +224,8 @@ import Foundation
#endif
}

/// The context size for the model.
///
/// - Important: This property is deprecated.
/// Use ``GenerationOptions`` with custom options instead:
/// ```swift
/// var options = GenerationOptions()
/// options[custom: LlamaLanguageModel.self] = .init(contextSize: 4096)
/// ```
@available(*, deprecated, message: "Use GenerationOptions custom options instead")
public var contextSize: UInt32 { legacyDefaults.contextSize }

/// The batch size for processing.
///
/// - Important: This property is deprecated.
/// Use ``GenerationOptions`` with custom options instead:
/// ```swift
/// var options = GenerationOptions()
/// options[custom: LlamaLanguageModel.self] = .init(batchSize: 1024)
/// ```
@available(*, deprecated, message: "Use GenerationOptions custom options instead")
public var batchSize: UInt32 { legacyDefaults.batchSize }

/// The number of threads to use.
///
/// - Important: This property is deprecated.
/// Use ``GenerationOptions`` with custom options instead:
/// ```swift
/// var options = GenerationOptions()
/// options[custom: LlamaLanguageModel.self] = .init(threads: 8)
/// ```
/// custom options instead.
@available(*, deprecated, message: "Use GenerationOptions custom options instead")
public var threads: Int32 { legacyDefaults.threads }

/// The random seed for generation.
///
/// - Important: This property is deprecated.
/// Use ``GenerationOptions`` with custom options instead:
/// ```swift
/// var options = GenerationOptions()
/// options[custom: LlamaLanguageModel.self] = .init(seed: 42)
/// ```
/// custom options instead.
@available(*, deprecated, message: "Use GenerationOptions custom options instead")
public var seed: UInt32 { legacyDefaults.seed }

/// The temperature for sampling.
///
/// - Important: This property is deprecated.
/// Use ``GenerationOptions`` with custom options instead:
/// ```swift
/// var options = GenerationOptions()
/// options[custom: LlamaLanguageModel.self] = .init(temperature: 0.6)
/// ```
@available(*, deprecated, message: "Use GenerationOptions custom options instead")
public var temperature: Float { legacyDefaults.temperature }

/// The top-K sampling parameter.
///
/// - Important: This property is deprecated.
/// Use ``GenerationOptions`` with custom options instead:
/// ```swift
/// var options = GenerationOptions()
/// options[custom: LlamaLanguageModel.self] = .init(topK: 25)
/// ```
@available(*, deprecated, message: "Use GenerationOptions custom options instead")
public var topK: Int32 { legacyDefaults.topK }

/// The top-P (nucleus) sampling parameter.
///
/// - Important: This property is deprecated.
/// Use ``GenerationOptions`` with custom options instead:
/// ```swift
/// var options = GenerationOptions()
/// options[custom: LlamaLanguageModel.self] = .init(topP: 0.9)
/// ```
@available(*, deprecated, message: "Use GenerationOptions custom options instead")
public var topP: Float { legacyDefaults.topP }

/// The repeat penalty for generation.
///
/// - Important: This property is deprecated.
/// Use ``GenerationOptions`` with custom options instead:
/// ```swift
/// var options = GenerationOptions()
/// options[custom: LlamaLanguageModel.self] = .init(repeatPenalty: 1.2)
/// ```
@available(*, deprecated, message: "Use GenerationOptions custom options instead")
public var repeatPenalty: Float { legacyDefaults.repeatPenalty }

/// The number of tokens to consider for repeat penalty.
///
/// - Important: This property is deprecated.
/// Use ``GenerationOptions`` with custom options instead:
/// ```swift
/// var options = GenerationOptions()
/// options[custom: LlamaLanguageModel.self] = .init(repeatLastN: 128)
/// ```
@available(*, deprecated, message: "Use GenerationOptions custom options instead")
public var repeatLastN: Int32 { legacyDefaults.repeatLastN }

/// Normalized legacy defaults used for deprecated properties.
private let legacyDefaults: ResolvedGenerationOptions
/// The default options that each request's options override.
private let defaultOptions: ResolvedGenerationOptions

/// The minimum log level for llama.cpp output.
///
Expand Down Expand Up @@ -733,43 +629,7 @@ import Foundation
self.modelPath = modelPath
self.gpuLayers = gpuLayers
self.mmprojPath = mmprojPath
self.legacyDefaults = ResolvedGenerationOptions()
}

/// Creates a Llama language model using legacy parameter defaults.
///
/// - Important: This initializer is deprecated.
/// Use `init(modelPath:)` and configure per-request values via
/// ``GenerationOptions`` custom options instead.
///
/// ```swift
/// let model = LlamaLanguageModel(modelPath: "/path/to/model.gguf")
/// var options = GenerationOptions()
/// options[custom: LlamaLanguageModel.self] = .init(contextSize: 4096)
///
/// let session = LanguageModelSession(model: model)
/// session.respond(to: "Hello, world!", options: options)
/// ```
@available(
*,
deprecated,
message: "Use init(modelPath:) and pass values via GenerationOptions custom options"
)
public convenience init(
modelPath: String,
contextSize: UInt32 = 2048,
batchSize: UInt32 = 512,
threads: Int32 = Int32(ProcessInfo.processInfo.processorCount),
seed: UInt32 = UInt32.random(in: 0 ... UInt32.max),
temperature: Float = 0.8,
topK: Int32 = 40,
topP: Float = 0.95,
repeatPenalty: Float = 1.1,
repeatLastN: Int32 = 64
) {
// Deprecated: prefer setting these via GenerationOptions custom options.
// We intentionally ignore legacy parameters to avoid storing model-level state.
self.init(modelPath: modelPath)
self.defaultOptions = ResolvedGenerationOptions()
}

deinit {
Expand Down Expand Up @@ -1455,7 +1315,7 @@ import Foundation
var mtmdParams = mtmd_context_params_default()
mtmdParams.use_gpu = gpuLayers != 0
mtmdParams.print_timings = false
mtmdParams.n_threads = legacyDefaults.threads
mtmdParams.n_threads = defaultOptions.threads
guard let projector = mtmd_init_from_file(mmprojPath, loadedModel, mtmdParams) else {
llama_model_free(loadedModel)
throw LlamaLanguageModelError.modelLoadFailed
Expand All @@ -1479,7 +1339,7 @@ import Foundation
}

private func resolvedOptions(from options: GenerationOptions) -> ResolvedGenerationOptions {
var base = legacyDefaults
var base = defaultOptions
if let temp = options.temperature {
base.temperature = Float(temp)
}
Expand All @@ -1494,7 +1354,7 @@ import Foundation

/// Builds structured-generation defaults while honoring explicit overrides.
private func resolvedStructuredOptions(from options: GenerationOptions) -> ResolvedGenerationOptions {
var base = legacyDefaults
var base = defaultOptions
if let temp = options.temperature {
base.temperature = Float(temp)
} else {
Expand Down
6 changes: 3 additions & 3 deletions Tests/AnyLanguageModelTests/GeneratedContentErrorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import AnyLanguageModel

@Suite("Generated content errors")
struct GeneratedContentErrorTests {
@Test func conversionErrorAliasPreservesEqualityAndHashing() {
let error = GeneratedContentConversionError.typeMismatch
@Test func errorsSupportEqualityAndHashing() {
let error = GeneratedContentError.typeMismatch
#expect(error == .typeMismatch)
#expect(error != .neverCannotBeInstantiated)

let errors: Set<GeneratedContentConversionError> = [
let errors: Set<GeneratedContentError> = [
.typeMismatch, .typeMismatch, .neverCannotBeInstantiated,
]
#expect(errors.count == 2)
Expand Down
Loading
Loading