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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions packages/app/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ Cypress.on('window:before:load', (win) => {
});

/**
* Unlock the shared feature gate for specs that exercise agentic surfaces
* (the "Agentic Traces" scenario, /datasets, /inference/agentic/[id], and the
* Datasets nav link). The gate is OFF by default so the PR can ship without
* publicly exposing agentic features; agentic specs opt in by seeding the same
* localStorage flag the ↑↑↓↓ konami unlock writes (see use-feature-gate.ts).
* Seed the shared feature-gate flag (the same localStorage key the ↑↑↓↓ konami
* unlock writes — see use-feature-gate.ts).
*
* The agentic surfaces (the "Agentic Traces" scenario, /datasets,
* /inference/agentic/[id], and the Datasets nav link) are now PUBLIC by default
* — they no longer sit behind this gate — so agentic specs no longer need it.
* The helper is retained as a harmless no-op for those specs (and still unlocks
* the remaining hidden features: the "Hidden" tab dropdown and Measured Energy).
*
* Call from a spec's `cy.visit(..., { onBeforeLoad })`:
* cy.visit('/datasets/x', { onBeforeLoad: unlockAgenticGate });
Expand All @@ -30,6 +33,7 @@ export function unlockAgenticGate(win: Window): void {
try {
win.localStorage.setItem('inferencex-feature-gate', '1');
} catch {
// localStorage unavailable — spec will see the gate locked and likely 404.
// localStorage unavailable — only the remaining hidden features stay locked;
// agentic surfaces are public regardless.
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Metadata } from 'next';
import { notFound } from 'next/navigation';

import { AgenticGate } from '@/components/agentic-gate';
import { AgenticPointDetail } from '@/components/inference/agentic-point/agentic-point-detail';
import { isPersistedBenchmarkId } from '@/lib/benchmark-id';

Expand All @@ -21,9 +20,5 @@ export default async function AgenticPointDetailPage({
// `/agentic/0`, `/agentic/-1`) can never resolve, so 404 instead of rendering a
// blank detail shell that fires doomed id-keyed fetches.
if (!isPersistedBenchmarkId(numericId)) notFound();
return (
<AgenticGate>
<AgenticPointDetail id={numericId} />
</AgenticGate>
);
return <AgenticPointDetail id={numericId} />;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Suspense } from 'react';
import type { Metadata } from 'next';

import { AgenticGate } from '@/components/agentic-gate';
import { ConversationView } from '@/components/datasets/conversation-view';
import { SITE_URL } from '@semianalysisai/inferencex-constants';

Expand Down Expand Up @@ -32,14 +31,12 @@ export default async function ConversationPage({ params }: Props) {
// A second decodeURIComponent here would over-decode (and throw for ids that
// contain a literal '%'). ConversationView re-encodes when it builds the API URL.
return (
<AgenticGate>
<main className="relative">
<div className="container mx-auto px-4 pb-8 lg:px-8">
<Suspense>
<ConversationView slug={slug} convId={convId} />
</Suspense>
</div>
</main>
</AgenticGate>
<main className="relative">
<div className="container mx-auto px-4 pb-8 lg:px-8">
<Suspense>
<ConversationView slug={slug} convId={convId} />
</Suspense>
</div>
</main>
);
}
13 changes: 5 additions & 8 deletions packages/app/src/app/datasets/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { Metadata } from 'next';

import { AgenticGate } from '@/components/agentic-gate';
import { DatasetDetail } from '@/components/datasets/dataset-detail';
import { SITE_URL } from '@semianalysisai/inferencex-constants';

Expand All @@ -24,12 +23,10 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
export default async function DatasetDetailPage({ params }: Props) {
const { slug } = await params;
return (
<AgenticGate>
<main className="relative">
<div className="container mx-auto px-4 pb-8 lg:px-8">
<DatasetDetail slug={slug} />
</div>
</main>
</AgenticGate>
<main className="relative">
<div className="container mx-auto px-4 pb-8 lg:px-8">
<DatasetDetail slug={slug} />
</div>
</main>
);
}
9 changes: 0 additions & 9 deletions packages/app/src/app/datasets/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { Metadata } from 'next';

import { AgenticGate } from '@/components/agentic-gate';
import { Card } from '@/components/ui/card';
import { JsonLd } from '@/components/json-ld';
import { DatasetList } from '@/components/datasets/dataset-list';
Expand Down Expand Up @@ -30,14 +29,6 @@ const jsonLd = {
};

export default function DatasetsPage() {
return (
<AgenticGate>
<DatasetsPageContent />
</AgenticGate>
);
}

function DatasetsPageContent() {
return (
<main className="relative">
<JsonLd data={jsonLd} />
Expand Down
26 changes: 4 additions & 22 deletions packages/app/src/components/GlobalFilterContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import {
import { computeAutoSwitchDecision } from '@/lib/unofficial-run-auto-switch';
import { countCurvesByPrecision, resolveEffectivePrecisions } from '@/lib/default-precisions';
import { resolveEffectiveSequence } from '@/lib/default-sequence';
import { useFeatureGate } from '@/lib/use-feature-gate';
import type { AvailabilityRow, WorkflowInfoResponse } from '@/lib/api';

const RUNDATE_RE = /^\d{4}-\d{2}-\d{2}$/u;
Expand Down Expand Up @@ -162,14 +161,6 @@ export function GlobalFilterProvider({
}) {
const { hasUrlParam, getUrlParam, setUrlParams } = useUrlState();

// Agentic surfaces are hidden behind the shared konami-code feature gate
// (default OFF until agentic launches). When locked, agentic sequences are
// filtered out of `availableSequences` below — the single chokepoint that
// cascades: no agentic default (resolveEffectiveSequence falls to 8k/1k), no
// "Agentic Traces" scenario-selector entry, and no agentic x-axis mode /
// percentile selector (those key off effectiveSequence === AgenticTraces).
const agenticGateUnlocked = useFeatureGate();

// ── Core filter state ─────────────────────────────────────────────────────
const [selectedModel, setSelectedModel] = useState<Model>(
() => initialModel ?? Model.DeepSeek_V4_Pro,
Expand Down Expand Up @@ -304,26 +295,17 @@ export function GlobalFilterProvider({
}, [unofficialAvailable, selectedModel]);

// Sequences available for the selected model (DB ∪ unofficial run for this model).
//
// When the agentic feature gate is locked (default), agentic sequences are
// dropped from every branch — including the static SEQUENCE_OPTIONS fallback —
// so no agentic scenario is ever selectable or defaulted. This is the single
// gate chokepoint for the main inference chart's agentic surfaces.
const availableSequences = useMemo(() => {
const dropAgentic = (seqs: Sequence[]) =>
agenticGateUnlocked ? seqs : seqs.filter((s) => s !== Sequence.AgenticTraces);
const unofficialSeqs = unofficialAvailable
.filter((a) => a.model === selectedModel)
.map((a) => a.sequence as Sequence);
if (!availabilityRows) {
return unofficialSeqs.length > 0
? dropAgentic([...new Set(unofficialSeqs)])
: dropAgentic(SEQUENCE_OPTIONS);
return unofficialSeqs.length > 0 ? [...new Set(unofficialSeqs)] : [...SEQUENCE_OPTIONS];
}
const dbSeqs = modelRows.map((r) => rowToSequence(r)).filter((s): s is Sequence => s !== null);
const merged = dropAgentic([...new Set([...dbSeqs, ...unofficialSeqs])]);
return merged.length > 0 ? merged : dropAgentic(SEQUENCE_OPTIONS);
}, [availabilityRows, modelRows, unofficialAvailable, selectedModel, agenticGateUnlocked]);
const merged = [...new Set([...dbSeqs, ...unofficialSeqs])];
return merged.length > 0 ? merged : [...SEQUENCE_OPTIONS];
}, [availabilityRows, modelRows, unofficialAvailable, selectedModel]);

// Whether we actually know the selected model's sequences yet. Availability
// may arrive from the DB (`availabilityRows`) OR from a loaded unofficial run
Expand Down
41 changes: 0 additions & 41 deletions packages/app/src/components/agentic-gate.tsx

This file was deleted.

9 changes: 1 addition & 8 deletions packages/app/src/components/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { track } from '@/lib/analytics';
import { ModeToggle } from '@/components/ui/mode-toggle';
import { MinecraftToggles } from '@/components/minecraft/minecraft-toggles';
import { navigateInApp } from '@/lib/client-navigation';
import { useFeatureGate } from '@/lib/use-feature-gate';
import { cn } from '@/lib/utils';

import { GitHubStars } from './GithubStars';
Expand Down Expand Up @@ -52,9 +51,6 @@ const NAV_LINKS = [
label: 'Datasets',
testId: 'nav-link-datasets',
event: 'header_datasets_clicked',
// Agentic surface — hidden behind the konami-code feature gate (default off)
// until agentic launches. Same gate as the Hidden tab dropdown.
gated: true,
},
{ href: '/blog', label: 'Articles', testId: 'nav-link-blog', event: 'header_blog_clicked' },
{ href: '/about', label: 'About', testId: 'nav-link-about', event: 'header_about_clicked' },
Expand All @@ -72,13 +68,10 @@ function isActive(pathname: string, href: string): boolean {
export const Header = ({ starCount }: { starCount?: number | null }) => {
const pathname = usePathname() ?? '/';
const router = useRouter();
const featureGateUnlocked = useFeatureGate();
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const menuRef = useRef<HTMLDivElement>(null);

// Hide gated nav links (e.g. Datasets — an agentic surface) unless the shared
// feature gate is unlocked. Mirrors the tab-nav "Hidden" dropdown gating.
const navLinks = NAV_LINKS.filter((l) => !('gated' in l && l.gated) || featureGateUnlocked);
const navLinks = NAV_LINKS;

// Close menu on route change
useEffect(() => {
Expand Down
Loading