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:
- Stored in
localStorageunder the keykimi-vis-auth-token - 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— ReturnsSessionDetail(implemented insrc/routes/sessions.ts)GET /api/sessions/:id/wire— Returns the execution wire graph (implemented insrc/routes/wire.ts)POST /api/imports— Accepts debug-zip bundles for importing external traces (implemented insrc/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/webthat visualizes AI agent execution traces - Authentication extracts tokens from URL parameters, stores them in
localStorage, and attaches them asBearerheaders - Data fetching uses typed hooks (
useSession,useWire,useTasks) that wrap a centralized API client - Routing in
App.tsxsupports 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →