@tambo-ai/react 0.38.1 → 0.40.1
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 +1 -1
- package/dist/hooks/use-component-state.js +0 -1
- package/dist/hooks/use-component-state.js.map +1 -1
- package/dist/hooks/use-thread-input.d.ts +1 -0
- package/dist/hooks/use-thread-input.d.ts.map +1 -1
- package/dist/hooks/use-thread-input.js +2 -1
- package/dist/hooks/use-thread-input.js.map +1 -1
- package/dist/mcp/mcp-client.d.ts +15 -15
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.js +144 -224
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.js.map +1 -1
- package/dist/providers/__tests__/tambo-thread-provider.test.js +65 -0
- package/dist/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
- package/dist/providers/index.d.ts +2 -2
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +4 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/tambo-prop-stream-provider/index.d.ts +19 -0
- package/dist/providers/tambo-prop-stream-provider/index.d.ts.map +1 -0
- package/dist/providers/tambo-prop-stream-provider/index.js +43 -0
- package/dist/providers/tambo-prop-stream-provider/index.js.map +1 -0
- package/dist/providers/tambo-prop-stream-provider/pending.d.ts +12 -0
- package/dist/providers/tambo-prop-stream-provider/pending.d.ts.map +1 -0
- package/dist/providers/tambo-prop-stream-provider/pending.js +31 -0
- package/dist/providers/tambo-prop-stream-provider/pending.js.map +1 -0
- package/dist/providers/tambo-prop-stream-provider/provider.d.ts +17 -0
- package/dist/providers/tambo-prop-stream-provider/provider.d.ts.map +1 -0
- package/dist/providers/tambo-prop-stream-provider/provider.js +107 -0
- package/dist/providers/tambo-prop-stream-provider/provider.js.map +1 -0
- package/dist/providers/tambo-prop-stream-provider/streaming.d.ts +12 -0
- package/dist/providers/tambo-prop-stream-provider/streaming.d.ts.map +1 -0
- package/dist/providers/tambo-prop-stream-provider/streaming.js +28 -0
- package/dist/providers/tambo-prop-stream-provider/streaming.js.map +1 -0
- package/dist/providers/tambo-prop-stream-provider/success.d.ts +12 -0
- package/dist/providers/tambo-prop-stream-provider/success.d.ts.map +1 -0
- package/dist/providers/tambo-prop-stream-provider/success.js +28 -0
- package/dist/providers/tambo-prop-stream-provider/success.js.map +1 -0
- package/dist/providers/tambo-prop-stream-provider/types.d.ts +25 -0
- package/dist/providers/tambo-prop-stream-provider/types.d.ts.map +1 -0
- package/dist/providers/tambo-prop-stream-provider/types.js +6 -0
- package/dist/providers/tambo-prop-stream-provider/types.js.map +1 -0
- package/dist/providers/tambo-thread-provider.d.ts +1 -0
- package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-provider.js +13 -2
- package/dist/providers/tambo-thread-provider.js.map +1 -1
- package/dist/util/registry.d.ts +4 -1
- package/dist/util/registry.d.ts.map +1 -1
- package/dist/util/registry.js +9 -11
- package/dist/util/registry.js.map +1 -1
- package/esm/hooks/use-component-state.js +0 -1
- package/esm/hooks/use-component-state.js.map +1 -1
- package/esm/hooks/use-thread-input.d.ts +1 -0
- package/esm/hooks/use-thread-input.d.ts.map +1 -1
- package/esm/hooks/use-thread-input.js +2 -1
- package/esm/hooks/use-thread-input.js.map +1 -1
- package/esm/mcp/mcp-client.d.ts +15 -15
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.js +144 -224
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.js.map +1 -1
- package/esm/providers/__tests__/tambo-thread-provider.test.js +65 -0
- package/esm/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
- package/esm/providers/index.d.ts +2 -2
- package/esm/providers/index.d.ts.map +1 -1
- package/esm/providers/index.js +1 -1
- package/esm/providers/index.js.map +1 -1
- package/esm/providers/tambo-prop-stream-provider/index.d.ts +19 -0
- package/esm/providers/tambo-prop-stream-provider/index.d.ts.map +1 -0
- package/esm/providers/tambo-prop-stream-provider/index.js +22 -0
- package/esm/providers/tambo-prop-stream-provider/index.js.map +1 -0
- package/esm/providers/tambo-prop-stream-provider/pending.d.ts +12 -0
- package/esm/providers/tambo-prop-stream-provider/pending.d.ts.map +1 -0
- package/esm/providers/tambo-prop-stream-provider/pending.js +24 -0
- package/esm/providers/tambo-prop-stream-provider/pending.js.map +1 -0
- package/esm/providers/tambo-prop-stream-provider/provider.d.ts +17 -0
- package/esm/providers/tambo-prop-stream-provider/provider.d.ts.map +1 -0
- package/esm/providers/tambo-prop-stream-provider/provider.js +70 -0
- package/esm/providers/tambo-prop-stream-provider/provider.js.map +1 -0
- package/esm/providers/tambo-prop-stream-provider/streaming.d.ts +12 -0
- package/esm/providers/tambo-prop-stream-provider/streaming.d.ts.map +1 -0
- package/esm/providers/tambo-prop-stream-provider/streaming.js +21 -0
- package/esm/providers/tambo-prop-stream-provider/streaming.js.map +1 -0
- package/esm/providers/tambo-prop-stream-provider/success.d.ts +12 -0
- package/esm/providers/tambo-prop-stream-provider/success.d.ts.map +1 -0
- package/esm/providers/tambo-prop-stream-provider/success.js +21 -0
- package/esm/providers/tambo-prop-stream-provider/success.js.map +1 -0
- package/esm/providers/tambo-prop-stream-provider/types.d.ts +25 -0
- package/esm/providers/tambo-prop-stream-provider/types.d.ts.map +1 -0
- package/esm/providers/tambo-prop-stream-provider/types.js +3 -0
- package/esm/providers/tambo-prop-stream-provider/types.js.map +1 -0
- package/esm/providers/tambo-thread-provider.d.ts +1 -0
- package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-provider.js +14 -3
- package/esm/providers/tambo-thread-provider.js.map +1 -1
- package/esm/util/registry.d.ts +4 -1
- package/esm/util/registry.d.ts.map +1 -1
- package/esm/util/registry.js +7 -9
- package/esm/util/registry.js.map +1 -1
- package/package.json +12 -11
- package/dist/providers/tambo-prop-stream-provider.d.ts +0 -96
- package/dist/providers/tambo-prop-stream-provider.d.ts.map +0 -1
- package/dist/providers/tambo-prop-stream-provider.js +0 -185
- package/dist/providers/tambo-prop-stream-provider.js.map +0 -1
- package/esm/providers/tambo-prop-stream-provider.d.ts +0 -96
- package/esm/providers/tambo-prop-stream-provider.d.ts.map +0 -1
- package/esm/providers/tambo-prop-stream-provider.js +0 -148
- package/esm/providers/tambo-prop-stream-provider.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,7 +6,6 @@ const react_1 = require("react");
|
|
|
6
6
|
const use_debounce_1 = require("use-debounce");
|
|
7
7
|
const providers_1 = require("../providers");
|
|
8
8
|
const use_current_message_1 = require("./use-current-message");
|
|
9
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
10
9
|
function useTamboComponentState(keyName, initialValue, debounceTime = 500) {
|
|
11
10
|
const { messageId } = (0, use_current_message_1.useTamboMessageContext)();
|
|
12
11
|
const { updateThreadMessage, thread } = (0, providers_1.useTamboThread)();
|
|
@@ -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":["\"use client\";\nimport { 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// 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 * @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 * @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 * @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 */\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>;\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function useTamboComponentState<S>(\n keyName: string,\n initialValue?: S,\n debounceTime = 500,\n): StateUpdateResult<S> {\n const { messageId } = useTamboMessageContext();\n const { updateThreadMessage, thread } = useTamboThread();\n const client = useTamboClient();\n const message = useTamboCurrentMessage();\n const threadId = thread.id;\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 // 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 // Only update local state if we haven't had any user changes yet\n if (lastUserValue === null) {\n setLocalState(messageState);\n }\n }\n // Otherwise fall back to initial value if we have one and no user changes\n else if (\n cachedInitialValue !== undefined &&\n !localState &&\n lastUserValue === null\n ) {\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 debouncedServerWrite = useDebouncedCallback(async (newValue: S) => {\n setIsPending(true);\n try {\n const componentStateUpdate = {\n state: { [keyName]: newValue },\n };\n\n await client.beta.threads.messages.updateComponentState(\n threadId,\n messageId,\n componentStateUpdate,\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 debouncedServerWrite(newValue);\n const messageUpdate = {\n ...message,\n componentState: {\n ...message.componentState,\n [keyName]: newValue,\n },\n };\n\n updateThreadMessage(messageId, messageUpdate, false);\n } else {\n console.warn(\n `Cannot update server for missing message ${messageId} with key \"${keyName}\"`,\n );\n }\n },\n [message, debouncedServerWrite, keyName, updateThreadMessage, messageId],\n );\n\n // Ensure pending changes are flushed on unmount\n useEffect(() => {\n return () => {\n debouncedServerWrite.flush();\n };\n }, [debouncedServerWrite]);\n\n // Return the local state for immediate UI rendering\n return [localState as S, setValue, { isPending }];\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":["\"use client\";\nimport { 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// 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 * @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 * @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 * @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 */\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>;\n\nexport function useTamboComponentState<S>(\n keyName: string,\n initialValue?: S,\n debounceTime = 500,\n): StateUpdateResult<S> {\n const { messageId } = useTamboMessageContext();\n const { updateThreadMessage, thread } = useTamboThread();\n const client = useTamboClient();\n const message = useTamboCurrentMessage();\n const threadId = thread.id;\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 // 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 // Only update local state if we haven't had any user changes yet\n if (lastUserValue === null) {\n setLocalState(messageState);\n }\n }\n // Otherwise fall back to initial value if we have one and no user changes\n else if (\n cachedInitialValue !== undefined &&\n !localState &&\n lastUserValue === null\n ) {\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 debouncedServerWrite = useDebouncedCallback(async (newValue: S) => {\n setIsPending(true);\n try {\n const componentStateUpdate = {\n state: { [keyName]: newValue },\n };\n\n await client.beta.threads.messages.updateComponentState(\n threadId,\n messageId,\n componentStateUpdate,\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 debouncedServerWrite(newValue);\n const messageUpdate = {\n ...message,\n componentState: {\n ...message.componentState,\n [keyName]: newValue,\n },\n };\n\n updateThreadMessage(messageId, messageUpdate, false);\n } else {\n console.warn(\n `Cannot update server for missing message ${messageId} with key \"${keyName}\"`,\n );\n }\n },\n [message, debouncedServerWrite, keyName, updateThreadMessage, messageId],\n );\n\n // Ensure pending changes are flushed on unmount\n useEffect(() => {\n return () => {\n debouncedServerWrite.flush();\n };\n }, [debouncedServerWrite]);\n\n // Return the local state for immediate UI rendering\n return [localState as S, setValue, { isPending }];\n}\n"]}
|
|
@@ -36,6 +36,7 @@ interface UseThreadInputInternal {
|
|
|
36
36
|
contextKey?: string;
|
|
37
37
|
streamResponse?: boolean;
|
|
38
38
|
forceToolChoice?: string;
|
|
39
|
+
additionalContext?: Record<string, any>;
|
|
39
40
|
}) => Promise<void>;
|
|
40
41
|
}
|
|
41
42
|
export type UseThreadInput = UseThreadInputInternal & UseMutationResult<void, Error, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-thread-input.d.ts","sourceRoot":"","sources":["../../src/hooks/use-thread-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAO1D;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;IAC/B,kDAAkD;;IAElD,0CAA0C;;IAE1C,qDAAqD;;IAErD,yCAAyC;;CAEjC,CAAC;AAEX;;;GAGG;AACH,UAAU,sBAAsB;IAC9B,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;;OAKG;IACH,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"use-thread-input.d.ts","sourceRoot":"","sources":["../../src/hooks/use-thread-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAO1D;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;IAC/B,kDAAkD;;IAElD,0CAA0C;;IAE1C,qDAAqD;;IAErD,yCAAyC;;CAEjC,CAAC;AAEX;;;GAGG;AACH,UAAU,sBAAsB;IAC9B,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;;OAKG;IACH,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACzC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AACD,MAAM,MAAM,cAAc,GAAG,sBAAsB,GACjD,iBAAiB,CACf,IAAI,EACJ,KAAK,EACL;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAC5E,CAAC;AAEJ;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,cAAc,CAiDvE"}
|
|
@@ -28,7 +28,7 @@ exports.INPUT_ERROR_MESSAGES = {
|
|
|
28
28
|
*/
|
|
29
29
|
function useTamboThreadInput(contextKey) {
|
|
30
30
|
const { thread, inputValue, setInputValue, sendThreadMessage } = (0, tambo_thread_provider_1.useTamboThread)();
|
|
31
|
-
const submit = (0, react_1.useCallback)(async ({ contextKey: submitContextKey, streamResponse, forceToolChoice, } = {}) => {
|
|
31
|
+
const submit = (0, react_1.useCallback)(async ({ contextKey: submitContextKey, streamResponse, forceToolChoice, additionalContext, } = {}) => {
|
|
32
32
|
const validation = (0, validate_input_1.validateInput)(inputValue);
|
|
33
33
|
if (!validation.isValid) {
|
|
34
34
|
throw new thread_input_error_1.ThreadInputError(`Cannot submit message: ${validation.error ?? exports.INPUT_ERROR_MESSAGES.VALIDATION}`, { cause: validation.error });
|
|
@@ -38,6 +38,7 @@ function useTamboThreadInput(contextKey) {
|
|
|
38
38
|
contextKey: submitContextKey ?? contextKey ?? undefined,
|
|
39
39
|
streamResponse: streamResponse,
|
|
40
40
|
forceToolChoice: forceToolChoice,
|
|
41
|
+
additionalContext: additionalContext,
|
|
41
42
|
});
|
|
42
43
|
setInputValue("");
|
|
43
44
|
}, [inputValue, sendThreadMessage, thread.id, contextKey, setInputValue]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-thread-input.js","sourceRoot":"","sources":["../../src/hooks/use-thread-input.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"use-thread-input.js","sourceRoot":"","sources":["../../src/hooks/use-thread-input.ts"],"names":[],"mappings":";;;AA2DA,kDAiDC;AA3GD,iCAAoC;AACpC,oEAA+D;AAC/D,4DAAwD;AACxD,8EAAoE;AACpE,2DAAuD;AAEvD;;;;GAIG;AACU,QAAA,oBAAoB,GAAG;IAClC,kDAAkD;IAClD,KAAK,EAAE,yBAAyB;IAChC,0CAA0C;IAC1C,OAAO,EAAE,6CAA6C;IACtD,qDAAqD;IACrD,MAAM,EAAE,gCAAgC;IACxC,yCAAyC;IACzC,UAAU,EAAE,wBAAwB;CAC5B,CAAC;AAkCX;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,UAAmB;IACrD,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,GAC5D,IAAA,sCAAc,GAAE,CAAC;IAEnB,MAAM,MAAM,GAAG,IAAA,mBAAW,EACxB,KAAK,EAAE,EACL,UAAU,EAAE,gBAAgB,EAC5B,cAAc,EACd,eAAe,EACf,iBAAiB,MAMf,EAAE,EAAE,EAAE;QACR,MAAM,UAAU,GAAG,IAAA,8BAAa,EAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,qCAAgB,CACxB,0BAA0B,UAAU,CAAC,KAAK,IAAI,4BAAoB,CAAC,UAAU,EAAE,EAC/E,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAC5B,CAAC;QACJ,CAAC;QAED,MAAM,iBAAiB,CAAC,UAAU,CAAC,cAAc,EAAE;YACjD,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,UAAU,EAAE,gBAAgB,IAAI,UAAU,IAAI,SAAS;YACvD,cAAc,EAAE,cAAc;YAC9B,eAAe,EAAE,eAAe;YAChC,iBAAiB,EAAE,iBAAiB;SACrC,CAAC,CAAC;QACH,aAAa,CAAC,EAAE,CAAC,CAAC;IACpB,CAAC,EACD,CAAC,UAAU,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,CACtE,CAAC;IACF,MAAM,EACJ,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,aAAa,EACrB,GAAG,aAAa,EACjB,GAAG,IAAA,oCAAgB,EAAC;QACnB,UAAU,EAAE,MAAM;KACnB,CAAC,CAAC;IAEH,OAAO;QACL,GAAG,aAAa;QAChB,KAAK,EAAE,UAAU;QACjB,QAAQ,EAAE,aAAa;QACvB,MAAM,EAAE,WAAW;KACF,CAAC;AACtB,CAAC","sourcesContent":["import { UseMutationResult } from \"@tanstack/react-query\";\nimport { useCallback } from \"react\";\nimport { ThreadInputError } from \"../model/thread-input-error\";\nimport { validateInput } from \"../model/validate-input\";\nimport { useTamboThread } from \"../providers/tambo-thread-provider\";\nimport { useTamboMutation } from \"./react-query-hooks\";\n\n/**\n * Error messages for various input-related error scenarios\n * These messages are used to provide user-friendly error feedback\n * @readonly\n */\nexport const INPUT_ERROR_MESSAGES = {\n /** Error when attempting to submit empty input */\n EMPTY: \"Message cannot be empty\",\n /** Error when network connection fails */\n NETWORK: \"Network error. Please check your connection\",\n /** Error when server fails to process the request */\n SERVER: \"Server error. Please try again\",\n /** Error when input format is invalid */\n VALIDATION: \"Invalid message format\",\n} as const;\n\n/**\n * Interface for the thread input hook return value\n * Provides all necessary functions and state for managing thread input\n */\ninterface UseThreadInputInternal {\n /** Current value of the input field */\n value: string;\n /**\n * Function to update the input value\n * @param value - New value for the input field\n */\n setValue: (value: string) => void;\n /**\n * Function to submit the current input value\n * Validates input, handles errors, and cleans up state after submission\n * @throws {ThreadInputError} If submission fails\n * @returns Promise that resolves when submission is complete\n */\n submit: (options?: {\n contextKey?: string;\n streamResponse?: boolean;\n forceToolChoice?: string;\n additionalContext?: Record<string, any>;\n }) => Promise<void>;\n}\nexport type UseThreadInput = UseThreadInputInternal &\n UseMutationResult<\n void,\n Error,\n { contextKey?: string; streamResponse?: boolean; forceToolChoice?: string }\n >;\n\n/**\n * Hook for managing thread message input state and submission\n * @returns Interface for managing thread input state and submission\n */\nexport function useTamboThreadInput(contextKey?: string): UseThreadInput {\n const { thread, inputValue, setInputValue, sendThreadMessage } =\n useTamboThread();\n\n const submit = useCallback(\n async ({\n contextKey: submitContextKey,\n streamResponse,\n forceToolChoice,\n additionalContext,\n }: {\n contextKey?: string;\n streamResponse?: boolean;\n forceToolChoice?: string;\n additionalContext?: Record<string, any>;\n } = {}) => {\n const validation = validateInput(inputValue);\n if (!validation.isValid) {\n throw new ThreadInputError(\n `Cannot submit message: ${validation.error ?? INPUT_ERROR_MESSAGES.VALIDATION}`,\n { cause: validation.error },\n );\n }\n\n await sendThreadMessage(validation.sanitizedInput, {\n threadId: thread.id,\n contextKey: submitContextKey ?? contextKey ?? undefined,\n streamResponse: streamResponse,\n forceToolChoice: forceToolChoice,\n additionalContext: additionalContext,\n });\n setInputValue(\"\");\n },\n [inputValue, sendThreadMessage, thread.id, contextKey, setInputValue],\n );\n const {\n mutateAsync: submitAsync,\n mutate: _unusedSubmit,\n ...mutationState\n } = useTamboMutation({\n mutationFn: submit,\n });\n\n return {\n ...mutationState,\n value: inputValue,\n setValue: setInputValue,\n submit: submitAsync,\n } as UseThreadInput;\n}\n"]}
|
package/dist/mcp/mcp-client.d.ts
CHANGED
|
@@ -65,32 +65,32 @@ export declare class MCPClient {
|
|
|
65
65
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
66
66
|
}, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<{
|
|
67
67
|
type: import("zod").ZodLiteral<"image">;
|
|
68
|
-
data: import("zod").ZodString
|
|
68
|
+
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
69
69
|
mimeType: import("zod").ZodString;
|
|
70
70
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
71
71
|
}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
|
|
72
72
|
type: import("zod").ZodLiteral<"image">;
|
|
73
|
-
data: import("zod").ZodString
|
|
73
|
+
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
74
74
|
mimeType: import("zod").ZodString;
|
|
75
75
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
76
76
|
}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
|
|
77
77
|
type: import("zod").ZodLiteral<"image">;
|
|
78
|
-
data: import("zod").ZodString
|
|
78
|
+
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
79
79
|
mimeType: import("zod").ZodString;
|
|
80
80
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
81
81
|
}, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<{
|
|
82
82
|
type: import("zod").ZodLiteral<"audio">;
|
|
83
|
-
data: import("zod").ZodString
|
|
83
|
+
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
84
84
|
mimeType: import("zod").ZodString;
|
|
85
85
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
86
86
|
}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
|
|
87
87
|
type: import("zod").ZodLiteral<"audio">;
|
|
88
|
-
data: import("zod").ZodString
|
|
88
|
+
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
89
89
|
mimeType: import("zod").ZodString;
|
|
90
90
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
91
91
|
}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
|
|
92
92
|
type: import("zod").ZodLiteral<"audio">;
|
|
93
|
-
data: import("zod").ZodString
|
|
93
|
+
data: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
94
94
|
mimeType: import("zod").ZodString;
|
|
95
95
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
96
96
|
}, import("zod").ZodTypeAny, "passthrough">>, import("zod").ZodObject<import("zod").objectUtil.extendShape<import("zod").objectUtil.extendShape<{
|
|
@@ -148,19 +148,19 @@ export declare class MCPClient {
|
|
|
148
148
|
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
149
149
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
150
150
|
}, {
|
|
151
|
-
blob: import("zod").ZodString
|
|
151
|
+
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
152
152
|
}>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
|
|
153
153
|
uri: import("zod").ZodString;
|
|
154
154
|
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
155
155
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
156
156
|
}, {
|
|
157
|
-
blob: import("zod").ZodString
|
|
157
|
+
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
158
158
|
}>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
|
|
159
159
|
uri: import("zod").ZodString;
|
|
160
160
|
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
161
161
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
162
162
|
}, {
|
|
163
|
-
blob: import("zod").ZodString
|
|
163
|
+
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
164
164
|
}>, import("zod").ZodTypeAny, "passthrough">>]>;
|
|
165
165
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
166
166
|
}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
|
|
@@ -188,19 +188,19 @@ export declare class MCPClient {
|
|
|
188
188
|
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
189
189
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
190
190
|
}, {
|
|
191
|
-
blob: import("zod").ZodString
|
|
191
|
+
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
192
192
|
}>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
|
|
193
193
|
uri: import("zod").ZodString;
|
|
194
194
|
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
195
195
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
196
196
|
}, {
|
|
197
|
-
blob: import("zod").ZodString
|
|
197
|
+
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
198
198
|
}>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
|
|
199
199
|
uri: import("zod").ZodString;
|
|
200
200
|
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
201
201
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
202
202
|
}, {
|
|
203
|
-
blob: import("zod").ZodString
|
|
203
|
+
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
204
204
|
}>, import("zod").ZodTypeAny, "passthrough">>]>;
|
|
205
205
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
206
206
|
}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
|
|
@@ -228,19 +228,19 @@ export declare class MCPClient {
|
|
|
228
228
|
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
229
229
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
230
230
|
}, {
|
|
231
|
-
blob: import("zod").ZodString
|
|
231
|
+
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
232
232
|
}>, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<import("zod").objectUtil.extendShape<{
|
|
233
233
|
uri: import("zod").ZodString;
|
|
234
234
|
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
235
235
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
236
236
|
}, {
|
|
237
|
-
blob: import("zod").ZodString
|
|
237
|
+
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
238
238
|
}>, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<import("zod").objectUtil.extendShape<{
|
|
239
239
|
uri: import("zod").ZodString;
|
|
240
240
|
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
241
241
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
242
242
|
}, {
|
|
243
|
-
blob: import("zod").ZodString
|
|
243
|
+
blob: import("zod").ZodEffects<import("zod").ZodString, string, string>;
|
|
244
244
|
}>, import("zod").ZodTypeAny, "passthrough">>]>;
|
|
245
245
|
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
246
246
|
}, import("zod").ZodTypeAny, "passthrough">>]>, "many">>;
|