Skip to content

Commit 86aad3f

Browse files
committed
fix(search): keep partial coverage through persisted search compaction
compactRetrievalCitations kept only citations, dropping data.retrieval, and stripToolResultOutput applies it on both save and load. A reloaded timed-out search with no matches therefore rendered "No results", which the live UI and the tool itself deliberately avoid because partial results cannot establish absence. Compaction now keeps a bounded retrieval: { status: 'partial' } marker (never the full retrieval object), and re-compacting compacted output keeps it. Complete searches compact exactly as before.
1 parent 8b603d5 commit 86aad3f

4 files changed

Lines changed: 84 additions & 2 deletions

File tree

‎apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/search-activity.test.tsx‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { act } from 'react'
33
import { createRoot, type Root } from 'react-dom/client'
44
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
5+
import { compactRetrievalCitations } from '@/lib/mothership/chat/retrieval-citations'
56
import { MainAgentActivity } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/main-agent-activity'
67
import { ToolCallItem } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item'
78
import type { ToolCallData } from '@/app/workspace/[workspaceId]/home/types'
@@ -311,6 +312,26 @@ describe('search in shared tool activity', () => {
311312
expect(container.textContent).not.toContain('No results')
312313
})
313314

315+
function renderReloadedEmptySearch(status: 'partial' | 'complete') {
316+
const output = compactRetrievalCitations('search_workspace', {
317+
success: true,
318+
data: { results: [], retrieval: { status, timedOutLegs: [] } },
319+
})
320+
render([{ ...tool, status: 'success', result: { success: true, output } }])
321+
}
322+
323+
it('never claims no results for a reloaded partial empty search', () => {
324+
renderReloadedEmptySearch('partial')
325+
expect(header()).toBeNull()
326+
expect(container.textContent).not.toContain('No results')
327+
})
328+
329+
it('still reports no results for a reloaded complete empty search', () => {
330+
renderReloadedEmptySearch('complete')
331+
expand()
332+
expect(container.textContent).toContain('No results')
333+
})
334+
314335
it('preserves available source matches when retrieval is partial', () => {
315336
const search = completedSearch('partial', 'Available matches')
316337
const output = search.result!.output as { data: Record<string, unknown> }

‎apps/sim/lib/mothership/chat/persisted-message.test.ts‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,43 @@ describe('persisted-message', () => {
561561
})
562562

563563
describe('stripToolResultOutput', () => {
564+
it('keeps the partial-coverage marker of an empty search through save and reload', () => {
565+
const message: PersistedMessage = {
566+
id: 'msg-search',
567+
role: 'assistant',
568+
content: '',
569+
timestamp: '2026-01-01T00:00:00.000Z',
570+
contentBlocks: [
571+
{
572+
type: 'tool',
573+
phase: 'call',
574+
toolCall: {
575+
id: 'search',
576+
name: 'search_workspace',
577+
state: 'success',
578+
result: {
579+
success: true,
580+
output: {
581+
success: true,
582+
data: {
583+
query: 'q',
584+
results: [],
585+
retrieval: { status: 'partial', timedOutLegs: ['vector'] },
586+
},
587+
},
588+
},
589+
},
590+
},
591+
],
592+
}
593+
const reloaded = stripToolResultOutput(stripToolResultOutput(message))
594+
595+
expect(reloaded.contentBlocks?.[0].toolCall?.result?.output).toEqual({
596+
success: true,
597+
data: { results: [], retrieval: { status: 'partial' } },
598+
})
599+
})
600+
564601
it('drops result.output but keeps success and error', () => {
565602
const message: PersistedMessage = {
566603
id: 'msg-1',

‎apps/sim/lib/mothership/chat/retrieval-citations.test.ts‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,21 @@ describe('persisted retrieval citations', () => {
3333
})
3434
).toBeUndefined()
3535
})
36+
it('keeps only a partial-coverage marker, and keeps it through re-compaction', () => {
37+
const compact = compactRetrievalCitations('search_workspace', {
38+
success: true,
39+
data: { results: [], retrieval: { status: 'partial', timedOutLegs: ['vector', 'keyword'] } },
40+
})
41+
expect(compact).toEqual({
42+
success: true,
43+
data: { results: [], retrieval: { status: 'partial' } },
44+
})
45+
expect(compactRetrievalCitations('search_workspace', compact)).toEqual(compact)
46+
expect(
47+
compactRetrievalCitations('search_workspace', {
48+
success: true,
49+
data: { results: [], retrieval: { status: 'complete', timedOutLegs: [] } },
50+
})
51+
).toEqual({ success: true, data: { results: [] } })
52+
})
3653
})

‎apps/sim/lib/mothership/chat/retrieval-citations.ts‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { isRecordLike } from '@sim/utils/object'
22

3-
/** Keeps only bounded display evidence when large retrieval results leave the live stream. */
3+
/**
4+
* Keeps only bounded display evidence when large retrieval results leave the live stream,
5+
* plus a partial-coverage marker so an empty timed-out search never reads as "No results".
6+
*/
47
export function compactRetrievalCitations(toolName: string, raw: unknown): unknown {
58
if (!['search_workspace', 'read_document'].includes(toolName)) return undefined
69
let output: unknown = raw
@@ -43,5 +46,9 @@ export function compactRetrievalCitations(toolName: string, raw: unknown): unkno
4346
}
4447
return [citation]
4548
})
46-
return { success: true, data: { results: citations } }
49+
const partial = isRecordLike(data.retrieval) && data.retrieval.status === 'partial'
50+
return {
51+
success: true,
52+
data: { results: citations, ...(partial ? { retrieval: { status: 'partial' } } : {}) },
53+
}
4754
}

0 commit comments

Comments
 (0)