@tambo-ai/react 0.59.0 → 0.62.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.
Files changed (135) hide show
  1. package/dist/__tests__/util/validate-zod-schema.test.js +25 -0
  2. package/dist/__tests__/util/validate-zod-schema.test.js.map +1 -1
  3. package/dist/hooks/index.d.ts +1 -0
  4. package/dist/hooks/index.d.ts.map +1 -1
  5. package/dist/hooks/index.js +3 -1
  6. package/dist/hooks/index.js.map +1 -1
  7. package/dist/hooks/react-query-hooks.d.ts +14 -1
  8. package/dist/hooks/react-query-hooks.d.ts.map +1 -1
  9. package/dist/hooks/react-query-hooks.js +13 -0
  10. package/dist/hooks/react-query-hooks.js.map +1 -1
  11. package/dist/hooks/use-tambo-voice.d.ts +21 -0
  12. package/dist/hooks/use-tambo-voice.d.ts.map +1 -0
  13. package/dist/hooks/use-tambo-voice.js +74 -0
  14. package/dist/hooks/use-tambo-voice.js.map +1 -0
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +5 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/mcp/__tests__/elicitation.test.d.ts +2 -0
  20. package/dist/mcp/__tests__/elicitation.test.d.ts.map +1 -0
  21. package/dist/mcp/__tests__/elicitation.test.js +261 -0
  22. package/dist/mcp/__tests__/elicitation.test.js.map +1 -0
  23. package/dist/mcp/__tests__/mcp-hooks.test.d.ts +2 -0
  24. package/dist/mcp/__tests__/mcp-hooks.test.d.ts.map +1 -0
  25. package/dist/mcp/__tests__/mcp-hooks.test.js +504 -0
  26. package/dist/mcp/__tests__/mcp-hooks.test.js.map +1 -0
  27. package/dist/mcp/__tests__/tambo-mcp-provider.test.js +155 -16
  28. package/dist/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -1
  29. package/dist/mcp/elicitation.d.ts +80 -0
  30. package/dist/mcp/elicitation.d.ts.map +1 -0
  31. package/dist/mcp/elicitation.js +55 -0
  32. package/dist/mcp/elicitation.js.map +1 -0
  33. package/dist/mcp/index.d.ts +3 -2
  34. package/dist/mcp/index.d.ts.map +1 -1
  35. package/dist/mcp/index.js +2 -1
  36. package/dist/mcp/index.js.map +1 -1
  37. package/dist/mcp/mcp-client.d.ts +41 -9
  38. package/dist/mcp/mcp-client.d.ts.map +1 -1
  39. package/dist/mcp/mcp-client.js.map +1 -1
  40. package/dist/mcp/mcp-hooks.d.ts +20 -6
  41. package/dist/mcp/mcp-hooks.d.ts.map +1 -1
  42. package/dist/mcp/mcp-hooks.js +71 -24
  43. package/dist/mcp/mcp-hooks.js.map +1 -1
  44. package/dist/mcp/tambo-mcp-provider.d.ts +61 -7
  45. package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
  46. package/dist/mcp/tambo-mcp-provider.js +231 -172
  47. package/dist/mcp/tambo-mcp-provider.js.map +1 -1
  48. package/dist/providers/__tests__/tambo-thread-provider-initial-messages.test.js +1 -1
  49. package/dist/providers/__tests__/tambo-thread-provider-initial-messages.test.js.map +1 -1
  50. package/dist/providers/__tests__/tambo-thread-provider.test.js +170 -0
  51. package/dist/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
  52. package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
  53. package/dist/providers/tambo-interactable-provider.js +11 -4
  54. package/dist/providers/tambo-interactable-provider.js.map +1 -1
  55. package/dist/providers/tambo-provider.d.ts +2 -0
  56. package/dist/providers/tambo-provider.d.ts.map +1 -1
  57. package/dist/providers/tambo-provider.js +4 -6
  58. package/dist/providers/tambo-provider.js.map +1 -1
  59. package/dist/providers/tambo-thread-provider.d.ts +6 -0
  60. package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
  61. package/dist/providers/tambo-thread-provider.js +112 -45
  62. package/dist/providers/tambo-thread-provider.js.map +1 -1
  63. package/dist/setupTests.js +10 -0
  64. package/dist/setupTests.js.map +1 -1
  65. package/dist/util/validate-zod-schema.d.ts.map +1 -1
  66. package/dist/util/validate-zod-schema.js +11 -0
  67. package/dist/util/validate-zod-schema.js.map +1 -1
  68. package/esm/__tests__/util/validate-zod-schema.test.js +25 -0
  69. package/esm/__tests__/util/validate-zod-schema.test.js.map +1 -1
  70. package/esm/hooks/index.d.ts +1 -0
  71. package/esm/hooks/index.d.ts.map +1 -1
  72. package/esm/hooks/index.js +1 -0
  73. package/esm/hooks/index.js.map +1 -1
  74. package/esm/hooks/react-query-hooks.d.ts +14 -1
  75. package/esm/hooks/react-query-hooks.d.ts.map +1 -1
  76. package/esm/hooks/react-query-hooks.js +13 -1
  77. package/esm/hooks/react-query-hooks.js.map +1 -1
  78. package/esm/hooks/use-tambo-voice.d.ts +21 -0
  79. package/esm/hooks/use-tambo-voice.d.ts.map +1 -0
  80. package/esm/hooks/use-tambo-voice.js +71 -0
  81. package/esm/hooks/use-tambo-voice.js.map +1 -0
  82. package/esm/index.d.ts +1 -0
  83. package/esm/index.d.ts.map +1 -1
  84. package/esm/index.js +3 -0
  85. package/esm/index.js.map +1 -1
  86. package/esm/mcp/__tests__/elicitation.test.d.ts +2 -0
  87. package/esm/mcp/__tests__/elicitation.test.d.ts.map +1 -0
  88. package/esm/mcp/__tests__/elicitation.test.js +259 -0
  89. package/esm/mcp/__tests__/elicitation.test.js.map +1 -0
  90. package/esm/mcp/__tests__/mcp-hooks.test.d.ts +2 -0
  91. package/esm/mcp/__tests__/mcp-hooks.test.d.ts.map +1 -0
  92. package/esm/mcp/__tests__/mcp-hooks.test.js +469 -0
  93. package/esm/mcp/__tests__/mcp-hooks.test.js.map +1 -0
  94. package/esm/mcp/__tests__/tambo-mcp-provider.test.js +155 -16
  95. package/esm/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -1
  96. package/esm/mcp/elicitation.d.ts +80 -0
  97. package/esm/mcp/elicitation.d.ts.map +1 -0
  98. package/esm/mcp/elicitation.js +52 -0
  99. package/esm/mcp/elicitation.js.map +1 -0
  100. package/esm/mcp/index.d.ts +3 -2
  101. package/esm/mcp/index.d.ts.map +1 -1
  102. package/esm/mcp/index.js +1 -1
  103. package/esm/mcp/index.js.map +1 -1
  104. package/esm/mcp/mcp-client.d.ts +41 -9
  105. package/esm/mcp/mcp-client.d.ts.map +1 -1
  106. package/esm/mcp/mcp-client.js.map +1 -1
  107. package/esm/mcp/mcp-hooks.d.ts +20 -6
  108. package/esm/mcp/mcp-hooks.d.ts.map +1 -1
  109. package/esm/mcp/mcp-hooks.js +73 -26
  110. package/esm/mcp/mcp-hooks.js.map +1 -1
  111. package/esm/mcp/tambo-mcp-provider.d.ts +61 -7
  112. package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
  113. package/esm/mcp/tambo-mcp-provider.js +231 -173
  114. package/esm/mcp/tambo-mcp-provider.js.map +1 -1
  115. package/esm/providers/__tests__/tambo-thread-provider-initial-messages.test.js +1 -1
  116. package/esm/providers/__tests__/tambo-thread-provider-initial-messages.test.js.map +1 -1
  117. package/esm/providers/__tests__/tambo-thread-provider.test.js +170 -0
  118. package/esm/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
  119. package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
  120. package/esm/providers/tambo-interactable-provider.js +11 -4
  121. package/esm/providers/tambo-interactable-provider.js.map +1 -1
  122. package/esm/providers/tambo-provider.d.ts +2 -0
  123. package/esm/providers/tambo-provider.d.ts.map +1 -1
  124. package/esm/providers/tambo-provider.js +4 -6
  125. package/esm/providers/tambo-provider.js.map +1 -1
  126. package/esm/providers/tambo-thread-provider.d.ts +6 -0
  127. package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
  128. package/esm/providers/tambo-thread-provider.js +112 -45
  129. package/esm/providers/tambo-thread-provider.js.map +1 -1
  130. package/esm/setupTests.js +10 -0
  131. package/esm/setupTests.js.map +1 -1
  132. package/esm/util/validate-zod-schema.d.ts.map +1 -1
  133. package/esm/util/validate-zod-schema.js +11 -0
  134. package/esm/util/validate-zod-schema.js.map +1 -1
  135. package/package.json +10 -9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tambo-voice.d.ts","sourceRoot":"","sources":["../../src/hooks/use-tambo-voice.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa;;;;;;;;EAyE5B"}
@@ -0,0 +1,71 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import { useReactMediaRecorder } from "react-media-recorder";
3
+ import { useTamboClient } from "../providers/tambo-client-provider";
4
+ import { useTamboMutation } from "./react-query-hooks";
5
+ /**
6
+ * Exposes functionality to record speech and transcribe it using the Tambo API.
7
+ * @returns An object with:
8
+ * - startRecording: A function to start recording audio and reset the current transcript.
9
+ * - stopRecording: A function to stop recording audio and automatically kick off transcription.
10
+ * - isRecording: A boolean indicating if the user is recording audio.
11
+ * - isTranscribing: A boolean indicating if the audio is being transcribed.
12
+ * - transcript: The transcript of the recorded audio.
13
+ * - transcriptionError: An error message if the transcription fails.
14
+ * - mediaAccessError: An error message if microphone access fails.
15
+ */
16
+ export function useTamboVoice() {
17
+ const [transcript, setTranscript] = useState(null);
18
+ const client = useTamboClient();
19
+ const { status, startRecording: startMediaRecording, stopRecording: stopMediaRecording, mediaBlobUrl, error: mediaAccessError, } = useReactMediaRecorder({
20
+ audio: true,
21
+ video: false,
22
+ blobPropertyBag: { type: "audio/webm" },
23
+ });
24
+ const isRecording = status === "recording";
25
+ const transcriptionMutation = useTamboMutation({
26
+ mutationFn: async (blobUrl) => {
27
+ const response = await fetch(blobUrl);
28
+ const audioBlob = await response.blob();
29
+ const file = new File([audioBlob], "recording.webm", {
30
+ type: "audio/webm",
31
+ });
32
+ return await client.beta.audio.transcribe({ file });
33
+ },
34
+ onSuccess: (transcription) => {
35
+ setTranscript(transcription);
36
+ },
37
+ });
38
+ // Trigger transcription when recording stops and we have a blob URL
39
+ const shouldTranscribe = status === "stopped" &&
40
+ mediaBlobUrl &&
41
+ !transcriptionMutation.isPending &&
42
+ !transcriptionMutation.isSuccess;
43
+ useEffect(() => {
44
+ if (shouldTranscribe) {
45
+ transcriptionMutation.mutate(mediaBlobUrl);
46
+ }
47
+ }, [shouldTranscribe, mediaBlobUrl, transcriptionMutation]);
48
+ const startRecording = useCallback(() => {
49
+ if (isRecording)
50
+ return;
51
+ // Reset state when starting new recording
52
+ setTranscript(null);
53
+ transcriptionMutation.reset(); // Clear any previous mutation state
54
+ startMediaRecording();
55
+ }, [isRecording, startMediaRecording, transcriptionMutation]);
56
+ const stopRecording = useCallback(() => {
57
+ if (isRecording) {
58
+ stopMediaRecording();
59
+ }
60
+ }, [isRecording, stopMediaRecording]);
61
+ return {
62
+ startRecording,
63
+ stopRecording,
64
+ isRecording,
65
+ mediaAccessError: mediaAccessError ?? null,
66
+ isTranscribing: transcriptionMutation.isPending,
67
+ transcript,
68
+ transcriptionError: transcriptionMutation.error?.message ?? null,
69
+ };
70
+ }
71
+ //# sourceMappingURL=use-tambo-voice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tambo-voice.js","sourceRoot":"","sources":["../../src/hooks/use-tambo-voice.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;IAChC,MAAM,EACJ,MAAM,EACN,cAAc,EAAE,mBAAmB,EACnC,aAAa,EAAE,kBAAkB,EACjC,YAAY,EACZ,KAAK,EAAE,gBAAgB,GACxB,GAAG,qBAAqB,CAAC;QACxB,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,KAAK;QACZ,eAAe,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;KACxC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,MAAM,KAAK,WAAW,CAAC;IAE3C,MAAM,qBAAqB,GAAG,gBAAgB,CAI5C;QACA,UAAU,EAAE,KAAK,EAAE,OAAe,EAAE,EAAE;YACpC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;YACtC,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,gBAAgB,EAAE;gBACnD,IAAI,EAAE,YAAY;aACnB,CAAC,CAAC;YAEH,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,SAAS,EAAE,CAAC,aAAa,EAAE,EAAE;YAC3B,aAAa,CAAC,aAAa,CAAC,CAAC;QAC/B,CAAC;KACF,CAAC,CAAC;IAEH,oEAAoE;IACpE,MAAM,gBAAgB,GACpB,MAAM,KAAK,SAAS;QACpB,YAAY;QACZ,CAAC,qBAAqB,CAAC,SAAS;QAChC,CAAC,qBAAqB,CAAC,SAAS,CAAC;IAEnC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,gBAAgB,EAAE,CAAC;YACrB,qBAAqB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC,EAAE,CAAC,gBAAgB,EAAE,YAAY,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAE5D,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;QACtC,IAAI,WAAW;YAAE,OAAO;QAExB,0CAA0C;QAC1C,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,qBAAqB,CAAC,KAAK,EAAE,CAAC,CAAC,oCAAoC;QACnE,mBAAmB,EAAE,CAAC;IACxB,CAAC,EAAE,CAAC,WAAW,EAAE,mBAAmB,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAE9D,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;QACrC,IAAI,WAAW,EAAE,CAAC;YAChB,kBAAkB,EAAE,CAAC;QACvB,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAEtC,OAAO;QACL,cAAc;QACd,aAAa;QACb,WAAW;QACX,gBAAgB,EAAE,gBAAgB,IAAI,IAAI;QAC1C,cAAc,EAAE,qBAAqB,CAAC,SAAS;QAC/C,UAAU;QACV,kBAAkB,EAAE,qBAAqB,CAAC,KAAK,EAAE,OAAO,IAAI,IAAI;KACjE,CAAC;AACJ,CAAC","sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { useReactMediaRecorder } from \"react-media-recorder\";\nimport { useTamboClient } from \"../providers/tambo-client-provider\";\nimport { useTamboMutation } from \"./react-query-hooks\";\n\n/**\n * Exposes functionality to record speech and transcribe it using the Tambo API.\n * @returns An object with:\n * - startRecording: A function to start recording audio and reset the current transcript.\n * - stopRecording: A function to stop recording audio and automatically kick off transcription.\n * - isRecording: A boolean indicating if the user is recording audio.\n * - isTranscribing: A boolean indicating if the audio is being transcribed.\n * - transcript: The transcript of the recorded audio.\n * - transcriptionError: An error message if the transcription fails.\n * - mediaAccessError: An error message if microphone access fails.\n */\nexport function useTamboVoice() {\n const [transcript, setTranscript] = useState<string | null>(null);\n const client = useTamboClient();\n const {\n status,\n startRecording: startMediaRecording,\n stopRecording: stopMediaRecording,\n mediaBlobUrl,\n error: mediaAccessError,\n } = useReactMediaRecorder({\n audio: true,\n video: false,\n blobPropertyBag: { type: \"audio/webm\" },\n });\n\n const isRecording = status === \"recording\";\n\n const transcriptionMutation = useTamboMutation<\n string,\n Error,\n string // blobUrl parameter\n >({\n mutationFn: async (blobUrl: string) => {\n const response = await fetch(blobUrl);\n const audioBlob = await response.blob();\n const file = new File([audioBlob], \"recording.webm\", {\n type: \"audio/webm\",\n });\n\n return await client.beta.audio.transcribe({ file });\n },\n onSuccess: (transcription) => {\n setTranscript(transcription);\n },\n });\n\n // Trigger transcription when recording stops and we have a blob URL\n const shouldTranscribe =\n status === \"stopped\" &&\n mediaBlobUrl &&\n !transcriptionMutation.isPending &&\n !transcriptionMutation.isSuccess;\n\n useEffect(() => {\n if (shouldTranscribe) {\n transcriptionMutation.mutate(mediaBlobUrl);\n }\n }, [shouldTranscribe, mediaBlobUrl, transcriptionMutation]);\n\n const startRecording = useCallback(() => {\n if (isRecording) return;\n\n // Reset state when starting new recording\n setTranscript(null);\n transcriptionMutation.reset(); // Clear any previous mutation state\n startMediaRecording();\n }, [isRecording, startMediaRecording, transcriptionMutation]);\n\n const stopRecording = useCallback(() => {\n if (isRecording) {\n stopMediaRecording();\n }\n }, [isRecording, stopMediaRecording]);\n\n return {\n startRecording,\n stopRecording,\n isRecording,\n mediaAccessError: mediaAccessError ?? null,\n isTranscribing: transcriptionMutation.isPending,\n transcript,\n transcriptionError: transcriptionMutation.error?.message ?? null,\n };\n}\n"]}
package/esm/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export { useMessageImages, type StagedImage } from "./hooks/use-message-images";
5
5
  export { useTamboStreamingProps } from "./hooks/use-streaming-props";
6
6
  export * from "./hooks/use-suggestions";
7
7
  export { useTamboStreamStatus, type PropStatus, type StreamStatus, } from "./hooks/use-tambo-stream-status";
8
+ export { useTamboVoice } from "./hooks/use-tambo-voice";
8
9
  export { TamboClientProvider, TamboComponentProvider, TamboContextHelpersProvider, TamboPropStreamProvider, TamboProvider, TamboStubProvider, TamboThreadInputProvider, TamboThreadProvider, useIsTamboTokenUpdating, useTambo, useTamboClient, useTamboContextHelpers, useTamboGenerationStage, useTamboStream, useTamboThread, useTamboThreadInput, type TamboComponent, type TamboContextHelpersContextProps, type TamboContextHelpersProviderProps, type TamboRegistryContext, type TamboStubProviderProps, type TamboThreadInputContextProps, type TamboThreadProviderProps, } from "./providers";
9
10
  export type { APIError, RateLimitError, TamboAIError, } from "@tambo-ai/typescript-sdk";
10
11
  export type { Suggestion, SuggestionGenerateParams, SuggestionGenerateResponse, SuggestionListResponse, } from "@tambo-ai/typescript-sdk/resources/beta/threads/suggestions";
@@ -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,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,EACjC,KAAK,wBAAwB,GAC9B,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;AACxD,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAEnF,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,+BAA+B,EAC/B,oBAAoB,GACrB,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;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD,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,EACjC,KAAK,wBAAwB,GAC9B,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;AACxD,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAEnF,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,+BAA+B,EAC/B,oBAAoB,GACrB,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/esm/index.js CHANGED
@@ -5,6 +5,7 @@ export { useMessageImages } from "./hooks/use-message-images";
5
5
  export { useTamboStreamingProps } from "./hooks/use-streaming-props";
6
6
  export * from "./hooks/use-suggestions";
7
7
  export { useTamboStreamStatus, } from "./hooks/use-tambo-stream-status";
8
+ export { useTamboVoice } from "./hooks/use-tambo-voice";
8
9
  // Re-export provider components
9
10
  export { TamboClientProvider, TamboComponentProvider, TamboContextHelpersProvider, TamboPropStreamProvider, TamboProvider, TamboStubProvider, TamboThreadInputProvider, TamboThreadProvider, useIsTamboTokenUpdating, useTambo, useTamboClient, useTamboContextHelpers, useTamboGenerationStage, useTamboStream, useTamboThread, useTamboThreadInput, } from "./providers";
10
11
  export { useTamboThreadList } from "./hooks/use-tambo-threads";
@@ -13,4 +14,6 @@ export { withTamboInteractable as withInteractable, } from "./providers/hoc/with
13
14
  export { useCurrentInteractablesSnapshot, useTamboInteractable, } from "./providers/tambo-interactable-provider";
14
15
  // Context helpers exports
15
16
  export { currentPageContextHelper, currentTimeContextHelper, } from "./context-helpers";
17
+ // Note MCP exports like TamboMcpProvider are available separately in the
18
+ // @tambo-ai/react/mcp package
16
19
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","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,EAAoB,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,cAAc,yBAAyB,CAAC;AACxC,OAAO,EACL,oBAAoB,GAGrB,MAAM,iCAAiC,CAAC;AAEzC,gCAAgC;AAChC,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,GAQpB,MAAM,aAAa,CAAC;AAcrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,OAAO,EACL,eAAe,GAEhB,MAAM,qCAAqC,CAAC;AAQ7C,OAAO,EACL,qBAAqB,IAAI,gBAAgB,GAG1C,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,+BAA+B,EAC/B,oBAAoB,GACrB,MAAM,yCAAyC,CAAC;AAEjD,0BAA0B;AAC1B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC","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 type TamboThreadProviderProps,\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\";\nexport { type InitialTamboThreadMessage } from \"./providers/tambo-thread-provider\";\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 useCurrentInteractablesSnapshot,\n useTamboInteractable,\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,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAoB,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,cAAc,yBAAyB,CAAC;AACxC,OAAO,EACL,oBAAoB,GAGrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,gCAAgC;AAChC,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,GAQpB,MAAM,aAAa,CAAC;AAcrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,OAAO,EACL,eAAe,GAEhB,MAAM,qCAAqC,CAAC;AAQ7C,OAAO,EACL,qBAAqB,IAAI,gBAAgB,GAG1C,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,+BAA+B,EAC/B,oBAAoB,GACrB,MAAM,yCAAyC,CAAC;AAEjD,0BAA0B;AAC1B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAO3B,yEAAyE;AACzE,8BAA8B","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\";\nexport { useTamboVoice } from \"./hooks/use-tambo-voice\";\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 type TamboThreadProviderProps,\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\";\nexport { type InitialTamboThreadMessage } from \"./providers/tambo-thread-provider\";\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 useCurrentInteractablesSnapshot,\n useTamboInteractable,\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\n// Note MCP exports like TamboMcpProvider are available separately in the\n// @tambo-ai/react/mcp package\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=elicitation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elicitation.test.d.ts","sourceRoot":"","sources":["../../../src/mcp/__tests__/elicitation.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,259 @@
1
+ import { renderHook, act } from "@testing-library/react";
2
+ import { useElicitation, } from "../elicitation";
3
+ // Create a mock RequestHandlerExtra for testing
4
+ function createMockExtra() {
5
+ return {
6
+ signal: new AbortController().signal,
7
+ requestId: "test-request-id",
8
+ sendNotification: (async () => { }),
9
+ sendRequest: (async () => ({ _meta: {} })),
10
+ };
11
+ }
12
+ describe("useElicitation", () => {
13
+ it("initializes with null state", () => {
14
+ const { result } = renderHook(() => useElicitation());
15
+ expect(result.current.elicitation).toBeNull();
16
+ expect(result.current.resolveElicitation).toBeNull();
17
+ });
18
+ it("provides state setters", () => {
19
+ const { result } = renderHook(() => useElicitation());
20
+ expect(typeof result.current.setElicitation).toBe("function");
21
+ expect(typeof result.current.setResolveElicitation).toBe("function");
22
+ });
23
+ it("provides a default elicitation handler", () => {
24
+ const { result } = renderHook(() => useElicitation());
25
+ expect(typeof result.current.defaultElicitationHandler).toBe("function");
26
+ });
27
+ describe("defaultElicitationHandler", () => {
28
+ it("sets elicitation state when called", async () => {
29
+ const { result } = renderHook(() => useElicitation());
30
+ const request = {
31
+ params: {
32
+ message: "Please provide your name",
33
+ requestedSchema: {
34
+ type: "object",
35
+ properties: {
36
+ name: { type: "string", description: "Your name" },
37
+ },
38
+ required: ["name"],
39
+ },
40
+ },
41
+ };
42
+ // Start the handler but don't await yet
43
+ let handlerPromise;
44
+ const extra = createMockExtra();
45
+ act(() => {
46
+ handlerPromise = result.current.defaultElicitationHandler(request, extra);
47
+ });
48
+ // Elicitation should be set
49
+ expect(result.current.elicitation).toEqual({
50
+ message: "Please provide your name",
51
+ requestedSchema: request.params.requestedSchema,
52
+ signal: extra.signal,
53
+ });
54
+ // Resolve callback should be set
55
+ expect(result.current.resolveElicitation).not.toBeNull();
56
+ // Clean up by resolving
57
+ act(() => {
58
+ result.current.resolveElicitation?.({
59
+ action: "cancel",
60
+ });
61
+ });
62
+ await handlerPromise;
63
+ });
64
+ it("resolves promise when resolveElicitation is called with accept", async () => {
65
+ const { result } = renderHook(() => useElicitation());
66
+ const request = {
67
+ params: {
68
+ message: "Enter your email",
69
+ requestedSchema: {
70
+ type: "object",
71
+ properties: {
72
+ email: {
73
+ type: "string",
74
+ format: "email",
75
+ description: "Email address",
76
+ },
77
+ },
78
+ },
79
+ },
80
+ };
81
+ // Start the handler
82
+ let handlerPromise;
83
+ const extra = createMockExtra();
84
+ act(() => {
85
+ handlerPromise = result.current.defaultElicitationHandler(request, extra);
86
+ });
87
+ // Resolve with accept
88
+ const response = {
89
+ action: "accept",
90
+ content: { email: "test@example.com" },
91
+ };
92
+ act(() => {
93
+ result.current.resolveElicitation?.(response);
94
+ });
95
+ // Wait for promise to resolve
96
+ const resolvedValue = await handlerPromise;
97
+ expect(resolvedValue).toEqual(response);
98
+ });
99
+ it("resolves promise when resolveElicitation is called with decline", async () => {
100
+ const { result } = renderHook(() => useElicitation());
101
+ const request = {
102
+ params: {
103
+ message: "Provide input",
104
+ requestedSchema: {
105
+ type: "object",
106
+ properties: {
107
+ value: { type: "string" },
108
+ },
109
+ },
110
+ },
111
+ };
112
+ let handlerPromise;
113
+ const extra = createMockExtra();
114
+ act(() => {
115
+ handlerPromise = result.current.defaultElicitationHandler(request, extra);
116
+ });
117
+ const response = {
118
+ action: "decline",
119
+ };
120
+ act(() => {
121
+ result.current.resolveElicitation?.(response);
122
+ });
123
+ const resolvedValue = await handlerPromise;
124
+ expect(resolvedValue).toEqual(response);
125
+ });
126
+ it("resolves promise when resolveElicitation is called with cancel", async () => {
127
+ const { result } = renderHook(() => useElicitation());
128
+ const request = {
129
+ params: {
130
+ message: "Provide input",
131
+ requestedSchema: {
132
+ type: "object",
133
+ properties: {
134
+ value: { type: "string" },
135
+ },
136
+ },
137
+ },
138
+ };
139
+ let handlerPromise;
140
+ const extra = createMockExtra();
141
+ act(() => {
142
+ handlerPromise = result.current.defaultElicitationHandler(request, extra);
143
+ });
144
+ const response = {
145
+ action: "cancel",
146
+ };
147
+ act(() => {
148
+ result.current.resolveElicitation?.(response);
149
+ });
150
+ const resolvedValue = await handlerPromise;
151
+ expect(resolvedValue).toEqual(response);
152
+ });
153
+ it("handles multiple sequential elicitations", async () => {
154
+ const { result } = renderHook(() => useElicitation());
155
+ // First elicitation
156
+ const request1 = {
157
+ params: {
158
+ message: "First request",
159
+ requestedSchema: {
160
+ type: "object",
161
+ properties: {
162
+ field1: { type: "string" },
163
+ },
164
+ },
165
+ },
166
+ };
167
+ let promise1;
168
+ const extra1 = createMockExtra();
169
+ act(() => {
170
+ promise1 = result.current.defaultElicitationHandler(request1, extra1);
171
+ });
172
+ expect(result.current.elicitation?.message).toBe("First request");
173
+ act(() => {
174
+ result.current.resolveElicitation?.({
175
+ action: "accept",
176
+ content: { field1: "value1" },
177
+ });
178
+ });
179
+ const result1 = await promise1;
180
+ expect(result1).toEqual({
181
+ action: "accept",
182
+ content: { field1: "value1" },
183
+ });
184
+ // Second elicitation
185
+ const request2 = {
186
+ params: {
187
+ message: "Second request",
188
+ requestedSchema: {
189
+ type: "object",
190
+ properties: {
191
+ field2: { type: "number" },
192
+ },
193
+ },
194
+ },
195
+ };
196
+ let promise2;
197
+ const extra2 = createMockExtra();
198
+ act(() => {
199
+ promise2 = result.current.defaultElicitationHandler(request2, extra2);
200
+ });
201
+ expect(result.current.elicitation?.message).toBe("Second request");
202
+ act(() => {
203
+ result.current.resolveElicitation?.({
204
+ action: "accept",
205
+ content: { field2: 42 },
206
+ });
207
+ });
208
+ const result2 = await promise2;
209
+ expect(result2).toEqual({
210
+ action: "accept",
211
+ content: { field2: 42 },
212
+ });
213
+ });
214
+ it("maintains stable handler reference across re-renders", () => {
215
+ const { result, rerender } = renderHook(() => useElicitation());
216
+ const firstHandler = result.current.defaultElicitationHandler;
217
+ rerender();
218
+ const secondHandler = result.current.defaultElicitationHandler;
219
+ expect(firstHandler).toBe(secondHandler);
220
+ });
221
+ });
222
+ describe("state management", () => {
223
+ it("allows manual state updates via setElicitation", () => {
224
+ const { result } = renderHook(() => useElicitation());
225
+ const customElicitation = {
226
+ message: "Custom message",
227
+ requestedSchema: {
228
+ type: "object",
229
+ properties: {
230
+ custom: { type: "boolean" },
231
+ },
232
+ },
233
+ };
234
+ act(() => {
235
+ result.current.setElicitation(customElicitation);
236
+ });
237
+ expect(result.current.elicitation).toEqual(customElicitation);
238
+ });
239
+ it("allows clearing elicitation state", () => {
240
+ const { result } = renderHook(() => useElicitation());
241
+ const elicitation = {
242
+ message: "Test",
243
+ requestedSchema: {
244
+ type: "object",
245
+ properties: {},
246
+ },
247
+ };
248
+ act(() => {
249
+ result.current.setElicitation(elicitation);
250
+ });
251
+ expect(result.current.elicitation).not.toBeNull();
252
+ act(() => {
253
+ result.current.setElicitation(null);
254
+ });
255
+ expect(result.current.elicitation).toBeNull();
256
+ });
257
+ });
258
+ });
259
+ //# sourceMappingURL=elicitation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elicitation.test.js","sourceRoot":"","sources":["../../../src/mcp/__tests__/elicitation.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { renderHook, act } from \"@testing-library/react\";\nimport {\n useElicitation,\n type TamboElicitationRequest,\n type TamboElicitationResponse,\n} from \"../elicitation\";\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n ClientNotification,\n ClientRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\n// Create a mock RequestHandlerExtra for testing\nfunction createMockExtra(): RequestHandlerExtra<\n ClientRequest,\n ClientNotification\n> {\n return {\n signal: new AbortController().signal,\n requestId: \"test-request-id\",\n\n sendNotification: (async () => {}) as any,\n\n sendRequest: (async () => ({ _meta: {} })) as any,\n };\n}\n\ndescribe(\"useElicitation\", () => {\n it(\"initializes with null state\", () => {\n const { result } = renderHook(() => useElicitation());\n\n expect(result.current.elicitation).toBeNull();\n expect(result.current.resolveElicitation).toBeNull();\n });\n\n it(\"provides state setters\", () => {\n const { result } = renderHook(() => useElicitation());\n\n expect(typeof result.current.setElicitation).toBe(\"function\");\n expect(typeof result.current.setResolveElicitation).toBe(\"function\");\n });\n\n it(\"provides a default elicitation handler\", () => {\n const { result } = renderHook(() => useElicitation());\n\n expect(typeof result.current.defaultElicitationHandler).toBe(\"function\");\n });\n\n describe(\"defaultElicitationHandler\", () => {\n it(\"sets elicitation state when called\", async () => {\n const { result } = renderHook(() => useElicitation());\n\n const request: Parameters<\n typeof result.current.defaultElicitationHandler\n >[0] = {\n params: {\n message: \"Please provide your name\",\n requestedSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Your name\" },\n },\n required: [\"name\"],\n },\n },\n };\n\n // Start the handler but don't await yet\n let handlerPromise: Promise<TamboElicitationResponse>;\n const extra = createMockExtra();\n act(() => {\n handlerPromise = result.current.defaultElicitationHandler(\n request,\n extra,\n );\n });\n\n // Elicitation should be set\n expect(result.current.elicitation).toEqual({\n message: \"Please provide your name\",\n requestedSchema: request.params.requestedSchema,\n signal: extra.signal,\n });\n\n // Resolve callback should be set\n expect(result.current.resolveElicitation).not.toBeNull();\n\n // Clean up by resolving\n act(() => {\n result.current.resolveElicitation?.({\n action: \"cancel\",\n });\n });\n\n await handlerPromise!;\n });\n\n it(\"resolves promise when resolveElicitation is called with accept\", async () => {\n const { result } = renderHook(() => useElicitation());\n\n const request: Parameters<\n typeof result.current.defaultElicitationHandler\n >[0] = {\n params: {\n message: \"Enter your email\",\n requestedSchema: {\n type: \"object\",\n properties: {\n email: {\n type: \"string\",\n format: \"email\",\n description: \"Email address\",\n },\n },\n },\n },\n };\n\n // Start the handler\n let handlerPromise: Promise<TamboElicitationResponse>;\n const extra = createMockExtra();\n act(() => {\n handlerPromise = result.current.defaultElicitationHandler(\n request,\n extra,\n );\n });\n\n // Resolve with accept\n const response: TamboElicitationResponse = {\n action: \"accept\",\n content: { email: \"test@example.com\" },\n };\n\n act(() => {\n result.current.resolveElicitation?.(response);\n });\n\n // Wait for promise to resolve\n const resolvedValue = await handlerPromise!;\n\n expect(resolvedValue).toEqual(response);\n });\n\n it(\"resolves promise when resolveElicitation is called with decline\", async () => {\n const { result } = renderHook(() => useElicitation());\n\n const request: Parameters<\n typeof result.current.defaultElicitationHandler\n >[0] = {\n params: {\n message: \"Provide input\",\n requestedSchema: {\n type: \"object\",\n properties: {\n value: { type: \"string\" },\n },\n },\n },\n };\n\n let handlerPromise: Promise<TamboElicitationResponse>;\n const extra = createMockExtra();\n act(() => {\n handlerPromise = result.current.defaultElicitationHandler(\n request,\n extra,\n );\n });\n\n const response: TamboElicitationResponse = {\n action: \"decline\",\n };\n\n act(() => {\n result.current.resolveElicitation?.(response);\n });\n\n const resolvedValue = await handlerPromise!;\n\n expect(resolvedValue).toEqual(response);\n });\n\n it(\"resolves promise when resolveElicitation is called with cancel\", async () => {\n const { result } = renderHook(() => useElicitation());\n\n const request: Parameters<\n typeof result.current.defaultElicitationHandler\n >[0] = {\n params: {\n message: \"Provide input\",\n requestedSchema: {\n type: \"object\",\n properties: {\n value: { type: \"string\" },\n },\n },\n },\n };\n\n let handlerPromise: Promise<TamboElicitationResponse>;\n const extra = createMockExtra();\n act(() => {\n handlerPromise = result.current.defaultElicitationHandler(\n request,\n extra,\n );\n });\n\n const response: TamboElicitationResponse = {\n action: \"cancel\",\n };\n\n act(() => {\n result.current.resolveElicitation?.(response);\n });\n\n const resolvedValue = await handlerPromise!;\n\n expect(resolvedValue).toEqual(response);\n });\n\n it(\"handles multiple sequential elicitations\", async () => {\n const { result } = renderHook(() => useElicitation());\n\n // First elicitation\n const request1: Parameters<\n typeof result.current.defaultElicitationHandler\n >[0] = {\n params: {\n message: \"First request\",\n requestedSchema: {\n type: \"object\",\n properties: {\n field1: { type: \"string\" },\n },\n },\n },\n };\n\n let promise1: Promise<TamboElicitationResponse>;\n const extra1 = createMockExtra();\n act(() => {\n promise1 = result.current.defaultElicitationHandler(request1, extra1);\n });\n\n expect(result.current.elicitation?.message).toBe(\"First request\");\n\n act(() => {\n result.current.resolveElicitation?.({\n action: \"accept\",\n content: { field1: \"value1\" },\n });\n });\n\n const result1 = await promise1!;\n expect(result1).toEqual({\n action: \"accept\",\n content: { field1: \"value1\" },\n });\n\n // Second elicitation\n const request2: Parameters<\n typeof result.current.defaultElicitationHandler\n >[0] = {\n params: {\n message: \"Second request\",\n requestedSchema: {\n type: \"object\",\n properties: {\n field2: { type: \"number\" },\n },\n },\n },\n };\n\n let promise2: Promise<TamboElicitationResponse>;\n const extra2 = createMockExtra();\n act(() => {\n promise2 = result.current.defaultElicitationHandler(request2, extra2);\n });\n\n expect(result.current.elicitation?.message).toBe(\"Second request\");\n\n act(() => {\n result.current.resolveElicitation?.({\n action: \"accept\",\n content: { field2: 42 },\n });\n });\n\n const result2 = await promise2!;\n expect(result2).toEqual({\n action: \"accept\",\n content: { field2: 42 },\n });\n });\n\n it(\"maintains stable handler reference across re-renders\", () => {\n const { result, rerender } = renderHook(() => useElicitation());\n\n const firstHandler = result.current.defaultElicitationHandler;\n\n rerender();\n\n const secondHandler = result.current.defaultElicitationHandler;\n\n expect(firstHandler).toBe(secondHandler);\n });\n });\n\n describe(\"state management\", () => {\n it(\"allows manual state updates via setElicitation\", () => {\n const { result } = renderHook(() => useElicitation());\n\n const customElicitation: TamboElicitationRequest = {\n message: \"Custom message\",\n requestedSchema: {\n type: \"object\",\n properties: {\n custom: { type: \"boolean\" },\n },\n },\n };\n\n act(() => {\n result.current.setElicitation(customElicitation);\n });\n\n expect(result.current.elicitation).toEqual(customElicitation);\n });\n\n it(\"allows clearing elicitation state\", () => {\n const { result } = renderHook(() => useElicitation());\n\n const elicitation: TamboElicitationRequest = {\n message: \"Test\",\n requestedSchema: {\n type: \"object\",\n properties: {},\n },\n };\n\n act(() => {\n result.current.setElicitation(elicitation);\n });\n\n expect(result.current.elicitation).not.toBeNull();\n\n act(() => {\n result.current.setElicitation(null);\n });\n\n expect(result.current.elicitation).toBeNull();\n });\n });\n});\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mcp-hooks.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-hooks.test.d.ts","sourceRoot":"","sources":["../../../src/mcp/__tests__/mcp-hooks.test.tsx"],"names":[],"mappings":""}