mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-13 14:35:33 +10:00
This commit is contained in:
@@ -12,7 +12,7 @@ import pdfParserUserPrompt from "@/integrations/ai/prompts/pdf-parser-user.md?ra
|
||||
import { defaultResumeData, resumeDataSchema } from "@/schema/resume/data";
|
||||
import { protectedProcedure } from "../context";
|
||||
|
||||
const aiProviderSchema = z.enum(["vercel-ai-gateway", "openai", "anthropic", "gemini", "ollama"]);
|
||||
const aiProviderSchema = z.enum(["ollama", "openai", "gemini", "anthropic", "vercel-ai-gateway"]);
|
||||
|
||||
type AIProvider = z.infer<typeof aiProviderSchema>;
|
||||
|
||||
@@ -20,18 +20,19 @@ type GetModelInput = {
|
||||
provider: AIProvider;
|
||||
model: string;
|
||||
apiKey: string;
|
||||
baseURL?: string;
|
||||
baseURL: string;
|
||||
};
|
||||
|
||||
function getModel(input: GetModelInput) {
|
||||
const { provider, model, apiKey, baseURL } = input;
|
||||
const { provider, model, apiKey } = input;
|
||||
const baseURL = input.baseURL || undefined;
|
||||
|
||||
return match(provider)
|
||||
.with("vercel-ai-gateway", () => createGateway({ apiKey }).languageModel(model))
|
||||
.with("openai", () => createOpenAI({ apiKey }).languageModel(model))
|
||||
.with("anthropic", () => createAnthropic({ apiKey }).languageModel(model))
|
||||
.with("gemini", () => createGoogleGenerativeAI({ apiKey }).languageModel(model))
|
||||
.with("openai", () => createOpenAI({ apiKey, baseURL }).languageModel(model))
|
||||
.with("ollama", () => createOllama({ apiKey, baseURL }).languageModel(model))
|
||||
.with("anthropic", () => createAnthropic({ apiKey, baseURL }).languageModel(model))
|
||||
.with("vercel-ai-gateway", () => createGateway({ apiKey, baseURL }).languageModel(model))
|
||||
.with("gemini", () => createGoogleGenerativeAI({ apiKey, baseURL }).languageModel(model))
|
||||
.exhaustive();
|
||||
}
|
||||
|
||||
@@ -39,7 +40,7 @@ const aiCredentialsSchema = z.object({
|
||||
provider: aiProviderSchema,
|
||||
model: z.string(),
|
||||
apiKey: z.string(),
|
||||
baseURL: z.string().optional(),
|
||||
baseURL: z.string(),
|
||||
});
|
||||
|
||||
const fileInputSchema = z.object({
|
||||
@@ -54,7 +55,7 @@ export const aiRouter = {
|
||||
provider: aiProviderSchema,
|
||||
model: z.string(),
|
||||
apiKey: z.string(),
|
||||
baseURL: z.string().optional(),
|
||||
baseURL: z.string(),
|
||||
}),
|
||||
)
|
||||
.handler(async function* ({ input }) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { BrainIcon, CheckCircleIcon, InfoIcon, XCircleIcon } from "@phosphor-ico
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import { motion } from "motion/react";
|
||||
import { useMemo } from "react";
|
||||
import { useIsClient } from "usehooks-ts";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Combobox, type ComboboxOption } from "@/components/ui/combobox";
|
||||
@@ -21,17 +22,46 @@ export const Route = createFileRoute("/dashboard/settings/ai")({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
const providerOptions: ComboboxOption<AIProvider>[] = [
|
||||
{ value: "vercel-ai-gateway", label: "Vercel AI Gateway", keywords: ["vercel", "gateway", "ai"] },
|
||||
{ value: "openai", label: "OpenAI", keywords: ["openai", "gpt", "chatgpt"] },
|
||||
{ value: "gemini", label: "Google Gemini", keywords: ["gemini", "google", "bard"] },
|
||||
{ value: "anthropic", label: "Anthropic Claude", keywords: ["anthropic", "claude", "ai"] },
|
||||
{ value: "ollama", label: "Ollama", keywords: ["ollama", "ai", "local"] },
|
||||
const providerOptions: (ComboboxOption<AIProvider> & { defaultBaseURL: string })[] = [
|
||||
{
|
||||
value: "openai",
|
||||
label: "OpenAI",
|
||||
keywords: ["openai", "gpt", "chatgpt"],
|
||||
defaultBaseURL: "https://api.openai.com/v1",
|
||||
},
|
||||
{
|
||||
value: "ollama",
|
||||
label: "Ollama",
|
||||
keywords: ["ollama", "ai", "local"],
|
||||
defaultBaseURL: "http://localhost:11434",
|
||||
},
|
||||
{
|
||||
value: "anthropic",
|
||||
label: "Anthropic Claude",
|
||||
keywords: ["anthropic", "claude", "ai"],
|
||||
defaultBaseURL: "https://api.anthropic.com/v1",
|
||||
},
|
||||
{
|
||||
value: "vercel-ai-gateway",
|
||||
label: "Vercel AI Gateway",
|
||||
keywords: ["vercel", "gateway", "ai"],
|
||||
defaultBaseURL: "https://ai-gateway.vercel.sh/v1/ai",
|
||||
},
|
||||
{
|
||||
value: "gemini",
|
||||
label: "Google Gemini",
|
||||
keywords: ["gemini", "google", "bard"],
|
||||
defaultBaseURL: "https://generativelanguage.googleapis.com/v1beta",
|
||||
},
|
||||
];
|
||||
|
||||
function AIForm() {
|
||||
const { set, model, apiKey, baseURL, provider, enabled, testStatus } = useAIStore();
|
||||
|
||||
const selectedOption = useMemo(() => {
|
||||
return providerOptions.find((option) => option.value === provider);
|
||||
}, [provider]);
|
||||
|
||||
const { mutate: testConnection, isPending: isTesting } = useMutation({
|
||||
mutationFn: async () => {
|
||||
if (testStatus === "success") return;
|
||||
@@ -113,21 +143,19 @@ function AIForm() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{provider === "ollama" && (
|
||||
<div className="flex flex-col gap-y-2 sm:col-span-2">
|
||||
<Label htmlFor="base-url">
|
||||
<Trans>Base URL (Optional)</Trans>
|
||||
</Label>
|
||||
<Input
|
||||
id="base-url"
|
||||
type="url"
|
||||
value={baseURL}
|
||||
disabled={enabled}
|
||||
placeholder="http://localhost:11434"
|
||||
onChange={(e) => handleBaseURLChange(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col gap-y-2 sm:col-span-2">
|
||||
<Label htmlFor="base-url">
|
||||
<Trans>Base URL (Optional)</Trans>
|
||||
</Label>
|
||||
<Input
|
||||
id="base-url"
|
||||
type="url"
|
||||
value={baseURL}
|
||||
disabled={enabled}
|
||||
placeholder={selectedOption?.defaultBaseURL}
|
||||
onChange={(e) => handleBaseURLChange(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Button variant="outline" disabled={isTesting || enabled} onClick={() => testConnection()}>
|
||||
|
||||
Reference in New Issue
Block a user