diff --git a/lib/app/distill-run.js b/lib/app/distill-run.js index f1d6fab..32e5372 100644 --- a/lib/app/distill-run.js +++ b/lib/app/distill-run.js @@ -96,16 +96,16 @@ async function keptResult(ports, claimed, result) { } // A session file that cannot be read costs the distillation its lineage, never the distillation itself. -async function reusedAssetIdsIn(ports, { sessionId, range }) { +async function reusedAssetIdsIn(ports, { sessionId, range }, session) { try { - return reusedAssetIdsOf(sessionOf(await ports.sessions.read(sessionId)), range); + return reusedAssetIdsOf(sessionOf(await ports.sessions.read(sessionId)), { ...range, turns: session.turns }); } catch { return []; } } async function posted(ports, claimed, session, { irs, usage, signal }) { - const reusedAssetIds = await reusedAssetIdsIn(ports, claimed); + const reusedAssetIds = await reusedAssetIdsIn(ports, claimed, session); const bodies = distillBodiesOf({ platform: ports.identity.agent, sessionId: taskSessionId(ports.identity, claimed.sessionId), trigger: claimed.trigger, session, irs, usage, reusedAssetIds }); const results = []; for (const body of bodies) { diff --git a/test/app/distill-session.test.js b/test/app/distill-session.test.js index 0b01792..457068b 100644 --- a/test/app/distill-session.test.js +++ b/test/app/distill-session.test.js @@ -108,6 +108,25 @@ test('a distillation names only the assets injected into the turns it read', asy assert.deepEqual(body.reused_asset_ids, [ASSET.asset_id]); }); +test('a fitted distillation names only assets from the turns the model still reads', async () => { + const lastAsset = { ...ASSET, asset_id: 'sha256:' + '1'.repeat(64), short_title: 'Weather lookups', signals_match: ['weather'] }; + const made = memoryPorts({ assets: [ASSET, lastAsset], distillAnswer: DRAFTED, model: modelAnswering(IR) }); + const steps = [ + ...Array.from({ length: 56 }, (_, index) => ['run', `fixture-command-${index} ${'x'.repeat(940)}`]), + ['pass', 'npm test'], + ]; + for (let turn = 1; turn <= 8; turn++) { + await turnOf(made.ports, 's1', { steps, ...(turn === 8 && { prompt: 'what is the weather like' }) }); + } + await endedAndDistilled(made); + const [{ body }] = distills(made.requests); + const turns = body.record.filter(({ kind }) => kind === 'turn').map(({ text }) => text); + assert.ok(!turns.includes('Turn 1'), 'the oldest work was cut to meet the Proxy body limit'); + assert.ok(turns.includes('Turn 8')); + assert.deepEqual(body.reused_asset_ids, [lastAsset.asset_id]); + assert.ok(bytesOf(body) <= 256 * 1024); +}); + test('a session ledger that cannot be read leaves out the reused assets, never the distillation', async () => { const made = await fixedSession({ model: modelAnswering(IR) }); await sessionEnded(made.ports, { sessionId: 's1', projectDir: '/proj' });