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
39 changes: 39 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# This workflow will build a Swift project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift

name: CI tests

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build_and_test:
runs-on: macos-latest
steps:
- uses: swift-actions/setup-swift@v2
with:
swift-version: "6.0.1"
- name: Get swift version
run: swift --version
- uses: actions/checkout@v4
- name: Build
run: swift build -q
- name: Run tests
run: swift test -q

lint:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master
- name: Install swiftformat
run: brew install swiftformat
- name: Run linter
run: swiftformat --config rules.swiftformat .
- name: Verify that `swiftformat --config rules.swiftformat .` did not change outputs (if it did, please re-run it and re-commit!)
run: git diff --exit-code
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

### Linting:
```bash
brew install swiftformat
swiftformat --config rules.swiftformat .
```
Original file line number Diff line number Diff line change
Expand Up @@ -5,61 +5,65 @@
// Created by Lou Zell on 3/27/24.
//

import SwiftUI
import SwiftOpenAI
import SwiftUI

struct AIProxyIntroView: View {

@State private var partialKey = ""
@State private var serviceURL = ""
var body: some View {
NavigationStack {
VStack {
Spacer()
VStack(spacing: 24) {
TextField("Enter partial key", text: $partialKey)
TextField("Enter your service's URL", text: $serviceURL)
}
.padding()
.textFieldStyle(.roundedBorder)

private var canProceed: Bool {
return !(self.partialKey.isEmpty || self.serviceURL.isEmpty)
}
Text("You receive a partial key and service URL when you configure an app in the AIProxy dashboard")
.font(.caption)

var body: some View {
NavigationStack {
VStack {
Spacer()
VStack(spacing: 24) {
TextField("Enter partial key", text: $partialKey)
TextField("Enter your service's URL", text: $serviceURL)
}
NavigationLink(destination: OptionsListView(
openAIService: aiproxyService,
options: OptionsListView.APIOption.allCases.filter { $0 != .localChat }))
{
Text("Continue")
.padding()
.textFieldStyle(.roundedBorder)
.padding(.horizontal, 48)
.foregroundColor(.white)
.background(
Capsule()
.foregroundColor(canProceed ? Color(red: 64 / 255, green: 195 / 255, blue: 125 / 255) : .gray.opacity(0.2)))
}
.disabled(!canProceed)
Spacer()
Group {
Text(
"AIProxy keeps your OpenAI API key secure. To configure AIProxy for your project, or to learn more about how it works, please see the docs at ") +
Text("[this link](https://www.aiproxy.pro/docs).")
}
.font(.caption)
}
.padding()
.navigationTitle("AIProxy Configuration")
}
}

Text("You receive a partial key and service URL when you configure an app in the AIProxy dashboard")
.font(.caption)
@State private var partialKey = ""
@State private var serviceURL = ""

NavigationLink(destination: OptionsListView(openAIService: aiproxyService, options: OptionsListView.APIOption.allCases.filter({ $0 != .localChat }))) {
Text("Continue")
.padding()
.padding(.horizontal, 48)
.foregroundColor(.white)
.background(
Capsule()
.foregroundColor(canProceed ? Color(red: 64/255, green: 195/255, blue: 125/255) : .gray.opacity(0.2)))
}
.disabled(!canProceed)
Spacer()
Group {
Text("AIProxy keeps your OpenAI API key secure. To configure AIProxy for your project, or to learn more about how it works, please see the docs at ") + Text("[this link](https://www.aiproxy.pro/docs).")
}
.font(.caption)
}
.padding()
.navigationTitle("AIProxy Configuration")
}
}
private var canProceed: Bool {
!(partialKey.isEmpty || serviceURL.isEmpty)
}

private var aiproxyService: OpenAIService {
OpenAIServiceFactory.service(
aiproxyPartialKey: partialKey,
aiproxyServiceURL: serviceURL != "" ? serviceURL : nil
)
}
private var aiproxyService: OpenAIService {
OpenAIServiceFactory.service(
aiproxyPartialKey: partialKey,
aiproxyServiceURL: serviceURL != "" ? serviceURL : nil)
}
}

#Preview {
ApiKeyIntroView()
ApiKeyIntroView()
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,54 +5,57 @@
// Created by James Rochabrun on 10/19/23.
//

import SwiftUI
import SwiftOpenAI
import SwiftUI

struct ApiKeyIntroView: View {

@State private var apiKey = ""
@State private var organizationIdentifier = ""
@State private var localOrganizationID: String? = nil

var body: some View {
NavigationStack {
VStack {
Spacer()
VStack(spacing: 24) {
TextField("Enter API Key", text: $apiKey)
TextField("Enter Organization ID (Optional)", text: $organizationIdentifier)
.onChange(of: organizationIdentifier) { _, newValue in
if !newValue.isEmpty {
localOrganizationID = newValue
}
}

var body: some View {
NavigationStack {
VStack {
Spacer()
VStack(spacing: 24) {
TextField("Enter API Key", text: $apiKey)
TextField("Enter Organization ID (Optional)", text: $organizationIdentifier)
.onChange(of: organizationIdentifier) { _, newValue in
if !newValue.isEmpty {
localOrganizationID = newValue
}
}
}
.padding()
.textFieldStyle(.roundedBorder)
NavigationLink(destination: OptionsListView(
openAIService: OpenAIServiceFactory.service(apiKey: apiKey, organizationID: localOrganizationID, debugEnabled: true),
options: OptionsListView.APIOption.allCases.filter { $0 != .localChat }))
{
Text("Continue")
.padding()
.textFieldStyle(.roundedBorder)
NavigationLink(destination: OptionsListView(openAIService: OpenAIServiceFactory.service(apiKey: apiKey, organizationID: localOrganizationID, debugEnabled: true), options: OptionsListView.APIOption.allCases.filter({ $0 != .localChat }))) {
Text("Continue")
.padding()
.padding(.horizontal, 48)
.foregroundColor(.white)
.background(
Capsule()
.foregroundColor(apiKey.isEmpty ? .gray.opacity(0.2) : Color(red: 64/255, green: 195/255, blue: 125/255)))
}
.disabled(apiKey.isEmpty)
Spacer()
Group {
Text("If you don't have a valid API KEY yet, you can visit ") + Text("[this link](https://platform.openai.com/account/api-keys)") + Text(" to get started.")
}
.font(.caption)
}
.padding()
.navigationTitle("Enter OpenAI API KEY")
.padding(.horizontal, 48)
.foregroundColor(.white)
.background(
Capsule()
.foregroundColor(apiKey.isEmpty ? .gray.opacity(0.2) : Color(red: 64 / 255, green: 195 / 255, blue: 125 / 255)))
}
.disabled(apiKey.isEmpty)
Spacer()
Group {
Text("If you don't have a valid API KEY yet, you can visit ") +
Text("[this link](https://platform.openai.com/account/api-keys)") + Text(" to get started.")
}
.font(.caption)
}
}
.padding()
.navigationTitle("Enter OpenAI API KEY")
}
}

@State private var apiKey = ""
@State private var organizationIdentifier = ""
@State private var localOrganizationID: String? = nil

}

#Preview {
ApiKeyIntroView()
ApiKeyIntroView()
}


Loading