├── .github └── workflows │ ├── android.yaml │ └── ios.yaml ├── .gitignore ├── LICENSE ├── README.md ├── clients ├── android │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── build.gradle.kts │ ├── files │ │ └── screenshot.jpg │ ├── gradle.properties │ ├── gradle │ │ ├── libs.versions.toml │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── open-sesame │ │ ├── .gitignore │ │ ├── build.gradle.kts │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── ic_launcher-playstore.png │ │ │ ├── java │ │ │ └── co │ │ │ │ └── daily │ │ │ │ └── opensesame │ │ │ │ ├── ComposableVoiceClient.kt │ │ │ │ ├── ConfigConstants.kt │ │ │ │ ├── LoadingOverlay.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── Model.kt │ │ │ │ ├── Preferences.kt │ │ │ │ ├── PreviewData.kt │ │ │ │ ├── RTVIApplication.kt │ │ │ │ ├── Screen.kt │ │ │ │ ├── api │ │ │ │ ├── ApiCache.kt │ │ │ │ ├── DataApi.kt │ │ │ │ ├── DataApiError.kt │ │ │ │ ├── DataApiPreview.kt │ │ │ │ ├── DataApiRestApi.kt │ │ │ │ └── RepeatingFetch.kt │ │ │ │ ├── chat │ │ │ │ ├── ChatMessageProcessor.kt │ │ │ │ ├── ChatMessageProcessorTextMode.kt │ │ │ │ ├── ChatMessageProcessorVoiceModeConversational.kt │ │ │ │ └── ChatMessageProcessorVoiceModeInformational.kt │ │ │ │ ├── ui │ │ │ │ ├── ActionBar.kt │ │ │ │ ├── AppConfigScreen.kt │ │ │ │ ├── AudioIndicator.kt │ │ │ │ ├── ChatScreen.kt │ │ │ │ ├── Common.kt │ │ │ │ ├── ConnectionError.kt │ │ │ │ ├── Context.kt │ │ │ │ ├── CreateWorkspaceScreen.kt │ │ │ │ ├── Dialog.kt │ │ │ │ ├── EditWorkspaceScreen.kt │ │ │ │ ├── ErrorDialog.kt │ │ │ │ ├── FormattedText.kt │ │ │ │ ├── LoadingDialog.kt │ │ │ │ ├── LoginDialogApiKey.kt │ │ │ │ ├── LoginDialogQrCode.kt │ │ │ │ ├── LoginDialogUsernamePassword.kt │ │ │ │ ├── Logo.kt │ │ │ │ ├── Menu.kt │ │ │ │ ├── QrCodeScanner.kt │ │ │ │ ├── TextInputDialog.kt │ │ │ │ ├── ToolbarIconButton.kt │ │ │ │ ├── WorkspaceChatList.kt │ │ │ │ ├── WorkspaceConfigEditor.kt │ │ │ │ ├── WorkspaceSidebar.kt │ │ │ │ ├── WorkspacesScreen.kt │ │ │ │ └── theme │ │ │ │ │ ├── Color.kt │ │ │ │ │ ├── Theme.kt │ │ │ │ │ └── Type.kt │ │ │ │ └── utils │ │ │ │ ├── Http.kt │ │ │ │ ├── JsonUtils.kt │ │ │ │ ├── MutableJsonElement.kt │ │ │ │ ├── MutexData.kt │ │ │ │ ├── RealTimeClock.kt │ │ │ │ └── TimeUtils.kt │ │ │ └── res │ │ │ ├── drawable │ │ │ ├── add_box.xml │ │ │ ├── alert_circle_outline.xml │ │ │ ├── camera.xml │ │ │ ├── cellphone_cog.xml │ │ │ ├── chevron_down.xml │ │ │ ├── chevron_right.xml │ │ │ ├── close.xml │ │ │ ├── cog.xml │ │ │ ├── console.xml │ │ │ ├── dropdown_unfold.xml │ │ │ ├── edit.xml │ │ │ ├── form_textbox_password.xml │ │ │ ├── frame.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── ic_launcher_foreground.xml │ │ │ ├── image.xml │ │ │ ├── key.xml │ │ │ ├── keyboard.xml │ │ │ ├── logo.png │ │ │ ├── logout.xml │ │ │ ├── menu.xml │ │ │ ├── mic_on.xml │ │ │ ├── microphone.xml │ │ │ ├── microphone_off.xml │ │ │ ├── moon_waning_crescent.xml │ │ │ ├── phone_hangup.xml │ │ │ ├── qrcode_scan.xml │ │ │ ├── settings.xml │ │ │ ├── speech.xml │ │ │ ├── timer_outline.xml │ │ │ ├── unfold_more.xml │ │ │ ├── video.xml │ │ │ ├── video_off.xml │ │ │ ├── weather_sunny.xml │ │ │ └── workspaces.xml │ │ │ ├── font │ │ │ ├── dm_mono_medium.ttf │ │ │ ├── dm_sans.ttf │ │ │ ├── inter.ttf │ │ │ └── sf_pro_medium.OTF │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── themes.xml │ └── settings.gradle.kts ├── cmdline │ ├── requirements.txt │ └── single-action.py ├── ios │ ├── .gitignore │ ├── .swiftlint.yml │ ├── OpenSesame.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── OpenSesame.xcscheme │ ├── OpenSesame.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ ├── OpenSesame │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ └── appIconWithoutAlpha.png │ │ │ ├── Contents.json │ │ │ ├── configWorkspace.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── configWorkspace.svg │ │ │ ├── editWorkspace.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── editorWorkspace.svg │ │ │ ├── keyboard.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── keyboard.svg │ │ │ ├── newChat.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── newChat.svg │ │ │ ├── openSesame.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── openSesame.svg │ │ │ ├── rightArrow.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── rightArrow.svg │ │ │ ├── selectDropDown.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── selectDropDown.svg │ │ │ ├── settings.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── settingsIcon 1.svg │ │ │ ├── speech.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── speech.svg │ │ │ ├── tray.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── trayIcon.svg │ │ │ ├── vision.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── vision.svg │ │ │ ├── workspace.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── workspaceIcon.svg │ │ │ └── workspaces.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── workspaces.svg │ │ ├── ExportOptions.plist │ │ ├── Info.plist │ │ ├── OpenSesame.entitlements │ │ ├── OpenSesameApp.swift │ │ ├── OpenSesameModel.swift │ │ ├── api │ │ │ ├── OpenSesameAPI.swift │ │ │ ├── OpenSesameConversationsAPI.swift │ │ │ ├── OpenSesameMessagesAPI.swift │ │ │ ├── OpenSesameUsersAPI.swift │ │ │ └── OpenSesameWorkspacesAPI.swift │ │ ├── errors │ │ │ └── OpenSesameError.swift │ │ ├── managers │ │ │ ├── ActivityManager.swift │ │ │ ├── RTVIManager.swift │ │ │ ├── SettingsManager.swift │ │ │ └── WakeWordManager.swift │ │ ├── resources │ │ │ ├── beep.wav │ │ │ └── open-sesame.ppn │ │ ├── shortcuts │ │ │ ├── SiriAppShortcuts.swift │ │ │ └── StartDailyBotIntent.swift │ │ ├── theme │ │ │ ├── OpenSesameColors.swift │ │ │ └── OpenSesameIcons.swift │ │ ├── types │ │ │ ├── Conversations.swift │ │ │ ├── LLMModel.swift │ │ │ ├── LLMProvider.swift │ │ │ ├── Language.swift │ │ │ ├── LiveMessage.swift │ │ │ ├── Messages.swift │ │ │ ├── QrcodeInfo.swift │ │ │ ├── SessionTokenResponse.swift │ │ │ ├── SettingsPreference.swift │ │ │ ├── Storage.swift │ │ │ ├── TTSProvider.swift │ │ │ ├── Voice.swift │ │ │ └── Workspaces.swift │ │ ├── util │ │ │ ├── OpenSesameHelper.swift │ │ │ ├── OpenSesameLogger.swift │ │ │ ├── OpenSesameMockModel.swift │ │ │ ├── RTVIDefaultData.swift │ │ │ └── RTVIHelper.swift │ │ └── views │ │ │ ├── ContentView.swift │ │ │ ├── components │ │ │ ├── BotSpeakingView.swift │ │ │ ├── ConfirmationView.swift │ │ │ ├── CreatePickerView.swift │ │ │ ├── DailyVideoView.swift │ │ │ ├── InfoComponent.swift │ │ │ ├── MicrophoneView.swift │ │ │ ├── SecureFieldWithPlaceholder.swift │ │ │ ├── SelectPickerView.swift │ │ │ ├── ToastModifier.swift │ │ │ ├── ViewExtensions.swift │ │ │ └── WaveformView.swift │ │ │ ├── main │ │ │ ├── BottonPanel.swift │ │ │ ├── ChatView.swift │ │ │ ├── FloatingComponent.swift │ │ │ └── HeaderToolBar.swift │ │ │ ├── onboarding │ │ │ ├── OnboardingApiKeys.swift │ │ │ ├── OnboardingServerSettings.swift │ │ │ ├── OnboardingView.swift │ │ │ └── QRCodeScannerView.swift │ │ │ ├── settings │ │ │ └── SettingsView.swift │ │ │ ├── tray │ │ │ ├── ConversationRow.swift │ │ │ └── TrayView.swift │ │ │ └── workspaces │ │ │ ├── WorkspaceItem.swift │ │ │ ├── WorkspaceView.swift │ │ │ ├── WorkspacesView.swift │ │ │ ├── llm │ │ │ ├── LLMView.swift │ │ │ ├── SelectLLMModel.swift │ │ │ └── SelectLLMProvider.swift │ │ │ ├── prompt │ │ │ ├── PromptView.swift │ │ │ └── SelectPrompt.swift │ │ │ ├── storage │ │ │ └── SelectStorage.swift │ │ │ └── tts │ │ │ ├── SelectLanguage.swift │ │ │ ├── SelectTTSProvider.swift │ │ │ └── SelectVoice.swift │ ├── OpenSesameStatus │ │ ├── Assets.xcassets │ │ │ ├── AccentColor.colorset │ │ │ │ └── Contents.json │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ └── WidgetBackground.colorset │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── OpenSesameStatusAttributes.swift │ │ ├── OpenSesameStatusBundle.swift │ │ └── OpenSesameStatusLiveActivity.swift │ ├── Podfile │ ├── Podfile.lock │ ├── README.md │ ├── docsAssets │ │ └── wakeWord.jpeg │ └── scripts │ │ ├── build_app.sh │ │ ├── fixLint.sh │ │ └── set_xcarchive_version.sh └── web │ ├── .eslintrc.json │ ├── .gitignore │ ├── .prettierrc │ ├── README.md │ ├── app │ ├── (auth) │ │ ├── layout.tsx │ │ └── sign-in │ │ │ ├── SignInForm.tsx │ │ │ ├── actions.ts │ │ │ └── page.tsx │ ├── (authenticated) │ │ ├── [workspaceId] │ │ │ ├── ConversationList.tsx │ │ │ ├── ConversationListItem.tsx │ │ │ ├── DeleteConversationModal.tsx │ │ │ ├── DisabledInSandboxModeModal.tsx │ │ │ ├── Navbar.tsx │ │ │ ├── SearchResults.tsx │ │ │ ├── Sidebar.tsx │ │ │ ├── SidebarTitle.tsx │ │ │ ├── c │ │ │ │ ├── [conversationId] │ │ │ │ │ └── page.tsx │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ └── workspaces │ │ │ ├── DeleteWorkspaceModal.tsx │ │ │ ├── Navbar.tsx │ │ │ ├── Sidebar.tsx │ │ │ ├── [workspaceId] │ │ │ ├── ConfigurationForm.tsx │ │ │ ├── ConfigurationGroup.tsx │ │ │ ├── ConfigurationItem.tsx │ │ │ ├── ConfigurationSection.tsx │ │ │ ├── SettingsRow.tsx │ │ │ ├── VoiceSettingsSection.tsx │ │ │ ├── WorkspaceOptionsSection.tsx │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ └── services │ │ │ ├── AddServiceModal.tsx │ │ │ ├── DeleteServiceModal.tsx │ │ │ ├── EditServiceModal.tsx │ │ │ ├── ServiceConfig.tsx │ │ │ ├── actions.ts │ │ │ └── page.tsx │ ├── NavigationState.tsx │ ├── api │ │ ├── bot-action │ │ │ └── route.ts │ │ ├── create-conversation │ │ │ └── route.ts │ │ ├── create-workspace │ │ │ └── route.ts │ │ ├── delete-conversation │ │ │ └── route.ts │ │ ├── delete-workspace │ │ │ └── route.ts │ │ ├── search │ │ │ └── route.ts │ │ ├── start-bot │ │ │ └── route.ts │ │ ├── update-conversation │ │ │ └── route.ts │ │ └── update-workspace │ │ │ └── route.ts │ ├── favicon.ico │ ├── fonts │ │ ├── GeistMonoVF.woff │ │ └── GeistVF.woff │ ├── globals.css │ ├── layout.tsx │ └── page.tsx │ ├── components.json │ ├── components │ ├── AutoScrollToBottom.tsx │ ├── BotReadyAudio.tsx │ ├── ChatControls.tsx │ ├── ChatMessage.tsx │ ├── ChatMessages.tsx │ ├── ClientPage.tsx │ ├── CodeBlock.tsx │ ├── CopyToClipboard.tsx │ ├── ErrorBoundary.tsx │ ├── ErrorPage.tsx │ ├── ExpiryCountdown.tsx │ ├── LiveMessages.tsx │ ├── PageRefresher.tsx │ ├── PageTransitionLink.tsx │ ├── QueryClientProvider.tsx │ ├── Settings.tsx │ ├── SignOutButton.tsx │ ├── svg │ │ └── Logo.tsx │ └── ui │ │ ├── alert.tsx │ │ ├── avatar.tsx │ │ ├── badge.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── carousel.tsx │ │ ├── dialog.tsx │ │ ├── dropdown-menu.tsx │ │ ├── form.tsx │ │ ├── input.tsx │ │ ├── label.tsx │ │ ├── radio-group.tsx │ │ ├── scroll-area.tsx │ │ ├── select.tsx │ │ ├── separator.tsx │ │ ├── sheet.tsx │ │ ├── skeleton.tsx │ │ ├── switch.tsx │ │ ├── table.tsx │ │ ├── textarea.tsx │ │ ├── toast.tsx │ │ ├── toaster.tsx │ │ ├── toggle-group.tsx │ │ ├── toggle.tsx │ │ └── tooltip.tsx │ ├── env.example │ ├── hooks │ └── use-toast.ts │ ├── lib │ ├── auth.ts │ ├── constants.ts │ ├── conversations.ts │ ├── eventEmitter.ts │ ├── llm.ts │ ├── markdown.ts │ ├── messages.ts │ ├── services.ts │ ├── sesameApi.ts │ ├── sesameApiClient.ts │ ├── utils.ts │ ├── voice.ts │ └── workspaces.ts │ ├── middleware.ts │ ├── next.config.mjs │ ├── package-lock.json │ ├── package.json │ ├── postcss.config.mjs │ ├── public │ ├── ready.mp3 │ └── sw.js │ ├── tailwind.config.ts │ ├── tsconfig.json │ └── yarn.lock ├── deployment └── modal │ ├── modal_app.py │ └── requirements.txt ├── docs ├── CONTRIBUTING.md ├── PULL_REQUEST_TEMPLATE.md ├── authentication.md ├── database.md ├── render.png ├── sesame-banner.png ├── sesame-dashboard.png ├── sesame.png └── supabaseurl.png ├── schema ├── README.md ├── alembic.ini ├── migrations │ ├── env.py │ └── script.py.mako └── postgresql.sql └── sesame ├── .dockerignore ├── Dockerfile ├── __init__.py ├── bots ├── __init__.py ├── http │ ├── __init__.py │ ├── bot.py │ └── frame_serializer.py ├── persistent_context.py ├── requirements.txt ├── rtvi.py ├── rtvi_actions.py ├── rtvi_services.py ├── tasks │ └── summarize.py ├── types.py └── voice │ ├── __init__.py │ ├── bot.py │ ├── bot_error_pipeline.py │ ├── bot_pipeline_runner.py │ ├── bot_pipeline_vision.py │ └── bot_pipeline_voice.py ├── common ├── __init__.py ├── auth.py ├── database.py ├── encryption.py ├── errors.py ├── models.py ├── service_factory.py ├── storage.py └── utils │ ├── __init__.py │ └── llm.py ├── dev-requirements.txt ├── docker-compose.yml ├── env.example ├── pytest.ini ├── sesame.py ├── tests ├── conftest.py ├── requirements.txt ├── test_api.py ├── test_services.py └── test_user.py └── webapp ├── __init__.py ├── api ├── __init__.py ├── auth.py ├── conversations.py ├── rtvi.py ├── services.py ├── tokens.py └── workspaces.py ├── dashboard ├── error.html ├── index.html ├── layout.html ├── login.html ├── services.html └── tokens.html ├── integrations └── clerk.py ├── main.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | logs 2 | *.log 3 | .env 4 | env/ 5 | .env.** 6 | venv 7 | .venv 8 | .idea 9 | .DS_Store 10 | __pycache__/ 11 | .pytest_cache/ 12 | .vscode/ 13 | .vscode/** 14 | node_modules/ 15 | wrangler.toml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2024, Daily 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /clients/android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | .cxx 10 | local.properties 11 | -------------------------------------------------------------------------------- /clients/android/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2024, Daily 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /clients/android/README.md: -------------------------------------------------------------------------------- 1 | # Open Sesame Android 2 | 3 | Android client for the Open Sesame server. 4 | 5 | The app can be built using Gradle: 6 | 7 | ``` 8 | ./gradlew installDebug 9 | ``` 10 | 11 | You can also open the project directory in Android Studio using `File > Open`. 12 | 13 | Once running, you will be prompted for the URL of your Open Sesame backend, and the 14 | authorization key to use when connecting. 15 | 16 | screenshot -------------------------------------------------------------------------------- /clients/android/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.jetbrains.kotlin.android) apply false 3 | alias(libs.plugins.android.application) apply false 4 | alias(libs.plugins.compose.compiler) apply false 5 | } 6 | -------------------------------------------------------------------------------- /clients/android/files/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/files/screenshot.jpg -------------------------------------------------------------------------------- /clients/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. For more details, visit 12 | # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Kotlin code style for this project: "official" or "obsolete": 19 | kotlin.code.style=official 20 | # Enables namespacing of each library's R class so that its R class includes only the 21 | # resources declared in the library itself and none from the library's dependencies, 22 | # thereby reducing the size of the R class for that library 23 | android.nonTransitiveRClass=true -------------------------------------------------------------------------------- /clients/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /clients/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Aug 05 13:01:27 BST 2024 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /clients/android/open-sesame/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /clients/android/open-sesame/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/LoadingOverlay.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame 2 | 3 | import androidx.compose.foundation.background 4 | import androidx.compose.foundation.layout.Box 5 | import androidx.compose.foundation.layout.fillMaxSize 6 | import androidx.compose.foundation.layout.size 7 | import androidx.compose.material3.CircularProgressIndicator 8 | import androidx.compose.runtime.Composable 9 | import androidx.compose.ui.Alignment 10 | import androidx.compose.ui.Modifier 11 | import androidx.compose.ui.graphics.Color 12 | import androidx.compose.ui.unit.dp 13 | import co.daily.opensesame.ui.theme.Colors 14 | 15 | @Composable 16 | fun LoadingOverlay() { 17 | Box( 18 | modifier = Modifier 19 | .fillMaxSize() 20 | .background(Color.Black.copy(alpha = 0.5f)), 21 | contentAlignment = Alignment.Center 22 | ) { 23 | CircularProgressIndicator( 24 | modifier = Modifier.size(48.dp), 25 | color = Colors.white, 26 | strokeWidth = 4.dp 27 | ) 28 | } 29 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/RTVIApplication.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame 2 | 3 | import android.app.Application 4 | 5 | class RTVIApplication : Application() { 6 | override fun onCreate() { 7 | super.onCreate() 8 | Preferences.initAppStart(this) 9 | } 10 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/Screen.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame 2 | 3 | sealed interface Screen { 4 | 5 | data object Workspaces : Screen { 6 | override val precedence = 10 7 | } 8 | 9 | data object AppConfig : Screen { 10 | override val precedence = 20 11 | } 12 | 13 | data object CreateWorkspace : Screen { 14 | override val precedence = 30 15 | } 16 | 17 | data class Chat( 18 | val workspaceId: WorkspaceId, 19 | val initialConversationId: ConversationId? 20 | ) : Screen { 21 | override val precedence = 40 22 | } 23 | 24 | data class EditWorkspace( 25 | val workspaceId: WorkspaceId, 26 | val cameFrom: Screen 27 | ) : Screen { 28 | override val precedence = 50 29 | } 30 | 31 | val precedence: Int 32 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/api/DataApi.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.api 2 | 3 | import ai.rtvi.client.result.Future 4 | import co.daily.opensesame.Conversation 5 | import co.daily.opensesame.ConversationId 6 | import co.daily.opensesame.Message 7 | import co.daily.opensesame.Workspace 8 | import co.daily.opensesame.WorkspaceId 9 | import kotlinx.serialization.json.JsonObject 10 | 11 | interface DataApi { 12 | 13 | fun getWorkspaces(): Future, DataApiError> 14 | 15 | fun createWorkspace( 16 | title: String, 17 | config: JsonObject 18 | ): Future 19 | 20 | fun getWorkspace(id: WorkspaceId): Future 21 | 22 | fun updateWorkspace( 23 | id: WorkspaceId, 24 | newTitle: String, 25 | newConfig: JsonObject 26 | ): Future 27 | 28 | fun deleteWorkspace(id: WorkspaceId): Future 29 | 30 | fun getConversations( 31 | workspaceId: WorkspaceId, 32 | limit: Int, 33 | offset: Int 34 | ): Future, DataApiError> 35 | 36 | fun createConversation( 37 | workspaceId: WorkspaceId, 38 | title: String, 39 | languageCode: String 40 | ): Future 41 | 42 | fun updateConversation( 43 | conversationId: ConversationId, 44 | newTitle: String, 45 | ): Future 46 | 47 | fun deleteConversation(conversationId: ConversationId): Future 48 | 49 | fun getConversationMessages(conversationId: ConversationId): Future, DataApiError> 50 | } 51 | 52 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/api/DataApiError.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.api 2 | 3 | import androidx.compose.runtime.Immutable 4 | 5 | @Immutable 6 | sealed interface DataApiError { 7 | 8 | @Immutable 9 | data class BadStatusCode(val url: String, val status: Int, val body: String?) : DataApiError { 10 | override val description = "HTTP status $status for $url, body: '$body'" 11 | } 12 | 13 | @Immutable 14 | data class ExceptionThrown(val url: String, val e: Exception): DataApiError { 15 | override val description = "Exception thrown while fetching $url: $e" 16 | } 17 | 18 | @Immutable 19 | data class MissingResponseBody(val url: String): DataApiError { 20 | override val description = "Missing response body for $url" 21 | } 22 | 23 | @Immutable 24 | data class ConfigError(val message: String): DataApiError { 25 | override val description = "Config error: $message" 26 | } 27 | 28 | val description: String 29 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/chat/ChatMessageProcessor.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.chat 2 | 3 | import ai.rtvi.client.transport.MsgServerToClient 4 | import ai.rtvi.client.types.Transcript 5 | import androidx.compose.runtime.Immutable 6 | import co.daily.opensesame.MessageRole 7 | 8 | @Immutable 9 | interface ChatMessageProcessorHelper { 10 | 11 | fun appendOrCreateMessage( 12 | role: MessageRole, 13 | text: String, 14 | transcriptionFinal: Boolean 15 | ) 16 | 17 | fun finalizeMessage( 18 | role: MessageRole, 19 | replacementText: String? 20 | ) 21 | } 22 | 23 | @Immutable 24 | interface ChatMessageProcessor { 25 | 26 | fun onBotTTSStarted() {} 27 | 28 | fun onBotLLMStarted() {} 29 | 30 | fun onUserStartedSpeaking() {} 31 | 32 | fun onUserTranscript(data: Transcript) {} 33 | 34 | fun onBotLLMText(data: MsgServerToClient.Data.BotLLMTextData) {} 35 | 36 | fun onBotTTSText(data: MsgServerToClient.Data.BotTTSTextData) {} 37 | 38 | fun onStorageItemStored(content: String, role: MessageRole) {} 39 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/chat/ChatMessageProcessorTextMode.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.chat 2 | 3 | import ai.rtvi.client.transport.MsgServerToClient 4 | import androidx.compose.runtime.Immutable 5 | import co.daily.opensesame.MessageRole 6 | 7 | @Immutable 8 | class ChatMessageProcessorTextMode( 9 | private val helper: ChatMessageProcessorHelper 10 | ) : ChatMessageProcessor { 11 | 12 | override fun onBotLLMStarted() { 13 | helper.finalizeMessage( 14 | role = MessageRole.Assistant, 15 | replacementText = null, 16 | ) 17 | } 18 | 19 | override fun onBotLLMText(data: MsgServerToClient.Data.BotLLMTextData) { 20 | helper.appendOrCreateMessage( 21 | role = MessageRole.Assistant, 22 | text = data.text, 23 | transcriptionFinal = true 24 | ) 25 | } 26 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/chat/ChatMessageProcessorVoiceModeConversational.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.chat 2 | 3 | import ai.rtvi.client.transport.MsgServerToClient 4 | import ai.rtvi.client.types.Transcript 5 | import androidx.compose.runtime.Immutable 6 | import co.daily.opensesame.MessageRole 7 | 8 | @Immutable 9 | class ChatMessageProcessorVoiceModeConversational( 10 | private val helper: ChatMessageProcessorHelper 11 | ) : ChatMessageProcessor { 12 | 13 | override fun onUserStartedSpeaking() { 14 | helper.finalizeMessage(MessageRole.User, replacementText = null) 15 | } 16 | 17 | override fun onUserTranscript(data: Transcript) { 18 | if (data.final) { 19 | helper.appendOrCreateMessage( 20 | role = MessageRole.User, 21 | text = data.text, 22 | transcriptionFinal = true 23 | ) 24 | } 25 | } 26 | 27 | override fun onBotTTSStarted() { 28 | helper.finalizeMessage(MessageRole.Assistant, replacementText = null) 29 | } 30 | 31 | override fun onBotTTSText(data: MsgServerToClient.Data.BotTTSTextData) { 32 | helper.appendOrCreateMessage( 33 | role = MessageRole.Assistant, 34 | text = data.text + " ", 35 | transcriptionFinal = true 36 | ) 37 | } 38 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/chat/ChatMessageProcessorVoiceModeInformational.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.chat 2 | 3 | import ai.rtvi.client.transport.MsgServerToClient 4 | import ai.rtvi.client.types.Transcript 5 | import androidx.compose.runtime.Immutable 6 | import co.daily.opensesame.MessageRole 7 | 8 | @Immutable 9 | class ChatMessageProcessorVoiceModeInformational( 10 | private val helper: ChatMessageProcessorHelper 11 | ) : ChatMessageProcessor { 12 | 13 | override fun onUserStartedSpeaking() { 14 | helper.finalizeMessage(MessageRole.User, replacementText = null) 15 | } 16 | 17 | override fun onUserTranscript(data: Transcript) { 18 | if (data.final) { 19 | helper.appendOrCreateMessage( 20 | role = MessageRole.User, 21 | text = data.text, 22 | transcriptionFinal = true 23 | ) 24 | } 25 | } 26 | 27 | override fun onBotLLMStarted() { 28 | helper.finalizeMessage( 29 | role = MessageRole.Assistant, 30 | replacementText = null, 31 | ) 32 | } 33 | 34 | override fun onBotLLMText(data: MsgServerToClient.Data.BotLLMTextData) { 35 | helper.appendOrCreateMessage( 36 | role = MessageRole.Assistant, 37 | text = data.text, 38 | transcriptionFinal = true 39 | ) 40 | } 41 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/ui/Common.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.ui 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.runtime.Immutable 5 | import androidx.compose.ui.Modifier 6 | 7 | @Composable 8 | fun Modifier.applyIfNotNull(value: E?, action: @Composable Modifier.(E) -> Modifier): Modifier { 9 | return action(value ?: return this) 10 | } 11 | @Composable 12 | fun Modifier.applyIf(condition: Boolean, action: @Composable Modifier.() -> Modifier): Modifier { 13 | return if (condition) action(this) else this 14 | } 15 | 16 | @JvmInline 17 | @Immutable 18 | value class ImmutableMarker(val value: E) -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/ui/ErrorDialog.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.ui 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.tooling.preview.Preview 5 | 6 | @Composable 7 | fun ErrorDialog( 8 | onDismissRequest: () -> Unit, 9 | text: String 10 | ) { 11 | Dialog( 12 | onDismissRequest = onDismissRequest, 13 | title = "Error", 14 | text = text, 15 | buttons = { 16 | DialogButton( 17 | onClick = onDismissRequest, 18 | text = "Close" 19 | ) 20 | } 21 | ) 22 | } 23 | 24 | @Composable 25 | @Preview 26 | private fun PreviewErrorDialog() { 27 | AppContextPreview { 28 | ErrorDialog(onDismissRequest = {}, text = "Preview error message") 29 | } 30 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/ui/Logo.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.ui 2 | 3 | import co.daily.opensesame.R 4 | import co.daily.opensesame.ui.theme.Colors 5 | import androidx.compose.foundation.Image 6 | import androidx.compose.foundation.background 7 | import androidx.compose.foundation.border 8 | import androidx.compose.foundation.layout.Box 9 | import androidx.compose.foundation.layout.size 10 | import androidx.compose.foundation.shape.RoundedCornerShape 11 | import androidx.compose.runtime.Composable 12 | import androidx.compose.ui.Alignment 13 | import androidx.compose.ui.Modifier 14 | import androidx.compose.ui.draw.clip 15 | import androidx.compose.ui.draw.shadow 16 | import androidx.compose.ui.graphics.Color 17 | import androidx.compose.ui.res.painterResource 18 | import androidx.compose.ui.tooling.preview.Preview 19 | import androidx.compose.ui.unit.dp 20 | 21 | @Composable 22 | fun Logo(modifier: Modifier) { 23 | 24 | val shape = RoundedCornerShape(12.dp) 25 | 26 | Box( 27 | modifier = modifier 28 | .size(64.dp) 29 | .shadow(5.dp, shape) 30 | .border(1.dp, Colors.logoBorder, shape) 31 | .clip(shape) 32 | .background(Color.White), 33 | contentAlignment = Alignment.Center 34 | ) { 35 | Image( 36 | modifier = Modifier.size(40.dp, 44.dp), 37 | painter = painterResource(id = R.drawable.logo), 38 | contentDescription = "RTVI" 39 | ) 40 | } 41 | } 42 | 43 | @Composable 44 | @Preview 45 | fun PreviewLogo() { 46 | Logo(Modifier) 47 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/ui/ToolbarIconButton.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.ui 2 | 3 | import androidx.annotation.DrawableRes 4 | import androidx.compose.foundation.clickable 5 | import androidx.compose.foundation.layout.Box 6 | import androidx.compose.foundation.layout.padding 7 | import androidx.compose.foundation.layout.size 8 | import androidx.compose.foundation.shape.RoundedCornerShape 9 | import androidx.compose.material3.Icon 10 | import androidx.compose.runtime.Composable 11 | import androidx.compose.ui.Modifier 12 | import androidx.compose.ui.draw.clip 13 | import androidx.compose.ui.graphics.Color 14 | import androidx.compose.ui.res.painterResource 15 | import androidx.compose.ui.unit.dp 16 | 17 | @Composable 18 | fun ToolbarIconButton( 19 | onClick: () -> Unit, 20 | @DrawableRes icon: Int, 21 | color: Color, 22 | contentDescription: String, 23 | ) { 24 | Box( 25 | Modifier 26 | .clip(RoundedCornerShape(6.dp)) 27 | .clickable(onClick = onClick) 28 | .padding(8.dp) 29 | ) { 30 | Icon( 31 | modifier = Modifier.size(24.dp), 32 | painter = painterResource(icon), 33 | contentDescription = contentDescription, 34 | tint = color 35 | ) 36 | } 37 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/ui/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.ui.theme 2 | 3 | import androidx.compose.material3.Text 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.Modifier 6 | import androidx.compose.ui.graphics.Color 7 | import androidx.compose.ui.text.TextStyle 8 | import androidx.compose.ui.text.font.Font 9 | import androidx.compose.ui.text.font.FontFamily 10 | import androidx.compose.ui.text.style.TextAlign 11 | import androidx.compose.ui.text.style.TextOverflow 12 | import co.daily.opensesame.R 13 | 14 | object TextStyles { 15 | val base = TextStyle(fontFamily = FontFamily(Font(R.font.dm_sans))) 16 | val mono = TextStyle(fontFamily = FontFamily(Font(R.font.dm_mono_medium))) 17 | } 18 | 19 | @Composable 20 | fun TextStyle.StyledText( 21 | text: String, 22 | modifier: Modifier = Modifier, 23 | overflow: TextOverflow = TextOverflow.Clip, 24 | maxLines: Int = Int.MAX_VALUE, 25 | textAlign: TextAlign = TextAlign.Left, 26 | color: Color = this.color, 27 | ) { 28 | Text( 29 | modifier = modifier, 30 | text = text, 31 | style = this, 32 | color = color, 33 | fontSize = fontSize, 34 | fontWeight = fontWeight, 35 | letterSpacing = letterSpacing, 36 | overflow = overflow, 37 | maxLines = maxLines, 38 | textAlign = textAlign 39 | ) 40 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/utils/JsonUtils.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.utils 2 | 3 | import ai.rtvi.client.result.Future 4 | import co.daily.opensesame.api.DataApiError 5 | import kotlinx.serialization.KSerializer 6 | import kotlinx.serialization.json.Json 7 | import okhttp3.MediaType.Companion.toMediaType 8 | import okhttp3.RequestBody 9 | import okhttp3.RequestBody.Companion.toRequestBody 10 | 11 | val JSON_INSTANCE = Json { ignoreUnknownKeys = true } 12 | 13 | inline fun E.toJsonBody(serializer: KSerializer): RequestBody = 14 | JSON_INSTANCE.encodeToString(serializer, this).toRequestBody("application/json".toMediaType()) 15 | 16 | // TODO handle deserialization exception 17 | inline fun Future.mapDeserialize(): Future = 18 | map { JSON_INSTANCE.decodeFromString(it) } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/utils/MutexData.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.utils 2 | 3 | class MutexData(initial: E) { 4 | 5 | private val lock = Object() 6 | private val value: E = initial 7 | 8 | fun lock(action: E.() -> R): R { 9 | return synchronized(lock) { 10 | action(value) 11 | } 12 | } 13 | } 14 | 15 | class MutexReplaceableData(initial: E) { 16 | 17 | interface Scope { 18 | var value: E 19 | } 20 | 21 | private val lock = Object() 22 | private var data: E = initial 23 | 24 | fun lock(action: Scope.() -> R): R { 25 | return synchronized(lock) { 26 | action(object : Scope { 27 | override var value 28 | get() = data 29 | set(newValue) { 30 | data = newValue 31 | } 32 | }) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/java/co/daily/opensesame/utils/RealTimeClock.kt: -------------------------------------------------------------------------------- 1 | package co.daily.opensesame.utils 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.runtime.collectAsState 5 | import kotlinx.coroutines.delay 6 | import kotlinx.coroutines.flow.flow 7 | import java.time.Duration 8 | 9 | private val rtcFlowSecs = flow { 10 | while(true) { 11 | val now = Timestamp.now().toEpochMilli() 12 | 13 | val rounded = ((now + 500) / 1000) * 1000 14 | emit(Timestamp.ofEpochMilli(rounded)) 15 | 16 | val target = rounded + 1000 17 | delay(target - now) 18 | } 19 | } 20 | 21 | @Composable 22 | fun rtcStateSecs() = rtcFlowSecs.collectAsState(initial = Timestamp.now()) 23 | 24 | private val rtcFlowHours = flow { 25 | while(true) { 26 | val now = Timestamp.now() 27 | 28 | val rounded = now.roundToNearestHour() 29 | emit(rounded) 30 | 31 | val target = rounded + Duration.ofHours(1) 32 | delay((target - now).toMillis()) 33 | } 34 | } 35 | 36 | @Composable 37 | fun rtcStateHours() = rtcFlowHours.collectAsState(initial = Timestamp.now().roundToNearestHour()) 38 | 39 | private val rtcFlowMins = flow { 40 | while(true) { 41 | val now = Timestamp.now() 42 | 43 | val rounded = now.roundToNearestMinute() 44 | emit(rounded) 45 | 46 | val target = rounded + Duration.ofMinutes(1) 47 | delay((target - now).toMillis()) 48 | } 49 | } 50 | 51 | @Composable 52 | fun rtcStateMins() = rtcFlowMins.collectAsState(initial = Timestamp.now().roundToNearestMinute()) 53 | 54 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/add_box.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 27 | 28 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/alert_circle_outline.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/camera.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/cellphone_cog.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/chevron_down.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/chevron_right.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/close.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/cog.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/console.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/dropdown_unfold.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/edit.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/form_textbox_password.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/frame.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/image.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/key.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/keyboard.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/drawable/logo.png -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/logout.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/menu.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/mic_on.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/microphone.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/microphone_off.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/moon_waning_crescent.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/phone_hangup.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/qrcode_scan.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/settings.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/speech.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/timer_outline.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/unfold_more.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/video.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/video_off.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/weather_sunny.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/drawable/workspaces.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 27 | 34 | 35 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/font/dm_mono_medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/font/dm_mono_medium.ttf -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/font/dm_sans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/font/dm_sans.ttf -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/font/inter.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/font/inter.ttf -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/font/sf_pro_medium.OTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/font/sf_pro_medium.OTF -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipecat-ai/open-sesame/00802245a7853ca71d715b9f433fb776270fa100/clients/android/open-sesame/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Open Sesame 3 | -------------------------------------------------------------------------------- /clients/android/open-sesame/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |