Skip to content

Commit 64e9e7c

Browse files
committed
Control evals concurrency in web app
1 parent 3f5f8bb commit 64e9e7c

File tree

8 files changed

+342
-7
lines changed

8 files changed

+342
-7
lines changed

evals/apps/cli/src/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import { IpcServer, IpcClient } from "@evals/ipc"
3333
import { __dirname, extensionDevelopmentPath, exercisesPath } from "./paths.js"
3434
import { getExercises } from "./exercises.js"
3535

36-
const maxConcurrency = 2
3736
const taskTimeLimit = 5 * 60 * 1_000
3837

3938
const testCommands: Record<ExerciseLanguage, { commands: string[]; timeout?: number; cwd?: string }> = {
@@ -74,12 +73,14 @@ const run = async (toolbox: GluegunToolbox) => {
7473
const exercises = getExercises()[language as ExerciseLanguage]
7574

7675
await pMap(exercises, (exercise) => createTask({ runId: run.id, language, exercise }), {
77-
concurrency: 10,
76+
concurrency: run.concurrency,
7877
})
7978
}
8079
} else if (exercise === "all") {
8180
const exercises = getExercises()[language as ExerciseLanguage]
82-
await pMap(exercises, (exercise) => createTask({ runId: run.id, language, exercise }), { concurrency: 10 })
81+
await pMap(exercises, (exercise) => createTask({ runId: run.id, language, exercise }), {
82+
concurrency: run.concurrency,
83+
})
8384
} else {
8485
language = language || (await askLanguage(prompt))
8586
exercise = exercise || (await askExercise(prompt, language))
@@ -140,7 +141,7 @@ const run = async (toolbox: GluegunToolbox) => {
140141
}
141142
})
142143

143-
if (runningPromises.length >= maxConcurrency) {
144+
if (runningPromises.length >= run.concurrency) {
144145
await Promise.race(runningPromises)
145146
}
146147
}

evals/apps/web/src/app/runs/[id]/run.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
DrawerHeader,
1414
DrawerTitle,
1515
ScrollArea,
16-
Separator,
1716
Table,
1817
TableBody,
1918
TableCell,

evals/apps/web/src/app/runs/new/new-run.tsx

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { useForm, FormProvider } from "react-hook-form"
77
import { zodResolver } from "@hookform/resolvers/zod"
88
import fuzzysort from "fuzzysort"
99
import { toast } from "sonner"
10-
import { X, Rocket, Check, ChevronsUpDown, HardDriveUpload, CircleCheck } from "lucide-react"
10+
import { X, Rocket, Check, ChevronsUpDown, HardDriveUpload, CircleCheck, Cpu } from "lucide-react"
1111

1212
import { globalSettingsSchema, rooCodeDefaults } from "@evals/types"
1313

@@ -39,6 +39,7 @@ import {
3939
PopoverContent,
4040
PopoverTrigger,
4141
ScrollArea,
42+
Slider,
4243
} from "@/components/ui"
4344

4445
import { SettingsDiff } from "./settings-diff"
@@ -68,6 +69,7 @@ export function NewRun() {
6869
suite: "full",
6970
exercises: [],
7071
settings: undefined,
72+
concurrency: 10,
7173
},
7274
})
7375

@@ -79,7 +81,7 @@ export function NewRun() {
7981
formState: { isSubmitting },
8082
} = form
8183

82-
const [model, suite, settings] = watch(["model", "suite", "settings"])
84+
const [model, suite, settings, concurrency] = watch(["model", "suite", "settings", "concurrency"])
8385

8486
const onSubmit = useCallback(
8587
async (data: FormValues) => {
@@ -280,6 +282,40 @@ export function NewRun() {
280282
)}
281283
/>
282284

285+
<FormField
286+
control={form.control}
287+
name="concurrency"
288+
render={({ field }) => (
289+
<FormItem>
290+
<FormLabel className="flex items-center gap-2">
291+
<Cpu className="size-4" />
292+
Concurrency
293+
</FormLabel>
294+
<FormControl>
295+
<div className="flex flex-col gap-2">
296+
<Slider
297+
defaultValue={[field.value]}
298+
min={1}
299+
max={50}
300+
step={1}
301+
onValueChange={(value) => field.onChange(value[0])}
302+
/>
303+
<div className="flex justify-between text-xs text-muted-foreground">
304+
<span>1</span>
305+
<span>{field.value}</span>
306+
<span>50</span>
307+
</div>
308+
</div>
309+
</FormControl>
310+
<FormDescription>
311+
Number of tasks to run in parallel. Higher values may improve speed but increase
312+
resource usage.
313+
</FormDescription>
314+
<FormMessage />
315+
</FormItem>
316+
)}
317+
/>
318+
283319
<FormField
284320
control={form.control}
285321
name="description"

evals/apps/web/src/lib/schemas.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const createRunSchema = z
1313
suite: z.enum(["full", "partial"]),
1414
exercises: z.array(z.string()).optional(),
1515
settings: globalSettingsSchema.optional(),
16+
concurrency: z.number().int().min(1).max(10).default(2),
1617
})
1718
.refine((data) => data.suite === "full" || (data.exercises || []).length > 0, {
1819
message: "Exercises are required when running a partial suite.",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE `runs` ADD `concurrency` integer DEFAULT 2 NOT NULL;

0 commit comments

Comments
 (0)