import * as fs from "node:fs"; /** * Creates a directory and ensures it is actually accessible. * On Windows with Azure AD/Entra ID, directories created shortly after * wake-from-sleep can end up with broken NTFS ACLs (null DACL) when the * cloud SID cannot be resolved without network connectivity. This leaves * the directory completely inaccessible to the creating user. */ export function ensureAccessibleDir(dirPath: string): void { fs.mkdirSync(dirPath, { recursive: true }); try { fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK); } catch { try { // If we can't access it, try deleting and recreating. // This often fixed the "Null DACL" issue on Windows. fs.rmSync(dirPath, { recursive: true, force: true }); } catch { // Best effort cleanup. } fs.mkdirSync(dirPath, { recursive: true }); fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK); } } /** * Common retryable model error patterns. */ const RETRYABLE_ERROR_PATTERNS = [ /rate limit/i, /overloaded/i, /timeout/i, /500/i, /502/i, /503/i, /504/i, /connection/i, /network/i, ]; /** * Returns true if the error is likely a transient model/provider failure. */ export function isRetryableModelFailure(error: unknown): boolean { const message = error instanceof Error ? error.message : String(error); return RETRYABLE_ERROR_PATTERNS.some((pattern) => pattern.test(message)); }