@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.
Files changed (129) hide show
  1. package/dist/v1/hooks/use-tambo-v1-messages.test.js +22 -9
  2. package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
  3. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +1 -0
  4. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  5. package/dist/v1/hooks/use-tambo-v1-send-message.js +9 -2
  6. package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  7. package/dist/v1/hooks/use-tambo-v1-send-message.test.js +22 -9
  8. package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  9. package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts +91 -0
  10. package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -0
  11. package/dist/v1/hooks/use-tambo-v1-suggestions.js +152 -0
  12. package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -0
  13. package/dist/v1/hooks/use-tambo-v1-suggestions.test.d.ts +2 -0
  14. package/dist/v1/hooks/use-tambo-v1-suggestions.test.d.ts.map +1 -0
  15. package/dist/v1/hooks/use-tambo-v1-suggestions.test.js +511 -0
  16. package/dist/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -0
  17. package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts +6 -57
  18. package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -1
  19. package/dist/v1/hooks/use-tambo-v1-thread-input.js +7 -67
  20. package/dist/v1/hooks/use-tambo-v1-thread-input.js.map +1 -1
  21. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +201 -72
  22. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
  23. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +6 -4
  24. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
  25. package/dist/v1/hooks/use-tambo-v1-thread-list.js +2 -2
  26. package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
  27. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +2 -2
  28. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
  29. package/dist/v1/hooks/use-tambo-v1.test.js +16 -7
  30. package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
  31. package/dist/v1/index.d.ts +22 -13
  32. package/dist/v1/index.d.ts.map +1 -1
  33. package/dist/v1/index.js +31 -39
  34. package/dist/v1/index.js.map +1 -1
  35. package/dist/v1/providers/tambo-v1-provider.d.ts +27 -9
  36. package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  37. package/dist/v1/providers/tambo-v1-provider.js +22 -11
  38. package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
  39. package/dist/v1/providers/tambo-v1-provider.test.js +27 -10
  40. package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
  41. package/dist/v1/providers/tambo-v1-stream-context.d.ts +19 -10
  42. package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  43. package/dist/v1/providers/tambo-v1-stream-context.js +43 -53
  44. package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
  45. package/dist/v1/providers/tambo-v1-stream-context.test.js +94 -19
  46. package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  47. package/dist/v1/providers/tambo-v1-stub-provider.d.ts +74 -0
  48. package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -0
  49. package/dist/v1/providers/tambo-v1-stub-provider.js +212 -0
  50. package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -0
  51. package/dist/v1/providers/tambo-v1-stub-provider.test.d.ts +2 -0
  52. package/dist/v1/providers/tambo-v1-stub-provider.test.d.ts.map +1 -0
  53. package/dist/v1/providers/tambo-v1-stub-provider.test.js +162 -0
  54. package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -0
  55. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +105 -0
  56. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -0
  57. package/dist/v1/providers/tambo-v1-thread-input-provider.js +191 -0
  58. package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -0
  59. package/dist/v1/utils/component-renderer.d.ts +15 -67
  60. package/dist/v1/utils/component-renderer.d.ts.map +1 -1
  61. package/dist/v1/utils/component-renderer.js +3 -149
  62. package/dist/v1/utils/component-renderer.js.map +1 -1
  63. package/dist/v1/utils/component-renderer.test.js +15 -350
  64. package/dist/v1/utils/component-renderer.test.js.map +1 -1
  65. package/esm/v1/hooks/use-tambo-v1-messages.test.js +22 -9
  66. package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
  67. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +1 -0
  68. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  69. package/esm/v1/hooks/use-tambo-v1-send-message.js +9 -2
  70. package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  71. package/esm/v1/hooks/use-tambo-v1-send-message.test.js +22 -9
  72. package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  73. package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts +91 -0
  74. package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -0
  75. package/esm/v1/hooks/use-tambo-v1-suggestions.js +149 -0
  76. package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -0
  77. package/esm/v1/hooks/use-tambo-v1-suggestions.test.d.ts +2 -0
  78. package/esm/v1/hooks/use-tambo-v1-suggestions.test.d.ts.map +1 -0
  79. package/esm/v1/hooks/use-tambo-v1-suggestions.test.js +506 -0
  80. package/esm/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -0
  81. package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +6 -57
  82. package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -1
  83. package/esm/v1/hooks/use-tambo-v1-thread-input.js +5 -66
  84. package/esm/v1/hooks/use-tambo-v1-thread-input.js.map +1 -1
  85. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +199 -73
  86. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
  87. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +6 -4
  88. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
  89. package/esm/v1/hooks/use-tambo-v1-thread-list.js +2 -2
  90. package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
  91. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +2 -2
  92. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
  93. package/esm/v1/hooks/use-tambo-v1.test.js +16 -7
  94. package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
  95. package/esm/v1/index.d.ts +22 -13
  96. package/esm/v1/index.d.ts.map +1 -1
  97. package/esm/v1/index.js +23 -18
  98. package/esm/v1/index.js.map +1 -1
  99. package/esm/v1/providers/tambo-v1-provider.d.ts +27 -9
  100. package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  101. package/esm/v1/providers/tambo-v1-provider.js +20 -10
  102. package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
  103. package/esm/v1/providers/tambo-v1-provider.test.js +28 -11
  104. package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
  105. package/esm/v1/providers/tambo-v1-stream-context.d.ts +19 -10
  106. package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  107. package/esm/v1/providers/tambo-v1-stream-context.js +44 -54
  108. package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
  109. package/esm/v1/providers/tambo-v1-stream-context.test.js +95 -20
  110. package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  111. package/esm/v1/providers/tambo-v1-stub-provider.d.ts +74 -0
  112. package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -0
  113. package/esm/v1/providers/tambo-v1-stub-provider.js +176 -0
  114. package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -0
  115. package/esm/v1/providers/tambo-v1-stub-provider.test.d.ts +2 -0
  116. package/esm/v1/providers/tambo-v1-stub-provider.test.d.ts.map +1 -0
  117. package/esm/v1/providers/tambo-v1-stub-provider.test.js +157 -0
  118. package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -0
  119. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +105 -0
  120. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -0
  121. package/esm/v1/providers/tambo-v1-thread-input-provider.js +153 -0
  122. package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -0
  123. package/esm/v1/utils/component-renderer.d.ts +15 -67
  124. package/esm/v1/utils/component-renderer.d.ts.map +1 -1
  125. package/esm/v1/utils/component-renderer.js +4 -146
  126. package/esm/v1/utils/component-renderer.js.map +1 -1
  127. package/esm/v1/utils/component-renderer.test.js +16 -351
  128. package/esm/v1/utils/component-renderer.test.js.map +1 -1
  129. package/package.json +2 -2
@@ -10,24 +10,33 @@ const tambo_v1_stream_context_1 = require("../providers/tambo-v1-stream-context"
10
10
  const use_tambo_v1_messages_1 = require("./use-tambo-v1-messages");
11
11
  describe("useTamboV1Messages", () => {
12
12
  function TestWrapper({ children }) {
13
- return (react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { threadId: "thread_123" }, children));
13
+ return react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children);
14
14
  }
15
15
  it("returns empty messages when thread has no messages", () => {
16
- const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_messages_1.useTamboV1Messages)("thread_123"), {
17
- wrapper: TestWrapper,
16
+ const { result } = (0, react_1.renderHook)(() => ({
17
+ messages: (0, use_tambo_v1_messages_1.useTamboV1Messages)("thread_123"),
18
+ dispatch: (0, tambo_v1_stream_context_1.useStreamDispatch)(),
19
+ }), { wrapper: TestWrapper });
20
+ // Initialize thread first
21
+ (0, react_1.act)(() => {
22
+ result.current.dispatch({ type: "INIT_THREAD", threadId: "thread_123" });
18
23
  });
19
- expect(result.current.messages).toEqual([]);
20
- expect(result.current.hasMessages).toBe(false);
21
- expect(result.current.messageCount).toBe(0);
22
- expect(result.current.lastMessage).toBeUndefined();
23
- expect(result.current.userMessages).toEqual([]);
24
- expect(result.current.assistantMessages).toEqual([]);
24
+ expect(result.current.messages.messages).toEqual([]);
25
+ expect(result.current.messages.hasMessages).toBe(false);
26
+ expect(result.current.messages.messageCount).toBe(0);
27
+ expect(result.current.messages.lastMessage).toBeUndefined();
28
+ expect(result.current.messages.userMessages).toEqual([]);
29
+ expect(result.current.messages.assistantMessages).toEqual([]);
25
30
  });
26
31
  it("returns messages after events are dispatched", () => {
27
32
  const { result } = (0, react_1.renderHook)(() => ({
28
33
  messages: (0, use_tambo_v1_messages_1.useTamboV1Messages)("thread_123"),
29
34
  dispatch: (0, tambo_v1_stream_context_1.useStreamDispatch)(),
30
35
  }), { wrapper: TestWrapper });
36
+ // Initialize thread first
37
+ (0, react_1.act)(() => {
38
+ result.current.dispatch({ type: "INIT_THREAD", threadId: "thread_123" });
39
+ });
31
40
  // Simulate a text message being received
32
41
  (0, react_1.act)(() => {
33
42
  result.current.dispatch({
@@ -74,6 +83,10 @@ describe("useTamboV1Messages", () => {
74
83
  messages: (0, use_tambo_v1_messages_1.useTamboV1Messages)("thread_123"),
75
84
  dispatch: (0, tambo_v1_stream_context_1.useStreamDispatch)(),
76
85
  }), { wrapper: TestWrapper });
86
+ // Initialize thread first
87
+ (0, react_1.act)(() => {
88
+ result.current.dispatch({ type: "INIT_THREAD", threadId: "thread_123" });
89
+ });
77
90
  // Add user message
78
91
  (0, react_1.act)(() => {
79
92
  result.current.dispatch({
@@ -1 +1 @@
1
- {"version":3,"file":"use-tambo-v1-messages.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-messages.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n EventType,\n type TextMessageStartEvent,\n type TextMessageContentEvent,\n type TextMessageEndEvent,\n} from \"@ag-ui/core\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport {\n TamboV1StreamProvider,\n useStreamDispatch,\n} from \"../providers/tambo-v1-stream-context\";\nimport { useTamboV1Messages } from \"./use-tambo-v1-messages\";\n\ndescribe(\"useTamboV1Messages\", () => {\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n );\n }\n\n it(\"returns empty messages when thread has no messages\", () => {\n const { result } = renderHook(() => useTamboV1Messages(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.messages).toEqual([]);\n expect(result.current.hasMessages).toBe(false);\n expect(result.current.messageCount).toBe(0);\n expect(result.current.lastMessage).toBeUndefined();\n expect(result.current.userMessages).toEqual([]);\n expect(result.current.assistantMessages).toEqual([]);\n });\n\n it(\"returns messages after events are dispatched\", () => {\n const { result } = renderHook(\n () => ({\n messages: useTamboV1Messages(\"thread_123\"),\n dispatch: useStreamDispatch(),\n }),\n { wrapper: TestWrapper },\n );\n\n // Simulate a text message being received\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n } as TextMessageStartEvent,\n threadId: \"thread_123\",\n });\n });\n\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: \"msg_1\",\n delta: \"Hello\",\n } as TextMessageContentEvent,\n threadId: \"thread_123\",\n });\n });\n\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_END,\n messageId: \"msg_1\",\n } as TextMessageEndEvent,\n threadId: \"thread_123\",\n });\n });\n\n expect(result.current.messages.messages.length).toBe(1);\n expect(result.current.messages.hasMessages).toBe(true);\n expect(result.current.messages.messageCount).toBe(1);\n expect(result.current.messages.lastMessage?.id).toBe(\"msg_1\");\n expect(result.current.messages.lastMessage?.role).toBe(\"assistant\");\n expect(result.current.messages.assistantMessages.length).toBe(1);\n expect(result.current.messages.userMessages.length).toBe(0);\n });\n\n it(\"filters user and assistant messages correctly\", () => {\n const { result } = renderHook(\n () => ({\n messages: useTamboV1Messages(\"thread_123\"),\n dispatch: useStreamDispatch(),\n }),\n { wrapper: TestWrapper },\n );\n\n // Add user message\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_user\",\n role: \"user\",\n } as TextMessageStartEvent,\n threadId: \"thread_123\",\n });\n });\n\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_END,\n messageId: \"msg_user\",\n } as TextMessageEndEvent,\n threadId: \"thread_123\",\n });\n });\n\n // Add assistant message\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_assistant\",\n role: \"assistant\",\n } as TextMessageStartEvent,\n threadId: \"thread_123\",\n });\n });\n\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_END,\n messageId: \"msg_assistant\",\n } as TextMessageEndEvent,\n threadId: \"thread_123\",\n });\n });\n\n expect(result.current.messages.messageCount).toBe(2);\n expect(result.current.messages.userMessages.length).toBe(1);\n expect(result.current.messages.userMessages[0].id).toBe(\"msg_user\");\n expect(result.current.messages.assistantMessages.length).toBe(1);\n expect(result.current.messages.assistantMessages[0].id).toBe(\n \"msg_assistant\",\n );\n expect(result.current.messages.lastMessage?.id).toBe(\"msg_assistant\");\n });\n\n it(\"returns empty messages when threadId does not exist in threadMap\", () => {\n const { result } = renderHook(\n () => useTamboV1Messages(\"nonexistent_thread\"),\n {\n wrapper: TestWrapper,\n },\n );\n\n expect(result.current.messages).toEqual([]);\n expect(result.current.hasMessages).toBe(false);\n expect(result.current.messageCount).toBe(0);\n });\n});\n"]}
1
+ {"version":3,"file":"use-tambo-v1-messages.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-messages.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n EventType,\n type TextMessageStartEvent,\n type TextMessageContentEvent,\n type TextMessageEndEvent,\n} from \"@ag-ui/core\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport {\n TamboV1StreamProvider,\n useStreamDispatch,\n} from \"../providers/tambo-v1-stream-context\";\nimport { useTamboV1Messages } from \"./use-tambo-v1-messages\";\n\ndescribe(\"useTamboV1Messages\", () => {\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return <TamboV1StreamProvider>{children}</TamboV1StreamProvider>;\n }\n\n it(\"returns empty messages when thread has no messages\", () => {\n const { result } = renderHook(\n () => ({\n messages: useTamboV1Messages(\"thread_123\"),\n dispatch: useStreamDispatch(),\n }),\n { wrapper: TestWrapper },\n );\n\n // Initialize thread first\n act(() => {\n result.current.dispatch({ type: \"INIT_THREAD\", threadId: \"thread_123\" });\n });\n\n expect(result.current.messages.messages).toEqual([]);\n expect(result.current.messages.hasMessages).toBe(false);\n expect(result.current.messages.messageCount).toBe(0);\n expect(result.current.messages.lastMessage).toBeUndefined();\n expect(result.current.messages.userMessages).toEqual([]);\n expect(result.current.messages.assistantMessages).toEqual([]);\n });\n\n it(\"returns messages after events are dispatched\", () => {\n const { result } = renderHook(\n () => ({\n messages: useTamboV1Messages(\"thread_123\"),\n dispatch: useStreamDispatch(),\n }),\n { wrapper: TestWrapper },\n );\n\n // Initialize thread first\n act(() => {\n result.current.dispatch({ type: \"INIT_THREAD\", threadId: \"thread_123\" });\n });\n\n // Simulate a text message being received\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_1\",\n role: \"assistant\",\n } as TextMessageStartEvent,\n threadId: \"thread_123\",\n });\n });\n\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId: \"msg_1\",\n delta: \"Hello\",\n } as TextMessageContentEvent,\n threadId: \"thread_123\",\n });\n });\n\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_END,\n messageId: \"msg_1\",\n } as TextMessageEndEvent,\n threadId: \"thread_123\",\n });\n });\n\n expect(result.current.messages.messages.length).toBe(1);\n expect(result.current.messages.hasMessages).toBe(true);\n expect(result.current.messages.messageCount).toBe(1);\n expect(result.current.messages.lastMessage?.id).toBe(\"msg_1\");\n expect(result.current.messages.lastMessage?.role).toBe(\"assistant\");\n expect(result.current.messages.assistantMessages.length).toBe(1);\n expect(result.current.messages.userMessages.length).toBe(0);\n });\n\n it(\"filters user and assistant messages correctly\", () => {\n const { result } = renderHook(\n () => ({\n messages: useTamboV1Messages(\"thread_123\"),\n dispatch: useStreamDispatch(),\n }),\n { wrapper: TestWrapper },\n );\n\n // Initialize thread first\n act(() => {\n result.current.dispatch({ type: \"INIT_THREAD\", threadId: \"thread_123\" });\n });\n\n // Add user message\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_user\",\n role: \"user\",\n } as TextMessageStartEvent,\n threadId: \"thread_123\",\n });\n });\n\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_END,\n messageId: \"msg_user\",\n } as TextMessageEndEvent,\n threadId: \"thread_123\",\n });\n });\n\n // Add assistant message\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_START,\n messageId: \"msg_assistant\",\n role: \"assistant\",\n } as TextMessageStartEvent,\n threadId: \"thread_123\",\n });\n });\n\n act(() => {\n result.current.dispatch({\n type: \"EVENT\",\n event: {\n type: EventType.TEXT_MESSAGE_END,\n messageId: \"msg_assistant\",\n } as TextMessageEndEvent,\n threadId: \"thread_123\",\n });\n });\n\n expect(result.current.messages.messageCount).toBe(2);\n expect(result.current.messages.userMessages.length).toBe(1);\n expect(result.current.messages.userMessages[0].id).toBe(\"msg_user\");\n expect(result.current.messages.assistantMessages.length).toBe(1);\n expect(result.current.messages.assistantMessages[0].id).toBe(\n \"msg_assistant\",\n );\n expect(result.current.messages.lastMessage?.id).toBe(\"msg_assistant\");\n });\n\n it(\"returns empty messages when threadId does not exist in threadMap\", () => {\n const { result } = renderHook(\n () => useTamboV1Messages(\"nonexistent_thread\"),\n {\n wrapper: TestWrapper,\n },\n );\n\n expect(result.current.messages).toEqual([]);\n expect(result.current.hasMessages).toBe(false);\n expect(result.current.messageCount).toBe(0);\n });\n});\n"]}
@@ -23,6 +23,7 @@ export interface CreateRunStreamParams {
23
23
  threadId: string | undefined;
24
24
  message: InputMessage;
25
25
  registry: TamboRegistry;
26
+ userKey: string | undefined;
26
27
  }
27
28
  /**
28
29
  * Stream types from the SDK
@@ -1 +1 @@
1
- {"version":3,"file":"use-tambo-v1-send-message.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-send-message.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AAEtE,OAAO,EAEL,KAAK,oBAAoB,IAAI,aAAa,EAC3C,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AASrD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,aAAa,CAAC;CACzB;AAED;;GAEG;AACH,KAAK,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AAC7D,KAAK,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC;IACjC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAoDD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAyBhC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,CAAC,EAAE,MAAM;;uCAqHtD"}
1
+ {"version":3,"file":"use-tambo-v1-send-message.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-send-message.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AAEtE,OAAO,EAEL,KAAK,oBAAoB,IAAI,aAAa,EAC3C,MAAM,yCAAyC,CAAC;AAGjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AASrD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED;;GAEG;AACH,KAAK,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AAC7D,KAAK,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC;IACjC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAuDD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CA2BhC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,CAAC,EAAE,MAAM;;uCAwHtD"}
@@ -15,6 +15,7 @@ const event_1 = require("../types/event");
15
15
  const tambo_client_provider_1 = require("../../providers/tambo-client-provider");
16
16
  const tambo_registry_provider_1 = require("../../providers/tambo-registry-provider");
17
17
  const tambo_v1_stream_context_1 = require("../providers/tambo-v1-stream-context");
18
+ const tambo_v1_provider_1 = require("../providers/tambo-v1-provider");
18
19
  const registry_conversion_1 = require("../utils/registry-conversion");
19
20
  const stream_handler_1 = require("../utils/stream-handler");
20
21
  const tool_executor_1 = require("../utils/tool-executor");
@@ -29,7 +30,7 @@ const tool_call_tracker_1 = require("../utils/tool-call-tracker");
29
30
  * @returns The continuation stream to process
30
31
  */
31
32
  async function executeToolsAndContinue(params) {
32
- const { event, toolTracker, registry, client, threadId, runId } = params;
33
+ const { event, toolTracker, registry, client, threadId, runId, userKey } = params;
33
34
  const { pendingToolCallIds } = event.value;
34
35
  const toolCallsToExecute = toolTracker.getToolCallsById(pendingToolCallIds);
35
36
  // Execute tools
@@ -45,6 +46,7 @@ async function executeToolsAndContinue(params) {
45
46
  previousRunId: runId,
46
47
  availableComponents: (0, registry_conversion_1.toAvailableComponents)(registry.componentList),
47
48
  tools: (0, registry_conversion_1.toAvailableTools)(registry.toolRegistry),
49
+ userKey,
48
50
  });
49
51
  }
50
52
  /**
@@ -56,7 +58,7 @@ async function executeToolsAndContinue(params) {
56
58
  * @returns The stream and initial thread ID (undefined if creating new thread)
57
59
  */
58
60
  async function createRunStream(params) {
59
- const { client, threadId, message, registry } = params;
61
+ const { client, threadId, message, registry, userKey } = params;
60
62
  // Convert registry components/tools to v1 API format
61
63
  const availableComponents = (0, registry_conversion_1.toAvailableComponents)(registry.componentList);
62
64
  const availableTools = (0, registry_conversion_1.toAvailableTools)(registry.toolRegistry);
@@ -66,6 +68,7 @@ async function createRunStream(params) {
66
68
  message,
67
69
  availableComponents,
68
70
  tools: availableTools,
71
+ userKey,
69
72
  });
70
73
  return { stream, initialThreadId: threadId };
71
74
  }
@@ -75,6 +78,7 @@ async function createRunStream(params) {
75
78
  message,
76
79
  availableComponents,
77
80
  tools: availableTools,
81
+ thread: userKey ? { userKey } : undefined,
78
82
  });
79
83
  // threadId will be extracted from first event (RUN_STARTED)
80
84
  return { stream, initialThreadId: undefined };
@@ -127,6 +131,7 @@ async function createRunStream(params) {
127
131
  function useTamboV1SendMessage(threadId) {
128
132
  const client = (0, tambo_client_provider_1.useTamboClient)();
129
133
  const dispatch = (0, tambo_v1_stream_context_1.useStreamDispatch)();
134
+ const { userKey } = (0, tambo_v1_provider_1.useTamboV1Config)();
130
135
  const registry = (0, react_1.useContext)(tambo_registry_provider_1.TamboRegistryContext);
131
136
  const queryClient = (0, react_query_1.useQueryClient)();
132
137
  if (!registry) {
@@ -142,6 +147,7 @@ function useTamboV1SendMessage(threadId) {
142
147
  threadId,
143
148
  message,
144
149
  registry,
150
+ userKey,
145
151
  });
146
152
  let actualThreadId = initialThreadId;
147
153
  let runId;
@@ -191,6 +197,7 @@ function useTamboV1SendMessage(threadId) {
191
197
  client,
192
198
  threadId: actualThreadId,
193
199
  runId,
200
+ userKey,
194
201
  });
195
202
  }
196
203
  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"]}
@@ -10,11 +10,15 @@ const react_2 = __importDefault(require("react"));
10
10
  const zod_1 = require("zod");
11
11
  const tambo_client_provider_1 = require("../../providers/tambo-client-provider");
12
12
  const tambo_registry_provider_1 = require("../../providers/tambo-registry-provider");
13
+ const tambo_v1_provider_1 = require("../providers/tambo-v1-provider");
13
14
  const tambo_v1_stream_context_1 = require("../providers/tambo-v1-stream-context");
14
15
  const use_tambo_v1_send_message_1 = require("./use-tambo-v1-send-message");
15
16
  jest.mock("../../providers/tambo-client-provider", () => ({
16
17
  useTamboClient: jest.fn(),
17
18
  }));
19
+ jest.mock("../providers/tambo-v1-provider", () => ({
20
+ useTamboV1Config: jest.fn(),
21
+ }));
18
22
  describe("useTamboV1SendMessage", () => {
19
23
  const mockThreadsRunsApi = {
20
24
  run: jest.fn(),
@@ -34,7 +38,7 @@ describe("useTamboV1SendMessage", () => {
34
38
  function TestWrapper({ children }) {
35
39
  return (react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient },
36
40
  react_2.default.createElement(tambo_registry_provider_1.TamboRegistryContext.Provider, { value: mockRegistry },
37
- react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { threadId: "thread_123" }, children))));
41
+ react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children))));
38
42
  }
39
43
  beforeEach(() => {
40
44
  queryClient = new react_query_1.QueryClient({
@@ -44,6 +48,7 @@ describe("useTamboV1SendMessage", () => {
44
48
  },
45
49
  });
46
50
  jest.mocked(tambo_client_provider_1.useTamboClient).mockReturnValue(mockTamboAI);
51
+ jest.mocked(tambo_v1_provider_1.useTamboV1Config).mockReturnValue({ userKey: undefined });
47
52
  mockThreadsRunsApi.run.mockReset();
48
53
  mockThreadsRunsApi.create.mockReset();
49
54
  });
@@ -117,11 +122,13 @@ describe("createRunStream", () => {
117
122
  threadId: "thread_123",
118
123
  message: testMessage,
119
124
  registry: mockRegistry,
125
+ userKey: undefined,
120
126
  });
121
127
  expect(mockThreadsRunsApi.run).toHaveBeenCalledWith("thread_123", {
122
128
  message: testMessage,
123
129
  availableComponents: expect.any(Array),
124
130
  tools: expect.any(Array),
131
+ userKey: undefined,
125
132
  });
126
133
  expect(mockThreadsRunsApi.create).not.toHaveBeenCalled();
127
134
  expect(result.stream).toBe(mockStream);
@@ -134,11 +141,13 @@ describe("createRunStream", () => {
134
141
  threadId: undefined,
135
142
  message: testMessage,
136
143
  registry: mockRegistry,
144
+ userKey: undefined,
137
145
  });
138
146
  expect(mockThreadsRunsApi.create).toHaveBeenCalledWith({
139
147
  message: testMessage,
140
148
  availableComponents: expect.any(Array),
141
149
  tools: expect.any(Array),
150
+ thread: undefined,
142
151
  });
143
152
  expect(mockThreadsRunsApi.run).not.toHaveBeenCalled();
144
153
  expect(result.stream).toBe(mockStream);
@@ -151,6 +160,7 @@ describe("createRunStream", () => {
151
160
  threadId: "thread_123",
152
161
  message: testMessage,
153
162
  registry: mockRegistry,
163
+ userKey: undefined,
154
164
  });
155
165
  const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];
156
166
  expect(callArgs.availableComponents).toEqual([
@@ -168,6 +178,7 @@ describe("createRunStream", () => {
168
178
  threadId: "thread_123",
169
179
  message: testMessage,
170
180
  registry: mockRegistry,
181
+ userKey: undefined,
171
182
  });
172
183
  const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];
173
184
  expect(callArgs.tools).toEqual([
@@ -188,6 +199,7 @@ describe("createRunStream", () => {
188
199
  threadId: "thread_123",
189
200
  message: testMessage,
190
201
  registry: emptyRegistry,
202
+ userKey: undefined,
191
203
  });
192
204
  const callArgs = mockThreadsRunsApi.run.mock.calls[0][1];
193
205
  expect(callArgs.availableComponents).toEqual([]);
@@ -223,6 +235,7 @@ describe("useTamboV1SendMessage mutation", () => {
223
235
  },
224
236
  });
225
237
  jest.mocked(tambo_client_provider_1.useTamboClient).mockReturnValue(mockTamboAI);
238
+ jest.mocked(tambo_v1_provider_1.useTamboV1Config).mockReturnValue({ userKey: undefined });
226
239
  mockThreadsRunsApi.run.mockReset();
227
240
  mockThreadsRunsApi.create.mockReset();
228
241
  });
@@ -344,7 +357,7 @@ describe("useTamboV1SendMessage mutation", () => {
344
357
  function TestWrapper({ children }) {
345
358
  return (react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient },
346
359
  react_2.default.createElement(tambo_registry_provider_1.TamboRegistryContext.Provider, { value: mockRegistry },
347
- react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { threadId: "thread_123" }, children))));
360
+ react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children))));
348
361
  }
349
362
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_send_message_1.useTamboV1SendMessage)("thread_123"), {
350
363
  wrapper: TestWrapper,
@@ -438,7 +451,7 @@ describe("useTamboV1SendMessage mutation", () => {
438
451
  function TestWrapper({ children }) {
439
452
  return (react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient },
440
453
  react_2.default.createElement(tambo_registry_provider_1.TamboRegistryContext.Provider, { value: mockRegistry },
441
- react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { threadId: "thread_123" }, children))));
454
+ react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children))));
442
455
  }
443
456
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_send_message_1.useTamboV1SendMessage)("thread_123"), {
444
457
  wrapper: TestWrapper,
@@ -510,7 +523,7 @@ describe("useTamboV1SendMessage mutation", () => {
510
523
  function TestWrapper({ children }) {
511
524
  return (react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient },
512
525
  react_2.default.createElement(tambo_registry_provider_1.TamboRegistryContext.Provider, { value: mockRegistry },
513
- react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { threadId: "thread_123" }, children))));
526
+ react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children))));
514
527
  }
515
528
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_send_message_1.useTamboV1SendMessage)("thread_123"), {
516
529
  wrapper: TestWrapper,
@@ -577,7 +590,7 @@ describe("useTamboV1SendMessage mutation", () => {
577
590
  function TestWrapper({ children }) {
578
591
  return (react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient },
579
592
  react_2.default.createElement(tambo_registry_provider_1.TamboRegistryContext.Provider, { value: mockRegistry },
580
- react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { threadId: "thread_123" }, children))));
593
+ react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children))));
581
594
  }
582
595
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_send_message_1.useTamboV1SendMessage)("thread_123"), {
583
596
  wrapper: TestWrapper,
@@ -607,7 +620,7 @@ describe("useTamboV1SendMessage mutation", () => {
607
620
  // (though with an empty registry)
608
621
  function TestWrapperWithoutRegistry({ children, }) {
609
622
  return (react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient },
610
- react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { threadId: "thread_123" }, children)));
623
+ react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children)));
611
624
  }
612
625
  // Should not throw - default context is used
613
626
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_send_message_1.useTamboV1SendMessage)("thread_123"), {
@@ -632,7 +645,7 @@ describe("useTamboV1SendMessage mutation", () => {
632
645
  function TestWrapper({ children }) {
633
646
  return (react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient },
634
647
  react_2.default.createElement(tambo_registry_provider_1.TamboRegistryContext.Provider, { value: mockRegistry },
635
- react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { threadId: "thread_123" }, children))));
648
+ react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children))));
636
649
  }
637
650
  const invalidateQueriesSpy = jest.spyOn(queryClient, "invalidateQueries");
638
651
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_send_message_1.useTamboV1SendMessage)("thread_123"), {
@@ -752,7 +765,7 @@ describe("useTamboV1SendMessage mutation", () => {
752
765
  function TestWrapper({ children }) {
753
766
  return (react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient },
754
767
  react_2.default.createElement(tambo_registry_provider_1.TamboRegistryContext.Provider, { value: mockRegistry },
755
- react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { threadId: "thread_123" }, children))));
768
+ react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children))));
756
769
  }
757
770
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_send_message_1.useTamboV1SendMessage)("thread_123"), {
758
771
  wrapper: TestWrapper,
@@ -800,7 +813,7 @@ describe("useTamboV1SendMessage mutation", () => {
800
813
  function TestWrapper({ children }) {
801
814
  return (react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient },
802
815
  react_2.default.createElement(tambo_registry_provider_1.TamboRegistryContext.Provider, { value: mockRegistry },
803
- react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { threadId: "thread_123" }, children))));
816
+ react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children))));
804
817
  }
805
818
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_send_message_1.useTamboV1SendMessage)("thread_123"), {
806
819
  wrapper: TestWrapper,