@tambo-ai/react 0.12.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 (158) hide show
  1. package/README.md +9 -0
  2. package/dist/hooks/__tests__/use-suggestions.test.d.ts +1 -0
  3. package/dist/hooks/__tests__/use-suggestions.test.js +167 -0
  4. package/dist/hooks/__tests__/use-suggestions.test.js.map +1 -0
  5. package/dist/hooks/react-query-hooks.d.ts +21 -0
  6. package/dist/hooks/react-query-hooks.js +33 -0
  7. package/dist/hooks/react-query-hooks.js.map +1 -0
  8. package/dist/hooks/use-component-state.d.ts +8 -0
  9. package/dist/hooks/use-component-state.js +42 -0
  10. package/dist/hooks/use-component-state.js.map +1 -0
  11. package/dist/hooks/use-current-message.d.ts +18 -0
  12. package/dist/hooks/use-current-message.js +73 -0
  13. package/dist/hooks/use-current-message.js.map +1 -0
  14. package/dist/hooks/use-query-client.d.ts +0 -0
  15. package/dist/hooks/use-query-client.js +2 -0
  16. package/dist/hooks/use-query-client.js.map +1 -0
  17. package/dist/hooks/use-suggestions.d.ts +44 -0
  18. package/dist/hooks/use-suggestions.js +111 -0
  19. package/dist/hooks/use-suggestions.js.map +1 -0
  20. package/dist/hooks/use-tambo-threads.d.ts +137 -0
  21. package/dist/hooks/use-tambo-threads.js +33 -0
  22. package/dist/hooks/use-tambo-threads.js.map +1 -0
  23. package/dist/hooks/use-thread-input.d.ts +48 -0
  24. package/dist/hooks/use-thread-input.js +53 -0
  25. package/dist/hooks/use-thread-input.js.map +1 -0
  26. package/dist/index.d.ts +12 -0
  27. package/dist/index.js +34 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/model/component-metadata.d.ts +32 -0
  30. package/dist/model/component-metadata.js +3 -0
  31. package/dist/model/component-metadata.js.map +1 -0
  32. package/dist/model/generate-component-response.d.ts +17 -0
  33. package/dist/model/generate-component-response.js +22 -0
  34. package/dist/model/generate-component-response.js.map +1 -0
  35. package/dist/model/tambo-thread.d.ts +7 -0
  36. package/dist/model/tambo-thread.js +3 -0
  37. package/dist/model/tambo-thread.js.map +1 -0
  38. package/dist/model/thread-input-error.d.ts +3 -0
  39. package/dist/model/thread-input-error.js +8 -0
  40. package/dist/model/thread-input-error.js.map +1 -0
  41. package/dist/model/validate-input.d.ts +6 -0
  42. package/dist/model/validate-input.js +27 -0
  43. package/dist/model/validate-input.js.map +1 -0
  44. package/dist/providers/index.d.ts +5 -0
  45. package/dist/providers/index.js +21 -0
  46. package/dist/providers/index.js.map +1 -0
  47. package/dist/providers/tambo-client-provider.d.ts +15 -0
  48. package/dist/providers/tambo-client-provider.js +66 -0
  49. package/dist/providers/tambo-client-provider.js.map +1 -0
  50. package/dist/providers/tambo-component-provider.d.ts +18 -0
  51. package/dist/providers/tambo-component-provider.js +129 -0
  52. package/dist/providers/tambo-component-provider.js.map +1 -0
  53. package/dist/providers/tambo-provider.d.ts +10 -0
  54. package/dist/providers/tambo-provider.js +70 -0
  55. package/dist/providers/tambo-provider.js.map +1 -0
  56. package/dist/providers/tambo-registry-provider.d.ts +21 -0
  57. package/dist/providers/tambo-registry-provider.js +117 -0
  58. package/dist/providers/tambo-registry-provider.js.map +1 -0
  59. package/dist/providers/tambo-thread-provider.d.ts +28 -0
  60. package/dist/providers/tambo-thread-provider.js +417 -0
  61. package/dist/providers/tambo-thread-provider.js.map +1 -0
  62. package/dist/setupTests.d.ts +1 -0
  63. package/dist/setupTests.js +20 -0
  64. package/dist/setupTests.js.map +1 -0
  65. package/dist/util/generate-component.d.ts +8 -0
  66. package/dist/util/generate-component.js +209 -0
  67. package/dist/util/generate-component.js.map +1 -0
  68. package/dist/util/messages.d.ts +2 -0
  69. package/dist/util/messages.js +12 -0
  70. package/dist/util/messages.js.map +1 -0
  71. package/dist/util/query-utils.d.ts +5 -0
  72. package/dist/util/query-utils.js +63 -0
  73. package/dist/util/query-utils.js.map +1 -0
  74. package/dist/util/registry.d.ts +7 -0
  75. package/dist/util/registry.js +99 -0
  76. package/dist/util/registry.js.map +1 -0
  77. package/dist/util/tool-caller.d.ts +3 -0
  78. package/dist/util/tool-caller.js +30 -0
  79. package/dist/util/tool-caller.js.map +1 -0
  80. package/esm/hooks/__tests__/use-suggestions.test.d.ts +1 -0
  81. package/esm/hooks/__tests__/use-suggestions.test.js +165 -0
  82. package/esm/hooks/__tests__/use-suggestions.test.js.map +1 -0
  83. package/esm/hooks/react-query-hooks.d.ts +21 -0
  84. package/esm/hooks/react-query-hooks.js +28 -0
  85. package/esm/hooks/react-query-hooks.js.map +1 -0
  86. package/esm/hooks/use-component-state.d.ts +8 -0
  87. package/esm/hooks/use-component-state.js +39 -0
  88. package/esm/hooks/use-component-state.js.map +1 -0
  89. package/esm/hooks/use-current-message.d.ts +18 -0
  90. package/esm/hooks/use-current-message.js +33 -0
  91. package/esm/hooks/use-current-message.js.map +1 -0
  92. package/esm/hooks/use-query-client.d.ts +0 -0
  93. package/esm/hooks/use-query-client.js +2 -0
  94. package/esm/hooks/use-query-client.js.map +1 -0
  95. package/esm/hooks/use-suggestions.d.ts +44 -0
  96. package/esm/hooks/use-suggestions.js +108 -0
  97. package/esm/hooks/use-suggestions.js.map +1 -0
  98. package/esm/hooks/use-tambo-threads.d.ts +137 -0
  99. package/esm/hooks/use-tambo-threads.js +30 -0
  100. package/esm/hooks/use-tambo-threads.js.map +1 -0
  101. package/esm/hooks/use-thread-input.d.ts +48 -0
  102. package/esm/hooks/use-thread-input.js +49 -0
  103. package/esm/hooks/use-thread-input.js.map +1 -0
  104. package/esm/index.d.ts +12 -0
  105. package/esm/index.js +10 -0
  106. package/esm/index.js.map +1 -0
  107. package/esm/model/component-metadata.d.ts +32 -0
  108. package/esm/model/component-metadata.js +2 -0
  109. package/esm/model/component-metadata.js.map +1 -0
  110. package/esm/model/generate-component-response.d.ts +17 -0
  111. package/esm/model/generate-component-response.js +18 -0
  112. package/esm/model/generate-component-response.js.map +1 -0
  113. package/esm/model/tambo-thread.d.ts +7 -0
  114. package/esm/model/tambo-thread.js +2 -0
  115. package/esm/model/tambo-thread.js.map +1 -0
  116. package/esm/model/thread-input-error.d.ts +3 -0
  117. package/esm/model/thread-input-error.js +4 -0
  118. package/esm/model/thread-input-error.js.map +1 -0
  119. package/esm/model/validate-input.d.ts +6 -0
  120. package/esm/model/validate-input.js +24 -0
  121. package/esm/model/validate-input.js.map +1 -0
  122. package/esm/providers/index.d.ts +5 -0
  123. package/esm/providers/index.js +6 -0
  124. package/esm/providers/index.js.map +1 -0
  125. package/esm/providers/tambo-client-provider.d.ts +15 -0
  126. package/esm/providers/tambo-client-provider.js +24 -0
  127. package/esm/providers/tambo-client-provider.js.map +1 -0
  128. package/esm/providers/tambo-component-provider.d.ts +18 -0
  129. package/esm/providers/tambo-component-provider.js +91 -0
  130. package/esm/providers/tambo-component-provider.js.map +1 -0
  131. package/esm/providers/tambo-provider.d.ts +10 -0
  132. package/esm/providers/tambo-provider.js +32 -0
  133. package/esm/providers/tambo-provider.js.map +1 -0
  134. package/esm/providers/tambo-registry-provider.d.ts +21 -0
  135. package/esm/providers/tambo-registry-provider.js +79 -0
  136. package/esm/providers/tambo-registry-provider.js.map +1 -0
  137. package/esm/providers/tambo-thread-provider.d.ts +28 -0
  138. package/esm/providers/tambo-thread-provider.js +379 -0
  139. package/esm/providers/tambo-thread-provider.js.map +1 -0
  140. package/esm/setupTests.d.ts +1 -0
  141. package/esm/setupTests.js +18 -0
  142. package/esm/setupTests.js.map +1 -0
  143. package/esm/util/generate-component.d.ts +8 -0
  144. package/esm/util/generate-component.js +202 -0
  145. package/esm/util/generate-component.js.map +1 -0
  146. package/esm/util/messages.d.ts +2 -0
  147. package/esm/util/messages.js +9 -0
  148. package/esm/util/messages.js.map +1 -0
  149. package/esm/util/query-utils.d.ts +5 -0
  150. package/esm/util/query-utils.js +59 -0
  151. package/esm/util/query-utils.js.map +1 -0
  152. package/esm/util/registry.d.ts +7 -0
  153. package/esm/util/registry.js +88 -0
  154. package/esm/util/registry.js.map +1 -0
  155. package/esm/util/tool-caller.d.ts +3 -0
  156. package/esm/util/tool-caller.js +26 -0
  157. package/esm/util/tool-caller.js.map +1 -0
  158. package/package.json +84 -0
@@ -0,0 +1,202 @@
1
+ import { generateStream, hydrateStream, } from "@tambo-ai/typescript-sdk";
2
+ import { parse } from "partial-json";
3
+ import React from "react";
4
+ import { z } from "zod";
5
+ import { wrapWithTamboMessageProvider } from "../hooks/use-current-message";
6
+ import { GenerationStage, } from "../model/generate-component-response";
7
+ import { getAvailableComponents, getComponentFromRegistry, } from "../util/registry";
8
+ import { handleToolCall } from "../util/tool-caller";
9
+ export async function generateAndHydrate(client, componentList, toolRegistry, toolAssociations, currentThreadId, content, params, onUpdateState, stream = false, options) {
10
+ const availableComponents = getAvailableComponents(componentList, toolRegistry, toolAssociations);
11
+ let threadId = currentThreadId;
12
+ onUpdateState(GenerationStage.CHOOSING_COMPONENT);
13
+ try {
14
+ if (stream) {
15
+ const streamResponse = await generateStream(client, {
16
+ availableComponents,
17
+ contextKey: params.contextKey,
18
+ content,
19
+ threadId: params.threadId === "placeholder" ? undefined : params.threadId,
20
+ }, options);
21
+ return processComponentDecisionStream(handleStream(streamResponse), componentList, toolRegistry, onUpdateState, client, options);
22
+ }
23
+ const response = await client.beta.components.generate({
24
+ availableComponents,
25
+ contextKey: params.contextKey,
26
+ content,
27
+ threadId: params.threadId === "placeholder" ? undefined : params.threadId,
28
+ }, options);
29
+ // Capture the current threadId in case the following processComponentDecision fails
30
+ threadId = response.message.threadId;
31
+ return await processComponentDecision(client, componentList, toolRegistry, response.message.threadId, content, response.message, onUpdateState, options);
32
+ }
33
+ catch (error) {
34
+ console.error(error);
35
+ onUpdateState(GenerationStage.ERROR);
36
+ // manually create a message with the error
37
+ const errorMessage = `Error generating component: ${error}`;
38
+ try {
39
+ const errorMessageResponse = await client.beta.threads.messages.create(threadId ?? currentThreadId ?? "", {
40
+ content: [{ type: "text", text: errorMessage }],
41
+ role: "hydra",
42
+ });
43
+ return errorMessageResponse;
44
+ }
45
+ catch (errorError) {
46
+ // Log to the console, there's nothing more we can do!
47
+ console.error(`Error creating error message: ${errorError}`);
48
+ console.error("Original error:", error);
49
+ }
50
+ return {
51
+ renderedComponent: null,
52
+ content: [{ type: "text", text: errorMessage }],
53
+ role: "hydra",
54
+ createdAt: new Date().toISOString(),
55
+ id: crypto.randomUUID(),
56
+ threadId: currentThreadId ?? "",
57
+ };
58
+ }
59
+ }
60
+ async function processComponentDecision(client, componentList, toolRegistry, currentThreadId, content, message, onUpdateState, options) {
61
+ if (!message.component?.componentName) {
62
+ const componentResponse = {
63
+ ...message,
64
+ renderedComponent: null,
65
+ };
66
+ // no component to hydrate, just return the message
67
+ onUpdateState(GenerationStage.COMPLETE);
68
+ return componentResponse;
69
+ }
70
+ if (message.toolCallRequest) {
71
+ onUpdateState(GenerationStage.FETCHING_CONTEXT);
72
+ const toolResult = await handleToolCall(message, toolRegistry);
73
+ onUpdateState(GenerationStage.HYDRATING_COMPONENT);
74
+ try {
75
+ const hydrationResponse = await client.beta.components.hydrate({
76
+ component: getComponentFromRegistry(message.component.componentName, componentList),
77
+ threadId: message.threadId,
78
+ toolResponse: toolResult,
79
+ }, options);
80
+ return await processComponentDecision(client, componentList, toolRegistry, currentThreadId, content, hydrationResponse.message, onUpdateState, options);
81
+ }
82
+ catch (error) {
83
+ console.error(error);
84
+ onUpdateState(GenerationStage.ERROR);
85
+ return {
86
+ threadId: message.threadId,
87
+ renderedComponent: null,
88
+ content: [
89
+ { type: "text", text: `Error hydrating component: ${error}` },
90
+ ],
91
+ role: "hydra",
92
+ createdAt: new Date().toISOString(),
93
+ id: crypto.randomUUID(),
94
+ };
95
+ }
96
+ }
97
+ const renderedComponent = React.createElement(getComponentFromRegistry(message.component.componentName, componentList)
98
+ .component, message.component.props);
99
+ const componentResponse = {
100
+ ...message,
101
+ renderedComponent: wrapWithTamboMessageProvider(renderedComponent, message.threadId, message.id),
102
+ };
103
+ onUpdateState(GenerationStage.COMPLETE);
104
+ return componentResponse;
105
+ }
106
+ async function* processComponentDecisionStream(stream, componentList, toolRegistry, onUpdateState, client, options) {
107
+ let accumulatedComponentResponse = null;
108
+ for await (const chunk of stream) {
109
+ if (!chunk.component?.componentName) {
110
+ onUpdateState(GenerationStage.STREAMING_RESPONSE);
111
+ accumulatedComponentResponse = {
112
+ ...chunk,
113
+ renderedComponent: null,
114
+ };
115
+ yield accumulatedComponentResponse;
116
+ }
117
+ if (chunk.toolCallRequest) {
118
+ if (!chunk.component?.componentName) {
119
+ continue;
120
+ }
121
+ onUpdateState(GenerationStage.FETCHING_CONTEXT);
122
+ const toolResult = await handleToolCall(chunk, toolRegistry);
123
+ onUpdateState(GenerationStage.HYDRATING_COMPONENT);
124
+ const streamResponse = await hydrateStream(client, {
125
+ component: getComponentFromRegistry(chunk.component?.componentName ?? "", componentList),
126
+ threadId: chunk.threadId,
127
+ toolResponse: toolResult,
128
+ }, options);
129
+ yield* processComponentDecisionStream(handleStream(streamResponse), componentList, toolRegistry, onUpdateState, client, options);
130
+ return;
131
+ }
132
+ if (chunk.component?.componentName) {
133
+ try {
134
+ onUpdateState(GenerationStage.STREAMING_RESPONSE);
135
+ // Try to parse and validate accumulated component choice props:
136
+ const messageWithComponent = renderComponentIntoMessage(chunk, componentList);
137
+ // TODO: do we have to do this now
138
+ accumulatedComponentResponse = {
139
+ ...accumulatedComponentResponse,
140
+ ...messageWithComponent,
141
+ };
142
+ yield messageWithComponent;
143
+ }
144
+ catch (error) {
145
+ console.error(error);
146
+ }
147
+ }
148
+ }
149
+ onUpdateState(GenerationStage.COMPLETE);
150
+ }
151
+ /**
152
+ * Generate a message that has a component rendered into it, if the message came with one
153
+ */
154
+ export function renderComponentIntoMessage(message, componentList) {
155
+ if (!message.component?.componentName) {
156
+ throw new Error("Component not found");
157
+ }
158
+ const parsedProps = parse(JSON.stringify(message.component.props));
159
+ const registeredComponent = getComponentFromRegistry(message.component.componentName, componentList);
160
+ const validatedProps = registeredComponent.props instanceof z.ZodType
161
+ ? registeredComponent.props.parse(parsedProps)
162
+ : parsedProps;
163
+ const renderedComponent = React.createElement(registeredComponent.component, validatedProps);
164
+ const wrappedComponent = wrapWithTamboMessageProvider(renderedComponent, message.threadId, message.id);
165
+ return {
166
+ ...message,
167
+ component: {
168
+ ...message.component,
169
+ props: validatedProps,
170
+ },
171
+ renderedComponent: wrappedComponent,
172
+ };
173
+ }
174
+ async function* handleStream(stream) {
175
+ let threadMessage = {
176
+ threadId: "",
177
+ content: [],
178
+ role: "hydra",
179
+ createdAt: new Date().toISOString(),
180
+ id: crypto.randomUUID(),
181
+ };
182
+ try {
183
+ for await (const chunk of stream) {
184
+ threadMessage = {
185
+ ...threadMessage,
186
+ ...chunk,
187
+ };
188
+ yield threadMessage;
189
+ }
190
+ }
191
+ catch (error) {
192
+ console.error("Error processing stream:", error);
193
+ yield {
194
+ threadId: "",
195
+ content: [{ type: "text", text: `Error processing stream: ${error}` }],
196
+ role: "hydra",
197
+ createdAt: new Date().toISOString(),
198
+ id: crypto.randomUUID(),
199
+ };
200
+ }
201
+ }
202
+ //# sourceMappingURL=generate-component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-component.js","sourceRoot":"","sources":["../../src/util/generate-component.ts"],"names":[],"mappings":"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","sourcesContent":["import TamboAI, {\n generateStream,\n hydrateStream,\n} from \"@tambo-ai/typescript-sdk\";\nimport { parse } from \"partial-json\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport { wrapWithTamboMessageProvider } from \"../hooks/use-current-message\";\nimport {\n ComponentRegistry,\n TamboToolAssociations,\n TamboToolRegistry,\n} from \"../model/component-metadata\";\nimport {\n GenerationStage,\n TamboThreadMessage,\n} from \"../model/generate-component-response\";\nimport {\n getAvailableComponents,\n getComponentFromRegistry,\n} from \"../util/registry\";\nimport { handleToolCall } from \"../util/tool-caller\";\n\nexport async function generateAndHydrate(\n client: TamboAI,\n componentList: ComponentRegistry,\n toolRegistry: TamboToolRegistry,\n toolAssociations: TamboToolAssociations,\n currentThreadId: string | undefined,\n content: TamboAI.Beta.Threads.ChatCompletionContentPart[],\n params: TamboAI.Beta.Components.ComponentGenerateParams,\n onUpdateState: (state: GenerationStage) => void,\n stream = false,\n options?: TamboAI.RequestOptions,\n): Promise<TamboThreadMessage | AsyncIterable<TamboThreadMessage>> {\n const availableComponents = getAvailableComponents(\n componentList,\n toolRegistry,\n toolAssociations,\n );\n let threadId = currentThreadId;\n\n onUpdateState(GenerationStage.CHOOSING_COMPONENT);\n try {\n if (stream) {\n const streamResponse = await generateStream(\n client,\n {\n availableComponents,\n contextKey: params.contextKey,\n content,\n threadId:\n params.threadId === \"placeholder\" ? undefined : params.threadId,\n },\n options,\n );\n\n return processComponentDecisionStream(\n handleStream(\n streamResponse as AsyncIterable<TamboAI.ComponentGenerateResponse>,\n ),\n componentList,\n toolRegistry,\n onUpdateState,\n client,\n options,\n );\n }\n const response = await client.beta.components.generate(\n {\n availableComponents,\n contextKey: params.contextKey,\n content,\n threadId:\n params.threadId === \"placeholder\" ? undefined : params.threadId,\n },\n options,\n );\n // Capture the current threadId in case the following processComponentDecision fails\n threadId = response.message.threadId;\n return await processComponentDecision(\n client,\n componentList,\n toolRegistry,\n response.message.threadId,\n content,\n response.message,\n onUpdateState,\n options,\n );\n } catch (error) {\n console.error(error);\n onUpdateState(GenerationStage.ERROR);\n // manually create a message with the error\n const errorMessage = `Error generating component: ${error}`;\n try {\n const errorMessageResponse = await client.beta.threads.messages.create(\n threadId ?? currentThreadId ?? \"\",\n {\n content: [{ type: \"text\", text: errorMessage }],\n role: \"hydra\",\n },\n );\n return errorMessageResponse;\n } catch (errorError) {\n // Log to the console, there's nothing more we can do!\n console.error(`Error creating error message: ${errorError}`);\n console.error(\"Original error:\", error);\n }\n return {\n renderedComponent: null,\n content: [{ type: \"text\", text: errorMessage }],\n role: \"hydra\",\n createdAt: new Date().toISOString(),\n id: crypto.randomUUID(),\n threadId: currentThreadId ?? \"\",\n };\n }\n}\n\nasync function processComponentDecision(\n client: TamboAI,\n componentList: ComponentRegistry,\n toolRegistry: TamboToolRegistry,\n currentThreadId: string,\n content: TamboAI.Beta.Components.ComponentGenerateParams[\"content\"],\n message: TamboAI.Beta.Threads.ThreadMessage,\n onUpdateState: (state: GenerationStage) => void,\n options?: TamboAI.RequestOptions,\n): Promise<TamboThreadMessage> {\n if (!message.component?.componentName) {\n const componentResponse: TamboThreadMessage = {\n ...message,\n renderedComponent: null,\n };\n // no component to hydrate, just return the message\n onUpdateState(GenerationStage.COMPLETE);\n return componentResponse;\n }\n\n if (message.toolCallRequest) {\n onUpdateState(GenerationStage.FETCHING_CONTEXT);\n const toolResult = await handleToolCall(message, toolRegistry);\n onUpdateState(GenerationStage.HYDRATING_COMPONENT);\n try {\n const hydrationResponse = await client.beta.components.hydrate(\n {\n component: getComponentFromRegistry(\n message.component.componentName,\n componentList,\n ),\n threadId: message.threadId,\n\n toolResponse: toolResult,\n },\n options,\n );\n return await processComponentDecision(\n client,\n componentList,\n toolRegistry,\n currentThreadId,\n content,\n hydrationResponse.message,\n onUpdateState,\n options,\n );\n } catch (error) {\n console.error(error);\n onUpdateState(GenerationStage.ERROR);\n return {\n threadId: message.threadId,\n renderedComponent: null,\n content: [\n { type: \"text\", text: `Error hydrating component: ${error}` },\n ],\n role: \"hydra\",\n createdAt: new Date().toISOString(),\n id: crypto.randomUUID(),\n };\n }\n }\n\n const renderedComponent = React.createElement(\n getComponentFromRegistry(message.component.componentName, componentList)\n .component,\n message.component.props,\n );\n const componentResponse: TamboThreadMessage = {\n ...message,\n renderedComponent: wrapWithTamboMessageProvider(\n renderedComponent,\n message.threadId,\n message.id,\n ),\n };\n\n onUpdateState(GenerationStage.COMPLETE);\n return componentResponse;\n}\n\nasync function* processComponentDecisionStream(\n stream: AsyncIterable<TamboThreadMessage>,\n componentList: ComponentRegistry,\n toolRegistry: TamboToolRegistry,\n onUpdateState: (state: GenerationStage) => void,\n client: TamboAI,\n options?: TamboAI.RequestOptions,\n): AsyncGenerator<TamboThreadMessage> {\n let accumulatedComponentResponse: TamboThreadMessage | null = null;\n\n for await (const chunk of stream) {\n if (!chunk.component?.componentName) {\n onUpdateState(GenerationStage.STREAMING_RESPONSE);\n accumulatedComponentResponse = {\n ...chunk,\n renderedComponent: null,\n };\n yield accumulatedComponentResponse;\n }\n\n if (chunk.toolCallRequest) {\n if (!chunk.component?.componentName) {\n continue;\n }\n onUpdateState(GenerationStage.FETCHING_CONTEXT);\n const toolResult = await handleToolCall(chunk, toolRegistry);\n onUpdateState(GenerationStage.HYDRATING_COMPONENT);\n const streamResponse = await hydrateStream(\n client,\n {\n component: getComponentFromRegistry(\n chunk.component?.componentName ?? \"\",\n componentList,\n ),\n threadId: chunk.threadId,\n toolResponse: toolResult,\n },\n options,\n );\n\n yield* processComponentDecisionStream(\n handleStream(\n streamResponse as AsyncIterable<TamboAI.ComponentHydrateResponse>,\n ),\n componentList,\n toolRegistry,\n onUpdateState,\n client,\n options,\n );\n return;\n }\n\n if (chunk.component?.componentName) {\n try {\n onUpdateState(GenerationStage.STREAMING_RESPONSE);\n // Try to parse and validate accumulated component choice props:\n const messageWithComponent = renderComponentIntoMessage(\n chunk,\n componentList,\n );\n // TODO: do we have to do this now\n accumulatedComponentResponse = {\n ...accumulatedComponentResponse,\n ...messageWithComponent,\n };\n yield messageWithComponent;\n } catch (error) {\n console.error(error);\n }\n }\n }\n onUpdateState(GenerationStage.COMPLETE);\n}\n\n/**\n * Generate a message that has a component rendered into it, if the message came with one\n */\nexport function renderComponentIntoMessage(\n message: TamboAI.Beta.Threads.ThreadMessage,\n componentList: ComponentRegistry,\n): TamboThreadMessage {\n if (!message.component?.componentName) {\n throw new Error(\"Component not found\");\n }\n const parsedProps = parse(JSON.stringify(message.component.props));\n const registeredComponent = getComponentFromRegistry(\n message.component.componentName,\n componentList,\n );\n\n const validatedProps =\n registeredComponent.props instanceof z.ZodType\n ? registeredComponent.props.parse(parsedProps)\n : parsedProps;\n\n const renderedComponent = React.createElement(\n registeredComponent.component,\n validatedProps,\n );\n const wrappedComponent = wrapWithTamboMessageProvider(\n renderedComponent,\n message.threadId,\n message.id,\n );\n\n return {\n ...message,\n component: {\n ...message.component,\n props: validatedProps,\n },\n renderedComponent: wrappedComponent,\n };\n}\n\nasync function* handleStream(\n stream: AsyncIterable<\n TamboAI.ComponentGenerateResponse | TamboAI.ComponentHydrateResponse\n >,\n): AsyncGenerator<TamboAI.Beta.Threads.ThreadMessage> {\n let threadMessage: TamboAI.Beta.Threads.ThreadMessage = {\n threadId: \"\",\n content: [],\n role: \"hydra\",\n createdAt: new Date().toISOString(),\n id: crypto.randomUUID(),\n };\n\n try {\n for await (const chunk of stream) {\n threadMessage = {\n ...threadMessage,\n ...chunk,\n };\n yield threadMessage;\n }\n } catch (error) {\n console.error(\"Error processing stream:\", error);\n yield {\n threadId: \"\",\n content: [{ type: \"text\", text: `Error processing stream: ${error}` }],\n role: \"hydra\",\n createdAt: new Date().toISOString(),\n id: crypto.randomUUID(),\n };\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import TamboAI from "@tambo-ai/typescript-sdk";
2
+ export declare function threadMessagesToLegacyMessages(messages: TamboAI.Beta.Threads.ThreadMessage[]): TamboAI.Components.LegacyChatMessage[];
@@ -0,0 +1,9 @@
1
+ export function threadMessagesToLegacyMessages(messages) {
2
+ return messages
3
+ .map((m) => ({
4
+ sender: m.role,
5
+ message: m.content[0].text ?? "",
6
+ }))
7
+ .filter((m) => !!m.message);
8
+ }
9
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/util/messages.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,8BAA8B,CAC5C,QAA8C;IAE9C,OAAO,QAAQ;SACZ,GAAG,CACF,CAAC,CAAC,EAAwC,EAAE,CAAC,CAAC;QAC5C,MAAM,EAAE,CAAC,CAAC,IAAwB;QAClC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE;KACjC,CAAC,CACH;SACA,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\n\nexport function threadMessagesToLegacyMessages(\n messages: TamboAI.Beta.Threads.ThreadMessage[],\n) {\n return messages\n .map(\n (m): TamboAI.Components.LegacyChatMessage => ({\n sender: m.role as \"user\" | \"hydra\",\n message: m.content[0].text ?? \"\",\n }),\n )\n .filter((m) => !!m.message);\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import { UseMutationResult, UseQueryResult } from "@tanstack/react-query";
2
+ export type CombinedMutationResult<TData = unknown, TError = unknown, TVariables = unknown, TContext = unknown> = Omit<UseMutationResult<TData, TError, TVariables, TContext>, "mutate" | "mutateAsync" | "reset" | "data" | "variables" | "context">;
3
+ export declare function combineMutationResults<TData1, TData2, TError1, TError2>(resultA: UseMutationResult<TData1, TError1, any, any>, resultB: UseMutationResult<TData2, TError2, any, any>): CombinedMutationResult<TData1 | TData2, TError1 | TError2>;
4
+ export type CombinedQueryResult<TData1, TData2, TError1, TError2> = Omit<UseQueryResult<TData1 | TData2, TError1 | TError2>, "data" | "refetch" | "promise">;
5
+ export declare function combineQueryResults<TData1, TData2, TError1, TError2>(resultA: UseQueryResult<TData1, TError1>, resultB: UseQueryResult<TData2, TError2>): CombinedQueryResult<void, void, TError1, TError2>;
@@ -0,0 +1,59 @@
1
+ export function combineMutationResults(resultA, resultB) {
2
+ {
3
+ return {
4
+ isPending: resultA.isPending || resultB.isPending,
5
+ isSuccess: resultA.isSuccess && resultB.isSuccess,
6
+ isError: resultA.isError || resultB.isError,
7
+ isIdle: resultA.isIdle && resultB.isIdle,
8
+ isPaused: resultA.isPaused || resultB.isPaused,
9
+ submittedAt: resultA.submittedAt || resultB.submittedAt,
10
+ status: resultA.isPending || resultB.isPending
11
+ ? "pending"
12
+ : resultA.isError || resultB.isError
13
+ ? "error"
14
+ : resultA.isSuccess && resultB.isSuccess
15
+ ? "success"
16
+ : "idle",
17
+ error: resultA.error ?? resultB.error,
18
+ failureCount: resultA.failureCount + resultB.failureCount,
19
+ failureReason: resultA.failureReason ?? resultB.failureReason,
20
+ };
21
+ }
22
+ }
23
+ export function combineQueryResults(resultA, resultB) {
24
+ return {
25
+ isPending: resultA.isPending || resultB.isPending,
26
+ isSuccess: resultA.isSuccess && resultB.isSuccess,
27
+ isError: resultA.isError || resultB.isError,
28
+ isLoading: resultA.isLoading || resultB.isLoading,
29
+ isFetched: resultA.isFetched && resultB.isFetched,
30
+ isFetchedAfterMount: resultA.isFetchedAfterMount && resultB.isFetchedAfterMount,
31
+ isInitialLoading: resultA.isInitialLoading || resultB.isInitialLoading,
32
+ isPaused: resultA.isPaused || resultB.isPaused,
33
+ isLoadingError: resultA.isLoadingError || resultB.isLoadingError,
34
+ isRefetchError: resultA.isRefetchError || resultB.isRefetchError,
35
+ isPlaceholderData: resultA.isPlaceholderData || resultB.isPlaceholderData,
36
+ isStale: resultA.isStale || resultB.isStale,
37
+ isRefetching: resultA.isRefetching || resultB.isRefetching,
38
+ isFetching: resultA.isFetching || resultB.isFetching,
39
+ status: resultA.isPending || resultB.isPending
40
+ ? "pending"
41
+ : resultA.isError || resultB.isError
42
+ ? "error"
43
+ : resultA.isSuccess && resultB.isSuccess
44
+ ? "success"
45
+ : "pending",
46
+ error: resultA.error ?? resultB.error,
47
+ failureCount: resultA.failureCount + resultB.failureCount,
48
+ failureReason: resultA.failureReason ?? resultB.failureReason,
49
+ errorUpdateCount: resultA.errorUpdateCount + resultB.errorUpdateCount,
50
+ fetchStatus: resultA.isFetching || resultB.isFetching
51
+ ? "fetching"
52
+ : resultA.isPaused || resultB.isPaused
53
+ ? "paused"
54
+ : "idle",
55
+ dataUpdatedAt: Math.max(resultA.dataUpdatedAt, resultB.dataUpdatedAt),
56
+ errorUpdatedAt: Math.max(resultA.errorUpdatedAt, resultB.errorUpdatedAt),
57
+ };
58
+ }
59
+ //# sourceMappingURL=query-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-utils.js","sourceRoot":"","sources":["../../src/util/query-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { UseMutationResult, UseQueryResult } from \"@tanstack/react-query\";\n\nexport type CombinedMutationResult<\n TData = unknown,\n TError = unknown,\n TVariables = unknown,\n TContext = unknown,\n> = Omit<\n UseMutationResult<TData, TError, TVariables, TContext>,\n \"mutate\" | \"mutateAsync\" | \"reset\" | \"data\" | \"variables\" | \"context\"\n>;\n\nexport function combineMutationResults<TData1, TData2, TError1, TError2>(\n resultA: UseMutationResult<TData1, TError1, any, any>,\n resultB: UseMutationResult<TData2, TError2, any, any>,\n): CombinedMutationResult<TData1 | TData2, TError1 | TError2> {\n {\n return {\n isPending: resultA.isPending || resultB.isPending,\n isSuccess: resultA.isSuccess && resultB.isSuccess,\n isError: resultA.isError || resultB.isError,\n isIdle: resultA.isIdle && resultB.isIdle,\n isPaused: resultA.isPaused || resultB.isPaused,\n submittedAt: resultA.submittedAt || resultB.submittedAt,\n status:\n resultA.isPending || resultB.isPending\n ? \"pending\"\n : resultA.isError || resultB.isError\n ? \"error\"\n : resultA.isSuccess && resultB.isSuccess\n ? \"success\"\n : \"idle\",\n error: resultA.error ?? resultB.error,\n failureCount: resultA.failureCount + resultB.failureCount,\n failureReason: resultA.failureReason ?? resultB.failureReason,\n };\n }\n}\n\nexport type CombinedQueryResult<TData1, TData2, TError1, TError2> = Omit<\n UseQueryResult<TData1 | TData2, TError1 | TError2>,\n \"data\" | \"refetch\" | \"promise\"\n>;\nexport function combineQueryResults<TData1, TData2, TError1, TError2>(\n resultA: UseQueryResult<TData1, TError1>,\n resultB: UseQueryResult<TData2, TError2>,\n): CombinedQueryResult<void, void, TError1, TError2> {\n return {\n isPending: resultA.isPending || resultB.isPending,\n isSuccess: resultA.isSuccess && resultB.isSuccess,\n isError: resultA.isError || resultB.isError,\n isLoading: resultA.isLoading || resultB.isLoading,\n isFetched: resultA.isFetched && resultB.isFetched,\n isFetchedAfterMount:\n resultA.isFetchedAfterMount && resultB.isFetchedAfterMount,\n isInitialLoading: resultA.isInitialLoading || resultB.isInitialLoading,\n isPaused: resultA.isPaused || resultB.isPaused,\n isLoadingError: resultA.isLoadingError || resultB.isLoadingError,\n isRefetchError: resultA.isRefetchError || resultB.isRefetchError,\n isPlaceholderData: resultA.isPlaceholderData || resultB.isPlaceholderData,\n isStale: resultA.isStale || resultB.isStale,\n isRefetching: resultA.isRefetching || resultB.isRefetching,\n isFetching: resultA.isFetching || resultB.isFetching,\n status:\n resultA.isPending || resultB.isPending\n ? \"pending\"\n : resultA.isError || resultB.isError\n ? \"error\"\n : resultA.isSuccess && resultB.isSuccess\n ? \"success\"\n : \"pending\",\n error: resultA.error ?? resultB.error,\n failureCount: resultA.failureCount + resultB.failureCount,\n failureReason: resultA.failureReason ?? resultB.failureReason,\n errorUpdateCount: resultA.errorUpdateCount + resultB.errorUpdateCount,\n fetchStatus:\n resultA.isFetching || resultB.isFetching\n ? \"fetching\"\n : resultA.isPaused || resultB.isPaused\n ? \"paused\"\n : \"idle\",\n dataUpdatedAt: Math.max(resultA.dataUpdatedAt, resultB.dataUpdatedAt),\n errorUpdatedAt: Math.max(resultA.errorUpdatedAt, resultB.errorUpdatedAt),\n };\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import TamboAI from "@tambo-ai/typescript-sdk";
2
+ import { ComponentContextToolMetadata, ComponentRegistry, RegisteredComponent, TamboTool, TamboToolAssociations, TamboToolRegistry } from "../model/component-metadata";
3
+ export declare const getAvailableComponents: (componentRegistry: ComponentRegistry, toolRegistry: TamboToolRegistry, toolAssociations: TamboToolAssociations) => TamboAI.AvailableComponent[];
4
+ export declare const getComponentFromRegistry: (componentName: string, componentRegistry: ComponentRegistry) => RegisteredComponent;
5
+ export declare const getDefaultContextAdditions: () => string[];
6
+ export declare const getClientContext: () => string;
7
+ export declare const mapTamboToolToContextTool: (tool: TamboTool) => ComponentContextToolMetadata;
@@ -0,0 +1,88 @@
1
+ import zodToJsonSchema from "zod-to-json-schema";
2
+ export const getAvailableComponents = (componentRegistry, toolRegistry, toolAssociations) => {
3
+ const availableComponents = [];
4
+ for (const [name, componentEntry] of Object.entries(componentRegistry)) {
5
+ const associatedToolNames = toolAssociations[name] || [];
6
+ const contextTools = [
7
+ ...associatedToolNames.map((toolName) => {
8
+ const tool = toolRegistry[toolName];
9
+ if (!tool)
10
+ return null;
11
+ return mapTamboToolToContextTool(tool);
12
+ }),
13
+ ].filter((tool) => tool !== null);
14
+ availableComponents.push({
15
+ name: componentEntry.name,
16
+ description: componentEntry.description,
17
+ props: componentEntry.props,
18
+ contextTools,
19
+ });
20
+ }
21
+ return availableComponents;
22
+ };
23
+ export const getComponentFromRegistry = (componentName, componentRegistry) => {
24
+ const componentEntry = componentRegistry[componentName];
25
+ if (!componentEntry) {
26
+ throw new Error(`Tambo tried to use Component ${componentName}, but it was not found.`);
27
+ }
28
+ return componentEntry;
29
+ };
30
+ export const getDefaultContextAdditions = () => {
31
+ const utcOffsetHours = new Date().getTimezoneOffset() / 60;
32
+ const utcOffset = `(UTC${utcOffsetHours > 0 ? "+" : ""}${utcOffsetHours})`;
33
+ return [
34
+ `The current time in user's timezone (${utcOffset}) is: ${new Date().toLocaleString()}`,
35
+ ];
36
+ };
37
+ export const getClientContext = () => {
38
+ const contextAdditions = getDefaultContextAdditions();
39
+ return contextAdditions.join("\n");
40
+ };
41
+ export const mapTamboToolToContextTool = (tool) => {
42
+ const parameters = getParametersFromZodFunction(tool.toolSchema);
43
+ return {
44
+ name: tool.name,
45
+ description: tool.description,
46
+ parameters,
47
+ };
48
+ };
49
+ const getParametersFromZodFunction = (schema) => {
50
+ const parameters = schema.parameters();
51
+ return parameters.items.map((param, index) => {
52
+ const name = `param${index + 1}`;
53
+ const type = getZodBaseType(param);
54
+ const description = param.description ?? "";
55
+ const isRequired = !param.isOptional();
56
+ const schema = zodToJsonSchema(param);
57
+ return {
58
+ name,
59
+ type,
60
+ description,
61
+ isRequired,
62
+ schema,
63
+ };
64
+ });
65
+ };
66
+ const getZodBaseType = (schema) => {
67
+ const typeName = schema._def.typeName;
68
+ switch (typeName) {
69
+ case "ZodString":
70
+ return "string";
71
+ case "ZodNumber":
72
+ return "number";
73
+ case "ZodBoolean":
74
+ return "boolean";
75
+ case "ZodArray":
76
+ return "array";
77
+ case "ZodEnum":
78
+ return "enum";
79
+ case "ZodDate":
80
+ return "date";
81
+ case "ZodObject":
82
+ return "object";
83
+ default:
84
+ console.warn("falling back to string for", typeName);
85
+ return "string";
86
+ }
87
+ };
88
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/util/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { z } from \"zod\";\nimport zodToJsonSchema from \"zod-to-json-schema\";\nimport {\n ComponentContextToolMetadata,\n ComponentRegistry,\n ParameterSpec,\n RegisteredComponent,\n TamboTool,\n TamboToolAssociations,\n TamboToolRegistry,\n} from \"../model/component-metadata\";\n\nexport const getAvailableComponents = (\n componentRegistry: ComponentRegistry,\n toolRegistry: TamboToolRegistry,\n toolAssociations: TamboToolAssociations,\n): TamboAI.AvailableComponent[] => {\n const availableComponents: TamboAI.AvailableComponent[] = [];\n\n for (const [name, componentEntry] of Object.entries(componentRegistry)) {\n const associatedToolNames = toolAssociations[name] || [];\n\n const contextTools = [\n ...associatedToolNames.map((toolName) => {\n const tool = toolRegistry[toolName];\n if (!tool) return null;\n return mapTamboToolToContextTool(tool);\n }),\n ].filter((tool): tool is ComponentContextToolMetadata => tool !== null);\n\n availableComponents.push({\n name: componentEntry.name,\n description: componentEntry.description,\n props: componentEntry.props,\n contextTools,\n });\n }\n\n return availableComponents;\n};\n\nexport const getComponentFromRegistry = (\n componentName: string,\n componentRegistry: ComponentRegistry,\n): RegisteredComponent => {\n const componentEntry = componentRegistry[componentName];\n\n if (!componentEntry) {\n throw new Error(\n `Tambo tried to use Component ${componentName}, but it was not found.`,\n );\n }\n\n return componentEntry;\n};\n\nexport const getDefaultContextAdditions = (): string[] => {\n const utcOffsetHours = new Date().getTimezoneOffset() / 60;\n const utcOffset = `(UTC${utcOffsetHours > 0 ? \"+\" : \"\"}${utcOffsetHours})`;\n return [\n `The current time in user's timezone (${utcOffset}) is: ${new Date().toLocaleString()}`,\n ];\n};\n\nexport const getClientContext = (): string => {\n const contextAdditions = getDefaultContextAdditions();\n return contextAdditions.join(\"\\n\");\n};\n\nexport const mapTamboToolToContextTool = (\n tool: TamboTool,\n): ComponentContextToolMetadata => {\n const parameters = getParametersFromZodFunction(tool.toolSchema);\n\n return {\n name: tool.name,\n description: tool.description,\n parameters,\n };\n};\n\nconst getParametersFromZodFunction = (\n schema: z.ZodFunction<any, any>,\n): ParameterSpec[] => {\n const parameters: z.ZodTuple = schema.parameters();\n return parameters.items.map((param, index): ParameterSpec => {\n const name = `param${index + 1}`;\n const type = getZodBaseType(param);\n const description = param.description ?? \"\";\n const isRequired = !param.isOptional();\n const schema = zodToJsonSchema(param);\n\n return {\n name,\n type,\n description,\n isRequired,\n schema,\n };\n });\n};\n\nconst getZodBaseType = (schema: z.ZodTypeAny): string => {\n const typeName = schema._def.typeName;\n switch (typeName) {\n case \"ZodString\":\n return \"string\";\n case \"ZodNumber\":\n return \"number\";\n case \"ZodBoolean\":\n return \"boolean\";\n case \"ZodArray\":\n return \"array\";\n case \"ZodEnum\":\n return \"enum\";\n case \"ZodDate\":\n return \"date\";\n case \"ZodObject\":\n return \"object\";\n default:\n console.warn(\"falling back to string for\", typeName);\n return \"string\";\n }\n};\n"]}
@@ -0,0 +1,3 @@
1
+ import TamboAI from "@tambo-ai/typescript-sdk";
2
+ import { TamboToolRegistry } from "../model/component-metadata";
3
+ export declare const handleToolCall: (message: TamboAI.Beta.ThreadMessage, toolRegistry: TamboToolRegistry) => Promise<any>;
@@ -0,0 +1,26 @@
1
+ import { mapTamboToolToContextTool } from "./registry";
2
+ export const handleToolCall = async (message, toolRegistry) => {
3
+ if (!message?.toolCallRequest?.toolName) {
4
+ throw new Error("Tool name is required");
5
+ }
6
+ const tool = findTool(message.toolCallRequest.toolName, toolRegistry);
7
+ const toolResult = await runToolChoice(message.toolCallRequest, tool);
8
+ return toolResult;
9
+ };
10
+ const findTool = (toolName, toolRegistry) => {
11
+ const registryTool = toolRegistry[toolName];
12
+ if (!registryTool) {
13
+ throw new Error(`Tool ${toolName} not found in registry`);
14
+ }
15
+ const contextTool = mapTamboToolToContextTool(registryTool);
16
+ return {
17
+ getComponentContext: registryTool.tool,
18
+ definition: contextTool,
19
+ };
20
+ };
21
+ const runToolChoice = async (toolCallRequest, tool) => {
22
+ // Assumes parameters are in the order they are defined in the tool
23
+ const parameterValues = toolCallRequest.parameters?.map((param) => param.parameterValue) ?? [];
24
+ return tool.getComponentContext(...parameterValues);
25
+ };
26
+ //# sourceMappingURL=tool-caller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-caller.js","sourceRoot":"","sources":["../../src/util/tool-caller.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AACvD,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,OAAmC,EACnC,YAA+B,EAC/B,EAAE;IACF,IAAI,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACtE,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAEtE,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAE,YAA+B,EAAE,EAAE;IACrE,MAAM,YAAY,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAE5C,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,wBAAwB,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,WAAW,GAAG,yBAAyB,CAAC,YAAY,CAAC,CAAC;IAC5D,OAAO;QACL,mBAAmB,EAAE,YAAY,CAAC,IAAI;QACtC,UAAU,EAAE,WAAW;KACxB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,KAAK,EACzB,eAAwC,EACxC,IAA0B,EACZ,EAAE;IAChB,mEAAmE;IACnE,MAAM,eAAe,GACnB,eAAe,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAEzE,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,eAAe,CAAC,CAAC;AACtD,CAAC,CAAC","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport {\n ComponentContextTool,\n TamboToolRegistry,\n} from \"../model/component-metadata\";\nimport { mapTamboToolToContextTool } from \"./registry\";\nexport const handleToolCall = async (\n message: TamboAI.Beta.ThreadMessage,\n toolRegistry: TamboToolRegistry,\n) => {\n if (!message?.toolCallRequest?.toolName) {\n throw new Error(\"Tool name is required\");\n }\n\n const tool = findTool(message.toolCallRequest.toolName, toolRegistry);\n const toolResult = await runToolChoice(message.toolCallRequest, tool);\n\n return toolResult;\n};\n\nconst findTool = (toolName: string, toolRegistry: TamboToolRegistry) => {\n const registryTool = toolRegistry[toolName];\n\n if (!registryTool) {\n throw new Error(`Tool ${toolName} not found in registry`);\n }\n\n const contextTool = mapTamboToolToContextTool(registryTool);\n return {\n getComponentContext: registryTool.tool,\n definition: contextTool,\n };\n};\n\nconst runToolChoice = async (\n toolCallRequest: TamboAI.ToolCallRequest,\n tool: ComponentContextTool,\n): Promise<any> => {\n // Assumes parameters are in the order they are defined in the tool\n const parameterValues =\n toolCallRequest.parameters?.map((param) => param.parameterValue) ?? [];\n\n return tool.getComponentContext(...parameterValues);\n};\n"]}
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@tambo-ai/react",
3
+ "version": "0.12.0",
4
+ "description": "React client package for Tambo AI",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/tambo-ai/hydra-ai-react.git"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "module": "./esm/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "import": "./esm/index.js",
15
+ "require": "./dist/index.js",
16
+ "types": "./dist/index.d.ts"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "esm"
22
+ ],
23
+ "sideEffects": false,
24
+ "scripts": {
25
+ "build": "npm run build:cjs && npm run build:esm",
26
+ "build:cjs": "tsc -p tsconfig.cjs.json",
27
+ "build:esm": "tsc -p tsconfig.esm.json",
28
+ "dev": "concurrently -c blue.bold,green.bold \"npm run dev:cjs\" \"npm run dev:esm\"",
29
+ "dev:cjs": "tsc -p tsconfig.cjs.json --watch",
30
+ "dev:esm": "tsc -p tsconfig.esm.json --watch",
31
+ "check-types": "tsc --noEmit",
32
+ "test": "jest --config jest.config.ts",
33
+ "format": "prettier --write .",
34
+ "lint": "eslint",
35
+ "lint:fix": "eslint --fix",
36
+ "format:lint": "npm run format && npm run lint:fix",
37
+ "prepare": "husky"
38
+ },
39
+ "lint-staged": {
40
+ "*.{js,jsx,ts,tsx}": [
41
+ "prettier --write",
42
+ "eslint --fix"
43
+ ],
44
+ "*.{json,md,yml,yaml}": [
45
+ "prettier --write"
46
+ ]
47
+ },
48
+ "peerDependencies": {
49
+ "@types/react": "^18.0.0 || ^19.0.0",
50
+ "@types/react-dom": "^18.0.0 || ^19.0.0",
51
+ "react": "^18.0.0 || ^19.0.0",
52
+ "react-dom": "^18.0.0 || ^19.0.0"
53
+ },
54
+ "dependencies": {
55
+ "@tambo-ai/typescript-sdk": "^0.31.0",
56
+ "@tanstack/react-query": "^5.67.1",
57
+ "partial-json": "^0.1.7",
58
+ "zod": "^3.24.1",
59
+ "zod-to-json-schema": "^3.24.1"
60
+ },
61
+ "devDependencies": {
62
+ "@eslint/js": "^9.19.0",
63
+ "@testing-library/jest-dom": "^6.4.2",
64
+ "@testing-library/react": "^16.2.0",
65
+ "@types/jest": "^29.5.12",
66
+ "@types/json-schema": "^7.0.15",
67
+ "@types/node": "^20.11.24",
68
+ "@types/react": "^18.3.12",
69
+ "@types/react-dom": "^18.3.5",
70
+ "concurrently": "^9.1.2",
71
+ "eslint": "^9.19.0",
72
+ "eslint-plugin-react": "^7.37.4",
73
+ "eslint-plugin-react-hooks": "^5.1.0",
74
+ "husky": "^9.1.7",
75
+ "jest": "^29.7.0",
76
+ "jest-environment-jsdom": "^29.7.0",
77
+ "lint-staged": "^15.4.3",
78
+ "prettier": "^3.4.2",
79
+ "ts-jest": "^29.1.2",
80
+ "ts-node": "^10.9.2",
81
+ "typescript": "^5.7.3",
82
+ "typescript-eslint": "^8.23.0"
83
+ }
84
+ }