Add agent workflows & stuff
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
import { ConvexError, v } from 'convex/values';
|
||||
|
||||
import type { Doc, Id } from './_generated/dataModel';
|
||||
import type { MutationCtx } from './_generated/server';
|
||||
import {
|
||||
internalMutation,
|
||||
internalQuery,
|
||||
mutation,
|
||||
query,
|
||||
} from './_generated/server';
|
||||
import { getRequiredUserId } from './model';
|
||||
|
||||
const reasoningEffort = v.union(
|
||||
v.literal('none'),
|
||||
v.literal('minimal'),
|
||||
v.literal('low'),
|
||||
v.literal('medium'),
|
||||
v.literal('high'),
|
||||
v.literal('xhigh'),
|
||||
);
|
||||
|
||||
export const getMine = query({
|
||||
args: {},
|
||||
handler: async (ctx) => {
|
||||
const userId = await getRequiredUserId(ctx);
|
||||
const settings = await ctx.db
|
||||
.query('userAiSettings')
|
||||
.withIndex('by_user_provider', (q) =>
|
||||
q.eq('userId', userId).eq('provider', 'openai'),
|
||||
)
|
||||
.first();
|
||||
if (!settings) {
|
||||
return {
|
||||
configured: false,
|
||||
apiKeyPreview: undefined,
|
||||
model: 'gpt-5.5',
|
||||
reasoningEffort: 'medium' as const,
|
||||
updatedAt: undefined,
|
||||
};
|
||||
}
|
||||
return {
|
||||
configured: Boolean(settings.encryptedApiKey),
|
||||
apiKeyPreview: settings.apiKeyPreview,
|
||||
model: settings.model,
|
||||
reasoningEffort: settings.reasoningEffort,
|
||||
updatedAt: settings.updatedAt,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const getForUserInternal = internalQuery({
|
||||
args: { userId: v.id('users') },
|
||||
handler: async (ctx, { userId }) => {
|
||||
return await ctx.db
|
||||
.query('userAiSettings')
|
||||
.withIndex('by_user_provider', (q) =>
|
||||
q.eq('userId', userId).eq('provider', 'openai'),
|
||||
)
|
||||
.first();
|
||||
},
|
||||
});
|
||||
|
||||
const upsert = async (
|
||||
ctx: MutationCtx,
|
||||
userId: Id<'users'>,
|
||||
patch: Partial<Doc<'userAiSettings'>>,
|
||||
) => {
|
||||
const now = Date.now();
|
||||
const existing = await ctx.db
|
||||
.query('userAiSettings')
|
||||
.withIndex('by_user_provider', (q) =>
|
||||
q.eq('userId', userId).eq('provider', 'openai'),
|
||||
)
|
||||
.first();
|
||||
if (existing) {
|
||||
await ctx.db.patch(existing._id, { ...patch, updatedAt: now });
|
||||
return existing._id;
|
||||
}
|
||||
return await ctx.db.insert('userAiSettings', {
|
||||
userId,
|
||||
provider: 'openai',
|
||||
model: patch.model ?? 'gpt-5.5',
|
||||
reasoningEffort: patch.reasoningEffort ?? 'medium',
|
||||
encryptedApiKey: patch.encryptedApiKey,
|
||||
apiKeyPreview: patch.apiKeyPreview,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
});
|
||||
};
|
||||
|
||||
export const upsertEncryptedInternal = internalMutation({
|
||||
args: {
|
||||
userId: v.id('users'),
|
||||
encryptedApiKey: v.string(),
|
||||
apiKeyPreview: v.string(),
|
||||
model: v.string(),
|
||||
reasoningEffort,
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
return await upsert(ctx, args.userId, {
|
||||
encryptedApiKey: args.encryptedApiKey,
|
||||
apiKeyPreview: args.apiKeyPreview,
|
||||
model: args.model,
|
||||
reasoningEffort: args.reasoningEffort,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const updatePreferences = mutation({
|
||||
args: {
|
||||
model: v.string(),
|
||||
reasoningEffort,
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
const userId = await getRequiredUserId(ctx);
|
||||
return await upsert(ctx, userId, {
|
||||
model: args.model.trim() || 'gpt-5.5',
|
||||
reasoningEffort: args.reasoningEffort,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const removeOpenAiKey = mutation({
|
||||
args: {},
|
||||
handler: async (ctx) => {
|
||||
const userId = await getRequiredUserId(ctx);
|
||||
const settings = await ctx.db
|
||||
.query('userAiSettings')
|
||||
.withIndex('by_user_provider', (q) =>
|
||||
q.eq('userId', userId).eq('provider', 'openai'),
|
||||
)
|
||||
.first();
|
||||
if (!settings) throw new ConvexError('OpenAI settings not found.');
|
||||
await ctx.db.patch(settings._id, {
|
||||
encryptedApiKey: undefined,
|
||||
apiKeyPreview: undefined,
|
||||
updatedAt: Date.now(),
|
||||
});
|
||||
return { success: true };
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user