@tambo-ai/react 0.72.0 → 0.73.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/dist/mcp/mcp-hooks.d.ts +4 -0
- package/dist/mcp/mcp-hooks.d.ts.map +1 -1
- package/dist/mcp/mcp-hooks.js +4 -0
- package/dist/mcp/mcp-hooks.js.map +1 -1
- package/dist/providers/tambo-provider.d.ts +3 -0
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js +3 -0
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/util/resource-content-resolver.d.ts.map +1 -1
- package/dist/util/resource-content-resolver.js +2 -0
- package/dist/util/resource-content-resolver.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-messages.test.js +22 -9
- package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +1 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.js +9 -2
- package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js +22 -9
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts +91 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.js +152 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.d.ts +2 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js +511 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts +6 -57
- package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.js +7 -67
- package/dist/v1/hooks/use-tambo-v1-thread-input.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +201 -72
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +6 -4
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.js +2 -2
- package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +2 -2
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.test.js +16 -7
- package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/dist/v1/index.d.ts +22 -13
- package/dist/v1/index.d.ts.map +1 -1
- package/dist/v1/index.js +31 -39
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts +27 -9
- package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.js +22 -11
- package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.test.js +27 -10
- package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.d.ts +19 -10
- package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.js +43 -53
- package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.test.js +94 -19
- package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts +74 -0
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -0
- package/dist/v1/providers/tambo-v1-stub-provider.js +212 -0
- package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -0
- package/dist/v1/providers/tambo-v1-stub-provider.test.d.ts +2 -0
- package/dist/v1/providers/tambo-v1-stub-provider.test.d.ts.map +1 -0
- package/dist/v1/providers/tambo-v1-stub-provider.test.js +162 -0
- package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -0
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +105 -0
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -0
- package/dist/v1/providers/tambo-v1-thread-input-provider.js +191 -0
- package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -0
- package/dist/v1/utils/component-renderer.d.ts +15 -67
- package/dist/v1/utils/component-renderer.d.ts.map +1 -1
- package/dist/v1/utils/component-renderer.js +3 -149
- package/dist/v1/utils/component-renderer.js.map +1 -1
- package/dist/v1/utils/component-renderer.test.js +15 -350
- package/dist/v1/utils/component-renderer.test.js.map +1 -1
- package/esm/mcp/mcp-hooks.d.ts +4 -0
- package/esm/mcp/mcp-hooks.d.ts.map +1 -1
- package/esm/mcp/mcp-hooks.js +4 -0
- package/esm/mcp/mcp-hooks.js.map +1 -1
- package/esm/providers/tambo-provider.d.ts +3 -0
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js +3 -0
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/util/resource-content-resolver.d.ts.map +1 -1
- package/esm/util/resource-content-resolver.js +2 -0
- package/esm/util/resource-content-resolver.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.test.js +22 -9
- package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +1 -0
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.js +9 -2
- package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js +22 -9
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts +91 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.js +149 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.d.ts +2 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js +506 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +6 -57
- package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.js +5 -66
- package/esm/v1/hooks/use-tambo-v1-thread-input.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +199 -73
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +6 -4
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.js +2 -2
- package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +2 -2
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.test.js +16 -7
- package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/esm/v1/index.d.ts +22 -13
- package/esm/v1/index.d.ts.map +1 -1
- package/esm/v1/index.js +23 -18
- package/esm/v1/index.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts +27 -9
- package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.js +20 -10
- package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.test.js +28 -11
- package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.d.ts +19 -10
- package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js +44 -54
- package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.test.js +95 -20
- package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts +74 -0
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -0
- package/esm/v1/providers/tambo-v1-stub-provider.js +176 -0
- package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -0
- package/esm/v1/providers/tambo-v1-stub-provider.test.d.ts +2 -0
- package/esm/v1/providers/tambo-v1-stub-provider.test.d.ts.map +1 -0
- package/esm/v1/providers/tambo-v1-stub-provider.test.js +157 -0
- package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -0
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +105 -0
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -0
- package/esm/v1/providers/tambo-v1-thread-input-provider.js +153 -0
- package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -0
- package/esm/v1/utils/component-renderer.d.ts +15 -67
- package/esm/v1/utils/component-renderer.d.ts.map +1 -1
- package/esm/v1/utils/component-renderer.js +4 -146
- package/esm/v1/utils/component-renderer.js.map +1 -1
- package/esm/v1/utils/component-renderer.test.js +16 -351
- package/esm/v1/utils/component-renderer.test.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-suggestions.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { renderHook, act, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { useTamboV1Suggestions } from \"./use-tambo-v1-suggestions\";\nimport { useTamboV1ThreadInput } from \"./use-tambo-v1-thread-input\";\nimport { useTamboV1 } from \"./use-tambo-v1\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\n\n// Mock dependencies\njest.mock(\"./use-tambo-v1-thread-input\", () => ({\n useTamboV1ThreadInput: jest.fn(),\n}));\n\njest.mock(\"./use-tambo-v1\", () => ({\n useTamboV1: jest.fn(),\n}));\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(() => new QueryClient()),\n}));\n\njest.mock(\"../../providers/tambo-registry-provider\", () => ({\n useTamboRegistry: jest.fn(),\n}));\n\ndescribe(\"useTamboV1Suggestions\", () => {\n let queryClient: QueryClient;\n const mockSetValue = jest.fn();\n const mockSubmit = jest.fn();\n const mockGenerateSuggestions = jest.fn();\n\n function createWrapper() {\n return function Wrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n {children}\n </QueryClientProvider>\n );\n };\n }\n\n beforeEach(() => {\n jest.clearAllMocks();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n // Default mock for thread input\n jest.mocked(useTamboV1ThreadInput).mockReturnValue({\n value: \"\",\n setValue: mockSetValue,\n submit: mockSubmit,\n threadId: \"thread_123\",\n setThreadId: jest.fn(),\n images: [],\n addImage: jest.fn(),\n addImages: jest.fn(),\n removeImage: jest.fn(),\n clearImages: jest.fn(),\n isPending: false,\n isError: false,\n error: undefined,\n } as any);\n\n // Default mock for useTamboV1\n jest.mocked(useTamboV1).mockReturnValue({\n messages: [],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n // Default mock for registry\n jest.mocked(useTamboRegistry).mockReturnValue({\n componentList: {},\n toolRegistry: {},\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n onCallUnregisteredTool: undefined,\n registerComponent: jest.fn(),\n unregisterComponent: jest.fn(),\n registerTool: jest.fn(),\n unregisterTool: jest.fn(),\n registerMcpServer: jest.fn(),\n unregisterMcpServer: jest.fn(),\n registerResource: jest.fn(),\n unregisterResource: jest.fn(),\n setResourceSource: jest.fn(),\n } as any);\n\n // Default mock for client\n mockGenerateSuggestions.mockResolvedValue([\n {\n id: \"suggestion_1\",\n suggestion: \"What's the weather?\",\n detailedSuggestion: \"What's the weather like today?\",\n },\n {\n id: \"suggestion_2\",\n suggestion: \"Tell me a joke\",\n detailedSuggestion: \"Can you tell me a funny joke?\",\n },\n ]);\n\n jest.mocked(useTamboClient).mockReturnValue({\n beta: {\n threads: {\n suggestions: {\n generate: mockGenerateSuggestions,\n },\n },\n },\n } as any);\n });\n\n describe(\"Initial State\", () => {\n it(\"returns empty suggestions when no messages\", () => {\n const { result } = renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n\n it(\"returns empty suggestions when latest message is from user\", () => {\n jest.mocked(useTamboV1).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"user\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n const { result } = renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.suggestions).toEqual([]);\n });\n });\n\n describe(\"Suggestion Generation\", () => {\n it(\"generates suggestions when latest message is from assistant and thread is idle\", async () => {\n jest.mocked(useTamboV1).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n const { result } = renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n expect(mockGenerateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({\n id: \"thread_123\",\n maxSuggestions: 3,\n }),\n );\n });\n\n it(\"does not generate suggestions when thread is streaming\", () => {\n jest.mocked(useTamboV1).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: false,\n isStreaming: true,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"streaming\",\n runId: \"run_1\",\n },\n } as any);\n\n renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(mockGenerateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"does not generate suggestions when no threadId\", () => {\n jest.mocked(useTamboV1ThreadInput).mockReturnValue({\n value: \"\",\n setValue: mockSetValue,\n submit: mockSubmit,\n threadId: undefined,\n setThreadId: jest.fn(),\n images: [],\n addImage: jest.fn(),\n addImages: jest.fn(),\n removeImage: jest.fn(),\n clearImages: jest.fn(),\n isPending: false,\n isError: false,\n error: undefined,\n } as any);\n\n jest.mocked(useTamboV1).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(mockGenerateSuggestions).not.toHaveBeenCalled();\n });\n\n it(\"uses custom maxSuggestions option\", async () => {\n jest.mocked(useTamboV1).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n const { result } = renderHook(\n () => useTamboV1Suggestions({ maxSuggestions: 5 }),\n { wrapper: createWrapper() },\n );\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n expect(mockGenerateSuggestions).toHaveBeenCalledWith(\n \"msg_1\",\n expect.objectContaining({\n maxSuggestions: 5,\n }),\n );\n });\n });\n\n describe(\"Accepting Suggestions\", () => {\n it(\"updates shared input value when accepting without submit\", async () => {\n jest.mocked(useTamboV1).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n const { result } = renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n const suggestion = result.current.suggestions[0];\n\n await act(async () => {\n await result.current.accept({ suggestion });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\n \"What's the weather like today?\",\n );\n expect(mockSubmit).not.toHaveBeenCalled();\n expect(result.current.selectedSuggestionId).toBe(\"suggestion_1\");\n });\n\n it(\"submits when accepting with shouldSubmit=true\", async () => {\n mockSubmit.mockResolvedValue({ threadId: \"thread_123\" });\n\n jest.mocked(useTamboV1).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n const { result } = renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n const suggestion = result.current.suggestions[0];\n\n await act(async () => {\n await result.current.accept({ suggestion, shouldSubmit: true });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\n \"What's the weather like today?\",\n );\n expect(mockSubmit).toHaveBeenCalled();\n });\n\n it(\"throws error when suggestion has no detailed content\", async () => {\n jest.mocked(useTamboV1).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n const { result } = renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n const emptySuggestion = {\n id: \"empty_suggestion\",\n suggestion: \"Empty\",\n detailedSuggestion: \"\",\n };\n\n await expect(\n result.current.accept({ suggestion: emptySuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no detailed content\");\n });\n\n it(\"throws error when detailedSuggestion is only whitespace\", async () => {\n jest.mocked(useTamboV1).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n const { result } = renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n const whitespaceSuggestion = {\n id: \"whitespace_suggestion\",\n suggestion: \"Whitespace\",\n detailedSuggestion: \" \",\n };\n\n await expect(\n result.current.accept({ suggestion: whitespaceSuggestion as any }),\n ).rejects.toThrow(\"Suggestion has no detailed content\");\n });\n });\n\n describe(\"State Management\", () => {\n it(\"resets selectedSuggestionId when message changes\", async () => {\n const mockUseTamboV1 = jest.mocked(useTamboV1);\n\n mockUseTamboV1.mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n const { result, rerender } = renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.suggestions).toHaveLength(2);\n });\n\n // Accept a suggestion\n await act(async () => {\n await result.current.accept({\n suggestion: result.current.suggestions[0],\n });\n });\n\n expect(result.current.selectedSuggestionId).toBe(\"suggestion_1\");\n\n // Change the latest message\n mockUseTamboV1.mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n {\n id: \"msg_2\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:01Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n rerender();\n\n await waitFor(() => {\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n });\n\n it(\"exposes mutation and query results\", async () => {\n jest.mocked(useTamboV1).mockReturnValue({\n messages: [\n {\n id: \"msg_1\",\n role: \"assistant\",\n content: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n },\n ],\n thread: undefined,\n isIdle: true,\n isStreaming: false,\n startNewThread: jest.fn(),\n switchThread: jest.fn(),\n initThread: jest.fn(),\n streamingState: {\n status: \"idle\",\n },\n } as any);\n\n const { result } = renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.acceptResult).toBeDefined();\n expect(result.current.generateResult).toBeDefined();\n expect(result.current.suggestionsResult).toBeDefined();\n });\n\n it(\"exposes combined mutation results (isPending, isError, error)\", () => {\n const { result } = renderHook(() => useTamboV1Suggestions(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.isPending).toBe(false);\n expect(result.current.isError).toBe(false);\n expect(result.current.error).toBeNull();\n });\n });\n});\n"]}
|
|
@@ -1,62 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*/
|
|
4
|
-
export interface SubmitOptions {
|
|
5
|
-
/**
|
|
6
|
-
* Enable debug logging for the stream
|
|
7
|
-
*/
|
|
8
|
-
debug?: boolean;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Return type for useTamboV1ThreadInput hook
|
|
12
|
-
*/
|
|
13
|
-
export interface UseTamboV1ThreadInputReturn {
|
|
14
|
-
/** Current value of the input field */
|
|
15
|
-
value: string;
|
|
16
|
-
/** Function to update the input value */
|
|
17
|
-
setValue: React.Dispatch<React.SetStateAction<string>>;
|
|
18
|
-
/** Submit the current input. Clears input on success. */
|
|
19
|
-
submit: (options?: SubmitOptions) => Promise<{
|
|
20
|
-
threadId: string | undefined;
|
|
21
|
-
}>;
|
|
22
|
-
isPending: boolean;
|
|
23
|
-
isError: boolean;
|
|
24
|
-
error: Error | null;
|
|
25
|
-
isSuccess: boolean;
|
|
26
|
-
reset: () => void;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Hook to manage thread input state and message submission.
|
|
30
|
-
*
|
|
31
|
-
* Provides a similar API to the beta SDK's useTamboThreadInput,
|
|
32
|
-
* managing input value state and providing a submit function.
|
|
33
|
-
* @param threadId - Optional thread ID to send messages to. If not provided, creates new thread
|
|
34
|
-
* @returns Thread input state and submit function
|
|
35
|
-
* @example
|
|
36
|
-
* ```tsx
|
|
37
|
-
* function ChatInput({ threadId }: { threadId?: string }) {
|
|
38
|
-
* const { value, setValue, submit, isPending } = useTamboV1ThreadInput(threadId);
|
|
2
|
+
* useTamboV1ThreadInput - Thread Input Hook for v1 API
|
|
39
3
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* console.log('Sent to thread:', result.threadId);
|
|
44
|
-
* };
|
|
4
|
+
* Re-exports the shared thread input hook from the provider.
|
|
5
|
+
* This hook uses shared context, enabling features like suggestions
|
|
6
|
+
* to update the input field directly.
|
|
45
7
|
*
|
|
46
|
-
*
|
|
47
|
-
* <form onSubmit={handleSubmit}>
|
|
48
|
-
* <input
|
|
49
|
-
* value={value}
|
|
50
|
-
* onChange={(e) => setValue(e.target.value)}
|
|
51
|
-
* disabled={isPending}
|
|
52
|
-
* />
|
|
53
|
-
* <button type="submit" disabled={isPending || !value.trim()}>
|
|
54
|
-
* Send
|
|
55
|
-
* </button>
|
|
56
|
-
* </form>
|
|
57
|
-
* );
|
|
58
|
-
* }
|
|
59
|
-
* ```
|
|
8
|
+
* For direct thread control without shared state, use useTamboV1SendMessage instead.
|
|
60
9
|
*/
|
|
61
|
-
export
|
|
10
|
+
export { useTamboV1ThreadInput, type TamboV1ThreadInputContextProps, type SubmitOptions, } from "../providers/tambo-v1-thread-input-provider";
|
|
62
11
|
//# sourceMappingURL=use-tambo-v1-thread-input.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-thread-input.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-thread-input.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-thread-input.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-thread-input.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EACL,qBAAqB,EACrB,KAAK,8BAA8B,EACnC,KAAK,aAAa,GACnB,MAAM,6CAA6C,CAAC"}
|
|
@@ -2,72 +2,11 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* useTamboV1ThreadInput - Thread Input Hook for v1 API
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
import { useCallback, useState } from "react";
|
|
9
|
-
import { useTamboV1SendMessage } from "./use-tambo-v1-send-message";
|
|
10
|
-
/**
|
|
11
|
-
* Hook to manage thread input state and message submission.
|
|
12
|
-
*
|
|
13
|
-
* Provides a similar API to the beta SDK's useTamboThreadInput,
|
|
14
|
-
* managing input value state and providing a submit function.
|
|
15
|
-
* @param threadId - Optional thread ID to send messages to. If not provided, creates new thread
|
|
16
|
-
* @returns Thread input state and submit function
|
|
17
|
-
* @example
|
|
18
|
-
* ```tsx
|
|
19
|
-
* function ChatInput({ threadId }: { threadId?: string }) {
|
|
20
|
-
* const { value, setValue, submit, isPending } = useTamboV1ThreadInput(threadId);
|
|
21
|
-
*
|
|
22
|
-
* const handleSubmit = async (e: React.FormEvent) => {
|
|
23
|
-
* e.preventDefault();
|
|
24
|
-
* const result = await submit();
|
|
25
|
-
* console.log('Sent to thread:', result.threadId);
|
|
26
|
-
* };
|
|
5
|
+
* Re-exports the shared thread input hook from the provider.
|
|
6
|
+
* This hook uses shared context, enabling features like suggestions
|
|
7
|
+
* to update the input field directly.
|
|
27
8
|
*
|
|
28
|
-
*
|
|
29
|
-
* <form onSubmit={handleSubmit}>
|
|
30
|
-
* <input
|
|
31
|
-
* value={value}
|
|
32
|
-
* onChange={(e) => setValue(e.target.value)}
|
|
33
|
-
* disabled={isPending}
|
|
34
|
-
* />
|
|
35
|
-
* <button type="submit" disabled={isPending || !value.trim()}>
|
|
36
|
-
* Send
|
|
37
|
-
* </button>
|
|
38
|
-
* </form>
|
|
39
|
-
* );
|
|
40
|
-
* }
|
|
41
|
-
* ```
|
|
9
|
+
* For direct thread control without shared state, use useTamboV1SendMessage instead.
|
|
42
10
|
*/
|
|
43
|
-
export
|
|
44
|
-
const [value, setValue] = useState("");
|
|
45
|
-
const mutation = useTamboV1SendMessage(threadId);
|
|
46
|
-
const submit = useCallback(async (options) => {
|
|
47
|
-
const trimmedValue = value.trim();
|
|
48
|
-
if (!trimmedValue) {
|
|
49
|
-
throw new Error("Message cannot be empty");
|
|
50
|
-
}
|
|
51
|
-
const result = await mutation.mutateAsync({
|
|
52
|
-
message: {
|
|
53
|
-
role: "user",
|
|
54
|
-
content: [{ type: "text", text: trimmedValue }],
|
|
55
|
-
},
|
|
56
|
-
debug: options?.debug,
|
|
57
|
-
});
|
|
58
|
-
// Clear input on successful submission
|
|
59
|
-
setValue("");
|
|
60
|
-
return result;
|
|
61
|
-
}, [value, mutation]);
|
|
62
|
-
return {
|
|
63
|
-
value,
|
|
64
|
-
setValue,
|
|
65
|
-
submit,
|
|
66
|
-
isPending: mutation.isPending,
|
|
67
|
-
isError: mutation.isError,
|
|
68
|
-
error: mutation.error,
|
|
69
|
-
isSuccess: mutation.isSuccess,
|
|
70
|
-
reset: mutation.reset,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
11
|
+
export { useTamboV1ThreadInput, } from "../providers/tambo-v1-thread-input-provider";
|
|
73
12
|
//# sourceMappingURL=use-tambo-v1-thread-input.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-thread-input.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-thread-input.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-thread-input.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-thread-input.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;;;GAQG;AAEH,OAAO,EACL,qBAAqB,GAGtB,MAAM,6CAA6C,CAAC","sourcesContent":["\"use client\";\n\n/**\n * useTamboV1ThreadInput - Thread Input Hook for v1 API\n *\n * Re-exports the shared thread input hook from the provider.\n * This hook uses shared context, enabling features like suggestions\n * to update the input field directly.\n *\n * For direct thread control without shared state, use useTamboV1SendMessage instead.\n */\n\nexport {\n useTamboV1ThreadInput,\n type TamboV1ThreadInputContextProps,\n type SubmitOptions,\n} from \"../providers/tambo-v1-thread-input-provider\";\n"]}
|
|
@@ -1,56 +1,99 @@
|
|
|
1
|
-
import { renderHook, act } from "@testing-library/react";
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const mockReset = jest.fn();
|
|
7
|
-
// Mock useTamboV1SendMessage module
|
|
8
|
-
jest.mock("./use-tambo-v1-send-message");
|
|
1
|
+
import { renderHook, act, waitFor } from "@testing-library/react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
4
|
+
import { TamboV1ThreadInputProvider, useTamboV1ThreadInput, } from "../providers/tambo-v1-thread-input-provider";
|
|
5
|
+
import { TamboV1StreamProvider } from "../providers/tambo-v1-stream-context";
|
|
9
6
|
import { useTamboV1SendMessage } from "./use-tambo-v1-send-message";
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
failureReason: null,
|
|
26
|
-
reset: mockReset,
|
|
27
|
-
context: undefined,
|
|
28
|
-
submittedAt: 0,
|
|
29
|
-
...overrides,
|
|
7
|
+
// Mock useTamboV1SendMessage
|
|
8
|
+
jest.mock("./use-tambo-v1-send-message", () => ({
|
|
9
|
+
useTamboV1SendMessage: jest.fn(),
|
|
10
|
+
}));
|
|
11
|
+
// Mock useTamboQueryClient to avoid TamboClientProvider dependency
|
|
12
|
+
jest.mock("../../providers/tambo-client-provider", () => ({
|
|
13
|
+
useTamboQueryClient: jest.fn(() => new QueryClient()),
|
|
14
|
+
useTamboClient: jest.fn(),
|
|
15
|
+
}));
|
|
16
|
+
const createSuccessfulFileReader = () => {
|
|
17
|
+
const reader = {
|
|
18
|
+
readAsDataURL: jest.fn(),
|
|
19
|
+
onload: null,
|
|
20
|
+
onerror: null,
|
|
21
|
+
result: "data:image/png;base64,mock-data",
|
|
30
22
|
};
|
|
31
|
-
jest.
|
|
32
|
-
|
|
33
|
-
}
|
|
23
|
+
reader.readAsDataURL = jest.fn(() => {
|
|
24
|
+
setTimeout(() => {
|
|
25
|
+
reader.onload?.({});
|
|
26
|
+
}, 0);
|
|
27
|
+
});
|
|
28
|
+
return reader;
|
|
29
|
+
};
|
|
30
|
+
const originalFileReader = global.FileReader;
|
|
34
31
|
describe("useTamboV1ThreadInput", () => {
|
|
32
|
+
const mockMutateAsync = jest.fn();
|
|
33
|
+
let queryClient;
|
|
34
|
+
function createWrapper({ streamState } = {}) {
|
|
35
|
+
const noopDispatch = () => { };
|
|
36
|
+
return function Wrapper({ children }) {
|
|
37
|
+
const streamProviderProps = streamState === undefined
|
|
38
|
+
? {}
|
|
39
|
+
: { state: streamState, dispatch: noopDispatch };
|
|
40
|
+
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
41
|
+
React.createElement(TamboV1StreamProvider, { ...streamProviderProps },
|
|
42
|
+
React.createElement(TamboV1ThreadInputProvider, null, children))));
|
|
43
|
+
};
|
|
44
|
+
}
|
|
35
45
|
beforeEach(() => {
|
|
36
46
|
jest.clearAllMocks();
|
|
47
|
+
global.FileReader = jest.fn(() => createSuccessfulFileReader());
|
|
48
|
+
queryClient = new QueryClient({
|
|
49
|
+
defaultOptions: {
|
|
50
|
+
queries: { retry: false },
|
|
51
|
+
mutations: { retry: false },
|
|
52
|
+
},
|
|
53
|
+
});
|
|
37
54
|
mockMutateAsync.mockResolvedValue({ threadId: "thread_123" });
|
|
38
|
-
|
|
55
|
+
jest.mocked(useTamboV1SendMessage).mockReturnValue({
|
|
56
|
+
mutateAsync: mockMutateAsync,
|
|
57
|
+
mutate: jest.fn(),
|
|
58
|
+
isPending: false,
|
|
59
|
+
isError: false,
|
|
60
|
+
error: null,
|
|
61
|
+
isSuccess: false,
|
|
62
|
+
isIdle: true,
|
|
63
|
+
isPaused: false,
|
|
64
|
+
status: "idle",
|
|
65
|
+
data: undefined,
|
|
66
|
+
variables: undefined,
|
|
67
|
+
failureCount: 0,
|
|
68
|
+
failureReason: null,
|
|
69
|
+
reset: jest.fn(),
|
|
70
|
+
context: undefined,
|
|
71
|
+
submittedAt: 0,
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
afterEach(() => {
|
|
75
|
+
global.FileReader = originalFileReader;
|
|
39
76
|
});
|
|
40
77
|
describe("State Management", () => {
|
|
41
78
|
it("initializes with empty value", () => {
|
|
42
|
-
const { result } = renderHook(() => useTamboV1ThreadInput()
|
|
79
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
80
|
+
wrapper: createWrapper(),
|
|
81
|
+
});
|
|
43
82
|
expect(result.current.value).toBe("");
|
|
44
83
|
});
|
|
45
84
|
it("updates value via setValue", () => {
|
|
46
|
-
const { result } = renderHook(() => useTamboV1ThreadInput()
|
|
85
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
86
|
+
wrapper: createWrapper(),
|
|
87
|
+
});
|
|
47
88
|
act(() => {
|
|
48
89
|
result.current.setValue("Hello world");
|
|
49
90
|
});
|
|
50
91
|
expect(result.current.value).toBe("Hello world");
|
|
51
92
|
});
|
|
52
93
|
it("supports functional updates for setValue", () => {
|
|
53
|
-
const { result } = renderHook(() => useTamboV1ThreadInput()
|
|
94
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
95
|
+
wrapper: createWrapper(),
|
|
96
|
+
});
|
|
54
97
|
act(() => {
|
|
55
98
|
result.current.setValue("Hello");
|
|
56
99
|
});
|
|
@@ -62,7 +105,9 @@ describe("useTamboV1ThreadInput", () => {
|
|
|
62
105
|
});
|
|
63
106
|
describe("Submit Behavior", () => {
|
|
64
107
|
it("submits message and clears input on success", async () => {
|
|
65
|
-
const { result } = renderHook(() => useTamboV1ThreadInput(
|
|
108
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
109
|
+
wrapper: createWrapper(),
|
|
110
|
+
});
|
|
66
111
|
act(() => {
|
|
67
112
|
result.current.setValue("Test message");
|
|
68
113
|
});
|
|
@@ -71,7 +116,9 @@ describe("useTamboV1ThreadInput", () => {
|
|
|
71
116
|
expect(response.threadId).toBe("thread_123");
|
|
72
117
|
});
|
|
73
118
|
// Input should be cleared
|
|
74
|
-
|
|
119
|
+
await waitFor(() => {
|
|
120
|
+
expect(result.current.value).toBe("");
|
|
121
|
+
});
|
|
75
122
|
// Should have called mutateAsync with correct message format
|
|
76
123
|
expect(mockMutateAsync).toHaveBeenCalledWith({
|
|
77
124
|
message: {
|
|
@@ -82,12 +129,16 @@ describe("useTamboV1ThreadInput", () => {
|
|
|
82
129
|
});
|
|
83
130
|
});
|
|
84
131
|
it("throws error when submitting empty message", async () => {
|
|
85
|
-
const { result } = renderHook(() => useTamboV1ThreadInput()
|
|
132
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
133
|
+
wrapper: createWrapper(),
|
|
134
|
+
});
|
|
86
135
|
await expect(result.current.submit()).rejects.toThrow("Message cannot be empty");
|
|
87
136
|
expect(mockMutateAsync).not.toHaveBeenCalled();
|
|
88
137
|
});
|
|
89
138
|
it("throws error when submitting whitespace-only message", async () => {
|
|
90
|
-
const { result } = renderHook(() => useTamboV1ThreadInput()
|
|
139
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
140
|
+
wrapper: createWrapper(),
|
|
141
|
+
});
|
|
91
142
|
act(() => {
|
|
92
143
|
result.current.setValue(" ");
|
|
93
144
|
});
|
|
@@ -95,7 +146,9 @@ describe("useTamboV1ThreadInput", () => {
|
|
|
95
146
|
expect(mockMutateAsync).not.toHaveBeenCalled();
|
|
96
147
|
});
|
|
97
148
|
it("passes debug option to mutation", async () => {
|
|
98
|
-
const { result } = renderHook(() => useTamboV1ThreadInput()
|
|
149
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
150
|
+
wrapper: createWrapper(),
|
|
151
|
+
});
|
|
99
152
|
act(() => {
|
|
100
153
|
result.current.setValue("Debug message");
|
|
101
154
|
});
|
|
@@ -110,10 +163,45 @@ describe("useTamboV1ThreadInput", () => {
|
|
|
110
163
|
debug: true,
|
|
111
164
|
});
|
|
112
165
|
});
|
|
113
|
-
it("
|
|
114
|
-
const { result } = renderHook(() => useTamboV1ThreadInput()
|
|
166
|
+
it("submits image-only messages as resource content", async () => {
|
|
167
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
168
|
+
wrapper: createWrapper(),
|
|
169
|
+
});
|
|
170
|
+
await act(async () => {
|
|
171
|
+
await result.current.addImage(new File(["image"], "photo.png", { type: "image/png" }));
|
|
172
|
+
});
|
|
173
|
+
await act(async () => {
|
|
174
|
+
await result.current.submit();
|
|
175
|
+
});
|
|
176
|
+
expect(mockMutateAsync).toHaveBeenCalledWith({
|
|
177
|
+
message: {
|
|
178
|
+
role: "user",
|
|
179
|
+
content: [
|
|
180
|
+
{
|
|
181
|
+
type: "resource",
|
|
182
|
+
resource: {
|
|
183
|
+
blob: "mock-data",
|
|
184
|
+
mimeType: "image/png",
|
|
185
|
+
name: "photo.png",
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
debug: undefined,
|
|
191
|
+
});
|
|
192
|
+
await waitFor(() => {
|
|
193
|
+
expect(result.current.images).toEqual([]);
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
it("includes both text and image resource content when both are present", async () => {
|
|
197
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
198
|
+
wrapper: createWrapper(),
|
|
199
|
+
});
|
|
115
200
|
act(() => {
|
|
116
|
-
result.current.setValue("
|
|
201
|
+
result.current.setValue("Test message");
|
|
202
|
+
});
|
|
203
|
+
await act(async () => {
|
|
204
|
+
await result.current.addImage(new File(["image"], "photo.png", { type: "image/png" }));
|
|
117
205
|
});
|
|
118
206
|
await act(async () => {
|
|
119
207
|
await result.current.submit();
|
|
@@ -121,45 +209,83 @@ describe("useTamboV1ThreadInput", () => {
|
|
|
121
209
|
expect(mockMutateAsync).toHaveBeenCalledWith({
|
|
122
210
|
message: {
|
|
123
211
|
role: "user",
|
|
124
|
-
content: [
|
|
212
|
+
content: [
|
|
213
|
+
{ type: "text", text: "Test message" },
|
|
214
|
+
{
|
|
215
|
+
type: "resource",
|
|
216
|
+
resource: {
|
|
217
|
+
blob: "mock-data",
|
|
218
|
+
mimeType: "image/png",
|
|
219
|
+
name: "photo.png",
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
],
|
|
125
223
|
},
|
|
126
224
|
debug: undefined,
|
|
127
225
|
});
|
|
128
226
|
});
|
|
129
227
|
});
|
|
130
|
-
describe("Thread ID
|
|
131
|
-
it("
|
|
132
|
-
renderHook(() => useTamboV1ThreadInput(
|
|
133
|
-
|
|
228
|
+
describe("Thread ID Management", () => {
|
|
229
|
+
it("initializes with undefined threadId", () => {
|
|
230
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
231
|
+
wrapper: createWrapper(),
|
|
232
|
+
});
|
|
233
|
+
expect(result.current.threadId).toBeUndefined();
|
|
134
234
|
});
|
|
135
|
-
it("
|
|
136
|
-
renderHook(() => useTamboV1ThreadInput()
|
|
137
|
-
|
|
235
|
+
it("allows setting threadId via setThreadId", () => {
|
|
236
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
237
|
+
wrapper: createWrapper(),
|
|
238
|
+
});
|
|
239
|
+
act(() => {
|
|
240
|
+
result.current.setThreadId("custom_thread_id");
|
|
241
|
+
});
|
|
242
|
+
expect(result.current.threadId).toBe("custom_thread_id");
|
|
138
243
|
});
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
setupMock({ isError: true, error: new Error("Test error") });
|
|
148
|
-
const { result } = renderHook(() => useTamboV1ThreadInput());
|
|
149
|
-
expect(result.current.isError).toBe(true);
|
|
150
|
-
expect(result.current.error?.message).toBe("Test error");
|
|
151
|
-
});
|
|
152
|
-
it("exposes isSuccess state", () => {
|
|
153
|
-
setupMock({ isSuccess: true });
|
|
154
|
-
const { result } = renderHook(() => useTamboV1ThreadInput());
|
|
155
|
-
expect(result.current.isSuccess).toBe(true);
|
|
156
|
-
});
|
|
157
|
-
it("exposes reset function", () => {
|
|
158
|
-
const { result } = renderHook(() => useTamboV1ThreadInput());
|
|
244
|
+
it("does not take ownership of threadId when inheriting stream selection", async () => {
|
|
245
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
246
|
+
wrapper: createWrapper({
|
|
247
|
+
streamState: { threadMap: {}, currentThreadId: "thread_stream" },
|
|
248
|
+
}),
|
|
249
|
+
});
|
|
250
|
+
expect(result.current.threadId).toBe("thread_stream");
|
|
251
|
+
expect(jest.mocked(useTamboV1SendMessage).mock.calls.map((call) => call[0])).toContain("thread_stream");
|
|
159
252
|
act(() => {
|
|
160
|
-
result.current.
|
|
253
|
+
result.current.setValue("Test message");
|
|
254
|
+
});
|
|
255
|
+
await act(async () => {
|
|
256
|
+
await result.current.submit();
|
|
257
|
+
});
|
|
258
|
+
expect(result.current.threadId).toBe("thread_stream");
|
|
259
|
+
expect(jest.mocked(useTamboV1SendMessage).mock.calls.map((call) => call[0])).not.toContain("thread_123");
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
describe("Image State", () => {
|
|
263
|
+
it("initializes with empty images array", () => {
|
|
264
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
265
|
+
wrapper: createWrapper(),
|
|
266
|
+
});
|
|
267
|
+
expect(result.current.images).toEqual([]);
|
|
268
|
+
});
|
|
269
|
+
it("exposes image management functions", () => {
|
|
270
|
+
const { result } = renderHook(() => useTamboV1ThreadInput(), {
|
|
271
|
+
wrapper: createWrapper(),
|
|
161
272
|
});
|
|
162
|
-
expect(
|
|
273
|
+
expect(typeof result.current.addImage).toBe("function");
|
|
274
|
+
expect(typeof result.current.addImages).toBe("function");
|
|
275
|
+
expect(typeof result.current.removeImage).toBe("function");
|
|
276
|
+
expect(typeof result.current.clearImages).toBe("function");
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
describe("Error handling", () => {
|
|
280
|
+
it("throws error when used outside provider", () => {
|
|
281
|
+
// Suppress console.error for this test
|
|
282
|
+
const consoleSpy = jest
|
|
283
|
+
.spyOn(console, "error")
|
|
284
|
+
.mockImplementation(() => { });
|
|
285
|
+
expect(() => {
|
|
286
|
+
renderHook(() => useTamboV1ThreadInput());
|
|
287
|
+
}).toThrow("useTamboV1ThreadInput must be used within TamboV1ThreadInputProvider");
|
|
288
|
+
consoleSpy.mockRestore();
|
|
163
289
|
});
|
|
164
290
|
});
|
|
165
291
|
});
|