@tambo-ai/react 0.49.0 → 0.50.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/__tests__/use-message-images.test.d.ts +2 -0
- package/dist/hooks/__tests__/use-message-images.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/use-message-images.test.js +66 -0
- package/dist/hooks/__tests__/use-message-images.test.js.map +1 -0
- package/dist/hooks/use-message-images.d.ts +25 -0
- package/dist/hooks/use-message-images.d.ts.map +1 -0
- package/dist/hooks/use-message-images.js +66 -0
- package/dist/hooks/use-message-images.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-input-provider.d.ts +11 -0
- package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-input-provider.js +63 -12
- package/dist/providers/tambo-thread-input-provider.js.map +1 -1
- 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 +7 -3
- package/dist/providers/tambo-thread-provider.js.map +1 -1
- package/dist/util/__tests__/message-builder.test.d.ts +2 -0
- package/dist/util/__tests__/message-builder.test.d.ts.map +1 -0
- package/dist/util/__tests__/message-builder.test.js +191 -0
- package/dist/util/__tests__/message-builder.test.js.map +1 -0
- package/dist/util/message-builder.d.ts +10 -0
- package/dist/util/message-builder.d.ts.map +1 -0
- package/dist/util/message-builder.js +31 -0
- package/dist/util/message-builder.js.map +1 -0
- package/esm/hooks/__tests__/use-message-images.test.d.ts +2 -0
- package/esm/hooks/__tests__/use-message-images.test.d.ts.map +1 -0
- package/esm/hooks/__tests__/use-message-images.test.js +64 -0
- package/esm/hooks/__tests__/use-message-images.test.js.map +1 -0
- package/esm/hooks/use-message-images.d.ts +25 -0
- package/esm/hooks/use-message-images.d.ts.map +1 -0
- package/esm/hooks/use-message-images.js +63 -0
- package/esm/hooks/use-message-images.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-input-provider.d.ts +11 -0
- package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-input-provider.js +63 -12
- package/esm/providers/tambo-thread-input-provider.js.map +1 -1
- 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 +7 -3
- package/esm/providers/tambo-thread-provider.js.map +1 -1
- package/esm/util/__tests__/message-builder.test.d.ts +2 -0
- package/esm/util/__tests__/message-builder.test.d.ts.map +1 -0
- package/esm/util/__tests__/message-builder.test.js +189 -0
- package/esm/util/__tests__/message-builder.test.js.map +1 -0
- package/esm/util/message-builder.d.ts +10 -0
- package/esm/util/message-builder.d.ts.map +1 -0
- package/esm/util/message-builder.js +28 -0
- package/esm/util/message-builder.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-message-images.test.d.ts","sourceRoot":"","sources":["../../../src/hooks/__tests__/use-message-images.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const react_1 = require("@testing-library/react");
|
|
4
|
+
const use_message_images_1 = require("../use-message-images");
|
|
5
|
+
// Mock crypto.randomUUID
|
|
6
|
+
global.crypto = {
|
|
7
|
+
randomUUID: jest.fn(() => "mock-uuid-" + Math.random()),
|
|
8
|
+
};
|
|
9
|
+
// Mock FileReader
|
|
10
|
+
const mockFileReader = {
|
|
11
|
+
readAsDataURL: jest.fn(),
|
|
12
|
+
onload: null,
|
|
13
|
+
onerror: null,
|
|
14
|
+
result: "data:image/png;base64,mock-data",
|
|
15
|
+
};
|
|
16
|
+
global.FileReader = jest.fn(() => {
|
|
17
|
+
const reader = { ...mockFileReader };
|
|
18
|
+
reader.readAsDataURL = jest.fn(() => {
|
|
19
|
+
setTimeout(() => {
|
|
20
|
+
if (reader.onload) {
|
|
21
|
+
reader.onload({});
|
|
22
|
+
}
|
|
23
|
+
}, 0);
|
|
24
|
+
});
|
|
25
|
+
return reader;
|
|
26
|
+
});
|
|
27
|
+
describe("useMessageImages", () => {
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
jest.clearAllMocks();
|
|
30
|
+
});
|
|
31
|
+
it("should initialize with empty images array", () => {
|
|
32
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_message_images_1.useMessageImages)());
|
|
33
|
+
expect(result.current.images).toEqual([]);
|
|
34
|
+
});
|
|
35
|
+
it("should reject non-image files", async () => {
|
|
36
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_message_images_1.useMessageImages)());
|
|
37
|
+
const mockFile = new File(["test"], "test-document.pdf", {
|
|
38
|
+
type: "application/pdf",
|
|
39
|
+
});
|
|
40
|
+
await expect(result.current.addImage(mockFile)).rejects.toThrow("Only image files are allowed");
|
|
41
|
+
});
|
|
42
|
+
it("should clear all images", () => {
|
|
43
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_message_images_1.useMessageImages)());
|
|
44
|
+
(0, react_1.act)(() => {
|
|
45
|
+
result.current.clearImages();
|
|
46
|
+
});
|
|
47
|
+
expect(result.current.images).toHaveLength(0);
|
|
48
|
+
});
|
|
49
|
+
it("should handle image validation correctly", () => {
|
|
50
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_message_images_1.useMessageImages)());
|
|
51
|
+
// Test that hooks are available
|
|
52
|
+
expect(typeof result.current.addImage).toBe("function");
|
|
53
|
+
expect(typeof result.current.addImages).toBe("function");
|
|
54
|
+
expect(typeof result.current.removeImage).toBe("function");
|
|
55
|
+
expect(typeof result.current.clearImages).toBe("function");
|
|
56
|
+
});
|
|
57
|
+
it("should reject when no valid image files provided to addImages", async () => {
|
|
58
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_message_images_1.useMessageImages)());
|
|
59
|
+
const mockFiles = [
|
|
60
|
+
new File(["test"], "document.pdf", { type: "application/pdf" }),
|
|
61
|
+
new File(["test"], "text.txt", { type: "text/plain" }),
|
|
62
|
+
];
|
|
63
|
+
await expect(result.current.addImages(mockFiles)).rejects.toThrow("No valid image files provided");
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
//# sourceMappingURL=use-message-images.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-message-images.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/use-message-images.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { act, renderHook } from \"@testing-library/react\";\nimport { useMessageImages } from \"../use-message-images\";\n\n// Mock crypto.randomUUID\nglobal.crypto = {\n randomUUID: jest.fn(() => \"mock-uuid-\" + Math.random()),\n} as any;\n\n// Mock FileReader\nconst mockFileReader = {\n readAsDataURL: jest.fn(),\n onload: null as any,\n onerror: null as any,\n result: \"data:image/png;base64,mock-data\",\n};\n\n(global as any).FileReader = jest.fn(() => {\n const reader = { ...mockFileReader };\n reader.readAsDataURL = jest.fn(() => {\n setTimeout(() => {\n if (reader.onload) {\n reader.onload({} as any);\n }\n }, 0);\n });\n return reader;\n});\n\ndescribe(\"useMessageImages\", () => {\n beforeEach(() => {\n jest.clearAllMocks();\n });\n\n it(\"should initialize with empty images array\", () => {\n const { result } = renderHook(() => useMessageImages());\n expect(result.current.images).toEqual([]);\n });\n\n it(\"should reject non-image files\", async () => {\n const { result } = renderHook(() => useMessageImages());\n const mockFile = new File([\"test\"], \"test-document.pdf\", {\n type: \"application/pdf\",\n });\n\n await expect(result.current.addImage(mockFile)).rejects.toThrow(\n \"Only image files are allowed\",\n );\n });\n\n it(\"should clear all images\", () => {\n const { result } = renderHook(() => useMessageImages());\n\n act(() => {\n result.current.clearImages();\n });\n\n expect(result.current.images).toHaveLength(0);\n });\n\n it(\"should handle image validation correctly\", () => {\n const { result } = renderHook(() => useMessageImages());\n\n // Test that hooks are available\n expect(typeof result.current.addImage).toBe(\"function\");\n expect(typeof result.current.addImages).toBe(\"function\");\n expect(typeof result.current.removeImage).toBe(\"function\");\n expect(typeof result.current.clearImages).toBe(\"function\");\n });\n\n it(\"should reject when no valid image files provided to addImages\", async () => {\n const { result } = renderHook(() => useMessageImages());\n const mockFiles = [\n new File([\"test\"], \"document.pdf\", { type: \"application/pdf\" }),\n new File([\"test\"], \"text.txt\", { type: \"text/plain\" }),\n ];\n\n await expect(result.current.addImages(mockFiles)).rejects.toThrow(\n \"No valid image files provided\",\n );\n });\n});\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents an image staged for upload
|
|
3
|
+
*/
|
|
4
|
+
export interface StagedImage {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
dataUrl: string;
|
|
8
|
+
file: File;
|
|
9
|
+
size: number;
|
|
10
|
+
type: string;
|
|
11
|
+
}
|
|
12
|
+
interface UseMessageImagesReturn {
|
|
13
|
+
images: StagedImage[];
|
|
14
|
+
addImage: (file: File) => Promise<void>;
|
|
15
|
+
addImages: (files: File[]) => Promise<void>;
|
|
16
|
+
removeImage: (id: string) => void;
|
|
17
|
+
clearImages: () => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Hook for managing images in message input
|
|
21
|
+
* @returns Object with images array and management functions
|
|
22
|
+
*/
|
|
23
|
+
export declare function useMessageImages(): UseMessageImagesReturn;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=use-message-images.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-message-images.d.ts","sourceRoot":"","sources":["../../src/hooks/use-message-images.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,sBAAsB;IAC9B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,SAAS,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,sBAAsB,CAqEzD"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useMessageImages = useMessageImages;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
/**
|
|
6
|
+
* Hook for managing images in message input
|
|
7
|
+
* @returns Object with images array and management functions
|
|
8
|
+
*/
|
|
9
|
+
function useMessageImages() {
|
|
10
|
+
const [images, setImages] = (0, react_1.useState)([]);
|
|
11
|
+
const fileToDataUrl = async (file) => {
|
|
12
|
+
return await new Promise((resolve, reject) => {
|
|
13
|
+
const reader = new FileReader();
|
|
14
|
+
reader.onload = () => resolve(reader.result);
|
|
15
|
+
reader.onerror = reject;
|
|
16
|
+
reader.readAsDataURL(file);
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
const addImage = (0, react_1.useCallback)(async (file) => {
|
|
20
|
+
if (!file.type.startsWith("image/")) {
|
|
21
|
+
throw new Error("Only image files are allowed");
|
|
22
|
+
}
|
|
23
|
+
const dataUrl = await fileToDataUrl(file);
|
|
24
|
+
const newImage = {
|
|
25
|
+
id: crypto.randomUUID(),
|
|
26
|
+
name: file.name,
|
|
27
|
+
dataUrl,
|
|
28
|
+
file,
|
|
29
|
+
size: file.size,
|
|
30
|
+
type: file.type,
|
|
31
|
+
};
|
|
32
|
+
setImages((prev) => [...prev, newImage]);
|
|
33
|
+
}, []);
|
|
34
|
+
const addImages = (0, react_1.useCallback)(async (files) => {
|
|
35
|
+
const imageFiles = files.filter((file) => file.type.startsWith("image/"));
|
|
36
|
+
if (imageFiles.length === 0) {
|
|
37
|
+
throw new Error("No valid image files provided");
|
|
38
|
+
}
|
|
39
|
+
const newImages = await Promise.all(imageFiles.map(async (file) => {
|
|
40
|
+
const dataUrl = await fileToDataUrl(file);
|
|
41
|
+
return {
|
|
42
|
+
id: crypto.randomUUID(),
|
|
43
|
+
name: file.name,
|
|
44
|
+
dataUrl,
|
|
45
|
+
file,
|
|
46
|
+
size: file.size,
|
|
47
|
+
type: file.type,
|
|
48
|
+
};
|
|
49
|
+
}));
|
|
50
|
+
setImages((prev) => [...prev, ...newImages]);
|
|
51
|
+
}, []);
|
|
52
|
+
const removeImage = (0, react_1.useCallback)((id) => {
|
|
53
|
+
setImages((prev) => prev.filter((img) => img.id !== id));
|
|
54
|
+
}, []);
|
|
55
|
+
const clearImages = (0, react_1.useCallback)(() => {
|
|
56
|
+
setImages([]);
|
|
57
|
+
}, []);
|
|
58
|
+
return {
|
|
59
|
+
images,
|
|
60
|
+
addImage,
|
|
61
|
+
addImages,
|
|
62
|
+
removeImage,
|
|
63
|
+
clearImages,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=use-message-images.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-message-images.js","sourceRoot":"","sources":["../../src/hooks/use-message-images.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useState } from \"react\";\n\n/**\n * Represents an image staged for upload\n */\nexport interface StagedImage {\n id: string;\n name: string;\n dataUrl: string;\n file: File;\n size: number;\n type: string;\n}\n\ninterface UseMessageImagesReturn {\n images: StagedImage[];\n addImage: (file: File) => Promise<void>;\n addImages: (files: File[]) => Promise<void>;\n removeImage: (id: string) => void;\n clearImages: () => void;\n}\n\n/**\n * Hook for managing images in message input\n * @returns Object with images array and management functions\n */\nexport function useMessageImages(): UseMessageImagesReturn {\n const [images, setImages] = useState<StagedImage[]>([]);\n\n const fileToDataUrl = async (file: File): Promise<string> => {\n return await new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n };\n\n const addImage = useCallback(async (file: File) => {\n if (!file.type.startsWith(\"image/\")) {\n throw new Error(\"Only image files are allowed\");\n }\n\n const dataUrl = await fileToDataUrl(file);\n const newImage: StagedImage = {\n id: crypto.randomUUID(),\n name: file.name,\n dataUrl,\n file,\n size: file.size,\n type: file.type,\n };\n\n setImages((prev) => [...prev, newImage]);\n }, []);\n\n const addImages = useCallback(async (files: File[]) => {\n const imageFiles = files.filter((file) => file.type.startsWith(\"image/\"));\n\n if (imageFiles.length === 0) {\n throw new Error(\"No valid image files provided\");\n }\n\n const newImages = await Promise.all(\n imageFiles.map(async (file) => {\n const dataUrl = await fileToDataUrl(file);\n return {\n id: crypto.randomUUID(),\n name: file.name,\n dataUrl,\n file,\n size: file.size,\n type: file.type,\n };\n }),\n );\n\n setImages((prev) => [...prev, ...newImages]);\n }, []);\n\n const removeImage = useCallback((id: string) => {\n setImages((prev) => prev.filter((img) => img.id !== id));\n }, []);\n\n const clearImages = useCallback(() => {\n setImages([]);\n }, []);\n\n return {\n images,\n addImage,\n addImages,\n removeImage,\n clearImages,\n };\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, } from "./hooks/use-current-message";
|
|
4
|
+
export { useMessageImages, type StagedImage } from "./hooks/use-message-images";
|
|
4
5
|
export { useTamboStreamingProps } from "./hooks/use-streaming-props";
|
|
5
6
|
export * from "./hooks/use-suggestions";
|
|
6
7
|
export { useTamboStreamStatus, type PropStatus, type StreamStatus, } from "./hooks/use-tambo-stream-status";
|
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;AAExK,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,cAAc,yBAAyB,CAAC;AACxC,OAAO,EACL,oBAAoB,EACpB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,2BAA2B,EAC3B,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,EACnB,uBAAuB,EACvB,QAAQ,EACR,cAAc,EACd,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,KAAK,cAAc,EACnB,KAAK,+BAA+B,EACpC,KAAK,gCAAgC,EACrC,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,GAClC,MAAM,aAAa,CAAC;AAGrB,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,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,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;AAExD,YAAY,EACV,0BAA0B,IAAI,qBAAqB,EACnD,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,qBAAqB,IAAI,gBAAgB,EACzC,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,GAChC,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,oBAAoB,EACpB,+BAA+B,GAChC,MAAM,yCAAyC,CAAC;AAGjD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,cAAc,GACf,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wKAAwK;AAExK,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,cAAc,yBAAyB,CAAC;AACxC,OAAO,EACL,oBAAoB,EACpB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,2BAA2B,EAC3B,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,EACnB,uBAAuB,EACvB,QAAQ,EACR,cAAc,EACd,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,KAAK,cAAc,EACnB,KAAK,+BAA+B,EACpC,KAAK,gCAAgC,EACrC,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,GAClC,MAAM,aAAa,CAAC;AAGrB,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,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,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;AAExD,YAAY,EACV,0BAA0B,IAAI,qBAAqB,EACnD,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,qBAAqB,IAAI,gBAAgB,EACzC,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,GAChC,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,oBAAoB,EACpB,+BAA+B,GAChC,MAAM,yCAAyC,CAAC;AAGjD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,cAAc,GACf,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -15,12 +15,14 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
16
16
|
};
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.currentTimeContextHelper = exports.currentPageContextHelper = exports.useCurrentInteractablesSnapshot = exports.useTamboInteractable = exports.withInteractable = exports.GenerationStage = exports.useTamboThreadList = exports.useTamboThreadInput = exports.useTamboThread = exports.useTamboStream = exports.useTamboGenerationStage = exports.useTamboContextHelpers = exports.useTamboClient = exports.useTambo = exports.useIsTamboTokenUpdating = exports.TamboThreadProvider = exports.TamboThreadInputProvider = exports.TamboStubProvider = exports.TamboProvider = exports.TamboPropStreamProvider = exports.TamboContextHelpersProvider = exports.TamboComponentProvider = exports.TamboClientProvider = exports.useTamboStreamStatus = exports.useTamboStreamingProps = exports.useTamboCurrentMessage = exports.TamboMessageProvider = exports.useTamboComponentState = void 0;
|
|
18
|
+
exports.currentTimeContextHelper = exports.currentPageContextHelper = exports.useCurrentInteractablesSnapshot = exports.useTamboInteractable = exports.withInteractable = exports.GenerationStage = exports.useTamboThreadList = exports.useTamboThreadInput = exports.useTamboThread = exports.useTamboStream = exports.useTamboGenerationStage = exports.useTamboContextHelpers = exports.useTamboClient = exports.useTambo = exports.useIsTamboTokenUpdating = exports.TamboThreadProvider = exports.TamboThreadInputProvider = exports.TamboStubProvider = exports.TamboProvider = exports.TamboPropStreamProvider = exports.TamboContextHelpersProvider = exports.TamboComponentProvider = exports.TamboClientProvider = exports.useTamboStreamStatus = exports.useTamboStreamingProps = exports.useMessageImages = exports.useTamboCurrentMessage = exports.TamboMessageProvider = exports.useTamboComponentState = void 0;
|
|
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; } });
|
|
21
21
|
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
|
+
var use_message_images_1 = require("./hooks/use-message-images");
|
|
25
|
+
Object.defineProperty(exports, "useMessageImages", { enumerable: true, get: function () { return use_message_images_1.useMessageImages; } });
|
|
24
26
|
var use_streaming_props_1 = require("./hooks/use-streaming-props");
|
|
25
27
|
Object.defineProperty(exports, "useTamboStreamingProps", { enumerable: true, get: function () { return use_streaming_props_1.useTamboStreamingProps; } });
|
|
26
28
|
__exportStar(require("./hooks/use-suggestions"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,wKAAwK;;;;;;;;;;;;;;;;;AAExK,mEAAqE;AAA5D,6HAAA,sBAAsB,OAAA;AAC/B,mEAGqC;AAFnC,2HAAA,oBAAoB,OAAA;AACpB,6HAAA,sBAAsB,OAAA;AAExB,mEAAqE;AAA5D,6HAAA,sBAAsB,OAAA;AAC/B,0DAAwC;AACxC,2EAIyC;AAHvC,+HAAA,oBAAoB,OAAA;AAKtB,gCAAgC;AAChC,yCAuBqB;AAtBnB,gHAAA,mBAAmB,OAAA;AACnB,mHAAA,sBAAsB,OAAA;AACtB,wHAAA,2BAA2B,OAAA;AAC3B,oHAAA,uBAAuB,OAAA;AACvB,0GAAA,aAAa,OAAA;AACb,8GAAA,iBAAiB,OAAA;AACjB,qHAAA,wBAAwB,OAAA;AACxB,gHAAA,mBAAmB,OAAA;AACnB,oHAAA,uBAAuB,OAAA;AACvB,qGAAA,QAAQ,OAAA;AACR,2GAAA,cAAc,OAAA;AACd,mHAAA,sBAAsB,OAAA;AACtB,oHAAA,uBAAuB,OAAA;AACvB,2GAAA,cAAc,OAAA;AACd,2GAAA,cAAc,OAAA;AACd,gHAAA,mBAAmB,OAAA;AAqBrB,+DAA+D;AAAtD,uHAAA,kBAAkB,OAAA;AAQ3B,mFAG6C;AAF3C,8HAAA,eAAe,OAAA;AASjB,mFAIiD;AAH/C,2HAAA,qBAAqB,OAAoB;AAI3C,uFAGiD;AAF/C,mIAAA,oBAAoB,OAAA;AACpB,8IAAA,+BAA+B,OAAA;AAGjC,0BAA0B;AAC1B,qDAG2B;AAFzB,2HAAA,wBAAwB,OAAA;AACxB,2HAAA,wBAAwB,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. */\n\nexport { useTamboComponentState } from \"./hooks/use-component-state\";\nexport {\n TamboMessageProvider,\n useTamboCurrentMessage,\n} from \"./hooks/use-current-message\";\nexport { useTamboStreamingProps } from \"./hooks/use-streaming-props\";\nexport * from \"./hooks/use-suggestions\";\nexport {\n useTamboStreamStatus,\n type PropStatus,\n type StreamStatus,\n} from \"./hooks/use-tambo-stream-status\";\n\n// Re-export provider components\nexport {\n TamboClientProvider,\n TamboComponentProvider,\n TamboContextHelpersProvider,\n TamboPropStreamProvider,\n TamboProvider,\n TamboStubProvider,\n TamboThreadInputProvider,\n TamboThreadProvider,\n useIsTamboTokenUpdating,\n useTambo,\n useTamboClient,\n useTamboContextHelpers,\n useTamboGenerationStage,\n useTamboStream,\n useTamboThread,\n useTamboThreadInput,\n type TamboComponent,\n type TamboContextHelpersContextProps,\n type TamboContextHelpersProviderProps,\n type TamboRegistryContext,\n type TamboStubProviderProps,\n type TamboThreadInputContextProps,\n} 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 { useTamboThreadList } 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\nexport type {\n TamboInteractableComponent as InteractableComponent,\n TamboInteractableContext,\n} from \"./model/tambo-interactable\";\nexport {\n withTamboInteractable as withInteractable,\n type InteractableConfig,\n type WithTamboInteractableProps,\n} from \"./providers/hoc/with-tambo-interactable\";\nexport {\n useTamboInteractable,\n useCurrentInteractablesSnapshot,\n} from \"./providers/tambo-interactable-provider\";\n\n// Context helpers exports\nexport {\n currentPageContextHelper,\n currentTimeContextHelper,\n} from \"./context-helpers\";\nexport type {\n AdditionalContext,\n ContextHelperFn,\n ContextHelpers,\n} from \"./context-helpers\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,wKAAwK;;;;;;;;;;;;;;;;;AAExK,mEAAqE;AAA5D,6HAAA,sBAAsB,OAAA;AAC/B,mEAGqC;AAFnC,2HAAA,oBAAoB,OAAA;AACpB,6HAAA,sBAAsB,OAAA;AAExB,iEAAgF;AAAvE,sHAAA,gBAAgB,OAAA;AACzB,mEAAqE;AAA5D,6HAAA,sBAAsB,OAAA;AAC/B,0DAAwC;AACxC,2EAIyC;AAHvC,+HAAA,oBAAoB,OAAA;AAKtB,gCAAgC;AAChC,yCAuBqB;AAtBnB,gHAAA,mBAAmB,OAAA;AACnB,mHAAA,sBAAsB,OAAA;AACtB,wHAAA,2BAA2B,OAAA;AAC3B,oHAAA,uBAAuB,OAAA;AACvB,0GAAA,aAAa,OAAA;AACb,8GAAA,iBAAiB,OAAA;AACjB,qHAAA,wBAAwB,OAAA;AACxB,gHAAA,mBAAmB,OAAA;AACnB,oHAAA,uBAAuB,OAAA;AACvB,qGAAA,QAAQ,OAAA;AACR,2GAAA,cAAc,OAAA;AACd,mHAAA,sBAAsB,OAAA;AACtB,oHAAA,uBAAuB,OAAA;AACvB,2GAAA,cAAc,OAAA;AACd,2GAAA,cAAc,OAAA;AACd,gHAAA,mBAAmB,OAAA;AAqBrB,+DAA+D;AAAtD,uHAAA,kBAAkB,OAAA;AAQ3B,mFAG6C;AAF3C,8HAAA,eAAe,OAAA;AASjB,mFAIiD;AAH/C,2HAAA,qBAAqB,OAAoB;AAI3C,uFAGiD;AAF/C,mIAAA,oBAAoB,OAAA;AACpB,8IAAA,+BAA+B,OAAA;AAGjC,0BAA0B;AAC1B,qDAG2B;AAFzB,2HAAA,wBAAwB,OAAA;AACxB,2HAAA,wBAAwB,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. */\n\nexport { useTamboComponentState } from \"./hooks/use-component-state\";\nexport {\n TamboMessageProvider,\n useTamboCurrentMessage,\n} from \"./hooks/use-current-message\";\nexport { useMessageImages, type StagedImage } from \"./hooks/use-message-images\";\nexport { useTamboStreamingProps } from \"./hooks/use-streaming-props\";\nexport * from \"./hooks/use-suggestions\";\nexport {\n useTamboStreamStatus,\n type PropStatus,\n type StreamStatus,\n} from \"./hooks/use-tambo-stream-status\";\n\n// Re-export provider components\nexport {\n TamboClientProvider,\n TamboComponentProvider,\n TamboContextHelpersProvider,\n TamboPropStreamProvider,\n TamboProvider,\n TamboStubProvider,\n TamboThreadInputProvider,\n TamboThreadProvider,\n useIsTamboTokenUpdating,\n useTambo,\n useTamboClient,\n useTamboContextHelpers,\n useTamboGenerationStage,\n useTamboStream,\n useTamboThread,\n useTamboThreadInput,\n type TamboComponent,\n type TamboContextHelpersContextProps,\n type TamboContextHelpersProviderProps,\n type TamboRegistryContext,\n type TamboStubProviderProps,\n type TamboThreadInputContextProps,\n} 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 { useTamboThreadList } 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\nexport type {\n TamboInteractableComponent as InteractableComponent,\n TamboInteractableContext,\n} from \"./model/tambo-interactable\";\nexport {\n withTamboInteractable as withInteractable,\n type InteractableConfig,\n type WithTamboInteractableProps,\n} from \"./providers/hoc/with-tambo-interactable\";\nexport {\n useTamboInteractable,\n useCurrentInteractablesSnapshot,\n} from \"./providers/tambo-interactable-provider\";\n\n// Context helpers exports\nexport {\n currentPageContextHelper,\n currentTimeContextHelper,\n} from \"./context-helpers\";\nexport type {\n AdditionalContext,\n ContextHelperFn,\n ContextHelpers,\n} from \"./context-helpers\";\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { PropsWithChildren } from "react";
|
|
2
2
|
import { UseTamboMutationResult } from "../hooks/react-query-hooks";
|
|
3
|
+
import { StagedImage } from "../hooks/use-message-images";
|
|
3
4
|
/**
|
|
4
5
|
* Error messages for various input-related error scenarios
|
|
5
6
|
* These messages are used to provide user-friendly error feedback
|
|
@@ -34,6 +35,16 @@ export interface TamboThreadInputContextProps extends Omit<UseTamboMutationResul
|
|
|
34
35
|
forceToolChoice?: string;
|
|
35
36
|
additionalContext?: Record<string, any>;
|
|
36
37
|
}) => Promise<void>;
|
|
38
|
+
/** Currently staged images */
|
|
39
|
+
images: StagedImage[];
|
|
40
|
+
/** Add a single image */
|
|
41
|
+
addImage: (file: File) => Promise<void>;
|
|
42
|
+
/** Add multiple images */
|
|
43
|
+
addImages: (files: File[]) => Promise<void>;
|
|
44
|
+
/** Remove an image by id */
|
|
45
|
+
removeImage: (id: string) => void;
|
|
46
|
+
/** Clear all staged images */
|
|
47
|
+
clearImages: () => void;
|
|
37
48
|
}
|
|
38
49
|
export declare const TamboThreadInputContext: React.Context<TamboThreadInputContextProps | undefined>;
|
|
39
50
|
export interface TamboThreadInputProviderProps {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-thread-input-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-thread-input-provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAIlB,MAAM,OAAO,CAAC;AACf,OAAO,EAEL,sBAAsB,EACvB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"tambo-thread-input-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-thread-input-provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAIlB,MAAM,OAAO,CAAC;AACf,OAAO,EAEL,sBAAsB,EACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAoB,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAM5E;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;CAKvB,CAAC;AAEX,MAAM,WAAW,4BACf,SAAQ,IAAI,CACV,sBAAsB,CACpB,IAAI,EACJ,KAAK,EACH;IACE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACzC,GACD,SAAS,EACX,OAAO,CACR,EACD,QAAQ,GAAG,aAAa,CACzB;IACD,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;OAGG;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;IACpB,8BAA8B;IAC9B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,yBAAyB;IACzB,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,0BAA0B;IAC1B,SAAS,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,4BAA4B;IAC5B,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,8BAA8B;IAC9B,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,eAAO,MAAM,uBAAuB,yDAExB,CAAC;AAEb,MAAM,WAAW,6BAA6B;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,EAAE,KAAK,CAAC,EAAE,CAC7C,iBAAiB,CAAC,6BAA6B,CAAC,CAuIjD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,oCAS/B,CAAC"}
|
|
@@ -37,8 +37,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
37
37
|
exports.useTamboThreadInput = exports.TamboThreadInputProvider = exports.TamboThreadInputContext = exports.INPUT_ERROR_MESSAGES = void 0;
|
|
38
38
|
const react_1 = __importStar(require("react"));
|
|
39
39
|
const react_query_hooks_1 = require("../hooks/react-query-hooks");
|
|
40
|
+
const use_message_images_1 = require("../hooks/use-message-images");
|
|
40
41
|
const thread_input_error_1 = require("../model/thread-input-error");
|
|
41
42
|
const validate_input_1 = require("../model/validate-input");
|
|
43
|
+
const message_builder_1 = require("../util/message-builder");
|
|
42
44
|
const tambo_thread_provider_1 = require("./tambo-thread-provider");
|
|
43
45
|
/**
|
|
44
46
|
* Error messages for various input-related error scenarios
|
|
@@ -64,20 +66,64 @@ exports.TamboThreadInputContext = (0, react_1.createContext)(undefined);
|
|
|
64
66
|
const TamboThreadInputProvider = ({ children, contextKey }) => {
|
|
65
67
|
const { thread, sendThreadMessage } = (0, tambo_thread_provider_1.useTamboThread)();
|
|
66
68
|
const [inputValue, setInputValue] = (0, react_1.useState)("");
|
|
69
|
+
const imageState = (0, use_message_images_1.useMessageImages)();
|
|
67
70
|
const submit = (0, react_1.useCallback)(async ({ contextKey: submitContextKey, streamResponse, forceToolChoice, additionalContext, } = {}) => {
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
+
// Validate text input if present
|
|
72
|
+
if (inputValue?.trim()) {
|
|
73
|
+
const validation = (0, validate_input_1.validateInput)(inputValue);
|
|
74
|
+
if (!validation.isValid) {
|
|
75
|
+
throw new thread_input_error_1.ThreadInputError(`Cannot submit message: ${validation.error ?? exports.INPUT_ERROR_MESSAGES.VALIDATION}`, { cause: validation.error });
|
|
76
|
+
}
|
|
71
77
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
// Check if we have content to send
|
|
79
|
+
if (!inputValue.trim() && imageState.images.length === 0) {
|
|
80
|
+
throw new thread_input_error_1.ThreadInputError(exports.INPUT_ERROR_MESSAGES.EMPTY, {
|
|
81
|
+
cause: "No text or images to send",
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// Build message content with text and images
|
|
85
|
+
const messageContent = (0, message_builder_1.buildMessageContent)(inputValue, imageState.images);
|
|
86
|
+
try {
|
|
87
|
+
await sendThreadMessage(inputValue || "Image message", {
|
|
88
|
+
threadId: thread.id,
|
|
89
|
+
contextKey: submitContextKey ?? contextKey ?? undefined,
|
|
90
|
+
streamResponse: streamResponse,
|
|
91
|
+
forceToolChoice: forceToolChoice,
|
|
92
|
+
additionalContext: additionalContext,
|
|
93
|
+
content: messageContent,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
// Handle image-related errors with friendly messages
|
|
98
|
+
if (imageState.images.length > 0) {
|
|
99
|
+
const errorMessage = error?.message?.toLowerCase() ?? "";
|
|
100
|
+
// Backend not yet supporting image content type
|
|
101
|
+
if (errorMessage.includes("unknown content part type: image")) {
|
|
102
|
+
throw new thread_input_error_1.ThreadInputError("Image attachments are not yet supported by the backend. This feature is coming soon.", { cause: error });
|
|
103
|
+
}
|
|
104
|
+
// Handle specific model vision support errors
|
|
105
|
+
// OpenAI errors
|
|
106
|
+
if (errorMessage.includes("does not support image message content types") ||
|
|
107
|
+
(errorMessage.includes("invalid model") &&
|
|
108
|
+
errorMessage.includes("image_url is only supported by certain models"))) {
|
|
109
|
+
throw new thread_input_error_1.ThreadInputError("This model doesn't support images. Please use GPT-4o, GPT-4 Turbo, or other vision-capable models.", { cause: error });
|
|
110
|
+
}
|
|
111
|
+
// Anthropic Claude errors
|
|
112
|
+
if (errorMessage.includes("does not support image") ||
|
|
113
|
+
errorMessage.includes("vision not supported")) {
|
|
114
|
+
throw new thread_input_error_1.ThreadInputError("This Claude model doesn't support images. Please use Claude 3.5 Sonnet, Claude 3 Opus, or other vision-capable models.", { cause: error });
|
|
115
|
+
}
|
|
116
|
+
// Generic image/vision errors
|
|
117
|
+
if (errorMessage.includes("image") ||
|
|
118
|
+
errorMessage.includes("vision")) {
|
|
119
|
+
throw new thread_input_error_1.ThreadInputError("This model doesn't support image attachments. Please use a vision-capable model.", { cause: error });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
// Clear text after successful submission
|
|
125
|
+
setInputValue("");
|
|
126
|
+
}, [inputValue, sendThreadMessage, thread.id, contextKey, imageState]);
|
|
81
127
|
const { mutateAsync: submitAsync, mutate: _unusedSubmit, ...mutationState } = (0, react_query_hooks_1.useTamboMutation)({
|
|
82
128
|
mutationFn: submit,
|
|
83
129
|
});
|
|
@@ -86,6 +132,11 @@ const TamboThreadInputProvider = ({ children, contextKey }) => {
|
|
|
86
132
|
value: inputValue,
|
|
87
133
|
setValue: setInputValue,
|
|
88
134
|
submit: submitAsync,
|
|
135
|
+
images: imageState.images,
|
|
136
|
+
addImage: imageState.addImage,
|
|
137
|
+
addImages: imageState.addImages,
|
|
138
|
+
removeImage: imageState.removeImage,
|
|
139
|
+
clearImages: imageState.clearImages,
|
|
89
140
|
};
|
|
90
141
|
return (react_1.default.createElement(exports.TamboThreadInputContext.Provider, { value: value }, children));
|
|
91
142
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-thread-input-provider.js","sourceRoot":"","sources":["../../src/providers/tambo-thread-input-provider.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACb,+CAMe;AACf,kEAGoC;AACpC,oEAA+D;AAC/D,4DAAwD;AACxD,mEAAyD;AAEzD;;;;GAIG;AACU,QAAA,oBAAoB,GAAG;IAClC,KAAK,EAAE,yBAAyB;IAChC,OAAO,EAAE,6CAA6C;IACtD,MAAM,EAAE,gCAAgC;IACxC,UAAU,EAAE,wBAAwB;CAC5B,CAAC;AAqCE,QAAA,uBAAuB,GAAG,IAAA,qBAAa,EAElD,SAAS,CAAC,CAAC;AAMb;;;;;;;;GAQG;AACI,MAAM,wBAAwB,GAEjC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;IAC/B,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAA,sCAAc,GAAE,CAAC;IACvD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,IAAA,gBAAQ,EAAC,EAAE,CAAC,CAAC;IAEjD,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,CAAC,oBAAoB;IACzC,CAAC,EACD,CAAC,UAAU,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,CACvD,CAAC;IAEF,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,MAAM,KAAK,GAAG;QACZ,GAAG,aAAa;QAChB,KAAK,EAAE,UAAU;QACjB,QAAQ,EAAE,aAAa;QACvB,MAAM,EAAE,WAAW;KACpB,CAAC;IAEF,OAAO,CACL,8BAAC,+BAAuB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,IAC3C,QAAQ,CACwB,CACpC,CAAC;AACJ,CAAC,CAAC;AA1DW,QAAA,wBAAwB,4BA0DnC;AAEF;;;;GAIG;AACI,MAAM,mBAAmB,GAAG,GAAG,EAAE;IACtC,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,+BAAuB,CAAC,CAAC;IACpD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AATW,QAAA,mBAAmB,uBAS9B","sourcesContent":["\"use client\";\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useState,\n} from \"react\";\nimport {\n useTamboMutation,\n UseTamboMutationResult,\n} from \"../hooks/react-query-hooks\";\nimport { ThreadInputError } from \"../model/thread-input-error\";\nimport { validateInput } from \"../model/validate-input\";\nimport { useTamboThread } from \"./tambo-thread-provider\";\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 EMPTY: \"Message cannot be empty\",\n NETWORK: \"Network error. Please check your connection\",\n SERVER: \"Server error. Please try again\",\n VALIDATION: \"Invalid message format\",\n} as const;\n\nexport interface TamboThreadInputContextProps\n extends Omit<\n UseTamboMutationResult<\n void,\n Error,\n | {\n contextKey?: string;\n streamResponse?: boolean;\n forceToolChoice?: string;\n additionalContext?: Record<string, any>;\n }\n | undefined,\n unknown\n >,\n \"mutate\" | \"mutateAsync\"\n > {\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 * @param options - Submission options\n */\n submit: (options?: {\n contextKey?: string;\n streamResponse?: boolean;\n forceToolChoice?: string;\n additionalContext?: Record<string, any>;\n }) => Promise<void>;\n}\n\nexport const TamboThreadInputContext = createContext<\n TamboThreadInputContextProps | undefined\n>(undefined);\n\nexport interface TamboThreadInputProviderProps {\n contextKey?: string;\n}\n\n/**\n * Provider that manages shared thread input state across all components\n * This ensures that useTamboThreadInput, useTamboSuggestions, and components\n * all share the same input state\n * @param props - The props for the TamboThreadInputProvider\n * @param props.contextKey - Optional context key.\n * @param props.children - The children to render.\n * @returns The thread input context\n */\nexport const TamboThreadInputProvider: React.FC<\n PropsWithChildren<TamboThreadInputProviderProps>\n> = ({ children, contextKey }) => {\n const { thread, sendThreadMessage } = useTamboThread();\n const [inputValue, setInputValue] = useState(\"\");\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(\"\"); // Clear local state\n },\n [inputValue, sendThreadMessage, thread.id, contextKey],\n );\n\n const {\n mutateAsync: submitAsync,\n mutate: _unusedSubmit,\n ...mutationState\n } = useTamboMutation({\n mutationFn: submit,\n });\n\n const value = {\n ...mutationState,\n value: inputValue,\n setValue: setInputValue,\n submit: submitAsync,\n };\n\n return (\n <TamboThreadInputContext.Provider value={value}>\n {children}\n </TamboThreadInputContext.Provider>\n );\n};\n\n/**\n * Hook to access the shared thread input state\n * contextKey parameter is not passed here anymore. Instead, use the contextKey prop in the TamboProvider.\n * @returns The thread input context\n */\nexport const useTamboThreadInput = () => {\n const context = useContext(TamboThreadInputContext);\n if (!context) {\n throw new Error(\n \"useTamboThreadInput must be used within a TamboThreadInputProvider\",\n );\n }\n\n return context;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"tambo-thread-input-provider.js","sourceRoot":"","sources":["../../src/providers/tambo-thread-input-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useState,\n} from \"react\";\nimport {\n useTamboMutation,\n UseTamboMutationResult,\n} from \"../hooks/react-query-hooks\";\nimport { useMessageImages, StagedImage } from \"../hooks/use-message-images\";\nimport { ThreadInputError } from \"../model/thread-input-error\";\nimport { validateInput } from \"../model/validate-input\";\nimport { buildMessageContent } from \"../util/message-builder\";\nimport { useTamboThread } from \"./tambo-thread-provider\";\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 EMPTY: \"Message cannot be empty\",\n NETWORK: \"Network error. Please check your connection\",\n SERVER: \"Server error. Please try again\",\n VALIDATION: \"Invalid message format\",\n} as const;\n\nexport interface TamboThreadInputContextProps\n extends Omit<\n UseTamboMutationResult<\n void,\n Error,\n | {\n contextKey?: string;\n streamResponse?: boolean;\n forceToolChoice?: string;\n additionalContext?: Record<string, any>;\n }\n | undefined,\n unknown\n >,\n \"mutate\" | \"mutateAsync\"\n > {\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 * @param options - Submission options\n */\n submit: (options?: {\n contextKey?: string;\n streamResponse?: boolean;\n forceToolChoice?: string;\n additionalContext?: Record<string, any>;\n }) => Promise<void>;\n /** Currently staged images */\n images: StagedImage[];\n /** Add a single image */\n addImage: (file: File) => Promise<void>;\n /** Add multiple images */\n addImages: (files: File[]) => Promise<void>;\n /** Remove an image by id */\n removeImage: (id: string) => void;\n /** Clear all staged images */\n clearImages: () => void;\n}\n\nexport const TamboThreadInputContext = createContext<\n TamboThreadInputContextProps | undefined\n>(undefined);\n\nexport interface TamboThreadInputProviderProps {\n contextKey?: string;\n}\n\n/**\n * Provider that manages shared thread input state across all components\n * This ensures that useTamboThreadInput, useTamboSuggestions, and components\n * all share the same input state\n * @param props - The props for the TamboThreadInputProvider\n * @param props.contextKey - Optional context key.\n * @param props.children - The children to render.\n * @returns The thread input context\n */\nexport const TamboThreadInputProvider: React.FC<\n PropsWithChildren<TamboThreadInputProviderProps>\n> = ({ children, contextKey }) => {\n const { thread, sendThreadMessage } = useTamboThread();\n const [inputValue, setInputValue] = useState(\"\");\n const imageState = useMessageImages();\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 // Validate text input if present\n if (inputValue?.trim()) {\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\n // Check if we have content to send\n if (!inputValue.trim() && imageState.images.length === 0) {\n throw new ThreadInputError(INPUT_ERROR_MESSAGES.EMPTY, {\n cause: \"No text or images to send\",\n });\n }\n\n // Build message content with text and images\n const messageContent = buildMessageContent(inputValue, imageState.images);\n\n try {\n await sendThreadMessage(inputValue || \"Image message\", {\n threadId: thread.id,\n contextKey: submitContextKey ?? contextKey ?? undefined,\n streamResponse: streamResponse,\n forceToolChoice: forceToolChoice,\n additionalContext: additionalContext,\n content: messageContent,\n });\n } catch (error: any) {\n // Handle image-related errors with friendly messages\n if (imageState.images.length > 0) {\n const errorMessage = error?.message?.toLowerCase() ?? \"\";\n\n // Backend not yet supporting image content type\n if (errorMessage.includes(\"unknown content part type: image\")) {\n throw new ThreadInputError(\n \"Image attachments are not yet supported by the backend. This feature is coming soon.\",\n { cause: error },\n );\n }\n\n // Handle specific model vision support errors\n // OpenAI errors\n if (\n errorMessage.includes(\n \"does not support image message content types\",\n ) ||\n (errorMessage.includes(\"invalid model\") &&\n errorMessage.includes(\n \"image_url is only supported by certain models\",\n ))\n ) {\n throw new ThreadInputError(\n \"This model doesn't support images. Please use GPT-4o, GPT-4 Turbo, or other vision-capable models.\",\n { cause: error },\n );\n }\n\n // Anthropic Claude errors\n if (\n errorMessage.includes(\"does not support image\") ||\n errorMessage.includes(\"vision not supported\")\n ) {\n throw new ThreadInputError(\n \"This Claude model doesn't support images. Please use Claude 3.5 Sonnet, Claude 3 Opus, or other vision-capable models.\",\n { cause: error },\n );\n }\n\n // Generic image/vision errors\n if (\n errorMessage.includes(\"image\") ||\n errorMessage.includes(\"vision\")\n ) {\n throw new ThreadInputError(\n \"This model doesn't support image attachments. Please use a vision-capable model.\",\n { cause: error },\n );\n }\n }\n\n throw error;\n }\n\n // Clear text after successful submission\n setInputValue(\"\");\n },\n [inputValue, sendThreadMessage, thread.id, contextKey, imageState],\n );\n\n const {\n mutateAsync: submitAsync,\n mutate: _unusedSubmit,\n ...mutationState\n } = useTamboMutation({\n mutationFn: submit,\n });\n\n const value = {\n ...mutationState,\n value: inputValue,\n setValue: setInputValue,\n submit: submitAsync,\n images: imageState.images,\n addImage: imageState.addImage,\n addImages: imageState.addImages,\n removeImage: imageState.removeImage,\n clearImages: imageState.clearImages,\n };\n\n return (\n <TamboThreadInputContext.Provider value={value}>\n {children}\n </TamboThreadInputContext.Provider>\n );\n};\n\n/**\n * Hook to access the shared thread input state\n * contextKey parameter is not passed here anymore. Instead, use the contextKey prop in the TamboProvider.\n * @returns The thread input context\n */\nexport const useTamboThreadInput = () => {\n const context = useContext(TamboThreadInputContext);\n if (!context) {\n throw new Error(\n \"useTamboThreadInput must be used within a TamboThreadInputProvider\",\n );\n }\n\n return context;\n};\n"]}
|
|
@@ -51,6 +51,7 @@ export interface TamboThreadContextProps {
|
|
|
51
51
|
contextKey?: string;
|
|
52
52
|
forceToolChoice?: string;
|
|
53
53
|
additionalContext?: Record<string, any>;
|
|
54
|
+
content?: TamboAI.Beta.Threads.ChatCompletionContentPart[];
|
|
54
55
|
}) => Promise<TamboThreadMessage>;
|
|
55
56
|
}
|
|
56
57
|
export interface CombinedTamboThreadContextProps extends TamboThreadContextProps, TamboGenerationStageContextProps {
|
|
@@ -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,EAAE,MAAM,EAAE,MAAM,yDAAyD,CAAC;AACjF,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAOlB,MAAM,OAAO,CAAC;AACf,OAAO,EACL,eAAe,EAEf,kBAAkB,EACnB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAapD,MAAM,WAAW,gCAAgC;IAC/C,eAAe,EAAE,eAAe,CAAC;IACjC,uBAAuB,EAAE,MAAM,CAAC;IAChC,MAAM,EAAE,OAAO,CAAC;CACjB;AAMD,UAAU,iCAAiC;IACzC,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,EAAE,KAAK,CAAC,EAAE,CACjD,iBAAiB,CAAC,iCAAiC,CAAC,CAiBrD,CAAC;AAGF,KAAK,qCAAqC,GAAG,OAAO,CAAC,kBAAkB,CAAC,GAAG;IACzE,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,yBAAyB;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,mCAAmC;IACnC,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACjE,yBAAyB;IACzB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,6BAA6B;IAC7B,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,gFAAgF;IAChF,kBAAkB,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3D,0CAA0C;IAC1C,gBAAgB,EAAE,CAChB,OAAO,EAAE,kBAAkB,EAC3B,YAAY,EAAE,OAAO,KAClB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACnD,6CAA6C;IAC7C,mBAAmB,EAAE,CACnB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,qCAAqC,EAC9C,YAAY,EAAE,OAAO,KAClB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,sBAAsB;IACtB,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,sCAAsC;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,2CAA2C;IAC3C,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;QACpB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"tambo-thread-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-thread-provider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -532,7 +532,7 @@ const TamboThreadProvider = ({ children, streaming = true }) => {
|
|
|
532
532
|
]);
|
|
533
533
|
const sendThreadMessage = (0, react_1.useCallback)(async (message, options = {}) => {
|
|
534
534
|
setIgnoreResponse(false);
|
|
535
|
-
const { threadId = currentThreadId ?? exports.PLACEHOLDER_THREAD.id, streamResponse = streaming, forceToolChoice, contextKey, additionalContext, } = options;
|
|
535
|
+
const { threadId = currentThreadId ?? exports.PLACEHOLDER_THREAD.id, streamResponse = streaming, forceToolChoice, contextKey, additionalContext, content, } = options;
|
|
536
536
|
updateThreadStatus(threadId, generate_component_response_1.GenerationStage.FETCHING_CONTEXT);
|
|
537
537
|
// Get additional context from enabled helpers
|
|
538
538
|
const helperContexts = await getAdditionalContext();
|
|
@@ -544,8 +544,12 @@ const TamboThreadProvider = ({ children, streaming = true }) => {
|
|
|
544
544
|
for (const helperContext of helperContexts) {
|
|
545
545
|
combinedContext[helperContext.name] = helperContext.context;
|
|
546
546
|
}
|
|
547
|
+
// Use provided content or build simple text message
|
|
548
|
+
const messageContent = content ?? [
|
|
549
|
+
{ type: "text", text: message },
|
|
550
|
+
];
|
|
547
551
|
addThreadMessage({
|
|
548
|
-
content:
|
|
552
|
+
content: messageContent,
|
|
549
553
|
renderedComponent: null,
|
|
550
554
|
role: "user",
|
|
551
555
|
threadId: threadId,
|
|
@@ -560,7 +564,7 @@ const TamboThreadProvider = ({ children, streaming = true }) => {
|
|
|
560
564
|
const toolCallCounts = {};
|
|
561
565
|
const params = {
|
|
562
566
|
messageToAppend: {
|
|
563
|
-
content:
|
|
567
|
+
content: messageContent,
|
|
564
568
|
role: "user",
|
|
565
569
|
additionalContext: combinedContext,
|
|
566
570
|
},
|