Revue : pistes ecartees et source (local/OpenRouter) gardees, historisation pour rejeu, carte verbeuse du conseiller
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
// les autres a /api/services/<domain>/<service>.
|
||||
// =====================================================
|
||||
|
||||
const { status, detail, pistes, rejetees, modelUsed, context } = $input.first().json;
|
||||
const { status, detail, pistes, rejetees, ecartees, source, modelUsed, context } = $input.first().json;
|
||||
|
||||
function stampParis() {
|
||||
const p = new Intl.DateTimeFormat('fr-FR', { timeZone: 'Europe/Paris', day: '2-digit', month: '2-digit',
|
||||
@@ -22,12 +22,17 @@ const setText = (entity, value) => push('input_text', 'set_value', { entity_id:
|
||||
|
||||
setText('input_text.evcs_advisor_status', status + (detail ? `: ${detail}` : ''));
|
||||
setText('input_text.evcs_advisor_last_run', stampParis());
|
||||
setText('input_text.evcs_advisor_model', modelUsed);
|
||||
setText('input_text.evcs_advisor_model', `${modelUsed} (${source === 'openrouter' ? 'OpenRouter, cloud' : 'local Spark'})`);
|
||||
|
||||
if (status === 'ok' && Array.isArray(pistes)) {
|
||||
calls.push({ json: { state_entity: 'sensor.evcs_advisor_revue', data: {
|
||||
state: context.jour,
|
||||
attributes: { friendly_name: 'Revue du conseiller IA', pistes, rejetees, modele: modelUsed,
|
||||
attributes: { friendly_name: 'Revue du conseiller IA', pistes, rejetees, ecartees: ecartees || [], modele: modelUsed,
|
||||
source,
|
||||
source_texte: source === 'openrouter'
|
||||
? 'Repli OpenRouter (cloud) : le modele local de la Spark n a pas repondu, les constats ont ete envoyes a OpenRouter.'
|
||||
: 'Modele local de la Spark : rien n est sorti de la maison.',
|
||||
constats_relus: context.constats.length,
|
||||
avertissement: 'Avis a verifier, pas des faits. Les constats chiffres sont dans sensor.evcs_revue_jour.' },
|
||||
} } });
|
||||
setText('input_text.evcs_advisor_reason',
|
||||
|
||||
@@ -10,9 +10,16 @@
|
||||
const resp = $input.first().json;
|
||||
const context = $('BUILD_PROMPT').first().json.context;
|
||||
|
||||
// QUI A REPONDU (08/10, proprietaire : « OpenRouter, garde-le mais affiche-le
|
||||
// clairement »). Le repli cloud n'est appele que si le modele local de la Spark
|
||||
// echoue ; dans ce cas les constats ont quitte la maison et il faut le dire.
|
||||
const viaCloud = (() => { try { return $('LLM_CLOUD').isExecuted === true; } catch { return false; } })()
|
||||
|| typeof resp?.provider === 'string' || /^gen-/.test(String(resp?.id || ''));
|
||||
const source = viaCloud ? 'openrouter' : 'local';
|
||||
|
||||
function fail(status, detail) {
|
||||
return [{ json: { status, detail: (detail || '').toString().slice(0, 200), pistes: null, rejetees: 0,
|
||||
modelUsed: (resp?.model || 'aucun').toString().slice(0, 60), context } }];
|
||||
return [{ json: { status, detail: (detail || '').toString().slice(0, 200), pistes: null, rejetees: 0, ecartees: [],
|
||||
source, modelUsed: (resp?.model || 'aucun').toString().slice(0, 60), context } }];
|
||||
}
|
||||
|
||||
const content = resp?.choices?.[0]?.message?.content;
|
||||
@@ -36,18 +43,23 @@ if (!Array.isArray(obj.pistes)) return fail('invalid', 'champ pistes absent');
|
||||
const nombres = (s) => (String(s).match(/\d+(?:[.,]\d+)?/g) || []).map((x) => String(Number(x.replace(',', '.'))));
|
||||
|
||||
const parCode = new Map(context.constats.map((c) => [c.code, c]));
|
||||
// Les pistes ECARTEES sont gardees avec leur motif : elles sont historisees
|
||||
// pour rejouer le conseiller plus tard (regression) et juger s'il progresse.
|
||||
const pistes = [];
|
||||
let rejetees = 0;
|
||||
const ecartees = [];
|
||||
const ecarter = (code, piste, motif) => ecartees.push({ code, piste: piste.slice(0, 280), motif });
|
||||
for (const p of obj.pistes) {
|
||||
const code = (p?.code ?? '').toString().trim();
|
||||
const piste = (p?.piste ?? '').toString().trim();
|
||||
const c = parCode.get(code);
|
||||
if (!c || !piste) { rejetees++; continue; }
|
||||
if (!piste) { ecarter(code, '', 'piste vide'); continue; }
|
||||
if (!c) { ecarter(code, piste, 'code inconnu ou constat non a examiner'); continue; }
|
||||
const permis = new Set(nombres(`${c.texte} ${c.contexte}`));
|
||||
if (nombres(piste).some((n) => !permis.has(n))) { rejetees++; continue; }
|
||||
if (pistes.some((x) => x.code === code)) { rejetees++; continue; }
|
||||
const inventes = nombres(piste).filter((n) => !permis.has(n));
|
||||
if (inventes.length) { ecarter(code, piste, `chiffre absent du constat : ${inventes.join(', ')}`); continue; }
|
||||
if (pistes.some((x) => x.code === code)) { ecarter(code, piste, 'doublon'); continue; }
|
||||
pistes.push({ code, piste: piste.slice(0, 280) });
|
||||
}
|
||||
|
||||
return [{ json: { status: 'ok', detail: '', pistes, rejetees,
|
||||
return [{ json: { status: 'ok', detail: '', pistes, rejetees: ecartees.length, ecartees, source,
|
||||
modelUsed: (resp.model || 'inconnu').toString().slice(0, 60), context } }];
|
||||
|
||||
Reference in New Issue
Block a user