/** * LeRobot Arena Inference Server TypeScript Client * * This client provides TypeScript access to the LeRobot Arena Inference Server * for ACT (Action Chunking Transformer) model inference and session management. * * @example Basic Usage * ```typescript * import { LeRobotInferenceServerClient, CreateSessionRequest } from '@lerobot-arena/inference-server-client'; * * const client = new LeRobotInferenceServerClient('http://localhost:8001'); * * // Create and start a session * const sessionRequest: CreateSessionRequest = { * session_id: 'my-robot-01', * policy_path: './checkpoints/act_so101_beyond', * camera_names: ['front', 'wrist'], * arena_server_url: 'http://localhost:8000' * }; * * const session = await client.createSession(sessionRequest); * await client.startInference('my-robot-01'); * * // Monitor session * const status = await client.getSessionStatus('my-robot-01'); * console.log(`Session status: ${status.status}`); * ``` */ // Export all generated types and services from OpenAPI export * from './generated'; // Import what we need for the convenience wrapper import { client, createSessionSessionsPost, listSessionsSessionsGet, getSessionStatusSessionsSessionIdGet, startInferenceSessionsSessionIdStartPost, stopInferenceSessionsSessionIdStopPost, restartInferenceSessionsSessionIdRestartPost, deleteSessionSessionsSessionIdDelete, healthCheckHealthGet, getSystemInfoDebugSystemGet, debugResetSessionDebugSessionsSessionIdResetPost, getSessionQueueInfoDebugSessionsSessionIdQueueGet } from './generated'; import type { CreateSessionRequest, CreateSessionResponse, SessionStatusResponse } from './generated'; /** * LeRobot Arena Inference Server Client * * A convenience wrapper around the generated OpenAPI client that provides * a simpler interface for common operations while maintaining full type safety. */ export class LeRobotInferenceServerClient { private baseUrl: string; constructor(baseUrl: string) { this.baseUrl = baseUrl; // Configure the generated client with the base URL client.setConfig({ baseUrl }); } /** * Check if the inference server is healthy and responding */ async isHealthy(): Promise { try { const response = await healthCheckHealthGet(); return !response.error; } catch { return false; } } /** * Get detailed server health information */ async getHealth() { const response = await healthCheckHealthGet(); if (response.error) { throw new Error(`Health check failed: ${JSON.stringify(response.error)}`); } return response.data; } /** * Create a new inference session */ async createSession(request: CreateSessionRequest): Promise { const response = await createSessionSessionsPost({ body: request }); if (response.error) { throw new Error(`Failed to create session: ${JSON.stringify(response.error)}`); } return response.data!; } /** * List all active sessions */ async listSessions(): Promise { const response = await listSessionsSessionsGet(); if (response.error) { throw new Error(`Failed to list sessions: ${JSON.stringify(response.error)}`); } return response.data!; } /** * Get detailed status of a specific session */ async getSessionStatus(sessionId: string): Promise { const response = await getSessionStatusSessionsSessionIdGet({ path: { session_id: sessionId } }); if (response.error) { throw new Error(`Failed to get session status: ${JSON.stringify(response.error)}`); } return response.data!; } /** * Start inference for a session */ async startInference(sessionId: string): Promise { const response = await startInferenceSessionsSessionIdStartPost({ path: { session_id: sessionId } }); if (response.error) { throw new Error(`Failed to start inference: ${JSON.stringify(response.error)}`); } } /** * Stop inference for a session */ async stopInference(sessionId: string): Promise { const response = await stopInferenceSessionsSessionIdStopPost({ path: { session_id: sessionId } }); if (response.error) { throw new Error(`Failed to stop inference: ${JSON.stringify(response.error)}`); } } /** * Restart inference for a session */ async restartInference(sessionId: string): Promise { const response = await restartInferenceSessionsSessionIdRestartPost({ path: { session_id: sessionId } }); if (response.error) { throw new Error(`Failed to restart inference: ${JSON.stringify(response.error)}`); } } /** * Delete a session and clean up all resources */ async deleteSession(sessionId: string): Promise { const response = await deleteSessionSessionsSessionIdDelete({ path: { session_id: sessionId } }); if (response.error) { throw new Error(`Failed to delete session: ${JSON.stringify(response.error)}`); } } /** * Wait for a session to reach a specific status */ async waitForSessionStatus( sessionId: string, targetStatus: string, timeoutMs: number = 30000 ): Promise { const startTime = Date.now(); while (Date.now() - startTime < timeoutMs) { const status = await this.getSessionStatus(sessionId); if (status.status === targetStatus) { return status; } // Wait 1 second before checking again await new Promise(resolve => setTimeout(resolve, 1000)); } throw new Error(`Timeout waiting for session ${sessionId} to reach status ${targetStatus}`); } /** * Convenience method to create a session and start inference in one call */ async createAndStartSession(request: CreateSessionRequest): Promise<{ session: CreateSessionResponse; status: SessionStatusResponse; }> { const session = await this.createSession(request); await this.startInference(request.session_id); // Wait for it to be running const status = await this.waitForSessionStatus(request.session_id, 'running'); return { session, status }; } /** * Get system information for debugging */ async getSystemInfo() { const response = await getSystemInfoDebugSystemGet(); if (response.error) { throw new Error(`Failed to get system info: ${JSON.stringify(response.error)}`); } return response.data; } /** * Reset a session's internal state (debug method) */ async debugResetSession(sessionId: string): Promise { const response = await debugResetSessionDebugSessionsSessionIdResetPost({ path: { session_id: sessionId } }); if (response.error) { throw new Error(`Failed to reset session: ${JSON.stringify(response.error)}`); } } /** * Get detailed information about a session's action queue */ async getSessionQueueInfo(sessionId: string) { const response = await getSessionQueueInfoDebugSessionsSessionIdQueueGet({ path: { session_id: sessionId } }); if (response.error) { throw new Error(`Failed to get queue info: ${JSON.stringify(response.error)}`); } return response.data; } } // Convenience function to create a client export function createClient(baseUrl: string): LeRobotInferenceServerClient { return new LeRobotInferenceServerClient(baseUrl); } // Export the old class name for backward compatibility export const LeRobotAIServerClient = LeRobotInferenceServerClient;