From 32a86bd9136be0ac044c561f341b537e591190da Mon Sep 17 00:00:00 2001 From: hieu-jan <150573299+hieu-jan@users.noreply.github.com> Date: Tue, 27 Feb 2024 19:21:10 +0900 Subject: [PATCH 01/10] docs: add newsletter --- .../community/{community.md => community.mdx} | 15 +++++++++++++++ docs/src/containers/Footer/index.js | 4 ++++ 2 files changed, 19 insertions(+) rename docs/docs/community/{community.md => community.mdx} (59%) diff --git a/docs/docs/community/community.md b/docs/docs/community/community.mdx similarity index 59% rename from docs/docs/community/community.md rename to docs/docs/community/community.mdx index 24a87daf0..d4866490e 100644 --- a/docs/docs/community/community.md +++ b/docs/docs/community/community.mdx @@ -29,3 +29,18 @@ keywords: ## Careers - [Jobs](https://janai.bamboohr.com/careers) + +## Newsletter + + diff --git a/docs/src/containers/Footer/index.js b/docs/src/containers/Footer/index.js index 7cd648149..3e62f579a 100644 --- a/docs/src/containers/Footer/index.js +++ b/docs/src/containers/Footer/index.js @@ -86,6 +86,10 @@ const menus = [ path: "https://janai.bamboohr.com/careers", external: true, }, + { + menu: "Newsletter", + path: "/community#newsletter", + } ], }, ]; From 222b4ad897c275dab0eaec3c8a8472bf3df7afc4 Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Tue, 27 Feb 2024 20:39:57 +0700 Subject: [PATCH 02/10] feat: temporary remove dark mode :( (#2168) * remove darkmode * fix progress component background color --- uikit/src/button/styles.scss | 8 +-- uikit/src/checkbox/styles.scss | 2 +- uikit/src/input/styles.scss | 2 +- uikit/src/progress/styles.scss | 4 +- uikit/src/select/styles.scss | 2 +- uikit/src/slider/styles.scss | 4 +- uikit/src/switch/styles.scss | 2 +- uikit/src/tooltip/styles.scss | 4 +- web/app/layout.tsx | 2 +- web/containers/CardSidebar/index.tsx | 14 ++--- web/containers/Checkbox/index.tsx | 6 +- web/containers/DropdownListSidebar/index.tsx | 10 ++-- web/containers/GPUDriverPromptModal/index.tsx | 2 +- .../BottomBar/DownloadingState/index.tsx | 2 +- .../BottomBar/ImportingModelState/index.tsx | 2 +- web/containers/Layout/Ribbon/index.tsx | 6 +- web/containers/Layout/TopBar/index.tsx | 6 +- web/containers/Loader/index.tsx | 12 ++-- web/containers/ModalTroubleShoot/AppLogs.tsx | 2 +- .../ModalTroubleShoot/DeviceSpecs.tsx | 2 +- web/containers/ModalTroubleShoot/index.tsx | 13 ++--- web/containers/ModelConfigInput/index.tsx | 6 +- web/containers/OpenAiKeyInput/index.tsx | 2 +- web/containers/Providers/Theme.tsx | 10 +--- web/containers/ServerLogs/index.tsx | 2 +- web/containers/SliderRightPanel/index.tsx | 6 +- web/containers/Toast/index.tsx | 12 ++-- web/hooks/useUserConfigs.ts | 11 ---- web/screens/Chat/CleanThreadModal/index.tsx | 4 +- web/screens/Chat/DeleteThreadModal/index.tsx | 6 +- web/screens/Chat/ErrorMessage/index.tsx | 4 +- web/screens/Chat/Sidebar/index.tsx | 20 +++---- web/screens/Chat/ThreadList/index.tsx | 8 +-- .../HuggingFaceSearchModal/index.tsx | 2 +- web/screens/ExploreModels/index.tsx | 2 +- web/screens/LocalServer/index.tsx | 26 ++++----- web/screens/Settings/Advanced/index.tsx | 2 +- .../Settings/Appearance/TogglePrimary.tsx | 57 ------------------- .../Settings/Appearance/ToggleTheme.tsx | 2 +- web/screens/Settings/Appearance/index.tsx | 2 - .../ImportModelOptionSelection.tsx | 2 +- .../Settings/ImportSuccessIcon/index.tsx | 2 +- web/screens/Settings/Models/Row.tsx | 6 +- .../Settings/SelectingModelModal/index.tsx | 4 +- web/screens/Settings/SettingMenu/index.tsx | 3 +- web/screens/Settings/index.tsx | 5 +- web/styles/components/message.scss | 4 +- web/types/appearance.d.ts | 6 -- 48 files changed, 107 insertions(+), 216 deletions(-) delete mode 100644 web/hooks/useUserConfigs.ts delete mode 100644 web/screens/Settings/Appearance/TogglePrimary.tsx delete mode 100644 web/types/appearance.d.ts diff --git a/uikit/src/button/styles.scss b/uikit/src/button/styles.scss index 003df5b4d..c97bec9e0 100644 --- a/uikit/src/button/styles.scss +++ b/uikit/src/button/styles.scss @@ -5,11 +5,11 @@ @apply disabled:pointer-events-none disabled:bg-zinc-100 disabled:text-zinc-400; &-primary { - @apply bg-primary hover:bg-primary/90 text-white; + @apply bg-blue-600 text-white hover:bg-blue-600/90; } &-secondary-blue { - @apply bg-blue-200 text-blue-600 hover:bg-blue-300/50 dark:hover:bg-blue-200/80; + @apply bg-blue-200 text-blue-600 hover:bg-blue-300/50; } &-danger { @@ -17,7 +17,7 @@ } &-secondary-danger { - @apply bg-red-200 text-red-600 hover:bg-red-300/50 dark:hover:bg-red-200/80; + @apply bg-red-200 text-red-600 hover:bg-red-300/50; } &-outline { @@ -66,7 +66,7 @@ [type='reset'], [type='submit'] { &.btn-primary { - @apply bg-primary hover:bg-primary/90; + @apply bg-blue-600 hover:bg-blue-600/90; @apply disabled:pointer-events-none disabled:bg-zinc-100 disabled:text-zinc-400; } &.btn-secondary { diff --git a/uikit/src/checkbox/styles.scss b/uikit/src/checkbox/styles.scss index 33610f837..cf35ed5ca 100644 --- a/uikit/src/checkbox/styles.scss +++ b/uikit/src/checkbox/styles.scss @@ -1,5 +1,5 @@ .checkbox { - @apply border-border data-[state=checked]:bg-primary h-5 w-5 flex-shrink-0 rounded-md border data-[state=checked]:text-white; + @apply border-border h-5 w-5 flex-shrink-0 rounded-md border data-[state=checked]:bg-blue-600 data-[state=checked]:text-white; &--icon { @apply h-4 w-4; diff --git a/uikit/src/input/styles.scss b/uikit/src/input/styles.scss index e649f494d..51efd8e57 100644 --- a/uikit/src/input/styles.scss +++ b/uikit/src/input/styles.scss @@ -1,6 +1,6 @@ .input { @apply border-border placeholder:text-muted-foreground flex h-9 w-full rounded-lg border bg-transparent px-3 py-1 transition-colors; - @apply disabled:text-muted-foreground disabled:cursor-not-allowed disabled:bg-zinc-100 disabled:dark:bg-zinc-800 disabled:dark:text-zinc-600; + @apply disabled:text-muted-foreground disabled:cursor-not-allowed disabled:bg-zinc-100; @apply focus-within:outline-none focus-visible:outline-0 focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-1; @apply file:border-0 file:bg-transparent file:font-medium; } diff --git a/uikit/src/progress/styles.scss b/uikit/src/progress/styles.scss index 0b7078f48..1a8483c47 100644 --- a/uikit/src/progress/styles.scss +++ b/uikit/src/progress/styles.scss @@ -1,7 +1,7 @@ .progress { - @apply bg-secondary relative h-4 w-full overflow-hidden rounded-full; + @apply relative h-4 w-full overflow-hidden rounded-full bg-gray-100; &-indicator { - @apply bg-primary h-full w-full flex-1 transition-all; + @apply h-full w-full flex-1 bg-blue-600 transition-all; } } diff --git a/uikit/src/select/styles.scss b/uikit/src/select/styles.scss index 90485723a..99db49766 100644 --- a/uikit/src/select/styles.scss +++ b/uikit/src/select/styles.scss @@ -1,6 +1,6 @@ .select { @apply placeholder:text-muted-foreground border-border flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border bg-transparent px-3 py-2 text-sm shadow-sm disabled:cursor-not-allowed [&>span]:line-clamp-1; - @apply disabled:text-muted-foreground disabled:cursor-not-allowed disabled:bg-zinc-100 disabled:dark:bg-zinc-800 disabled:dark:text-zinc-600; + @apply disabled:text-muted-foreground disabled:cursor-not-allowed disabled:bg-zinc-100; @apply focus-within:outline-none focus-visible:outline-0 focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-1; &-caret { diff --git a/uikit/src/slider/styles.scss b/uikit/src/slider/styles.scss index 718972efb..465392419 100644 --- a/uikit/src/slider/styles.scss +++ b/uikit/src/slider/styles.scss @@ -2,7 +2,7 @@ @apply relative flex w-full touch-none select-none items-center; &-track { - @apply relative h-1.5 w-full grow overflow-hidden rounded-full bg-gray-200 dark:bg-gray-800; + @apply relative h-1.5 w-full grow overflow-hidden rounded-full bg-gray-200; [data-disabled] { @apply cursor-not-allowed opacity-50; } @@ -13,6 +13,6 @@ } &-thumb { - @apply border-primary/50 bg-background focus-visible:ring-ring block h-4 w-4 rounded-full border shadow transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50; + @apply bg-background focus-visible:ring-ring block h-4 w-4 rounded-full border border-blue-600/50 shadow transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50; } } diff --git a/uikit/src/switch/styles.scss b/uikit/src/switch/styles.scss index c8a12cdf5..57fa128ba 100644 --- a/uikit/src/switch/styles.scss +++ b/uikit/src/switch/styles.scss @@ -1,7 +1,7 @@ .switch { @apply inline-flex h-[20px] w-[36px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent; @apply focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2; - @apply data-[state=checked]:bg-primary data-[state=unchecked]:bg-input; + @apply data-[state=unchecked]:bg-input data-[state=checked]:bg-blue-600; @apply disabled:cursor-not-allowed disabled:opacity-50; &-toggle { diff --git a/uikit/src/tooltip/styles.scss b/uikit/src/tooltip/styles.scss index 8ae645cee..169e081b7 100644 --- a/uikit/src/tooltip/styles.scss +++ b/uikit/src/tooltip/styles.scss @@ -1,6 +1,6 @@ .tooltip { - @apply dark:bg-input dark:text-foreground z-50 overflow-hidden rounded-md bg-gray-950 px-2 py-1.5 text-xs font-medium text-gray-200 shadow-md; + @apply z-50 overflow-hidden rounded-md bg-gray-950 px-2 py-1.5 text-xs font-medium text-gray-200 shadow-md; &-arrow { - @apply dark:fill-input fill-gray-950; + @apply fill-gray-950; } } diff --git a/web/app/layout.tsx b/web/app/layout.tsx index 6c6fc65ab..37bcdf53e 100644 --- a/web/app/layout.tsx +++ b/web/app/layout.tsx @@ -15,7 +15,7 @@ export const metadata: Metadata = { export default function RootLayout({ children }: PropsWithChildren) { return ( - +
{children} diff --git a/web/containers/CardSidebar/index.tsx b/web/containers/CardSidebar/index.tsx index 132494d48..3013360e9 100644 --- a/web/containers/CardSidebar/index.tsx +++ b/web/containers/CardSidebar/index.tsx @@ -45,7 +45,7 @@ export default function CardSidebar({ return (
@@ -61,7 +61,7 @@ export default function CardSidebar({ if (!children) return setShow(!show) }} - className="flex w-full flex-1 items-center space-x-2 rounded-lg bg-zinc-100 py-2 pr-2 dark:bg-zinc-900" + className="flex w-full flex-1 items-center space-x-2 rounded-lg bg-zinc-100 py-2 pr-2" > setMore(!more)} > @@ -114,7 +114,7 @@ export default function CardSidebar({ <> {title === 'Model' ? (
- + {openFileTitle()} @@ -122,7 +122,7 @@ export default function CardSidebar({
) : ( - + {openFileTitle()} )} @@ -141,7 +141,7 @@ export default function CardSidebar({ /> <>
- + Edit Global Defaults for{' '} diff --git a/web/containers/Checkbox/index.tsx b/web/containers/Checkbox/index.tsx index a545771b6..1ced3e19d 100644 --- a/web/containers/Checkbox/index.tsx +++ b/web/containers/Checkbox/index.tsx @@ -34,12 +34,10 @@ const Checkbox: React.FC = ({ return (
-

- {title} -

+

{title}

- + diff --git a/web/containers/DropdownListSidebar/index.tsx b/web/containers/DropdownListSidebar/index.tsx index c05d26e51..dc5ee2605 100644 --- a/web/containers/DropdownListSidebar/index.tsx +++ b/web/containers/DropdownListSidebar/index.tsx @@ -203,15 +203,14 @@ const DropdownListSidebar = ({ isTabActive === 1 && '[&_.select-scroll-down-button]:hidden' )} > -
-
    +
    +
      {engineOptions.map((name, i) => { return (
    • setIsTabActive(i)} @@ -230,8 +229,7 @@ const DropdownListSidebar = ({ {name} diff --git a/web/containers/GPUDriverPromptModal/index.tsx b/web/containers/GPUDriverPromptModal/index.tsx index bdcf1b2f8..8d11b4efa 100644 --- a/web/containers/GPUDriverPromptModal/index.tsx +++ b/web/containers/GPUDriverPromptModal/index.tsx @@ -60,7 +60,7 @@ const GPUDriverPrompt: React.FC = () => { id="default-checkbox" type="checkbox" onChange={onDoNotShowAgainChange} - className="h-4 w-4 rounded border-gray-300 bg-gray-100 text-blue-600 focus:ring-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600" + className="h-4 w-4 rounded border-gray-300 bg-gray-100 text-blue-600 focus:ring-2 focus:ring-blue-500" /> Don't show again
    diff --git a/web/containers/Layout/BottomBar/DownloadingState/index.tsx b/web/containers/Layout/BottomBar/DownloadingState/index.tsx index dcebacd3c..4c3d596b0 100644 --- a/web/containers/Layout/BottomBar/DownloadingState/index.tsx +++ b/web/containers/Layout/BottomBar/DownloadingState/index.tsx @@ -47,7 +47,7 @@ export default function DownloadingState() { { className="h-2 w-24" value={transferredSize / totalSize} /> - + {progress.toFixed(2)}%
diff --git a/web/containers/Layout/Ribbon/index.tsx b/web/containers/Layout/Ribbon/index.tsx index c0bc46586..dc6191f09 100644 --- a/web/containers/Layout/Ribbon/index.tsx +++ b/web/containers/Layout/Ribbon/index.tsx @@ -45,7 +45,7 @@ export default function RibbonNav() { size={20} className={twMerge( 'flex-shrink-0 text-muted-foreground', - serverEnabled && 'text-gray-300 dark:text-gray-700' + serverEnabled && 'text-gray-300' )} /> ), @@ -114,7 +114,7 @@ export default function RibbonNav() {
{isActive && ( )} @@ -166,7 +166,7 @@ export default function RibbonNav() {
{isActive && ( )} diff --git a/web/containers/Layout/TopBar/index.tsx b/web/containers/Layout/TopBar/index.tsx index 605d8e44d..9686a7fd9 100644 --- a/web/containers/Layout/TopBar/index.tsx +++ b/web/containers/Layout/TopBar/index.tsx @@ -159,7 +159,7 @@ const TopBar = () => { size={16} className="text-muted-foreground" /> - + {openFileTitle()}
@@ -175,7 +175,7 @@ const TopBar = () => { className="mt-0.5 flex-shrink-0 text-muted-foreground" />
- + Edit Threads Settings @@ -204,7 +204,7 @@ const TopBar = () => { className="text-muted-foreground" />
- + {openFileTitle()}
diff --git a/web/containers/Loader/index.tsx b/web/containers/Loader/index.tsx index dcf1bec65..cf6604fc8 100644 --- a/web/containers/Loader/index.tsx +++ b/web/containers/Loader/index.tsx @@ -7,12 +7,12 @@ export default function Loader({ description }: Props) {
-

{description}

diff --git a/web/containers/ModalTroubleShoot/AppLogs.tsx b/web/containers/ModalTroubleShoot/AppLogs.tsx index d4f6bddb8..98f076599 100644 --- a/web/containers/ModalTroubleShoot/AppLogs.tsx +++ b/web/containers/ModalTroubleShoot/AppLogs.tsx @@ -28,7 +28,7 @@ const AppLogs = () => {
- ) - })} -
- ) -} diff --git a/web/screens/Settings/Appearance/ToggleTheme.tsx b/web/screens/Settings/Appearance/ToggleTheme.tsx index a183348d9..369a216fa 100644 --- a/web/screens/Settings/Appearance/ToggleTheme.tsx +++ b/web/screens/Settings/Appearance/ToggleTheme.tsx @@ -28,7 +28,7 @@ export default function ToggleTheme() { {isActive ? ( ) : null} diff --git a/web/screens/Settings/Appearance/index.tsx b/web/screens/Settings/Appearance/index.tsx index 51899ba40..9e2c551d6 100644 --- a/web/screens/Settings/Appearance/index.tsx +++ b/web/screens/Settings/Appearance/index.tsx @@ -1,4 +1,3 @@ -import ToggleAccent from '@/screens/Settings/Appearance/TogglePrimary' import ToggleTheme from '@/screens/Settings/Appearance/ToggleTheme' export default function AppearanceOptions() { @@ -22,7 +21,6 @@ export default function AppearanceOptions() { Choose the primary accent color used throughout the app.

-
) diff --git a/web/screens/Settings/ImportModelOptionModal/ImportModelOptionSelection.tsx b/web/screens/Settings/ImportModelOptionModal/ImportModelOptionSelection.tsx index 5276ee195..e4f5c4cf8 100644 --- a/web/screens/Settings/ImportModelOptionModal/ImportModelOptionSelection.tsx +++ b/web/screens/Settings/ImportModelOptionModal/ImportModelOptionSelection.tsx @@ -16,7 +16,7 @@ const ImportModelOptionSelection: React.FC = ({ onClick={() => setSelectedOptionType(option.type)} >
- {checked &&
} + {checked &&
}
diff --git a/web/screens/Settings/ImportSuccessIcon/index.tsx b/web/screens/Settings/ImportSuccessIcon/index.tsx index ae6526d78..6bc8d0b9d 100644 --- a/web/screens/Settings/ImportSuccessIcon/index.tsx +++ b/web/screens/Settings/ImportSuccessIcon/index.tsx @@ -29,7 +29,7 @@ const ImportSuccessIcon: React.FC = ({ onEditModelClick }) => { } const SuccessIcon: React.FC = React.memo(() => ( -
+
)) diff --git a/web/screens/Settings/Models/Row.tsx b/web/screens/Settings/Models/Row.tsx index 5ade3bad6..9ceeab92a 100644 --- a/web/screens/Settings/Models/Row.tsx +++ b/web/screens/Settings/Models/Row.tsx @@ -152,7 +152,7 @@ export default function RowModel(props: RowModelProps) { ) : ( )} - + {isActiveModel ? stateModel.state : 'Start'}  Model @@ -189,9 +189,7 @@ export default function RowModel(props: RowModelProps) { }} > - - Delete Model - + Delete Model
)} diff --git a/web/screens/Settings/SelectingModelModal/index.tsx b/web/screens/Settings/SelectingModelModal/index.tsx index cfdf21392..086a668c6 100644 --- a/web/screens/Settings/SelectingModelModal/index.tsx +++ b/web/screens/Settings/SelectingModelModal/index.tsx @@ -97,7 +97,7 @@ const SelectingModelModal: React.FC = () => { }) const borderColor = isDragActive ? 'border-primary' : 'border-[#F4F4F5]' - const textColor = isDragActive ? 'text-primary' : 'text-[#71717A]' + const textColor = isDragActive ? 'text-blue-600' : 'text-[#71717A]' const dragAndDropBgColor = isDragActive ? 'bg-[#EFF6FF]' : 'bg-white' return ( @@ -128,7 +128,7 @@ const SelectingModelModal: React.FC = () => {
- + Click to upload diff --git a/web/screens/Settings/SettingMenu/index.tsx b/web/screens/Settings/SettingMenu/index.tsx index fd0ea1560..9e40d1fda 100644 --- a/web/screens/Settings/SettingMenu/index.tsx +++ b/web/screens/Settings/SettingMenu/index.tsx @@ -15,7 +15,6 @@ const SettingMenu: React.FC = ({ activeMenu, onMenuClick }) => { useEffect(() => { setMenus([ 'My Models', - 'My Settings', 'Advanced Settings', ...(window.electronAPI ? ['Extensions'] : []), ]) @@ -39,7 +38,7 @@ const SettingMenu: React.FC = ({ activeMenu, onMenuClick }) => { {isActive && ( )} diff --git a/web/screens/Settings/index.tsx b/web/screens/Settings/index.tsx index 1a5e4011e..ed8af3c46 100644 --- a/web/screens/Settings/index.tsx +++ b/web/screens/Settings/index.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react' import Advanced from '@/screens/Settings/Advanced' -import AppearanceOptions from '@/screens/Settings/Appearance' + import ExtensionCatalog from '@/screens/Settings/CoreExtensions' import Models from '@/screens/Settings/Models' @@ -14,9 +14,6 @@ const handleShowOptions = (menu: string) => { case 'Extensions': return - case 'My Settings': - return - case 'Advanced Settings': return diff --git a/web/styles/components/message.scss b/web/styles/components/message.scss index a9bec5d48..f95061599 100644 --- a/web/styles/components/message.scss +++ b/web/styles/components/message.scss @@ -1,5 +1,5 @@ .message { - @apply text-black dark:text-gray-300; + @apply text-black; white-space: pre-line; ul, @@ -10,7 +10,7 @@ } a { - @apply text-blue-600 dark:text-blue-300; + @apply text-blue-600; &:hover { @apply underline; } diff --git a/web/types/appearance.d.ts b/web/types/appearance.d.ts deleted file mode 100644 index 14e0c14c2..000000000 --- a/web/types/appearance.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -type PrimaryColor = 'primary-blue' | 'primary-green' | 'primary-purple' - -type UserConfig = { - gettingStartedShow?: boolean - primaryColor?: PrimaryColor -} From d4df43ed68a0062c3709574c51f57e719fcc38b4 Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Tue, 27 Feb 2024 20:40:06 +0700 Subject: [PATCH 03/10] fix: disabled user promp using dangerouslySetInnerHTML (#2176) --- web/screens/Chat/SimpleTextMessage/index.tsx | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/web/screens/Chat/SimpleTextMessage/index.tsx b/web/screens/Chat/SimpleTextMessage/index.tsx index c3bdc8661..e5e2364b4 100644 --- a/web/screens/Chat/SimpleTextMessage/index.tsx +++ b/web/screens/Chat/SimpleTextMessage/index.tsx @@ -18,7 +18,7 @@ import hljs from 'highlight.js' import { useAtomValue } from 'jotai' import { FolderOpenIcon } from 'lucide-react' -import { Marked, Renderer, marked as markedDefault } from 'marked' +import { Marked, Renderer } from 'marked' import { markedHighlight } from 'marked-highlight' @@ -43,19 +43,6 @@ import { getCurrentChatMessagesAtom, } from '@/helpers/atoms/ChatMessage.atom' -function isMarkdownValue(value: string): boolean { - const tokenTypes: string[] = [] - markedDefault(value, { - walkTokens: (token) => { - tokenTypes.push(token.type) - }, - }) - const isMarkdown = ['code', 'codespan'].some((tokenType) => { - return tokenTypes.includes(tokenType) - }) - return isMarkdown -} - const SimpleTextMessage: React.FC = (props) => { let text = '' const isUser = props.role === ChatCompletionRole.User @@ -282,7 +269,7 @@ const SimpleTextMessage: React.FC = (props) => {
)} - {isUser && !isMarkdownValue(text) ? ( + {isUser ? ( <> {editMessage === props.id ? (
From 883d6314521945b9a7741096e55718760f13a221 Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Tue, 27 Feb 2024 21:25:31 +0700 Subject: [PATCH 04/10] fix space between progress bar and title list of gpu (#2177) --- web/containers/Layout/BottomBar/SystemMonitor/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/containers/Layout/BottomBar/SystemMonitor/index.tsx b/web/containers/Layout/BottomBar/SystemMonitor/index.tsx index 90510aae7..989ae7777 100644 --- a/web/containers/Layout/BottomBar/SystemMonitor/index.tsx +++ b/web/containers/Layout/BottomBar/SystemMonitor/index.tsx @@ -140,7 +140,7 @@ const SystemMonitor = () => { {gpus.length > 0 && (
{gpus.map((gpu, index) => ( -
+
{gpu.name} From 95946ab9f2ebcab437d3f5e2613feb965b92e055 Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Tue, 27 Feb 2024 21:25:42 +0700 Subject: [PATCH 05/10] fix: change button import model on hub page (#2178) --- web/screens/ExploreModels/index.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/web/screens/ExploreModels/index.tsx b/web/screens/ExploreModels/index.tsx index 96bc6ba2c..e7fd3a9dc 100644 --- a/web/screens/ExploreModels/index.tsx +++ b/web/screens/ExploreModels/index.tsx @@ -13,7 +13,7 @@ import { } from '@janhq/uikit' import { useAtomValue, useSetAtom } from 'jotai' -import { Plus, SearchIcon } from 'lucide-react' +import { UploadIcon, SearchIcon } from 'lucide-react' import { FeatureToggleContext } from '@/context/FeatureToggle' @@ -96,12 +96,12 @@ const ExploreModelsScreen = () => { />
{experimentalFeature && ( From 65e5921cd155564b15520de0b6cc835816ab7aad Mon Sep 17 00:00:00 2001 From: hieu-jan <150573299+hieu-jan@users.noreply.github.com> Date: Tue, 27 Feb 2024 23:40:32 +0900 Subject: [PATCH 06/10] docs: update wall of love --- docs/docs/wall-of-love.md | 92 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/docs/docs/wall-of-love.md b/docs/docs/wall-of-love.md index f196c90e9..102102739 100644 --- a/docs/docs/wall-of-love.md +++ b/docs/docs/wall-of-love.md @@ -1,3 +1,93 @@ --- title: Wall of Love ❤️ ---- \ No newline at end of file +--- + +## Twitter + +Check out our amazing users and what they are saying about Jan! Please share your love for Jan on Twitter and tag us [@janframework](https://twitter.com/janframework)! We would love to hear from you! + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +## YouTube + +Watch these amazing videos to see how Jan is being used and loved by the community! + +### Run Any Chatbot FREE Locally on Your Computer + +
+ +
+ +

+ +### Jan AI: Run Open Source LLM 100% Local with OpenAI endpoints + +
+ +
+ +

+ +### Setup Tutorial on Jan.ai. JAN AI: Run open source LLM on local Windows PC. 100% offline LLM and AI. + +
+ +
+ +

+ +### Jan.ai: Like Offline ChatGPT on Your Computer 💡 + +
+ +
+ +

+ +### Jan: Bring AI to your Desktop With 100% Offline AI + +
+ +
+ +

+ +### AI on Your Local PC: Install JanAI (ChatGPT alternative) for Enhanced Privacy + +
+ +
+ +

+ +### Install Jan to Run LLM Offline and Local First + +
+ +
From 0bb29fc93ffaf9a532c776eab46af353f4641837 Mon Sep 17 00:00:00 2001 From: hieu-jan <150573299+hieu-jan@users.noreply.github.com> Date: Tue, 27 Feb 2024 23:47:31 +0900 Subject: [PATCH 07/10] docs: change text --- docs/docs/wall-of-love.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/docs/wall-of-love.md b/docs/docs/wall-of-love.md index 102102739..76548ef7a 100644 --- a/docs/docs/wall-of-love.md +++ b/docs/docs/wall-of-love.md @@ -4,7 +4,7 @@ title: Wall of Love ❤️ ## Twitter -Check out our amazing users and what they are saying about Jan! Please share your love for Jan on Twitter and tag us [@janframework](https://twitter.com/janframework)! We would love to hear from you! +Check out our amazing users and what they are saying about Jan!
@@ -34,6 +34,8 @@ Check out our amazing users and what they are saying about Jan! Please share you
+Please share your love for Jan on Twitter and tag us [@janframework](https://twitter.com/janframework)! We would love to hear from you! + ## YouTube Watch these amazing videos to see how Jan is being used and loved by the community! From d7070d8c4a8e4088ee49a94dbb36e0b05b361ed7 Mon Sep 17 00:00:00 2001 From: NamH Date: Tue, 27 Feb 2024 23:59:37 +0700 Subject: [PATCH 08/10] fix: some bugs for import model (#2181) * fix: some bugs for import model Signed-off-by: James Signed-off-by: James Co-authored-by: James --- core/src/api/index.ts | 2 +- core/src/core.ts | 2 +- core/src/types/model/modelImport.ts | 1 + extensions/model-extension/src/index.ts | 28 +++++---- .../Providers/ModelImportListener.tsx | 25 +++++++- web/helpers/atoms/Model.atom.ts | 18 ++++++ web/hooks/useDropModelBinaries.ts | 55 ++++++++++++++++++ .../Settings/EditModelInfoModal/index.tsx | 32 +++++++--- .../Settings/ImportInProgressIcon/index.tsx | 3 +- .../ImportingModelItem.tsx | 31 +++++++--- .../Settings/ImportingModelModal/index.tsx | 14 ++++- web/screens/Settings/Models/index.tsx | 40 ++----------- .../Settings/SelectingModelModal/index.tsx | 58 ++++++++----------- web/utils/file.ts | 19 +++--- 14 files changed, 212 insertions(+), 116 deletions(-) create mode 100644 web/hooks/useDropModelBinaries.ts diff --git a/core/src/api/index.ts b/core/src/api/index.ts index c7dd9146e..7fb8eeb38 100644 --- a/core/src/api/index.ts +++ b/core/src/api/index.ts @@ -49,7 +49,7 @@ export enum DownloadEvent { export enum LocalImportModelEvent { onLocalImportModelUpdate = 'onLocalImportModelUpdate', - onLocalImportModelError = 'onLocalImportModelError', + onLocalImportModelFailed = 'onLocalImportModelFailed', onLocalImportModelSuccess = 'onLocalImportModelSuccess', onLocalImportModelFinished = 'onLocalImportModelFinished', } diff --git a/core/src/core.ts b/core/src/core.ts index 8831c6001..6e2442c2b 100644 --- a/core/src/core.ts +++ b/core/src/core.ts @@ -65,7 +65,7 @@ const joinPath: (paths: string[]) => Promise = (paths) => global.core.ap * @param path - The path to retrieve. * @returns {Promise} A promise that resolves with the basename. */ -const baseName: (paths: string[]) => Promise = (path) => global.core.api?.baseName(path) +const baseName: (paths: string) => Promise = (path) => global.core.api?.baseName(path) /** * Opens an external URL in the default web browser. diff --git a/core/src/types/model/modelImport.ts b/core/src/types/model/modelImport.ts index 8977c42a0..7c72a691b 100644 --- a/core/src/types/model/modelImport.ts +++ b/core/src/types/model/modelImport.ts @@ -19,4 +19,5 @@ export type ImportingModel = { status: ImportingModelStatus format: string percentage?: number + error?: string } diff --git a/extensions/model-extension/src/index.ts b/extensions/model-extension/src/index.ts index dd5bcdf26..fb1f26885 100644 --- a/extensions/model-extension/src/index.ts +++ b/extensions/model-extension/src/index.ts @@ -16,6 +16,7 @@ import { OptionType, ImportingModel, LocalImportModelEvent, + baseName, } from '@janhq/core' import { extractFileName } from './helpers/path' @@ -488,7 +489,7 @@ export default class JanModelExtension extends ModelExtension { return } - const binaryFileName = extractFileName(modelBinaryPath, '') + const binaryFileName = await baseName(modelBinaryPath) const model: Model = { ...defaultModel, @@ -555,7 +556,7 @@ export default class JanModelExtension extends ModelExtension { model: ImportingModel, optionType: OptionType ): Promise { - const binaryName = extractFileName(model.path, '').replace(/\s/g, '') + const binaryName = (await baseName(model.path)).replace(/\s/g, '') let modelFolderName = binaryName if (binaryName.endsWith(JanModelExtension._supportedModelFormat)) { @@ -568,7 +569,7 @@ export default class JanModelExtension extends ModelExtension { const modelFolderPath = await this.getModelFolderName(modelFolderName) await fs.mkdirSync(modelFolderPath) - const uniqueFolderName = modelFolderPath.split('/').pop() + const uniqueFolderName = await baseName(modelFolderPath) const modelBinaryFile = binaryName.endsWith( JanModelExtension._supportedModelFormat ) @@ -637,14 +638,21 @@ export default class JanModelExtension extends ModelExtension { for (const model of models) { events.emit(LocalImportModelEvent.onLocalImportModelUpdate, model) - const importedModel = await this.importModel(model, optionType) - - events.emit(LocalImportModelEvent.onLocalImportModelSuccess, { - ...model, - modelId: importedModel.id, - }) - importedModels.push(importedModel) + try { + const importedModel = await this.importModel(model, optionType) + events.emit(LocalImportModelEvent.onLocalImportModelSuccess, { + ...model, + modelId: importedModel.id, + }) + importedModels.push(importedModel) + } catch (err) { + events.emit(LocalImportModelEvent.onLocalImportModelFailed, { + ...model, + error: err, + }) + } } + events.emit( LocalImportModelEvent.onLocalImportModelFinished, importedModels diff --git a/web/containers/Providers/ModelImportListener.tsx b/web/containers/Providers/ModelImportListener.tsx index 60347ba40..f1ca2a768 100644 --- a/web/containers/Providers/ModelImportListener.tsx +++ b/web/containers/Providers/ModelImportListener.tsx @@ -12,6 +12,7 @@ import { useSetAtom } from 'jotai' import { snackbar } from '../Toast' import { + setImportingModelErrorAtom, setImportingModelSuccessAtom, updateImportingModelProgressAtom, } from '@/helpers/atoms/Model.atom' @@ -21,6 +22,7 @@ const ModelImportListener = ({ children }: PropsWithChildren) => { updateImportingModelProgressAtom ) const setImportingModelSuccess = useSetAtom(setImportingModelSuccessAtom) + const setImportingModelFailed = useSetAtom(setImportingModelErrorAtom) const onImportModelUpdate = useCallback( async (state: ImportingModel) => { @@ -30,6 +32,14 @@ const ModelImportListener = ({ children }: PropsWithChildren) => { [updateImportingModelProgress] ) + const onImportModelFailed = useCallback( + async (state: ImportingModel) => { + if (!state.importId) return + setImportingModelFailed(state.importId, state.error ?? '') + }, + [setImportingModelFailed] + ) + const onImportModelSuccess = useCallback( (state: ImportingModel) => { if (!state.modelId) return @@ -62,6 +72,10 @@ const ModelImportListener = ({ children }: PropsWithChildren) => { LocalImportModelEvent.onLocalImportModelFinished, onImportModelFinished ) + events.on( + LocalImportModelEvent.onLocalImportModelFailed, + onImportModelFailed + ) return () => { console.debug('ModelImportListener: unregistering event listeners...') @@ -77,8 +91,17 @@ const ModelImportListener = ({ children }: PropsWithChildren) => { LocalImportModelEvent.onLocalImportModelFinished, onImportModelFinished ) + events.off( + LocalImportModelEvent.onLocalImportModelFailed, + onImportModelFailed + ) } - }, [onImportModelUpdate, onImportModelSuccess, onImportModelFinished]) + }, [ + onImportModelUpdate, + onImportModelSuccess, + onImportModelFinished, + onImportModelFailed, + ]) return {children} } diff --git a/web/helpers/atoms/Model.atom.ts b/web/helpers/atoms/Model.atom.ts index 7a6aa6440..da6dc5918 100644 --- a/web/helpers/atoms/Model.atom.ts +++ b/web/helpers/atoms/Model.atom.ts @@ -67,6 +67,24 @@ export const updateImportingModelProgressAtom = atom( } ) +export const setImportingModelErrorAtom = atom( + null, + (get, set, importId: string, error: string) => { + const model = get(importingModelsAtom).find((x) => x.importId === importId) + if (!model) return + const newModel: ImportingModel = { + ...model, + status: 'FAILED', + } + + console.error(`Importing model ${model} failed`, error) + const newList = get(importingModelsAtom).map((m) => + m.importId === importId ? newModel : m + ) + set(importingModelsAtom, newList) + } +) + export const setImportingModelSuccessAtom = atom( null, (get, set, importId: string, modelId: string) => { diff --git a/web/hooks/useDropModelBinaries.ts b/web/hooks/useDropModelBinaries.ts new file mode 100644 index 000000000..c08e1dc73 --- /dev/null +++ b/web/hooks/useDropModelBinaries.ts @@ -0,0 +1,55 @@ +import { useCallback } from 'react' + +import { ImportingModel } from '@janhq/core' +import { useSetAtom } from 'jotai' + +import { v4 as uuidv4 } from 'uuid' + +import { snackbar } from '@/containers/Toast' + +import { getFileInfoFromFile } from '@/utils/file' + +import { setImportModelStageAtom } from './useImportModel' + +import { importingModelsAtom } from '@/helpers/atoms/Model.atom' + +export default function useDropModelBinaries() { + const setImportingModels = useSetAtom(importingModelsAtom) + const setImportModelStage = useSetAtom(setImportModelStageAtom) + + const onDropModels = useCallback( + async (acceptedFiles: File[]) => { + const files = await getFileInfoFromFile(acceptedFiles) + + const unsupportedFiles = files.filter( + (file) => !file.path.endsWith('.gguf') + ) + const supportedFiles = files.filter((file) => file.path.endsWith('.gguf')) + + const importingModels: ImportingModel[] = supportedFiles.map((file) => ({ + importId: uuidv4(), + modelId: undefined, + name: file.name.replace('.gguf', ''), + description: '', + path: file.path, + tags: [], + size: file.size, + status: 'PREPARING', + format: 'gguf', + })) + if (unsupportedFiles.length > 0) { + snackbar({ + description: `File has to be a .gguf file`, + type: 'error', + }) + } + if (importingModels.length === 0) return + + setImportingModels(importingModels) + setImportModelStage('MODEL_SELECTED') + }, + [setImportModelStage, setImportingModels] + ) + + return { onDropModels } +} diff --git a/web/screens/Settings/EditModelInfoModal/index.tsx b/web/screens/Settings/EditModelInfoModal/index.tsx index bb87b7ed9..bc9d6521d 100644 --- a/web/screens/Settings/EditModelInfoModal/index.tsx +++ b/web/screens/Settings/EditModelInfoModal/index.tsx @@ -1,6 +1,12 @@ -import { useCallback, useEffect, useMemo, useState } from 'react' +import { useCallback, useEffect, useState } from 'react' -import { Model, ModelEvent, events, openFileExplorer } from '@janhq/core' +import { + Model, + ModelEvent, + events, + joinPath, + openFileExplorer, +} from '@janhq/core' import { Modal, ModalContent, @@ -47,6 +53,7 @@ const EditModelInfoModal: React.FC = () => { const janDataFolder = useAtomValue(janDataFolderPathAtom) const updateImportingModel = useSetAtom(updateImportingModelAtom) const { updateModelInfo } = useImportModel() + const [modelPath, setModelPath] = useState('') const editingModel = importingModels.find( (model) => model.importId === editingModelId @@ -88,13 +95,19 @@ const EditModelInfoModal: React.FC = () => { setEditingModelId(undefined) } - const modelFolderPath = useMemo(() => { - return `${janDataFolder}/models/${editingModel?.modelId}` + useEffect(() => { + const getModelPath = async () => { + const modelId = editingModel?.modelId + if (!modelId) return '' + const path = await joinPath([janDataFolder, 'models', modelId]) + setModelPath(path) + } + getModelPath() }, [janDataFolder, editingModel]) const onShowInFinderClick = useCallback(() => { - openFileExplorer(modelFolderPath) - }, [modelFolderPath]) + openFileExplorer(modelPath) + }, [modelPath]) if (!editingModel) { setImportModelStage('IMPORTING_MODEL') @@ -104,7 +117,10 @@ const EditModelInfoModal: React.FC = () => { } return ( - + Edit Model Information @@ -130,7 +146,7 @@ const EditModelInfoModal: React.FC = () => {
- {modelFolderPath} + {modelPath}