Skip to content
Closed
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
4 changes: 3 additions & 1 deletion Package.swift
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These products are all explicitly imported in GenerableMacro.swift.

Image

Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ let package = Package(
.macro(
name: "AnyLanguageModelMacros",
dependencies: [
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
.product(name: "SwiftCompilerPlugin", package: "swift-syntax"),
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
]
),
.testTarget(
Expand Down
22 changes: 20 additions & 2 deletions Sources/AnyLanguageModel/Models/MLXLanguageModel.swift
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Core Image is not available on watchOS.

Image

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import Foundation

#if canImport(UIKit)
#if canImport(UIKit) && canImport(CoreImage)
import UIKit
import CoreImage
#endif

#if canImport(AppKit)
#if canImport(AppKit) && canImport(CoreImage)
import AppKit
import CoreImage
#endif
Expand Down Expand Up @@ -357,6 +357,24 @@ import Foundation

return LanguageModelSession.ResponseStream(stream: stream)
}

/// Prewarms the model
public func prewarm(
for session: LanguageModelSession,
promptPrefix: Prompt?
) {
let modelId = self.modelId
let hub = self.hub
let directory = self.directory

Task {
do {
_ = try await loadContext(modelId: modelId, hub: hub, directory: directory)
} catch {
// Ignore errors during prewarm
}
}
}
}

// MARK: - Options Mapping
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import Testing
import AnyLanguageModel

private let isSystemLanguageModelAvailable: Bool = {
if #available(macOS 26.0, *) {
if #available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *) {
return SystemLanguageModel.default.isAvailable
}
return false
}()

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test("AnyLanguageModel Drop-In Compatibility", .enabled(if: isSystemLanguageModelAvailable))
func anyLanguageModelCompatibility() async throws {
let model = SystemLanguageModel.default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import Testing
import FoundationModels

private let isFoundationModelsSystemLanguageModelAvailable: Bool = {
if #available(macOS 26.0, *) {
if #available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *) {
return SystemLanguageModel.default.isAvailable
}
return false
}()

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test(
"FoundationModels Drop-In Compatibility",
.enabled(if: isFoundationModelsSystemLanguageModelAvailable)
Expand Down
32 changes: 16 additions & 16 deletions Tests/AnyLanguageModelTests/SystemLanguageModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import AnyLanguageModel

#if canImport(FoundationModels)
private let isSystemLanguageModelAvailable = {
if #available(macOS 26.0, *) {
if #available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *) {
return SystemLanguageModel.default.isAvailable
} else {
return false
Expand Down Expand Up @@ -88,7 +88,7 @@ import AnyLanguageModel
.enabled(if: isSystemLanguageModelAvailable)
)
struct SystemLanguageModelTests {
@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func basicResponse() async throws {
let model: SystemLanguageModel = SystemLanguageModel()
let session = LanguageModelSession(model: model)
Expand All @@ -97,7 +97,7 @@ import AnyLanguageModel
#expect(!response.content.isEmpty)
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func withInstructions() async throws {
let model = SystemLanguageModel()
let session = LanguageModelSession(
Expand All @@ -109,7 +109,7 @@ import AnyLanguageModel
#expect(!response.content.isEmpty)
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func withTemperature() async throws {
let model: SystemLanguageModel = SystemLanguageModel()
let session = LanguageModelSession(model: model)
Expand All @@ -122,7 +122,7 @@ import AnyLanguageModel
#expect(!response.content.isEmpty)
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func streamingString() async throws {
guard isSystemLanguageModelAvailable else { return }
let model: SystemLanguageModel = SystemLanguageModel()
Expand All @@ -139,7 +139,7 @@ import AnyLanguageModel
#expect(!snapshots.last!.rawContent.jsonString.isEmpty)
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func streamingGeneratedContent() async throws {
guard isSystemLanguageModelAvailable else { return }
let model: SystemLanguageModel = SystemLanguageModel()
Expand All @@ -159,7 +159,7 @@ import AnyLanguageModel
#expect(!snapshots.last!.rawContent.jsonString.isEmpty)
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func withTools() async throws {
let weatherTool = WeatherTool()
let session = LanguageModelSession(model: SystemLanguageModel.default, tools: [weatherTool])
Expand All @@ -180,7 +180,7 @@ import AnyLanguageModel
#expect(content.contains("72°F"))
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func conversationContext() async throws {
let model: SystemLanguageModel = SystemLanguageModel()
let session = LanguageModelSession(model: model)
Expand Down Expand Up @@ -222,7 +222,7 @@ import AnyLanguageModel

// MARK: - Guided Generation Tests

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func guidedGenerationSimpleStruct() async throws {
let session = LanguageModelSession(model: SystemLanguageModel.default)

Expand All @@ -234,7 +234,7 @@ import AnyLanguageModel
#expect(!response.content.message.isEmpty)
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func guidedGenerationWithMultipleFields() async throws {
let session = LanguageModelSession(model: SystemLanguageModel.default)

Expand All @@ -248,7 +248,7 @@ import AnyLanguageModel
#expect(!response.content.occupation.isEmpty)
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func guidedGenerationMathCalculation() async throws {
let session = LanguageModelSession(model: SystemLanguageModel.default)

Expand All @@ -263,7 +263,7 @@ import AnyLanguageModel
#expect(combined.contains("15") || combined.contains("27") || combined.contains("42"))
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func guidedGenerationNestedStruct() async throws {
let session = LanguageModelSession(model: SystemLanguageModel.default)

Expand All @@ -279,7 +279,7 @@ import AnyLanguageModel
#expect(response.content.rgb.blue >= 0 && response.content.rgb.blue <= 255)
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func guidedGenerationWithArray() async throws {
let session = LanguageModelSession(model: SystemLanguageModel.default)

Expand All @@ -295,7 +295,7 @@ import AnyLanguageModel
}
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func guidedGenerationWithEnumConstraint() async throws {
let session = LanguageModelSession(model: SystemLanguageModel.default)

Expand All @@ -308,7 +308,7 @@ import AnyLanguageModel
#expect(response.content.confidence >= 0.0 && response.content.confidence <= 1.0)
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func guidedGenerationWithInstructions() async throws {
let session = LanguageModelSession(
model: SystemLanguageModel.default,
Expand All @@ -325,7 +325,7 @@ import AnyLanguageModel
#expect(!response.content.occupation.isEmpty)
}

@available(macOS 26.0, *)
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
@Test func guidedGenerationStreaming() async throws {
let session = LanguageModelSession(model: SystemLanguageModel.default)

Expand Down