Skip to content

Implement Tool macro #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
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
15 changes: 15 additions & 0 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 30 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,23 +1,50 @@
// swift-tools-version: 5.7
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import CompilerPluginSupport
import PackageDescription

let package = Package(
name: "Ollama",
platforms: [
.macOS(.v13)
.macOS(.v14),
.macCatalyst(.v14),
.iOS(.v17),
.watchOS(.v10),
.tvOS(.v17),
.visionOS(.v1),
],
products: [
.library(
name: "Ollama",
targets: ["Ollama"])
],
dependencies: [
.package(url: "https://github.com/swiftlang/swift-syntax.git", from: "600.0.0-latest")
],
targets: [
.target(
name: "Ollama"),
name: "Ollama",
dependencies: ["OllamaMacro"]),
.testTarget(
name: "OllamaTests",
dependencies: ["Ollama"]),

.macro(
name: "OllamaMacro",
dependencies: [
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
.product(name: "SwiftCompilerPlugin", package: "swift-syntax"),
]
),
.testTarget(
name: "OllamaMacroTests",
dependencies: [
"OllamaMacro",
.product(name: "SwiftSyntaxMacroExpansion", package: "swift-syntax"),
.product(name: "SwiftSyntaxMacrosGenericTestSupport", package: "swift-syntax"),
]
),
]
)
4 changes: 2 additions & 2 deletions Sources/Ollama/Chat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import struct Foundation.TimeInterval
/// Namespace for chat-related types and functionality.
public enum Chat {
/// Represents a message in a chat conversation.
public struct Message: Hashable, Codable {
public struct Message: Hashable, Codable, Sendable {
/// The role of the message sender.
public enum Role: String, Hashable, CaseIterable, Codable {
public enum Role: String, Hashable, CaseIterable, Codable, Sendable {
/// Represents a message from the user.
case user
/// Represents a system message.
Expand Down
23 changes: 12 additions & 11 deletions Sources/Ollama/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import Foundation
/// allowing you to generate text, chat, create embeddings, and manage models.
///
/// - SeeAlso: [Ollama API Documentation](https://github.com/ollama/ollama/blob/main/docs/api.md)
open class Client {
@MainActor
public final class Client: Sendable {
/// The default host URL for the Ollama API.
public static let defaultHost = URL(string: "http://localhost:11434")!

/// A default client instance using the default host.
public static let `default` = Client(host: Client.defaultHost)
public static let `default` = Client(host: defaultHost)

/// The host URL for requests made by the client.
public let host: URL
Expand All @@ -24,7 +25,7 @@ open class Client {
public let userAgent: String?

/// The underlying client session.
internal(set) public var session: URLSession
private let session: URLSession

/// Creates a client with the specified session, host, and user agent.
///
Expand Down Expand Up @@ -179,7 +180,7 @@ open class Client {
// MARK: - Generate

extension Client {
public struct GenerateResponse: Hashable, Decodable {
public struct GenerateResponse: Hashable, Decodable, Sendable {
public let model: Model.ID
public let createdAt: Date
public let response: String
Expand Down Expand Up @@ -269,7 +270,7 @@ extension Client {
// MARK: - Chat

extension Client {
public struct ChatResponse: Hashable, Decodable {
public struct ChatResponse: Hashable, Decodable, Sendable {
public let model: Model.ID
public let createdAt: Date
public let message: Chat.Message
Expand Down Expand Up @@ -334,7 +335,7 @@ extension Client {
// MARK: - Embeddings

extension Client {
public struct EmbedResponse: Decodable {
public struct EmbedResponse: Decodable, Sendable {
public let model: Model.ID
public let embeddings: Embeddings
public let totalDuration: TimeInterval
Expand Down Expand Up @@ -384,8 +385,8 @@ extension Client {
// MARK: - List Models

extension Client {
public struct ListModelsResponse: Decodable {
public struct Model: Decodable {
public struct ListModelsResponse: Decodable, Sendable {
public struct Model: Decodable, Sendable {
public let name: String
public let modifiedAt: String
public let size: Int64
Expand Down Expand Up @@ -416,8 +417,8 @@ extension Client {
// MARK: - List Running Models

extension Client {
public struct ListRunningModelsResponse: Decodable {
public struct Model: Decodable {
public struct ListRunningModelsResponse: Decodable, Sendable {
public struct Model: Decodable, Sendable {
public let name: String
public let model: String
public let size: Int64
Expand Down Expand Up @@ -568,7 +569,7 @@ extension Client {

extension Client {
/// A response containing information about a model.
public struct ShowModelResponse: Decodable {
public struct ShowModelResponse: Decodable, Sendable {
/// The contents of the Modelfile for the model.
let modelfile: String

Expand Down
2 changes: 1 addition & 1 deletion Sources/Ollama/Embeddings.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public struct Embeddings: RawRepresentable, Hashable {
public struct Embeddings: RawRepresentable, Hashable, Sendable {
public let rawValue: [[Double]]

public init(rawValue: [[Double]]) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Ollama/Extensions/Data+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation
import RegexBuilder

/// Regex pattern for data URLs
private let dataURLRegex = Regex {
nonisolated(unsafe) private let dataURLRegex = Regex {
"data:"
Capture {
ZeroOrMore(.reluctant) {
Expand Down
4 changes: 2 additions & 2 deletions Sources/Ollama/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public enum Model {
/// An identifier in the form of "[namespace/]model[:tag]".
/// This structure is used to uniquely identify models in the Ollama ecosystem.
public struct ID: Hashable, Equatable, Comparable, RawRepresentable, CustomStringConvertible,
ExpressibleByStringLiteral, ExpressibleByStringInterpolation, Codable
ExpressibleByStringLiteral, ExpressibleByStringInterpolation, Codable, Sendable
{
/// The optional namespace of the model.
/// Namespaces are used to organize models, often representing the creator or organization.
Expand Down Expand Up @@ -125,7 +125,7 @@ public enum Model {
// MARK: -

/// Represents additional information about a model.
public struct Details: Hashable, Decodable {
public struct Details: Hashable, Decodable, Sendable {
/// The format of the model file (e.g., "gguf").
public let format: String

Expand Down
14 changes: 14 additions & 0 deletions Sources/Ollama/Tool.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation

/// Macro that transforms functions and types into Tools
@attached(peer, names: prefixed(Tool_))
public macro Tool() = #externalMacro(module: "OllamaMacro", type: "ToolMacro")

public protocol Tool {
associatedtype Input: Codable
associatedtype Output: Codable

static var schema: [String: Value] { get }

static func call(_ input: Input) async throws -> Output
}
2 changes: 1 addition & 1 deletion Sources/Ollama/Value.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import class Foundation.JSONDecoder
import class Foundation.JSONEncoder

/// A codable value.
public enum Value: Hashable {
public enum Value: Hashable, Sendable {
case null
case bool(Bool)
case int(Int)
Expand Down
9 changes: 9 additions & 0 deletions Sources/OllamaMacro/OllamaToolPlugin.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import SwiftCompilerPlugin
import SwiftSyntaxMacros

@main
struct OllamaToolPlugin: CompilerPlugin {
let providingMacros: [Macro.Type] = [
ToolMacro.self
]
}
Loading