Important
This package is presently in its alpha stage of development
The definitive, open-source Swift framework for interfacing with generative AI.
- Import the framework
- Initialize an AI Client
- LLM Clients Abstraction
- Supported Models
- Completions
- DALLE-3 Image Generation
- Text Embeddings
Roadmap
Acknowledgements
License
- Open your Swift project in Xcode.
- Go to
File
->Add Package Dependency
. - In the search bar, enter this URL.
- Choose the version you'd like to install.
- Click
Add Package
.
+ import AI
Initialize an instance of an AI API provider of your choice. Here are some examples:
import AI
// OpenAI / GPT
import OpenAI
let client: OpenAI.Client = OpenAI.Client(apiKey: "YOUR_API_KEY")
// Anthropic / Claude
import Anthropic
let client: Anthropic.Client = Anthropic.Client(apiKey: "YOUR_API_KEY")
// Mistral
import Mistral
let client: Mistral.Client = Mistral.Client(apiKey: "YOUR_API_KEY")
// Groq
import Groq
let client: Groq.Client = Groq.Client(apiKey: "YOUR_API_KEY")
// ElevenLabs
import ElevenLabs
let client: ElevenLabs.Client = ElevenLabs.Client(apiKey: "YOUR_API_KEY")
You can now use client
as an interface to the supported providers.
If you need to abstract out the LLM Client (for example, if you want to allow your user to choose between clients), simply initialize an instance of LLMRequestHandling
with an LLM API provider of your choice. Here are some examples:
import AI
import OpenAI
import Anthropic
import Mistral
import Groq
// OpenAI / GPT
let client: any LLMRequestHandling = OpenAI.Client(apiKey: "YOUR_API_KEY")
// Anthropic / Claude
let client: any LLMRequestHandling = Anthropic.Client(apiKey: "YOUR_API_KEY")
// Mistral
let client: any LLMRequestHandling = Mistral.Client(apiKey: "YOUR_API_KEY")
// Groq
let client: any LLMRequestHandling = Groq.Client(apiKey: "YOUR_API_KEY")
You can now use client
as an interface to an LLM as provided by the underlying provider.
Each AI Client supports multiple models. For example:
// OpenAI GPT Models
let gpt_4o_Model: OpenAI.Model = .gpt_4o
let gpt_4_Model: OpenAI.Model = .gpt_4
let gpt_3_5_Model: OpenAI.Model = .gpt_3_5
let otherGPTModels: OpenAI.Model = .chat(.gpt_OTHER_MODEL_OPTIONS)
// Open AI Text Embedding Models
let smallTextEmbeddingsModel: OpenAI.Model = .embedding(.text_embedding_3_small)
let largeTextEmbeddingsModel: OpenAI.Model = .embedding(.text_embedding_3_large)
let adaTextEmbeddingsModel: OpenAI.Model = .embedding(.text_embedding_ada_002)
// Anthropic Models
let caludeHaikuModel: Anthropic.Model = .haiku
let claudeSonnetModel: Anthropic.Model = .sonnet
let claudeOpusModel: Anthropic.Model = .opus
// Mistral Models
let mistralTiny: Mistral.Model = .mistral_tiny
let mistralSmall: Mistral.Model = Mistral.Model.mistral_small
let mistralMedium: Mistral.Model = Mistral.Model.mistral_medium
// Groq Models
let gemma_7b: Groq.Model = .gemma_7b
let llama3_8b: Groq.Model = .llama3_8b
let llama3_70b: Groq.Model = .llama3_70b
let mixtral_8x7b: Groq.Model = .mixtral_8x7b
// ElevenLabs Models
let multilingualV2: ElevenLabs.Model = .MultilingualV2
let turboV2: ElevenLabs.Model = .TurboV2 // English
let multilingualV1: ElevenLabs.Model = .MultilingualV1
let englishV1: ElevenLabs.Model = .EnglishV1
Modern Large Language Models (LLMs) operate by receiving a series of inputs, often in the form of messages or prompts, and completing the inputs with the next probable output based on calculations performed by their complex neural network architectures that leverage the vast amounts of data on which it was trained.
You can use the LLMRequestHandling.complete(_:model:)
function to generate a chat completion for a specific model of your choice. For example:
import AI
import OpenAI
let client: any LLMRequestHandling = OpenAI.Client(apiKey: "YOUR_KEY")
// the system prompt is optional
let systemPrompt: PromptLiteral = "You are an extremely intelligent assistant."
let userPrompt: PromptLiteral = "What is the meaning of life?"
let messages: [AbstractLLM.ChatMessage] = [
.system(systemPrompt),
.user(userPrompt)
]
// Each of these is Optional
let parameters = AbstractLLM.ChatCompletionParameters(
// .max or maximum amount of tokens is default
tokenLimit: .fixed(200),
// controls the randomness of the result
temperatureOrTopP: .temperature(1.2),
// stop sequences that indicate to the model when to stop generating further text
stops: ["END OF CHAPTER"],
// check the function calling section below
functions: nil)
let model: OpenAI.Model = .gpt_4o
do {
let result: String = try await client.complete(
messages,
parameters: parameters,
model: model,
as: .string)
return result
} catch {
print(error)
}
Language models (LLMs) are rapidly evolving and expanding into multimodal capabilities. This shift signifies a major transformation in the field, as LLMs are no longer limited to understanding and generating text. With Vision, LLMs can take an image as an input, and provide information about the content of the image.
import AI
import OpenAI
let client: any LLMRequestHandling = OpenAI.Client(apiKey: "YOUR_KEY")
let systemPrompt: PromptLiteral = "You are a VisionExpertGPT. You will receive an image. Your job is to list all the items in the image and write a one-sentence poem about each item. Make sure your poems are creative, capturing the essence of each item in an evocative and imaginative way."
let userPrompt: PromptLiteral = "List the items in this image and write a short one-sentence poem about each item. Only reply with the items and poems. NOTHING MORE."
// Image or NSImage is supported
let imageLiteral = try PromptLiteral(image: imageInput)
let model = OpenAI.Model.gpt_4o
let messages: [AbstractLLM.ChatMessage] = [
.system(systemPrompt),
.user {
.concatenate(separator: nil) {
userPrompt
imageLiteral
}
}]
let result: String = try await client.complete(
messages,
model: model,
as: .string
)
return result
With OpenAI's DALLE-3, text-to-image generation is as easy as just providing a prompt. This gives us, as Apple Developers, the opportunity to include very personalized images for all kinds of use-cases instead of using any generic stock images.
For instance, consider we are building a personal journal app. With the DALLE-3 Image Generation API by OpenAI, we can generate a unique, beautiful image for each journal entry.
import AI
import OpenAI
let client: any LLMRequestHandling = OpenAI.Client(apiKey: "YOUR_KEY")
// user's journal entry for today.
// Note that the imagePrompt should be less than 4000 characters.
let imagePrompt = "Today was an unforgettable day in Japan, filled with awe and wonder at every turn. We began our journey in the bustling streets of Tokyo, where the neon lights and towering skyscrapers left us mesmerized. The serene beauty of the Meiji Shrine provided a stark contrast, offering a peaceful retreat amidst the city's chaos. We indulged in delicious sushi at a local restaurant, the flavors so fresh and vibrant. Later, we took a train to Kyoto, where the sight of the historic temples and the tranquil Arashiyama Bamboo Grove left us breathless. The day ended with a soothing dip in an onsen, the hot springs melting away all our fatigue. Japan's blend of modernity and tradition, coupled with its unparalleled hospitality, made this trip a truly magical experience."
let images = try await openAIClient.createImage(
prompt: imagePrompt,
// either standard or hd (costs more)
quality: OpenAI.Image.Quality.standard,
// 1024x1024, 1792x1024, or 1024x1792 supported
size: OpenAI.Image.Size.w1024h1024,
// either vivid or natural
style: OpenAI.Image.Style.vivid
if let imageURL = images.first?.url {
return URL(string: imageURL)
}
Text embedding models are translators for machines. They convert text, such as sentences or paragraphs, into sets of numbers, which the machine can easily use in complex calculations. The biggest use-case for Text Embeddings is improving Search in your application.
Just simply provide any text and the model will return an embedding (an array of doubles) of that text back.
import AI
import OpenAI
let client: any LLMRequestHandling = OpenAI.Client(apiKey: "YOUR_KEY")
// supported models (Only OpenAI Embeddings Models are supported)
let smallTextEmbeddingsModel: OpenAI.Model = .embedding(.text_embedding_3_small)
let largeTextEmbeddingsModel: OpenAI.Model = .embedding(.text_embedding_3_large)
let adaTextEmbeddingsModel: OpenAI.Model = .embedding(.text_embedding_ada_002)
let textInput = "Hello, Text Embeddings!"
let textEmbeddingsModel: OpenAI.Model = .embedding(.text_embedding_3_small)
let embeddings = try await LLMManager.client.textEmbeddings(
for: [textInput],
model: textEmbeddingsModel)
return embeddings.data.first?.embedding.description
- OpenAI
- Anthropic
- Mistral
- Ollama
- Perplexity
- Groq
This package is licensed under the MIT License.