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
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,11 @@ yarn-error.log*

# local env files
.env*.local
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# local generated benchmark artifacts
site/messages.json
site/tasks.json
3 changes: 3 additions & 0 deletions .husky/pre-push
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove, do not make it part of pre-push

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove, do not use pre-push

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env sh

./site/scripts/check-missing-trajectory-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1avj7FtT
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ZpkJoMPs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ljyVNHyr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GbY4G3Od
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0vlY8QN5
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
XrjDASVY
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ZAyJoMPs
Original file line number Diff line number Diff line change
Expand Up @@ -2,86 +2,25 @@

import { useEffect, useRef, useState } from "react";
import { Loader2 } from "lucide-react";
import zealtConfig from "@/../zealt.json";

type TrajectoryPageProps = {
name: string;
jobName: string;
title: string;
trajectoryUrl: string | null;
fallbackUrl: string;
};

let messagesCachePromise: Promise<Record<string, unknown>> | null = null;

async function loadMessages() {
if (!messagesCachePromise) {
messagesCachePromise = import("@/messages.json").then((module) => {
const data = module.default || module;
return data as Record<string, unknown>;
});
}

return messagesCachePromise;
}

function getServerBaseUrl() {
const isDev = process.env.NODE_ENV === "development";
return isDev ? "http://localhost:4113" : "https://cc.getpochi.com";
}

export function TrajectoryPage({ name, jobName }: TrajectoryPageProps) {
const [error, setError] = useState<string | null>(null);
const [redirectUrl, setRedirectUrl] = useState<string | null>(null);
export function TrajectoryPage({ title, trajectoryUrl, fallbackUrl }: TrajectoryPageProps) {
const [iframeLoading, setIframeLoading] = useState(false);
const [showIframe, setShowIframe] = useState(false);
const fallbackUrlRef = useRef<string>("");
const iframeRef = useRef<HTMLIFrameElement>(null);

useEffect(() => {
if (!name || !jobName) {
setError("Missing name or jobName parameters.");
if (!trajectoryUrl) {
window.location.replace(fallbackUrl);
return;
}

const fallback = `${zealtConfig.github_repo}/blob/main/jobs/${jobName}/${name}/result.json`;
fallbackUrlRef.current = fallback;

const processRedirect = async () => {
try {
const messagesData = await loadMessages();
const trialMessages = messagesData[name];

if (trialMessages) {
const baseUrl = getServerBaseUrl();
const response = await fetch(`${baseUrl}/api/clips`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ data: { messages: trialMessages } }),
});

if (!response.ok) {
throw new Error(`Failed to post clip: ${response.statusText}`);
}

const { id } = await response.json();
if (id) {
const url = new URL(`/e/${id}`, baseUrl);
url.searchParams.set("embed", "true");
url.searchParams.set("title", name);
url.searchParams.set("theme", "dark")
setRedirectUrl(url.toString());
setIframeLoading(true);
setShowIframe(true);
return;
}
}

window.location.replace(fallback);
} catch (_err) {
window.location.replace(fallback);
}
};

processRedirect();
}, [name, jobName]);
setIframeLoading(true);
}, [trajectoryUrl, fallbackUrl]);

const handleIframeLoad = () => {
setIframeLoading(false);
Expand All @@ -93,18 +32,10 @@ export function TrajectoryPage({ name, jobName }: TrajectoryPageProps) {
};

const handleIframeError = () => {
window.location.replace(fallbackUrlRef.current);
};

if (error) {
return (
<div className="flex flex-col items-center justify-center h-[50vh] space-y-4">
<div className="text-red-500 font-medium">{error}</div>
</div>
);
window.location.replace(fallbackUrl);
}

if (redirectUrl) {
if (trajectoryUrl) {
return (
<div className="fixed inset-0 w-full h-full">
{iframeLoading && (
Expand All @@ -117,16 +48,14 @@ export function TrajectoryPage({ name, jobName }: TrajectoryPageProps) {
</div>
</div>
)}
{showIframe && (
<iframe
ref={iframeRef}
src={redirectUrl}
className="fixed inset-0 w-full h-full border-0 opacity-0"
title={name || "Trial Details"}
onLoad={handleIframeLoad}
onError={handleIframeError}
/>
)}
<iframe
ref={iframeRef}
src={trajectoryUrl}
className="fixed inset-0 w-full h-full border-0 opacity-0"
title={title || "Trial Details"}
onLoad={handleIframeLoad}
onError={handleIframeError}
/>
</div>
);
}
Expand Down
57 changes: 54 additions & 3 deletions site/app/tasks/[name]/[jobName]/trajectory/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import tasksData from "@/tasks.json";
import { TrajectoryPage } from "./components/trajectory-page";
import zealtConfig from "@/../zealt.json";


type RouteParams = {
name: string;
Expand All @@ -9,15 +11,59 @@ type RouteParams = {
type TrialEntry = {
trial_name: string;
job_name: string;
trajectory_id?: string;
};

function buildFallbackUrl(jobName: string, trialName: string) {
return `${zealtConfig.github_repo}/blob/main/jobs/${jobName}/${trialName}/result.json`
}

function getServerBaseUrl() {
return process.env.CLIPS_BASE_URL || 'https://cc.getpochi.com';
}

function buildClipUrl(clipId: string, title: string): string {
const url = new URL(`/e/${clipId}`, getServerBaseUrl());
url.searchParams.set("title", title);
url.searchParams.set("theme", "dark");
return url.toString();
}

function isTrialEntry(value: unknown): value is TrialEntry {
if (typeof value !== "object" || value === null) {
return false;
}

const trial = value as Record<string, unknown>;
return typeof trial.trial_name === "string" && typeof trial.job_name === "string";
if (typeof trial.trial_name !== "string" || typeof trial.job_name !== "string") {
return false;
}

if (typeof trial.trajectory_id === "undefined") {
return true;
}

return typeof trial.trajectory_id === "string";
}

function findTrialEntry(jobName: string, trialName: string): TrialEntry | null {
for (const trials of Object.values(tasksData as Record<string, unknown>)) {
if (!Array.isArray(trials)) {
continue;
}

for (const trial of trials) {
if (!isTrialEntry(trial)) {
continue;
}

if (trial.job_name === jobName && trial.trial_name === trialName) {
return trial;
}
}
}

return null;
}

export const dynamicParams = false;
Expand Down Expand Up @@ -51,13 +97,18 @@ export default async function TrajectoryRoutePage({
params: Promise<RouteParams>;
}) {
const resolvedParams = await params;
const fallbackUrl = buildFallbackUrl(resolvedParams.jobName, resolvedParams.name);
const trialEntry = findTrialEntry(resolvedParams.jobName, resolvedParams.name);
const clipId = trialEntry?.trajectory_id?.trim() || null;
const trajectoryUrl = clipId ? buildClipUrl(clipId, resolvedParams.name) : null;

return (
<div className="w-full h-screen bg-background text-foreground font-sans selection:bg-primary/20 overflow-hidden">
<div className="fixed inset-0 -z-10 h-full w-full bg-background bg-[radial-gradient(#2a2a2a_1px,transparent_1px)] [background-size:16px_16px] [mask-image:radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)] opacity-20 dark:opacity-40"></div>
<TrajectoryPage
name={resolvedParams.name}
jobName={resolvedParams.jobName}
title={resolvedParams.name}
trajectoryUrl={trajectoryUrl}
fallbackUrl={fallbackUrl}
/>
</div>
);
Expand Down
17 changes: 0 additions & 17 deletions site/app/tasks/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,6 @@ function TasksContent() {
const pathname = usePathname();
const searchParams = useSearchParams();

useEffect(() => {
// Preload messages data in the background
const loadMessages = async () => {
try {
await import("../../messages.json");
} catch (error) {
console.error("Failed to preload messages:", error);
}
};

if (typeof window !== "undefined" && "requestIdleCallback" in window) {
window.requestIdleCallback(() => loadMessages());
} else {
setTimeout(loadMessages, 1000); // Fallback for Safari
}
}, []);

const queryQ = searchParams.get("q") || "";
const queryStatusStr = searchParams.get("status") || "";
const queryModelStr = searchParams.get("model") || "";
Expand Down
8 changes: 3 additions & 5 deletions site/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
{
"private": true,
"scripts": {
"dev": "next dev --turbo",
"build": "next build",
"predev": "bun run compute-tasks && bun run compute-messages",
"prebuild": "bun run compute-tasks && bun run compute-messages",
"compute-tasks": "bun run scripts/compute-tasks.ts",
"compute-messages": "bun run scripts/compute-messages.ts"
"predev": "bun run compute-tasks",
"prebuild": "bun run compute-tasks",
"compute-tasks": "bun run scripts/compute-tasks.ts"
},
"dependencies": {
"class-variance-authority": "^0.7.1",
Expand Down
63 changes: 63 additions & 0 deletions site/scripts/check-missing-trajectory-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env bun

import fs from 'fs/promises';
import path from 'path';

type TaskTrialEntry = {
job_name?: unknown;
trial_name?: unknown;
trajectory_id?: unknown;
};

async function main() {
const tasksPath = path.join(process.cwd(), 'site', 'tasks.json');
const raw = await fs.readFile(tasksPath, 'utf-8');
const parsed = JSON.parse(raw) as unknown;

if (typeof parsed !== 'object' || parsed === null) {
throw new Error(`Invalid tasks.json format: ${tasksPath}`);
}

const tasks = parsed as Record<string, unknown>;
const missing: Array<{ taskName: string; jobName: string; trialName: string }> = [];

for (const [taskName, entries] of Object.entries(tasks)) {
if (!Array.isArray(entries)) {
continue;
}

for (const entry of entries) {
if (typeof entry !== 'object' || entry === null) {
continue;
}

const trial = entry as TaskTrialEntry;
const jobName = typeof trial.job_name === 'string' ? trial.job_name : 'unknown-job';
const trialName = typeof trial.trial_name === 'string' ? trial.trial_name : 'unknown-trial';
const trajectoryId = typeof trial.trajectory_id === 'string' ? trial.trajectory_id.trim() : '';

if (!trajectoryId) {
missing.push({ taskName, jobName, trialName });
}
}
}

if (missing.length > 0) {
console.error(`Missing trajectory_id in ${missing.length} trial(s):`);
const maxLines = 100;
for (const item of missing.slice(0, maxLines)) {
console.error(`- ${item.taskName}: ${item.jobName}/${item.trialName}`);
}
if (missing.length > maxLines) {
console.error(`... and ${missing.length - maxLines} more`);
}
process.exit(1);
}

console.log('All trials have trajectory_id.');
}

main().catch((error) => {
console.error(error instanceof Error ? error.message : String(error));
process.exit(1);
});
Loading
Loading