@tambo-ai/react 0.29.0 → 0.29.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.
Files changed (2) hide show
  1. package/README.md +170 -46
  2. package/package.json +12 -12
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
- # tambo-ai
1
+ # Tambo React SDK
2
2
 
3
- A React package for adding generative React UI components to your AI assistant, copilot, or agent.
3
+ Tambo allows AI models to dynamically render React components in response to user messages, enabling AI assistants to display interactive widgets, charts, forms, and other UI elements instead of just text. Tambo is a great way to add generative UI to your AI assistant, copilot, or agent.
4
+
5
+ This package provides react hooks to talk to the Tambo API and render custom components inline, but does not provide any UI components on its own. For pre-built UI components that use this package, see [tambo-ui](https://ui.tambo.co).
4
6
 
5
7
  ## Build with MCP and Generative UI
6
8
 
@@ -8,19 +10,54 @@ A React package for adding generative React UI components to your AI assistant,
8
10
 
9
11
  [Source code](https://github.com/tambo-ai/mcp-template)
10
12
 
11
- Create a new project using our MCP template:
13
+ ### Creating a new project
14
+
15
+ You can create a new project using our MCP template:
12
16
 
13
17
  ```bash
14
18
  npx tambo create-app -t mcp tambo-mcp-app
15
19
  ```
16
20
 
17
- ## How does tambo-ai work?
21
+ This will create a new nextjs project with Tambo pre-configured, and then step you through the process of setting up a Tambo project, including signing up for an API key, and adding it to `.env.local`.
22
+
23
+ ### Adding components to an existing project
24
+
25
+ If you have an existing project, you can add components to it. First, initialize your project:
26
+
27
+ ```bash
28
+ npx tambo init
29
+ ```
30
+
31
+ This will step you through the process of setting up a Tambo project, including signing up for an API key, and adding it to `.env.local`.
32
+
33
+ Then add components from our library to your project in the `components/ui` directory:
34
+
35
+ ```bash
36
+ npx tambo add message-thread-full
37
+ ```
38
+
39
+ See the complete component library at [ui.tambo.co](https://ui.tambo.co).
40
+
41
+ ### Manual installation
42
+
43
+ You can also install Tambo manually:
44
+
45
+ ```bash
46
+ npm install @tambo-ai/react
47
+ # or
48
+ yarn add @tambo-ai/react
49
+ ```
50
+
51
+ ## How does Tambo work?
18
52
 
19
- tambo-ai is a client-side registry of React components that can be used by an LLM.
53
+ Tambo uses a client-side registry of React components that can be used by an LLM.
20
54
 
21
55
  ### 1. Register your components
22
56
 
23
57
  ```tsx
58
+ import { type TamboComponent } from "@tambo-ai/react";
59
+ import { Graph, graphSchema } from "@/components/ui/graph";
60
+
24
61
  const components: TamboComponent[] = [
25
62
  {
26
63
  name: "Graph",
@@ -35,50 +72,120 @@ const components: TamboComponent[] = [
35
72
 
36
73
  ### 2. Wrap your app in a TamboProvider
37
74
 
75
+ If you are using one of Tambo's pre-built components, you can wrap your app in a TamboProvider.
76
+
38
77
  ```tsx
78
+ import { TamboProvider } from "@tambo-ai/react";
79
+ import { MessageThreadFull } from "@/components/ui/message-thread-full";
80
+
39
81
  // In your chat page
40
82
  <TamboProvider
41
83
  apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}
42
84
  components={components}
43
85
  >
44
- <MessageThreadFull contextKey="tambo-template" />
45
- </TamboProvider>
86
+ <MessageThreadFull />
87
+ </TamboProvider>;
46
88
  ```
47
89
 
48
- ### 3. Submit user messages
90
+ You can also use your own components with the TamboProvider:
49
91
 
50
92
  ```tsx
51
- const { submit } = useTamboThreadInput(contextKey);
93
+ import { TamboProvider } from "@tambo-ai/react";
52
94
 
53
- await submit({
54
- contextKey,
55
- streamResponse: true,
56
- });
95
+ <TamboProvider
96
+ apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}
97
+ components={components}
98
+ >
99
+ <YourChatComponents />
100
+ </TamboProvider>;
57
101
  ```
58
102
 
59
- ### 4. Render AI-generated components
103
+ ### 3. Render AI-generated components
104
+
105
+ This is also handled automatically for you if you are using the `MessageThreadFull` component.
106
+
107
+ For custom components, you can use the `useMessageContext` hook to get the current message.
60
108
 
61
109
  ```tsx
62
- const { message } = useMessageContext();
110
+ import {
111
+ useTambo,
112
+ useMessageContext,
113
+ type TamboThreadMessage,
114
+ } from "@tambo-ai/react";
115
+
116
+ function ChatHistory() {
117
+ const { thread } = useTambo();
118
+ return (
119
+ <div>
120
+ {thread.messages.map((message) => (
121
+ <CustomMessage key={message.id} message={message} />
122
+ ))}
123
+ </div>
124
+ );
125
+ }
63
126
 
64
- // Render the component
65
- <div>{message.renderedComponent}</div>;
127
+ function CustomMessage({ message }: { message: TamboThreadMessage }) {
128
+ // Render the component
129
+ return (
130
+ <div>
131
+ {/* Render the message content */}
132
+ <div>Role: {message.role}</div>
133
+ <div>
134
+ {message.content.map((part) =>
135
+ part.type === "text" ? (
136
+ <div key={part.id}>{part.text}</div>
137
+ ) : (
138
+ <div key={part.id}>Non-text content: {part.type}</div>
139
+ ),
140
+ )}
141
+ </div>
142
+ {/* Render the component, if any */}
143
+ <div>{message.renderedComponent}</div>
144
+ </div>
145
+ );
146
+ }
66
147
  ```
67
148
 
68
- We provide components that use these hooks for you in our templates and in our component library at [ui.tambo.co](https://ui.tambo.co).
149
+ ### 4. Submit user messages
69
150
 
70
- ## Getting Started
151
+ If you are using the `MessageThreadFull` component, you can skip this step, it is handled automatically.
71
152
 
72
- ### Quick Start
153
+ If you are using a custom component, you can use the `useTamboThreadInput` hook to submit user messages.
73
154
 
74
- Create a new tambo app:
155
+ ```tsx
156
+ import { useTamboThreadInput } from "@tambo-ai/react";
75
157
 
76
- ```bash
77
- npm create tambo-app my-tambo-app
78
- cd my-tambo-app
79
- npm run dev
158
+ function ChatInput() {
159
+ const { submit, value, setValue } = useTamboThreadInput();
160
+
161
+ return (
162
+ <div>
163
+ <input
164
+ type="text"
165
+ value={value}
166
+ onChange={(e) => setValue(e.target.value)}
167
+ />
168
+ <button onClick={() => submit()}>Send</button>
169
+ </div>
170
+ );
171
+ }
80
172
  ```
81
173
 
174
+ ### 5. Put it all together
175
+
176
+ ```tsx
177
+ function ChatInterface() {
178
+ return (
179
+ <div>
180
+ <ChatHistory />
181
+ <ChatInput />
182
+ </div>
183
+ );
184
+ }
185
+ ```
186
+
187
+ ## Getting Started
188
+
82
189
  ### Templates
83
190
 
84
191
  | App | Description |
@@ -89,11 +196,11 @@ npm run dev
89
196
 
90
197
  Check out our UI library [tambo-ui](https://ui.tambo.co) for components that leverage tambo.
91
198
 
92
- ### Basic Usage
199
+ ### In depth examples
93
200
 
94
201
  #### 1. Displaying a message thread:
95
202
 
96
- ```jsx
203
+ ```tsx
97
204
  import { useTambo, useTamboThreadInput } from "@tambo-ai/react";
98
205
 
99
206
  function ChatInterface() {
@@ -107,7 +214,7 @@ function ChatInterface() {
107
214
  {thread.messages.map((message, index) => (
108
215
  <div key={index} className={`message ${message.role}`}>
109
216
  <div>{message.content}</div>
110
- {message.component && message.component.renderedComponent}
217
+ {message.renderedComponent}
111
218
  </div>
112
219
  ))}
113
220
  </div>
@@ -137,29 +244,39 @@ function ChatInterface() {
137
244
 
138
245
  Create components that can be dynamically generated by the AI:
139
246
 
140
- ```jsx
247
+ ```tsx
141
248
  // components/WeatherCard.jsx
142
249
  import { useTamboComponentState } from "@tambo-ai/react";
143
250
 
144
- export function WeatherCard() {
145
- const [weatherState, setWeatherState, { isPending }] = useTamboComponentState(
146
- "weather",
147
- {
148
- temperature: 0,
149
- condition: "",
150
- location: "",
151
- },
251
+ export function WeatherCard({
252
+ location,
253
+ temperature,
254
+ condition,
255
+ }: {
256
+ location: string;
257
+ temperature: number;
258
+ condition: string;
259
+ }) {
260
+ // useTamboComponentState manages state that persists even if
261
+ // the component is unmounted
262
+ const [isMetric, setIsMetric] = useTamboComponentState(
263
+ "isMetric", // unique identifier for this component's state
264
+ false, // default value
152
265
  );
153
266
 
154
- if (isPending) {
155
- return <div>Loading weather data...</div>;
156
- }
157
-
158
267
  return (
159
268
  <div>
160
- <h3>{weatherState.location}</h3>
161
- <div>{weatherState.temperature}°C</div>
162
- <div>{weatherState.condition}</div>
269
+ <h3>{location}</h3>
270
+ <div>
271
+ {isMetric ? temperature : (temperature * 1.8 + 32).toFixed(1)}°
272
+ {isMetric ? "C" : "F"}
273
+ </div>
274
+ <div>{condition}</div>
275
+ <input
276
+ type="checkbox"
277
+ checked={isMetric}
278
+ onChange={(e) => setIsMetric(e.target.checked)}
279
+ />
163
280
  </div>
164
281
  );
165
282
  }
@@ -167,7 +284,7 @@ export function WeatherCard() {
167
284
 
168
285
  #### 3. Register your components:
169
286
 
170
- ```jsx
287
+ ```tsx
171
288
  // App.jsx
172
289
  import { TamboProvider } from "@tambo-ai/react";
173
290
  import { WeatherCard } from "./components/WeatherCard";
@@ -201,7 +318,11 @@ function App() {
201
318
 
202
319
  Register tools to make them available to the AI:
203
320
 
204
- ```jsx
321
+ ```tsx
322
+ import { TamboTool } from "@tambo-ai/react";
323
+ import { z } from "zod";
324
+
325
+ // Define your tools
205
326
  const tools: TamboTool[] = [
206
327
  {
207
328
  name: "getWeather",
@@ -243,6 +364,9 @@ const tools: TamboTool[] = [
243
364
  ### Using MCP Servers
244
365
 
245
366
  ```tsx
367
+ import { TamboProvider } from "@tambo-ai/react";
368
+ import { TamboMcpProvider } from "@tambo-ai/react/mcp";
369
+
246
370
  const mcpServers = [
247
371
  {
248
372
  url: "https://mcp-server-1.com",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tambo-ai/react",
3
- "version": "0.29.0",
3
+ "version": "0.29.1",
4
4
  "description": "React client package for Tambo AI",
5
5
  "repository": {
6
6
  "type": "git",
@@ -67,41 +67,41 @@
67
67
  "react-dom": "^18.0.0 || ^19.0.0"
68
68
  },
69
69
  "dependencies": {
70
- "@modelcontextprotocol/sdk": "^1.12.0",
70
+ "@modelcontextprotocol/sdk": "^1.12.1",
71
71
  "@tambo-ai/typescript-sdk": "^0.52.0",
72
- "@tanstack/react-query": "^5.77.2",
72
+ "@tanstack/react-query": "^5.80.6",
73
73
  "partial-json": "^0.1.7",
74
74
  "react-fast-compare": "^3.2.2",
75
- "ts-essentials": "^10.0.4",
76
- "use-debounce": "^10.0.4",
77
- "zod": "^3.25.28",
75
+ "ts-essentials": "^10.1.0",
76
+ "use-debounce": "^10.0.5",
77
+ "zod": "^3.25.56",
78
78
  "zod-to-json-schema": "^3.24.5"
79
79
  },
80
80
  "devDependencies": {
81
- "@eslint/js": "^9.27.0",
81
+ "@eslint/js": "^9.28.0",
82
82
  "@tambo-ai/eslint-config": "*",
83
83
  "@tambo-ai/typescript-config": "*",
84
84
  "@testing-library/jest-dom": "^6.4.2",
85
85
  "@testing-library/react": "^16.3.0",
86
86
  "@types/jest": "^29.5.12",
87
87
  "@types/json-schema": "^7.0.15",
88
- "@types/node": "^20.17.50",
88
+ "@types/node": "^20.19.0",
89
89
  "@types/react": "^18.3.12",
90
90
  "@types/react-dom": "^18.3.5",
91
91
  "concurrently": "^9.1.2",
92
- "eslint": "^9.27.0",
93
- "eslint-plugin-jsdoc": "^50.6.17",
92
+ "eslint": "^9.28.0",
93
+ "eslint-plugin-jsdoc": "^50.7.1",
94
94
  "eslint-plugin-react": "^7.37.5",
95
95
  "eslint-plugin-react-hooks": "^5.1.0",
96
96
  "jest": "^29.7.0",
97
97
  "jest-environment-jsdom": "^29.7.0",
98
- "lint-staged": "^16.0.0",
98
+ "lint-staged": "^16.1.0",
99
99
  "prettier": "^3.4.2",
100
100
  "prettier-2": "npm:prettier@^2",
101
101
  "react": "^18.3.1",
102
102
  "react-dom": "^18.3.1",
103
103
  "ts-jest": "^29.3.4",
104
104
  "typescript": "^5.8.3",
105
- "typescript-eslint": "^8.32.1"
105
+ "typescript-eslint": "^8.34.0"
106
106
  }
107
107
  }