feat(secretary): reconcileTurn прокидывает step в результат
Task 3/5 плана. stampProvenance отдаёт фиксированную форму без step, поэтому reconcileTurn оборачивает результат: finish() прикладывает parsed.step к возвращаемому объекту (транзитно), при отсутствии — поля нет. Свод 111/111. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -275,13 +275,15 @@ export async function reconcileTurn({ proto, ex, turn, session, callModel, diag
|
||||
catch (e) { report({ reason: 'model-threw', error: String((e && e.message) || e) }); return null; }
|
||||
const parsed = parseReconcileResponse(typeof text === 'string' ? text : '');
|
||||
if (!parsed) { report({ reason: 'bad-json' }); return null; } // кривой JSON — прежний протокол цел
|
||||
const step = parsed.step || null;
|
||||
const finish = (p) => { const out = collapseProtocol(p); return step ? { ...out, step } : out; };
|
||||
const returned = collapseProtocol(parsed);
|
||||
const guard = reconcileGuard(clean, returned);
|
||||
if (guard.ok) return collapseProtocol(stampProvenance(clean, returned, turn, session));
|
||||
if (guard.ok) return finish(stampProvenance(clean, returned, turn, session));
|
||||
// Потеряны строки → НЕ выкидываем ход: возвращаем пропавшие старые строки на место (модель-агностично).
|
||||
// Что модель уронила — хук вернул; что обновила (закрыла вопрос, добавила решение) — сохранено.
|
||||
report({ reason: 'guard-restored', lost: guard.lost });
|
||||
return collapseProtocol(stampProvenance(clean, restoreLostLines(clean, returned), turn, session));
|
||||
return finish(stampProvenance(clean, restoreLostLines(clean, returned), turn, session));
|
||||
}
|
||||
|
||||
/** Протокол к записи независимо от исхода reconcile: при успехе база — updated, при срыве —
|
||||
|
||||
@@ -164,6 +164,14 @@ describe('reconcileTurn', () => {
|
||||
expect(out).toBeNull();
|
||||
expect(n).toBe(1);
|
||||
});
|
||||
it('проброс step из ответа модели в результат; без step — поля нет', async () => {
|
||||
const withStep = async () => '{ "subject":"дело", "decisions":[{"text":"A","struck":false}], "open":[{"text":"Q?","struck":true}], "will":[], "doneNext":[], "step":{"user":"u","assistant":"a"} }';
|
||||
const r1 = await reconcileTurn({ proto, ex, turn: 5, session: 's1', callModel: withStep });
|
||||
expect(r1.step).toEqual({ user: 'u', assistant: 'a' });
|
||||
const noStep = async () => '{ "subject":"дело", "decisions":[{"text":"A","struck":false}], "open":[{"text":"Q?","struck":true}], "will":[], "doneNext":[] }';
|
||||
const r2 = await reconcileTurn({ proto, ex, turn: 5, session: 's1', callModel: noStep });
|
||||
expect(r2.step).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
import { mergeTurnIntoProtocol, formatReconcileLogLine, restoreLostLines, collapseProtocol } from './secretary-reconcile.mjs';
|
||||
|
||||
Reference in New Issue
Block a user