@tambo-ai/react 0.16.1 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +32 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/use-component-state.d.ts +40 -5
- package/dist/hooks/use-component-state.d.ts.map +1 -1
- package/dist/hooks/use-component-state.js +138 -47
- package/dist/hooks/use-component-state.js.map +1 -1
- package/dist/hooks/use-streaming-props.d.ts +25 -0
- package/dist/hooks/use-streaming-props.d.ts.map +1 -0
- package/dist/hooks/use-streaming-props.js +49 -0
- package/dist/hooks/use-streaming-props.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/tambo-thread-provider.d.ts +1 -1
- package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-provider.js.map +1 -1
- package/esm/hooks/index.d.ts +8 -0
- package/esm/hooks/index.d.ts.map +1 -0
- package/esm/hooks/index.js +9 -0
- package/esm/hooks/index.js.map +1 -0
- package/esm/hooks/use-component-state.d.ts +40 -5
- package/esm/hooks/use-component-state.d.ts.map +1 -1
- package/esm/hooks/use-component-state.js +139 -48
- package/esm/hooks/use-component-state.js.map +1 -1
- package/esm/hooks/use-streaming-props.d.ts +25 -0
- package/esm/hooks/use-streaming-props.d.ts.map +1 -0
- package/esm/hooks/use-streaming-props.js +46 -0
- package/esm/hooks/use-streaming-props.js.map +1 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/esm/providers/tambo-thread-provider.d.ts +1 -1
- package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-provider.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./react-query-hooks";
|
|
2
|
+
export { useTamboComponentState } from "./use-component-state";
|
|
3
|
+
export { useTamboCurrentMessage, useTamboMessageContext, } from "./use-current-message";
|
|
4
|
+
export { useTamboStreamingProps } from "./use-streaming-props";
|
|
5
|
+
export * from "./use-suggestions";
|
|
6
|
+
export { useTamboThreads } from "./use-tambo-threads";
|
|
7
|
+
export { useTamboThreadInput } from "./use-thread-input";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.useTamboThreadInput = exports.useTamboThreads = exports.useTamboStreamingProps = exports.useTamboMessageContext = exports.useTamboCurrentMessage = exports.useTamboComponentState = void 0;
|
|
18
|
+
// Export all hooks from this directory
|
|
19
|
+
__exportStar(require("./react-query-hooks"), exports);
|
|
20
|
+
var use_component_state_1 = require("./use-component-state");
|
|
21
|
+
Object.defineProperty(exports, "useTamboComponentState", { enumerable: true, get: function () { return use_component_state_1.useTamboComponentState; } });
|
|
22
|
+
var use_current_message_1 = require("./use-current-message");
|
|
23
|
+
Object.defineProperty(exports, "useTamboCurrentMessage", { enumerable: true, get: function () { return use_current_message_1.useTamboCurrentMessage; } });
|
|
24
|
+
Object.defineProperty(exports, "useTamboMessageContext", { enumerable: true, get: function () { return use_current_message_1.useTamboMessageContext; } });
|
|
25
|
+
var use_streaming_props_1 = require("./use-streaming-props");
|
|
26
|
+
Object.defineProperty(exports, "useTamboStreamingProps", { enumerable: true, get: function () { return use_streaming_props_1.useTamboStreamingProps; } });
|
|
27
|
+
__exportStar(require("./use-suggestions"), exports);
|
|
28
|
+
var use_tambo_threads_1 = require("./use-tambo-threads");
|
|
29
|
+
Object.defineProperty(exports, "useTamboThreads", { enumerable: true, get: function () { return use_tambo_threads_1.useTamboThreads; } });
|
|
30
|
+
var use_thread_input_1 = require("./use-thread-input");
|
|
31
|
+
Object.defineProperty(exports, "useTamboThreadInput", { enumerable: true, get: function () { return use_thread_input_1.useTamboThreadInput; } });
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,uCAAuC;AACvC,sDAAoC;AACpC,6DAA+D;AAAtD,6HAAA,sBAAsB,OAAA;AAC/B,6DAG+B;AAF7B,6HAAA,sBAAsB,OAAA;AACtB,6HAAA,sBAAsB,OAAA;AAExB,6DAA+D;AAAtD,6HAAA,sBAAsB,OAAA;AAC/B,oDAAkC;AAClC,yDAAsD;AAA7C,oHAAA,eAAe,OAAA;AACxB,uDAAyD;AAAhD,uHAAA,mBAAmB,OAAA","sourcesContent":["// Export all hooks from this directory\nexport * from \"./react-query-hooks\";\nexport { useTamboComponentState } from \"./use-component-state\";\nexport {\n useTamboCurrentMessage,\n useTamboMessageContext,\n} from \"./use-current-message\";\nexport { useTamboStreamingProps } from \"./use-streaming-props\";\nexport * from \"./use-suggestions\";\nexport { useTamboThreads } from \"./use-tambo-threads\";\nexport { useTamboThreadInput } from \"./use-thread-input\";\n"]}
|
|
@@ -1,9 +1,44 @@
|
|
|
1
|
-
|
|
1
|
+
interface ComponentStateMeta {
|
|
2
|
+
isPending: boolean;
|
|
3
|
+
}
|
|
4
|
+
type StateUpdateResult<T> = [
|
|
5
|
+
currentState: T,
|
|
6
|
+
setState: (newState: T) => void,
|
|
7
|
+
meta: ComponentStateMeta
|
|
8
|
+
];
|
|
2
9
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
10
|
+
* A React hook that provides state management and passes user updates to Tambo.
|
|
11
|
+
* Benefits: Passes user changes to AI, and when threads are returned, state is preserved.
|
|
12
|
+
*
|
|
13
|
+
* @param keyName - The unique key to identify this state within the message's componentState object
|
|
14
|
+
* @param initialValue - Optional initial value for the state, used if no value exists in the message
|
|
15
|
+
* @param debounceTime - Optional debounce time in milliseconds (default: 300ms) to limit API calls
|
|
16
|
+
*
|
|
17
|
+
* @returns A tuple containing:
|
|
18
|
+
* - The current state value
|
|
19
|
+
* - A setter function to update the state (updates UI immediately, debounces server sync)
|
|
20
|
+
* - A metadata object with properties like isPending to track sync status
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Basic usage
|
|
24
|
+
* const [count, setCount, { isPending }] = useTamboComponentState("counter", 0);
|
|
25
|
+
*
|
|
26
|
+
* // Usage with object state
|
|
27
|
+
* const [formState, setFormState] = useTamboComponentState("myForm", {
|
|
28
|
+
* name: "",
|
|
29
|
+
* email: "",
|
|
30
|
+
* message: ""
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* // Handling form input
|
|
34
|
+
* const handleChange = (e) => {
|
|
35
|
+
* setFormState({
|
|
36
|
+
* ...formState,
|
|
37
|
+
* [e.target.name]: e.target.value
|
|
38
|
+
* });
|
|
39
|
+
* };
|
|
5
40
|
*/
|
|
6
|
-
export declare function useTamboComponentState<S = undefined>(keyName: string): StateUpdateResult<S | undefined>;
|
|
7
|
-
export declare function useTamboComponentState<S>(keyName: string, initialValue?:
|
|
41
|
+
export declare function useTamboComponentState<S = undefined>(keyName: string, initialValue?: S, debounceTime?: number): StateUpdateResult<S | undefined>;
|
|
42
|
+
export declare function useTamboComponentState<S>(keyName: string, initialValue: S, debounceTime?: number): StateUpdateResult<S>;
|
|
8
43
|
export {};
|
|
9
44
|
//# sourceMappingURL=use-component-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-component-state.d.ts","sourceRoot":"","sources":["../../src/hooks/use-component-state.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-component-state.d.ts","sourceRoot":"","sources":["../../src/hooks/use-component-state.tsx"],"names":[],"mappings":"AASA,UAAU,kBAAkB;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,KAAK,iBAAiB,CAAC,CAAC,IAAI;IAC1B,YAAY,EAAE,CAAC;IACf,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,IAAI;IAC/B,IAAI,EAAE,kBAAkB;CACzB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,wBAAgB,sBAAsB,CAAC,CAAC,GAAG,SAAS,EAClD,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,CAAC,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,iBAAiB,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;AACpC,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,CAAC,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,iBAAiB,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -2,42 +2,136 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useTamboComponentState = useTamboComponentState;
|
|
4
4
|
const react_1 = require("react");
|
|
5
|
+
const use_debounce_1 = require("use-debounce");
|
|
5
6
|
const providers_1 = require("../providers");
|
|
6
7
|
const use_current_message_1 = require("./use-current-message");
|
|
7
|
-
function useTamboComponentState(keyName, initialValue) {
|
|
8
|
+
function useTamboComponentState(keyName, initialValue, debounceTime = 300) {
|
|
8
9
|
const { threadId, messageId } = (0, use_current_message_1.useTamboMessageContext)();
|
|
9
10
|
const { updateThreadMessage } = (0, providers_1.useTamboThread)();
|
|
10
11
|
const client = (0, providers_1.useTamboClient)();
|
|
11
12
|
const message = (0, use_current_message_1.useTamboCurrentMessage)();
|
|
13
|
+
// Initial value management
|
|
12
14
|
const [cachedInitialValue] = (0, react_1.useState)(() => initialValue);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
// UI state management
|
|
16
|
+
const [localState, setLocalState] = (0, react_1.useState)(cachedInitialValue);
|
|
17
|
+
// Synchronization state
|
|
18
|
+
const [isPending, setIsPending] = (0, react_1.useState)(false);
|
|
19
|
+
// Track the last user-initiated value instead of a simple boolean flag
|
|
20
|
+
const [lastUserValue, setLastUserValue] = (0, react_1.useState)(null);
|
|
21
|
+
const [haveInitialized, setHaveInitialized] = (0, react_1.useState)(false);
|
|
22
|
+
// Determine if we need to initialize state
|
|
23
|
+
const shouldInitialize = !haveInitialized &&
|
|
24
|
+
message &&
|
|
25
|
+
cachedInitialValue !== undefined &&
|
|
26
|
+
(!message.componentState || !(keyName in message.componentState));
|
|
27
|
+
// Helper function to check if two values are deeply equal
|
|
28
|
+
const isEqual = (a, b) => {
|
|
29
|
+
if (a === b)
|
|
30
|
+
return true;
|
|
31
|
+
// Handle primitive types
|
|
32
|
+
if (typeof a !== "object" ||
|
|
33
|
+
typeof b !== "object" ||
|
|
34
|
+
a === null ||
|
|
35
|
+
b === null)
|
|
36
|
+
return false;
|
|
37
|
+
// For objects and arrays, do a shallow comparison for simplicity
|
|
38
|
+
// This could be enhanced with a proper deep equality check if needed
|
|
39
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
40
|
+
if (a.length !== b.length)
|
|
41
|
+
return false;
|
|
42
|
+
return a.every((val, idx) => val === b[idx]);
|
|
43
|
+
}
|
|
44
|
+
const keysA = Object.keys(a);
|
|
45
|
+
const keysB = Object.keys(b);
|
|
46
|
+
if (keysA.length !== keysB.length)
|
|
47
|
+
return false;
|
|
48
|
+
return keysA.every((key) => a[key] === b[key]);
|
|
49
|
+
};
|
|
50
|
+
// Sync local state with message state on initial load and when message changes
|
|
51
|
+
(0, react_1.useEffect)(() => {
|
|
52
|
+
if (message?.componentState && keyName in message.componentState) {
|
|
53
|
+
const messageState = message.componentState[keyName];
|
|
54
|
+
// If this is a user-initiated state that matches what we're getting from server,
|
|
55
|
+
// we can clear the lastUserValue flag since it's been synchronized
|
|
56
|
+
if (lastUserValue !== null && isEqual(messageState, lastUserValue)) {
|
|
57
|
+
setLastUserValue(null);
|
|
58
|
+
}
|
|
59
|
+
// Update local state with server state unless user has specifically changed this value
|
|
60
|
+
// This allows streaming updates to continue while protecting user edits
|
|
61
|
+
if (lastUserValue === null || !isEqual(localState, lastUserValue)) {
|
|
62
|
+
setLocalState(messageState);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Otherwise fall back to initial value if we have one
|
|
66
|
+
else if (cachedInitialValue !== undefined && !localState) {
|
|
67
|
+
setLocalState(cachedInitialValue);
|
|
68
|
+
}
|
|
69
|
+
}, [
|
|
70
|
+
keyName,
|
|
71
|
+
message?.componentState,
|
|
72
|
+
cachedInitialValue,
|
|
73
|
+
lastUserValue,
|
|
74
|
+
localState,
|
|
75
|
+
]);
|
|
76
|
+
// Create debounced save function for efficient server synchronization
|
|
77
|
+
const debouncedSave = (0, use_debounce_1.useDebouncedCallback)(async (newValue) => {
|
|
78
|
+
if (!message) {
|
|
79
|
+
console.warn(`Cannot update missing message ${messageId} for state key "${keyName}"`);
|
|
80
|
+
setLastUserValue(null);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
setIsPending(true);
|
|
84
|
+
try {
|
|
85
|
+
const messageUpdate = {
|
|
86
|
+
...message,
|
|
87
|
+
componentState: {
|
|
88
|
+
...message.componentState,
|
|
89
|
+
[keyName]: newValue,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
const componentStateUpdate = {
|
|
93
|
+
state: { [keyName]: newValue },
|
|
94
|
+
};
|
|
95
|
+
await Promise.all([
|
|
96
|
+
updateThreadMessage(messageId, messageUpdate, false),
|
|
97
|
+
client.beta.threads.messages.updateComponentState(threadId, messageId, componentStateUpdate),
|
|
98
|
+
]);
|
|
99
|
+
// Only clear the lastUserValue when we've successfully synced this exact value
|
|
100
|
+
if (isEqual(newValue, lastUserValue)) {
|
|
101
|
+
setLastUserValue(null);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
console.error(`Failed to save component state for key "${keyName}":`, err);
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
setIsPending(false);
|
|
109
|
+
}
|
|
110
|
+
}, debounceTime);
|
|
111
|
+
// Initialize state on first render if needed
|
|
20
112
|
const initializeState = (0, react_1.useCallback)(async () => {
|
|
21
113
|
if (!message) {
|
|
22
|
-
console.warn(`Cannot initialize state for missing message ${messageId}`);
|
|
114
|
+
console.warn(`Cannot initialize state for missing message ${messageId} with key "${keyName}"`);
|
|
23
115
|
return;
|
|
24
116
|
}
|
|
25
117
|
try {
|
|
118
|
+
const messageUpdate = {
|
|
119
|
+
...message,
|
|
120
|
+
componentState: {
|
|
121
|
+
...message.componentState,
|
|
122
|
+
[keyName]: cachedInitialValue,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
const componentStateUpdate = {
|
|
126
|
+
state: { [keyName]: cachedInitialValue },
|
|
127
|
+
};
|
|
26
128
|
await Promise.all([
|
|
27
|
-
updateThreadMessage(messageId,
|
|
28
|
-
|
|
29
|
-
componentState: {
|
|
30
|
-
...message.componentState,
|
|
31
|
-
[keyName]: cachedInitialValue,
|
|
32
|
-
},
|
|
33
|
-
}, false),
|
|
34
|
-
client.beta.threads.messages.updateComponentState(threadId, messageId, {
|
|
35
|
-
state: { [keyName]: cachedInitialValue },
|
|
36
|
-
}),
|
|
129
|
+
updateThreadMessage(messageId, messageUpdate, false),
|
|
130
|
+
client.beta.threads.messages.updateComponentState(threadId, messageId, componentStateUpdate),
|
|
37
131
|
]);
|
|
38
132
|
}
|
|
39
133
|
catch (err) {
|
|
40
|
-
console.warn(
|
|
134
|
+
console.warn(`Failed to initialize component state for key "${keyName}":`, err);
|
|
41
135
|
}
|
|
42
136
|
}, [
|
|
43
137
|
cachedInitialValue,
|
|
@@ -48,39 +142,36 @@ function useTamboComponentState(keyName, initialValue) {
|
|
|
48
142
|
threadId,
|
|
49
143
|
updateThreadMessage,
|
|
50
144
|
]);
|
|
51
|
-
|
|
52
|
-
const shouldInitialize = !haveInitialized &&
|
|
53
|
-
message &&
|
|
54
|
-
cachedInitialValue !== undefined &&
|
|
55
|
-
(!message.componentState || !(keyName in message.componentState));
|
|
56
|
-
// send initial state
|
|
145
|
+
// Send initial state when component mounts
|
|
57
146
|
(0, react_1.useEffect)(() => {
|
|
58
147
|
if (shouldInitialize) {
|
|
59
148
|
initializeState();
|
|
60
149
|
setHaveInitialized(true);
|
|
61
150
|
}
|
|
62
151
|
}, [initializeState, shouldInitialize]);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
152
|
+
// setValue function for updating state
|
|
153
|
+
// Updates local state immediately and schedules debounced server sync
|
|
154
|
+
const setValue = (0, react_1.useCallback)((newValue) => {
|
|
155
|
+
// Track this as a user-initiated update
|
|
156
|
+
setLastUserValue(newValue);
|
|
157
|
+
setLocalState(newValue);
|
|
158
|
+
// Only trigger server updates if we have a message
|
|
159
|
+
if (message) {
|
|
160
|
+
debouncedSave(newValue);
|
|
67
161
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
updateThreadMessage,
|
|
83
|
-
]);
|
|
84
|
-
return [value, setValue];
|
|
162
|
+
else {
|
|
163
|
+
console.warn(`Cannot update server for missing message ${messageId} with key "${keyName}"`);
|
|
164
|
+
setLastUserValue(null);
|
|
165
|
+
}
|
|
166
|
+
}, [debouncedSave, message, messageId, keyName]);
|
|
167
|
+
// Ensure pending changes are flushed on unmount
|
|
168
|
+
(0, react_1.useEffect)(() => {
|
|
169
|
+
return () => {
|
|
170
|
+
debouncedSave.flush();
|
|
171
|
+
setLastUserValue(null);
|
|
172
|
+
};
|
|
173
|
+
}, [debouncedSave]);
|
|
174
|
+
// Return the local state for immediate UI rendering
|
|
175
|
+
return [localState, setValue, { isPending }];
|
|
85
176
|
}
|
|
86
177
|
//# sourceMappingURL=use-component-state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-component-state.js","sourceRoot":"","sources":["../../src/hooks/use-component-state.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useTamboClient, useTamboThread } from \"../providers\";\nimport {\n useTamboCurrentMessage,\n useTamboMessageContext,\n} from \"./use-current-message\";\n\ntype StateUpdateResult<T> = [currentState: T, setState: (newState: T) => void];\n\n/**\n * Behaves similarly to useState, but the value is stored in the thread\n * message, and the state is keyed by the keyName\n */\nexport function useTamboComponentState<S = undefined>(\n keyName: string,\n): StateUpdateResult<S | undefined>;\nexport function useTamboComponentState<S>(\n keyName: string,\n initialValue?: S,\n): StateUpdateResult<S>;\nexport function useTamboComponentState<S>(\n keyName: string,\n initialValue?: S,\n): StateUpdateResult<S> {\n const { threadId, messageId } = useTamboMessageContext();\n const { updateThreadMessage } = useTamboThread();\n const client = useTamboClient();\n\n const message = useTamboCurrentMessage();\n const [cachedInitialValue] = useState(() => initialValue);\n\n const value = useMemo(() => {\n if (!message?.componentState) return cachedInitialValue;\n return keyName in message.componentState\n ? (message.componentState[keyName] as S)\n : cachedInitialValue;\n }, [cachedInitialValue, keyName, message?.componentState]);\n\n const initializeState = useCallback(async () => {\n if (!message) {\n console.warn(`Cannot initialize state for missing message ${messageId}`);\n return;\n }\n try {\n await Promise.all([\n updateThreadMessage(\n messageId,\n {\n ...message,\n componentState: {\n ...message.componentState,\n [keyName]: cachedInitialValue,\n },\n },\n false,\n ),\n client.beta.threads.messages.updateComponentState(threadId, messageId, {\n state: { [keyName]: cachedInitialValue },\n }),\n ]);\n } catch (err) {\n console.warn(\"Failed to initialize component state:\", err);\n }\n }, [\n cachedInitialValue,\n client.beta.threads.messages,\n keyName,\n message,\n messageId,\n threadId,\n updateThreadMessage,\n ]);\n const [haveInitialized, setHaveInitialized] = useState(false);\n const shouldInitialize =\n !haveInitialized &&\n message &&\n cachedInitialValue !== undefined &&\n (!message.componentState || !(keyName in message.componentState));\n\n // send initial state\n useEffect(() => {\n if (shouldInitialize) {\n initializeState();\n setHaveInitialized(true);\n }\n }, [initializeState, shouldInitialize]);\n\n const setValue = useCallback(\n async (newValue: S) => {\n if (!message) {\n console.warn(`Cannot update missing message ${messageId}`);\n return;\n }\n await updateThreadMessage(\n messageId,\n {\n ...message,\n componentState: {\n ...message.componentState,\n [keyName]: newValue,\n },\n },\n false,\n );\n await client.beta.threads.messages.updateComponentState(\n threadId,\n messageId,\n { state: { [keyName]: newValue } },\n );\n },\n [\n client.beta.threads.messages,\n keyName,\n message,\n messageId,\n threadId,\n updateThreadMessage,\n ],\n );\n return [value as S, setValue];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-component-state.js","sourceRoot":"","sources":["../../src/hooks/use-component-state.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { useDebouncedCallback } from \"use-debounce\";\nimport { useTamboClient, useTamboThread } from \"../providers\";\nimport {\n useTamboCurrentMessage,\n useTamboMessageContext,\n} from \"./use-current-message\";\n\n// Define metadata interface for better extensibility\ninterface ComponentStateMeta {\n isPending: boolean;\n}\n\ntype StateUpdateResult<T> = [\n currentState: T,\n setState: (newState: T) => void,\n meta: ComponentStateMeta,\n];\n\n/**\n * A React hook that provides state management and passes user updates to Tambo.\n * Benefits: Passes user changes to AI, and when threads are returned, state is preserved.\n *\n * @param keyName - The unique key to identify this state within the message's componentState object\n * @param initialValue - Optional initial value for the state, used if no value exists in the message\n * @param debounceTime - Optional debounce time in milliseconds (default: 300ms) to limit API calls\n *\n * @returns A tuple containing:\n * - The current state value\n * - A setter function to update the state (updates UI immediately, debounces server sync)\n * - A metadata object with properties like isPending to track sync status\n *\n * @example\n * // Basic usage\n * const [count, setCount, { isPending }] = useTamboComponentState(\"counter\", 0);\n *\n * // Usage with object state\n * const [formState, setFormState] = useTamboComponentState(\"myForm\", {\n * name: \"\",\n * email: \"\",\n * message: \"\"\n * });\n *\n * // Handling form input\n * const handleChange = (e) => {\n * setFormState({\n * ...formState,\n * [e.target.name]: e.target.value\n * });\n * };\n */\n\nexport function useTamboComponentState<S = undefined>(\n keyName: string,\n initialValue?: S,\n debounceTime?: number,\n): StateUpdateResult<S | undefined>;\nexport function useTamboComponentState<S>(\n keyName: string,\n initialValue: S,\n debounceTime?: number,\n): StateUpdateResult<S>;\nexport function useTamboComponentState<S>(\n keyName: string,\n initialValue?: S,\n debounceTime = 300,\n): StateUpdateResult<S> {\n const { threadId, messageId } = useTamboMessageContext();\n const { updateThreadMessage } = useTamboThread();\n const client = useTamboClient();\n const message = useTamboCurrentMessage();\n\n // Initial value management\n const [cachedInitialValue] = useState(() => initialValue);\n // UI state management\n const [localState, setLocalState] = useState<S | undefined>(\n cachedInitialValue,\n );\n // Synchronization state\n const [isPending, setIsPending] = useState(false);\n // Track the last user-initiated value instead of a simple boolean flag\n const [lastUserValue, setLastUserValue] = useState<S | null>(null);\n const [haveInitialized, setHaveInitialized] = useState(false);\n\n // Determine if we need to initialize state\n const shouldInitialize =\n !haveInitialized &&\n message &&\n cachedInitialValue !== undefined &&\n (!message.componentState || !(keyName in message.componentState));\n\n // Helper function to check if two values are deeply equal\n const isEqual = (a: any, b: any): boolean => {\n if (a === b) return true;\n\n // Handle primitive types\n if (\n typeof a !== \"object\" ||\n typeof b !== \"object\" ||\n a === null ||\n b === null\n )\n return false;\n\n // For objects and arrays, do a shallow comparison for simplicity\n // This could be enhanced with a proper deep equality check if needed\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n return a.every((val, idx) => val === b[idx]);\n }\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n return keysA.every((key) => a[key] === b[key]);\n };\n\n // Sync local state with message state on initial load and when message changes\n useEffect(() => {\n if (message?.componentState && keyName in message.componentState) {\n const messageState = message.componentState[keyName] as S;\n\n // If this is a user-initiated state that matches what we're getting from server,\n // we can clear the lastUserValue flag since it's been synchronized\n if (lastUserValue !== null && isEqual(messageState, lastUserValue)) {\n setLastUserValue(null);\n }\n\n // Update local state with server state unless user has specifically changed this value\n // This allows streaming updates to continue while protecting user edits\n if (lastUserValue === null || !isEqual(localState, lastUserValue)) {\n setLocalState(messageState);\n }\n }\n // Otherwise fall back to initial value if we have one\n else if (cachedInitialValue !== undefined && !localState) {\n setLocalState(cachedInitialValue);\n }\n }, [\n keyName,\n message?.componentState,\n cachedInitialValue,\n lastUserValue,\n localState,\n ]);\n\n // Create debounced save function for efficient server synchronization\n const debouncedSave = useDebouncedCallback(async (newValue: S) => {\n if (!message) {\n console.warn(\n `Cannot update missing message ${messageId} for state key \"${keyName}\"`,\n );\n setLastUserValue(null);\n return;\n }\n\n setIsPending(true);\n try {\n const messageUpdate = {\n ...message,\n componentState: {\n ...message.componentState,\n [keyName]: newValue,\n },\n };\n\n const componentStateUpdate = {\n state: { [keyName]: newValue },\n };\n\n await Promise.all([\n updateThreadMessage(messageId, messageUpdate, false),\n client.beta.threads.messages.updateComponentState(\n threadId,\n messageId,\n componentStateUpdate,\n ),\n ]);\n\n // Only clear the lastUserValue when we've successfully synced this exact value\n if (isEqual(newValue, lastUserValue)) {\n setLastUserValue(null);\n }\n } catch (err) {\n console.error(\n `Failed to save component state for key \"${keyName}\":`,\n err,\n );\n } finally {\n setIsPending(false);\n }\n }, debounceTime);\n\n // Initialize state on first render if needed\n const initializeState = useCallback(async () => {\n if (!message) {\n console.warn(\n `Cannot initialize state for missing message ${messageId} with key \"${keyName}\"`,\n );\n return;\n }\n\n try {\n const messageUpdate = {\n ...message,\n componentState: {\n ...message.componentState,\n [keyName]: cachedInitialValue,\n },\n };\n\n const componentStateUpdate = {\n state: { [keyName]: cachedInitialValue },\n };\n\n await Promise.all([\n updateThreadMessage(messageId, messageUpdate, false),\n client.beta.threads.messages.updateComponentState(\n threadId,\n messageId,\n componentStateUpdate,\n ),\n ]);\n } catch (err) {\n console.warn(\n `Failed to initialize component state for key \"${keyName}\":`,\n err,\n );\n }\n }, [\n cachedInitialValue,\n client.beta.threads.messages,\n keyName,\n message,\n messageId,\n threadId,\n updateThreadMessage,\n ]);\n\n // Send initial state when component mounts\n useEffect(() => {\n if (shouldInitialize) {\n initializeState();\n setHaveInitialized(true);\n }\n }, [initializeState, shouldInitialize]);\n\n // setValue function for updating state\n // Updates local state immediately and schedules debounced server sync\n const setValue = useCallback(\n (newValue: S) => {\n // Track this as a user-initiated update\n setLastUserValue(newValue);\n setLocalState(newValue);\n\n // Only trigger server updates if we have a message\n if (message) {\n debouncedSave(newValue);\n } else {\n console.warn(\n `Cannot update server for missing message ${messageId} with key \"${keyName}\"`,\n );\n setLastUserValue(null);\n }\n },\n [debouncedSave, message, messageId, keyName],\n );\n\n // Ensure pending changes are flushed on unmount\n useEffect(() => {\n return () => {\n debouncedSave.flush();\n setLastUserValue(null);\n };\n }, [debouncedSave]);\n\n // Return the local state for immediate UI rendering\n return [localState as S, setValue, { isPending }];\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A helper hook that automatically updates Tambo component state when specified props change.
|
|
3
|
+
*
|
|
4
|
+
* This hook streamlines the common pattern of updating component state when receiving new
|
|
5
|
+
* streamed values from Tambo, eliminating the need to write repetitive useEffect code.
|
|
6
|
+
*
|
|
7
|
+
* @param currentState - The current state object from useTamboComponentState
|
|
8
|
+
* @param setState - The setState function from useTamboComponentState
|
|
9
|
+
* @param streamingProps - An object mapping state keys to prop values that should update the state
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* // Instead of writing a complex useEffect:
|
|
14
|
+
* const [emailState, setEmailState] = useTamboComponentState("email", initialState);
|
|
15
|
+
*
|
|
16
|
+
* // Simply use:
|
|
17
|
+
* useTamboStreamingProps(emailState, setEmailState, {
|
|
18
|
+
* subject: aiGeneratedSubject,
|
|
19
|
+
* body: aiGeneratedBody,
|
|
20
|
+
* usersEmail: usersEmail
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function useTamboStreamingProps<T extends Record<string, any>>(currentState: T | undefined, setState: (state: T) => void, streamingProps: Partial<T>): void;
|
|
25
|
+
//# sourceMappingURL=use-streaming-props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-streaming-props.d.ts","sourceRoot":"","sources":["../../src/hooks/use-streaming-props.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAClE,YAAY,EAAE,CAAC,GAAG,SAAS,EAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,EAC5B,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,QAuB3B"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useTamboStreamingProps = useTamboStreamingProps;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
/**
|
|
6
|
+
* A helper hook that automatically updates Tambo component state when specified props change.
|
|
7
|
+
*
|
|
8
|
+
* This hook streamlines the common pattern of updating component state when receiving new
|
|
9
|
+
* streamed values from Tambo, eliminating the need to write repetitive useEffect code.
|
|
10
|
+
*
|
|
11
|
+
* @param currentState - The current state object from useTamboComponentState
|
|
12
|
+
* @param setState - The setState function from useTamboComponentState
|
|
13
|
+
* @param streamingProps - An object mapping state keys to prop values that should update the state
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* // Instead of writing a complex useEffect:
|
|
18
|
+
* const [emailState, setEmailState] = useTamboComponentState("email", initialState);
|
|
19
|
+
*
|
|
20
|
+
* // Simply use:
|
|
21
|
+
* useTamboStreamingProps(emailState, setEmailState, {
|
|
22
|
+
* subject: aiGeneratedSubject,
|
|
23
|
+
* body: aiGeneratedBody,
|
|
24
|
+
* usersEmail: usersEmail
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
function useTamboStreamingProps(currentState, setState, streamingProps) {
|
|
29
|
+
(0, react_1.useEffect)(() => {
|
|
30
|
+
if (currentState) {
|
|
31
|
+
let shouldUpdate = false;
|
|
32
|
+
const updates = {};
|
|
33
|
+
Object.entries(streamingProps).forEach(([key, value]) => {
|
|
34
|
+
if (value !== undefined && value !== currentState[key]) {
|
|
35
|
+
shouldUpdate = true;
|
|
36
|
+
updates[key] = value;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
if (shouldUpdate) {
|
|
40
|
+
setState({
|
|
41
|
+
...currentState,
|
|
42
|
+
...updates,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
47
|
+
}, [currentState, setState, ...Object.values(streamingProps)]);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=use-streaming-props.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-streaming-props.js","sourceRoot":"","sources":["../../src/hooks/use-streaming-props.tsx"],"names":[],"mappings":";;AAyBA,wDA0BC;AAnDD,iCAAkC;AAElC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,SAAgB,sBAAsB,CACpC,YAA2B,EAC3B,QAA4B,EAC5B,cAA0B;IAE1B,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,YAAY,GAAG,KAAK,CAAC;YACzB,MAAM,OAAO,GAAe,EAAE,CAAC;YAE/B,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;gBACtD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;oBACvD,YAAY,GAAG,IAAI,CAAC;oBACpB,OAAO,CAAC,GAAc,CAAC,GAAG,KAAmB,CAAC;gBAChD,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,YAAY,EAAE,CAAC;gBACjB,QAAQ,CAAC;oBACP,GAAG,YAAY;oBACf,GAAG,OAAO;iBACX,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,uDAAuD;IACzD,CAAC,EAAE,CAAC,YAAY,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC","sourcesContent":["import { useEffect } from \"react\";\n\n/**\n * A helper hook that automatically updates Tambo component state when specified props change.\n *\n * This hook streamlines the common pattern of updating component state when receiving new\n * streamed values from Tambo, eliminating the need to write repetitive useEffect code.\n *\n * @param currentState - The current state object from useTamboComponentState\n * @param setState - The setState function from useTamboComponentState\n * @param streamingProps - An object mapping state keys to prop values that should update the state\n *\n * @example\n * ```tsx\n * // Instead of writing a complex useEffect:\n * const [emailState, setEmailState] = useTamboComponentState(\"email\", initialState);\n *\n * // Simply use:\n * useTamboStreamingProps(emailState, setEmailState, {\n * subject: aiGeneratedSubject,\n * body: aiGeneratedBody,\n * usersEmail: usersEmail\n * });\n * ```\n */\nexport function useTamboStreamingProps<T extends Record<string, any>>(\n currentState: T | undefined,\n setState: (state: T) => void,\n streamingProps: Partial<T>,\n) {\n useEffect(() => {\n if (currentState) {\n let shouldUpdate = false;\n const updates: Partial<T> = {};\n\n Object.entries(streamingProps).forEach(([key, value]) => {\n if (value !== undefined && value !== currentState[key]) {\n shouldUpdate = true;\n updates[key as keyof T] = value as T[keyof T];\n }\n });\n\n if (shouldUpdate) {\n setState({\n ...currentState,\n ...updates,\n });\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [currentState, setState, ...Object.values(streamingProps)]);\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** Exports for the library. Only publically available exports are re-exported here. Anything not exported here is not supported and may change or break at any time. */
|
|
2
2
|
export { useTamboComponentState } from "./hooks/use-component-state";
|
|
3
3
|
export { TamboMessageProvider, useTamboCurrentMessage, useTamboMessageContext, } from "./hooks/use-current-message";
|
|
4
|
+
export { useTamboStreamingProps } from "./hooks/use-streaming-props";
|
|
4
5
|
export * from "./hooks/use-suggestions";
|
|
5
6
|
export { useTamboThreadInput } from "./hooks/use-thread-input";
|
|
6
7
|
export * from "./providers";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wKAAwK;AACxK,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG/D,cAAc,aAAa,CAAC;AAG5B,YAAY,EACV,QAAQ,EACR,cAAc,EACd,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,UAAU,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,6DAA6D,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,SAAS,GACf,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,eAAe,EACf,KAAK,kBAAkB,GACxB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wKAAwK;AACxK,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG/D,cAAc,aAAa,CAAC;AAG5B,YAAY,EACV,QAAQ,EACR,cAAc,EACd,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,UAAU,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,6DAA6D,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,SAAS,GACf,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,eAAe,EACf,KAAK,kBAAkB,GACxB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.GenerationStage = exports.useTamboThreads = exports.useTamboThreadInput = exports.useTamboMessageContext = exports.useTamboCurrentMessage = exports.TamboMessageProvider = exports.useTamboComponentState = void 0;
|
|
17
|
+
exports.GenerationStage = exports.useTamboThreads = exports.useTamboThreadInput = exports.useTamboStreamingProps = exports.useTamboMessageContext = exports.useTamboCurrentMessage = exports.TamboMessageProvider = exports.useTamboComponentState = void 0;
|
|
18
18
|
/** Exports for the library. Only publically available exports are re-exported here. Anything not exported here is not supported and may change or break at any time. */
|
|
19
19
|
var use_component_state_1 = require("./hooks/use-component-state");
|
|
20
20
|
Object.defineProperty(exports, "useTamboComponentState", { enumerable: true, get: function () { return use_component_state_1.useTamboComponentState; } });
|
|
@@ -22,6 +22,8 @@ var use_current_message_1 = require("./hooks/use-current-message");
|
|
|
22
22
|
Object.defineProperty(exports, "TamboMessageProvider", { enumerable: true, get: function () { return use_current_message_1.TamboMessageProvider; } });
|
|
23
23
|
Object.defineProperty(exports, "useTamboCurrentMessage", { enumerable: true, get: function () { return use_current_message_1.useTamboCurrentMessage; } });
|
|
24
24
|
Object.defineProperty(exports, "useTamboMessageContext", { enumerable: true, get: function () { return use_current_message_1.useTamboMessageContext; } });
|
|
25
|
+
var use_streaming_props_1 = require("./hooks/use-streaming-props");
|
|
26
|
+
Object.defineProperty(exports, "useTamboStreamingProps", { enumerable: true, get: function () { return use_streaming_props_1.useTamboStreamingProps; } });
|
|
25
27
|
__exportStar(require("./hooks/use-suggestions"), exports);
|
|
26
28
|
var use_thread_input_1 = require("./hooks/use-thread-input");
|
|
27
29
|
Object.defineProperty(exports, "useTamboThreadInput", { enumerable: true, get: function () { return use_thread_input_1.useTamboThreadInput; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,wKAAwK;AACxK,mEAAqE;AAA5D,6HAAA,sBAAsB,OAAA;AAC/B,mEAIqC;AAHnC,2HAAA,oBAAoB,OAAA;AACpB,6HAAA,sBAAsB,OAAA;AACtB,6HAAA,sBAAsB,OAAA;AAExB,0DAAwC;AACxC,6DAA+D;AAAtD,uHAAA,mBAAmB,OAAA;AAE5B,gCAAgC;AAChC,8CAA4B;AAc5B,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AAQxB,mFAG6C;AAF3C,8HAAA,eAAe,OAAA","sourcesContent":["/** Exports for the library. Only publically available exports are re-exported here. Anything not exported here is not supported and may change or break at any time. */\nexport { useTamboComponentState } from \"./hooks/use-component-state\";\nexport {\n TamboMessageProvider,\n useTamboCurrentMessage,\n useTamboMessageContext,\n} from \"./hooks/use-current-message\";\nexport * from \"./hooks/use-suggestions\";\nexport { useTamboThreadInput } from \"./hooks/use-thread-input\";\n\n// Re-export provider components\nexport * from \"./providers\";\n\n// Re-export types from Tambo Node SDK\nexport type {\n APIError,\n RateLimitError,\n TamboAIError,\n} from \"@tambo-ai/typescript-sdk\";\nexport type {\n Suggestion,\n SuggestionGenerateParams,\n SuggestionGenerateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/beta/threads/suggestions\";\nexport { useTamboThreads } from \"./hooks/use-tambo-threads\";\nexport {\n type ComponentContextToolMetadata,\n type ComponentRegistry,\n type ParameterSpec,\n type RegisteredComponent,\n type TamboTool,\n} from \"./model/component-metadata\";\nexport {\n GenerationStage,\n type TamboThreadMessage,\n} from \"./model/generate-component-response\";\nexport { type TamboThread } from \"./model/tambo-thread\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,wKAAwK;AACxK,mEAAqE;AAA5D,6HAAA,sBAAsB,OAAA;AAC/B,mEAIqC;AAHnC,2HAAA,oBAAoB,OAAA;AACpB,6HAAA,sBAAsB,OAAA;AACtB,6HAAA,sBAAsB,OAAA;AAExB,mEAAqE;AAA5D,6HAAA,sBAAsB,OAAA;AAC/B,0DAAwC;AACxC,6DAA+D;AAAtD,uHAAA,mBAAmB,OAAA;AAE5B,gCAAgC;AAChC,8CAA4B;AAc5B,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AAQxB,mFAG6C;AAF3C,8HAAA,eAAe,OAAA","sourcesContent":["/** Exports for the library. Only publically available exports are re-exported here. Anything not exported here is not supported and may change or break at any time. */\nexport { useTamboComponentState } from \"./hooks/use-component-state\";\nexport {\n TamboMessageProvider,\n useTamboCurrentMessage,\n useTamboMessageContext,\n} from \"./hooks/use-current-message\";\nexport { useTamboStreamingProps } from \"./hooks/use-streaming-props\";\nexport * from \"./hooks/use-suggestions\";\nexport { useTamboThreadInput } from \"./hooks/use-thread-input\";\n\n// Re-export provider components\nexport * from \"./providers\";\n\n// Re-export types from Tambo Node SDK\nexport type {\n APIError,\n RateLimitError,\n TamboAIError,\n} from \"@tambo-ai/typescript-sdk\";\nexport type {\n Suggestion,\n SuggestionGenerateParams,\n SuggestionGenerateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/beta/threads/suggestions\";\nexport { useTamboThreads } from \"./hooks/use-tambo-threads\";\nexport {\n type ComponentContextToolMetadata,\n type ComponentRegistry,\n type ParameterSpec,\n type RegisteredComponent,\n type TamboTool,\n} from \"./model/component-metadata\";\nexport {\n GenerationStage,\n type TamboThreadMessage,\n} from \"./model/generate-component-response\";\nexport { type TamboThread } from \"./model/tambo-thread\";\n"]}
|
|
@@ -4,7 +4,7 @@ import { GenerationStage, TamboThreadMessage } from "../model/generate-component
|
|
|
4
4
|
import { TamboThread } from "../model/tambo-thread";
|
|
5
5
|
export interface TamboThreadContextProps {
|
|
6
6
|
thread: TamboThread;
|
|
7
|
-
switchCurrentThread: (threadId: string) => void;
|
|
7
|
+
switchCurrentThread: (threadId: string, fetch?: boolean) => void;
|
|
8
8
|
addThreadMessage: (message: TamboThreadMessage, sendToServer: boolean) => Promise<TamboAI.Beta.Threads.ThreadMessage[]>;
|
|
9
9
|
updateThreadMessage: (id: string, message: TamboThreadMessage, sendToServer: boolean) => Promise<void>;
|
|
10
10
|
setLastThreadStatus: (status: GenerationStage) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-thread-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-thread-provider.tsx"],"names":[],"mappings":"AACA,OAAO,OAA0B,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAMlB,MAAM,OAAO,CAAC;AACf,OAAO,EACL,eAAe,EAEf,kBAAkB,EACnB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOpD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,WAAW,CAAC;IACpB,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"tambo-thread-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-thread-provider.tsx"],"names":[],"mappings":"AACA,OAAO,OAA0B,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAMlB,MAAM,OAAO,CAAC;AACf,OAAO,EACL,eAAe,EAEf,kBAAkB,EACnB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOpD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,WAAW,CAAC;IACpB,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACjE,gBAAgB,EAAE,CAChB,OAAO,EAAE,kBAAkB,EAC3B,YAAY,EAAE,OAAO,KAClB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACnD,mBAAmB,EAAE,CACnB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,kBAAkB,EAC3B,YAAY,EAAE,OAAO,KAClB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,mBAAmB,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,iBAAiB,EAAE,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,KACE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,eAAe,EAAE,eAAe,CAAC;IACjC,uBAAuB,EAAE,MAAM,CAAC;IAChC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAOhC,CAAC;AAEF,eAAO,MAAM,kBAAkB,wCAwB7B,CAAC;AAEH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA0e3D,CAAC;AAEF,eAAO,MAAM,cAAc,+BAM1B,CAAC"}
|