feat: Add OpenAI provider support
This commit is contained in:
parent
acce9b97f6
commit
f1e40d5908
@ -1,5 +1,11 @@
|
|||||||
import { ChromeIcon, CpuIcon } from "lucide-react"
|
import { ChromeIcon, CpuIcon } from "lucide-react"
|
||||||
import { OllamaIcon } from "../Icons/Ollama"
|
import { OllamaIcon } from "../Icons/Ollama"
|
||||||
|
import { FireworksMonoIcon } from "../Icons/Fireworks"
|
||||||
|
import { GroqMonoIcon } from "../Icons/Groq"
|
||||||
|
import { LMStudioIcon } from "../Icons/LMStudio"
|
||||||
|
import { OpenAiIcon } from "../Icons/OpenAI"
|
||||||
|
import { TogtherMonoIcon } from "../Icons/Togther"
|
||||||
|
import { OpenRouterIcon } from "../Icons/OpenRouter"
|
||||||
|
|
||||||
export const ProviderIcons = ({
|
export const ProviderIcons = ({
|
||||||
provider,
|
provider,
|
||||||
@ -13,6 +19,18 @@ export const ProviderIcons = ({
|
|||||||
return <ChromeIcon className={className} />
|
return <ChromeIcon className={className} />
|
||||||
case "custom":
|
case "custom":
|
||||||
return <CpuIcon className={className} />
|
return <CpuIcon className={className} />
|
||||||
|
case "fireworks":
|
||||||
|
return <FireworksMonoIcon className={className} />
|
||||||
|
case "groq":
|
||||||
|
return <GroqMonoIcon className={className} />
|
||||||
|
case "lmstudio":
|
||||||
|
return <LMStudioIcon className={className} />
|
||||||
|
case "openai":
|
||||||
|
return <OpenAiIcon className={className} />
|
||||||
|
case "together":
|
||||||
|
return <TogtherMonoIcon className={className} />
|
||||||
|
case "openrouter":
|
||||||
|
return <OpenRouterIcon className={className} />
|
||||||
default:
|
default:
|
||||||
return <OllamaIcon className={className} />
|
return <OllamaIcon className={className} />
|
||||||
}
|
}
|
||||||
|
19
src/components/Icons/Fireworks.tsx
Normal file
19
src/components/Icons/Fireworks.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import React from "react"
|
||||||
|
|
||||||
|
export const FireworksMonoIcon = React.forwardRef<
|
||||||
|
SVGSVGElement,
|
||||||
|
React.SVGProps<SVGSVGElement>
|
||||||
|
>((props, ref) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 638 315"
|
||||||
|
ref={ref}
|
||||||
|
{...props}>
|
||||||
|
<path
|
||||||
|
fill="#fff"
|
||||||
|
d="M318.563 221.755c-17.7 0-33.584-10.508-40.357-26.777L196.549 0h47.793l74.5 178.361L393.273 0h47.793L358.92 195.048c-6.808 16.199-22.657 26.707-40.357 26.707zM425.111 314.933c-17.63 0-33.444-10.439-40.287-26.567-6.877-16.269-3.317-34.842 9.112-47.445l148.721-150.64 18.572 43.813-136.153 137.654 194.071-1.082 18.573 43.813-212.574.524-.07-.07h.035zM0 314.408l18.573-43.813 194.07 1.082L76.525 133.988l18.573-43.813 148.721 150.641c12.428 12.568 16.024 31.21 9.111 47.444-6.842 16.164-22.727 26.567-40.287 26.567L.07 314.339l-.07.069z"></path>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
})
|
18
src/components/Icons/Groq.tsx
Normal file
18
src/components/Icons/Groq.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import React from "react"
|
||||||
|
|
||||||
|
export const GroqMonoIcon = React.forwardRef<
|
||||||
|
SVGSVGElement,
|
||||||
|
React.SVGProps<SVGSVGElement>
|
||||||
|
>((props, ref) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
fill="currentColor"
|
||||||
|
fillRule="evenodd"
|
||||||
|
ref={ref}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}>
|
||||||
|
<path d="M12.036 2c-3.853-.035-7 3-7.036 6.781-.035 3.782 3.055 6.872 6.908 6.907h2.42v-2.566h-2.292c-2.407.028-4.38-1.866-4.408-4.23-.029-2.362 1.901-4.298 4.308-4.326h.1c2.407 0 4.358 1.915 4.365 4.278v6.305c0 2.342-1.944 4.25-4.323 4.279a4.375 4.375 0 01-3.033-1.252l-1.851 1.818A7 7 0 0012.029 22h.092c3.803-.056 6.858-3.083 6.879-6.816v-6.5C18.907 4.963 15.817 2 12.036 2z"></path>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
})
|
33
src/components/Icons/LMStudio.tsx
Normal file
33
src/components/Icons/LMStudio.tsx
Normal file
File diff suppressed because one or more lines are too long
18
src/components/Icons/OpenAI.tsx
Normal file
18
src/components/Icons/OpenAI.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import React from "react"
|
||||||
|
|
||||||
|
export const OpenAiIcon = React.forwardRef<
|
||||||
|
SVGSVGElement,
|
||||||
|
React.SVGProps<SVGSVGElement>
|
||||||
|
>((props, ref) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
fill="currentColor"
|
||||||
|
fillRule="evenodd"
|
||||||
|
ref={ref}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}>
|
||||||
|
<path d="M21.55 10.004a5.416 5.416 0 00-.478-4.501c-1.217-2.09-3.662-3.166-6.05-2.66A5.59 5.59 0 0010.831 1C8.39.995 6.224 2.546 5.473 4.838A5.553 5.553 0 001.76 7.496a5.487 5.487 0 00.691 6.5 5.416 5.416 0 00.477 4.502c1.217 2.09 3.662 3.165 6.05 2.66A5.586 5.586 0 0013.168 23c2.443.006 4.61-1.546 5.361-3.84a5.553 5.553 0 003.715-2.66 5.488 5.488 0 00-.693-6.497v.001zm-8.381 11.558a4.199 4.199 0 01-2.675-.954c.034-.018.093-.05.132-.074l4.44-2.53a.71.71 0 00.364-.623v-6.176l1.877 1.069c.02.01.033.029.036.05v5.115c-.003 2.274-1.87 4.118-4.174 4.123zM4.192 17.78a4.059 4.059 0 01-.498-2.763c.032.02.09.055.131.078l4.44 2.53c.225.13.504.13.73 0l5.42-3.088v2.138a.068.068 0 01-.027.057L9.9 19.288c-1.999 1.136-4.552.46-5.707-1.51h-.001zM3.023 8.216A4.15 4.15 0 015.198 6.41l-.002.151v5.06a.711.711 0 00.364.624l5.42 3.087-1.876 1.07a.067.067 0 01-.063.005l-4.489-2.559c-1.995-1.14-2.679-3.658-1.53-5.63h.001zm15.417 3.54l-5.42-3.088L14.896 7.6a.067.067 0 01.063-.006l4.489 2.557c1.998 1.14 2.683 3.662 1.529 5.633a4.163 4.163 0 01-2.174 1.807V12.38a.71.71 0 00-.363-.623zm1.867-2.773a6.04 6.04 0 00-.132-.078l-4.44-2.53a.731.731 0 00-.729 0l-5.42 3.088V7.325a.068.068 0 01.027-.057L14.1 4.713c2-1.137 4.555-.46 5.707 1.513.487.833.664 1.809.499 2.757h.001zm-11.741 3.81l-1.877-1.068a.065.065 0 01-.036-.051V6.559c.001-2.277 1.873-4.122 4.181-4.12.976 0 1.92.338 2.671.954-.034.018-.092.05-.131.073l-4.44 2.53a.71.71 0 00-.365.623l-.003 6.173v.002zm1.02-2.168L12 9.25l2.414 1.375v2.75L12 14.75l-2.415-1.375v-2.75z"></path>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
})
|
18
src/components/Icons/OpenRouter.tsx
Normal file
18
src/components/Icons/OpenRouter.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import React from "react"
|
||||||
|
|
||||||
|
export const OpenRouterIcon = React.forwardRef<
|
||||||
|
SVGSVGElement,
|
||||||
|
React.SVGProps<SVGSVGElement>
|
||||||
|
>((props, ref) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
fill="currentColor"
|
||||||
|
fillRule="evenodd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
ref={ref}
|
||||||
|
{...props}>
|
||||||
|
<path d="M16.804 1.957l7.22 4.105v.087L16.73 10.21l.017-2.117-.821-.03c-1.059-.028-1.611.002-2.268.11-1.064.175-2.038.577-3.147 1.352L8.345 11.03c-.284.195-.495.336-.68.455l-.515.322-.397.234.385.23.53.338c.476.314 1.17.796 2.701 1.866 1.11.775 2.083 1.177 3.147 1.352l.3.045c.694.091 1.375.094 2.825.033l.022-2.159 7.22 4.105v.087L16.589 22l.014-1.862-.635.022c-1.386.042-2.137.002-3.138-.162-1.694-.28-3.26-.926-4.881-2.059l-2.158-1.5a21.997 21.997 0 00-.755-.498l-.467-.28a55.927 55.927 0 00-.76-.43C2.908 14.73.563 14.116 0 14.116V9.888l.14.004c.564-.007 2.91-.622 3.809-1.124l1.016-.58.438-.274c.428-.28 1.072-.726 2.686-1.853 1.621-1.133 3.186-1.78 4.881-2.059 1.152-.19 1.974-.213 3.814-.138l.02-1.907z"></path>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
})
|
23
src/components/Icons/Togther.tsx
Normal file
23
src/components/Icons/Togther.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import React from "react"
|
||||||
|
|
||||||
|
export const TogtherMonoIcon = React.forwardRef<
|
||||||
|
SVGSVGElement,
|
||||||
|
React.SVGProps<SVGSVGElement>
|
||||||
|
>((props, ref) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
fill="currentColor"
|
||||||
|
fillRule="evenodd"
|
||||||
|
ref={ref}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}>
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
d="M17.385 11.23a4.615 4.615 0 100-9.23 4.615 4.615 0 000 9.23zm0 10.77a4.615 4.615 0 100-9.23 4.615 4.615 0 000 9.23zm-10.77 0a4.615 4.615 0 100-9.23 4.615 4.615 0 000 9.23z"
|
||||||
|
opacity=".2"></path>
|
||||||
|
<circle cx="6.615" cy="6.615" r="4.615"></circle>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
})
|
@ -8,7 +8,7 @@ import {
|
|||||||
updateOpenAIConfig
|
updateOpenAIConfig
|
||||||
} from "@/db/openai"
|
} from "@/db/openai"
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
|
||||||
import { Pencil, Trash2, RotateCwIcon } from "lucide-react"
|
import { Pencil, Trash2, RotateCwIcon, DownloadIcon } from "lucide-react"
|
||||||
import { OpenAIFetchModel } from "./openai-fetch-model"
|
import { OpenAIFetchModel } from "./openai-fetch-model"
|
||||||
import { OAI_API_PROVIDERS } from "@/utils/oai-api-providers"
|
import { OAI_API_PROVIDERS } from "@/utils/oai-api-providers"
|
||||||
|
|
||||||
@ -20,6 +20,7 @@ export const OpenAIApp = () => {
|
|||||||
const [form] = Form.useForm()
|
const [form] = Form.useForm()
|
||||||
const [openaiId, setOpenaiId] = useState<string | null>(null)
|
const [openaiId, setOpenaiId] = useState<string | null>(null)
|
||||||
const [openModelModal, setOpenModelModal] = useState(false)
|
const [openModelModal, setOpenModelModal] = useState(false)
|
||||||
|
const [provider, setProvider] = useState("custom")
|
||||||
|
|
||||||
const { data: configs, isLoading } = useQuery({
|
const { data: configs, isLoading } = useQuery({
|
||||||
queryKey: ["openAIConfigs"],
|
queryKey: ["openAIConfigs"],
|
||||||
@ -69,8 +70,13 @@ export const OpenAIApp = () => {
|
|||||||
if (editingConfig) {
|
if (editingConfig) {
|
||||||
updateMutation.mutate({ id: editingConfig.id, ...values })
|
updateMutation.mutate({ id: editingConfig.id, ...values })
|
||||||
} else {
|
} else {
|
||||||
addMutation.mutate(values)
|
addMutation.mutate({
|
||||||
|
...values,
|
||||||
|
provider
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setProvider("custom")
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEdit = (record: any) => {
|
const handleEdit = (record: any) => {
|
||||||
@ -144,7 +150,7 @@ export const OpenAIApp = () => {
|
|||||||
setOpenaiId(record.id)
|
setOpenaiId(record.id)
|
||||||
}}
|
}}
|
||||||
disabled={!record.id}>
|
disabled={!record.id}>
|
||||||
<RotateCwIcon className="size-4" />
|
<DownloadIcon className="size-4" />
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={t("delete")}>
|
<Tooltip title={t("delete")}>
|
||||||
@ -180,18 +186,20 @@ export const OpenAIApp = () => {
|
|||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
setEditingConfig(null)
|
setEditingConfig(null)
|
||||||
|
setProvider("custom")
|
||||||
form.resetFields()
|
form.resetFields()
|
||||||
}}
|
}}
|
||||||
footer={null}>
|
footer={null}>
|
||||||
{!editingConfig && (
|
{!editingConfig && (
|
||||||
<Select
|
<Select
|
||||||
defaultValue="custom"
|
value={provider}
|
||||||
onSelect={(e) => {
|
onSelect={(e) => {
|
||||||
const value = OAI_API_PROVIDERS.find((item) => item.value === e)
|
const value = OAI_API_PROVIDERS.find((item) => item.value === e)
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
baseUrl: value?.baseUrl,
|
baseUrl: value?.baseUrl,
|
||||||
name: value?.label
|
name: value?.label
|
||||||
})
|
})
|
||||||
|
setProvider(e)
|
||||||
}}
|
}}
|
||||||
className="w-full !mb-4"
|
className="w-full !mb-4"
|
||||||
options={OAI_API_PROVIDERS}
|
options={OAI_API_PROVIDERS}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import { getOpenAIConfigById as providerInfo } from "./openai"
|
import {
|
||||||
|
getAllOpenAIConfig,
|
||||||
|
getOpenAIConfigById as providerInfo
|
||||||
|
} from "./openai"
|
||||||
|
|
||||||
type Model = {
|
type Model = {
|
||||||
id: string
|
id: string
|
||||||
@ -16,11 +19,15 @@ export const generateID = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const removeModelSuffix = (id: string) => {
|
export const removeModelSuffix = (id: string) => {
|
||||||
return id.replace(/_model-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{3,4}-[a-f0-9]{4}/, "")
|
return id.replace(
|
||||||
|
/_model-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{3,4}-[a-f0-9]{4}/,
|
||||||
|
""
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isCustomModel = (model: string) => {
|
export const isCustomModel = (model: string) => {
|
||||||
const customModelRegex = /_model-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{3,4}-[a-f0-9]{4}/
|
const customModelRegex =
|
||||||
|
/_model-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{3,4}-[a-f0-9]{4}/
|
||||||
return customModelRegex.test(model)
|
return customModelRegex.test(model)
|
||||||
}
|
}
|
||||||
export class ModelDb {
|
export class ModelDb {
|
||||||
@ -174,6 +181,17 @@ export const deleteModel = async (id: string) => {
|
|||||||
await db.delete(id)
|
await db.delete(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const deleteAllModelsByProviderId = async (provider_id: string) => {
|
||||||
|
const db = new ModelDb()
|
||||||
|
const models = await db.getAll()
|
||||||
|
const modelsToDelete = models.filter(
|
||||||
|
(model) => model.provider_id === provider_id
|
||||||
|
)
|
||||||
|
for (const model of modelsToDelete) {
|
||||||
|
await db.delete(model.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const isLookupExist = async (lookup: string) => {
|
export const isLookupExist = async (lookup: string) => {
|
||||||
const db = new ModelDb()
|
const db = new ModelDb()
|
||||||
const models = await db.getAll()
|
const models = await db.getAll()
|
||||||
@ -181,17 +199,19 @@ export const isLookupExist = async (lookup: string) => {
|
|||||||
return model ? true : false
|
return model ? true : false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const ollamaFormatAllCustomModels = async () => {
|
export const ollamaFormatAllCustomModels = async () => {
|
||||||
|
|
||||||
const allModles = await getAllCustomModels()
|
const allModles = await getAllCustomModels()
|
||||||
|
|
||||||
|
const allProviders = await getAllOpenAIConfig()
|
||||||
|
|
||||||
const ollamaModels = allModles.map((model) => {
|
const ollamaModels = allModles.map((model) => {
|
||||||
return {
|
return {
|
||||||
name: model.name,
|
name: model.name,
|
||||||
model: model.id,
|
model: model.id,
|
||||||
modified_at: "",
|
modified_at: "",
|
||||||
provider: "custom",
|
provider:
|
||||||
|
allProviders.find((provider) => provider.id === model.provider_id)
|
||||||
|
?.provider || "custom",
|
||||||
size: 0,
|
size: 0,
|
||||||
digest: "",
|
digest: "",
|
||||||
details: {
|
details: {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { cleanUrl } from "@/libs/clean-url"
|
import { cleanUrl } from "@/libs/clean-url"
|
||||||
|
import { deleteAllModelsByProviderId } from "./models"
|
||||||
|
|
||||||
type OpenAIModelConfig = {
|
type OpenAIModelConfig = {
|
||||||
id: string
|
id: string
|
||||||
@ -93,7 +94,7 @@ export class OpenAIModelDb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const addOpenAICofig = async ({ name, baseUrl, apiKey }: { name: string, baseUrl: string, apiKey: string }) => {
|
export const addOpenAICofig = async ({ name, baseUrl, apiKey, provider }: { name: string, baseUrl: string, apiKey: string, provider?: string }) => {
|
||||||
const openaiDb = new OpenAIModelDb()
|
const openaiDb = new OpenAIModelDb()
|
||||||
const id = generateID()
|
const id = generateID()
|
||||||
const config: OpenAIModelConfig = {
|
const config: OpenAIModelConfig = {
|
||||||
@ -102,7 +103,8 @@ export const addOpenAICofig = async ({ name, baseUrl, apiKey }: { name: string,
|
|||||||
baseUrl: cleanUrl(baseUrl),
|
baseUrl: cleanUrl(baseUrl),
|
||||||
apiKey,
|
apiKey,
|
||||||
createdAt: Date.now(),
|
createdAt: Date.now(),
|
||||||
db_type: "openai"
|
db_type: "openai",
|
||||||
|
provider
|
||||||
}
|
}
|
||||||
await openaiDb.create(config)
|
await openaiDb.create(config)
|
||||||
return id
|
return id
|
||||||
@ -117,13 +119,15 @@ export const getAllOpenAIConfig = async () => {
|
|||||||
|
|
||||||
export const updateOpenAIConfig = async ({ id, name, baseUrl, apiKey }: { id: string, name: string, baseUrl: string, apiKey: string }) => {
|
export const updateOpenAIConfig = async ({ id, name, baseUrl, apiKey }: { id: string, name: string, baseUrl: string, apiKey: string }) => {
|
||||||
const openaiDb = new OpenAIModelDb()
|
const openaiDb = new OpenAIModelDb()
|
||||||
|
const oldData = await openaiDb.getById(id)
|
||||||
const config: OpenAIModelConfig = {
|
const config: OpenAIModelConfig = {
|
||||||
|
...oldData,
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
baseUrl: cleanUrl(baseUrl),
|
baseUrl: cleanUrl(baseUrl),
|
||||||
apiKey,
|
apiKey,
|
||||||
createdAt: Date.now(),
|
createdAt: Date.now(),
|
||||||
db_type: "openai"
|
db_type: "openai",
|
||||||
}
|
}
|
||||||
|
|
||||||
await openaiDb.update(config)
|
await openaiDb.update(config)
|
||||||
@ -135,6 +139,7 @@ export const updateOpenAIConfig = async ({ id, name, baseUrl, apiKey }: { id: st
|
|||||||
export const deleteOpenAIConfig = async (id: string) => {
|
export const deleteOpenAIConfig = async (id: string) => {
|
||||||
const openaiDb = new OpenAIModelDb()
|
const openaiDb = new OpenAIModelDb()
|
||||||
await openaiDb.delete(id)
|
await openaiDb.delete(id)
|
||||||
|
await deleteAllModelsByProviderId(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
type Model = {
|
type Model = {
|
||||||
id: string
|
id: string
|
||||||
name?: string
|
name?: string
|
||||||
|
display_name?: string
|
||||||
|
type: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getAllOpenAIModels = async (baseUrl: string, apiKey?: string) => {
|
export const getAllOpenAIModels = async (baseUrl: string, apiKey?: string) => {
|
||||||
|
try {
|
||||||
const url = `${baseUrl}/models`
|
const url = `${baseUrl}/models`
|
||||||
const headers = apiKey
|
const headers = apiKey
|
||||||
? {
|
? {
|
||||||
@ -19,7 +22,19 @@ export const getAllOpenAIModels = async (baseUrl: string, apiKey?: string) => {
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (baseUrl === "https://api.together.xyz/v1") {
|
||||||
|
const data = (await res.json()) as Model[]
|
||||||
|
return data.map(model => ({
|
||||||
|
id: model.id,
|
||||||
|
name: model.display_name,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
const data = (await res.json()) as { data: Model[] }
|
const data = (await res.json()) as { data: Model[] }
|
||||||
|
|
||||||
return data.data
|
return data.data
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
return []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,11 @@ export const OAI_API_PROVIDERS = [
|
|||||||
value: "together",
|
value: "together",
|
||||||
baseUrl: "https://api.together.xyz/v1"
|
baseUrl: "https://api.together.xyz/v1"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "OpenRouter",
|
||||||
|
value: "openrouter",
|
||||||
|
baseUrl: "https://openrouter.ai/api/v1"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "Custsom",
|
label: "Custsom",
|
||||||
value: "custom",
|
value: "custom",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user