Skip to content

Commit

Permalink
Add reset button to toolbar and update README with new screenshots
Browse files Browse the repository at this point in the history
  • Loading branch information
vishnuravi committed Mar 28, 2024
1 parent 8ef1477 commit 72c694f
Show file tree
Hide file tree
Showing 19 changed files with 93 additions and 20 deletions.
Binary file added Figures/Chat-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Figures/Chat-dark.png.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This source file is part of the HealthGPT open-source project

SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md)

SPDX-License-Identifier: MIT
Binary file added Figures/Chat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Figures/Chat.png.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This source file is part of the HealthGPT open-source project

SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md)

SPDX-License-Identifier: MIT
Binary file added Figures/Export-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Figures/Export-dark.png.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This source file is part of the HealthGPT open-source project

SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md)

SPDX-License-Identifier: MIT
Binary file added Figures/Export.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Figures/Export.png.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This source file is part of the HealthGPT open-source project

SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md)

SPDX-License-Identifier: MIT
Binary file added Figures/Settings-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Figures/Settings-dark.png.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This source file is part of the HealthGPT open-source project

SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md)

SPDX-License-Identifier: MIT
Binary file added Figures/Settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions Figures/Settings.png.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This source file is part of the HealthGPT open-source project

SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md)

SPDX-License-Identifier: MIT
1 change: 0 additions & 1 deletion HealthGPT/HealthGPT/HealthDataInterpreter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ class HealthDataInterpreter: DefaultInitializable, Module, EnvironmentAccessible
/// and passes it to the `PromptGenerator` to create the system prompt.
private func generateSystemPrompt() async -> String {
let healthData = await healthDataFetcher.fetchAndProcessHealthData()
print(healthData)
return PromptGenerator(with: healthData).buildMainPrompt()
}
}
30 changes: 26 additions & 4 deletions HealthGPT/HealthGPT/HealthGPTView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ struct HealthGPTView: View {
ToolbarItem(placement: .primaryAction) {
settingsButton
}
ToolbarItem(placement: .primaryAction) {
resetChatButton
}
}
.onChange(of: llm.context, initial: true) { _, _ in
Task {
Expand All @@ -50,10 +53,7 @@ struct HealthGPTView: View {
}
}
} else {
VStack {
Text("LOADING_CHAT_VIEW")
ProgressView()
}
loadingChatView
}
}
.sheet(isPresented: $showSettings) {
Expand Down Expand Up @@ -81,4 +81,26 @@ struct HealthGPTView: View {
)
.accessibilityIdentifier("settingsButton")
}

private var resetChatButton: some View {
Button(
action: {
Task {
await healthDataInterpreter.resetChat()
}
},
label: {
Image(systemName: "arrow.counterclockwise")
.accessibilityLabel(Text("RESET"))
}
)
.accessibilityIdentifier("resetChatButton")
}

private var loadingChatView: some View {
VStack {
Text("LOADING_CHAT_VIEW")
ProgressView()
}
}
}
2 changes: 1 addition & 1 deletion HealthGPT/HealthGPT/PromptGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PromptGenerator {

func buildMainPrompt() -> String {
let today = DateFormatter.localizedString(from: Date(), dateStyle: .full, timeStyle: .none)
var mainPrompt = "You are HealthGPT, an enthusiastic, expert caretaker with a deep understanding in personal health. Given the context, provide a short response that could answer the user's question. Do NOT provide statistics. If numbers seem low, provide advice on how they can improve.\n\nSome health metrics over the past two weeks (14 days) to incorporate is given below. If a value is zero, the user has not inputted anything for that day. Today is \(today). Note that you do not have data about the current day.\n\n"
var mainPrompt = "You are HealthGPT, an enthusiastic, expert caretaker with a deep understanding in personal health. Given the context, provide a short response that could answer the user's question. Do NOT provide statistics. If numbers seem low, provide advice on how they can improve.\n\nSome health metrics over the past two weeks (14 days) to incorporate is given below. If a value is zero, the user has not inputted anything for that day. Today is \(today). Note that you do not have data about the current day. \n\n"
mainPrompt += buildFourteenDaysHealthDataPrompt()
return mainPrompt
}
Expand Down
4 changes: 3 additions & 1 deletion HealthGPT/Onboarding/HealthKitPermissions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// SPDX-License-Identifier: MIT
//

import OSLog
import SpeziHealthKit
import SpeziOnboarding
import SwiftUI
Expand All @@ -15,6 +16,7 @@ struct HealthKitPermissions: View {
@Environment(HealthKit.self) var healthKitDataSource
@Environment(OnboardingNavigationPath.self) private var onboardingNavigationPath
@State var healthKitProcessing = false
let logger = Logger(subsystem: "HealthGPT", category: "Onboarding")


var body: some View {
Expand Down Expand Up @@ -48,7 +50,7 @@ struct HealthKitPermissions: View {
try await healthKitDataSource.askForAuthorization()
}
} catch {
print("Could not request HealthKit permissions.")
logger.error("Could not request HealthKit permissions: \(error.localizedDescription)")

Check warning on line 53 in HealthGPT/Onboarding/HealthKitPermissions.swift

View check run for this annotation

Codecov / codecov/patch

HealthGPT/Onboarding/HealthKitPermissions.swift#L53

Added line #L53 was not covered by tests
}
onboardingNavigationPath.nextStep()
healthKitProcessing = false
Expand Down
10 changes: 10 additions & 0 deletions HealthGPT/Supporting Files/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,16 @@
}
}
},
"RESET" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reset"
}
}
}
},
"SETTINGS_CHAT" : {
"localizations" : {
"en" : {
Expand Down
9 changes: 9 additions & 0 deletions HealthGPTUITests/HealthGPTViewUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,13 @@ final class HealthGPTViewUITests: XCTestCase {

XCTAssert(app.staticTexts["HealthGPT"].waitForExistence(timeout: 2))
}

func testResetChat() throws {
let app = XCUIApplication()
try app.conductOnboardingIfNeeded()

let resetChatButton = app.buttons["resetChatButton"]
XCTAssertTrue(resetChatButton.waitForExistence(timeout: 5))
resetChatButton.tap()
}
}
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,19 @@ SPDX-License-Identifier: MIT
[![codecov](https://codecov.io/gh/StanfordBDHG/HealthGPT/branch/main/graph/badge.svg?token=5BEldGX6G1)](https://codecov.io/gh/StanfordBDHG/HealthGPT)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7850785.svg)](https://doi.org/10.5281/zenodo.7850785)

![Example Conversation](Figures/Example.png)
|<picture><source media="(prefers-color-scheme: dark)" srcset="Figures/Chat-dark.png"><img src="Figures/Chat.png" width="250" alt="Screenshot showing an example conversation with HealthGPT" /></picture>|<picture><source media="(prefers-color-scheme: dark)" srcset="Figures/Settings-dark.png"><img src="Figures/Settings.png" width="250" alt="Screenshot showing settings for HealthGPT." /></picture>|<picture><source media="(prefers-color-scheme: dark)" srcset="Figures/Export-dark.png"><img src="Figures/Export.png" width="250" alt="Screenshot showing chat export for HealthGPT." /></picture>|
|:--:|:--:|:--:|
|Example Conversation|Settings|Export Chat|

HealthGPT is an experimental iOS app based on [Stanford Spezi](https://github.com/StanfordSpezi/Spezi) that allows users to interact with their health data stored in the Apple Health app using natural language.
The application offers an easy-to-extend solution for those looking to make large language model powered apps within the Apple Health ecosystem.
HealthGPT is an experimental iOS app based on [Stanford Spezi](https://github.com/StanfordSpezi/Spezi) that allows users to interact with their health data stored in the Apple Health app using natural language. The application offers an easy-to-extend solution for those looking to make large language model (LLM) powered apps within the Apple Health ecosystem.

The initial prototype based on [Spezi](https://github.com/StanfordSpezi/Spezi) and the [SpeziTemplateApplication](https://github.com/StanfordSpezi/SpeziTemplateApplication/) was built by [Varun Shenoy](https://varunshenoy.com).
HealthGPT is an open-source project of the [Stanford Biodesign Digital Health](https://bdh.stanford.edu/) team. The initial prototype based on [Spezi](https://github.com/StanfordSpezi/Spezi) and the [SpeziTemplateApplication](https://github.com/StanfordSpezi/SpeziTemplateApplication/) was built by [Varun Shenoy](https://varunshenoy.com).

## Features

- Extensible architecture built on [Stanford Spezi](https://github.com/StanfordSpezi/Spezi) for easy customization.
- Chat-style interface for user-friendly health data interaction using the [SpeziChat](https://github.com/StanfordSpezi/SpeziChat) module.
- Integration with the Apple Health app to ensure seamless first-party data usage.
- Extensible architecture built on the [Stanford Spezi](https://github.com/StanfordSpezi/Spezi) open-source digital health development framework for easy customization.
- Chat-style interface for user-friendly health data interaction using the [SpeziChat](https://github.com/StanfordSpezi/SpeziChat) module with speech-to-text (recognition) as well as text-to-speech (synthesize) accessibility capabilities and chat export functionality.
- Integration with the Apple Health app via [SpeziHealthKit](https://github.com/StanfordSpezi/SpeziHealthKit).
- GPT-3.5 + GPT-4 queries through the [SpeziLLM](https://github.com/StanfordSpezi/SpeziLLM) module.
- Out of the box support for querying sleep, step count, active energy, exercise minutes, heart rate, and body mass.

Expand All @@ -34,19 +35,19 @@ The initial prototype based on [Spezi](https://github.com/StanfordSpezi/Spezi) a

HealthGPT is provided for general informational purposes only and is not intended as a substitute for professional medical advice, diagnosis, or treatment. Large language models, such as those provided by OpenAI, are known to hallucinate and at times return false information. The use of HealthGPT is at your own risk. Always consult a qualified healthcare provider for personalized advice regarding your health and well-being. Aggregated HealthKit data for the past 14 days will be uploaded to OpenAI. Please refer to the [OpenAI privacy policy](https://openai.com/policies/privacy-policy) for more information.


## Set Up

1. Clone this repository.
Building and running HealthGPT requires a Mac with [Xcode 15.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 device or in the simulator) and play with HealthGPT on your own data 🚀
3. Run the app (on an iOS device or in the iOS simulator) and play with HealthGPT on your own data 🚀

Note: if you're using the simulator, you will need to manually add data in the Health app.
Otherwise, all of your results will read zero.
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.

You can add queries for additional [HealthKit](https://developer.apple.com/documentation/healthkit) quantities and categories as follows:

1. Update the SpeziHealthKit configuration in [`HealthGPT/HealthGPT/AppDelegate.swift`](https://github.com/StanfordBDHG/HealthGPT/blob/main/HealthGPT/HealthGPTAppDelegate.swift) to include the additional data type(s).
1. Update the SpeziHealthKit configuration in [`HealthGPT/HealthGPT/AppDelegate.swift`](https://github.com/StanfordBDHG/HealthGPT/blob/main/HealthGPT/HealthGPTAppDelegate.swift) to include the additional data type(s). For more information about configuring SpeziHealthKit, please refer to the [official documentation](https://swiftpackageindex.com/StanfordSpezi/SpeziHealthKit/0.5.3/documentation/spezihealthkit).
2. Edit [`HealthGPT/HealthGPT/HealthDataFetcher.swift`](https://github.com/StanfordBDHG/HealthGPT/blob/main/HealthGPT/HealthGPT/HealthDataFetcher.swift) to create appropriate query for your data type(s).
3. Update the prompt in [`HealthGPT/HealthGPT/PromptGenerator.swift`](https://github.com/StanfordBDHG/HealthGPT/blob/main/HealthGPT/HealthGPT/PromptGenerator.swift) to pass the newly acquired data to the OpenAI API.

Expand Down

0 comments on commit 72c694f

Please sign in to comment.