/** * @llm-gateway/client * * TypeScript client library for the LLM Gateway. * Used by all Context X projects: TIP, EO Global Pulse, SwitchBlade, * PeerCortex, NOGnet, ShieldX, and CtxEvent. * * Usage: * import { LLMGatewayClient, createTIPClient } from '@llm-gateway/client'; * const client = createTIPClient(); * const result = await client.completion({ task_type: 'summarize', input: '...' }); */ // ============================================================ // Request / Response types // ============================================================ export interface CompletionRequest { /** Identifies which project/service is calling (e.g. 'tip-scraper', 'eo-global-pulse') */ caller: string; /** Task type that maps to a prompt template (e.g. 'summarize', 'classify', 'translate') */ task_type: string; /** The raw input text to process */ input: string; /** Preferred output language */ language?: 'de' | 'en'; /** Additional context passed to the prompt template */ context?: Record; /** Per-request model / behavior overrides */ options?: { /** Override the model (e.g. 'qwen2.5:32b'). Gateway picks a sensible default. */ model?: string; /** Sampling temperature 0–1 */ temperature?: number; /** Max output tokens */ max_tokens?: number; /** Include full validation details in the response */ return_validation_details?: boolean; }; } export interface CompletionResponse { /** Request ID for tracing */ id: string; /** Overall status of the response */ status: 'approved' | 'warning' | 'pending_review' | 'rejected'; /** Model confidence score 0–10 */ confidence: number; /** Ollama model that produced the output */ model: string; /** Task type that was processed */ task_type: string; /** End-to-end latency in milliseconds */ latency_ms: number; /** Token usage */ tokens: { in: number; out: number }; /** The LLM output text */ output: string; /** Validation details (present when return_validation_details=true) */ validation?: { passed: boolean; score: number; validators: Record; }; } export interface ClassifyResponse { task_type: string; content_type: string; language: string; complexity: 'low' | 'medium' | 'high'; requires_facts: boolean; suggested_task_types: string[]; } export interface BatchResponse { batch_id: string; } export interface HealthResponse { status: 'ok' | 'degraded' | 'down'; ollama: unknown; queue: unknown; } // ============================================================ // Gateway client // ============================================================ export class LLMGatewayClient { private readonly baseUrl: string; private readonly caller: string; private readonly timeout: number; constructor(config: { baseUrl?: string; caller: string; /** Request timeout in ms (default: 30 000) */ timeout?: number; }) { this.baseUrl = config.baseUrl ?? process.env['LLM_GATEWAY_URL'] ?? 'https://llm-gateway.context-x.org'; this.caller = config.caller; this.timeout = config.timeout ?? 30_000; } // ---------------------------------------------------------- // Core: completion // ---------------------------------------------------------- async completion( params: Omit, ): Promise { const body: CompletionRequest = { ...params, caller: this.caller }; return this.post('/v1/completion', body); } // ---------------------------------------------------------- // Classify input before routing // ---------------------------------------------------------- async classify(input: string): Promise { return this.post('/v1/classify', { caller: this.caller, input, }); } // ---------------------------------------------------------- // Batch: submit multiple tasks, results delivered via webhook // ---------------------------------------------------------- async batch( tasks: Array>, webhookUrl: string, ): Promise { return this.post('/v1/batch', { caller: this.caller, tasks, webhook_url: webhookUrl, }); } // ---------------------------------------------------------- // Health // ---------------------------------------------------------- async health(): Promise { const res = await this.fetchWithTimeout(`${this.baseUrl}/health`); if (!res.ok) { throw new Error(`Health check failed: ${res.status}`); } return res.json() as Promise; } // ---------------------------------------------------------- // Graceful degradation — returns null when gateway is unavailable // ---------------------------------------------------------- async safeCompletion( params: Omit, ): Promise { try { return await this.completion(params); } catch { // Gateway is down or timed out — caller handles degraded mode return null; } } // ---------------------------------------------------------- // Internal helpers // ---------------------------------------------------------- private async post(path: string, body: unknown): Promise { const res = await this.fetchWithTimeout(`${this.baseUrl}${path}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); if (!res.ok) { const text = await res.text().catch(() => ''); throw new Error(`Gateway error ${res.status} on ${path}: ${text}`); } return res.json() as Promise; } private fetchWithTimeout(url: string, init?: RequestInit): Promise { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), this.timeout); return fetch(url, { ...init, signal: controller.signal }).finally(() => clearTimeout(timer), ); } } // ============================================================ // Project-specific pre-configured factory functions // ============================================================ /** * TIP (Transceiver Intelligence Platform) * Long timeout because scraping + AI analysis can take time. */ export function createTIPClient(baseUrl?: string): LLMGatewayClient { return new LLMGatewayClient({ caller: 'tip-scraper', baseUrl, timeout: 60_000 }); } /** * EO Global Pulse — team collaboration & CRM intelligence */ export function createEOPulseClient(baseUrl?: string): LLMGatewayClient { return new LLMGatewayClient({ caller: 'eo-global-pulse', baseUrl, timeout: 30_000 }); } /** * SwitchBlade — infrastructure management platform */ export function createSwitchBladeClient(baseUrl?: string): LLMGatewayClient { return new LLMGatewayClient({ caller: 'switchblade', baseUrl, timeout: 15_000 }); } /** * PeerCortex — BGP/RPKI network intelligence * Short timeout: results must be near-real-time for network monitoring. */ export function createPeerCortexClient(baseUrl?: string): LLMGatewayClient { return new LLMGatewayClient({ caller: 'peercortex', baseUrl, timeout: 8_000 }); } /** * NOGnet — NOG Support Program & event management */ export function createNOGnetClient(baseUrl?: string): LLMGatewayClient { return new LLMGatewayClient({ caller: 'nognet', baseUrl, timeout: 30_000 }); } /** * ShieldX — LLM prompt injection defense */ export function createShieldXClient(baseUrl?: string): LLMGatewayClient { return new LLMGatewayClient({ caller: 'shieldx', baseUrl, timeout: 10_000 }); } /** * CtxEvent — event management platform */ export function createCtxEventClient(baseUrl?: string): LLMGatewayClient { return new LLMGatewayClient({ caller: 'ctxevent', baseUrl, timeout: 20_000 }); }