mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
102 lines
4.9 KiB
TypeScript
102 lines
4.9 KiB
TypeScript
'use client'
|
|
|
|
import { Fragment } from 'react'
|
|
import { ArrowRight } from 'lucide-react'
|
|
import { YStack, Text } from '@hanzo/ui'
|
|
import { Cta, Section } from '@/components/marketing/page-kit'
|
|
import { Chip, Run } from '@hanzo/ui/marketing'
|
|
|
|
/**
|
|
* The observability layer, stated as a flagship rather than a footnote.
|
|
*
|
|
* A company that runs on agents is a company whose work happens where nobody is
|
|
* looking. The claim is that the work is legible end to end, and the chain line
|
|
* IS the claim — one trace, from what was asked to what it cost.
|
|
*
|
|
* THE DETAIL LIVES ON /o11y. Eight cards used to stand here (one trace end to
|
|
* end · one store one query · every model call · every cost · sessions · scores
|
|
* and review · infrastructure underneath · dashboards and alerts), each read out
|
|
* of `hanzoai/o11y` before it was written. That is documentation, and the
|
|
* product page is where documentation belongs; /o11y states all eight in the
|
|
* same words, so the two cannot drift.
|
|
*
|
|
* WHAT THE SOURCE REFUSED, kept here because each was proposed once and will be
|
|
* proposed again: there is no dataset type, table, route or migration in o11y
|
|
* (`lib/data/catalog.json` lists one against /v1/evals/datasets — the code
|
|
* wins); experiment comparison is `hanzoai/insights`, a different product;
|
|
* "approvals" appear nowhere in o11y, the nearest real thing being an annotation
|
|
* queue with a PENDING status, which is post-hoc review; and `gen_ai.agent.*`
|
|
* exists only in a test fixture, so agent handoffs and model routing are not
|
|
* o11y's to claim — routing is Enso's.
|
|
*
|
|
* "Objective" in the lede is the page's own framing, set by the Enso section
|
|
* above. o11y's root span is a REQUEST and there is no objective entity behind
|
|
* it, so nothing downstream of this line may promise a company goal graph.
|
|
*
|
|
* One `Cta`, to /o11y, which is a real directory. The sub-products live at
|
|
* /cloud/<slug> behind a dynamic route, and a link that depends on a slug
|
|
* surviving in a generated catalog is a link that rots quietly. `/observability`
|
|
* is not a directory and must never be linked.
|
|
*/
|
|
/** The path one trace follows, in the order it is walked. */
|
|
const TRACE = ['Models', 'agents', 'tools', 'infrastructure', 'result', 'cost', 'evaluation']
|
|
|
|
export default function Observability() {
|
|
return (
|
|
<Section
|
|
title="See the whole company think."
|
|
lede="One trace connects the objective that started the work to everything that followed."
|
|
>
|
|
<YStack gap="$4">
|
|
{/* THE LEDE STOPPED NAMING THEM. It listed models, agents, tools,
|
|
services, infrastructure, cost, evaluation and outcome — the same
|
|
eight the chain below draws — so the section said its list twice and
|
|
the drawing was reduced to an illustration of the sentence above it.
|
|
The lede states what a trace IS; the chain is the evidence.
|
|
|
|
The trace, DRAWN. This was one bold line of prose whose separators
|
|
were already arrows — a chain written out as a sentence, in a page
|
|
that draws its layer stack with the same arrow one section up. Seven
|
|
steps a reader can count is the point of the claim above it; seven
|
|
words in a row is a claim about a picture nobody was shown.
|
|
|
|
Chips and not a grid, for the reason One system gives: each step is
|
|
as wide as its word, and equal tracks would pad `cost` out to the
|
|
width of `infrastructure` and turn a path into a table.
|
|
|
|
IT RUNS, because this one is genuinely ordered — the arrows are the
|
|
claim — so the `Run` steps near cycle/7 and the light walks the chain
|
|
rather than lifting all seven at once. A chip takes the even beats
|
|
and the arrow after it the odd one between, so the light crosses the
|
|
arrow on its way and the path is drawn rather than blinked.
|
|
|
|
Chip and arrow are FLAT siblings of the run, not a chip wrapped with
|
|
its arrow: the run animates its direct children, and a wrapper would
|
|
have taken the animation and passed nothing to the chip, whose border
|
|
is the thing that lights. */}
|
|
<Run step={0.31} flexDirection="row" flexWrap="wrap" items="center" gap="$2">
|
|
{TRACE.map((step, i) => (
|
|
<Fragment key={step}>
|
|
<Chip py={6} px={14} data-beat={2 * i}>
|
|
{step}
|
|
</Chip>
|
|
{i < TRACE.length - 1 ? (
|
|
<Text fontSize="$2" color="inherit" data-beat={2 * i + 1} aria-hidden>
|
|
→
|
|
</Text>
|
|
) : null}
|
|
</Fragment>
|
|
))}
|
|
</Run>
|
|
|
|
<Text render="p" fontSize="$3" color="$quiet" maxW={672}>
|
|
Logs, metrics, traces, sessions and scores share the same operational context.
|
|
</Text>
|
|
<Cta href="/o11y" icon={ArrowRight}>
|
|
Explore Observability
|
|
</Cta>
|
|
</YStack>
|
|
</Section>
|
|
)
|
|
}
|