Add agent workflows & stuff
Build and Push Next App / quality (push) Failing after 48s
Build and Push Next App / build-next (push) Has been skipped

This commit is contained in:
Gabriel Brown
2026-06-21 21:15:15 -05:00
parent cf7ff2ee4e
commit 2dfa97ee4f
102 changed files with 8488 additions and 161 deletions
@@ -0,0 +1,145 @@
'use client';
import { useState } from 'react';
import { useMutation, useQuery } from 'convex/react';
import { Bot } from 'lucide-react';
import { toast } from 'sonner';
import type { Doc, Id } from '@spoon/backend/convex/_generated/dataModel.js';
import { api } from '@spoon/backend/convex/_generated/api.js';
import {
Button,
Card,
CardContent,
CardHeader,
CardTitle,
Input,
Label,
Textarea,
} from '@spoon/ui';
import { SecretSelector } from './secret-selector';
type AgentSettings = {
defaultBaseBranch?: string;
agentModel: string;
reasoningEffort: string;
};
export const AgentRequestForm = ({
spoon,
agentSettings,
}: {
spoon: Doc<'spoons'>;
agentSettings?: AgentSettings | null;
}) => {
const secrets = useQuery(api.spoonSecrets.listForSpoon, {
spoonId: spoon._id,
});
const createRequest = useMutation(api.agentRequests.create);
const createJob = useMutation(api.agentJobs.createFromRequest);
const [prompt, setPrompt] = useState('');
const [baseBranch, setBaseBranch] = useState(
agentSettings?.defaultBaseBranch ??
spoon.forkDefaultBranch ??
spoon.upstreamDefaultBranch,
);
const [requestedBranchName, setRequestedBranchName] = useState('');
const [selectedSecretIds, setSelectedSecretIds] = useState<
Id<'spoonSecrets'>[]
>([]);
const [submitting, setSubmitting] = useState(false);
const submit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
setSubmitting(true);
try {
const requestId = await createRequest({
spoonId: spoon._id,
prompt,
targetBranch: baseBranch,
});
await createJob({
requestId,
selectedSecretIds,
baseBranch,
requestedBranchName: requestedBranchName || undefined,
});
setPrompt('');
setRequestedBranchName('');
setSelectedSecretIds([]);
toast.success('Agent job queued.');
} catch (error) {
console.error(error);
toast.error('Could not queue agent job.');
} finally {
setSubmitting(false);
}
};
return (
<Card className='shadow-none'>
<CardHeader className='pb-3'>
<CardTitle className='flex items-center gap-2 text-base'>
<Bot className='size-4' />
Request agent work
</CardTitle>
</CardHeader>
<CardContent>
<form onSubmit={submit} className='space-y-4'>
<div className='grid gap-2'>
<Label htmlFor='agentPrompt'>Prompt</Label>
<Textarea
id='agentPrompt'
required
minLength={12}
value={prompt}
placeholder='Update this fork to use Authentik as the sole Auth.js provider.'
onChange={(event) => setPrompt(event.target.value)}
/>
</div>
<div className='grid gap-3 md:grid-cols-2'>
<div className='grid gap-2'>
<Label htmlFor='baseBranch'>Base branch</Label>
<Input
id='baseBranch'
value={baseBranch}
onChange={(event) => setBaseBranch(event.target.value)}
/>
</div>
<div className='grid gap-2'>
<Label htmlFor='workBranch'>Work branch</Label>
<Input
id='workBranch'
value={requestedBranchName}
placeholder='Auto-generated if blank'
onChange={(event) => setRequestedBranchName(event.target.value)}
/>
</div>
</div>
<div className='grid gap-2'>
<Label>Secrets exposed to this job</Label>
<SecretSelector
secrets={secrets ?? []}
selectedSecretIds={selectedSecretIds}
onChange={setSelectedSecretIds}
/>
</div>
<div className='bg-muted/40 grid gap-1 rounded-md p-3 text-xs'>
<span>
Model:{' '}
<strong>{agentSettings?.agentModel ?? 'gpt-5.1-codex'}</strong>
</span>
<span>
Reasoning:{' '}
<strong>{agentSettings?.reasoningEffort ?? 'high'}</strong>
</span>
</div>
<Button type='submit' disabled={submitting}>
{submitting ? 'Queueing...' : 'Queue agent job'}
</Button>
</form>
</CardContent>
</Card>
);
};