Skip to content

Commit 8e45a5b

Browse files
committed
fix(tables): keep oversized memory rows pageable
1 parent 352a2fc commit 8e45a5b

2 files changed

Lines changed: 35 additions & 15 deletions

File tree

apps/sim/lib/virtual-tables/memory-virtual-table.server.test.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ describe('Memory virtual table', () => {
333333
expect(result.hasMore).toBe(true)
334334
})
335335

336-
it('rejects a transcript that alone exceeds the query byte budget', async () => {
336+
it('returns bounded metadata without loading a transcript that exceeds the query byte budget', async () => {
337337
const oversized = {
338338
id: 'memory-1',
339339
key: 'conversation-1',
@@ -344,14 +344,24 @@ describe('Memory virtual table', () => {
344344
rowBytes: 5 * 1024 * 1024 + 1,
345345
}
346346
queueTableRows(schemaMock.memory, [oversized])
347-
await expect(
348-
queryMemoryTableRows({
349-
workspaceId: 'workspace-1',
350-
limit: 1000,
351-
includeTotal: false,
352-
})
353-
).rejects.toThrow('Memory transcript exceeds the 5MB table query limit')
347+
const result = await queryMemoryTableRows({
348+
workspaceId: 'workspace-1',
349+
limit: 1000,
350+
includeTotal: false,
351+
})
354352

353+
expect(result.rows).toEqual([
354+
expect.objectContaining({
355+
id: oversized.id,
356+
data: expect.objectContaining({
357+
transcript: {
358+
omitted: true,
359+
reason: 'Transcript exceeds the 5MB table query limit',
360+
},
361+
}),
362+
}),
363+
])
364+
expect(result.hasMore).toBe(false)
355365
expect(dbChainMockFns.select).toHaveBeenCalledTimes(2)
356366
})
357367

apps/sim/lib/virtual-tables/memory-virtual-table.server.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ export async function queryMemoryTableRows({
204204
getMaxPageBytes() ?? TABLE_LIMITS.MAX_QUERY_RESULT_BYTES,
205205
TABLE_LIMITS.MAX_QUERY_RESULT_BYTES
206206
)
207+
const omittedTranscript: JsonValue = {
208+
omitted: true,
209+
reason: `Transcript exceeds the ${Math.floor(pageByteBudget / (1024 * 1024))}MB table query limit`,
210+
}
211+
const oversizedTranscriptIds = new Set<string>()
207212
const selectedCandidates: typeof candidates = []
208213
let selectedBytes = 0
209214
let hasMore = candidates.length === limit
@@ -213,21 +218,24 @@ export async function queryMemoryTableRows({
213218
if (!Number.isFinite(rowBytes) || rowBytes < 0) {
214219
throw new TableQueryValidationError('Memory table returned an invalid row size')
215220
}
221+
let outputRowBytes = rowBytes
216222
if (rowBytes > pageByteBudget) {
217-
throw new TableQueryValidationError(
218-
`Memory transcript exceeds the ${Math.floor(pageByteBudget / (1024 * 1024))}MB table query limit`,
219-
'TABLE_QUERY_RESULT_TOO_LARGE'
223+
oversizedTranscriptIds.add(candidate.id)
224+
outputRowBytes = Buffer.byteLength(
225+
JSON.stringify(mapMemoryRecordToTableRow({ ...candidate, data: omittedTranscript }).data)
220226
)
221227
}
222-
if (selectedCandidates.length > 0 && selectedBytes + rowBytes > pageByteBudget) {
228+
if (selectedCandidates.length > 0 && selectedBytes + outputRowBytes > pageByteBudget) {
223229
hasMore = true
224230
break
225231
}
226232
selectedCandidates.push(candidate)
227-
selectedBytes += rowBytes
233+
selectedBytes += outputRowBytes
228234
}
229235

230-
const selectedIds = selectedCandidates.map((candidate) => candidate.id)
236+
const selectedIds = selectedCandidates
237+
.filter((candidate) => !oversizedTranscriptIds.has(candidate.id))
238+
.map((candidate) => candidate.id)
231239
const transcripts =
232240
selectedIds.length > 0
233241
? await db
@@ -244,7 +252,9 @@ export async function queryMemoryTableRows({
244252
: []
245253
const transcriptById = new Map(transcripts.map((record) => [record.id, record.data]))
246254
const rows = selectedCandidates.flatMap((candidate, index) => {
247-
const transcript = transcriptById.get(candidate.id)
255+
const transcript = oversizedTranscriptIds.has(candidate.id)
256+
? omittedTranscript
257+
: transcriptById.get(candidate.id)
248258
if (transcript === undefined) return []
249259
return [
250260
mapMemoryRecordToTableRow(

0 commit comments

Comments
 (0)