Skip to content

Commit 2ca9eac

Browse files
authored
Enable the Roo Code Cloud provider in evals (#9492)
1 parent 529c686 commit 2ca9eac

File tree

19 files changed

+793
-171
lines changed

19 files changed

+793
-171
lines changed

apps/web-evals/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"dependencies": {
1515
"@hookform/resolvers": "^5.1.1",
1616
"@radix-ui/react-alert-dialog": "^1.1.7",
17+
"@radix-ui/react-checkbox": "^1.1.5",
1718
"@radix-ui/react-dialog": "^1.1.6",
1819
"@radix-ui/react-dropdown-menu": "^2.1.7",
1920
"@radix-ui/react-label": "^2.1.2",

apps/web-evals/src/actions/runs.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ import { CreateRun } from "@/lib/schemas"
2121

2222
const EVALS_REPO_PATH = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../../../../evals")
2323

24-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
25-
export async function createRun({ suite, exercises = [], systemPrompt, timeout, ...values }: CreateRun) {
24+
export async function createRun({ suite, exercises = [], timeout, ...values }: CreateRun) {
2625
const run = await _createRun({
2726
...values,
2827
timeout,

apps/web-evals/src/app/api/health/route.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

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

Lines changed: 119 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
"use client"
22

3-
import { useCallback, useRef, useState } from "react"
3+
import { useCallback, useState } from "react"
44
import { useRouter } from "next/navigation"
55
import { z } from "zod"
66
import { useQuery } from "@tanstack/react-query"
77
import { useForm, FormProvider } from "react-hook-form"
88
import { zodResolver } from "@hookform/resolvers/zod"
9-
import fuzzysort from "fuzzysort"
109
import { toast } from "sonner"
11-
import { X, Rocket, Check, ChevronsUpDown, SlidersHorizontal, CircleCheck } from "lucide-react"
10+
import { X, Rocket, Check, ChevronsUpDown, SlidersHorizontal } from "lucide-react"
1211

1312
import { globalSettingsSchema, providerSettingsSchema, EVALS_SETTINGS, getModelId } from "@roo-code/types"
1413

1514
import { createRun } from "@/actions/runs"
1615
import { getExercises } from "@/actions/exercises"
16+
1717
import {
18-
createRunSchema,
1918
type CreateRun,
20-
MODEL_DEFAULT,
19+
createRunSchema,
2120
CONCURRENCY_MIN,
2221
CONCURRENCY_MAX,
2322
CONCURRENCY_DEFAULT,
@@ -26,14 +25,19 @@ import {
2625
TIMEOUT_DEFAULT,
2726
} from "@/lib/schemas"
2827
import { cn } from "@/lib/utils"
28+
2929
import { useOpenRouterModels } from "@/hooks/use-open-router-models"
30+
import { useRooCodeCloudModels } from "@/hooks/use-roo-code-cloud-models"
31+
3032
import {
3133
Button,
34+
Checkbox,
3235
FormControl,
3336
FormField,
3437
FormItem,
3538
FormLabel,
3639
FormMessage,
40+
Input,
3741
Textarea,
3842
Tabs,
3943
TabsList,
@@ -48,36 +52,40 @@ import {
4852
Popover,
4953
PopoverContent,
5054
PopoverTrigger,
51-
ScrollArea,
52-
ScrollBar,
5355
Slider,
56+
Label,
57+
FormDescription,
5458
} from "@/components/ui"
5559

5660
import { SettingsDiff } from "./settings-diff"
5761

5862
export function NewRun() {
5963
const router = useRouter()
6064

61-
const [mode, setMode] = useState<"openrouter" | "settings">("openrouter")
62-
const [modelSearchValue, setModelSearchValue] = useState("")
65+
const [provider, setModelSource] = useState<"roo" | "openrouter" | "other">("roo")
6366
const [modelPopoverOpen, setModelPopoverOpen] = useState(false)
67+
const [useNativeToolProtocol, setUseNativeToolProtocol] = useState(true)
6468

65-
const modelSearchResultsRef = useRef<Map<string, number>>(new Map())
66-
const modelSearchValueRef = useRef("")
69+
const openRouter = useOpenRouterModels()
70+
const rooCodeCloud = useRooCodeCloudModels()
71+
const models = provider === "openrouter" ? openRouter.data : rooCodeCloud.data
72+
const searchValue = provider === "openrouter" ? openRouter.searchValue : rooCodeCloud.searchValue
73+
const setSearchValue = provider === "openrouter" ? openRouter.setSearchValue : rooCodeCloud.setSearchValue
74+
const onFilter = provider === "openrouter" ? openRouter.onFilter : rooCodeCloud.onFilter
6775

68-
const models = useOpenRouterModels()
6976
const exercises = useQuery({ queryKey: ["getExercises"], queryFn: () => getExercises() })
7077

7178
const form = useForm<CreateRun>({
7279
resolver: zodResolver(createRunSchema),
7380
defaultValues: {
74-
model: MODEL_DEFAULT,
81+
model: "",
7582
description: "",
7683
suite: "full",
7784
exercises: [],
7885
settings: undefined,
7986
concurrency: CONCURRENCY_DEFAULT,
8087
timeout: TIMEOUT_DEFAULT,
88+
jobToken: "",
8189
},
8290
})
8391

@@ -93,8 +101,20 @@ export function NewRun() {
93101
const onSubmit = useCallback(
94102
async (values: CreateRun) => {
95103
try {
96-
if (mode === "openrouter") {
97-
values.settings = { ...(values.settings || {}), openRouterModelId: model }
104+
if (provider === "openrouter") {
105+
values.settings = {
106+
...(values.settings || {}),
107+
apiProvider: "openrouter",
108+
openRouterModelId: model,
109+
toolProtocol: useNativeToolProtocol ? "native" : "xml",
110+
}
111+
} else if (provider === "roo") {
112+
values.settings = {
113+
...(values.settings || {}),
114+
apiProvider: "roo",
115+
apiModelId: model,
116+
toolProtocol: useNativeToolProtocol ? "native" : "xml",
117+
}
98118
}
99119

100120
const { id } = await createRun(values)
@@ -103,36 +123,15 @@ export function NewRun() {
103123
toast.error(e instanceof Error ? e.message : "An unknown error occurred.")
104124
}
105125
},
106-
[mode, model, router],
107-
)
108-
109-
const onFilterModels = useCallback(
110-
(value: string, search: string) => {
111-
if (modelSearchValueRef.current !== search) {
112-
modelSearchValueRef.current = search
113-
modelSearchResultsRef.current.clear()
114-
115-
for (const {
116-
obj: { id },
117-
score,
118-
} of fuzzysort.go(search, models.data || [], {
119-
key: "name",
120-
})) {
121-
modelSearchResultsRef.current.set(id, score)
122-
}
123-
}
124-
125-
return modelSearchResultsRef.current.get(value) ?? 0
126-
},
127-
[models.data],
126+
[provider, model, router, useNativeToolProtocol],
128127
)
129128

130129
const onSelectModel = useCallback(
131130
(model: string) => {
132131
setValue("model", model)
133132
setModelPopoverOpen(false)
134133
},
135-
[setValue],
134+
[setValue, setModelPopoverOpen],
136135
)
137136

138137
const onImportSettings = useCallback(
@@ -160,7 +159,6 @@ export function NewRun() {
160159

161160
setValue("model", getModelId(providerSettings) ?? "")
162161
setValue("settings", { ...EVALS_SETTINGS, ...providerSettings, ...globalSettings })
163-
setMode("settings")
164162

165163
event.target.value = ""
166164
} catch (e) {
@@ -177,13 +175,44 @@ export function NewRun() {
177175
<form
178176
onSubmit={form.handleSubmit(onSubmit)}
179177
className="flex flex-col justify-center divide-y divide-primary *:py-5">
180-
<div className="flex flex-row justify-between gap-4">
181-
{mode === "openrouter" && (
182-
<FormField
183-
control={form.control}
184-
name="model"
185-
render={() => (
186-
<FormItem className="flex-1">
178+
<FormField
179+
control={form.control}
180+
name="model"
181+
render={() => (
182+
<FormItem>
183+
<Tabs
184+
value={provider}
185+
onValueChange={(value) => setModelSource(value as "roo" | "openrouter" | "other")}>
186+
<TabsList className="mb-2">
187+
<TabsTrigger value="roo">Roo Code Cloud</TabsTrigger>
188+
<TabsTrigger value="openrouter">OpenRouter</TabsTrigger>
189+
<TabsTrigger value="other">Other</TabsTrigger>
190+
</TabsList>
191+
</Tabs>
192+
193+
{provider === "other" ? (
194+
<div className="space-y-2 overflow-auto">
195+
<Button
196+
type="button"
197+
variant="secondary"
198+
onClick={() => document.getElementById("json-upload")?.click()}
199+
className="w-full">
200+
<SlidersHorizontal />
201+
Import Settings
202+
</Button>
203+
<input
204+
id="json-upload"
205+
type="file"
206+
accept="application/json"
207+
className="hidden"
208+
onChange={onImportSettings}
209+
/>
210+
{settings && (
211+
<SettingsDiff defaultSettings={EVALS_SETTINGS} customSettings={settings} />
212+
)}
213+
</div>
214+
) : (
215+
<>
187216
<Popover open={modelPopoverOpen} onOpenChange={setModelPopoverOpen}>
188217
<PopoverTrigger asChild>
189218
<Button
@@ -192,25 +221,23 @@ export function NewRun() {
192221
aria-expanded={modelPopoverOpen}
193222
className="flex items-center justify-between">
194223
<div>
195-
{models.data?.find(({ id }) => id === model)?.name ||
196-
model ||
197-
"Select OpenRouter Model"}
224+
{models?.find(({ id }) => id === model)?.name || `Select`}
198225
</div>
199226
<ChevronsUpDown className="opacity-50" />
200227
</Button>
201228
</PopoverTrigger>
202229
<PopoverContent className="p-0 w-[var(--radix-popover-trigger-width)]">
203-
<Command filter={onFilterModels}>
230+
<Command filter={onFilter}>
204231
<CommandInput
205232
placeholder="Search"
206-
value={modelSearchValue}
207-
onValueChange={setModelSearchValue}
233+
value={searchValue}
234+
onValueChange={setSearchValue}
208235
className="h-9"
209236
/>
210237
<CommandList>
211238
<CommandEmpty>No model found.</CommandEmpty>
212239
<CommandGroup>
213-
{models.data?.map(({ id, name }) => (
240+
{models?.map(({ id, name }) => (
214241
<CommandItem
215242
key={id}
216243
value={id}
@@ -229,45 +256,49 @@ export function NewRun() {
229256
</Command>
230257
</PopoverContent>
231258
</Popover>
232-
<FormMessage />
233-
</FormItem>
234-
)}
235-
/>
236-
)}
237259

238-
<FormItem className="flex-1">
239-
<Button
240-
type="button"
241-
variant="secondary"
242-
onClick={() => document.getElementById("json-upload")?.click()}>
243-
<SlidersHorizontal />
244-
Import Settings
245-
</Button>
246-
<input
247-
id="json-upload"
248-
type="file"
249-
accept="application/json"
250-
className="hidden"
251-
onChange={onImportSettings}
252-
/>
253-
{settings && (
254-
<ScrollArea className="max-h-64 border rounded-sm">
255-
<>
256-
<div className="flex items-center gap-1 p-2 border-b">
257-
<CircleCheck className="size-4 text-ring" />
258-
<div className="text-sm">
259-
Imported valid Roo Code settings. Showing differences from default
260-
settings.
261-
</div>
260+
<div className="flex items-center gap-1.5">
261+
<Checkbox
262+
id="native"
263+
checked={useNativeToolProtocol}
264+
onCheckedChange={(checked) =>
265+
setUseNativeToolProtocol(checked === true)
266+
}
267+
/>
268+
<Label htmlFor="native">Use Native Tool Calls</Label>
262269
</div>
263-
<SettingsDiff defaultSettings={EVALS_SETTINGS} customSettings={settings} />
264270
</>
265-
<ScrollBar orientation="horizontal" />
266-
</ScrollArea>
271+
)}
272+
273+
<FormMessage />
274+
</FormItem>
275+
)}
276+
/>
277+
278+
{provider === "roo" && (
279+
<FormField
280+
control={form.control}
281+
name="jobToken"
282+
render={({ field }) => (
283+
<FormItem>
284+
<FormLabel>Roo Code Cloud Token</FormLabel>
285+
<FormControl>
286+
<Input type="password" {...field} />
287+
</FormControl>
288+
<FormMessage />
289+
<FormDescription>
290+
If you have access to the Roo Code Cloud repository then you can generate a
291+
token with:
292+
<br />
293+
<code className="text-xs">
294+
pnpm --filter @roo-code-cloud/auth production:create-job-token [org]
295+
[timeout]
296+
</code>
297+
</FormDescription>
298+
</FormItem>
267299
)}
268-
<FormMessage />
269-
</FormItem>
270-
</div>
300+
/>
301+
)}
271302

272303
<FormField
273304
control={form.control}

0 commit comments

Comments
 (0)