ui: rendering performance follow-up (#26097)

This commit is contained in:
Aleksander Grygier
2026-07-28 17:13:25 +02:00
committed by GitHub
parent ad77bd31a6
commit 6e2bc65fb2
10 changed files with 538 additions and 134 deletions
+35 -5
View File
@@ -155,41 +155,71 @@ function parseChunk(chunk: string): SearchResult | null {
return result;
}
/** Bounded cache for extractSearchResults results. */
const SEARCH_RESULTS_CACHE_MAX_SIZE = 32;
const searchResultsCache = new Map<string, SearchResult[]>();
/**
* Extract a SearchResult[] from a tool-result string. Returns `[]` when
* the input does not match the expected shape — useful for branching
* between dedicated search-results rendering and the generic tool-call
* block.
* block. Memoized: called per render during streaming on unchanged
* tool result strings.
*/
export function extractSearchResults(text: string | undefined | null): SearchResult[] {
if (!text) return [];
const cached = searchResultsCache.get(text);
if (cached) return cached;
const results: SearchResult[] = [];
for (const chunk of splitChunks(text)) {
const parsed = parseChunk(chunk);
if (parsed) results.push(parsed);
}
if (searchResultsCache.size >= SEARCH_RESULTS_CACHE_MAX_SIZE) {
searchResultsCache.delete(searchResultsCache.keys().next().value!);
}
searchResultsCache.set(text, results);
return results;
}
/** Bounded cache for extractSearchQuery results. */
const SEARCH_QUERY_CACHE_MAX_SIZE = 32;
const searchQueryCache = new Map<string, string>();
/**
* Best-effort extraction of the search query out of a tool call's JSON
* argument blob. Currently looks for a `query` field (the convention
* used by Exa and most web-search MCP servers); returns an empty string
* if it cannot be located.
* if it cannot be located. Memoized: called per render during streaming
* on unchanged tool args strings.
*/
export function extractSearchQuery(toolArgs: string | undefined | null): string {
if (!toolArgs) return '';
const cached = searchQueryCache.get(toolArgs);
if (cached !== undefined) return cached;
let result = '';
try {
const parsed: unknown = JSON.parse(toolArgs);
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
const candidate = (parsed as Record<string, unknown>)[SEARCH_TOOL_QUERY_FIELD];
if (typeof candidate === 'string') return candidate.trim();
if (typeof candidate === 'string') result = candidate.trim();
}
} catch {
return '';
result = '';
}
return '';
if (searchQueryCache.size >= SEARCH_QUERY_CACHE_MAX_SIZE) {
searchQueryCache.delete(searchQueryCache.keys().next().value!);
}
searchQueryCache.set(toolArgs, result);
return result;
}
/**