@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.
- package/README.md +9 -0
- package/dist/hooks/__tests__/use-suggestions.test.d.ts +1 -0
- package/dist/hooks/__tests__/use-suggestions.test.js +167 -0
- package/dist/hooks/__tests__/use-suggestions.test.js.map +1 -0
- package/dist/hooks/react-query-hooks.d.ts +21 -0
- package/dist/hooks/react-query-hooks.js +33 -0
- package/dist/hooks/react-query-hooks.js.map +1 -0
- package/dist/hooks/use-component-state.d.ts +8 -0
- package/dist/hooks/use-component-state.js +42 -0
- package/dist/hooks/use-component-state.js.map +1 -0
- package/dist/hooks/use-current-message.d.ts +18 -0
- package/dist/hooks/use-current-message.js +73 -0
- package/dist/hooks/use-current-message.js.map +1 -0
- package/dist/hooks/use-query-client.d.ts +0 -0
- package/dist/hooks/use-query-client.js +2 -0
- package/dist/hooks/use-query-client.js.map +1 -0
- package/dist/hooks/use-suggestions.d.ts +44 -0
- package/dist/hooks/use-suggestions.js +111 -0
- package/dist/hooks/use-suggestions.js.map +1 -0
- package/dist/hooks/use-tambo-threads.d.ts +137 -0
- package/dist/hooks/use-tambo-threads.js +33 -0
- package/dist/hooks/use-tambo-threads.js.map +1 -0
- package/dist/hooks/use-thread-input.d.ts +48 -0
- package/dist/hooks/use-thread-input.js +53 -0
- package/dist/hooks/use-thread-input.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/model/component-metadata.d.ts +32 -0
- package/dist/model/component-metadata.js +3 -0
- package/dist/model/component-metadata.js.map +1 -0
- package/dist/model/generate-component-response.d.ts +17 -0
- package/dist/model/generate-component-response.js +22 -0
- package/dist/model/generate-component-response.js.map +1 -0
- package/dist/model/tambo-thread.d.ts +7 -0
- package/dist/model/tambo-thread.js +3 -0
- package/dist/model/tambo-thread.js.map +1 -0
- package/dist/model/thread-input-error.d.ts +3 -0
- package/dist/model/thread-input-error.js +8 -0
- package/dist/model/thread-input-error.js.map +1 -0
- package/dist/model/validate-input.d.ts +6 -0
- package/dist/model/validate-input.js +27 -0
- package/dist/model/validate-input.js.map +1 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.js +21 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/tambo-client-provider.d.ts +15 -0
- package/dist/providers/tambo-client-provider.js +66 -0
- package/dist/providers/tambo-client-provider.js.map +1 -0
- package/dist/providers/tambo-component-provider.d.ts +18 -0
- package/dist/providers/tambo-component-provider.js +129 -0
- package/dist/providers/tambo-component-provider.js.map +1 -0
- package/dist/providers/tambo-provider.d.ts +10 -0
- package/dist/providers/tambo-provider.js +70 -0
- package/dist/providers/tambo-provider.js.map +1 -0
- package/dist/providers/tambo-registry-provider.d.ts +21 -0
- package/dist/providers/tambo-registry-provider.js +117 -0
- package/dist/providers/tambo-registry-provider.js.map +1 -0
- package/dist/providers/tambo-thread-provider.d.ts +28 -0
- package/dist/providers/tambo-thread-provider.js +417 -0
- package/dist/providers/tambo-thread-provider.js.map +1 -0
- package/dist/setupTests.d.ts +1 -0
- package/dist/setupTests.js +20 -0
- package/dist/setupTests.js.map +1 -0
- package/dist/util/generate-component.d.ts +8 -0
- package/dist/util/generate-component.js +209 -0
- package/dist/util/generate-component.js.map +1 -0
- package/dist/util/messages.d.ts +2 -0
- package/dist/util/messages.js +12 -0
- package/dist/util/messages.js.map +1 -0
- package/dist/util/query-utils.d.ts +5 -0
- package/dist/util/query-utils.js +63 -0
- package/dist/util/query-utils.js.map +1 -0
- package/dist/util/registry.d.ts +7 -0
- package/dist/util/registry.js +99 -0
- package/dist/util/registry.js.map +1 -0
- package/dist/util/tool-caller.d.ts +3 -0
- package/dist/util/tool-caller.js +30 -0
- package/dist/util/tool-caller.js.map +1 -0
- package/esm/hooks/__tests__/use-suggestions.test.d.ts +1 -0
- package/esm/hooks/__tests__/use-suggestions.test.js +165 -0
- package/esm/hooks/__tests__/use-suggestions.test.js.map +1 -0
- package/esm/hooks/react-query-hooks.d.ts +21 -0
- package/esm/hooks/react-query-hooks.js +28 -0
- package/esm/hooks/react-query-hooks.js.map +1 -0
- package/esm/hooks/use-component-state.d.ts +8 -0
- package/esm/hooks/use-component-state.js +39 -0
- package/esm/hooks/use-component-state.js.map +1 -0
- package/esm/hooks/use-current-message.d.ts +18 -0
- package/esm/hooks/use-current-message.js +33 -0
- package/esm/hooks/use-current-message.js.map +1 -0
- package/esm/hooks/use-query-client.d.ts +0 -0
- package/esm/hooks/use-query-client.js +2 -0
- package/esm/hooks/use-query-client.js.map +1 -0
- package/esm/hooks/use-suggestions.d.ts +44 -0
- package/esm/hooks/use-suggestions.js +108 -0
- package/esm/hooks/use-suggestions.js.map +1 -0
- package/esm/hooks/use-tambo-threads.d.ts +137 -0
- package/esm/hooks/use-tambo-threads.js +30 -0
- package/esm/hooks/use-tambo-threads.js.map +1 -0
- package/esm/hooks/use-thread-input.d.ts +48 -0
- package/esm/hooks/use-thread-input.js +49 -0
- package/esm/hooks/use-thread-input.js.map +1 -0
- package/esm/index.d.ts +12 -0
- package/esm/index.js +10 -0
- package/esm/index.js.map +1 -0
- package/esm/model/component-metadata.d.ts +32 -0
- package/esm/model/component-metadata.js +2 -0
- package/esm/model/component-metadata.js.map +1 -0
- package/esm/model/generate-component-response.d.ts +17 -0
- package/esm/model/generate-component-response.js +18 -0
- package/esm/model/generate-component-response.js.map +1 -0
- package/esm/model/tambo-thread.d.ts +7 -0
- package/esm/model/tambo-thread.js +2 -0
- package/esm/model/tambo-thread.js.map +1 -0
- package/esm/model/thread-input-error.d.ts +3 -0
- package/esm/model/thread-input-error.js +4 -0
- package/esm/model/thread-input-error.js.map +1 -0
- package/esm/model/validate-input.d.ts +6 -0
- package/esm/model/validate-input.js +24 -0
- package/esm/model/validate-input.js.map +1 -0
- package/esm/providers/index.d.ts +5 -0
- package/esm/providers/index.js +6 -0
- package/esm/providers/index.js.map +1 -0
- package/esm/providers/tambo-client-provider.d.ts +15 -0
- package/esm/providers/tambo-client-provider.js +24 -0
- package/esm/providers/tambo-client-provider.js.map +1 -0
- package/esm/providers/tambo-component-provider.d.ts +18 -0
- package/esm/providers/tambo-component-provider.js +91 -0
- package/esm/providers/tambo-component-provider.js.map +1 -0
- package/esm/providers/tambo-provider.d.ts +10 -0
- package/esm/providers/tambo-provider.js +32 -0
- package/esm/providers/tambo-provider.js.map +1 -0
- package/esm/providers/tambo-registry-provider.d.ts +21 -0
- package/esm/providers/tambo-registry-provider.js +79 -0
- package/esm/providers/tambo-registry-provider.js.map +1 -0
- package/esm/providers/tambo-thread-provider.d.ts +28 -0
- package/esm/providers/tambo-thread-provider.js +379 -0
- package/esm/providers/tambo-thread-provider.js.map +1 -0
- package/esm/setupTests.d.ts +1 -0
- package/esm/setupTests.js +18 -0
- package/esm/setupTests.js.map +1 -0
- package/esm/util/generate-component.d.ts +8 -0
- package/esm/util/generate-component.js +202 -0
- package/esm/util/generate-component.js.map +1 -0
- package/esm/util/messages.d.ts +2 -0
- package/esm/util/messages.js +9 -0
- package/esm/util/messages.js.map +1 -0
- package/esm/util/query-utils.d.ts +5 -0
- package/esm/util/query-utils.js +59 -0
- package/esm/util/query-utils.js.map +1 -0
- package/esm/util/registry.d.ts +7 -0
- package/esm/util/registry.js +88 -0
- package/esm/util/registry.js.map +1 -0
- package/esm/util/tool-caller.d.ts +3 -0
- package/esm/util/tool-caller.js +26 -0
- package/esm/util/tool-caller.js.map +1 -0
- 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":"AAAA,OAAgB,EACd,cAAc,EACd,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAM5E,OAAO,EACL,eAAe,GAEhB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAe,EACf,aAAgC,EAChC,YAA+B,EAC/B,gBAAuC,EACvC,eAAmC,EACnC,OAAyD,EACzD,MAAuD,EACvD,aAA+C,EAC/C,MAAM,GAAG,KAAK,EACd,OAAgC;IAEhC,MAAM,mBAAmB,GAAG,sBAAsB,CAChD,aAAa,EACb,YAAY,EACZ,gBAAgB,CACjB,CAAC;IACF,IAAI,QAAQ,GAAG,eAAe,CAAC;IAE/B,aAAa,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;IAClD,IAAI,CAAC;QACH,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,cAAc,GAAG,MAAM,cAAc,CACzC,MAAM,EACN;gBACE,mBAAmB;gBACnB,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,OAAO;gBACP,QAAQ,EACN,MAAM,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ;aAClE,EACD,OAAO,CACR,CAAC;YAEF,OAAO,8BAA8B,CACnC,YAAY,CACV,cAAkE,CACnE,EACD,aAAa,EACb,YAAY,EACZ,aAAa,EACb,MAAM,EACN,OAAO,CACR,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CACpD;YACE,mBAAmB;YACnB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,OAAO;YACP,QAAQ,EACN,MAAM,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ;SAClE,EACD,OAAO,CACR,CAAC;QACF,oFAAoF;QACpF,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;QACrC,OAAO,MAAM,wBAAwB,CACnC,MAAM,EACN,aAAa,EACb,YAAY,EACZ,QAAQ,CAAC,OAAO,CAAC,QAAQ,EACzB,OAAO,EACP,QAAQ,CAAC,OAAO,EAChB,aAAa,EACb,OAAO,CACR,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,aAAa,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QACrC,2CAA2C;QAC3C,MAAM,YAAY,GAAG,+BAA+B,KAAK,EAAE,CAAC;QAC5D,IAAI,CAAC;YACH,MAAM,oBAAoB,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CACpE,QAAQ,IAAI,eAAe,IAAI,EAAE,EACjC;gBACE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;gBAC/C,IAAI,EAAE,OAAO;aACd,CACF,CAAC;YACF,OAAO,oBAAoB,CAAC;QAC9B,CAAC;QAAC,OAAO,UAAU,EAAE,CAAC;YACpB,sDAAsD;YACtD,OAAO,CAAC,KAAK,CAAC,iCAAiC,UAAU,EAAE,CAAC,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO;YACL,iBAAiB,EAAE,IAAI;YACvB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;YAC/C,IAAI,EAAE,OAAO;YACb,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;YACvB,QAAQ,EAAE,eAAe,IAAI,EAAE;SAChC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,MAAe,EACf,aAAgC,EAChC,YAA+B,EAC/B,eAAuB,EACvB,OAAmE,EACnE,OAA2C,EAC3C,aAA+C,EAC/C,OAAgC;IAEhC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;QACtC,MAAM,iBAAiB,GAAuB;YAC5C,GAAG,OAAO;YACV,iBAAiB,EAAE,IAAI;SACxB,CAAC;QACF,mDAAmD;QACnD,aAAa,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QACxC,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,aAAa,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC/D,aAAa,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAC5D;gBACE,SAAS,EAAE,wBAAwB,CACjC,OAAO,CAAC,SAAS,CAAC,aAAa,EAC/B,aAAa,CACd;gBACD,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAE1B,YAAY,EAAE,UAAU;aACzB,EACD,OAAO,CACR,CAAC;YACF,OAAO,MAAM,wBAAwB,CACnC,MAAM,EACN,aAAa,EACb,YAAY,EACZ,eAAe,EACf,OAAO,EACP,iBAAiB,CAAC,OAAO,EACzB,aAAa,EACb,OAAO,CACR,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACrB,aAAa,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YACrC,OAAO;gBACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,iBAAiB,EAAE,IAAI;gBACvB,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,8BAA8B,KAAK,EAAE,EAAE;iBAC9D;gBACD,IAAI,EAAE,OAAO;gBACb,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;aACxB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,iBAAiB,GAAG,KAAK,CAAC,aAAa,CAC3C,wBAAwB,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;SACrE,SAAS,EACZ,OAAO,CAAC,SAAS,CAAC,KAAK,CACxB,CAAC;IACF,MAAM,iBAAiB,GAAuB;QAC5C,GAAG,OAAO;QACV,iBAAiB,EAAE,4BAA4B,CAC7C,iBAAiB,EACjB,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,EAAE,CACX;KACF,CAAC;IAEF,aAAa,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IACxC,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,8BAA8B,CAC5C,MAAyC,EACzC,aAAgC,EAChC,YAA+B,EAC/B,aAA+C,EAC/C,MAAe,EACf,OAAgC;IAEhC,IAAI,4BAA4B,GAA8B,IAAI,CAAC;IAEnE,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;YACpC,aAAa,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;YAClD,4BAA4B,GAAG;gBAC7B,GAAG,KAAK;gBACR,iBAAiB,EAAE,IAAI;aACxB,CAAC;YACF,MAAM,4BAA4B,CAAC;QACrC,CAAC;QAED,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;gBACpC,SAAS;YACX,CAAC;YACD,aAAa,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC;YAChD,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;YAC7D,aAAa,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC;YACnD,MAAM,cAAc,GAAG,MAAM,aAAa,CACxC,MAAM,EACN;gBACE,SAAS,EAAE,wBAAwB,CACjC,KAAK,CAAC,SAAS,EAAE,aAAa,IAAI,EAAE,EACpC,aAAa,CACd;gBACD,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,YAAY,EAAE,UAAU;aACzB,EACD,OAAO,CACR,CAAC;YAEF,KAAK,CAAC,CAAC,8BAA8B,CACnC,YAAY,CACV,cAAiE,CAClE,EACD,aAAa,EACb,YAAY,EACZ,aAAa,EACb,MAAM,EACN,OAAO,CACR,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,aAAa,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;gBAClD,gEAAgE;gBAChE,MAAM,oBAAoB,GAAG,0BAA0B,CACrD,KAAK,EACL,aAAa,CACd,CAAC;gBACF,kCAAkC;gBAClC,4BAA4B,GAAG;oBAC7B,GAAG,4BAA4B;oBAC/B,GAAG,oBAAoB;iBACxB,CAAC;gBACF,MAAM,oBAAoB,CAAC;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IACD,aAAa,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAA2C,EAC3C,aAAgC;IAEhC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACnE,MAAM,mBAAmB,GAAG,wBAAwB,CAClD,OAAO,CAAC,SAAS,CAAC,aAAa,EAC/B,aAAa,CACd,CAAC;IAEF,MAAM,cAAc,GAClB,mBAAmB,CAAC,KAAK,YAAY,CAAC,CAAC,OAAO;QAC5C,CAAC,CAAC,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC;QAC9C,CAAC,CAAC,WAAW,CAAC;IAElB,MAAM,iBAAiB,GAAG,KAAK,CAAC,aAAa,CAC3C,mBAAmB,CAAC,SAAS,EAC7B,cAAc,CACf,CAAC;IACF,MAAM,gBAAgB,GAAG,4BAA4B,CACnD,iBAAiB,EACjB,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,EAAE,CACX,CAAC;IAEF,OAAO;QACL,GAAG,OAAO;QACV,SAAS,EAAE;YACT,GAAG,OAAO,CAAC,SAAS;YACpB,KAAK,EAAE,cAAc;SACtB;QACD,iBAAiB,EAAE,gBAAgB;KACpC,CAAC;AACJ,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,YAAY,CAC1B,MAEC;IAED,IAAI,aAAa,GAAuC;QACtD,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,EAAE;QACX,IAAI,EAAE,OAAO;QACb,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;KACxB,CAAC;IAEF,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACjC,aAAa,GAAG;gBACd,GAAG,aAAa;gBAChB,GAAG,KAAK;aACT,CAAC;YACF,MAAM,aAAa,CAAC;QACtB,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;QACjD,MAAM;YACJ,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,4BAA4B,KAAK,EAAE,EAAE,CAAC;YACtE,IAAI,EAAE,OAAO;YACb,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;SACxB,CAAC;IACJ,CAAC;AACH,CAAC","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 @@
|
|
|
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":"AAYA,MAAM,UAAU,sBAAsB,CACpC,OAAqD,EACrD,OAAqD;IAErD,CAAC;QACC,OAAO;YACL,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;YACjD,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;YACjD,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO;YAC3C,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM;YACxC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ;YAC9C,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW;YACvD,MAAM,EACJ,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;gBACpC,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO;oBAClC,CAAC,CAAC,OAAO;oBACT,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;wBACtC,CAAC,CAAC,SAAS;wBACX,CAAC,CAAC,MAAM;YAChB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK;YACrC,YAAY,EAAE,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY;YACzD,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,aAAa;SAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAMD,MAAM,UAAU,mBAAmB,CACjC,OAAwC,EACxC,OAAwC;IAExC,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;QACjD,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;QACjD,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO;QAC3C,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;QACjD,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;QACjD,mBAAmB,EACjB,OAAO,CAAC,mBAAmB,IAAI,OAAO,CAAC,mBAAmB;QAC5D,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,gBAAgB;QACtE,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ;QAC9C,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,cAAc;QAChE,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,cAAc;QAChE,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,OAAO,CAAC,iBAAiB;QACzE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO;QAC3C,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,YAAY;QAC1D,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU;QACpD,MAAM,EACJ,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;YACpC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO;gBAClC,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;oBACtC,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,SAAS;QACnB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK;QACrC,YAAY,EAAE,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY;QACzD,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,aAAa;QAC7D,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB;QACrE,WAAW,EACT,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU;YACtC,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ;gBACpC,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,MAAM;QACd,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,aAAa,CAAC;QACrE,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,cAAc,CAAC;KACzE,CAAC;AACJ,CAAC","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,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
|
+
}
|