Skip to content

Commit a7bd5ee

Browse files
Waleed Latifclaude
andcommitted
fix(search): never fail a knowledge query over a citation decision
Whether to ask for a citation is answered by a billing-backed availability lookup, and it sat in the same `Promise.all` as the search itself — so a rejection there discarded a search that had already succeeded and returned "Failed to query knowledge base". A presentation choice could take out the query it decorates. Settle it to "do not cite" instead — the same answer the feature being off gives — and log why, so the lookup failing is visible without being fatal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014JmUGTitFeoQXVf9T3skEa
1 parent 991feb9 commit a7bd5ee

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

apps/sim/lib/copilot/tools/server/knowledge/knowledge-base.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,18 @@ describe('manage_knowledge_base trusted application delegation', () => {
437437
expect(result.message).toBe('Found 0 result(s) for query "query".')
438438
})
439439

440+
it('answers without citations when the eligibility lookup fails, rather than failing the query', async () => {
441+
mockIsKnowledgeMemberAccessAvailable.mockRejectedValueOnce(new Error('billing unavailable'))
442+
443+
const result = await knowledgeBaseServerTool.execute(
444+
{ operation: 'query', args: { knowledgeBaseId: KNOWLEDGE_BASE.id, query: 'query' } },
445+
{ ...CONTEXT, resolvedSecretTraceRegistry: new ResolvedSecretTraceRegistry() }
446+
)
447+
448+
expect(result).toMatchObject({ success: true })
449+
expect(result.message).toBe('Found 0 result(s) for query "query".')
450+
})
451+
440452
it('returns a safe model result for search infrastructure failures', async () => {
441453
mockSearchKnowledge.mockRejectedValueOnce(new Error('database unavailable'))
442454

apps/sim/lib/copilot/tools/server/knowledge/knowledge-base.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,20 @@ export const knowledgeBaseServerTool: BaseServerTool<KnowledgeBaseArgs, Knowledg
451451
topK,
452452
resultSecretRegistry: context.resolvedSecretTraceRegistry,
453453
}),
454-
isKnowledgeMemberAccessAvailable({ workspaceId }),
454+
/**
455+
* Whether to ask for a citation is a presentation choice, and it is
456+
* answered by a billing-backed lookup that can reject. A rejection
457+
* must not discard a search that succeeded, so it settles to "do not
458+
* cite" — the same answer the feature being off gives — rather than
459+
* failing the query.
460+
*/
461+
isKnowledgeMemberAccessAvailable({ workspaceId }).catch((error) => {
462+
logger.warn('Citation eligibility unavailable; answering without citations', {
463+
workspaceId,
464+
error: getErrorMessage(error),
465+
})
466+
return false
467+
}),
455468
])
456469
const results = searchResult.results
457470
const knowledgeBase = searchResult.knowledgeBases[0]

0 commit comments

Comments
 (0)