chore: Update version to 1.1.9 and add Model Settings to Ollama settings page
This commit is contained in:
138
src/components/Common/CurrentChatModelSettings.tsx
Normal file
138
src/components/Common/CurrentChatModelSettings.tsx
Normal file
@@ -0,0 +1,138 @@
|
||||
import { getAllModelSettings } from "@/services/model-settings"
|
||||
import { useStoreChatModelSettings } from "@/store/model"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { Collapse, Form, Input, InputNumber, Modal, Skeleton } from "antd"
|
||||
import React from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
type Props = {
|
||||
open: boolean
|
||||
setOpen: (open: boolean) => void
|
||||
}
|
||||
|
||||
export const CurrentChatModelSettings = ({ open, setOpen }: Props) => {
|
||||
const { t } = useTranslation("common")
|
||||
const [form] = Form.useForm()
|
||||
const cUserSettings = useStoreChatModelSettings()
|
||||
const { isPending: isLoading } = useQuery({
|
||||
queryKey: ["fetchModelConfig2", open],
|
||||
queryFn: async () => {
|
||||
const data = await getAllModelSettings()
|
||||
form.setFieldsValue({
|
||||
temperature: cUserSettings.temperature ?? data.temperature,
|
||||
topK: cUserSettings.topK ?? data.topK,
|
||||
topP: cUserSettings.topP ?? data.topP,
|
||||
keepAlive: cUserSettings.keepAlive ?? data.keepAlive,
|
||||
numCtx: cUserSettings.numCtx ?? data.numCtx,
|
||||
seed: cUserSettings.seed
|
||||
})
|
||||
return data
|
||||
},
|
||||
enabled: open,
|
||||
refetchOnMount: true
|
||||
})
|
||||
return (
|
||||
<Modal
|
||||
title={t("modelSettings.currentChatModelSettings")}
|
||||
open={open}
|
||||
onOk={() => setOpen(false)}
|
||||
onCancel={() => setOpen(false)}
|
||||
footer={null}>
|
||||
{!isLoading ? (
|
||||
<Form
|
||||
onFinish={(values: {
|
||||
keepAlive: string
|
||||
temperature: number
|
||||
topK: number
|
||||
topP: number
|
||||
}) => {
|
||||
Object.entries(values).forEach(([key, value]) => {
|
||||
cUserSettings.setX(key, value)
|
||||
setOpen(false)
|
||||
})
|
||||
}}
|
||||
form={form}
|
||||
layout="vertical">
|
||||
<Form.Item
|
||||
name="keepAlive"
|
||||
help={t("modelSettings.form.keepAlive.help")}
|
||||
label={t("modelSettings.form.keepAlive.label")}>
|
||||
<Input
|
||||
size="large"
|
||||
placeholder={t("modelSettings.form.keepAlive.placeholder")}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="temperature"
|
||||
label={t("modelSettings.form.temperature.label")}>
|
||||
<InputNumber
|
||||
size="large"
|
||||
style={{ width: "100%" }}
|
||||
placeholder={t("modelSettings.form.temperature.placeholder")}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="seed"
|
||||
help={t("modelSettings.form.seed.help")}
|
||||
label={t("modelSettings.form.seed.label")}>
|
||||
<InputNumber
|
||||
size="large"
|
||||
style={{ width: "100%" }}
|
||||
placeholder={t("modelSettings.form.seed.placeholder")}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="numCtx" label={t("modelSettings.form.numCtx.label")}>
|
||||
<InputNumber
|
||||
style={{ width: "100%" }}
|
||||
placeholder={t("modelSettings.form.numCtx.placeholder")}
|
||||
size="large"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Collapse
|
||||
ghost
|
||||
className="border-none bg-transparent"
|
||||
items={[
|
||||
{
|
||||
key: "1",
|
||||
label: t("modelSettings.advanced"),
|
||||
children: (
|
||||
<React.Fragment>
|
||||
<Form.Item
|
||||
name="topK"
|
||||
label={t("modelSettings.form.topK.label")}>
|
||||
<InputNumber
|
||||
style={{ width: "100%" }}
|
||||
placeholder={t("modelSettings.form.topK.placeholder")}
|
||||
size="large"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="topP"
|
||||
label={t("modelSettings.form.topP.label")}>
|
||||
<InputNumber
|
||||
style={{ width: "100%" }}
|
||||
size="large"
|
||||
placeholder={t("modelSettings.form.topP.placeholder")}
|
||||
/>
|
||||
</Form.Item>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="inline-flex justify-center w-full text-center mt-4 items-center rounded-md border border-transparent bg-black px-2 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50 ">
|
||||
{t("save")}
|
||||
</button>
|
||||
</Form>
|
||||
) : (
|
||||
<Skeleton active />
|
||||
)}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
29
src/components/Icons/ChatSettings.tsx
Normal file
29
src/components/Icons/ChatSettings.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import React from "react"
|
||||
|
||||
export const ChatSettings = React.forwardRef<
|
||||
SVGSVGElement,
|
||||
React.SVGProps<SVGSVGElement>
|
||||
>((props, ref) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="lucide lucide-message-circle-x"
|
||||
viewBox="0 0 24 24"
|
||||
ref={ref}
|
||||
strokeWidth={2}
|
||||
{...props}>
|
||||
<path d="M7.9 20A9 9 0 104 16.1L2 22z"
|
||||
></path>
|
||||
<path
|
||||
strokeWidth={1}
|
||||
|
||||
d="M12 2h-.44a2 2 0 00-2 2v.18a2 2 0 01-1 1.73l-.43.25a2 2 0 01-2 0l-.15-.08a2 2 0 00-2.73.73l-.22.38a2 2 0 00.73 2.73l.15.1a2 2 0 011 1.72v.51a2 2 0 01-1 1.74l-.15.09a2 2 0 00-.73 2.73l.22.38a2 2 0 002.73.73l.15-.08a2 2 0 012 0l.43.25a2 2 0 011 1.73V20a2 2 0 002 2H12a2 2 0 002-2v-.18a2 2 0 011-1.73l.43-.25a2 2 0 012 0l.15.08a2 2 0 002.73-.73l.22-.39a2 2 0 00-.73-2.73l-.15-.08a2 2 0 01-1-1.74v-.5a2 2 0 011-1.74l.15-.09a2 2 0 00.73-2.73l-.22-.38a2 2 0 00-2.73-.73l-.15.08a2 2 0 01-2 0L15 5.91a2 2 0 01-1-1.73V4a2 2 0 00-2-2z"
|
||||
transform="matrix(.5 0 0 .5 6 6)"></path>
|
||||
<circle cx="12" cy="12" r="0.5"></circle>
|
||||
</svg>
|
||||
)
|
||||
})
|
||||
@@ -7,6 +7,7 @@ import { useQuery } from "@tanstack/react-query"
|
||||
import { fetchChatModels, getAllModels } from "~/services/ollama"
|
||||
import { useMessageOption } from "~/hooks/useMessageOption"
|
||||
import {
|
||||
BrainCog,
|
||||
ChevronLeft,
|
||||
CogIcon,
|
||||
ComputerIcon,
|
||||
@@ -24,6 +25,8 @@ import { SelectedKnowledge } from "../Option/Knowledge/SelectedKnwledge"
|
||||
import { useStorage } from "@plasmohq/storage/hook"
|
||||
import { ModelSelect } from "../Common/ModelSelect"
|
||||
import { PromptSelect } from "../Common/PromptSelect"
|
||||
import { ChatSettings } from "../Icons/ChatSettings"
|
||||
import { CurrentChatModelSettings } from "../Common/CurrentChatModelSettings"
|
||||
|
||||
export default function OptionLayout({
|
||||
children
|
||||
@@ -33,6 +36,7 @@ export default function OptionLayout({
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false)
|
||||
const { t } = useTranslation(["option", "common"])
|
||||
const [shareModeEnabled] = useStorage("shareMode", false)
|
||||
const [openModelSettings, setOpenModelSettings] = useState(false)
|
||||
|
||||
const {
|
||||
selectedModel,
|
||||
@@ -108,9 +112,7 @@ export default function OptionLayout({
|
||||
onClick={clearChat}
|
||||
className="inline-flex dark:bg-transparent bg-white items-center rounded-lg border dark:border-gray-700 bg-transparent px-3 py-2.5 text-xs lg:text-sm font-medium leading-4 text-gray-800 dark:text-white disabled:opacity-50 ease-in-out transition-colors duration-200 hover:bg-gray-100 dark:hover:bg-gray-800 dark:hover:text-white">
|
||||
<SquarePen className="h-5 w-5 " />
|
||||
<span className=" truncate ml-3">
|
||||
{t("newChat")}
|
||||
</span>
|
||||
<span className=" truncate ml-3">{t("newChat")}</span>
|
||||
</button>
|
||||
</div>
|
||||
<span className="text-lg font-thin text-zinc-300 dark:text-zinc-600">
|
||||
@@ -193,6 +195,13 @@ export default function OptionLayout({
|
||||
<div className="flex flex-1 justify-end px-4">
|
||||
<div className="ml-4 flex items-center md:ml-6">
|
||||
<div className="flex gap-4 items-center">
|
||||
<Tooltip title={t("currentChatModelSettings")}>
|
||||
<button
|
||||
onClick={() => setOpenModelSettings(true)}
|
||||
className="!text-gray-500 dark:text-gray-300 hover:text-gray-600 dark:hover:text-gray-300 transition-colors">
|
||||
<BrainCog className="w-6 h-6" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
{pathname === "/" &&
|
||||
messages.length > 0 &&
|
||||
!streaming &&
|
||||
@@ -228,6 +237,11 @@ export default function OptionLayout({
|
||||
open={sidebarOpen}>
|
||||
<Sidebar onClose={() => setSidebarOpen(false)} />
|
||||
</Drawer>
|
||||
|
||||
<CurrentChatModelSettings
|
||||
open={openModelSettings}
|
||||
setOpen={setOpenModelSettings}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
123
src/components/Option/Settings/model-settings.tsx
Normal file
123
src/components/Option/Settings/model-settings.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import { SaveButton } from "@/components/Common/SaveButton"
|
||||
import { getAllModelSettings, setModelSetting } from "@/services/model-settings"
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query"
|
||||
import { Form, Skeleton, Input, Switch, InputNumber, Collapse } from "antd"
|
||||
import React from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
// keepAlive?: string
|
||||
// temperature?: number
|
||||
// topK?: number
|
||||
// topP?: number
|
||||
|
||||
export const ModelSettings = () => {
|
||||
const { t } = useTranslation("common")
|
||||
const [form] = Form.useForm()
|
||||
const client = useQueryClient()
|
||||
const { isPending: isLoading } = useQuery({
|
||||
queryKey: ["fetchModelConfig"],
|
||||
queryFn: async () => {
|
||||
const data = await getAllModelSettings()
|
||||
form.setFieldsValue(data)
|
||||
return data
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<h2 className="text-base font-semibold leading-7 text-gray-900 dark:text-white">
|
||||
{t("modelSettings.label")}
|
||||
</h2>
|
||||
<p className="text-sm text-gray-500 dark:text-neutral-400 mt-1">
|
||||
{t("modelSettings.description")}
|
||||
</p>
|
||||
<div className="border border-b border-gray-200 dark:border-gray-600 mt-3 mb-6"></div>
|
||||
</div>
|
||||
{!isLoading ? (
|
||||
<Form
|
||||
onFinish={(values: {
|
||||
keepAlive: string
|
||||
temperature: number
|
||||
topK: number
|
||||
topP: number
|
||||
}) => {
|
||||
Object.entries(values).forEach(([key, value]) => {
|
||||
setModelSetting(key, value)
|
||||
})
|
||||
client.invalidateQueries({
|
||||
queryKey: ["fetchModelConfig"]
|
||||
})
|
||||
}}
|
||||
form={form}
|
||||
layout="vertical">
|
||||
<Form.Item
|
||||
name="keepAlive"
|
||||
help={t("modelSettings.form.keepAlive.help")}
|
||||
label={t("modelSettings.form.keepAlive.label")}>
|
||||
<Input
|
||||
size="large"
|
||||
placeholder={t("modelSettings.form.keepAlive.placeholder")}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="temperature"
|
||||
label={t("modelSettings.form.temperature.label")}>
|
||||
<InputNumber
|
||||
size="large"
|
||||
style={{ width: "100%" }}
|
||||
placeholder={t("modelSettings.form.temperature.placeholder")}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="numCtx" label={t("modelSettings.form.numCtx.label")}>
|
||||
<InputNumber
|
||||
style={{ width: "100%" }}
|
||||
placeholder={t("modelSettings.form.numCtx.placeholder")}
|
||||
size="large"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Collapse
|
||||
ghost
|
||||
className="border-none bg-transparent"
|
||||
items={[
|
||||
{
|
||||
key: "1",
|
||||
label: t("modelSettings.advanced"),
|
||||
children: (
|
||||
<React.Fragment>
|
||||
<Form.Item
|
||||
name="topK"
|
||||
label={t("modelSettings.form.topK.label")}>
|
||||
<InputNumber
|
||||
style={{ width: "100%" }}
|
||||
placeholder={t("modelSettings.form.topK.placeholder")}
|
||||
size="large"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="topP"
|
||||
label={t("modelSettings.form.topP.label")}>
|
||||
<InputNumber
|
||||
style={{ width: "100%" }}
|
||||
size="large"
|
||||
placeholder={t("modelSettings.form.topP.placeholder")}
|
||||
/>
|
||||
</Form.Item>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<SaveButton btnType="submit" />
|
||||
</div>
|
||||
</Form>
|
||||
) : (
|
||||
<Skeleton active />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import { SettingPrompt } from "./prompt"
|
||||
import { Trans, useTranslation } from "react-i18next"
|
||||
import { useStorage } from "@plasmohq/storage/hook"
|
||||
import { AdvanceOllamaSettings } from "@/components/Common/AdvanceOllamaSettings"
|
||||
import { ModelSettings } from "./model-settings"
|
||||
|
||||
export const SettingsOllama = () => {
|
||||
const [ollamaURL, setOllamaURL] = useState<string>("")
|
||||
@@ -219,6 +220,7 @@ export const SettingsOllama = () => {
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
<ModelSettings />
|
||||
|
||||
<div>
|
||||
<div>
|
||||
@@ -229,6 +231,8 @@ export const SettingsOllama = () => {
|
||||
</div>
|
||||
<SettingPrompt />
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,6 @@ import { useTranslation } from "react-i18next"
|
||||
|
||||
export const SearchModeSettings = () => {
|
||||
const { t } = useTranslation("settings")
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const form = useForm({
|
||||
initialValues: {
|
||||
|
||||
Reference in New Issue
Block a user