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,192 @@
'use client';
import { useState } from 'react';
import { useMutation } from 'convex/react';
import { Bot } from 'lucide-react';
import { toast } from 'sonner';
import type { Doc } from '@spoon/backend/convex/_generated/dataModel.js';
import { api } from '@spoon/backend/convex/_generated/api.js';
import {
Button,
Card,
CardContent,
CardHeader,
CardTitle,
Input,
Label,
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
Switch,
} from '@spoon/ui';
const efforts = ['minimal', 'low', 'medium', 'high', 'xhigh'] as const;
type AgentSettings = {
enabled: boolean;
defaultBaseBranch?: string;
branchPrefix: string;
installCommand?: string;
checkCommand?: string;
testCommand?: string;
agentModel: string;
reasoningEffort: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
};
export const SpoonAgentSettingsForm = ({
spoon,
settings,
}: {
spoon: Doc<'spoons'>;
settings?: AgentSettings | null;
}) => {
const update = useMutation(api.spoonAgentSettings.update);
const [enabled, setEnabled] = useState(settings?.enabled ?? true);
const [defaultBaseBranch, setDefaultBaseBranch] = useState(
settings?.defaultBaseBranch ??
spoon.forkDefaultBranch ??
spoon.upstreamDefaultBranch,
);
const [branchPrefix, setBranchPrefix] = useState(
settings?.branchPrefix ?? 'spoon/agent',
);
const [installCommand, setInstallCommand] = useState(
settings?.installCommand ?? '',
);
const [checkCommand, setCheckCommand] = useState(
settings?.checkCommand ?? '',
);
const [testCommand, setTestCommand] = useState(settings?.testCommand ?? '');
const [agentModel, setAgentModel] = useState(
settings?.agentModel ?? 'gpt-5.1-codex',
);
const [reasoningEffort, setReasoningEffort] = useState<
'minimal' | 'low' | 'medium' | 'high' | 'xhigh'
>(
settings?.reasoningEffort === 'none'
? 'minimal'
: (settings?.reasoningEffort ?? 'high'),
);
const save = async () => {
try {
await update({
spoonId: spoon._id,
enabled,
defaultBaseBranch,
branchPrefix,
installCommand: installCommand || undefined,
checkCommand: checkCommand || undefined,
testCommand: testCommand || undefined,
agentModel,
reasoningEffort,
});
toast.success('Agent settings saved.');
} catch (error) {
console.error(error);
toast.error('Could not save agent settings.');
}
};
return (
<Card className='shadow-none'>
<CardHeader>
<CardTitle className='flex items-center gap-2 text-base'>
<Bot className='size-4' />
Agent runtime
</CardTitle>
</CardHeader>
<CardContent className='space-y-4'>
<div className='flex items-center justify-between gap-4'>
<Label htmlFor='agentEnabled'>Enable agent jobs</Label>
<Switch
id='agentEnabled'
checked={enabled}
onCheckedChange={setEnabled}
/>
</div>
<div className='grid gap-3 md:grid-cols-2'>
<div className='grid gap-2'>
<Label htmlFor='defaultBaseBranch'>Default base branch</Label>
<Input
id='defaultBaseBranch'
value={defaultBaseBranch}
onChange={(event) => setDefaultBaseBranch(event.target.value)}
/>
</div>
<div className='grid gap-2'>
<Label htmlFor='branchPrefix'>Branch prefix</Label>
<Input
id='branchPrefix'
value={branchPrefix}
onChange={(event) => setBranchPrefix(event.target.value)}
/>
</div>
<div className='grid gap-2'>
<Label htmlFor='agentModel'>Model</Label>
<Input
id='agentModel'
value={agentModel}
onChange={(event) => setAgentModel(event.target.value)}
/>
</div>
<div className='grid gap-2'>
<Label>Reasoning effort</Label>
<Select
value={reasoningEffort}
onValueChange={(value) =>
setReasoningEffort(
value as 'minimal' | 'low' | 'medium' | 'high' | 'xhigh',
)
}
>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
{efforts.map((effort) => (
<SelectItem key={effort} value={effort}>
{effort}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className='grid gap-2'>
<Label htmlFor='installCommand'>Install command</Label>
<Input
id='installCommand'
value={installCommand}
placeholder='bun install'
onChange={(event) => setInstallCommand(event.target.value)}
/>
</div>
<div className='grid gap-2'>
<Label htmlFor='checkCommand'>Check command</Label>
<Input
id='checkCommand'
value={checkCommand}
placeholder='bun typecheck'
onChange={(event) => setCheckCommand(event.target.value)}
/>
</div>
<div className='grid gap-2'>
<Label htmlFor='testCommand'>Test command</Label>
<Input
id='testCommand'
value={testCommand}
placeholder='bun test'
onChange={(event) => setTestCommand(event.target.value)}
/>
</div>
</div>
<Button type='button' onClick={save}>
Save agent settings
</Button>
</CardContent>
</Card>
);
};