@lantos1618/better-ui 0.2.3 → 0.4.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 (83) hide show
  1. package/README.md +271 -354
  2. package/dist/ThemeProvider-BYeqWMsn.d.mts +187 -0
  3. package/dist/ThemeProvider-BaVZaDBO.d.ts +187 -0
  4. package/dist/auth/index.d.mts +56 -0
  5. package/dist/auth/index.d.ts +56 -0
  6. package/dist/auth/index.js +104 -0
  7. package/dist/auth/index.mjs +67 -0
  8. package/dist/chunk-Y6FXYEAI.mjs +10 -0
  9. package/dist/components/index.d.mts +258 -0
  10. package/dist/components/index.d.ts +258 -0
  11. package/dist/components/index.js +1977 -0
  12. package/dist/components/index.mjs +1922 -0
  13. package/dist/index.d.mts +75 -0
  14. package/dist/index.d.ts +75 -0
  15. package/dist/index.js +587 -0
  16. package/dist/index.mjs +557 -0
  17. package/dist/persistence/index.d.mts +11 -0
  18. package/dist/persistence/index.d.ts +11 -0
  19. package/dist/persistence/index.js +66 -0
  20. package/dist/persistence/index.mjs +41 -0
  21. package/dist/react/index.d.mts +91 -0
  22. package/dist/react/index.d.ts +91 -0
  23. package/dist/react/index.js +284 -0
  24. package/dist/react/index.mjs +257 -0
  25. package/dist/tool-Ca2x-VNK.d.mts +361 -0
  26. package/dist/tool-Ca2x-VNK.d.ts +361 -0
  27. package/dist/types-CAOfGUPH.d.mts +31 -0
  28. package/dist/types-CAOfGUPH.d.ts +31 -0
  29. package/package.json +85 -30
  30. package/src/theme.css +101 -0
  31. package/lib/aui/README.md +0 -136
  32. package/lib/aui/__tests__/aui-complete.test.ts +0 -251
  33. package/lib/aui/__tests__/aui-comprehensive.test.ts +0 -376
  34. package/lib/aui/__tests__/aui-concise.test.ts +0 -278
  35. package/lib/aui/__tests__/aui-integration.test.ts +0 -309
  36. package/lib/aui/__tests__/aui-simple.test.ts +0 -116
  37. package/lib/aui/__tests__/aui.test.ts +0 -269
  38. package/lib/aui/__tests__/concise-api.test.ts +0 -165
  39. package/lib/aui/__tests__/core.test.ts +0 -265
  40. package/lib/aui/__tests__/simple-api.test.ts +0 -200
  41. package/lib/aui/ai-assistant.ts +0 -408
  42. package/lib/aui/ai-control.ts +0 -353
  43. package/lib/aui/client/use-aui.ts +0 -55
  44. package/lib/aui/client-control.ts +0 -551
  45. package/lib/aui/client-executor.ts +0 -417
  46. package/lib/aui/components/ToolRenderer.tsx +0 -22
  47. package/lib/aui/core.ts +0 -137
  48. package/lib/aui/demo.tsx +0 -89
  49. package/lib/aui/examples/ai-complete-demo.tsx +0 -359
  50. package/lib/aui/examples/ai-control-demo.tsx +0 -356
  51. package/lib/aui/examples/ai-control-tools.ts +0 -308
  52. package/lib/aui/examples/concise-api.tsx +0 -153
  53. package/lib/aui/examples/index.tsx +0 -163
  54. package/lib/aui/examples/quick-demo.tsx +0 -91
  55. package/lib/aui/examples/simple-demo.tsx +0 -71
  56. package/lib/aui/examples/simple-tools.tsx +0 -160
  57. package/lib/aui/examples/user-api.tsx +0 -208
  58. package/lib/aui/examples/user-requested.tsx +0 -174
  59. package/lib/aui/examples/weather-search-tools.tsx +0 -119
  60. package/lib/aui/examples.tsx +0 -367
  61. package/lib/aui/hooks/useAUITool.ts +0 -142
  62. package/lib/aui/hooks/useAUIToolEnhanced.ts +0 -343
  63. package/lib/aui/hooks/useAUITools.ts +0 -195
  64. package/lib/aui/index.ts +0 -156
  65. package/lib/aui/provider.tsx +0 -45
  66. package/lib/aui/server-control.ts +0 -386
  67. package/lib/aui/server-executor.ts +0 -165
  68. package/lib/aui/server.ts +0 -167
  69. package/lib/aui/tool-registry.ts +0 -380
  70. package/lib/aui/tools/advanced-examples.tsx +0 -86
  71. package/lib/aui/tools/ai-complete.ts +0 -375
  72. package/lib/aui/tools/api-tools.tsx +0 -230
  73. package/lib/aui/tools/data-tools.tsx +0 -232
  74. package/lib/aui/tools/dom-tools.tsx +0 -202
  75. package/lib/aui/tools/examples.ts +0 -43
  76. package/lib/aui/tools/file-tools.tsx +0 -202
  77. package/lib/aui/tools/form-tools.tsx +0 -233
  78. package/lib/aui/tools/index.ts +0 -8
  79. package/lib/aui/tools/navigation-tools.tsx +0 -172
  80. package/lib/aui/tools/notification-tools.ts +0 -213
  81. package/lib/aui/tools/state-tools.tsx +0 -209
  82. package/lib/aui/types.ts +0 -47
  83. package/lib/aui/vercel-ai.ts +0 -100
package/README.md CHANGED
@@ -1,457 +1,374 @@
1
- # Better UI - AUI (Assistant-UI) System
1
+ # Better UI
2
2
 
3
- > A powerful, type-safe tool system for Next.js that enables AI assistants to control both frontend and backend operations through a fluent API.
3
+ > A minimal, type-safe AI-first UI framework for building tools
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@lantos1618/better-ui.svg)](https://www.npmjs.com/package/@lantos1618/better-ui)
6
6
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
7
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue)](https://www.typescriptlang.org/)
8
- [![Next.js](https://img.shields.io/badge/Next.js-15.5-black)](https://nextjs.org/)
9
8
 
10
- ## 🎯 What is Better UI?
9
+ ## What is Better UI?
11
10
 
12
- Better UI is an **AI-first UI framework** that revolutionizes how AI assistants interact with web applications. It provides a clean, type-safe abstraction layer that allows AI models to execute both frontend and backend operations seamlessly.
11
+ Better UI provides a clean, fluent API for creating tools that AI assistants can execute. Define input/output schemas with Zod, implement server and client logic separately, and render results with React components.
13
12
 
14
- ### Key Benefits
13
+ **Key differentiators**:
14
+ - **View integration** - tools render their own results in UI (no other framework does this)
15
+ - **Multi-provider support** - OpenAI, Anthropic, Google Gemini, OpenRouter
16
+ - **Streaming tool views** - progressive partial data rendering
17
+ - **Pre-made chat components** - drop-in `<Chat />` with automatic tool view rendering
18
+ - **Server infrastructure** - rate limiting, caching, Next.js/Express adapters
15
19
 
16
- - **🚀 Minimal Boilerplate**: Create powerful tools with just 2 required methods
17
- - **🔒 Type Safety**: Full TypeScript + Zod schema validation
18
- - **🎨 AI-Native**: Built specifically for AI assistants to control applications
19
- - **⚡ Performance**: Smart client-side caching and optimization
20
- - **🔧 Extensible**: Easy to create custom tools for any use case
21
-
22
- ## 📦 Installation
20
+ ## Installation
23
21
 
24
22
  ```bash
25
- npm install @lantos1618/better-ui
26
- # or
27
- yarn add @lantos1618/better-ui
28
- # or
29
- bun add @lantos1618/better-ui
23
+ npm install @lantos1618/better-ui zod
30
24
  ```
31
25
 
32
- ## 🚀 Quick Start
33
-
34
- ### 1. Simple Tool (2 methods only!)
26
+ ## Quick Start
35
27
 
36
- ```tsx
37
- import { aui } from '@lantos1618/better-ui';
28
+ ```typescript
29
+ import { tool } from '@lantos1618/better-ui';
38
30
  import { z } from 'zod';
39
31
 
40
- const weatherTool = aui
41
- .tool('weather')
42
- .input(z.object({ city: z.string() }))
43
- .execute(async ({ input }) => ({ temp: 72, city: input.city }))
44
- .render(({ data }) => <div>{data.city}: {data.temp}°</div>);
45
- ```
32
+ const weather = tool({
33
+ name: 'weather',
34
+ description: 'Get weather for a city',
35
+ input: z.object({ city: z.string() }),
36
+ output: z.object({ temp: z.number(), condition: z.string() }),
37
+ });
46
38
 
47
- ### 2. Advanced Tool with Client Optimization
39
+ // Server implementation (runs on server)
40
+ weather.server(async ({ city }) => {
41
+ const data = await weatherAPI.get(city);
42
+ return { temp: data.temp, condition: data.condition };
43
+ });
48
44
 
49
- ```tsx
50
- const searchTool = aui
51
- .tool('search')
52
- .input(z.object({ query: z.string() }))
53
- .execute(async ({ input }) => db.search(input.query))
54
- .clientExecute(async ({ input, ctx }) => {
55
- // Optional: Add caching, offline support, optimistic updates
56
- const cached = ctx.cache.get(input.query);
57
- return cached || ctx.fetch('/api/tools/search', { body: input });
58
- })
59
- .render(({ data }) => <SearchResults results={data} />);
45
+ // View for rendering results (our differentiator!)
46
+ weather.view((data) => (
47
+ <div className="weather-card">
48
+ <span>{data.temp}</span>
49
+ <span>{data.condition}</span>
50
+ </div>
51
+ ));
60
52
  ```
61
53
 
62
- ## 💻 AI SDK Integration (Vercel AI SDK)
63
-
64
- Better UI seamlessly integrates with Vercel's AI SDK for building chat interfaces:
65
-
66
- ### Basic Chat Integration
54
+ ## Drop-in Chat UI
67
55
 
68
56
  ```tsx
69
- // app/api/chat/route.ts
70
- import { openai } from '@ai-sdk/openai';
71
- import { streamText, convertToCoreMessages } from 'ai';
72
- import { aui } from '@lantos1618/better-ui';
73
- import { z } from 'zod';
74
-
75
- // Define your tools
76
- const weatherTool = aui
77
- .tool('getWeather')
78
- .description('Get current weather for a city')
79
- .input(z.object({
80
- city: z.string().describe('City name'),
81
- unit: z.enum(['celsius', 'fahrenheit']).optional()
82
- }))
83
- .execute(async ({ input }) => {
84
- // Fetch real weather data
85
- const response = await fetch(`https://api.weather.com/v1/weather?city=${input.city}`);
86
- return response.json();
87
- });
88
-
89
- const stockTool = aui
90
- .tool('getStockPrice')
91
- .description('Get current stock price')
92
- .input(z.object({
93
- symbol: z.string().describe('Stock symbol (e.g., AAPL)')
94
- }))
95
- .execute(async ({ input }) => {
96
- const response = await fetch(`https://api.stocks.com/v1/quote/${input.symbol}`);
97
- return response.json();
98
- });
99
-
100
- // Convert to AI SDK format
101
- const tools = {
102
- getWeather: weatherTool.toAISDKTool(),
103
- getStockPrice: stockTool.toAISDKTool(),
104
- };
105
-
106
- export async function POST(req: Request) {
107
- const { messages } = await req.json();
108
-
109
- const result = await streamText({
110
- model: openai('gpt-4'),
111
- messages: convertToCoreMessages(messages),
112
- tools,
113
- maxToolRoundtrips: 5,
114
- });
57
+ import { Chat } from '@lantos1618/better-ui/components';
115
58
 
116
- return result.toDataStreamResponse();
59
+ function App() {
60
+ return (
61
+ <Chat
62
+ endpoint="/api/chat"
63
+ tools={{ weather, search, counter }}
64
+ className="h-[600px]"
65
+ placeholder="Ask something..."
66
+ />
67
+ );
117
68
  }
118
69
  ```
119
70
 
120
- ### React Chat Component
71
+ Or compose your own layout:
121
72
 
122
73
  ```tsx
123
- // app/chat/page.tsx
124
- 'use client';
125
-
126
- import { useChat } from 'ai/react';
127
- import { ToolExecutorProvider, ToolRenderer } from '@lantos1618/better-ui/client';
128
-
129
- export default function ChatPage() {
130
- const { messages, input, handleInputChange, handleSubmit } = useChat();
74
+ import { ChatProvider, Thread, Composer } from '@lantos1618/better-ui/components';
131
75
 
76
+ function App() {
132
77
  return (
133
- <ToolExecutorProvider tools={[weatherTool, stockTool]}>
78
+ <ChatProvider endpoint="/api/chat" tools={tools}>
134
79
  <div className="flex flex-col h-screen">
135
- <div className="flex-1 overflow-y-auto p-4">
136
- {messages.map((message) => (
137
- <div key={message.id} className="mb-4">
138
- <div className="font-bold">{message.role}:</div>
139
- <div>{message.content}</div>
140
-
141
- {/* Render tool calls with Better UI */}
142
- {message.toolInvocations?.map((toolCall) => (
143
- <ToolRenderer
144
- key={toolCall.toolCallId}
145
- toolCall={toolCall}
146
- tool={tools[toolCall.toolName]}
147
- />
148
- ))}
149
- </div>
150
- ))}
151
- </div>
152
-
153
- <form onSubmit={handleSubmit} className="p-4 border-t">
154
- <input
155
- value={input}
156
- onChange={handleInputChange}
157
- placeholder="Ask about weather or stocks..."
158
- className="w-full p-2 border rounded"
159
- />
160
- </form>
80
+ <Thread className="flex-1 overflow-y-auto" />
81
+ <Composer placeholder="Type a message..." />
161
82
  </div>
162
- </ToolExecutorProvider>
83
+ </ChatProvider>
163
84
  );
164
85
  }
165
86
  ```
166
87
 
167
- ### Advanced Chat with Multiple Tools
88
+ Tool results in chat automatically render using the tool's `.view()` component.
168
89
 
169
- ```tsx
170
- // lib/ai-tools.ts
171
- import { aui } from '@lantos1618/better-ui';
172
- import { z } from 'zod';
90
+ ## Multi-Provider Support
173
91
 
174
- // Database search tool
175
- export const searchDatabaseTool = aui
176
- .tool('searchDatabase')
177
- .description('Search internal database')
178
- .input(z.object({
179
- query: z.string(),
180
- filters: z.object({
181
- category: z.string().optional(),
182
- dateRange: z.object({
183
- start: z.string().optional(),
184
- end: z.string().optional(),
185
- }).optional(),
186
- }).optional(),
187
- }))
188
- .execute(async ({ input }) => {
189
- // Your database logic
190
- return await db.search(input.query, input.filters);
191
- })
192
- .clientExecute(async ({ input, ctx }) => {
193
- // Client-side caching
194
- const cacheKey = JSON.stringify(input);
195
- const cached = ctx.cache.get(cacheKey);
196
- if (cached && Date.now() - cached.timestamp < 60000) {
197
- return cached.data;
198
- }
199
-
200
- const result = await ctx.fetch('/api/search', {
201
- method: 'POST',
202
- body: JSON.stringify(input)
203
- });
204
-
205
- ctx.cache.set(cacheKey, { data: result, timestamp: Date.now() });
206
- return result;
207
- })
208
- .render(({ data }) => (
209
- <div className="grid gap-2">
210
- {data.results.map((item) => (
211
- <div key={item.id} className="p-2 border rounded">
212
- <h3>{item.title}</h3>
213
- <p>{item.description}</p>
214
- </div>
215
- ))}
216
- </div>
217
- ));
218
-
219
- // Chart generation tool
220
- export const createChartTool = aui
221
- .tool('createChart')
222
- .description('Generate interactive charts')
223
- .input(z.object({
224
- type: z.enum(['line', 'bar', 'pie', 'scatter']),
225
- data: z.array(z.object({
226
- label: z.string(),
227
- value: z.number(),
228
- })),
229
- title: z.string().optional(),
230
- }))
231
- .execute(async ({ input }) => input)
232
- .render(({ data }) => (
233
- <ChartComponent type={data.type} data={data.data} title={data.title} />
234
- ));
235
-
236
- // Form generation tool
237
- export const generateFormTool = aui
238
- .tool('generateForm')
239
- .description('Create dynamic forms')
240
- .input(z.object({
241
- fields: z.array(z.object({
242
- name: z.string(),
243
- type: z.enum(['text', 'number', 'email', 'select', 'checkbox']),
244
- label: z.string(),
245
- required: z.boolean().optional(),
246
- options: z.array(z.string()).optional(),
247
- })),
248
- submitUrl: z.string(),
249
- }))
250
- .execute(async ({ input }) => input)
251
- .render(({ data }) => (
252
- <DynamicForm fields={data.fields} submitUrl={data.submitUrl} />
253
- ));
92
+ ```typescript
93
+ import { createProvider } from '@lantos1618/better-ui';
94
+
95
+ // OpenAI
96
+ const provider = createProvider({ provider: 'openai', model: 'gpt-4o' });
97
+
98
+ // Anthropic
99
+ const provider = createProvider({ provider: 'anthropic', model: 'claude-4-sonnet' });
100
+
101
+ // Google Gemini
102
+ const provider = createProvider({ provider: 'google', model: 'gemini-2.5-pro' });
103
+
104
+ // OpenRouter (access any model)
105
+ const provider = createProvider({
106
+ provider: 'openrouter',
107
+ model: 'anthropic/claude-4-sonnet',
108
+ apiKey: process.env.OPENROUTER_API_KEY,
109
+ });
254
110
  ```
255
111
 
256
- ### Streaming with Tool Results
112
+ Use with the chat handler:
257
113
 
258
- ```tsx
259
- // app/api/chat/route.ts
260
- import { streamText } from 'ai';
261
- import { openai } from '@ai-sdk/openai';
114
+ ```typescript
115
+ import { streamText, convertToModelMessages } from 'ai';
116
+ import { createProvider } from '@lantos1618/better-ui';
117
+
118
+ const provider = createProvider({ provider: 'openai', model: 'gpt-4o' });
262
119
 
263
120
  export async function POST(req: Request) {
264
121
  const { messages } = await req.json();
265
-
266
- const result = await streamText({
267
- model: openai('gpt-4'),
268
- messages,
122
+ const result = streamText({
123
+ model: provider.model(),
124
+ messages: convertToModelMessages(messages),
269
125
  tools: {
270
- searchDatabase: searchDatabaseTool.toAISDKTool(),
271
- createChart: createChartTool.toAISDKTool(),
272
- generateForm: generateFormTool.toAISDKTool(),
273
- },
274
- toolChoice: 'auto', // Let AI decide when to use tools
275
- async onToolCall({ toolCall, toolResult }) {
276
- // Log tool usage for analytics
277
- console.log(`Tool ${toolCall.toolName} called with:`, toolCall.args);
278
- console.log(`Result:`, toolResult);
126
+ weather: weatherTool.toAITool(),
279
127
  },
280
128
  });
281
-
282
- return result.toDataStreamResponse();
129
+ return result.toUIMessageStreamResponse();
283
130
  }
284
131
  ```
285
132
 
286
- ## 🛠️ Pre-built Tools
133
+ ## Streaming Tool Views
287
134
 
288
- Better UI comes with a comprehensive set of pre-built tools:
135
+ Tools can stream partial results progressively:
289
136
 
290
- ### DOM Manipulation Tools
291
- - `clickTool` - Click elements on the page
292
- - `typeTool` - Type text into inputs
293
- - `scrollTool` - Scroll to elements
294
- - `selectTool` - Select dropdown options
137
+ ```typescript
138
+ import { useToolStream } from '@lantos1618/better-ui';
295
139
 
296
- ### API Tools
297
- - `fetchTool` - Make HTTP requests
298
- - `graphqlTool` - Execute GraphQL queries
140
+ // Define a streaming tool
141
+ const analysis = tool({
142
+ name: 'analysis',
143
+ input: z.object({ query: z.string() }),
144
+ output: z.object({ summary: z.string(), score: z.number() }),
145
+ });
299
146
 
300
- ### Form Tools
301
- - `formGeneratorTool` - Create dynamic forms
302
- - `formValidatorTool` - Validate form data
147
+ analysis.stream(async ({ query }, { stream }) => {
148
+ stream({ summary: 'Analyzing...' }); // Partial update
149
+ const result = await analyzeData(query);
150
+ stream({ summary: result.summary }); // More data
151
+ return { summary: result.summary, score: result.score }; // Final
152
+ });
303
153
 
304
- ### Data Tools
305
- - `databaseQueryTool` - Query databases
306
- - `dataTransformTool` - Transform data structures
154
+ // In a component:
155
+ function AnalysisWidget({ query }) {
156
+ const { data, streaming, loading, execute } = useToolStream(analysis);
307
157
 
308
- ### State Management
309
- - `stateManagerTool` - Manage application state
310
- - `localStorageTool` - Persist data locally
158
+ return (
159
+ <div>
160
+ <button onClick={() => execute({ query })}>Analyze</button>
161
+ {loading && <p>Starting...</p>}
162
+ {streaming && <p>Streaming: {data?.summary}</p>}
163
+ {data?.score && <p>Score: {data.score}</p>}
164
+ </div>
165
+ );
166
+ }
167
+ ```
311
168
 
312
- ## 📚 Full API Reference
169
+ ## Core Concepts
313
170
 
314
- ### Core Builder Methods
171
+ ### 1. Tool Definition
315
172
 
316
173
  ```typescript
317
- aui
318
- .tool(name: string) // Create tool with name
319
- .description(text: string) // Add description (for AI)
320
- .tags(...tags: string[]) // Add tags for discovery
321
- .input(schema: ZodSchema) // Input validation schema
322
- .execute(handler: ExecuteHandler) // Server-side logic (required)
323
- .clientExecute(handler: ClientHandler) // Client-side logic (optional)
324
- .render(component: RenderFunction) // React component (optional)
325
- .stream(handler: StreamHandler) // Streaming support (optional)
174
+ const myTool = tool({
175
+ name: 'myTool',
176
+ description: 'What this tool does',
177
+ input: z.object({ /* input schema */ }),
178
+ output: z.object({ /* output schema */ }),
179
+ tags: ['category', 'type'],
180
+ cache: { ttl: 60000 }, // optional caching
181
+ });
326
182
  ```
327
183
 
328
- ### React Hooks & Components
329
-
330
- ```tsx
331
- // Provider for tool execution
332
- <ToolExecutorProvider tools={tools}>
333
- <App />
334
- </ToolExecutorProvider>
335
-
336
- // Render tool results
337
- <ToolRenderer toolCall={toolCall} tool={tool} />
184
+ ### 2. Server Implementation
338
185
 
339
- // Hook for manual execution
340
- const executor = useToolExecutor();
341
- const result = await executor.execute(toolCall);
186
+ The `.server()` method defines logic that runs on the server (API routes, server components):
342
187
 
343
- // Hook for tool discovery
344
- const tools = useToolRegistry();
345
- const weatherTools = tools.getByTag('weather');
188
+ ```typescript
189
+ myTool.server(async ({ query }, ctx) => {
190
+ // Direct access to databases, secrets, file system
191
+ const results = await db.search(query);
192
+ return { results };
193
+ });
346
194
  ```
347
195
 
348
- ### AI Assistant Integration
196
+ ### 3. Client Implementation (Optional)
197
+
198
+ The `.client()` method defines what happens when called from the browser. If not specified, auto-fetches to `/api/tools/execute`.
349
199
 
350
200
  ```typescript
351
- import { createAIAssistant } from '@lantos1618/better-ui';
201
+ myTool.client(async ({ query }, ctx) => {
202
+ const cached = ctx.cache.get(query);
203
+ if (cached) return cached;
352
204
 
353
- const assistant = createAIAssistant({
354
- model: 'gpt-4',
355
- tools: [weatherTool, searchTool],
356
- systemPrompt: 'You are a helpful assistant.',
205
+ return ctx.fetch('/api/search', {
206
+ method: 'POST',
207
+ body: JSON.stringify({ query })
208
+ });
357
209
  });
358
-
359
- const response = await assistant.chat('What\'s the weather in NYC?');
360
210
  ```
361
211
 
362
- ## 🏗️ Architecture
212
+ ### 4. View (Our Differentiator)
363
213
 
364
- ```
365
- ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
366
- │ AI Model │────▶│ AUI System │────▶│ Your App │
367
- (GPT, etc) │ │ │ │ │
368
- └──────────────┘ └──────────────┘ └──────────────┘
369
- │ │ │
370
- ▼ ▼ ▼
371
- Tool Calls Tool Registry Tool Execution
372
- Type Validation React Rendering
373
- Client/Server Split State Management
214
+ The `.view()` method defines how to render the tool's results:
215
+
216
+ ```typescript
217
+ myTool.view((data, { loading, error, streaming }) => {
218
+ if (loading) return <Spinner />;
219
+ if (error) return <Error message={error.message} />;
220
+ if (streaming) return <PartialResults data={data} />;
221
+ return <Results items={data.results} />;
222
+ });
374
223
  ```
375
224
 
376
- ## 🧪 Testing
225
+ ### 5. Streaming
377
226
 
378
- ```bash
379
- # Run all tests
380
- npm test
227
+ The `.stream()` method enables progressive partial updates:
381
228
 
382
- # Run with coverage
383
- npm run test:coverage
229
+ ```typescript
230
+ myTool.stream(async ({ query }, { stream }) => {
231
+ stream({ status: 'searching...' });
232
+ const results = await search(query);
233
+ stream({ results, status: 'done' });
234
+ return { results, status: 'done', count: results.length };
235
+ });
236
+ ```
384
237
 
385
- # Type checking
386
- npm run type-check
238
+ ## Fluent Builder Alternative
387
239
 
388
- # Linting
389
- npm run lint
240
+ ```typescript
241
+ const search = tool('search')
242
+ .description('Search the database')
243
+ .input(z.object({ query: z.string() }))
244
+ .output(z.object({ results: z.array(z.string()) }))
245
+ .server(async ({ query }) => ({ results: await db.search(query) }))
246
+ .stream(async ({ query }, { stream }) => {
247
+ stream({ results: [] });
248
+ const results = await db.search(query);
249
+ return { results };
250
+ })
251
+ .view((data) => <ResultsList items={data.results} />);
390
252
  ```
391
253
 
392
- ## 🚀 Deployment
254
+ ## React Hooks
393
255
 
394
- ### Vercel Deployment
256
+ ### `useTool(tool, input?, options?)`
395
257
 
396
- ```bash
397
- # Install Vercel CLI
398
- npm i -g vercel
258
+ ```typescript
259
+ import { useTool } from '@lantos1618/better-ui';
260
+
261
+ const {
262
+ data, // Result data
263
+ loading, // Loading state
264
+ error, // Error if any
265
+ execute, // Execute function
266
+ reset, // Reset state
267
+ executed, // Has been executed
268
+ } = useTool(myTool, initialInput, {
269
+ auto: false,
270
+ onSuccess: (data) => {},
271
+ onError: (error) => {},
272
+ });
273
+ ```
399
274
 
400
- # Deploy
401
- vercel
275
+ ### `useToolStream(tool, options?)`
402
276
 
403
- # Deploy with environment variables
404
- vercel --env API_KEY=xxx
277
+ ```typescript
278
+ import { useToolStream } from '@lantos1618/better-ui';
279
+
280
+ const {
281
+ data, // Progressive partial data
282
+ finalData, // Complete validated data (when done)
283
+ streaming, // True while receiving partial updates
284
+ loading, // True before first chunk
285
+ error,
286
+ execute,
287
+ reset,
288
+ } = useToolStream(myTool);
405
289
  ```
406
290
 
407
- ### Environment Variables
291
+ ### `useTools(tools, options?)`
408
292
 
409
- ```env
410
- # Required for AI features
411
- OPENAI_API_KEY=your_api_key
293
+ ```typescript
294
+ import { useTools } from '@lantos1618/better-ui';
412
295
 
413
- # Optional
414
- DATABASE_URL=your_db_url
415
- REDIS_URL=your_redis_url
416
- ```
296
+ const tools = useTools({ weather, search });
417
297
 
418
- ## 📖 Examples
298
+ await tools.weather.execute({ city: 'London' });
299
+ await tools.search.execute({ query: 'restaurants' });
419
300
 
420
- Check out our example applications:
301
+ tools.weather.data; // Weather result
302
+ tools.search.loading; // Search loading state
303
+ ```
421
304
 
422
- - [Chat Application](./examples/chat-app) - Full chat UI with tool execution
423
- - [Dashboard](./examples/dashboard) - Analytics dashboard with AI controls
424
- - [Form Builder](./examples/form-builder) - Dynamic form generation
425
- - [Data Explorer](./examples/data-explorer) - Database exploration tool
305
+ ## Chat Components
426
306
 
427
- ## 🤝 Contributing
307
+ Import from `@lantos1618/better-ui/components`:
428
308
 
429
- We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
309
+ | Component | Description |
310
+ |-----------|-------------|
311
+ | `Chat` | All-in-one chat component (ChatProvider + Thread + Composer) |
312
+ | `ChatProvider` | Context provider wrapping AI SDK's `useChat` |
313
+ | `Thread` | Message list with auto-scroll |
314
+ | `Message` | Single message with automatic tool view rendering |
315
+ | `Composer` | Input form with send button |
316
+ | `ToolResult` | Renders a tool's `.View` in chat context |
430
317
 
431
- 1. Fork the repository
432
- 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
433
- 3. Commit your changes (`git commit -m 'Add amazing feature'`)
434
- 4. Push to the branch (`git push origin feature/amazing-feature`)
435
- 5. Open a Pull Request
318
+ All components accept `className` for styling customization.
436
319
 
437
- ## 📄 License
320
+ ## Providers
438
321
 
439
- MIT License - see [LICENSE](LICENSE) for details.
322
+ | Provider | Package Required | Example Model |
323
+ |----------|-----------------|---------------|
324
+ | OpenAI | `@ai-sdk/openai` (included) | `gpt-4o`, `gpt-5.2` |
325
+ | Anthropic | `@ai-sdk/anthropic` (optional) | `claude-4-sonnet` |
326
+ | Google | `@ai-sdk/google` (optional) | `gemini-2.5-pro` |
327
+ | OpenRouter | `@ai-sdk/openai` (included) | `anthropic/claude-4-sonnet` |
328
+
329
+ ```bash
330
+ # Optional providers
331
+ npm install @ai-sdk/anthropic # For Anthropic
332
+ npm install @ai-sdk/google # For Google Gemini
333
+ ```
440
334
 
441
- ## 🙏 Acknowledgments
335
+ ## Project Structure
442
336
 
443
- Built with:
444
- - [Next.js](https://nextjs.org/) - The React framework
445
- - [TypeScript](https://www.typescriptlang.org/) - Type safety
446
- - [Zod](https://zod.dev/) - Schema validation
447
- - [Vercel AI SDK](https://sdk.vercel.ai/) - AI integration
337
+ ```
338
+ src/
339
+ tool.tsx # Core tool() API with streaming
340
+ react/
341
+ useTool.ts # React hooks (useTool, useTools)
342
+ useToolStream.ts # Streaming hook
343
+ components/
344
+ Chat.tsx # All-in-one chat component
345
+ ChatProvider.tsx # Chat context provider
346
+ Thread.tsx # Message list
347
+ Message.tsx # Single message
348
+ Composer.tsx # Input form
349
+ ToolResult.tsx # Tool view renderer
350
+ providers/
351
+ openai.ts # OpenAI adapter
352
+ anthropic.ts # Anthropic adapter
353
+ google.ts # Google Gemini adapter
354
+ openrouter.ts # OpenRouter adapter
355
+ adapters/
356
+ nextjs.ts # Next.js route handlers
357
+ express.ts # Express middleware
358
+ index.ts # Main exports
359
+ ```
448
360
 
449
- ## 📞 Support
361
+ ## Development
450
362
 
451
- - [GitHub Issues](https://github.com/lantos1618/better-ui/issues)
452
- - [Documentation](https://docs.better-ui.dev)
453
- - Email: support@better-ui.dev
363
+ ```bash
364
+ npm install
365
+ npm run dev # Run dev server
366
+ npm run build:lib # Build library
367
+ npm run build # Build everything
368
+ npm run type-check # TypeScript check
369
+ npm test # Run tests
370
+ ```
454
371
 
455
- ---
372
+ ## License
456
373
 
457
- Built with ❤️ by the Better UI team
374
+ MIT