mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 03:30:33 +00:00
539 lines
22 KiB
TypeScript
539 lines
22 KiB
TypeScript
'use client'
|
||
|
||
import { useState, useEffect } from 'react'
|
||
import { phrase } from '@hanzo/i18n'
|
||
import { useI18n } from '@hanzo/i18n/react'
|
||
import { Block, Foot, H2, Inline, Meta, Note, P, Part, Table, Td, Th, Tr } from './kit'
|
||
import { Play, RotateCcw, Clock } from '@hanzogui/lucide-icons-2'
|
||
|
||
interface TaskData {
|
||
id: string
|
||
title: string
|
||
description: string
|
||
target: string
|
||
hanzo: {
|
||
latency: string
|
||
latencyMs: number
|
||
turns: number
|
||
tokens: number
|
||
savings: string
|
||
detail: string
|
||
}
|
||
containerRAG: {
|
||
latency: string
|
||
latencyMs: number
|
||
turns: number
|
||
tokens: number
|
||
savings: string
|
||
detail: string
|
||
}
|
||
traditional: {
|
||
latency: string
|
||
latencyMs: number
|
||
turns: number
|
||
tokens: number
|
||
steps: string[]
|
||
detail: string
|
||
}
|
||
}
|
||
|
||
const TASKS: TaskData[] = [
|
||
{
|
||
id: 'subsystem',
|
||
title: phrase('Subsystem Logic (State Tracking & Auth)'),
|
||
description: 'Find where workspace change detection, file state tracking, and incremental cache are implemented.',
|
||
target: phrase('Workspace state diffing & hashing logic'),
|
||
hanzo: {
|
||
latency: '0.7 ms',
|
||
latencyMs: 0.7,
|
||
turns: 1,
|
||
tokens: 398,
|
||
savings: '98.4%',
|
||
detail: phrase('In-process Trigram + Tree-Sitter AST context bundle (0 daemons)'),
|
||
},
|
||
containerRAG: {
|
||
latency: '202 ms',
|
||
latencyMs: 202,
|
||
turns: 1,
|
||
tokens: 382,
|
||
savings: '98.5%',
|
||
detail: phrase('Qdrant Vector DB container + Ollama mxbai-embed-large (10 GB)'),
|
||
},
|
||
traditional: {
|
||
latency: '36.4 s',
|
||
latencyMs: 36360,
|
||
turns: 8,
|
||
tokens: 25078,
|
||
steps: [phrase('Grep "state"'), phrase('Read main.go'), phrase('Read manager.go'), phrase('Read detector.go'), phrase('Read state.go'), phrase('Read cache.go'), phrase('Read watcher.go'), phrase('Synthesize')],
|
||
detail: phrase('Iterative grep + full file reads over stdio (8 roundtrips to LLM)'),
|
||
},
|
||
},
|
||
{
|
||
id: 'symbol',
|
||
title: phrase('Function Signature & Implementation'),
|
||
description: 'Retrieve exact signature, parameters, return types, and complete body for a specific function.',
|
||
target: 'func buildEmbedText(ch CodeChunk, maxChars int)',
|
||
hanzo: {
|
||
latency: '0.05 ms',
|
||
latencyMs: 0.05,
|
||
turns: 1,
|
||
tokens: 407,
|
||
savings: '87.3%',
|
||
detail: phrase('Tree-Sitter exact AST node definition resolution'),
|
||
},
|
||
containerRAG: {
|
||
latency: '37 ms',
|
||
latencyMs: 37,
|
||
turns: 1,
|
||
tokens: 437,
|
||
savings: '86.4%',
|
||
detail: phrase('Qdrant payload filter (name + type scroll)'),
|
||
},
|
||
traditional: {
|
||
latency: '9.0 s',
|
||
latencyMs: 9000,
|
||
turns: 2,
|
||
tokens: 3204,
|
||
steps: [phrase('Grep symbol name'), phrase('Read entire source file (1,000+ lines)')],
|
||
detail: phrase('Grep search followed by reading the entire parent source file'),
|
||
},
|
||
},
|
||
{
|
||
id: 'routes',
|
||
title: phrase('API Surface & Route Discovery'),
|
||
description: 'Enumerate all registered MCP tool handlers, schema endpoints, and router definitions across the codebase.',
|
||
target: phrase('Full surface tool and route table'),
|
||
hanzo: {
|
||
latency: '0.4 ms',
|
||
latencyMs: 0.4,
|
||
turns: 1,
|
||
tokens: 160,
|
||
savings: '98.4%',
|
||
detail: phrase('Tree-Sitter exports & outline scan in-process'),
|
||
},
|
||
containerRAG: {
|
||
latency: '190 ms',
|
||
latencyMs: 190,
|
||
turns: 1,
|
||
tokens: 176,
|
||
savings: '98.2%',
|
||
detail: phrase('Hybrid lexical + vector search across Qdrant chunks'),
|
||
},
|
||
traditional: {
|
||
latency: '49.7 s',
|
||
latencyMs: 49670,
|
||
turns: 11,
|
||
tokens: 125687,
|
||
steps: [phrase('Grep tool definitions'), phrase('Read handlers (11 files)'), phrase('Synthesize route surface')],
|
||
detail: phrase('Multi-file scan reading 11+ route and handler files into context'),
|
||
},
|
||
},
|
||
{
|
||
id: 'claude_repair',
|
||
title: phrase('Claude Code Acceleration: Zero-Model Fault Repair (Kai)'),
|
||
description: 'Diagnose and repair a failing test fault across a multi-module repository (reproducing coding.repair).',
|
||
target: phrase('Single-token fault repair on failing unit test'),
|
||
hanzo: {
|
||
latency: '180 ms',
|
||
latencyMs: 180,
|
||
turns: 1,
|
||
tokens: 0,
|
||
savings: '100%',
|
||
detail: phrase('Kai deterministic test search settles fault with 0 model calls in 180ms'),
|
||
},
|
||
containerRAG: {
|
||
latency: '4.2 s',
|
||
latencyMs: 4200,
|
||
turns: 2,
|
||
tokens: 2840,
|
||
savings: '94.8%',
|
||
detail: phrase('Qdrant vector retrieval + 1 LLM inference turn'),
|
||
},
|
||
traditional: {
|
||
latency: '24.8 s',
|
||
latencyMs: 24800,
|
||
turns: 6,
|
||
tokens: 55000,
|
||
steps: [phrase('Run test suite'), phrase('Read failure trace'), phrase('Inspect implementation'), phrase('Attempt patch'), phrase('Re-run test'), phrase('Verify diff')],
|
||
detail: phrase('Native Claude Code multi-turn LLM reasoning and file editing (6 roundtrips)'),
|
||
},
|
||
},
|
||
{
|
||
id: 'claude_refactor',
|
||
title: phrase('Claude Code Acceleration: Atomic AST Refactoring'),
|
||
description: 'Rename an exported interface and update all references across 10+ modules.',
|
||
target: phrase('Rename BackendKind to BackendType across 10 files'),
|
||
hanzo: {
|
||
latency: '1.46 s',
|
||
latencyMs: 1460,
|
||
turns: 2,
|
||
tokens: 1480,
|
||
savings: '94.9%',
|
||
detail: phrase('Hanzo AST Refactor tool executes atomic multi-file rename in 18ms'),
|
||
},
|
||
containerRAG: {
|
||
latency: '14.8 s',
|
||
latencyMs: 14800,
|
||
turns: 4,
|
||
tokens: 8900,
|
||
savings: '69.0%',
|
||
detail: phrase('Vector search for callers + multi-step edits'),
|
||
},
|
||
traditional: {
|
||
latency: '54.8 s',
|
||
latencyMs: 54750,
|
||
turns: 13,
|
||
tokens: 28740,
|
||
steps: [phrase('Grep usages'), phrase('Edit file 1'), phrase('Edit file 2'), phrase('Edit file 3'), phrase('Edit file 4'), phrase('Edit file 5'), phrase('Edit file 6'), phrase('Edit file 7'), phrase('Edit file 8'), phrase('Edit file 9'), phrase('Edit file 10'), phrase('Run typecheck'), phrase('Synthesize diff')],
|
||
detail: phrase('Native Claude Code sequential file edits (13 LLM roundtrips)'),
|
||
},
|
||
},
|
||
]
|
||
|
||
export function CodeRace() {
|
||
const { t } = useI18n()
|
||
const [taskIndex, setTaskIndex] = useState(0)
|
||
const [isRacing, setIsRacing] = useState(false)
|
||
const [hanzoProgress, setHanzoProgress] = useState(0)
|
||
const [ragProgress, setRagProgress] = useState(0)
|
||
const [tradProgress, setTradProgress] = useState(0)
|
||
const [tradStep, setTradStep] = useState(0)
|
||
const [elapsedMs, setElapsedMs] = useState(0)
|
||
const [tokensBurned, setTokensBurned] = useState(0)
|
||
|
||
const task = TASKS[taskIndex]
|
||
const TOTAL_DOTS = 24
|
||
|
||
// Racing simulation loop
|
||
useEffect(() => {
|
||
let timer: ReturnType<typeof setInterval> | null = null
|
||
if (isRacing) {
|
||
const startTime = Date.now()
|
||
const totalSimDuration = 6000 // 6 seconds simulated race timeline
|
||
|
||
timer = setInterval(() => {
|
||
const elapsed = Date.now() - startTime
|
||
setElapsedMs(elapsed)
|
||
|
||
// Hanzo finishes immediately (at 100ms mark)
|
||
if (elapsed >= 100) {
|
||
setHanzoProgress(100)
|
||
} else {
|
||
setHanzoProgress((elapsed / 100) * 100)
|
||
}
|
||
|
||
// Containerized RAG finishes at ~1500ms mark
|
||
if (elapsed >= 1500) {
|
||
setRagProgress(100)
|
||
} else {
|
||
setRagProgress((elapsed / 1500) * 100)
|
||
}
|
||
|
||
// Traditional agent finishes near the end of race
|
||
const tradRatio = Math.min(1, elapsed / totalSimDuration)
|
||
setTradProgress(tradRatio * 100)
|
||
|
||
const currentStep = Math.min(
|
||
task.traditional.steps.length - 1,
|
||
Math.floor(tradRatio * task.traditional.steps.length)
|
||
)
|
||
setTradStep(currentStep)
|
||
|
||
// Tokens burn count up
|
||
setTokensBurned(Math.floor(tradRatio * task.traditional.tokens))
|
||
|
||
if (elapsed >= totalSimDuration) {
|
||
setIsRacing(false)
|
||
setTradProgress(100)
|
||
setTokensBurned(task.traditional.tokens)
|
||
if (timer) clearInterval(timer)
|
||
}
|
||
}, 30)
|
||
}
|
||
return () => {
|
||
if (timer) clearInterval(timer)
|
||
}
|
||
}, [isRacing, task])
|
||
|
||
const startRace = () => {
|
||
setHanzoProgress(0)
|
||
setRagProgress(0)
|
||
setTradProgress(0)
|
||
setTradStep(0)
|
||
setElapsedMs(0)
|
||
setTokensBurned(0)
|
||
setIsRacing(true)
|
||
}
|
||
|
||
// Render glowing dot fill track
|
||
const renderDotTrack = (progressPercent: number, activeColor: string, isFinished: boolean) => {
|
||
const filledCount = Math.floor((progressPercent / 100) * TOTAL_DOTS)
|
||
return (
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: '5px', flexWrap: 'wrap' }}>
|
||
{Array.from({ length: TOTAL_DOTS }).map((_, i) => {
|
||
const filled = i < filledCount
|
||
const isLatest = i === filledCount - 1 && isRacing && !isFinished
|
||
return (
|
||
<span
|
||
key={i}
|
||
style={{
|
||
width: '8px',
|
||
height: '8px',
|
||
borderRadius: '50%',
|
||
backgroundColor: filled ? activeColor : 'var(--border)',
|
||
boxShadow: filled
|
||
? isLatest
|
||
? `0 0 10px ${activeColor}, 0 0 4px ${activeColor}`
|
||
: `0 0 4px ${activeColor}88`
|
||
: 'none',
|
||
transform: isLatest ? 'scale(1.3)' : 'scale(1)',
|
||
transition: 'background-color 0.15s ease, transform 0.15s ease',
|
||
}}
|
||
/>
|
||
)
|
||
})}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<Part id="agent-race">
|
||
<H2>{t('Agent Code Intelligence: The Race')}</H2>
|
||
<P>
|
||
{t(
|
||
'How Hanzo Dev and Hanzo MCP accelerate agentic code comprehension compared to traditional raw-file reading and containerized local RAG stacks (Qdrant + Ollama). Benchmarked across production multi-language repositories.',
|
||
)}
|
||
</P>
|
||
|
||
{/* Task Selection Pills */}
|
||
<div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap', marginTop: '16px', marginBottom: '24px' }}>
|
||
{TASKS.map((x, idx) => (
|
||
<button
|
||
key={x.id}
|
||
onClick={() => {
|
||
setTaskIndex(idx)
|
||
setIsRacing(false)
|
||
setHanzoProgress(100)
|
||
setRagProgress(100)
|
||
setTradProgress(100)
|
||
setTokensBurned(x.traditional.tokens)
|
||
}}
|
||
style={{
|
||
padding: '8px 16px',
|
||
borderRadius: '9999px',
|
||
fontSize: '13px',
|
||
fontFamily: 'var(--font-mono, monospace)',
|
||
border: taskIndex === idx ? '1px solid var(--text-primary)' : '1px solid var(--border)',
|
||
backgroundColor: taskIndex === idx ? 'var(--text-primary)' : 'var(--card)',
|
||
color: taskIndex === idx ? 'var(--background)' : 'var(--text-secondary)',
|
||
cursor: 'pointer',
|
||
transition: 'all 0.2s ease',
|
||
}}
|
||
>
|
||
{t(x.title)}
|
||
</button>
|
||
))}
|
||
</div>
|
||
|
||
{/* Race Arena Card */}
|
||
<Block id="race-arena">
|
||
<div style={{ padding: '24px', backgroundColor: 'var(--card)', borderRadius: '12px', border: '1px solid var(--border)' }}>
|
||
{/* Header & Controls */}
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '16px', marginBottom: '24px' }}>
|
||
<div>
|
||
<Meta>{t('TARGET QUERY')}</Meta>
|
||
<div style={{ fontSize: '15px', fontWeight: '500', color: 'var(--text-primary)' }}>{t(task.target)}</div>
|
||
</div>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
|
||
{isRacing && (
|
||
<div style={{ display: 'inline-flex', alignItems: 'center', gap: '6px', fontSize: '13px', fontFamily: 'var(--font-mono, monospace)', color: 'var(--muted-foreground)' }}>
|
||
<Clock size={14} />
|
||
<span>{(elapsedMs / 1000).toFixed(2)}s</span>
|
||
</div>
|
||
)}
|
||
<button
|
||
onClick={startRace}
|
||
disabled={isRacing}
|
||
style={{
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
gap: '8px',
|
||
padding: '10px 20px',
|
||
borderRadius: '9999px',
|
||
border: 'none',
|
||
backgroundColor: isRacing ? 'var(--border)' : 'var(--text-primary)',
|
||
color: 'var(--background)',
|
||
fontWeight: '600',
|
||
cursor: isRacing ? 'not-allowed' : 'pointer',
|
||
fontFamily: 'var(--font-mono, monospace)',
|
||
fontSize: '13px',
|
||
}}
|
||
>
|
||
{isRacing ? (
|
||
<>
|
||
<RotateCcw size={14} /> {t('Racing...')}
|
||
</>
|
||
) : (
|
||
<>
|
||
<Play size={14} /> {t('Run Race Simulation')}
|
||
</>
|
||
)}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Lane 1: Hanzo Native */}
|
||
<div style={{ padding: '16px', borderRadius: '8px', border: '1px solid rgba(16, 185, 129, 0.3)', backgroundColor: 'rgba(16, 185, 129, 0.04)', marginBottom: '16px' }}>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px', flexWrap: 'wrap', gap: '8px' }}>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||
<span style={{ display: 'inline-flex', padding: '4px 8px', borderRadius: '4px', backgroundColor: '#10b981', color: '#000', fontSize: '11px', fontWeight: 'bold' }}>
|
||
⚡ {t('HANZO NATIVE')}
|
||
</span>
|
||
<span style={{ fontSize: '14px', fontWeight: '500', color: 'var(--text-primary)' }}>
|
||
hanzo dev + hanzo-mcp
|
||
</span>
|
||
</div>
|
||
<div style={{ display: 'flex', gap: '16px', fontSize: '12px', fontFamily: 'var(--font-mono, monospace)', color: '#10b981' }}>
|
||
<span><strong>{task.hanzo.latency}</strong></span>
|
||
<span>{t('{n} turn', { n: task.hanzo.turns })}</span>
|
||
<span>
|
||
{t('{n} tokens ({saved})', {
|
||
n: task.hanzo.tokens,
|
||
saved: <strong>{t('{savings} saved', { savings: task.hanzo.savings })}</strong>,
|
||
})}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
{renderDotTrack(hanzoProgress, '#10b981', hanzoProgress >= 100)}
|
||
<div style={{ marginTop: '8px', fontSize: '12px', color: 'var(--muted-foreground)' }}>
|
||
{t(task.hanzo.detail)} · <strong>{t('Zero Docker, Zero background model daemons')}</strong>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Lane 2: Heavy Local RAG */}
|
||
<div style={{ padding: '16px', borderRadius: '8px', border: '1px solid var(--border)', backgroundColor: 'rgba(245, 158, 11, 0.03)', marginBottom: '16px' }}>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px', flexWrap: 'wrap', gap: '8px' }}>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||
<span style={{ display: 'inline-flex', padding: '4px 8px', borderRadius: '4px', backgroundColor: '#f59e0b', color: '#000', fontSize: '11px', fontWeight: 'bold' }}>
|
||
⚙️ {t('LOCAL RAG')}
|
||
</span>
|
||
<span style={{ fontSize: '14px', fontWeight: '500', color: 'var(--text-primary)' }}>
|
||
Qdrant Container + Ollama (phi3 / mxbai)
|
||
</span>
|
||
</div>
|
||
<div style={{ display: 'flex', gap: '16px', fontSize: '12px', fontFamily: 'var(--font-mono, monospace)', color: '#f59e0b' }}>
|
||
<span><strong>{task.containerRAG.latency}</strong></span>
|
||
<span>{t('{n} turn', { n: task.containerRAG.turns })}</span>
|
||
<span>{t('{n} tokens', { n: task.containerRAG.tokens })}</span>
|
||
</div>
|
||
</div>
|
||
{renderDotTrack(ragProgress, '#f59e0b', ragProgress >= 100)}
|
||
<div style={{ marginTop: '8px', fontSize: '12px', color: 'var(--muted-foreground)' }}>
|
||
{t(task.containerRAG.detail)} · <strong>{t('Requires 16 GB RAM + Docker daemon')}</strong>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Lane 3: Traditional Agent */}
|
||
<div style={{ padding: '16px', borderRadius: '8px', border: '1px solid var(--border)', backgroundColor: 'rgba(239, 68, 68, 0.03)' }}>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px', flexWrap: 'wrap', gap: '8px' }}>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||
<span style={{ display: 'inline-flex', padding: '4px 8px', borderRadius: '4px', backgroundColor: '#ef4444', color: '#fff', fontSize: '11px', fontWeight: 'bold' }}>
|
||
🐌 {t('TRADITIONAL AGENT')}
|
||
</span>
|
||
<span style={{ fontSize: '14px', fontWeight: '500', color: 'var(--text-primary)' }}>
|
||
{t('Claude Code / Cursor (Raw Grep + File Reads)')}
|
||
</span>
|
||
</div>
|
||
<div style={{ display: 'flex', gap: '16px', fontSize: '12px', fontFamily: 'var(--font-mono, monospace)', color: '#ef4444' }}>
|
||
<span><strong>{task.traditional.latency}</strong></span>
|
||
<span>{t('{n} turns', { n: task.traditional.turns })}</span>
|
||
<span>{t('{n} tokens', { n: tokensBurned.toLocaleString() })}</span>
|
||
</div>
|
||
</div>
|
||
{renderDotTrack(tradProgress, '#ef4444', tradProgress >= 100)}
|
||
<div style={{ marginTop: '8px', fontSize: '12px', color: 'var(--muted-foreground)', display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap' }}>
|
||
<span>
|
||
{isRacing && tradProgress < 100 ? (
|
||
<span style={{ color: '#ef4444', fontWeight: '500' }}>
|
||
{t('Active Step: {step}', { step: t(task.traditional.steps[tradStep]) })}
|
||
</span>
|
||
) : (
|
||
t(task.traditional.detail)
|
||
)}
|
||
</span>
|
||
<span style={{ color: '#ef4444' }}>
|
||
{tradProgress >= 100 ? t('Context saturated (blowup)') : t('Burning prompt tokens...')}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Detailed Metrics Table */}
|
||
<Table>
|
||
<thead>
|
||
<tr>
|
||
<Th left>{t('Architecture')}</Th>
|
||
<Th>{t('Latency')}</Th>
|
||
<Th>{t('Tool Turns')}</Th>
|
||
<Th>{t('Tokens Injected')}</Th>
|
||
<Th>{t('Token Savings')}</Th>
|
||
<Th>{t('Speedup')}</Th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<Tr dim>
|
||
<Td left wrap>
|
||
{t('Traditional Agent (Grep + Whole File Reads)')}
|
||
</Td>
|
||
<Td>{task.traditional.latency}</Td>
|
||
<Td>{task.traditional.turns}</Td>
|
||
<Td>{task.traditional.tokens.toLocaleString()}</Td>
|
||
<Td>{t('Baseline')}</Td>
|
||
<Td>1.0×</Td>
|
||
</Tr>
|
||
<Tr dim>
|
||
<Td left wrap>
|
||
{t('Containerized Local RAG (Qdrant + Ollama)')}
|
||
</Td>
|
||
<Td>{task.containerRAG.latency}</Td>
|
||
<Td>{task.containerRAG.turns}</Td>
|
||
<Td>{task.containerRAG.tokens.toLocaleString()}</Td>
|
||
<Td>{task.containerRAG.savings}</Td>
|
||
<Td>{task.containerRAG.latencyMs > 0 ? `${(task.traditional.latencyMs / task.containerRAG.latencyMs).toFixed(1)}×` : '10×–20×'}</Td>
|
||
</Tr>
|
||
<Tr>
|
||
<Td left wrap>
|
||
<strong>{t('Hanzo Native (`hanzo dev` / `hanzo code claude`)')}</strong>
|
||
</Td>
|
||
<Td><strong>{task.hanzo.latency}</strong></Td>
|
||
<Td><strong>{task.hanzo.turns}</strong></Td>
|
||
<Td><strong>{task.hanzo.tokens.toLocaleString()}</strong></Td>
|
||
<Td><strong>{task.hanzo.savings}</strong></Td>
|
||
<Td><strong>{task.hanzo.latencyMs > 0 ? (task.traditional.latencyMs / task.hanzo.latencyMs > 1000 ? '100×+' : `${Math.round(task.traditional.latencyMs / task.hanzo.latencyMs)}×`) : '100×+'}</strong></Td>
|
||
</Tr>
|
||
</tbody>
|
||
</Table>
|
||
|
||
<Note>
|
||
{t(
|
||
'In a real agentic workflow (e.g. Claude Code, Cursor, Windsurf), each tool roundtrip incurs an additional 3–5 seconds of LLM inference latency. By replacing 6–13 iterative file exploration roundtrips with Hanzo’s in-process AST indexing (`code_context`, `code_tool`, `hanzo_refactor`) and Kai deterministic test-driven search, Hanzo Dev accelerates Claude Code by {speed}, while slashing token consumption by {tokens}.',
|
||
{
|
||
speed: <strong>{t('20× to 50× (and up to 137× on zero-model search-settled faults)')}</strong>,
|
||
tokens: <strong>{t('90% to 100%')}</strong>,
|
||
},
|
||
)}
|
||
</Note>
|
||
|
||
<Foot>
|
||
{t('Research runs on benchmarks claude-acceleration and code-rag-navigation, harness commit hanzoai/benchmarks:')}{' '}
|
||
<Inline href="https://api.hanzo.ai/v1/research/runs?org=hanzo&benchmark=claude-acceleration">{`GET /v1/research/runs?org=hanzo&benchmark=claude-acceleration`}</Inline>
|
||
{` · `}
|
||
<Inline href="https://api.hanzo.ai/v1/research/runs?org=hanzo&benchmark=code-rag-navigation">{`GET /v1/research/runs?org=hanzo&benchmark=code-rag-navigation`}</Inline>
|
||
{` · `}
|
||
<Inline href="https://api.hanzo.ai/v1/benchmark/leaderboard?benchmark=code-rag-navigation">{`GET /v1/benchmark/leaderboard?benchmark=code-rag-navigation`}</Inline>
|
||
</Foot>
|
||
</Block>
|
||
</Part>
|
||
)
|
||
}
|