Skip to content

Commit 321350c

Browse files
authored
Merge pull request #645 from n4ze3m/next
v1.5.20
2 parents 8395974 + 37fd441 commit 321350c

File tree

16 files changed

+354
-52
lines changed

16 files changed

+354
-52
lines changed

src/components/Common/ProviderIcon.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { AliBaBaCloudIcon } from "../Icons/AliBaBaCloud"
1717
import { LlamaCppLogo } from "../Icons/LlamacppLogo"
1818
import { InfinigenceAI } from "../Icons/InfinigenceAI"
1919
import { NovitaIcon } from "../Icons/Novita"
20+
import { VllmLogo } from "../Icons/VllmLogo"
2021

2122
export const ProviderIcons = ({
2223
provider,
@@ -64,6 +65,8 @@ export const ProviderIcons = ({
6465
return <InfinigenceAI className={className} />
6566
case "novita":
6667
return <NovitaIcon className={className} />
68+
case "vllm":
69+
return <VllmLogo className={className} />
6770
default:
6871
return <OllamaIcon className={className} />
6972
}

src/components/Icons/VllmLogo.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from "react"
2+
3+
export const VllmLogo = React.forwardRef<
4+
SVGSVGElement,
5+
React.SVGProps<SVGSVGElement>
6+
>((props, ref) => {
7+
return (
8+
<svg
9+
xmlns="http://www.w3.org/2000/svg"
10+
viewBox="0 0 460 460"
11+
{...props}
12+
ref={ref}>
13+
<path
14+
fill="#63A1FC"
15+
d="M196.952 394.188c-.976-.241-1.952-.482-3.039-1.382-.02-1.292.071-1.925.435-2.828 2.018-6.88 3.763-13.487 5.508-20.096 5.243-19.703 10.593-39.379 15.702-59.117 6.44-24.884 12.58-49.846 19.042-74.725 6.918-26.634 14.083-53.204 21.092-79.815 2.446-9.288 5.003-18.56 7.012-27.945 1.034-4.832 3.499-7.432 7.857-9.664 20.658-10.58 41.092-21.597 61.63-32.41 17.864-9.405 35.762-18.745 54.706-28.67-1.102 3.546-1.9 6.116-2.783 9.439-1.73 6.836-3.437 12.903-5.01 19.005-4.519 17.514-8.84 35.081-13.508 52.556-5.004 18.734-10.468 37.345-15.447 56.086-4.72 17.765-8.925 35.667-13.62 53.44-8.386 31.752-16.987 63.448-25.466 95.177-4.489 16.797-8.91 33.612-13.452 50.764-2.26 0-4.23-.004-6.2 0z"></path>
16+
<path
17+
fill="#EBB432"
18+
d="M194.075 390.248a139 139 0 0 1-.331 2.214c-5.776-10.717-11.576-21.707-17.187-32.793-6.359-12.562-12.54-25.213-18.813-37.818-7.388-14.847-14.768-29.696-22.19-44.525-8.9-17.78-17.885-35.518-26.756-53.313-14.122-28.33-28.171-56.694-42.28-85.03-1.384-2.78-2.964-5.462-4.752-8.736 2.163-.132 3.585-.295 5.007-.295 40.662-.014 81.325.008 121.987-.05 3.117-.005 5.813-.059 5.094 5.157.006 84.33-.002 167.77.002 251.208 0 1.327.143 2.654.219 3.981"></path>
19+
<path
20+
fill="#D7D8D9"
21+
d="M197.123 394.504c31.315-.378 62.802-.44 94.288-.5 1.97-.005 3.94-.001 6.2-.001 4.543-17.152 8.963-33.967 13.452-50.764 8.479-31.729 17.08-63.425 25.467-95.178 4.694-17.772 8.899-35.674 13.62-53.44 4.978-18.74 10.442-37.351 15.446-56.085 4.668-17.475 8.99-35.042 13.507-52.556 1.574-6.102 3.28-12.17 5.01-18.646 2.473-1.275 4.861-2.156 8.033-3.328-2.087 8.294-3.922 15.954-5.95 23.563-3.664 13.747-7.485 27.451-11.163 41.194-6.513 24.331-13.055 48.655-19.422 73.024-6.365 24.36-12.432 48.796-18.823 73.147-3.322 12.66-7.213 25.171-10.574 37.822-4.892 18.406-9.477 36.893-14.313 55.314-2.477 9.434-5.3 18.778-7.79 28.209-.796 3.017-2.461 3.779-5.397 3.77-31.831-.083-63.664-.152-95.494.07-4.283.03-4.791-2.612-6.097-5.615"></path>
22+
<path
23+
fill="#D8D8D8"
24+
d="M194.348 389.978c-.35-1.057-.492-2.384-.492-3.71-.004-83.44.004-166.88.071-250.782 1.527-.384 2.994-.306 5.123-.192v6.588c0 73.977-.002 147.954.012 221.932 0 1.82.177 3.64.532 5.765-1.483 6.912-3.228 13.52-5.246 20.399"></path>
25+
</svg>
26+
)
27+
})

src/components/Option/Playground/Playground.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ export const Playground = () => {
170170
</div>
171171
<div className="absolute bottom-0 w-full z-10">
172172
{!isAtBottom && (
173-
<div className="fixed bottom-28 z-20 left-0 right-0 flex justify-center">
173+
<div className="fixed bottom-28 z-10 left-0 right-0 flex justify-center pointer-events-none">
174174
<button
175175
onClick={scrollToBottom}
176176
className="bg-gray-50 shadow border border-gray-200 dark:border-none dark:bg-white/20 p-1.5 rounded-full pointer-events-auto">

src/components/Option/Settings/openai.tsx

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@
44
* The component uses React Query to manage the state and perform CRUD operations on the OpenAI configurations.
55
* It also includes a modal for fetching the available models from the selected OpenAI configuration.
66
*/
7-
import { Form, Input, Modal, Table, message, Tooltip, Select } from "antd"
7+
import {
8+
Form,
9+
Input,
10+
Modal,
11+
Table,
12+
message,
13+
Tooltip,
14+
Select,
15+
Switch
16+
} from "antd"
817
import { useState } from "react"
918
import { useTranslation } from "react-i18next"
1019
import {
@@ -18,7 +27,7 @@ import { Pencil, Trash2, DownloadIcon, Trash2Icon } from "lucide-react"
1827
import { OpenAIFetchModel } from "./openai-fetch-model"
1928
import { OAI_API_PROVIDERS } from "@/utils/oai-api-providers"
2029
import { ProviderIcons } from "@/components/Common/ProviderIcon"
21-
const noPopupProvider = ["lmstudio", "llamafile", "ollama2", "llamacpp"]
30+
const noPopupProvider = ["lmstudio", "llamafile", "ollama2", "llamacpp", "vllm"]
2231

2332
export const OpenAIApp = () => {
2433
const { t } = useTranslation(["openai", "settings"])
@@ -35,7 +44,6 @@ export const OpenAIApp = () => {
3544
queryFn: getAllOpenAIConfig
3645
})
3746

38-
3947
const addMutation = useMutation({
4048
mutationFn: addOpenAICofig,
4149
onSuccess: (data) => {
@@ -81,6 +89,7 @@ export const OpenAIApp = () => {
8189
name: string
8290
baseUrl: string
8391
apiKey: string
92+
fix_cors?: boolean
8493
headers?: { key: string; value: string }[]
8594
}) => {
8695
if (editingConfig) {
@@ -103,7 +112,8 @@ export const OpenAIApp = () => {
103112
})
104113
form.setFieldsValue({
105114
...record,
106-
headers: record?.headers || []
115+
headers: record?.headers || [],
116+
fix_cors: record?.fix_cors || false
107117
})
108118
setOpen(true)
109119
}
@@ -296,6 +306,16 @@ export const OpenAIApp = () => {
296306
placeholder={t("modal.apiKey.placeholder")}
297307
/>
298308
</Form.Item>
309+
310+
<Form.Item
311+
name="fix_cors"
312+
label={t("modal.fixCors.label", {
313+
defaultValue: "Fix CORS issues"
314+
})}
315+
valuePropName="checked">
316+
<Switch />
317+
</Form.Item>
318+
299319
<Form.List name="headers">
300320
{(fields, { add, remove }) => (
301321
<div className="flex flex-col ">

src/db/dexie/helpers.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
LastUsedModelType
1717
} from "./types";
1818
import { PageAssistDatabase } from "./chat";
19+
import { db as chatDB } from './schema';
1920

2021
// Helper function to generate IDs (keeping the same format)
2122
export const generateID = () => {
@@ -159,23 +160,11 @@ export const deleteByHistoryId = async (history_id: string) => {
159160
};
160161

161162
export const updateHistory = async (id: string, title: string) => {
162-
const db = new PageAssistDatabase();
163-
const chatHistories = await db.getChatHistories();
164-
const historyToUpdate = chatHistories.find(h => h.id === id);
165-
if (historyToUpdate) {
166-
await db.deleteChatHistory(id);
167-
await db.addChatHistory({ ...historyToUpdate, title });
168-
}
163+
await chatDB.chatHistories.update(id, { title });
169164
};
170165

171166
export const pinHistory = async (id: string, is_pinned: boolean) => {
172-
const db = new PageAssistDatabase();
173-
const chatHistories = await db.getChatHistories();
174-
const historyToUpdate = chatHistories.find(h => h.id === id);
175-
if (historyToUpdate) {
176-
await db.deleteChatHistory(id);
177-
await db.addChatHistory({ ...historyToUpdate, is_pinned });
178-
}
167+
await chatDB.chatHistories.update(id, { is_pinned });
179168
};
180169

181170
export const removeMessageUsingHistoryId = async (history_id: string) => {

src/db/dexie/models.ts

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const removeModelSuffix = (id: string) => {
2121
.replace(/_llamafile_openai-[a-f0-9]{4}-[a-f0-9]{3}-[a-f0-9]{4}/, "")
2222
.replace(/_ollama2_openai-[a-f0-9]{4}-[a-f0-9]{3}-[a-f0-9]{4}/, "")
2323
.replace(/_llamacpp_openai-[a-f0-9]{4}-[a-f0-9]{3}-[a-f0-9]{4}/, "")
24+
.replace(/_vllm_openai-[a-f0-9]{4}-[a-f0-9]{3}-[a-f0-9]{4}/, "")
2425
}
2526
export const isLMStudioModel = (model: string) => {
2627
const lmstudioModelRegex =
@@ -39,6 +40,11 @@ export const isLLamaCppModel = (model: string) => {
3940
return llamaCppModelRegex.test(model)
4041
}
4142

43+
export const isVLLMModel = (model: string) => {
44+
const vllmModelRegex = /_vllm_openai-[a-f0-9]{4}-[a-f0-9]{3}-[a-f0-9]{4}/
45+
return vllmModelRegex.test(model)
46+
}
47+
4248
export const isOllamaModel = (model: string) => {
4349
const ollamaModelRegex =
4450
/_ollama2_openai-[a-f0-9]{4}-[a-f0-9]{3}-[a-f0-9]{4}/
@@ -98,6 +104,20 @@ export const getLLamaCppModelId = (
98104
return null
99105
}
100106

107+
export const getVLLMModelId = (
108+
model: string
109+
): { model_id: string; provider_id: string } => {
110+
const vllmModelRegex =
111+
/_vllm_openai-[a-f0-9]{4}-[a-f0-9]{3}-[a-f0-9]{4}/
112+
const match = model.match(vllmModelRegex)
113+
if (match) {
114+
const modelId = match[0]
115+
const providerId = match[0].replace("_vllm_openai-", "")
116+
return { model_id: modelId, provider_id: providerId }
117+
}
118+
return null
119+
}
120+
101121
export const isCustomModel = (model: string) => {
102122
if (isLMStudioModel(model)) {
103123
return true
@@ -115,6 +135,10 @@ export const isCustomModel = (model: string) => {
115135
return true
116136
}
117137

138+
if (isVLLMModel(model)) {
139+
return true
140+
}
141+
118142
const customModelRegex =
119143
/_model-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{3,4}-[a-f0-9]{4}/
120144
return customModelRegex.test(model)
@@ -258,7 +282,7 @@ export const getModelInfo = async (id: string) => {
258282
if (isLLamaCppModel(id)) {
259283
const llamaCppId = getLLamaCppModelId(id)
260284
if (!llamaCppId) {
261-
throw new Error("Invalid LMStudio model ID")
285+
throw new Error("Invalid llamaCPP model ID")
262286
}
263287

264288
return {
@@ -274,6 +298,24 @@ export const getModelInfo = async (id: string) => {
274298
}
275299
}
276300

301+
if (isVLLMModel(id)) {
302+
const vllmId = getVLLMModelId(id)
303+
if (!vllmId) {
304+
throw new Error("Invalid Vllm model ID")
305+
}
306+
return {
307+
model_id: id.replace(
308+
/_vllm_openai-[a-f0-9]{4}-[a-f0-9]{3}-[a-f0-9]{4}/,
309+
""
310+
),
311+
provider_id: `openai-${vllmId.provider_id}`,
312+
name: id.replace(
313+
/_vllm_openai-[a-f0-9]{4}-[a-f0-9]{3}-[a-f0-9]{4}/,
314+
""
315+
)
316+
}
317+
}
318+
277319

278320
if (isOllamaModel(id)) {
279321
const ollamaId = getOllamaModelId(id)
@@ -388,6 +430,30 @@ export const dynamicFetchLLamaCpp = async ({
388430
return llamaCppModels
389431
}
390432

433+
434+
export const dynamicFetchVLLM = async ({
435+
baseUrl,
436+
providerId,
437+
customHeaders = []
438+
}: {
439+
baseUrl: string
440+
providerId: string
441+
customHeaders?: { key: string; value: string }[]
442+
}) => {
443+
const models = await getAllOpenAIModels({ baseUrl, customHeaders })
444+
const vllmModels = models.map((e) => {
445+
return {
446+
name: e?.name || e?.id,
447+
id: `${e?.id}_vllm_${providerId}`,
448+
provider: providerId,
449+
lookup: `${e?.id}_${providerId}`,
450+
provider_id: providerId
451+
}
452+
})
453+
454+
return vllmModels
455+
}
456+
391457
export const dynamicFetchOllama2 = async ({
392458
baseUrl,
393459
providerId,
@@ -459,6 +525,10 @@ export const ollamaFormatAllCustomModels = async (
459525
(model) => model.provider === "llamacpp"
460526
)
461527

528+
const vllmProviders = allProviders.filter(
529+
(model) => model.provider === "vllm"
530+
)
531+
462532
const lmModelsPromises = lmstudioProviders.map((provider) =>
463533
dynamicFetchLMStudio({
464534
baseUrl: provider.baseUrl,
@@ -489,6 +559,13 @@ export const ollamaFormatAllCustomModels = async (
489559
customHeaders: provider.headers
490560
}))
491561

562+
const vllmModelsPromises = vllmProviders.map((provider) =>
563+
dynamicFetchVLLM({
564+
baseUrl: provider.baseUrl,
565+
providerId: provider.id,
566+
customHeaders: provider.headers
567+
}))
568+
492569
const lmModelsFetch = await Promise.all(lmModelsPromises)
493570

494571
const llamafileModelsFetch = await Promise.all(llamafileModelsPromises)
@@ -497,6 +574,8 @@ export const ollamaFormatAllCustomModels = async (
497574

498575
const llamacppModelsFetch = await Promise.all(llamacppModelsPromises)
499576

577+
const vllmModelsFetch = await Promise.all(vllmModelsPromises)
578+
500579
const lmModels = lmModelsFetch.flat()
501580

502581
const llamafileModels = llamafileModelsFetch.flat()
@@ -505,6 +584,8 @@ export const ollamaFormatAllCustomModels = async (
505584

506585
const llamacppModels = llamacppModelsFetch.flat()
507586

587+
const vllmModels = vllmModelsFetch.flat()
588+
508589
// merge allModels and lmModels
509590
const allModlesWithLMStudio = [
510591
...(modelType !== "all"
@@ -513,7 +594,8 @@ export const ollamaFormatAllCustomModels = async (
513594
...lmModels,
514595
...llamafileModels,
515596
...ollama2Models,
516-
...llamacppModels
597+
...llamacppModels,
598+
...vllmModels
517599
]
518600

519601
const ollamaModels = allModlesWithLMStudio.map((model) => {

src/db/dexie/openai.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export class OpenAIModelDb {
5959
}
6060

6161

62-
export const addOpenAICofig = async ({ name, baseUrl, apiKey, provider, headers }: { name: string, baseUrl: string, apiKey: string, provider?: string, headers?: { key: string; value: string }[] }) => {
62+
export const addOpenAICofig = async ({ name, baseUrl, apiKey, provider, headers, fix_cors }: { name: string, baseUrl: string, apiKey: string, provider?: string, headers?: { key: string; value: string }[], fix_cors?: boolean }) => {
6363
const openaiDb = new OpenAIModelDb()
6464
const id = generateID()
6565
const config: OpenAIModelConfig = {
@@ -70,7 +70,8 @@ export const addOpenAICofig = async ({ name, baseUrl, apiKey, provider, headers
7070
createdAt: Date.now(),
7171
db_type: "openai",
7272
provider,
73-
headers
73+
headers,
74+
fix_cors
7475
}
7576
await openaiDb.create(config)
7677
return id
@@ -83,7 +84,7 @@ export const getAllOpenAIConfig = async () => {
8384
return configs.filter(config => config?.db_type === "openai")
8485
}
8586

86-
export const updateOpenAIConfig = async ({ id, name, baseUrl, apiKey, headers }: { id: string, name: string, baseUrl: string, apiKey: string, headers?: { key: string; value: string }[] }) => {
87+
export const updateOpenAIConfig = async ({ id, name, baseUrl, apiKey, headers, fix_cors }: { id: string, name: string, baseUrl: string, apiKey: string, headers?: { key: string; value: string }[], fix_cors?: boolean }) => {
8788
const openaiDb = new OpenAIModelDb()
8889
const oldData = await openaiDb.getById(id)
8990
const config: OpenAIModelConfig = {
@@ -94,7 +95,8 @@ export const updateOpenAIConfig = async ({ id, name, baseUrl, apiKey, headers }:
9495
apiKey,
9596
createdAt: Date.now(),
9697
db_type: "openai",
97-
headers: headers || []
98+
headers: headers || [],
99+
fix_cors: fix_cors
98100
}
99101

100102
await openaiDb.update(config)

src/db/dexie/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export type OpenAIModelConfig = {
147147
createdAt: number
148148
provider?: string
149149
db_type: string
150+
fix_cors?: boolean
150151
headers?: { key: string; value: string }[]
151152
}
152153

0 commit comments

Comments
 (0)