refactor api keys logic
This commit is contained in:
parent
d1c95d0ee3
commit
07ec0ade92
10 changed files with 69 additions and 58 deletions
|
|
@ -3,7 +3,8 @@ import type { Handle } from '@sveltejs/kit';
|
|||
import { svelteKitHandler } from 'better-auth/svelte-kit';
|
||||
|
||||
export const handle: Handle = async ({ event, resolve }) => {
|
||||
event.locals.auth = () => auth.api.getSession({ headers: event.request.headers });
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
event.locals.auth = () => auth.api.getSession({ headers: event.request.headers }) as any;
|
||||
|
||||
return svelteKitHandler({ event, resolve, auth });
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@ export const auth = betterAuth({
|
|||
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
||||
},
|
||||
},
|
||||
databaseHooks: {
|
||||
user: {
|
||||
create: {
|
||||
after: async ({ user }) => {
|
||||
// TODO: automatically enable default models for the user
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// databaseHooks: {
|
||||
// user: {
|
||||
// create: {
|
||||
// after: async ({ user }) => {
|
||||
// // TODO: automatically enable default models for the user
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
plugins: [],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Provider } from '../../types';
|
|||
import { mutation, query } from './_generated/server';
|
||||
import { providerValidator } from './schema';
|
||||
|
||||
export const get = query({
|
||||
export const all = query({
|
||||
args: {
|
||||
user_id: v.string(),
|
||||
},
|
||||
|
|
@ -23,6 +23,23 @@ export const get = query({
|
|||
},
|
||||
});
|
||||
|
||||
export const get = query({
|
||||
args: {
|
||||
user_id: v.string(),
|
||||
provider: providerValidator,
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
const key = await ctx.db
|
||||
.query('user_keys')
|
||||
.withIndex('by_provider_user', (q) =>
|
||||
q.eq('provider', args.provider).eq('user_id', args.user_id)
|
||||
)
|
||||
.first();
|
||||
|
||||
return key?.key;
|
||||
},
|
||||
});
|
||||
|
||||
export const set = mutation({
|
||||
args: {
|
||||
provider: providerValidator,
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export function getOpenRouterModels() {
|
|||
(async () => {
|
||||
const res = await fetch('https://openrouter.ai/api/v1/models');
|
||||
|
||||
const { data } = await res.json()
|
||||
const { data } = await res.json();
|
||||
|
||||
return data as OpenRouterModel[];
|
||||
})(),
|
||||
|
|
|
|||
|
|
@ -6,3 +6,11 @@ export const Provider = {
|
|||
} as const;
|
||||
|
||||
export type Provider = (typeof Provider)[keyof typeof Provider];
|
||||
|
||||
export type ProviderMeta = {
|
||||
title: string;
|
||||
link: string;
|
||||
description: string;
|
||||
models?: string[];
|
||||
placeholder?: string;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-8 pl-12 md:col-start-2">
|
||||
<div class="pl-12 md:col-start-2">
|
||||
<div
|
||||
class="bg-card text-muted-foreground flex w-fit place-items-center gap-2 rounded-lg p-1 text-sm"
|
||||
>
|
||||
|
|
@ -80,7 +80,9 @@
|
|||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
{@render children?.()}
|
||||
<div class="pt-8">
|
||||
{@render children?.()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { Provider } from '$lib/types';
|
||||
import { Provider, type ProviderMeta } from '$lib/types';
|
||||
import { useQuery } from 'convex-svelte';
|
||||
import { api } from '$lib/backend/convex/_generated/api';
|
||||
import { session } from '$lib/state/session.svelte.js';
|
||||
|
|
@ -7,14 +7,6 @@
|
|||
|
||||
const allProviders = Object.values(Provider);
|
||||
|
||||
type ProviderMeta = {
|
||||
title: string;
|
||||
link: string;
|
||||
description: string;
|
||||
models?: string[];
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
const providersMeta: Record<Provider, ProviderMeta> = {
|
||||
[Provider.OpenRouter]: {
|
||||
title: 'OpenRouter',
|
||||
|
|
@ -51,8 +43,6 @@
|
|||
placeholder: 'sk-ant-...',
|
||||
},
|
||||
};
|
||||
|
||||
const keys = useQuery(api.user_keys.get, { user_id: session.current?.user.id ?? '' });
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
|
@ -67,9 +57,9 @@
|
|||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 flex flex-col gap-8">
|
||||
<div class="mt-8 flex flex-col gap-4">
|
||||
{#each allProviders as provider (provider)}
|
||||
{@const meta = providersMeta[provider]}
|
||||
<ProviderCard {provider} {meta} key={(async () => await keys.data?.[provider])()} />
|
||||
<ProviderCard {provider} {meta} />
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,26 +4,22 @@
|
|||
import { Input } from '$lib/components/ui/input';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { Link } from '$lib/components/ui/link';
|
||||
import { useConvexClient } from 'convex-svelte';
|
||||
import { useConvexClient, useQuery } from 'convex-svelte';
|
||||
import { api } from '$lib/backend/convex/_generated/api';
|
||||
import { session } from '$lib/state/session.svelte.js';
|
||||
import type { Provider } from '$lib/types';
|
||||
|
||||
type ProviderMeta = {
|
||||
title: string;
|
||||
link: string;
|
||||
description: string;
|
||||
models?: string[];
|
||||
placeholder?: string;
|
||||
};
|
||||
import type { Provider, ProviderMeta } from '$lib/types';
|
||||
|
||||
type Props = {
|
||||
provider: Provider;
|
||||
meta: ProviderMeta;
|
||||
key: Promise<string>;
|
||||
};
|
||||
|
||||
let { provider, meta, key: keyPromise }: Props = $props();
|
||||
let { provider, meta }: Props = $props();
|
||||
|
||||
const keyQuery = useQuery(api.user_keys.get, {
|
||||
user_id: session.current?.user.id ?? '',
|
||||
provider,
|
||||
});
|
||||
|
||||
const client = useConvexClient();
|
||||
|
||||
|
|
@ -44,9 +40,8 @@
|
|||
user_id: session.current?.user.id ?? '',
|
||||
key: `${key}`,
|
||||
});
|
||||
|
||||
// TODO: Setup toast notifications
|
||||
} catch {
|
||||
// TODO: Setup toast notifications
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
@ -63,17 +58,17 @@
|
|||
</Card.Header>
|
||||
<Card.Content tag="form" onsubmit={submit}>
|
||||
<div class="flex flex-col gap-1">
|
||||
{#await keyPromise}
|
||||
{#if keyQuery.isLoading}
|
||||
<div class="bg-input h-9 animate-pulse rounded-md"></div>
|
||||
{:then key}
|
||||
{:else}
|
||||
<Input
|
||||
type="password"
|
||||
placeholder={meta.placeholder ?? ''}
|
||||
autocomplete="off"
|
||||
name="key"
|
||||
value={key}
|
||||
value={keyQuery.data!}
|
||||
/>
|
||||
{/await}
|
||||
{/if}
|
||||
<span class="text-muted-foreground text-xs">
|
||||
Get your API key from
|
||||
<Link href={meta.link} target="_blank" class="text-blue-500">
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import { getOpenRouterModels, type OpenRouterModel } from '$lib/backend/models/open-router';
|
||||
|
||||
export async function load() {
|
||||
const [openRouterModels] = await Promise.all([getOpenRouterModels()]);
|
||||
|
||||
return {
|
||||
openRouterModels: openRouterModels.unwrapOr([] as OpenRouterModel[]),
|
||||
openRouterModels: (await getOpenRouterModels()).unwrapOr([] as OpenRouterModel[]),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@
|
|||
<title>Models | Thom.chat</title>
|
||||
</svelte:head>
|
||||
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold">Available Models</h1>
|
||||
<h2 class="text-muted-foreground mt-2 text-sm">
|
||||
Choose which models appear in your model selector. This won't affect existing conversations.
|
||||
</h2>
|
||||
</div>
|
||||
<h1 class="text-2xl font-bold">Available Models</h1>
|
||||
<h2 class="text-muted-foreground mt-2 text-sm">
|
||||
Choose which models appear in your model selector. This won't affect existing conversations.
|
||||
</h2>
|
||||
|
||||
{#each data.openRouterModels as model}
|
||||
{@const enabled = enabledModels.data?.[`${Provider.OpenRouter}:${model.id}`] !== undefined}
|
||||
<Model provider={Provider.OpenRouter} {model} {enabled} />
|
||||
{/each}
|
||||
<div class="mt-8 flex flex-col gap-4">
|
||||
{#each data.openRouterModels as model (model.id)}
|
||||
{@const enabled = enabledModels.data?.[`${Provider.OpenRouter}:${model.id}`] !== undefined}
|
||||
<Model provider={Provider.OpenRouter} {model} {enabled} />
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue