* feat: add custom OpenAI provider * chore: add HF token setting * chore: move HF token setting to llama.cpp provider - later deprecate model extension
151 lines
5.0 KiB
TypeScript
151 lines
5.0 KiB
TypeScript
import { route } from '@/constants/routes'
|
|
import { useModelProvider } from '@/hooks/useModelProvider'
|
|
import { cn, getProviderLogo, getProviderTitle } from '@/lib/utils'
|
|
import { useNavigate, useMatches, Link } from '@tanstack/react-router'
|
|
import { IconArrowLeft, IconCirclePlus } from '@tabler/icons-react'
|
|
import {
|
|
Dialog,
|
|
DialogClose,
|
|
DialogContent,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogTrigger,
|
|
} from '@/components/ui/dialog'
|
|
import { Input } from '@/components/ui/input'
|
|
import { Button } from '@/components/ui/button'
|
|
import { useCallback, useState } from 'react'
|
|
import { openAIProviderSettings } from '@/mock/data'
|
|
|
|
const ProvidersMenu = ({
|
|
stepSetupRemoteProvider,
|
|
}: {
|
|
stepSetupRemoteProvider: boolean
|
|
}) => {
|
|
const { providers, addProvider } = useModelProvider()
|
|
const navigate = useNavigate()
|
|
const matches = useMatches()
|
|
const [name, setName] = useState('')
|
|
const createProvider = useCallback(() => {
|
|
addProvider({
|
|
provider: name,
|
|
active: true,
|
|
models: [],
|
|
settings: openAIProviderSettings as ProviderSetting[],
|
|
api_key: '',
|
|
base_url: 'https://api.openai.com/v1',
|
|
})
|
|
setTimeout(() => {
|
|
navigate({
|
|
to: route.settings.providers,
|
|
params: {
|
|
providerName: name,
|
|
},
|
|
})
|
|
}, 0)
|
|
}, [name, addProvider, navigate])
|
|
|
|
return (
|
|
<div className="w-44 py-2 border-r border-main-view-fg/5 pb-10 overflow-y-auto">
|
|
<Link to={route.settings.general}>
|
|
<div className="flex items-center gap-0.5 ml-3 mb-4 mt-1">
|
|
<IconArrowLeft size={16} className="text-main-view-fg/70" />
|
|
<span className="text-main-view-fg/80">Back</span>
|
|
</div>
|
|
</Link>
|
|
<div className="first-step-setup-remote-provider">
|
|
{providers.map((provider, index) => {
|
|
const isActive = matches.some(
|
|
(match) =>
|
|
match.routeId === '/settings/providers/$providerName' &&
|
|
'providerName' in match.params &&
|
|
match.params.providerName === provider.provider
|
|
)
|
|
|
|
return (
|
|
<div key={index} className="flex flex-col px-2 my-1.5 ">
|
|
<div
|
|
className={cn(
|
|
'flex px-2 items-center gap-1.5 cursor-pointer hover:bg-main-view-fg/5 py-1 w-full rounded [&.active]:bg-main-view-fg/5 text-main-view-fg/80',
|
|
isActive && 'bg-main-view-fg/5',
|
|
// hidden for llama.cpp provider for setup remote provider
|
|
provider.provider === 'llama.cpp' &&
|
|
stepSetupRemoteProvider &&
|
|
'hidden'
|
|
)}
|
|
onClick={() =>
|
|
navigate({
|
|
to: route.settings.providers,
|
|
params: {
|
|
providerName: provider.provider,
|
|
},
|
|
...(stepSetupRemoteProvider
|
|
? { search: { step: 'setup_remote_provider' } }
|
|
: {}),
|
|
})
|
|
}
|
|
>
|
|
<img
|
|
src={getProviderLogo(provider.provider)}
|
|
alt={`${provider.provider} - Logo`}
|
|
className="size-4"
|
|
/>
|
|
<span className="capitalize">
|
|
{getProviderTitle(provider.provider)}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
)
|
|
})}
|
|
|
|
<Dialog>
|
|
<DialogTrigger asChild>
|
|
<div
|
|
className="bg-main-view flex cursor-pointer px-4 my-1.5 items-center gap-1.5 text-main-view-fg/80"
|
|
onClick={() => {}}
|
|
>
|
|
<IconCirclePlus size={16} />
|
|
<span className="capitalize">
|
|
Add Provider
|
|
</span>
|
|
</div>
|
|
</DialogTrigger>
|
|
<DialogContent>
|
|
<DialogHeader>
|
|
<DialogTitle>Add OpenAI Provider</DialogTitle>
|
|
<Input
|
|
value={name}
|
|
onChange={(e) => setName(e.target.value)}
|
|
className="mt-2"
|
|
placeholder="Enter a name for your provider"
|
|
onKeyDown={(e) => {
|
|
// Prevent key from being captured by parent components
|
|
e.stopPropagation()
|
|
}}
|
|
/>
|
|
<DialogFooter className="mt-2 flex items-center">
|
|
<DialogClose asChild>
|
|
<Button
|
|
variant="link"
|
|
size="sm"
|
|
className="hover:no-underline"
|
|
>
|
|
Cancel
|
|
</Button>
|
|
</DialogClose>
|
|
<DialogClose asChild>
|
|
<Button disabled={!name} onClick={createProvider}>
|
|
Create
|
|
</Button>
|
|
</DialogClose>
|
|
</DialogFooter>
|
|
</DialogHeader>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default ProvidersMenu
|