Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinhermawan committed Nov 10, 2023
0 parents commit 3189c6d
Show file tree
Hide file tree
Showing 18 changed files with 639 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Code Quality

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
test-ios:
runs-on: macos-13

steps:
- uses: actions/checkout@v3

- name: Build and test
run: xcodebuild test -scheme OllamaKit -destination 'platform=iOS Simulator,name=iPhone 14 Pro'

test-macos:
runs-on: macos-13

steps:
- uses: actions/checkout@v3

- name: Build and test
run: xcodebuild test -scheme OllamaKit -destination 'platform=macOS,arch=x86_64'
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Kevin Hermawan

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
14 changes: 14 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"pins" : [
{
"identity" : "alamofire",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Alamofire/Alamofire.git",
"state" : {
"revision" : "3dc6a42c7727c49bf26508e29b0a0b35f9c7e1ad",
"version" : "5.8.1"
}
}
],
"version" : 2
}
29 changes: 29 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "OllamaKit",
platforms: [
.iOS(.v13),
.macOS(.v11),
.macCatalyst(.v13)
],
products: [
.library(
name: "OllamaKit",
targets: ["OllamaKit"]),
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.8.1"))
],
targets: [
.target(
name: "OllamaKit",
dependencies: ["Alamofire"]),
.testTarget(
name: "OllamaKitTests",
dependencies: ["OllamaKit", "Alamofire"]),
]
)
63 changes: 63 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# OllamaKit

A Swift library for interacting with the Ollama API.

## Overview

`OllamaKit` is a Swift library for interacting with the Ollama API, built on top of the powerful [Alamofire](https://github.com/Alamofire/Alamofire) networking framework. It extends Alamofire's capabilities to provide a streamlined and intuitive interface for managing network interactions and data processing specific to the [Ollama API](https://github.com/jmorganca/ollama/blob/main/docs/api.md).

## Primary Use

`OllamaKit` is primarily designed for use within [Ollamac](https://github.com/kevinhermawan/Ollamac), a macOS application dedicated to interacting with Ollama models. While the library offers comprehensive functionalities for Ollama API interaction, its features and optimizations are specifically aligned with the requirements of `Ollamac`. This focus ensures that `OllamaKit` provides an ideal toolset for `Ollamac`, facilitating efficient and effective model management and interaction.

## Requirements

- iOS 13.0+ / macOS 11+

## Installation

You can add `OllamaKit` as a dependency to your project using Swift Package Manager by adding it to the dependencies value of your `Package.swift`.

```swift
dependencies: [
.package(url: "https://github.com/kevinhermawan/OllamaKit.git", .upToNextMajor(from: "1.0.0"))
]
```

Alternatively, in Xcode:

1. Open your project in Xcode.
2. Click on `File` -> `Swift Packages` -> `Add Package Dependency...`
3. Enter the repository URL: `https://github.com/kevinhermawan/OllamaKit.git`
4. Choose the version you want to add. You probably want to add the latest version.
5. Click `Add Package`.

## Acknowledgements

- [Alamofire](https://github.com/Alamofire/Alamofire)

## License

```
MIT License
Copyright (c) 2023 Kevin Hermawan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
23 changes: 23 additions & 0 deletions Sources/OllamaKit/Extensions/JSONDecoder+Default.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// JSONDecoder+Default.swift
//
//
// Created by Kevin Hermawan on 10/11/23.
//

import Foundation

internal extension JSONDecoder {
static var `default`: JSONDecoder {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSZZZZZ"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(dateFormatter)
decoder.keyDecodingStrategy = .convertFromSnakeCase

return decoder
}
}
17 changes: 17 additions & 0 deletions Sources/OllamaKit/Extensions/JSONEncoder+Default.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// JSONEncoder+Default.swift
//
//
// Created by Kevin Hermawan on 10/11/23.
//

import Foundation

internal extension JSONEncoder {
static var `default`: JSONEncoder {
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase

return encoder
}
}
124 changes: 124 additions & 0 deletions Sources/OllamaKit/OllamaKit.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
//
// OllamaKit.swift
//
//
// Created by Kevin Hermawan on 10/11/23.
//

import Alamofire
import Foundation

/// A Swift library for interacting with the Ollama API.
///
/// `OllamaKit` simplifies the process of connecting Swift applications to the Ollama API, abstracting the complexities of network requests and data handling.
public struct OllamaKit {
private var router: OKRouter.Type
private var decoder: JSONDecoder = .default

/// Initializes a new instance of `OllamaKit` with the specified base URL for the Ollama API.
///
/// This initializer configures `OllamaKit` with a base URL, laying the groundwork for all network interactions with the Ollama API. It ensures that the library is properly set up to communicate with the API endpoints.
///
/// - Parameter baseURL: The base URL to be used for Ollama API requests.
public init(baseURL: URL) {
let router = OKRouter.self
router.baseURL = baseURL

self.router = router
}
}

extension OllamaKit {
/// Checks the reachability of the Ollama API.
///
/// This asynchronous method performs a network request to determine if the Ollama API is reachable from the current client. It can be used to verify network connectivity and API availability before attempting further API interactions.
///
/// - Returns: A Boolean value indicating whether the Ollama API is reachable (`true`) or not (`false`).
public func reachable() async -> Bool {
let request = AF.request(router.root).validate()
let response = request.serializingData()

do {
_ = try await response.value

return true
} catch {
return false
}
}
}

extension OllamaKit {
/// Establishes a stream to the Ollama API for generating responses based on the provided data.
///
/// This method continuously streams responses as they are generated by the Ollama API,
/// with the final response including detailed data about the generation process.
///
/// - Parameters:
/// - data: The data used to generate the stream.
/// - stream: A closure that processes the streaming data.
public func generate(data: OKGenerateRequestData, stream: @escaping (DataStreamRequest.Stream<OKGenerateResponse, AFError>) -> Void) {
let request = AF.streamRequest(router.generate(data: data)).validate()
request.responseStreamDecodable(of: OKGenerateResponse.self, using: decoder, stream: stream)
}
}

extension OllamaKit {
/// Asynchronously retrieves a list of available models from the Ollama API.
///
/// This method returns an `OKModelResponse` containing the details of the available models,
/// making it easy to understand what models are currently accessible.
///
/// - Returns: An `OKModelResponse` object listing the available models.
public func models() async throws -> OKModelResponse {
let request = AF.request(router.models).validate()
let response = request.serializingDecodable(OKModelResponse.self, decoder: decoder)

return try await response.value
}
}

extension OllamaKit {
/// Asynchronously fetches detailed information about a specific model from the Ollama API.
///
/// This method provides comprehensive details about the model, such as its modelfile, template, and parameters.
///
/// - Parameter data: The data specifying the model to inquire about.
/// - Returns: An `OKModelInfoResponse` containing detailed information about the model.
public func modelInfo(data: OKModelInfoRequestData) async throws -> OKModelInfoResponse {
let request = AF.request(router.modelInfo(data: data)).validate()
let response = request.serializingDecodable(OKModelInfoResponse.self, decoder: decoder)

return try await response.value
}
}

extension OllamaKit {
/// Facilitates the duplication of an existing model, creating a new instance under a different name.
///
/// This asynchronous method makes it straightforward to copy a model, requiring only the necessary parameters for the operation.
///
/// - Parameter data: The data required for the model copy operation.
/// - Throws: An error if the copy operation fails.
public func copyModel(data: OKCopyModelRequestData) async throws -> Void {
let request = AF.request(router.copyModel(data: data)).validate()
let response = request.serializingData()

_ = try await response.value
}
}

extension OllamaKit {
/// Removes a specified model and its data from the Ollama API.
///
/// This asynchronous method allows for the deletion of a model, requiring the model name to be specified for a successful operation.
///
/// - Parameter data: The data specifying the model to be deleted.
/// - Throws: An error if the deletion fails.
public func deleteModel(data: OKDeleteModelRequestData) async throws -> Void {
let request = AF.request(router.deleteModel(data: data)).validate()
let response = request.serializingData()

_ = try await response.value
}
}
21 changes: 21 additions & 0 deletions Sources/OllamaKit/RequestData/OKCopyModelRequestData.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// OKCopyModelRequestData.swift
//
//
// Created by Kevin Hermawan on 10/11/23.
//

import Foundation

/// A structure representing the request data for copying a model via the Ollama API.
///
/// This structure holds the information necessary to duplicate a model, including the source model's name and the desired destination name.
public struct OKCopyModelRequestData: Encodable {
public let source: String
public let destination: String

public init(source: String, destination: String) {
self.source = source
self.destination = destination
}
}
19 changes: 19 additions & 0 deletions Sources/OllamaKit/RequestData/OKDeleteModelRequestData.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// OKDeleteModelRequestData.swift
//
//
// Created by Kevin Hermawan on 10/11/23.
//

import Foundation

/// A structure representing the request data for deleting a model through the Ollama API.
///
/// This structure encapsulates the name of the model to be deleted, providing a straightforward way to specify which model should be removed.
public struct OKDeleteModelRequestData: Encodable {
public let name: String

public init(name: String) {
self.name = name
}
}
Loading

0 comments on commit 3189c6d

Please sign in to comment.