From d5fe1fd730c8864b882b637578db836f49ed2256 Mon Sep 17 00:00:00 2001 From: Leon Nissen <> Date: Thu, 12 Dec 2024 10:22:54 -0800 Subject: [PATCH 1/6] bump version --- HealthGPT.xcodeproj/project.pbxproj | 14 +-- .../xcshareddata/swiftpm/Package.resolved | 115 ++++++++++++++---- .../HealthGPT/HealthDataInterpreter.swift | 4 +- HealthGPT/HealthGPT/HealthGPTView.swift | 5 +- HealthGPT/HealthGPT/SettingsView.swift | 2 +- .../CodableArray+RawRepresentable.swift | 2 +- HealthGPT/Onboarding/LLMLocalDownload.swift | 5 +- .../Onboarding/OpenAIModelSelection.swift | 2 +- 8 files changed, 104 insertions(+), 45 deletions(-) diff --git a/HealthGPT.xcodeproj/project.pbxproj b/HealthGPT.xcodeproj/project.pbxproj index a1ef9df..90acd1b 100644 --- a/HealthGPT.xcodeproj/project.pbxproj +++ b/HealthGPT.xcodeproj/project.pbxproj @@ -1012,7 +1012,7 @@ repositoryURL = "https://github.com/StanfordSpezi/Spezi.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 1.2.0; + minimumVersion = 1.8.0; }; }; 27859C022A34F16A00397C85 /* XCRemoteSwiftPackageReference "SpeziHealthKit" */ = { @@ -1020,7 +1020,7 @@ repositoryURL = "https://github.com/StanfordSpezi/SpeziHealthKit.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.5.0; + minimumVersion = 0.6.0; }; }; 27859C052A34F17800397C85 /* XCRemoteSwiftPackageReference "SpeziOnboarding" */ = { @@ -1028,7 +1028,7 @@ repositoryURL = "https://github.com/StanfordSpezi/SpeziOnboarding.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 1.1.0; + minimumVersion = 1.2.2; }; }; 27859C0E2A34F1A900397C85 /* XCRemoteSwiftPackageReference "SpeziStorage" */ = { @@ -1036,7 +1036,7 @@ repositoryURL = "https://github.com/StanfordSpezi/SpeziStorage.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 1.0.2; + minimumVersion = 1.2.1; }; }; 27859C1E2A34F2BF00397C85 /* XCRemoteSwiftPackageReference "XCTestExtensions" */ = { @@ -1044,7 +1044,7 @@ repositoryURL = "https://github.com/StanfordBDHG/XCTestExtensions.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.4.7; + minimumVersion = 1.1.0; }; }; 27859C232A34F2D000397C85 /* XCRemoteSwiftPackageReference "XCTHealthKit" */ = { @@ -1060,7 +1060,7 @@ repositoryURL = "https://github.com/StanfordBDHG/XCTRuntimeAssertions.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 1.0.1; + minimumVersion = 1.1.3; }; }; 63439A4C2BA6069E008BDBFD /* XCRemoteSwiftPackageReference "SpeziLLM" */ = { @@ -1068,7 +1068,7 @@ repositoryURL = "https://github.com/StanfordSpezi/SpeziLLM"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.8.1; + minimumVersion = 0.9.0; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/HealthGPT.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/HealthGPT.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 39d3033..b61aceb 100644 --- a/HealthGPT.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/HealthGPT.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -2,12 +2,39 @@ "originHash" : "763dd6c3fb283cd30c2edd3e18fad0c0f9ef9fb226c4b08bdd490e0a7de07181", "pins" : [ { - "identity" : "llama.cpp", + "identity" : "gzipswift", "kind" : "remoteSourceControl", - "location" : "https://github.com/StanfordBDHG/llama.cpp", + "location" : "https://github.com/1024jp/GzipSwift", "state" : { - "revision" : "6839853a321778906e210a33ee2c6aec52f34c97", - "version" : "0.3.3" + "revision" : "731037f6cc2be2ec01562f6597c1d0aa3fe6fd05", + "version" : "6.0.1" + } + }, + { + "identity" : "jinja", + "kind" : "remoteSourceControl", + "location" : "https://github.com/maiqingqiang/Jinja", + "state" : { + "revision" : "6dbe4c449469fb586d0f7339f900f0dd4d78b167", + "version" : "1.0.6" + } + }, + { + "identity" : "mlx-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ml-explore/mlx-swift", + "state" : { + "revision" : "70dbb62128a5a1471a5ab80363430adb33470cab", + "version" : "0.21.2" + } + }, + { + "identity" : "mlx-swift-examples", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ml-explore/mlx-swift-examples", + "state" : { + "revision" : "7baf9bc2d7a2b68b4bfcae308e448ec68b8ef049", + "version" : "1.18.1" } }, { @@ -15,8 +42,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordBDHG/OpenAI", "state" : { - "revision" : "29316babb446c34bb07bf528d96de7eb41e7b03c", - "version" : "0.2.8" + "revision" : "1ad95dd531d7c854a3f98f588b0eb68fa83e8a8c", + "version" : "0.2.9" } }, { @@ -24,8 +51,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/Spezi.git", "state" : { - "revision" : "c43e4fa3d3938a847de2b677091a34ddaea5bc76", - "version" : "1.2.3" + "revision" : "4513a697572e8e1faea1e0ee52e6fad4b8d3dd8d", + "version" : "1.8.0" } }, { @@ -33,8 +60,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziChat", "state" : { - "revision" : "aaa10d71431b78ece8bf29f95c0050632714984d", - "version" : "0.2.0" + "revision" : "940ffbec504849968305d9f956344a4f35b6cd48", + "version" : "0.2.1" } }, { @@ -42,8 +69,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziFoundation", "state" : { - "revision" : "01af5b91a54f30ddd121258e81aff2ddc2a99ff9", - "version" : "1.0.4" + "revision" : "5b4ad1b343154b52a68c33a6bfe02d9cb07cb9dc", + "version" : "2.0.0" } }, { @@ -51,8 +78,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziHealthKit.git", "state" : { - "revision" : "1e9cb5a6036ac7f4ff37ea1c3ed4898103339ad1", - "version" : "0.5.3" + "revision" : "fbdec78fcb2f90d6338f1968e21dd11fbee65070", + "version" : "0.6.0" } }, { @@ -60,8 +87,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziLLM", "state" : { - "revision" : "94f14f6a1d0fb4c7bb54efa6b6241f18dfc5004d", - "version" : "0.8.2" + "revision" : "fd9f1cacb19199576656db4c4dd0c81923b3597a", + "version" : "0.9.0" } }, { @@ -69,8 +96,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziOnboarding.git", "state" : { - "revision" : "4971a82e94996ce0c3d8ecf64fdeec874a1f20d6", - "version" : "1.1.1" + "revision" : "a3d7bc15e6803b2205eb8dca010a48b1a40215be", + "version" : "1.2.2" } }, { @@ -87,8 +114,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziStorage.git", "state" : { - "revision" : "b958df9b31f24800388a7bfc28f457ce7b82556c", - "version" : "1.0.2" + "revision" : "0f4a54430e51f82d29da63a7ce5f61bad7dfb9cd", + "version" : "1.2.1" } }, { @@ -100,13 +127,49 @@ "version" : "1.3.1" } }, + { + "identity" : "swift-argument-parser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-argument-parser.git", + "state" : { + "revision" : "41982a3656a71c768319979febd796c6fd111d5c", + "version" : "1.5.0" + } + }, + { + "identity" : "swift-atomics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-atomics.git", + "state" : { + "revision" : "cd142fd2f64be2100422d658e7411e39489da985", + "version" : "1.2.0" + } + }, { "identity" : "swift-collections", "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-collections.git", "state" : { - "revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb", - "version" : "1.1.0" + "revision" : "671108c96644956dddcd89dd59c203dcdb36cec7", + "version" : "1.1.4" + } + }, + { + "identity" : "swift-numerics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-numerics", + "state" : { + "revision" : "0a5bc04095a675662cf24757cc0640aa2204253b", + "version" : "1.0.2" + } + }, + { + "identity" : "swift-transformers", + "kind" : "remoteSourceControl", + "location" : "https://github.com/huggingface/swift-transformers", + "state" : { + "revision" : "d42fdae473c49ea216671da8caae58e102d28709", + "version" : "0.1.14" } }, { @@ -114,8 +177,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordBDHG/XCTestExtensions.git", "state" : { - "revision" : "1fe9b8e76aeb7a132af37bfa0892160c9b662dcc", - "version" : "0.4.10" + "revision" : "5379d70249cae926927105bfb6686770f03ee5b9", + "version" : "1.1.0" } }, { @@ -132,8 +195,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordBDHG/XCTRuntimeAssertions.git", "state" : { - "revision" : "51da3403f128b120705571ce61e0fe190f8889e6", - "version" : "1.0.1" + "revision" : "f560ec8410af032dd485ca9386e8c2b5d3e1a1f8", + "version" : "1.1.3" } } ], diff --git a/HealthGPT/HealthGPT/HealthDataInterpreter.swift b/HealthGPT/HealthGPT/HealthDataInterpreter.swift index 24201ea..a794b52 100644 --- a/HealthGPT/HealthGPT/HealthDataInterpreter.swift +++ b/HealthGPT/HealthGPT/HealthDataInterpreter.swift @@ -17,8 +17,8 @@ import SpeziSpeechSynthesizer @Observable class HealthDataInterpreter: DefaultInitializable, Module, EnvironmentAccessible { - @ObservationIgnored @Dependency private var llmRunner: LLMRunner - @ObservationIgnored @Dependency private var healthDataFetcher: HealthDataFetcher + @ObservationIgnored @Dependency(LLMRunner.self) private var llmRunner + @ObservationIgnored @Dependency(HealthDataFetcher.self) private var healthDataFetcher var llm: (any LLMSession)? @ObservationIgnored private var systemPrompt = "" diff --git a/HealthGPT/HealthGPT/HealthGPTView.swift b/HealthGPT/HealthGPT/HealthGPTView.swift index e64a635..6c536a6 100644 --- a/HealthGPT/HealthGPT/HealthGPTView.swift +++ b/HealthGPT/HealthGPT/HealthGPTView.swift @@ -71,10 +71,7 @@ struct HealthGPTView: View { if FeatureFlags.mockMode { await healthDataInterpreter.prepareLLM(with: LLMMockSchema()) } else if FeatureFlags.localLLM || llmSource == .local { - await healthDataInterpreter.prepareLLM(with: LLMLocalSchema( - modelPath: .cachesDirectory.appending(path: "llm.gguf"), - formatChat: LLMLocalSchema.PromptFormattingDefaults.llama3 - )) + await healthDataInterpreter.prepareLLM(with: LLMLocalSchema(model: .llama3_8B_4bit)) } else { await healthDataInterpreter.prepareLLM(with: LLMOpenAISchema(parameters: .init(modelType: openAIModel))) } diff --git a/HealthGPT/HealthGPT/SettingsView.swift b/HealthGPT/HealthGPT/SettingsView.swift index 15e9f98..15d5333 100644 --- a/HealthGPT/HealthGPT/SettingsView.swift +++ b/HealthGPT/HealthGPT/SettingsView.swift @@ -102,7 +102,7 @@ struct SettingsView: View { case .openAIModelSelection: LLMOpenAIModelOnboardingStep( actionText: "OPEN_AI_MODEL_SAVE_ACTION", - models: [.gpt3_5Turbo, .gpt4, .gpt4_turbo_preview] + models: [.gpt3_5Turbo, .gpt4, .gpt4_o] ) { model in Task { openAIModel = model diff --git a/HealthGPT/Helper/CodableArray+RawRepresentable.swift b/HealthGPT/Helper/CodableArray+RawRepresentable.swift index 47c0ac0..017db05 100644 --- a/HealthGPT/Helper/CodableArray+RawRepresentable.swift +++ b/HealthGPT/Helper/CodableArray+RawRepresentable.swift @@ -9,7 +9,7 @@ import Foundation -extension Array: RawRepresentable where Element: Codable { +extension Array: @retroactive RawRepresentable where Element: Codable { public var rawValue: String { guard let data = try? JSONEncoder().encode(self), let rawValue = String(data: data, encoding: .utf8) else { diff --git a/HealthGPT/Onboarding/LLMLocalDownload.swift b/HealthGPT/Onboarding/LLMLocalDownload.swift index c475cd1..03f6336 100644 --- a/HealthGPT/Onboarding/LLMLocalDownload.swift +++ b/HealthGPT/Onboarding/LLMLocalDownload.swift @@ -16,9 +16,8 @@ struct LLMLocalDownload: View { var body: some View { LLMLocalDownloadView( - downloadDescription: "LLAMA3_DOWNLOAD_DESCRIPTION", - llmDownloadUrl: LLMLocalDownloadManager.LLMUrlDefaults.llama3InstructModelUrl, - llmStorageUrl: .cachesDirectory.appending(path: "llm.gguf") + model: .llama3_8B_4bit, + downloadDescription: "LLAMA3_DOWNLOAD_DESCRIPTION" ) { onboardingNavigationPath.nextStep() } diff --git a/HealthGPT/Onboarding/OpenAIModelSelection.swift b/HealthGPT/Onboarding/OpenAIModelSelection.swift index 994f28f..4f2e9d3 100644 --- a/HealthGPT/Onboarding/OpenAIModelSelection.swift +++ b/HealthGPT/Onboarding/OpenAIModelSelection.swift @@ -19,7 +19,7 @@ struct OpenAIModelSelection: View { var body: some View { LLMOpenAIModelOnboardingStep( actionText: "OPEN_AI_MODEL_SAVE_ACTION", - models: [.gpt3_5Turbo, .gpt4, .gpt4_turbo_preview] + models: [.gpt3_5Turbo, .gpt4, .gpt4_o] ) { model in openAIModel = model onboardingNavigationPath.nextStep() From 088e5da2b7ebd567fb73afd75f3a6ed36babb18e Mon Sep 17 00:00:00 2001 From: Leon Nissen <> Date: Thu, 12 Dec 2024 13:24:55 -0800 Subject: [PATCH 2/6] adapt to new versions --- HealthGPT/HealthGPT/HealthDataInterpreter.swift | 5 ++++- HealthGPT/HealthGPT/HealthGPTView.swift | 17 +++++++++++------ HealthGPT/HealthGPT/SettingsView.swift | 2 +- .../Supporting Files/HealthGPT.entitlements | 2 ++ 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/HealthGPT/HealthGPT/HealthDataInterpreter.swift b/HealthGPT/HealthGPT/HealthDataInterpreter.swift index a794b52..5c1bcf1 100644 --- a/HealthGPT/HealthGPT/HealthDataInterpreter.swift +++ b/HealthGPT/HealthGPT/HealthDataInterpreter.swift @@ -32,10 +32,13 @@ class HealthDataInterpreter: DefaultInitializable, Module, EnvironmentAccessible /// /// - Parameter schema: the LLMSchema to use @MainActor - func prepareLLM(with schema: any LLMSchema) async { + func prepareLLM(with schema: any LLMSchema) async throws { let llm = llmRunner(with: schema) systemPrompt = await generateSystemPrompt() llm.context.append(systemMessage: systemPrompt) + if let localLLM = llm as? LLMLocalSession { + try await localLLM.setup() + } self.llm = llm } diff --git a/HealthGPT/HealthGPT/HealthGPTView.swift b/HealthGPT/HealthGPT/HealthGPTView.swift index 6c536a6..bbb32bb 100644 --- a/HealthGPT/HealthGPT/HealthGPTView.swift +++ b/HealthGPT/HealthGPT/HealthGPTView.swift @@ -68,12 +68,17 @@ struct HealthGPTView: View { Text(errorMessage) } .task { - if FeatureFlags.mockMode { - await healthDataInterpreter.prepareLLM(with: LLMMockSchema()) - } else if FeatureFlags.localLLM || llmSource == .local { - await healthDataInterpreter.prepareLLM(with: LLMLocalSchema(model: .llama3_8B_4bit)) - } else { - await healthDataInterpreter.prepareLLM(with: LLMOpenAISchema(parameters: .init(modelType: openAIModel))) + do { + if FeatureFlags.mockMode { + try await healthDataInterpreter.prepareLLM(with: LLMMockSchema()) + } else if FeatureFlags.localLLM || llmSource == .local { + try await healthDataInterpreter.prepareLLM(with: LLMLocalSchema(model: .llama3_8B_4bit)) + } else { + try await healthDataInterpreter.prepareLLM(with: LLMOpenAISchema(parameters: .init(modelType: openAIModel))) + } + } catch { + showErrorAlert = true + errorMessage = "Error querying LLM: \(error.localizedDescription)" } } } diff --git a/HealthGPT/HealthGPT/SettingsView.swift b/HealthGPT/HealthGPT/SettingsView.swift index 15d5333..129dfda 100644 --- a/HealthGPT/HealthGPT/SettingsView.swift +++ b/HealthGPT/HealthGPT/SettingsView.swift @@ -106,7 +106,7 @@ struct SettingsView: View { ) { model in Task { openAIModel = model - await healthDataInterpreter.prepareLLM(with: LLMOpenAISchema(parameters: .init(modelType: model))) + try? await healthDataInterpreter.prepareLLM(with: LLMOpenAISchema(parameters: .init(modelType: model))) path.removeLast() } } diff --git a/HealthGPT/Supporting Files/HealthGPT.entitlements b/HealthGPT/Supporting Files/HealthGPT.entitlements index dab226c..ee45c67 100644 --- a/HealthGPT/Supporting Files/HealthGPT.entitlements +++ b/HealthGPT/Supporting Files/HealthGPT.entitlements @@ -8,5 +8,7 @@ com.apple.developer.healthkit.background-delivery + com.apple.developer.kernel.increased-memory-limit + From cdfabc4fd7036cecf69d01dee9c3292f9417f6c5 Mon Sep 17 00:00:00 2001 From: Leon Nissen <> Date: Thu, 12 Dec 2024 13:35:33 -0800 Subject: [PATCH 3/6] fix tests --- HealthGPTUITests/HealthGPTViewUITests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HealthGPTUITests/HealthGPTViewUITests.swift b/HealthGPTUITests/HealthGPTViewUITests.swift index 3035047..7db6045 100644 --- a/HealthGPTUITests/HealthGPTViewUITests.swift +++ b/HealthGPTUITests/HealthGPTViewUITests.swift @@ -30,7 +30,7 @@ final class HealthGPTViewUITests: XCTestCase { XCTAssert(app.buttons["Record Message"].waitForExistence(timeout: 2)) - try app.textViews["Message Input Textfield"].enter(value: "New Message!", dismissKeyboard: false) + try app.textFields["Message Input Textfield"].enter(value: "New Message!") XCTAssert(app.buttons["Send Message"].waitForExistence(timeout: 2)) app.buttons["Send Message"].tap() From cb03f2d5c5374eb4095d3895bcf1332f892b214c Mon Sep 17 00:00:00 2001 From: Vishnu Ravi Date: Tue, 24 Dec 2024 14:44:47 -0500 Subject: [PATCH 4/6] Updates SpeziLLM with local LLM fix --- HealthGPT.xcodeproj/project.pbxproj | 2 +- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HealthGPT.xcodeproj/project.pbxproj b/HealthGPT.xcodeproj/project.pbxproj index 90acd1b..6f65328 100644 --- a/HealthGPT.xcodeproj/project.pbxproj +++ b/HealthGPT.xcodeproj/project.pbxproj @@ -1068,7 +1068,7 @@ repositoryURL = "https://github.com/StanfordSpezi/SpeziLLM"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.9.0; + minimumVersion = 0.9.1; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/HealthGPT.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/HealthGPT.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index b61aceb..dbc97b0 100644 --- a/HealthGPT.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/HealthGPT.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -87,8 +87,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziLLM", "state" : { - "revision" : "fd9f1cacb19199576656db4c4dd0c81923b3597a", - "version" : "0.9.0" + "revision" : "26b1e07756556b1b329f3a9a3267a5f99c0c2e78", + "version" : "0.9.1" } }, { From e60387631619d0d5df633ed7241f54c2d1022c14 Mon Sep 17 00:00:00 2001 From: Vishnu Ravi Date: Sun, 29 Dec 2024 08:05:40 -0500 Subject: [PATCH 5/6] Improve patch coverage --- HealthGPTUITests/HealthGPTViewUITests.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/HealthGPTUITests/HealthGPTViewUITests.swift b/HealthGPTUITests/HealthGPTViewUITests.swift index 7db6045..4fe287d 100644 --- a/HealthGPTUITests/HealthGPTViewUITests.swift +++ b/HealthGPTUITests/HealthGPTViewUITests.swift @@ -56,7 +56,12 @@ final class HealthGPTViewUITests: XCTestCase { XCTAssertTrue(app.buttons["Open AI Model"].exists) app.buttons["Open AI Model"].tap() - app.navigationBars.buttons["Settings"].tap() + + let picker = app.pickers["modelPicker"] + let optionToSelect = picker.pickerWheels.element(boundBy: 0) + optionToSelect.adjust(toPickerWheelValue: "GPT 4") + + app.buttons["Save OpenAI Model"].tap() XCTAssertTrue(app.staticTexts["Enable Text to Speech"].exists) From 9895e50a0fa45a9c0b8d32f3286886670a7571fd Mon Sep 17 00:00:00 2001 From: Vishnu Ravi Date: Sun, 29 Dec 2024 08:21:16 -0500 Subject: [PATCH 6/6] Update README [skip ci] --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 21461ce..3330045 100644 --- a/README.md +++ b/README.md @@ -41,13 +41,17 @@ HealthGPT is provided for general informational purposes only and is not intende ## Set Up -Building and running HealthGPT requires a Mac with [Xcode 15.2](https://developer.apple.com/xcode/) or newer installed. +Building and running HealthGPT requires a Mac with [Xcode 16.2](https://developer.apple.com/xcode/) or newer installed. 1. Clone this repository to your local computer. 2. Open `HealthGPT.xcodeproj` in Xcode. Wait for all dependencies to install and indexing to finish. 3. Run the app (on an iOS device or in the iOS simulator) and play with HealthGPT on your own data 🚀 -Note: If you are running HealthGPT using the simulator, you will need to manually add data in the Apple Health app. Otherwise, all of your results will read zero. +> [!IMPORTANT] +> If you are running HealthGPT using the simulator, you will need to manually add data in the Apple Health app. Otherwise, all of your results will read zero. + +> [!IMPORTANT] +> Running HealthGPT with a local LLM requires installing the app on a physical device, as [SpeziLLMLocal](https://swiftpackageindex.com/stanfordspezi/spezillm/documentation/spezillmlocal) requires a modern Metal MTLGPUFamily and simulators do not provide that. You can add queries for additional [HealthKit](https://developer.apple.com/documentation/healthkit) quantities and categories as follows: