Skip to content

Commit a027520

Browse files
authored
Merge pull request #270 from n4ze3m/next
v1.3.7
2 parents bd5b3f9 + 0566089 commit a027520

File tree

7 files changed

+188
-75
lines changed

7 files changed

+188
-75
lines changed

src/components/Option/Playground/Playground.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,24 @@ import { webUIResumeLastChat } from "@/services/app"
66
import {
77
formatToChatHistory,
88
formatToMessage,
9+
getPromptById,
910
getRecentChatFromWebUI
1011
} from "@/db"
12+
import { getLastUsedChatSystemPrompt } from "@/services/model-settings"
13+
import { useStoreChatModelSettings } from "@/store/model"
1114

1215
export const Playground = () => {
1316
const drop = React.useRef<HTMLDivElement>(null)
1417
const [dropedFile, setDropedFile] = React.useState<File | undefined>()
15-
const { selectedKnowledge, messages, setHistoryId, setHistory, setMessages } =
16-
useMessageOption()
18+
const {
19+
selectedKnowledge,
20+
messages,
21+
setHistoryId,
22+
setHistory,
23+
setMessages,
24+
setSelectedSystemPrompt
25+
} = useMessageOption()
26+
const { setSystemPrompt } = useStoreChatModelSettings()
1727

1828
const [dropState, setDropState] = React.useState<
1929
"idle" | "dragging" | "error"
@@ -90,6 +100,19 @@ export const Playground = () => {
90100
setHistoryId(recentChat.history.id)
91101
setHistory(formatToChatHistory(recentChat.messages))
92102
setMessages(formatToMessage(recentChat.messages))
103+
104+
const lastUsedPrompt = await getLastUsedChatSystemPrompt(
105+
recentChat.history.id
106+
)
107+
if (lastUsedPrompt) {
108+
if (lastUsedPrompt.prompt_id) {
109+
const prompt = await getPromptById(lastUsedPrompt.prompt_id)
110+
if (prompt) {
111+
setSelectedSystemPrompt(lastUsedPrompt.prompt_id)
112+
}
113+
}
114+
setSystemPrompt(lastUsedPrompt.prompt_content)
115+
}
93116
}
94117
}
95118
}

src/components/Option/Sidebar.tsx

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
formatToMessage,
66
deleteByHistoryId,
77
updateHistory,
8-
pinHistory
8+
pinHistory,
9+
getPromptById
910
} from "@/db"
1011
import { Empty, Skeleton, Dropdown, Menu } from "antd"
1112
import { useMessageOption } from "~/hooks/useMessageOption"
@@ -20,8 +21,10 @@ import { useNavigate } from "react-router-dom"
2021
import { useTranslation } from "react-i18next"
2122
import {
2223
getLastUsedChatModel,
24+
getLastUsedChatSystemPrompt,
2325
lastUsedChatModelEnabled
2426
} from "@/services/model-settings"
27+
import { useStoreChatModelSettings } from "@/store/model"
2528

2629
type Props = {
2730
onClose: () => void
@@ -35,8 +38,12 @@ export const Sidebar = ({ onClose }: Props) => {
3538
historyId,
3639
clearChat,
3740
setSelectedModel,
38-
temporaryChat
41+
temporaryChat,
42+
setSelectedSystemPrompt
3943
} = useMessageOption()
44+
45+
const { setSystemPrompt } = useStoreChatModelSettings()
46+
4047
const { t } = useTranslation(["option", "common"])
4148
const client = useQueryClient()
4249
const navigate = useNavigate()
@@ -127,7 +134,8 @@ export const Sidebar = ({ onClose }: Props) => {
127134
})
128135

129136
return (
130-
<div className={`overflow-y-auto z-99 ${temporaryChat ? 'pointer-events-none opacity-50' : ''}`}>
137+
<div
138+
className={`overflow-y-auto z-99 ${temporaryChat ? "pointer-events-none opacity-50" : ""}`}>
131139
{status === "success" && chatHistories.length === 0 && (
132140
<div className="flex justify-center items-center mt-20 overflow-hidden">
133141
<Empty description={t("common:noHistory")} />
@@ -173,6 +181,19 @@ export const Sidebar = ({ onClose }: Props) => {
173181
setSelectedModel(currentChatModel)
174182
}
175183
}
184+
const lastUsedPrompt =
185+
await getLastUsedChatSystemPrompt(chat.id)
186+
if (lastUsedPrompt) {
187+
if (lastUsedPrompt.prompt_id) {
188+
const prompt = await getPromptById(
189+
lastUsedPrompt.prompt_id
190+
)
191+
if (prompt) {
192+
setSelectedSystemPrompt(lastUsedPrompt.prompt_id)
193+
}
194+
}
195+
setSystemPrompt(lastUsedPrompt.prompt_content)
196+
}
176197
navigate("/")
177198
onClose()
178199
}}>
@@ -245,4 +266,4 @@ export const Sidebar = ({ onClose }: Props) => {
245266
)}
246267
</div>
247268
)
248-
}
269+
}

src/components/Sidepanel/Chat/empty.tsx

Lines changed: 85 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { cleanUrl } from "@/libs/clean-url"
22
import { useStorage } from "@plasmohq/storage/hook"
33
import { useQuery, useQueryClient } from "@tanstack/react-query"
44
import { Select } from "antd"
5-
import { RotateCcw } from "lucide-react"
5+
import { Loader2, RotateCcw } from "lucide-react"
66
import { useEffect, useState } from "react"
77
import { Trans, useTranslation } from "react-i18next"
88
import { useMessage } from "~/hooks/useMessage"
@@ -50,6 +50,88 @@ export const EmptySidePanel = () => {
5050

5151
const { setSelectedModel, selectedModel, chatMode, setChatMode } =
5252
useMessage()
53+
const renderSection = () => {
54+
return (
55+
<div className="mt-4">
56+
<Select
57+
onChange={(e) => {
58+
setSelectedModel(e)
59+
localStorage.setItem("selectedModel", e)
60+
}}
61+
value={selectedModel}
62+
size="large"
63+
filterOption={(input, option) =>
64+
option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
65+
option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
66+
}
67+
showSearch
68+
placeholder={t("common:selectAModel")}
69+
style={{ width: "100%" }}
70+
className="mt-4"
71+
options={ollamaInfo.models?.map((model) => ({
72+
label: model.name,
73+
value: model.model
74+
}))}
75+
/>
76+
77+
<div className="mt-4">
78+
<div className="inline-flex items-center">
79+
<label
80+
className="relative flex items-center p-3 rounded-full cursor-pointer"
81+
htmlFor="check">
82+
<input
83+
type="checkbox"
84+
checked={chatMode === "rag"}
85+
onChange={(e) => {
86+
setChatMode(e.target.checked ? "rag" : "normal")
87+
}}
88+
className="before:content[''] peer relative h-5 w-5 cursor-pointer appearance-none rounded-md border border-blue-gray-200 transition-all before:absolute before:top-2/4 before:left-2/4 before:block before:h-12 before:w-12 before:-translate-y-2/4 before:-translate-x-2/4 before:rounded-full before:bg-blue-gray-500 before:opacity-0 before:transition-opacity"
89+
id="check"
90+
/>
91+
<span className="absolute text-white transition-opacity opacity-0 pointer-events-none top-2/4 left-2/4 -translate-y-2/4 -translate-x-2/4 peer-checked:opacity-100 ">
92+
<svg
93+
xmlns="http://www.w3.org/2000/svg"
94+
className="h-3.5 w-3.5"
95+
viewBox="0 0 20 20"
96+
fill="currentColor"
97+
stroke="currentColor"
98+
strokeWidth="1">
99+
<path
100+
fillRule="evenodd"
101+
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
102+
clipRule="evenodd"></path>
103+
</svg>
104+
</span>
105+
</label>
106+
<label
107+
className="mt-px font-light cursor-pointer select-none text-gray-900 dark:text-gray-400"
108+
htmlFor="check">
109+
{t("common:chatWithCurrentPage")}
110+
</label>
111+
</div>
112+
</div>
113+
</div>
114+
)
115+
}
116+
117+
if (!checkOllamaStatus) {
118+
return (
119+
<div className="mx-auto sm:max-w-md px-4 mt-10">
120+
<div className="rounded-lg justify-center items-center flex flex-col border dark:border-gray-700 p-8 bg-white dark:bg-[#262626] shadow-sm">
121+
<div className="inline-flex items-center space-x-2">
122+
<p className="dark:text-gray-400 text-gray-900">
123+
<span>👋</span>
124+
{t("welcome")}
125+
</p>
126+
</div>
127+
{ollamaStatus === "pending" && (
128+
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
129+
)}
130+
{ollamaStatus === "success" && ollamaInfo.isOk && renderSection()}
131+
</div>
132+
</div>
133+
)
134+
}
53135

54136
return (
55137
<div className="mx-auto sm:max-w-md px-4 mt-10">
@@ -62,7 +144,7 @@ export const EmptySidePanel = () => {
62144
</p>
63145
</div>
64146
)}
65-
{!isRefetching && ollamaStatus === "success" && checkOllamaStatus ? (
147+
{!isRefetching && ollamaStatus === "success" ? (
66148
ollamaInfo.isOk ? (
67149
<div className="inline-flex items-center space-x-2">
68150
<div className="w-3 h-3 bg-green-500 rounded-full"></div>
@@ -115,67 +197,7 @@ export const EmptySidePanel = () => {
115197
)
116198
) : null}
117199

118-
{ollamaStatus === "success" && ollamaInfo.isOk && (
119-
<div className="mt-4">
120-
<Select
121-
onChange={(e) => {
122-
setSelectedModel(e)
123-
localStorage.setItem("selectedModel", e)
124-
}}
125-
value={selectedModel}
126-
size="large"
127-
filterOption={(input, option) =>
128-
option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
129-
option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
130-
}
131-
showSearch
132-
placeholder={t("common:selectAModel")}
133-
style={{ width: "100%" }}
134-
className="mt-4"
135-
options={ollamaInfo.models?.map((model) => ({
136-
label: model.name,
137-
value: model.model
138-
}))}
139-
/>
140-
141-
<div className="mt-4">
142-
<div className="inline-flex items-center">
143-
<label
144-
className="relative flex items-center p-3 rounded-full cursor-pointer"
145-
htmlFor="check">
146-
<input
147-
type="checkbox"
148-
checked={chatMode === "rag"}
149-
onChange={(e) => {
150-
setChatMode(e.target.checked ? "rag" : "normal")
151-
}}
152-
className="before:content[''] peer relative h-5 w-5 cursor-pointer appearance-none rounded-md border border-blue-gray-200 transition-all before:absolute before:top-2/4 before:left-2/4 before:block before:h-12 before:w-12 before:-translate-y-2/4 before:-translate-x-2/4 before:rounded-full before:bg-blue-gray-500 before:opacity-0 before:transition-opacity"
153-
id="check"
154-
/>
155-
<span className="absolute text-white transition-opacity opacity-0 pointer-events-none top-2/4 left-2/4 -translate-y-2/4 -translate-x-2/4 peer-checked:opacity-100 ">
156-
<svg
157-
xmlns="http://www.w3.org/2000/svg"
158-
className="h-3.5 w-3.5"
159-
viewBox="0 0 20 20"
160-
fill="currentColor"
161-
stroke="currentColor"
162-
strokeWidth="1">
163-
<path
164-
fillRule="evenodd"
165-
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
166-
clipRule="evenodd"></path>
167-
</svg>
168-
</span>
169-
</label>
170-
<label
171-
className="mt-px font-light cursor-pointer select-none text-gray-900 dark:text-gray-400"
172-
htmlFor="check">
173-
{t("common:chatWithCurrentPage")}
174-
</label>
175-
</div>
176-
</div>
177-
</div>
178-
)}
200+
{ollamaStatus === "success" && ollamaInfo.isOk && renderSection()}
179201
</div>
180202
</div>
181203
)

src/hooks/chat-helper/index.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { saveHistory, saveMessage } from "@/db"
2-
import { setLastUsedChatModel } from "@/services/model-settings"
2+
import { setLastUsedChatModel, setLastUsedChatSystemPrompt } from "@/services/model-settings"
33
import { generateTitle } from "@/services/title"
44
import { ChatHistory } from "@/store/option"
55

@@ -15,7 +15,9 @@ export const saveMessageOnError = async ({
1515
setHistoryId,
1616
isRegenerating,
1717
message_source = "web-ui",
18-
message_type
18+
message_type,
19+
prompt_content,
20+
prompt_id
1921
}: {
2022
e: any
2123
setHistory: (history: ChatHistory) => void
@@ -29,6 +31,8 @@ export const saveMessageOnError = async ({
2931
isRegenerating: boolean
3032
message_source?: "copilot" | "web-ui"
3133
message_type?: string
34+
prompt_id?: string
35+
prompt_content?: string
3236
}) => {
3337
if (
3438
e?.name === "AbortError" ||
@@ -73,6 +77,9 @@ export const saveMessageOnError = async ({
7377
message_type
7478
)
7579
await setLastUsedChatModel(historyId, selectedModel)
80+
if (prompt_id || prompt_content) {
81+
await setLastUsedChatSystemPrompt(historyId, { prompt_content, prompt_id })
82+
}
7683
} else {
7784
const title = await generateTitle(selectedModel, userMessage, userMessage)
7885
const newHistoryId = await saveHistory(title, false, message_source)
@@ -100,6 +107,9 @@ export const saveMessageOnError = async ({
100107
)
101108
setHistoryId(newHistoryId.id)
102109
await setLastUsedChatModel(newHistoryId.id, selectedModel)
110+
if (prompt_id || prompt_content) {
111+
await setLastUsedChatSystemPrompt(historyId, { prompt_content, prompt_id })
112+
}
103113
}
104114

105115
return true
@@ -118,7 +128,9 @@ export const saveMessageOnSuccess = async ({
118128
fullText,
119129
source,
120130
message_source = "web-ui",
121-
message_type, generationInfo
131+
message_type, generationInfo,
132+
prompt_id,
133+
prompt_content
122134
}: {
123135
historyId: string | null
124136
setHistoryId: (historyId: string) => void
@@ -131,6 +143,8 @@ export const saveMessageOnSuccess = async ({
131143
message_source?: "copilot" | "web-ui",
132144
message_type?: string
133145
generationInfo?: any
146+
prompt_id?: string
147+
prompt_content?: string
134148
}) => {
135149
if (historyId) {
136150
if (!isRegenerate) {
@@ -158,6 +172,9 @@ export const saveMessageOnSuccess = async ({
158172
generationInfo
159173
)
160174
await setLastUsedChatModel(historyId, selectedModel!)
175+
if (prompt_id || prompt_content) {
176+
await setLastUsedChatSystemPrompt(historyId, { prompt_content, prompt_id })
177+
}
161178
} else {
162179
const title = await generateTitle(selectedModel, message, message)
163180
const newHistoryId = await saveHistory(title, false, message_source)
@@ -185,5 +202,8 @@ export const saveMessageOnSuccess = async ({
185202
)
186203
setHistoryId(newHistoryId.id)
187204
await setLastUsedChatModel(newHistoryId.id, selectedModel!)
205+
if (prompt_id || prompt_content) {
206+
await setLastUsedChatSystemPrompt(historyId, { prompt_content, prompt_id })
207+
}
188208
}
189209
}

0 commit comments

Comments
 (0)