UNPKG

@juspay/neurolink

Version:

Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio

95 lines (94 loc) 3.35 kB
/** * Deterministic experiment log parser. * * Extracts metrics from run.log output. Never throws — returns * crashed/timedOut summary on parse failure. */ /** * Parse experiment output into a structured summary. * * This function is deterministic and pure — no side effects, no throws. */ export function parseExperimentSummary(logContent, metricConfig, memoryConfig, options) { const lines = logContent.split("\n"); const tailLines = lines.slice(-50); const rawTail = tailLines.join("\n"); // Check for crash indicators (only if not already determined by exit code) let crashed = options?.exitCode !== undefined && options.exitCode !== 0 && !options?.timedOut; if (!crashed) { const lastMeaningfulLine = [...lines] .reverse() .find((l) => l.trim().length > 0) ?.trim() ?? ""; crashed = lastMeaningfulLine === "FAIL" || lastMeaningfulLine.toLowerCase().includes("traceback") || lastMeaningfulLine.toLowerCase().includes("error:"); } // Parse primary metric let metric = null; try { const regex = new RegExp(metricConfig.pattern, "m"); const match = regex.exec(logContent); if (match && match[1]) { const parsed = parseFloat(match[1]); if (!isNaN(parsed) && isFinite(parsed)) { metric = parsed; } } } catch { // Invalid regex — treat as parse failure } // Parse memory metric let memoryValue = null; if (memoryConfig) { try { const regex = new RegExp(memoryConfig.pattern, "m"); const match = regex.exec(logContent); if (match && match[1]) { const parsed = parseFloat(match[1]); if (!isNaN(parsed) && isFinite(parsed)) { memoryValue = parsed; // Convert MB to GB if the name suggests MB. // Uses binary divisor (1024 = MiB→GiB). For decimal MB→GB use 1000. // The 1024 convention matches GPU monitoring tools (nvidia-smi, etc.). const MIB_TO_GIB_DIVISOR = 1024; if (memoryConfig.name.toLowerCase().includes("mb")) { memoryValue = Math.round((memoryValue / MIB_TO_GIB_DIVISOR) * 100) / 100; } } } } catch { // Invalid regex — treat as parse failure } } // Parse training time let trainingSeconds = null; try { const timeRegex = /^training_seconds:\s+([\d.]+)/m; const match = timeRegex.exec(logContent); if (match && match[1]) { trainingSeconds = parseFloat(match[1]); } } catch { // Ignore } // Only treat as timeout if explicitly signaled by the runner — don't infer from missing metric const timedOut = options?.timedOut ?? false; // Missing metric without explicit timeout is a crash (regex failure, spawn error, etc.) const finalCrashed = crashed || (metric === null && !timedOut); return { crashed: finalCrashed, timedOut, metric, memoryValue, trainingSeconds, rawTail, }; }