Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 77 additions & 4 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,18 +1,91 @@
# Build artifacts
# git
.git

# build artifacts
bin/
!bin/roo-code-latest.vsix
dist/
**/dist/
out/
**/out/
src/webview-ui/

# Dependencies
# dependencies
node_modules/
**/node_modules/

# Test and development files
# testing
coverage/
**/.vscode-test/
**/mock/

# devtools
knip.json
.husky/

# monorepo
.turbo/
**/.turbo/

# next.js
**/.next/
.vercel

# Ignore common development files
node_modules
.git
.gitignore
.dockerignore
.env*
.vscode
.idea

# Ignore build artifacts
dist
build
*.log
*.tmp
.cache
coverage

# Ignore OS files
.DS_Store
Thumbs.db

# Ignore test files
__tests__
*.test.js
*.spec.js
*.test.ts
*.spec.ts

# Ignore development config files
.eslintrc*
.prettierrc*
jest.config*

# Ignore most directories except what we need for the build
apps/
evals/
webview-ui/node_modules
src/node_modules

# Keep essential files for the build
!README.md
!CHANGELOG.md
!package.json
!pnpm-lock.yaml
!pnpm-workspace.yaml
!scripts/bootstrap.mjs
!apps/web-evals/
!src/
!webview-ui/
!packages/evals/.docker/entrypoints/runner.sh
!packages/build/
!packages/cloud/
!packages/config-eslint/
!packages/config-typescript/
!packages/evals/
!packages/ipc/
!packages/telemetry/
!packages/types/
!locales/
8 changes: 4 additions & 4 deletions apps/web-evals/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"lint": "next lint",
"check-types": "tsc -b",
"dev": "next dev --turbopack",
"dev": "scripts/check-services.sh && next dev --turbopack",
"format": "prettier --write src",
"build": "next build",
"start": "next start"
Expand All @@ -25,7 +25,6 @@
"@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-tooltip": "^1.1.8",
"@roo-code/evals": "workspace:^",
"@roo-code/ipc": "workspace:^",
"@roo-code/types": "workspace:^",
"@tanstack/react-query": "^5.69.0",
"class-variance-authority": "^0.7.1",
Expand All @@ -36,11 +35,11 @@
"next": "^15.2.5",
"next-themes": "^0.4.6",
"p-map": "^7.0.3",
"ps-tree": "^1.2.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.57.0",
"react-use": "^17.6.0",
"redis": "^5.5.5",
"sonner": "^2.0.5",
"tailwind-merge": "^3.3.0",
"tailwindcss-animate": "^1.0.7",
Expand All @@ -54,6 +53,7 @@
"@types/ps-tree": "^1.1.6",
"@types/react": "^18.3.23",
"@types/react-dom": "^18.3.5",
"tailwindcss": "^4"
"tailwindcss": "^4",
"vitest": "^3.2.1"
}
}
20 changes: 20 additions & 0 deletions apps/web-evals/scripts/check-services.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

if ! docker info &> /dev/null; then
echo "❌ Docker is not running. Please start Docker Desktop and try again."
exit 1
fi

if ! nc -z localhost 5432 2>/dev/null; then
echo "❌ PostgreSQL is not running on port 5432"
echo "💡 Start it with: pnpm --filter @roo-code/evals db:start"
exit 1
fi

if ! nc -z localhost 6379 2>/dev/null; then
echo "❌ Redis is not running on port 6379"
echo "💡 Start it with: pnpm --filter @roo-code/evals redis:start"
exit 1
fi

echo "✅ All required services are running"
60 changes: 46 additions & 14 deletions apps/web-evals/src/app/api/runs/[id]/stream/route.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { NextRequest } from "next/server"

import { taskEventSchema } from "@roo-code/types"
import { findRun } from "@roo-code/evals"
import { IpcClient } from "@roo-code/ipc"
import { IpcMessageType } from "@roo-code/types"

import { SSEStream } from "@/lib/server/sse-stream"
import { redisClient } from "@/lib/server/redis"

export const dynamic = "force-dynamic"

Expand All @@ -13,26 +13,58 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
const requestId = crypto.randomUUID()
const stream = new SSEStream()
const run = await findRun(Number(id))
const client = new IpcClient(run.socketPath, () => {})
const redis = await redisClient()

const write = async (data: string | object) => {
// console.log(`[stream#${requestId}] write`, data)
const success = await stream.write(data)
let isStreamClosed = false
const channelName = `evals:${run.id}`

if (!success) {
client.disconnect()
const onMessage = async (data: string) => {
if (isStreamClosed || stream.isClosed) {
return
}

try {
const taskEvent = taskEventSchema.parse(JSON.parse(data))
// console.log(`[stream#${requestId}] task event -> ${taskEvent.eventName}`)
const writeSuccess = await stream.write(JSON.stringify(taskEvent))

if (!writeSuccess) {
await disconnect()
}
} catch (_error) {
console.error(`[stream#${requestId}] invalid task event:`, data)
}
}

const disconnect = async () => {
if (isStreamClosed) {
return
}

isStreamClosed = true

try {
await redis.unsubscribe(channelName)
console.log(`[stream#${requestId}] unsubscribed from ${channelName}`)
} catch (error) {
console.error(`[stream#${requestId}] error unsubscribing:`, error)
}

try {
await stream.close()
} catch (error) {
console.error(`[stream#${requestId}] error closing stream:`, error)
}
}

console.log(`[stream#${requestId}] connect`)
client.on(IpcMessageType.Connect, () => write("connect"))
client.on(IpcMessageType.Disconnect, () => write("disconnect"))
client.on(IpcMessageType.TaskEvent, write)
await redis.subscribe(channelName, onMessage)

request.signal.addEventListener("abort", () => {
console.log(`[stream#${requestId}] abort`)
client.disconnect()
stream.close().catch(() => {})

disconnect().catch((error) => {
console.error(`[stream#${requestId}] cleanup error:`, error)
})
})

return stream.getResponse()
Expand Down
12 changes: 0 additions & 12 deletions apps/web-evals/src/app/api/runs/route.ts

This file was deleted.

12 changes: 0 additions & 12 deletions apps/web-evals/src/app/api/tasks/route.ts

This file was deleted.

35 changes: 8 additions & 27 deletions apps/web-evals/src/app/runs/[id]/connection-status.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
"use client"

import { useCallback } from "react"
import { Skull } from "lucide-react"

import { killProcessTree } from "@/lib/server/processes"
import { EventSourceStatus } from "@/hooks/use-event-source"
import { useProcessList } from "@/hooks/use-process-tree"
import type { EventSourceStatus } from "@/hooks/use-event-source"
import { useRunners } from "@/hooks/use-runners"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui"

type ConnectionStatusProps = {
status: EventSourceStatus
pid: number | null
runId: number
}

export const ConnectionStatus = (connectionStatus: ConnectionStatusProps) => {
const { data: pids, isLoading } = useProcessList(connectionStatus.pid)
const status = isLoading ? "loading" : pids === null ? "dead" : connectionStatus.status

const onKill = useCallback(async () => {
if (connectionStatus.pid) {
await killProcessTree(connectionStatus.pid)
window.location.reload()
}
}, [connectionStatus.pid])
const { data: runners, isLoading } = useRunners(connectionStatus.runId)
const status = isLoading ? "loading" : runners === null ? "dead" : connectionStatus.status

return (
<div>
Expand Down Expand Up @@ -52,16 +40,9 @@ export const ConnectionStatus = (connectionStatus: ConnectionStatusProps) => {
</div>
</div>
<div className="flex items-center gap-2">
<div>PIDs:</div>
<div className="font-mono text-sm">{connectionStatus.pid}</div>
{status === "connected" && (
<>
<div className="font-mono text-sm text-muted-foreground">{pids?.join(" ")}</div>
<Button variant="ghost" size="sm" onClick={onKill}>
Kill
<Skull />
</Button>
</>
<div>Runners:</div>
{runners && runners.length > 0 && (
<div className="font-mono text-sm text-muted-foreground">{runners?.join(", ")}</div>
)}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion apps/web-evals/src/app/runs/[id]/run.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function Run({ run }: { run: Run }) {
<div>{run.model}</div>
{run.description && <div className="text-sm text-muted-foreground">{run.description}</div>}
</div>
{!run.taskMetricsId && <ConnectionStatus status={status} pid={run.pid} />}
{!run.taskMetricsId && <ConnectionStatus status={status} runId={run.id} />}
</div>
{!tasks ? (
<LoaderCircle className="size-4 animate-spin" />
Expand Down
66 changes: 0 additions & 66 deletions apps/web-evals/src/app/runs/new/defaults.ts

This file was deleted.

Loading
Loading