@vercel/agent-eval-playground 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +1 -0
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/cache/.previewinfo +1 -1
  5. package/.next/cache/.rscinfo +1 -1
  6. package/.next/cache/.tsbuildinfo +1 -1
  7. package/.next/cache/config.json +3 -3
  8. package/.next/fallback-build-manifest.json +2 -2
  9. package/.next/prerender-manifest.json +3 -3
  10. package/.next/routes-manifest.json +8 -0
  11. package/.next/server/app/_global-error.html +2 -2
  12. package/.next/server/app/_global-error.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  16. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  17. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  18. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  19. package/.next/server/app/_not-found.html +1 -1
  20. package/.next/server/app/_not-found.rsc +2 -2
  21. package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  22. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  23. package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  24. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  25. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  26. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  27. package/.next/server/app/compare/page.js.nft.json +1 -1
  28. package/.next/server/app/compare/page_client-reference-manifest.js +1 -1
  29. package/.next/server/app/evals/[name]/page.js.nft.json +1 -1
  30. package/.next/server/app/evals/[name]/page_client-reference-manifest.js +1 -1
  31. package/.next/server/app/evals/page.js.nft.json +1 -1
  32. package/.next/server/app/evals/page_client-reference-manifest.js +1 -1
  33. package/.next/server/app/experiments/[name]/[timestamp]/page.js.nft.json +1 -1
  34. package/.next/server/app/experiments/[name]/[timestamp]/page_client-reference-manifest.js +1 -1
  35. package/.next/server/app/experiments/[name]/page/app-paths-manifest.json +3 -0
  36. package/.next/server/app/experiments/[name]/page/build-manifest.json +17 -0
  37. package/.next/server/app/experiments/[name]/page/next-font-manifest.json +12 -0
  38. package/.next/server/app/experiments/[name]/page/react-loadable-manifest.json +1 -0
  39. package/.next/server/app/experiments/[name]/page/server-reference-manifest.json +4 -0
  40. package/.next/server/app/experiments/[name]/page.js +17 -0
  41. package/.next/server/app/experiments/[name]/page.js.map +5 -0
  42. package/.next/server/app/experiments/[name]/page.js.nft.json +1 -0
  43. package/.next/server/app/experiments/[name]/page_client-reference-manifest.js +2 -0
  44. package/.next/server/app/experiments/page.js.nft.json +1 -1
  45. package/.next/server/app/experiments/page_client-reference-manifest.js +1 -1
  46. package/.next/server/app/page.js.nft.json +1 -1
  47. package/.next/server/app/page_client-reference-manifest.js +1 -1
  48. package/.next/server/app/transcript/[experiment]/[timestamp]/[evalName]/[run]/page.js.nft.json +1 -1
  49. package/.next/server/app/transcript/[experiment]/[timestamp]/[evalName]/[run]/page_client-reference-manifest.js +1 -1
  50. package/.next/server/app-paths-manifest.json +1 -0
  51. package/.next/server/chunks/ssr/730ea_playground__next-internal_server_app_experiments_[name]_page_actions_9b119c24.js +3 -0
  52. package/.next/server/chunks/ssr/730ea_playground__next-internal_server_app_experiments_[name]_page_actions_9b119c24.js.map +1 -0
  53. package/.next/server/chunks/ssr/[root-of-the-server]__3702960d._.js +1 -1
  54. package/.next/server/chunks/ssr/[root-of-the-server]__3702960d._.js.map +1 -1
  55. package/.next/server/chunks/ssr/[root-of-the-server]__4228b9c3._.js +1 -1
  56. package/.next/server/chunks/ssr/[root-of-the-server]__4228b9c3._.js.map +1 -1
  57. package/.next/server/chunks/ssr/[root-of-the-server]__a216b589._.js +1 -1
  58. package/.next/server/chunks/ssr/[root-of-the-server]__a216b589._.js.map +1 -1
  59. package/.next/server/chunks/ssr/[root-of-the-server]__ac2a456c._.js +1 -1
  60. package/.next/server/chunks/ssr/[root-of-the-server]__ac2a456c._.js.map +1 -1
  61. package/.next/server/chunks/ssr/[root-of-the-server]__aca11d57._.js +3 -0
  62. package/.next/server/chunks/ssr/[root-of-the-server]__aca11d57._.js.map +1 -0
  63. package/.next/server/chunks/ssr/[root-of-the-server]__b8fc4094._.js +1 -1
  64. package/.next/server/chunks/ssr/[root-of-the-server]__b8fc4094._.js.map +1 -1
  65. package/.next/server/chunks/ssr/[root-of-the-server]__c73d60f7._.js +1 -1
  66. package/.next/server/chunks/ssr/[root-of-the-server]__c73d60f7._.js.map +1 -1
  67. package/.next/server/chunks/ssr/[root-of-the-server]__f286e9a8._.js +1 -1
  68. package/.next/server/chunks/ssr/[root-of-the-server]__f286e9a8._.js.map +1 -1
  69. package/.next/server/chunks/ssr/_fa6de7c6._.js +4 -0
  70. package/.next/server/chunks/ssr/_fa6de7c6._.js.map +1 -0
  71. package/.next/server/chunks/ssr/packages_playground_components_TranscriptViewer_tsx_ba8ff423._.js +1 -1
  72. package/.next/server/chunks/ssr/packages_playground_components_TranscriptViewer_tsx_ba8ff423._.js.map +1 -1
  73. package/.next/server/next-font-manifest.js +1 -1
  74. package/.next/server/next-font-manifest.json +5 -0
  75. package/.next/server/pages/404.html +1 -1
  76. package/.next/server/pages/500.html +2 -2
  77. package/.next/server/server-reference-manifest.js +1 -1
  78. package/.next/server/server-reference-manifest.json +1 -1
  79. package/.next/static/chunks/225815167619f532.css +4 -0
  80. package/.next/static/chunks/{419a92b5c17e94a8.js → 405f69d0b8bdad66.js} +1 -1
  81. package/.next/trace +1 -1
  82. package/.next/trace-build +1 -1
  83. package/.next/types/routes.d.ts +2 -1
  84. package/.next/types/validator.ts +9 -0
  85. package/app/experiments/[name]/page.tsx +124 -0
  86. package/components/ExperimentList.tsx +34 -14
  87. package/components/O11ySummary.tsx +14 -9
  88. package/package.json +1 -1
  89. package/.next/static/chunks/b7a73603aa202938.css +0 -4
  90. /package/.next/static/{e-_lBXo-NK4NsMjf8KVfw → 7WvStP5_xMiGBpz094_IB}/_buildManifest.js +0 -0
  91. /package/.next/static/{e-_lBXo-NK4NsMjf8KVfw → 7WvStP5_xMiGBpz094_IB}/_clientMiddlewareManifest.json +0 -0
  92. /package/.next/static/{e-_lBXo-NK4NsMjf8KVfw → 7WvStP5_xMiGBpz094_IB}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/playground/lib/data.ts","../../../../../../packages/playground/components/ComparePage.tsx/__nextjs-internal-proxy.mjs","../../../../../../packages/playground/app/compare/page.tsx"],"sourcesContent":["/**\n * Server-side data access for the playground.\n * Reads JSON files from the results/ and evals/ directories.\n * Directory paths are provided via RESULTS_DIR and EVALS_DIR env vars.\n */\n\nimport { readdirSync, readFileSync, existsSync } from \"fs\";\nimport { join, resolve } from \"path\";\n\nfunction getResultsDir(): string {\n return resolve(process.env.RESULTS_DIR || \"./results\");\n}\n\nfunction getEvalsDir(): string {\n return resolve(process.env.EVALS_DIR || \"./evals\");\n}\n\n/** Check if a directory name looks like an ISO timestamp (used as run ID) */\nfunction isTimestamp(name: string): boolean {\n return /^\\d{4}-\\d{2}-\\d{2}T/.test(name);\n}\n\n/** List experiments from the results directory. Pass limit to cap expensive per-item reads. */\nexport function listExperiments(limit?: number) {\n const resultsDir = getResultsDir();\n\n if (!existsSync(resultsDir)) {\n return { items: [], total: 0 };\n }\n\n // Discover experiments by walking the directory tree until we find\n // timestamp directories. The path from resultsDir to the parent of the\n // first timestamp is the experiment name (e.g. \"my-config/openai/gpt-5.2-codex\").\n const entries: string[] = [];\n\n function walk(dir: string, prefix: string) {\n const children = readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n\n // If any child looks like a timestamp, this directory is an experiment\n if (children.some(isTimestamp)) {\n entries.push(prefix);\n return;\n }\n\n // Otherwise keep recursing\n for (const child of children) {\n walk(join(dir, child), prefix ? `${prefix}/${child}` : child);\n }\n }\n\n walk(resultsDir, \"\");\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const expDir = join(resultsDir, name);\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && isTimestamp(e.name))\n .map((e) => e.name)\n .sort()\n .reverse();\n\n let latestPassRate: number | undefined;\n let latestTotalRuns = 0;\n let latestPassedRuns = 0;\n\n if (timestamps.length > 0) {\n const latestDir = join(expDir, timestamps[0]);\n const evalDirs = readdirSync(latestDir, { withFileTypes: true }).filter(\n (e) => e.isDirectory()\n );\n\n for (const evalDir of evalDirs) {\n const summaryPath = join(latestDir, evalDir.name, \"summary.json\");\n if (existsSync(summaryPath)) {\n try {\n const summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n latestTotalRuns += summary.totalRuns ?? 0;\n latestPassedRuns += summary.passedRuns ?? 0;\n } catch {\n // Skip invalid summary files\n }\n }\n }\n\n if (latestTotalRuns > 0) {\n latestPassRate = (latestPassedRuns / latestTotalRuns) * 100;\n }\n }\n\n return {\n name,\n timestamps,\n latestTimestamp: timestamps[0] ?? null,\n latestPassRate,\n latestTotalRuns,\n latestPassedRuns,\n };\n });\n\n return { items, total };\n}\n\n/** Get timestamps for a specific experiment */\nexport function getExperiment(name: string) {\n const expDir = join(getResultsDir(), name);\n\n if (!existsSync(expDir)) {\n return null;\n }\n\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .sort()\n .reverse();\n\n return { name, timestamps, latestTimestamp: timestamps[0] ?? null };\n}\n\n/** Get full experiment detail for a specific timestamp */\nexport function getExperimentDetail(name: string, timestamp: string) {\n const runDir = join(getResultsDir(), name, timestamp);\n\n if (!existsSync(runDir)) {\n return null;\n }\n\n // Recursively discover all eval result directories (directories with summary.json)\n const evalDirs: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\") || entry.name.startsWith(\"run-\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const summaryPath = join(entryPath, \"summary.json\");\n\n // Check if this is an eval result directory (has summary.json)\n if (existsSync(summaryPath)) {\n evalDirs.push(relativePath);\n } else {\n // Not an eval result, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(runDir);\n evalDirs.sort();\n\n const evals = evalDirs.map((evalName) => {\n const evalDir = join(runDir, evalName);\n const summaryPath = join(evalDir, \"summary.json\");\n\n let summary = {\n totalRuns: 0,\n passedRuns: 0,\n passRate: \"0%\",\n meanDuration: 0,\n };\n if (existsSync(summaryPath)) {\n try {\n summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n } catch {\n // Use defaults\n }\n }\n\n // List run directories\n const runDirs = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && e.name.startsWith(\"run-\"))\n .map((e) => e.name)\n .sort();\n\n // Read each run's result.json\n const runs = runDirs.map((runDirName) => {\n const resultPath = join(evalDir, runDirName, \"result.json\");\n let result = null;\n if (existsSync(resultPath)) {\n try {\n result = JSON.parse(readFileSync(resultPath, \"utf-8\"));\n } catch {\n // Skip\n }\n }\n return { name: runDirName, result };\n });\n\n return {\n name: evalName,\n totalRuns: summary.totalRuns,\n passedRuns: summary.passedRuns,\n passRate:\n typeof summary.passRate === \"string\"\n ? parseFloat(summary.passRate)\n : summary.passRate,\n meanDuration: summary.meanDuration,\n runs,\n };\n });\n\n return { name, timestamp, evals };\n}\n\n/** Get result for a specific run */\nexport function getRunResult(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const resultPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"result.json\"\n );\n\n if (!existsSync(resultPath)) {\n return null;\n }\n\n try {\n return { result: JSON.parse(readFileSync(resultPath, \"utf-8\")) };\n } catch {\n return null;\n }\n}\n\n/** Get parsed transcript for a specific run */\nexport function getTranscript(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const transcriptPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"transcript.json\"\n );\n\n if (!existsSync(transcriptPath)) {\n return null;\n }\n\n try {\n return JSON.parse(readFileSync(transcriptPath, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\n/** List evals from the evals directory. Pass limit to cap per-item reads. */\nexport function listEvals(limit?: number) {\n const evalsDir = getEvalsDir();\n\n if (!existsSync(evalsDir)) {\n return { items: [], total: 0 };\n }\n\n // Recursively discover all evals (directories with PROMPT.md)\n const entries: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const promptPath = join(entryPath, \"PROMPT.md\");\n\n // Check if this is an eval directory (has PROMPT.md)\n if (existsSync(promptPath)) {\n entries.push(relativePath);\n } else {\n // Not an eval, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(evalsDir);\n entries.sort();\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const evalDir = join(evalsDir, name);\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n const files = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isFile())\n .map((e) => e.name);\n\n return { name, prompt, files };\n });\n\n return { items, total };\n}\n\n/** Get detail for a specific eval */\nexport function getEvalDetail(name: string) {\n const evalDir = join(getEvalsDir(), name);\n\n if (!existsSync(evalDir)) {\n return null;\n }\n\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n // Recursively list files\n const files: string[] = [];\n function walk(dir: string, prefix: string) {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name === \"node_modules\" || entry.name === \".git\") continue;\n const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (entry.isDirectory()) {\n walk(join(dir, entry.name), relativePath);\n } else {\n files.push(relativePath);\n }\n }\n }\n walk(evalDir, \"\");\n\n // Read file contents for key files\n const fileContents: Record<string, string> = {};\n const keyFiles = [\"PROMPT.md\", \"EVAL.ts\", \"EVAL.tsx\", \"package.json\"];\n for (const file of keyFiles) {\n const filePath = join(evalDir, file);\n if (existsSync(filePath)) {\n try {\n fileContents[file] = readFileSync(filePath, \"utf-8\");\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return { name, prompt, files, fileContents };\n}\n","// This file is generated by next-core EcmascriptClientReferenceModule.\nimport { registerClientReference } from \"react-server-dom-turbopack/server\";\nexport const ComparePage = registerClientReference(\n function() { throw new Error(\"Attempted to call ComparePage() from the server but ComparePage is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ComparePage.tsx\",\n \"ComparePage\",\n);\n","import { ComparePage } from \"@/components/ComparePage\";\nimport { listExperiments, getExperimentDetail } from \"@/lib/data\";\n\nexport const dynamic = \"force-dynamic\";\n\nfunction formatTimestamp(ts: string): string {\n try {\n const isoString = ts.replace(/T(\\d{2})-(\\d{2})-(\\d{2})/, \"T$1:$2:$3\");\n const date = new Date(isoString);\n if (isNaN(date.getTime())) return ts;\n return date.toLocaleString();\n } catch {\n return ts;\n }\n}\n\nexport default async function CompareRoute() {\n const { items: experiments } = listExperiments();\n\n // Build options and details map server-side to avoid hydration mismatch\n // (toLocaleString differs between Node.js and browser)\n const options = experiments.flatMap((exp) =>\n exp.timestamps.map((ts) => ({\n value: `${exp.name}|||${ts}`,\n label: `${exp.name} / ${formatTimestamp(ts)}`,\n }))\n );\n\n const detailsMap: Record<string, ReturnType<typeof getExperimentDetail>> = {};\n for (const exp of experiments) {\n for (const ts of exp.timestamps) {\n const detail = getExperimentDetail(exp.name, ts);\n if (detail) {\n detailsMap[`${exp.name}|||${ts}`] = detail;\n }\n }\n }\n\n return <ComparePage options={options} detailsMap={detailsMap} />;\n}\n"],"names":[],"mappings":"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","ignoreList":[1]}
1
+ {"version":3,"sources":["../../../../../../packages/playground/lib/data.ts","../../../../../../packages/playground/components/ComparePage.tsx/__nextjs-internal-proxy.mjs","../../../../../../packages/playground/app/compare/page.tsx"],"sourcesContent":["/**\n * Server-side data access for the playground.\n * Reads JSON files from the results/ and evals/ directories.\n * Directory paths are provided via RESULTS_DIR and EVALS_DIR env vars.\n */\n\nimport { readdirSync, readFileSync, existsSync } from \"fs\";\nimport { join, resolve } from \"path\";\n\nfunction getResultsDir(): string {\n return resolve(process.env.RESULTS_DIR || \"./results\");\n}\n\nfunction getEvalsDir(): string {\n return resolve(process.env.EVALS_DIR || \"./evals\");\n}\n\n/** Check if a directory name looks like an ISO timestamp (used as run ID) */\nfunction isTimestamp(name: string): boolean {\n return /^\\d{4}-\\d{2}-\\d{2}T/.test(name);\n}\n\n/** List experiments from the results directory. Pass limit to cap expensive per-item reads. */\nexport function listExperiments(limit?: number) {\n const resultsDir = getResultsDir();\n\n if (!existsSync(resultsDir)) {\n return { items: [], total: 0 };\n }\n\n // Discover experiments by walking the directory tree until we find\n // timestamp directories. The path from resultsDir to the parent of the\n // first timestamp is the experiment name (e.g. \"my-config/openai/gpt-5.2-codex\").\n const entries: string[] = [];\n\n function walk(dir: string, prefix: string) {\n const children = readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n\n // If any child looks like a timestamp, this directory is an experiment\n if (children.some(isTimestamp)) {\n entries.push(prefix);\n return;\n }\n\n // Otherwise keep recursing\n for (const child of children) {\n walk(join(dir, child), prefix ? `${prefix}/${child}` : child);\n }\n }\n\n walk(resultsDir, \"\");\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const expDir = join(resultsDir, name);\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && isTimestamp(e.name))\n .map((e) => e.name)\n .sort()\n .reverse();\n\n let latestPassRate: number | undefined;\n let latestTotalRuns = 0;\n let latestPassedRuns = 0;\n\n if (timestamps.length > 0) {\n const latestDir = join(expDir, timestamps[0]);\n const evalDirs = readdirSync(latestDir, { withFileTypes: true }).filter(\n (e) => e.isDirectory()\n );\n\n for (const evalDir of evalDirs) {\n const summaryPath = join(latestDir, evalDir.name, \"summary.json\");\n if (existsSync(summaryPath)) {\n try {\n const summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n latestTotalRuns += summary.totalRuns ?? 0;\n latestPassedRuns += summary.passedRuns ?? 0;\n } catch {\n // Skip invalid summary files\n }\n }\n }\n\n if (latestTotalRuns > 0) {\n latestPassRate = (latestPassedRuns / latestTotalRuns) * 100;\n }\n }\n\n return {\n name,\n timestamps,\n latestTimestamp: timestamps[0] ?? null,\n latestPassRate,\n latestTotalRuns,\n latestPassedRuns,\n };\n });\n\n return { items, total };\n}\n\n/** Get timestamps for a specific experiment */\nexport function getExperiment(name: string) {\n const expDir = join(getResultsDir(), name);\n\n if (!existsSync(expDir)) {\n return null;\n }\n\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .sort()\n .reverse();\n\n return { name, timestamps, latestTimestamp: timestamps[0] ?? null };\n}\n\n/** Get full experiment detail for a specific timestamp */\nexport function getExperimentDetail(name: string, timestamp: string) {\n const runDir = join(getResultsDir(), name, timestamp);\n\n if (!existsSync(runDir)) {\n return null;\n }\n\n // Recursively discover all eval result directories (directories with summary.json)\n const evalDirs: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\") || entry.name.startsWith(\"run-\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const summaryPath = join(entryPath, \"summary.json\");\n\n // Check if this is an eval result directory (has summary.json)\n if (existsSync(summaryPath)) {\n evalDirs.push(relativePath);\n } else {\n // Not an eval result, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(runDir);\n evalDirs.sort();\n\n const evals = evalDirs.map((evalName) => {\n const evalDir = join(runDir, evalName);\n const summaryPath = join(evalDir, \"summary.json\");\n\n let summary = {\n totalRuns: 0,\n passedRuns: 0,\n passRate: \"0%\",\n meanDuration: 0,\n };\n if (existsSync(summaryPath)) {\n try {\n summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n } catch {\n // Use defaults\n }\n }\n\n // List run directories\n const runDirs = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && e.name.startsWith(\"run-\"))\n .map((e) => e.name)\n .sort();\n\n // Read each run's result.json\n const runs = runDirs.map((runDirName) => {\n const resultPath = join(evalDir, runDirName, \"result.json\");\n let result = null;\n if (existsSync(resultPath)) {\n try {\n result = JSON.parse(readFileSync(resultPath, \"utf-8\"));\n } catch {\n // Skip\n }\n }\n return { name: runDirName, result };\n });\n\n return {\n name: evalName,\n totalRuns: summary.totalRuns,\n passedRuns: summary.passedRuns,\n passRate:\n typeof summary.passRate === \"string\"\n ? parseFloat(summary.passRate)\n : summary.passRate,\n meanDuration: summary.meanDuration,\n runs,\n };\n });\n\n return { name, timestamp, evals };\n}\n\n/** Get result for a specific run */\nexport function getRunResult(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const resultPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"result.json\"\n );\n\n if (!existsSync(resultPath)) {\n return null;\n }\n\n try {\n return { result: JSON.parse(readFileSync(resultPath, \"utf-8\")) };\n } catch {\n return null;\n }\n}\n\n/** Get parsed transcript for a specific run */\nexport function getTranscript(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const transcriptPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"transcript.json\"\n );\n\n if (!existsSync(transcriptPath)) {\n return null;\n }\n\n try {\n return JSON.parse(readFileSync(transcriptPath, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\n/** List evals from the evals directory. Pass limit to cap per-item reads. */\nexport function listEvals(limit?: number) {\n const evalsDir = getEvalsDir();\n\n if (!existsSync(evalsDir)) {\n return { items: [], total: 0 };\n }\n\n // Recursively discover all evals (directories with PROMPT.md)\n const entries: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const promptPath = join(entryPath, \"PROMPT.md\");\n\n // Check if this is an eval directory (has PROMPT.md)\n if (existsSync(promptPath)) {\n entries.push(relativePath);\n } else {\n // Not an eval, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(evalsDir);\n entries.sort();\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const evalDir = join(evalsDir, name);\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n const files = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isFile())\n .map((e) => e.name);\n\n return { name, prompt, files };\n });\n\n return { items, total };\n}\n\n/** Get detail for a specific eval */\nexport function getEvalDetail(name: string) {\n const evalDir = join(getEvalsDir(), name);\n\n if (!existsSync(evalDir)) {\n return null;\n }\n\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n // Recursively list files\n const files: string[] = [];\n function walk(dir: string, prefix: string) {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name === \"node_modules\" || entry.name === \".git\") continue;\n const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (entry.isDirectory()) {\n walk(join(dir, entry.name), relativePath);\n } else {\n files.push(relativePath);\n }\n }\n }\n walk(evalDir, \"\");\n\n // Read file contents for key files\n const fileContents: Record<string, string> = {};\n const keyFiles = [\"PROMPT.md\", \"EVAL.ts\", \"EVAL.tsx\", \"package.json\"];\n for (const file of keyFiles) {\n const filePath = join(evalDir, file);\n if (existsSync(filePath)) {\n try {\n fileContents[file] = readFileSync(filePath, \"utf-8\");\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return { name, prompt, files, fileContents };\n}\n","// This file is generated by next-core EcmascriptClientReferenceModule.\nimport { registerClientReference } from \"react-server-dom-turbopack/server\";\nexport const ComparePage = registerClientReference(\n function() { throw new Error(\"Attempted to call ComparePage() from the server but ComparePage is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ComparePage.tsx\",\n \"ComparePage\",\n);\n","import { ComparePage } from \"@/components/ComparePage\";\nimport { listExperiments, getExperimentDetail } from \"@/lib/data\";\n\nexport const dynamic = \"force-dynamic\";\n\nfunction formatTimestamp(ts: string): string {\n try {\n const isoString = ts.replace(/T(\\d{2})-(\\d{2})-(\\d{2})/, \"T$1:$2:$3\");\n const date = new Date(isoString);\n if (isNaN(date.getTime())) return ts;\n return date.toLocaleString();\n } catch {\n return ts;\n }\n}\n\nexport default async function CompareRoute() {\n const { items: experiments } = listExperiments();\n\n // Build options and details map server-side to avoid hydration mismatch\n // (toLocaleString differs between Node.js and browser)\n const options = experiments.flatMap((exp) =>\n exp.timestamps.map((ts) => ({\n value: `${exp.name}|||${ts}`,\n label: `${exp.name} / ${formatTimestamp(ts)}`,\n }))\n );\n\n const detailsMap: Record<string, ReturnType<typeof getExperimentDetail>> = {};\n for (const exp of experiments) {\n for (const ts of exp.timestamps) {\n const detail = getExperimentDetail(exp.name, ts);\n if (detail) {\n detailsMap[`${exp.name}|||${ts}`] = detail;\n }\n }\n }\n\n return <ComparePage options={options} detailsMap={detailsMap} />;\n}\n"],"names":[],"mappings":"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","ignoreList":[1]}
@@ -1,3 +1,3 @@
1
- module.exports=[69046,a=>{a.n(a.i(80979))},43619,a=>{a.n(a.i(79962))},13718,a=>{a.n(a.i(85523))},18198,a=>{a.n(a.i(45518))},62212,a=>{a.n(a.i(66114))},22734,(a,b,c)=>{b.exports=a.x("fs",()=>require("fs"))},5419,a=>{"use strict";var b=a.i(22734),c=a.i(14747);function d(){return(0,c.resolve)(process.env.RESULTS_DIR||"./results")}function e(){return(0,c.resolve)(process.env.EVALS_DIR||"./evals")}function f(a){return/^\d{4}-\d{2}-\d{2}T/.test(a)}function g(a){let e=d();if(!(0,b.existsSync)(e))return{items:[],total:0};let g=[];!function a(d,e){let h=(0,b.readdirSync)(d,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name);if(h.some(f))return void g.push(e);for(let b of h)a((0,c.join)(d,b),e?`${e}/${b}`:b)}(e,"");let h=g.length;return{items:(a?g.slice(0,a):g).map(a=>{let d,g=(0,c.join)(e,a),h=(0,b.readdirSync)(g,{withFileTypes:!0}).filter(a=>a.isDirectory()&&f(a.name)).map(a=>a.name).sort().reverse(),i=0,j=0;if(h.length>0){let a=(0,c.join)(g,h[0]);for(let d of(0,b.readdirSync)(a,{withFileTypes:!0}).filter(a=>a.isDirectory())){let e=(0,c.join)(a,d.name,"summary.json");if((0,b.existsSync)(e))try{let a=JSON.parse((0,b.readFileSync)(e,"utf-8"));i+=a.totalRuns??0,j+=a.passedRuns??0}catch{}}i>0&&(d=j/i*100)}return{name:a,timestamps:h,latestTimestamp:h[0]??null,latestPassRate:d,latestTotalRuns:i,latestPassedRuns:j}}),total:h}}function h(a,e){let f=(0,c.join)(d(),a,e);if(!(0,b.existsSync)(f))return null;let g=[];return!function a(d,e=""){for(let f of(0,b.readdirSync)(d,{withFileTypes:!0})){if(!f.isDirectory()||f.name.startsWith(".")||f.name.startsWith("run-"))continue;let h=e?`${e}/${f.name}`:f.name,i=(0,c.join)(d,f.name),j=(0,c.join)(i,"summary.json");(0,b.existsSync)(j)?g.push(h):a(i,h)}}(f),g.sort(),{name:a,timestamp:e,evals:g.map(a=>{let d=(0,c.join)(f,a),e=(0,c.join)(d,"summary.json"),g={totalRuns:0,passedRuns:0,passRate:"0%",meanDuration:0};if((0,b.existsSync)(e))try{g=JSON.parse((0,b.readFileSync)(e,"utf-8"))}catch{}let h=(0,b.readdirSync)(d,{withFileTypes:!0}).filter(a=>a.isDirectory()&&a.name.startsWith("run-")).map(a=>a.name).sort().map(a=>{let e=(0,c.join)(d,a,"result.json"),f=null;if((0,b.existsSync)(e))try{f=JSON.parse((0,b.readFileSync)(e,"utf-8"))}catch{}return{name:a,result:f}});return{name:a,totalRuns:g.totalRuns,passedRuns:g.passedRuns,passRate:"string"==typeof g.passRate?parseFloat(g.passRate):g.passRate,meanDuration:g.meanDuration,runs:h}})}}function i(a,e,f,g){let h=(0,c.join)(d(),a,e,f,g,"transcript.json");if(!(0,b.existsSync)(h))return null;try{return JSON.parse((0,b.readFileSync)(h,"utf-8"))}catch{return null}}function j(a){let d=e();if(!(0,b.existsSync)(d))return{items:[],total:0};let f=[];!function a(d,e=""){for(let g of(0,b.readdirSync)(d,{withFileTypes:!0})){if(!g.isDirectory()||g.name.startsWith("."))continue;let h=e?`${e}/${g.name}`:g.name,i=(0,c.join)(d,g.name),j=(0,c.join)(i,"PROMPT.md");(0,b.existsSync)(j)?f.push(h):a(i,h)}}(d),f.sort();let g=f.length;return{items:(a?f.slice(0,a):f).map(a=>{let e=(0,c.join)(d,a),f=(0,c.join)(e,"PROMPT.md"),g="";return(0,b.existsSync)(f)&&(g=(0,b.readFileSync)(f,"utf-8")),{name:a,prompt:g,files:(0,b.readdirSync)(e,{withFileTypes:!0}).filter(a=>a.isFile()).map(a=>a.name)}}),total:g}}function k(a){let d=(0,c.join)(e(),a);if(!(0,b.existsSync)(d))return null;let f=(0,c.join)(d,"PROMPT.md"),g="";(0,b.existsSync)(f)&&(g=(0,b.readFileSync)(f,"utf-8"));let h=[];!function a(d,e){for(let f of(0,b.readdirSync)(d,{withFileTypes:!0})){if("node_modules"===f.name||".git"===f.name)continue;let b=e?`${e}/${f.name}`:f.name;f.isDirectory()?a((0,c.join)(d,f.name),b):h.push(b)}}(d,"");let i={};for(let a of["PROMPT.md","EVAL.ts","EVAL.tsx","package.json"]){let e=(0,c.join)(d,a);if((0,b.existsSync)(e))try{i[a]=(0,b.readFileSync)(e,"utf-8")}catch{}}return{name:a,prompt:g,files:h,fileContents:i}}a.s(["getEvalDetail",()=>k,"getExperimentDetail",()=>h,"getTranscript",()=>i,"listEvals",()=>j,"listExperiments",()=>g])},35613,a=>{"use strict";a.s(["Tabs",()=>c,"TabsContent",()=>d,"TabsList",()=>e,"TabsTrigger",()=>f,"tabsListVariants",()=>g]);var b=a.i(11857);let c=(0,b.registerClientReference)(function(){throw Error("Attempted to call Tabs() from the server but Tabs is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx <module evaluation>","Tabs"),d=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsContent() from the server but TabsContent is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx <module evaluation>","TabsContent"),e=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsList() from the server but TabsList is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx <module evaluation>","TabsList"),f=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsTrigger() from the server but TabsTrigger is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx <module evaluation>","TabsTrigger"),g=(0,b.registerClientReference)(function(){throw Error("Attempted to call tabsListVariants() from the server but tabsListVariants is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx <module evaluation>","tabsListVariants")},84346,a=>{"use strict";a.s(["Tabs",()=>c,"TabsContent",()=>d,"TabsList",()=>e,"TabsTrigger",()=>f,"tabsListVariants",()=>g]);var b=a.i(11857);let c=(0,b.registerClientReference)(function(){throw Error("Attempted to call Tabs() from the server but Tabs is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx","Tabs"),d=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsContent() from the server but TabsContent is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx","TabsContent"),e=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsList() from the server but TabsList is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx","TabsList"),f=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsTrigger() from the server but TabsTrigger is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx","TabsTrigger"),g=(0,b.registerClientReference)(function(){throw Error("Attempted to call tabsListVariants() from the server but tabsListVariants is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx","tabsListVariants")},84336,a=>{"use strict";a.i(35613);var b=a.i(84346);a.n(b)},28372,a=>{"use strict";a.s(["ScrollArea",()=>c,"ScrollBar",()=>d]);var b=a.i(11857);let c=(0,b.registerClientReference)(function(){throw Error("Attempted to call ScrollArea() from the server but ScrollArea is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/scroll-area.tsx <module evaluation>","ScrollArea"),d=(0,b.registerClientReference)(function(){throw Error("Attempted to call ScrollBar() from the server but ScrollBar is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/scroll-area.tsx <module evaluation>","ScrollBar")},22448,a=>{"use strict";a.s(["ScrollArea",()=>c,"ScrollBar",()=>d]);var b=a.i(11857);let c=(0,b.registerClientReference)(function(){throw Error("Attempted to call ScrollArea() from the server but ScrollArea is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/scroll-area.tsx","ScrollArea"),d=(0,b.registerClientReference)(function(){throw Error("Attempted to call ScrollBar() from the server but ScrollBar is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/scroll-area.tsx","ScrollBar")},46804,a=>{"use strict";a.i(28372);var b=a.i(22448);a.n(b)},86568,a=>{"use strict";var b=a.i(7997);a.i(70396);var c=a.i(73727),d=a.i(95936),e=a.i(20954),f=a.i(84336),g=a.i(46804);function h({data:a}){let c=a.fileContents?.["EVAL.ts"]||a.fileContents?.["EVAL.tsx"],e=a.fileContents?.["EVAL.ts"]?"EVAL.ts":"EVAL.tsx",h=a.fileContents?.["package.json"];return(0,b.jsxs)("div",{className:"space-y-6",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[(0,b.jsx)(d.default,{href:"/evals",className:"cursor-pointer hover:underline underline-offset-4",children:"Evals"}),(0,b.jsx)("span",{children:"/"}),(0,b.jsx)("span",{children:a.name})]}),(0,b.jsx)("div",{children:(0,b.jsx)("h1",{className:"text-2xl font-bold tracking-tight",children:a.name})}),(0,b.jsxs)(f.Tabs,{defaultValue:"prompt",className:"w-full",children:[(0,b.jsxs)(f.TabsList,{children:[(0,b.jsx)(f.TabsTrigger,{value:"prompt",children:"PROMPT.md"}),c&&(0,b.jsx)(f.TabsTrigger,{value:"eval",children:e}),h&&(0,b.jsx)(f.TabsTrigger,{value:"package",children:"package.json"}),(0,b.jsx)(f.TabsTrigger,{value:"files",children:"Files"})]}),(0,b.jsx)(f.TabsContent,{value:"prompt",className:"mt-4",children:(0,b.jsx)(g.ScrollArea,{className:"h-[calc(100vh-300px)]",children:(0,b.jsx)("pre",{className:"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4",children:a.prompt||"No PROMPT.md found."})})}),c&&(0,b.jsx)(f.TabsContent,{value:"eval",className:"mt-4",children:(0,b.jsx)(g.ScrollArea,{className:"h-[calc(100vh-300px)]",children:(0,b.jsx)("pre",{className:"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4 overflow-x-auto",children:c})})}),h&&(0,b.jsx)(f.TabsContent,{value:"package",className:"mt-4",children:(0,b.jsx)(g.ScrollArea,{className:"h-[calc(100vh-300px)]",children:(0,b.jsx)("pre",{className:"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4 overflow-x-auto",children:h})})}),(0,b.jsxs)(f.TabsContent,{value:"files",className:"mt-4",children:[(0,b.jsxs)("div",{className:"text-sm text-muted-foreground mb-3",children:[a.files.length," files"]}),(0,b.jsx)("div",{className:"space-y-1",children:a.files.map(a=>(0,b.jsxs)("div",{className:"flex items-center gap-2 text-sm font-mono bg-muted rounded-lg px-3 py-1.5",children:[(0,b.jsx)(i,{filename:a}),(0,b.jsx)("span",{children:a})]},a))})]})]})]})}function i({filename:a}){let c=a.split(".").pop()?.toLowerCase();return(0,b.jsx)(e.Badge,{variant:"outline",className:"text-[10px] font-mono px-1 py-0 h-5 w-6 flex items-center justify-center",children:{ts:"TS",tsx:"TX",js:"JS",json:"{}",md:"MD",css:"CS",html:"HT"}[c||""]||"F"})}var j=a.i(5419);async function k({params:a}){let{name:d}=await a,e=decodeURIComponent(d),f=(0,j.getEvalDetail)(e);return f||(0,c.notFound)(),(0,b.jsx)(h,{data:f})}a.s(["default",()=>k,"dynamic",0,"force-dynamic"],86568)}];
1
+ module.exports=[69046,a=>{a.n(a.i(80979))},43619,a=>{a.n(a.i(79962))},13718,a=>{a.n(a.i(85523))},18198,a=>{a.n(a.i(45518))},62212,a=>{a.n(a.i(66114))},22734,(a,b,c)=>{b.exports=a.x("fs",()=>require("fs"))},5419,a=>{"use strict";var b=a.i(22734),c=a.i(14747);function d(){return(0,c.resolve)(process.env.RESULTS_DIR||"./results")}function e(){return(0,c.resolve)(process.env.EVALS_DIR||"./evals")}function f(a){return/^\d{4}-\d{2}-\d{2}T/.test(a)}function g(a){let e=d();if(!(0,b.existsSync)(e))return{items:[],total:0};let g=[];!function a(d,e){let h=(0,b.readdirSync)(d,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name);if(h.some(f))return void g.push(e);for(let b of h)a((0,c.join)(d,b),e?`${e}/${b}`:b)}(e,"");let h=g.length;return{items:(a?g.slice(0,a):g).map(a=>{let d,g=(0,c.join)(e,a),h=(0,b.readdirSync)(g,{withFileTypes:!0}).filter(a=>a.isDirectory()&&f(a.name)).map(a=>a.name).sort().reverse(),i=0,j=0;if(h.length>0){let a=(0,c.join)(g,h[0]);for(let d of(0,b.readdirSync)(a,{withFileTypes:!0}).filter(a=>a.isDirectory())){let e=(0,c.join)(a,d.name,"summary.json");if((0,b.existsSync)(e))try{let a=JSON.parse((0,b.readFileSync)(e,"utf-8"));i+=a.totalRuns??0,j+=a.passedRuns??0}catch{}}i>0&&(d=j/i*100)}return{name:a,timestamps:h,latestTimestamp:h[0]??null,latestPassRate:d,latestTotalRuns:i,latestPassedRuns:j}}),total:h}}function h(a){let e=(0,c.join)(d(),a);if(!(0,b.existsSync)(e))return null;let f=(0,b.readdirSync)(e,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name).sort().reverse();return{name:a,timestamps:f,latestTimestamp:f[0]??null}}function i(a,e){let f=(0,c.join)(d(),a,e);if(!(0,b.existsSync)(f))return null;let g=[];return!function a(d,e=""){for(let f of(0,b.readdirSync)(d,{withFileTypes:!0})){if(!f.isDirectory()||f.name.startsWith(".")||f.name.startsWith("run-"))continue;let h=e?`${e}/${f.name}`:f.name,i=(0,c.join)(d,f.name),j=(0,c.join)(i,"summary.json");(0,b.existsSync)(j)?g.push(h):a(i,h)}}(f),g.sort(),{name:a,timestamp:e,evals:g.map(a=>{let d=(0,c.join)(f,a),e=(0,c.join)(d,"summary.json"),g={totalRuns:0,passedRuns:0,passRate:"0%",meanDuration:0};if((0,b.existsSync)(e))try{g=JSON.parse((0,b.readFileSync)(e,"utf-8"))}catch{}let h=(0,b.readdirSync)(d,{withFileTypes:!0}).filter(a=>a.isDirectory()&&a.name.startsWith("run-")).map(a=>a.name).sort().map(a=>{let e=(0,c.join)(d,a,"result.json"),f=null;if((0,b.existsSync)(e))try{f=JSON.parse((0,b.readFileSync)(e,"utf-8"))}catch{}return{name:a,result:f}});return{name:a,totalRuns:g.totalRuns,passedRuns:g.passedRuns,passRate:"string"==typeof g.passRate?parseFloat(g.passRate):g.passRate,meanDuration:g.meanDuration,runs:h}})}}function j(a,e,f,g){let h=(0,c.join)(d(),a,e,f,g,"transcript.json");if(!(0,b.existsSync)(h))return null;try{return JSON.parse((0,b.readFileSync)(h,"utf-8"))}catch{return null}}function k(a){let d=e();if(!(0,b.existsSync)(d))return{items:[],total:0};let f=[];!function a(d,e=""){for(let g of(0,b.readdirSync)(d,{withFileTypes:!0})){if(!g.isDirectory()||g.name.startsWith("."))continue;let h=e?`${e}/${g.name}`:g.name,i=(0,c.join)(d,g.name),j=(0,c.join)(i,"PROMPT.md");(0,b.existsSync)(j)?f.push(h):a(i,h)}}(d),f.sort();let g=f.length;return{items:(a?f.slice(0,a):f).map(a=>{let e=(0,c.join)(d,a),f=(0,c.join)(e,"PROMPT.md"),g="";return(0,b.existsSync)(f)&&(g=(0,b.readFileSync)(f,"utf-8")),{name:a,prompt:g,files:(0,b.readdirSync)(e,{withFileTypes:!0}).filter(a=>a.isFile()).map(a=>a.name)}}),total:g}}function l(a){let d=(0,c.join)(e(),a);if(!(0,b.existsSync)(d))return null;let f=(0,c.join)(d,"PROMPT.md"),g="";(0,b.existsSync)(f)&&(g=(0,b.readFileSync)(f,"utf-8"));let h=[];!function a(d,e){for(let f of(0,b.readdirSync)(d,{withFileTypes:!0})){if("node_modules"===f.name||".git"===f.name)continue;let b=e?`${e}/${f.name}`:f.name;f.isDirectory()?a((0,c.join)(d,f.name),b):h.push(b)}}(d,"");let i={};for(let a of["PROMPT.md","EVAL.ts","EVAL.tsx","package.json"]){let e=(0,c.join)(d,a);if((0,b.existsSync)(e))try{i[a]=(0,b.readFileSync)(e,"utf-8")}catch{}}return{name:a,prompt:g,files:h,fileContents:i}}a.s(["getEvalDetail",()=>l,"getExperiment",()=>h,"getExperimentDetail",()=>i,"getTranscript",()=>j,"listEvals",()=>k,"listExperiments",()=>g])},35613,a=>{"use strict";a.s(["Tabs",()=>c,"TabsContent",()=>d,"TabsList",()=>e,"TabsTrigger",()=>f,"tabsListVariants",()=>g]);var b=a.i(11857);let c=(0,b.registerClientReference)(function(){throw Error("Attempted to call Tabs() from the server but Tabs is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx <module evaluation>","Tabs"),d=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsContent() from the server but TabsContent is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx <module evaluation>","TabsContent"),e=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsList() from the server but TabsList is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx <module evaluation>","TabsList"),f=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsTrigger() from the server but TabsTrigger is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx <module evaluation>","TabsTrigger"),g=(0,b.registerClientReference)(function(){throw Error("Attempted to call tabsListVariants() from the server but tabsListVariants is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx <module evaluation>","tabsListVariants")},84346,a=>{"use strict";a.s(["Tabs",()=>c,"TabsContent",()=>d,"TabsList",()=>e,"TabsTrigger",()=>f,"tabsListVariants",()=>g]);var b=a.i(11857);let c=(0,b.registerClientReference)(function(){throw Error("Attempted to call Tabs() from the server but Tabs is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx","Tabs"),d=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsContent() from the server but TabsContent is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx","TabsContent"),e=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsList() from the server but TabsList is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx","TabsList"),f=(0,b.registerClientReference)(function(){throw Error("Attempted to call TabsTrigger() from the server but TabsTrigger is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx","TabsTrigger"),g=(0,b.registerClientReference)(function(){throw Error("Attempted to call tabsListVariants() from the server but tabsListVariants is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/tabs.tsx","tabsListVariants")},84336,a=>{"use strict";a.i(35613);var b=a.i(84346);a.n(b)},28372,a=>{"use strict";a.s(["ScrollArea",()=>c,"ScrollBar",()=>d]);var b=a.i(11857);let c=(0,b.registerClientReference)(function(){throw Error("Attempted to call ScrollArea() from the server but ScrollArea is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/scroll-area.tsx <module evaluation>","ScrollArea"),d=(0,b.registerClientReference)(function(){throw Error("Attempted to call ScrollBar() from the server but ScrollBar is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/scroll-area.tsx <module evaluation>","ScrollBar")},22448,a=>{"use strict";a.s(["ScrollArea",()=>c,"ScrollBar",()=>d]);var b=a.i(11857);let c=(0,b.registerClientReference)(function(){throw Error("Attempted to call ScrollArea() from the server but ScrollArea is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/scroll-area.tsx","ScrollArea"),d=(0,b.registerClientReference)(function(){throw Error("Attempted to call ScrollBar() from the server but ScrollBar is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ui/scroll-area.tsx","ScrollBar")},46804,a=>{"use strict";a.i(28372);var b=a.i(22448);a.n(b)},86568,a=>{"use strict";var b=a.i(7997);a.i(70396);var c=a.i(73727),d=a.i(95936),e=a.i(20954),f=a.i(84336),g=a.i(46804);function h({data:a}){let c=a.fileContents?.["EVAL.ts"]||a.fileContents?.["EVAL.tsx"],e=a.fileContents?.["EVAL.ts"]?"EVAL.ts":"EVAL.tsx",h=a.fileContents?.["package.json"];return(0,b.jsxs)("div",{className:"space-y-6",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[(0,b.jsx)(d.default,{href:"/evals",className:"cursor-pointer hover:underline underline-offset-4",children:"Evals"}),(0,b.jsx)("span",{children:"/"}),(0,b.jsx)("span",{children:a.name})]}),(0,b.jsx)("div",{children:(0,b.jsx)("h1",{className:"text-2xl font-bold tracking-tight",children:a.name})}),(0,b.jsxs)(f.Tabs,{defaultValue:"prompt",className:"w-full",children:[(0,b.jsxs)(f.TabsList,{children:[(0,b.jsx)(f.TabsTrigger,{value:"prompt",children:"PROMPT.md"}),c&&(0,b.jsx)(f.TabsTrigger,{value:"eval",children:e}),h&&(0,b.jsx)(f.TabsTrigger,{value:"package",children:"package.json"}),(0,b.jsx)(f.TabsTrigger,{value:"files",children:"Files"})]}),(0,b.jsx)(f.TabsContent,{value:"prompt",className:"mt-4",children:(0,b.jsx)(g.ScrollArea,{className:"h-[calc(100vh-300px)]",children:(0,b.jsx)("pre",{className:"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4",children:a.prompt||"No PROMPT.md found."})})}),c&&(0,b.jsx)(f.TabsContent,{value:"eval",className:"mt-4",children:(0,b.jsx)(g.ScrollArea,{className:"h-[calc(100vh-300px)]",children:(0,b.jsx)("pre",{className:"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4 overflow-x-auto",children:c})})}),h&&(0,b.jsx)(f.TabsContent,{value:"package",className:"mt-4",children:(0,b.jsx)(g.ScrollArea,{className:"h-[calc(100vh-300px)]",children:(0,b.jsx)("pre",{className:"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4 overflow-x-auto",children:h})})}),(0,b.jsxs)(f.TabsContent,{value:"files",className:"mt-4",children:[(0,b.jsxs)("div",{className:"text-sm text-muted-foreground mb-3",children:[a.files.length," files"]}),(0,b.jsx)("div",{className:"space-y-1",children:a.files.map(a=>(0,b.jsxs)("div",{className:"flex items-center gap-2 text-sm font-mono bg-muted rounded-lg px-3 py-1.5",children:[(0,b.jsx)(i,{filename:a}),(0,b.jsx)("span",{children:a})]},a))})]})]})]})}function i({filename:a}){let c=a.split(".").pop()?.toLowerCase();return(0,b.jsx)(e.Badge,{variant:"outline",className:"text-[10px] font-mono px-1 py-0 h-5 w-6 flex items-center justify-center",children:{ts:"TS",tsx:"TX",js:"JS",json:"{}",md:"MD",css:"CS",html:"HT"}[c||""]||"F"})}var j=a.i(5419);async function k({params:a}){let{name:d}=await a,e=decodeURIComponent(d),f=(0,j.getEvalDetail)(e);return f||(0,c.notFound)(),(0,b.jsx)(h,{data:f})}a.s(["default",()=>k,"dynamic",0,"force-dynamic"],86568)}];
2
2
 
3
3
  //# sourceMappingURL=%5Broot-of-the-server%5D__a216b589._.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/playground/lib/data.ts","../../../../../../packages/playground/components/ui/tabs.tsx/__nextjs-internal-proxy.mjs","../../../../../../packages/playground/components/ui/scroll-area.tsx/__nextjs-internal-proxy.mjs","../../../../../../packages/playground/app/evals/%5Bname%5D/page.tsx","../../../../../../packages/playground/components/EvalDetail.tsx"],"sourcesContent":["/**\n * Server-side data access for the playground.\n * Reads JSON files from the results/ and evals/ directories.\n * Directory paths are provided via RESULTS_DIR and EVALS_DIR env vars.\n */\n\nimport { readdirSync, readFileSync, existsSync } from \"fs\";\nimport { join, resolve } from \"path\";\n\nfunction getResultsDir(): string {\n return resolve(process.env.RESULTS_DIR || \"./results\");\n}\n\nfunction getEvalsDir(): string {\n return resolve(process.env.EVALS_DIR || \"./evals\");\n}\n\n/** Check if a directory name looks like an ISO timestamp (used as run ID) */\nfunction isTimestamp(name: string): boolean {\n return /^\\d{4}-\\d{2}-\\d{2}T/.test(name);\n}\n\n/** List experiments from the results directory. Pass limit to cap expensive per-item reads. */\nexport function listExperiments(limit?: number) {\n const resultsDir = getResultsDir();\n\n if (!existsSync(resultsDir)) {\n return { items: [], total: 0 };\n }\n\n // Discover experiments by walking the directory tree until we find\n // timestamp directories. The path from resultsDir to the parent of the\n // first timestamp is the experiment name (e.g. \"my-config/openai/gpt-5.2-codex\").\n const entries: string[] = [];\n\n function walk(dir: string, prefix: string) {\n const children = readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n\n // If any child looks like a timestamp, this directory is an experiment\n if (children.some(isTimestamp)) {\n entries.push(prefix);\n return;\n }\n\n // Otherwise keep recursing\n for (const child of children) {\n walk(join(dir, child), prefix ? `${prefix}/${child}` : child);\n }\n }\n\n walk(resultsDir, \"\");\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const expDir = join(resultsDir, name);\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && isTimestamp(e.name))\n .map((e) => e.name)\n .sort()\n .reverse();\n\n let latestPassRate: number | undefined;\n let latestTotalRuns = 0;\n let latestPassedRuns = 0;\n\n if (timestamps.length > 0) {\n const latestDir = join(expDir, timestamps[0]);\n const evalDirs = readdirSync(latestDir, { withFileTypes: true }).filter(\n (e) => e.isDirectory()\n );\n\n for (const evalDir of evalDirs) {\n const summaryPath = join(latestDir, evalDir.name, \"summary.json\");\n if (existsSync(summaryPath)) {\n try {\n const summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n latestTotalRuns += summary.totalRuns ?? 0;\n latestPassedRuns += summary.passedRuns ?? 0;\n } catch {\n // Skip invalid summary files\n }\n }\n }\n\n if (latestTotalRuns > 0) {\n latestPassRate = (latestPassedRuns / latestTotalRuns) * 100;\n }\n }\n\n return {\n name,\n timestamps,\n latestTimestamp: timestamps[0] ?? null,\n latestPassRate,\n latestTotalRuns,\n latestPassedRuns,\n };\n });\n\n return { items, total };\n}\n\n/** Get timestamps for a specific experiment */\nexport function getExperiment(name: string) {\n const expDir = join(getResultsDir(), name);\n\n if (!existsSync(expDir)) {\n return null;\n }\n\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .sort()\n .reverse();\n\n return { name, timestamps, latestTimestamp: timestamps[0] ?? null };\n}\n\n/** Get full experiment detail for a specific timestamp */\nexport function getExperimentDetail(name: string, timestamp: string) {\n const runDir = join(getResultsDir(), name, timestamp);\n\n if (!existsSync(runDir)) {\n return null;\n }\n\n // Recursively discover all eval result directories (directories with summary.json)\n const evalDirs: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\") || entry.name.startsWith(\"run-\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const summaryPath = join(entryPath, \"summary.json\");\n\n // Check if this is an eval result directory (has summary.json)\n if (existsSync(summaryPath)) {\n evalDirs.push(relativePath);\n } else {\n // Not an eval result, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(runDir);\n evalDirs.sort();\n\n const evals = evalDirs.map((evalName) => {\n const evalDir = join(runDir, evalName);\n const summaryPath = join(evalDir, \"summary.json\");\n\n let summary = {\n totalRuns: 0,\n passedRuns: 0,\n passRate: \"0%\",\n meanDuration: 0,\n };\n if (existsSync(summaryPath)) {\n try {\n summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n } catch {\n // Use defaults\n }\n }\n\n // List run directories\n const runDirs = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && e.name.startsWith(\"run-\"))\n .map((e) => e.name)\n .sort();\n\n // Read each run's result.json\n const runs = runDirs.map((runDirName) => {\n const resultPath = join(evalDir, runDirName, \"result.json\");\n let result = null;\n if (existsSync(resultPath)) {\n try {\n result = JSON.parse(readFileSync(resultPath, \"utf-8\"));\n } catch {\n // Skip\n }\n }\n return { name: runDirName, result };\n });\n\n return {\n name: evalName,\n totalRuns: summary.totalRuns,\n passedRuns: summary.passedRuns,\n passRate:\n typeof summary.passRate === \"string\"\n ? parseFloat(summary.passRate)\n : summary.passRate,\n meanDuration: summary.meanDuration,\n runs,\n };\n });\n\n return { name, timestamp, evals };\n}\n\n/** Get result for a specific run */\nexport function getRunResult(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const resultPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"result.json\"\n );\n\n if (!existsSync(resultPath)) {\n return null;\n }\n\n try {\n return { result: JSON.parse(readFileSync(resultPath, \"utf-8\")) };\n } catch {\n return null;\n }\n}\n\n/** Get parsed transcript for a specific run */\nexport function getTranscript(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const transcriptPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"transcript.json\"\n );\n\n if (!existsSync(transcriptPath)) {\n return null;\n }\n\n try {\n return JSON.parse(readFileSync(transcriptPath, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\n/** List evals from the evals directory. Pass limit to cap per-item reads. */\nexport function listEvals(limit?: number) {\n const evalsDir = getEvalsDir();\n\n if (!existsSync(evalsDir)) {\n return { items: [], total: 0 };\n }\n\n // Recursively discover all evals (directories with PROMPT.md)\n const entries: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const promptPath = join(entryPath, \"PROMPT.md\");\n\n // Check if this is an eval directory (has PROMPT.md)\n if (existsSync(promptPath)) {\n entries.push(relativePath);\n } else {\n // Not an eval, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(evalsDir);\n entries.sort();\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const evalDir = join(evalsDir, name);\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n const files = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isFile())\n .map((e) => e.name);\n\n return { name, prompt, files };\n });\n\n return { items, total };\n}\n\n/** Get detail for a specific eval */\nexport function getEvalDetail(name: string) {\n const evalDir = join(getEvalsDir(), name);\n\n if (!existsSync(evalDir)) {\n return null;\n }\n\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n // Recursively list files\n const files: string[] = [];\n function walk(dir: string, prefix: string) {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name === \"node_modules\" || entry.name === \".git\") continue;\n const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (entry.isDirectory()) {\n walk(join(dir, entry.name), relativePath);\n } else {\n files.push(relativePath);\n }\n }\n }\n walk(evalDir, \"\");\n\n // Read file contents for key files\n const fileContents: Record<string, string> = {};\n const keyFiles = [\"PROMPT.md\", \"EVAL.ts\", \"EVAL.tsx\", \"package.json\"];\n for (const file of keyFiles) {\n const filePath = join(evalDir, file);\n if (existsSync(filePath)) {\n try {\n fileContents[file] = readFileSync(filePath, \"utf-8\");\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return { name, prompt, files, fileContents };\n}\n","// This file is generated by next-core EcmascriptClientReferenceModule.\nimport { registerClientReference } from \"react-server-dom-turbopack/server\";\nexport const Tabs = registerClientReference(\n function() { throw new Error(\"Attempted to call Tabs() from the server but Tabs is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/tabs.tsx\",\n \"Tabs\",\n);\nexport const TabsContent = registerClientReference(\n function() { throw new Error(\"Attempted to call TabsContent() from the server but TabsContent is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/tabs.tsx\",\n \"TabsContent\",\n);\nexport const TabsList = registerClientReference(\n function() { throw new Error(\"Attempted to call TabsList() from the server but TabsList is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/tabs.tsx\",\n \"TabsList\",\n);\nexport const TabsTrigger = registerClientReference(\n function() { throw new Error(\"Attempted to call TabsTrigger() from the server but TabsTrigger is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/tabs.tsx\",\n \"TabsTrigger\",\n);\nexport const tabsListVariants = registerClientReference(\n function() { throw new Error(\"Attempted to call tabsListVariants() from the server but tabsListVariants is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/tabs.tsx\",\n \"tabsListVariants\",\n);\n","// This file is generated by next-core EcmascriptClientReferenceModule.\nimport { registerClientReference } from \"react-server-dom-turbopack/server\";\nexport const ScrollArea = registerClientReference(\n function() { throw new Error(\"Attempted to call ScrollArea() from the server but ScrollArea is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/scroll-area.tsx\",\n \"ScrollArea\",\n);\nexport const ScrollBar = registerClientReference(\n function() { throw new Error(\"Attempted to call ScrollBar() from the server but ScrollBar is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/scroll-area.tsx\",\n \"ScrollBar\",\n);\n","import { notFound } from \"next/navigation\";\nimport { EvalDetail } from \"@/components/EvalDetail\";\nimport { getEvalDetail } from \"@/lib/data\";\n\nexport const dynamic = \"force-dynamic\";\n\nexport default async function EvalDetailRoute({\n params,\n}: {\n params: Promise<{ name: string }>;\n}) {\n const { name } = await params;\n const decodedName = decodeURIComponent(name);\n\n const data = getEvalDetail(decodedName);\n\n if (!data) {\n notFound();\n }\n\n return <EvalDetail data={data} />;\n}\n","import Link from \"next/link\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\n\ninterface EvalDetailData {\n name: string;\n prompt: string;\n files: string[];\n fileContents?: Record<string, string>;\n}\n\ninterface EvalDetailProps {\n data: EvalDetailData;\n}\n\nexport function EvalDetail({ data }: EvalDetailProps) {\n const evalFile = data.fileContents?.[\"EVAL.ts\"] || data.fileContents?.[\"EVAL.tsx\"];\n const evalFileName = data.fileContents?.[\"EVAL.ts\"] ? \"EVAL.ts\" : \"EVAL.tsx\";\n const packageJson = data.fileContents?.[\"package.json\"];\n\n return (\n <div className=\"space-y-6\">\n {/* Breadcrumb */}\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Link href=\"/evals\" className=\"cursor-pointer hover:underline underline-offset-4\">\n Evals\n </Link>\n <span>/</span>\n <span>{data.name}</span>\n </div>\n\n <div>\n <h1 className=\"text-2xl font-bold tracking-tight\">{data.name}</h1>\n </div>\n\n <Tabs defaultValue=\"prompt\" className=\"w-full\">\n <TabsList>\n <TabsTrigger value=\"prompt\">PROMPT.md</TabsTrigger>\n {evalFile && <TabsTrigger value=\"eval\">{evalFileName}</TabsTrigger>}\n {packageJson && <TabsTrigger value=\"package\">package.json</TabsTrigger>}\n <TabsTrigger value=\"files\">Files</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"prompt\" className=\"mt-4\">\n <ScrollArea className=\"h-[calc(100vh-300px)]\">\n <pre className=\"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4\">\n {data.prompt || \"No PROMPT.md found.\"}\n </pre>\n </ScrollArea>\n </TabsContent>\n\n {evalFile && (\n <TabsContent value=\"eval\" className=\"mt-4\">\n <ScrollArea className=\"h-[calc(100vh-300px)]\">\n <pre className=\"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4 overflow-x-auto\">\n {evalFile}\n </pre>\n </ScrollArea>\n </TabsContent>\n )}\n\n {packageJson && (\n <TabsContent value=\"package\" className=\"mt-4\">\n <ScrollArea className=\"h-[calc(100vh-300px)]\">\n <pre className=\"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4 overflow-x-auto\">\n {packageJson}\n </pre>\n </ScrollArea>\n </TabsContent>\n )}\n\n <TabsContent value=\"files\" className=\"mt-4\">\n <div className=\"text-sm text-muted-foreground mb-3\">\n {data.files.length} files\n </div>\n <div className=\"space-y-1\">\n {data.files.map((file) => (\n <div\n key={file}\n className=\"flex items-center gap-2 text-sm font-mono bg-muted rounded-lg px-3 py-1.5\"\n >\n <FileIcon filename={file} />\n <span>{file}</span>\n </div>\n ))}\n </div>\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n\nfunction FileIcon({ filename }: { filename: string }) {\n const ext = filename.split(\".\").pop()?.toLowerCase();\n\n const iconMap: Record<string, string> = {\n ts: \"TS\",\n tsx: \"TX\",\n js: \"JS\",\n json: \"{}\",\n md: \"MD\",\n css: \"CS\",\n html: \"HT\",\n };\n\n const label = iconMap[ext || \"\"] || \"F\";\n\n return (\n <Badge variant=\"outline\" className=\"text-[10px] font-mono px-1 py-0 h-5 w-6 flex items-center justify-center\">\n {label}\n </Badge>\n );\n}\n"],"names":[],"mappings":"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","ignoreList":[1,2]}
1
+ {"version":3,"sources":["../../../../../../packages/playground/lib/data.ts","../../../../../../packages/playground/components/ui/tabs.tsx/__nextjs-internal-proxy.mjs","../../../../../../packages/playground/components/ui/scroll-area.tsx/__nextjs-internal-proxy.mjs","../../../../../../packages/playground/app/evals/%5Bname%5D/page.tsx","../../../../../../packages/playground/components/EvalDetail.tsx"],"sourcesContent":["/**\n * Server-side data access for the playground.\n * Reads JSON files from the results/ and evals/ directories.\n * Directory paths are provided via RESULTS_DIR and EVALS_DIR env vars.\n */\n\nimport { readdirSync, readFileSync, existsSync } from \"fs\";\nimport { join, resolve } from \"path\";\n\nfunction getResultsDir(): string {\n return resolve(process.env.RESULTS_DIR || \"./results\");\n}\n\nfunction getEvalsDir(): string {\n return resolve(process.env.EVALS_DIR || \"./evals\");\n}\n\n/** Check if a directory name looks like an ISO timestamp (used as run ID) */\nfunction isTimestamp(name: string): boolean {\n return /^\\d{4}-\\d{2}-\\d{2}T/.test(name);\n}\n\n/** List experiments from the results directory. Pass limit to cap expensive per-item reads. */\nexport function listExperiments(limit?: number) {\n const resultsDir = getResultsDir();\n\n if (!existsSync(resultsDir)) {\n return { items: [], total: 0 };\n }\n\n // Discover experiments by walking the directory tree until we find\n // timestamp directories. The path from resultsDir to the parent of the\n // first timestamp is the experiment name (e.g. \"my-config/openai/gpt-5.2-codex\").\n const entries: string[] = [];\n\n function walk(dir: string, prefix: string) {\n const children = readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n\n // If any child looks like a timestamp, this directory is an experiment\n if (children.some(isTimestamp)) {\n entries.push(prefix);\n return;\n }\n\n // Otherwise keep recursing\n for (const child of children) {\n walk(join(dir, child), prefix ? `${prefix}/${child}` : child);\n }\n }\n\n walk(resultsDir, \"\");\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const expDir = join(resultsDir, name);\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && isTimestamp(e.name))\n .map((e) => e.name)\n .sort()\n .reverse();\n\n let latestPassRate: number | undefined;\n let latestTotalRuns = 0;\n let latestPassedRuns = 0;\n\n if (timestamps.length > 0) {\n const latestDir = join(expDir, timestamps[0]);\n const evalDirs = readdirSync(latestDir, { withFileTypes: true }).filter(\n (e) => e.isDirectory()\n );\n\n for (const evalDir of evalDirs) {\n const summaryPath = join(latestDir, evalDir.name, \"summary.json\");\n if (existsSync(summaryPath)) {\n try {\n const summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n latestTotalRuns += summary.totalRuns ?? 0;\n latestPassedRuns += summary.passedRuns ?? 0;\n } catch {\n // Skip invalid summary files\n }\n }\n }\n\n if (latestTotalRuns > 0) {\n latestPassRate = (latestPassedRuns / latestTotalRuns) * 100;\n }\n }\n\n return {\n name,\n timestamps,\n latestTimestamp: timestamps[0] ?? null,\n latestPassRate,\n latestTotalRuns,\n latestPassedRuns,\n };\n });\n\n return { items, total };\n}\n\n/** Get timestamps for a specific experiment */\nexport function getExperiment(name: string) {\n const expDir = join(getResultsDir(), name);\n\n if (!existsSync(expDir)) {\n return null;\n }\n\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .sort()\n .reverse();\n\n return { name, timestamps, latestTimestamp: timestamps[0] ?? null };\n}\n\n/** Get full experiment detail for a specific timestamp */\nexport function getExperimentDetail(name: string, timestamp: string) {\n const runDir = join(getResultsDir(), name, timestamp);\n\n if (!existsSync(runDir)) {\n return null;\n }\n\n // Recursively discover all eval result directories (directories with summary.json)\n const evalDirs: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\") || entry.name.startsWith(\"run-\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const summaryPath = join(entryPath, \"summary.json\");\n\n // Check if this is an eval result directory (has summary.json)\n if (existsSync(summaryPath)) {\n evalDirs.push(relativePath);\n } else {\n // Not an eval result, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(runDir);\n evalDirs.sort();\n\n const evals = evalDirs.map((evalName) => {\n const evalDir = join(runDir, evalName);\n const summaryPath = join(evalDir, \"summary.json\");\n\n let summary = {\n totalRuns: 0,\n passedRuns: 0,\n passRate: \"0%\",\n meanDuration: 0,\n };\n if (existsSync(summaryPath)) {\n try {\n summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n } catch {\n // Use defaults\n }\n }\n\n // List run directories\n const runDirs = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && e.name.startsWith(\"run-\"))\n .map((e) => e.name)\n .sort();\n\n // Read each run's result.json\n const runs = runDirs.map((runDirName) => {\n const resultPath = join(evalDir, runDirName, \"result.json\");\n let result = null;\n if (existsSync(resultPath)) {\n try {\n result = JSON.parse(readFileSync(resultPath, \"utf-8\"));\n } catch {\n // Skip\n }\n }\n return { name: runDirName, result };\n });\n\n return {\n name: evalName,\n totalRuns: summary.totalRuns,\n passedRuns: summary.passedRuns,\n passRate:\n typeof summary.passRate === \"string\"\n ? parseFloat(summary.passRate)\n : summary.passRate,\n meanDuration: summary.meanDuration,\n runs,\n };\n });\n\n return { name, timestamp, evals };\n}\n\n/** Get result for a specific run */\nexport function getRunResult(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const resultPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"result.json\"\n );\n\n if (!existsSync(resultPath)) {\n return null;\n }\n\n try {\n return { result: JSON.parse(readFileSync(resultPath, \"utf-8\")) };\n } catch {\n return null;\n }\n}\n\n/** Get parsed transcript for a specific run */\nexport function getTranscript(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const transcriptPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"transcript.json\"\n );\n\n if (!existsSync(transcriptPath)) {\n return null;\n }\n\n try {\n return JSON.parse(readFileSync(transcriptPath, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\n/** List evals from the evals directory. Pass limit to cap per-item reads. */\nexport function listEvals(limit?: number) {\n const evalsDir = getEvalsDir();\n\n if (!existsSync(evalsDir)) {\n return { items: [], total: 0 };\n }\n\n // Recursively discover all evals (directories with PROMPT.md)\n const entries: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const promptPath = join(entryPath, \"PROMPT.md\");\n\n // Check if this is an eval directory (has PROMPT.md)\n if (existsSync(promptPath)) {\n entries.push(relativePath);\n } else {\n // Not an eval, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(evalsDir);\n entries.sort();\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const evalDir = join(evalsDir, name);\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n const files = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isFile())\n .map((e) => e.name);\n\n return { name, prompt, files };\n });\n\n return { items, total };\n}\n\n/** Get detail for a specific eval */\nexport function getEvalDetail(name: string) {\n const evalDir = join(getEvalsDir(), name);\n\n if (!existsSync(evalDir)) {\n return null;\n }\n\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n // Recursively list files\n const files: string[] = [];\n function walk(dir: string, prefix: string) {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name === \"node_modules\" || entry.name === \".git\") continue;\n const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (entry.isDirectory()) {\n walk(join(dir, entry.name), relativePath);\n } else {\n files.push(relativePath);\n }\n }\n }\n walk(evalDir, \"\");\n\n // Read file contents for key files\n const fileContents: Record<string, string> = {};\n const keyFiles = [\"PROMPT.md\", \"EVAL.ts\", \"EVAL.tsx\", \"package.json\"];\n for (const file of keyFiles) {\n const filePath = join(evalDir, file);\n if (existsSync(filePath)) {\n try {\n fileContents[file] = readFileSync(filePath, \"utf-8\");\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return { name, prompt, files, fileContents };\n}\n","// This file is generated by next-core EcmascriptClientReferenceModule.\nimport { registerClientReference } from \"react-server-dom-turbopack/server\";\nexport const Tabs = registerClientReference(\n function() { throw new Error(\"Attempted to call Tabs() from the server but Tabs is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/tabs.tsx\",\n \"Tabs\",\n);\nexport const TabsContent = registerClientReference(\n function() { throw new Error(\"Attempted to call TabsContent() from the server but TabsContent is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/tabs.tsx\",\n \"TabsContent\",\n);\nexport const TabsList = registerClientReference(\n function() { throw new Error(\"Attempted to call TabsList() from the server but TabsList is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/tabs.tsx\",\n \"TabsList\",\n);\nexport const TabsTrigger = registerClientReference(\n function() { throw new Error(\"Attempted to call TabsTrigger() from the server but TabsTrigger is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/tabs.tsx\",\n \"TabsTrigger\",\n);\nexport const tabsListVariants = registerClientReference(\n function() { throw new Error(\"Attempted to call tabsListVariants() from the server but tabsListVariants is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/tabs.tsx\",\n \"tabsListVariants\",\n);\n","// This file is generated by next-core EcmascriptClientReferenceModule.\nimport { registerClientReference } from \"react-server-dom-turbopack/server\";\nexport const ScrollArea = registerClientReference(\n function() { throw new Error(\"Attempted to call ScrollArea() from the server but ScrollArea is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/scroll-area.tsx\",\n \"ScrollArea\",\n);\nexport const ScrollBar = registerClientReference(\n function() { throw new Error(\"Attempted to call ScrollBar() from the server but ScrollBar is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ui/scroll-area.tsx\",\n \"ScrollBar\",\n);\n","import { notFound } from \"next/navigation\";\nimport { EvalDetail } from \"@/components/EvalDetail\";\nimport { getEvalDetail } from \"@/lib/data\";\n\nexport const dynamic = \"force-dynamic\";\n\nexport default async function EvalDetailRoute({\n params,\n}: {\n params: Promise<{ name: string }>;\n}) {\n const { name } = await params;\n const decodedName = decodeURIComponent(name);\n\n const data = getEvalDetail(decodedName);\n\n if (!data) {\n notFound();\n }\n\n return <EvalDetail data={data} />;\n}\n","import Link from \"next/link\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\n\ninterface EvalDetailData {\n name: string;\n prompt: string;\n files: string[];\n fileContents?: Record<string, string>;\n}\n\ninterface EvalDetailProps {\n data: EvalDetailData;\n}\n\nexport function EvalDetail({ data }: EvalDetailProps) {\n const evalFile = data.fileContents?.[\"EVAL.ts\"] || data.fileContents?.[\"EVAL.tsx\"];\n const evalFileName = data.fileContents?.[\"EVAL.ts\"] ? \"EVAL.ts\" : \"EVAL.tsx\";\n const packageJson = data.fileContents?.[\"package.json\"];\n\n return (\n <div className=\"space-y-6\">\n {/* Breadcrumb */}\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Link href=\"/evals\" className=\"cursor-pointer hover:underline underline-offset-4\">\n Evals\n </Link>\n <span>/</span>\n <span>{data.name}</span>\n </div>\n\n <div>\n <h1 className=\"text-2xl font-bold tracking-tight\">{data.name}</h1>\n </div>\n\n <Tabs defaultValue=\"prompt\" className=\"w-full\">\n <TabsList>\n <TabsTrigger value=\"prompt\">PROMPT.md</TabsTrigger>\n {evalFile && <TabsTrigger value=\"eval\">{evalFileName}</TabsTrigger>}\n {packageJson && <TabsTrigger value=\"package\">package.json</TabsTrigger>}\n <TabsTrigger value=\"files\">Files</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"prompt\" className=\"mt-4\">\n <ScrollArea className=\"h-[calc(100vh-300px)]\">\n <pre className=\"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4\">\n {data.prompt || \"No PROMPT.md found.\"}\n </pre>\n </ScrollArea>\n </TabsContent>\n\n {evalFile && (\n <TabsContent value=\"eval\" className=\"mt-4\">\n <ScrollArea className=\"h-[calc(100vh-300px)]\">\n <pre className=\"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4 overflow-x-auto\">\n {evalFile}\n </pre>\n </ScrollArea>\n </TabsContent>\n )}\n\n {packageJson && (\n <TabsContent value=\"package\" className=\"mt-4\">\n <ScrollArea className=\"h-[calc(100vh-300px)]\">\n <pre className=\"text-sm font-mono whitespace-pre-wrap rounded-lg bg-muted p-4 overflow-x-auto\">\n {packageJson}\n </pre>\n </ScrollArea>\n </TabsContent>\n )}\n\n <TabsContent value=\"files\" className=\"mt-4\">\n <div className=\"text-sm text-muted-foreground mb-3\">\n {data.files.length} files\n </div>\n <div className=\"space-y-1\">\n {data.files.map((file) => (\n <div\n key={file}\n className=\"flex items-center gap-2 text-sm font-mono bg-muted rounded-lg px-3 py-1.5\"\n >\n <FileIcon filename={file} />\n <span>{file}</span>\n </div>\n ))}\n </div>\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n\nfunction FileIcon({ filename }: { filename: string }) {\n const ext = filename.split(\".\").pop()?.toLowerCase();\n\n const iconMap: Record<string, string> = {\n ts: \"TS\",\n tsx: \"TX\",\n js: \"JS\",\n json: \"{}\",\n md: \"MD\",\n css: \"CS\",\n html: \"HT\",\n };\n\n const label = iconMap[ext || \"\"] || \"F\";\n\n return (\n <Badge variant=\"outline\" className=\"text-[10px] font-mono px-1 py-0 h-5 w-6 flex items-center justify-center\">\n {label}\n </Badge>\n );\n}\n"],"names":[],"mappings":"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","ignoreList":[1,2]}
@@ -1,3 +1,3 @@
1
- module.exports=[69046,a=>{a.n(a.i(80979))},43619,a=>{a.n(a.i(79962))},13718,a=>{a.n(a.i(85523))},18198,a=>{a.n(a.i(45518))},62212,a=>{a.n(a.i(66114))},22734,(a,b,c)=>{b.exports=a.x("fs",()=>require("fs"))},5419,a=>{"use strict";var b=a.i(22734),c=a.i(14747);function d(){return(0,c.resolve)(process.env.RESULTS_DIR||"./results")}function e(){return(0,c.resolve)(process.env.EVALS_DIR||"./evals")}function f(a){return/^\d{4}-\d{2}-\d{2}T/.test(a)}function g(a){let e=d();if(!(0,b.existsSync)(e))return{items:[],total:0};let g=[];!function a(d,e){let h=(0,b.readdirSync)(d,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name);if(h.some(f))return void g.push(e);for(let b of h)a((0,c.join)(d,b),e?`${e}/${b}`:b)}(e,"");let h=g.length;return{items:(a?g.slice(0,a):g).map(a=>{let d,g=(0,c.join)(e,a),h=(0,b.readdirSync)(g,{withFileTypes:!0}).filter(a=>a.isDirectory()&&f(a.name)).map(a=>a.name).sort().reverse(),i=0,j=0;if(h.length>0){let a=(0,c.join)(g,h[0]);for(let d of(0,b.readdirSync)(a,{withFileTypes:!0}).filter(a=>a.isDirectory())){let e=(0,c.join)(a,d.name,"summary.json");if((0,b.existsSync)(e))try{let a=JSON.parse((0,b.readFileSync)(e,"utf-8"));i+=a.totalRuns??0,j+=a.passedRuns??0}catch{}}i>0&&(d=j/i*100)}return{name:a,timestamps:h,latestTimestamp:h[0]??null,latestPassRate:d,latestTotalRuns:i,latestPassedRuns:j}}),total:h}}function h(a,e){let f=(0,c.join)(d(),a,e);if(!(0,b.existsSync)(f))return null;let g=[];return!function a(d,e=""){for(let f of(0,b.readdirSync)(d,{withFileTypes:!0})){if(!f.isDirectory()||f.name.startsWith(".")||f.name.startsWith("run-"))continue;let h=e?`${e}/${f.name}`:f.name,i=(0,c.join)(d,f.name),j=(0,c.join)(i,"summary.json");(0,b.existsSync)(j)?g.push(h):a(i,h)}}(f),g.sort(),{name:a,timestamp:e,evals:g.map(a=>{let d=(0,c.join)(f,a),e=(0,c.join)(d,"summary.json"),g={totalRuns:0,passedRuns:0,passRate:"0%",meanDuration:0};if((0,b.existsSync)(e))try{g=JSON.parse((0,b.readFileSync)(e,"utf-8"))}catch{}let h=(0,b.readdirSync)(d,{withFileTypes:!0}).filter(a=>a.isDirectory()&&a.name.startsWith("run-")).map(a=>a.name).sort().map(a=>{let e=(0,c.join)(d,a,"result.json"),f=null;if((0,b.existsSync)(e))try{f=JSON.parse((0,b.readFileSync)(e,"utf-8"))}catch{}return{name:a,result:f}});return{name:a,totalRuns:g.totalRuns,passedRuns:g.passedRuns,passRate:"string"==typeof g.passRate?parseFloat(g.passRate):g.passRate,meanDuration:g.meanDuration,runs:h}})}}function i(a,e,f,g){let h=(0,c.join)(d(),a,e,f,g,"transcript.json");if(!(0,b.existsSync)(h))return null;try{return JSON.parse((0,b.readFileSync)(h,"utf-8"))}catch{return null}}function j(a){let d=e();if(!(0,b.existsSync)(d))return{items:[],total:0};let f=[];!function a(d,e=""){for(let g of(0,b.readdirSync)(d,{withFileTypes:!0})){if(!g.isDirectory()||g.name.startsWith("."))continue;let h=e?`${e}/${g.name}`:g.name,i=(0,c.join)(d,g.name),j=(0,c.join)(i,"PROMPT.md");(0,b.existsSync)(j)?f.push(h):a(i,h)}}(d),f.sort();let g=f.length;return{items:(a?f.slice(0,a):f).map(a=>{let e=(0,c.join)(d,a),f=(0,c.join)(e,"PROMPT.md"),g="";return(0,b.existsSync)(f)&&(g=(0,b.readFileSync)(f,"utf-8")),{name:a,prompt:g,files:(0,b.readdirSync)(e,{withFileTypes:!0}).filter(a=>a.isFile()).map(a=>a.name)}}),total:g}}function k(a){let d=(0,c.join)(e(),a);if(!(0,b.existsSync)(d))return null;let f=(0,c.join)(d,"PROMPT.md"),g="";(0,b.existsSync)(f)&&(g=(0,b.readFileSync)(f,"utf-8"));let h=[];!function a(d,e){for(let f of(0,b.readdirSync)(d,{withFileTypes:!0})){if("node_modules"===f.name||".git"===f.name)continue;let b=e?`${e}/${f.name}`:f.name;f.isDirectory()?a((0,c.join)(d,f.name),b):h.push(b)}}(d,"");let i={};for(let a of["PROMPT.md","EVAL.ts","EVAL.tsx","package.json"]){let e=(0,c.join)(d,a);if((0,b.existsSync)(e))try{i[a]=(0,b.readFileSync)(e,"utf-8")}catch{}}return{name:a,prompt:g,files:h,fileContents:i}}a.s(["getEvalDetail",()=>k,"getExperimentDetail",()=>h,"getTranscript",()=>i,"listEvals",()=>j,"listExperiments",()=>g])},22977,a=>{"use strict";var b=a.i(7997),c=a.i(95387);function d({className:a,size:d="default",...e}){return(0,b.jsx)("div",{"data-slot":"card","data-size":d,className:(0,c.cn)("ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-lg py-4 text-xs/relaxed ring-1 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg group/card flex flex-col",a),...e})}function e({className:a,...d}){return(0,b.jsx)("div",{"data-slot":"card-header",className:(0,c.cn)("gap-1 rounded-t-lg px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]",a),...d})}function f({className:a,...d}){return(0,b.jsx)("div",{"data-slot":"card-title",className:(0,c.cn)("text-sm font-medium",a),...d})}function g({className:a,...d}){return(0,b.jsx)("div",{"data-slot":"card-content",className:(0,c.cn)("px-4 group-data-[size=sm]/card:px-3",a),...d})}a.s(["Card",()=>d,"CardContent",()=>g,"CardHeader",()=>e,"CardTitle",()=>f])},31636,a=>{"use strict";a.s(["ShowMore",()=>b]);let b=(0,a.i(11857).registerClientReference)(function(){throw Error("Attempted to call ShowMore() from the server but ShowMore is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ShowMore.tsx <module evaluation>","ShowMore")},15821,a=>{"use strict";a.s(["ShowMore",()=>b]);let b=(0,a.i(11857).registerClientReference)(function(){throw Error("Attempted to call ShowMore() from the server but ShowMore is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ShowMore.tsx","ShowMore")},93835,a=>{"use strict";a.i(31636);var b=a.i(15821);a.n(b)},33383,a=>{"use strict";var b=a.i(7997),c=a.i(95936),d=a.i(20954),e=a.i(22977),f=a.i(93835);function g({experiments:a,total:g,showAll:h}){return 0===a.length?(0,b.jsx)(e.Card,{children:(0,b.jsxs)(e.CardContent,{className:"py-12 text-center",children:[(0,b.jsx)("p",{className:"text-muted-foreground text-lg",children:"No experiments found"}),(0,b.jsxs)("p",{className:"text-muted-foreground text-sm mt-2",children:["Run an experiment with ",(0,b.jsx)("code",{className:"text-foreground bg-muted px-1.5 py-0.5 rounded text-xs",children:"agent-eval <config>"})," to see results here."]})]})}):(0,b.jsx)(e.Card,{children:(0,b.jsx)(e.CardContent,{className:"pt-0",children:(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"grid grid-cols-[1fr_auto_auto_auto] gap-4 px-3 py-2 text-xs text-muted-foreground font-medium border-b border-border",children:[(0,b.jsx)("span",{children:"Name"}),(0,b.jsx)("span",{className:"w-12 text-right",children:"Runs"}),(0,b.jsx)("span",{className:"w-24",children:"Pass Rate"}),(0,b.jsx)("span",{className:"w-44",children:"Latest Run"})]}),(0,b.jsx)(f.ShowMore,{total:g,showAllHref:h?void 0:"/experiments?all",children:a.map(a=>(0,b.jsxs)(c.default,{href:a.latestTimestamp?`/experiments/${encodeURIComponent(a.name)}/${encodeURIComponent(a.latestTimestamp)}`:"#",className:"grid grid-cols-[1fr_auto_auto_auto] gap-4 items-center px-3 py-2.5 cursor-pointer transition-colors hover:bg-muted rounded-md",children:[(0,b.jsx)("span",{className:"font-medium truncate",children:a.name}),(0,b.jsx)("span",{className:"w-12 text-right text-muted-foreground",children:a.timestamps.length}),(0,b.jsx)("span",{className:"w-24",children:void 0!==a.latestPassRate?(0,b.jsxs)("span",{className:"flex items-center gap-2",children:[(0,b.jsxs)(d.Badge,{variant:100===a.latestPassRate?"default":a.latestPassRate>=50?"secondary":"destructive",children:[a.latestPassRate.toFixed(0),"%"]}),(0,b.jsxs)("span",{className:"text-xs text-muted-foreground",children:[a.latestPassedRuns,"/",a.latestTotalRuns]})]}):(0,b.jsx)("span",{className:"text-muted-foreground",children:"--"})}),(0,b.jsx)("span",{className:"w-44 text-xs text-muted-foreground",children:a.latestTimestamp?function(a){try{let b=a.replace(/T(\d{2})-(\d{2})-(\d{2})/,"T$1:$2:$3"),c=new Date(b);if(isNaN(c.getTime()))return a;return c.toLocaleString()}catch{return a}}(a.latestTimestamp):"--"})]},a.name))})]})})})}var h=a.i(5419);async function i({searchParams:a}){let{all:c}=await a,d=void 0!==c,{items:e,total:f}=(0,h.listExperiments)(d?void 0:20);return(0,b.jsxs)("div",{className:"space-y-6",children:[(0,b.jsxs)("div",{children:[(0,b.jsx)("h1",{className:"text-2xl font-bold tracking-tight",children:"Experiments"}),(0,b.jsx)("p",{className:"text-muted-foreground mt-1",children:"Browse and inspect your agent evaluation results."})]}),(0,b.jsx)(g,{experiments:e,total:f,showAll:d})]})}a.s(["default",()=>i,"dynamic",0,"force-dynamic"],33383)}];
1
+ module.exports=[69046,a=>{a.n(a.i(80979))},43619,a=>{a.n(a.i(79962))},13718,a=>{a.n(a.i(85523))},18198,a=>{a.n(a.i(45518))},62212,a=>{a.n(a.i(66114))},22734,(a,b,c)=>{b.exports=a.x("fs",()=>require("fs"))},5419,a=>{"use strict";var b=a.i(22734),c=a.i(14747);function d(){return(0,c.resolve)(process.env.RESULTS_DIR||"./results")}function e(){return(0,c.resolve)(process.env.EVALS_DIR||"./evals")}function f(a){return/^\d{4}-\d{2}-\d{2}T/.test(a)}function g(a){let e=d();if(!(0,b.existsSync)(e))return{items:[],total:0};let g=[];!function a(d,e){let h=(0,b.readdirSync)(d,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name);if(h.some(f))return void g.push(e);for(let b of h)a((0,c.join)(d,b),e?`${e}/${b}`:b)}(e,"");let h=g.length;return{items:(a?g.slice(0,a):g).map(a=>{let d,g=(0,c.join)(e,a),h=(0,b.readdirSync)(g,{withFileTypes:!0}).filter(a=>a.isDirectory()&&f(a.name)).map(a=>a.name).sort().reverse(),i=0,j=0;if(h.length>0){let a=(0,c.join)(g,h[0]);for(let d of(0,b.readdirSync)(a,{withFileTypes:!0}).filter(a=>a.isDirectory())){let e=(0,c.join)(a,d.name,"summary.json");if((0,b.existsSync)(e))try{let a=JSON.parse((0,b.readFileSync)(e,"utf-8"));i+=a.totalRuns??0,j+=a.passedRuns??0}catch{}}i>0&&(d=j/i*100)}return{name:a,timestamps:h,latestTimestamp:h[0]??null,latestPassRate:d,latestTotalRuns:i,latestPassedRuns:j}}),total:h}}function h(a){let e=(0,c.join)(d(),a);if(!(0,b.existsSync)(e))return null;let f=(0,b.readdirSync)(e,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name).sort().reverse();return{name:a,timestamps:f,latestTimestamp:f[0]??null}}function i(a,e){let f=(0,c.join)(d(),a,e);if(!(0,b.existsSync)(f))return null;let g=[];return!function a(d,e=""){for(let f of(0,b.readdirSync)(d,{withFileTypes:!0})){if(!f.isDirectory()||f.name.startsWith(".")||f.name.startsWith("run-"))continue;let h=e?`${e}/${f.name}`:f.name,i=(0,c.join)(d,f.name),j=(0,c.join)(i,"summary.json");(0,b.existsSync)(j)?g.push(h):a(i,h)}}(f),g.sort(),{name:a,timestamp:e,evals:g.map(a=>{let d=(0,c.join)(f,a),e=(0,c.join)(d,"summary.json"),g={totalRuns:0,passedRuns:0,passRate:"0%",meanDuration:0};if((0,b.existsSync)(e))try{g=JSON.parse((0,b.readFileSync)(e,"utf-8"))}catch{}let h=(0,b.readdirSync)(d,{withFileTypes:!0}).filter(a=>a.isDirectory()&&a.name.startsWith("run-")).map(a=>a.name).sort().map(a=>{let e=(0,c.join)(d,a,"result.json"),f=null;if((0,b.existsSync)(e))try{f=JSON.parse((0,b.readFileSync)(e,"utf-8"))}catch{}return{name:a,result:f}});return{name:a,totalRuns:g.totalRuns,passedRuns:g.passedRuns,passRate:"string"==typeof g.passRate?parseFloat(g.passRate):g.passRate,meanDuration:g.meanDuration,runs:h}})}}function j(a,e,f,g){let h=(0,c.join)(d(),a,e,f,g,"transcript.json");if(!(0,b.existsSync)(h))return null;try{return JSON.parse((0,b.readFileSync)(h,"utf-8"))}catch{return null}}function k(a){let d=e();if(!(0,b.existsSync)(d))return{items:[],total:0};let f=[];!function a(d,e=""){for(let g of(0,b.readdirSync)(d,{withFileTypes:!0})){if(!g.isDirectory()||g.name.startsWith("."))continue;let h=e?`${e}/${g.name}`:g.name,i=(0,c.join)(d,g.name),j=(0,c.join)(i,"PROMPT.md");(0,b.existsSync)(j)?f.push(h):a(i,h)}}(d),f.sort();let g=f.length;return{items:(a?f.slice(0,a):f).map(a=>{let e=(0,c.join)(d,a),f=(0,c.join)(e,"PROMPT.md"),g="";return(0,b.existsSync)(f)&&(g=(0,b.readFileSync)(f,"utf-8")),{name:a,prompt:g,files:(0,b.readdirSync)(e,{withFileTypes:!0}).filter(a=>a.isFile()).map(a=>a.name)}}),total:g}}function l(a){let d=(0,c.join)(e(),a);if(!(0,b.existsSync)(d))return null;let f=(0,c.join)(d,"PROMPT.md"),g="";(0,b.existsSync)(f)&&(g=(0,b.readFileSync)(f,"utf-8"));let h=[];!function a(d,e){for(let f of(0,b.readdirSync)(d,{withFileTypes:!0})){if("node_modules"===f.name||".git"===f.name)continue;let b=e?`${e}/${f.name}`:f.name;f.isDirectory()?a((0,c.join)(d,f.name),b):h.push(b)}}(d,"");let i={};for(let a of["PROMPT.md","EVAL.ts","EVAL.tsx","package.json"]){let e=(0,c.join)(d,a);if((0,b.existsSync)(e))try{i[a]=(0,b.readFileSync)(e,"utf-8")}catch{}}return{name:a,prompt:g,files:h,fileContents:i}}a.s(["getEvalDetail",()=>l,"getExperiment",()=>h,"getExperimentDetail",()=>i,"getTranscript",()=>j,"listEvals",()=>k,"listExperiments",()=>g])},22977,a=>{"use strict";var b=a.i(7997),c=a.i(95387);function d({className:a,size:d="default",...e}){return(0,b.jsx)("div",{"data-slot":"card","data-size":d,className:(0,c.cn)("ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-lg py-4 text-xs/relaxed ring-1 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg group/card flex flex-col",a),...e})}function e({className:a,...d}){return(0,b.jsx)("div",{"data-slot":"card-header",className:(0,c.cn)("gap-1 rounded-t-lg px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]",a),...d})}function f({className:a,...d}){return(0,b.jsx)("div",{"data-slot":"card-title",className:(0,c.cn)("text-sm font-medium",a),...d})}function g({className:a,...d}){return(0,b.jsx)("div",{"data-slot":"card-content",className:(0,c.cn)("px-4 group-data-[size=sm]/card:px-3",a),...d})}a.s(["Card",()=>d,"CardContent",()=>g,"CardHeader",()=>e,"CardTitle",()=>f])},31636,a=>{"use strict";a.s(["ShowMore",()=>b]);let b=(0,a.i(11857).registerClientReference)(function(){throw Error("Attempted to call ShowMore() from the server but ShowMore is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ShowMore.tsx <module evaluation>","ShowMore")},15821,a=>{"use strict";a.s(["ShowMore",()=>b]);let b=(0,a.i(11857).registerClientReference)(function(){throw Error("Attempted to call ShowMore() from the server but ShowMore is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/packages/playground/components/ShowMore.tsx","ShowMore")},93835,a=>{"use strict";a.i(31636);var b=a.i(15821);a.n(b)},33383,a=>{"use strict";var b=a.i(7997),c=a.i(95936),d=a.i(20954),e=a.i(22977),f=a.i(93835);function g({experiments:a,total:g,showAll:h}){return 0===a.length?(0,b.jsx)(e.Card,{children:(0,b.jsxs)(e.CardContent,{className:"py-12 text-center",children:[(0,b.jsx)("p",{className:"text-muted-foreground text-lg",children:"No experiments found"}),(0,b.jsxs)("p",{className:"text-muted-foreground text-sm mt-2",children:["Run an experiment with ",(0,b.jsx)("code",{className:"text-foreground bg-muted px-1.5 py-0.5 rounded text-xs",children:"agent-eval <config>"})," to see results here."]})]})}):(0,b.jsx)(e.Card,{children:(0,b.jsx)(e.CardContent,{className:"pt-0",children:(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"grid grid-cols-[1fr_auto_auto_auto] gap-4 px-3 py-2 text-xs text-muted-foreground font-medium border-b border-border",children:[(0,b.jsx)("span",{children:"Name"}),(0,b.jsx)("span",{className:"w-12 text-right",children:"Runs"}),(0,b.jsx)("span",{className:"w-24",children:"Pass Rate"}),(0,b.jsx)("span",{className:"w-44",children:"Latest Run"})]}),(0,b.jsx)(f.ShowMore,{total:g,showAllHref:h?void 0:"/experiments?all",children:a.map(a=>(0,b.jsxs)("div",{className:"grid grid-cols-[1fr_auto_auto_auto] gap-4 items-center px-3 py-2.5 transition-colors hover:bg-muted rounded-md",children:[(0,b.jsx)(c.default,{href:`/experiments/${encodeURIComponent(a.name)}`,className:"font-medium truncate hover:underline",children:a.name}),(0,b.jsx)(c.default,{href:`/experiments/${encodeURIComponent(a.name)}`,className:"w-12 text-right text-muted-foreground hover:text-foreground hover:underline",title:"View all runs",children:a.timestamps.length}),(0,b.jsx)(c.default,{href:a.latestTimestamp?`/experiments/${encodeURIComponent(a.name)}/${encodeURIComponent(a.latestTimestamp)}`:"#",className:"w-24 block",children:void 0!==a.latestPassRate?(0,b.jsxs)("span",{className:"flex items-center gap-2",children:[(0,b.jsxs)(d.Badge,{variant:100===a.latestPassRate?"default":a.latestPassRate>=50?"secondary":"destructive",children:[a.latestPassRate.toFixed(0),"%"]}),(0,b.jsxs)("span",{className:"text-xs text-muted-foreground",children:[a.latestPassedRuns,"/",a.latestTotalRuns]})]}):(0,b.jsx)("span",{className:"text-muted-foreground",children:"--"})}),(0,b.jsx)(c.default,{href:a.latestTimestamp?`/experiments/${encodeURIComponent(a.name)}/${encodeURIComponent(a.latestTimestamp)}`:"#",className:"w-44 text-xs text-muted-foreground hover:text-foreground",children:a.latestTimestamp?function(a){try{let b=a.replace(/T(\d{2})-(\d{2})-(\d{2})/,"T$1:$2:$3"),c=new Date(b);if(isNaN(c.getTime()))return a;return c.toLocaleString()}catch{return a}}(a.latestTimestamp):"--"})]},a.name))})]})})})}var h=a.i(5419);async function i({searchParams:a}){let{all:c}=await a,d=void 0!==c,{items:e,total:f}=(0,h.listExperiments)(d?void 0:20);return(0,b.jsxs)("div",{className:"space-y-6",children:[(0,b.jsxs)("div",{children:[(0,b.jsx)("h1",{className:"text-2xl font-bold tracking-tight",children:"Experiments"}),(0,b.jsx)("p",{className:"text-muted-foreground mt-1",children:"Browse and inspect your agent evaluation results."})]}),(0,b.jsx)(g,{experiments:e,total:f,showAll:d})]})}a.s(["default",()=>i,"dynamic",0,"force-dynamic"],33383)}];
2
2
 
3
3
  //# sourceMappingURL=%5Broot-of-the-server%5D__ac2a456c._.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/playground/lib/data.ts","../../../../../../packages/playground/components/ui/card.tsx","../../../../../../packages/playground/components/ShowMore.tsx/__nextjs-internal-proxy.mjs","../../../../../../packages/playground/components/ExperimentList.tsx","../../../../../../packages/playground/app/experiments/page.tsx"],"sourcesContent":["/**\n * Server-side data access for the playground.\n * Reads JSON files from the results/ and evals/ directories.\n * Directory paths are provided via RESULTS_DIR and EVALS_DIR env vars.\n */\n\nimport { readdirSync, readFileSync, existsSync } from \"fs\";\nimport { join, resolve } from \"path\";\n\nfunction getResultsDir(): string {\n return resolve(process.env.RESULTS_DIR || \"./results\");\n}\n\nfunction getEvalsDir(): string {\n return resolve(process.env.EVALS_DIR || \"./evals\");\n}\n\n/** Check if a directory name looks like an ISO timestamp (used as run ID) */\nfunction isTimestamp(name: string): boolean {\n return /^\\d{4}-\\d{2}-\\d{2}T/.test(name);\n}\n\n/** List experiments from the results directory. Pass limit to cap expensive per-item reads. */\nexport function listExperiments(limit?: number) {\n const resultsDir = getResultsDir();\n\n if (!existsSync(resultsDir)) {\n return { items: [], total: 0 };\n }\n\n // Discover experiments by walking the directory tree until we find\n // timestamp directories. The path from resultsDir to the parent of the\n // first timestamp is the experiment name (e.g. \"my-config/openai/gpt-5.2-codex\").\n const entries: string[] = [];\n\n function walk(dir: string, prefix: string) {\n const children = readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n\n // If any child looks like a timestamp, this directory is an experiment\n if (children.some(isTimestamp)) {\n entries.push(prefix);\n return;\n }\n\n // Otherwise keep recursing\n for (const child of children) {\n walk(join(dir, child), prefix ? `${prefix}/${child}` : child);\n }\n }\n\n walk(resultsDir, \"\");\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const expDir = join(resultsDir, name);\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && isTimestamp(e.name))\n .map((e) => e.name)\n .sort()\n .reverse();\n\n let latestPassRate: number | undefined;\n let latestTotalRuns = 0;\n let latestPassedRuns = 0;\n\n if (timestamps.length > 0) {\n const latestDir = join(expDir, timestamps[0]);\n const evalDirs = readdirSync(latestDir, { withFileTypes: true }).filter(\n (e) => e.isDirectory()\n );\n\n for (const evalDir of evalDirs) {\n const summaryPath = join(latestDir, evalDir.name, \"summary.json\");\n if (existsSync(summaryPath)) {\n try {\n const summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n latestTotalRuns += summary.totalRuns ?? 0;\n latestPassedRuns += summary.passedRuns ?? 0;\n } catch {\n // Skip invalid summary files\n }\n }\n }\n\n if (latestTotalRuns > 0) {\n latestPassRate = (latestPassedRuns / latestTotalRuns) * 100;\n }\n }\n\n return {\n name,\n timestamps,\n latestTimestamp: timestamps[0] ?? null,\n latestPassRate,\n latestTotalRuns,\n latestPassedRuns,\n };\n });\n\n return { items, total };\n}\n\n/** Get timestamps for a specific experiment */\nexport function getExperiment(name: string) {\n const expDir = join(getResultsDir(), name);\n\n if (!existsSync(expDir)) {\n return null;\n }\n\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .sort()\n .reverse();\n\n return { name, timestamps, latestTimestamp: timestamps[0] ?? null };\n}\n\n/** Get full experiment detail for a specific timestamp */\nexport function getExperimentDetail(name: string, timestamp: string) {\n const runDir = join(getResultsDir(), name, timestamp);\n\n if (!existsSync(runDir)) {\n return null;\n }\n\n // Recursively discover all eval result directories (directories with summary.json)\n const evalDirs: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\") || entry.name.startsWith(\"run-\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const summaryPath = join(entryPath, \"summary.json\");\n\n // Check if this is an eval result directory (has summary.json)\n if (existsSync(summaryPath)) {\n evalDirs.push(relativePath);\n } else {\n // Not an eval result, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(runDir);\n evalDirs.sort();\n\n const evals = evalDirs.map((evalName) => {\n const evalDir = join(runDir, evalName);\n const summaryPath = join(evalDir, \"summary.json\");\n\n let summary = {\n totalRuns: 0,\n passedRuns: 0,\n passRate: \"0%\",\n meanDuration: 0,\n };\n if (existsSync(summaryPath)) {\n try {\n summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n } catch {\n // Use defaults\n }\n }\n\n // List run directories\n const runDirs = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && e.name.startsWith(\"run-\"))\n .map((e) => e.name)\n .sort();\n\n // Read each run's result.json\n const runs = runDirs.map((runDirName) => {\n const resultPath = join(evalDir, runDirName, \"result.json\");\n let result = null;\n if (existsSync(resultPath)) {\n try {\n result = JSON.parse(readFileSync(resultPath, \"utf-8\"));\n } catch {\n // Skip\n }\n }\n return { name: runDirName, result };\n });\n\n return {\n name: evalName,\n totalRuns: summary.totalRuns,\n passedRuns: summary.passedRuns,\n passRate:\n typeof summary.passRate === \"string\"\n ? parseFloat(summary.passRate)\n : summary.passRate,\n meanDuration: summary.meanDuration,\n runs,\n };\n });\n\n return { name, timestamp, evals };\n}\n\n/** Get result for a specific run */\nexport function getRunResult(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const resultPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"result.json\"\n );\n\n if (!existsSync(resultPath)) {\n return null;\n }\n\n try {\n return { result: JSON.parse(readFileSync(resultPath, \"utf-8\")) };\n } catch {\n return null;\n }\n}\n\n/** Get parsed transcript for a specific run */\nexport function getTranscript(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const transcriptPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"transcript.json\"\n );\n\n if (!existsSync(transcriptPath)) {\n return null;\n }\n\n try {\n return JSON.parse(readFileSync(transcriptPath, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\n/** List evals from the evals directory. Pass limit to cap per-item reads. */\nexport function listEvals(limit?: number) {\n const evalsDir = getEvalsDir();\n\n if (!existsSync(evalsDir)) {\n return { items: [], total: 0 };\n }\n\n // Recursively discover all evals (directories with PROMPT.md)\n const entries: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const promptPath = join(entryPath, \"PROMPT.md\");\n\n // Check if this is an eval directory (has PROMPT.md)\n if (existsSync(promptPath)) {\n entries.push(relativePath);\n } else {\n // Not an eval, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(evalsDir);\n entries.sort();\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const evalDir = join(evalsDir, name);\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n const files = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isFile())\n .map((e) => e.name);\n\n return { name, prompt, files };\n });\n\n return { items, total };\n}\n\n/** Get detail for a specific eval */\nexport function getEvalDetail(name: string) {\n const evalDir = join(getEvalsDir(), name);\n\n if (!existsSync(evalDir)) {\n return null;\n }\n\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n // Recursively list files\n const files: string[] = [];\n function walk(dir: string, prefix: string) {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name === \"node_modules\" || entry.name === \".git\") continue;\n const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (entry.isDirectory()) {\n walk(join(dir, entry.name), relativePath);\n } else {\n files.push(relativePath);\n }\n }\n }\n walk(evalDir, \"\");\n\n // Read file contents for key files\n const fileContents: Record<string, string> = {};\n const keyFiles = [\"PROMPT.md\", \"EVAL.ts\", \"EVAL.tsx\", \"package.json\"];\n for (const file of keyFiles) {\n const filePath = join(evalDir, file);\n if (existsSync(filePath)) {\n try {\n fileContents[file] = readFileSync(filePath, \"utf-8\");\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return { name, prompt, files, fileContents };\n}\n","import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Card({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\n return (\n <div\n data-slot=\"card\"\n data-size={size}\n className={cn(\"ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-lg py-4 text-xs/relaxed ring-1 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg group/card flex flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"gap-1 rounded-t-lg px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\"text-sm font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-muted-foreground text-xs/relaxed\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-4 group-data-[size=sm]/card:px-3\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\"rounded-b-lg px-4 group-data-[size=sm]/card:px-3 [.border-t]:pt-4 group-data-[size=sm]/card:[.border-t]:pt-3 flex items-center\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n","// This file is generated by next-core EcmascriptClientReferenceModule.\nimport { registerClientReference } from \"react-server-dom-turbopack/server\";\nexport const ShowMore = registerClientReference(\n function() { throw new Error(\"Attempted to call ShowMore() from the server but ShowMore is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ShowMore.tsx\",\n \"ShowMore\",\n);\n","import Link from \"next/link\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { ShowMore } from \"@/components/ShowMore\";\n\ninterface ExperimentInfo {\n name: string;\n timestamps: string[];\n latestTimestamp: string | null;\n latestPassRate?: number;\n latestTotalRuns?: number;\n latestPassedRuns?: number;\n}\n\ninterface ExperimentListProps {\n experiments: ExperimentInfo[];\n total: number;\n showAll: boolean;\n}\n\nexport function ExperimentList({ experiments, total, showAll }: ExperimentListProps) {\n if (experiments.length === 0) {\n return (\n <Card>\n <CardContent className=\"py-12 text-center\">\n <p className=\"text-muted-foreground text-lg\">No experiments found</p>\n <p className=\"text-muted-foreground text-sm mt-2\">\n Run an experiment with <code className=\"text-foreground bg-muted px-1.5 py-0.5 rounded text-xs\">agent-eval &lt;config&gt;</code> to see results here.\n </p>\n </CardContent>\n </Card>\n );\n }\n\n return (\n <Card>\n <CardContent className=\"pt-0\">\n <div>\n {/* Header */}\n <div className=\"grid grid-cols-[1fr_auto_auto_auto] gap-4 px-3 py-2 text-xs text-muted-foreground font-medium border-b border-border\">\n <span>Name</span>\n <span className=\"w-12 text-right\">Runs</span>\n <span className=\"w-24\">Pass Rate</span>\n <span className=\"w-44\">Latest Run</span>\n </div>\n {/* Rows */}\n <ShowMore total={total} showAllHref={showAll ? undefined : \"/experiments?all\"}>\n {experiments.map((exp) => (\n <Link\n key={exp.name}\n href={\n exp.latestTimestamp\n ? `/experiments/${encodeURIComponent(exp.name)}/${encodeURIComponent(exp.latestTimestamp)}`\n : \"#\"\n }\n className=\"grid grid-cols-[1fr_auto_auto_auto] gap-4 items-center px-3 py-2.5 cursor-pointer transition-colors hover:bg-muted rounded-md\"\n >\n <span className=\"font-medium truncate\">{exp.name}</span>\n <span className=\"w-12 text-right text-muted-foreground\">{exp.timestamps.length}</span>\n <span className=\"w-24\">\n {exp.latestPassRate !== undefined ? (\n <span className=\"flex items-center gap-2\">\n <Badge\n variant={\n exp.latestPassRate === 100\n ? \"default\"\n : exp.latestPassRate >= 50\n ? \"secondary\"\n : \"destructive\"\n }\n >\n {exp.latestPassRate.toFixed(0)}%\n </Badge>\n <span className=\"text-xs text-muted-foreground\">\n {exp.latestPassedRuns}/{exp.latestTotalRuns}\n </span>\n </span>\n ) : (\n <span className=\"text-muted-foreground\">--</span>\n )}\n </span>\n <span className=\"w-44 text-xs text-muted-foreground\">\n {exp.latestTimestamp ? formatTimestamp(exp.latestTimestamp) : \"--\"}\n </span>\n </Link>\n ))}\n </ShowMore>\n </div>\n </CardContent>\n </Card>\n );\n}\n\nfunction formatTimestamp(ts: string): string {\n try {\n const isoString = ts.replace(/T(\\d{2})-(\\d{2})-(\\d{2})/, \"T$1:$2:$3\");\n const date = new Date(isoString);\n if (isNaN(date.getTime())) return ts;\n return date.toLocaleString();\n } catch {\n return ts;\n }\n}\n","import { ExperimentList } from \"@/components/ExperimentList\";\nimport { listExperiments } from \"@/lib/data\";\n\nexport const dynamic = \"force-dynamic\";\n\nconst LIMIT = 20;\n\nexport default async function ExperimentsPage({\n searchParams,\n}: {\n searchParams: Promise<{ all?: string }>;\n}) {\n const { all } = await searchParams;\n const showAll = all !== undefined;\n const { items: experiments, total } = listExperiments(showAll ? undefined : LIMIT);\n\n return (\n <div className=\"space-y-6\">\n <div>\n <h1 className=\"text-2xl font-bold tracking-tight\">Experiments</h1>\n <p className=\"text-muted-foreground mt-1\">\n Browse and inspect your agent evaluation results.\n </p>\n </div>\n <ExperimentList experiments={experiments} total={total} showAll={showAll} />\n </div>\n );\n}\n"],"names":[],"mappings":"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","ignoreList":[2]}
1
+ {"version":3,"sources":["../../../../../../packages/playground/lib/data.ts","../../../../../../packages/playground/components/ui/card.tsx","../../../../../../packages/playground/components/ShowMore.tsx/__nextjs-internal-proxy.mjs","../../../../../../packages/playground/components/ExperimentList.tsx","../../../../../../packages/playground/app/experiments/page.tsx"],"sourcesContent":["/**\n * Server-side data access for the playground.\n * Reads JSON files from the results/ and evals/ directories.\n * Directory paths are provided via RESULTS_DIR and EVALS_DIR env vars.\n */\n\nimport { readdirSync, readFileSync, existsSync } from \"fs\";\nimport { join, resolve } from \"path\";\n\nfunction getResultsDir(): string {\n return resolve(process.env.RESULTS_DIR || \"./results\");\n}\n\nfunction getEvalsDir(): string {\n return resolve(process.env.EVALS_DIR || \"./evals\");\n}\n\n/** Check if a directory name looks like an ISO timestamp (used as run ID) */\nfunction isTimestamp(name: string): boolean {\n return /^\\d{4}-\\d{2}-\\d{2}T/.test(name);\n}\n\n/** List experiments from the results directory. Pass limit to cap expensive per-item reads. */\nexport function listExperiments(limit?: number) {\n const resultsDir = getResultsDir();\n\n if (!existsSync(resultsDir)) {\n return { items: [], total: 0 };\n }\n\n // Discover experiments by walking the directory tree until we find\n // timestamp directories. The path from resultsDir to the parent of the\n // first timestamp is the experiment name (e.g. \"my-config/openai/gpt-5.2-codex\").\n const entries: string[] = [];\n\n function walk(dir: string, prefix: string) {\n const children = readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n\n // If any child looks like a timestamp, this directory is an experiment\n if (children.some(isTimestamp)) {\n entries.push(prefix);\n return;\n }\n\n // Otherwise keep recursing\n for (const child of children) {\n walk(join(dir, child), prefix ? `${prefix}/${child}` : child);\n }\n }\n\n walk(resultsDir, \"\");\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const expDir = join(resultsDir, name);\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && isTimestamp(e.name))\n .map((e) => e.name)\n .sort()\n .reverse();\n\n let latestPassRate: number | undefined;\n let latestTotalRuns = 0;\n let latestPassedRuns = 0;\n\n if (timestamps.length > 0) {\n const latestDir = join(expDir, timestamps[0]);\n const evalDirs = readdirSync(latestDir, { withFileTypes: true }).filter(\n (e) => e.isDirectory()\n );\n\n for (const evalDir of evalDirs) {\n const summaryPath = join(latestDir, evalDir.name, \"summary.json\");\n if (existsSync(summaryPath)) {\n try {\n const summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n latestTotalRuns += summary.totalRuns ?? 0;\n latestPassedRuns += summary.passedRuns ?? 0;\n } catch {\n // Skip invalid summary files\n }\n }\n }\n\n if (latestTotalRuns > 0) {\n latestPassRate = (latestPassedRuns / latestTotalRuns) * 100;\n }\n }\n\n return {\n name,\n timestamps,\n latestTimestamp: timestamps[0] ?? null,\n latestPassRate,\n latestTotalRuns,\n latestPassedRuns,\n };\n });\n\n return { items, total };\n}\n\n/** Get timestamps for a specific experiment */\nexport function getExperiment(name: string) {\n const expDir = join(getResultsDir(), name);\n\n if (!existsSync(expDir)) {\n return null;\n }\n\n const timestamps = readdirSync(expDir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .sort()\n .reverse();\n\n return { name, timestamps, latestTimestamp: timestamps[0] ?? null };\n}\n\n/** Get full experiment detail for a specific timestamp */\nexport function getExperimentDetail(name: string, timestamp: string) {\n const runDir = join(getResultsDir(), name, timestamp);\n\n if (!existsSync(runDir)) {\n return null;\n }\n\n // Recursively discover all eval result directories (directories with summary.json)\n const evalDirs: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\") || entry.name.startsWith(\"run-\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const summaryPath = join(entryPath, \"summary.json\");\n\n // Check if this is an eval result directory (has summary.json)\n if (existsSync(summaryPath)) {\n evalDirs.push(relativePath);\n } else {\n // Not an eval result, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(runDir);\n evalDirs.sort();\n\n const evals = evalDirs.map((evalName) => {\n const evalDir = join(runDir, evalName);\n const summaryPath = join(evalDir, \"summary.json\");\n\n let summary = {\n totalRuns: 0,\n passedRuns: 0,\n passRate: \"0%\",\n meanDuration: 0,\n };\n if (existsSync(summaryPath)) {\n try {\n summary = JSON.parse(readFileSync(summaryPath, \"utf-8\"));\n } catch {\n // Use defaults\n }\n }\n\n // List run directories\n const runDirs = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && e.name.startsWith(\"run-\"))\n .map((e) => e.name)\n .sort();\n\n // Read each run's result.json\n const runs = runDirs.map((runDirName) => {\n const resultPath = join(evalDir, runDirName, \"result.json\");\n let result = null;\n if (existsSync(resultPath)) {\n try {\n result = JSON.parse(readFileSync(resultPath, \"utf-8\"));\n } catch {\n // Skip\n }\n }\n return { name: runDirName, result };\n });\n\n return {\n name: evalName,\n totalRuns: summary.totalRuns,\n passedRuns: summary.passedRuns,\n passRate:\n typeof summary.passRate === \"string\"\n ? parseFloat(summary.passRate)\n : summary.passRate,\n meanDuration: summary.meanDuration,\n runs,\n };\n });\n\n return { name, timestamp, evals };\n}\n\n/** Get result for a specific run */\nexport function getRunResult(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const resultPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"result.json\"\n );\n\n if (!existsSync(resultPath)) {\n return null;\n }\n\n try {\n return { result: JSON.parse(readFileSync(resultPath, \"utf-8\")) };\n } catch {\n return null;\n }\n}\n\n/** Get parsed transcript for a specific run */\nexport function getTranscript(\n experiment: string,\n timestamp: string,\n evalName: string,\n run: string\n) {\n const transcriptPath = join(\n getResultsDir(),\n experiment,\n timestamp,\n evalName,\n run,\n \"transcript.json\"\n );\n\n if (!existsSync(transcriptPath)) {\n return null;\n }\n\n try {\n return JSON.parse(readFileSync(transcriptPath, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\n/** List evals from the evals directory. Pass limit to cap per-item reads. */\nexport function listEvals(limit?: number) {\n const evalsDir = getEvalsDir();\n\n if (!existsSync(evalsDir)) {\n return { items: [], total: 0 };\n }\n\n // Recursively discover all evals (directories with PROMPT.md)\n const entries: string[] = [];\n function walk(dir: string, basePath: string = \"\") {\n const dirEntries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\")) {\n continue;\n }\n\n const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;\n const entryPath = join(dir, entry.name);\n const promptPath = join(entryPath, \"PROMPT.md\");\n\n // Check if this is an eval directory (has PROMPT.md)\n if (existsSync(promptPath)) {\n entries.push(relativePath);\n } else {\n // Not an eval, recurse into it\n walk(entryPath, relativePath);\n }\n }\n }\n\n walk(evalsDir);\n entries.sort();\n\n const total = entries.length;\n const toProcess = limit ? entries.slice(0, limit) : entries;\n\n const items = toProcess.map((name) => {\n const evalDir = join(evalsDir, name);\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n const files = readdirSync(evalDir, { withFileTypes: true })\n .filter((e) => e.isFile())\n .map((e) => e.name);\n\n return { name, prompt, files };\n });\n\n return { items, total };\n}\n\n/** Get detail for a specific eval */\nexport function getEvalDetail(name: string) {\n const evalDir = join(getEvalsDir(), name);\n\n if (!existsSync(evalDir)) {\n return null;\n }\n\n const promptPath = join(evalDir, \"PROMPT.md\");\n let prompt = \"\";\n if (existsSync(promptPath)) {\n prompt = readFileSync(promptPath, \"utf-8\");\n }\n\n // Recursively list files\n const files: string[] = [];\n function walk(dir: string, prefix: string) {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name === \"node_modules\" || entry.name === \".git\") continue;\n const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (entry.isDirectory()) {\n walk(join(dir, entry.name), relativePath);\n } else {\n files.push(relativePath);\n }\n }\n }\n walk(evalDir, \"\");\n\n // Read file contents for key files\n const fileContents: Record<string, string> = {};\n const keyFiles = [\"PROMPT.md\", \"EVAL.ts\", \"EVAL.tsx\", \"package.json\"];\n for (const file of keyFiles) {\n const filePath = join(evalDir, file);\n if (existsSync(filePath)) {\n try {\n fileContents[file] = readFileSync(filePath, \"utf-8\");\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return { name, prompt, files, fileContents };\n}\n","import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Card({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\n return (\n <div\n data-slot=\"card\"\n data-size={size}\n className={cn(\"ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-lg py-4 text-xs/relaxed ring-1 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg group/card flex flex-col\", className)}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"gap-1 rounded-t-lg px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\"text-sm font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-muted-foreground text-xs/relaxed\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-4 group-data-[size=sm]/card:px-3\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\"rounded-b-lg px-4 group-data-[size=sm]/card:px-3 [.border-t]:pt-4 group-data-[size=sm]/card:[.border-t]:pt-3 flex items-center\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n","// This file is generated by next-core EcmascriptClientReferenceModule.\nimport { registerClientReference } from \"react-server-dom-turbopack/server\";\nexport const ShowMore = registerClientReference(\n function() { throw new Error(\"Attempted to call ShowMore() from the server but ShowMore is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.\"); },\n \"[project]/packages/playground/components/ShowMore.tsx\",\n \"ShowMore\",\n);\n","import Link from \"next/link\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { ShowMore } from \"@/components/ShowMore\";\n\ninterface ExperimentInfo {\n name: string;\n timestamps: string[];\n latestTimestamp: string | null;\n latestPassRate?: number;\n latestTotalRuns?: number;\n latestPassedRuns?: number;\n}\n\ninterface ExperimentListProps {\n experiments: ExperimentInfo[];\n total: number;\n showAll: boolean;\n}\n\nexport function ExperimentList({ experiments, total, showAll }: ExperimentListProps) {\n if (experiments.length === 0) {\n return (\n <Card>\n <CardContent className=\"py-12 text-center\">\n <p className=\"text-muted-foreground text-lg\">No experiments found</p>\n <p className=\"text-muted-foreground text-sm mt-2\">\n Run an experiment with <code className=\"text-foreground bg-muted px-1.5 py-0.5 rounded text-xs\">agent-eval &lt;config&gt;</code> to see results here.\n </p>\n </CardContent>\n </Card>\n );\n }\n\n return (\n <Card>\n <CardContent className=\"pt-0\">\n <div>\n {/* Header */}\n <div className=\"grid grid-cols-[1fr_auto_auto_auto] gap-4 px-3 py-2 text-xs text-muted-foreground font-medium border-b border-border\">\n <span>Name</span>\n <span className=\"w-12 text-right\">Runs</span>\n <span className=\"w-24\">Pass Rate</span>\n <span className=\"w-44\">Latest Run</span>\n </div>\n {/* Rows */}\n <ShowMore total={total} showAllHref={showAll ? undefined : \"/experiments?all\"}>\n {experiments.map((exp) => (\n <div\n key={exp.name}\n className=\"grid grid-cols-[1fr_auto_auto_auto] gap-4 items-center px-3 py-2.5 transition-colors hover:bg-muted rounded-md\"\n >\n <Link\n href={`/experiments/${encodeURIComponent(exp.name)}`}\n className=\"font-medium truncate hover:underline\"\n >\n {exp.name}\n </Link>\n <Link\n href={`/experiments/${encodeURIComponent(exp.name)}`}\n className=\"w-12 text-right text-muted-foreground hover:text-foreground hover:underline\"\n title=\"View all runs\"\n >\n {exp.timestamps.length}\n </Link>\n <Link\n href={\n exp.latestTimestamp\n ? `/experiments/${encodeURIComponent(exp.name)}/${encodeURIComponent(exp.latestTimestamp)}`\n : \"#\"\n }\n className=\"w-24 block\"\n >\n {exp.latestPassRate !== undefined ? (\n <span className=\"flex items-center gap-2\">\n <Badge\n variant={\n exp.latestPassRate === 100\n ? \"default\"\n : exp.latestPassRate >= 50\n ? \"secondary\"\n : \"destructive\"\n }\n >\n {exp.latestPassRate.toFixed(0)}%\n </Badge>\n <span className=\"text-xs text-muted-foreground\">\n {exp.latestPassedRuns}/{exp.latestTotalRuns}\n </span>\n </span>\n ) : (\n <span className=\"text-muted-foreground\">--</span>\n )}\n </Link>\n <Link\n href={\n exp.latestTimestamp\n ? `/experiments/${encodeURIComponent(exp.name)}/${encodeURIComponent(exp.latestTimestamp)}`\n : \"#\"\n }\n className=\"w-44 text-xs text-muted-foreground hover:text-foreground\"\n >\n {exp.latestTimestamp ? formatTimestamp(exp.latestTimestamp) : \"--\"}\n </Link>\n </div>\n ))}\n </ShowMore>\n </div>\n </CardContent>\n </Card>\n );\n}\n\nfunction formatTimestamp(ts: string): string {\n try {\n const isoString = ts.replace(/T(\\d{2})-(\\d{2})-(\\d{2})/, \"T$1:$2:$3\");\n const date = new Date(isoString);\n if (isNaN(date.getTime())) return ts;\n return date.toLocaleString();\n } catch {\n return ts;\n }\n}\n","import { ExperimentList } from \"@/components/ExperimentList\";\nimport { listExperiments } from \"@/lib/data\";\n\nexport const dynamic = \"force-dynamic\";\n\nconst LIMIT = 20;\n\nexport default async function ExperimentsPage({\n searchParams,\n}: {\n searchParams: Promise<{ all?: string }>;\n}) {\n const { all } = await searchParams;\n const showAll = all !== undefined;\n const { items: experiments, total } = listExperiments(showAll ? undefined : LIMIT);\n\n return (\n <div className=\"space-y-6\">\n <div>\n <h1 className=\"text-2xl font-bold tracking-tight\">Experiments</h1>\n <p className=\"text-muted-foreground mt-1\">\n Browse and inspect your agent evaluation results.\n </p>\n </div>\n <ExperimentList experiments={experiments} total={total} showAll={showAll} />\n </div>\n );\n}\n"],"names":[],"mappings":"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","ignoreList":[2]}
@@ -0,0 +1,3 @@
1
+ module.exports=[69046,a=>{a.n(a.i(80979))},43619,a=>{a.n(a.i(79962))},13718,a=>{a.n(a.i(85523))},18198,a=>{a.n(a.i(45518))},62212,a=>{a.n(a.i(66114))},22734,(a,b,c)=>{b.exports=a.x("fs",()=>require("fs"))},5419,a=>{"use strict";var b=a.i(22734),c=a.i(14747);function d(){return(0,c.resolve)(process.env.RESULTS_DIR||"./results")}function e(){return(0,c.resolve)(process.env.EVALS_DIR||"./evals")}function f(a){return/^\d{4}-\d{2}-\d{2}T/.test(a)}function g(a){let e=d();if(!(0,b.existsSync)(e))return{items:[],total:0};let g=[];!function a(d,e){let h=(0,b.readdirSync)(d,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name);if(h.some(f))return void g.push(e);for(let b of h)a((0,c.join)(d,b),e?`${e}/${b}`:b)}(e,"");let h=g.length;return{items:(a?g.slice(0,a):g).map(a=>{let d,g=(0,c.join)(e,a),h=(0,b.readdirSync)(g,{withFileTypes:!0}).filter(a=>a.isDirectory()&&f(a.name)).map(a=>a.name).sort().reverse(),i=0,j=0;if(h.length>0){let a=(0,c.join)(g,h[0]);for(let d of(0,b.readdirSync)(a,{withFileTypes:!0}).filter(a=>a.isDirectory())){let e=(0,c.join)(a,d.name,"summary.json");if((0,b.existsSync)(e))try{let a=JSON.parse((0,b.readFileSync)(e,"utf-8"));i+=a.totalRuns??0,j+=a.passedRuns??0}catch{}}i>0&&(d=j/i*100)}return{name:a,timestamps:h,latestTimestamp:h[0]??null,latestPassRate:d,latestTotalRuns:i,latestPassedRuns:j}}),total:h}}function h(a){let e=(0,c.join)(d(),a);if(!(0,b.existsSync)(e))return null;let f=(0,b.readdirSync)(e,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name).sort().reverse();return{name:a,timestamps:f,latestTimestamp:f[0]??null}}function i(a,e){let f=(0,c.join)(d(),a,e);if(!(0,b.existsSync)(f))return null;let g=[];return!function a(d,e=""){for(let f of(0,b.readdirSync)(d,{withFileTypes:!0})){if(!f.isDirectory()||f.name.startsWith(".")||f.name.startsWith("run-"))continue;let h=e?`${e}/${f.name}`:f.name,i=(0,c.join)(d,f.name),j=(0,c.join)(i,"summary.json");(0,b.existsSync)(j)?g.push(h):a(i,h)}}(f),g.sort(),{name:a,timestamp:e,evals:g.map(a=>{let d=(0,c.join)(f,a),e=(0,c.join)(d,"summary.json"),g={totalRuns:0,passedRuns:0,passRate:"0%",meanDuration:0};if((0,b.existsSync)(e))try{g=JSON.parse((0,b.readFileSync)(e,"utf-8"))}catch{}let h=(0,b.readdirSync)(d,{withFileTypes:!0}).filter(a=>a.isDirectory()&&a.name.startsWith("run-")).map(a=>a.name).sort().map(a=>{let e=(0,c.join)(d,a,"result.json"),f=null;if((0,b.existsSync)(e))try{f=JSON.parse((0,b.readFileSync)(e,"utf-8"))}catch{}return{name:a,result:f}});return{name:a,totalRuns:g.totalRuns,passedRuns:g.passedRuns,passRate:"string"==typeof g.passRate?parseFloat(g.passRate):g.passRate,meanDuration:g.meanDuration,runs:h}})}}function j(a,e,f,g){let h=(0,c.join)(d(),a,e,f,g,"transcript.json");if(!(0,b.existsSync)(h))return null;try{return JSON.parse((0,b.readFileSync)(h,"utf-8"))}catch{return null}}function k(a){let d=e();if(!(0,b.existsSync)(d))return{items:[],total:0};let f=[];!function a(d,e=""){for(let g of(0,b.readdirSync)(d,{withFileTypes:!0})){if(!g.isDirectory()||g.name.startsWith("."))continue;let h=e?`${e}/${g.name}`:g.name,i=(0,c.join)(d,g.name),j=(0,c.join)(i,"PROMPT.md");(0,b.existsSync)(j)?f.push(h):a(i,h)}}(d),f.sort();let g=f.length;return{items:(a?f.slice(0,a):f).map(a=>{let e=(0,c.join)(d,a),f=(0,c.join)(e,"PROMPT.md"),g="";return(0,b.existsSync)(f)&&(g=(0,b.readFileSync)(f,"utf-8")),{name:a,prompt:g,files:(0,b.readdirSync)(e,{withFileTypes:!0}).filter(a=>a.isFile()).map(a=>a.name)}}),total:g}}function l(a){let d=(0,c.join)(e(),a);if(!(0,b.existsSync)(d))return null;let f=(0,c.join)(d,"PROMPT.md"),g="";(0,b.existsSync)(f)&&(g=(0,b.readFileSync)(f,"utf-8"));let h=[];!function a(d,e){for(let f of(0,b.readdirSync)(d,{withFileTypes:!0})){if("node_modules"===f.name||".git"===f.name)continue;let b=e?`${e}/${f.name}`:f.name;f.isDirectory()?a((0,c.join)(d,f.name),b):h.push(b)}}(d,"");let i={};for(let a of["PROMPT.md","EVAL.ts","EVAL.tsx","package.json"]){let e=(0,c.join)(d,a);if((0,b.existsSync)(e))try{i[a]=(0,b.readFileSync)(e,"utf-8")}catch{}}return{name:a,prompt:g,files:h,fileContents:i}}a.s(["getEvalDetail",()=>l,"getExperiment",()=>h,"getExperimentDetail",()=>i,"getTranscript",()=>j,"listEvals",()=>k,"listExperiments",()=>g])},22977,a=>{"use strict";var b=a.i(7997),c=a.i(95387);function d({className:a,size:d="default",...e}){return(0,b.jsx)("div",{"data-slot":"card","data-size":d,className:(0,c.cn)("ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-lg py-4 text-xs/relaxed ring-1 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg group/card flex flex-col",a),...e})}function e({className:a,...d}){return(0,b.jsx)("div",{"data-slot":"card-header",className:(0,c.cn)("gap-1 rounded-t-lg px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]",a),...d})}function f({className:a,...d}){return(0,b.jsx)("div",{"data-slot":"card-title",className:(0,c.cn)("text-sm font-medium",a),...d})}function g({className:a,...d}){return(0,b.jsx)("div",{"data-slot":"card-content",className:(0,c.cn)("px-4 group-data-[size=sm]/card:px-3",a),...d})}a.s(["Card",()=>d,"CardContent",()=>g,"CardHeader",()=>e,"CardTitle",()=>f])},7093,a=>{"use strict";var b=a.i(7997),c=a.i(95936),d=a.i(22977),e=a.i(20954),f=a.i(5419);a.i(70396);var g=a.i(73727);async function h({params:a}){let{name:h}=await a,i=decodeURIComponent(h),j=(0,f.getExperiment)(i);j||(0,g.notFound)();let k=j.timestamps.map(a=>{let b=(0,f.getExperimentDetail)(i,a);if(!b)return{timestamp:a,passRate:null,totalRuns:0,passedRuns:0};let c=b.evals.reduce((a,b)=>a+b.totalRuns,0),d=b.evals.reduce((a,b)=>a+b.passedRuns,0);return{timestamp:a,passRate:c>0?d/c*100:0,totalRuns:c,passedRuns:d,evalCount:b.evals.length}});return(0,b.jsxs)("div",{className:"space-y-6",children:[(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"flex items-center gap-2 text-sm text-muted-foreground mb-2",children:[(0,b.jsx)(c.default,{href:"/experiments",className:"hover:text-foreground",children:"Experiments"}),(0,b.jsx)("span",{children:"/"}),(0,b.jsx)("span",{children:i})]}),(0,b.jsx)("h1",{className:"text-2xl font-bold tracking-tight",children:i}),(0,b.jsxs)("p",{className:"text-muted-foreground mt-1",children:["All runs for this experiment (",j.timestamps.length," total)"]})]}),(0,b.jsx)(d.Card,{children:(0,b.jsx)(d.CardContent,{className:"pt-0",children:(0,b.jsxs)("div",{children:[(0,b.jsxs)("div",{className:"grid grid-cols-[auto_1fr_auto_auto] gap-4 px-3 py-2 text-xs text-muted-foreground font-medium border-b border-border",children:[(0,b.jsx)("span",{className:"w-8",children:"#"}),(0,b.jsx)("span",{children:"Timestamp"}),(0,b.jsx)("span",{className:"w-24",children:"Pass Rate"}),(0,b.jsx)("span",{className:"w-32",children:"Evals"})]}),k.map((a,d)=>(0,b.jsxs)(c.default,{href:`/experiments/${encodeURIComponent(i)}/${encodeURIComponent(a.timestamp)}`,className:"grid grid-cols-[auto_1fr_auto_auto] gap-4 items-center px-3 py-2.5 cursor-pointer transition-colors hover:bg-muted rounded-md",children:[(0,b.jsx)("span",{className:"w-8 text-muted-foreground",children:k.length-d}),(0,b.jsx)("span",{className:"font-mono text-sm",children:function(a){try{let b=a.replace(/T(\d{2})-(\d{2})-(\d{2})/,"T$1:$2:$3"),c=new Date(b);if(isNaN(c.getTime()))return a;return c.toLocaleString()}catch{return a}}(a.timestamp)}),(0,b.jsx)("span",{className:"w-24",children:null!==a.passRate?(0,b.jsxs)("span",{className:"flex items-center gap-2",children:[(0,b.jsxs)(e.Badge,{variant:100===a.passRate?"default":a.passRate>=50?"secondary":"destructive",children:[a.passRate.toFixed(0),"%"]}),(0,b.jsxs)("span",{className:"text-xs text-muted-foreground",children:[a.passedRuns,"/",a.totalRuns]})]}):(0,b.jsx)("span",{className:"text-muted-foreground",children:"--"})}),(0,b.jsxs)("span",{className:"w-32 text-sm text-muted-foreground",children:[a.evalCount??0," eval",1!==a.evalCount?"s":""]})]},a.timestamp))]})})})]})}a.s(["default",()=>h,"dynamic",0,"force-dynamic"])}];
2
+
3
+ //# sourceMappingURL=%5Broot-of-the-server%5D__aca11d57._.js.map