From 0130a7b83d2f8a86fff384244ff40d520994c3e2 Mon Sep 17 00:00:00 2001 From: YanceyOfficial Date: Tue, 11 Mar 2025 18:18:48 +0800 Subject: [PATCH 01/12] feat: migrate to next.js --- .eslintrc.json | 43 - .github/FUNDING.yml | 12 - .github/ISSUE_TEMPLATE/bug_report.md | 32 - .github/PULL_REQUEST_TEMPLATE.md | 26 - .github/dependabot.yml | 23 - .github/workflows/cross-platform-release.yml | 70 - .github/workflows/cross-platform-test.yml | 60 - .github/workflows/release-please.yml | 24 - .github/workflows/slack-notify.yml | 17 - .gitignore | 56 +- .husky/pre-commit | 1 - .lintstagedrc.js | 3 - .npmrc | 4 +- .vscode/extensions.json | 3 - .vscode/settings.json | 12 - AUTHORS | 6 - CHANGELOG.md | 266 - CODE_OF_CONDUCT.md | 45 - CONTRIBUTING.md | 29 - LICENSE | 21 - README.md | 104 +- SECURITY.md | 7 - app/(chat)/actions.ts | 22 + app/(chat)/api/chat/route.ts | 123 + app/(chat)/api/document/route.ts | 103 + app/(chat)/api/files/upload/route.ts | 91 + app/(chat)/api/history/route.ts | 6 + app/(chat)/api/setting/route.ts | 15 + app/(chat)/api/suggestions/route.ts | 33 + app/(chat)/api/upload-pdf/route.ts | 0 app/(chat)/api/vote/route.ts | 48 + app/(chat)/chat/[id]/page.tsx | 22 + app/layout.tsx | 75 + app/page.tsx | 7 + components.json | 21 + .../chatbox/attatch/attachemnt-uploader.tsx | 68 + .../chatbox/attatch/attachment-previewer.tsx | 73 + .../chatbox/attatch/recorder.tsx | 53 +- components/chatbox/attatch/token-count.tsx | 25 + components/chatbox/attatch/tool-box.tsx | 51 + .../chatbox/attatch/wave-form.tsx | 41 +- components/chatbox/chat-bubble.tsx | 56 + components/chatbox/chat.tsx | 66 + components/chatbox/config.tsx | 263 + components/chatbox/markdown.tsx | 59 + .../chatbox/message-spinner.tsx | 0 components/chatbox/messages.tsx | 47 + components/chatbox/multimodel-input.tsx | 133 + .../common/emoji-picker.tsx | 2 +- components/common/input-slider.tsx | 105 + components/common/search-form.tsx | 24 + components/common/team-switcher.tsx | 77 + components/common/theme-provider.tsx | 11 + components/layout/app-sidebar.tsx | 57 + components/layout/nav-actions.tsx | 38 + components/layout/nav-histories.tsx | 215 + components/layout/nav-main.tsx | 35 + components/layout/nav-secondary.tsx | 34 + components/setting/settings-dialog.tsx | 55 + components/setting/settings-form.tsx | 315 + components/setting/settings-sidebar.tsx | 85 + components/setting/siderbar-data.ts | 40 + components/ui/avatar.tsx | 51 + components/ui/badge.tsx | 45 + components/ui/breadcrumb.tsx | 109 + components/ui/button.tsx | 58 + components/ui/card.tsx | 67 + components/ui/collapsible.tsx | 31 + components/ui/dialog.tsx | 135 + components/ui/dropdown-menu.tsx | 257 + components/ui/form.tsx | 175 + components/ui/input.tsx | 21 + components/ui/label.tsx | 21 + components/ui/popover.tsx | 48 + components/ui/radio-group.tsx | 45 + components/ui/select.tsx | 178 + components/ui/separator.tsx | 26 + components/ui/sheet.tsx | 139 + components/ui/sidebar.tsx | 723 + components/ui/skeleton.tsx | 13 + components/ui/slider.tsx | 30 + components/ui/sonner.tsx | 29 + components/ui/textarea.tsx | 17 + components/ui/toggle-group.tsx | 58 + components/ui/toggle.tsx | 44 + components/ui/tooltip.tsx | 59 + docker-compose.yml | 12 + drizzle.config.ts | 11 + eslint.config.mjs | 16 + hooks/use-mobile.ts | 19 + hooks/use-setting.ts | 27 + index.html | 14 - lib/ai/models.ts | 5 + lib/ai/prompts.ts | 21 + lib/ai/providers.ts | 35 + lib/ai/rag/embeddings.ts | 29 + lib/ai/rag/index.ts | 18 + lib/ai/rag/loaders.ts | 7 + lib/ai/rag/splitters.ts | 28 + lib/ai/tools/calculator.tsx | 26 + lib/ai/tools/find-way.tsx | 0 lib/ai/tools/generate-image.tsx | 0 lib/ai/tools/get-currency-rate.tsx | 701 + lib/ai/tools/get-date.tsx | 22 + lib/ai/tools/get-weather.tsx | 43 + lib/ai/tools/retrieve-using-rag.tsx | 26 + lib/ai/tools/search-online.tsx | 33 + lib/ai/tools/web-scraper.tsx | 30 + lib/db/migrate.ts | 26 + lib/db/migrations/0000_wooden_blindfold.sql | 42 + .../migrations/0001_dizzy_cassandra_nova.sql | 1 + lib/db/migrations/meta/0000_snapshot.json | 268 + lib/db/migrations/meta/0001_snapshot.json | 268 + lib/db/migrations/meta/_journal.json | 20 + lib/db/queries.ts | 178 + lib/db/schema.ts | 73 + lib/utils.ts | 243 + next.config.ts | 7 + package.json | 150 +- pnpm-lock.yaml | 14681 +++++++++------- postcss.config.js | 6 - postcss.config.mjs | 5 + public/favicon.ico | Bin 0 -> 25931 bytes public/file.svg | 1 + public/globe.svg | 1 + public/next.svg | 1 + public/stylesheets/globals.css | 194 + public/stylesheets/weather.css | 2129 +++ public/vercel.svg | 1 + public/window.svg | 1 + screenshots/can't-be-oepn-in-macos.png | Bin 60173 -> 0 bytes screenshots/chat-completion.png | Bin 1093174 -> 0 bytes src-tauri/.gitignore | 4 - src-tauri/Cargo.lock | 4591 ----- src-tauri/Cargo.toml | 28 - src-tauri/Info.plist | 8 - src-tauri/build.rs | 3 - src-tauri/capabilities/desktop.json | 11 - src-tauri/capabilities/migrated.json | 28 - src-tauri/gen/schemas/acl-manifests.json | 1 - src-tauri/gen/schemas/capabilities.json | 1 - src-tauri/gen/schemas/desktop-schema.json | 5031 ------ src-tauri/gen/schemas/macOS-schema.json | 5031 ------ src-tauri/icons/128x128.png | Bin 5373 -> 0 bytes src-tauri/icons/128x128@2x.png | Bin 9733 -> 0 bytes src-tauri/icons/32x32.png | Bin 3427 -> 0 bytes src-tauri/icons/Square107x107Logo.png | Bin 4677 -> 0 bytes src-tauri/icons/Square142x142Logo.png | Bin 5825 -> 0 bytes src-tauri/icons/Square150x150Logo.png | Bin 6307 -> 0 bytes src-tauri/icons/Square284x284Logo.png | Bin 11279 -> 0 bytes src-tauri/icons/Square30x30Logo.png | Bin 1852 -> 0 bytes src-tauri/icons/Square310x310Logo.png | Bin 12419 -> 0 bytes src-tauri/icons/Square44x44Logo.png | Bin 2285 -> 0 bytes src-tauri/icons/Square71x71Logo.png | Bin 3309 -> 0 bytes src-tauri/icons/Square89x89Logo.png | Bin 3959 -> 0 bytes src-tauri/icons/StoreLogo.png | Bin 2463 -> 0 bytes src-tauri/icons/icon.icns | Bin 88126 -> 0 bytes src-tauri/icons/icon.ico | Bin 182976 -> 0 bytes src-tauri/icons/icon.png | Bin 32828 -> 0 bytes src-tauri/src/main.rs | 18 - src-tauri/tauri.conf.json | 58 - src/assets/chatbot.png | Bin 32828 -> 0 bytes src/assets/chatgpt-avatar.png | Bin 145390 -> 0 bytes src/assets/illustrations/no-data.svg | 1 - src/assets/lotties/recorder.json | 566 - src/components/Avatar/index.tsx | 26 - src/components/ChatBox/ChatBubble.tsx | 61 - src/components/ChatBox/ChatMessages.tsx | 169 - src/components/ChatBox/ContactHeader.tsx | 206 - src/components/ChatBox/InputBox.tsx | 269 - src/components/ChatBox/Markdown.tsx | 153 - src/components/ChatBox/MediaUploader.tsx | 92 - src/components/ChatBox/index.tsx | 18 - .../Configuration/AudioTranscription.tsx | 185 - .../Configuration/AudioTranslation.tsx | 131 - .../Configuration/ChatCompletion.tsx | 223 - src/components/Configuration/Completion.tsx | 274 - .../Configuration/ConfigurationWrapper.tsx | 76 - .../Configuration/ImageGeneration.tsx | 144 - src/components/Configuration/index.ts | 13 - .../ConversationList/ConversationItem.tsx | 69 - src/components/ConversationList/EmptyItem.tsx | 25 - .../ConversationList/ItemWrapper.tsx | 28 - src/components/ConversationList/index.tsx | 89 - src/components/Divider/index.tsx | 22 - src/components/Icons/AzureLogoIcon.tsx | 81 - src/components/Icons/LoadingIcon.tsx | 33 - src/components/Icons/OpenAILogoIcon.tsx | 32 - src/components/Icons/OutlinePlusIcon.tsx | 27 - .../Icons/OutlineTranslationIcon.tsx | 24 - src/components/Icons/SolidCloseIcon.tsx | 27 - src/components/Icons/SolidSendIcon.tsx | 27 - .../Icons/SolidSettingsBrightnessIcon.tsx | 23 - src/components/Icons/SolidTranslationIcon.tsx | 21 - src/components/Icons/index.tsx | 21 - src/components/ImportAndExportDexie/index.tsx | 81 - src/components/InputSlider/index.tsx | 109 - src/components/Loading/index.tsx | 24 - src/components/Sidebar/Items.tsx | 60 - src/components/Sidebar/index.tsx | 98 - src/configurations/audioTranscription.ts | 17 - src/configurations/audioTranslation.ts | 12 - src/configurations/chatCompletion.ts | 46 - src/configurations/completion.ts | 42 - src/configurations/imageGeneration.ts | 24 - src/configurations/index.ts | 36 - src/containers/Conversation/index.tsx | 48 - src/containers/Settings/index.tsx | 371 - src/db/index.ts | 19 - src/hooks/index.ts | 27 - src/hooks/useAppData.ts | 43 - src/hooks/useAudio.ts | 178 - src/hooks/useChatCompletion.ts | 312 - src/hooks/useClients.ts | 29 - src/hooks/useCompletion.ts | 114 - src/hooks/useDB.ts | 63 - src/hooks/useImageGeneration.ts | 94 - src/hooks/useOnline.ts | 26 - src/hooks/useSettings.ts | 106 - src/hooks/useSpeech.ts | 73 - src/hooks/useStoreMessages.ts | 167 - src/hooks/useTheme.ts | 79 - src/layouts/index.tsx | 50 - src/main.tsx | 16 - src/routers/index.ts | 15 - src/shared/constants.ts | 24 - src/shared/countries.ts | 424 - src/shared/utils.ts | 67 - src/stores/conversation.ts | 44 - src/stores/global.ts | 25 - src/stores/settings.ts | 7 - src/styles.css | 31 - src/types/conversation.ts | 51 - src/types/settings.ts | 20 - src/vite-env.d.ts | 1 - stores/conversation.ts | 20 + stores/global.ts | 10 + stores/settings.ts | 3 + tailwind.config.js | 86 - tsconfig.json | 49 +- tsconfig.node.json | 9 - types/conversation.ts | 72 + {src/types => types}/global.ts | 17 +- types/index.ts | 51 + types/settings.ts | 15 + vite.config.ts | 38 - 246 files changed, 18606 insertions(+), 28062 deletions(-) delete mode 100644 .eslintrc.json delete mode 100644 .github/FUNDING.yml delete mode 100755 .github/ISSUE_TEMPLATE/bug_report.md delete mode 100755 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/cross-platform-release.yml delete mode 100644 .github/workflows/cross-platform-test.yml delete mode 100644 .github/workflows/release-please.yml delete mode 100644 .github/workflows/slack-notify.yml delete mode 100755 .husky/pre-commit delete mode 100644 .lintstagedrc.js delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/settings.json delete mode 100644 AUTHORS delete mode 100644 CHANGELOG.md delete mode 100755 CODE_OF_CONDUCT.md delete mode 100755 CONTRIBUTING.md delete mode 100644 LICENSE delete mode 100644 SECURITY.md create mode 100644 app/(chat)/actions.ts create mode 100644 app/(chat)/api/chat/route.ts create mode 100644 app/(chat)/api/document/route.ts create mode 100644 app/(chat)/api/files/upload/route.ts create mode 100644 app/(chat)/api/history/route.ts create mode 100644 app/(chat)/api/setting/route.ts create mode 100644 app/(chat)/api/suggestions/route.ts create mode 100644 app/(chat)/api/upload-pdf/route.ts create mode 100644 app/(chat)/api/vote/route.ts create mode 100644 app/(chat)/chat/[id]/page.tsx create mode 100644 app/layout.tsx create mode 100644 app/page.tsx create mode 100644 components.json create mode 100644 components/chatbox/attatch/attachemnt-uploader.tsx create mode 100644 components/chatbox/attatch/attachment-previewer.tsx rename src/components/ChatBox/Recorder.tsx => components/chatbox/attatch/recorder.tsx (60%) create mode 100644 components/chatbox/attatch/token-count.tsx create mode 100644 components/chatbox/attatch/tool-box.tsx rename src/components/Waveform/index.tsx => components/chatbox/attatch/wave-form.tsx (65%) create mode 100644 components/chatbox/chat-bubble.tsx create mode 100644 components/chatbox/chat.tsx create mode 100644 components/chatbox/config.tsx create mode 100644 components/chatbox/markdown.tsx rename src/components/ChatBox/MessageSpinner.tsx => components/chatbox/message-spinner.tsx (100%) create mode 100644 components/chatbox/messages.tsx create mode 100644 components/chatbox/multimodel-input.tsx rename src/components/EmojiPicker/index.tsx => components/common/emoji-picker.tsx (87%) create mode 100644 components/common/input-slider.tsx create mode 100644 components/common/search-form.tsx create mode 100644 components/common/team-switcher.tsx create mode 100644 components/common/theme-provider.tsx create mode 100644 components/layout/app-sidebar.tsx create mode 100644 components/layout/nav-actions.tsx create mode 100644 components/layout/nav-histories.tsx create mode 100644 components/layout/nav-main.tsx create mode 100644 components/layout/nav-secondary.tsx create mode 100644 components/setting/settings-dialog.tsx create mode 100644 components/setting/settings-form.tsx create mode 100644 components/setting/settings-sidebar.tsx create mode 100644 components/setting/siderbar-data.ts create mode 100644 components/ui/avatar.tsx create mode 100644 components/ui/badge.tsx create mode 100644 components/ui/breadcrumb.tsx create mode 100644 components/ui/button.tsx create mode 100644 components/ui/card.tsx create mode 100644 components/ui/collapsible.tsx create mode 100644 components/ui/dialog.tsx create mode 100644 components/ui/dropdown-menu.tsx create mode 100644 components/ui/form.tsx create mode 100644 components/ui/input.tsx create mode 100644 components/ui/label.tsx create mode 100644 components/ui/popover.tsx create mode 100644 components/ui/radio-group.tsx create mode 100644 components/ui/select.tsx create mode 100644 components/ui/separator.tsx create mode 100644 components/ui/sheet.tsx create mode 100644 components/ui/sidebar.tsx create mode 100644 components/ui/skeleton.tsx create mode 100644 components/ui/slider.tsx create mode 100644 components/ui/sonner.tsx create mode 100644 components/ui/textarea.tsx create mode 100644 components/ui/toggle-group.tsx create mode 100644 components/ui/toggle.tsx create mode 100644 components/ui/tooltip.tsx create mode 100644 docker-compose.yml create mode 100644 drizzle.config.ts create mode 100644 eslint.config.mjs create mode 100644 hooks/use-mobile.ts create mode 100644 hooks/use-setting.ts delete mode 100644 index.html create mode 100644 lib/ai/models.ts create mode 100644 lib/ai/prompts.ts create mode 100644 lib/ai/providers.ts create mode 100644 lib/ai/rag/embeddings.ts create mode 100644 lib/ai/rag/index.ts create mode 100644 lib/ai/rag/loaders.ts create mode 100644 lib/ai/rag/splitters.ts create mode 100644 lib/ai/tools/calculator.tsx create mode 100644 lib/ai/tools/find-way.tsx create mode 100644 lib/ai/tools/generate-image.tsx create mode 100644 lib/ai/tools/get-currency-rate.tsx create mode 100644 lib/ai/tools/get-date.tsx create mode 100644 lib/ai/tools/get-weather.tsx create mode 100644 lib/ai/tools/retrieve-using-rag.tsx create mode 100644 lib/ai/tools/search-online.tsx create mode 100644 lib/ai/tools/web-scraper.tsx create mode 100644 lib/db/migrate.ts create mode 100644 lib/db/migrations/0000_wooden_blindfold.sql create mode 100644 lib/db/migrations/0001_dizzy_cassandra_nova.sql create mode 100644 lib/db/migrations/meta/0000_snapshot.json create mode 100644 lib/db/migrations/meta/0001_snapshot.json create mode 100644 lib/db/migrations/meta/_journal.json create mode 100644 lib/db/queries.ts create mode 100644 lib/db/schema.ts create mode 100644 lib/utils.ts create mode 100644 next.config.ts delete mode 100644 postcss.config.js create mode 100644 postcss.config.mjs create mode 100644 public/favicon.ico create mode 100644 public/file.svg create mode 100644 public/globe.svg create mode 100644 public/next.svg create mode 100644 public/stylesheets/globals.css create mode 100644 public/stylesheets/weather.css create mode 100644 public/vercel.svg create mode 100644 public/window.svg delete mode 100644 screenshots/can't-be-oepn-in-macos.png delete mode 100644 screenshots/chat-completion.png delete mode 100644 src-tauri/.gitignore delete mode 100644 src-tauri/Cargo.lock delete mode 100644 src-tauri/Cargo.toml delete mode 100644 src-tauri/Info.plist delete mode 100644 src-tauri/build.rs delete mode 100644 src-tauri/capabilities/desktop.json delete mode 100644 src-tauri/capabilities/migrated.json delete mode 100644 src-tauri/gen/schemas/acl-manifests.json delete mode 100644 src-tauri/gen/schemas/capabilities.json delete mode 100644 src-tauri/gen/schemas/desktop-schema.json delete mode 100644 src-tauri/gen/schemas/macOS-schema.json delete mode 100644 src-tauri/icons/128x128.png delete mode 100644 src-tauri/icons/128x128@2x.png delete mode 100644 src-tauri/icons/32x32.png delete mode 100644 src-tauri/icons/Square107x107Logo.png delete mode 100644 src-tauri/icons/Square142x142Logo.png delete mode 100644 src-tauri/icons/Square150x150Logo.png delete mode 100644 src-tauri/icons/Square284x284Logo.png delete mode 100644 src-tauri/icons/Square30x30Logo.png delete mode 100644 src-tauri/icons/Square310x310Logo.png delete mode 100644 src-tauri/icons/Square44x44Logo.png delete mode 100644 src-tauri/icons/Square71x71Logo.png delete mode 100644 src-tauri/icons/Square89x89Logo.png delete mode 100644 src-tauri/icons/StoreLogo.png delete mode 100644 src-tauri/icons/icon.icns delete mode 100644 src-tauri/icons/icon.ico delete mode 100644 src-tauri/icons/icon.png delete mode 100644 src-tauri/src/main.rs delete mode 100644 src-tauri/tauri.conf.json delete mode 100644 src/assets/chatbot.png delete mode 100644 src/assets/chatgpt-avatar.png delete mode 100644 src/assets/illustrations/no-data.svg delete mode 100644 src/assets/lotties/recorder.json delete mode 100644 src/components/Avatar/index.tsx delete mode 100644 src/components/ChatBox/ChatBubble.tsx delete mode 100644 src/components/ChatBox/ChatMessages.tsx delete mode 100644 src/components/ChatBox/ContactHeader.tsx delete mode 100644 src/components/ChatBox/InputBox.tsx delete mode 100644 src/components/ChatBox/Markdown.tsx delete mode 100644 src/components/ChatBox/MediaUploader.tsx delete mode 100644 src/components/ChatBox/index.tsx delete mode 100644 src/components/Configuration/AudioTranscription.tsx delete mode 100644 src/components/Configuration/AudioTranslation.tsx delete mode 100644 src/components/Configuration/ChatCompletion.tsx delete mode 100644 src/components/Configuration/Completion.tsx delete mode 100644 src/components/Configuration/ConfigurationWrapper.tsx delete mode 100644 src/components/Configuration/ImageGeneration.tsx delete mode 100644 src/components/Configuration/index.ts delete mode 100644 src/components/ConversationList/ConversationItem.tsx delete mode 100644 src/components/ConversationList/EmptyItem.tsx delete mode 100644 src/components/ConversationList/ItemWrapper.tsx delete mode 100644 src/components/ConversationList/index.tsx delete mode 100644 src/components/Divider/index.tsx delete mode 100644 src/components/Icons/AzureLogoIcon.tsx delete mode 100644 src/components/Icons/LoadingIcon.tsx delete mode 100644 src/components/Icons/OpenAILogoIcon.tsx delete mode 100644 src/components/Icons/OutlinePlusIcon.tsx delete mode 100644 src/components/Icons/OutlineTranslationIcon.tsx delete mode 100644 src/components/Icons/SolidCloseIcon.tsx delete mode 100644 src/components/Icons/SolidSendIcon.tsx delete mode 100644 src/components/Icons/SolidSettingsBrightnessIcon.tsx delete mode 100644 src/components/Icons/SolidTranslationIcon.tsx delete mode 100644 src/components/Icons/index.tsx delete mode 100644 src/components/ImportAndExportDexie/index.tsx delete mode 100644 src/components/InputSlider/index.tsx delete mode 100644 src/components/Loading/index.tsx delete mode 100644 src/components/Sidebar/Items.tsx delete mode 100644 src/components/Sidebar/index.tsx delete mode 100644 src/configurations/audioTranscription.ts delete mode 100644 src/configurations/audioTranslation.ts delete mode 100644 src/configurations/chatCompletion.ts delete mode 100644 src/configurations/completion.ts delete mode 100644 src/configurations/imageGeneration.ts delete mode 100644 src/configurations/index.ts delete mode 100644 src/containers/Conversation/index.tsx delete mode 100644 src/containers/Settings/index.tsx delete mode 100644 src/db/index.ts delete mode 100644 src/hooks/index.ts delete mode 100644 src/hooks/useAppData.ts delete mode 100644 src/hooks/useAudio.ts delete mode 100644 src/hooks/useChatCompletion.ts delete mode 100644 src/hooks/useClients.ts delete mode 100644 src/hooks/useCompletion.ts delete mode 100644 src/hooks/useDB.ts delete mode 100644 src/hooks/useImageGeneration.ts delete mode 100644 src/hooks/useOnline.ts delete mode 100644 src/hooks/useSettings.ts delete mode 100644 src/hooks/useSpeech.ts delete mode 100644 src/hooks/useStoreMessages.ts delete mode 100644 src/hooks/useTheme.ts delete mode 100644 src/layouts/index.tsx delete mode 100644 src/main.tsx delete mode 100644 src/routers/index.ts delete mode 100644 src/shared/constants.ts delete mode 100644 src/shared/countries.ts delete mode 100644 src/shared/utils.ts delete mode 100644 src/stores/conversation.ts delete mode 100644 src/stores/global.ts delete mode 100644 src/stores/settings.ts delete mode 100644 src/styles.css delete mode 100644 src/types/conversation.ts delete mode 100644 src/types/settings.ts delete mode 100644 src/vite-env.d.ts create mode 100644 stores/conversation.ts create mode 100644 stores/global.ts create mode 100644 stores/settings.ts delete mode 100644 tailwind.config.js delete mode 100644 tsconfig.node.json create mode 100644 types/conversation.ts rename {src/types => types}/global.ts (66%) create mode 100644 types/index.ts create mode 100644 types/settings.ts delete mode 100644 vite.config.ts diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 7bb69f45..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "env": { - "browser": true, - "es6": true, - "node": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:import/recommended", - "plugin:import/typescript", - "plugin:react/recommended", - "plugin:react-hooks/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": "latest", - "ecmaFeatures": { - "jsx": true - } - }, - "settings": { - "import/resolver": { - "alias": { - "map": [ - [ - "src", - "./src" - ] - ], - "extensions": [ - ".ts", - ".tsx" - ] - } - } - }, - "rules": { - "react/jsx-uses-react": "off", - "react/react-in-jsx-scope": "off" - } -} \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index b7c1755e..00000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,12 +0,0 @@ -# These are supported funding model platforms - -github: [YanceyOfficial] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100755 index 518aeba7..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: - -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Desktop (please complete the following information):** - -- OS: [e.g. macOS 13.2.1] -- Version [e.g. 1.0.0] - -**Additional context** -Add any other context about the problem here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100755 index ee269da8..00000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,26 +0,0 @@ - - -### Description - - - -### Additional context - - - ---- - -### What is the purpose of this pull request? - -- [ ] Bug fix -- [ ] New Feature -- [ ] Documentation update -- [ ] Other - -### Before submitting the PR, please make sure you do the following - -- [ ] Read the [Contributing Guidelines](https://github.com/YanceyOfficial/hyperchat/blob/master/CONTRIBUTING.md). -- [ ] Read the [Pull Request Guidelines](https://github.com/YanceyOfficial/hyperchat/blob/master/CONTRIBUTING.md#pull-request-guidelines) and follow the [Angular Team's Commit Message Guidelines](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit). -- [ ] Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate. -- [ ] Provide a description in this PR that addresses **what** the PR is solving, or reference the issue that it solves (e.g. `fixes #123`). -- [ ] Ideally, include relevant tests that fail without this PR but pass with it. diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 8ec5ac63..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,23 +0,0 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: - - package-ecosystem: 'npm' - directory: '/' - schedule: - interval: 'weekly' - target-branch: 'master' - commit-message: - prefix: 'deps' - open-pull-requests-limit: 20 - - package-ecosystem: 'npm' - directory: '/website' - schedule: - interval: 'weekly' - target-branch: 'develop' - commit-message: - prefix: 'deps' - open-pull-requests-limit: 20 diff --git a/.github/workflows/cross-platform-release.yml b/.github/workflows/cross-platform-release.yml deleted file mode 100644 index db869e4d..00000000 --- a/.github/workflows/cross-platform-release.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: 'cross-platform-release' - -on: - push: - branches: - - release - -# This is the example from the readme. -# On each push to the `release` branch it will create or update a GitHub release, build your app, and upload the artifacts to the release. - -jobs: - publish-tauri: - permissions: - contents: write - strategy: - fail-fast: false - matrix: - include: - - platform: 'macos-latest' # for Arm based macs (M1 and above). - args: '--target aarch64-apple-darwin' - - platform: 'macos-latest' # for Intel based macs. - args: '--target x86_64-apple-darwin' - - platform: 'ubuntu-22.04' # for Tauri v1 you could replace this with ubuntu-20.04. - args: '' - - platform: 'windows-latest' - args: '' - - runs-on: ${{ matrix.platform }} - steps: - - uses: actions/checkout@v4 - - - name: setup node - uses: actions/setup-node@v4 - with: - node-version: lts/* - - - name: setup pnpm - uses: pnpm/action-setup@v4 - with: - version: 9 - - - name: install Rust stable - uses: dtolnay/rust-toolchain@stable - with: - # Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds. - targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} - - - name: install dependencies (ubuntu only) - if: matrix.platform == 'ubuntu-22.04' # This must match the platform value defined above. - run: | - sudo apt-get update - sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf - # webkitgtk 4.0 is for Tauri v1 - webkitgtk 4.1 is for Tauri v2. - # You can remove the one that doesn't apply to your app to speed up the workflow a bit. - - - name: install frontend dependencies - run: pnpm install # change this to npm, pnpm or bun depending on which one you use. - - - uses: tauri-apps/tauri-action@v0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} - TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} - with: - tagName: app-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version. - releaseName: 'App v__VERSION__' - releaseBody: 'See the assets to download this version and install.' - releaseDraft: true - prerelease: false - args: ${{ matrix.args }} diff --git a/.github/workflows/cross-platform-test.yml b/.github/workflows/cross-platform-test.yml deleted file mode 100644 index 79cf9e79..00000000 --- a/.github/workflows/cross-platform-test.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: 'cross-platform-test' - -on: [pull_request] - -# This workflow will build your tauri app without uploading it anywhere. - -jobs: - test-tauri: - strategy: - fail-fast: false - matrix: - include: - - platform: 'macos-latest' # for Arm based macs (M1 and above). - args: '--target aarch64-apple-darwin' - - platform: 'macos-latest' # for Intel based macs. - args: '--target x86_64-apple-darwin' - - platform: 'ubuntu-22.04' # for Tauri v1 you could replace this with ubuntu-20.04. - args: '' - - platform: 'windows-latest' - args: '' - - runs-on: ${{ matrix.platform }} - steps: - - uses: actions/checkout@v4 - - - name: setup node - uses: actions/setup-node@v4 - with: - node-version: lts/* - - - name: setup pnpm - uses: pnpm/action-setup@v4 - with: - version: 9 - - - name: install Rust stable - uses: dtolnay/rust-toolchain@stable - with: - # Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds. - targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} - - - name: install dependencies (ubuntu only) - if: matrix.platform == 'ubuntu-22.04' # This must match the platform value defined above. - run: | - sudo apt-get update - sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf - # webkitgtk 4.0 is for Tauri v1 - webkitgtk 4.1 is for Tauri v2. - # You can remove the one that doesn't apply to your app to speed up the workflow a bit. - - - name: install frontend dependencies - run: pnpm install # change this to npm, pnpm or bun depending on which one you use. - - # If tagName and releaseId are omitted tauri-action will only build the app and won't try to upload any assets. - - uses: tauri-apps/tauri-action@v0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} - TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} - with: - args: ${{ matrix.args }} diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml deleted file mode 100644 index fc33996b..00000000 --- a/.github/workflows/release-please.yml +++ /dev/null @@ -1,24 +0,0 @@ -on: - push: - branches: - - master - -permissions: - contents: write - pull-requests: write - -name: release-please - -jobs: - release-please: - runs-on: ubuntu-latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - uses: googleapis/release-please-action@v4 - with: - release-type: node - package-name: release-please-action - extra-files: | - src-tauri/Cargo.toml - src-tauri/tauri.conf.json diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml deleted file mode 100644 index 71fd9497..00000000 --- a/.github/workflows/slack-notify.yml +++ /dev/null @@ -1,17 +0,0 @@ -on: [push, pull_request] -name: slack-notification -jobs: - slackNotification: - name: Slack Notification when Pushing - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Slack Notification when Pushing - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - SLACK_CHANNEL: github-actions - SLACK_TITLE: '${{ github.actor }} is ${{ github.event_name }}ing the ${{ github.ref }} to ${{ github.repository }}.' - SLACK_FOOTER: 'Powered by Yancey Inc. and its affiliates.' - SLACK_COLOR: ${{ job.status }} - SLACK_MESSAGE: 'Commit: ${{ github.event.head_commit.message }}.' diff --git a/.gitignore b/.gitignore index 6c52bd72..54acf666 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,44 @@ -# Logs -logs -*.log +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug npm-debug.log* yarn-debug.log* yarn-error.log* -pnpm-debug.log* -lerna-debug.log* +.pnpm-debug.log* -node_modules -dist -dist-ssr -*.local +# env files (can opt-in for committing if needed) +.env* -# Editor directories and files -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts -.env \ No newline at end of file +# Database data +lib/db/data/* \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index 2312dc58..00000000 --- a/.husky/pre-commit +++ /dev/null @@ -1 +0,0 @@ -npx lint-staged diff --git a/.lintstagedrc.js b/.lintstagedrc.js deleted file mode 100644 index 43c8ee21..00000000 --- a/.lintstagedrc.js +++ /dev/null @@ -1,3 +0,0 @@ -export default { - 'src/*.{js,jsx,ts,tsx}': ['pnpm run prettier', 'pnpm run lint'] -} diff --git a/.npmrc b/.npmrc index a835b235..bcaafc32 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,2 @@ -registry=https://registry.npmjs.org/ -auto-install-peers=true \ No newline at end of file + +registry=https://registry.npmjs.org/ \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 24d7cc6d..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index e5352d63..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "files.associations": { - "*.css": "tailwindcss" - }, - "editor.quickSuggestions": { - "strings": true - }, - "tailwindCSS.includeLanguages": { - "html": "html", - "javascript": "javascript" - } -} diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 8717e939..00000000 --- a/AUTHORS +++ /dev/null @@ -1,6 +0,0 @@ -# Below is a list of people and organizations that have contributed -# to the Lighthouse project. Names should be added to the list like so: -# -# Name/Organization - -Yancey Leo diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index b8d06667..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,266 +0,0 @@ -# Changelog - -## [2.0.1](https://github.com/HyperChatBot/hyperchat/compare/v1.0.5...v2.0.1) (2024-10-18) - -### Bug Fixes - -- delete image icon isn't shown in dark mode ([a20c5bb](https://github.com/HyperChatBot/hyperchat/commit/a20c5bb3bc3c1672c55a94f090c8c11564c8521f)) - -## [2.0.0](https://github.com/HyperChatBot/hyperchat/compare/v1.0.5...v2.0.0) (2024-10-18) - -### Features - -- update to tauri v2 - -## [1.0.5](https://github.com/Hyper-Chat-Bot/hyperchat/compare/v1.0.4...v1.0.5) (2023-10-07) - -### Bug Fixes - -- uses DATE_MED instead DATE_FULL for the better visual experience ([686895d](https://github.com/Hyper-Chat-Bot/hyperchat/commit/686895d0a5629d19b5ac66c89d1d42c2fa60d97f)) - -## [1.0.4](https://github.com/HyperChatBot/hyperchat/compare/v1.0.3...v1.0.4) (2023-08-01) - -### Bug Fixes - -- allow local and azure assets in csp ([f7de69c](https://github.com/HyperChatBot/hyperchat/commit/f7de69c4e8e4b79289d540b90e1e90925c2250c9)) -- azure image generation should return 202 status code for continuous request ([fa6ac62](https://github.com/HyperChatBot/hyperchat/commit/fa6ac6271d7e8b6894b98e7fd561a5576e6eb11a)) -- reset the value of input:type=file when the request finished ([6534f98](https://github.com/HyperChatBot/hyperchat/commit/6534f9880cef375a598ebd3bfad6acf884db0115)) - -## [1.0.3](https://github.com/HyperChatBot/hyperchat/compare/v1.0.2...v1.0.3) (2023-07-25) - -### Bug Fixes - -- remake 32x32 icon ([aea7089](https://github.com/HyperChatBot/hyperchat/commit/aea7089c01c5480e1943bfdb7867ee2c0770811e)) - -## [1.0.2](https://github.com/HyperChatBot/hyperchat/compare/v1.0.1...v1.0.2) (2023-07-25) - -### Bug Fixes - -- show common toast if request error ([a6275ba](https://github.com/HyperChatBot/hyperchat/commit/a6275bab837697f44f9ad6743a46d70d1999e256)) - -## [1.0.1](https://github.com/HyperChatBot/hyperchat/compare/v1.0.0...v1.0.1) (2023-07-25) - -### Bug Fixes - -- remove showErrorToast ([0b46792](https://github.com/HyperChatBot/hyperchat/commit/0b4679246ebda726da60095ce0d83af735a66d6b)) - -## 1.0.0 (2023-07-24) - -### Features - -- access husky, commitlint and lintstage ([44ce86b](https://github.com/HyperChatBot/hyperchat/commit/44ce86b64d978c24605e90f8f1c6cf475eee2937)) -- access husky, commitlint and lintstage ([0f06706](https://github.com/HyperChatBot/hyperchat/commit/0f0670604cb794dc2579630964aa4f6a6cff970b)) -- access husky, commitlint and lintstage ([be59fc5](https://github.com/HyperChatBot/hyperchat/commit/be59fc5b6342741ce8063a8e56ebffbe37d66033)) -- access husky, commitlint and lintstage ([737005e](https://github.com/HyperChatBot/hyperchat/commit/737005e307b3619775185cffca96206a5e5f39e2)) -- access wavesurfer ([9ecae98](https://github.com/HyperChatBot/hyperchat/commit/9ecae9811a114a7fc4b5961bac3a1cccbcb5484b)) -- add basic stylesheet for markdown table ([fd66748](https://github.com/HyperChatBot/hyperchat/commit/fd6674835fcd3f9c18534796a7855050a545d6b5)) -- add claude settings ([15bee53](https://github.com/HyperChatBot/hyperchat/commit/15bee53e7faa9e13bfee818fd2d6789e29583257)) -- add edit ([8022823](https://github.com/HyperChatBot/hyperchat/commit/8022823607c8dd68176d8072bd0ed1e73a0e8f24)) -- add Empty ChatItem ([9fe2330](https://github.com/HyperChatBot/hyperchat/commit/9fe2330706c00a2a773d12d7d10209795d03b613)) -- add inputPlaceholders ([b3e3ed2](https://github.com/HyperChatBot/hyperchat/commit/b3e3ed2d1b3e1ed0ebeecbc413961773161a691b)) -- add loading spinner ([2c1c0ec](https://github.com/HyperChatBot/hyperchat/commit/2c1c0ec8302d5ddd40cdc6e20258f3dd0dcbb37a)) -- add loading="lazy" for img ([4a845a1](https://github.com/HyperChatBot/hyperchat/commit/4a845a1ef87b74b0919e6c6cd4d187bbc36a5eed)) -- add more db schema ([489c850](https://github.com/HyperChatBot/hyperchat/commit/489c850639cc7e4259c4624f5e2dfaeac9969861)) -- add no-scrollbar if sidebar too long ([ebcb6ad](https://github.com/HyperChatBot/hyperchat/commit/ebcb6adf421526c891b622995b6c26821740c58e)) -- add openai hooks ([a9c7b85](https://github.com/HyperChatBot/hyperchat/commit/a9c7b85cb1a1ccfc8dcceeb6756bcb04fbdb037d)) -- add project meta files, such as github action ([bc83411](https://github.com/HyperChatBot/hyperchat/commit/bc834114746de606d016da3e86b5e02a35daf100)) -- add question_created_at and answer_created_at ([c06b7c3](https://github.com/HyperChatBot/hyperchat/commit/c06b7c36a5ecc38d047bb3b6b4034ca7f9a107fb)) -- add rollback when error ([e7b5f14](https://github.com/HyperChatBot/hyperchat/commit/e7b5f149ce61333ac65101ec746d0b1fd4608229)) -- add routers ([f021908](https://github.com/HyperChatBot/hyperchat/commit/f021908c5fb34327e2c6aceedcd49a9888f84c44)) -- avoid user activity when loading ([675b3d6](https://github.com/HyperChatBot/hyperchat/commit/675b3d6fb5045ddcf5f270ac38d8e4d4ae043d95)) -- backoff current messsage when fail ([c5029c8](https://github.com/HyperChatBot/hyperchat/commit/c5029c8d2276414370740c44236cc6a2e7bc3ba7)) -- chanage html title ([185e071](https://github.com/HyperChatBot/hyperchat/commit/185e0710614dfbfc374527a1f737c702ed51fd03)) -- change bot logo ([1b0f578](https://github.com/HyperChatBot/hyperchat/commit/1b0f578a256846aeee91b244444b4dad5b4b6166)) -- change productName ([ba96042](https://github.com/HyperChatBot/hyperchat/commit/ba96042766da3df52c1236f658d510ec36d42d67)) -- change svg icon for audio translation ([7023e8f](https://github.com/HyperChatBot/hyperchat/commit/7023e8fc39085a8c8b45bdd7d36c61778bdde972)) -- create embeddings schema ([937c235](https://github.com/HyperChatBot/hyperchat/commit/937c23514d1e6d8e8694789088fd0d548e8cdce3)) -- css optimization ([ba921d4](https://github.com/HyperChatBot/hyperchat/commit/ba921d4383e07a9ff492f2bf0609b698c1a02c44)) -- dark bg ([b7728b3](https://github.com/HyperChatBot/hyperchat/commit/b7728b32f47216525a8554c529017b31a4210bdd)) -- decoupling all db operations to `useDB` ([1f0770d](https://github.com/HyperChatBot/hyperchat/commit/1f0770dfa024cc1bfbfa661b7d025612b2acda67)) -- delete mock image ([c6d8e8f](https://github.com/HyperChatBot/hyperchat/commit/c6d8e8fdfe6382812d147fda93cb0914df2751b7)) -- delete useless files ([35014c2](https://github.com/HyperChatBot/hyperchat/commit/35014c2ccc3b03aacd8ef91c9a66a47415fd9f1b)) -- delete useless files ([c07e322](https://github.com/HyperChatBot/hyperchat/commit/c07e322f5d00690f7d159fa6b76f319dd08d5afc)) -- delete useless icons ([15199d3](https://github.com/HyperChatBot/hyperchat/commit/15199d3f87b85cfcf0310d108886225315738d90)) -- do not refresh conversations when streaming ([44b68b3](https://github.com/HyperChatBot/hyperchat/commit/44b68b31b5adbe5b8ed1fcb4850e355c86830c12)) -- extract common conversation system ([65f2256](https://github.com/HyperChatBot/hyperchat/commit/65f22569dad3eee94cf72965251c27e9eff79a31)) -- extract ConversationBox component ([5c9b3dc](https://github.com/HyperChatBot/hyperchat/commit/5c9b3dc6180916f02a7e78f9b95a6c81e578b669)) -- extract generateEmptyMessage ([014f118](https://github.com/HyperChatBot/hyperchat/commit/014f118d2dae51fe0312d18498735174c2d6fe91)) -- extract InputBox component ([a92119d](https://github.com/HyperChatBot/hyperchat/commit/a92119d24165a538aa579fbbc15f6ba8d8e6f07c)) -- extract only two router items ([aa847ce](https://github.com/HyperChatBot/hyperchat/commit/aa847ce9a9ca1801eaa5daa136bbdca6b65afb25)) -- extract updateMessageState ([3135504](https://github.com/HyperChatBot/hyperchat/commit/31355042221fd7ab6b3da8fe5ddbd45f87dbda1b)) -- extract useChatCompletionStream ([84e7de4](https://github.com/HyperChatBot/hyperchat/commit/84e7de46c3530dc98dbd49e828ae4a4165742bf8)) -- finish all configurations form ([a940892](https://github.com/HyperChatBot/hyperchat/commit/a9408928d5145d0f76786367e9a29dd74e6446b8)) -- finish ChatBubble components ([c895476](https://github.com/HyperChatBot/hyperchat/commit/c895476b9a5c8c0ebe96bd6d1f8aacac08c1469a)) -- finish ContractHeader components ([5223534](https://github.com/HyperChatBot/hyperchat/commit/52235345c0f2dccff5b4dfeed4640ca9e1522823)) -- finish message card's style ([3d30f61](https://github.com/HyperChatBot/hyperchat/commit/3d30f6162b459fb9bebb9da7e53b2f2c025f9a84)) -- finish message list components ([7c6465d](https://github.com/HyperChatBot/hyperchat/commit/7c6465de246afbbd309efb1e3802691a79a58d70)) -- finish theme toggle ([fadd8d6](https://github.com/HyperChatBot/hyperchat/commit/fadd8d69a99fa6b4c5148428f8296df2cb4fe62f)) -- ignore catch error types ([5412306](https://github.com/HyperChatBot/hyperchat/commit/54123066e80d0fbb4a2153f5b830e322b9b1ee91)) -- initial repo ([9ba8b3d](https://github.com/HyperChatBot/hyperchat/commit/9ba8b3d58463093b44f3fe99ef075439531d3b82)) -- initial repo ([6f70f52](https://github.com/HyperChatBot/hyperchat/commit/6f70f5283fdefddf520eda1494b522718e198470)) -- lazy components ([ce78ab1](https://github.com/HyperChatBot/hyperchat/commit/ce78ab1bb5690b8a9a20dd20e531e8dea9edd22b)) -- new type ([c1147ea](https://github.com/HyperChatBot/hyperchat/commit/c1147ea60b935518c46daff5200278842dc99667)) -- performance optimization ([ef9f281](https://github.com/HyperChatBot/hyperchat/commit/ef9f281ab213bf14970780e6152fd8bbd4ade8da)) -- reduce the threshold for new product access. ([d4b59d1](https://github.com/HyperChatBot/hyperchat/commit/d4b59d14bdeba83d56c8fe27b4c3242b96ee1870)) -- reduce the threshold for new product access. ([4864d95](https://github.com/HyperChatBot/hyperchat/commit/4864d952cfb9a9997b7b32d2a71882425f194a3c)) -- reduce the threshold for new product access. ([805e4cb](https://github.com/HyperChatBot/hyperchat/commit/805e4cb44e5e10021dc1daba7e50df6468c33fba)) -- register svg icons ([294b788](https://github.com/HyperChatBot/hyperchat/commit/294b788654156a368f76e5421be0be87ccff169c)) -- register svg icons ([660e12e](https://github.com/HyperChatBot/hyperchat/commit/660e12eeed64da69d32a7aa92ff427db03726e7c)) -- remove srcoll to bottom for the better performance ([b594651](https://github.com/HyperChatBot/hyperchat/commit/b594651634f1619d590acecdf6c371eaa2ed3a7f)) -- rename to ([8a88d96](https://github.com/HyperChatBot/hyperchat/commit/8a88d9640d3281f9a01c0f1784627c2a82615840)) -- rename to ([6536f0f](https://github.com/HyperChatBot/hyperchat/commit/6536f0f3129177715e1eb943fd38cd15aa2d2d3e)) -- rename to ([70ecbb4](https://github.com/HyperChatBot/hyperchat/commit/70ecbb4453f3d125fb03bbe693de1ac1c0a9d85a)) -- rename to ([06b2144](https://github.com/HyperChatBot/hyperchat/commit/06b214411ff914257afe123b721cf44073858c7c)) -- rename recoil's key ([31611f8](https://github.com/HyperChatBot/hyperchat/commit/31611f86913b52c244979996219948badb5d32e2)) -- set update settings ([48476d7](https://github.com/HyperChatBot/hyperchat/commit/48476d7348a6e172328dfdf8b7b798050da62801)) -- settings params for every openai hooks ([44828f6](https://github.com/HyperChatBot/hyperchat/commit/44828f6c6d6d60024d641d32678a8d3368095e1c)) -- show in InputBox if loading ([74fb71d](https://github.com/HyperChatBot/hyperchat/commit/74fb71d93a52a3e8ba5406cd4b7320ee9e45500d)) -- show file tooltips if use audio products ([aecbcc9](https://github.com/HyperChatBot/hyperchat/commit/aecbcc95b23b60d19fe7a8ec9d9c3a83ceb1e7b7)) -- show Loading component if refresh conversation data ([97d7f2f](https://github.com/HyperChatBot/hyperchat/commit/97d7f2ffc7db8f10606de79115930fd2079af8ab)) -- store to indexedDB ([b7799a4](https://github.com/HyperChatBot/hyperchat/commit/b7799a4292e5ad1fbb9155ddf41588dacfde7f5f)) -- support audio translation ([b96c468](https://github.com/HyperChatBot/hyperchat/commit/b96c4689482cfa945934a982a3d48e87a9904805)) -- support dexie import and export ([6a1dbed](https://github.com/HyperChatBot/hyperchat/commit/6a1dbedf5f33325c09fc49ac1d03f4fc9ef571ef)) -- supports [@emoji-mart](https://github.com/emoji-mart) ([ca5e2b3](https://github.com/HyperChatBot/hyperchat/commit/ca5e2b3cafa7b3bf4bf24c95f62e8fa8ef88588a)) -- supports audio translation ([87dccc3](https://github.com/HyperChatBot/hyperchat/commit/87dccc3d90faf8b483f020a90daba31b356c3111)) -- supports basic dark mode ([a3a4bc4](https://github.com/HyperChatBot/hyperchat/commit/a3a4bc4ba8b7971437a8a49fdc7d73d37eb8c04a)) -- supports basic markdown render ([9ebf8c4](https://github.com/HyperChatBot/hyperchat/commit/9ebf8c4b84d1f436d5f4323840f0456b79ffc7c7)) -- supports configuration for very products ([92e086a](https://github.com/HyperChatBot/hyperchat/commit/92e086a966e925761175b2e538f890931a72273a)) -- supports context with a greedy strategy ([18194bc](https://github.com/HyperChatBot/hyperchat/commit/18194bc9ae8dc32c8e4afdb6c395043f56a65ad5)) -- supports custom assistant avatar ([1c9758c](https://github.com/HyperChatBot/hyperchat/commit/1c9758c2c8d4300b3f928254bb4cbfb783ae69c2)) -- supports delete conversation ([a3bbae8](https://github.com/HyperChatBot/hyperchat/commit/a3bbae889e4d04e12297e229d8dbc59c3656e809)) -- supports modify summary ([c6dcc8c](https://github.com/HyperChatBot/hyperchat/commit/c6dcc8c8355f7df978680683b78168c5559c83cf)) -- supports online status ([9d012b3](https://github.com/HyperChatBot/hyperchat/commit/9d012b38e1463ae84b90f9d219e1c8670e2705ff)) -- supports router ([34edd6a](https://github.com/HyperChatBot/hyperchat/commit/34edd6a6832f0e0f1a5866920e2008377e9e020e)) -- supports scroll to bottom ([616e560](https://github.com/HyperChatBot/hyperchat/commit/616e5600e19ae78a928ecdbac8c5c9944095415a)) -- supports to moderation ([b93f98c](https://github.com/HyperChatBot/hyperchat/commit/b93f98c8cb8ecdce64f130f24911a00c5ed7adc5)) -- supports useSettings ([9b12aaf](https://github.com/HyperChatBot/hyperchat/commit/9b12aaf0aeee41671165ce3d5686b2156d6749a5)) -- switch to dexiejs ([7d28106](https://github.com/HyperChatBot/hyperchat/commit/7d281067fe2f57abe5d021969a7c92e38d21270e)) -- The first version ([4e77c27](https://github.com/HyperChatBot/hyperchat/commit/4e77c2770944a1dbb417cacdd12ab8b9aa692c07)) -- The first version ([764e6ef](https://github.com/HyperChatBot/hyperchat/commit/764e6ef05b6a123d057b93d3d9986abba8372067)) -- try basic rxdb ([1b49616](https://github.com/HyperChatBot/hyperchat/commit/1b4961646f15c05f57b077a2641f0dd470743a22)) -- try context ([a5b99ca](https://github.com/HyperChatBot/hyperchat/commit/a5b99cafc85461f86293a121a8b9cff1f8e531dc)) -- try selector setter ([abe869c](https://github.com/HyperChatBot/hyperchat/commit/abe869cab556b8d699356652f65b52fc741d1e3a)) -- try uploader ([9c58594](https://github.com/HyperChatBot/hyperchat/commit/9c58594d628c7c5d3e8e3905fd34bd46556ca865)) -- try wavesurfer ([3dc7c06](https://github.com/HyperChatBot/hyperchat/commit/3dc7c06b8e4154db11d77896cc1945dc20907330)) -- update chats state from updating curr chat selector ([20f3ea8](https://github.com/HyperChatBot/hyperchat/commit/20f3ea81e033535c5469094e563bec3063c17f61)) -- update configuration ([d23f1bd](https://github.com/HyperChatBot/hyperchat/commit/d23f1bdd90a3082cd1c190ff1d62ae2dd6c81f10)) -- update error strategy ([caa3c60](https://github.com/HyperChatBot/hyperchat/commit/caa3c60514c8ff7e7a54ef09c56424bab79f4bb7)) -- update form id ([416605e](https://github.com/HyperChatBot/hyperchat/commit/416605eb1acf7781858211259aeff2249ae9bd62)) -- update formik config ([6f30578](https://github.com/HyperChatBot/hyperchat/commit/6f30578c1215755e1344fe53a91ab408c17582cd)) -- update logo ([e162d18](https://github.com/HyperChatBot/hyperchat/commit/e162d183ccf09f1c8f916c8d0098c9e3a20821f2)) -- update newcomer's guide ([9a6ecb4](https://github.com/HyperChatBot/hyperchat/commit/9a6ecb4299ff910f18da8d511b238554e00bb4b7)) -- update response value name ([c8926ae](https://github.com/HyperChatBot/hyperchat/commit/c8926aedca925c798bf46090fd4d741d150f86f3)) -- update settings form ([91d0592](https://github.com/HyperChatBot/hyperchat/commit/91d05923bc8eedf4339c502cdf04b1538d55bbba)) -- update useChatCompletion error ([4b4fe73](https://github.com/HyperChatBot/hyperchat/commit/4b4fe73ded53c6a1e0a94ed22e27a10b2ceb9b66)) -- update useTheme ([e296046](https://github.com/HyperChatBot/hyperchat/commit/e29604616496027df18c3e26cfec89156564c612)) -- use dexie instead of rxdb ([b06a37e](https://github.com/HyperChatBot/hyperchat/commit/b06a37ec793a2f3e260c5f4c9ffed62014556292)) -- use dynamic updater endpoint ([ccc4722](https://github.com/HyperChatBot/hyperchat/commit/ccc472241137b468d8673d3286e4a3eedc5f1183)) -- use fetch stream ([ca424ae](https://github.com/HyperChatBot/hyperchat/commit/ca424aefc747c000e99020a38ee21c9c7b27762b)) -- use locale time format ([79afe31](https://github.com/HyperChatBot/hyperchat/commit/79afe3112da94280cf1d62c9a82273fc361acee4)) -- use mui instead of flowbite ([5f5a769](https://github.com/HyperChatBot/hyperchat/commit/5f5a7693ef7981bc7a0ef2b80fa0e4be5aa8525d)) -- use snakeCaseToTitleCase instead of conversationTitles ([48cde7e](https://github.com/HyperChatBot/hyperchat/commit/48cde7eaf2efc8a3fc9057bd3f6a1cd9c92ada8f)) -- use textarea instead of input ([7648af4](https://github.com/HyperChatBot/hyperchat/commit/7648af4a8d07c3c0137b425f74e122469ed190ba)) -- uses new state updater ([15601ee](https://github.com/HyperChatBot/hyperchat/commit/15601ee8a9ffbf82410dbb03bcdedb18e3845c7e)) -- wip ([9224852](https://github.com/HyperChatBot/hyperchat/commit/92248526e2d5e124d711ba6e70ebac9114897fa2)) -- **wip:** add landing website ([928d08f](https://github.com/HyperChatBot/hyperchat/commit/928d08f16404965c819be28519b017b246eec9df)) -- **wip:** add landing website ([53adeab](https://github.com/HyperChatBot/hyperchat/commit/53adeabf2773e07942b9ccd754c1436c692de144)) -- **wip:** add network status ([687c882](https://github.com/HyperChatBot/hyperchat/commit/687c882cf371c8e50ba900deb87589acd964072b)) -- **wip:** dark settings ([dc3bb95](https://github.com/HyperChatBot/hyperchat/commit/dc3bb95544846bff00aeed7e92cfa394657e2a56)) -- **wip:** finish basic form elements ([a0f8ede](https://github.com/HyperChatBot/hyperchat/commit/a0f8ede128bd1bc3019d92d8338cdeb0d74fda29)) -- **wip:** supports azure openai api ([516da09](https://github.com/HyperChatBot/hyperchat/commit/516da09ecf1d0ce63ae64d7421ebf9861dba9f7b)) -- **wip:** supports azure openai api for sidebar ([b10d97b](https://github.com/HyperChatBot/hyperchat/commit/b10d97b34cc179eb13e6c3633a3de96e88f6d739)) -- **wip:** supports azure openai api for sidebar ([a6d4133](https://github.com/HyperChatBot/hyperchat/commit/a6d4133937995ef2fd97c683eaf7a14aafbdef2c)) -- **wip:** supports azure settings paramsr ([e8179df](https://github.com/HyperChatBot/hyperchat/commit/e8179dfac7bf0135e38a7f5406a575df6a35977b)) -- **wip:** supports router ([c1f3f03](https://github.com/HyperChatBot/hyperchat/commit/c1f3f03bf6385e84127d9a4efda6f722f439b6a2)) -- **wip:** try split message ([f855a34](https://github.com/HyperChatBot/hyperchat/commit/f855a34ba8fc0975dda9354f46d37b918d415a4b)) -- **wip:** try switch to split mode ([38ff6c6](https://github.com/HyperChatBot/hyperchat/commit/38ff6c641878681206678860616b458e0ddd544b)) -- **wip:** update initial dialog ([2d0b824](https://github.com/HyperChatBot/hyperchat/commit/2d0b8241db0247a2be587a2cfab004cf184234af)) - -### Bug Fixes - -- add when update configuration ([cb54f62](https://github.com/HyperChatBot/hyperchat/commit/cb54f621a7b7221083b26897de9e36b7a7b39ea7)) -- add unsafe-inline to render mui ([b9612b1](https://github.com/HyperChatBot/hyperchat/commit/b9612b1ed84a3455bff0f1a21b7e6b6e9e8a34d5)) -- add updated_at when modify conversation title or avatar ([698cb7b](https://github.com/HyperChatBot/hyperchat/commit/698cb7b9dc8b1b6c91696598b4ab13e15b4817ff)) -- cannot visit a product if the product's company have not register api keys ([e5cb551](https://github.com/HyperChatBot/hyperchat/commit/e5cb551b8733267a11bc490a48e3d7c97cc921c8)) -- currConversation state ([3173002](https://github.com/HyperChatBot/hyperchat/commit/317300209f4b8a60205c822e87885d93bf64a6fb)) -- delete props for react-markdown element ([5eb7afe](https://github.com/HyperChatBot/hyperchat/commit/5eb7afeea424df495f4a59b52088d57e64c96e6d)) -- fix contact header's style ([aaed988](https://github.com/HyperChatBot/hyperchat/commit/aaed9888874e9d89679a846fcecd397907c4b190)) -- fix input box ([e6d8e76](https://github.com/HyperChatBot/hyperchat/commit/e6d8e766d0b8b113be59075bb5627ac130cba666)) -- fix spelling mistake of ([81bef54](https://github.com/HyperChatBot/hyperchat/commit/81bef540fd860d351d11a5df8db2ba6f5ceebdb8)) -- fix textarea line ([51f3b0d](https://github.com/HyperChatBot/hyperchat/commit/51f3b0ddf064b30558b570060bbc9d0f6db7ec1d)) -- if `response_format` is `text`, `vtt` `or `srt`, the result is `translation.data` ([c49d19a](https://github.com/HyperChatBot/hyperchat/commit/c49d19a1fe1724d9141c5109a62216bb3ebb1147)) -- if no `stop` pass null ([cbad896](https://github.com/HyperChatBot/hyperchat/commit/cbad8964cab29afa0ee170f595621eaa05497654)) -- listen prefers-color-scheme:dark) change needs to settings object ready ([b95a87f](https://github.com/HyperChatBot/hyperchat/commit/b95a87f6b5348eefba17a4503ead6312ccf4426b)) -- listen prefers-color-scheme:dark) change needs to settings object ready ([a5fff12](https://github.com/HyperChatBot/hyperchat/commit/a5fff12b7226e245c1fbb1f46a58081235e45664)) -- only submit secret key can close initial dialog ([c361876](https://github.com/HyperChatBot/hyperchat/commit/c361876adace439d2f7eb2c61a60b9f5d79ce1c5)) -- read settings theme when init app ([d7d8534](https://github.com/HyperChatBot/hyperchat/commit/d7d8534cf4e1578096e3f3116692f7d8de4ee7b8)) -- rollback empty messsage into currConversationState when error catched ([c8d68e2](https://github.com/HyperChatBot/hyperchat/commit/c8d68e2c9bbc99e62fccdf44c4a4908c857c6568)) -- set loading to when error catched ([85766bc](https://github.com/HyperChatBot/hyperchat/commit/85766bc007d8f65d441a968ad9b44d44164c753a)) -- show mainPurple color when input in dark mode ([863328d](https://github.com/HyperChatBot/hyperchat/commit/863328d64bceca98715e273d411d7e00d4bb4228)) -- update CSP for fetch api ([70418fe](https://github.com/HyperChatBot/hyperchat/commit/70418fedf37de1eb1cac13dc17a8db28680ad73f)) -- use conversationTitles instead of snakeCaseTotitleCase ([cb098dc](https://github.com/HyperChatBot/hyperchat/commit/cb098dcaf786bafc820ecaa72e43358edd10bf6c)) -- uses onCompositionStart and onCompositionEnd to avoid conflict with ([cf238c7](https://github.com/HyperChatBot/hyperchat/commit/cf238c7c8f71a20df5d81051121763bd3195f5de)) -- uses onCompositionStart and onCompositionEnd to avoid conflict with ([01b49e8](https://github.com/HyperChatBot/hyperchat/commit/01b49e8ab4f8c2f5aea6714fb54c23ab11be1109)) - -## [0.0.0](https://github.com/Hyper-Chat-Bot/hyperchat/compare/v1.0.0...v0.0.0) (2023-07-24) - -### Bug Fixes - -- add when update configuration ([cb54f62](https://github.com/Hyper-Chat-Bot/hyperchat/commit/cb54f621a7b7221083b26897de9e36b7a7b39ea7)) -- add updated_at when modify conversation title or avatar ([698cb7b](https://github.com/Hyper-Chat-Bot/hyperchat/commit/698cb7b9dc8b1b6c91696598b4ab13e15b4817ff)) -- cannot visit a product if the product's company have not register api keys ([e5cb551](https://github.com/Hyper-Chat-Bot/hyperchat/commit/e5cb551b8733267a11bc490a48e3d7c97cc921c8)) -- delete props for react-markdown element ([5eb7afe](https://github.com/Hyper-Chat-Bot/hyperchat/commit/5eb7afeea424df495f4a59b52088d57e64c96e6d)) -- fix spelling mistake of ([81bef54](https://github.com/Hyper-Chat-Bot/hyperchat/commit/81bef540fd860d351d11a5df8db2ba6f5ceebdb8)) -- if `response_format` is `text`, `vtt` `or `srt`, the result is `translation.data` ([c49d19a](https://github.com/Hyper-Chat-Bot/hyperchat/commit/c49d19a1fe1724d9141c5109a62216bb3ebb1147)) -- if no `stop` pass null ([cbad896](https://github.com/Hyper-Chat-Bot/hyperchat/commit/cbad8964cab29afa0ee170f595621eaa05497654)) -- listen prefers-color-scheme:dark) change needs to settings object ready ([b95a87f](https://github.com/Hyper-Chat-Bot/hyperchat/commit/b95a87f6b5348eefba17a4503ead6312ccf4426b)) -- listen prefers-color-scheme:dark) change needs to settings object ready ([a5fff12](https://github.com/Hyper-Chat-Bot/hyperchat/commit/a5fff12b7226e245c1fbb1f46a58081235e45664)) -- update CSP for fetch api ([70418fe](https://github.com/Hyper-Chat-Bot/hyperchat/commit/70418fedf37de1eb1cac13dc17a8db28680ad73f)) -- use conversationTitles instead of snakeCaseTotitleCase ([cb098dc](https://github.com/Hyper-Chat-Bot/hyperchat/commit/cb098dcaf786bafc820ecaa72e43358edd10bf6c)) -- uses onCompositionStart and onCompositionEnd to avoid conflict with ([cf238c7](https://github.com/Hyper-Chat-Bot/hyperchat/commit/cf238c7c8f71a20df5d81051121763bd3195f5de)) -- uses onCompositionStart and onCompositionEnd to avoid conflict with ([01b49e8](https://github.com/Hyper-Chat-Bot/hyperchat/commit/01b49e8ab4f8c2f5aea6714fb54c23ab11be1109)) - -### Features - -- access husky, commitlint and lintstage ([44ce86b](https://github.com/Hyper-Chat-Bot/hyperchat/commit/44ce86b64d978c24605e90f8f1c6cf475eee2937)) -- access husky, commitlint and lintstage ([0f06706](https://github.com/Hyper-Chat-Bot/hyperchat/commit/0f0670604cb794dc2579630964aa4f6a6cff970b)) -- access husky, commitlint and lintstage ([be59fc5](https://github.com/Hyper-Chat-Bot/hyperchat/commit/be59fc5b6342741ce8063a8e56ebffbe37d66033)) -- access husky, commitlint and lintstage ([737005e](https://github.com/Hyper-Chat-Bot/hyperchat/commit/737005e307b3619775185cffca96206a5e5f39e2)) -- add basic stylesheet for markdown table ([fd66748](https://github.com/Hyper-Chat-Bot/hyperchat/commit/fd6674835fcd3f9c18534796a7855050a545d6b5)) -- add claude settings ([15bee53](https://github.com/Hyper-Chat-Bot/hyperchat/commit/15bee53e7faa9e13bfee818fd2d6789e29583257)) -- add loading="lazy" for img ([4a845a1](https://github.com/Hyper-Chat-Bot/hyperchat/commit/4a845a1ef87b74b0919e6c6cd4d187bbc36a5eed)) -- add no-scrollbar if sidebar too long ([ebcb6ad](https://github.com/Hyper-Chat-Bot/hyperchat/commit/ebcb6adf421526c891b622995b6c26821740c58e)) -- add rollback when error ([e7b5f14](https://github.com/Hyper-Chat-Bot/hyperchat/commit/e7b5f149ce61333ac65101ec746d0b1fd4608229)) -- avoid user activity when loading ([675b3d6](https://github.com/Hyper-Chat-Bot/hyperchat/commit/675b3d6fb5045ddcf5f270ac38d8e4d4ae043d95)) -- decoupling all db operations to `useDB` ([1f0770d](https://github.com/Hyper-Chat-Bot/hyperchat/commit/1f0770dfa024cc1bfbfa661b7d025612b2acda67)) -- do not refresh conversations when streaming ([44b68b3](https://github.com/Hyper-Chat-Bot/hyperchat/commit/44b68b31b5adbe5b8ed1fcb4850e355c86830c12)) -- finish all configurations form ([a940892](https://github.com/Hyper-Chat-Bot/hyperchat/commit/a9408928d5145d0f76786367e9a29dd74e6446b8)) -- ignore catch error types ([5412306](https://github.com/Hyper-Chat-Bot/hyperchat/commit/54123066e80d0fbb4a2153f5b830e322b9b1ee91)) -- lazy components ([ce78ab1](https://github.com/Hyper-Chat-Bot/hyperchat/commit/ce78ab1bb5690b8a9a20dd20e531e8dea9edd22b)) -- new type ([c1147ea](https://github.com/Hyper-Chat-Bot/hyperchat/commit/c1147ea60b935518c46daff5200278842dc99667)) -- performance optimization ([ef9f281](https://github.com/Hyper-Chat-Bot/hyperchat/commit/ef9f281ab213bf14970780e6152fd8bbd4ade8da)) -- reduce the threshold for new product access. ([4864d95](https://github.com/Hyper-Chat-Bot/hyperchat/commit/4864d952cfb9a9997b7b32d2a71882425f194a3c)) -- reduce the threshold for new product access. ([805e4cb](https://github.com/Hyper-Chat-Bot/hyperchat/commit/805e4cb44e5e10021dc1daba7e50df6468c33fba)) -- rename to ([8a88d96](https://github.com/Hyper-Chat-Bot/hyperchat/commit/8a88d9640d3281f9a01c0f1784627c2a82615840)) -- rename to ([6536f0f](https://github.com/Hyper-Chat-Bot/hyperchat/commit/6536f0f3129177715e1eb943fd38cd15aa2d2d3e)) -- rename recoil's key ([31611f8](https://github.com/Hyper-Chat-Bot/hyperchat/commit/31611f86913b52c244979996219948badb5d32e2)) -- show in InputBox if loading ([74fb71d](https://github.com/Hyper-Chat-Bot/hyperchat/commit/74fb71d93a52a3e8ba5406cd4b7320ee9e45500d)) -- show file tooltips if use audio products ([aecbcc9](https://github.com/Hyper-Chat-Bot/hyperchat/commit/aecbcc95b23b60d19fe7a8ec9d9c3a83ceb1e7b7)) -- show Loading component if refresh conversation data ([97d7f2f](https://github.com/Hyper-Chat-Bot/hyperchat/commit/97d7f2ffc7db8f10606de79115930fd2079af8ab)) -- support dexie import and export ([6a1dbed](https://github.com/Hyper-Chat-Bot/hyperchat/commit/6a1dbedf5f33325c09fc49ac1d03f4fc9ef571ef)) -- supports configuration for very products ([92e086a](https://github.com/Hyper-Chat-Bot/hyperchat/commit/92e086a966e925761175b2e538f890931a72273a)) -- supports context with a greedy strategy ([18194bc](https://github.com/Hyper-Chat-Bot/hyperchat/commit/18194bc9ae8dc32c8e4afdb6c395043f56a65ad5)) -- try context ([a5b99ca](https://github.com/Hyper-Chat-Bot/hyperchat/commit/a5b99cafc85461f86293a121a8b9cff1f8e531dc)) -- update configuration ([d23f1bd](https://github.com/Hyper-Chat-Bot/hyperchat/commit/d23f1bdd90a3082cd1c190ff1d62ae2dd6c81f10)) -- update newcomer's guide ([9a6ecb4](https://github.com/Hyper-Chat-Bot/hyperchat/commit/9a6ecb4299ff910f18da8d511b238554e00bb4b7)) -- update useChatCompletion error ([4b4fe73](https://github.com/Hyper-Chat-Bot/hyperchat/commit/4b4fe73ded53c6a1e0a94ed22e27a10b2ceb9b66)) -- use dynamic updater endpoint ([ccc4722](https://github.com/Hyper-Chat-Bot/hyperchat/commit/ccc472241137b468d8673d3286e4a3eedc5f1183)) -- use snakeCaseToTitleCase instead of conversationTitles ([48cde7e](https://github.com/Hyper-Chat-Bot/hyperchat/commit/48cde7eaf2efc8a3fc9057bd3f6a1cd9c92ada8f)) -- uses new state updater ([15601ee](https://github.com/Hyper-Chat-Bot/hyperchat/commit/15601ee8a9ffbf82410dbb03bcdedb18e3845c7e)) -- **wip:** supports azure openai api ([516da09](https://github.com/Hyper-Chat-Bot/hyperchat/commit/516da09ecf1d0ce63ae64d7421ebf9861dba9f7b)) -- **wip:** supports azure openai api for sidebar ([b10d97b](https://github.com/Hyper-Chat-Bot/hyperchat/commit/b10d97b34cc179eb13e6c3633a3de96e88f6d739)) -- **wip:** supports azure openai api for sidebar ([a6d4133](https://github.com/Hyper-Chat-Bot/hyperchat/commit/a6d4133937995ef2fd97c683eaf7a14aafbdef2c)) -- **wip:** supports azure settings paramsr ([e8179df](https://github.com/Hyper-Chat-Bot/hyperchat/commit/e8179dfac7bf0135e38a7f5406a575df6a35977b)) -- **wip:** try split message ([f855a34](https://github.com/Hyper-Chat-Bot/hyperchat/commit/f855a34ba8fc0975dda9354f46d37b918d415a4b)) -- **wip:** try switch to split mode ([38ff6c6](https://github.com/Hyper-Chat-Bot/hyperchat/commit/38ff6c641878681206678860616b458e0ddd544b)) -- **wip:** update initial dialog ([2d0b824](https://github.com/Hyper-Chat-Bot/hyperchat/commit/2d0b8241db0247a2be587a2cfab004cf184234af)) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100755 index 5e4ff13e..00000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,45 +0,0 @@ -# Code Of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, political party, or sexual identity and orientation. Note, however, that religion, political party, or other ideological affiliation provide no exemptions for the behavior we outline as unacceptable in this Code of Conduct. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -- Using welcoming and inclusive language -- Being respectful of differing viewpoints and experiences -- Gracefully accepting constructive criticism -- Focusing on what is best for the community -- Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -- The use of sexualized language or imagery and unwelcome sexual attention or advances -- Trolling, insulting/derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or electronic address, without explicit permission -- Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team by DM at [Hyper Chat](https://discord.gg/tHzYjTqn). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html - -[homepage]: https://www.contributor-covenant.org diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100755 index dbe2b211..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,29 +0,0 @@ -# Hyper Chat Contributing Guide - -Hi! We are really excited that you are interested in contributing to Hyper Chat. Before submitting your contribution, please make sure to take a moment and read through the following guide: - -## Repo Setup - -To develop and test the core `Hyper Chat` package, please respect the [Tauri Guide](https://tauri.app/v1/guides/). - -## Pull Request Guidelines - -- Checkout a topic branch from a base branch, e.g. `master`, and merge back against that branch. - -- If adding a new feature: - - - Add accompanying test case. - - Provide a convincing reason to add this feature. Ideally, you should open a suggestion issue first and have it approved before working on it. - -- If fixing bug: - - - If you are resolving a special issue, add `(fix #xxxx[,#xxxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `fix: update entities encoding/decoding (fix #3899)`. - - Provide a detailed description of the bug in the PR. Live demo preferred. - - Add appropriate test coverage if applicable. - -- It's OK to have multiple small commits as you work on the PR - GitHub can automatically squash them before merging. - -- Make sure tests pass! - -- Commit messages must follow the [Angular Team's Commit Message Guidelines](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit) so that changelogs can be automatically generated. Commit messages are automatically validated before commit. -- No need to worry about code style as long as you have installed the dev dependencies - modified files are automatically formatted with Prettier on commit. diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 01b7950e..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Yancey Leo - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index 293ab699..e215bc4c 100644 --- a/README.md +++ b/README.md @@ -1,94 +1,36 @@ -# Hyper Chat +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). -![Hyper Chat](./screenshots/chat-completion.png) +## Getting Started -[![CodeQL](https://github.com/HyperChatBot/hyperchat/actions/workflows/github-code-scanning/codeql/badge.svg?branch=master)](https://github.com/HyperChatBot/hyperchat/actions/workflows/github-code-scanning/codeql) -[![Release](https://github.com/HyperChatBot/hyperchat/actions/workflows/cross-platform-release.yml/badge.svg)](https://github.com/HyperChatBot/hyperchat/actions/workflows/cross-platform-release.yml) -[![Test](https://github.com/HyperChatBot/hyperchat/actions/workflows/cross-platform-test.yml/badge.svg)](https://github.com/HyperChatBot/hyperchat/actions/workflows/cross-platform-test.yml) -[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) -[![Code Style](https://img.shields.io/badge/code%20style-prettier-green)](https://prettier.io/) -[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-green.svg)](https://github.com/HyperChatBot/hyperchat/pulls) -[![Node](https://img.shields.io/badge/Node.js-%3E%3D18.19.0-green.svg)](https://nodejs.org/en/) -[![Rust](https://img.shields.io/badge/Rust-%3E%3D1.81.0-orange.svg)](https://nodejs.org/en/) -[![Version](https://img.shields.io/badge/Version-v2.0.1-blue.svg)](https://nodejs.org/en/) -[![Twitter](https://img.shields.io/badge/Twitter-Connect-brightgreen?logo=twitter)](https://twitter/YanceyOfficial) +First, run the development server: -## Introduction +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` -Hyper Chat is a high-performance cross-platform AI chat application for desktop that is compatible with both OpenAI and Azure OpenAI services' APIs. In addition, Hyper Chat also provides features such as Text Completion, Image Generation, Audio Transcription, and Audio Translation. +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. -## To start using Hyper Chat +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. -You can download Hyper Chat on our [Landing Page](https://hyperchat.yancey.app), or manual download on [GitHub Release](https://github.com/HyperChatBot/hyperchat/releases/). +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. -We always keep the dev tools(eg: Command + Option + I) open in the production environment. In Hyper Chat, everything is transparent and controllable. +## Learn More -### macOS +To learn more about Next.js, take a look at the following resources: -As Hyper Chat is not planning to be released on the App Store, you may encounter the following issue when you open it for the first time. Please follow the steps below to resolve it: +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. -![can't-be-oepn-in-macos](./screenshots/can't-be-oepn-in-macos.png) +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! -1. Move the Hyper Chat.app to the /Applications directory. -2. Open your terminal App, execute the command `chmod +x /Applications/Hyper\ Chat.app/Contents/MacOS/Hyper\ Chat`. +## Deploy on Vercel -## To start developing Hyper Chat +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. -### Prerequisites - -We have chosen [Tauri](https://tauri.app/) as our cross-platform base. Please make sure that [Rust](https://www.rust-lang.org/) is installed on your system. - -Then, to install Tauri CLI globally, please follow the tutorial on [create-tauri-app](https://github.com/tauri-apps/create-tauri-app). We recommend using `cargo install tauri-cli`. - -Additionally, we use [React](https://react.dev/) + [Vite](https://vitejs.dev/) for rendering and packaging pages, so please install [Node.js](https://nodejs.org/en) and [pnpm](https://pnpm.io/) globally in advance. - -### Recommended IDE Setup - -- [VS Code](https://code.visualstudio.com/) -- [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) -- [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) -- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) -- [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) -- [Eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - -### Available Scripts - -- To start tauri development window, you can execute `cargo tauri dev`. -- To build the bundle, you can execute `cargo tauri build`. - -## Contributing - -The main purpose of this repository is to continue to evolve Hyper Chat, making it faster and easier to use. Development of Hyper Chat happens in the open on GitHub, and we are grateful to the community for contributing bugfixes and improvements. Read below to learn how you can take part in improving Hyper Chat. - -### [Code of Conduct](./CODE_OF_CONDUCT.md) - -Hyper Chat has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](./CODE_OF_CONDUCT.md) so that you can understand what actions will and will not be tolerated. - -### [Contributing Guide](./CONTRIBUTING.md) - -Read our [contributing guide](./CONTRIBUTING.md) to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to Hyper Chat. - -### Good Issues - -Please make sure to read the [Issue Reporting Checklist](./.github/ISSUE_TEMPLATE/bug_report.md) before opening an issue. Issues not conforming to the guidelines may be closed immediately. - -## Upgrade Plans - -We are continuously working to enhance Hyper Chat's capabilities and performance. Here are some of the features and upgrades that we plan to add in the future releases: - -- Support function call and plugin -- Support audio input -- Support for Claude, Gemini, Llama and so on -- Improve Performance - -## Discussions - -If you have any questions or feedback about Hyper Chat, please visit our [official discussion forum](https://github.com/orgs/HyperChatBot/discussions/71) to start a conversation with our team or other users. We are committed to making Hyper Chat the best possible chat application, and your feedback plays a crucial role in achieving this goal. - -## Thanks - -The UI design is inspired by [Chat-Web-App-UI-Kit](https://www.figma.com/community/file/1167012734150108159/Chat-Web-App-UI-Kit), Thank you [Figma UI Free](https://www.figma.com/@figmauifree)! - -## License - -Hyper Chat is licensed under the terms of the [MIT licensed](https://opensource.org/licenses/MIT). +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index c6e25a22..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,7 +0,0 @@ -# Reporting Security Issues - -If you discover a security issue in Hyper Chat, please report it by sending an email to [yanceyofficial@gmail.com](mailto:yanceyofficial@gmail.com). - -This will allow us to assess the risk, and make a fix available before we add a bug report to the GitHub repository. - -Thanks for helping make Hyper Chat safe for everyone! diff --git a/app/(chat)/actions.ts b/app/(chat)/actions.ts new file mode 100644 index 00000000..23772533 --- /dev/null +++ b/app/(chat)/actions.ts @@ -0,0 +1,22 @@ +'use server' + +import { openai } from '@/lib/ai/providers' +import { generateText, Message } from 'ai' + +export async function generateTitleFromUserMessage({ + message +}: { + message: Message +}) { + const { text: title } = await generateText({ + model: openai('gpt-4o'), + system: `\n + - you will generate a short title based on the first message a user begins a conversation with + - ensure it is not more than 80 characters long + - the title should be a summary of the user's message + - do not use quotes or colons`, + prompt: JSON.stringify(message) + }) + + return title +} diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts new file mode 100644 index 00000000..be239ea2 --- /dev/null +++ b/app/(chat)/api/chat/route.ts @@ -0,0 +1,123 @@ +import { regularPrompt } from '@/lib/ai/prompts' +import { toolFn as calculator } from '@/lib/ai/tools/calculator' +import { toolFn as getCurrencyRate } from '@/lib/ai/tools/get-currency-rate' +import { toolFn as getDate } from '@/lib/ai/tools/get-date' +import { toolFn as getWeather } from '@/lib/ai/tools/get-weather' +import { toolFn as searchOnline } from '@/lib/ai/tools/search-online' +import { toolFn as webScraper } from '@/lib/ai/tools/web-scraper' +import { + deleteChatById, + getChatById, + saveChat, + saveMessages +} from '@/lib/db/queries' +import { Setting } from '@/lib/db/schema' +import { getMostRecentUserMessage, sanitizeResponseMessages } from '@/lib/utils' +import { createOpenAI } from '@ai-sdk/openai' +import { type Message, createDataStreamResponse, streamText } from 'ai' +import { v4 as uuidV4 } from 'uuid' +import { generateTitleFromUserMessage } from '../../actions' + +export const maxDuration = 60 + +export async function POST(request: Request) { + const { + id, + setting, + messages + }: { id: string; messages: Array; setting: Setting } = + await request.json() + + const userMessage = getMostRecentUserMessage(messages) + + if (!userMessage) { + return new Response('No user message found', { status: 400 }) + } + const chat = await getChatById({ id }) + if (!chat) { + const title = await generateTitleFromUserMessage({ message: userMessage }) + await saveChat({ id, title }) + } + + await saveMessages({ + messages: [{ ...userMessage, createdAt: new Date(), chatId: id }] + }) + + const openai = createOpenAI({ + apiKey: setting.openaiApiKey, + baseURL: setting.openaiBaseUrl + }) + + return createDataStreamResponse({ + execute: (dataStream) => { + const result = streamText({ + model: openai('gpt-4o'), + system: regularPrompt, + messages, + maxSteps: 10, + experimental_generateMessageId: uuidV4, + providerOptions: { + openai: { + // reasoningEffort: 'medium' + } + }, + tools: { + ...calculator, + ...getWeather, + ...getCurrencyRate, + ...searchOnline, + ...getDate, + ...webScraper + }, + onFinish: async ({ response, reasoning }) => { + try { + const sanitizedResponseMessages = sanitizeResponseMessages({ + messages: response.messages, + reasoning + }) + + await saveMessages({ + messages: sanitizedResponseMessages.map((message) => { + return { + id: message.id, + chatId: id, + role: message.role, + content: message.content, + createdAt: new Date() + } + }) + }) + } catch { + console.error('Failed to save chat') + } + } + }) + + result.mergeIntoDataStream(dataStream, { + sendReasoning: true + }) + }, + onError: (e) => { + return e instanceof Error ? e.message : 'Oops, an error occured!' + } + }) +} + +export async function DELETE(request: Request) { + const { searchParams } = new URL(request.url) + const id = searchParams.get('id') + + if (!id) { + return new Response('Not Found', { status: 404 }) + } + + try { + await deleteChatById({ id }) + + return new Response('Chat deleted', { status: 200 }) + } catch { + return new Response('An error occurred while processing your request', { + status: 500 + }) + } +} diff --git a/app/(chat)/api/document/route.ts b/app/(chat)/api/document/route.ts new file mode 100644 index 00000000..3571846c --- /dev/null +++ b/app/(chat)/api/document/route.ts @@ -0,0 +1,103 @@ +import { auth } from '@/app/(auth)/auth' +import { ArtifactKind } from '@/components/artifact' +import { + deleteDocumentsByIdAfterTimestamp, + getDocumentsById, + saveDocument +} from '@/lib/db/queries' + +export async function GET(request: Request) { + const { searchParams } = new URL(request.url) + const id = searchParams.get('id') + + if (!id) { + return new Response('Missing id', { status: 400 }) + } + + const session = await auth() + + if (!session || !session.user) { + return new Response('Unauthorized', { status: 401 }) + } + + const documents = await getDocumentsById({ id }) + + const [document] = documents + + if (!document) { + return new Response('Not Found', { status: 404 }) + } + + if (document.userId !== session.user.id) { + return new Response('Unauthorized', { status: 401 }) + } + + return Response.json(documents, { status: 200 }) +} + +export async function POST(request: Request) { + const { searchParams } = new URL(request.url) + const id = searchParams.get('id') + + if (!id) { + return new Response('Missing id', { status: 400 }) + } + + const session = await auth() + + if (!session) { + return new Response('Unauthorized', { status: 401 }) + } + + const { + content, + title, + kind + }: { content: string; title: string; kind: ArtifactKind } = + await request.json() + + if (session.user?.id) { + const document = await saveDocument({ + id, + content, + title, + kind, + userId: session.user.id + }) + + return Response.json(document, { status: 200 }) + } + return new Response('Unauthorized', { status: 401 }) +} + +export async function PATCH(request: Request) { + const { searchParams } = new URL(request.url) + const id = searchParams.get('id') + + const { timestamp }: { timestamp: string } = await request.json() + + if (!id) { + return new Response('Missing id', { status: 400 }) + } + + const session = await auth() + + if (!session || !session.user) { + return new Response('Unauthorized', { status: 401 }) + } + + const documents = await getDocumentsById({ id }) + + const [document] = documents + + if (document.userId !== session.user.id) { + return new Response('Unauthorized', { status: 401 }) + } + + await deleteDocumentsByIdAfterTimestamp({ + id, + timestamp: new Date(timestamp) + }) + + return new Response('Deleted', { status: 200 }) +} diff --git a/app/(chat)/api/files/upload/route.ts b/app/(chat)/api/files/upload/route.ts new file mode 100644 index 00000000..f1818e71 --- /dev/null +++ b/app/(chat)/api/files/upload/route.ts @@ -0,0 +1,91 @@ +import { put } from '@vercel/blob' +import { NextResponse } from 'next/server' +import { z } from 'zod' + +import { auth } from '@/app/(auth)/auth' + +// Use Blob instead of File since File is not available in Node.js environment +const FileSchema = z.object({ + file: z + .instanceof(Blob) + .refine((file) => file.size <= 5 * 1024 * 1024, { + message: 'File size should be less than 5MB' + }) + // Update the file type based on the kind of files you want to accept + .refine((file) => ['image/jpeg', 'image/png'].includes(file.type), { + message: 'File type should be JPEG or PNG' + }) +}) + +export async function POST(request: Request) { + const session = await auth() + + if (!session) { + return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) + } + + if (request.body === null) { + return new Response('Request body is empty', { status: 400 }) + } + + try { + const formData = await request.formData() + const file = formData.get('file') as Blob + + if (!file) { + return NextResponse.json({ error: 'No file uploaded' }, { status: 400 }) + } + + const validatedFile = FileSchema.safeParse({ file }) + + if (!validatedFile.success) { + const errorMessage = validatedFile.error.errors + .map((error) => error.message) + .join(', ') + + return NextResponse.json({ error: errorMessage }, { status: 400 }) + } + + // Get filename from formData since Blob doesn't have name property + const filename = (formData.get('file') as File).name + const fileBuffer = await file.arrayBuffer() + + try { + const data = await put(`${filename}`, fileBuffer, { + access: 'public' + }) + + return NextResponse.json(data) + } catch (error) { + return NextResponse.json({ error: 'Upload failed' }, { status: 500 }) + } + } catch (error) { + return NextResponse.json( + { error: 'Failed to process request' }, + { status: 500 } + ) + } +} + +// import { +// generateChunksByRecursiveCharacterTextSplitter, +// generateEmbeddings, +// loadPDF, +// } from '@/lib/ai/document-to-embeddings' +// import { storeEmbeddingsToDb } from '@/lib/db/queries' +// import { NextResponse } from 'next/server' + +// export async function POST(req: Request) { +// const formData = await req.formData() +// const pdfFile = formData.get('pdf') as Blob +// const docs = await loadPDF(pdfFile) +// const chunks = await generateChunksByRecursiveCharacterTextSplitter(docs) +// const embeddings = await generateEmbeddings( +// chunks.map((chunk) => chunk.pageContent) +// ) +// await storeEmbeddingsToDb(embeddings) + +// return NextResponse.json({ +// success: true +// }) +// } diff --git a/app/(chat)/api/history/route.ts b/app/(chat)/api/history/route.ts new file mode 100644 index 00000000..82f49c56 --- /dev/null +++ b/app/(chat)/api/history/route.ts @@ -0,0 +1,6 @@ +import { getChats } from '@/lib/db/queries' + +export async function GET() { + const chats = await getChats() + return Response.json(chats) +} diff --git a/app/(chat)/api/setting/route.ts b/app/(chat)/api/setting/route.ts new file mode 100644 index 00000000..0868c1fc --- /dev/null +++ b/app/(chat)/api/setting/route.ts @@ -0,0 +1,15 @@ +import { getSetting, updateSetting } from '@/lib/db/queries' +import { Setting } from '@/lib/db/schema' + +export async function GET() { + const setting = await getSetting() + return Response.json(setting, { status: 200 }) +} + +export async function POST(request: Request) { + const { id, setting: settingPayload }: { id: string; setting: Setting } = + await request.json() + const setting = await updateSetting(id, settingPayload) + + return Response.json(setting, { status: 200 }) +} diff --git a/app/(chat)/api/suggestions/route.ts b/app/(chat)/api/suggestions/route.ts new file mode 100644 index 00000000..404c057c --- /dev/null +++ b/app/(chat)/api/suggestions/route.ts @@ -0,0 +1,33 @@ +import { auth } from '@/app/(auth)/auth' +import { getSuggestionsByDocumentId } from '@/lib/db/queries' + +export async function GET(request: Request) { + const { searchParams } = new URL(request.url) + const documentId = searchParams.get('documentId') + + if (!documentId) { + return new Response('Not Found', { status: 404 }) + } + + const session = await auth() + + if (!session || !session.user) { + return new Response('Unauthorized', { status: 401 }) + } + + const suggestions = await getSuggestionsByDocumentId({ + documentId + }) + + const [suggestion] = suggestions + + if (!suggestion) { + return Response.json([], { status: 200 }) + } + + if (suggestion.userId !== session.user.id) { + return new Response('Unauthorized', { status: 401 }) + } + + return Response.json(suggestions, { status: 200 }) +} diff --git a/app/(chat)/api/upload-pdf/route.ts b/app/(chat)/api/upload-pdf/route.ts new file mode 100644 index 00000000..e69de29b diff --git a/app/(chat)/api/vote/route.ts b/app/(chat)/api/vote/route.ts new file mode 100644 index 00000000..d84a9c7a --- /dev/null +++ b/app/(chat)/api/vote/route.ts @@ -0,0 +1,48 @@ +import { auth } from '@/app/(auth)/auth' +import { getVotesByChatId, voteMessage } from '@/lib/db/queries' + +export async function GET(request: Request) { + const { searchParams } = new URL(request.url) + const chatId = searchParams.get('chatId') + + if (!chatId) { + return new Response('chatId is required', { status: 400 }) + } + + const session = await auth() + + if (!session || !session.user || !session.user.email) { + return new Response('Unauthorized', { status: 401 }) + } + + const votes = await getVotesByChatId({ id: chatId }) + + return Response.json(votes, { status: 200 }) +} + +export async function PATCH(request: Request) { + const { + chatId, + messageId, + type + }: { chatId: string; messageId: string; type: 'up' | 'down' } = + await request.json() + + if (!chatId || !messageId || !type) { + return new Response('messageId and type are required', { status: 400 }) + } + + const session = await auth() + + if (!session || !session.user || !session.user.email) { + return new Response('Unauthorized', { status: 401 }) + } + + await voteMessage({ + chatId, + messageId, + type: type + }) + + return new Response('Message voted', { status: 200 }) +} diff --git a/app/(chat)/chat/[id]/page.tsx b/app/(chat)/chat/[id]/page.tsx new file mode 100644 index 00000000..b9b29179 --- /dev/null +++ b/app/(chat)/chat/[id]/page.tsx @@ -0,0 +1,22 @@ +import { Chat } from '@/components/chatbox/chat' +import { getChatById, getMessagesByChatId } from '@/lib/db/queries' +import { convertToUIMessages } from '@/lib/utils' +import { notFound } from 'next/navigation' + +export default async function Page(props: { params: Promise<{ id: string }> }) { + const params = await props.params + const { id } = params + const chat = await getChatById({ id }) + + if (!chat) { + notFound() + } + + const messagesFromDb = await getMessagesByChatId({ + id + }) + + return ( + + ) +} diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 00000000..773aacfe --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,75 @@ +import { SidebarRight } from '@/components/chatbox/config' +import { AppSidebar } from '@/components/layout/app-sidebar' +import { NavActions } from '@/components/layout/nav-actions' +import { SettingsDialog } from '@/components/setting/settings-dialog' +import { Separator } from '@/components/ui/separator' +import { + SidebarInset, + SidebarProvider, + SidebarTrigger +} from '@/components/ui/sidebar' +import { Toaster } from '@/components/ui/sonner' +import '@/public/stylesheets/globals.css' +import { Provider } from 'jotai' +import type { Metadata } from 'next' +import { ThemeProvider } from 'next-themes' +import { Geist, Geist_Mono } from 'next/font/google' + +const geistSans = Geist({ + variable: '--font-geist-sans', + subsets: ['latin'] +}) + +const geistMono = Geist_Mono({ + variable: '--font-geist-mono', + subsets: ['latin'] +}) + +export const metadata: Metadata = { + title: 'Hyper Chat', + description: 'Advanced AI Agent' +} + +export default function RootLayout({ + children +}: Readonly<{ + children: React.ReactNode +}>) { + return ( + + + + + + + +
+
+
+ + +
+
+ +
+
+ {children} + + +
+
+ +
+
+
+ + + ) +} diff --git a/app/page.tsx b/app/page.tsx new file mode 100644 index 00000000..1e6588ea --- /dev/null +++ b/app/page.tsx @@ -0,0 +1,7 @@ +import { Chat } from '@/components/chatbox/chat' +import { v4 as uuidV4 } from 'uuid' + +export default async function Page() { + const id = uuidV4() + return +} diff --git a/components.json b/components.json new file mode 100644 index 00000000..a64445d7 --- /dev/null +++ b/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "app/globals.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} diff --git a/components/chatbox/attatch/attachemnt-uploader.tsx b/components/chatbox/attatch/attachemnt-uploader.tsx new file mode 100644 index 00000000..30891938 --- /dev/null +++ b/components/chatbox/attatch/attachemnt-uploader.tsx @@ -0,0 +1,68 @@ +import { convertToBase64 } from '@/lib/utils' +import { base64FilePromptAtom } from '@/stores/conversation' +import classNames from 'classnames' +import { useAtom } from 'jotai' +import { Paperclip } from 'lucide-react' +import { ChangeEvent, FC, useRef } from 'react' + +interface Props { + className?: string +} + +const AttachmentUploader: FC = ({ className }) => { + const fileInputRef = useRef(null) + const [base64FilePrompt, setBase64FilePrompt] = useAtom(base64FilePromptAtom) + + const validate = () => true + + const onFileChange = async (e: ChangeEvent) => { + const files = e.target.files + if (!files) return + + try { + const promises = [] + for (const file of files) { + promises.push(convertToBase64(file)) + } + + const base64Files = await Promise.all(promises) + setBase64FilePrompt([...base64FilePrompt, ...base64Files]) + } catch { + // TODO: + } finally { + fileInputRef.current.files = null + } + } + + return ( +
+ +
+ ) +} + +export default AttachmentUploader diff --git a/components/chatbox/attatch/attachment-previewer.tsx b/components/chatbox/attatch/attachment-previewer.tsx new file mode 100644 index 00000000..eb7d2d77 --- /dev/null +++ b/components/chatbox/attatch/attachment-previewer.tsx @@ -0,0 +1,73 @@ +import { base64FilePromptAtom } from '@/stores/conversation' +import { useAtom } from 'jotai' +import { ShieldClose } from 'lucide-react' +import { FC } from 'react' + +interface Props { + className?: string +} + +const AttachmentPreview: FC = ({ className }) => { + const [base64FilePrompt, setBase64FilePrompt] = useAtom(base64FilePromptAtom) + + const deleteBase64FilePrompt = (id: string) => { + setBase64FilePrompt(base64FilePrompt.filter((prompt) => prompt.id !== id)) + } + + return ( +
+ {base64FilePrompt.map((prompt) => { + if (prompt.mimeType.includes('image')) { + return ( +
+
+ + deleteBase64FilePrompt(prompt.id)} + /> + + +
+
+ ) + } + + if (prompt.mimeType.includes('audio')) { + return ( +
+
+ ) + } + + if (prompt.mimeType.includes('video')) { + return ( +
+
+ ) + } + + return ( +
+ {prompt.name} +
+ ) + })} +
+ ) +} + +export default AttachmentPreview diff --git a/src/components/ChatBox/Recorder.tsx b/components/chatbox/attatch/recorder.tsx similarity index 60% rename from src/components/ChatBox/Recorder.tsx rename to components/chatbox/attatch/recorder.tsx index f42caeae..b2295e68 100644 --- a/src/components/ChatBox/Recorder.tsx +++ b/components/chatbox/attatch/recorder.tsx @@ -1,21 +1,21 @@ +import RecorderJSON from '@/assets/lotties/recorder.json' +import { useSTT } from '@/hooks' +import { inputTextAtom } from '@/stores/conversation' +import { settingsAtom } from '@/stores/global' import { Player } from '@lottiefiles/react-lottie-player' import classNames from 'classnames' +import { useAtom, useAtomValue } from 'jotai' import { enqueueSnackbar } from 'notistack' import { FC, useRef, useState } from 'react' -import { useRecoilState, useRecoilValue } from 'recoil' -import RecorderJSON from 'src/assets/lotties/recorder.json' -import { useClients } from 'src/hooks' -import { userInputState } from 'src/stores/conversation' -import { settingsState } from 'src/stores/settings' interface Props { className?: string } const AudioRecorder: FC = ({ className }) => { - const settings = useRecoilValue(settingsState) - const { azureClient } = useClients() - const [userInput, setUserInput] = useRecoilState(userInputState) + const settings = useAtomValue(settingsAtom) + const createSTT = useSTT() + const [inputText, setInputText] = useAtom(inputTextAtom) const [isRecording, setIsRecording] = useState(false) // const [audioUrl, setAudioUrl] = useState('') const mediaRecorderRef = useRef(null) @@ -35,19 +35,17 @@ const AudioRecorder: FC = ({ className }) => { audioChunksRef.current.push(event.data) } mediaRecorderRef.current.onstop = async () => { - const audioBlob = new Blob(audioChunksRef.current, { - type: 'audio/mp3' - }) - const uint8Array = new Uint8Array(await audioBlob.arrayBuffer()) - const transcription = await azureClient.getAudioTranscription( - settings.azureDeploymentNameAudioGeneration, - uint8Array - ) - setUserInput(`${userInput}${transcription.text}`) - - // const audioUrl = URL.createObjectURL(audioBlob) - // setAudioUrl(audioUrl) + const transcriptionText = await createSTT(audioChunksRef.current) + setInputText(`${inputText}${transcriptionText}`) audioChunksRef.current = [] + + // setAudioUrl( + // URL.createObjectURL( + // new Blob(audioChunksRef.current, { + // type: 'audio/mp3' + // }) + // ) + // ) } } catch (error) { enqueueSnackbar('Error accessing media devices.', { variant: 'error' }) @@ -75,13 +73,14 @@ const AudioRecorder: FC = ({ className }) => { /> {/* { - // the audio preview is just for test. - audioUrl && ( - - )} */} + // the audio preview is just for test. + audioUrl && ( + + ) + } */} ) } diff --git a/components/chatbox/attatch/token-count.tsx b/components/chatbox/attatch/token-count.tsx new file mode 100644 index 00000000..cb6e24a2 --- /dev/null +++ b/components/chatbox/attatch/token-count.tsx @@ -0,0 +1,25 @@ +import configurations from '@/lib/ai/configurations' +import { configurationAtom, conversationAtom } from '@/stores/conversation' +import { companyAtom } from '@/stores/global' +import { useAtomValue } from 'jotai' +import { FC } from 'react' + +const TokenCount: FC = () => { + const conversation = useAtomValue(conversationAtom) + const company = useAtomValue(companyAtom) + const configuration = useAtomValue(configurationAtom) + const { models } = configurations[company] + const { maxInput } = + models.find((m) => m.modelName === configuration.model) ?? {} + const usedTokenCount = + conversation?.messages.reduce((acc, val) => acc + val.tokenCount, 0) + + configuration.systemMessageTokensCount + + return ( +

+ Token count: {usedTokenCount} / {maxInput} +

+ ) +} + +export default TokenCount diff --git a/components/chatbox/attatch/tool-box.tsx b/components/chatbox/attatch/tool-box.tsx new file mode 100644 index 00000000..84508f09 --- /dev/null +++ b/components/chatbox/attatch/tool-box.tsx @@ -0,0 +1,51 @@ +import { useTTS } from '@/hooks' +import { ContentPartType, Message, Roles } from '@/types/conversation' +import { Copy, Speaker } from 'lucide-react' +import { DateTime } from 'luxon' +import { FC, useState } from 'react' + +interface Props { + message: Message +} + +const ToolsBox: FC = ({ message: { createdAt, content, role } }) => { + const [audioUrl, setAudioUrl] = useState('') + const createSpeech = useTTS() + + const createTTSUrl = async () => { + if (typeof createSpeech === 'function') { + const textPrompt = content.find( + (item) => item.type === ContentPartType.TextPrompt + ) + + if (textPrompt) { + const url = await createSpeech(textPrompt.text) + if (url) { + setAudioUrl(url) + } + } + } + } + + return ( +
+ {role === Roles.Assistant && ( + <> + + + + )} + + {DateTime.fromMillis(createdAt).toLocaleString( + DateTime.DATETIME_SHORT_WITH_SECONDS + )} + + {audioUrl &&
+ ) +} + +export default ToolsBox diff --git a/src/components/Waveform/index.tsx b/components/chatbox/attatch/wave-form.tsx similarity index 65% rename from src/components/Waveform/index.tsx rename to components/chatbox/attatch/wave-form.tsx index 4f8ad442..15e9df51 100644 --- a/src/components/Waveform/index.tsx +++ b/components/chatbox/attatch/wave-form.tsx @@ -1,8 +1,7 @@ -import { PauseCircleIcon, PlayCircleIcon } from '@heroicons/react/24/outline' +import { currPlayingAudioIdAtom } from '@/stores/conversation' +import { useAtom } from 'jotai' +import { PauseCircle, PlayCircle } from 'lucide-react' import { FC, useEffect, useRef, useState } from 'react' -import { useRecoilState } from 'recoil' -import { useAppData } from 'src/hooks' -import { currPlayingAudioIdState } from 'src/stores/conversation' import WaveSurfer from 'wavesurfer.js' interface Props { @@ -10,28 +9,36 @@ interface Props { } const Waveform: FC = ({ filename }) => { - const [currPlayingAudioId, setCurrPlayingAudioId] = useRecoilState( - currPlayingAudioIdState + const [currPlayingAudioId, setCurrPlayingAudioId] = useAtom( + currPlayingAudioIdAtom ) - const { transformFilenameToSrc } = useAppData() const [src, setSrc] = useState('') - const [isPlaying, toggleIsPlaying] = useState(false) + const [isPlaying, setIsPlaying] = useState(false) const containerRef = useRef(null) const waveSurferRef = useRef(null) const handlePlaying = () => { - toggleIsPlaying(!waveSurferRef.current?.isPlaying()) + const isCurrentlyPlaying = waveSurferRef.current?.isPlaying() || false + setIsPlaying(!isCurrentlyPlaying) - if (!waveSurferRef.current?.isPlaying()) { - setCurrPlayingAudioId(filename) + if (!isCurrentlyPlaying) { + if (typeof setCurrPlayingAudioId === 'function') { + setCurrPlayingAudioId(filename) + } } waveSurferRef.current?.playPause() } const createFileSrc = async () => { - const currSrc = await transformFilenameToSrc(filename) - setSrc(currSrc || '') + const src = await window.electronAPI.transformFilenameToSrc({ + filename + }) + const blob = new Blob([src.arrayBuffer], { + type: 'application/octet-stream' + }) + const assetUrl = URL.createObjectURL(blob) + setSrc(assetUrl || '') } useEffect(() => { @@ -41,7 +48,7 @@ const Waveform: FC = ({ filename }) => { useEffect(() => { if (currPlayingAudioId !== filename) { waveSurferRef.current?.stop() - toggleIsPlaying(false) + setIsPlaying(false) } }, [currPlayingAudioId]) @@ -61,7 +68,7 @@ const Waveform: FC = ({ filename }) => { waveSurferRef.current = waveSurfer }) waveSurfer.on('finish', () => { - toggleIsPlaying(false) + setIsPlaying(false) }) return () => { @@ -72,14 +79,14 @@ const Waveform: FC = ({ filename }) => { return (
{isPlaying ? ( - ) : ( - = ({ message }) => { + const customBotAvatarUrl = useAtomValue(customBotAvatarUrlAtom) + + return ( +
+ {message.role === Roles.Assistant && ( + + + + )} + +
+
+ {message.role === Roles.Assistant && ( + + )} + + {message.role === Roles.User &&

{message.content}

} +
+
+
+ ) +} + +export default memo(ChatBubble) diff --git a/components/chatbox/chat.tsx b/components/chatbox/chat.tsx new file mode 100644 index 00000000..d6cfcf82 --- /dev/null +++ b/components/chatbox/chat.tsx @@ -0,0 +1,66 @@ +'use client' + +import { useSetting } from '@/hooks/use-setting' +import { useChat } from '@ai-sdk/react' +import type { Message } from 'ai' +import { toast } from 'sonner' +import { mutate } from 'swr' +import { v4 as uuidV4 } from 'uuid' +import Messages from './messages' +import MultimodalInput from './multimodel-input' + +interface Props { + id: string + initialMessages: Message[] +} + +export function Chat({ id, initialMessages }: Props) { + const { data: setting } = useSetting() + const { + messages, + setMessages, + handleSubmit, + input, + status, + setInput, + append, + stop, + reload + } = useChat({ + id, + body: { id, setting }, + initialMessages, + experimental_throttle: 100, + sendExtraMessageFields: true, + generateId: uuidV4, + onFinish: () => { + mutate('/api/history') + }, + onError: () => { + toast.error('An error occured, please try again!') + } + }) + + return ( + <> + + + + ) +} diff --git a/components/chatbox/config.tsx b/components/chatbox/config.tsx new file mode 100644 index 00000000..bb78e62c --- /dev/null +++ b/components/chatbox/config.tsx @@ -0,0 +1,263 @@ +'use client' + +import { Badge } from '@/components/ui/badge' +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel +} from '@/components/ui/form' +import { Input } from '@/components/ui/input' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue +} from '@/components/ui/select' +import { Textarea } from '@/components/ui/textarea' +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from '@/components/ui/tooltip' +import { configurationAtom } from '@/stores/conversation' +import { Configuration as IConfiguration } from '@/types/conversation' +import { useAtomValue } from 'jotai' +import { X } from 'lucide-react' +import * as React from 'react' +import { useEffect } from 'react' +import { Controller, useForm } from 'react-hook-form' +import InputSlider from '../common/input-slider' +import { Sidebar, SidebarContent } from '../ui/sidebar' + +export function SidebarRight({ + ...props +}: React.ComponentProps) { + const configuration = useAtomValue(configurationAtom) + const availableModels = [] + + const form = useForm({ + defaultValues: configuration + }) + + // Update form values when configuration changes + useEffect(() => { + if (configuration) { + form.reset(configuration) + } + }, [configuration, form]) + + const onSubmit = async (values: IConfiguration) => {} + + const maxOutput = availableModels?.find( + (availableModel) => availableModel.modelName === form.watch('model') + )?.maxOutput + + return ( + + +
+ + ( + + Model + + + )} + /> + + ( + + System Message + +