Unrag
DebuggingExperimental
Experimental Feature

Programmatic API

Integrate debug capabilities programmatically beyond the TUI.

The Debug Panel TUI is built on top of a programmatic API that you can use directly. This is useful if you want to build custom debugging tools, integrate debug events into your existing observability stack, or automate debugging workflows.

Server-side API

These functions run in your application alongside the debug server.

Starting the server manually

The debug server starts automatically when UNRAG_DEBUG=true is set and your engine is created. If you need more control, you can start and stop it manually:

import { startDebugServer, stopDebugServer, getDebugServer } from "@unrag/debug";

// Start with custom configuration
const server = await startDebugServer({
  port: 4000,           // Default: 3847
  host: "0.0.0.0",      // Default: "localhost"
  maxClients: 10,       // Default: 5
});

if (server) {
  console.log(`Debug server running at ws://${server.host}:${server.port}`);
}

// Check if server is running
const current = getDebugServer();
if (current) {
  console.log(`Connected clients: ${current.clientCount}`);
}

// Stop the server
await stopDebugServer();

The startDebugServer function returns null if UNRAG_DEBUG isn't enabled, so you can call it unconditionally and it will only start when appropriate.

Registering the runtime

For interactive commands (queries, ingestion, document inspection), register your engine:

import { registerUnragDebug, getUnragDebugRuntime } from "@unrag/debug";

// Basic registration (enables Query, Ingest panels)
registerUnragDebug({ engine });

// Full registration (also enables Docs panel)
registerUnragDebug({
  engine,
  storeInspector: engine.storeInspector,
});

// Check current registration
const runtime = getUnragDebugRuntime();
if (runtime?.engine) {
  console.log("Engine registered for debug commands");
}

The storeInspector provides methods for listing and retrieving documents from your vector store. It's available from your engine instance if your store adapter supports it.

Client-side API

These functions let you build custom tools that connect to a running debug server.

Connecting to the server

import { connectDebugClient, createAutoReconnectClient } from "@unrag/debug";

// Simple connection
const connection = await connectDebugClient({
  url: "ws://localhost:3847",
});

console.log(`Status: ${connection.status}`);
console.log(`Session: ${connection.sessionId}`);
console.log(`Capabilities: ${connection.capabilities?.join(", ")}`);

// With auto-reconnect
const client = createAutoReconnectClient({
  url: "ws://localhost:3847",
  reconnect: true,
  reconnectDelay: 1000,
  maxReconnectAttempts: 10,
});

Receiving events

Subscribe to debug events as they stream from the server:

// Subscribe to events
const unsubscribe = connection.onEvent((event) => {
  console.log(`[${event.type}]`, event);
  
  if (event.type === "ingest:complete") {
    console.log(`Ingested ${event.chunkCount} chunks in ${event.totalDurationMs}ms`);
  }
});

// Monitor connection status
connection.onStatusChange((status) => {
  console.log(`Connection status: ${status}`);
});

// Cleanup
unsubscribe();
connection.disconnect();

Sending commands

Execute debug commands and receive results:

// Run a query
const queryResult = await connection.sendCommand({
  type: "query",
  query: "how does ingestion work?",
  topK: 5,
});

if (queryResult.success && queryResult.type === "query") {
  for (const chunk of queryResult.chunks ?? []) {
    console.log(`${chunk.score.toFixed(4)} | ${chunk.sourceId}`);
  }
}

// List documents
const docsResult = await connection.sendCommand({
  type: "list-documents",
  prefix: "docs:",
  limit: 10,
});

// Get store stats
const statsResult = await connection.sendCommand({
  type: "store-stats",
});

// Run doctor checks
const doctorResult = await connection.sendCommand({
  type: "doctor",
});

Available commands

CommandDescriptionCapability Required
queryExecute a retrieval queryquery
ingestIngest a documentingest
list-documentsList stored documentsdocs
get-documentGet document details with chunksdocs
delete-documentDelete a documentdocs
delete-chunksDelete specific chunksdocs
store-statsGet store statisticsstoreInspector
doctorRun diagnosticsdoctor
run-evalRun an evaluation dataseteval
pingTest connection
clear-bufferClear event buffer
get-bufferGet buffered events

Type exports

The debug module exports TypeScript types for building type-safe integrations:

import type {
  // Server types
  DebugServerConfig,
  DebugServer,
  
  // Client types
  DebugClientConfig,
  DebugConnection,
  DebugConnectionStatus,
  
  // Command types
  DebugCommand,
  QueryCommand,
  IngestCommand,
  ListDocumentsCommand,
  // ... and more
  
  // Result types
  DebugCommandResult,
  QueryResult,
  IngestResult,
  // ... and more
  
  // Event types
  DebugEvent,
  DebugEventType,
  IngestStartEvent,
  IngestCompleteEvent,
  RetrieveCompleteEvent,
  // ... and more
} from "@unrag/debug";

WebSocket protocol

The debug server uses a simple JSON-over-WebSocket protocol. If you're building a client in a language other than TypeScript, here's what you need to know:

Handshake. After connecting, the server sends a hello message with its protocol version and capabilities. Your client should respond with its supported protocol versions. The server then sends a welcome message with the session ID and buffered events.

Events. The server broadcasts events as { type: "event", event: DebugEvent } messages.

Commands. Send commands as { type: "command", requestId: string, command: DebugCommand }. The server responds with { type: "result", requestId: string, result: DebugCommandResult }.

The protocol version is incremented when breaking changes are made. The current version is 2.

What's next

On this page

RAG handbook banner image

Free comprehensive guide

Complete RAG Handbook

Learn RAG from first principles to production operations. Tackle decisions, tradeoffs and failure modes in production RAG operations

The RAG handbook covers retrieval augmented generation from foundational principles through production deployment, including quality-latency-cost tradeoffs and operational considerations. Click to access the complete handbook.