Skip to content

Commit 76ff76e

Browse files
committed
fix: report an oversized wire record as an incomplete sync pass
A wire record larger than the pending cap now marks the pass truncated instead of leaving the index reporting ready with an unindexed tail, and a regression test pins the state.
1 parent e75fd62 commit 76ff76e

2 files changed

Lines changed: 17 additions & 2 deletions

File tree

packages/agent-gateway/src/search/indexCore.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ export class SearchIndexCore {
749749
let byteCursor = offset;
750750
let position = offset;
751751
let wireError: unknown;
752+
let pendingOverflow = false;
752753
try {
753754
let pending: Buffer = EMPTY_BUFFER;
754755
let finishing = false;
@@ -802,7 +803,10 @@ export class SearchIndexCore {
802803
pending.length > 0
803804
? Buffer.concat([pending, slice.subarray(start)])
804805
: Buffer.from(slice.subarray(start));
805-
if (pending.length > MAX_WIRE_PENDING_BYTES) break;
806+
if (pending.length > MAX_WIRE_PENDING_BYTES) {
807+
pendingOverflow = true;
808+
break;
809+
}
806810
if (finishing && completedRecord) break;
807811
if (ops.length >= WIRE_BATCH_OPS) {
808812
ops.push({ op: 'set', key: metaKey, value: fileMeta(byteCursor, turnState, stepState) });
@@ -818,7 +822,7 @@ export class SearchIndexCore {
818822
await handle.close();
819823
}
820824

821-
const truncated = position < size && syncBudgetExhausted(budget);
825+
const truncated = pendingOverflow || (position < size && syncBudgetExhausted(budget));
822826
if (byteCursor !== offset || legacyKey !== null) {
823827
ops.push({ op: 'set', key: metaKey, value: fileMeta(byteCursor, turnState, stepState) });
824828
if (legacyKey !== null) ops.push({ op: 'del', key: legacyKey });

packages/agent-gateway/test/search/searchService.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,17 @@ describe('GlobalSearchService', () => {
423423
expect(page.items.length).toBe(2);
424424
expect(page.items.some((h) => h.snippet.includes('appended'))).toBe(true);
425425
});
426+
it('keeps the index incomplete while a wire record exceeds the pending cap', async () => {
427+
const s1 = summary('s1', 'overflow', T1);
428+
const file = await writeWire(home!, 's1', 'main', [userLine('\u82F9\u679C head', T1)]);
429+
await appendFile(file, `{"kind":"step","pad":"${'x'.repeat(5 * 1024 * 1024)}"`, 'utf8');
430+
const service = track(makeService(home!, staticIndex([s1])));
431+
432+
await service.reindex();
433+
const page = await service.search({ query: '\u82F9\u679C' });
434+
expect(page.items.length).toBe(1);
435+
expect(page.indexState.state).not.toBe('ready');
436+
});
426437

427438
it('reports indexState building before the first full sync and ready after', async () => {
428439
const s1 = summary('s1', 'state', T1);

0 commit comments

Comments
 (0)