mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
- Cut root homepage description by 1/3 (170 -> 114 chars) for SERP mobile/desktop truncation threshold - Updated apex gate test in e2e/gates/apex.spec.ts to match the optimized homepage description - Shortened and enriched 70+ page and layout descriptions to the optimal 110-145 character sweet spot - Front-loaded high-intent keywords across agents, foundation models, MCP, benchmarks, and sovereign cloud - Ensured unique titles for all model variant routes to satisfy title uniqueness gates Co-authored-by: Hanzo Dev <[email protected]>
79 lines
2.8 KiB
TypeScript
79 lines
2.8 KiB
TypeScript
import type { Metadata } from 'next'
|
|
import EnsoLanding from '@/components/enso/EnsoLanding'
|
|
import { ProductJsonLd } from '@/components/product/ProductJsonLd'
|
|
import { at } from '@/lib/product'
|
|
import { fetchModels } from '@/lib/models/served'
|
|
|
|
// Hanzo Enso, the router. At the app ROOT beside /kai and /zen, so only the
|
|
// root layout wraps it and it ships the shared site chrome itself. Served at
|
|
// /enso on both hanzo.ai and cloud.hanzo.ai.
|
|
|
|
const TITLE = 'Hanzo Enso — Choose an outcome'
|
|
const DESCRIPTION =
|
|
'Intelligent model routing for frontier AI. Enso balances quality, latency, cost, and policy across top models and agents via one API.'
|
|
|
|
export const metadata: Metadata = {
|
|
title: TITLE,
|
|
description: DESCRIPTION,
|
|
alternates: { canonical: 'https://hanzo.ai/enso' },
|
|
openGraph: {
|
|
title: TITLE,
|
|
description: DESCRIPTION,
|
|
url: 'https://hanzo.ai/enso',
|
|
siteName: 'Hanzo',
|
|
type: 'website',
|
|
},
|
|
twitter: { card: 'summary_large_image', title: TITLE, description: DESCRIPTION },
|
|
}
|
|
|
|
/**
|
|
* How many labs the catalog's models come from: one per lab (the catalog
|
|
* writes OpenAI, openai and ~openai; x-ai and xAI; mistralai and Mistral), a
|
|
* host or an aggregator not a lab, and Hanzo's own models not counted among
|
|
* theirs. The page states the count; it names no lab.
|
|
*/
|
|
const UNNAMED = /^(hanzo|zenlm|openrouter|fireworks|stealth|inference-net)$/i
|
|
|
|
/** One key per lab: case, punctuation and a trailing "ai" are spelling, not identity. */
|
|
const labKey = (raw: string) => raw.toLowerCase().replace(/[^a-z0-9]/g, '').replace(/ai$/, '')
|
|
|
|
function labs(models: { provider?: string }[]) {
|
|
const keys = new Set<string>()
|
|
for (const m of models) {
|
|
const raw = (m.provider ?? '').replace(/^~/, '').trim()
|
|
if (raw && !UNNAMED.test(raw)) keys.add(labKey(raw))
|
|
}
|
|
return keys.size
|
|
}
|
|
|
|
export default async function EnsoRoutePage() {
|
|
/* Same source as the homepage strip, so the two figures cannot disagree. */
|
|
const { total, models: catalog } = await fetchModels()
|
|
const models = total >= 100 ? `${Math.floor(total / 100) * 100}+` : String(total)
|
|
|
|
const product = at('/enso')
|
|
|
|
return (
|
|
<>
|
|
{/* Enso is outside the ProductLanding kit, so it names itself here. Every
|
|
feature is a clause of the sentence above, not a second description
|
|
written for the machine. */}
|
|
{product && (
|
|
<ProductJsonLd
|
|
product={product}
|
|
path="/enso"
|
|
description={DESCRIPTION}
|
|
features={[
|
|
'Routes each request by quality, latency, and cost',
|
|
'OpenAI-compatible endpoint',
|
|
'Anthropic-compatible endpoint',
|
|
'Flash, Pro and Ultra presets',
|
|
'Scores on your traffic take over the choice',
|
|
]}
|
|
/>
|
|
)}
|
|
<EnsoLanding models={models} labs={labs(catalog)} />
|
|
</>
|
|
)
|
|
}
|