From 2d17673b6b88d181cfb7c40cd4ef73696ce38b42 Mon Sep 17 00:00:00 2001 From: Kevin Hermawan <84965338+kevinhermawan@users.noreply.github.com> Date: Sun, 9 Jun 2024 05:11:31 +0700 Subject: [PATCH] chore: adds Playground (#28) --- .../OKPlayground.xcodeproj/project.pbxproj | 429 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/swiftpm/Package.resolved | 23 + Playground/OKPlayground/OKPlaygroundApp.swift | 20 + .../Preview Assets.xcassets/Contents.json | 6 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 13 + .../Resources/Assets.xcassets/Contents.json | 6 + .../OKPlayground/ViewModels/ViewModel.swift | 28 ++ Playground/OKPlayground/Views/AppView.swift | 63 +++ Playground/OKPlayground/Views/ChatView.swift | 85 ++++ .../OKPlayground/Views/CopyModelView.swift | 73 +++ .../OKPlayground/Views/DeleteModelView.swift | 73 +++ .../OKPlayground/Views/EmbeddingsView.swift | 84 ++++ .../OKPlayground/Views/GenerateView.swift | 83 ++++ .../OKPlayground/Views/ModelInfoView.swift | 95 ++++ .../OKPlayground/Views/ModelListView.swift | 18 + 18 files changed, 1125 insertions(+) create mode 100644 Playground/OKPlayground.xcodeproj/project.pbxproj create mode 100644 Playground/OKPlayground.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 Playground/OKPlayground.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Playground/OKPlayground.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 Playground/OKPlayground/OKPlaygroundApp.swift create mode 100644 Playground/OKPlayground/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 Playground/OKPlayground/Resources/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 Playground/OKPlayground/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Playground/OKPlayground/Resources/Assets.xcassets/Contents.json create mode 100644 Playground/OKPlayground/ViewModels/ViewModel.swift create mode 100644 Playground/OKPlayground/Views/AppView.swift create mode 100644 Playground/OKPlayground/Views/ChatView.swift create mode 100644 Playground/OKPlayground/Views/CopyModelView.swift create mode 100644 Playground/OKPlayground/Views/DeleteModelView.swift create mode 100644 Playground/OKPlayground/Views/EmbeddingsView.swift create mode 100644 Playground/OKPlayground/Views/GenerateView.swift create mode 100644 Playground/OKPlayground/Views/ModelInfoView.swift create mode 100644 Playground/OKPlayground/Views/ModelListView.swift diff --git a/Playground/OKPlayground.xcodeproj/project.pbxproj b/Playground/OKPlayground.xcodeproj/project.pbxproj new file mode 100644 index 0000000..e9ae3e8 --- /dev/null +++ b/Playground/OKPlayground.xcodeproj/project.pbxproj @@ -0,0 +1,429 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 0A5648C42C1468E0008FB5F6 /* OKPlaygroundApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5648C32C1468E0008FB5F6 /* OKPlaygroundApp.swift */; }; + 0A5648C82C1468E1008FB5F6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0A5648C72C1468E1008FB5F6 /* Assets.xcassets */; }; + 0A5648CB2C1468E1008FB5F6 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0A5648CA2C1468E1008FB5F6 /* Preview Assets.xcassets */; }; + 0A5648D62C1469C3008FB5F6 /* CopyModelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5648D52C1469C3008FB5F6 /* CopyModelView.swift */; }; + 0A5648D82C146A8C008FB5F6 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5648D72C146A8C008FB5F6 /* AppView.swift */; }; + 0A5648DB2C14BF8A008FB5F6 /* DeleteModelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5648DA2C14BF8A008FB5F6 /* DeleteModelView.swift */; }; + 0A5648DF2C14C583008FB5F6 /* EmbeddingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5648DE2C14C583008FB5F6 /* EmbeddingsView.swift */; }; + 0A5648E22C14C7E1008FB5F6 /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5648E12C14C7E1008FB5F6 /* ViewModel.swift */; }; + 0A5648E42C14D342008FB5F6 /* ModelInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5648E32C14D342008FB5F6 /* ModelInfoView.swift */; }; + 0A5648E62C14D846008FB5F6 /* ModelListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5648E52C14D846008FB5F6 /* ModelListView.swift */; }; + 0A5648E82C14E00E008FB5F6 /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5648E72C14E00E008FB5F6 /* ChatView.swift */; }; + 0A5648EA2C1504CD008FB5F6 /* GenerateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5648E92C1504CD008FB5F6 /* GenerateView.swift */; }; + 0A5648EE2C150C66008FB5F6 /* OllamaKit in Frameworks */ = {isa = PBXBuildFile; productRef = 0A5648ED2C150C66008FB5F6 /* OllamaKit */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0A5648C02C1468E0008FB5F6 /* OKPlayground.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OKPlayground.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0A5648C32C1468E0008FB5F6 /* OKPlaygroundApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OKPlaygroundApp.swift; sourceTree = ""; }; + 0A5648C72C1468E1008FB5F6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 0A5648CA2C1468E1008FB5F6 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 0A5648D52C1469C3008FB5F6 /* CopyModelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyModelView.swift; sourceTree = ""; }; + 0A5648D72C146A8C008FB5F6 /* AppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppView.swift; sourceTree = ""; }; + 0A5648DA2C14BF8A008FB5F6 /* DeleteModelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteModelView.swift; sourceTree = ""; }; + 0A5648DE2C14C583008FB5F6 /* EmbeddingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmbeddingsView.swift; sourceTree = ""; }; + 0A5648E12C14C7E1008FB5F6 /* ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = ""; }; + 0A5648E32C14D342008FB5F6 /* ModelInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelInfoView.swift; sourceTree = ""; }; + 0A5648E52C14D846008FB5F6 /* ModelListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelListView.swift; sourceTree = ""; }; + 0A5648E72C14E00E008FB5F6 /* ChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatView.swift; sourceTree = ""; }; + 0A5648E92C1504CD008FB5F6 /* GenerateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerateView.swift; sourceTree = ""; }; + 0A5648EC2C150C3A008FB5F6 /* OllamaKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = OllamaKit; path = ..; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 0A5648BD2C1468E0008FB5F6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0A5648EE2C150C66008FB5F6 /* OllamaKit in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0A5648B72C1468E0008FB5F6 = { + isa = PBXGroup; + children = ( + 0A5648C22C1468E0008FB5F6 /* OKPlayground */, + 0A5648C12C1468E0008FB5F6 /* Products */, + 0A5648EB2C150C3A008FB5F6 /* Frameworks */, + ); + sourceTree = ""; + }; + 0A5648C12C1468E0008FB5F6 /* Products */ = { + isa = PBXGroup; + children = ( + 0A5648C02C1468E0008FB5F6 /* OKPlayground.app */, + ); + name = Products; + sourceTree = ""; + }; + 0A5648C22C1468E0008FB5F6 /* OKPlayground */ = { + isa = PBXGroup; + children = ( + 0A5648E02C14C7D6008FB5F6 /* ViewModels */, + 0A5648C32C1468E0008FB5F6 /* OKPlaygroundApp.swift */, + 0A5648C92C1468E1008FB5F6 /* Preview Content */, + 0A5648D92C146AAD008FB5F6 /* Resources */, + 0A5648D42C1469A3008FB5F6 /* Views */, + ); + path = OKPlayground; + sourceTree = ""; + }; + 0A5648C92C1468E1008FB5F6 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 0A5648CA2C1468E1008FB5F6 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 0A5648D42C1469A3008FB5F6 /* Views */ = { + isa = PBXGroup; + children = ( + 0A5648D72C146A8C008FB5F6 /* AppView.swift */, + 0A5648D52C1469C3008FB5F6 /* CopyModelView.swift */, + 0A5648DA2C14BF8A008FB5F6 /* DeleteModelView.swift */, + 0A5648DE2C14C583008FB5F6 /* EmbeddingsView.swift */, + 0A5648E32C14D342008FB5F6 /* ModelInfoView.swift */, + 0A5648E52C14D846008FB5F6 /* ModelListView.swift */, + 0A5648E72C14E00E008FB5F6 /* ChatView.swift */, + 0A5648E92C1504CD008FB5F6 /* GenerateView.swift */, + ); + path = Views; + sourceTree = ""; + }; + 0A5648D92C146AAD008FB5F6 /* Resources */ = { + isa = PBXGroup; + children = ( + 0A5648C72C1468E1008FB5F6 /* Assets.xcassets */, + ); + path = Resources; + sourceTree = ""; + }; + 0A5648E02C14C7D6008FB5F6 /* ViewModels */ = { + isa = PBXGroup; + children = ( + 0A5648E12C14C7E1008FB5F6 /* ViewModel.swift */, + ); + path = ViewModels; + sourceTree = ""; + }; + 0A5648EB2C150C3A008FB5F6 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 0A5648EC2C150C3A008FB5F6 /* OllamaKit */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 0A5648BF2C1468E0008FB5F6 /* OKPlayground */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0A5648CE2C1468E1008FB5F6 /* Build configuration list for PBXNativeTarget "OKPlayground" */; + buildPhases = ( + 0A5648BC2C1468E0008FB5F6 /* Sources */, + 0A5648BD2C1468E0008FB5F6 /* Frameworks */, + 0A5648BE2C1468E0008FB5F6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = OKPlayground; + packageProductDependencies = ( + 0A5648ED2C150C66008FB5F6 /* OllamaKit */, + ); + productName = OKPlayground; + productReference = 0A5648C02C1468E0008FB5F6 /* OKPlayground.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0A5648B82C1468E0008FB5F6 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1540; + LastUpgradeCheck = 1540; + TargetAttributes = { + 0A5648BF2C1468E0008FB5F6 = { + CreatedOnToolsVersion = 15.4; + }; + }; + }; + buildConfigurationList = 0A5648BB2C1468E0008FB5F6 /* Build configuration list for PBXProject "OKPlayground" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 0A5648B72C1468E0008FB5F6; + packageReferences = ( + ); + productRefGroup = 0A5648C12C1468E0008FB5F6 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 0A5648BF2C1468E0008FB5F6 /* OKPlayground */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 0A5648BE2C1468E0008FB5F6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0A5648CB2C1468E1008FB5F6 /* Preview Assets.xcassets in Resources */, + 0A5648C82C1468E1008FB5F6 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 0A5648BC2C1468E0008FB5F6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0A5648D82C146A8C008FB5F6 /* AppView.swift in Sources */, + 0A5648D62C1469C3008FB5F6 /* CopyModelView.swift in Sources */, + 0A5648E62C14D846008FB5F6 /* ModelListView.swift in Sources */, + 0A5648EA2C1504CD008FB5F6 /* GenerateView.swift in Sources */, + 0A5648C42C1468E0008FB5F6 /* OKPlaygroundApp.swift in Sources */, + 0A5648E82C14E00E008FB5F6 /* ChatView.swift in Sources */, + 0A5648DB2C14BF8A008FB5F6 /* DeleteModelView.swift in Sources */, + 0A5648E42C14D342008FB5F6 /* ModelInfoView.swift in Sources */, + 0A5648E22C14C7E1008FB5F6 /* ViewModel.swift in Sources */, + 0A5648DF2C14C583008FB5F6 /* EmbeddingsView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 0A5648CC2C1468E1008FB5F6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 0A5648CD2C1468E1008FB5F6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 0A5648CF2C1468E1008FB5F6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"OKPlayground/Preview Content\""; + DEVELOPMENT_TEAM = 84ZM7K56B5; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.kevinhermawan.OKPlayground; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 0A5648D02C1468E1008FB5F6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"OKPlayground/Preview Content\""; + DEVELOPMENT_TEAM = 84ZM7K56B5; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.kevinhermawan.OKPlayground; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 0A5648BB2C1468E0008FB5F6 /* Build configuration list for PBXProject "OKPlayground" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0A5648CC2C1468E1008FB5F6 /* Debug */, + 0A5648CD2C1468E1008FB5F6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0A5648CE2C1468E1008FB5F6 /* Build configuration list for PBXNativeTarget "OKPlayground" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0A5648CF2C1468E1008FB5F6 /* Debug */, + 0A5648D02C1468E1008FB5F6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCSwiftPackageProductDependency section */ + 0A5648ED2C150C66008FB5F6 /* OllamaKit */ = { + isa = XCSwiftPackageProductDependency; + productName = OllamaKit; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 0A5648B82C1468E0008FB5F6 /* Project object */; +} diff --git a/Playground/OKPlayground.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Playground/OKPlayground.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/Playground/OKPlayground.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Playground/OKPlayground.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Playground/OKPlayground.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Playground/OKPlayground.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Playground/OKPlayground.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Playground/OKPlayground.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..10155ea --- /dev/null +++ b/Playground/OKPlayground.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,23 @@ +{ + "pins" : [ + { + "identity" : "swift-docc-plugin", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-docc-plugin.git", + "state" : { + "revision" : "26ac5758409154cc448d7ab82389c520fa8a8247", + "version" : "1.3.0" + } + }, + { + "identity" : "swift-docc-symbolkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-docc-symbolkit", + "state" : { + "revision" : "b45d1f2ed151d057b54504d653e0da5552844e34", + "version" : "1.0.0" + } + } + ], + "version" : 2 +} diff --git a/Playground/OKPlayground/OKPlaygroundApp.swift b/Playground/OKPlayground/OKPlaygroundApp.swift new file mode 100644 index 0000000..efc7cd9 --- /dev/null +++ b/Playground/OKPlayground/OKPlaygroundApp.swift @@ -0,0 +1,20 @@ +// +// OKPlaygroundApp.swift +// OKPlayground +// +// Created by Kevin Hermawan on 08/06/24. +// + +import SwiftUI + +@main +struct OKPlaygroundApp: App { + @State private var viewModel = ViewModel() + + var body: some Scene { + WindowGroup { + AppView() + .environment(viewModel) + } + } +} diff --git a/Playground/OKPlayground/Preview Content/Preview Assets.xcassets/Contents.json b/Playground/OKPlayground/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Playground/OKPlayground/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Playground/OKPlayground/Resources/Assets.xcassets/AccentColor.colorset/Contents.json b/Playground/OKPlayground/Resources/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Playground/OKPlayground/Resources/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Playground/OKPlayground/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/Playground/OKPlayground/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..13613e3 --- /dev/null +++ b/Playground/OKPlayground/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Playground/OKPlayground/Resources/Assets.xcassets/Contents.json b/Playground/OKPlayground/Resources/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Playground/OKPlayground/Resources/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Playground/OKPlayground/ViewModels/ViewModel.swift b/Playground/OKPlayground/ViewModels/ViewModel.swift new file mode 100644 index 0000000..32fd6fc --- /dev/null +++ b/Playground/OKPlayground/ViewModels/ViewModel.swift @@ -0,0 +1,28 @@ +// +// ViewModel.swift +// OKPlayground +// +// Created by Kevin Hermawan on 09/06/24. +// + +import Foundation +import OllamaKit + +@Observable +final class ViewModel { + var ollamaKit = OllamaKit() + + var isReachable = false + var models = [String]() + + func reachable() async { + self.isReachable = await ollamaKit.reachable() + } + + func fetchModels() async { + let response = try? await ollamaKit.models() + guard let models = response?.models.map({ $0.name }) else { return } + + self.models = models + } +} diff --git a/Playground/OKPlayground/Views/AppView.swift b/Playground/OKPlayground/Views/AppView.swift new file mode 100644 index 0000000..e26c715 --- /dev/null +++ b/Playground/OKPlayground/Views/AppView.swift @@ -0,0 +1,63 @@ +// +// AppView.swift +// OKPlayground +// +// Created by Kevin Hermawan on 08/06/24. +// + +import SwiftUI + +struct AppView: View { + @Environment(ViewModel.self) private var viewModel + + var body: some View { + NavigationStack { + Form { + Section { + Text("Reachable") + .badge(viewModel.isReachable ? "Yes" : "No") + } + + Section("Models") { + NavigationLink("Model List") { + ModelListView() + } + + NavigationLink("Model Info") { + ModelInfoView() + } + + NavigationLink("Copy Model") { + CopyModelView() + } + + NavigationLink("Delete Model") { + DeleteModelView() + } + } + + Section("Generation") { + NavigationLink("Chat") { + ChatView() + } + + NavigationLink("Generate") { + GenerateView() + } + } + + Section("Embeddings") { + NavigationLink("Embeddings") { + EmbeddingsView() + } + } + } + .navigationTitle("OKPlayground") + .navigationBarTitleDisplayMode(.inline) + .task { + await viewModel.reachable() + await viewModel.fetchModels() + } + } + } +} diff --git a/Playground/OKPlayground/Views/ChatView.swift b/Playground/OKPlayground/Views/ChatView.swift new file mode 100644 index 0000000..384ff9a --- /dev/null +++ b/Playground/OKPlayground/Views/ChatView.swift @@ -0,0 +1,85 @@ +// +// ChatView.swift +// OKPlayground +// +// Created by Kevin Hermawan on 09/06/24. +// + +import Combine +import SwiftUI +import OllamaKit + +struct ChatView: View { + @Environment(ViewModel.self) private var viewModel + + @State private var model: String? = nil + @State private var prompt = "" + @State private var response = "" + @State private var cancellables = Set() + + var body: some View { + NavigationStack { + Form { + Section { + Picker("Model", selection: $model) { + ForEach(viewModel.models, id: \.self) { model in + Text(model) + .tag(model as String?) + } + } + + TextField("Prompt", text: $prompt) + } + + Section { + Button("Chat Async", action: actionAsync) + Button("Chat Combine", action: actionCombine) + } + + Section("Response") { + Text(response) + } + } + .navigationTitle("Chat") + .navigationBarTitleDisplayMode(.inline) + .onAppear { + model = viewModel.models.first + } + } + } + + func actionAsync() { + self.response = "" + + guard let model = model else { return } + let messages = [OKChatRequestData.Message(role: .user, content: prompt)] + let data = OKChatRequestData(model: model, messages: messages) + + Task { + for try await chunk in viewModel.ollamaKit.chat(data: data) { + self.response += chunk.message?.content ?? "" + } + } + } + + func actionCombine() { + self.response = "" + + guard let model = model else { return } + let messages = [OKChatRequestData.Message(role: .user, content: prompt)] + let data = OKChatRequestData(model: model, messages: messages) + + viewModel.ollamaKit.chat(data: data) + .sink { completion in + switch completion { + case .finished: + print("Finished") + case .failure(let error): + print("Error:", error.localizedDescription) + } + } receiveValue: { value in + self.response += value.message?.content ?? "" + } + .store(in: &cancellables) + } +} diff --git a/Playground/OKPlayground/Views/CopyModelView.swift b/Playground/OKPlayground/Views/CopyModelView.swift new file mode 100644 index 0000000..eb1b2db --- /dev/null +++ b/Playground/OKPlayground/Views/CopyModelView.swift @@ -0,0 +1,73 @@ +// +// CopyModelView.swift +// OKPlayground +// +// Created by Kevin Hermawan on 08/06/24. +// + +import Combine +import SwiftUI +import OllamaKit + +struct CopyModelView: View { + @Environment(ViewModel.self) private var viewModel + + @State private var model: String? + @State private var destination: String = "" + @State private var cancellables = Set() + + var body: some View { + NavigationStack { + Form { + Section { + Picker("Source", selection: $model) { + ForEach(viewModel.models, id: \.self) { model in + Text(model) + .tag(model as String?) + } + } + + TextField("Destination", text: $destination) + .textInputAutocapitalization(.never) + } + + Section { + Button("Copy Async", action: actionAsync) + Button("Copy Combine", action: actionCombine) + } + } + .navigationTitle("Copy Model") + .navigationBarTitleDisplayMode(.inline) + .onAppear { + model = viewModel.models.first + } + } + } + + private func actionAsync() { + Task { + guard let model = model else { return } + let data = OKCopyModelRequestData(source: model, destination: destination) + + try await viewModel.ollamaKit.copyModel(data: data) + } + } + + private func actionCombine() { + guard let model = model else { return } + let data = OKCopyModelRequestData(source: model, destination: destination) + + viewModel.ollamaKit.copyModel(data: data) + .sink { completion in + switch completion { + case .finished: + print("Finished") + case .failure(let error): + print("Error:", error.localizedDescription) + } + } receiveValue: { value in + print("Value:", value) + } + .store(in: &cancellables) + } +} diff --git a/Playground/OKPlayground/Views/DeleteModelView.swift b/Playground/OKPlayground/Views/DeleteModelView.swift new file mode 100644 index 0000000..3cff89c --- /dev/null +++ b/Playground/OKPlayground/Views/DeleteModelView.swift @@ -0,0 +1,73 @@ +// +// DeleteModelView.swift +// OKPlayground +// +// Created by Kevin Hermawan on 08/06/24. +// + +import Combine +import SwiftUI +import OllamaKit + +struct DeleteModelView: View { + @Environment(ViewModel.self) private var viewModel + + @State private var model: String? = nil + @State private var cancellables = Set() + + var body: some View { + NavigationStack { + Form { + Section { + Picker("Model", selection: $model) { + ForEach(viewModel.models, id: \.self) { model in + Text(model) + .tag(model as String?) + } + } + } + + Section { + Button("Delete Async", action: actionAsync) + Button("Delete Combine", action: actionCombine) + } + } + .navigationTitle("Delete Model") + .navigationBarTitleDisplayMode(.inline) + .onAppear { + model = viewModel.models.first + } + } + } + + private func actionAsync() { + Task { + guard let model = model else { return } + let data = OKDeleteModelRequestData(name: model) + + try await viewModel.ollamaKit.deleteModel(data: data) + } + } + + private func actionCombine() { + guard let model = model else { return } + let data = OKDeleteModelRequestData(name: model) + + viewModel.ollamaKit.deleteModel(data: data) + .sink { completion in + switch completion { + case .finished: + print("Finished") + case .failure(let error): + print("Error:", error.localizedDescription) + } + } receiveValue: { value in + print("Value:", value) + } + .store(in: &cancellables) + } +} + +#Preview { + DeleteModelView() +} diff --git a/Playground/OKPlayground/Views/EmbeddingsView.swift b/Playground/OKPlayground/Views/EmbeddingsView.swift new file mode 100644 index 0000000..27a3160 --- /dev/null +++ b/Playground/OKPlayground/Views/EmbeddingsView.swift @@ -0,0 +1,84 @@ +// +// EmbeddingsView.swift +// OKPlayground +// +// Created by Kevin Hermawan on 08/06/24. +// + +import Combine +import SwiftUI +import OllamaKit + +struct EmbeddingsView: View { + @Environment(ViewModel.self) private var viewModel + + @State private var model: String? = nil + @State private var prompt = "" + @State private var embedding = [Double]() + @State private var cancellables = Set() + + var body: some View { + NavigationStack { + Form { + Section { + Picker("Source", selection: $model) { + ForEach(viewModel.models, id: \.self) { model in + Text(model) + .tag(model as String?) + } + } + + TextField("Prompt", text: $prompt) + .textInputAutocapitalization(.never) + } + + Section { + Text("Embedding Length") + .badge(embedding.count) + } + + Section { + Button("Embed Async", action: actionAsync) + Button("Embed Combine", action: actionCombine) + } + } + .navigationTitle("Embeddings") + .navigationBarTitleDisplayMode(.inline) + .onAppear { + model = viewModel.models.first + } + } + } + + private func actionAsync() { + Task { + guard let model = model else { return } + let data = OKEmbeddingsRequestData(model: model, prompt: prompt) + + let response = try await viewModel.ollamaKit.embeddings(data: data) + guard let embedding = response.embedding else { return } + + self.embedding = embedding + } + } + + private func actionCombine() { + guard let model = model else { return } + let data = OKEmbeddingsRequestData(model: model, prompt: prompt) + + viewModel.ollamaKit.embeddings(data: data) + .sink { completion in + switch completion { + case .finished: + print("Finished") + case .failure(let error): + print("Error:", error.localizedDescription) + } + } receiveValue: { value in + guard let embedding = value.embedding else { return } + + self.embedding = embedding + } + .store(in: &cancellables) + } +} diff --git a/Playground/OKPlayground/Views/GenerateView.swift b/Playground/OKPlayground/Views/GenerateView.swift new file mode 100644 index 0000000..c1ec1f5 --- /dev/null +++ b/Playground/OKPlayground/Views/GenerateView.swift @@ -0,0 +1,83 @@ +// +// GenerateView.swift +// OKPlayground +// +// Created by Kevin Hermawan on 09/06/24. +// + +import Combine +import SwiftUI +import OllamaKit + +struct GenerateView: View { + @Environment(ViewModel.self) private var viewModel + + @State private var model: String? = nil + @State private var prompt = "" + @State private var response = "" + @State private var cancellables = Set() + + var body: some View { + NavigationStack { + Form { + Section { + Picker("Model", selection: $model) { + ForEach(viewModel.models, id: \.self) { model in + Text(model) + .tag(model as String?) + } + } + + TextField("Prompt", text: $prompt) + } + + Section { + Button("Generate Async", action: actionAsync) + Button("Generate Combine", action: actionCombine) + } + + Section("Response") { + Text(response) + } + } + .navigationTitle("Generate") + .navigationBarTitleDisplayMode(.inline) + .onAppear { + model = viewModel.models.first + } + } + } + + func actionAsync() { + self.response = "" + + guard let model = model else { return } + let data = OKGenerateRequestData(model: model, prompt: prompt) + + Task { + for try await chunk in viewModel.ollamaKit.generate(data: data) { + self.response += chunk.response + } + } + } + + func actionCombine() { + self.response = "" + + guard let model = model else { return } + let data = OKGenerateRequestData(model: model, prompt: prompt) + + viewModel.ollamaKit.generate(data: data) + .sink { completion in + switch completion { + case .finished: + print("Finished") + case .failure(let error): + print("Error:", error.localizedDescription) + } + } receiveValue: { value in + self.response += value.response + } + .store(in: &cancellables) + } +} diff --git a/Playground/OKPlayground/Views/ModelInfoView.swift b/Playground/OKPlayground/Views/ModelInfoView.swift new file mode 100644 index 0000000..fb050c1 --- /dev/null +++ b/Playground/OKPlayground/Views/ModelInfoView.swift @@ -0,0 +1,95 @@ +// +// ModelInfoView.swift +// OKPlayground +// +// Created by Kevin Hermawan on 09/06/24. +// + +import Combine +import SwiftUI +import OllamaKit + +struct ModelInfoView: View { + @Environment(ViewModel.self) private var viewModel + + @State private var model: String? = nil + @State private var modelInfo: OKModelInfoResponse? = nil + @State private var embedding = [Double]() + @State private var cancellables = Set() + + var body: some View { + NavigationStack { + Form { + Section { + Picker("Source", selection: $model) { + ForEach(viewModel.models, id: \.self) { model in + Text(model) + .tag(model as String?) + } + } + } + + if let modelInfo { + Section("License") { + Text(modelInfo.license) + } + + Section("Modelfile") { + Text(modelInfo.modelfile) + } + + Section("Parameters") { + Text(modelInfo.parameters) + } + + Section("Template") { + Text(modelInfo.template) + } + } + + Section { + Button("Get Async", action: actionAsync) + Button("Get Combine", action: actionCombine) + } + } + .navigationTitle("Model Info") + .navigationBarTitleDisplayMode(.inline) + .onAppear { + model = viewModel.models.first + } + } + } + + private func actionAsync() { + Task { + guard let model = model else { return } + let data = OKModelInfoRequestData(name: model) + + let response = try await viewModel.ollamaKit.modelInfo(data: data) + + self.modelInfo = response + } + } + + private func actionCombine() { + guard let model = model else { return } + let data = OKModelInfoRequestData(name: model) + + viewModel.ollamaKit.modelInfo(data: data) + .sink { completion in + switch completion { + case .finished: + print("Finished") + case .failure(let error): + print("Error:", error.localizedDescription) + } + } receiveValue: { value in + self.modelInfo = value + } + .store(in: &cancellables) + } +} + +#Preview { + ModelInfoView() +} diff --git a/Playground/OKPlayground/Views/ModelListView.swift b/Playground/OKPlayground/Views/ModelListView.swift new file mode 100644 index 0000000..26dbf59 --- /dev/null +++ b/Playground/OKPlayground/Views/ModelListView.swift @@ -0,0 +1,18 @@ +// +// ModelListView.swift +// OKPlayground +// +// Created by Kevin Hermawan on 09/06/24. +// + +import SwiftUI + +struct ModelListView: View { + @Environment(ViewModel.self) private var viewModel + + var body: some View { + List(viewModel.models, id: \.self) { model in + Text(model) + } + } +}