Skip to content

Commit f72bb1d

Browse files
committed
More progress
1 parent f2a2367 commit f72bb1d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1879
-974
lines changed

.dockerignore

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,63 @@ knip.json
2929
# next.js
3030
**/.next/
3131
.vercel
32+
33+
# Ignore common development files
34+
node_modules
35+
.git
36+
.gitignore
37+
.dockerignore
38+
.env*
39+
.vscode
40+
.idea
41+
42+
# Ignore build artifacts
43+
dist
44+
build
45+
*.log
46+
*.tmp
47+
.cache
48+
coverage
49+
50+
# Ignore OS files
51+
.DS_Store
52+
Thumbs.db
53+
54+
# Ignore test files
55+
__tests__
56+
*.test.js
57+
*.spec.js
58+
*.test.ts
59+
*.spec.ts
60+
61+
# Ignore development config files
62+
.eslintrc*
63+
.prettierrc*
64+
jest.config*
65+
66+
# Ignore most directories except what we need for the build
67+
apps/
68+
evals/
69+
webview-ui/node_modules
70+
src/node_modules
71+
72+
# Keep essential files for the build
73+
!README.md
74+
!CHANGELOG.md
75+
!package.json
76+
!pnpm-lock.yaml
77+
!pnpm-workspace.yaml
78+
!scripts/bootstrap.mjs
79+
!apps/web-evals/
80+
!src/
81+
!webview-ui/
82+
!packages/evals/.docker/entrypoints/runner.sh
83+
!packages/build/
84+
!packages/cloud/
85+
!packages/config-eslint/
86+
!packages/config-typescript/
87+
!packages/evals/
88+
!packages/ipc/
89+
!packages/telemetry/
90+
!packages/types/
91+
!locales/

apps/web-evals/next.config.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import type { NextConfig } from "next"
22

33
const nextConfig: NextConfig = {
4-
/* config options here */
4+
webpack: (config) => {
5+
config.resolve.extensionAlias = { ".js": [".ts", ".tsx", ".js", ".jsx"] }
6+
return config
7+
},
58
}
69

710
export default nextConfig

apps/web-evals/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"scripts": {
55
"lint": "next lint",
66
"check-types": "tsc -b",
7-
"dev": "next dev --turbopack",
7+
"dev": "scripts/check-services.sh && next dev --turbopack",
88
"format": "prettier --write src",
99
"build": "next build",
1010
"start": "next start"
@@ -24,7 +24,6 @@
2424
"@radix-ui/react-tabs": "^1.1.3",
2525
"@radix-ui/react-tooltip": "^1.1.8",
2626
"@roo-code/evals": "workspace:^",
27-
"@roo-code/ipc": "workspace:^",
2827
"@roo-code/types": "workspace:^",
2928
"@tanstack/react-query": "^5.69.0",
3029
"class-variance-authority": "^0.7.1",
@@ -35,11 +34,11 @@
3534
"next": "^15.2.5",
3635
"next-themes": "^0.4.6",
3736
"p-map": "^7.0.3",
38-
"ps-tree": "^1.2.0",
3937
"react": "^18.3.1",
4038
"react-dom": "^18.3.1",
4139
"react-hook-form": "^7.57.0",
4240
"react-use": "^17.6.0",
41+
"redis": "^5.5.5",
4342
"sonner": "^2.0.5",
4443
"tailwind-merge": "^3.3.0",
4544
"tailwindcss-animate": "^1.0.7",
@@ -53,6 +52,7 @@
5352
"@types/ps-tree": "^1.1.6",
5453
"@types/react": "^18.3.23",
5554
"@types/react-dom": "^18.3.5",
56-
"tailwindcss": "^4"
55+
"tailwindcss": "^4",
56+
"vitest": "^3.2.1"
5757
}
5858
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
3+
if ! docker info &> /dev/null; then
4+
echo "❌ Docker is not running. Please start Docker Desktop and try again."
5+
exit 1
6+
fi
7+
8+
if ! nc -z localhost 5432 2>/dev/null; then
9+
echo "❌ PostgreSQL is not running on port 5432"
10+
echo "💡 Start it with: pnpm --filter @roo-code/evals db:start"
11+
exit 1
12+
fi
13+
14+
if ! nc -z localhost 6379 2>/dev/null; then
15+
echo "❌ Redis is not running on port 6379"
16+
echo "💡 Start it with: pnpm --filter @roo-code/evals redis:start"
17+
exit 1
18+
fi
19+
20+
echo "✅ All required services are running"

apps/web-evals/src/app/api/runs/[id]/stream/route.ts

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { NextRequest } from "next/server"
22

3+
import { taskEventSchema } from "@roo-code/types"
34
import { findRun } from "@roo-code/evals"
4-
import { IpcClient } from "@roo-code/ipc"
5-
import { IpcMessageType } from "@roo-code/types"
65

76
import { SSEStream } from "@/lib/server/sse-stream"
7+
import { redisClient } from "@/lib/server/redis"
88

99
export const dynamic = "force-dynamic"
1010

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

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

22-
if (!success) {
23-
client.disconnect()
21+
const onMessage = async (data: string) => {
22+
if (isStreamClosed || stream.isClosed) {
23+
return
24+
}
25+
26+
try {
27+
const taskEvent = taskEventSchema.parse(JSON.parse(data))
28+
// console.log(`[stream#${requestId}] task event -> ${taskEvent.eventName}`)
29+
const writeSuccess = await stream.write(JSON.stringify(taskEvent))
30+
31+
if (!writeSuccess) {
32+
await disconnect()
33+
}
34+
} catch (_error) {
35+
console.error(`[stream#${requestId}] invalid task event:`, data)
36+
}
37+
}
38+
39+
const disconnect = async () => {
40+
if (isStreamClosed) {
41+
return
42+
}
43+
44+
isStreamClosed = true
45+
46+
try {
47+
await redis.unsubscribe(channelName)
48+
console.log(`[stream#${requestId}] unsubscribed from ${channelName}`)
49+
} catch (error) {
50+
console.error(`[stream#${requestId}] error unsubscribing:`, error)
51+
}
52+
53+
try {
54+
await stream.close()
55+
} catch (error) {
56+
console.error(`[stream#${requestId}] error closing stream:`, error)
2457
}
2558
}
2659

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

3262
request.signal.addEventListener("abort", () => {
3363
console.log(`[stream#${requestId}] abort`)
34-
client.disconnect()
35-
stream.close().catch(() => {})
64+
65+
disconnect().catch((error) => {
66+
console.error(`[stream#${requestId}] cleanup error:`, error)
67+
})
3668
})
3769

3870
return stream.getResponse()

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

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

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

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

apps/web-evals/src/app/runs/[id]/connection-status.tsx

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,17 @@
11
"use client"
22

3-
import { useCallback } from "react"
4-
import { Skull } from "lucide-react"
5-
6-
import { killProcessTree } from "@/lib/server/processes"
7-
import { EventSourceStatus } from "@/hooks/use-event-source"
8-
import { useProcessList } from "@/hooks/use-process-tree"
3+
import type { EventSourceStatus } from "@/hooks/use-event-source"
4+
import { useRunners } from "@/hooks/use-runners"
95
import { cn } from "@/lib/utils"
10-
import { Button } from "@/components/ui"
116

127
type ConnectionStatusProps = {
138
status: EventSourceStatus
14-
pid: number | null
9+
runId: number
1510
}
1611

1712
export const ConnectionStatus = (connectionStatus: ConnectionStatusProps) => {
18-
const { data: pids, isLoading } = useProcessList(connectionStatus.pid)
19-
const status = isLoading ? "loading" : pids === null ? "dead" : connectionStatus.status
20-
21-
const onKill = useCallback(async () => {
22-
if (connectionStatus.pid) {
23-
await killProcessTree(connectionStatus.pid)
24-
window.location.reload()
25-
}
26-
}, [connectionStatus.pid])
13+
const { data: runners, isLoading } = useRunners(connectionStatus.runId)
14+
const status = isLoading ? "loading" : runners === null ? "dead" : connectionStatus.status
2715

2816
return (
2917
<div>
@@ -52,16 +40,9 @@ export const ConnectionStatus = (connectionStatus: ConnectionStatusProps) => {
5240
</div>
5341
</div>
5442
<div className="flex items-center gap-2">
55-
<div>PIDs:</div>
56-
<div className="font-mono text-sm">{connectionStatus.pid}</div>
57-
{status === "connected" && (
58-
<>
59-
<div className="font-mono text-sm text-muted-foreground">{pids?.join(" ")}</div>
60-
<Button variant="ghost" size="sm" onClick={onKill}>
61-
Kill
62-
<Skull />
63-
</Button>
64-
</>
43+
<div>Runners:</div>
44+
{runners && runners.length > 0 && (
45+
<div className="font-mono text-sm text-muted-foreground">{runners?.join(", ")}</div>
6546
)}
6647
</div>
6748
</div>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export function Run({ run }: { run: Run }) {
4848
<div>{run.model}</div>
4949
{run.description && <div className="text-sm text-muted-foreground">{run.description}</div>}
5050
</div>
51-
{!run.taskMetricsId && <ConnectionStatus status={status} pid={run.pid} />}
51+
{!run.taskMetricsId && <ConnectionStatus status={status} runId={run.id} />}
5252
</div>
5353
{!tasks ? (
5454
<LoaderCircle className="size-4 animate-spin" />

apps/web-evals/src/app/runs/new/defaults.ts

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

0 commit comments

Comments
 (0)