@tambo-ai/react 0.64.1 → 0.65.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +304 -327
- package/dist/hooks/use-tambo-threads.d.ts +0 -12
- package/dist/hooks/use-tambo-threads.d.ts.map +1 -1
- package/dist/hooks/use-tambo-threads.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/__tests__/elicitation.test.js +7 -3
- package/dist/mcp/__tests__/elicitation.test.js.map +1 -1
- package/dist/mcp/__tests__/mcp-hooks.test.js +149 -123
- package/dist/mcp/__tests__/mcp-hooks.test.js.map +1 -1
- package/dist/mcp/__tests__/tambo-mcp-provider.test.js +176 -120
- package/dist/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -1
- package/dist/mcp/__tests__/use-mcp-servers.test.js +12 -9
- package/dist/mcp/__tests__/use-mcp-servers.test.js.map +1 -1
- package/dist/mcp/elicitation.d.ts +4 -40
- package/dist/mcp/elicitation.d.ts.map +1 -1
- package/dist/mcp/elicitation.js +1 -1
- package/dist/mcp/elicitation.js.map +1 -1
- package/dist/mcp/index.d.ts +2 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +2 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/mcp-client.d.ts +14 -26
- package/dist/mcp/mcp-client.d.ts.map +1 -1
- package/dist/mcp/mcp-client.js +4 -7
- package/dist/mcp/mcp-client.js.map +1 -1
- package/dist/mcp/mcp-hooks.d.ts +27 -78
- package/dist/mcp/mcp-hooks.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.d.ts +27 -45
- package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.js +36 -87
- package/dist/mcp/tambo-mcp-provider.js.map +1 -1
- package/dist/model/mcp-server-info.d.ts +74 -0
- package/dist/model/mcp-server-info.d.ts.map +1 -0
- package/dist/model/mcp-server-info.js +29 -0
- package/dist/model/mcp-server-info.js.map +1 -0
- package/dist/providers/__tests__/tambo-thread-provider-initial-messages.test.js +22 -8
- package/dist/providers/__tests__/tambo-thread-provider-initial-messages.test.js.map +1 -1
- package/dist/providers/__tests__/tambo-thread-provider.test.js +318 -129
- package/dist/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +2 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/tambo-client-provider.d.ts +4 -0
- package/dist/providers/tambo-client-provider.d.ts.map +1 -1
- package/dist/providers/tambo-client-provider.js +3 -0
- package/dist/providers/tambo-client-provider.js.map +1 -1
- package/dist/providers/tambo-mcp-token-provider.d.ts +3 -0
- package/dist/providers/tambo-mcp-token-provider.d.ts.map +1 -1
- package/dist/providers/tambo-mcp-token-provider.js +11 -3
- package/dist/providers/tambo-mcp-token-provider.js.map +1 -1
- package/dist/providers/tambo-provider.d.ts +1 -0
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js +10 -5
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/providers/tambo-registry-provider.d.ts +37 -0
- package/dist/providers/tambo-registry-provider.d.ts.map +1 -1
- package/dist/providers/tambo-registry-provider.js +162 -2
- package/dist/providers/tambo-registry-provider.js.map +1 -1
- package/dist/providers/tambo-stubs.d.ts.map +1 -1
- package/dist/providers/tambo-stubs.js +10 -1
- package/dist/providers/tambo-stubs.js.map +1 -1
- package/esm/hooks/use-tambo-threads.d.ts +0 -12
- package/esm/hooks/use-tambo-threads.d.ts.map +1 -1
- package/esm/hooks/use-tambo-threads.js.map +1 -1
- package/esm/index.d.ts +3 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -2
- package/esm/index.js.map +1 -1
- package/esm/mcp/__tests__/elicitation.test.js +8 -4
- package/esm/mcp/__tests__/elicitation.test.js.map +1 -1
- package/esm/mcp/__tests__/mcp-hooks.test.js +149 -123
- package/esm/mcp/__tests__/mcp-hooks.test.js.map +1 -1
- package/esm/mcp/__tests__/tambo-mcp-provider.test.js +178 -122
- package/esm/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -1
- package/esm/mcp/__tests__/use-mcp-servers.test.js +12 -9
- package/esm/mcp/__tests__/use-mcp-servers.test.js.map +1 -1
- package/esm/mcp/elicitation.d.ts +4 -40
- package/esm/mcp/elicitation.d.ts.map +1 -1
- package/esm/mcp/elicitation.js +2 -2
- package/esm/mcp/elicitation.js.map +1 -1
- package/esm/mcp/index.d.ts +2 -1
- package/esm/mcp/index.d.ts.map +1 -1
- package/esm/mcp/index.js +1 -1
- package/esm/mcp/index.js.map +1 -1
- package/esm/mcp/mcp-client.d.ts +14 -26
- package/esm/mcp/mcp-client.d.ts.map +1 -1
- package/esm/mcp/mcp-client.js +3 -5
- package/esm/mcp/mcp-client.js.map +1 -1
- package/esm/mcp/mcp-hooks.d.ts +27 -78
- package/esm/mcp/mcp-hooks.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.d.ts +27 -45
- package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.js +35 -86
- package/esm/mcp/tambo-mcp-provider.js.map +1 -1
- package/esm/model/mcp-server-info.d.ts +74 -0
- package/esm/model/mcp-server-info.d.ts.map +1 -0
- package/esm/model/mcp-server-info.js +25 -0
- package/esm/model/mcp-server-info.js.map +1 -0
- package/esm/providers/__tests__/tambo-thread-provider-initial-messages.test.js +23 -9
- package/esm/providers/__tests__/tambo-thread-provider-initial-messages.test.js.map +1 -1
- package/esm/providers/__tests__/tambo-thread-provider.test.js +319 -130
- package/esm/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
- package/esm/providers/index.d.ts +1 -1
- package/esm/providers/index.d.ts.map +1 -1
- package/esm/providers/index.js +1 -1
- package/esm/providers/index.js.map +1 -1
- package/esm/providers/tambo-client-provider.d.ts +4 -0
- package/esm/providers/tambo-client-provider.d.ts.map +1 -1
- package/esm/providers/tambo-client-provider.js +3 -0
- package/esm/providers/tambo-client-provider.js.map +1 -1
- package/esm/providers/tambo-mcp-token-provider.d.ts +3 -0
- package/esm/providers/tambo-mcp-token-provider.d.ts.map +1 -1
- package/esm/providers/tambo-mcp-token-provider.js +13 -5
- package/esm/providers/tambo-mcp-token-provider.js.map +1 -1
- package/esm/providers/tambo-provider.d.ts +1 -0
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js +11 -6
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.d.ts +37 -0
- package/esm/providers/tambo-registry-provider.d.ts.map +1 -1
- package/esm/providers/tambo-registry-provider.js +161 -2
- package/esm/providers/tambo-registry-provider.js.map +1 -1
- package/esm/providers/tambo-stubs.d.ts.map +1 -1
- package/esm/providers/tambo-stubs.js +10 -1
- package/esm/providers/tambo-stubs.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1,42 +1,68 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>@tambo-ai/react</h1>
|
|
3
|
+
<h3>The core React SDK for generative UI</h3>
|
|
4
|
+
<p>Register your components once. The AI decides which to render and what props to pass based on user conversations.</p>
|
|
5
|
+
</div>
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/@tambo-ai/react"><img src="https://img.shields.io/npm/v/%40tambo-ai%2Freact?logo=npm" alt="npm version" /></a>
|
|
9
|
+
<a href="https://github.com/tambo-ai/tambo/blob/main/LICENSE"><img src="https://img.shields.io/github/license/tambo-ai/tambo" alt="License" /></a>
|
|
10
|
+
<a href="https://discord.gg/dJNvPEHth6"><img src="https://img.shields.io/discord/1251581895414911016?color=7289da&label=discord" alt="Discord"></a>
|
|
11
|
+
</p>
|
|
4
12
|
|
|
5
|
-
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://docs.tambo.co">Documentation</a> •
|
|
15
|
+
<a href="https://docs.tambo.co/api-reference">API Reference</a> •
|
|
16
|
+
<a href="https://discord.gg/dJNvPEHth6">Discord</a>
|
|
17
|
+
</p>
|
|
6
18
|
|
|
7
|
-
|
|
19
|
+
---
|
|
8
20
|
|
|
9
|
-
|
|
21
|
+
## Overview
|
|
10
22
|
|
|
11
|
-
|
|
23
|
+
The `@tambo-ai/react` package provides React hooks and providers for building generative UI applications. The AI dynamically decides which components to render and what props to pass based on natural language conversations.
|
|
12
24
|
|
|
13
|
-
|
|
14
|
-
npx tambo create-app my-tambo-app
|
|
15
|
-
```
|
|
25
|
+
**MCP-native** from the ground up — integrates the Model Context Protocol (MCP) for seamless integrations with databases, APIs, files, and external systems.
|
|
16
26
|
|
|
17
|
-
|
|
27
|
+
## Why Use This SDK?
|
|
18
28
|
|
|
19
|
-
|
|
29
|
+
You don't want to write 200 lines of boilerplate to show a chart.
|
|
20
30
|
|
|
21
|
-
|
|
31
|
+
Tambo handles:
|
|
22
32
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
- ✅ AI orchestration (which component to render)
|
|
34
|
+
- ✅ Streaming (progressive prop updates)
|
|
35
|
+
- ✅ State management (persistence across conversation)
|
|
36
|
+
- ✅ Error handling (retries, fallbacks)
|
|
37
|
+
- ✅ Tool coordination (MCP servers, local functions)
|
|
26
38
|
|
|
27
|
-
|
|
39
|
+
You write:
|
|
28
40
|
|
|
29
|
-
|
|
41
|
+
- Your existing React components
|
|
42
|
+
- Zod schemas for props
|
|
43
|
+
- React hooks for advanced AI features
|
|
30
44
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
45
|
+
That's the entire API.
|
|
46
|
+
|
|
47
|
+
## Key Benefits
|
|
34
48
|
|
|
35
|
-
|
|
49
|
+
- **No AI Expertise Needed** - If you can write React, you can build generative UIs
|
|
50
|
+
- **MCP-Native Architecture** - Built-in Model Context Protocol support
|
|
51
|
+
- **Bring Your Own LLM** - Works with OpenAI, Anthropic, Google, Mistral, or any OpenAI-compatible provider
|
|
52
|
+
- **Dual Build Output** - CommonJS and ESM modules for broad compatibility
|
|
53
|
+
- **Type-Safe** - Full TypeScript support with Zod schemas
|
|
36
54
|
|
|
37
|
-
|
|
55
|
+
## Installation
|
|
38
56
|
|
|
39
|
-
|
|
57
|
+
### Create New App
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx tambo create-app my-tambo-app
|
|
61
|
+
cd my-tambo-app
|
|
62
|
+
npm run dev
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Add to Existing Project
|
|
40
66
|
|
|
41
67
|
```bash
|
|
42
68
|
npm install @tambo-ai/react
|
|
@@ -44,333 +70,219 @@ npm install @tambo-ai/react
|
|
|
44
70
|
yarn add @tambo-ai/react
|
|
45
71
|
```
|
|
46
72
|
|
|
47
|
-
|
|
73
|
+
Then initialize:
|
|
48
74
|
|
|
49
|
-
|
|
75
|
+
```bash
|
|
76
|
+
npx tambo init
|
|
77
|
+
```
|
|
50
78
|
|
|
51
|
-
|
|
79
|
+
## Quick Start
|
|
52
80
|
|
|
53
81
|
```tsx
|
|
54
|
-
import {
|
|
55
|
-
|
|
82
|
+
import {
|
|
83
|
+
TamboProvider,
|
|
84
|
+
useTamboThread,
|
|
85
|
+
useTamboThreadInput,
|
|
86
|
+
} from "@tambo-ai/react";
|
|
87
|
+
import { z } from "zod";
|
|
56
88
|
|
|
57
|
-
|
|
89
|
+
// 1. Register your components
|
|
90
|
+
const components = [
|
|
58
91
|
{
|
|
59
92
|
name: "Graph",
|
|
60
|
-
description:
|
|
61
|
-
"A component that renders various types of charts (bar, line, pie) using Recharts. Supports customizable data visualization with labels, datasets, and styling options.",
|
|
93
|
+
description: "Displays data as charts (bar, line, pie)",
|
|
62
94
|
component: Graph,
|
|
63
|
-
propsSchema:
|
|
95
|
+
propsSchema: z.object({
|
|
96
|
+
data: z.array(z.object({ name: z.string(), value: z.number() })),
|
|
97
|
+
type: z.enum(["line", "bar", "pie"]),
|
|
98
|
+
}),
|
|
64
99
|
},
|
|
65
|
-
// Add more components
|
|
66
100
|
];
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### 2. Wrap your app in a TamboProvider
|
|
70
|
-
|
|
71
|
-
If you are using one of Tambo's pre-built components, you can wrap your app in a TamboProvider.
|
|
72
|
-
|
|
73
|
-
```tsx
|
|
74
|
-
import { TamboProvider } from "@tambo-ai/react";
|
|
75
|
-
import { MessageThreadFull } from "@/components/ui/message-thread-full";
|
|
76
|
-
|
|
77
|
-
// In your chat page
|
|
78
|
-
<TamboProvider
|
|
79
|
-
apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}
|
|
80
|
-
components={components}
|
|
81
|
-
>
|
|
82
|
-
<MessageThreadFull />
|
|
83
|
-
</TamboProvider>;
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
You can also use your own components with the TamboProvider:
|
|
87
|
-
|
|
88
|
-
```tsx
|
|
89
|
-
import { TamboProvider } from "@tambo-ai/react";
|
|
90
|
-
|
|
91
|
-
<TamboProvider
|
|
92
|
-
apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}
|
|
93
|
-
components={components}
|
|
94
|
-
>
|
|
95
|
-
<YourChatComponents />
|
|
96
|
-
</TamboProvider>;
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### 3. Render AI-generated components
|
|
100
|
-
|
|
101
|
-
This is also handled automatically for you if you are using the `MessageThreadFull` component.
|
|
102
|
-
|
|
103
|
-
For custom components rendered by Tambo, you can use the `useTamboCurrentMessage` hook inside the component to access the current message.
|
|
104
|
-
|
|
105
|
-
_Example (Tambo‑rendered custom component):_
|
|
106
101
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
export function TamboRenderedMessage() {
|
|
111
|
-
const message = useTamboCurrentMessage();
|
|
102
|
+
// 2. Wrap your app
|
|
103
|
+
function App() {
|
|
112
104
|
return (
|
|
113
|
-
<
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
) : (
|
|
120
|
-
<div key={i}>Non-text content: {part.type}</div>
|
|
121
|
-
),
|
|
122
|
-
)}
|
|
123
|
-
</div>
|
|
124
|
-
{/* If Tambo provided rendered output, include it */}
|
|
125
|
-
<div>{message.renderedComponent}</div>
|
|
126
|
-
</div>
|
|
105
|
+
<TamboProvider
|
|
106
|
+
apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}
|
|
107
|
+
components={components}
|
|
108
|
+
>
|
|
109
|
+
<ChatInterface />
|
|
110
|
+
</TamboProvider>
|
|
127
111
|
);
|
|
128
112
|
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
If you're rendering your own message list (outside of a Tambo‑rendered component), you can instead pass each `message` as a prop, as shown below:
|
|
132
113
|
|
|
133
|
-
|
|
134
|
-
|
|
114
|
+
// 3. Use hooks to build your UI
|
|
115
|
+
function ChatInterface() {
|
|
116
|
+
const { thread } = useTamboThread();
|
|
117
|
+
const { value, setValue, submit, isPending } = useTamboThreadInput();
|
|
135
118
|
|
|
136
|
-
function ChatHistory() {
|
|
137
|
-
const { thread } = useTambo();
|
|
138
119
|
return (
|
|
139
120
|
<div>
|
|
140
121
|
{thread.messages.map((message) => (
|
|
141
|
-
<
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
function CustomMessage({ message }: { message: TamboThreadMessage }) {
|
|
148
|
-
// Render the component
|
|
149
|
-
return (
|
|
150
|
-
<div>
|
|
151
|
-
{/* Render the message content */}
|
|
152
|
-
<div>Role: {message.role}</div>
|
|
153
|
-
<div>
|
|
154
|
-
{message.content.map((part, i) =>
|
|
155
|
-
part.type === "text" ? (
|
|
156
|
-
<div key={i}>{part.text}</div>
|
|
122
|
+
<div key={message.id}>
|
|
123
|
+
{Array.isArray(message.content) ? (
|
|
124
|
+
message.content.map((part, i) =>
|
|
125
|
+
part.type === "text" ? <p key={i}>{part.text}</p> : null,
|
|
126
|
+
)
|
|
157
127
|
) : (
|
|
158
|
-
<
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
<
|
|
128
|
+
<p>{String(message.content)}</p>
|
|
129
|
+
)}
|
|
130
|
+
{message.renderedComponent}
|
|
131
|
+
</div>
|
|
132
|
+
))}
|
|
133
|
+
<input value={value} onChange={(e) => setValue(e.target.value)} />
|
|
134
|
+
<button onClick={() => submit()} disabled={isPending}>
|
|
135
|
+
Send
|
|
136
|
+
</button>
|
|
164
137
|
</div>
|
|
165
138
|
);
|
|
166
139
|
}
|
|
167
140
|
```
|
|
168
141
|
|
|
169
|
-
|
|
142
|
+
[→ Full tutorial](https://docs.tambo.co/getting-started/quickstart)
|
|
170
143
|
|
|
171
|
-
|
|
144
|
+
## Core Concepts
|
|
172
145
|
|
|
173
|
-
|
|
146
|
+
### Component Registration
|
|
174
147
|
|
|
175
|
-
|
|
176
|
-
import { useTamboThreadInput } from "@tambo-ai/react";
|
|
148
|
+
Register React components with Zod schemas for type-safe props:
|
|
177
149
|
|
|
178
|
-
|
|
179
|
-
|
|
150
|
+
```tsx
|
|
151
|
+
import { type TamboComponent } from "@tambo-ai/react";
|
|
180
152
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
153
|
+
const components: TamboComponent[] = [
|
|
154
|
+
{
|
|
155
|
+
name: "WeatherCard",
|
|
156
|
+
description: "Displays weather information with temperature and conditions",
|
|
157
|
+
component: WeatherCard,
|
|
158
|
+
propsSchema: z.object({
|
|
159
|
+
location: z.string(),
|
|
160
|
+
temperature: z.number(),
|
|
161
|
+
condition: z.string(),
|
|
162
|
+
}),
|
|
163
|
+
},
|
|
164
|
+
];
|
|
192
165
|
```
|
|
193
166
|
|
|
194
|
-
|
|
167
|
+
[→ Learn more about components](https://docs.tambo.co/concepts/components)
|
|
168
|
+
|
|
169
|
+
### Provider Setup
|
|
170
|
+
|
|
171
|
+
Wrap your app with `TamboProvider` to enable AI capabilities:
|
|
195
172
|
|
|
196
173
|
```tsx
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
174
|
+
<TamboProvider
|
|
175
|
+
apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}
|
|
176
|
+
components={components}
|
|
177
|
+
tools={tools} // optional
|
|
178
|
+
userToken={userToken} // optional
|
|
179
|
+
>
|
|
180
|
+
<YourApp />
|
|
181
|
+
</TamboProvider>
|
|
205
182
|
```
|
|
206
183
|
|
|
207
|
-
|
|
184
|
+
[→ See all provider options](https://docs.tambo.co/api-reference/tambo-provider)
|
|
208
185
|
|
|
209
|
-
###
|
|
186
|
+
### Hooks
|
|
210
187
|
|
|
211
|
-
|
|
|
212
|
-
|
|
|
213
|
-
|
|
|
188
|
+
| Hook | Description |
|
|
189
|
+
| -------------------------- | -------------------------------------------------- |
|
|
190
|
+
| `useTamboThread()` | Access current thread and messages |
|
|
191
|
+
| `useTamboThreadInput()` | Handle user input and message submission |
|
|
192
|
+
| `useTamboCurrentMessage()` | Access current message context (inside components) |
|
|
193
|
+
| `useTamboComponentState()` | Persistent component state across renders |
|
|
194
|
+
| `useTamboStreamStatus()` | Monitor streaming status for progressive loading |
|
|
195
|
+
| `useTamboSuggestions()` | Generate contextual suggestions |
|
|
214
196
|
|
|
215
|
-
|
|
197
|
+
[→ API Reference](https://docs.tambo.co/api-reference)
|
|
216
198
|
|
|
217
|
-
|
|
199
|
+
## Key Features
|
|
218
200
|
|
|
219
|
-
|
|
201
|
+
### Generative Components
|
|
220
202
|
|
|
221
|
-
|
|
222
|
-
import { useTambo, useTamboThreadInput } from "@tambo-ai/react";
|
|
203
|
+
AI renders these once in response to user messages. Best for charts, data visualizations, and summary cards.
|
|
223
204
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
part.type === "text" ? (
|
|
237
|
-
<div key={i}>{part.text}</div>
|
|
238
|
-
) : (
|
|
239
|
-
<div key={i}>Non-text content: {part.type}</div>
|
|
240
|
-
),
|
|
241
|
-
)}
|
|
242
|
-
</div>
|
|
243
|
-
{message.renderedComponent}
|
|
244
|
-
</div>
|
|
245
|
-
))}
|
|
246
|
-
</div>
|
|
247
|
-
|
|
248
|
-
{/* Input form */}
|
|
249
|
-
<form
|
|
250
|
-
onSubmit={(e) => {
|
|
251
|
-
e.preventDefault();
|
|
252
|
-
submit();
|
|
253
|
-
}}
|
|
254
|
-
className="input-form"
|
|
255
|
-
>
|
|
256
|
-
<input
|
|
257
|
-
type="text"
|
|
258
|
-
value={value}
|
|
259
|
-
onChange={(e) => setValue(e.target.value)}
|
|
260
|
-
placeholder="Type your message..."
|
|
261
|
-
/>
|
|
262
|
-
<button type="submit">Send</button>
|
|
263
|
-
</form>
|
|
264
|
-
</div>
|
|
265
|
-
);
|
|
266
|
-
}
|
|
205
|
+
```tsx
|
|
206
|
+
const components: TamboComponent[] = [
|
|
207
|
+
{
|
|
208
|
+
name: "Graph",
|
|
209
|
+
description: "Displays data as charts",
|
|
210
|
+
component: Graph,
|
|
211
|
+
propsSchema: z.object({
|
|
212
|
+
data: z.array(z.object({ name: z.string(), value: z.number() })),
|
|
213
|
+
type: z.enum(["line", "bar", "pie"]),
|
|
214
|
+
}),
|
|
215
|
+
},
|
|
216
|
+
];
|
|
267
217
|
```
|
|
268
218
|
|
|
269
|
-
|
|
219
|
+
[→ Learn more about components](https://docs.tambo.co/concepts/components)
|
|
270
220
|
|
|
271
|
-
|
|
221
|
+
### Interactable Components
|
|
272
222
|
|
|
273
|
-
|
|
274
|
-
// components/WeatherCard.jsx
|
|
275
|
-
import { useTamboComponentState } from "@tambo-ai/react";
|
|
276
|
-
|
|
277
|
-
export function WeatherCard({
|
|
278
|
-
location,
|
|
279
|
-
temperature,
|
|
280
|
-
condition,
|
|
281
|
-
}: {
|
|
282
|
-
location: string;
|
|
283
|
-
temperature: number;
|
|
284
|
-
condition: string;
|
|
285
|
-
}) {
|
|
286
|
-
// useTamboComponentState manages state that persists even if
|
|
287
|
-
// the component is unmounted
|
|
288
|
-
const [isMetric, setIsMetric] = useTamboComponentState(
|
|
289
|
-
"isMetric", // unique identifier for this component's state
|
|
290
|
-
false, // default value
|
|
291
|
-
);
|
|
223
|
+
Components that persist on the page and update by ID across conversations. Perfect for shopping carts, spreadsheets, task boards, or dashboards.
|
|
292
224
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
225
|
+
```tsx
|
|
226
|
+
import { withInteractable } from "@tambo-ai/react";
|
|
227
|
+
|
|
228
|
+
const InteractableNote = withInteractable(Note, {
|
|
229
|
+
componentName: "Note",
|
|
230
|
+
description: "A note supporting title, content, and color modifications",
|
|
231
|
+
propsSchema: z.object({
|
|
232
|
+
title: z.string(),
|
|
233
|
+
content: z.string(),
|
|
234
|
+
color: z.enum(["white", "yellow", "blue", "green"]).optional(),
|
|
235
|
+
}),
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// Pre-place in your UI or let AI generate dynamically
|
|
239
|
+
<InteractableNote id="note-1" title="My Note" content="Content here" />;
|
|
309
240
|
```
|
|
310
241
|
|
|
311
|
-
|
|
242
|
+
[→ Learn more about interactable components](https://docs.tambo.co/concepts/components/interactable-components)
|
|
243
|
+
|
|
244
|
+
### MCP Integration
|
|
245
|
+
|
|
246
|
+
Connect to external systems using the Model Context Protocol:
|
|
312
247
|
|
|
313
248
|
```tsx
|
|
314
|
-
|
|
315
|
-
import { TamboProvider } from "@tambo-ai/react";
|
|
316
|
-
import { WeatherCard } from "./components/WeatherCard";
|
|
317
|
-
import { z } from "zod";
|
|
249
|
+
import { TamboMcpProvider, MCPTransport } from "@tambo-ai/react/mcp";
|
|
318
250
|
|
|
319
|
-
|
|
320
|
-
const components = [
|
|
251
|
+
const mcpServers = [
|
|
321
252
|
{
|
|
322
|
-
name: "
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
propsSchema: z.object({
|
|
326
|
-
temperature: z.number(),
|
|
327
|
-
condition: z.string(),
|
|
328
|
-
location: z.string(),
|
|
329
|
-
}),
|
|
253
|
+
name: "filesystem",
|
|
254
|
+
url: "http://localhost:3001/mcp",
|
|
255
|
+
transport: MCPTransport.HTTP,
|
|
330
256
|
},
|
|
331
257
|
];
|
|
332
258
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
</TamboProvider>
|
|
339
|
-
);
|
|
340
|
-
}
|
|
259
|
+
<TamboProvider components={components}>
|
|
260
|
+
<TamboMcpProvider mcpServers={mcpServers}>
|
|
261
|
+
<App />
|
|
262
|
+
</TamboMcpProvider>
|
|
263
|
+
</TamboProvider>;
|
|
341
264
|
```
|
|
342
265
|
|
|
343
|
-
|
|
266
|
+
Supports full MCP protocol: tools, prompts, elicitations, and sampling. Client-side or server-side execution.
|
|
267
|
+
|
|
268
|
+
[→ Learn more about MCP](https://docs.tambo.co/concepts/model-context-protocol)
|
|
344
269
|
|
|
345
|
-
|
|
270
|
+
### Local Tools
|
|
271
|
+
|
|
272
|
+
Write JavaScript functions that execute in your React app:
|
|
346
273
|
|
|
347
274
|
```tsx
|
|
348
|
-
import { TamboTool } from "@tambo-ai/react";
|
|
349
|
-
import { z } from "zod";
|
|
275
|
+
import { type TamboTool } from "@tambo-ai/react";
|
|
350
276
|
|
|
351
|
-
// Define your tools
|
|
352
277
|
const tools: TamboTool[] = [
|
|
353
278
|
{
|
|
354
279
|
name: "getWeather",
|
|
355
|
-
description: "Fetches
|
|
356
|
-
tool: async (location: string
|
|
357
|
-
|
|
358
|
-
const weather = await fetchWeatherData(location);
|
|
359
|
-
return {
|
|
360
|
-
temperature: weather.temp,
|
|
361
|
-
condition: weather.condition,
|
|
362
|
-
location: weather.city,
|
|
363
|
-
};
|
|
364
|
-
},
|
|
280
|
+
description: "Fetches weather data for a location",
|
|
281
|
+
tool: async (location: string) =>
|
|
282
|
+
fetch(`/api/weather?q=${location}`).then((r) => r.json()),
|
|
365
283
|
toolSchema: z
|
|
366
284
|
.function()
|
|
367
|
-
.args(
|
|
368
|
-
z.string().describe("Location name (city)"),
|
|
369
|
-
z
|
|
370
|
-
.string()
|
|
371
|
-
.optional()
|
|
372
|
-
.describe("Temperature units (celsius/fahrenheit)"),
|
|
373
|
-
)
|
|
285
|
+
.args(z.string())
|
|
374
286
|
.returns(
|
|
375
287
|
z.object({
|
|
376
288
|
temperature: z.number(),
|
|
@@ -381,15 +293,18 @@ const tools: TamboTool[] = [
|
|
|
381
293
|
},
|
|
382
294
|
];
|
|
383
295
|
|
|
384
|
-
|
|
385
|
-
<
|
|
386
|
-
<YourApp />
|
|
296
|
+
<TamboProvider tools={tools} components={components}>
|
|
297
|
+
<App />
|
|
387
298
|
</TamboProvider>;
|
|
388
299
|
```
|
|
389
300
|
|
|
301
|
+
**When to use:** DOM interactions, wrapping authenticated fetch requests, or accessing React state. Runs entirely in the browser.
|
|
302
|
+
|
|
303
|
+
[→ Learn more about tools](https://docs.tambo.co/concepts/tools)
|
|
304
|
+
|
|
390
305
|
#### Advanced: Transforming Tool Responses
|
|
391
306
|
|
|
392
|
-
|
|
307
|
+
For tools that return rich content (images, audio, mixed media), provide a `transformToContent` function:
|
|
393
308
|
|
|
394
309
|
```tsx
|
|
395
310
|
const tools: TamboTool[] = [
|
|
@@ -398,21 +313,12 @@ const tools: TamboTool[] = [
|
|
|
398
313
|
description: "Fetches image data with metadata",
|
|
399
314
|
tool: async (imageId: string) => {
|
|
400
315
|
const data = await fetchImageData(imageId);
|
|
401
|
-
return {
|
|
402
|
-
url: data.imageUrl,
|
|
403
|
-
description: data.description,
|
|
404
|
-
};
|
|
316
|
+
return { url: data.imageUrl, description: data.description };
|
|
405
317
|
},
|
|
406
318
|
toolSchema: z
|
|
407
319
|
.function()
|
|
408
|
-
.args(z.string()
|
|
409
|
-
.returns(
|
|
410
|
-
z.object({
|
|
411
|
-
url: z.string(),
|
|
412
|
-
description: z.string(),
|
|
413
|
-
}),
|
|
414
|
-
),
|
|
415
|
-
// Transform the tool response into content parts
|
|
320
|
+
.args(z.string())
|
|
321
|
+
.returns(z.object({ url: z.string(), description: z.string() })),
|
|
416
322
|
transformToContent: (result) => [
|
|
417
323
|
{ type: "text", text: result.description },
|
|
418
324
|
{ type: "image_url", image_url: { url: result.url } },
|
|
@@ -421,44 +327,115 @@ const tools: TamboTool[] = [
|
|
|
421
327
|
];
|
|
422
328
|
```
|
|
423
329
|
|
|
424
|
-
|
|
330
|
+
The MCP integration automatically uses `transformToContent` to pass through rich content.
|
|
425
331
|
|
|
426
|
-
###
|
|
332
|
+
### Streaming Status
|
|
333
|
+
|
|
334
|
+
Monitor streaming status for progressive loading:
|
|
427
335
|
|
|
428
336
|
```tsx
|
|
429
|
-
import {
|
|
430
|
-
import { TamboMcpProvider } from "@tambo-ai/react/mcp";
|
|
431
|
-
import { MCPTransport } from "@tambo-ai/react/mcp";
|
|
337
|
+
import { useTamboStreamStatus } from "@tambo-ai/react";
|
|
432
338
|
|
|
433
|
-
|
|
434
|
-
{
|
|
435
|
-
url: "https://mcp-server-1.com",
|
|
436
|
-
transport: MCPTransport.HTTP,
|
|
437
|
-
name: "mcp-server-1",
|
|
438
|
-
},
|
|
439
|
-
];
|
|
339
|
+
function LoadingComponent({ title, data }) {
|
|
340
|
+
const { streamStatus, propStatus } = useTamboStreamStatus();
|
|
440
341
|
|
|
441
|
-
//
|
|
442
|
-
<
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
</
|
|
342
|
+
// Show spinner until complete
|
|
343
|
+
if (!streamStatus.isSuccess) return <Spinner />;
|
|
344
|
+
|
|
345
|
+
// Or show each prop as it arrives
|
|
346
|
+
return (
|
|
347
|
+
<div>
|
|
348
|
+
{propStatus["title"]?.isSuccess && <h3>{title}</h3>}
|
|
349
|
+
{propStatus["data"]?.isSuccess && <Chart data={data} />}
|
|
350
|
+
</div>
|
|
351
|
+
);
|
|
352
|
+
}
|
|
450
353
|
```
|
|
451
354
|
|
|
452
|
-
[
|
|
355
|
+
[→ Learn more about streaming](https://docs.tambo.co/concepts/streaming/component-streaming-status)
|
|
453
356
|
|
|
454
|
-
|
|
357
|
+
### Additional Context
|
|
455
358
|
|
|
456
|
-
|
|
359
|
+
Send metadata about user state, app settings, or environment:
|
|
457
360
|
|
|
458
|
-
|
|
361
|
+
```tsx
|
|
362
|
+
const contextHelpers = {
|
|
363
|
+
selectedItems: () => ({
|
|
364
|
+
key: "selectedItems",
|
|
365
|
+
value: `User has selected: ${selectedItems.map((i) => i.name).join(", ")}`,
|
|
366
|
+
}),
|
|
367
|
+
currentPage: () => ({
|
|
368
|
+
key: "page",
|
|
369
|
+
value: window.location.pathname,
|
|
370
|
+
}),
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
<TamboProvider contextHelpers={contextHelpers} />;
|
|
374
|
+
```
|
|
459
375
|
|
|
460
|
-
|
|
376
|
+
[→ Learn more](https://docs.tambo.co/concepts/additional-context)
|
|
461
377
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
378
|
+
### Suggestions
|
|
379
|
+
|
|
380
|
+
Auto-generate contextual suggestions:
|
|
381
|
+
|
|
382
|
+
```tsx
|
|
383
|
+
import { useTamboSuggestions } from "@tambo-ai/react";
|
|
384
|
+
|
|
385
|
+
function SuggestionsList() {
|
|
386
|
+
const { suggestions, accept } = useTamboSuggestions({ maxSuggestions: 3 });
|
|
387
|
+
|
|
388
|
+
return suggestions.map((s) => (
|
|
389
|
+
<button key={s.id} onClick={() => accept(s)}>
|
|
390
|
+
{s.title}
|
|
391
|
+
</button>
|
|
392
|
+
));
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
[→ Learn more](https://docs.tambo.co/concepts/suggestions)
|
|
397
|
+
|
|
398
|
+
## When to Use This SDK
|
|
399
|
+
|
|
400
|
+
Use `@tambo-ai/react` directly when you need:
|
|
401
|
+
|
|
402
|
+
- **Custom implementations** - Build your own chat interface or UI patterns
|
|
403
|
+
- **Existing design systems** - Integrate with your component library
|
|
404
|
+
- **Fine-grained control** - Customize rendering, state, and behavior
|
|
405
|
+
- **Non-Next.js frameworks** - Works with any React setup
|
|
406
|
+
|
|
407
|
+
For quick starts with pre-built components, use:
|
|
408
|
+
|
|
409
|
+
- `npx tambo create-app` - Full-featured template with UI components
|
|
410
|
+
- [Tambo UI Library](https://ui.tambo.co) - Copy/paste production-ready components
|
|
411
|
+
|
|
412
|
+
## Build Output
|
|
413
|
+
|
|
414
|
+
This package provides dual build outputs for broad compatibility:
|
|
415
|
+
|
|
416
|
+
- **CommonJS** (`dist/`) - For Node.js and older bundlers
|
|
417
|
+
- **ESM** (`esm/`) - For modern bundlers and native ES modules
|
|
418
|
+
|
|
419
|
+
TypeScript definitions included for both outputs.
|
|
420
|
+
|
|
421
|
+
## Community & Support
|
|
422
|
+
|
|
423
|
+
- **Discord:** [Join our community](https://discord.gg/dJNvPEHth6) for help and discussions
|
|
424
|
+
- **GitHub:** [Star the repo](https://github.com/tambo-ai/tambo) and contribute
|
|
425
|
+
- **Showcase:** See [projects built with Tambo](https://github.com/tambo-ai/tambo#built-with-tambo)
|
|
426
|
+
|
|
427
|
+
## Documentation
|
|
428
|
+
|
|
429
|
+
- [Full Documentation](https://docs.tambo.co)
|
|
430
|
+
- [Getting Started Guide](https://docs.tambo.co/getting-started/quickstart)
|
|
431
|
+
- [API Reference](https://docs.tambo.co/api-reference)
|
|
432
|
+
- [Component Guides](https://docs.tambo.co/concepts/components)
|
|
433
|
+
- [UI Library](https://ui.tambo.co)
|
|
434
|
+
|
|
435
|
+
## License
|
|
436
|
+
|
|
437
|
+
MIT License - see [LICENSE](../LICENSE) for details.
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
**Note for AI/LLM agents:** For comprehensive documentation in a format optimized for language models, visit [docs.tambo.co/llms.txt](https://docs.tambo.co/llms.txt)
|