feat: Add Chrome AI support

This commit is contained in:
n4ze3m
2024-06-30 20:45:06 +05:30
parent 52f9a2953a
commit d41ec2a89c
36 changed files with 463 additions and 47 deletions

View File

@@ -6,11 +6,17 @@ import "property-information"
import React from "react"
import { CodeBlock } from "./CodeBlock"
export default function Markdown({ message }: { message: string }) {
export default function Markdown({
message,
className = "prose break-words dark:prose-invert prose-p:leading-relaxed prose-pre:p-0 dark:prose-dark"
}: {
message: string
className?: string
}) {
return (
<React.Fragment>
<ReactMarkdown
className="prose break-words dark:prose-invert prose-p:leading-relaxed prose-pre:p-0 dark:prose-dark"
className={className}
remarkPlugins={[remarkGfm, remarkMath]}
components={{
code({ node, inline, className, children, ...props }) {

View File

@@ -3,9 +3,9 @@ import { Dropdown, Tooltip } from "antd"
import { LucideBrain } from "lucide-react"
import React from "react"
import { useTranslation } from "react-i18next"
import { OllamaIcon } from "../Icons/Ollama"
import { fetchChatModels } from "@/services/ollama"
import { useMessage } from "@/hooks/useMessage"
import { ProviderIcons } from "./ProviderIcon"
export const ModelSelect: React.FC = () => {
const { t } = useTranslation("common")
@@ -29,7 +29,10 @@ export const ModelSelect: React.FC = () => {
label: (
<div className="w-52 gap-2 text-lg truncate inline-flex line-clamp-3 items-center dark:border-gray-700">
<div>
<OllamaIcon className="h-6 w-6 text-gray-400" />
<ProviderIcons
provider={d?.provider}
className="h-6 w-6 text-gray-400"
/>
</div>
{d.name}
</div>
@@ -53,7 +56,7 @@ export const ModelSelect: React.FC = () => {
trigger={["click"]}>
<Tooltip title={t("selectAModel")}>
<button type="button" className="dark:text-gray-300">
<LucideBrain className="h-5 w-5"/>
<LucideBrain className="h-5 w-5" />
</button>
</Tooltip>
</Dropdown>

View File

@@ -64,7 +64,11 @@ export const PlaygroundMessage = (props: Props) => {
</div>
<div className="flex w-[calc(100%-50px)] flex-col gap-3 lg:w-[calc(100%-115px)]">
<span className="text-xs font-bold text-gray-800 dark:text-white">
{props.isBot ? props.name : "You"}
{props.isBot
? props.name === "chrome::gemini-nano::page-assist"
? "Gemini Nano"
: props.name
: "You"}
</span>
{props.isBot &&

View File

@@ -0,0 +1,17 @@
import { ChromeIcon } from "lucide-react"
import { OllamaIcon } from "../Icons/Ollama"
export const ProviderIcons = ({
provider,
className
}: {
provider: string
className?: string
}) => {
switch (provider) {
case "chrome":
return <ChromeIcon className={className} />
default:
return <OllamaIcon className={className} />
}
}

View File

@@ -21,6 +21,7 @@ import { useMessageOption } from "~/hooks/useMessageOption"
import { Select, Tooltip } from "antd"
import { getAllPrompts } from "@/db"
import { ShareBtn } from "~/components/Common/ShareBtn"
import { ProviderIcons } from "../Common/ProviderIcon"
type Props = {
setSidebarOpen: (open: boolean) => void
setOpenModelSettings: (open: boolean) => void
@@ -132,7 +133,10 @@ export const Header: React.FC<Props> = ({
<span
key={model.model}
className="flex flex-row gap-3 items-center truncate">
<OllamaIcon className="w-5 h-5" />
<ProviderIcons
provider={model?.provider}
className="w-5 h-5"
/>
<span className="truncate">{model.name}</span>
</span>
),

View File

@@ -6,11 +6,13 @@ import {
BlocksIcon,
InfoIcon,
CombineIcon,
ChromeIcon
} from "lucide-react"
import { useTranslation } from "react-i18next"
import { Link, useLocation } from "react-router-dom"
import { OllamaIcon } from "../Icons/Ollama"
import { Tag } from "antd"
import { BetaTag } from "../Common/Beta"
function classNames(...classes: string[]) {
return classes.filter(Boolean).join(" ")
@@ -20,10 +22,12 @@ const LinkComponent = (item: {
href: string
name: string | JSX.Element
icon: any
current: string
current: string,
beta?: boolean
}) => {
return (
<li>
<li className="inline-flex items-center">
<Link
to={item.href}
className={classNames(
@@ -43,6 +47,9 @@ const LinkComponent = (item: {
/>
{item.name}
</Link>
{
item.beta && <BetaTag />
}
</li>
)
}
@@ -65,7 +72,7 @@ export const SettingsLayout = ({ children }: { children: React.ReactNode }) => {
icon={OrbitIcon}
current={location.pathname}
/>
<LinkComponent
<LinkComponent
href="/settings/rag"
name={t("rag.title")}
icon={CombineIcon}
@@ -77,6 +84,15 @@ export const SettingsLayout = ({ children }: { children: React.ReactNode }) => {
icon={OllamaIcon}
current={location.pathname}
/>
{import.meta.env.BROWSER === "chrome" && (
<LinkComponent
href="/settings/chrome"
name={t("chromeAiSettings.title")}
icon={ChromeIcon}
current={location.pathname}
beta
/>
)}
<LinkComponent
href="/settings/model"
name={t("manageModels.title")}

View File

@@ -0,0 +1,73 @@
import { useStorage } from "@plasmohq/storage/hook"
import { useQuery } from "@tanstack/react-query"
import { Alert, Skeleton, Switch } from "antd"
import { useTranslation } from "react-i18next"
import { getChromeAISupported } from "@/utils/chrome"
import Markdown from "@/components/Common/Markdown"
export const ChromeApp = () => {
const { t } = useTranslation("chrome")
const [chromeAIStatus, setChromeAIStatus] = useStorage(
"chromeAIStatus",
false
)
const [selectedModel, setSelectedModel] = useStorage("selectedModel")
const { status, data } = useQuery({
queryKey: ["fetchChromeAIInfo"],
queryFn: async () => {
const data = await getChromeAISupported()
return data
}
})
return (
<div className="flex flex-col space-y-3">
{status === "pending" && <Skeleton paragraph={{ rows: 4 }} active />}
{status === "success" && (
<div className="flex flex-col space-y-6">
<div>
<div>
<h2 className="text-base font-semibold leading-7 text-gray-900 dark:text-white">
{t("heading")}
</h2>
<div className="border border-b border-gray-200 dark:border-gray-600 mt-3 mb-6"></div>
</div>
<div className="flex mb-3 flex-row justify-between">
<div className="inline-flex items-center gap-2">
<span className="text-gray-700 text-sm dark:text-neutral-50">
{t("status.label")}
</span>
</div>
<Switch
disabled={data !== "success"}
checked={chromeAIStatus}
onChange={(value) => {
setChromeAIStatus(value)
if (
!value &&
selectedModel === "chrome::gemini-nano::page-assist"
) {
setSelectedModel(null)
}
}}
/>
</div>
{data !== "success" && (
<div className="space-y-3">
<Alert message={t(`error.${data}`)} type="error" showIcon />
<div className=" w-full">
<Markdown
className="text-sm text-gray-700 dark:text-neutral-50 leading-7 text-justify"
message={t("errorDescription")}
/>
</div>
</div>
)}
</div>
</div>
)}
</div>
)
}

View File

@@ -13,7 +13,6 @@ import {
exportPageAssistData,
importPageAssistData
} from "@/libs/export-import"
import { BetaTag } from "@/components/Common/Beta"
import { useStorage } from "@plasmohq/storage/hook"
export const GeneralSettings = () => {
@@ -87,7 +86,6 @@ export const GeneralSettings = () => {
</div>
<div className="flex flex-row justify-between">
<div className="inline-flex items-center gap-2">
<BetaTag />
<span className="text-gray-700 dark:text-neutral-50">
{t("generalSettings.settings.copilotResumeLastChat.label")}
</span>
@@ -99,7 +97,6 @@ export const GeneralSettings = () => {
</div>
<div className="flex flex-row justify-between">
<div className="inline-flex items-center gap-2">
<BetaTag />
<span className="text-gray-700 dark:text-neutral-50">
{t("generalSettings.settings.hideCurrentChatModelSettings.label")}
</span>