Merge branch 'model-list' into dialog
This commit is contained in:
commit
9bc1b3766c
10 changed files with 69 additions and 35 deletions
|
|
@ -72,7 +72,7 @@
|
|||
--muted-foreground: oklch(0.794 0.0372 307.1032);
|
||||
--accent: oklch(0.3649 0.0508 308.4911);
|
||||
--accent-foreground: oklch(0.9647 0.0091 341.8035);
|
||||
--destructive: oklch(0.2258 0.0524 12.6119);
|
||||
--destructive: oklch(0.5248 0.1368 20.8317);
|
||||
--destructive-foreground: oklch(1 0 0);
|
||||
--border: oklch(0.3286 0.0154 343.4461);
|
||||
--input: oklch(0.3387 0.0195 332.8347);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import * as array from '../../utils/array';
|
|||
import * as object from '../../utils/object';
|
||||
import { internal } from './_generated/api';
|
||||
import { Provider } from '../../types';
|
||||
import type { Doc } from './_generated/dataModel';
|
||||
|
||||
export const getModelKey = (args: { provider: Provider; model_id: string }) => {
|
||||
return `${args.provider}:${args.model_id}`;
|
||||
|
|
@ -12,12 +13,18 @@ export const getModelKey = (args: { provider: Provider; model_id: string }) => {
|
|||
|
||||
export const get_enabled = query({
|
||||
args: {
|
||||
user_id: v.string(),
|
||||
session_token: v.string(),
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
handler: async (ctx, args): Promise<Record<string, Doc<'user_enabled_models'>>> => {
|
||||
const session = await ctx.runQuery(internal.betterAuth.getSession, {
|
||||
sessionToken: args.session_token,
|
||||
});
|
||||
|
||||
if (!session) throw new Error('Invalid session token');
|
||||
|
||||
const models = await ctx.db
|
||||
.query('user_enabled_models')
|
||||
.withIndex('by_user', (q) => q.eq('user_id', args.user_id))
|
||||
.withIndex('by_user', (q) => q.eq('user_id', session.userId))
|
||||
.collect();
|
||||
|
||||
return array.toMap(models, (m) => [getModelKey(m), m]);
|
||||
|
|
@ -26,15 +33,21 @@ export const get_enabled = query({
|
|||
|
||||
export const is_enabled = query({
|
||||
args: {
|
||||
user_id: v.string(),
|
||||
sessionToken: v.string(),
|
||||
provider: providerValidator,
|
||||
model_id: v.string(),
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
handler: async (ctx, args): Promise<boolean> => {
|
||||
const session = await ctx.runQuery(internal.betterAuth.getSession, {
|
||||
sessionToken: args.sessionToken,
|
||||
});
|
||||
|
||||
if (!session) throw new Error('Invalid session token');
|
||||
|
||||
const model = await ctx.db
|
||||
.query('user_enabled_models')
|
||||
.withIndex('by_model_provider_user', (q) =>
|
||||
q.eq('model_id', args.model_id).eq('provider', args.provider).eq('user_id', args.user_id)
|
||||
q.eq('model_id', args.model_id).eq('provider', args.provider).eq('user_id', session.userId)
|
||||
)
|
||||
.first();
|
||||
|
||||
|
|
@ -46,13 +59,19 @@ export const get = query({
|
|||
args: {
|
||||
provider: providerValidator,
|
||||
model_id: v.string(),
|
||||
user_id: v.string(),
|
||||
session_token: v.string(),
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
handler: async (ctx, args): Promise<Doc<'user_enabled_models'> | null> => {
|
||||
const session = await ctx.runQuery(internal.betterAuth.getSession, {
|
||||
sessionToken: args.session_token,
|
||||
});
|
||||
|
||||
if (!session) throw new Error('Invalid session token');
|
||||
|
||||
const model = await ctx.db
|
||||
.query('user_enabled_models')
|
||||
.withIndex('by_model_provider_user', (q) =>
|
||||
q.eq('model_id', args.model_id).eq('provider', args.provider).eq('user_id', args.user_id)
|
||||
q.eq('model_id', args.model_id).eq('provider', args.provider).eq('user_id', session.userId)
|
||||
)
|
||||
.first();
|
||||
|
||||
|
|
@ -64,7 +83,6 @@ export const set = mutation({
|
|||
args: {
|
||||
provider: providerValidator,
|
||||
model_id: v.string(),
|
||||
user_id: v.string(),
|
||||
enabled: v.boolean(),
|
||||
session_token: v.string(),
|
||||
},
|
||||
|
|
@ -73,9 +91,7 @@ export const set = mutation({
|
|||
sessionToken: args.session_token,
|
||||
});
|
||||
|
||||
if (!session) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
if (!session) throw new Error('Invalid session token');
|
||||
|
||||
const existing = await ctx.db
|
||||
.query('user_enabled_models')
|
||||
|
|
@ -90,7 +106,8 @@ export const set = mutation({
|
|||
await ctx.db.delete(existing._id);
|
||||
} else {
|
||||
await ctx.db.insert('user_enabled_models', {
|
||||
...object.pick(args, ['provider', 'model_id', 'user_id']),
|
||||
...object.pick(args, ['provider', 'model_id']),
|
||||
user_id: session.userId,
|
||||
pinned: null,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ export const create = mutation({
|
|||
name: v.string(),
|
||||
attach: ruleAttachValidator,
|
||||
rule: v.string(),
|
||||
sessionToken: v.string(),
|
||||
session_token: v.string(),
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
const session = await ctx.runQuery(internal.betterAuth.getSession, {
|
||||
sessionToken: args.sessionToken,
|
||||
sessionToken: args.session_token,
|
||||
});
|
||||
|
||||
if (!session) throw new Error('Invalid session token');
|
||||
|
|
@ -39,11 +39,11 @@ export const update = mutation({
|
|||
ruleId: v.id('user_rules'),
|
||||
attach: ruleAttachValidator,
|
||||
rule: v.string(),
|
||||
sessionToken: v.string(),
|
||||
session_token: v.string(),
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
const session = await ctx.runQuery(internal.betterAuth.getSession, {
|
||||
sessionToken: args.sessionToken,
|
||||
sessionToken: args.session_token,
|
||||
});
|
||||
|
||||
if (!session) throw new Error('Invalid session token');
|
||||
|
|
@ -63,11 +63,11 @@ export const update = mutation({
|
|||
export const remove = mutation({
|
||||
args: {
|
||||
ruleId: v.id('user_rules'),
|
||||
sessionToken: v.string(),
|
||||
session_token: v.string(),
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
const session = await ctx.runQuery(internal.betterAuth.getSession, {
|
||||
sessionToken: args.sessionToken,
|
||||
sessionToken: args.session_token,
|
||||
});
|
||||
|
||||
if (!session) throw new Error('Invalid session token');
|
||||
|
|
@ -83,11 +83,11 @@ export const remove = mutation({
|
|||
|
||||
export const all = query({
|
||||
args: {
|
||||
sessionToken: v.string(),
|
||||
session_token: v.string(),
|
||||
},
|
||||
handler: async (ctx, args): Promise<Doc<'user_rules'>[]> => {
|
||||
const session = await ctx.runQuery(internal.betterAuth.getSession, {
|
||||
sessionToken: args.sessionToken,
|
||||
sessionToken: args.session_token,
|
||||
});
|
||||
|
||||
if (!session) throw new Error('Invalid session token');
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export class Models {
|
|||
|
||||
init = createInit(() => {
|
||||
const query = useCachedQuery(api.user_enabled_models.get_enabled, {
|
||||
user_id: session.current?.user.id ?? '',
|
||||
session_token: session.current?.session.token ?? '',
|
||||
});
|
||||
watch(
|
||||
() => $state.snapshot(query.data),
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
let creatingRule = $state(false);
|
||||
|
||||
const userRulesQuery: QueryResult<Doc<'user_rules'>[]> = useCachedQuery(api.user_rules.all, {
|
||||
sessionToken: session.current?.session.token ?? '',
|
||||
session_token: session.current?.session.token ?? '',
|
||||
});
|
||||
|
||||
async function submitNewRule(e: SubmitEvent) {
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
name,
|
||||
attach,
|
||||
rule,
|
||||
sessionToken: session.current?.session.token ?? '',
|
||||
session_token: session.current?.session.token ?? '',
|
||||
});
|
||||
|
||||
creatingRule = false;
|
||||
|
|
@ -92,7 +92,7 @@
|
|||
<Input id="name" name="name" placeholder="My Rule" required />
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<Label for="attach">Attach</Label>
|
||||
<Label for="attach">Rule Type</Label>
|
||||
<select
|
||||
id="attach"
|
||||
name="attach"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
import { session } from '$lib/state/session.svelte';
|
||||
import { LocalToasts } from '$lib/builders/local-toasts.svelte';
|
||||
import { ResultAsync } from 'neverthrow';
|
||||
import TrashIcon from '~icons/lucide/trash';
|
||||
|
||||
type Props = {
|
||||
rule: Doc<'user_rules'>;
|
||||
|
|
@ -21,6 +22,7 @@
|
|||
const client = useConvexClient();
|
||||
|
||||
let updating = $state(false);
|
||||
let deleting = $state(false);
|
||||
|
||||
const toasts = new LocalToasts({ id });
|
||||
|
||||
|
|
@ -39,7 +41,7 @@
|
|||
ruleId: rule._id,
|
||||
attach,
|
||||
rule: ruleText,
|
||||
sessionToken: session.current?.session.token ?? '',
|
||||
session_token: session.current?.session.token ?? '',
|
||||
}),
|
||||
(e) => e
|
||||
);
|
||||
|
|
@ -53,15 +55,31 @@
|
|||
|
||||
updating = false;
|
||||
}
|
||||
|
||||
async function deleteRule() {
|
||||
deleting = true;
|
||||
|
||||
await client.mutation(api.user_rules.remove, {
|
||||
ruleId: rule._id,
|
||||
session_token: session.current?.session.token ?? '',
|
||||
});
|
||||
|
||||
deleting = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Card.Root>
|
||||
<Card.Header>
|
||||
<Card.Title>{rule.name}</Card.Title>
|
||||
<div class="flex items-center justify-between">
|
||||
<Card.Title>{rule.name}</Card.Title>
|
||||
<Button variant="destructive" size="icon" onclick={deleteRule} disabled={deleting}>
|
||||
<TrashIcon class="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Content tag="form" onsubmit={updateRule}>
|
||||
<div class="flex flex-col gap-2">
|
||||
<Label for="attach">Attach</Label>
|
||||
<Label for="attach">Rule Type</Label>
|
||||
<select
|
||||
id="attach"
|
||||
name="attach"
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
const res = await ResultAsync.fromPromise(
|
||||
client.mutation(api.user_enabled_models.set, {
|
||||
provider,
|
||||
user_id: session.current.user.id,
|
||||
model_id: model.id,
|
||||
enabled: v,
|
||||
session_token: session.current?.session.token,
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ async function generateAIResponse(
|
|||
client.query(api.user_enabled_models.get, {
|
||||
provider: Provider.OpenRouter,
|
||||
model_id: modelId,
|
||||
user_id: session.userId,
|
||||
session_token: session.token,
|
||||
}),
|
||||
(e) => `Failed to get model: ${e}`
|
||||
);
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@
|
|||
<Sidebar.Trigger class="fixed top-3 left-2">
|
||||
<PanelLeftIcon />
|
||||
</Sidebar.Trigger>
|
||||
<div class="mx-auto flex size-full max-w-3xl flex-col">
|
||||
<div class="mx-auto flex size-full min-h-svh max-w-3xl flex-col">
|
||||
{@render children()}
|
||||
<div class="mt-auto flex w-full flex-col gap-1">
|
||||
<ModelPicker class=" w-min " />
|
||||
|
|
@ -129,7 +129,7 @@
|
|||
<SendIcon />
|
||||
</Button>
|
||||
</form>
|
||||
<div class="flex w-full place-items-center justify-between gap-2">
|
||||
<div class="flex w-full place-items-center justify-between gap-2 pb-1">
|
||||
<span class="text-muted-foreground text-xs">
|
||||
Crafted by <Icons.Svelte class="inline size-3" /> wizards.
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
let { class: className }: Props = $props();
|
||||
|
||||
const enabledModelsQuery = useCachedQuery(api.user_enabled_models.get_enabled, {
|
||||
user_id: session.current?.user.id ?? '',
|
||||
session_token: session.current?.session.token ?? '',
|
||||
});
|
||||
|
||||
const enabledArr = $derived(Object.values(enabledModelsQuery.data ?? {}));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue