Skip to content

Commit d5610a4

Browse files
ouiliameclaude
andcommitted
docs: harden Ask AI retrieval + fix stale loading state
- searchDocs: wrap the keyword query in try/catch too, so each retrieval path (keyword, vector) is independent best-effort - ask-ai: gate the loading ellipsis to the in-progress (last) message so older empty bubbles don't re-show it while a later request streams Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 3066d06 commit d5610a4

2 files changed

Lines changed: 21 additions & 12 deletions

File tree

apps/docs/app/api/chat/route.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -216,16 +216,23 @@ type SearchRow = {
216216
async function searchDocs(query: string, locale: string) {
217217
const tsConfig = TS_CONFIG[locale] ?? 'simple'
218218

219-
const keywordRows = await db
220-
.select(SEARCH_COLUMNS)
221-
.from(docsEmbeddings)
222-
.where(
223-
sql`${docsEmbeddings.chunkTextTsv} @@ plainto_tsquery(${tsConfig}, ${query}) and ${localeFilter(locale)}`
224-
)
225-
.orderBy(
226-
sql`ts_rank(${docsEmbeddings.chunkTextTsv}, plainto_tsquery(${tsConfig}, ${query})) DESC`
227-
)
228-
.limit(SEARCH_CANDIDATES)
219+
// Each retrieval path is best-effort and independent: a failure in one still
220+
// lets the other ground the answer (both empty just yields no grounding).
221+
let keywordRows: SearchRow[] = []
222+
try {
223+
keywordRows = await db
224+
.select(SEARCH_COLUMNS)
225+
.from(docsEmbeddings)
226+
.where(
227+
sql`${docsEmbeddings.chunkTextTsv} @@ plainto_tsquery(${tsConfig}, ${query}) and ${localeFilter(locale)}`
228+
)
229+
.orderBy(
230+
sql`ts_rank(${docsEmbeddings.chunkTextTsv}, plainto_tsquery(${tsConfig}, ${query})) DESC`
231+
)
232+
.limit(SEARCH_CANDIDATES)
233+
} catch (error) {
234+
console.error('Ask AI keyword search failed:', error)
235+
}
229236

230237
let vectorRows: SearchRow[] = []
231238
if (locale === DEFAULT_LOCALE) {

apps/docs/components/ai/ask-ai.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ export function AskAI({ locale }: AskAIProps) {
118118
</p>
119119
)}
120120

121-
{messages.map((message) => {
121+
{messages.map((message, index) => {
122122
const text = getText(message.parts)
123+
// Only the in-progress (last) message should show the loading state.
124+
const isStreaming = isBusy && index === messages.length - 1
123125
const sources = message.role === 'assistant' ? getSources(message.parts) : []
124126
return (
125127
<div
@@ -139,7 +141,7 @@ export function AskAI({ locale }: AskAIProps) {
139141
<Streamdown className='space-y-2 text-sm leading-relaxed [&_a]:text-[var(--text-link)] [&_a]:underline [&_li]:my-0.5 [&_ol]:list-decimal [&_ol]:pl-5 [&_ul]:list-disc [&_ul]:pl-5'>
140142
{text}
141143
</Streamdown>
142-
) : isBusy ? (
144+
) : isStreaming ? (
143145
'…'
144146
) : sources.length === 0 ? (
145147
<span className='text-[var(--text-muted)]'>No answer returned.</span>

0 commit comments

Comments
 (0)