import test from 'node:test'; import assert from 'node:assert'; import { safeImport } from '../_helpers/path.js'; import { MockLLMManager } from '../_helpers/mockLLMManager.js'; import { AutoReporter } from '../reporters/AutoReporter.js'; // Auto-Reporter Configuration const autoReporter = new AutoReporter(); test('LLM transient error is retried or bubbled cleanly', async () => { const mgrRes = safeImport('LLMManager'); if (!mgrRes.ok || typeof mgrRes.mod.callModel !== 'function') { console.warn('[SKIP] LLMManager.callModel missing'); return; } // On teste la nôtre (mock) pour vérifier le comportement désiré, // puis on appelle la “vraie” et on vérifie au moins la remontée d’erreur propre. const mock = new MockLLMManager({ failTimes: 2, failCode: 429 }); const ok = await mock.callModel({ input:'test' }).catch(e => e); // après 2 fails, la troisième doit passer: const ok2 = await mock.callModel({ input:'test 2' }); assert.ok(ok2.completion?.startsWith('MOCK')); // Vraie impl: au minimum, qu’elle throw une Error avec statusCode si pas de retry let threw = false; try { await mgrRes.mod.callModel({ provider:'X', model:'Y', input:'Z', __forceFail429:true }); } catch (e) { threw = true; // Pas obligatoire d’avoir statusCode, mais on log si présent if (e?.statusCode) { assert.ok([429,500,502,503,504].includes(e.statusCode)); } } assert.ok(threw, 'real callModel should throw or handle gracefully when forced to fail'); });