How the Vis Web Client Works in MoonshotAI/kimi-code: Architecture and Implementation Guide

The Vis web client is a React single-page application in apps/vis/web that communicates with the Vis server via HTTP/JSON API to visualize AI agent sessions, execution graphs, and task outputs.

The Vis (visualization) system in MoonshotAI/kimi-code provides a web-based debugging interface for exploring AI agent traces. Built as a client-server pair, it enables developers to inspect sessions, sub-agents, and execution "wire" graphs through an interactive React frontend. This guide breaks down how the Vis web client operates, from routing and authentication to data fetching and presentation.

Routing and Application Shell

The entry point for the Vis web client is src/App.tsx, which defines the application's route structure and wraps all pages in a shared layout component.

// apps/vis/web/src/App.tsx

The router handles three primary URL patterns:

  • / — Session list overview
  • /sessions/:sessionId — Detailed view of a specific session
  • /sessions/:sessionId/agents/:agentId — Sub-agent detail page with tree and logs

The <AppShell> component provides the persistent UI chrome, ensuring consistent navigation and styling across all views.

API Client and Authentication Flow

All server communication flows through src/api.ts, a centralized fetch wrapper that handles authentication, URL construction, and error handling.

Token Extraction and Storage

When the Vis UI loads, the client searches URL query parameters and hash fragments for token or vis_token. If found, the token is:

  1. Stored in localStorage under the key kimi-vis-auth-token
  2. Removed from the URL to prevent credential leakage in browser history
// apps/vis/web/src/api.ts#L18-L47

Subsequent API calls automatically attach this token as a Bearer header in the Authorization field.

Request Building and Error Handling

The api.ts module exports a typed client object with methods that:

  • Prefix all paths with /api/
  • Serialize request bodies as JSON
  • Parse and validate response payloads
  • Centralize error handling for network failures and HTTP errors

Data Layer: Custom Hooks

The Vis web client uses domain-specific React hooks to fetch and cache data. Each hook follows a consistent pattern, returning a tuple of [data, error, loading] that components use to render appropriate UI states.

Hook Purpose Source File
useSession Fetch session metadata and configuration src/hooks/useSession.ts
useWire Retrieve the execution "wire" graph showing agent call relationships src/hooks/useWire.ts
useTasks Load task outputs and status src/hooks/useTasks.ts
useSubagents Get sub-agent listings and details src/hooks/useSubagents.ts

These hooks wrap the low-level api object and memoize request promises. When route parameters change—such as navigating between sessions—the hooks trigger refetches automatically.

Example: Fetching session and wire data in a component

import { useParams } from 'react-router-dom';
import { useSession } from '#/apps/vis/web/src/hooks/useSession';
import { useWire } from '#/apps/vis/web/src/hooks/useWire';

export function SessionDetailPage() {
  const { sessionId } = useParams<{ sessionId: string }>();
  const [session, sessionError, sessionLoading] = useSession(sessionId);
  const [wire, wireError, wireLoading] = useWire(sessionId, session?.agentId ?? '');

  // Render loading / error states …
}

Presentation Layer: Pages and Components

The UI is organized into page-level components in src/pages/ that compose smaller reusable components from src/components/.

SessionListPage

SessionListPage.tsx displays all available sessions fetched via api.listSessions. It renders a scrollable list with basic metadata for each session.

// apps/vis/web/src/pages/SessionListPage.tsx

SessionDetailPage

SessionDetailPage.tsx is the most complex view, aggregating data from multiple hooks:

  • Session configuration and context
  • Execution wire graph (via <WireRow> components)
  • Task outputs and message history (via <MessageBubble> components)
// apps/vis/web/src/pages/SessionDetailPage.tsx

SubagentDetailPage

SubagentDetailPage.tsx focuses on a single sub-agent, displaying its execution tree and associated logs for deep debugging.

// apps/vis/web/src/pages/SubagentDetailPage.tsx

Server Communication Protocol

The Vis server (apps/vis/server) exposes a RESTful JSON API that the web client consumes. Key endpoints include:

  • GET /api/sessions/:id — Returns SessionDetail (implemented in src/routes/sessions.ts)
  • GET /api/sessions/:id/wire — Returns the execution wire graph (implemented in src/routes/wire.ts)
  • POST /api/imports — Accepts debug-zip bundles for importing external traces (implemented in src/routes/imports.ts)

The server bootstrap in apps/vis/server/src/app.ts mounts these routes and serves the pre-built web assets from apps/vis/web/dist for production deployments.

Importing Debug Data

Developers can import external session traces by uploading zip files through the UI. The API client exposes this functionality via api.importZip:

import { api } from '#/apps/vis/web/src/api';

async function handleDrop(file: File) {
  try {
    const result = await api.importZip(file);
    console.log('Import succeeded:', result);
  } catch (e) {
    console.error('Import failed:', e);
  }
}

Type Safety and Data Contracts

Shared TypeScript interfaces in apps/vis/web/src/types.ts enforce consistency between client and server. These type definitions cover:

  • Session and agent structures
  • Wire graph node and edge types
  • Task status enumerations
  • API request and response shapes

This contract-driven approach catches mismatches at compile time and enables IDE autocompletion throughout the codebase.

Summary

  • The Vis web client is a React SPA in apps/vis/web that visualizes AI agent execution traces
  • Authentication extracts tokens from URL parameters, stores them in localStorage, and attaches them as Bearer headers
  • Data fetching uses typed hooks (useSession, useWire, useTasks) that wrap a centralized API client
  • Routing in App.tsx supports session lists, detail views, and sub-agent inspection
  • Server communication follows RESTful patterns against the Vis server (apps/vis/server) with endpoints under /api/
  • Type safety is enforced through shared interfaces in types.ts

Frequently Asked Questions

How does the Vis web client authenticate with the server?

The client extracts an authentication token from URL query parameters (token or vis_token) on initial load, stores it in localStorage under kimi-vis-auth-token, and scrubs it from the URL. All subsequent API calls in api.ts automatically include this token as a Bearer header in the Authorization field.

What is the "wire" in the Vis web client?

The wire is a directed graph representing the execution flow of an AI agent session—showing which agents called which sub-agents, in what order, with what inputs and outputs. The useWire hook fetches this graph from GET /api/sessions/:id/wire, and components like <WireRow> render it as an interactive visualization.

Can the Vis web client import external debug data?

Yes. The client supports importing session traces via zip file upload. The api.importZip method in api.ts sends a POST request to /api/imports, allowing developers to analyze agent runs captured from other environments or share reproducible debugging scenarios.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →