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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions src/commands/benchmark-job/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,16 +204,31 @@ async function ensureAgentSecrets(
return secrets;
}

const BENCHMARK_ID_PREFIXES = ["bm_", "bmk_", "bmd_"];

function looksLikeBenchmarkId(s: string): boolean {
return BENCHMARK_ID_PREFIXES.some((p) => s.startsWith(p));
}

// Extract a benchmark ID from strings like "Name (bmd_xxx)" copied from the TUI
function extractEmbeddedId(s: string): string | null {
const match = s.match(/\((bm[dk]?_\S+)\)\s*$/);
return match ? match[1] : null;
}

Comment on lines +207 to +218
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

they always start with bmd_

message BenchmarkDefinitionPb {
  option (db_schema_options) = {
    db_table_name: "benchmark_definition"
    db_table_schema_type: DB_TABLE_SCHEMA
    db_type_prefix: "bmd"
  };

// Resolve benchmark name to ID if needed
async function resolveBenchmarkId(benchmarkIdOrName: string): Promise<string> {
// If it looks like an ID (starts with bm_ or similar), return as-is
if (
benchmarkIdOrName.startsWith("bm_") ||
benchmarkIdOrName.startsWith("bmk_")
) {
// If it looks like a bare ID, return as-is
if (looksLikeBenchmarkId(benchmarkIdOrName)) {
return benchmarkIdOrName;
}

// If the input has an embedded ID like "Name (bmd_xxx)", extract and use it
const embeddedId = extractEmbeddedId(benchmarkIdOrName);
if (embeddedId) {
return embeddedId;
}

// Search both user benchmarks and public benchmarks
const [userResult, publicResult] = await Promise.all([
listBenchmarks({
Expand Down
4 changes: 2 additions & 2 deletions src/screens/BenchmarkDetailScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,10 @@ export function BenchmarkDetailScreen({
const operations: ResourceOperation[] = [
{
key: "create-job",
label: "Create Benchmark Job",
label: "Run Benchmark Job",
color: colors.success,
icon: figures.play,
shortcut: "c",
shortcut: "r",
},
];

Expand Down
11 changes: 7 additions & 4 deletions src/screens/BenchmarkJobListScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ export function BenchmarkJobListScreen() {
data={benchmarkJobs}
keyExtractor={(job: BenchmarkJob) => job.id}
selectedIndex={selectedIndex}
title={`benchmark_jobs[${totalCount}]`}
title={`benchmark_jobs[${totalCount}${hasMore ? "+" : ""}]`}
columns={columns}
emptyState={
<Text color={colors.textDim}>
Expand All @@ -613,12 +613,13 @@ export function BenchmarkJobListScreen() {
<Box marginTop={1} paddingX={1}>
<Text color={colors.primary} bold>
{figures.hamburger} {totalCount}
{hasMore ? "+" : ""}
</Text>
<Text color={colors.textDim} dimColor>
{" "}
total
</Text>
{totalPages > 1 && (
{(hasMore || hasPrev) && (
<>
<Text color={colors.textDim} dimColor>
{" "}
Expand All @@ -630,7 +631,8 @@ export function BenchmarkJobListScreen() {
</Text>
) : (
<Text color={colors.textDim} dimColor>
Page {currentPage + 1} of {totalPages}
Page {currentPage + 1}
{!hasMore ? ` of ${totalPages}` : ""}
</Text>
)}
</>
Expand All @@ -640,7 +642,8 @@ export function BenchmarkJobListScreen() {
•{" "}
</Text>
<Text color={colors.textDim} dimColor>
Showing {startIndex + 1}-{endIndex} of {totalCount}
Showing {startIndex + 1}-{endIndex}
{!hasMore ? ` of ${totalCount}` : ""}
</Text>
</Box>
)}
Expand Down
114 changes: 91 additions & 23 deletions src/screens/BenchmarkListScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,32 @@ import { useViewportHeight } from "../hooks/useViewportHeight.js";
import { useExitOnCtrlC } from "../hooks/useExitOnCtrlC.js";
import { useCursorPagination } from "../hooks/useCursorPagination.js";
import { useListSearch } from "../hooks/useListSearch.js";
import { listBenchmarks } from "../services/benchmarkService.js";
import {
listBenchmarks,
listPublicBenchmarks,
} from "../services/benchmarkService.js";
import type { Benchmark } from "../store/benchmarkStore.js";

export function BenchmarkListScreen() {
const { exit: inkExit } = useApp();
const { navigate, goBack } = useNavigation();
const [selectedIndex, setSelectedIndex] = React.useState(0);
const { navigate, goBack, params, updateCurrentParams } = useNavigation();
const [selectedIndex, setSelectedIndex] = React.useState(
params.selectedIndex ? Number(params.selectedIndex) : 0,
);
const [showPopup, setShowPopup] = React.useState(false);
const [selectedOperation, setSelectedOperation] = React.useState(0);
const [tab, setTab] = React.useState<"private" | "public">(
params.tab === "public" ? "public" : "private",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

private should be custom to match our branding for non-public benchmarks

);
const isPublic = tab === "public";

// Save current tab and cursor into route params so back-navigation restores them
const saveListState = React.useCallback(() => {
updateCurrentParams({
tab,
selectedIndex: String(selectedIndex),
});
}, [updateCurrentParams, tab, selectedIndex]);

// Search state
const search = useListSearch({
Expand All @@ -41,7 +58,7 @@ export function BenchmarkListScreen() {
});

// Calculate overhead for viewport height
const overhead = 13 + search.getSearchOverhead();
const overhead = 14 + search.getSearchOverhead();
const { viewportHeight, terminalWidth } = useViewportHeight({
overhead,
minHeight: 5,
Expand All @@ -61,19 +78,27 @@ export function BenchmarkListScreen() {
// Fetch function for pagination hook
const fetchPage = React.useCallback(
async (params: { limit: number; startingAt?: string }) => {
const result = await listBenchmarks({
const listFn = isPublic ? listPublicBenchmarks : listBenchmarks;
const result = await listFn({
limit: params.limit,
startingAfter: params.startingAt,
search: search.submittedSearchQuery || undefined,
});

// Public tab: only show benchmarks with bmj_support metadata
const items = isPublic
? result.benchmarks.filter((b) => b.metadata?.bmj_support === "true")
: result.benchmarks;

return {
items: result.benchmarks,
items,
hasMore: result.hasMore,
totalCount: result.totalCount,
totalCount: isPublic
? items.length + (result.hasMore ? 1 : 0)
: result.totalCount,
};
},
[search.submittedSearchQuery],
[search.submittedSearchQuery, isPublic],
);

// Use the shared pagination hook
Expand All @@ -94,7 +119,7 @@ export function BenchmarkListScreen() {
getItemId: (benchmark: Benchmark) => benchmark.id,
pollInterval: 5000,
pollingEnabled: !showPopup && !search.searchMode,
deps: [PAGE_SIZE, search.submittedSearchQuery],
deps: [PAGE_SIZE, search.submittedSearchQuery, isPublic],
});

// Operations for benchmarks
Expand All @@ -108,7 +133,7 @@ export function BenchmarkListScreen() {
},
{
key: "create_job",
label: "Create Benchmark Job",
label: "Run Benchmark Job",
color: colors.success,
icon: figures.play,
},
Expand Down Expand Up @@ -209,21 +234,25 @@ export function BenchmarkListScreen() {
const operationKey = operations[selectedOperation].key;

if (operationKey === "view_details") {
saveListState();
navigate("benchmark-detail", {
benchmarkId: selectedBenchmark.id,
});
} else if (operationKey === "create_job") {
saveListState();
navigate("benchmark-job-create", {
initialBenchmarkIds: selectedBenchmark.id,
});
}
} else if (input === "v" && selectedBenchmark) {
setShowPopup(false);
saveListState();
navigate("benchmark-detail", {
benchmarkId: selectedBenchmark.id,
});
} else if (input === "c" && selectedBenchmark) {
} else if (input === "r" && selectedBenchmark) {
setShowPopup(false);
saveListState();
navigate("benchmark-job-create", {
initialBenchmarkIds: selectedBenchmark.id,
});
Expand Down Expand Up @@ -258,19 +287,26 @@ export function BenchmarkListScreen() {
prevPage();
setSelectedIndex(0);
} else if (key.return && selectedBenchmark) {
saveListState();
navigate("benchmark-detail", {
benchmarkId: selectedBenchmark.id,
});
} else if (input === "a" && selectedBenchmark) {
setShowPopup(true);
setSelectedOperation(0);
} else if (input === "c" && selectedBenchmark) {
// Quick shortcut to create a job
} else if (input === "r" && selectedBenchmark) {
saveListState();
navigate("benchmark-job-create", {
initialBenchmarkIds: selectedBenchmark.id,
});
} else if (input === "/") {
search.enterSearchMode();
} else if (input === "1" && tab !== "private") {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"private" --> "custom"

setTab("private");
setSelectedIndex(0);
} else if (input === "2" && tab !== "public") {
setTab("public");
setSelectedIndex(0);
} else if (key.escape) {
if (search.handleEscape()) {
return;
Expand All @@ -287,7 +323,10 @@ export function BenchmarkListScreen() {
items={[
{ label: "Home" },
{ label: "Benchmarks" },
{ label: "Benchmark Definitions", active: true },
{
label: isPublic ? "Public Benchmarks" : "Benchmark Defs",
active: true,
},
]}
/>
<SpinnerComponent message="Loading benchmarks..." />
Expand All @@ -303,7 +342,10 @@ export function BenchmarkListScreen() {
items={[
{ label: "Home" },
{ label: "Benchmarks" },
{ label: "Benchmark Definitions", active: true },
{
label: isPublic ? "Public Benchmarks" : "Benchmark Defs",
active: true,
},
]}
/>
<ErrorMessage message="Failed to list benchmarks" error={error} />
Expand All @@ -318,10 +360,30 @@ export function BenchmarkListScreen() {
items={[
{ label: "Home" },
{ label: "Benchmarks" },
{ label: "Benchmark Definitions", active: true },
{
label: isPublic ? "Public Benchmarks" : "Benchmark Defs",
active: true,
},
]}
/>

{/* Tab indicator */}
<Box paddingX={2} marginBottom={0}>
<Text
color={!isPublic ? colors.primary : colors.textDim}
bold={!isPublic}
>
[1] Private
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Custom

</Text>
<Text> </Text>
<Text
color={isPublic ? colors.primary : colors.textDim}
bold={isPublic}
>
[2] Public
</Text>
</Box>

{/* Search bar */}
<SearchBar
searchMode={search.searchMode}
Expand All @@ -330,7 +392,9 @@ export function BenchmarkListScreen() {
resultCount={totalCount}
onSearchChange={search.setSearchQuery}
onSearchSubmit={search.submitSearch}
placeholder="Search benchmarks..."
placeholder={
isPublic ? "Search public benchmarks..." : "Search benchmarks..."
}
/>

{/* Table */}
Expand All @@ -339,7 +403,7 @@ export function BenchmarkListScreen() {
data={benchmarks}
keyExtractor={(benchmark: Benchmark) => benchmark.id}
selectedIndex={selectedIndex}
title={`benchmarks[${totalCount}]`}
title={`${isPublic ? "public " : ""}benchmarks[${totalCount}${hasMore ? "+" : ""}]`}
columns={columns}
emptyState={
<Text color={colors.textDim}>
Expand All @@ -354,12 +418,13 @@ export function BenchmarkListScreen() {
<Box marginTop={1} paddingX={1}>
<Text color={colors.primary} bold>
{figures.hamburger} {totalCount}
{hasMore ? "+" : ""}
</Text>
<Text color={colors.textDim} dimColor>
{" "}
total
</Text>
{totalPages > 1 && (
{(hasMore || hasPrev) && (
<>
<Text color={colors.textDim} dimColor>
{" "}
Expand All @@ -371,7 +436,8 @@ export function BenchmarkListScreen() {
</Text>
) : (
<Text color={colors.textDim} dimColor>
Page {currentPage + 1} of {totalPages}
Page {currentPage + 1}
{!hasMore ? ` of ${totalPages}` : ""}
</Text>
)}
</>
Expand All @@ -381,7 +447,8 @@ export function BenchmarkListScreen() {
•{" "}
</Text>
<Text color={colors.textDim} dimColor>
Showing {startIndex + 1}-{endIndex} of {totalCount}
Showing {startIndex + 1}-{endIndex}
{!hasMore ? ` of ${totalCount}` : ""}
</Text>
</Box>
)}
Expand All @@ -400,7 +467,7 @@ export function BenchmarkListScreen() {
op.key === "view_details"
? "v"
: op.key === "create_job"
? "s"
? "r"
: "",
}))}
selectedOperation={selectedOperation}
Expand All @@ -418,8 +485,9 @@ export function BenchmarkListScreen() {
label: "Page",
condition: hasMore || hasPrev,
},
{ key: "1/2", label: "Private/Public" },
{ key: "Enter", label: "Details" },
{ key: "c", label: "Create Job" },
{ key: "r", label: "Run Benchmark Job" },
{ key: "a", label: "Actions" },
{ key: "/", label: "Search" },
{ key: "Esc", label: "Back" },
Expand Down
Loading
Loading