MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / StepRow

Function StepRow

apps/vis/web/src/components/analysis/TimelineTab.tsx:282–334  ·  view source on GitHub ↗
({ step, turnDurationMs }: { step: StepNode; turnDurationMs?: number })

Source from the content-addressed store, hash-verified

280}
281
282function StepRow({ step, turnDurationMs }: { step: StepNode; turnDurationMs?: number }) {
283 const widthPct = turnDurationMs && step.durationMs ? Math.max(2, (step.durationMs / turnDurationMs) * 100) : 0;
284 return (
285 <div className="border-l-2 pl-2" style={{ borderColor: step.isError ? 'var(--color-sev-error)' : 'var(--color-border)' }}>
286 <div className="flex flex-wrap items-center gap-2 font-mono text-[11px]">
287 <span className="text-fg-2">step {step.step}</span>
288 {step.finishReason ? (
289 <span className={step.isError ? 'text-[var(--color-sev-error)]' : 'text-fg-3'}>{step.finishReason}</span>
290 ) : null}
291 <span className="text-fg-3 tabular" title="step wall-clock duration">{formatDuration(step.durationMs)}</span>
292 {step.llmFirstTokenLatencyMs !== undefined ? (
293 <span
294 className="text-fg-3 tabular"
295 title={
296 step.llmServerFirstTokenMs !== undefined && step.llmRequestBuildMs !== undefined
297 ? `time to first token (api ${step.llmServerFirstTokenMs}ms + client ${step.llmRequestBuildMs}ms)`
298 : 'time to first token'
299 }
300 >
301 ttft {step.llmFirstTokenLatencyMs}ms
302 {step.llmServerFirstTokenMs !== undefined && step.llmRequestBuildMs !== undefined
303 ? ` (api ${step.llmServerFirstTokenMs} + client ${step.llmRequestBuildMs})`
304 : ''}
305 </span>
306 ) : null}
307 {step.llmServerDecodeMs !== undefined && step.llmClientConsumeMs !== undefined ? (
308 <span
309 className="text-fg-3 tabular"
310 title="decode window split (server awaiting parts + client processing parts)"
311 >
312 decode {step.llmServerDecodeMs}+{step.llmClientConsumeMs}ms
313 </span>
314 ) : null}
315 {step.contextTokens !== undefined ? (
316 <span className="text-fg-3 tabular" title="context-window fill after step">ctx {formatTokens(step.contextTokens)}</span>
317 ) : null}
318 {step.content.thinkChars > 0 ? <span className="text-[var(--color-cat-meta)]" title="reasoning chars">💭 {step.content.thinkChars}</span> : null}
319 </div>
320 {widthPct > 0 ? (
321 <div className="mt-0.5 h-1 w-full bg-surface-2">
322 <div className="h-1" style={{ width: `${widthPct}%`, backgroundColor: step.isError ? 'var(--color-sev-error)' : 'var(--color-cat-conversation)' }} />
323 </div>
324 ) : null}
325 {step.toolCalls.length > 0 ? (
326 <div className="mt-1 flex flex-col gap-0.5">
327 {step.toolCalls.map((tc) => (
328 <ToolRow key={tc.toolCallId} tc={tc} stepDurationMs={step.durationMs} />
329 ))}
330 </div>
331 ) : null}
332 </div>
333 );
334}
335
336function ToolRow({ tc, stepDurationMs }: { tc: ToolCallNode; stepDurationMs?: number }) {
337 const widthPct = stepDurationMs && tc.durationMs ? Math.max(2, (tc.durationMs / stepDurationMs) * 100) : 0;

Callers

nothing calls this directly

Calls 2

formatDurationFunction · 0.90
formatTokensFunction · 0.90

Tested by

no test coverage detected