From 457ca0c2da887a548dbc6a00eb3f9b471aa0a86e Mon Sep 17 00:00:00 2001 From: Philipp Zagar Date: Thu, 25 Jan 2024 14:20:38 -0800 Subject: [PATCH 1/7] First demo draft --- ExampleApplication.xcodeproj/project.pbxproj | 91 ++++++++++++++++++- .../xcshareddata/swiftpm/Package.resolved | 90 ++++++++++-------- .../ExampleApplicationDelegate.swift | 8 ++ ExampleApplication/Home.swift | 6 ++ .../LLMInteraction/LLMInteraction.swift | 66 ++++++++++++++ .../LLMInteraction/LLMOnboardingView.swift | 28 ++++++ .../Local/LLMLocalDownloadOnboarding.swift | 34 +++++++ .../OpenAI/LLMOpenAIFunctionWeather.swift | 34 +++++++ .../OpenAI/LLMOpenAITokenOnboarding.swift | 30 ++++++ .../Resources/Localizable.xcstrings | 20 ++++ 10 files changed, 369 insertions(+), 38 deletions(-) create mode 100644 ExampleApplication/LLMInteraction/LLMInteraction.swift create mode 100644 ExampleApplication/LLMInteraction/LLMOnboardingView.swift create mode 100644 ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift create mode 100644 ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift create mode 100644 ExampleApplication/LLMInteraction/OpenAI/LLMOpenAITokenOnboarding.swift diff --git a/ExampleApplication.xcodeproj/project.pbxproj b/ExampleApplication.xcodeproj/project.pbxproj index 43a8afc..15a69f5 100644 --- a/ExampleApplication.xcodeproj/project.pbxproj +++ b/ExampleApplication.xcodeproj/project.pbxproj @@ -69,6 +69,15 @@ 653A256228338800005D4D48 /* ExampleApplicationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653A256128338800005D4D48 /* ExampleApplicationTests.swift */; }; 9733CFC62A8066DE001B7ABC /* SpeziOnboarding in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC8029EDD91D004B9AB4 /* SpeziOnboarding */; }; 9739A0C62AD7B5730084BEA5 /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 9739A0C52AD7B5730084BEA5 /* FirebaseStorage */; }; + 97AA38842B61D81A006627C6 /* LLMLocalDownloadOnboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97AA38832B61D81A006627C6 /* LLMLocalDownloadOnboarding.swift */; }; + 97AA38892B61D971006627C6 /* LLMOpenAIFunctionWeather.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97AA38882B61D971006627C6 /* LLMOpenAIFunctionWeather.swift */; }; + 97CFE5BF2B61D31C00BEE444 /* LLMOpenAITokenOnboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CFE5BC2B61D31C00BEE444 /* LLMOpenAITokenOnboarding.swift */; }; + 97CFE5C02B61D31C00BEE444 /* LLMOnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CFE5BD2B61D31C00BEE444 /* LLMOnboardingView.swift */; }; + 97CFE5C12B61D31C00BEE444 /* LLMInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CFE5BE2B61D31C00BEE444 /* LLMInteraction.swift */; }; + 97CFE5C42B61D37800BEE444 /* SpeziLLM in Frameworks */ = {isa = PBXBuildFile; productRef = 97CFE5C32B61D37800BEE444 /* SpeziLLM */; }; + 97CFE5C62B61D37800BEE444 /* SpeziLLMLocal in Frameworks */ = {isa = PBXBuildFile; productRef = 97CFE5C52B61D37800BEE444 /* SpeziLLMLocal */; }; + 97CFE5C82B61D37800BEE444 /* SpeziLLMLocalDownload in Frameworks */ = {isa = PBXBuildFile; productRef = 97CFE5C72B61D37800BEE444 /* SpeziLLMLocalDownload */; }; + 97CFE5CA2B61D37800BEE444 /* SpeziLLMOpenAI in Frameworks */ = {isa = PBXBuildFile; productRef = 97CFE5C92B61D37800BEE444 /* SpeziLLMOpenAI */; }; 97D73D6A2AD860AD00B47FA0 /* SpeziFirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 97D73D692AD860AD00B47FA0 /* SpeziFirebaseStorage */; }; A9720E432ABB68CC00872D23 /* AccountSetupHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9720E422ABB68CC00872D23 /* AccountSetupHeader.swift */; }; A9D83F962B083794000D0C78 /* SpeziFirebaseAccountStorage in Frameworks */ = {isa = PBXBuildFile; productRef = A9D83F952B083794000D0C78 /* SpeziFirebaseAccountStorage */; }; @@ -139,6 +148,11 @@ 653A256128338800005D4D48 /* ExampleApplicationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleApplicationTests.swift; sourceTree = ""; }; 653A256728338800005D4D48 /* ExampleApplicationUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleApplicationUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 653A258928339462005D4D48 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 97AA38832B61D81A006627C6 /* LLMLocalDownloadOnboarding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LLMLocalDownloadOnboarding.swift; sourceTree = ""; }; + 97AA38882B61D971006627C6 /* LLMOpenAIFunctionWeather.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LLMOpenAIFunctionWeather.swift; sourceTree = ""; }; + 97CFE5BC2B61D31C00BEE444 /* LLMOpenAITokenOnboarding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMOpenAITokenOnboarding.swift; sourceTree = ""; }; + 97CFE5BD2B61D31C00BEE444 /* LLMOnboardingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMOnboardingView.swift; sourceTree = ""; }; + 97CFE5BE2B61D31C00BEE444 /* LLMInteraction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMInteraction.swift; sourceTree = ""; }; A9720E422ABB68CC00872D23 /* AccountSetupHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSetupHeader.swift; sourceTree = ""; }; A9DFE8A82ABE551400428242 /* AccountButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountButton.swift; sourceTree = ""; }; A9FE7ACF2AA39BAB0077B045 /* AccountSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSheet.swift; sourceTree = ""; }; @@ -149,13 +163,16 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 97CFE5C62B61D37800BEE444 /* SpeziLLMLocal in Frameworks */, 9733CFC62A8066DE001B7ABC /* SpeziOnboarding in Frameworks */, 2FE5DC6429EDD883004B9AB4 /* SpeziAccount in Frameworks */, 2FB099AF2A875DF100B20952 /* FirebaseAuth in Frameworks */, + 97CFE5CA2B61D37800BEE444 /* SpeziLLMOpenAI in Frameworks */, 97D73D6A2AD860AD00B47FA0 /* SpeziFirebaseStorage in Frameworks */, 2FE5DC6729EDD894004B9AB4 /* SpeziContact in Frameworks */, - 2FE5DC8429EDD934004B9AB4 /* SpeziQuestionnaire in Frameworks */, + 2FE5DC8429EDD934004B9AB4 /* SpeziQuestionnaire in Frameworks */, 2FB099B32A875DF100B20952 /* FirebaseFirestoreSwift in Frameworks */, + 97CFE5C42B61D37800BEE444 /* SpeziLLM in Frameworks */, 5661551D2AB8384200209B80 /* SwiftPackageList in Frameworks */, 2FB099B12A875DF100B20952 /* FirebaseFirestore in Frameworks */, A9D83F962B083794000D0C78 /* SpeziFirebaseAccountStorage in Frameworks */, @@ -167,6 +184,7 @@ 2FF53D8B2A8725DE00042B76 /* SpeziMockWebService in Frameworks */, 2FE5DC7229EDD8D3004B9AB4 /* SpeziHealthKit in Frameworks */, 2F49B7762980407C00BCB272 /* Spezi in Frameworks */, + 97CFE5C82B61D37800BEE444 /* SpeziLLMLocalDownload in Frameworks */, 2FE5DC8F29EDD980004B9AB4 /* SpeziViews in Frameworks */, 2F3D4ABC2A4E7C290068FB2F /* SpeziScheduler in Frameworks */, 2FBD738C2A3BD150004228E7 /* SpeziScheduler in Frameworks */, @@ -358,6 +376,34 @@ name = Frameworks; sourceTree = ""; }; + 97AA38852B61D927006627C6 /* Local */ = { + isa = PBXGroup; + children = ( + 97AA38832B61D81A006627C6 /* LLMLocalDownloadOnboarding.swift */, + ); + path = Local; + sourceTree = ""; + }; + 97AA38862B61D92D006627C6 /* OpenAI */ = { + isa = PBXGroup; + children = ( + 97CFE5BC2B61D31C00BEE444 /* LLMOpenAITokenOnboarding.swift */, + 97AA38882B61D971006627C6 /* LLMOpenAIFunctionWeather.swift */, + ); + path = OpenAI; + sourceTree = ""; + }; + 97CFE5B72B61D2E900BEE444 /* LLMInteraction */ = { + isa = PBXGroup; + children = ( + 97AA38852B61D927006627C6 /* Local */, + 97AA38862B61D92D006627C6 /* OpenAI */, + 97CFE5BD2B61D31C00BEE444 /* LLMOnboardingView.swift */, + 97CFE5BE2B61D31C00BEE444 /* LLMInteraction.swift */, + ); + path = LLMInteraction; + sourceTree = ""; + }; A9720E412ABB68B300872D23 /* Account */ = { isa = PBXGroup; children = ( @@ -410,6 +456,10 @@ 9739A0C52AD7B5730084BEA5 /* FirebaseStorage */, 97D73D692AD860AD00B47FA0 /* SpeziFirebaseStorage */, A9D83F952B083794000D0C78 /* SpeziFirebaseAccountStorage */, + 97CFE5C32B61D37800BEE444 /* SpeziLLM */, + 97CFE5C52B61D37800BEE444 /* SpeziLLMLocal */, + 97CFE5C72B61D37800BEE444 /* SpeziLLMLocalDownload */, + 97CFE5C92B61D37800BEE444 /* SpeziLLMOpenAI */, ); productName = ExampleApplication; productReference = 653A254D283387FE005D4D48 /* ExampleApplication.app */; @@ -504,6 +554,7 @@ 2FE750CA2A87240100723EAE /* XCRemoteSwiftPackageReference "SpeziMockWebService" */, 2FB099B42A875E2B00B20952 /* XCRemoteSwiftPackageReference "HealthKitOnFHIR" */, 5661551B2AB8384200209B80 /* XCRemoteSwiftPackageReference "swift-package-list" */, + 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */, ); productRefGroup = 653A254E283387FE005D4D48 /* Products */; projectDirPath = ""; @@ -578,24 +629,28 @@ 2FE5DC3A29EDD7CA004B9AB4 /* Welcome.swift in Sources */, 2FE5DC3829EDD7CA004B9AB4 /* InterestingModules.swift in Sources */, 2FE5DC3529EDD7CA004B9AB4 /* Consent.swift in Sources */, + 97CFE5BF2B61D31C00BEE444 /* LLMOpenAITokenOnboarding.swift in Sources */, 2FE5DC4529EDD7F2004B9AB4 /* Binding+Negate.swift in Sources */, 2FC975A82978F11A00BA99FE /* Home.swift in Sources */, 2FE5DC4E29EDD7FA004B9AB4 /* ScheduleView.swift in Sources */, A9DFE8A92ABE551400428242 /* AccountButton.swift in Sources */, 2FE5DC3729EDD7CA004B9AB4 /* OnboardingFlow.swift in Sources */, 2F1AC9DF2B4E840E00C24973 /* ExampleApplication.docc in Sources */, + 97AA38842B61D81A006627C6 /* LLMLocalDownloadOnboarding.swift in Sources */, 2FF53D8D2A8729D600042B76 /* ExampleApplicationStandard.swift in Sources */, 2FE5DC4729EDD7F2004B9AB4 /* CodableArray+RawRepresentable.swift in Sources */, A9720E432ABB68CC00872D23 /* AccountSetupHeader.swift in Sources */, + 97CFE5C12B61D31C00BEE444 /* LLMInteraction.swift in Sources */, 2FE5DC4029EDD7EE004B9AB4 /* FeatureFlags.swift in Sources */, 2FE5DC4629EDD7F2004B9AB4 /* Bundle+Image.swift in Sources */, 2FE5DC4F29EDD7FA004B9AB4 /* EventContext.swift in Sources */, 2FE5DC5029EDD7FA004B9AB4 /* EventContextView.swift in Sources */, 2F4E23832989D51F0013F3D9 /* ExampleApplicationTestingSetup.swift in Sources */, - 2FE5DC5329EDD7FA004B9AB4 /* Bundle+Questionnaire.swift in Sources */, + 2FE5DC5329EDD7FA004B9AB4 /* Bundle+Questionnaire.swift in Sources */, 2FE5DC5129EDD7FA004B9AB4 /* ExampleApplicationTaskContext.swift in Sources */, 56F6F2A02AB441930022FE5A /* ContributionsList.swift in Sources */, 566155292AB8447C00209B80 /* Package+LicenseType.swift in Sources */, + 97CFE5C02B61D31C00BEE444 /* LLMOnboardingView.swift in Sources */, 5680DD392AB8983D004E6D4A /* PackageCell.swift in Sources */, 2F5E32BD297E05EA003432F8 /* ExampleApplicationDelegate.swift in Sources */, 2FE5DC5229EDD7FA004B9AB4 /* ExampleApplicationScheduler.swift in Sources */, @@ -605,6 +660,7 @@ 2F65B44E2A3B8B0600A36932 /* NotificationPermissions.swift in Sources */, 5661552E2AB854C000209B80 /* PackageHelper.swift in Sources */, 27FA29902A388E9B009CAC45 /* ModalView.swift in Sources */, + 97AA38892B61D971006627C6 /* LLMOpenAIFunctionWeather.swift in Sources */, 2FE5DC2629EDD38A004B9AB4 /* Contacts.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -704,6 +760,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = TEST; + SWIFT_OBJC_INTEROP_MODE = objcxx; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Test; @@ -852,6 +909,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OBJC_INTEROP_MODE = objcxx; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; @@ -908,6 +966,7 @@ MTL_FAST_MATH = YES; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OBJC_INTEROP_MODE = objcxx; SWIFT_OPTIMIZATION_LEVEL = "-O"; VALIDATE_PRODUCT = YES; }; @@ -1252,6 +1311,14 @@ minimumVersion = 3.0.10; }; }; + 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/StanfordSpezi/SpeziLLM"; + requirement = { + kind = upToNextMinorVersion; + minimumVersion = 0.6.1; + }; + }; 97F466E62A76BBEE005DC9B4 /* XCRemoteSwiftPackageReference "SpeziOnboarding" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/StanfordSpezi/SpeziOnboarding"; @@ -1382,6 +1449,26 @@ package = 2FE5DC9029EDD9C3004B9AB4 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseStorage; }; + 97CFE5C32B61D37800BEE444 /* SpeziLLM */ = { + isa = XCSwiftPackageProductDependency; + package = 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */; + productName = SpeziLLM; + }; + 97CFE5C52B61D37800BEE444 /* SpeziLLMLocal */ = { + isa = XCSwiftPackageProductDependency; + package = 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */; + productName = SpeziLLMLocal; + }; + 97CFE5C72B61D37800BEE444 /* SpeziLLMLocalDownload */ = { + isa = XCSwiftPackageProductDependency; + package = 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */; + productName = SpeziLLMLocalDownload; + }; + 97CFE5C92B61D37800BEE444 /* SpeziLLMOpenAI */ = { + isa = XCSwiftPackageProductDependency; + package = 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */; + productName = SpeziLLMOpenAI; + }; 97D73D692AD860AD00B47FA0 /* SpeziFirebaseStorage */ = { isa = XCSwiftPackageProductDependency; package = 2FE5DC7329EDD8E6004B9AB4 /* XCRemoteSwiftPackageReference "SpeziFirebase" */; diff --git a/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index c6a59ae..9d83d11 100644 --- a/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/app-check.git", "state" : { - "revision" : "5746b2d35c91c50581590ed97abe4c06b5037274", - "version" : "10.18.0" + "revision" : "3e464dad87dad2d29bb29a97836789bf0f8f67d2", + "version" : "10.18.1" } }, { @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/firebase-ios-sdk.git", "state" : { - "revision" : "c60c958e707c50a9cf8bcb7cfd7d51c566d726c5", - "version" : "10.19.1" + "revision" : "b880ec8ec927a838c51c12862c6222c30d7097d7", + "version" : "10.20.0" } }, { @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleAppMeasurement.git", "state" : { - "revision" : "6b332152355c372ace9966d8ee76ed191f97025e", - "version" : "10.17.0" + "revision" : "ceec9f28dea12b7cf3dabf18b5ed7621c88fd4aa", + "version" : "10.20.0" } }, { @@ -109,39 +109,39 @@ } }, { - "identity" : "nanopb", + "identity" : "llama.cpp", "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/nanopb.git", + "location" : "https://github.com/StanfordBDHG/llama.cpp", "state" : { - "revision" : "819d0a2173aff699fb8c364b6fb906f7cdb1a692", - "version" : "2.30909.0" + "revision" : "b0611c7d3cb049822f9911878514e4706b80e2ac", + "version" : "0.1.8" } }, { - "identity" : "promises", + "identity" : "nanopb", "kind" : "remoteSourceControl", - "location" : "https://github.com/google/promises.git", + "location" : "https://github.com/firebase/nanopb.git", "state" : { - "revision" : "e70e889c0196c76d22759eb50d6a0270ca9f1d9e", - "version" : "2.3.1" + "revision" : "819d0a2173aff699fb8c364b6fb906f7cdb1a692", + "version" : "2.30909.0" } }, { - "identity" : "researchkit", + "identity" : "openai", "kind" : "remoteSourceControl", - "location" : "https://github.com/StanfordBDHG/ResearchKit", + "location" : "https://github.com/MacPaw/OpenAI", "state" : { - "revision" : "cf79a15c7d8c436f98937fe93e72e880dd2f73e4", - "version" : "2.2.20" + "revision" : "ac5892fd0de8d283362ddc30f8e9f1a0eaba8cc0", + "version" : "0.2.5" } }, { - "identity" : "researchkitonfhir", + "identity" : "promises", "kind" : "remoteSourceControl", - "location" : "https://github.com/StanfordBDHG/ResearchKitOnFHIR", + "location" : "https://github.com/google/promises.git", "state" : { - "revision" : "7dc09f7acd7fb19673594e0fdd4d72d0869ee006", - "version" : "1.0.0" + "revision" : "e70e889c0196c76d22759eb50d6a0270ca9f1d9e", + "version" : "2.3.1" } }, { @@ -162,6 +162,15 @@ "version" : "1.1.0" } }, + { + "identity" : "spezichat", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordSpezi/SpeziChat", + "state" : { + "revision" : "9d45c10bcf859c98f2998ecd4f6a80f31894fe2c", + "version" : "0.1.4" + } + }, { "identity" : "spezicontact", "kind" : "remoteSourceControl", @@ -185,8 +194,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziFoundation.git", "state" : { - "revision" : "683c66f922a4cfe0882c4a86a43854f613b48541", - "version" : "1.0.0" + "revision" : "d1e6d4cddcf236038d21a73d671806d8ba51b01c", + "version" : "1.0.1" } }, { @@ -198,6 +207,15 @@ "version" : "0.5.0" } }, + { + "identity" : "spezillm", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordSpezi/SpeziLLM", + "state" : { + "revision" : "4e1e3e7ff5efc37dc63e603eb8fae048fcfadf91", + "version" : "0.6.1" + } + }, { "identity" : "spezimockwebservice", "kind" : "remoteSourceControl", @@ -212,26 +230,26 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziOnboarding", "state" : { - "revision" : "ae7b18a18453557cd95c7adeb8f75846f48c343c", - "version" : "1.0.0" + "revision" : "8fb6d9f1a080661c0cc564a93b82ead3c8d44d4f", + "version" : "1.0.2" } }, { - "identity" : "speziquestionnaire", + "identity" : "spezischeduler", "kind" : "remoteSourceControl", - "location" : "https://github.com/StanfordSpezi/SpeziQuestionnaire.git", + "location" : "https://github.com/StanfordSpezi/SpeziScheduler.git", "state" : { - "revision" : "930a4099db1aca9db0b6ed4e77687141c4780052", - "version" : "1.0.0" + "revision" : "adf793cb47dc199f8ae88f5c719f4d3ba06a4c4e", + "version" : "0.8.0" } }, { - "identity" : "spezischeduler", + "identity" : "spezispeech", "kind" : "remoteSourceControl", - "location" : "https://github.com/StanfordSpezi/SpeziScheduler.git", + "location" : "https://github.com/StanfordSpezi/SpeziSpeech", "state" : { - "revision" : "adf793cb47dc199f8ae88f5c719f4d3ba06a4c4e", - "version" : "0.8.0" + "revision" : "a1e1d021d8f605b5e6b23aee773115d7125a57e3", + "version" : "1.0.0" } }, { @@ -293,8 +311,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordBDHG/XCTestExtensions.git", "state" : { - "revision" : "388a6d6a5be48eff5d98a2c45e0b50f30ed21dc3", - "version" : "0.4.7" + "revision" : "fb7fcee97c574b950e03b0a53874e26db27db2fe", + "version" : "0.4.8" } }, { diff --git a/ExampleApplication/ExampleApplicationDelegate.swift b/ExampleApplication/ExampleApplicationDelegate.swift index be9503b..dd266c8 100644 --- a/ExampleApplication/ExampleApplicationDelegate.swift +++ b/ExampleApplication/ExampleApplicationDelegate.swift @@ -12,6 +12,9 @@ import SpeziFirebaseAccount import SpeziFirebaseStorage import SpeziFirestore import SpeziHealthKit +import SpeziLLM +import SpeziLLMLocal +import SpeziLLMOpenAI import SpeziMockWebService import SpeziOnboarding import SpeziScheduler @@ -55,6 +58,11 @@ class ExampleApplicationDelegate: SpeziAppDelegate { ExampleApplicationScheduler() OnboardingDataSource() + + LLMRunner { + LLMLocalRunnerSetupTask() + LLMOpenAIRunnerSetupTask() + } } } diff --git a/ExampleApplication/Home.swift b/ExampleApplication/Home.swift index 53b4762..042d66a 100644 --- a/ExampleApplication/Home.swift +++ b/ExampleApplication/Home.swift @@ -16,6 +16,7 @@ struct HomeView: View { case schedule case contact case mockUpload + case llmInteraction } static var accountEnabled: Bool { @@ -46,6 +47,11 @@ struct HomeView: View { Label("MOCK_WEB_SERVICE_TAB_TITLE", systemImage: "server.rack") } } + LLMInteraction(presentingAccount: $presentingAccount) + .tag(Tabs.llmInteraction) + .tabItem { + Label("LLM_INTERACTION_TAB_TITLE", systemImage: "captions.bubble.fill") + } } .sheet(isPresented: $presentingAccount) { AccountSheet() diff --git a/ExampleApplication/LLMInteraction/LLMInteraction.swift b/ExampleApplication/LLMInteraction/LLMInteraction.swift new file mode 100644 index 0000000..8044a79 --- /dev/null +++ b/ExampleApplication/LLMInteraction/LLMInteraction.swift @@ -0,0 +1,66 @@ +// +// This source file is part of the Stanford Spezi Template Application open-source project +// +// SPDX-FileCopyrightText: 2023 Stanford University +// +// SPDX-License-Identifier: MIT +// + +import SpeziLLM +import SpeziLLMLocal +import SpeziLLMOpenAI +import SwiftUI + + +struct LLMInteraction: View { + @Binding var presentingAccount: Bool + + @State var showOnboarding = true + + @State var openAIModel: LLM = LLMOpenAI( + parameters: .init( + modelType: .gpt4_1106_preview, + systemPrompt: "You're speaking in front of Stanford students, be as funny and ironic as possible." + ) + ) { + LLMOpenAIFunctionWeather() + } + + @State var localModel: LLM = LLMLocal( + modelPath: .cachesDirectory.appending(path: "llm.gguf"), + contextParameters: .init(contextWindowSize: 1024), + formatChat: LLMLocal.PromptFormattingDefaults.phi2 + ) + + var body: some View { + NavigationStack { + LLMChatView( + model: openAIModel + ) + .navigationTitle("LLM_CHAT_VIEW_TITLE") + .toolbar { + if AccountButton.shouldDisplay { + AccountButton(isPresented: $presentingAccount) + } + + if openAIModel.state == .generating { + ProgressView() + } + } + .sheet(isPresented: $showOnboarding) { + LLMOnboardingView(showOnboarding: $showOnboarding) + } + } + } +} + + +#Preview { + LLMInteraction(presentingAccount: .constant(true)) + .previewWith { + LLMRunner { + LLMLocalRunnerSetupTask() + LLMOpenAIRunnerSetupTask() + } + } +} diff --git a/ExampleApplication/LLMInteraction/LLMOnboardingView.swift b/ExampleApplication/LLMInteraction/LLMOnboardingView.swift new file mode 100644 index 0000000..5a0e2b0 --- /dev/null +++ b/ExampleApplication/LLMInteraction/LLMOnboardingView.swift @@ -0,0 +1,28 @@ +// +// This source file is part of the Stanford Spezi open source project +// +// SPDX-FileCopyrightText: 2022 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import SpeziLLMOpenAI +import SpeziOnboarding +import SwiftUI + + +struct LLMOnboardingView: View { + @Binding var showOnboarding: Bool + + + var body: some View { + OnboardingStack(onboardingFlowComplete: !$showOnboarding) { + // OpenAI Onboarding + LLMOpenAITokenOnboarding() + + // Local Onboarding + // LLMLocalDownloadOnboarding() + } + .interactiveDismissDisabled(showOnboarding) + } +} diff --git a/ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift b/ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift new file mode 100644 index 0000000..bfc0f74 --- /dev/null +++ b/ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift @@ -0,0 +1,34 @@ +// +// This source file is part of the Stanford Spezi open source project +// +// SPDX-FileCopyrightText: 2022 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import SpeziLLMLocalDownload +import SpeziOnboarding +import SpeziViews +import SwiftUI + + +struct LLMLocalDownloadOnboarding: View { + @Environment(OnboardingNavigationPath.self) private var onboardingNavigationPath + + + var body: some View { + LLMLocalDownloadView( + llmDownloadUrl: LLMLocalDownloadManager.LLMUrlDefaults.phi2ModelUrl, + llmStorageUrl: .cachesDirectory.appending(path: "llm.gguf") + ) { + onboardingNavigationPath.nextStep() + } + } +} + + +#Preview { + OnboardingStack { + LLMLocalDownloadOnboarding() + } +} diff --git a/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift b/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift new file mode 100644 index 0000000..32ab3fb --- /dev/null +++ b/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift @@ -0,0 +1,34 @@ +// +// This source file is part of the Stanford Spezi open source project +// +// SPDX-FileCopyrightText: 2022 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import SpeziLLMOpenAI + + +struct LLMOpenAIFunctionWeather: LLMFunction { + enum TemperatureUnit: String, LLMFunctionParameterEnum { + case celsius + case fahrenheit + } + + + static let name: String = "get_current_weather" + static let description: String = "Get the current weather in a given location" + + + // swiftlint:disable attributes + @Parameter(description: "The city and state of the to be determined weather, e.g. San Francisco, CA") + var location: String + @Parameter(description: "The unit of the temperature") + var unit: TemperatureUnit + // swiftlint:enable attributes + + + func execute() async throws -> String? { + "The weather at \(location) is 30 degrees \(unit)" + } +} diff --git a/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAITokenOnboarding.swift b/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAITokenOnboarding.swift new file mode 100644 index 0000000..737b1c1 --- /dev/null +++ b/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAITokenOnboarding.swift @@ -0,0 +1,30 @@ +// +// This source file is part of the Stanford Spezi open source project +// +// SPDX-FileCopyrightText: 2022 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import SpeziLLMOpenAI +import SpeziOnboarding +import SwiftUI + + +struct LLMOpenAITokenOnboarding: View { + @Environment(OnboardingNavigationPath.self) private var onboardingNavigationPath + + + var body: some View { + LLMOpenAIAPITokenOnboardingStep { + onboardingNavigationPath.nextStep() + } + } +} + + +#Preview { + OnboardingStack { + LLMOpenAITokenOnboarding() + } +} diff --git a/ExampleApplication/Resources/Localizable.xcstrings b/ExampleApplication/Resources/Localizable.xcstrings index 09a9a1d..2c6bdbb 100644 --- a/ExampleApplication/Resources/Localizable.xcstrings +++ b/ExampleApplication/Resources/Localizable.xcstrings @@ -306,6 +306,26 @@ } } }, + "LLM_CHAT_VIEW_TITLE" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "LLM Chat" + } + } + } + }, + "LLM_INTERACTION_TAB_TITLE" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "LLM Interaction" + } + } + } + }, "MOCK_WEB_SERVICE_TAB_TITLE" : { "comment" : "MARK: - Mock Upload Data Storage Provider", "localizations" : { From 5ff9e7abaa289454a9302704b2917004e9e6c44d Mon Sep 17 00:00:00 2001 From: Philipp Zagar Date: Thu, 25 Jan 2024 14:43:41 -0800 Subject: [PATCH 2/7] Update dependencies --- ExampleApplication.xcodeproj/project.pbxproj | 105 +++++++++--------- .../xcshareddata/swiftpm/Package.resolved | 27 +++++ .../Supporting Files/Info.plist | 4 +- 3 files changed, 82 insertions(+), 54 deletions(-) diff --git a/ExampleApplication.xcodeproj/project.pbxproj b/ExampleApplication.xcodeproj/project.pbxproj index 15a69f5..2bcd4e9 100644 --- a/ExampleApplication.xcodeproj/project.pbxproj +++ b/ExampleApplication.xcodeproj/project.pbxproj @@ -69,15 +69,15 @@ 653A256228338800005D4D48 /* ExampleApplicationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653A256128338800005D4D48 /* ExampleApplicationTests.swift */; }; 9733CFC62A8066DE001B7ABC /* SpeziOnboarding in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC8029EDD91D004B9AB4 /* SpeziOnboarding */; }; 9739A0C62AD7B5730084BEA5 /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 9739A0C52AD7B5730084BEA5 /* FirebaseStorage */; }; - 97AA38842B61D81A006627C6 /* LLMLocalDownloadOnboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97AA38832B61D81A006627C6 /* LLMLocalDownloadOnboarding.swift */; }; - 97AA38892B61D971006627C6 /* LLMOpenAIFunctionWeather.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97AA38882B61D971006627C6 /* LLMOpenAIFunctionWeather.swift */; }; - 97CFE5BF2B61D31C00BEE444 /* LLMOpenAITokenOnboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CFE5BC2B61D31C00BEE444 /* LLMOpenAITokenOnboarding.swift */; }; - 97CFE5C02B61D31C00BEE444 /* LLMOnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CFE5BD2B61D31C00BEE444 /* LLMOnboardingView.swift */; }; - 97CFE5C12B61D31C00BEE444 /* LLMInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CFE5BE2B61D31C00BEE444 /* LLMInteraction.swift */; }; - 97CFE5C42B61D37800BEE444 /* SpeziLLM in Frameworks */ = {isa = PBXBuildFile; productRef = 97CFE5C32B61D37800BEE444 /* SpeziLLM */; }; - 97CFE5C62B61D37800BEE444 /* SpeziLLMLocal in Frameworks */ = {isa = PBXBuildFile; productRef = 97CFE5C52B61D37800BEE444 /* SpeziLLMLocal */; }; - 97CFE5C82B61D37800BEE444 /* SpeziLLMLocalDownload in Frameworks */ = {isa = PBXBuildFile; productRef = 97CFE5C72B61D37800BEE444 /* SpeziLLMLocalDownload */; }; - 97CFE5CA2B61D37800BEE444 /* SpeziLLMOpenAI in Frameworks */ = {isa = PBXBuildFile; productRef = 97CFE5C92B61D37800BEE444 /* SpeziLLMOpenAI */; }; + 975AF9212B63177500CB02A2 /* SpeziLLM in Frameworks */ = {isa = PBXBuildFile; productRef = 975AF9202B63177500CB02A2 /* SpeziLLM */; }; + 975AF9232B63177500CB02A2 /* SpeziLLMLocal in Frameworks */ = {isa = PBXBuildFile; productRef = 975AF9222B63177500CB02A2 /* SpeziLLMLocal */; }; + 975AF9252B63177500CB02A2 /* SpeziLLMLocalDownload in Frameworks */ = {isa = PBXBuildFile; productRef = 975AF9242B63177500CB02A2 /* SpeziLLMLocalDownload */; }; + 975AF9272B63177500CB02A2 /* SpeziLLMOpenAI in Frameworks */ = {isa = PBXBuildFile; productRef = 975AF9262B63177500CB02A2 /* SpeziLLMOpenAI */; }; + 979EC7732B631A1800B63213 /* LLMInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979EC76C2B631A1800B63213 /* LLMInteraction.swift */; }; + 979EC7742B631A1800B63213 /* LLMLocalDownloadOnboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979EC76E2B631A1800B63213 /* LLMLocalDownloadOnboarding.swift */; }; + 979EC7752B631A1800B63213 /* LLMOpenAIFunctionWeather.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979EC7702B631A1800B63213 /* LLMOpenAIFunctionWeather.swift */; }; + 979EC7762B631A1800B63213 /* LLMOpenAITokenOnboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979EC7712B631A1800B63213 /* LLMOpenAITokenOnboarding.swift */; }; + 979EC7772B631A1800B63213 /* LLMOnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979EC7722B631A1800B63213 /* LLMOnboardingView.swift */; }; 97D73D6A2AD860AD00B47FA0 /* SpeziFirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 97D73D692AD860AD00B47FA0 /* SpeziFirebaseStorage */; }; A9720E432ABB68CC00872D23 /* AccountSetupHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9720E422ABB68CC00872D23 /* AccountSetupHeader.swift */; }; A9D83F962B083794000D0C78 /* SpeziFirebaseAccountStorage in Frameworks */ = {isa = PBXBuildFile; productRef = A9D83F952B083794000D0C78 /* SpeziFirebaseAccountStorage */; }; @@ -148,11 +148,11 @@ 653A256128338800005D4D48 /* ExampleApplicationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleApplicationTests.swift; sourceTree = ""; }; 653A256728338800005D4D48 /* ExampleApplicationUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleApplicationUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 653A258928339462005D4D48 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 97AA38832B61D81A006627C6 /* LLMLocalDownloadOnboarding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LLMLocalDownloadOnboarding.swift; sourceTree = ""; }; - 97AA38882B61D971006627C6 /* LLMOpenAIFunctionWeather.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LLMOpenAIFunctionWeather.swift; sourceTree = ""; }; - 97CFE5BC2B61D31C00BEE444 /* LLMOpenAITokenOnboarding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMOpenAITokenOnboarding.swift; sourceTree = ""; }; - 97CFE5BD2B61D31C00BEE444 /* LLMOnboardingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMOnboardingView.swift; sourceTree = ""; }; - 97CFE5BE2B61D31C00BEE444 /* LLMInteraction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMInteraction.swift; sourceTree = ""; }; + 979EC76C2B631A1800B63213 /* LLMInteraction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMInteraction.swift; sourceTree = ""; }; + 979EC76E2B631A1800B63213 /* LLMLocalDownloadOnboarding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMLocalDownloadOnboarding.swift; sourceTree = ""; }; + 979EC7702B631A1800B63213 /* LLMOpenAIFunctionWeather.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMOpenAIFunctionWeather.swift; sourceTree = ""; }; + 979EC7712B631A1800B63213 /* LLMOpenAITokenOnboarding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMOpenAITokenOnboarding.swift; sourceTree = ""; }; + 979EC7722B631A1800B63213 /* LLMOnboardingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMOnboardingView.swift; sourceTree = ""; }; A9720E422ABB68CC00872D23 /* AccountSetupHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSetupHeader.swift; sourceTree = ""; }; A9DFE8A82ABE551400428242 /* AccountButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountButton.swift; sourceTree = ""; }; A9FE7ACF2AA39BAB0077B045 /* AccountSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSheet.swift; sourceTree = ""; }; @@ -163,19 +163,20 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 97CFE5C62B61D37800BEE444 /* SpeziLLMLocal in Frameworks */, + 975AF9212B63177500CB02A2 /* SpeziLLM in Frameworks */, 9733CFC62A8066DE001B7ABC /* SpeziOnboarding in Frameworks */, 2FE5DC6429EDD883004B9AB4 /* SpeziAccount in Frameworks */, + 975AF9232B63177500CB02A2 /* SpeziLLMLocal in Frameworks */, 2FB099AF2A875DF100B20952 /* FirebaseAuth in Frameworks */, - 97CFE5CA2B61D37800BEE444 /* SpeziLLMOpenAI in Frameworks */, 97D73D6A2AD860AD00B47FA0 /* SpeziFirebaseStorage in Frameworks */, + 975AF9272B63177500CB02A2 /* SpeziLLMOpenAI in Frameworks */, 2FE5DC6729EDD894004B9AB4 /* SpeziContact in Frameworks */, - 2FE5DC8429EDD934004B9AB4 /* SpeziQuestionnaire in Frameworks */, + 2FE5DC8429EDD934004B9AB4 /* SpeziQuestionnaire in Frameworks */, 2FB099B32A875DF100B20952 /* FirebaseFirestoreSwift in Frameworks */, - 97CFE5C42B61D37800BEE444 /* SpeziLLM in Frameworks */, 5661551D2AB8384200209B80 /* SwiftPackageList in Frameworks */, 2FB099B12A875DF100B20952 /* FirebaseFirestore in Frameworks */, A9D83F962B083794000D0C78 /* SpeziFirebaseAccountStorage in Frameworks */, + 975AF9252B63177500CB02A2 /* SpeziLLMLocalDownload in Frameworks */, 2FB099B62A875E2B00B20952 /* HealthKitOnFHIR in Frameworks */, 2FE5DC8A29EDD972004B9AB4 /* SpeziLocalStorage in Frameworks */, 2FE5DC8C29EDD972004B9AB4 /* SpeziSecureStorage in Frameworks */, @@ -184,7 +185,6 @@ 2FF53D8B2A8725DE00042B76 /* SpeziMockWebService in Frameworks */, 2FE5DC7229EDD8D3004B9AB4 /* SpeziHealthKit in Frameworks */, 2F49B7762980407C00BCB272 /* Spezi in Frameworks */, - 97CFE5C82B61D37800BEE444 /* SpeziLLMLocalDownload in Frameworks */, 2FE5DC8F29EDD980004B9AB4 /* SpeziViews in Frameworks */, 2F3D4ABC2A4E7C290068FB2F /* SpeziScheduler in Frameworks */, 2FBD738C2A3BD150004228E7 /* SpeziScheduler in Frameworks */, @@ -339,6 +339,7 @@ 2FF53D8C2A8729D600042B76 /* ExampleApplicationStandard.swift */, 2F4E23822989D51F0013F3D9 /* ExampleApplicationTestingSetup.swift */, 2FC975A72978F11A00BA99FE /* Home.swift */, + 979EC76B2B631A1800B63213 /* LLMInteraction */, A9720E412ABB68B300872D23 /* Account */, 2FE5DC2829EDD398004B9AB4 /* Onboarding */, 2FE5DC3B29EDD7D0004B9AB4 /* Schedule */, @@ -376,32 +377,32 @@ name = Frameworks; sourceTree = ""; }; - 97AA38852B61D927006627C6 /* Local */ = { + 979EC76B2B631A1800B63213 /* LLMInteraction */ = { isa = PBXGroup; children = ( - 97AA38832B61D81A006627C6 /* LLMLocalDownloadOnboarding.swift */, + 979EC76D2B631A1800B63213 /* Local */, + 979EC76F2B631A1800B63213 /* OpenAI */, + 979EC7722B631A1800B63213 /* LLMOnboardingView.swift */, + 979EC76C2B631A1800B63213 /* LLMInteraction.swift */, ); - path = Local; + path = LLMInteraction; sourceTree = ""; }; - 97AA38862B61D92D006627C6 /* OpenAI */ = { + 979EC76D2B631A1800B63213 /* Local */ = { isa = PBXGroup; children = ( - 97CFE5BC2B61D31C00BEE444 /* LLMOpenAITokenOnboarding.swift */, - 97AA38882B61D971006627C6 /* LLMOpenAIFunctionWeather.swift */, + 979EC76E2B631A1800B63213 /* LLMLocalDownloadOnboarding.swift */, ); - path = OpenAI; + path = Local; sourceTree = ""; }; - 97CFE5B72B61D2E900BEE444 /* LLMInteraction */ = { + 979EC76F2B631A1800B63213 /* OpenAI */ = { isa = PBXGroup; children = ( - 97AA38852B61D927006627C6 /* Local */, - 97AA38862B61D92D006627C6 /* OpenAI */, - 97CFE5BD2B61D31C00BEE444 /* LLMOnboardingView.swift */, - 97CFE5BE2B61D31C00BEE444 /* LLMInteraction.swift */, + 979EC7702B631A1800B63213 /* LLMOpenAIFunctionWeather.swift */, + 979EC7712B631A1800B63213 /* LLMOpenAITokenOnboarding.swift */, ); - path = LLMInteraction; + path = OpenAI; sourceTree = ""; }; A9720E412ABB68B300872D23 /* Account */ = { @@ -456,10 +457,10 @@ 9739A0C52AD7B5730084BEA5 /* FirebaseStorage */, 97D73D692AD860AD00B47FA0 /* SpeziFirebaseStorage */, A9D83F952B083794000D0C78 /* SpeziFirebaseAccountStorage */, - 97CFE5C32B61D37800BEE444 /* SpeziLLM */, - 97CFE5C52B61D37800BEE444 /* SpeziLLMLocal */, - 97CFE5C72B61D37800BEE444 /* SpeziLLMLocalDownload */, - 97CFE5C92B61D37800BEE444 /* SpeziLLMOpenAI */, + 975AF9202B63177500CB02A2 /* SpeziLLM */, + 975AF9222B63177500CB02A2 /* SpeziLLMLocal */, + 975AF9242B63177500CB02A2 /* SpeziLLMLocalDownload */, + 975AF9262B63177500CB02A2 /* SpeziLLMOpenAI */, ); productName = ExampleApplication; productReference = 653A254D283387FE005D4D48 /* ExampleApplication.app */; @@ -554,7 +555,7 @@ 2FE750CA2A87240100723EAE /* XCRemoteSwiftPackageReference "SpeziMockWebService" */, 2FB099B42A875E2B00B20952 /* XCRemoteSwiftPackageReference "HealthKitOnFHIR" */, 5661551B2AB8384200209B80 /* XCRemoteSwiftPackageReference "swift-package-list" */, - 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */, + 975AF91F2B63177400CB02A2 /* XCRemoteSwiftPackageReference "SpeziLLM" */, ); productRefGroup = 653A254E283387FE005D4D48 /* Products */; projectDirPath = ""; @@ -627,30 +628,31 @@ 2FE5DCB129EE6107004B9AB4 /* AccountOnboarding.swift in Sources */, 2F4FC8D729EE69D300BFFE26 /* MockUpload.swift in Sources */, 2FE5DC3A29EDD7CA004B9AB4 /* Welcome.swift in Sources */, + 979EC7732B631A1800B63213 /* LLMInteraction.swift in Sources */, 2FE5DC3829EDD7CA004B9AB4 /* InterestingModules.swift in Sources */, + 979EC7772B631A1800B63213 /* LLMOnboardingView.swift in Sources */, + 979EC7752B631A1800B63213 /* LLMOpenAIFunctionWeather.swift in Sources */, 2FE5DC3529EDD7CA004B9AB4 /* Consent.swift in Sources */, - 97CFE5BF2B61D31C00BEE444 /* LLMOpenAITokenOnboarding.swift in Sources */, 2FE5DC4529EDD7F2004B9AB4 /* Binding+Negate.swift in Sources */, 2FC975A82978F11A00BA99FE /* Home.swift in Sources */, 2FE5DC4E29EDD7FA004B9AB4 /* ScheduleView.swift in Sources */, A9DFE8A92ABE551400428242 /* AccountButton.swift in Sources */, 2FE5DC3729EDD7CA004B9AB4 /* OnboardingFlow.swift in Sources */, + 979EC7742B631A1800B63213 /* LLMLocalDownloadOnboarding.swift in Sources */, 2F1AC9DF2B4E840E00C24973 /* ExampleApplication.docc in Sources */, - 97AA38842B61D81A006627C6 /* LLMLocalDownloadOnboarding.swift in Sources */, 2FF53D8D2A8729D600042B76 /* ExampleApplicationStandard.swift in Sources */, 2FE5DC4729EDD7F2004B9AB4 /* CodableArray+RawRepresentable.swift in Sources */, A9720E432ABB68CC00872D23 /* AccountSetupHeader.swift in Sources */, - 97CFE5C12B61D31C00BEE444 /* LLMInteraction.swift in Sources */, + 979EC7762B631A1800B63213 /* LLMOpenAITokenOnboarding.swift in Sources */, 2FE5DC4029EDD7EE004B9AB4 /* FeatureFlags.swift in Sources */, 2FE5DC4629EDD7F2004B9AB4 /* Bundle+Image.swift in Sources */, 2FE5DC4F29EDD7FA004B9AB4 /* EventContext.swift in Sources */, 2FE5DC5029EDD7FA004B9AB4 /* EventContextView.swift in Sources */, 2F4E23832989D51F0013F3D9 /* ExampleApplicationTestingSetup.swift in Sources */, - 2FE5DC5329EDD7FA004B9AB4 /* Bundle+Questionnaire.swift in Sources */, + 2FE5DC5329EDD7FA004B9AB4 /* Bundle+Questionnaire.swift in Sources */, 2FE5DC5129EDD7FA004B9AB4 /* ExampleApplicationTaskContext.swift in Sources */, 56F6F2A02AB441930022FE5A /* ContributionsList.swift in Sources */, 566155292AB8447C00209B80 /* Package+LicenseType.swift in Sources */, - 97CFE5C02B61D31C00BEE444 /* LLMOnboardingView.swift in Sources */, 5680DD392AB8983D004E6D4A /* PackageCell.swift in Sources */, 2F5E32BD297E05EA003432F8 /* ExampleApplicationDelegate.swift in Sources */, 2FE5DC5229EDD7FA004B9AB4 /* ExampleApplicationScheduler.swift in Sources */, @@ -660,7 +662,6 @@ 2F65B44E2A3B8B0600A36932 /* NotificationPermissions.swift in Sources */, 5661552E2AB854C000209B80 /* PackageHelper.swift in Sources */, 27FA29902A388E9B009CAC45 /* ModalView.swift in Sources */, - 97AA38892B61D971006627C6 /* LLMOpenAIFunctionWeather.swift in Sources */, 2FE5DC2629EDD38A004B9AB4 /* Contacts.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1311,7 +1312,7 @@ minimumVersion = 3.0.10; }; }; - 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */ = { + 975AF91F2B63177400CB02A2 /* XCRemoteSwiftPackageReference "SpeziLLM" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/StanfordSpezi/SpeziLLM"; requirement = { @@ -1449,24 +1450,24 @@ package = 2FE5DC9029EDD9C3004B9AB4 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseStorage; }; - 97CFE5C32B61D37800BEE444 /* SpeziLLM */ = { + 975AF9202B63177500CB02A2 /* SpeziLLM */ = { isa = XCSwiftPackageProductDependency; - package = 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */; + package = 975AF91F2B63177400CB02A2 /* XCRemoteSwiftPackageReference "SpeziLLM" */; productName = SpeziLLM; }; - 97CFE5C52B61D37800BEE444 /* SpeziLLMLocal */ = { + 975AF9222B63177500CB02A2 /* SpeziLLMLocal */ = { isa = XCSwiftPackageProductDependency; - package = 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */; + package = 975AF91F2B63177400CB02A2 /* XCRemoteSwiftPackageReference "SpeziLLM" */; productName = SpeziLLMLocal; }; - 97CFE5C72B61D37800BEE444 /* SpeziLLMLocalDownload */ = { + 975AF9242B63177500CB02A2 /* SpeziLLMLocalDownload */ = { isa = XCSwiftPackageProductDependency; - package = 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */; + package = 975AF91F2B63177400CB02A2 /* XCRemoteSwiftPackageReference "SpeziLLM" */; productName = SpeziLLMLocalDownload; }; - 97CFE5C92B61D37800BEE444 /* SpeziLLMOpenAI */ = { + 975AF9262B63177500CB02A2 /* SpeziLLMOpenAI */ = { isa = XCSwiftPackageProductDependency; - package = 97CFE5C22B61D37700BEE444 /* XCRemoteSwiftPackageReference "SpeziLLM" */; + package = 975AF91F2B63177400CB02A2 /* XCRemoteSwiftPackageReference "SpeziLLM" */; productName = SpeziLLMOpenAI; }; 97D73D692AD860AD00B47FA0 /* SpeziFirebaseStorage */ = { diff --git a/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9d83d11..8ff0e60 100644 --- a/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -144,6 +144,24 @@ "version" : "2.3.1" } }, + { + "identity" : "researchkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordBDHG/ResearchKit", + "state" : { + "revision" : "209164ed20592a2213c4bd69cefcb078d9de0692", + "version" : "2.2.21" + } + }, + { + "identity" : "researchkitonfhir", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordBDHG/ResearchKitOnFHIR", + "state" : { + "revision" : "ea4d9691591594177e7dfbc8c246324855d73eb5", + "version" : "1.0.1" + } + }, { "identity" : "spezi", "kind" : "remoteSourceControl", @@ -234,6 +252,15 @@ "version" : "1.0.2" } }, + { + "identity" : "speziquestionnaire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordSpezi/SpeziQuestionnaire.git", + "state" : { + "revision" : "fac0bb02f7027b4c09bd7afdad55eb7b47ec67f3", + "version" : "1.0.1" + } + }, { "identity" : "spezischeduler", "kind" : "remoteSourceControl", diff --git a/ExampleApplication/Supporting Files/Info.plist b/ExampleApplication/Supporting Files/Info.plist index 5dc3321..8541b3e 100644 --- a/ExampleApplication/Supporting Files/Info.plist +++ b/ExampleApplication/Supporting Files/Info.plist @@ -2,6 +2,8 @@ + CFBundleAllowMixedLocalizations + ITSAppUsesNonExemptEncryption UIApplicationSceneManifest @@ -11,7 +13,5 @@ UISceneConfigurations - CFBundleAllowMixedLocalizations - From af7f4f3edb621ba840cdf1830650a4cfd711977c Mon Sep 17 00:00:00 2001 From: Philipp Zagar Date: Thu, 25 Jan 2024 14:51:10 -0800 Subject: [PATCH 3/7] Doc improvements --- ExampleApplication/LLMInteraction/LLMInteraction.swift | 3 +++ ExampleApplication/LLMInteraction/LLMOnboardingView.swift | 1 + .../LLMInteraction/Local/LLMLocalDownloadOnboarding.swift | 1 + .../LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift | 1 + .../LLMInteraction/OpenAI/LLMOpenAITokenOnboarding.swift | 1 + 5 files changed, 7 insertions(+) diff --git a/ExampleApplication/LLMInteraction/LLMInteraction.swift b/ExampleApplication/LLMInteraction/LLMInteraction.swift index 8044a79..a0c083b 100644 --- a/ExampleApplication/LLMInteraction/LLMInteraction.swift +++ b/ExampleApplication/LLMInteraction/LLMInteraction.swift @@ -12,11 +12,13 @@ import SpeziLLMOpenAI import SwiftUI +/// Showcases a minimal demo of SpeziLLM struct LLMInteraction: View { @Binding var presentingAccount: Bool @State var showOnboarding = true + /// OpenAI model @State var openAIModel: LLM = LLMOpenAI( parameters: .init( modelType: .gpt4_1106_preview, @@ -26,6 +28,7 @@ struct LLMInteraction: View { LLMOpenAIFunctionWeather() } + /// Local Phi-2 model @State var localModel: LLM = LLMLocal( modelPath: .cachesDirectory.appending(path: "llm.gguf"), contextParameters: .init(contextWindowSize: 1024), diff --git a/ExampleApplication/LLMInteraction/LLMOnboardingView.swift b/ExampleApplication/LLMInteraction/LLMOnboardingView.swift index 5a0e2b0..b446a96 100644 --- a/ExampleApplication/LLMInteraction/LLMOnboardingView.swift +++ b/ExampleApplication/LLMInteraction/LLMOnboardingView.swift @@ -11,6 +11,7 @@ import SpeziOnboarding import SwiftUI +/// Provide an onboarding flow for the LLM demo in ``LLMInteraction``. struct LLMOnboardingView: View { @Binding var showOnboarding: Bool diff --git a/ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift b/ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift index bfc0f74..c8f348e 100644 --- a/ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift +++ b/ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift @@ -12,6 +12,7 @@ import SpeziViews import SwiftUI +/// Onboarding view that downloads a model to the local device. struct LLMLocalDownloadOnboarding: View { @Environment(OnboardingNavigationPath.self) private var onboardingNavigationPath diff --git a/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift b/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift index 32ab3fb..a75599b 100644 --- a/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift +++ b/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift @@ -9,6 +9,7 @@ import SpeziLLMOpenAI +/// OpenAI Function that enables the LLM to fetch the current weather. struct LLMOpenAIFunctionWeather: LLMFunction { enum TemperatureUnit: String, LLMFunctionParameterEnum { case celsius diff --git a/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAITokenOnboarding.swift b/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAITokenOnboarding.swift index 737b1c1..96b217b 100644 --- a/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAITokenOnboarding.swift +++ b/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAITokenOnboarding.swift @@ -11,6 +11,7 @@ import SpeziOnboarding import SwiftUI +/// Onboarding view that gets the OpenAI token from the user. struct LLMOpenAITokenOnboarding: View { @Environment(OnboardingNavigationPath.self) private var onboardingNavigationPath From 2fdf6d37a9d438ea7ca9db1d189e5b88fcc8b293 Mon Sep 17 00:00:00 2001 From: Philipp Zagar Date: Thu, 25 Jan 2024 15:14:24 -0800 Subject: [PATCH 4/7] Use the Llama2 model for demo --- ExampleApplication/LLMInteraction/LLMInteraction.swift | 5 ++--- .../LLMInteraction/Local/LLMLocalDownloadOnboarding.swift | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ExampleApplication/LLMInteraction/LLMInteraction.swift b/ExampleApplication/LLMInteraction/LLMInteraction.swift index a0c083b..caaca6e 100644 --- a/ExampleApplication/LLMInteraction/LLMInteraction.swift +++ b/ExampleApplication/LLMInteraction/LLMInteraction.swift @@ -28,11 +28,10 @@ struct LLMInteraction: View { LLMOpenAIFunctionWeather() } - /// Local Phi-2 model + /// Local Llama2 model @State var localModel: LLM = LLMLocal( modelPath: .cachesDirectory.appending(path: "llm.gguf"), - contextParameters: .init(contextWindowSize: 1024), - formatChat: LLMLocal.PromptFormattingDefaults.phi2 + contextParameters: .init(contextWindowSize: 1024) ) var body: some View { diff --git a/ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift b/ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift index c8f348e..5508d25 100644 --- a/ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift +++ b/ExampleApplication/LLMInteraction/Local/LLMLocalDownloadOnboarding.swift @@ -19,7 +19,7 @@ struct LLMLocalDownloadOnboarding: View { var body: some View { LLMLocalDownloadView( - llmDownloadUrl: LLMLocalDownloadManager.LLMUrlDefaults.phi2ModelUrl, + llmDownloadUrl: LLMLocalDownloadManager.LLMUrlDefaults.llama2ChatModelUrl, llmStorageUrl: .cachesDirectory.appending(path: "llm.gguf") ) { onboardingNavigationPath.nextStep() From d30e3622e62eef3165a87e270c530a28a44afcb1 Mon Sep 17 00:00:00 2001 From: Philipp Zagar Date: Thu, 25 Jan 2024 16:05:39 -0800 Subject: [PATCH 5/7] Incorporate feedback --- .swiftlint.yml | 3 --- .../LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift | 6 ++---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 2c9b00a..0b264bc 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -369,9 +369,6 @@ only_rules: # The variable should be placed on the left, the constant on the right of a comparison operator. - yoda_condition -attributes: - attributes_with_arguments_always_on_line_above: false - deployment_target: # Availability checks or attributes shouldn’t be using older versions that are satisfied by the deployment target. iOSApplicationExtension_deployment_target: 16.0 iOS_deployment_target: 16.0 diff --git a/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift b/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift index a75599b..1783bca 100644 --- a/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift +++ b/ExampleApplication/LLMInteraction/OpenAI/LLMOpenAIFunctionWeather.swift @@ -21,15 +21,13 @@ struct LLMOpenAIFunctionWeather: LLMFunction { static let description: String = "Get the current weather in a given location" - // swiftlint:disable attributes @Parameter(description: "The city and state of the to be determined weather, e.g. San Francisco, CA") var location: String @Parameter(description: "The unit of the temperature") - var unit: TemperatureUnit - // swiftlint:enable attributes + var unit: TemperatureUnit? func execute() async throws -> String? { - "The weather at \(location) is 30 degrees \(unit)" + "The weather at \(location) is 30 degrees \(unit?.rawValue ?? "celsius")" } } From 0f15deeac066eb8ab712b5240c5ebb234dc9b1bc Mon Sep 17 00:00:00 2001 From: Philipp Zagar Date: Thu, 25 Jan 2024 16:06:24 -0800 Subject: [PATCH 6/7] Fix linter --- .swiftlint.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 0b264bc..a2a12a0 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -10,8 +10,6 @@ only_rules: # All Images that provide context should have an accessibility label. Purely decorative images can be hidden from accessibility. - accessibility_label_for_image - # Attributes should be on their own lines in functions and types, but on the same line as variables and imports. - - attributes # Prefer using Array(seq) over seq.map { $0 } to convert a sequence into an Array. - array_init # Prefer the new block based KVO API with keypaths when using Swift 3.2 or later. From 20536acb61b441aef96cded4c823e357d51bcd4d Mon Sep 17 00:00:00 2001 From: Philipp Zagar Date: Thu, 25 Jan 2024 16:16:45 -0800 Subject: [PATCH 7/7] Update dependency --- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 8ff0e60..be92578 100644 --- a/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ExampleApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -230,7 +230,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/StanfordSpezi/SpeziLLM", "state" : { - "revision" : "4e1e3e7ff5efc37dc63e603eb8fae048fcfadf91", + "revision" : "94c1f3bd3eb9412e3321a46730c1572da11bd951", "version" : "0.6.1" } },