feat(web): i18n (#12471)
This commit is contained in:
@@ -3,6 +3,7 @@ import { createAsync, query, useParams } from "@solidjs/router"
|
||||
import { createSignal, For, Show } from "solid-js"
|
||||
import { Database, desc, eq } from "@opencode-ai/console-core/drizzle/index.js"
|
||||
import { BenchmarkTable } from "@opencode-ai/console-core/schema/benchmark.sql.js"
|
||||
import { useI18n } from "~/context/i18n"
|
||||
|
||||
interface TaskSource {
|
||||
repo: string
|
||||
@@ -100,32 +101,33 @@ function formatDuration(ms: number): string {
|
||||
|
||||
export default function BenchDetail() {
|
||||
const params = useParams()
|
||||
const i18n = useI18n()
|
||||
const [benchmarkId, taskId] = (params.id ?? "").split(":")
|
||||
const task = createAsync(() => queryTaskDetail(benchmarkId, taskId))
|
||||
|
||||
return (
|
||||
<main data-page="bench-detail">
|
||||
<Title>Benchmark - {taskId}</Title>
|
||||
<Title>{i18n.t("bench.detail.title", { task: taskId })}</Title>
|
||||
<div style={{ padding: "1rem" }}>
|
||||
<Show when={task()} fallback={<p>Task not found</p>}>
|
||||
<Show when={task()} fallback={<p>{i18n.t("bench.detail.notFound")}</p>}>
|
||||
<div style={{ "margin-bottom": "1rem" }}>
|
||||
<div>
|
||||
<strong>Agent: </strong>
|
||||
{task()?.agent ?? "N/A"}
|
||||
<strong>{i18n.t("bench.detail.labels.agent")}: </strong>
|
||||
{task()?.agent ?? i18n.t("bench.detail.na")}
|
||||
</div>
|
||||
<div>
|
||||
<strong>Model: </strong>
|
||||
{task()?.model ?? "N/A"}
|
||||
<strong>{i18n.t("bench.detail.labels.model")}: </strong>
|
||||
{task()?.model ?? i18n.t("bench.detail.na")}
|
||||
</div>
|
||||
<div>
|
||||
<strong>Task: </strong>
|
||||
<strong>{i18n.t("bench.detail.labels.task")}: </strong>
|
||||
{task()!.task.id}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ "margin-bottom": "1rem" }}>
|
||||
<div>
|
||||
<strong>Repo: </strong>
|
||||
<strong>{i18n.t("bench.detail.labels.repo")}: </strong>
|
||||
<a
|
||||
href={`https://github.com/${task()!.task.source.repo}`}
|
||||
target="_blank"
|
||||
@@ -136,7 +138,7 @@ export default function BenchDetail() {
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<strong>From: </strong>
|
||||
<strong>{i18n.t("bench.detail.labels.from")}: </strong>
|
||||
<a
|
||||
href={`https://github.com/${task()!.task.source.repo}/commit/${task()!.task.source.from}`}
|
||||
target="_blank"
|
||||
@@ -147,7 +149,7 @@ export default function BenchDetail() {
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<strong>To: </strong>
|
||||
<strong>{i18n.t("bench.detail.labels.to")}: </strong>
|
||||
<a
|
||||
href={`https://github.com/${task()!.task.source.repo}/commit/${task()!.task.source.to}`}
|
||||
target="_blank"
|
||||
@@ -161,11 +163,13 @@ export default function BenchDetail() {
|
||||
|
||||
<Show when={task()?.task.prompts && task()!.task.prompts!.length > 0}>
|
||||
<div style={{ "margin-bottom": "1rem" }}>
|
||||
<strong>Prompt:</strong>
|
||||
<strong>{i18n.t("bench.detail.labels.prompt")}:</strong>
|
||||
<For each={task()!.task.prompts}>
|
||||
{(p) => (
|
||||
<div style={{ "margin-top": "0.5rem" }}>
|
||||
<div style={{ "font-size": "0.875rem", color: "#666" }}>Commit: {p.commit.slice(0, 7)}</div>
|
||||
<div style={{ "font-size": "0.875rem", color: "#666" }}>
|
||||
{i18n.t("bench.detail.labels.commit")}: {p.commit.slice(0, 7)}
|
||||
</div>
|
||||
<p style={{ "margin-top": "0.25rem", "white-space": "pre-wrap" }}>{p.prompt}</p>
|
||||
</div>
|
||||
)}
|
||||
@@ -177,33 +181,35 @@ export default function BenchDetail() {
|
||||
|
||||
<div style={{ "margin-bottom": "1rem" }}>
|
||||
<div>
|
||||
<strong>Average Duration: </strong>
|
||||
{task()?.averageDuration ? formatDuration(task()!.averageDuration!) : "N/A"}
|
||||
<strong>{i18n.t("bench.detail.labels.averageDuration")}: </strong>
|
||||
{task()?.averageDuration ? formatDuration(task()!.averageDuration!) : i18n.t("bench.detail.na")}
|
||||
</div>
|
||||
<div>
|
||||
<strong>Average Score: </strong>
|
||||
{task()?.averageScore?.toFixed(3) ?? "N/A"}
|
||||
<strong>{i18n.t("bench.detail.labels.averageScore")}: </strong>
|
||||
{task()?.averageScore?.toFixed(3) ?? i18n.t("bench.detail.na")}
|
||||
</div>
|
||||
<div>
|
||||
<strong>Average Cost: </strong>
|
||||
{task()?.averageUsage?.cost ? `$${task()!.averageUsage!.cost.toFixed(4)}` : "N/A"}
|
||||
<strong>{i18n.t("bench.detail.labels.averageCost")}: </strong>
|
||||
{task()?.averageUsage?.cost ? `$${task()!.averageUsage!.cost.toFixed(4)}` : i18n.t("bench.detail.na")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Show when={task()?.summary}>
|
||||
<div style={{ "margin-bottom": "1rem" }}>
|
||||
<strong>Summary:</strong>
|
||||
<strong>{i18n.t("bench.detail.labels.summary")}:</strong>
|
||||
<p style={{ "margin-top": "0.5rem", "white-space": "pre-wrap" }}>{task()!.summary}</p>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<Show when={task()?.runs && task()!.runs!.length > 0}>
|
||||
<div style={{ "margin-bottom": "1rem" }}>
|
||||
<strong>Runs:</strong>
|
||||
<strong>{i18n.t("bench.detail.labels.runs")}:</strong>
|
||||
<table style={{ "margin-top": "0.5rem", "border-collapse": "collapse", width: "100%" }}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ border: "1px solid #ccc", padding: "0.5rem", "text-align": "left" }}>Run</th>
|
||||
<th style={{ border: "1px solid #ccc", padding: "0.5rem", "text-align": "left" }}>
|
||||
{i18n.t("bench.detail.table.run")}
|
||||
</th>
|
||||
<th
|
||||
style={{
|
||||
border: "1px solid #ccc",
|
||||
@@ -212,10 +218,14 @@ export default function BenchDetail() {
|
||||
"white-space": "nowrap",
|
||||
}}
|
||||
>
|
||||
Score (Base - Penalty)
|
||||
{i18n.t("bench.detail.table.score")}
|
||||
</th>
|
||||
<th style={{ border: "1px solid #ccc", padding: "0.5rem", "text-align": "left" }}>
|
||||
{i18n.t("bench.detail.table.cost")}
|
||||
</th>
|
||||
<th style={{ border: "1px solid #ccc", padding: "0.5rem", "text-align": "left" }}>
|
||||
{i18n.t("bench.detail.table.duration")}
|
||||
</th>
|
||||
<th style={{ border: "1px solid #ccc", padding: "0.5rem", "text-align": "left" }}>Cost</th>
|
||||
<th style={{ border: "1px solid #ccc", padding: "0.5rem", "text-align": "left" }}>Duration</th>
|
||||
<For each={task()!.runs![0]?.scoreDetails}>
|
||||
{(detail) => (
|
||||
<th style={{ border: "1px solid #ccc", padding: "0.5rem", "text-align": "left" }}>
|
||||
@@ -234,10 +244,10 @@ export default function BenchDetail() {
|
||||
{run.score.final.toFixed(3)} ({run.score.base.toFixed(3)} - {run.score.penalty.toFixed(3)})
|
||||
</td>
|
||||
<td style={{ border: "1px solid #ccc", padding: "0.5rem" }}>
|
||||
{run.usage?.cost ? `$${run.usage.cost.toFixed(4)}` : "N/A"}
|
||||
{run.usage?.cost ? `$${run.usage.cost.toFixed(4)}` : i18n.t("bench.detail.na")}
|
||||
</td>
|
||||
<td style={{ border: "1px solid #ccc", padding: "0.5rem" }}>
|
||||
{run.duration ? formatDuration(run.duration) : "N/A"}
|
||||
{run.duration ? formatDuration(run.duration) : i18n.t("bench.detail.na")}
|
||||
</td>
|
||||
<For each={run.scoreDetails}>
|
||||
{(detail) => (
|
||||
@@ -265,17 +275,17 @@ export default function BenchDetail() {
|
||||
<For each={task()!.runs}>
|
||||
{(run, index) => (
|
||||
<div style={{ "margin-top": "1rem" }}>
|
||||
<h3 style={{ margin: "0 0 0.5rem 0" }}>Run {index() + 1}</h3>
|
||||
<h3 style={{ margin: "0 0 0.5rem 0" }}>{i18n.t("bench.detail.run.title", { n: index() + 1 })}</h3>
|
||||
<div>
|
||||
<strong>Score: </strong>
|
||||
{run.score.final.toFixed(3)} (Base: {run.score.base.toFixed(3)} - Penalty:{" "}
|
||||
{run.score.penalty.toFixed(3)})
|
||||
<strong>{i18n.t("bench.detail.labels.score")}: </strong>
|
||||
{run.score.final.toFixed(3)} ({i18n.t("bench.detail.labels.base")}: {run.score.base.toFixed(3)} -{" "}
|
||||
{i18n.t("bench.detail.labels.penalty")}: {run.score.penalty.toFixed(3)})
|
||||
</div>
|
||||
<For each={run.scoreDetails}>
|
||||
{(detail) => (
|
||||
<div style={{ "margin-top": "1rem", "padding-left": "1rem", "border-left": "2px solid #ccc" }}>
|
||||
<div>
|
||||
{detail.criterion} (weight: {detail.weight}){" "}
|
||||
{detail.criterion} ({i18n.t("bench.detail.labels.weight")}: {detail.weight}){" "}
|
||||
<For each={detail.judges}>
|
||||
{(judge) => (
|
||||
<span
|
||||
@@ -350,7 +360,7 @@ export default function BenchDetail() {
|
||||
onClick={() => setJsonExpanded(!jsonExpanded())}
|
||||
>
|
||||
<span style={{ "margin-right": "0.5rem" }}>{jsonExpanded() ? "▼" : "▶"}</span>
|
||||
Raw JSON
|
||||
{i18n.t("bench.detail.rawJson")}
|
||||
</button>
|
||||
<Show when={jsonExpanded()}>
|
||||
<pre>{JSON.stringify(task(), null, 2)}</pre>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { A, createAsync, query } from "@solidjs/router"
|
||||
import { createMemo, For, Show } from "solid-js"
|
||||
import { Database, desc } from "@opencode-ai/console-core/drizzle/index.js"
|
||||
import { BenchmarkTable } from "@opencode-ai/console-core/schema/benchmark.sql.js"
|
||||
import { useI18n } from "~/context/i18n"
|
||||
|
||||
interface BenchmarkResult {
|
||||
averageScore: number
|
||||
@@ -33,6 +34,7 @@ async function getBenchmarks() {
|
||||
const queryBenchmarks = query(getBenchmarks, "benchmarks.list")
|
||||
|
||||
export default function Bench() {
|
||||
const i18n = useI18n()
|
||||
const benchmarks = createAsync(() => queryBenchmarks())
|
||||
|
||||
const taskIds = createMemo(() => {
|
||||
@@ -47,14 +49,14 @@ export default function Bench() {
|
||||
|
||||
return (
|
||||
<main data-page="bench" style={{ padding: "2rem" }}>
|
||||
<Title>Benchmark</Title>
|
||||
<h1 style={{ "margin-bottom": "1.5rem" }}>Benchmarks</h1>
|
||||
<Title>{i18n.t("bench.list.title")}</Title>
|
||||
<h1 style={{ "margin-bottom": "1.5rem" }}>{i18n.t("bench.list.heading")}</h1>
|
||||
<table style={{ "border-collapse": "collapse", width: "100%" }}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ "text-align": "left", padding: "0.75rem" }}>Agent</th>
|
||||
<th style={{ "text-align": "left", padding: "0.75rem" }}>Model</th>
|
||||
<th style={{ "text-align": "left", padding: "0.75rem" }}>Score</th>
|
||||
<th style={{ "text-align": "left", padding: "0.75rem" }}>{i18n.t("bench.list.table.agent")}</th>
|
||||
<th style={{ "text-align": "left", padding: "0.75rem" }}>{i18n.t("bench.list.table.model")}</th>
|
||||
<th style={{ "text-align": "left", padding: "0.75rem" }}>{i18n.t("bench.list.table.score")}</th>
|
||||
<For each={taskIds()}>{(id) => <th style={{ "text-align": "left", padding: "0.75rem" }}>{id}</th>}</For>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
Reference in New Issue
Block a user