@tambo-ai/react 1.2.7 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.js +8 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js +27 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.test.js +2 -2
- package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.js +8 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js +27 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.test.js +2 -2
- package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/package.json +12 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-suggestions.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC;AACpD,OAAO,KAAK,EACV,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,wDAAwD,CAAC;AAYhE;;GAEG;AACH,KAAK,wBAAwB,GACzB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,EAAE,IAAI,CACjB,eAAe,CAAC,wBAAwB,CAAC,EACzC,UAAU,GAAG,SAAS,GAAG,SAAS,CACnC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,+BAA+B;IAC/B,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;IAC5C,sFAAsF;IACtF,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IAKxC;;;OAGG;IACH,IAAI,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAE3C,mFAAmF;IACnF,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;IAM/C,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;IAEnB,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IAEnB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IAEjB,6CAA6C;IAC7C,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEpB,8EAA8E;IAC9E,UAAU,EAAE,OAAO,CAAC;IAMpB;;;OAGG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAAC;IAE9D,iEAAiE;IACjE,YAAY,EAAE,OAAO,CAAC;IAEtB,gDAAgD;IAChD,aAAa,EAAE,KAAK,GAAG,IAAI,CAAC;IAM5B;;;OAGG;IACH,MAAM,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5D,oDAAoD;IACpD,WAAW,EAAE,OAAO,CAAC;IAErB,gDAAgD;IAChD,WAAW,EAAE,KAAK,GAAG,IAAI,CAAC;IAM1B,8CAA8C;IAC9C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,0BAA+B,GACvC,yBAAyB,
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-suggestions.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC;AACpD,OAAO,KAAK,EACV,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,wDAAwD,CAAC;AAYhE;;GAEG;AACH,KAAK,wBAAwB,GACzB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,EAAE,IAAI,CACjB,eAAe,CAAC,wBAAwB,CAAC,EACzC,UAAU,GAAG,SAAS,GAAG,SAAS,CACnC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,+BAA+B;IAC/B,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;IAC5C,sFAAsF;IACtF,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IAKxC;;;OAGG;IACH,IAAI,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAE3C,mFAAmF;IACnF,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;IAM/C,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;IAEnB,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IAEnB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IAEjB,6CAA6C;IAC7C,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEpB,8EAA8E;IAC9E,UAAU,EAAE,OAAO,CAAC;IAMpB;;;OAGG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAAC;IAE9D,iEAAiE;IACjE,YAAY,EAAE,OAAO,CAAC;IAEtB,gDAAgD;IAChD,aAAa,EAAE,KAAK,GAAG,IAAI,CAAC;IAM5B;;;OAGG;IACH,MAAM,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5D,oDAAoD;IACpD,WAAW,EAAE,OAAO,CAAC;IAErB,gDAAgD;IAChD,WAAW,EAAE,KAAK,GAAG,IAAI,CAAC;IAM1B,8CAA8C;IAC9C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,0BAA+B,GACvC,yBAAyB,CAmO3B"}
|
|
@@ -66,6 +66,9 @@ function useTamboSuggestions(options = {}) {
|
|
|
66
66
|
const latestMessage = messages[messages.length - 1];
|
|
67
67
|
const isLatestFromAssistant = latestMessage?.role === "assistant";
|
|
68
68
|
const latestMessageId = latestMessage?.id;
|
|
69
|
+
// Ephemeral ids (e.g. reasoning placeholders) are never persisted server-side,
|
|
70
|
+
// so suggestion requests against them can only ever 404.
|
|
71
|
+
const isEphemeralMessageId = latestMessageId?.startsWith("ephemeral_") ?? false;
|
|
69
72
|
// Reset selected suggestion when the message changes
|
|
70
73
|
(0, react_1.useEffect)(() => {
|
|
71
74
|
setSelectedSuggestionId(null);
|
|
@@ -73,6 +76,7 @@ function useTamboSuggestions(options = {}) {
|
|
|
73
76
|
// Determine if we should fetch/generate suggestions
|
|
74
77
|
const shouldFetchSuggestions = currentThreadId &&
|
|
75
78
|
latestMessageId &&
|
|
79
|
+
!isEphemeralMessageId &&
|
|
76
80
|
isLatestFromAssistant &&
|
|
77
81
|
isIdle &&
|
|
78
82
|
autoGenerate;
|
|
@@ -115,7 +119,10 @@ function useTamboSuggestions(options = {}) {
|
|
|
115
119
|
// Mutation to manually generate suggestions
|
|
116
120
|
const generateMutation = (0, react_query_hooks_1.useTamboMutation)({
|
|
117
121
|
mutationFn: async () => {
|
|
118
|
-
if (!currentThreadId ||
|
|
122
|
+
if (!currentThreadId ||
|
|
123
|
+
!latestMessageId ||
|
|
124
|
+
isEphemeralMessageId ||
|
|
125
|
+
!isLatestFromAssistant) {
|
|
119
126
|
return undefined;
|
|
120
127
|
}
|
|
121
128
|
const availableComponents = (0, client_1.toAvailableComponents)(componentList);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-suggestions.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * useTamboSuggestions - Suggestions Hook\n *\n * Manages AI-powered suggestions for thread messages.\n * Uses the API endpoints for listing and creating suggestions.\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { UseQueryOptions } from \"@tanstack/react-query\";\nimport type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport type {\n SuggestionCreateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/threads/suggestions\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboQuery, useTamboMutation } from \"../../hooks/react-query-hooks\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboConfig } from \"../providers/tambo-v1-provider\";\nimport { useTambo } from \"./use-tambo-v1\";\nimport { useTamboThreadInput } from \"./use-tambo-v1-thread-input\";\nimport { toAvailableComponents } from \"@tambo-ai/client\";\n\n/**\n * Response type for suggestions queries (union of list and create responses)\n */\ntype SuggestionsQueryResponse =\n | SuggestionListResponse\n | SuggestionCreateResponse;\n\n/**\n * Configuration options for the useTamboSuggestions hook\n */\nexport interface UseTamboSuggestionsOptions {\n /** Maximum number of suggestions to generate (1-10, default 3) */\n maxSuggestions?: number;\n /**\n * Whether to automatically generate suggestions when the latest message is from the assistant.\n * Default: true\n */\n autoGenerate?: boolean;\n /**\n * Additional React Query options for the suggestions query.\n * Allows customizing caching, refetching behavior, etc.\n */\n queryOptions?: Omit<\n UseQueryOptions<SuggestionsQueryResponse>,\n \"queryKey\" | \"queryFn\" | \"enabled\"\n >;\n}\n\n/**\n * Options for accepting a suggestion\n */\nexport interface AcceptSuggestionOptions {\n /** The suggestion to accept */\n suggestion: TamboAI.Beta.Threads.Suggestion;\n /** Whether to automatically submit the suggestion after accepting (default: false) */\n shouldSubmit?: boolean;\n}\n\n/**\n * Return type for useTamboSuggestions hook\n */\nexport interface UseTamboSuggestionsReturn {\n // ---------------------------------------------------------------------------\n // Data (mirrors react-query patterns)\n // ---------------------------------------------------------------------------\n\n /**\n * The raw response data from the suggestions query.\n * Use this for direct access to the API response shape.\n */\n data: SuggestionsQueryResponse | undefined;\n\n /** List of available suggestions for the current message (convenience accessor) */\n suggestions: TamboAI.Beta.Threads.Suggestion[];\n\n // ---------------------------------------------------------------------------\n // Query state (matches react-query UseQueryResult)\n // ---------------------------------------------------------------------------\n\n /** Whether the suggestions query is loading (first fetch) */\n isLoading: boolean;\n\n /** Whether suggestions have been successfully loaded */\n isSuccess: boolean;\n\n /** Whether there was an error loading suggestions */\n isError: boolean;\n\n /** Error from loading suggestions, if any */\n error: Error | null;\n\n /** Whether the query is currently fetching (includes background refetches) */\n isFetching: boolean;\n\n // ---------------------------------------------------------------------------\n // Generate mutation (for manual suggestion generation)\n // ---------------------------------------------------------------------------\n\n /**\n * Manually generate new suggestions for the current message.\n * Use this when autoGenerate is false or to refresh suggestions.\n */\n generate: () => Promise<SuggestionCreateResponse | undefined>;\n\n /** Whether suggestions are being generated (mutation pending) */\n isGenerating: boolean;\n\n /** Error from generating suggestions, if any */\n generateError: Error | null;\n\n // ---------------------------------------------------------------------------\n // Accept mutation (for applying a suggestion)\n // ---------------------------------------------------------------------------\n\n /**\n * Accept and apply a suggestion.\n * Sets the suggestion text as input value, optionally submitting it.\n */\n accept: (options: AcceptSuggestionOptions) => Promise<void>;\n\n /** Whether accepting a suggestion is in progress */\n isAccepting: boolean;\n\n /** Error from accepting a suggestion, if any */\n acceptError: Error | null;\n\n // ---------------------------------------------------------------------------\n // UI state\n // ---------------------------------------------------------------------------\n\n /** ID of the currently selected suggestion */\n selectedSuggestionId: string | null;\n}\n\n/**\n * Hook for managing AI-powered suggestions in a thread.\n *\n * Provides functionality to:\n * - Automatically generate suggestions when an assistant message arrives\n * - Manually generate suggestions on demand\n * - Accept suggestions by setting them as input or auto-submitting\n * @param options - Configuration options\n * @returns Suggestions state and control functions\n * @example\n * ```tsx\n * function SuggestionsPanel() {\n * const {\n * suggestions,\n * accept,\n * isLoading,\n * selectedSuggestionId,\n * } = useTamboSuggestions();\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * {suggestions.map((suggestion) => (\n * <button\n * key={suggestion.id}\n * onClick={() => accept({ suggestion })}\n * className={selectedSuggestionId === suggestion.id ? 'selected' : ''}\n * >\n * {suggestion.title}\n * </button>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useTamboSuggestions(\n options: UseTamboSuggestionsOptions = {},\n): UseTamboSuggestionsReturn {\n const { maxSuggestions = 3, autoGenerate = true, queryOptions } = options;\n\n const client = useTamboClient();\n const { userKey } = useTamboConfig();\n const { componentList } = useTamboRegistry();\n const queryClient = useTamboQueryClient();\n\n const { messages, isIdle, currentThreadId } = useTambo();\n const { setValue: setInputValue, submit } = useTamboThreadInput();\n\n const [selectedSuggestionId, setSelectedSuggestionId] = useState<\n string | null\n >(null);\n\n // Get the latest message info\n const latestMessage = messages[messages.length - 1];\n const isLatestFromAssistant = latestMessage?.role === \"assistant\";\n const latestMessageId = latestMessage?.id;\n\n // Reset selected suggestion when the message changes\n useEffect(() => {\n setSelectedSuggestionId(null);\n }, [latestMessageId]);\n\n // Determine if we should fetch/generate suggestions\n const shouldFetchSuggestions =\n currentThreadId &&\n latestMessageId &&\n isLatestFromAssistant &&\n isIdle &&\n autoGenerate;\n\n const suggestionsQueryKey = [\n \"v1-suggestions\",\n currentThreadId ?? null,\n latestMessageId ?? null,\n ] as const;\n\n // Query to list existing suggestions\n const suggestionsQuery = useTamboQuery({\n queryKey: suggestionsQueryKey,\n queryFn: async (): Promise<SuggestionsQueryResponse> => {\n if (!shouldFetchSuggestions || !latestMessageId || !currentThreadId) {\n return { suggestions: [], hasMore: false };\n }\n\n return await client.threads.suggestions.list(latestMessageId, {\n threadId: currentThreadId,\n userKey,\n });\n },\n ...queryOptions,\n enabled: Boolean(shouldFetchSuggestions),\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n // Retry on 404s to handle the race condition where the assistant message\n // hasn't been persisted to the DB yet when suggestions are requested\n // immediately after a run completes.\n retry: (failureCount, error) => {\n if (failureCount >= 3) return false;\n // Use structural check instead of instanceof to handle duplicate SDK copies\n // where the APIError constructor identity may differ between packages.\n const status =\n typeof error === \"object\" && error !== null && \"status\" in error\n ? (error as { status: unknown }).status\n : undefined;\n return status === 404;\n },\n retryDelay: (attemptIndex) => Math.min(500 * 2 ** attemptIndex, 3000),\n });\n\n // Mutation to manually generate suggestions\n const generateMutation = useTamboMutation({\n mutationFn: async () => {\n if (!currentThreadId || !latestMessageId || !isLatestFromAssistant) {\n return undefined;\n }\n\n const availableComponents = toAvailableComponents(componentList);\n\n return await client.threads.suggestions.create(latestMessageId, {\n threadId: currentThreadId,\n maxSuggestions,\n availableComponents,\n userKey,\n });\n },\n onSuccess: (data) => {\n if (data && currentThreadId && latestMessageId) {\n // Update the query cache with new suggestions\n queryClient.setQueryData(suggestionsQueryKey, data);\n }\n },\n });\n\n const lastAutoGenerateMessageIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n lastAutoGenerateMessageIdRef.current = null;\n }, [latestMessageId]);\n\n const listSuggestionsCount = suggestionsQuery.data?.suggestions.length ?? 0;\n const generateMutate = generateMutation.mutate;\n const isGenerating = generateMutation.isPending;\n const isListError = suggestionsQuery.isError;\n const isListSuccess = suggestionsQuery.isSuccess;\n\n useEffect(() => {\n if (!shouldFetchSuggestions || !latestMessageId) {\n return;\n }\n\n if (listSuggestionsCount > 0) {\n return;\n }\n\n const shouldAutoGenerate =\n (isListSuccess && listSuggestionsCount === 0) || isListError;\n\n if (!shouldAutoGenerate) {\n return;\n }\n\n if (isGenerating) {\n return;\n }\n\n if (lastAutoGenerateMessageIdRef.current === latestMessageId) {\n return;\n }\n\n lastAutoGenerateMessageIdRef.current = latestMessageId;\n generateMutate();\n }, [\n generateMutate,\n isGenerating,\n isListError,\n isListSuccess,\n latestMessageId,\n listSuggestionsCount,\n shouldFetchSuggestions,\n ]);\n\n // Mutation to accept a suggestion\n const acceptMutation = useTamboMutation({\n mutationFn: async ({\n suggestion,\n shouldSubmit = false,\n }: AcceptSuggestionOptions) => {\n const text = suggestion.detailedSuggestion?.trim();\n if (!text) {\n throw new Error(\"Suggestion has no content\");\n }\n\n if (shouldSubmit) {\n // Set value and submit\n setInputValue(text);\n await submit();\n } else {\n // Just set the input value\n setInputValue(text);\n }\n\n setSelectedSuggestionId(suggestion.id);\n },\n });\n\n // Generate callback\n const generateMutateAsync = generateMutation.mutateAsync;\n const generate = useCallback(async () => {\n return await generateMutateAsync();\n }, [generateMutateAsync]);\n\n // Accept callback\n const accept = useCallback(\n async (acceptOptions: AcceptSuggestionOptions) => {\n await acceptMutation.mutateAsync(acceptOptions);\n },\n [acceptMutation],\n );\n\n // Get suggestions from query or mutation result\n const queryData = suggestionsQuery.data;\n const mutationData = generateMutation.data;\n\n // Use mutation data if available (more recent), otherwise query data\n const currentData = mutationData ?? queryData;\n const suggestions = isLatestFromAssistant\n ? (currentData?.suggestions ?? [])\n : [];\n\n return {\n // Data\n data: currentData,\n suggestions,\n\n // Query state (matches react-query patterns)\n isLoading: suggestionsQuery.isLoading,\n isSuccess: suggestionsQuery.isSuccess,\n isError: suggestionsQuery.isError,\n error: suggestionsQuery.error,\n isFetching: suggestionsQuery.isFetching,\n\n // Generate mutation\n generate,\n isGenerating: generateMutation.isPending,\n generateError: generateMutation.error,\n\n // Accept mutation\n accept,\n isAccepting: acceptMutation.isPending,\n acceptError: acceptMutation.error,\n\n // UI state\n selectedSuggestionId,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-suggestions.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * useTamboSuggestions - Suggestions Hook\n *\n * Manages AI-powered suggestions for thread messages.\n * Uses the API endpoints for listing and creating suggestions.\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { UseQueryOptions } from \"@tanstack/react-query\";\nimport type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport type {\n SuggestionCreateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/threads/suggestions\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboQuery, useTamboMutation } from \"../../hooks/react-query-hooks\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboConfig } from \"../providers/tambo-v1-provider\";\nimport { useTambo } from \"./use-tambo-v1\";\nimport { useTamboThreadInput } from \"./use-tambo-v1-thread-input\";\nimport { toAvailableComponents } from \"@tambo-ai/client\";\n\n/**\n * Response type for suggestions queries (union of list and create responses)\n */\ntype SuggestionsQueryResponse =\n | SuggestionListResponse\n | SuggestionCreateResponse;\n\n/**\n * Configuration options for the useTamboSuggestions hook\n */\nexport interface UseTamboSuggestionsOptions {\n /** Maximum number of suggestions to generate (1-10, default 3) */\n maxSuggestions?: number;\n /**\n * Whether to automatically generate suggestions when the latest message is from the assistant.\n * Default: true\n */\n autoGenerate?: boolean;\n /**\n * Additional React Query options for the suggestions query.\n * Allows customizing caching, refetching behavior, etc.\n */\n queryOptions?: Omit<\n UseQueryOptions<SuggestionsQueryResponse>,\n \"queryKey\" | \"queryFn\" | \"enabled\"\n >;\n}\n\n/**\n * Options for accepting a suggestion\n */\nexport interface AcceptSuggestionOptions {\n /** The suggestion to accept */\n suggestion: TamboAI.Beta.Threads.Suggestion;\n /** Whether to automatically submit the suggestion after accepting (default: false) */\n shouldSubmit?: boolean;\n}\n\n/**\n * Return type for useTamboSuggestions hook\n */\nexport interface UseTamboSuggestionsReturn {\n // ---------------------------------------------------------------------------\n // Data (mirrors react-query patterns)\n // ---------------------------------------------------------------------------\n\n /**\n * The raw response data from the suggestions query.\n * Use this for direct access to the API response shape.\n */\n data: SuggestionsQueryResponse | undefined;\n\n /** List of available suggestions for the current message (convenience accessor) */\n suggestions: TamboAI.Beta.Threads.Suggestion[];\n\n // ---------------------------------------------------------------------------\n // Query state (matches react-query UseQueryResult)\n // ---------------------------------------------------------------------------\n\n /** Whether the suggestions query is loading (first fetch) */\n isLoading: boolean;\n\n /** Whether suggestions have been successfully loaded */\n isSuccess: boolean;\n\n /** Whether there was an error loading suggestions */\n isError: boolean;\n\n /** Error from loading suggestions, if any */\n error: Error | null;\n\n /** Whether the query is currently fetching (includes background refetches) */\n isFetching: boolean;\n\n // ---------------------------------------------------------------------------\n // Generate mutation (for manual suggestion generation)\n // ---------------------------------------------------------------------------\n\n /**\n * Manually generate new suggestions for the current message.\n * Use this when autoGenerate is false or to refresh suggestions.\n */\n generate: () => Promise<SuggestionCreateResponse | undefined>;\n\n /** Whether suggestions are being generated (mutation pending) */\n isGenerating: boolean;\n\n /** Error from generating suggestions, if any */\n generateError: Error | null;\n\n // ---------------------------------------------------------------------------\n // Accept mutation (for applying a suggestion)\n // ---------------------------------------------------------------------------\n\n /**\n * Accept and apply a suggestion.\n * Sets the suggestion text as input value, optionally submitting it.\n */\n accept: (options: AcceptSuggestionOptions) => Promise<void>;\n\n /** Whether accepting a suggestion is in progress */\n isAccepting: boolean;\n\n /** Error from accepting a suggestion, if any */\n acceptError: Error | null;\n\n // ---------------------------------------------------------------------------\n // UI state\n // ---------------------------------------------------------------------------\n\n /** ID of the currently selected suggestion */\n selectedSuggestionId: string | null;\n}\n\n/**\n * Hook for managing AI-powered suggestions in a thread.\n *\n * Provides functionality to:\n * - Automatically generate suggestions when an assistant message arrives\n * - Manually generate suggestions on demand\n * - Accept suggestions by setting them as input or auto-submitting\n * @param options - Configuration options\n * @returns Suggestions state and control functions\n * @example\n * ```tsx\n * function SuggestionsPanel() {\n * const {\n * suggestions,\n * accept,\n * isLoading,\n * selectedSuggestionId,\n * } = useTamboSuggestions();\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * {suggestions.map((suggestion) => (\n * <button\n * key={suggestion.id}\n * onClick={() => accept({ suggestion })}\n * className={selectedSuggestionId === suggestion.id ? 'selected' : ''}\n * >\n * {suggestion.title}\n * </button>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useTamboSuggestions(\n options: UseTamboSuggestionsOptions = {},\n): UseTamboSuggestionsReturn {\n const { maxSuggestions = 3, autoGenerate = true, queryOptions } = options;\n\n const client = useTamboClient();\n const { userKey } = useTamboConfig();\n const { componentList } = useTamboRegistry();\n const queryClient = useTamboQueryClient();\n\n const { messages, isIdle, currentThreadId } = useTambo();\n const { setValue: setInputValue, submit } = useTamboThreadInput();\n\n const [selectedSuggestionId, setSelectedSuggestionId] = useState<\n string | null\n >(null);\n\n // Get the latest message info\n const latestMessage = messages[messages.length - 1];\n const isLatestFromAssistant = latestMessage?.role === \"assistant\";\n const latestMessageId = latestMessage?.id;\n // Ephemeral ids (e.g. reasoning placeholders) are never persisted server-side,\n // so suggestion requests against them can only ever 404.\n const isEphemeralMessageId =\n latestMessageId?.startsWith(\"ephemeral_\") ?? false;\n\n // Reset selected suggestion when the message changes\n useEffect(() => {\n setSelectedSuggestionId(null);\n }, [latestMessageId]);\n\n // Determine if we should fetch/generate suggestions\n const shouldFetchSuggestions =\n currentThreadId &&\n latestMessageId &&\n !isEphemeralMessageId &&\n isLatestFromAssistant &&\n isIdle &&\n autoGenerate;\n\n const suggestionsQueryKey = [\n \"v1-suggestions\",\n currentThreadId ?? null,\n latestMessageId ?? null,\n ] as const;\n\n // Query to list existing suggestions\n const suggestionsQuery = useTamboQuery({\n queryKey: suggestionsQueryKey,\n queryFn: async (): Promise<SuggestionsQueryResponse> => {\n if (!shouldFetchSuggestions || !latestMessageId || !currentThreadId) {\n return { suggestions: [], hasMore: false };\n }\n\n return await client.threads.suggestions.list(latestMessageId, {\n threadId: currentThreadId,\n userKey,\n });\n },\n ...queryOptions,\n enabled: Boolean(shouldFetchSuggestions),\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n // Retry on 404s to handle the race condition where the assistant message\n // hasn't been persisted to the DB yet when suggestions are requested\n // immediately after a run completes.\n retry: (failureCount, error) => {\n if (failureCount >= 3) return false;\n // Use structural check instead of instanceof to handle duplicate SDK copies\n // where the APIError constructor identity may differ between packages.\n const status =\n typeof error === \"object\" && error !== null && \"status\" in error\n ? (error as { status: unknown }).status\n : undefined;\n return status === 404;\n },\n retryDelay: (attemptIndex) => Math.min(500 * 2 ** attemptIndex, 3000),\n });\n\n // Mutation to manually generate suggestions\n const generateMutation = useTamboMutation({\n mutationFn: async () => {\n if (\n !currentThreadId ||\n !latestMessageId ||\n isEphemeralMessageId ||\n !isLatestFromAssistant\n ) {\n return undefined;\n }\n\n const availableComponents = toAvailableComponents(componentList);\n\n return await client.threads.suggestions.create(latestMessageId, {\n threadId: currentThreadId,\n maxSuggestions,\n availableComponents,\n userKey,\n });\n },\n onSuccess: (data) => {\n if (data && currentThreadId && latestMessageId) {\n // Update the query cache with new suggestions\n queryClient.setQueryData(suggestionsQueryKey, data);\n }\n },\n });\n\n const lastAutoGenerateMessageIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n lastAutoGenerateMessageIdRef.current = null;\n }, [latestMessageId]);\n\n const listSuggestionsCount = suggestionsQuery.data?.suggestions.length ?? 0;\n const generateMutate = generateMutation.mutate;\n const isGenerating = generateMutation.isPending;\n const isListError = suggestionsQuery.isError;\n const isListSuccess = suggestionsQuery.isSuccess;\n\n useEffect(() => {\n if (!shouldFetchSuggestions || !latestMessageId) {\n return;\n }\n\n if (listSuggestionsCount > 0) {\n return;\n }\n\n const shouldAutoGenerate =\n (isListSuccess && listSuggestionsCount === 0) || isListError;\n\n if (!shouldAutoGenerate) {\n return;\n }\n\n if (isGenerating) {\n return;\n }\n\n if (lastAutoGenerateMessageIdRef.current === latestMessageId) {\n return;\n }\n\n lastAutoGenerateMessageIdRef.current = latestMessageId;\n generateMutate();\n }, [\n generateMutate,\n isGenerating,\n isListError,\n isListSuccess,\n latestMessageId,\n listSuggestionsCount,\n shouldFetchSuggestions,\n ]);\n\n // Mutation to accept a suggestion\n const acceptMutation = useTamboMutation({\n mutationFn: async ({\n suggestion,\n shouldSubmit = false,\n }: AcceptSuggestionOptions) => {\n const text = suggestion.detailedSuggestion?.trim();\n if (!text) {\n throw new Error(\"Suggestion has no content\");\n }\n\n if (shouldSubmit) {\n // Set value and submit\n setInputValue(text);\n await submit();\n } else {\n // Just set the input value\n setInputValue(text);\n }\n\n setSelectedSuggestionId(suggestion.id);\n },\n });\n\n // Generate callback\n const generateMutateAsync = generateMutation.mutateAsync;\n const generate = useCallback(async () => {\n return await generateMutateAsync();\n }, [generateMutateAsync]);\n\n // Accept callback\n const accept = useCallback(\n async (acceptOptions: AcceptSuggestionOptions) => {\n await acceptMutation.mutateAsync(acceptOptions);\n },\n [acceptMutation],\n );\n\n // Get suggestions from query or mutation result\n const queryData = suggestionsQuery.data;\n const mutationData = generateMutation.data;\n\n // Use mutation data if available (more recent), otherwise query data\n const currentData = mutationData ?? queryData;\n const suggestions = isLatestFromAssistant\n ? (currentData?.suggestions ?? [])\n : [];\n\n return {\n // Data\n data: currentData,\n suggestions,\n\n // Query state (matches react-query patterns)\n isLoading: suggestionsQuery.isLoading,\n isSuccess: suggestionsQuery.isSuccess,\n isError: suggestionsQuery.isError,\n error: suggestionsQuery.error,\n isFetching: suggestionsQuery.isFetching,\n\n // Generate mutation\n generate,\n isGenerating: generateMutation.isPending,\n generateError: generateMutation.error,\n\n // Accept mutation\n accept,\n isAccepting: acceptMutation.isPending,\n acceptError: acceptMutation.error,\n\n // UI state\n selectedSuggestionId,\n };\n}\n"]}
|
|
@@ -273,6 +273,33 @@ describe("useTamboSuggestions", () => {
|
|
|
273
273
|
expect(mockListSuggestions).not.toHaveBeenCalled();
|
|
274
274
|
expect(mockCreateSuggestions).not.toHaveBeenCalled();
|
|
275
275
|
});
|
|
276
|
+
it("does not fetch or generate suggestions for ephemeral message ids", async () => {
|
|
277
|
+
jest.mocked(use_tambo_v1_1.useTambo).mockReturnValue({
|
|
278
|
+
messages: [
|
|
279
|
+
{
|
|
280
|
+
id: "ephemeral_cb2decbe-9423-4b09-9ac2-feb385cea075",
|
|
281
|
+
role: "assistant",
|
|
282
|
+
content: [],
|
|
283
|
+
createdAt: "2024-01-01T00:00:00Z",
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
thread: undefined,
|
|
287
|
+
isIdle: true,
|
|
288
|
+
isStreaming: false,
|
|
289
|
+
currentThreadId: "thread_123",
|
|
290
|
+
startNewThread: jest.fn(),
|
|
291
|
+
switchThread: jest.fn(),
|
|
292
|
+
initThread: jest.fn(),
|
|
293
|
+
streamingState: { status: "idle" },
|
|
294
|
+
});
|
|
295
|
+
(0, react_1.renderHook)(() => (0, use_tambo_v1_suggestions_1.useTamboSuggestions)(), {
|
|
296
|
+
wrapper: createWrapper(),
|
|
297
|
+
});
|
|
298
|
+
// Give effects a chance to fire
|
|
299
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
300
|
+
expect(mockListSuggestions).not.toHaveBeenCalled();
|
|
301
|
+
expect(mockCreateSuggestions).not.toHaveBeenCalled();
|
|
302
|
+
});
|
|
276
303
|
it("does not generate suggestions when autoGenerate is false", () => {
|
|
277
304
|
jest.mocked(use_tambo_v1_1.useTambo).mockReturnValue({
|
|
278
305
|
messages: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-suggestions.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { renderHook, act, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { useTamboSuggestions } from \"./use-tambo-v1-suggestions\";\nimport { useTamboThreadInput } from \"./use-tambo-v1-thread-input\";\nimport { useTambo } from \"./use-tambo-v1\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboConfig } from \"../providers/tambo-v1-provider\";\n\n// Mock dependencies\njest.mock(\"./use-tambo-v1-thread-input\", () => ({\n useTamboThreadInput: jest.fn(),\n}));\n\njest.mock(\"./use-tambo-v1\", () => ({\n useTambo: jest.fn(),\n}));\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(() => new QueryClient()),\n}));\n\njest.mock(\"../../providers/tambo-registry-provider\", () => ({\n useTamboRegistry: jest.fn(),\n}));\n\njest.mock(\"../providers/tambo-v1-provider\", () => ({\n useTamboConfig: jest.fn(),\n}));\n\ndescribe(\"useTamboSuggestions\", () => {\n let queryClient: QueryClient;\n const mockSetValue = jest.fn();\n const mockSubmit = jest.fn();\n const mockListSuggestions = jest.fn();\n const mockCreateSuggestions = jest.fn();\n\n const mockSuggestions: TamboAI.Beta.Threads.Suggestion[] = [\n {\n id: \"suggestion_1\",\n messageId: \"msg_1\",\n title: \"What's the weather?\",\n description: \"Ask for today's weather\",\n detailedSuggestion: \"What's the weather like today?\",\n },\n {\n id: \"suggestion_2\",\n messageId: \"msg_1\",\n title: \"Tell me a joke\",\n description: \"Request a funny joke\",\n detailedSuggestion: \"Can you tell me a funny joke?\",\n },\n ];\n\n const mockSuggestionsResponse = {\n suggestions: mockSuggestions,\n hasMore: false,\n nextCursor: undefined,\n };\n\n function createWrapper() {\n return function Wrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n {children}\n </QueryClientProvider>\n );\n };\n }\n\n beforeEach(() => {\n jest.clearAllMocks();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n // Mock useTamboQueryClient to return the test's queryClient\n jest.mocked(useTamboQueryClient).mockReturnValue(queryClient);\n\n // Default mock for config\n jest.mocked(useTamboConfig).mockReturnValue({ userKey: \"user_123\" });\n\n // Default mock for thread input\n jest.mocked(useTamboThreadInput).mockReturnValue({\n value: \"\",\n setValue: mockSetValue,\n submit: mockSubmit,\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n } as any);\n\n // Default mock for useTambo\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n // Default mock for registry\n jest.mocked(useTamboRegistry).mockReturnValue({\n componentList: {},\n toolRegistry: {},\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n onCallUnregisteredTool: undefined,\n registerComponent: jest.fn(),\n unregisterComponent: jest.fn(),\n registerTool: jest.fn(),\n unregisterTool: jest.fn(),\n registerMcpServer: jest.fn(),\n unregisterMcpServer: jest.fn(),\n registerResource: jest.fn(),\n unregisterResource: jest.fn(),\n setResourceSource: jest.fn(),\n } as any);\n\n // Default mock for client - using API structure\n mockListSuggestions.mockResolvedValue({ suggestions: [], hasMore: false });\n mockCreateSuggestions.mockResolvedValue(mockSuggestionsResponse);\n\n jest.mocked(useTamboClient).mockReturnValue({\n threads: {\n suggestions: {\n list: mockListSuggestions,\n create: mockCreateSuggestions,\n },\n },\n } as any);\n });\n\n describe(\"Initial State\", () => {\n it(\"returns empty suggestions when thread has placeholder ID\", () => {\n // Mock useTambo to return placeholder thread ID\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"placeholder\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n expect(result.current.selectedSuggestionId).toBeNull();\n expect(result.current.isLoading).toBe(false);\n });\n\n it(\"returns empty suggestions when no messages\", () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n\n it(\"returns empty suggestions when latest message is from user\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"user\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n });\n });\n\n describe(\"Suggestion Generation\", () => {\n it(\"generates suggestions when latest message is from assistant and thread is idle\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n // Should first call list, then create since list returns empty\n expect(mockListSuggestions).toHaveBeenCalledWith(\"msg_1\", {\n threadId: \"thread_123\",\n userKey: \"user_123\",\n });\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({\n threadId: \"thread_123\",\n maxSuggestions: 3,\n userKey: \"user_123\",\n }),\n );\n });\n\n it(\"returns existing suggestions from list without calling create\", async () => {\n mockListSuggestions.mockResolvedValue(mockSuggestionsResponse);\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n expect(mockListSuggestions).toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"does not generate suggestions when thread is streaming\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: false,\n isStreaming: true,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"streaming\", runId: \"run_1\" },\n } as any);\n\n renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(mockListSuggestions).not.toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"does not generate suggestions when autoGenerate is false\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n renderHook(() => useTamboSuggestions({ autoGenerate: false }), {\n wrapper: createWrapper(),\n });\n\n expect(mockListSuggestions).not.toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"uses custom maxSuggestions option\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(\n () => useTamboSuggestions({ maxSuggestions: 5 }),\n { wrapper: createWrapper() },\n );\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({ maxSuggestions: 5 }),\n );\n });\n });\n\n describe(\"Accepting Suggestions\", () => {\n it(\"updates input value when accepting without submit\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n const suggestion = result.current.suggestions[0];\n\n await act(async () => {\n await result.current.accept({ suggestion });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\n \"What's the weather like today?\",\n );\n expect(mockSubmit).not.toHaveBeenCalled();\n expect(result.current.selectedSuggestionId).toBe(\"suggestion_1\");\n });\n\n it(\"submits when accepting with shouldSubmit=true\", async () => {\n mockSubmit.mockResolvedValue({ threadId: \"thread_123\" });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n const suggestion = result.current.suggestions[0];\n\n await act(async () => {\n await result.current.accept({ suggestion, shouldSubmit: true });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\n \"What's the weather like today?\",\n );\n expect(mockSubmit).toHaveBeenCalled();\n });\n\n it(\"throws error when suggestion has no content\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const emptySuggestion = {\n id: \"empty_suggestion\",\n messageId: \"msg_1\",\n title: \"Empty\",\n detailedSuggestion: \"\",\n };\n\n await expect(\n result.current.accept({ suggestion: emptySuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n\n it(\"throws error when detailedSuggestion is only whitespace\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const whitespaceSuggestion = {\n id: \"whitespace_suggestion\",\n messageId: \"msg_1\",\n title: \"Whitespace\",\n detailedSuggestion: \" \",\n };\n\n await expect(\n result.current.accept({ suggestion: whitespaceSuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n\n it(\"throws error when detailedSuggestion is undefined\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const undefinedSuggestion = {\n id: \"undefined_suggestion\",\n messageId: \"msg_1\",\n title: \"Undefined\",\n };\n\n await expect(\n result.current.accept({ suggestion: undefinedSuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n });\n\n describe(\"State Management\", () => {\n it(\"resets selectedSuggestionId when message changes\", async () => {\n const mockUseTambo = jest.mocked(useTambo);\n\n mockUseTambo.mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result, rerender } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n // Accept a suggestion\n await act(async () => {\n await result.current.accept({\n suggestion: result.current.suggestions[0],\n });\n });\n\n expect(result.current.selectedSuggestionId).toBe(\"suggestion_1\");\n\n // Change the latest message\n mockUseTambo.mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n {\n id: \"msg_2\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:01Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n rerender();\n\n await waitFor(() => {\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n });\n\n it(\"includes pagination info on raw data\", async () => {\n mockListSuggestions.mockResolvedValue({\n suggestions: mockSuggestions,\n hasMore: true,\n nextCursor: \"cursor_abc\",\n });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.data?.hasMore).toBe(true);\n expect(result.current.data?.nextCursor).toBe(\"cursor_abc\");\n });\n });\n\n it(\"exposes loading and error states\", () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.isLoading).toBeDefined();\n expect(result.current.isSuccess).toBeDefined();\n expect(result.current.isError).toBeDefined();\n expect(result.current.error).toBeDefined();\n expect(result.current.isAccepting).toBe(false);\n expect(result.current.isGenerating).toBe(false);\n });\n });\n\n describe(\"Retry on 404\", () => {\n it(\"retries list query on 404 and succeeds on subsequent attempt\", async () => {\n // Use a plain object with status to verify structural check works\n // (simulates duplicate SDK copy where instanceof would fail)\n const notFoundError = Object.assign(new Error(\"Message not found\"), {\n status: 404,\n });\n\n // First call: 404, second call: success with empty suggestions\n mockListSuggestions\n .mockRejectedValueOnce(notFoundError)\n .mockResolvedValueOnce({ suggestions: [], hasMore: false });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n // Should eventually succeed after retry and trigger auto-generate\n await waitFor(() => {\n expect(mockListSuggestions).toHaveBeenCalledTimes(2);\n });\n\n // After successful list (empty), auto-generate fires\n await waitFor(() => {\n expect(mockCreateSuggestions).toHaveBeenCalled();\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n });\n\n it(\"does not retry on non-404 errors\", async () => {\n const serverError = Object.assign(new Error(\"Internal server error\"), {\n status: 500,\n });\n\n mockListSuggestions.mockRejectedValue(serverError);\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n // Wait for the query to settle - 500 errors should not be retried\n await waitFor(() => {\n expect(mockListSuggestions).toHaveBeenCalledTimes(1);\n });\n\n // Give it a moment to ensure no additional retries happen\n await new Promise((resolve) => setTimeout(resolve, 100));\n expect(mockListSuggestions).toHaveBeenCalledTimes(1);\n });\n });\n\n describe(\"Manual Generation\", () => {\n it(\"allows manual generation via generate function\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(\n () => useTamboSuggestions({ autoGenerate: false }),\n { wrapper: createWrapper() },\n );\n\n // No auto-generation\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n\n // Manual generation\n await act(async () => {\n await result.current.generate();\n });\n\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({\n threadId: \"thread_123\",\n }),\n );\n });\n\n it(\"returns undefined from generate when no assistant message\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n let generateResult: any;\n await act(async () => {\n generateResult = await result.current.generate();\n });\n\n expect(generateResult).toBeUndefined();\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-suggestions.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { renderHook, act, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { useTamboSuggestions } from \"./use-tambo-v1-suggestions\";\nimport { useTamboThreadInput } from \"./use-tambo-v1-thread-input\";\nimport { useTambo } from \"./use-tambo-v1\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboConfig } from \"../providers/tambo-v1-provider\";\n\n// Mock dependencies\njest.mock(\"./use-tambo-v1-thread-input\", () => ({\n useTamboThreadInput: jest.fn(),\n}));\n\njest.mock(\"./use-tambo-v1\", () => ({\n useTambo: jest.fn(),\n}));\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(() => new QueryClient()),\n}));\n\njest.mock(\"../../providers/tambo-registry-provider\", () => ({\n useTamboRegistry: jest.fn(),\n}));\n\njest.mock(\"../providers/tambo-v1-provider\", () => ({\n useTamboConfig: jest.fn(),\n}));\n\ndescribe(\"useTamboSuggestions\", () => {\n let queryClient: QueryClient;\n const mockSetValue = jest.fn();\n const mockSubmit = jest.fn();\n const mockListSuggestions = jest.fn();\n const mockCreateSuggestions = jest.fn();\n\n const mockSuggestions: TamboAI.Beta.Threads.Suggestion[] = [\n {\n id: \"suggestion_1\",\n messageId: \"msg_1\",\n title: \"What's the weather?\",\n description: \"Ask for today's weather\",\n detailedSuggestion: \"What's the weather like today?\",\n },\n {\n id: \"suggestion_2\",\n messageId: \"msg_1\",\n title: \"Tell me a joke\",\n description: \"Request a funny joke\",\n detailedSuggestion: \"Can you tell me a funny joke?\",\n },\n ];\n\n const mockSuggestionsResponse = {\n suggestions: mockSuggestions,\n hasMore: false,\n nextCursor: undefined,\n };\n\n function createWrapper() {\n return function Wrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n {children}\n </QueryClientProvider>\n );\n };\n }\n\n beforeEach(() => {\n jest.clearAllMocks();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n // Mock useTamboQueryClient to return the test's queryClient\n jest.mocked(useTamboQueryClient).mockReturnValue(queryClient);\n\n // Default mock for config\n jest.mocked(useTamboConfig).mockReturnValue({ userKey: \"user_123\" });\n\n // Default mock for thread input\n jest.mocked(useTamboThreadInput).mockReturnValue({\n value: \"\",\n setValue: mockSetValue,\n submit: mockSubmit,\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n } as any);\n\n // Default mock for useTambo\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n // Default mock for registry\n jest.mocked(useTamboRegistry).mockReturnValue({\n componentList: {},\n toolRegistry: {},\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n onCallUnregisteredTool: undefined,\n registerComponent: jest.fn(),\n unregisterComponent: jest.fn(),\n registerTool: jest.fn(),\n unregisterTool: jest.fn(),\n registerMcpServer: jest.fn(),\n unregisterMcpServer: jest.fn(),\n registerResource: jest.fn(),\n unregisterResource: jest.fn(),\n setResourceSource: jest.fn(),\n } as any);\n\n // Default mock for client - using API structure\n mockListSuggestions.mockResolvedValue({ suggestions: [], hasMore: false });\n mockCreateSuggestions.mockResolvedValue(mockSuggestionsResponse);\n\n jest.mocked(useTamboClient).mockReturnValue({\n threads: {\n suggestions: {\n list: mockListSuggestions,\n create: mockCreateSuggestions,\n },\n },\n } as any);\n });\n\n describe(\"Initial State\", () => {\n it(\"returns empty suggestions when thread has placeholder ID\", () => {\n // Mock useTambo to return placeholder thread ID\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"placeholder\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n expect(result.current.selectedSuggestionId).toBeNull();\n expect(result.current.isLoading).toBe(false);\n });\n\n it(\"returns empty suggestions when no messages\", () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n\n it(\"returns empty suggestions when latest message is from user\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"user\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n });\n });\n\n describe(\"Suggestion Generation\", () => {\n it(\"generates suggestions when latest message is from assistant and thread is idle\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n // Should first call list, then create since list returns empty\n expect(mockListSuggestions).toHaveBeenCalledWith(\"msg_1\", {\n threadId: \"thread_123\",\n userKey: \"user_123\",\n });\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({\n threadId: \"thread_123\",\n maxSuggestions: 3,\n userKey: \"user_123\",\n }),\n );\n });\n\n it(\"returns existing suggestions from list without calling create\", async () => {\n mockListSuggestions.mockResolvedValue(mockSuggestionsResponse);\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n expect(mockListSuggestions).toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"does not generate suggestions when thread is streaming\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: false,\n isStreaming: true,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"streaming\", runId: \"run_1\" },\n } as any);\n\n renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(mockListSuggestions).not.toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"does not fetch or generate suggestions for ephemeral message ids\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"ephemeral_cb2decbe-9423-4b09-9ac2-feb385cea075\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n // Give effects a chance to fire\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n expect(mockListSuggestions).not.toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"does not generate suggestions when autoGenerate is false\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n renderHook(() => useTamboSuggestions({ autoGenerate: false }), {\n wrapper: createWrapper(),\n });\n\n expect(mockListSuggestions).not.toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"uses custom maxSuggestions option\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(\n () => useTamboSuggestions({ maxSuggestions: 5 }),\n { wrapper: createWrapper() },\n );\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({ maxSuggestions: 5 }),\n );\n });\n });\n\n describe(\"Accepting Suggestions\", () => {\n it(\"updates input value when accepting without submit\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n const suggestion = result.current.suggestions[0];\n\n await act(async () => {\n await result.current.accept({ suggestion });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\n \"What's the weather like today?\",\n );\n expect(mockSubmit).not.toHaveBeenCalled();\n expect(result.current.selectedSuggestionId).toBe(\"suggestion_1\");\n });\n\n it(\"submits when accepting with shouldSubmit=true\", async () => {\n mockSubmit.mockResolvedValue({ threadId: \"thread_123\" });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n const suggestion = result.current.suggestions[0];\n\n await act(async () => {\n await result.current.accept({ suggestion, shouldSubmit: true });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\n \"What's the weather like today?\",\n );\n expect(mockSubmit).toHaveBeenCalled();\n });\n\n it(\"throws error when suggestion has no content\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const emptySuggestion = {\n id: \"empty_suggestion\",\n messageId: \"msg_1\",\n title: \"Empty\",\n detailedSuggestion: \"\",\n };\n\n await expect(\n result.current.accept({ suggestion: emptySuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n\n it(\"throws error when detailedSuggestion is only whitespace\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const whitespaceSuggestion = {\n id: \"whitespace_suggestion\",\n messageId: \"msg_1\",\n title: \"Whitespace\",\n detailedSuggestion: \" \",\n };\n\n await expect(\n result.current.accept({ suggestion: whitespaceSuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n\n it(\"throws error when detailedSuggestion is undefined\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const undefinedSuggestion = {\n id: \"undefined_suggestion\",\n messageId: \"msg_1\",\n title: \"Undefined\",\n };\n\n await expect(\n result.current.accept({ suggestion: undefinedSuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n });\n\n describe(\"State Management\", () => {\n it(\"resets selectedSuggestionId when message changes\", async () => {\n const mockUseTambo = jest.mocked(useTambo);\n\n mockUseTambo.mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result, rerender } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n // Accept a suggestion\n await act(async () => {\n await result.current.accept({\n suggestion: result.current.suggestions[0],\n });\n });\n\n expect(result.current.selectedSuggestionId).toBe(\"suggestion_1\");\n\n // Change the latest message\n mockUseTambo.mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n {\n id: \"msg_2\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:01Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n rerender();\n\n await waitFor(() => {\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n });\n\n it(\"includes pagination info on raw data\", async () => {\n mockListSuggestions.mockResolvedValue({\n suggestions: mockSuggestions,\n hasMore: true,\n nextCursor: \"cursor_abc\",\n });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.data?.hasMore).toBe(true);\n expect(result.current.data?.nextCursor).toBe(\"cursor_abc\");\n });\n });\n\n it(\"exposes loading and error states\", () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.isLoading).toBeDefined();\n expect(result.current.isSuccess).toBeDefined();\n expect(result.current.isError).toBeDefined();\n expect(result.current.error).toBeDefined();\n expect(result.current.isAccepting).toBe(false);\n expect(result.current.isGenerating).toBe(false);\n });\n });\n\n describe(\"Retry on 404\", () => {\n it(\"retries list query on 404 and succeeds on subsequent attempt\", async () => {\n // Use a plain object with status to verify structural check works\n // (simulates duplicate SDK copy where instanceof would fail)\n const notFoundError = Object.assign(new Error(\"Message not found\"), {\n status: 404,\n });\n\n // First call: 404, second call: success with empty suggestions\n mockListSuggestions\n .mockRejectedValueOnce(notFoundError)\n .mockResolvedValueOnce({ suggestions: [], hasMore: false });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n // Should eventually succeed after retry and trigger auto-generate\n await waitFor(() => {\n expect(mockListSuggestions).toHaveBeenCalledTimes(2);\n });\n\n // After successful list (empty), auto-generate fires\n await waitFor(() => {\n expect(mockCreateSuggestions).toHaveBeenCalled();\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n });\n\n it(\"does not retry on non-404 errors\", async () => {\n const serverError = Object.assign(new Error(\"Internal server error\"), {\n status: 500,\n });\n\n mockListSuggestions.mockRejectedValue(serverError);\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n // Wait for the query to settle - 500 errors should not be retried\n await waitFor(() => {\n expect(mockListSuggestions).toHaveBeenCalledTimes(1);\n });\n\n // Give it a moment to ensure no additional retries happen\n await new Promise((resolve) => setTimeout(resolve, 100));\n expect(mockListSuggestions).toHaveBeenCalledTimes(1);\n });\n });\n\n describe(\"Manual Generation\", () => {\n it(\"allows manual generation via generate function\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(\n () => useTamboSuggestions({ autoGenerate: false }),\n { wrapper: createWrapper() },\n );\n\n // No auto-generation\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n\n // Manual generation\n await act(async () => {\n await result.current.generate();\n });\n\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({\n threadId: \"thread_123\",\n }),\n );\n });\n\n it(\"returns undefined from generate when no assistant message\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n let generateResult: any;\n await act(async () => {\n generateResult = await result.current.generate();\n });\n\n expect(generateResult).toBeUndefined();\n });\n });\n});\n"]}
|
|
@@ -25,10 +25,10 @@ jest.mock("../../providers/tambo-client-provider", () => {
|
|
|
25
25
|
});
|
|
26
26
|
// Mock MCP providers to avoid TamboClientContext dependency
|
|
27
27
|
jest.mock("../../providers/tambo-mcp-token-provider", () => ({
|
|
28
|
-
TamboMcpTokenProvider: ({ children }) => children,
|
|
28
|
+
TamboMcpTokenProvider: ({ children, }) => children,
|
|
29
29
|
}));
|
|
30
30
|
jest.mock("../../mcp/tambo-mcp-provider", () => ({
|
|
31
|
-
TamboMcpProvider: ({ children }) => children,
|
|
31
|
+
TamboMcpProvider: ({ children, }) => children,
|
|
32
32
|
}));
|
|
33
33
|
// Mock auth state to avoid TamboClientContext dependency
|
|
34
34
|
jest.mock("../hooks/use-tambo-v1-auth-state", () => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-v1-provider.test.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.test.tsx"],"names":[],"mappings":";;;;;AAAA,8EAA+C;AAC/C,uDAAyE;AACzE,kDAAyD;AACzD,kDAA0B;AAC1B,6BAAwB;AACxB,iFAG+C;AAC/C,qFAA2E;AAC3E,mGAAwF;AACxF,uEAAgF;AAChF,2DAAoE;AAEpE,sDAAsD;AACtD,IAAI,eAAe,GAAuB,IAAI,CAAC;AAE/C,iDAAiD;AACjD,IAAI,CAAC,IAAI,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACtD,OAAO;QACL,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;QACzB,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC9B,mBAAmB,EAAE,IAAI,CAAC,EAAE,CAC1B,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,QAAQ,CAC1D;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,4DAA4D;AAC5D,IAAI,CAAC,IAAI,CAAC,0CAA0C,EAAE,GAAG,EAAE,CAAC,CAAC;IAC3D,qBAAqB,EAAE,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CACrE,QAAQ;CACX,CAAC,CAAC,CAAC;AAEJ,IAAI,CAAC,IAAI,CAAC,8BAA8B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/C,gBAAgB,EAAE,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,QAAQ;CAC5E,CAAC,CAAC,CAAC;AAEJ,yDAAyD;AACzD,IAAI,CAAC,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE,CAAC,CAAC;IACnD,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC;QACxB,MAAM,EAAE,YAAY;QACpB,MAAM,EAAE,SAAS;KAClB,CAAC;CACH,CAAC,CAAC,CAAC;AAEJ,yDAAyD;AACzD,IAAI,CAAC,IAAI,CAAC,oCAAoC,EAAE,GAAG,EAAE,CAAC,CAAC;IACrD,mBAAmB,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QAClC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;QACtB,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;QACjB,SAAS,EAAE,KAAK;QAChB,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,KAAK;QAChB,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;KACjB,CAAC,CAAC;CACJ,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,MAAM,SAAS,GAAiB,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE;QACjD,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,wBAAO,CAAC;QAC7B,MAAM,EAAE,cAAc;QACtB,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IAEH,UAAU,CAAC,GAAG,EAAE;QACd,2CAA2C;QAC3C,eAAe,GAAG,IAAI,yBAAW,CAAC;YAChC,cAAc,EAAE;gBACd,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;gBACzB,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;aAC5B;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,sCAAc,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,2CAAmB,CAAC,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;QAElE,qEAAqE;QACrE,MAAM,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC,WAAW,CAC9C,uCAAuC,CACxC,CAAC;QACF,IAAI;aACD,MAAM,CAAC,mBAAmB,CAAC;aAC3B,kBAAkB,CAAC,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CACnE,8BAAC,iCAAmB,IAAC,MAAM,EAAE,eAAgB,IAC1C,QAAQ,CACW,CACvB,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAiB,CAChE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjE,MAAM,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAiB,CAChE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,wCAAc,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/C,yDAAyD;QACzD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAiB,CAChE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAC3B,GAAG,EAAE,CAAC,CAAC;YACL,KAAK,EAAE,IAAA,wCAAc,GAAE;YACvB,UAAU,EAAE,IAAA,6CAAmB,GAAE;SAClC,CAAC,EACF,EAAE,OAAO,EAAE,CACZ,CAAC;QAEF,qDAAqD;QACrD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAEjE,8CAA8C;QAC9C,IAAA,WAAG,EAAC,GAAG,EAAE;YACP,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YACnD,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAiB,CAChE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,2CAAmB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAExE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,yBAAW,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,kDAAe,CAAC;QAC5C,MAAM,WAAW,GAAG,OAAC,CAAC,MAAM,CAAC;YAC3B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;SACxC,CAAC,CAAC;QACH,MAAM,UAAU,GAAG;YACjB;gBACE,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,kBAAkB;gBAC/B,SAAS,EAAE,aAAa;gBACxB,WAAW;aACZ;SACF,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,EAAC,UAAU,EAAE,UAAU,IACxD,QAAQ,CACK,CACjB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAC1D,eAAe,CAChB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,WAAW,GAAG,OAAC,CAAC,MAAM,CAAC;YAC3B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;SAC3C,CAAC,CAAC;QACH,MAAM,YAAY,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG;YACZ;gBACE,IAAI,EAAE,UAAU;gBAChB,WAAW,EAAE,aAAa;gBAC1B,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ;gBAC1B,WAAW;gBACX,YAAY;aACb;SACF,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,EAAC,KAAK,EAAE,KAAK,IAC9C,QAAQ,CACK,CACjB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,UAAU,GAAG;YACjB,EAAE,GAAG,EAAE,yBAAyB,EAAE,IAAI,EAAE,aAAa,EAAE;SACxD,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,EAAC,UAAU,EAAE,UAAU,IACxD,QAAQ,CACK,CACjB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAC/C,yBAAyB,CAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,sBAAsB,GAAG,IAAI;aAChC,EAAE,EAAE;aACJ,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;QAExC,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IACZ,MAAM,EAAC,cAAc,EACrB,sBAAsB,EAAE,sBAAsB,IAE7C,QAAQ,CACK,CACjB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,SAAS,GAAG;YAChB;gBACE,GAAG,EAAE,yBAAyB;gBAC9B,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,iBAAiB;gBAC9B,QAAQ,EAAE,YAAY;aACvB;SACF,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,EAAC,SAAS,EAAE,SAAS,IACtD,QAAQ,CACK,CACjB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACxE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,aAAa,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;QACrE,MAAM,WAAW,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QAElE,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IACZ,MAAM,EAAC,cAAc,EACrB,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW,IAEvB,QAAQ,CACK,CACjB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACzE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,EAAC,OAAO,EAAC,aAAa,IACvD,QAAQ,CACK,CACjB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,kCAAc,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAiB,CAChE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,kCAAc,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,cAAc,GAAG;YACrB,WAAW,EAAE,GAAG,EAAE,CAAC,WAAW;YAC9B,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC/C,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,EAAC,cAAc,EAAE,cAAc,IAChE,QAAQ,CACK,CACjB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,uDAAsB,GAAE,EAAE;YACtE,OAAO;SACR,CAAC,CAAC;QAEH,yEAAyE;QACzE,MAAM,IAAA,WAAG,EAAC,KAAK,IAAI,EAAE;YACnB,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAC7D,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,iCAAa,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAiB,CAChE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,uDAAsB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAE3E,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;QACnD,wHAAwH;QACxH,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YACnC,eAAe;YACf,oBAAoB;SACrB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport { useStreamState, useThreadManagement } from \"./tambo-v1-stream-context\";\nimport { TamboProvider, useTamboConfig } from \"./tambo-v1-provider\";\n\n// Module-level QueryClient for tests - created lazily\nlet testQueryClient: QueryClient | null = null;\n\n// Mock the client provider to capture the apiKey\njest.mock(\"../../providers/tambo-client-provider\", () => {\n return {\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(),\n TamboClientProvider: jest.fn(\n ({ children }: { children: React.ReactNode }) => children,\n ),\n };\n});\n\n// Mock MCP providers to avoid TamboClientContext dependency\njest.mock(\"../../providers/tambo-mcp-token-provider\", () => ({\n TamboMcpTokenProvider: ({ children }: { children: React.ReactNode }) =>\n children,\n}));\n\njest.mock(\"../../mcp/tambo-mcp-provider\", () => ({\n TamboMcpProvider: ({ children }: { children: React.ReactNode }) => children,\n}));\n\n// Mock auth state to avoid TamboClientContext dependency\njest.mock(\"../hooks/use-tambo-v1-auth-state\", () => ({\n useTamboAuthState: () => ({\n status: \"identified\",\n source: \"userKey\",\n }),\n}));\n\n// Mock useTamboSendMessage to avoid complex dependencies\njest.mock(\"../hooks/use-tambo-v1-send-message\", () => ({\n useTamboSendMessage: jest.fn(() => ({\n mutateAsync: jest.fn(),\n mutate: jest.fn(),\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n })),\n}));\n\ndescribe(\"TamboProvider\", () => {\n const mockFetch: typeof fetch = async (..._args) => {\n throw new Error(\"fetch not implemented\");\n };\n\n const mockClient = new TamboAI({\n apiKey: \"test-api-key\",\n fetch: mockFetch,\n });\n\n beforeEach(() => {\n // Create a fresh QueryClient for each test\n testQueryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n jest.mocked(useTamboClient).mockReturnValue(mockClient);\n jest.mocked(useTamboQueryClient).mockReturnValue(testQueryClient);\n\n // Mock TamboClientProvider to wrap children with QueryClientProvider\n const { TamboClientProvider } = jest.requireMock(\n \"../../providers/tambo-client-provider\",\n );\n jest\n .mocked(TamboClientProvider)\n .mockImplementation(({ children }: { children: React.ReactNode }) => (\n <QueryClientProvider client={testQueryClient!}>\n {children}\n </QueryClientProvider>\n ));\n });\n\n it(\"provides access to registry context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList).toBeDefined();\n expect(result.current.toolRegistry).toBeDefined();\n expect(typeof result.current.registerComponent).toBe(\"function\");\n expect(typeof result.current.registerTool).toBe(\"function\");\n });\n\n it(\"provides access to stream context with placeholder thread ready\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap).toBeDefined();\n // Initial state has placeholder thread for optimistic UI\n expect(result.current.currentThreadId).toBe(\"placeholder\");\n expect(result.current.threadMap.placeholder).toBeDefined();\n });\n\n it(\"manages threads via useThreadManagement\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(\n () => ({\n state: useStreamState(),\n management: useThreadManagement(),\n }),\n { wrapper },\n );\n\n // Initially has placeholder thread for optimistic UI\n expect(result.current.state.currentThreadId).toBe(\"placeholder\");\n\n // Initialize and switch to a different thread\n act(() => {\n result.current.management.initThread(\"thread_123\");\n result.current.management.switchThread(\"thread_123\");\n });\n\n expect(result.current.state.currentThreadId).toBe(\"thread_123\");\n expect(result.current.state.threadMap.thread_123).toBeDefined();\n });\n\n it(\"provides access to query client via useTamboQueryClient\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboQueryClient(), { wrapper });\n\n expect(result.current).toBeInstanceOf(QueryClient);\n });\n\n it(\"registers components when provided\", () => {\n const TestComponent = () => <div>Test</div>;\n const propsSchema = z.object({\n title: z.string().describe(\"The title\"),\n });\n const components = [\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: TestComponent,\n propsSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" components={components}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList.TestComponent).toBeDefined();\n expect(result.current.componentList.TestComponent.name).toBe(\n \"TestComponent\",\n );\n });\n\n it(\"registers tools when provided\", () => {\n const inputSchema = z.object({\n query: z.string().describe(\"Search query\"),\n });\n const outputSchema = z.string().describe(\"Result string\");\n const tools = [\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema,\n outputSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" tools={tools}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.toolRegistry.testTool).toBeDefined();\n expect(result.current.toolRegistry.testTool.name).toBe(\"testTool\");\n });\n\n it(\"registers MCP servers when provided\", () => {\n const mcpServers = [\n { url: \"https://mcp.example.com\", name: \"Example MCP\" },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" mcpServers={mcpServers}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.mcpServerInfos).toHaveLength(1);\n expect(result.current.mcpServerInfos[0].url).toBe(\n \"https://mcp.example.com\",\n );\n });\n\n it(\"provides onCallUnregisteredTool to registry\", () => {\n const onCallUnregisteredTool = jest\n .fn()\n .mockResolvedValue(\"fallback result\");\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider\n apiKey=\"test-api-key\"\n onCallUnregisteredTool={onCallUnregisteredTool}\n >\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.onCallUnregisteredTool).toBe(onCallUnregisteredTool);\n });\n\n it(\"registers static resources when provided\", () => {\n const resources = [\n {\n uri: \"resource://test/example\",\n name: \"Test Resource\",\n description: \"A test resource\",\n mimeType: \"text/plain\",\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" resources={resources}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resources).toHaveLength(1);\n expect(result.current.resources[0].uri).toBe(\"resource://test/example\");\n expect(result.current.resources[0].name).toBe(\"Test Resource\");\n });\n\n it(\"registers resource source when listResources and getResource provided\", () => {\n const listResources = jest.fn().mockResolvedValue({ resources: [] });\n const getResource = jest.fn().mockResolvedValue({ contents: [] });\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider\n apiKey=\"test-api-key\"\n listResources={listResources}\n getResource={getResource}\n >\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resourceSource).toBeDefined();\n expect(result.current.resourceSource?.listResources).toBe(listResources);\n expect(result.current.resourceSource?.getResource).toBe(getResource);\n });\n\n it(\"provides userKey via useTamboConfig\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" userKey=\"my-user-key\">\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboConfig(), { wrapper });\n\n expect(result.current.userKey).toBe(\"my-user-key\");\n });\n\n it(\"returns undefined userKey from useTamboConfig when no userKey provided\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboConfig(), { wrapper });\n\n expect(result.current.userKey).toBeUndefined();\n });\n\n it(\"provides context helpers via useTamboContextHelpers hook\", async () => {\n const contextHelpers = {\n getUserName: () => \"Test User\",\n getCurrentTime: () => new Date().toISOString(),\n };\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" contextHelpers={contextHelpers}>\n {children}\n </TamboProvider>\n );\n\n const { result, rerender } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Helpers are registered via useEffect, so we need to trigger a rerender\n await act(async () => {\n rerender();\n });\n\n const helpers = result.current.getContextHelpers();\n expect(helpers.getUserName).toBe(contextHelpers.getUserName);\n expect(helpers.getCurrentTime).toBe(contextHelpers.getCurrentTime);\n });\n\n it(\"returns only interactables contextHelper when none explicitly provided\", async () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboContextHelpers(), { wrapper });\n\n const helpers = result.current.getContextHelpers();\n // TamboInteractableProvider registers \"interactables\" and TamboContextAttachmentProvider registers \"contextAttachments\"\n expect(Object.keys(helpers)).toEqual([\n \"interactables\",\n \"contextAttachments\",\n ]);\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"tambo-v1-provider.test.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport { useStreamState, useThreadManagement } from \"./tambo-v1-stream-context\";\nimport { TamboProvider, useTamboConfig } from \"./tambo-v1-provider\";\n\n// Module-level QueryClient for tests - created lazily\nlet testQueryClient: QueryClient | null = null;\n\n// Mock the client provider to capture the apiKey\njest.mock(\"../../providers/tambo-client-provider\", () => {\n return {\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(),\n TamboClientProvider: jest.fn(\n ({ children }: { children: React.ReactNode }): React.ReactNode =>\n children,\n ),\n };\n});\n\n// Mock MCP providers to avoid TamboClientContext dependency\njest.mock(\"../../providers/tambo-mcp-token-provider\", () => ({\n TamboMcpTokenProvider: ({\n children,\n }: {\n children: React.ReactNode;\n }): React.ReactNode => children,\n}));\n\njest.mock(\"../../mcp/tambo-mcp-provider\", () => ({\n TamboMcpProvider: ({\n children,\n }: {\n children: React.ReactNode;\n }): React.ReactNode => children,\n}));\n\n// Mock auth state to avoid TamboClientContext dependency\njest.mock(\"../hooks/use-tambo-v1-auth-state\", () => ({\n useTamboAuthState: () => ({\n status: \"identified\",\n source: \"userKey\",\n }),\n}));\n\n// Mock useTamboSendMessage to avoid complex dependencies\njest.mock(\"../hooks/use-tambo-v1-send-message\", () => ({\n useTamboSendMessage: jest.fn(() => ({\n mutateAsync: jest.fn(),\n mutate: jest.fn(),\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n })),\n}));\n\ndescribe(\"TamboProvider\", () => {\n const mockFetch: typeof fetch = async (..._args) => {\n throw new Error(\"fetch not implemented\");\n };\n\n const mockClient = new TamboAI({\n apiKey: \"test-api-key\",\n fetch: mockFetch,\n });\n\n beforeEach(() => {\n // Create a fresh QueryClient for each test\n testQueryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n jest.mocked(useTamboClient).mockReturnValue(mockClient);\n jest.mocked(useTamboQueryClient).mockReturnValue(testQueryClient);\n\n // Mock TamboClientProvider to wrap children with QueryClientProvider\n const { TamboClientProvider } = jest.requireMock(\n \"../../providers/tambo-client-provider\",\n );\n jest\n .mocked(TamboClientProvider)\n .mockImplementation(({ children }: { children: React.ReactNode }) => (\n <QueryClientProvider client={testQueryClient!}>\n {children}\n </QueryClientProvider>\n ));\n });\n\n it(\"provides access to registry context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList).toBeDefined();\n expect(result.current.toolRegistry).toBeDefined();\n expect(typeof result.current.registerComponent).toBe(\"function\");\n expect(typeof result.current.registerTool).toBe(\"function\");\n });\n\n it(\"provides access to stream context with placeholder thread ready\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap).toBeDefined();\n // Initial state has placeholder thread for optimistic UI\n expect(result.current.currentThreadId).toBe(\"placeholder\");\n expect(result.current.threadMap.placeholder).toBeDefined();\n });\n\n it(\"manages threads via useThreadManagement\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(\n () => ({\n state: useStreamState(),\n management: useThreadManagement(),\n }),\n { wrapper },\n );\n\n // Initially has placeholder thread for optimistic UI\n expect(result.current.state.currentThreadId).toBe(\"placeholder\");\n\n // Initialize and switch to a different thread\n act(() => {\n result.current.management.initThread(\"thread_123\");\n result.current.management.switchThread(\"thread_123\");\n });\n\n expect(result.current.state.currentThreadId).toBe(\"thread_123\");\n expect(result.current.state.threadMap.thread_123).toBeDefined();\n });\n\n it(\"provides access to query client via useTamboQueryClient\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboQueryClient(), { wrapper });\n\n expect(result.current).toBeInstanceOf(QueryClient);\n });\n\n it(\"registers components when provided\", () => {\n const TestComponent = () => <div>Test</div>;\n const propsSchema = z.object({\n title: z.string().describe(\"The title\"),\n });\n const components = [\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: TestComponent,\n propsSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" components={components}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList.TestComponent).toBeDefined();\n expect(result.current.componentList.TestComponent.name).toBe(\n \"TestComponent\",\n );\n });\n\n it(\"registers tools when provided\", () => {\n const inputSchema = z.object({\n query: z.string().describe(\"Search query\"),\n });\n const outputSchema = z.string().describe(\"Result string\");\n const tools = [\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema,\n outputSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" tools={tools}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.toolRegistry.testTool).toBeDefined();\n expect(result.current.toolRegistry.testTool.name).toBe(\"testTool\");\n });\n\n it(\"registers MCP servers when provided\", () => {\n const mcpServers = [\n { url: \"https://mcp.example.com\", name: \"Example MCP\" },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" mcpServers={mcpServers}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.mcpServerInfos).toHaveLength(1);\n expect(result.current.mcpServerInfos[0].url).toBe(\n \"https://mcp.example.com\",\n );\n });\n\n it(\"provides onCallUnregisteredTool to registry\", () => {\n const onCallUnregisteredTool = jest\n .fn()\n .mockResolvedValue(\"fallback result\");\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider\n apiKey=\"test-api-key\"\n onCallUnregisteredTool={onCallUnregisteredTool}\n >\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.onCallUnregisteredTool).toBe(onCallUnregisteredTool);\n });\n\n it(\"registers static resources when provided\", () => {\n const resources = [\n {\n uri: \"resource://test/example\",\n name: \"Test Resource\",\n description: \"A test resource\",\n mimeType: \"text/plain\",\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" resources={resources}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resources).toHaveLength(1);\n expect(result.current.resources[0].uri).toBe(\"resource://test/example\");\n expect(result.current.resources[0].name).toBe(\"Test Resource\");\n });\n\n it(\"registers resource source when listResources and getResource provided\", () => {\n const listResources = jest.fn().mockResolvedValue({ resources: [] });\n const getResource = jest.fn().mockResolvedValue({ contents: [] });\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider\n apiKey=\"test-api-key\"\n listResources={listResources}\n getResource={getResource}\n >\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resourceSource).toBeDefined();\n expect(result.current.resourceSource?.listResources).toBe(listResources);\n expect(result.current.resourceSource?.getResource).toBe(getResource);\n });\n\n it(\"provides userKey via useTamboConfig\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" userKey=\"my-user-key\">\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboConfig(), { wrapper });\n\n expect(result.current.userKey).toBe(\"my-user-key\");\n });\n\n it(\"returns undefined userKey from useTamboConfig when no userKey provided\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboConfig(), { wrapper });\n\n expect(result.current.userKey).toBeUndefined();\n });\n\n it(\"provides context helpers via useTamboContextHelpers hook\", async () => {\n const contextHelpers = {\n getUserName: () => \"Test User\",\n getCurrentTime: () => new Date().toISOString(),\n };\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" contextHelpers={contextHelpers}>\n {children}\n </TamboProvider>\n );\n\n const { result, rerender } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Helpers are registered via useEffect, so we need to trigger a rerender\n await act(async () => {\n rerender();\n });\n\n const helpers = result.current.getContextHelpers();\n expect(helpers.getUserName).toBe(contextHelpers.getUserName);\n expect(helpers.getCurrentTime).toBe(contextHelpers.getCurrentTime);\n });\n\n it(\"returns only interactables contextHelper when none explicitly provided\", async () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboContextHelpers(), { wrapper });\n\n const helpers = result.current.getContextHelpers();\n // TamboInteractableProvider registers \"interactables\" and TamboContextAttachmentProvider registers \"contextAttachments\"\n expect(Object.keys(helpers)).toEqual([\n \"interactables\",\n \"contextAttachments\",\n ]);\n });\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-suggestions.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC;AACpD,OAAO,KAAK,EACV,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,wDAAwD,CAAC;AAYhE;;GAEG;AACH,KAAK,wBAAwB,GACzB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,EAAE,IAAI,CACjB,eAAe,CAAC,wBAAwB,CAAC,EACzC,UAAU,GAAG,SAAS,GAAG,SAAS,CACnC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,+BAA+B;IAC/B,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;IAC5C,sFAAsF;IACtF,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IAKxC;;;OAGG;IACH,IAAI,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAE3C,mFAAmF;IACnF,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;IAM/C,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;IAEnB,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IAEnB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IAEjB,6CAA6C;IAC7C,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEpB,8EAA8E;IAC9E,UAAU,EAAE,OAAO,CAAC;IAMpB;;;OAGG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAAC;IAE9D,iEAAiE;IACjE,YAAY,EAAE,OAAO,CAAC;IAEtB,gDAAgD;IAChD,aAAa,EAAE,KAAK,GAAG,IAAI,CAAC;IAM5B;;;OAGG;IACH,MAAM,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5D,oDAAoD;IACpD,WAAW,EAAE,OAAO,CAAC;IAErB,gDAAgD;IAChD,WAAW,EAAE,KAAK,GAAG,IAAI,CAAC;IAM1B,8CAA8C;IAC9C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,0BAA+B,GACvC,yBAAyB,
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-suggestions.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC;AACpD,OAAO,KAAK,EACV,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,wDAAwD,CAAC;AAYhE;;GAEG;AACH,KAAK,wBAAwB,GACzB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,EAAE,IAAI,CACjB,eAAe,CAAC,wBAAwB,CAAC,EACzC,UAAU,GAAG,SAAS,GAAG,SAAS,CACnC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,+BAA+B;IAC/B,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;IAC5C,sFAAsF;IACtF,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IAKxC;;;OAGG;IACH,IAAI,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAE3C,mFAAmF;IACnF,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;IAM/C,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;IAEnB,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IAEnB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IAEjB,6CAA6C;IAC7C,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEpB,8EAA8E;IAC9E,UAAU,EAAE,OAAO,CAAC;IAMpB;;;OAGG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAAC;IAE9D,iEAAiE;IACjE,YAAY,EAAE,OAAO,CAAC;IAEtB,gDAAgD;IAChD,aAAa,EAAE,KAAK,GAAG,IAAI,CAAC;IAM5B;;;OAGG;IACH,MAAM,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5D,oDAAoD;IACpD,WAAW,EAAE,OAAO,CAAC;IAErB,gDAAgD;IAChD,WAAW,EAAE,KAAK,GAAG,IAAI,CAAC;IAM1B,8CAA8C;IAC9C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,0BAA+B,GACvC,yBAAyB,CAmO3B"}
|
|
@@ -63,6 +63,9 @@ export function useTamboSuggestions(options = {}) {
|
|
|
63
63
|
const latestMessage = messages[messages.length - 1];
|
|
64
64
|
const isLatestFromAssistant = latestMessage?.role === "assistant";
|
|
65
65
|
const latestMessageId = latestMessage?.id;
|
|
66
|
+
// Ephemeral ids (e.g. reasoning placeholders) are never persisted server-side,
|
|
67
|
+
// so suggestion requests against them can only ever 404.
|
|
68
|
+
const isEphemeralMessageId = latestMessageId?.startsWith("ephemeral_") ?? false;
|
|
66
69
|
// Reset selected suggestion when the message changes
|
|
67
70
|
useEffect(() => {
|
|
68
71
|
setSelectedSuggestionId(null);
|
|
@@ -70,6 +73,7 @@ export function useTamboSuggestions(options = {}) {
|
|
|
70
73
|
// Determine if we should fetch/generate suggestions
|
|
71
74
|
const shouldFetchSuggestions = currentThreadId &&
|
|
72
75
|
latestMessageId &&
|
|
76
|
+
!isEphemeralMessageId &&
|
|
73
77
|
isLatestFromAssistant &&
|
|
74
78
|
isIdle &&
|
|
75
79
|
autoGenerate;
|
|
@@ -112,7 +116,10 @@ export function useTamboSuggestions(options = {}) {
|
|
|
112
116
|
// Mutation to manually generate suggestions
|
|
113
117
|
const generateMutation = useTamboMutation({
|
|
114
118
|
mutationFn: async () => {
|
|
115
|
-
if (!currentThreadId ||
|
|
119
|
+
if (!currentThreadId ||
|
|
120
|
+
!latestMessageId ||
|
|
121
|
+
isEphemeralMessageId ||
|
|
122
|
+
!isLatestFromAssistant) {
|
|
116
123
|
return undefined;
|
|
117
124
|
}
|
|
118
125
|
const availableComponents = toAvailableComponents(componentList);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-suggestions.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * useTamboSuggestions - Suggestions Hook\n *\n * Manages AI-powered suggestions for thread messages.\n * Uses the API endpoints for listing and creating suggestions.\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { UseQueryOptions } from \"@tanstack/react-query\";\nimport type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport type {\n SuggestionCreateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/threads/suggestions\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboQuery, useTamboMutation } from \"../../hooks/react-query-hooks\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboConfig } from \"../providers/tambo-v1-provider\";\nimport { useTambo } from \"./use-tambo-v1\";\nimport { useTamboThreadInput } from \"./use-tambo-v1-thread-input\";\nimport { toAvailableComponents } from \"@tambo-ai/client\";\n\n/**\n * Response type for suggestions queries (union of list and create responses)\n */\ntype SuggestionsQueryResponse =\n | SuggestionListResponse\n | SuggestionCreateResponse;\n\n/**\n * Configuration options for the useTamboSuggestions hook\n */\nexport interface UseTamboSuggestionsOptions {\n /** Maximum number of suggestions to generate (1-10, default 3) */\n maxSuggestions?: number;\n /**\n * Whether to automatically generate suggestions when the latest message is from the assistant.\n * Default: true\n */\n autoGenerate?: boolean;\n /**\n * Additional React Query options for the suggestions query.\n * Allows customizing caching, refetching behavior, etc.\n */\n queryOptions?: Omit<\n UseQueryOptions<SuggestionsQueryResponse>,\n \"queryKey\" | \"queryFn\" | \"enabled\"\n >;\n}\n\n/**\n * Options for accepting a suggestion\n */\nexport interface AcceptSuggestionOptions {\n /** The suggestion to accept */\n suggestion: TamboAI.Beta.Threads.Suggestion;\n /** Whether to automatically submit the suggestion after accepting (default: false) */\n shouldSubmit?: boolean;\n}\n\n/**\n * Return type for useTamboSuggestions hook\n */\nexport interface UseTamboSuggestionsReturn {\n // ---------------------------------------------------------------------------\n // Data (mirrors react-query patterns)\n // ---------------------------------------------------------------------------\n\n /**\n * The raw response data from the suggestions query.\n * Use this for direct access to the API response shape.\n */\n data: SuggestionsQueryResponse | undefined;\n\n /** List of available suggestions for the current message (convenience accessor) */\n suggestions: TamboAI.Beta.Threads.Suggestion[];\n\n // ---------------------------------------------------------------------------\n // Query state (matches react-query UseQueryResult)\n // ---------------------------------------------------------------------------\n\n /** Whether the suggestions query is loading (first fetch) */\n isLoading: boolean;\n\n /** Whether suggestions have been successfully loaded */\n isSuccess: boolean;\n\n /** Whether there was an error loading suggestions */\n isError: boolean;\n\n /** Error from loading suggestions, if any */\n error: Error | null;\n\n /** Whether the query is currently fetching (includes background refetches) */\n isFetching: boolean;\n\n // ---------------------------------------------------------------------------\n // Generate mutation (for manual suggestion generation)\n // ---------------------------------------------------------------------------\n\n /**\n * Manually generate new suggestions for the current message.\n * Use this when autoGenerate is false or to refresh suggestions.\n */\n generate: () => Promise<SuggestionCreateResponse | undefined>;\n\n /** Whether suggestions are being generated (mutation pending) */\n isGenerating: boolean;\n\n /** Error from generating suggestions, if any */\n generateError: Error | null;\n\n // ---------------------------------------------------------------------------\n // Accept mutation (for applying a suggestion)\n // ---------------------------------------------------------------------------\n\n /**\n * Accept and apply a suggestion.\n * Sets the suggestion text as input value, optionally submitting it.\n */\n accept: (options: AcceptSuggestionOptions) => Promise<void>;\n\n /** Whether accepting a suggestion is in progress */\n isAccepting: boolean;\n\n /** Error from accepting a suggestion, if any */\n acceptError: Error | null;\n\n // ---------------------------------------------------------------------------\n // UI state\n // ---------------------------------------------------------------------------\n\n /** ID of the currently selected suggestion */\n selectedSuggestionId: string | null;\n}\n\n/**\n * Hook for managing AI-powered suggestions in a thread.\n *\n * Provides functionality to:\n * - Automatically generate suggestions when an assistant message arrives\n * - Manually generate suggestions on demand\n * - Accept suggestions by setting them as input or auto-submitting\n * @param options - Configuration options\n * @returns Suggestions state and control functions\n * @example\n * ```tsx\n * function SuggestionsPanel() {\n * const {\n * suggestions,\n * accept,\n * isLoading,\n * selectedSuggestionId,\n * } = useTamboSuggestions();\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * {suggestions.map((suggestion) => (\n * <button\n * key={suggestion.id}\n * onClick={() => accept({ suggestion })}\n * className={selectedSuggestionId === suggestion.id ? 'selected' : ''}\n * >\n * {suggestion.title}\n * </button>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useTamboSuggestions(\n options: UseTamboSuggestionsOptions = {},\n): UseTamboSuggestionsReturn {\n const { maxSuggestions = 3, autoGenerate = true, queryOptions } = options;\n\n const client = useTamboClient();\n const { userKey } = useTamboConfig();\n const { componentList } = useTamboRegistry();\n const queryClient = useTamboQueryClient();\n\n const { messages, isIdle, currentThreadId } = useTambo();\n const { setValue: setInputValue, submit } = useTamboThreadInput();\n\n const [selectedSuggestionId, setSelectedSuggestionId] = useState<\n string | null\n >(null);\n\n // Get the latest message info\n const latestMessage = messages[messages.length - 1];\n const isLatestFromAssistant = latestMessage?.role === \"assistant\";\n const latestMessageId = latestMessage?.id;\n\n // Reset selected suggestion when the message changes\n useEffect(() => {\n setSelectedSuggestionId(null);\n }, [latestMessageId]);\n\n // Determine if we should fetch/generate suggestions\n const shouldFetchSuggestions =\n currentThreadId &&\n latestMessageId &&\n isLatestFromAssistant &&\n isIdle &&\n autoGenerate;\n\n const suggestionsQueryKey = [\n \"v1-suggestions\",\n currentThreadId ?? null,\n latestMessageId ?? null,\n ] as const;\n\n // Query to list existing suggestions\n const suggestionsQuery = useTamboQuery({\n queryKey: suggestionsQueryKey,\n queryFn: async (): Promise<SuggestionsQueryResponse> => {\n if (!shouldFetchSuggestions || !latestMessageId || !currentThreadId) {\n return { suggestions: [], hasMore: false };\n }\n\n return await client.threads.suggestions.list(latestMessageId, {\n threadId: currentThreadId,\n userKey,\n });\n },\n ...queryOptions,\n enabled: Boolean(shouldFetchSuggestions),\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n // Retry on 404s to handle the race condition where the assistant message\n // hasn't been persisted to the DB yet when suggestions are requested\n // immediately after a run completes.\n retry: (failureCount, error) => {\n if (failureCount >= 3) return false;\n // Use structural check instead of instanceof to handle duplicate SDK copies\n // where the APIError constructor identity may differ between packages.\n const status =\n typeof error === \"object\" && error !== null && \"status\" in error\n ? (error as { status: unknown }).status\n : undefined;\n return status === 404;\n },\n retryDelay: (attemptIndex) => Math.min(500 * 2 ** attemptIndex, 3000),\n });\n\n // Mutation to manually generate suggestions\n const generateMutation = useTamboMutation({\n mutationFn: async () => {\n if (!currentThreadId || !latestMessageId || !isLatestFromAssistant) {\n return undefined;\n }\n\n const availableComponents = toAvailableComponents(componentList);\n\n return await client.threads.suggestions.create(latestMessageId, {\n threadId: currentThreadId,\n maxSuggestions,\n availableComponents,\n userKey,\n });\n },\n onSuccess: (data) => {\n if (data && currentThreadId && latestMessageId) {\n // Update the query cache with new suggestions\n queryClient.setQueryData(suggestionsQueryKey, data);\n }\n },\n });\n\n const lastAutoGenerateMessageIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n lastAutoGenerateMessageIdRef.current = null;\n }, [latestMessageId]);\n\n const listSuggestionsCount = suggestionsQuery.data?.suggestions.length ?? 0;\n const generateMutate = generateMutation.mutate;\n const isGenerating = generateMutation.isPending;\n const isListError = suggestionsQuery.isError;\n const isListSuccess = suggestionsQuery.isSuccess;\n\n useEffect(() => {\n if (!shouldFetchSuggestions || !latestMessageId) {\n return;\n }\n\n if (listSuggestionsCount > 0) {\n return;\n }\n\n const shouldAutoGenerate =\n (isListSuccess && listSuggestionsCount === 0) || isListError;\n\n if (!shouldAutoGenerate) {\n return;\n }\n\n if (isGenerating) {\n return;\n }\n\n if (lastAutoGenerateMessageIdRef.current === latestMessageId) {\n return;\n }\n\n lastAutoGenerateMessageIdRef.current = latestMessageId;\n generateMutate();\n }, [\n generateMutate,\n isGenerating,\n isListError,\n isListSuccess,\n latestMessageId,\n listSuggestionsCount,\n shouldFetchSuggestions,\n ]);\n\n // Mutation to accept a suggestion\n const acceptMutation = useTamboMutation({\n mutationFn: async ({\n suggestion,\n shouldSubmit = false,\n }: AcceptSuggestionOptions) => {\n const text = suggestion.detailedSuggestion?.trim();\n if (!text) {\n throw new Error(\"Suggestion has no content\");\n }\n\n if (shouldSubmit) {\n // Set value and submit\n setInputValue(text);\n await submit();\n } else {\n // Just set the input value\n setInputValue(text);\n }\n\n setSelectedSuggestionId(suggestion.id);\n },\n });\n\n // Generate callback\n const generateMutateAsync = generateMutation.mutateAsync;\n const generate = useCallback(async () => {\n return await generateMutateAsync();\n }, [generateMutateAsync]);\n\n // Accept callback\n const accept = useCallback(\n async (acceptOptions: AcceptSuggestionOptions) => {\n await acceptMutation.mutateAsync(acceptOptions);\n },\n [acceptMutation],\n );\n\n // Get suggestions from query or mutation result\n const queryData = suggestionsQuery.data;\n const mutationData = generateMutation.data;\n\n // Use mutation data if available (more recent), otherwise query data\n const currentData = mutationData ?? queryData;\n const suggestions = isLatestFromAssistant\n ? (currentData?.suggestions ?? [])\n : [];\n\n return {\n // Data\n data: currentData,\n suggestions,\n\n // Query state (matches react-query patterns)\n isLoading: suggestionsQuery.isLoading,\n isSuccess: suggestionsQuery.isSuccess,\n isError: suggestionsQuery.isError,\n error: suggestionsQuery.error,\n isFetching: suggestionsQuery.isFetching,\n\n // Generate mutation\n generate,\n isGenerating: generateMutation.isPending,\n generateError: generateMutation.error,\n\n // Accept mutation\n accept,\n isAccepting: acceptMutation.isPending,\n acceptError: acceptMutation.error,\n\n // UI state\n selectedSuggestionId,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-suggestions.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * useTamboSuggestions - Suggestions Hook\n *\n * Manages AI-powered suggestions for thread messages.\n * Uses the API endpoints for listing and creating suggestions.\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { UseQueryOptions } from \"@tanstack/react-query\";\nimport type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport type {\n SuggestionCreateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/threads/suggestions\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboQuery, useTamboMutation } from \"../../hooks/react-query-hooks\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboConfig } from \"../providers/tambo-v1-provider\";\nimport { useTambo } from \"./use-tambo-v1\";\nimport { useTamboThreadInput } from \"./use-tambo-v1-thread-input\";\nimport { toAvailableComponents } from \"@tambo-ai/client\";\n\n/**\n * Response type for suggestions queries (union of list and create responses)\n */\ntype SuggestionsQueryResponse =\n | SuggestionListResponse\n | SuggestionCreateResponse;\n\n/**\n * Configuration options for the useTamboSuggestions hook\n */\nexport interface UseTamboSuggestionsOptions {\n /** Maximum number of suggestions to generate (1-10, default 3) */\n maxSuggestions?: number;\n /**\n * Whether to automatically generate suggestions when the latest message is from the assistant.\n * Default: true\n */\n autoGenerate?: boolean;\n /**\n * Additional React Query options for the suggestions query.\n * Allows customizing caching, refetching behavior, etc.\n */\n queryOptions?: Omit<\n UseQueryOptions<SuggestionsQueryResponse>,\n \"queryKey\" | \"queryFn\" | \"enabled\"\n >;\n}\n\n/**\n * Options for accepting a suggestion\n */\nexport interface AcceptSuggestionOptions {\n /** The suggestion to accept */\n suggestion: TamboAI.Beta.Threads.Suggestion;\n /** Whether to automatically submit the suggestion after accepting (default: false) */\n shouldSubmit?: boolean;\n}\n\n/**\n * Return type for useTamboSuggestions hook\n */\nexport interface UseTamboSuggestionsReturn {\n // ---------------------------------------------------------------------------\n // Data (mirrors react-query patterns)\n // ---------------------------------------------------------------------------\n\n /**\n * The raw response data from the suggestions query.\n * Use this for direct access to the API response shape.\n */\n data: SuggestionsQueryResponse | undefined;\n\n /** List of available suggestions for the current message (convenience accessor) */\n suggestions: TamboAI.Beta.Threads.Suggestion[];\n\n // ---------------------------------------------------------------------------\n // Query state (matches react-query UseQueryResult)\n // ---------------------------------------------------------------------------\n\n /** Whether the suggestions query is loading (first fetch) */\n isLoading: boolean;\n\n /** Whether suggestions have been successfully loaded */\n isSuccess: boolean;\n\n /** Whether there was an error loading suggestions */\n isError: boolean;\n\n /** Error from loading suggestions, if any */\n error: Error | null;\n\n /** Whether the query is currently fetching (includes background refetches) */\n isFetching: boolean;\n\n // ---------------------------------------------------------------------------\n // Generate mutation (for manual suggestion generation)\n // ---------------------------------------------------------------------------\n\n /**\n * Manually generate new suggestions for the current message.\n * Use this when autoGenerate is false or to refresh suggestions.\n */\n generate: () => Promise<SuggestionCreateResponse | undefined>;\n\n /** Whether suggestions are being generated (mutation pending) */\n isGenerating: boolean;\n\n /** Error from generating suggestions, if any */\n generateError: Error | null;\n\n // ---------------------------------------------------------------------------\n // Accept mutation (for applying a suggestion)\n // ---------------------------------------------------------------------------\n\n /**\n * Accept and apply a suggestion.\n * Sets the suggestion text as input value, optionally submitting it.\n */\n accept: (options: AcceptSuggestionOptions) => Promise<void>;\n\n /** Whether accepting a suggestion is in progress */\n isAccepting: boolean;\n\n /** Error from accepting a suggestion, if any */\n acceptError: Error | null;\n\n // ---------------------------------------------------------------------------\n // UI state\n // ---------------------------------------------------------------------------\n\n /** ID of the currently selected suggestion */\n selectedSuggestionId: string | null;\n}\n\n/**\n * Hook for managing AI-powered suggestions in a thread.\n *\n * Provides functionality to:\n * - Automatically generate suggestions when an assistant message arrives\n * - Manually generate suggestions on demand\n * - Accept suggestions by setting them as input or auto-submitting\n * @param options - Configuration options\n * @returns Suggestions state and control functions\n * @example\n * ```tsx\n * function SuggestionsPanel() {\n * const {\n * suggestions,\n * accept,\n * isLoading,\n * selectedSuggestionId,\n * } = useTamboSuggestions();\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * {suggestions.map((suggestion) => (\n * <button\n * key={suggestion.id}\n * onClick={() => accept({ suggestion })}\n * className={selectedSuggestionId === suggestion.id ? 'selected' : ''}\n * >\n * {suggestion.title}\n * </button>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useTamboSuggestions(\n options: UseTamboSuggestionsOptions = {},\n): UseTamboSuggestionsReturn {\n const { maxSuggestions = 3, autoGenerate = true, queryOptions } = options;\n\n const client = useTamboClient();\n const { userKey } = useTamboConfig();\n const { componentList } = useTamboRegistry();\n const queryClient = useTamboQueryClient();\n\n const { messages, isIdle, currentThreadId } = useTambo();\n const { setValue: setInputValue, submit } = useTamboThreadInput();\n\n const [selectedSuggestionId, setSelectedSuggestionId] = useState<\n string | null\n >(null);\n\n // Get the latest message info\n const latestMessage = messages[messages.length - 1];\n const isLatestFromAssistant = latestMessage?.role === \"assistant\";\n const latestMessageId = latestMessage?.id;\n // Ephemeral ids (e.g. reasoning placeholders) are never persisted server-side,\n // so suggestion requests against them can only ever 404.\n const isEphemeralMessageId =\n latestMessageId?.startsWith(\"ephemeral_\") ?? false;\n\n // Reset selected suggestion when the message changes\n useEffect(() => {\n setSelectedSuggestionId(null);\n }, [latestMessageId]);\n\n // Determine if we should fetch/generate suggestions\n const shouldFetchSuggestions =\n currentThreadId &&\n latestMessageId &&\n !isEphemeralMessageId &&\n isLatestFromAssistant &&\n isIdle &&\n autoGenerate;\n\n const suggestionsQueryKey = [\n \"v1-suggestions\",\n currentThreadId ?? null,\n latestMessageId ?? null,\n ] as const;\n\n // Query to list existing suggestions\n const suggestionsQuery = useTamboQuery({\n queryKey: suggestionsQueryKey,\n queryFn: async (): Promise<SuggestionsQueryResponse> => {\n if (!shouldFetchSuggestions || !latestMessageId || !currentThreadId) {\n return { suggestions: [], hasMore: false };\n }\n\n return await client.threads.suggestions.list(latestMessageId, {\n threadId: currentThreadId,\n userKey,\n });\n },\n ...queryOptions,\n enabled: Boolean(shouldFetchSuggestions),\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n // Retry on 404s to handle the race condition where the assistant message\n // hasn't been persisted to the DB yet when suggestions are requested\n // immediately after a run completes.\n retry: (failureCount, error) => {\n if (failureCount >= 3) return false;\n // Use structural check instead of instanceof to handle duplicate SDK copies\n // where the APIError constructor identity may differ between packages.\n const status =\n typeof error === \"object\" && error !== null && \"status\" in error\n ? (error as { status: unknown }).status\n : undefined;\n return status === 404;\n },\n retryDelay: (attemptIndex) => Math.min(500 * 2 ** attemptIndex, 3000),\n });\n\n // Mutation to manually generate suggestions\n const generateMutation = useTamboMutation({\n mutationFn: async () => {\n if (\n !currentThreadId ||\n !latestMessageId ||\n isEphemeralMessageId ||\n !isLatestFromAssistant\n ) {\n return undefined;\n }\n\n const availableComponents = toAvailableComponents(componentList);\n\n return await client.threads.suggestions.create(latestMessageId, {\n threadId: currentThreadId,\n maxSuggestions,\n availableComponents,\n userKey,\n });\n },\n onSuccess: (data) => {\n if (data && currentThreadId && latestMessageId) {\n // Update the query cache with new suggestions\n queryClient.setQueryData(suggestionsQueryKey, data);\n }\n },\n });\n\n const lastAutoGenerateMessageIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n lastAutoGenerateMessageIdRef.current = null;\n }, [latestMessageId]);\n\n const listSuggestionsCount = suggestionsQuery.data?.suggestions.length ?? 0;\n const generateMutate = generateMutation.mutate;\n const isGenerating = generateMutation.isPending;\n const isListError = suggestionsQuery.isError;\n const isListSuccess = suggestionsQuery.isSuccess;\n\n useEffect(() => {\n if (!shouldFetchSuggestions || !latestMessageId) {\n return;\n }\n\n if (listSuggestionsCount > 0) {\n return;\n }\n\n const shouldAutoGenerate =\n (isListSuccess && listSuggestionsCount === 0) || isListError;\n\n if (!shouldAutoGenerate) {\n return;\n }\n\n if (isGenerating) {\n return;\n }\n\n if (lastAutoGenerateMessageIdRef.current === latestMessageId) {\n return;\n }\n\n lastAutoGenerateMessageIdRef.current = latestMessageId;\n generateMutate();\n }, [\n generateMutate,\n isGenerating,\n isListError,\n isListSuccess,\n latestMessageId,\n listSuggestionsCount,\n shouldFetchSuggestions,\n ]);\n\n // Mutation to accept a suggestion\n const acceptMutation = useTamboMutation({\n mutationFn: async ({\n suggestion,\n shouldSubmit = false,\n }: AcceptSuggestionOptions) => {\n const text = suggestion.detailedSuggestion?.trim();\n if (!text) {\n throw new Error(\"Suggestion has no content\");\n }\n\n if (shouldSubmit) {\n // Set value and submit\n setInputValue(text);\n await submit();\n } else {\n // Just set the input value\n setInputValue(text);\n }\n\n setSelectedSuggestionId(suggestion.id);\n },\n });\n\n // Generate callback\n const generateMutateAsync = generateMutation.mutateAsync;\n const generate = useCallback(async () => {\n return await generateMutateAsync();\n }, [generateMutateAsync]);\n\n // Accept callback\n const accept = useCallback(\n async (acceptOptions: AcceptSuggestionOptions) => {\n await acceptMutation.mutateAsync(acceptOptions);\n },\n [acceptMutation],\n );\n\n // Get suggestions from query or mutation result\n const queryData = suggestionsQuery.data;\n const mutationData = generateMutation.data;\n\n // Use mutation data if available (more recent), otherwise query data\n const currentData = mutationData ?? queryData;\n const suggestions = isLatestFromAssistant\n ? (currentData?.suggestions ?? [])\n : [];\n\n return {\n // Data\n data: currentData,\n suggestions,\n\n // Query state (matches react-query patterns)\n isLoading: suggestionsQuery.isLoading,\n isSuccess: suggestionsQuery.isSuccess,\n isError: suggestionsQuery.isError,\n error: suggestionsQuery.error,\n isFetching: suggestionsQuery.isFetching,\n\n // Generate mutation\n generate,\n isGenerating: generateMutation.isPending,\n generateError: generateMutation.error,\n\n // Accept mutation\n accept,\n isAccepting: acceptMutation.isPending,\n acceptError: acceptMutation.error,\n\n // UI state\n selectedSuggestionId,\n };\n}\n"]}
|
|
@@ -268,6 +268,33 @@ describe("useTamboSuggestions", () => {
|
|
|
268
268
|
expect(mockListSuggestions).not.toHaveBeenCalled();
|
|
269
269
|
expect(mockCreateSuggestions).not.toHaveBeenCalled();
|
|
270
270
|
});
|
|
271
|
+
it("does not fetch or generate suggestions for ephemeral message ids", async () => {
|
|
272
|
+
jest.mocked(useTambo).mockReturnValue({
|
|
273
|
+
messages: [
|
|
274
|
+
{
|
|
275
|
+
id: "ephemeral_cb2decbe-9423-4b09-9ac2-feb385cea075",
|
|
276
|
+
role: "assistant",
|
|
277
|
+
content: [],
|
|
278
|
+
createdAt: "2024-01-01T00:00:00Z",
|
|
279
|
+
},
|
|
280
|
+
],
|
|
281
|
+
thread: undefined,
|
|
282
|
+
isIdle: true,
|
|
283
|
+
isStreaming: false,
|
|
284
|
+
currentThreadId: "thread_123",
|
|
285
|
+
startNewThread: jest.fn(),
|
|
286
|
+
switchThread: jest.fn(),
|
|
287
|
+
initThread: jest.fn(),
|
|
288
|
+
streamingState: { status: "idle" },
|
|
289
|
+
});
|
|
290
|
+
renderHook(() => useTamboSuggestions(), {
|
|
291
|
+
wrapper: createWrapper(),
|
|
292
|
+
});
|
|
293
|
+
// Give effects a chance to fire
|
|
294
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
295
|
+
expect(mockListSuggestions).not.toHaveBeenCalled();
|
|
296
|
+
expect(mockCreateSuggestions).not.toHaveBeenCalled();
|
|
297
|
+
});
|
|
271
298
|
it("does not generate suggestions when autoGenerate is false", () => {
|
|
272
299
|
jest.mocked(useTambo).mockReturnValue({
|
|
273
300
|
messages: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-suggestions.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { renderHook, act, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { useTamboSuggestions } from \"./use-tambo-v1-suggestions\";\nimport { useTamboThreadInput } from \"./use-tambo-v1-thread-input\";\nimport { useTambo } from \"./use-tambo-v1\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboConfig } from \"../providers/tambo-v1-provider\";\n\n// Mock dependencies\njest.mock(\"./use-tambo-v1-thread-input\", () => ({\n useTamboThreadInput: jest.fn(),\n}));\n\njest.mock(\"./use-tambo-v1\", () => ({\n useTambo: jest.fn(),\n}));\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(() => new QueryClient()),\n}));\n\njest.mock(\"../../providers/tambo-registry-provider\", () => ({\n useTamboRegistry: jest.fn(),\n}));\n\njest.mock(\"../providers/tambo-v1-provider\", () => ({\n useTamboConfig: jest.fn(),\n}));\n\ndescribe(\"useTamboSuggestions\", () => {\n let queryClient: QueryClient;\n const mockSetValue = jest.fn();\n const mockSubmit = jest.fn();\n const mockListSuggestions = jest.fn();\n const mockCreateSuggestions = jest.fn();\n\n const mockSuggestions: TamboAI.Beta.Threads.Suggestion[] = [\n {\n id: \"suggestion_1\",\n messageId: \"msg_1\",\n title: \"What's the weather?\",\n description: \"Ask for today's weather\",\n detailedSuggestion: \"What's the weather like today?\",\n },\n {\n id: \"suggestion_2\",\n messageId: \"msg_1\",\n title: \"Tell me a joke\",\n description: \"Request a funny joke\",\n detailedSuggestion: \"Can you tell me a funny joke?\",\n },\n ];\n\n const mockSuggestionsResponse = {\n suggestions: mockSuggestions,\n hasMore: false,\n nextCursor: undefined,\n };\n\n function createWrapper() {\n return function Wrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n {children}\n </QueryClientProvider>\n );\n };\n }\n\n beforeEach(() => {\n jest.clearAllMocks();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n // Mock useTamboQueryClient to return the test's queryClient\n jest.mocked(useTamboQueryClient).mockReturnValue(queryClient);\n\n // Default mock for config\n jest.mocked(useTamboConfig).mockReturnValue({ userKey: \"user_123\" });\n\n // Default mock for thread input\n jest.mocked(useTamboThreadInput).mockReturnValue({\n value: \"\",\n setValue: mockSetValue,\n submit: mockSubmit,\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n } as any);\n\n // Default mock for useTambo\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n // Default mock for registry\n jest.mocked(useTamboRegistry).mockReturnValue({\n componentList: {},\n toolRegistry: {},\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n onCallUnregisteredTool: undefined,\n registerComponent: jest.fn(),\n unregisterComponent: jest.fn(),\n registerTool: jest.fn(),\n unregisterTool: jest.fn(),\n registerMcpServer: jest.fn(),\n unregisterMcpServer: jest.fn(),\n registerResource: jest.fn(),\n unregisterResource: jest.fn(),\n setResourceSource: jest.fn(),\n } as any);\n\n // Default mock for client - using API structure\n mockListSuggestions.mockResolvedValue({ suggestions: [], hasMore: false });\n mockCreateSuggestions.mockResolvedValue(mockSuggestionsResponse);\n\n jest.mocked(useTamboClient).mockReturnValue({\n threads: {\n suggestions: {\n list: mockListSuggestions,\n create: mockCreateSuggestions,\n },\n },\n } as any);\n });\n\n describe(\"Initial State\", () => {\n it(\"returns empty suggestions when thread has placeholder ID\", () => {\n // Mock useTambo to return placeholder thread ID\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"placeholder\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n expect(result.current.selectedSuggestionId).toBeNull();\n expect(result.current.isLoading).toBe(false);\n });\n\n it(\"returns empty suggestions when no messages\", () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n\n it(\"returns empty suggestions when latest message is from user\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"user\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n });\n });\n\n describe(\"Suggestion Generation\", () => {\n it(\"generates suggestions when latest message is from assistant and thread is idle\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n // Should first call list, then create since list returns empty\n expect(mockListSuggestions).toHaveBeenCalledWith(\"msg_1\", {\n threadId: \"thread_123\",\n userKey: \"user_123\",\n });\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({\n threadId: \"thread_123\",\n maxSuggestions: 3,\n userKey: \"user_123\",\n }),\n );\n });\n\n it(\"returns existing suggestions from list without calling create\", async () => {\n mockListSuggestions.mockResolvedValue(mockSuggestionsResponse);\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n expect(mockListSuggestions).toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"does not generate suggestions when thread is streaming\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: false,\n isStreaming: true,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"streaming\", runId: \"run_1\" },\n } as any);\n\n renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(mockListSuggestions).not.toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"does not generate suggestions when autoGenerate is false\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n renderHook(() => useTamboSuggestions({ autoGenerate: false }), {\n wrapper: createWrapper(),\n });\n\n expect(mockListSuggestions).not.toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"uses custom maxSuggestions option\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(\n () => useTamboSuggestions({ maxSuggestions: 5 }),\n { wrapper: createWrapper() },\n );\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({ maxSuggestions: 5 }),\n );\n });\n });\n\n describe(\"Accepting Suggestions\", () => {\n it(\"updates input value when accepting without submit\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n const suggestion = result.current.suggestions[0];\n\n await act(async () => {\n await result.current.accept({ suggestion });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\n \"What's the weather like today?\",\n );\n expect(mockSubmit).not.toHaveBeenCalled();\n expect(result.current.selectedSuggestionId).toBe(\"suggestion_1\");\n });\n\n it(\"submits when accepting with shouldSubmit=true\", async () => {\n mockSubmit.mockResolvedValue({ threadId: \"thread_123\" });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n const suggestion = result.current.suggestions[0];\n\n await act(async () => {\n await result.current.accept({ suggestion, shouldSubmit: true });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\n \"What's the weather like today?\",\n );\n expect(mockSubmit).toHaveBeenCalled();\n });\n\n it(\"throws error when suggestion has no content\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const emptySuggestion = {\n id: \"empty_suggestion\",\n messageId: \"msg_1\",\n title: \"Empty\",\n detailedSuggestion: \"\",\n };\n\n await expect(\n result.current.accept({ suggestion: emptySuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n\n it(\"throws error when detailedSuggestion is only whitespace\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const whitespaceSuggestion = {\n id: \"whitespace_suggestion\",\n messageId: \"msg_1\",\n title: \"Whitespace\",\n detailedSuggestion: \" \",\n };\n\n await expect(\n result.current.accept({ suggestion: whitespaceSuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n\n it(\"throws error when detailedSuggestion is undefined\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const undefinedSuggestion = {\n id: \"undefined_suggestion\",\n messageId: \"msg_1\",\n title: \"Undefined\",\n };\n\n await expect(\n result.current.accept({ suggestion: undefinedSuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n });\n\n describe(\"State Management\", () => {\n it(\"resets selectedSuggestionId when message changes\", async () => {\n const mockUseTambo = jest.mocked(useTambo);\n\n mockUseTambo.mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result, rerender } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n // Accept a suggestion\n await act(async () => {\n await result.current.accept({\n suggestion: result.current.suggestions[0],\n });\n });\n\n expect(result.current.selectedSuggestionId).toBe(\"suggestion_1\");\n\n // Change the latest message\n mockUseTambo.mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n {\n id: \"msg_2\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:01Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n rerender();\n\n await waitFor(() => {\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n });\n\n it(\"includes pagination info on raw data\", async () => {\n mockListSuggestions.mockResolvedValue({\n suggestions: mockSuggestions,\n hasMore: true,\n nextCursor: \"cursor_abc\",\n });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.data?.hasMore).toBe(true);\n expect(result.current.data?.nextCursor).toBe(\"cursor_abc\");\n });\n });\n\n it(\"exposes loading and error states\", () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.isLoading).toBeDefined();\n expect(result.current.isSuccess).toBeDefined();\n expect(result.current.isError).toBeDefined();\n expect(result.current.error).toBeDefined();\n expect(result.current.isAccepting).toBe(false);\n expect(result.current.isGenerating).toBe(false);\n });\n });\n\n describe(\"Retry on 404\", () => {\n it(\"retries list query on 404 and succeeds on subsequent attempt\", async () => {\n // Use a plain object with status to verify structural check works\n // (simulates duplicate SDK copy where instanceof would fail)\n const notFoundError = Object.assign(new Error(\"Message not found\"), {\n status: 404,\n });\n\n // First call: 404, second call: success with empty suggestions\n mockListSuggestions\n .mockRejectedValueOnce(notFoundError)\n .mockResolvedValueOnce({ suggestions: [], hasMore: false });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n // Should eventually succeed after retry and trigger auto-generate\n await waitFor(() => {\n expect(mockListSuggestions).toHaveBeenCalledTimes(2);\n });\n\n // After successful list (empty), auto-generate fires\n await waitFor(() => {\n expect(mockCreateSuggestions).toHaveBeenCalled();\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n });\n\n it(\"does not retry on non-404 errors\", async () => {\n const serverError = Object.assign(new Error(\"Internal server error\"), {\n status: 500,\n });\n\n mockListSuggestions.mockRejectedValue(serverError);\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n // Wait for the query to settle - 500 errors should not be retried\n await waitFor(() => {\n expect(mockListSuggestions).toHaveBeenCalledTimes(1);\n });\n\n // Give it a moment to ensure no additional retries happen\n await new Promise((resolve) => setTimeout(resolve, 100));\n expect(mockListSuggestions).toHaveBeenCalledTimes(1);\n });\n });\n\n describe(\"Manual Generation\", () => {\n it(\"allows manual generation via generate function\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(\n () => useTamboSuggestions({ autoGenerate: false }),\n { wrapper: createWrapper() },\n );\n\n // No auto-generation\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n\n // Manual generation\n await act(async () => {\n await result.current.generate();\n });\n\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({\n threadId: \"thread_123\",\n }),\n );\n });\n\n it(\"returns undefined from generate when no assistant message\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n let generateResult: any;\n await act(async () => {\n generateResult = await result.current.generate();\n });\n\n expect(generateResult).toBeUndefined();\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-suggestions.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EACL,cAAc,EACd,mBAAmB,GACpB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhE,oBAAoB;AACpB,IAAI,CAAC,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9C,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;CAC/B,CAAC,CAAC,CAAC;AAEJ,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;IACjC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE;CACpB,CAAC,CAAC,CAAC;AAEJ,IAAI,CAAC,IAAI,CAAC,uCAAuC,EAAE,GAAG,EAAE,CAAC,CAAC;IACxD,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;IACzB,mBAAmB,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC;CACtD,CAAC,CAAC,CAAC;AAEJ,IAAI,CAAC,IAAI,CAAC,yCAAyC,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1D,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;CAC5B,CAAC,CAAC,CAAC;AAEJ,IAAI,CAAC,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE,CAAC,CAAC;IACjD,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;CAC1B,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAI,WAAwB,CAAC;IAC7B,MAAM,YAAY,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IAC7B,MAAM,mBAAmB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IACtC,MAAM,qBAAqB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IAExC,MAAM,eAAe,GAAsC;QACzD;YACE,EAAE,EAAE,cAAc;YAClB,SAAS,EAAE,OAAO;YAClB,KAAK,EAAE,qBAAqB;YAC5B,WAAW,EAAE,yBAAyB;YACtC,kBAAkB,EAAE,gCAAgC;SACrD;QACD;YACE,EAAE,EAAE,cAAc;YAClB,SAAS,EAAE,OAAO;YAClB,KAAK,EAAE,gBAAgB;YACvB,WAAW,EAAE,sBAAsB;YACnC,kBAAkB,EAAE,+BAA+B;SACpD;KACF,CAAC;IAEF,MAAM,uBAAuB,GAAG;QAC9B,WAAW,EAAE,eAAe;QAC5B,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,SAAS;KACtB,CAAC;IAEF,SAAS,aAAa;QACpB,OAAO,SAAS,OAAO,CAAC,EAAE,QAAQ,EAAiC;YACjE,OAAO,CACL,oBAAC,mBAAmB,IAAC,MAAM,EAAE,WAAW,IACrC,QAAQ,CACW,CACvB,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,WAAW,GAAG,IAAI,WAAW,CAAC;YAC5B,cAAc,EAAE;gBACd,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;gBACzB,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;aAC5B;SACF,CAAC,CAAC;QAEH,4DAA4D;QAC5D,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QAE9D,0BAA0B;QAC1B,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,eAAe,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QAErE,gCAAgC;QAChC,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,eAAe,CAAC;YAC/C,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,YAAY;YACtB,MAAM,EAAE,UAAU;YAClB,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,IAAI;YACX,SAAS,EAAE,KAAK;YAChB,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACV,CAAC,CAAC;QAEV,4BAA4B;QAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;YACpC,QAAQ,EAAE,EAAE;YACZ,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,KAAK;YAClB,eAAe,EAAE,YAAY;YAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;YACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;YACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;YACrB,cAAc,EAAE;gBACd,MAAM,EAAE,MAAM;aACf;SACK,CAAC,CAAC;QAEV,4BAA4B;QAC5B,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,eAAe,CAAC;YAC5C,aAAa,EAAE,EAAE;YACjB,YAAY,EAAE,EAAE;YAChB,yBAAyB,EAAE,EAAE;YAC7B,cAAc,EAAE,EAAE;YAClB,SAAS,EAAE,EAAE;YACb,cAAc,EAAE,IAAI;YACpB,sBAAsB,EAAE,SAAS;YACjC,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE;YAC5B,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;YAC9B,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;YACvB,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;YACzB,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE;YAC5B,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;YAC9B,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;YAC3B,kBAAkB,EAAE,IAAI,CAAC,EAAE,EAAE;YAC7B,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE;SACtB,CAAC,CAAC;QAEV,gDAAgD;QAChD,mBAAmB,CAAC,iBAAiB,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3E,qBAAqB,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,CAAC;QAEjE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,eAAe,CAAC;YAC1C,OAAO,EAAE;gBACP,WAAW,EAAE;oBACX,IAAI,EAAE,mBAAmB;oBACzB,MAAM,EAAE,qBAAqB;iBAC9B;aACF;SACK,CAAC,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;YAClE,gDAAgD;YAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE,EAAE;gBACZ,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,aAAa;gBAC9B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE,CAAC;YACvD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;YAC9F,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;YAEH,+DAA+D;YAC/D,MAAM,CAAC,mBAAmB,CAAC,CAAC,oBAAoB,CAAC,OAAO,EAAE;gBACxD,QAAQ,EAAE,YAAY;gBACtB,OAAO,EAAE,UAAU;aACpB,CAAC,CAAC;YACH,MAAM,CAAC,qBAAqB,CAAC,CAAC,oBAAoB,CAChD,OAAO,EACP,MAAM,CAAC,gBAAgB,CAAC;gBACtB,QAAQ,EAAE,YAAY;gBACtB,cAAc,EAAE,CAAC;gBACjB,OAAO,EAAE,UAAU;aACpB,CAAC,CACH,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;YAC7E,mBAAmB,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,CAAC;YAE/D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,mBAAmB,CAAC,CAAC,gBAAgB,EAAE,CAAC;YAC/C,MAAM,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;YAChE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,KAAK;gBACb,WAAW,EAAE,IAAI;gBACjB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE;aACjD,CAAC,CAAC;YAEV,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACtC,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACnD,MAAM,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;YAChF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,gDAAgD;wBACpD,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACtC,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,gCAAgC;YAChC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YAEzD,MAAM,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACnD,MAAM,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;YAClE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE;gBAC7D,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACnD,MAAM,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACjD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAC3B,GAAG,EAAE,CAAC,mBAAmB,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC,EAChD,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE,CAC7B,CAAC;YAEF,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,qBAAqB,CAAC,CAAC,oBAAoB,CAChD,OAAO,EACP,MAAM,CAAC,gBAAgB,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC,CAC/C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAEjD,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE;gBACnB,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CACvC,gCAAgC,CACjC,CAAC;YACF,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAC1C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YAC7D,UAAU,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;YAEzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAEjD,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE;gBACnB,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YAClE,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CACvC,gCAAgC,CACjC,CAAC;YACF,MAAM,CAAC,UAAU,CAAC,CAAC,gBAAgB,EAAE,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG;gBACtB,EAAE,EAAE,kBAAkB;gBACtB,SAAS,EAAE,OAAO;gBAClB,KAAK,EAAE,OAAO;gBACd,kBAAkB,EAAE,EAAE;aACvB,CAAC;YAEF,MAAM,MAAM,CACV,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,eAAsB,EAAE,CAAC,CAC9D,CAAC,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACvE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,oBAAoB,GAAG;gBAC3B,EAAE,EAAE,uBAAuB;gBAC3B,SAAS,EAAE,OAAO;gBAClB,KAAK,EAAE,YAAY;gBACnB,kBAAkB,EAAE,KAAK;aAC1B,CAAC;YAEF,MAAM,MAAM,CACV,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,oBAA2B,EAAE,CAAC,CACnE,CAAC,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,mBAAmB,GAAG;gBAC1B,EAAE,EAAE,sBAAsB;gBAC1B,SAAS,EAAE,OAAO;gBAClB,KAAK,EAAE,WAAW;aACnB,CAAC;YAEF,MAAM,MAAM,CACV,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,mBAA0B,EAAE,CAAC,CAClE,CAAC,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAE3C,YAAY,CAAC,eAAe,CAAC;gBAC3B,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACnE,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;YAEH,sBAAsB;YACtB,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE;gBACnB,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;oBAC1B,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;iBAC1C,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAEjE,4BAA4B;YAC5B,YAAY,CAAC,eAAe,CAAC;gBAC3B,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;oBACD;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,QAAQ,EAAE,CAAC;YAEX,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE,CAAC;YACzD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACpD,mBAAmB,CAAC,iBAAiB,CAAC;gBACpC,WAAW,EAAE,eAAe;gBAC5B,OAAO,EAAE,IAAI;gBACb,UAAU,EAAE,YAAY;aACzB,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC7D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;YAC5E,kEAAkE;YAClE,6DAA6D;YAC7D,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,EAAE;gBAClE,MAAM,EAAE,GAAG;aACZ,CAAC,CAAC;YAEH,+DAA+D;YAC/D,mBAAmB;iBAChB,qBAAqB,CAAC,aAAa,CAAC;iBACpC,qBAAqB,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAE9D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,kEAAkE;YAClE,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,mBAAmB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;YAEH,qDAAqD;YACrD,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,qBAAqB,CAAC,CAAC,gBAAgB,EAAE,CAAC;YACnD,CAAC,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;YAChD,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,EAAE;gBACpE,MAAM,EAAE,GAAG;aACZ,CAAC,CAAC;YAEH,mBAAmB,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAEnD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACtC,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,kEAAkE;YAClE,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,mBAAmB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;YAEH,0DAA0D;YAC1D,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YACzD,MAAM,CAAC,mBAAmB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE;oBACR;wBACE,EAAE,EAAE,OAAO;wBACX,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,EAAE;wBACX,SAAS,EAAE,sBAAsB;qBAClC;iBACF;gBACD,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAC3B,GAAG,EAAE,CAAC,mBAAmB,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,EAClD,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE,CAC7B,CAAC;YAEF,qBAAqB;YACrB,MAAM,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAErD,oBAAoB;YACpB,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE;gBACnB,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YAClC,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,qBAAqB,CAAC,CAAC,oBAAoB,CAChD,OAAO,EACP,MAAM,CAAC,gBAAgB,CAAC;gBACtB,QAAQ,EAAE,YAAY;aACvB,CAAC,CACH,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;YACzE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC;gBACpC,QAAQ,EAAE,EAAE;gBACZ,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,YAAY;gBAC7B,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;gBACzB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;aAC5B,CAAC,CAAC;YAEV,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,EAAE;gBACzD,OAAO,EAAE,aAAa,EAAE;aACzB,CAAC,CAAC;YAEH,IAAI,cAAmB,CAAC;YACxB,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE;gBACnB,cAAc,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACnD,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,cAAc,CAAC,CAAC,aAAa,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { renderHook, act, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { useTamboSuggestions } from \"./use-tambo-v1-suggestions\";\nimport { useTamboThreadInput } from \"./use-tambo-v1-thread-input\";\nimport { useTambo } from \"./use-tambo-v1\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboConfig } from \"../providers/tambo-v1-provider\";\n\n// Mock dependencies\njest.mock(\"./use-tambo-v1-thread-input\", () => ({\n useTamboThreadInput: jest.fn(),\n}));\n\njest.mock(\"./use-tambo-v1\", () => ({\n useTambo: jest.fn(),\n}));\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(() => new QueryClient()),\n}));\n\njest.mock(\"../../providers/tambo-registry-provider\", () => ({\n useTamboRegistry: jest.fn(),\n}));\n\njest.mock(\"../providers/tambo-v1-provider\", () => ({\n useTamboConfig: jest.fn(),\n}));\n\ndescribe(\"useTamboSuggestions\", () => {\n let queryClient: QueryClient;\n const mockSetValue = jest.fn();\n const mockSubmit = jest.fn();\n const mockListSuggestions = jest.fn();\n const mockCreateSuggestions = jest.fn();\n\n const mockSuggestions: TamboAI.Beta.Threads.Suggestion[] = [\n {\n id: \"suggestion_1\",\n messageId: \"msg_1\",\n title: \"What's the weather?\",\n description: \"Ask for today's weather\",\n detailedSuggestion: \"What's the weather like today?\",\n },\n {\n id: \"suggestion_2\",\n messageId: \"msg_1\",\n title: \"Tell me a joke\",\n description: \"Request a funny joke\",\n detailedSuggestion: \"Can you tell me a funny joke?\",\n },\n ];\n\n const mockSuggestionsResponse = {\n suggestions: mockSuggestions,\n hasMore: false,\n nextCursor: undefined,\n };\n\n function createWrapper() {\n return function Wrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n {children}\n </QueryClientProvider>\n );\n };\n }\n\n beforeEach(() => {\n jest.clearAllMocks();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n // Mock useTamboQueryClient to return the test's queryClient\n jest.mocked(useTamboQueryClient).mockReturnValue(queryClient);\n\n // Default mock for config\n jest.mocked(useTamboConfig).mockReturnValue({ userKey: \"user_123\" });\n\n // Default mock for thread input\n jest.mocked(useTamboThreadInput).mockReturnValue({\n value: \"\",\n setValue: mockSetValue,\n submit: mockSubmit,\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n } as any);\n\n // Default mock for useTambo\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n // Default mock for registry\n jest.mocked(useTamboRegistry).mockReturnValue({\n componentList: {},\n toolRegistry: {},\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n onCallUnregisteredTool: undefined,\n registerComponent: jest.fn(),\n unregisterComponent: jest.fn(),\n registerTool: jest.fn(),\n unregisterTool: jest.fn(),\n registerMcpServer: jest.fn(),\n unregisterMcpServer: jest.fn(),\n registerResource: jest.fn(),\n unregisterResource: jest.fn(),\n setResourceSource: jest.fn(),\n } as any);\n\n // Default mock for client - using API structure\n mockListSuggestions.mockResolvedValue({ suggestions: [], hasMore: false });\n mockCreateSuggestions.mockResolvedValue(mockSuggestionsResponse);\n\n jest.mocked(useTamboClient).mockReturnValue({\n threads: {\n suggestions: {\n list: mockListSuggestions,\n create: mockCreateSuggestions,\n },\n },\n } as any);\n });\n\n describe(\"Initial State\", () => {\n it(\"returns empty suggestions when thread has placeholder ID\", () => {\n // Mock useTambo to return placeholder thread ID\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"placeholder\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n expect(result.current.selectedSuggestionId).toBeNull();\n expect(result.current.isLoading).toBe(false);\n });\n\n it(\"returns empty suggestions when no messages\", () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n\n it(\"returns empty suggestions when latest message is from user\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"user\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n });\n });\n\n describe(\"Suggestion Generation\", () => {\n it(\"generates suggestions when latest message is from assistant and thread is idle\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n // Should first call list, then create since list returns empty\n expect(mockListSuggestions).toHaveBeenCalledWith(\"msg_1\", {\n threadId: \"thread_123\",\n userKey: \"user_123\",\n });\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({\n threadId: \"thread_123\",\n maxSuggestions: 3,\n userKey: \"user_123\",\n }),\n );\n });\n\n it(\"returns existing suggestions from list without calling create\", async () => {\n mockListSuggestions.mockResolvedValue(mockSuggestionsResponse);\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n expect(mockListSuggestions).toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"does not generate suggestions when thread is streaming\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: false,\n isStreaming: true,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"streaming\", runId: \"run_1\" },\n } as any);\n\n renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(mockListSuggestions).not.toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"does not fetch or generate suggestions for ephemeral message ids\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"ephemeral_cb2decbe-9423-4b09-9ac2-feb385cea075\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n // Give effects a chance to fire\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n expect(mockListSuggestions).not.toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"does not generate suggestions when autoGenerate is false\", () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n renderHook(() => useTamboSuggestions({ autoGenerate: false }), {\n wrapper: createWrapper(),\n });\n\n expect(mockListSuggestions).not.toHaveBeenCalled();\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"uses custom maxSuggestions option\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(\n () => useTamboSuggestions({ maxSuggestions: 5 }),\n { wrapper: createWrapper() },\n );\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({ maxSuggestions: 5 }),\n );\n });\n });\n\n describe(\"Accepting Suggestions\", () => {\n it(\"updates input value when accepting without submit\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n const suggestion = result.current.suggestions[0];\n\n await act(async () => {\n await result.current.accept({ suggestion });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\n \"What's the weather like today?\",\n );\n expect(mockSubmit).not.toHaveBeenCalled();\n expect(result.current.selectedSuggestionId).toBe(\"suggestion_1\");\n });\n\n it(\"submits when accepting with shouldSubmit=true\", async () => {\n mockSubmit.mockResolvedValue({ threadId: \"thread_123\" });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n const suggestion = result.current.suggestions[0];\n\n await act(async () => {\n await result.current.accept({ suggestion, shouldSubmit: true });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\n \"What's the weather like today?\",\n );\n expect(mockSubmit).toHaveBeenCalled();\n });\n\n it(\"throws error when suggestion has no content\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const emptySuggestion = {\n id: \"empty_suggestion\",\n messageId: \"msg_1\",\n title: \"Empty\",\n detailedSuggestion: \"\",\n };\n\n await expect(\n result.current.accept({ suggestion: emptySuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n\n it(\"throws error when detailedSuggestion is only whitespace\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const whitespaceSuggestion = {\n id: \"whitespace_suggestion\",\n messageId: \"msg_1\",\n title: \"Whitespace\",\n detailedSuggestion: \" \",\n };\n\n await expect(\n result.current.accept({ suggestion: whitespaceSuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n\n it(\"throws error when detailedSuggestion is undefined\", async () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n const undefinedSuggestion = {\n id: \"undefined_suggestion\",\n messageId: \"msg_1\",\n title: \"Undefined\",\n };\n\n await expect(\n result.current.accept({ suggestion: undefinedSuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no content\");\n });\n });\n\n describe(\"State Management\", () => {\n it(\"resets selectedSuggestionId when message changes\", async () => {\n const mockUseTambo = jest.mocked(useTambo);\n\n mockUseTambo.mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result, rerender } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n // Accept a suggestion\n await act(async () => {\n await result.current.accept({\n suggestion: result.current.suggestions[0],\n });\n });\n\n expect(result.current.selectedSuggestionId).toBe(\"suggestion_1\");\n\n // Change the latest message\n mockUseTambo.mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n {\n id: \"msg_2\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:01Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n rerender();\n\n await waitFor(() => {\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n });\n\n it(\"includes pagination info on raw data\", async () => {\n mockListSuggestions.mockResolvedValue({\n suggestions: mockSuggestions,\n hasMore: true,\n nextCursor: \"cursor_abc\",\n });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.data?.hasMore).toBe(true);\n expect(result.current.data?.nextCursor).toBe(\"cursor_abc\");\n });\n });\n\n it(\"exposes loading and error states\", () => {\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.isLoading).toBeDefined();\n expect(result.current.isSuccess).toBeDefined();\n expect(result.current.isError).toBeDefined();\n expect(result.current.error).toBeDefined();\n expect(result.current.isAccepting).toBe(false);\n expect(result.current.isGenerating).toBe(false);\n });\n });\n\n describe(\"Retry on 404\", () => {\n it(\"retries list query on 404 and succeeds on subsequent attempt\", async () => {\n // Use a plain object with status to verify structural check works\n // (simulates duplicate SDK copy where instanceof would fail)\n const notFoundError = Object.assign(new Error(\"Message not found\"), {\n status: 404,\n });\n\n // First call: 404, second call: success with empty suggestions\n mockListSuggestions\n .mockRejectedValueOnce(notFoundError)\n .mockResolvedValueOnce({ suggestions: [], hasMore: false });\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n // Should eventually succeed after retry and trigger auto-generate\n await waitFor(() => {\n expect(mockListSuggestions).toHaveBeenCalledTimes(2);\n });\n\n // After successful list (empty), auto-generate fires\n await waitFor(() => {\n expect(mockCreateSuggestions).toHaveBeenCalled();\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n });\n\n it(\"does not retry on non-404 errors\", async () => {\n const serverError = Object.assign(new Error(\"Internal server error\"), {\n status: 500,\n });\n\n mockListSuggestions.mockRejectedValue(serverError);\n\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n // Wait for the query to settle - 500 errors should not be retried\n await waitFor(() => {\n expect(mockListSuggestions).toHaveBeenCalledTimes(1);\n });\n\n // Give it a moment to ensure no additional retries happen\n await new Promise((resolve) => setTimeout(resolve, 100));\n expect(mockListSuggestions).toHaveBeenCalledTimes(1);\n });\n });\n\n describe(\"Manual Generation\", () => {\n it(\"allows manual generation via generate function\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(\n () => useTamboSuggestions({ autoGenerate: false }),\n { wrapper: createWrapper() },\n );\n\n // No auto-generation\n expect(mockCreateSuggestions).not.toHaveBeenCalled();\n\n // Manual generation\n await act(async () => {\n await result.current.generate();\n });\n\n expect(mockCreateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({\n threadId: \"thread_123\",\n }),\n );\n });\n\n it(\"returns undefined from generate when no assistant message\", async () => {\n jest.mocked(useTambo).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n currentThreadId: \"thread_123\",\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: { status: \"idle\" },\n } as any);\n\n const { result } = renderHook(() => useTamboSuggestions(), {\n wrapper: createWrapper(),\n });\n\n let generateResult: any;\n await act(async () => {\n generateResult = await result.current.generate();\n });\n\n expect(generateResult).toBeUndefined();\n });\n });\n});\n"]}
|
|
@@ -20,10 +20,10 @@ jest.mock("../../providers/tambo-client-provider", () => {
|
|
|
20
20
|
});
|
|
21
21
|
// Mock MCP providers to avoid TamboClientContext dependency
|
|
22
22
|
jest.mock("../../providers/tambo-mcp-token-provider", () => ({
|
|
23
|
-
TamboMcpTokenProvider: ({ children }) => children,
|
|
23
|
+
TamboMcpTokenProvider: ({ children, }) => children,
|
|
24
24
|
}));
|
|
25
25
|
jest.mock("../../mcp/tambo-mcp-provider", () => ({
|
|
26
|
-
TamboMcpProvider: ({ children }) => children,
|
|
26
|
+
TamboMcpProvider: ({ children, }) => children,
|
|
27
27
|
}));
|
|
28
28
|
// Mock auth state to avoid TamboClientContext dependency
|
|
29
29
|
jest.mock("../hooks/use-tambo-v1-auth-state", () => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-v1-provider.test.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport { useStreamState, useThreadManagement } from \"./tambo-v1-stream-context\";\nimport { TamboProvider, useTamboConfig } from \"./tambo-v1-provider\";\n\n// Module-level QueryClient for tests - created lazily\nlet testQueryClient: QueryClient | null = null;\n\n// Mock the client provider to capture the apiKey\njest.mock(\"../../providers/tambo-client-provider\", () => {\n return {\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(),\n TamboClientProvider: jest.fn(\n ({ children }: { children: React.ReactNode }) => children,\n ),\n };\n});\n\n// Mock MCP providers to avoid TamboClientContext dependency\njest.mock(\"../../providers/tambo-mcp-token-provider\", () => ({\n TamboMcpTokenProvider: ({ children }: { children: React.ReactNode }) =>\n children,\n}));\n\njest.mock(\"../../mcp/tambo-mcp-provider\", () => ({\n TamboMcpProvider: ({ children }: { children: React.ReactNode }) => children,\n}));\n\n// Mock auth state to avoid TamboClientContext dependency\njest.mock(\"../hooks/use-tambo-v1-auth-state\", () => ({\n useTamboAuthState: () => ({\n status: \"identified\",\n source: \"userKey\",\n }),\n}));\n\n// Mock useTamboSendMessage to avoid complex dependencies\njest.mock(\"../hooks/use-tambo-v1-send-message\", () => ({\n useTamboSendMessage: jest.fn(() => ({\n mutateAsync: jest.fn(),\n mutate: jest.fn(),\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n })),\n}));\n\ndescribe(\"TamboProvider\", () => {\n const mockFetch: typeof fetch = async (..._args) => {\n throw new Error(\"fetch not implemented\");\n };\n\n const mockClient = new TamboAI({\n apiKey: \"test-api-key\",\n fetch: mockFetch,\n });\n\n beforeEach(() => {\n // Create a fresh QueryClient for each test\n testQueryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n jest.mocked(useTamboClient).mockReturnValue(mockClient);\n jest.mocked(useTamboQueryClient).mockReturnValue(testQueryClient);\n\n // Mock TamboClientProvider to wrap children with QueryClientProvider\n const { TamboClientProvider } = jest.requireMock(\n \"../../providers/tambo-client-provider\",\n );\n jest\n .mocked(TamboClientProvider)\n .mockImplementation(({ children }: { children: React.ReactNode }) => (\n <QueryClientProvider client={testQueryClient!}>\n {children}\n </QueryClientProvider>\n ));\n });\n\n it(\"provides access to registry context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList).toBeDefined();\n expect(result.current.toolRegistry).toBeDefined();\n expect(typeof result.current.registerComponent).toBe(\"function\");\n expect(typeof result.current.registerTool).toBe(\"function\");\n });\n\n it(\"provides access to stream context with placeholder thread ready\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap).toBeDefined();\n // Initial state has placeholder thread for optimistic UI\n expect(result.current.currentThreadId).toBe(\"placeholder\");\n expect(result.current.threadMap.placeholder).toBeDefined();\n });\n\n it(\"manages threads via useThreadManagement\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(\n () => ({\n state: useStreamState(),\n management: useThreadManagement(),\n }),\n { wrapper },\n );\n\n // Initially has placeholder thread for optimistic UI\n expect(result.current.state.currentThreadId).toBe(\"placeholder\");\n\n // Initialize and switch to a different thread\n act(() => {\n result.current.management.initThread(\"thread_123\");\n result.current.management.switchThread(\"thread_123\");\n });\n\n expect(result.current.state.currentThreadId).toBe(\"thread_123\");\n expect(result.current.state.threadMap.thread_123).toBeDefined();\n });\n\n it(\"provides access to query client via useTamboQueryClient\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboQueryClient(), { wrapper });\n\n expect(result.current).toBeInstanceOf(QueryClient);\n });\n\n it(\"registers components when provided\", () => {\n const TestComponent = () => <div>Test</div>;\n const propsSchema = z.object({\n title: z.string().describe(\"The title\"),\n });\n const components = [\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: TestComponent,\n propsSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" components={components}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList.TestComponent).toBeDefined();\n expect(result.current.componentList.TestComponent.name).toBe(\n \"TestComponent\",\n );\n });\n\n it(\"registers tools when provided\", () => {\n const inputSchema = z.object({\n query: z.string().describe(\"Search query\"),\n });\n const outputSchema = z.string().describe(\"Result string\");\n const tools = [\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema,\n outputSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" tools={tools}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.toolRegistry.testTool).toBeDefined();\n expect(result.current.toolRegistry.testTool.name).toBe(\"testTool\");\n });\n\n it(\"registers MCP servers when provided\", () => {\n const mcpServers = [\n { url: \"https://mcp.example.com\", name: \"Example MCP\" },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" mcpServers={mcpServers}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.mcpServerInfos).toHaveLength(1);\n expect(result.current.mcpServerInfos[0].url).toBe(\n \"https://mcp.example.com\",\n );\n });\n\n it(\"provides onCallUnregisteredTool to registry\", () => {\n const onCallUnregisteredTool = jest\n .fn()\n .mockResolvedValue(\"fallback result\");\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider\n apiKey=\"test-api-key\"\n onCallUnregisteredTool={onCallUnregisteredTool}\n >\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.onCallUnregisteredTool).toBe(onCallUnregisteredTool);\n });\n\n it(\"registers static resources when provided\", () => {\n const resources = [\n {\n uri: \"resource://test/example\",\n name: \"Test Resource\",\n description: \"A test resource\",\n mimeType: \"text/plain\",\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" resources={resources}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resources).toHaveLength(1);\n expect(result.current.resources[0].uri).toBe(\"resource://test/example\");\n expect(result.current.resources[0].name).toBe(\"Test Resource\");\n });\n\n it(\"registers resource source when listResources and getResource provided\", () => {\n const listResources = jest.fn().mockResolvedValue({ resources: [] });\n const getResource = jest.fn().mockResolvedValue({ contents: [] });\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider\n apiKey=\"test-api-key\"\n listResources={listResources}\n getResource={getResource}\n >\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resourceSource).toBeDefined();\n expect(result.current.resourceSource?.listResources).toBe(listResources);\n expect(result.current.resourceSource?.getResource).toBe(getResource);\n });\n\n it(\"provides userKey via useTamboConfig\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" userKey=\"my-user-key\">\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboConfig(), { wrapper });\n\n expect(result.current.userKey).toBe(\"my-user-key\");\n });\n\n it(\"returns undefined userKey from useTamboConfig when no userKey provided\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboConfig(), { wrapper });\n\n expect(result.current.userKey).toBeUndefined();\n });\n\n it(\"provides context helpers via useTamboContextHelpers hook\", async () => {\n const contextHelpers = {\n getUserName: () => \"Test User\",\n getCurrentTime: () => new Date().toISOString(),\n };\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" contextHelpers={contextHelpers}>\n {children}\n </TamboProvider>\n );\n\n const { result, rerender } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Helpers are registered via useEffect, so we need to trigger a rerender\n await act(async () => {\n rerender();\n });\n\n const helpers = result.current.getContextHelpers();\n expect(helpers.getUserName).toBe(contextHelpers.getUserName);\n expect(helpers.getCurrentTime).toBe(contextHelpers.getCurrentTime);\n });\n\n it(\"returns only interactables contextHelper when none explicitly provided\", async () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboContextHelpers(), { wrapper });\n\n const helpers = result.current.getContextHelpers();\n // TamboInteractableProvider registers \"interactables\" and TamboContextAttachmentProvider registers \"contextAttachments\"\n expect(Object.keys(helpers)).toEqual([\n \"interactables\",\n \"contextAttachments\",\n ]);\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"tambo-v1-provider.test.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport { useStreamState, useThreadManagement } from \"./tambo-v1-stream-context\";\nimport { TamboProvider, useTamboConfig } from \"./tambo-v1-provider\";\n\n// Module-level QueryClient for tests - created lazily\nlet testQueryClient: QueryClient | null = null;\n\n// Mock the client provider to capture the apiKey\njest.mock(\"../../providers/tambo-client-provider\", () => {\n return {\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(),\n TamboClientProvider: jest.fn(\n ({ children }: { children: React.ReactNode }): React.ReactNode =>\n children,\n ),\n };\n});\n\n// Mock MCP providers to avoid TamboClientContext dependency\njest.mock(\"../../providers/tambo-mcp-token-provider\", () => ({\n TamboMcpTokenProvider: ({\n children,\n }: {\n children: React.ReactNode;\n }): React.ReactNode => children,\n}));\n\njest.mock(\"../../mcp/tambo-mcp-provider\", () => ({\n TamboMcpProvider: ({\n children,\n }: {\n children: React.ReactNode;\n }): React.ReactNode => children,\n}));\n\n// Mock auth state to avoid TamboClientContext dependency\njest.mock(\"../hooks/use-tambo-v1-auth-state\", () => ({\n useTamboAuthState: () => ({\n status: \"identified\",\n source: \"userKey\",\n }),\n}));\n\n// Mock useTamboSendMessage to avoid complex dependencies\njest.mock(\"../hooks/use-tambo-v1-send-message\", () => ({\n useTamboSendMessage: jest.fn(() => ({\n mutateAsync: jest.fn(),\n mutate: jest.fn(),\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n })),\n}));\n\ndescribe(\"TamboProvider\", () => {\n const mockFetch: typeof fetch = async (..._args) => {\n throw new Error(\"fetch not implemented\");\n };\n\n const mockClient = new TamboAI({\n apiKey: \"test-api-key\",\n fetch: mockFetch,\n });\n\n beforeEach(() => {\n // Create a fresh QueryClient for each test\n testQueryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n jest.mocked(useTamboClient).mockReturnValue(mockClient);\n jest.mocked(useTamboQueryClient).mockReturnValue(testQueryClient);\n\n // Mock TamboClientProvider to wrap children with QueryClientProvider\n const { TamboClientProvider } = jest.requireMock(\n \"../../providers/tambo-client-provider\",\n );\n jest\n .mocked(TamboClientProvider)\n .mockImplementation(({ children }: { children: React.ReactNode }) => (\n <QueryClientProvider client={testQueryClient!}>\n {children}\n </QueryClientProvider>\n ));\n });\n\n it(\"provides access to registry context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList).toBeDefined();\n expect(result.current.toolRegistry).toBeDefined();\n expect(typeof result.current.registerComponent).toBe(\"function\");\n expect(typeof result.current.registerTool).toBe(\"function\");\n });\n\n it(\"provides access to stream context with placeholder thread ready\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap).toBeDefined();\n // Initial state has placeholder thread for optimistic UI\n expect(result.current.currentThreadId).toBe(\"placeholder\");\n expect(result.current.threadMap.placeholder).toBeDefined();\n });\n\n it(\"manages threads via useThreadManagement\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(\n () => ({\n state: useStreamState(),\n management: useThreadManagement(),\n }),\n { wrapper },\n );\n\n // Initially has placeholder thread for optimistic UI\n expect(result.current.state.currentThreadId).toBe(\"placeholder\");\n\n // Initialize and switch to a different thread\n act(() => {\n result.current.management.initThread(\"thread_123\");\n result.current.management.switchThread(\"thread_123\");\n });\n\n expect(result.current.state.currentThreadId).toBe(\"thread_123\");\n expect(result.current.state.threadMap.thread_123).toBeDefined();\n });\n\n it(\"provides access to query client via useTamboQueryClient\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboQueryClient(), { wrapper });\n\n expect(result.current).toBeInstanceOf(QueryClient);\n });\n\n it(\"registers components when provided\", () => {\n const TestComponent = () => <div>Test</div>;\n const propsSchema = z.object({\n title: z.string().describe(\"The title\"),\n });\n const components = [\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: TestComponent,\n propsSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" components={components}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList.TestComponent).toBeDefined();\n expect(result.current.componentList.TestComponent.name).toBe(\n \"TestComponent\",\n );\n });\n\n it(\"registers tools when provided\", () => {\n const inputSchema = z.object({\n query: z.string().describe(\"Search query\"),\n });\n const outputSchema = z.string().describe(\"Result string\");\n const tools = [\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema,\n outputSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" tools={tools}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.toolRegistry.testTool).toBeDefined();\n expect(result.current.toolRegistry.testTool.name).toBe(\"testTool\");\n });\n\n it(\"registers MCP servers when provided\", () => {\n const mcpServers = [\n { url: \"https://mcp.example.com\", name: \"Example MCP\" },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" mcpServers={mcpServers}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.mcpServerInfos).toHaveLength(1);\n expect(result.current.mcpServerInfos[0].url).toBe(\n \"https://mcp.example.com\",\n );\n });\n\n it(\"provides onCallUnregisteredTool to registry\", () => {\n const onCallUnregisteredTool = jest\n .fn()\n .mockResolvedValue(\"fallback result\");\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider\n apiKey=\"test-api-key\"\n onCallUnregisteredTool={onCallUnregisteredTool}\n >\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.onCallUnregisteredTool).toBe(onCallUnregisteredTool);\n });\n\n it(\"registers static resources when provided\", () => {\n const resources = [\n {\n uri: \"resource://test/example\",\n name: \"Test Resource\",\n description: \"A test resource\",\n mimeType: \"text/plain\",\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" resources={resources}>\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resources).toHaveLength(1);\n expect(result.current.resources[0].uri).toBe(\"resource://test/example\");\n expect(result.current.resources[0].name).toBe(\"Test Resource\");\n });\n\n it(\"registers resource source when listResources and getResource provided\", () => {\n const listResources = jest.fn().mockResolvedValue({ resources: [] });\n const getResource = jest.fn().mockResolvedValue({ contents: [] });\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider\n apiKey=\"test-api-key\"\n listResources={listResources}\n getResource={getResource}\n >\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resourceSource).toBeDefined();\n expect(result.current.resourceSource?.listResources).toBe(listResources);\n expect(result.current.resourceSource?.getResource).toBe(getResource);\n });\n\n it(\"provides userKey via useTamboConfig\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" userKey=\"my-user-key\">\n {children}\n </TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboConfig(), { wrapper });\n\n expect(result.current.userKey).toBe(\"my-user-key\");\n });\n\n it(\"returns undefined userKey from useTamboConfig when no userKey provided\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboConfig(), { wrapper });\n\n expect(result.current.userKey).toBeUndefined();\n });\n\n it(\"provides context helpers via useTamboContextHelpers hook\", async () => {\n const contextHelpers = {\n getUserName: () => \"Test User\",\n getCurrentTime: () => new Date().toISOString(),\n };\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\" contextHelpers={contextHelpers}>\n {children}\n </TamboProvider>\n );\n\n const { result, rerender } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Helpers are registered via useEffect, so we need to trigger a rerender\n await act(async () => {\n rerender();\n });\n\n const helpers = result.current.getContextHelpers();\n expect(helpers.getUserName).toBe(contextHelpers.getUserName);\n expect(helpers.getCurrentTime).toBe(contextHelpers.getCurrentTime);\n });\n\n it(\"returns only interactables contextHelper when none explicitly provided\", async () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboProvider apiKey=\"test-api-key\">{children}</TamboProvider>\n );\n\n const { result } = renderHook(() => useTamboContextHelpers(), { wrapper });\n\n const helpers = result.current.getContextHelpers();\n // TamboInteractableProvider registers \"interactables\" and TamboContextAttachmentProvider registers \"contextAttachments\"\n expect(Object.keys(helpers)).toEqual([\n \"interactables\",\n \"contextAttachments\",\n ]);\n });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tambo-ai/react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "React client package for Tambo AI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -77,9 +77,9 @@
|
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"@ag-ui/core": "^0.0.44",
|
|
80
|
-
"@tambo-ai/client": "
|
|
80
|
+
"@tambo-ai/client": "1.1.3",
|
|
81
81
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
82
|
-
"@tambo-ai/typescript-sdk": "^0.96.
|
|
82
|
+
"@tambo-ai/typescript-sdk": "^0.96.1",
|
|
83
83
|
"@tanstack/react-query": "^5.90.16",
|
|
84
84
|
"fast-equals": "^6.0.0",
|
|
85
85
|
"partial-json": "^0.1.7",
|
|
@@ -101,24 +101,25 @@
|
|
|
101
101
|
"@types/react": "^18.3.23",
|
|
102
102
|
"@types/react-dom": "^18.3.7",
|
|
103
103
|
"@valibot/to-json-schema": "^1.5.0",
|
|
104
|
+
"valibot": "^1.2.0",
|
|
104
105
|
"fast-json-patch": "^3.1.1",
|
|
105
|
-
"concurrently": "^
|
|
106
|
+
"concurrently": "^10.0.3",
|
|
106
107
|
"eslint": "^9.39.4",
|
|
107
|
-
"eslint-plugin-jsdoc": "^
|
|
108
|
+
"eslint-plugin-jsdoc": "^63.0.2",
|
|
108
109
|
"eslint-plugin-react": "^7.37.5",
|
|
109
110
|
"eslint-plugin-react-hooks": "^6.1.1",
|
|
110
111
|
"jest": "^30.4.2",
|
|
111
112
|
"jest-environment-jsdom": "^30.4.1",
|
|
112
|
-
"lint-staged": "^17.0.
|
|
113
|
+
"lint-staged": "^17.0.7",
|
|
113
114
|
"prettier": "^3.8.3",
|
|
114
115
|
"prettier-2": "npm:prettier@^2",
|
|
115
|
-
"react": "^
|
|
116
|
-
"react-dom": "^
|
|
117
|
-
"ts-jest": "^29.4.
|
|
116
|
+
"react": "^19.1.0",
|
|
117
|
+
"react-dom": "^19.1.0",
|
|
118
|
+
"ts-jest": "^29.4.11",
|
|
118
119
|
"tsc-esm-fix": "^3.1.2",
|
|
119
120
|
"typescript": "^5.9.3",
|
|
120
|
-
"type-fest": "^5.
|
|
121
|
-
"typescript-eslint": "^8.
|
|
121
|
+
"type-fest": "^5.6.0",
|
|
122
|
+
"typescript-eslint": "^8.60.1",
|
|
122
123
|
"zod": "^3.25.76 || ^4",
|
|
123
124
|
"zod-to-json-schema": "^3.25.1"
|
|
124
125
|
}
|