@tambo-ai/react 0.72.0 → 0.73.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-messages.test.js +22 -9
- package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +1 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.js +9 -2
- package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js +22 -9
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts +91 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.js +152 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.d.ts +2 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js +511 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts +6 -57
- package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.js +7 -67
- package/dist/v1/hooks/use-tambo-v1-thread-input.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +201 -72
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +6 -4
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.js +2 -2
- package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +2 -2
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.test.js +16 -7
- package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/dist/v1/index.d.ts +22 -13
- package/dist/v1/index.d.ts.map +1 -1
- package/dist/v1/index.js +31 -39
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts +27 -9
- package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.js +22 -11
- package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.test.js +27 -10
- package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.d.ts +19 -10
- package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.js +43 -53
- package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.test.js +94 -19
- package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts +74 -0
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -0
- package/dist/v1/providers/tambo-v1-stub-provider.js +212 -0
- package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -0
- package/dist/v1/providers/tambo-v1-stub-provider.test.d.ts +2 -0
- package/dist/v1/providers/tambo-v1-stub-provider.test.d.ts.map +1 -0
- package/dist/v1/providers/tambo-v1-stub-provider.test.js +162 -0
- package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -0
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +105 -0
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -0
- package/dist/v1/providers/tambo-v1-thread-input-provider.js +191 -0
- package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -0
- package/dist/v1/utils/component-renderer.d.ts +15 -67
- package/dist/v1/utils/component-renderer.d.ts.map +1 -1
- package/dist/v1/utils/component-renderer.js +3 -149
- package/dist/v1/utils/component-renderer.js.map +1 -1
- package/dist/v1/utils/component-renderer.test.js +15 -350
- package/dist/v1/utils/component-renderer.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.test.js +22 -9
- package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +1 -0
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.js +9 -2
- package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js +22 -9
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts +91 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.js +149 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.d.ts +2 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js +506 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +6 -57
- package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.js +5 -66
- package/esm/v1/hooks/use-tambo-v1-thread-input.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +199 -73
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +6 -4
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.js +2 -2
- package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +2 -2
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.test.js +16 -7
- package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/esm/v1/index.d.ts +22 -13
- package/esm/v1/index.d.ts.map +1 -1
- package/esm/v1/index.js +23 -18
- package/esm/v1/index.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts +27 -9
- package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.js +20 -10
- package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.test.js +28 -11
- package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.d.ts +19 -10
- package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js +44 -54
- package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.test.js +95 -20
- package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts +74 -0
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -0
- package/esm/v1/providers/tambo-v1-stub-provider.js +176 -0
- package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -0
- package/esm/v1/providers/tambo-v1-stub-provider.test.d.ts +2 -0
- package/esm/v1/providers/tambo-v1-stub-provider.test.d.ts.map +1 -0
- package/esm/v1/providers/tambo-v1-stub-provider.test.js +157 -0
- package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -0
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +105 -0
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -0
- package/esm/v1/providers/tambo-v1-thread-input-provider.js +153 -0
- package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -0
- package/esm/v1/utils/component-renderer.d.ts +15 -67
- package/esm/v1/utils/component-renderer.d.ts.map +1 -1
- package/esm/v1/utils/component-renderer.js +4 -146
- package/esm/v1/utils/component-renderer.js.map +1 -1
- package/esm/v1/utils/component-renderer.test.js +16 -351
- package/esm/v1/utils/component-renderer.test.js.map +1 -1
- package/package.json +2 -2
|
@@ -11,6 +11,7 @@ import { asTamboCustomEvent } from "../types/event";
|
|
|
11
11
|
import { useTamboClient } from "../../providers/tambo-client-provider";
|
|
12
12
|
import { TamboRegistryContext, } from "../../providers/tambo-registry-provider";
|
|
13
13
|
import { useStreamDispatch } from "../providers/tambo-v1-stream-context";
|
|
14
|
+
import { useTamboV1Config } from "../providers/tambo-v1-provider";
|
|
14
15
|
import { toAvailableComponents, toAvailableTools, } from "../utils/registry-conversion";
|
|
15
16
|
import { handleEventStream } from "../utils/stream-handler";
|
|
16
17
|
import { executeAllPendingTools } from "../utils/tool-executor";
|
|
@@ -25,7 +26,7 @@ import { ToolCallTracker } from "../utils/tool-call-tracker";
|
|
|
25
26
|
* @returns The continuation stream to process
|
|
26
27
|
*/
|
|
27
28
|
async function executeToolsAndContinue(params) {
|
|
28
|
-
const { event, toolTracker, registry, client, threadId, runId } = params;
|
|
29
|
+
const { event, toolTracker, registry, client, threadId, runId, userKey } = params;
|
|
29
30
|
const { pendingToolCallIds } = event.value;
|
|
30
31
|
const toolCallsToExecute = toolTracker.getToolCallsById(pendingToolCallIds);
|
|
31
32
|
// Execute tools
|
|
@@ -41,6 +42,7 @@ async function executeToolsAndContinue(params) {
|
|
|
41
42
|
previousRunId: runId,
|
|
42
43
|
availableComponents: toAvailableComponents(registry.componentList),
|
|
43
44
|
tools: toAvailableTools(registry.toolRegistry),
|
|
45
|
+
userKey,
|
|
44
46
|
});
|
|
45
47
|
}
|
|
46
48
|
/**
|
|
@@ -52,7 +54,7 @@ async function executeToolsAndContinue(params) {
|
|
|
52
54
|
* @returns The stream and initial thread ID (undefined if creating new thread)
|
|
53
55
|
*/
|
|
54
56
|
export async function createRunStream(params) {
|
|
55
|
-
const { client, threadId, message, registry } = params;
|
|
57
|
+
const { client, threadId, message, registry, userKey } = params;
|
|
56
58
|
// Convert registry components/tools to v1 API format
|
|
57
59
|
const availableComponents = toAvailableComponents(registry.componentList);
|
|
58
60
|
const availableTools = toAvailableTools(registry.toolRegistry);
|
|
@@ -62,6 +64,7 @@ export async function createRunStream(params) {
|
|
|
62
64
|
message,
|
|
63
65
|
availableComponents,
|
|
64
66
|
tools: availableTools,
|
|
67
|
+
userKey,
|
|
65
68
|
});
|
|
66
69
|
return { stream, initialThreadId: threadId };
|
|
67
70
|
}
|
|
@@ -71,6 +74,7 @@ export async function createRunStream(params) {
|
|
|
71
74
|
message,
|
|
72
75
|
availableComponents,
|
|
73
76
|
tools: availableTools,
|
|
77
|
+
thread: userKey ? { userKey } : undefined,
|
|
74
78
|
});
|
|
75
79
|
// threadId will be extracted from first event (RUN_STARTED)
|
|
76
80
|
return { stream, initialThreadId: undefined };
|
|
@@ -123,6 +127,7 @@ export async function createRunStream(params) {
|
|
|
123
127
|
export function useTamboV1SendMessage(threadId) {
|
|
124
128
|
const client = useTamboClient();
|
|
125
129
|
const dispatch = useStreamDispatch();
|
|
130
|
+
const { userKey } = useTamboV1Config();
|
|
126
131
|
const registry = useContext(TamboRegistryContext);
|
|
127
132
|
const queryClient = useQueryClient();
|
|
128
133
|
if (!registry) {
|
|
@@ -138,6 +143,7 @@ export function useTamboV1SendMessage(threadId) {
|
|
|
138
143
|
threadId,
|
|
139
144
|
message,
|
|
140
145
|
registry,
|
|
146
|
+
userKey,
|
|
141
147
|
});
|
|
142
148
|
let actualThreadId = initialThreadId;
|
|
143
149
|
let runId;
|
|
@@ -187,6 +193,7 @@ export function useTamboV1SendMessage(threadId) {
|
|
|
187
193
|
client,
|
|
188
194
|
threadId: actualThreadId,
|
|
189
195
|
runId,
|
|
196
|
+
userKey,
|
|
190
197
|
});
|
|
191
198
|
}
|
|
192
199
|
return { threadId: actualThreadId };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-send-message.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-send-message.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * Send Message Hook for v1 API\n *\n * React Query mutation hook for sending messages and handling streaming responses.\n */\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useContext } from \"react\";\nimport { EventType, type RunErrorEvent } from \"@ag-ui/core\";\nimport { asTamboCustomEvent, type RunAwaitingInputEvent } from \"../types/event\";\nimport type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport type { Stream } from \"@tambo-ai/typescript-sdk/core/streaming\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport {\n TamboRegistryContext,\n type TamboRegistryContext as TamboRegistry,\n} from \"../../providers/tambo-registry-provider\";\nimport { useStreamDispatch } from \"../providers/tambo-v1-stream-context\";\nimport type { InputMessage } from \"../types/message\";\nimport {\n toAvailableComponents,\n toAvailableTools,\n} from \"../utils/registry-conversion\";\nimport { handleEventStream } from \"../utils/stream-handler\";\nimport { executeAllPendingTools } from \"../utils/tool-executor\";\nimport { ToolCallTracker } from \"../utils/tool-call-tracker\";\n\n/**\n * Options for sending a message\n */\nexport interface SendMessageOptions {\n /**\n * The message to send\n */\n message: InputMessage;\n\n /**\n * Enable debug logging for the stream\n */\n debug?: boolean;\n}\n\n/**\n * Parameters for creating a run stream\n */\nexport interface CreateRunStreamParams {\n client: TamboAI;\n threadId: string | undefined;\n message: InputMessage;\n registry: TamboRegistry;\n}\n\n/**\n * Stream types from the SDK\n */\ntype RunStream = Stream<TamboAI.Threads.Runs.RunRunResponse>;\ntype CreateStream = Stream<TamboAI.Threads.Runs.RunCreateResponse>;\n\n/**\n * Result from creating a run stream\n */\nexport interface CreateRunStreamResult {\n stream: RunStream | CreateStream;\n initialThreadId: string | undefined;\n}\n\n/**\n * Parameters for executing tools and continuing the run\n */\ninterface ExecuteToolsParams {\n event: RunAwaitingInputEvent;\n toolTracker: ToolCallTracker;\n registry: TamboRegistry;\n client: TamboAI;\n threadId: string;\n runId: string;\n}\n\n/**\n * Executes pending tools and returns a continuation stream.\n *\n * This function does NOT process the continuation stream - it just executes\n * the tools and returns the new stream for the caller to process. This enables\n * the flat loop pattern that correctly handles multi-round tool execution.\n * @param params - The parameters for tool execution\n * @returns The continuation stream to process\n */\nasync function executeToolsAndContinue(\n params: ExecuteToolsParams,\n): Promise<RunStream> {\n const { event, toolTracker, registry, client, threadId, runId } = params;\n\n const { pendingToolCallIds } = event.value;\n const toolCallsToExecute = toolTracker.getToolCallsById(pendingToolCallIds);\n\n // Execute tools\n const toolResults = await executeAllPendingTools(\n toolCallsToExecute,\n registry.toolRegistry,\n );\n\n // Clear executed tool calls before continuing\n toolTracker.clearToolCalls(pendingToolCallIds);\n\n // Return the continuation stream (caller will process it)\n return await client.threads.runs.run(threadId, {\n message: {\n role: \"user\",\n content: toolResults,\n },\n previousRunId: runId,\n availableComponents: toAvailableComponents(registry.componentList),\n tools: toAvailableTools(registry.toolRegistry),\n });\n}\n\n/**\n * Creates a run stream by calling the appropriate API method.\n *\n * If threadId is provided, runs on existing thread via client.threads.runs.run().\n * If no threadId, creates new thread via client.threads.runs.create().\n * @param params - The parameters for creating the run stream\n * @returns The stream and initial thread ID (undefined if creating new thread)\n */\nexport async function createRunStream(\n params: CreateRunStreamParams,\n): Promise<CreateRunStreamResult> {\n const { client, threadId, message, registry } = params;\n\n // Convert registry components/tools to v1 API format\n const availableComponents = toAvailableComponents(registry.componentList);\n const availableTools = toAvailableTools(registry.toolRegistry);\n\n if (threadId) {\n // Run on existing thread\n const stream = await client.threads.runs.run(threadId, {\n message,\n availableComponents,\n tools: availableTools,\n });\n return { stream, initialThreadId: threadId };\n } else {\n // Create new thread\n const stream = await client.threads.runs.create({\n message,\n availableComponents,\n tools: availableTools,\n });\n // threadId will be extracted from first event (RUN_STARTED)\n return { stream, initialThreadId: undefined };\n }\n}\n\n/**\n * Hook to send a message and handle streaming responses.\n *\n * This hook handles two scenarios:\n * - If threadId provided: runs on existing thread via client.threads.runs.run()\n * - If no threadId: creates new thread via client.threads.runs.create()\n *\n * The hook:\n * - Sends a user message to the API\n * - Streams AG-UI events in real-time\n * - Dispatches events to the stream reducer\n * - Extracts threadId from events when creating new thread\n * - Handles tool execution (Phase 6)\n * - Invalidates thread queries on completion\n * @param threadId - Optional thread ID to send message to. If not provided, creates new thread\n * @returns React Query mutation object with threadId in mutation result\n * @example\n * ```tsx\n * function ChatInput({ threadId }: { threadId?: string }) {\n * const sendMessage = useTamboV1SendMessage(threadId);\n *\n * const handleSubmit = async (text: string) => {\n * const result = await sendMessage.mutateAsync({\n * message: {\n * role: \"user\",\n * content: [{ type: \"text\", text }],\n * },\n * });\n *\n * // If threadId wasn't provided, a new thread was created\n * if (!threadId) {\n * console.log(\"Created thread:\", result.threadId);\n * }\n * };\n *\n * return (\n * <div>\n * <input onSubmit={handleSubmit} />\n * {sendMessage.isPending && <Spinner />}\n * </div>\n * );\n * }\n * ```\n */\nexport function useTamboV1SendMessage(threadId?: string) {\n const client = useTamboClient();\n const dispatch = useStreamDispatch();\n const registry = useContext(TamboRegistryContext);\n const queryClient = useQueryClient();\n\n if (!registry) {\n throw new Error(\n \"useTamboV1SendMessage must be used within TamboRegistryProvider\",\n );\n }\n\n return useMutation({\n mutationFn: async (options: SendMessageOptions) => {\n const { message, debug = false } = options;\n\n const toolTracker = new ToolCallTracker();\n\n // Create the run stream\n const { stream, initialThreadId } = await createRunStream({\n client,\n threadId,\n message,\n registry,\n });\n\n let actualThreadId = initialThreadId;\n let runId: string | undefined;\n let currentStream: CreateRunStreamResult[\"stream\"] = stream;\n\n try {\n // Outer loop handles stream replacement for multi-round tool execution.\n // When we hit awaiting_input, we execute tools, get a new stream, and continue.\n // This flat loop pattern correctly handles tool→AI→tool→AI chains.\n while (true) {\n let pendingAwaitingInput: RunAwaitingInputEvent | undefined;\n\n // Process current stream until completion or awaiting_input\n for await (const event of handleEventStream(currentStream, {\n debug,\n })) {\n // Extract threadId and runId from RUN_STARTED event\n if (event.type === EventType.RUN_STARTED) {\n runId = event.runId;\n actualThreadId ??= event.threadId;\n } else if (!actualThreadId) {\n throw new Error(\n `Expected first event to be RUN_STARTED with threadId, got: ${event.type}`,\n );\n }\n\n toolTracker.handleEvent(event);\n dispatch({ type: \"EVENT\", event, threadId: actualThreadId });\n\n // Check for awaiting_input - if found, break to execute tools\n if (event.type === EventType.CUSTOM) {\n const customEvent = asTamboCustomEvent(event);\n if (customEvent?.name === \"tambo.run.awaiting_input\") {\n pendingAwaitingInput = customEvent;\n break; // Exit stream loop to handle tool execution\n }\n }\n }\n\n // If stream finished without awaiting_input, we're done\n if (!pendingAwaitingInput) {\n break;\n }\n\n // Execute tools and get continuation stream\n // These checks should never fail since awaiting_input comes after RUN_STARTED\n if (!runId || !actualThreadId) {\n throw new Error(\n \"Cannot continue run after awaiting_input: missing runId or threadId\",\n );\n }\n\n currentStream = await executeToolsAndContinue({\n event: pendingAwaitingInput,\n toolTracker,\n registry,\n client,\n threadId: actualThreadId,\n runId,\n });\n }\n\n return { threadId: actualThreadId };\n } catch (error) {\n // Dispatch a synthetic RUN_ERROR event to clean up thread state\n // This ensures the thread doesn't stay stuck in \"streaming\" status\n if (actualThreadId) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown streaming error\";\n const errorEvent: RunErrorEvent = {\n type: EventType.RUN_ERROR,\n message: errorMessage,\n };\n dispatch({\n type: \"EVENT\",\n event: errorEvent,\n threadId: actualThreadId,\n });\n }\n throw error;\n }\n },\n onSuccess: async (result) => {\n // Invalidate thread queries to refetch updated state\n await queryClient.invalidateQueries({\n queryKey: [\"v1-threads\", result.threadId],\n });\n },\n onError: (error) => {\n console.error(\"[useTamboV1SendMessage] Mutation failed:\", error);\n },\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-send-message.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-send-message.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * Send Message Hook for v1 API\n *\n * React Query mutation hook for sending messages and handling streaming responses.\n */\n\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useContext } from \"react\";\nimport { EventType, type RunErrorEvent } from \"@ag-ui/core\";\nimport { asTamboCustomEvent, type RunAwaitingInputEvent } from \"../types/event\";\nimport type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport type { Stream } from \"@tambo-ai/typescript-sdk/core/streaming\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport {\n TamboRegistryContext,\n type TamboRegistryContext as TamboRegistry,\n} from \"../../providers/tambo-registry-provider\";\nimport { useStreamDispatch } from \"../providers/tambo-v1-stream-context\";\nimport { useTamboV1Config } from \"../providers/tambo-v1-provider\";\nimport type { InputMessage } from \"../types/message\";\nimport {\n toAvailableComponents,\n toAvailableTools,\n} from \"../utils/registry-conversion\";\nimport { handleEventStream } from \"../utils/stream-handler\";\nimport { executeAllPendingTools } from \"../utils/tool-executor\";\nimport { ToolCallTracker } from \"../utils/tool-call-tracker\";\n\n/**\n * Options for sending a message\n */\nexport interface SendMessageOptions {\n /**\n * The message to send\n */\n message: InputMessage;\n\n /**\n * Enable debug logging for the stream\n */\n debug?: boolean;\n}\n\n/**\n * Parameters for creating a run stream\n */\nexport interface CreateRunStreamParams {\n client: TamboAI;\n threadId: string | undefined;\n message: InputMessage;\n registry: TamboRegistry;\n userKey: string | undefined;\n}\n\n/**\n * Stream types from the SDK\n */\ntype RunStream = Stream<TamboAI.Threads.Runs.RunRunResponse>;\ntype CreateStream = Stream<TamboAI.Threads.Runs.RunCreateResponse>;\n\n/**\n * Result from creating a run stream\n */\nexport interface CreateRunStreamResult {\n stream: RunStream | CreateStream;\n initialThreadId: string | undefined;\n}\n\n/**\n * Parameters for executing tools and continuing the run\n */\ninterface ExecuteToolsParams {\n event: RunAwaitingInputEvent;\n toolTracker: ToolCallTracker;\n registry: TamboRegistry;\n client: TamboAI;\n threadId: string;\n runId: string;\n userKey: string | undefined;\n}\n\n/**\n * Executes pending tools and returns a continuation stream.\n *\n * This function does NOT process the continuation stream - it just executes\n * the tools and returns the new stream for the caller to process. This enables\n * the flat loop pattern that correctly handles multi-round tool execution.\n * @param params - The parameters for tool execution\n * @returns The continuation stream to process\n */\nasync function executeToolsAndContinue(\n params: ExecuteToolsParams,\n): Promise<RunStream> {\n const { event, toolTracker, registry, client, threadId, runId, userKey } =\n params;\n\n const { pendingToolCallIds } = event.value;\n const toolCallsToExecute = toolTracker.getToolCallsById(pendingToolCallIds);\n\n // Execute tools\n const toolResults = await executeAllPendingTools(\n toolCallsToExecute,\n registry.toolRegistry,\n );\n\n // Clear executed tool calls before continuing\n toolTracker.clearToolCalls(pendingToolCallIds);\n\n // Return the continuation stream (caller will process it)\n return await client.threads.runs.run(threadId, {\n message: {\n role: \"user\",\n content: toolResults,\n },\n previousRunId: runId,\n availableComponents: toAvailableComponents(registry.componentList),\n tools: toAvailableTools(registry.toolRegistry),\n userKey,\n });\n}\n\n/**\n * Creates a run stream by calling the appropriate API method.\n *\n * If threadId is provided, runs on existing thread via client.threads.runs.run().\n * If no threadId, creates new thread via client.threads.runs.create().\n * @param params - The parameters for creating the run stream\n * @returns The stream and initial thread ID (undefined if creating new thread)\n */\nexport async function createRunStream(\n params: CreateRunStreamParams,\n): Promise<CreateRunStreamResult> {\n const { client, threadId, message, registry, userKey } = params;\n\n // Convert registry components/tools to v1 API format\n const availableComponents = toAvailableComponents(registry.componentList);\n const availableTools = toAvailableTools(registry.toolRegistry);\n\n if (threadId) {\n // Run on existing thread\n const stream = await client.threads.runs.run(threadId, {\n message,\n availableComponents,\n tools: availableTools,\n userKey,\n });\n return { stream, initialThreadId: threadId };\n } else {\n // Create new thread\n const stream = await client.threads.runs.create({\n message,\n availableComponents,\n tools: availableTools,\n thread: userKey ? { userKey } : undefined,\n });\n // threadId will be extracted from first event (RUN_STARTED)\n return { stream, initialThreadId: undefined };\n }\n}\n\n/**\n * Hook to send a message and handle streaming responses.\n *\n * This hook handles two scenarios:\n * - If threadId provided: runs on existing thread via client.threads.runs.run()\n * - If no threadId: creates new thread via client.threads.runs.create()\n *\n * The hook:\n * - Sends a user message to the API\n * - Streams AG-UI events in real-time\n * - Dispatches events to the stream reducer\n * - Extracts threadId from events when creating new thread\n * - Handles tool execution (Phase 6)\n * - Invalidates thread queries on completion\n * @param threadId - Optional thread ID to send message to. If not provided, creates new thread\n * @returns React Query mutation object with threadId in mutation result\n * @example\n * ```tsx\n * function ChatInput({ threadId }: { threadId?: string }) {\n * const sendMessage = useTamboV1SendMessage(threadId);\n *\n * const handleSubmit = async (text: string) => {\n * const result = await sendMessage.mutateAsync({\n * message: {\n * role: \"user\",\n * content: [{ type: \"text\", text }],\n * },\n * });\n *\n * // If threadId wasn't provided, a new thread was created\n * if (!threadId) {\n * console.log(\"Created thread:\", result.threadId);\n * }\n * };\n *\n * return (\n * <div>\n * <input onSubmit={handleSubmit} />\n * {sendMessage.isPending && <Spinner />}\n * </div>\n * );\n * }\n * ```\n */\nexport function useTamboV1SendMessage(threadId?: string) {\n const client = useTamboClient();\n const dispatch = useStreamDispatch();\n const { userKey } = useTamboV1Config();\n const registry = useContext(TamboRegistryContext);\n const queryClient = useQueryClient();\n\n if (!registry) {\n throw new Error(\n \"useTamboV1SendMessage must be used within TamboRegistryProvider\",\n );\n }\n\n return useMutation({\n mutationFn: async (options: SendMessageOptions) => {\n const { message, debug = false } = options;\n\n const toolTracker = new ToolCallTracker();\n\n // Create the run stream\n const { stream, initialThreadId } = await createRunStream({\n client,\n threadId,\n message,\n registry,\n userKey,\n });\n\n let actualThreadId = initialThreadId;\n let runId: string | undefined;\n let currentStream: CreateRunStreamResult[\"stream\"] = stream;\n\n try {\n // Outer loop handles stream replacement for multi-round tool execution.\n // When we hit awaiting_input, we execute tools, get a new stream, and continue.\n // This flat loop pattern correctly handles tool→AI→tool→AI chains.\n while (true) {\n let pendingAwaitingInput: RunAwaitingInputEvent | undefined;\n\n // Process current stream until completion or awaiting_input\n for await (const event of handleEventStream(currentStream, {\n debug,\n })) {\n // Extract threadId and runId from RUN_STARTED event\n if (event.type === EventType.RUN_STARTED) {\n runId = event.runId;\n actualThreadId ??= event.threadId;\n } else if (!actualThreadId) {\n throw new Error(\n `Expected first event to be RUN_STARTED with threadId, got: ${event.type}`,\n );\n }\n\n toolTracker.handleEvent(event);\n dispatch({ type: \"EVENT\", event, threadId: actualThreadId });\n\n // Check for awaiting_input - if found, break to execute tools\n if (event.type === EventType.CUSTOM) {\n const customEvent = asTamboCustomEvent(event);\n if (customEvent?.name === \"tambo.run.awaiting_input\") {\n pendingAwaitingInput = customEvent;\n break; // Exit stream loop to handle tool execution\n }\n }\n }\n\n // If stream finished without awaiting_input, we're done\n if (!pendingAwaitingInput) {\n break;\n }\n\n // Execute tools and get continuation stream\n // These checks should never fail since awaiting_input comes after RUN_STARTED\n if (!runId || !actualThreadId) {\n throw new Error(\n \"Cannot continue run after awaiting_input: missing runId or threadId\",\n );\n }\n\n currentStream = await executeToolsAndContinue({\n event: pendingAwaitingInput,\n toolTracker,\n registry,\n client,\n threadId: actualThreadId,\n runId,\n userKey,\n });\n }\n\n return { threadId: actualThreadId };\n } catch (error) {\n // Dispatch a synthetic RUN_ERROR event to clean up thread state\n // This ensures the thread doesn't stay stuck in \"streaming\" status\n if (actualThreadId) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown streaming error\";\n const errorEvent: RunErrorEvent = {\n type: EventType.RUN_ERROR,\n message: errorMessage,\n };\n dispatch({\n type: \"EVENT\",\n event: errorEvent,\n threadId: actualThreadId,\n });\n }\n throw error;\n }\n },\n onSuccess: async (result) => {\n // Invalidate thread queries to refetch updated state\n await queryClient.invalidateQueries({\n queryKey: [\"v1-threads\", result.threadId],\n });\n },\n onError: (error) => {\n console.error(\"[useTamboV1SendMessage] Mutation failed:\", error);\n },\n });\n}\n"]}
|
|
@@ -5,11 +5,15 @@ import React from "react";
|
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { useTamboClient } from "../../providers/tambo-client-provider";
|
|
7
7
|
import { TamboRegistryContext } from "../../providers/tambo-registry-provider";
|
|
8
|
+
import { useTamboV1Config } from "../providers/tambo-v1-provider";
|
|
8
9
|
import { TamboV1StreamProvider } from "../providers/tambo-v1-stream-context";
|
|
9
10
|
import { createRunStream, useTamboV1SendMessage, } from "./use-tambo-v1-send-message";
|
|
10
11
|
jest.mock("../../providers/tambo-client-provider", () => ({
|
|
11
12
|
useTamboClient: jest.fn(),
|
|
12
13
|
}));
|
|
14
|
+
jest.mock("../providers/tambo-v1-provider", () => ({
|
|
15
|
+
useTamboV1Config: jest.fn(),
|
|
16
|
+
}));
|
|
13
17
|
describe("useTamboV1SendMessage", () => {
|
|
14
18
|
const mockThreadsRunsApi = {
|
|
15
19
|
run: jest.fn(),
|
|
@@ -29,7 +33,7 @@ describe("useTamboV1SendMessage", () => {
|
|
|
29
33
|
function TestWrapper({ children }) {
|
|
30
34
|
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
31
35
|
React.createElement(TamboRegistryContext.Provider, { value: mockRegistry },
|
|
32
|
-
React.createElement(TamboV1StreamProvider,
|
|
36
|
+
React.createElement(TamboV1StreamProvider, null, children))));
|
|
33
37
|
}
|
|
34
38
|
beforeEach(() => {
|
|
35
39
|
queryClient = new QueryClient({
|
|
@@ -39,6 +43,7 @@ describe("useTamboV1SendMessage", () => {
|
|
|
39
43
|
},
|
|
40
44
|
});
|
|
41
45
|
jest.mocked(useTamboClient).mockReturnValue(mockTamboAI);
|
|
46
|
+
jest.mocked(useTamboV1Config).mockReturnValue({ userKey: undefined });
|
|
42
47
|
mockThreadsRunsApi.run.mockReset();
|
|
43
48
|
mockThreadsRunsApi.create.mockReset();
|
|
44
49
|
});
|
|
@@ -112,11 +117,13 @@ describe("createRunStream", () => {
|
|
|
112
117
|
threadId: "thread_123",
|
|
113
118
|
message: testMessage,
|
|
114
119
|
registry: mockRegistry,
|
|
120
|
+
userKey: undefined,
|
|
115
121
|
});
|
|
116
122
|
expect(mockThreadsRunsApi.run).toHaveBeenCalledWith("thread_123", {
|
|
117
123
|
message: testMessage,
|
|
118
124
|
availableComponents: expect.any(Array),
|
|
119
125
|
tools: expect.any(Array),
|
|
126
|
+
userKey: undefined,
|
|
120
127
|
});
|
|
121
128
|
expect(mockThreadsRunsApi.create).not.toHaveBeenCalled();
|
|
122
129
|
expect(result.stream).toBe(mockStream);
|
|
@@ -129,11 +136,13 @@ describe("createRunStream", () => {
|
|
|
129
136
|
threadId: undefined,
|
|
130
137
|
message: testMessage,
|
|
131
138
|
registry: mockRegistry,
|
|
139
|
+
userKey: undefined,
|
|
132
140
|
});
|
|
133
141
|
expect(mockThreadsRunsApi.create).toHaveBeenCalledWith({
|
|
134
142
|
message: testMessage,
|
|
135
143
|
availableComponents: expect.any(Array),
|
|
136
144
|
tools: expect.any(Array),
|
|
145
|
+
thread: undefined,
|
|
137
146
|
});
|
|
138
147
|
expect(mockThreadsRunsApi.run).not.toHaveBeenCalled();
|
|
139
148
|
expect(result.stream).toBe(mockStream);
|
|
@@ -146,6 +155,7 @@ describe("createRunStream", () => {
|
|
|
146
155
|
threadId: "thread_123",
|
|
147
156
|
message: testMessage,
|
|
148
157
|
registry: mockRegistry,
|
|
158
|
+
userKey: undefined,
|
|
149
159
|
});
|
|
150
160
|
const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];
|
|
151
161
|
expect(callArgs.availableComponents).toEqual([
|
|
@@ -163,6 +173,7 @@ describe("createRunStream", () => {
|
|
|
163
173
|
threadId: "thread_123",
|
|
164
174
|
message: testMessage,
|
|
165
175
|
registry: mockRegistry,
|
|
176
|
+
userKey: undefined,
|
|
166
177
|
});
|
|
167
178
|
const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];
|
|
168
179
|
expect(callArgs.tools).toEqual([
|
|
@@ -183,6 +194,7 @@ describe("createRunStream", () => {
|
|
|
183
194
|
threadId: "thread_123",
|
|
184
195
|
message: testMessage,
|
|
185
196
|
registry: emptyRegistry,
|
|
197
|
+
userKey: undefined,
|
|
186
198
|
});
|
|
187
199
|
const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];
|
|
188
200
|
expect(callArgs.availableComponents).toEqual([]);
|
|
@@ -218,6 +230,7 @@ describe("useTamboV1SendMessage mutation", () => {
|
|
|
218
230
|
},
|
|
219
231
|
});
|
|
220
232
|
jest.mocked(useTamboClient).mockReturnValue(mockTamboAI);
|
|
233
|
+
jest.mocked(useTamboV1Config).mockReturnValue({ userKey: undefined });
|
|
221
234
|
mockThreadsRunsApi.run.mockReset();
|
|
222
235
|
mockThreadsRunsApi.create.mockReset();
|
|
223
236
|
});
|
|
@@ -339,7 +352,7 @@ describe("useTamboV1SendMessage mutation", () => {
|
|
|
339
352
|
function TestWrapper({ children }) {
|
|
340
353
|
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
341
354
|
React.createElement(TamboRegistryContext.Provider, { value: mockRegistry },
|
|
342
|
-
React.createElement(TamboV1StreamProvider,
|
|
355
|
+
React.createElement(TamboV1StreamProvider, null, children))));
|
|
343
356
|
}
|
|
344
357
|
const { result } = renderHook(() => useTamboV1SendMessage("thread_123"), {
|
|
345
358
|
wrapper: TestWrapper,
|
|
@@ -433,7 +446,7 @@ describe("useTamboV1SendMessage mutation", () => {
|
|
|
433
446
|
function TestWrapper({ children }) {
|
|
434
447
|
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
435
448
|
React.createElement(TamboRegistryContext.Provider, { value: mockRegistry },
|
|
436
|
-
React.createElement(TamboV1StreamProvider,
|
|
449
|
+
React.createElement(TamboV1StreamProvider, null, children))));
|
|
437
450
|
}
|
|
438
451
|
const { result } = renderHook(() => useTamboV1SendMessage("thread_123"), {
|
|
439
452
|
wrapper: TestWrapper,
|
|
@@ -505,7 +518,7 @@ describe("useTamboV1SendMessage mutation", () => {
|
|
|
505
518
|
function TestWrapper({ children }) {
|
|
506
519
|
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
507
520
|
React.createElement(TamboRegistryContext.Provider, { value: mockRegistry },
|
|
508
|
-
React.createElement(TamboV1StreamProvider,
|
|
521
|
+
React.createElement(TamboV1StreamProvider, null, children))));
|
|
509
522
|
}
|
|
510
523
|
const { result } = renderHook(() => useTamboV1SendMessage("thread_123"), {
|
|
511
524
|
wrapper: TestWrapper,
|
|
@@ -572,7 +585,7 @@ describe("useTamboV1SendMessage mutation", () => {
|
|
|
572
585
|
function TestWrapper({ children }) {
|
|
573
586
|
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
574
587
|
React.createElement(TamboRegistryContext.Provider, { value: mockRegistry },
|
|
575
|
-
React.createElement(TamboV1StreamProvider,
|
|
588
|
+
React.createElement(TamboV1StreamProvider, null, children))));
|
|
576
589
|
}
|
|
577
590
|
const { result } = renderHook(() => useTamboV1SendMessage("thread_123"), {
|
|
578
591
|
wrapper: TestWrapper,
|
|
@@ -602,7 +615,7 @@ describe("useTamboV1SendMessage mutation", () => {
|
|
|
602
615
|
// (though with an empty registry)
|
|
603
616
|
function TestWrapperWithoutRegistry({ children, }) {
|
|
604
617
|
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
605
|
-
React.createElement(TamboV1StreamProvider,
|
|
618
|
+
React.createElement(TamboV1StreamProvider, null, children)));
|
|
606
619
|
}
|
|
607
620
|
// Should not throw - default context is used
|
|
608
621
|
const { result } = renderHook(() => useTamboV1SendMessage("thread_123"), {
|
|
@@ -627,7 +640,7 @@ describe("useTamboV1SendMessage mutation", () => {
|
|
|
627
640
|
function TestWrapper({ children }) {
|
|
628
641
|
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
629
642
|
React.createElement(TamboRegistryContext.Provider, { value: mockRegistry },
|
|
630
|
-
React.createElement(TamboV1StreamProvider,
|
|
643
|
+
React.createElement(TamboV1StreamProvider, null, children))));
|
|
631
644
|
}
|
|
632
645
|
const invalidateQueriesSpy = jest.spyOn(queryClient, "invalidateQueries");
|
|
633
646
|
const { result } = renderHook(() => useTamboV1SendMessage("thread_123"), {
|
|
@@ -747,7 +760,7 @@ describe("useTamboV1SendMessage mutation", () => {
|
|
|
747
760
|
function TestWrapper({ children }) {
|
|
748
761
|
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
749
762
|
React.createElement(TamboRegistryContext.Provider, { value: mockRegistry },
|
|
750
|
-
React.createElement(TamboV1StreamProvider,
|
|
763
|
+
React.createElement(TamboV1StreamProvider, null, children))));
|
|
751
764
|
}
|
|
752
765
|
const { result } = renderHook(() => useTamboV1SendMessage("thread_123"), {
|
|
753
766
|
wrapper: TestWrapper,
|
|
@@ -795,7 +808,7 @@ describe("useTamboV1SendMessage mutation", () => {
|
|
|
795
808
|
function TestWrapper({ children }) {
|
|
796
809
|
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
797
810
|
React.createElement(TamboRegistryContext.Provider, { value: mockRegistry },
|
|
798
|
-
React.createElement(TamboV1StreamProvider,
|
|
811
|
+
React.createElement(TamboV1StreamProvider, null, children))));
|
|
799
812
|
}
|
|
800
813
|
const { result } = renderHook(() => useTamboV1SendMessage("thread_123"), {
|
|
801
814
|
wrapper: TestWrapper,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-send-message.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-send-message.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { EventType } from \"@ag-ui/core\";\nimport TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { renderHook, waitFor, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport type { TamboTool } from \"../../model/component-metadata\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport { TamboRegistryContext } from \"../../providers/tambo-registry-provider\";\nimport { TamboV1StreamProvider } from \"../providers/tambo-v1-stream-context\";\nimport {\n createRunStream,\n useTamboV1SendMessage,\n} from \"./use-tambo-v1-send-message\";\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n}));\n\ndescribe(\"useTamboV1SendMessage\", () => {\n const mockThreadsRunsApi = {\n run: jest.fn(),\n create: jest.fn(),\n };\n\n const mockTamboAI = {\n apiKey: \"\",\n threads: {\n runs: mockThreadsRunsApi,\n },\n } as unknown as TamboAI;\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n let queryClient: QueryClient;\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n beforeEach(() => {\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n jest.mocked(useTamboClient).mockReturnValue(mockTamboAI);\n mockThreadsRunsApi.run.mockReset();\n mockThreadsRunsApi.create.mockReset();\n });\n\n it(\"returns a mutation object\", () => {\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.mutate).toBeDefined();\n expect(result.current.mutateAsync).toBeDefined();\n expect(result.current.isPending).toBe(false);\n });\n\n it(\"returns a mutation object when threadId is not provided\", () => {\n const { result } = renderHook(() => useTamboV1SendMessage(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.mutate).toBeDefined();\n expect(result.current.mutateAsync).toBeDefined();\n });\n});\n\ndescribe(\"createRunStream\", () => {\n const mockStream = {\n [Symbol.asyncIterator]: async function* () {\n yield { type: \"RUN_STARTED\", runId: \"run_1\", threadId: \"thread_123\" };\n },\n };\n\n const mockThreadsRunsApi = {\n run: jest.fn(),\n create: jest.fn(),\n };\n\n const mockClient = {\n threads: {\n runs: mockThreadsRunsApi,\n },\n } as unknown as TamboAI;\n\n const mockRegistry = {\n componentList: new Map([\n [\n \"TestComponent\",\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: () => null,\n propsSchema: z.object({ title: z.string() }),\n },\n ],\n ]),\n toolRegistry: new Map([\n [\n \"testTool\",\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema: z.object({ query: z.string() }),\n },\n ],\n ]),\n };\n\n const testMessage = {\n role: \"user\" as const,\n content: [{ type: \"text\" as const, text: \"Hello\" }],\n };\n\n beforeEach(() => {\n mockThreadsRunsApi.run.mockReset();\n mockThreadsRunsApi.create.mockReset();\n });\n\n it(\"calls client.threads.runs.run when threadId is provided\", async () => {\n mockThreadsRunsApi.run.mockResolvedValue(mockStream);\n\n const result = await createRunStream({\n client: mockClient,\n threadId: \"thread_123\",\n message: testMessage,\n registry: mockRegistry as any,\n });\n\n expect(mockThreadsRunsApi.run).toHaveBeenCalledWith(\"thread_123\", {\n message: testMessage,\n availableComponents: expect.any(Array),\n tools: expect.any(Array),\n });\n expect(mockThreadsRunsApi.create).not.toHaveBeenCalled();\n expect(result.stream).toBe(mockStream);\n expect(result.initialThreadId).toBe(\"thread_123\");\n });\n\n it(\"calls client.threads.runs.create when threadId is not provided\", async () => {\n mockThreadsRunsApi.create.mockResolvedValue(mockStream);\n\n const result = await createRunStream({\n client: mockClient,\n threadId: undefined,\n message: testMessage,\n registry: mockRegistry as any,\n });\n\n expect(mockThreadsRunsApi.create).toHaveBeenCalledWith({\n message: testMessage,\n availableComponents: expect.any(Array),\n tools: expect.any(Array),\n });\n expect(mockThreadsRunsApi.run).not.toHaveBeenCalled();\n expect(result.stream).toBe(mockStream);\n expect(result.initialThreadId).toBeUndefined();\n });\n\n it(\"converts registry components to availableComponents format\", async () => {\n mockThreadsRunsApi.run.mockResolvedValue(mockStream);\n\n await createRunStream({\n client: mockClient,\n threadId: \"thread_123\",\n message: testMessage,\n registry: mockRegistry as any,\n });\n\n const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];\n expect(callArgs.availableComponents).toEqual([\n {\n name: \"TestComponent\",\n description: \"A test component\",\n propsSchema: expect.any(Object),\n },\n ]);\n });\n\n it(\"converts registry tools to tools format\", async () => {\n mockThreadsRunsApi.run.mockResolvedValue(mockStream);\n\n await createRunStream({\n client: mockClient,\n threadId: \"thread_123\",\n message: testMessage,\n registry: mockRegistry as any,\n });\n\n const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];\n expect(callArgs.tools).toEqual([\n expect.objectContaining({\n name: \"testTool\",\n description: \"A test tool\",\n }),\n ]);\n });\n\n it(\"handles empty registry\", async () => {\n mockThreadsRunsApi.run.mockResolvedValue(mockStream);\n\n const emptyRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n await createRunStream({\n client: mockClient,\n threadId: \"thread_123\",\n message: testMessage,\n registry: emptyRegistry as any,\n });\n\n const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];\n expect(callArgs.availableComponents).toEqual([]);\n expect(callArgs.tools).toEqual([]);\n });\n});\n\ndescribe(\"useTamboV1SendMessage mutation\", () => {\n const mockThreadsRunsApi = {\n run: jest.fn(),\n create: jest.fn(),\n };\n\n const mockTamboAI = {\n apiKey: \"\",\n threads: {\n runs: mockThreadsRunsApi,\n },\n } as unknown as TamboAI;\n\n let queryClient: QueryClient;\n\n function createAsyncIterator<T>(events: T[]) {\n return {\n [Symbol.asyncIterator]: async function* () {\n for (const event of events) {\n yield event;\n }\n },\n };\n }\n\n beforeEach(() => {\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n jest.mocked(useTamboClient).mockReturnValue(mockTamboAI);\n mockThreadsRunsApi.run.mockReset();\n mockThreadsRunsApi.create.mockReset();\n });\n\n it(\"extracts threadId from RUN_STARTED event when creating new thread\", async () => {\n const mockStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"new_thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.create.mockResolvedValue(mockStream);\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(), {\n wrapper: TestWrapper,\n });\n\n let mutationResult: { threadId: string | undefined } | undefined;\n await act(async () => {\n mutationResult = await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n });\n\n expect(mutationResult?.threadId).toBe(\"new_thread_123\");\n });\n\n it(\"throws error when first event is not RUN_STARTED on new thread\", async () => {\n const mockStream = createAsyncIterator([\n { type: EventType.TEXT_MESSAGE_START, messageId: \"msg_1\" },\n ]);\n\n mockThreadsRunsApi.create.mockResolvedValue(mockStream);\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(), {\n wrapper: TestWrapper,\n });\n\n await expect(\n act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n }),\n ).rejects.toThrow(\"Expected first event to be RUN_STARTED with threadId\");\n });\n\n it(\"executes tools on awaiting_input event\", async () => {\n const toolExecuted = jest.fn().mockResolvedValue(\"tool result\");\n\n const testTool: TamboTool = {\n name: \"test_tool\",\n description: \"A test tool\",\n tool: toolExecuted,\n inputSchema: z.object({ query: z.string() }),\n outputSchema: z.string(),\n };\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map([[\"test_tool\", testTool]]),\n };\n\n const initialStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_1\",\n toolCallName: \"test_tool\",\n parentMessageId: \"msg_1\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: '{\"query\":\"test\"}',\n },\n {\n type: EventType.TOOL_CALL_END,\n toolCallId: \"call_1\",\n },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_1\"] },\n },\n ]);\n\n const continueStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_2\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run\n .mockResolvedValueOnce(initialStream)\n .mockResolvedValueOnce(continueStream);\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n });\n\n expect(toolExecuted).toHaveBeenCalledWith({ query: \"test\" });\n\n // Verify continuation was called with tool results\n expect(mockThreadsRunsApi.run).toHaveBeenCalledTimes(2);\n const continueCall = mockThreadsRunsApi.run.mock.calls[1];\n expect(continueCall[0]).toBe(\"thread_123\");\n expect(continueCall[1].previousRunId).toBe(\"run_1\");\n expect(continueCall[1].message.content[0]).toEqual({\n type: \"tool_result\",\n toolUseId: \"call_1\",\n content: [{ type: \"text\", text: \"tool result\" }],\n });\n });\n\n it(\"handles tool calls with chunked args\", async () => {\n const toolExecuted = jest.fn().mockResolvedValue({ result: 42 });\n\n const testTool: TamboTool = {\n name: \"chunked_tool\",\n description: \"Tool with chunked args\",\n tool: toolExecuted,\n inputSchema: z.object({ a: z.number(), b: z.number() }),\n outputSchema: z.object({ result: z.number() }),\n };\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map([[\"chunked_tool\", testTool]]),\n };\n\n const initialStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_1\",\n toolCallName: \"chunked_tool\",\n parentMessageId: \"msg_1\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: '{\"a\":',\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: \"10,\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: '\"b\":20}',\n },\n {\n type: EventType.TOOL_CALL_END,\n toolCallId: \"call_1\",\n },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_1\"] },\n },\n ]);\n\n const continueStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_2\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run\n .mockResolvedValueOnce(initialStream)\n .mockResolvedValueOnce(continueStream);\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Calculate\" }],\n },\n });\n });\n\n expect(toolExecuted).toHaveBeenCalledWith({ a: 10, b: 20 });\n });\n\n it(\"handles missing TOOL_CALL_ARGS gracefully\", async () => {\n // Test that tools can be executed even when no args events are received\n // (the hook keeps input as empty object)\n const toolExecuted = jest.fn().mockResolvedValue(\"result\");\n\n const testTool: TamboTool = {\n name: \"test_tool\",\n description: \"Test tool\",\n tool: toolExecuted,\n inputSchema: z.object({}),\n outputSchema: z.string(),\n };\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map([[\"test_tool\", testTool]]),\n };\n\n const initialStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_1\",\n toolCallName: \"test_tool\",\n parentMessageId: \"msg_1\",\n },\n // No TOOL_CALL_ARGS events - args will be empty\n {\n type: EventType.TOOL_CALL_END,\n toolCallId: \"call_1\",\n },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_1\"] },\n },\n ]);\n\n const continueStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_2\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run\n .mockResolvedValueOnce(initialStream)\n .mockResolvedValueOnce(continueStream);\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Test\" }],\n },\n });\n });\n\n // Tool should be called with empty input due to no args events\n expect(toolExecuted).toHaveBeenCalledWith({});\n });\n\n it(\"handles unknown tool in awaiting_input by returning error result\", async () => {\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(), // Empty registry - tool not found\n };\n\n const initialStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_1\",\n toolCallName: \"unknown_tool\",\n parentMessageId: \"msg_1\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: \"{}\",\n },\n {\n type: EventType.TOOL_CALL_END,\n toolCallId: \"call_1\",\n },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_1\"] },\n },\n ]);\n\n const continueStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_2\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run\n .mockResolvedValueOnce(initialStream)\n .mockResolvedValueOnce(continueStream);\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Test\" }],\n },\n });\n });\n\n // Verify continuation was called (second call)\n expect(mockThreadsRunsApi.run).toHaveBeenCalledTimes(2);\n\n // Continuation should include error message for unknown tool\n const continueCall = mockThreadsRunsApi.run.mock.calls[1];\n expect(continueCall[1].message.content[0]).toEqual({\n type: \"tool_result\",\n toolUseId: \"call_1\",\n content: [\n { type: \"text\", text: 'Tool \"unknown_tool\" not found in registry' },\n ],\n });\n });\n\n it(\"works with default registry context when no provider is present\", () => {\n // TamboRegistryContext has a default value, so the hook should work\n // (though with an empty registry)\n function TestWrapperWithoutRegistry({\n children,\n }: {\n children: React.ReactNode;\n }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n </QueryClientProvider>\n );\n }\n\n // Should not throw - default context is used\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapperWithoutRegistry,\n });\n\n expect(result.current.mutate).toBeDefined();\n });\n\n it(\"invalidates queries on successful mutation\", async () => {\n const mockStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run.mockResolvedValue(mockStream);\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const invalidateQueriesSpy = jest.spyOn(queryClient, \"invalidateQueries\");\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n });\n\n await waitFor(() => {\n expect(invalidateQueriesSpy).toHaveBeenCalledWith({\n queryKey: [\"v1-threads\", \"thread_123\"],\n });\n });\n });\n\n it(\"handles multi-round tool execution (tool→AI→tool→AI)\", async () => {\n const tool1Executed = jest.fn().mockResolvedValue(\"result from tool 1\");\n const tool2Executed = jest.fn().mockResolvedValue(\"result from tool 2\");\n\n const tool1: TamboTool = {\n name: \"tool_1\",\n description: \"First tool\",\n tool: tool1Executed,\n inputSchema: z.object({ input: z.string() }),\n outputSchema: z.string(),\n };\n\n const tool2: TamboTool = {\n name: \"tool_2\",\n description: \"Second tool\",\n tool: tool2Executed,\n inputSchema: z.object({ input: z.string() }),\n outputSchema: z.string(),\n };\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map([\n [\"tool_1\", tool1],\n [\"tool_2\", tool2],\n ]),\n };\n\n // Initial stream: AI calls tool_1\n const initialStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_1\",\n toolCallName: \"tool_1\",\n parentMessageId: \"msg_1\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: '{\"input\":\"first\"}',\n },\n { type: EventType.TOOL_CALL_END, toolCallId: \"call_1\" },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_1\"] },\n },\n ]);\n\n // Second stream: AI receives tool_1 result, then calls tool_2\n const secondStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_2\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_2\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_2\",\n toolCallName: \"tool_2\",\n parentMessageId: \"msg_2\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_2\",\n delta: '{\"input\":\"second\"}',\n },\n { type: EventType.TOOL_CALL_END, toolCallId: \"call_2\" },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_2\"] },\n },\n ]);\n\n // Third stream: AI receives tool_2 result, finishes\n const thirdStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_3\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run\n .mockResolvedValueOnce(initialStream)\n .mockResolvedValueOnce(secondStream)\n .mockResolvedValueOnce(thirdStream);\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n });\n\n // Both tools should have been executed\n expect(tool1Executed).toHaveBeenCalledWith({ input: \"first\" });\n expect(tool2Executed).toHaveBeenCalledWith({ input: \"second\" });\n\n // Should have made 3 API calls (initial + 2 continuations)\n expect(mockThreadsRunsApi.run).toHaveBeenCalledTimes(3);\n\n // First continuation should have tool_1 result with previousRunId: run_1\n const firstContinue = mockThreadsRunsApi.run.mock.calls[1];\n expect(firstContinue[1].previousRunId).toBe(\"run_1\");\n expect(firstContinue[1].message.content[0]).toEqual({\n type: \"tool_result\",\n toolUseId: \"call_1\",\n content: [{ type: \"text\", text: \"result from tool 1\" }],\n });\n\n // Second continuation should have tool_2 result with previousRunId: run_2\n const secondContinue = mockThreadsRunsApi.run.mock.calls[2];\n expect(secondContinue[1].previousRunId).toBe(\"run_2\");\n expect(secondContinue[1].message.content[0]).toEqual({\n type: \"tool_result\",\n toolUseId: \"call_2\",\n content: [{ type: \"text\", text: \"result from tool 2\" }],\n });\n });\n\n it(\"logs error on mutation failure\", async () => {\n const consoleSpy = jest\n .spyOn(console, \"error\")\n .mockImplementation(() => {});\n const testError = new Error(\"API Error\");\n mockThreadsRunsApi.run.mockRejectedValue(testError);\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n try {\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n });\n } catch {\n // Expected to throw\n }\n\n await waitFor(() => {\n expect(consoleSpy).toHaveBeenCalledWith(\n \"[useTamboV1SendMessage] Mutation failed:\",\n testError,\n );\n });\n\n consoleSpy.mockRestore();\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-send-message.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-send-message.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { EventType } from \"@ag-ui/core\";\nimport TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { renderHook, waitFor, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport type { TamboTool } from \"../../model/component-metadata\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport { TamboRegistryContext } from \"../../providers/tambo-registry-provider\";\nimport { useTamboV1Config } from \"../providers/tambo-v1-provider\";\nimport { TamboV1StreamProvider } from \"../providers/tambo-v1-stream-context\";\nimport {\n createRunStream,\n useTamboV1SendMessage,\n} from \"./use-tambo-v1-send-message\";\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n}));\n\njest.mock(\"../providers/tambo-v1-provider\", () => ({\n useTamboV1Config: jest.fn(),\n}));\n\ndescribe(\"useTamboV1SendMessage\", () => {\n const mockThreadsRunsApi = {\n run: jest.fn(),\n create: jest.fn(),\n };\n\n const mockTamboAI = {\n apiKey: \"\",\n threads: {\n runs: mockThreadsRunsApi,\n },\n } as unknown as TamboAI;\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n let queryClient: QueryClient;\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n beforeEach(() => {\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n jest.mocked(useTamboClient).mockReturnValue(mockTamboAI);\n jest.mocked(useTamboV1Config).mockReturnValue({ userKey: undefined });\n mockThreadsRunsApi.run.mockReset();\n mockThreadsRunsApi.create.mockReset();\n });\n\n it(\"returns a mutation object\", () => {\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.mutate).toBeDefined();\n expect(result.current.mutateAsync).toBeDefined();\n expect(result.current.isPending).toBe(false);\n });\n\n it(\"returns a mutation object when threadId is not provided\", () => {\n const { result } = renderHook(() => useTamboV1SendMessage(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.mutate).toBeDefined();\n expect(result.current.mutateAsync).toBeDefined();\n });\n});\n\ndescribe(\"createRunStream\", () => {\n const mockStream = {\n [Symbol.asyncIterator]: async function* () {\n yield { type: \"RUN_STARTED\", runId: \"run_1\", threadId: \"thread_123\" };\n },\n };\n\n const mockThreadsRunsApi = {\n run: jest.fn(),\n create: jest.fn(),\n };\n\n const mockClient = {\n threads: {\n runs: mockThreadsRunsApi,\n },\n } as unknown as TamboAI;\n\n const mockRegistry = {\n componentList: new Map([\n [\n \"TestComponent\",\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: () => null,\n propsSchema: z.object({ title: z.string() }),\n },\n ],\n ]),\n toolRegistry: new Map([\n [\n \"testTool\",\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema: z.object({ query: z.string() }),\n },\n ],\n ]),\n };\n\n const testMessage = {\n role: \"user\" as const,\n content: [{ type: \"text\" as const, text: \"Hello\" }],\n };\n\n beforeEach(() => {\n mockThreadsRunsApi.run.mockReset();\n mockThreadsRunsApi.create.mockReset();\n });\n\n it(\"calls client.threads.runs.run when threadId is provided\", async () => {\n mockThreadsRunsApi.run.mockResolvedValue(mockStream);\n\n const result = await createRunStream({\n client: mockClient,\n threadId: \"thread_123\",\n message: testMessage,\n registry: mockRegistry as any,\n userKey: undefined,\n });\n\n expect(mockThreadsRunsApi.run).toHaveBeenCalledWith(\"thread_123\", {\n message: testMessage,\n availableComponents: expect.any(Array),\n tools: expect.any(Array),\n userKey: undefined,\n });\n expect(mockThreadsRunsApi.create).not.toHaveBeenCalled();\n expect(result.stream).toBe(mockStream);\n expect(result.initialThreadId).toBe(\"thread_123\");\n });\n\n it(\"calls client.threads.runs.create when threadId is not provided\", async () => {\n mockThreadsRunsApi.create.mockResolvedValue(mockStream);\n\n const result = await createRunStream({\n client: mockClient,\n threadId: undefined,\n message: testMessage,\n registry: mockRegistry as any,\n userKey: undefined,\n });\n\n expect(mockThreadsRunsApi.create).toHaveBeenCalledWith({\n message: testMessage,\n availableComponents: expect.any(Array),\n tools: expect.any(Array),\n thread: undefined,\n });\n expect(mockThreadsRunsApi.run).not.toHaveBeenCalled();\n expect(result.stream).toBe(mockStream);\n expect(result.initialThreadId).toBeUndefined();\n });\n\n it(\"converts registry components to availableComponents format\", async () => {\n mockThreadsRunsApi.run.mockResolvedValue(mockStream);\n\n await createRunStream({\n client: mockClient,\n threadId: \"thread_123\",\n message: testMessage,\n registry: mockRegistry as any,\n userKey: undefined,\n });\n\n const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];\n expect(callArgs.availableComponents).toEqual([\n {\n name: \"TestComponent\",\n description: \"A test component\",\n propsSchema: expect.any(Object),\n },\n ]);\n });\n\n it(\"converts registry tools to tools format\", async () => {\n mockThreadsRunsApi.run.mockResolvedValue(mockStream);\n\n await createRunStream({\n client: mockClient,\n threadId: \"thread_123\",\n message: testMessage,\n registry: mockRegistry as any,\n userKey: undefined,\n });\n\n const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];\n expect(callArgs.tools).toEqual([\n expect.objectContaining({\n name: \"testTool\",\n description: \"A test tool\",\n }),\n ]);\n });\n\n it(\"handles empty registry\", async () => {\n mockThreadsRunsApi.run.mockResolvedValue(mockStream);\n\n const emptyRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n await createRunStream({\n client: mockClient,\n threadId: \"thread_123\",\n message: testMessage,\n registry: emptyRegistry as any,\n userKey: undefined,\n });\n\n const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];\n expect(callArgs.availableComponents).toEqual([]);\n expect(callArgs.tools).toEqual([]);\n });\n});\n\ndescribe(\"useTamboV1SendMessage mutation\", () => {\n const mockThreadsRunsApi = {\n run: jest.fn(),\n create: jest.fn(),\n };\n\n const mockTamboAI = {\n apiKey: \"\",\n threads: {\n runs: mockThreadsRunsApi,\n },\n } as unknown as TamboAI;\n\n let queryClient: QueryClient;\n\n function createAsyncIterator<T>(events: T[]) {\n return {\n [Symbol.asyncIterator]: async function* () {\n for (const event of events) {\n yield event;\n }\n },\n };\n }\n\n beforeEach(() => {\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n jest.mocked(useTamboClient).mockReturnValue(mockTamboAI);\n jest.mocked(useTamboV1Config).mockReturnValue({ userKey: undefined });\n mockThreadsRunsApi.run.mockReset();\n mockThreadsRunsApi.create.mockReset();\n });\n\n it(\"extracts threadId from RUN_STARTED event when creating new thread\", async () => {\n const mockStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"new_thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.create.mockResolvedValue(mockStream);\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(), {\n wrapper: TestWrapper,\n });\n\n let mutationResult: { threadId: string | undefined } | undefined;\n await act(async () => {\n mutationResult = await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n });\n\n expect(mutationResult?.threadId).toBe(\"new_thread_123\");\n });\n\n it(\"throws error when first event is not RUN_STARTED on new thread\", async () => {\n const mockStream = createAsyncIterator([\n { type: EventType.TEXT_MESSAGE_START, messageId: \"msg_1\" },\n ]);\n\n mockThreadsRunsApi.create.mockResolvedValue(mockStream);\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(), {\n wrapper: TestWrapper,\n });\n\n await expect(\n act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n }),\n ).rejects.toThrow(\"Expected first event to be RUN_STARTED with threadId\");\n });\n\n it(\"executes tools on awaiting_input event\", async () => {\n const toolExecuted = jest.fn().mockResolvedValue(\"tool result\");\n\n const testTool: TamboTool = {\n name: \"test_tool\",\n description: \"A test tool\",\n tool: toolExecuted,\n inputSchema: z.object({ query: z.string() }),\n outputSchema: z.string(),\n };\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map([[\"test_tool\", testTool]]),\n };\n\n const initialStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_1\",\n toolCallName: \"test_tool\",\n parentMessageId: \"msg_1\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: '{\"query\":\"test\"}',\n },\n {\n type: EventType.TOOL_CALL_END,\n toolCallId: \"call_1\",\n },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_1\"] },\n },\n ]);\n\n const continueStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_2\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run\n .mockResolvedValueOnce(initialStream)\n .mockResolvedValueOnce(continueStream);\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n });\n\n expect(toolExecuted).toHaveBeenCalledWith({ query: \"test\" });\n\n // Verify continuation was called with tool results\n expect(mockThreadsRunsApi.run).toHaveBeenCalledTimes(2);\n const continueCall = mockThreadsRunsApi.run.mock.calls[1];\n expect(continueCall[0]).toBe(\"thread_123\");\n expect(continueCall[1].previousRunId).toBe(\"run_1\");\n expect(continueCall[1].message.content[0]).toEqual({\n type: \"tool_result\",\n toolUseId: \"call_1\",\n content: [{ type: \"text\", text: \"tool result\" }],\n });\n });\n\n it(\"handles tool calls with chunked args\", async () => {\n const toolExecuted = jest.fn().mockResolvedValue({ result: 42 });\n\n const testTool: TamboTool = {\n name: \"chunked_tool\",\n description: \"Tool with chunked args\",\n tool: toolExecuted,\n inputSchema: z.object({ a: z.number(), b: z.number() }),\n outputSchema: z.object({ result: z.number() }),\n };\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map([[\"chunked_tool\", testTool]]),\n };\n\n const initialStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_1\",\n toolCallName: \"chunked_tool\",\n parentMessageId: \"msg_1\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: '{\"a\":',\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: \"10,\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: '\"b\":20}',\n },\n {\n type: EventType.TOOL_CALL_END,\n toolCallId: \"call_1\",\n },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_1\"] },\n },\n ]);\n\n const continueStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_2\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run\n .mockResolvedValueOnce(initialStream)\n .mockResolvedValueOnce(continueStream);\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Calculate\" }],\n },\n });\n });\n\n expect(toolExecuted).toHaveBeenCalledWith({ a: 10, b: 20 });\n });\n\n it(\"handles missing TOOL_CALL_ARGS gracefully\", async () => {\n // Test that tools can be executed even when no args events are received\n // (the hook keeps input as empty object)\n const toolExecuted = jest.fn().mockResolvedValue(\"result\");\n\n const testTool: TamboTool = {\n name: \"test_tool\",\n description: \"Test tool\",\n tool: toolExecuted,\n inputSchema: z.object({}),\n outputSchema: z.string(),\n };\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map([[\"test_tool\", testTool]]),\n };\n\n const initialStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_1\",\n toolCallName: \"test_tool\",\n parentMessageId: \"msg_1\",\n },\n // No TOOL_CALL_ARGS events - args will be empty\n {\n type: EventType.TOOL_CALL_END,\n toolCallId: \"call_1\",\n },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_1\"] },\n },\n ]);\n\n const continueStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_2\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run\n .mockResolvedValueOnce(initialStream)\n .mockResolvedValueOnce(continueStream);\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Test\" }],\n },\n });\n });\n\n // Tool should be called with empty input due to no args events\n expect(toolExecuted).toHaveBeenCalledWith({});\n });\n\n it(\"handles unknown tool in awaiting_input by returning error result\", async () => {\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(), // Empty registry - tool not found\n };\n\n const initialStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_1\",\n toolCallName: \"unknown_tool\",\n parentMessageId: \"msg_1\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: \"{}\",\n },\n {\n type: EventType.TOOL_CALL_END,\n toolCallId: \"call_1\",\n },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_1\"] },\n },\n ]);\n\n const continueStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_2\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run\n .mockResolvedValueOnce(initialStream)\n .mockResolvedValueOnce(continueStream);\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Test\" }],\n },\n });\n });\n\n // Verify continuation was called (second call)\n expect(mockThreadsRunsApi.run).toHaveBeenCalledTimes(2);\n\n // Continuation should include error message for unknown tool\n const continueCall = mockThreadsRunsApi.run.mock.calls[1];\n expect(continueCall[1].message.content[0]).toEqual({\n type: \"tool_result\",\n toolUseId: \"call_1\",\n content: [\n { type: \"text\", text: 'Tool \"unknown_tool\" not found in registry' },\n ],\n });\n });\n\n it(\"works with default registry context when no provider is present\", () => {\n // TamboRegistryContext has a default value, so the hook should work\n // (though with an empty registry)\n function TestWrapperWithoutRegistry({\n children,\n }: {\n children: React.ReactNode;\n }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </QueryClientProvider>\n );\n }\n\n // Should not throw - default context is used\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapperWithoutRegistry,\n });\n\n expect(result.current.mutate).toBeDefined();\n });\n\n it(\"invalidates queries on successful mutation\", async () => {\n const mockStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run.mockResolvedValue(mockStream);\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const invalidateQueriesSpy = jest.spyOn(queryClient, \"invalidateQueries\");\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n });\n\n await waitFor(() => {\n expect(invalidateQueriesSpy).toHaveBeenCalledWith({\n queryKey: [\"v1-threads\", \"thread_123\"],\n });\n });\n });\n\n it(\"handles multi-round tool execution (tool→AI→tool→AI)\", async () => {\n const tool1Executed = jest.fn().mockResolvedValue(\"result from tool 1\");\n const tool2Executed = jest.fn().mockResolvedValue(\"result from tool 2\");\n\n const tool1: TamboTool = {\n name: \"tool_1\",\n description: \"First tool\",\n tool: tool1Executed,\n inputSchema: z.object({ input: z.string() }),\n outputSchema: z.string(),\n };\n\n const tool2: TamboTool = {\n name: \"tool_2\",\n description: \"Second tool\",\n tool: tool2Executed,\n inputSchema: z.object({ input: z.string() }),\n outputSchema: z.string(),\n };\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map([\n [\"tool_1\", tool1],\n [\"tool_2\", tool2],\n ]),\n };\n\n // Initial stream: AI calls tool_1\n const initialStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_1\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_1\",\n toolCallName: \"tool_1\",\n parentMessageId: \"msg_1\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_1\",\n delta: '{\"input\":\"first\"}',\n },\n { type: EventType.TOOL_CALL_END, toolCallId: \"call_1\" },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_1\"] },\n },\n ]);\n\n // Second stream: AI receives tool_1 result, then calls tool_2\n const secondStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_2\",\n threadId: \"thread_123\",\n },\n {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_2\",\n role: \"assistant\",\n },\n {\n type: EventType.TOOL_CALL_START,\n toolCallId: \"call_2\",\n toolCallName: \"tool_2\",\n parentMessageId: \"msg_2\",\n },\n {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: \"call_2\",\n delta: '{\"input\":\"second\"}',\n },\n { type: EventType.TOOL_CALL_END, toolCallId: \"call_2\" },\n {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: { pendingToolCallIds: [\"call_2\"] },\n },\n ]);\n\n // Third stream: AI receives tool_2 result, finishes\n const thirdStream = createAsyncIterator([\n {\n type: EventType.RUN_STARTED,\n runId: \"run_3\",\n threadId: \"thread_123\",\n },\n { type: EventType.RUN_FINISHED },\n ]);\n\n mockThreadsRunsApi.run\n .mockResolvedValueOnce(initialStream)\n .mockResolvedValueOnce(secondStream)\n .mockResolvedValueOnce(thirdStream);\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n });\n\n // Both tools should have been executed\n expect(tool1Executed).toHaveBeenCalledWith({ input: \"first\" });\n expect(tool2Executed).toHaveBeenCalledWith({ input: \"second\" });\n\n // Should have made 3 API calls (initial + 2 continuations)\n expect(mockThreadsRunsApi.run).toHaveBeenCalledTimes(3);\n\n // First continuation should have tool_1 result with previousRunId: run_1\n const firstContinue = mockThreadsRunsApi.run.mock.calls[1];\n expect(firstContinue[1].previousRunId).toBe(\"run_1\");\n expect(firstContinue[1].message.content[0]).toEqual({\n type: \"tool_result\",\n toolUseId: \"call_1\",\n content: [{ type: \"text\", text: \"result from tool 1\" }],\n });\n\n // Second continuation should have tool_2 result with previousRunId: run_2\n const secondContinue = mockThreadsRunsApi.run.mock.calls[2];\n expect(secondContinue[1].previousRunId).toBe(\"run_2\");\n expect(secondContinue[1].message.content[0]).toEqual({\n type: \"tool_result\",\n toolUseId: \"call_2\",\n content: [{ type: \"text\", text: \"result from tool 2\" }],\n });\n });\n\n it(\"logs error on mutation failure\", async () => {\n const consoleSpy = jest\n .spyOn(console, \"error\")\n .mockImplementation(() => {});\n const testError = new Error(\"API Error\");\n mockThreadsRunsApi.run.mockRejectedValue(testError);\n\n const mockRegistry = {\n componentList: new Map(),\n toolRegistry: new Map(),\n };\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n <TamboRegistryContext.Provider value={mockRegistry as any}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n </QueryClientProvider>\n );\n }\n\n const { result } = renderHook(() => useTamboV1SendMessage(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n try {\n await act(async () => {\n await result.current.mutateAsync({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Hello\" }],\n },\n });\n });\n } catch {\n // Expected to throw\n }\n\n await waitFor(() => {\n expect(consoleSpy).toHaveBeenCalledWith(\n \"[useTamboV1SendMessage] Mutation failed:\",\n testError,\n );\n });\n\n consoleSpy.mockRestore();\n });\n});\n"]}
|