Add Roo Code types

This commit is contained in:
cte 2025-03-26 22:27:56 -07:00
parent 5c4680a900
commit f3fc363830
11 changed files with 415 additions and 151 deletions

View file

@ -3,18 +3,18 @@ import * as fs from "fs"
import { filesystem } from "gluegun"
import { type Language, languages } from "@benchmark/types"
import { type ExerciseLanguage, exerciseLanguages } from "@benchmark/types"
import { exercisesPath } from "./paths.js"
let exercisesByLanguage: Record<Language, string[]> | null = null
let exercisesByLanguage: Record<ExerciseLanguage, string[]> | null = null
export const getExercises = () => {
if (exercisesByLanguage !== null) {
return exercisesByLanguage
}
const getLanguageExercises = (language: Language) =>
const getLanguageExercises = (language: ExerciseLanguage) =>
fs.existsSync(path.resolve(exercisesPath, language))
? filesystem
.subdirectories(path.resolve(exercisesPath, language))
@ -22,9 +22,9 @@ export const getExercises = () => {
.filter((exercise) => !exercise.startsWith("."))
: []
exercisesByLanguage = languages.reduce(
exercisesByLanguage = exerciseLanguages.reduce(
(collect, language) => ({ ...collect, [language]: getLanguageExercises(language) }),
{} as Record<Language, string[]>,
{} as Record<ExerciseLanguage, string[]>,
)
return exercisesByLanguage

View file

@ -7,14 +7,14 @@ import { build, filesystem, GluegunPrompt, GluegunToolbox } from "gluegun"
import { runTests } from "@vscode/test-electron"
import { execa, parseCommandString } from "execa"
import { type Language, languages, IpcOrigin, IpcMessageType, TaskEventName } from "@benchmark/types"
import { type ExerciseLanguage, exerciseLanguages, IpcOrigin, IpcMessageType, TaskEventName } from "@benchmark/types"
import { type Run, findRun, createRun, finishRun, createTask, Task, getTasks, updateTask } from "@benchmark/db"
import { IpcServer } from "@benchmark/ipc"
import { __dirname, extensionDevelopmentPath, extensionTestsPath, exercisesPath } from "./paths.js"
import { getExercises } from "./exercises.js"
const testCommands: Record<Language, { commands: string[]; timeout?: number; cwd?: string }> = {
const testCommands: Record<ExerciseLanguage, { commands: string[]; timeout?: number; cwd?: string }> = {
cpp: { commands: ["cmake -G 'Unix\\ Makefiles' -DEXERCISM_RUN_ALL_TESTS=1 ..", "make"], cwd: "build" }, // timeout 15s bash -c "cd '$dir' && mkdir -p build && cd build && cmake -G 'Unix Makefiles' -DEXERCISM_RUN_ALL_TESTS=1 .. >/dev/null 2>&1 && make >/dev/null 2>&1"
go: { commands: ["go test"] }, // timeout 15s bash -c "cd '$dir' && go test > /dev/null 2>&1"
java: { commands: ["./gradlew test"] }, // timeout --foreground 15s bash -c "cd '$dir' && ./gradlew test > /dev/null 2>&1"
@ -28,7 +28,7 @@ const run = async (toolbox: GluegunToolbox) => {
let { language, exercise } = config
if (![undefined, ...languages, "all"].includes(language)) {
if (![undefined, ...exerciseLanguages, "all"].includes(language)) {
throw new Error(`Language is invalid: ${language}`)
}
@ -49,15 +49,15 @@ const run = async (toolbox: GluegunToolbox) => {
})
if (language === "all") {
for (const language of languages) {
const exercises = getExercises()[language as Language]
for (const language of exerciseLanguages) {
const exercises = getExercises()[language as ExerciseLanguage]
await pMap(exercises, (exercise) => createTask({ runId: run.id, language, exercise }), {
concurrency: 10,
})
}
} else if (exercise === "all") {
const exercises = getExercises()[language as Language]
const exercises = getExercises()[language as ExerciseLanguage]
await pMap(exercises, (exercise) => createTask({ runId: run.id, language, exercise }), { concurrency: 10 })
} else {
language = language || (await askLanguage(prompt))
@ -166,17 +166,17 @@ const runExercise = async ({ run, task }: { run: Run; task: Task }) => {
}
const askLanguage = async (prompt: GluegunPrompt) => {
const { language } = await prompt.ask<{ language: Language }>({
const { language } = await prompt.ask<{ language: ExerciseLanguage }>({
type: "select",
name: "language",
message: "Which language?",
choices: [...languages],
choices: [...exerciseLanguages],
})
return language
}
const askExercise = async (prompt: GluegunPrompt, language: Language) => {
const askExercise = async (prompt: GluegunPrompt, language: ExerciseLanguage) => {
const exercises = filesystem.subdirectories(path.join(exercisesPath, language))
if (exercises.length === 0) {

View file

@ -4,7 +4,7 @@ import * as fs from "fs/promises"
import * as path from "path"
import { fileURLToPath } from "url"
import { Language, languages } from "@benchmark/types"
import { ExerciseLanguage, exerciseLanguages } from "@benchmark/types"
const __dirname = path.dirname(fileURLToPath(import.meta.url))
@ -24,7 +24,7 @@ const EXERCISES_BASE_PATH = path.resolve(__dirname, "../../../../../../../exerci
export const getExercises = async () => {
const result = await Promise.all(
languages.map(async (language) => {
exerciseLanguages.map(async (language) => {
const languagePath = path.join(EXERCISES_BASE_PATH, language)
const exercises = await listDirectories(languagePath)
return exercises.map((exercise) => `${language}/${exercise}`)
@ -34,5 +34,5 @@ export const getExercises = async () => {
return result.flat()
}
export const getExercisesForLanguage = async (language: Language) =>
export const getExercisesForLanguage = async (language: ExerciseLanguage) =>
listDirectories(path.join(EXERCISES_BASE_PATH, language))

View file

@ -7,7 +7,7 @@ import os from "os"
import { revalidatePath } from "next/cache"
import pMap from "p-map"
import { Language, languages } from "@benchmark/types"
import { ExerciseLanguage, exerciseLanguages } from "@benchmark/types"
import * as db from "@benchmark/db"
import { CreateRun } from "@/lib/schemas"
@ -27,10 +27,10 @@ export async function createRun({ suite, exercises = [], ...values }: CreateRun)
throw new Error("Invalid exercise path: " + path)
}
await db.createTask({ ...values, runId: run.id, language: language as Language, exercise })
await db.createTask({ ...values, runId: run.id, language: language as ExerciseLanguage, exercise })
}
} else {
for (const language of languages) {
for (const language of exerciseLanguages) {
const exercises = await getExercisesForLanguage(language)
await pMap(exercises, (exercise) => db.createTask({ ...values, runId: run.id, language, exercise }), {

View file

@ -1,6 +1,6 @@
import { and, eq } from "drizzle-orm"
import type { Language } from "@benchmark/types"
import type { ExerciseLanguage } from "@benchmark/types"
import { RecordNotFoundError, RecordNotCreatedError } from "./errors.js"
import type { InsertTask, UpdateTask } from "../schema.js"
@ -49,7 +49,7 @@ export const updateTask = async (id: number, values: UpdateTask) => {
}
type GetTask = {
runId: number
language: Language
language: ExerciseLanguage
exercise: string
}

View file

@ -3,7 +3,7 @@ import { relations } from "drizzle-orm"
import { createInsertSchema } from "drizzle-zod"
import { z } from "zod"
import { languages } from "@benchmark/types"
import { exerciseLanguages } from "@benchmark/types"
/**
* runs
@ -45,7 +45,7 @@ export const tasks = sqliteTable(
.references(() => runs.id)
.notNull(),
taskMetricsId: integer({ mode: "number" }).references(() => taskMetrics.id),
language: text({ enum: languages }).notNull(),
language: text({ enum: exerciseLanguages }).notNull(),
exercise: text().notNull(),
passed: integer({ mode: "boolean" }),
startedAt: integer({ mode: "timestamp" }),

View file

@ -0,0 +1,10 @@
/**
* ExerciseLanguage
*/
export const exerciseLanguages = ["cpp", "go", "java", "javascript", "python", "rust"] as const
export type ExerciseLanguage = (typeof exerciseLanguages)[number]
export const isExerciseLanguage = (value: string): value is ExerciseLanguage =>
exerciseLanguages.includes(value as ExerciseLanguage)

View file

@ -1,125 +1,3 @@
import { z } from "zod"
/**
* Language
*/
export const languages = ["cpp", "go", "java", "javascript", "python", "rust"] as const
export type Language = (typeof languages)[number]
export const isLanguage = (value: string): value is Language => languages.includes(value as Language)
/**
* TaskEvent
*/
export enum TaskEventName {
Connect = "Connect",
TaskStarted = "TaskStarted",
Message = "Message",
TaskTokenUsageUpdated = "TaskTokenUsageUpdated",
TaskFinished = "TaskFinished",
}
export const taskEventSchema = z.discriminatedUnion("eventName", [
z.object({
eventName: z.literal(TaskEventName.Connect),
data: z.object({ task: z.object({ id: z.number() }) }),
}),
z.object({
eventName: z.literal(TaskEventName.TaskStarted),
data: z.object({ task: z.object({ id: z.number() }) }),
}),
z.object({
eventName: z.literal(TaskEventName.Message),
data: z.object({
task: z.object({ id: z.number() }),
message: z.object({
taskId: z.string(),
action: z.enum(["created", "updated"]),
message: z.object({
// See ClineMessage.
ts: z.number(),
type: z.enum(["ask", "say"]),
ask: z.string().optional(),
say: z.string().optional(),
partial: z.boolean().optional(),
text: z.string().optional(),
reasoning: z.string().optional(),
}),
}),
}),
}),
z.object({
eventName: z.literal(TaskEventName.TaskTokenUsageUpdated),
data: z.object({
task: z.object({ id: z.number() }),
usage: z.object({}),
}),
}),
z.object({
eventName: z.literal(TaskEventName.TaskFinished),
data: z.object({ task: z.object({ id: z.number() }), taskMetrics: z.unknown() }),
}),
])
export type TaskEvent = z.infer<typeof taskEventSchema>
/**
* TaskCommand
*/
export enum TaskCommandName {
StartNewTask = "StartNewTask",
}
export const taskCommandSchema = z.discriminatedUnion("commandName", [
z.object({
commandName: z.literal(TaskCommandName.StartNewTask),
data: z.object({
text: z.string(),
images: z.array(z.string()).optional(),
}),
}),
])
export type TaskCommand = z.infer<typeof taskCommandSchema>
/**
* IpcMessage
*/
export enum IpcMessageType {
Ack = "Ack",
TaskCommand = "TaskCommand",
TaskEvent = "TaskEvent",
}
export enum IpcOrigin {
Client = "client",
Server = "server",
Relay = "relay",
}
export const ipcMessageSchema = z.discriminatedUnion("type", [
z.object({
type: z.literal(IpcMessageType.Ack),
origin: z.literal(IpcOrigin.Server),
data: z.object({ clientId: z.string() }),
}),
z.object({
type: z.literal(IpcMessageType.TaskCommand),
origin: z.literal(IpcOrigin.Client),
clientId: z.string(),
data: taskCommandSchema,
}),
z.object({
type: z.literal(IpcMessageType.TaskEvent),
origin: z.union([z.literal(IpcOrigin.Server), z.literal(IpcOrigin.Relay)]),
relayClientId: z.string().optional(),
data: taskEventSchema,
}),
])
export type IpcMessage = z.infer<typeof ipcMessageSchema>
export * from "./exercises.js"
export * from "./ipc.js"
export * from "./roo-code.js"

View file

@ -0,0 +1,115 @@
import { z } from "zod"
/**
* TaskEvent
*/
export enum TaskEventName {
Connect = "Connect",
TaskStarted = "TaskStarted",
Message = "Message",
TaskTokenUsageUpdated = "TaskTokenUsageUpdated",
TaskFinished = "TaskFinished",
}
export const taskEventSchema = z.discriminatedUnion("eventName", [
z.object({
eventName: z.literal(TaskEventName.Connect),
data: z.object({ task: z.object({ id: z.number() }) }),
}),
z.object({
eventName: z.literal(TaskEventName.TaskStarted),
data: z.object({ task: z.object({ id: z.number() }) }),
}),
z.object({
eventName: z.literal(TaskEventName.Message),
data: z.object({
task: z.object({ id: z.number() }),
message: z.object({
taskId: z.string(),
action: z.enum(["created", "updated"]),
message: z.object({
// See ClineMessage.
ts: z.number(),
type: z.enum(["ask", "say"]),
ask: z.string().optional(),
say: z.string().optional(),
partial: z.boolean().optional(),
text: z.string().optional(),
reasoning: z.string().optional(),
}),
}),
}),
}),
z.object({
eventName: z.literal(TaskEventName.TaskTokenUsageUpdated),
data: z.object({
task: z.object({ id: z.number() }),
usage: z.object({}),
}),
}),
z.object({
eventName: z.literal(TaskEventName.TaskFinished),
data: z.object({ task: z.object({ id: z.number() }), taskMetrics: z.unknown() }),
}),
])
export type TaskEvent = z.infer<typeof taskEventSchema>
/**
* TaskCommand
*/
export enum TaskCommandName {
StartNewTask = "StartNewTask",
}
export const taskCommandSchema = z.discriminatedUnion("commandName", [
z.object({
commandName: z.literal(TaskCommandName.StartNewTask),
data: z.object({
text: z.string(),
images: z.array(z.string()).optional(),
}),
}),
])
export type TaskCommand = z.infer<typeof taskCommandSchema>
/**
* IpcMessage
*/
export enum IpcMessageType {
Ack = "Ack",
TaskCommand = "TaskCommand",
TaskEvent = "TaskEvent",
}
export enum IpcOrigin {
Client = "client",
Server = "server",
Relay = "relay",
}
export const ipcMessageSchema = z.discriminatedUnion("type", [
z.object({
type: z.literal(IpcMessageType.Ack),
origin: z.literal(IpcOrigin.Server),
data: z.object({ clientId: z.string() }),
}),
z.object({
type: z.literal(IpcMessageType.TaskCommand),
origin: z.literal(IpcOrigin.Client),
clientId: z.string(),
data: taskCommandSchema,
}),
z.object({
type: z.literal(IpcMessageType.TaskEvent),
origin: z.union([z.literal(IpcOrigin.Server), z.literal(IpcOrigin.Relay)]),
relayClientId: z.string().optional(),
data: taskEventSchema,
}),
])
export type IpcMessage = z.infer<typeof ipcMessageSchema>

View file

@ -0,0 +1,259 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { z } from "zod"
/**
* ProviderName
*/
const providerNames = [
"anthropic",
"glama",
"openrouter",
"bedrock",
"vertex",
"openai",
"ollama",
"vscode-lm",
"lmstudio",
"gemini",
"openai-native",
"mistral",
"deepseek",
"unbound",
"requesty",
"human-relay",
"fake-ai",
] as const
export type ProviderName = (typeof providerNames)[number]
/**
* ToolGroup
*/
export const toolGroups = ["read", "edit", "browser", "command", "mcp", "modes"] as const
export type ToolGroup = (typeof toolGroups)[number]
/**
* CheckpointStorage
*/
export const checkpointStorages = ["task", "workspace"] as const
export type CheckpointStorage = (typeof checkpointStorages)[number]
/**
* Language
*/
const languages = [
"ca",
"de",
"en",
"es",
"fr",
"hi",
"it",
"ja",
"ko",
"pl",
"pt-BR",
"tr",
"vi",
"zh-CN",
"zh-TW",
] as const
export type Language = (typeof languages)[number]
/**
* TelemetrySetting
*/
export const telemetrySettings = ["unset", "enabled", "disabled"] as const
export type TelemetrySetting = (typeof telemetrySettings)[number]
/**
* ModelInfo
*/
const modelInfoSchema = z.object({
maxTokens: z.number().optional(),
contextWindow: z.number(),
supportsImages: z.boolean().optional(),
supportsComputerUse: z.boolean().optional(),
supportsPromptCache: z.boolean(),
inputPrice: z.number().optional(),
outputPrice: z.number().optional(),
cacheWritesPrice: z.number().optional(),
cacheReadsPrice: z.number().optional(),
description: z.string().optional(),
reasoningEffort: z.enum(["low", "medium", "high"]).optional(),
thinking: z.boolean().optional(),
})
export type ModelInfo = z.infer<typeof modelInfoSchema>
/**
* ApiConfigMeta
*/
const apiConfigMetaSchema = z.object({
id: z.string(),
name: z.string(),
apiProvider: z.enum(providerNames).optional(),
})
export type ApiConfigMeta = z.infer<typeof apiConfigMetaSchema>
/**
* HistoryItem
*/
const historyItemSchema = z.object({
id: z.string(),
number: z.number(),
ts: z.number(),
task: z.string(),
tokensIn: z.number(),
tokensOut: z.number(),
cacheWrites: z.number().optional(),
cacheReads: z.number().optional(),
totalCost: z.number(),
size: z.number().optional(),
})
export type HistoryItem = z.infer<typeof historyItemSchema>
/**
* GroupEntry
*/
const groupEntrySchema = z.union([
z.enum(toolGroups),
z
.tuple([
z.enum(toolGroups),
z.object({
fileRegex: z.string().optional(),
description: z.string().optional(),
}),
])
.readonly(),
])
export type GroupEntry = z.infer<typeof groupEntrySchema>
/**
* ModeConfig
*/
const modeConfigSchema = z.object({
slug: z.string(),
name: z.string(),
roleDefinition: z.string(),
customInstructions: z.string().optional(),
groups: z.array(groupEntrySchema).readonly(),
source: z.enum(["global", "project"]).optional(),
})
export type ModeConfig = z.infer<typeof modeConfigSchema>
/**
* ExperimentId
*/
const experimentsSchema = z.object({
experimentalDiffStrategy: z.boolean(),
search_and_replace: z.boolean(),
insert_content: z.boolean(),
powerSteering: z.boolean(),
multi_search_and_replace: z.boolean(),
})
export type Experiments = z.infer<typeof experimentsSchema>
/**
* GlobalSettings
*/
export const globalSettingsSchema = z.object({
currentApiConfigName: z.string().optional(),
listApiConfigMeta: z.array(apiConfigMetaSchema).optional(),
pinnedApiConfigs: z.record(z.string(), z.boolean()).optional(),
lastShownAnnouncementId: z.string().optional(),
customInstructions: z.string().optional(),
taskHistory: z.array(historyItemSchema).optional(),
autoApprovalEnabled: z.boolean().optional(),
alwaysAllowReadOnly: z.boolean().optional(),
alwaysAllowReadOnlyOutsideWorkspace: z.boolean().optional(),
alwaysAllowWrite: z.boolean().optional(),
alwaysAllowWriteOutsideWorkspace: z.boolean().optional(),
writeDelayMs: z.number().optional(),
alwaysAllowBrowser: z.boolean().optional(),
alwaysApproveResubmit: z.boolean().optional(),
requestDelaySeconds: z.number().optional(),
alwaysAllowMcp: z.boolean().optional(),
alwaysAllowModeSwitch: z.boolean().optional(),
alwaysAllowSubtasks: z.boolean().optional(),
alwaysAllowExecute: z.boolean().optional(),
allowedCommands: z.array(z.string()).optional(),
browserToolEnabled: z.boolean().optional(),
browserViewportSize: z.string().optional(),
screenshotQuality: z.number().optional(),
remoteBrowserEnabled: z.boolean().optional(),
remoteBrowserHost: z.string().optional(),
enableCheckpoints: z.boolean().optional(),
checkpointStorage: z.enum(checkpointStorages).optional(),
ttsEnabled: z.boolean().optional(),
ttsSpeed: z.number().optional(),
soundEnabled: z.boolean().optional(),
soundVolume: z.number().optional(),
maxOpenTabsContext: z.number().optional(),
maxWorkspaceFiles: z.number().optional(),
showRooIgnoredFiles: z.boolean().optional(),
maxReadFileLine: z.number().optional(),
terminalOutputLineLimit: z.number().optional(),
terminalShellIntegrationTimeout: z.number().optional(),
rateLimitSeconds: z.number().optional(),
diffEnabled: z.boolean().optional(),
fuzzyMatchThreshold: z.number().optional(),
experiments: experimentsSchema.optional(),
language: z.enum(languages).optional(),
telemetrySetting: z.enum(telemetrySettings).optional(),
mcpEnabled: z.boolean().optional(),
enableMcpServerCreation: z.boolean().optional(),
mode: z.string().optional(),
modeApiConfigs: z.record(z.string(), z.string()).optional(),
customModes: z.array(modeConfigSchema).optional(),
customModePrompts: z
.record(
z.string(),
z
.object({
roleDefinition: z.string().optional(),
customInstructions: z.string().optional(),
})
.optional(),
)
.optional(),
customSupportPrompts: z.record(z.string(), z.string().optional()).optional(),
enhancementApiConfigId: z.string().optional(),
})
export type GlobalSettings = z.infer<typeof globalSettingsSchema>

View file

@ -73,9 +73,11 @@
"views": {
"roo-cline-ActivityBar": [
{
"type": "webview",
"id": "roo-cline.SidebarProvider",
"name": ""
"type": "webview",
"name": "Roo Code",
"icon": "$(rocket)",
"contextualTitle": "Roo Code!"
}
]
},