From 141a6af4f78c9da968f70c4f2b52e9a44facfdac Mon Sep 17 00:00:00 2001 From: MauritsBrinkman Date: Thu, 12 Jun 2025 15:25:57 +0100 Subject: [PATCH] feat(react): add initialValues option to useStream for cached thread display Add initialValues parameter to UseStreamOptions to enable immediate display of cached thread data while official history is being fetched from the server. This addresses the common use case where applications cache thread data locally (IndexedDB, localStorage, etc.) and want to show it instantly when users navigate to existing threads, providing better UX with faster loading. Key changes: - Add initialValues?: Partial | null to UseStreamOptions interface - Update values precedence: streamValues > initialValues > historyValues - Ensure optimisticValues properly override initialValues during submission - Maintain full backward compatibility with existing API Example usage: ```typescript const stream = useStream({ threadId, assistantId: 'my-assistant', initialValues: cachedThreadData?.values // Show cached data immediately }); ``` The values flow now follows this priority: 1. Initial load: shows initialValues while history loads 2. During submit: optimisticValues take precedence 3. After server response: official history replaces all --- libs/sdk-js/src/react/stream.tsx | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/libs/sdk-js/src/react/stream.tsx b/libs/sdk-js/src/react/stream.tsx index f4bd54cf5..73288dc54 100644 --- a/libs/sdk-js/src/react/stream.tsx +++ b/libs/sdk-js/src/react/stream.tsx @@ -530,6 +530,17 @@ export interface UseStreamOptions< /** Will reconnect the stream on mount */ reconnectOnMount?: boolean | (() => RunMetadataStorage); + + /** + * Initial values to display immediately when loading a thread. + * Useful for displaying cached thread data while official history loads. + * These values will be replaced when official thread data is fetched. + * + * Note: UI components from initialValues will render immediately if they're + * predefined in LoadExternalComponent's components prop, providing instant + * cached UI display without server fetches. + */ + initialValues?: Partial | null; } interface RunMetadataStorage { @@ -925,7 +936,8 @@ export function useStream< } setStreamValues((streamValues) => { - const values = { ...historyValues, ...streamValues }; + const baseValues = options.initialValues ? { ...historyValues, ...options.initialValues } : historyValues; + const values = { ...baseValues, ...streamValues }; // Assumption: we're concatenating the message const messages = getMessages(values).slice(); @@ -1004,18 +1016,18 @@ export function useStream< // Assumption: we're setting the initial value // Used for instant feedback setStreamValues(() => { - const values = { ...historyValues }; + const baseValues = options.initialValues ? { ...historyValues, ...options.initialValues } : historyValues; if (submitOptions?.optimisticValues != null) { return { - ...values, + ...baseValues, ...(typeof submitOptions.optimisticValues === "function" - ? submitOptions.optimisticValues(values) + ? submitOptions.optimisticValues(baseValues) : submitOptions.optimisticValues), }; } - return values; + return baseValues; }); let usableThreadId = threadId; @@ -1116,7 +1128,7 @@ export function useStream< }, [reconnectKey]); const error = streamError ?? historyError; - const values = streamValues ?? historyValues; + const values = streamValues ?? (options.initialValues ? { ...historyValues, ...options.initialValues } : historyValues); return { get values() {