import { ConvexError, v } from 'convex/values'; import { mutation, query } from './_generated/server'; import { getOwnedSpoon, getRequiredUserId, optionalText, requireText, } from './model'; export const listRecent = query({ args: { limit: v.optional(v.number()) }, handler: async (ctx, { limit }) => { const ownerId = await getRequiredUserId(ctx); return await ctx.db .query('agentRequests') .withIndex('by_owner', (q) => q.eq('ownerId', ownerId)) .order('desc') .take(limit ?? 25); }, }); export const create = mutation({ args: { spoonId: v.id('spoons'), prompt: v.string(), targetBranch: v.optional(v.string()), }, handler: async (ctx, args) => { const ownerId = await getRequiredUserId(ctx); await getOwnedSpoon(ctx, args.spoonId, ownerId); const now = Date.now(); return await ctx.db.insert('agentRequests', { spoonId: args.spoonId, ownerId, prompt: requireText(args.prompt, 'Prompt'), status: 'queued', targetBranch: optionalText(args.targetBranch), createdAt: now, updatedAt: now, }); }, }); export const cancel = mutation({ args: { requestId: v.id('agentRequests') }, handler: async (ctx, { requestId }) => { const ownerId = await getRequiredUserId(ctx); const request = await ctx.db.get(requestId); if (request?.ownerId !== ownerId) { throw new ConvexError('Agent request not found.'); } if (request.status !== 'draft' && request.status !== 'queued') { throw new ConvexError('Only draft or queued requests can be cancelled.'); } await ctx.db.patch(requestId, { status: 'cancelled', updatedAt: Date.now(), }); return { success: true }; }, });