Skip to content

Commit

Permalink
ollama http host config
Browse files Browse the repository at this point in the history
  • Loading branch information
CrazyNeil committed Jan 24, 2025
1 parent d8eaed9 commit fd95c9a
Show file tree
Hide file tree
Showing 10 changed files with 284 additions and 31 deletions.
4 changes: 4 additions & 0 deletions OllamaSpring.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
FBD459472C86B680000BE5C1 /* GroqApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBD459462C86B680000BE5C1 /* GroqApi.swift */; };
FBD4948E2BFD92CA009AFAC1 /* RightTopBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBD4948D2BFD92CA009AFAC1 /* RightTopBarView.swift */; };
FBDF8C532C0775DC00BED237 /* OllamaLibraryModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBDF8C522C0775DC00BED237 /* OllamaLibraryModalView.swift */; };
FBEF6E4F2D431812001C9AB6 /* OllamaHostConfigModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBEF6E4E2D431807001C9AB6 /* OllamaHostConfigModalView.swift */; };
FBEFBE512C9D077600B93648 /* HttpProxyConfigPanelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBEFBE502C9D077600B93648 /* HttpProxyConfigPanelView.swift */; };
FBF304822C8C1C5100C91CB4 /* GroqApiKeyConfigModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBF304812C8C1C5100C91CB4 /* GroqApiKeyConfigModalView.swift */; };
FBF304842C8EAB9A00C91CB4 /* GroqModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBF304832C8EAB9A00C91CB4 /* GroqModel.swift */; };
Expand Down Expand Up @@ -139,6 +140,7 @@
FBD459462C86B680000BE5C1 /* GroqApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroqApi.swift; sourceTree = "<group>"; };
FBD4948D2BFD92CA009AFAC1 /* RightTopBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RightTopBarView.swift; sourceTree = "<group>"; };
FBDF8C522C0775DC00BED237 /* OllamaLibraryModalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OllamaLibraryModalView.swift; sourceTree = "<group>"; };
FBEF6E4E2D431807001C9AB6 /* OllamaHostConfigModalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OllamaHostConfigModalView.swift; sourceTree = "<group>"; };
FBEFBE502C9D077600B93648 /* HttpProxyConfigPanelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HttpProxyConfigPanelView.swift; sourceTree = "<group>"; };
FBF304812C8C1C5100C91CB4 /* GroqApiKeyConfigModalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroqApiKeyConfigModalView.swift; sourceTree = "<group>"; };
FBF304832C8EAB9A00C91CB4 /* GroqModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroqModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -257,6 +259,7 @@
FB65CFE82BF984FB00E1EA88 /* Modal */ = {
isa = PBXGroup;
children = (
FBEF6E4E2D431807001C9AB6 /* OllamaHostConfigModalView.swift */,
FB65CFE92BF9851900E1EA88 /* ConfirmModalView.swift */,
FBDF8C522C0775DC00BED237 /* OllamaLibraryModalView.swift */,
FBF304812C8C1C5100C91CB4 /* GroqApiKeyConfigModalView.swift */,
Expand Down Expand Up @@ -507,6 +510,7 @@
FB9871762C281881000A4808 /* custom.swift in Sources */,
FB0FC7E52BEF1657007E4EB9 /* OllamaSpringApp.swift in Sources */,
FBEFBE512C9D077600B93648 /* HttpProxyConfigPanelView.swift in Sources */,
FBEF6E4F2D431812001C9AB6 /* OllamaHostConfigModalView.swift in Sources */,
FB65CFE72BF8798C00E1EA88 /* OllamaLocalModelListRowView.swift in Sources */,
FB98716D2C1C47BF000A4808 /* AppDelegate.swift in Sources */,
FBD459472C86B680000BE5C1 /* GroqApi.swift in Sources */,
Expand Down
15 changes: 1 addition & 14 deletions OllamaSpring/Constant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ import Foundation

/// conversation avatars
let avatars = ["ollama-1","ollama-2","ollama-3"]

/// default conversation name
let default_conversation_name = "New Chat"

/// preferred response language
let PreferredLangList = [
PreferredResponseLanguage(lang: "Auto"),
Expand All @@ -26,25 +24,18 @@ let PreferredLangList = [
PreferredResponseLanguage(lang: "Simplified Chinese"),
PreferredResponseLanguage(lang: "Traditional Chinese")
]

/// default response language
let defaultResponseLang = "English"

/// Api Host
let ApiHostList = [
ApiHost(baseUrl: "http://localhost", port: 11434, name: "Ollama"),
ApiHost(baseUrl: "https://api.groq.com", port: 443, name: "Groq Fast AI")
]

let defaultApiHost = ApiHostList[0].name

/// Groq
let defaultGroqApiKey = ""
let groqWebUrl = "https://groq.com"
let groqApiBaseUrl = ApiHostList[1].baseUrl + ":" + String(ApiHostList[1].port)



/// Http Proxy
let defaultHttpProxyHostName = "127.0.0.1"
let defaultHttpProxyHostPort = "6152"
Expand All @@ -57,15 +48,11 @@ let httpProxyAuthDefaultStatus = false
let ollamaWebUrl = "https://ollama.com"
/// ollama search page
let ollamaLibraryUrl = "https://ollama.com/library"


/// no model downloaded
let noModelFound = "No model found"

/// ollama api default params
let ollamaApiBaseUrl = "http://localhost"
let ollamaApiDefaultBaseUrl = "localhost"
let ollamaApiDefaultPort = "11434"

/// models json url
struct OllamaSpringModelsApiURL {
static let groqModels = "https://www.ollamaspring.com/groq-models.json"
Expand Down
11 changes: 11 additions & 0 deletions OllamaSpring/Database/RealmModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,17 @@ class PreferenceManager {
realm.delete(record)
}
}

/// Load preference value with default value
func loadPreferenceValue(forKey key: String, defaultValue: String) -> String {
let preferenceValue = getPreference(preferenceKey: key).first?.preferenceValue
if let value = preferenceValue, !value.isEmpty {
return value
} else {
setPreference(preferenceKey: key, preferenceValue: defaultValue)
return defaultValue
}
}

}

Expand Down
25 changes: 22 additions & 3 deletions OllamaSpring/Network/OllamaApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,31 @@ import SwiftUI
class OllamaApi {
private var apiBaseUrl: String
private var port: String
private let preference = PreferenceManager()

init(apiBaseUrl:String = ollamaApiBaseUrl, port:String = ollamaApiDefaultPort) {
self.apiBaseUrl = apiBaseUrl
self.port = port
init(apiBaseUrl: String? = nil, port: String? = nil) {
// First initialize stored properties
self.apiBaseUrl = ollamaApiDefaultBaseUrl
self.port = ollamaApiDefaultPort

// Then update with provided values or load from database
if let baseUrl = apiBaseUrl, let portNumber = port {
self.apiBaseUrl = baseUrl
self.port = portNumber
} else {
let config = loadConfigFromDatabase()
self.apiBaseUrl = config.baseUrl
self.port = config.port
}
}

private func loadConfigFromDatabase() -> (baseUrl: String, port: String) {
let baseUrl = preference.loadPreferenceValue(forKey: "ollamaHostName", defaultValue: ollamaApiDefaultBaseUrl)
let port = preference.loadPreferenceValue(forKey: "ollamaHostPort", defaultValue: ollamaApiDefaultPort)
return ("http://" + baseUrl, port)
}


private func makeRequest(
method: String,
endpoint: String,
Expand Down
10 changes: 10 additions & 0 deletions OllamaSpring/View/Menu/RightTopBarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ struct RightTopBarView: View {

@Binding var openOllamaLibraryModal:Bool
@Binding var openGroqApiKeyConfigModal:Bool
@Binding var openOllamaHostConfigModal:Bool

@State private var streamingOutputToggleAlert = false

Expand Down Expand Up @@ -215,6 +216,15 @@ struct RightTopBarView: View {
}
}

Button(role: .destructive, action: {
self.openOllamaHostConfigModal.toggle()
}) {
HStack {
Text("Ollama HTTP Host Config")
.font(.subheadline)
}
}

}
.font(.subheadline)
.buttonStyle(PlainButtonStyle())
Expand Down
127 changes: 127 additions & 0 deletions OllamaSpring/View/Modal/OllamaHostConfigModalView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//
// OllamaHostConfigModal.swift
// OllamaSpring
//
// Created by NeilStudio on 2024/3/21.
//

import SwiftUI

struct OllamaHostConfigModalView: View {
@ObservedObject var commonViewModel: CommonViewModel

@Binding var openOllamaHostConfigModal: Bool

@State private var hostText = ""
@State private var portText = ""

var body: some View {
VStack(spacing: 0) {
HStack {
Text("Ollama HTTP Host Configuration")
.font(.subheadline)
.foregroundColor(.gray)

Spacer()
}
.padding(.leading, 45)
.onAppear() {
let config = commonViewModel.loadOllamaHostConfigFromDatabase()
self.hostText = config.host
self.portText = config.port
}

VStack(spacing: 0) {
HStack {
TextField(self.hostText == "" ? ollamaApiDefaultBaseUrl : self.hostText, text: $hostText)
.textFieldStyle(PlainTextFieldStyle())
.frame(width: 300, height: 25)
.padding(EdgeInsets(top: 5, leading: 12, bottom: 5, trailing: 12))
.background(Color.black)
.opacity(0.5)
.cornerRadius(4)
.padding(.horizontal)
.padding(.vertical, 5)
}

HStack {
TextField(self.portText.isEmpty ? ollamaApiDefaultPort : self.portText, text: $portText)
.textFieldStyle(PlainTextFieldStyle())
.frame(width: 300, height: 25)
.padding(EdgeInsets(top: 5, leading: 12, bottom: 5, trailing: 12))
.background(Color.black)
.opacity(0.5)
.cornerRadius(4)
.padding(.horizontal)
.padding(.vertical, 5)
}
}
.padding(.horizontal)
.padding(.vertical, 5)

HStack {
Spacer()

Text("Save")
.font(.subheadline)
.padding(.horizontal, 2)
.padding(.vertical, 3)
.frame(width: 100)
.background(Color.blue)
.cornerRadius(4)
.onTapGesture {
Task {
let isSuccess = await commonViewModel.testOllamaHostConfig(host: hostText, port: portText)
if isSuccess {
self.openOllamaHostConfigModal = false
} else {
// 显示错误提示
#if os(macOS)
let alert = NSAlert()
alert.messageText = "Connection Failed"
alert.informativeText = "Failed to connect to Ollama host. Please check your configuration and try again."
alert.alertStyle = .warning
alert.addButton(withTitle: "OK")
alert.runModal()
#endif
}
}
}

Text("Cancel")
.font(.subheadline)
.foregroundColor(.black)
.padding(.horizontal, 2)
.padding(.vertical, 3)
.frame(width: 100)
.background(Color.white)
.cornerRadius(4)
.onTapGesture {
self.openOllamaHostConfigModal.toggle()
}
}
.padding(.trailing, 40)
.padding(.leading, 75)
.padding(.top, 0)

HStack(spacing: 0) {
Text("Configure the Ollama HTTP host and port. By default, the host is set to 127.0.0.1 and the port to 11434 in your local environment. You may only connect to remote hosts that do not require authentication.")
.font(.subheadline)
.foregroundColor(.gray)
.lineLimit(4)
.opacity(0.9)
.padding(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.gray, lineWidth: 1)
)

Spacer()
}
.padding(.leading, 37)
.padding(.top, 15)
.padding(.trailing, 25)
}
.frame(width: 400, height: 270)
}
}
7 changes: 7 additions & 0 deletions OllamaSpring/View/Panel/ChatListPanelView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct ChatListPanelView: View {

@Binding var openOllamaLibraryModal:Bool
@Binding var openGroqApiKeyConfigModal:Bool
@Binding var openOllamaHostConfigModal:Bool

@State private var isShowingTemperatureDesc = false
@State private var isShowingSeedDesc = false
Expand Down Expand Up @@ -183,6 +184,12 @@ struct ChatListPanelView: View {
openGroqApiKeyConfigModal: $openGroqApiKeyConfigModal
)
}
.sheet(isPresented:$openOllamaHostConfigModal) {
OllamaHostConfigModalView(
commonViewModel: commonViewModel,
openOllamaHostConfigModal: $openOllamaHostConfigModal
)
}
}
.frame(maxHeight: .infinity)
.frame(width: 280)
Expand Down
19 changes: 17 additions & 2 deletions OllamaSpring/View/Panel/MainPanelView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ struct MainPanelView: View {

@State private var openOllamaLibraryModal = false
@State private var openGroqApiKeyConfigModal = false
@State private var openOllamaHostConfigModal = false

init() {
let commonViewModel = CommonViewModel()
Expand All @@ -25,15 +26,17 @@ struct MainPanelView: View {
messagesViewModel: messagesViewModel,
commonViewModel: commonViewModel,
openOllamaLibraryModal: $openOllamaLibraryModal,
openGroqApiKeyConfigModal: $openGroqApiKeyConfigModal
openGroqApiKeyConfigModal: $openGroqApiKeyConfigModal,
openOllamaHostConfigModal: $openOllamaHostConfigModal
)

VStack() {
RightTopBarView(
commonViewModel: commonViewModel,
messagesViewModel: messagesViewModel,
openOllamaLibraryModal: $openOllamaLibraryModal,
openGroqApiKeyConfigModal: $openGroqApiKeyConfigModal
openGroqApiKeyConfigModal: $openGroqApiKeyConfigModal,
openOllamaHostConfigModal: $openOllamaHostConfigModal
)

MessagesPanelView(
Expand Down Expand Up @@ -128,6 +131,18 @@ struct MainPanelView: View {
commonViewModel.ollamaApiServiceStatusCheck()
}

Text("Ollama Host Config")
.font(.body)
.foregroundColor(.gray)
.padding(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.gray, lineWidth: 1)
)
.onTapGesture {
openOllamaHostConfigModal.toggle()
}


}
.frame(maxWidth: 600)
Expand Down
Loading

0 comments on commit fd95c9a

Please sign in to comment.