ai-props 0.1.2 → 2.0.2

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 (69) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/CHANGELOG.md +15 -0
  3. package/README.md +345 -352
  4. package/dist/ai.d.ts +125 -0
  5. package/dist/ai.d.ts.map +1 -0
  6. package/dist/ai.js +199 -0
  7. package/dist/ai.js.map +1 -0
  8. package/dist/cache.d.ts +66 -0
  9. package/dist/cache.d.ts.map +1 -0
  10. package/dist/cache.js +183 -0
  11. package/dist/cache.js.map +1 -0
  12. package/dist/generate.d.ts +69 -0
  13. package/dist/generate.d.ts.map +1 -0
  14. package/dist/generate.js +221 -0
  15. package/dist/generate.js.map +1 -0
  16. package/dist/hoc.d.ts +164 -0
  17. package/dist/hoc.d.ts.map +1 -0
  18. package/dist/hoc.js +236 -0
  19. package/dist/hoc.js.map +1 -0
  20. package/dist/index.d.ts +14 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +21 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/types.d.ts +152 -0
  25. package/dist/types.d.ts.map +1 -0
  26. package/dist/types.js +7 -0
  27. package/dist/types.js.map +1 -0
  28. package/dist/validate.d.ts +58 -0
  29. package/dist/validate.d.ts.map +1 -0
  30. package/dist/validate.js +253 -0
  31. package/dist/validate.js.map +1 -0
  32. package/package.json +16 -63
  33. package/src/ai.ts +264 -0
  34. package/src/cache.ts +216 -0
  35. package/src/generate.ts +276 -0
  36. package/src/hoc.ts +309 -0
  37. package/src/index.ts +66 -0
  38. package/src/types.ts +167 -0
  39. package/src/validate.ts +333 -0
  40. package/test/ai.test.ts +327 -0
  41. package/test/cache.test.ts +236 -0
  42. package/test/generate.test.ts +406 -0
  43. package/test/hoc.test.ts +411 -0
  44. package/test/validate.test.ts +324 -0
  45. package/tsconfig.json +9 -0
  46. package/vitest.config.ts +15 -0
  47. package/LICENSE +0 -21
  48. package/dist/AI.d.ts +0 -27
  49. package/dist/AI.d.ts.map +0 -1
  50. package/dist/AI.test.d.ts +0 -2
  51. package/dist/AI.test.d.ts.map +0 -1
  52. package/dist/ai-props.es.js +0 -3697
  53. package/dist/ai-props.umd.js +0 -30
  54. package/dist/components/ErrorBoundary.d.ts +0 -17
  55. package/dist/components/ErrorBoundary.d.ts.map +0 -1
  56. package/dist/examples/BlogList.d.ts +0 -2
  57. package/dist/examples/BlogList.d.ts.map +0 -1
  58. package/dist/examples/BlogList.fixture.d.ts +0 -5
  59. package/dist/examples/BlogList.fixture.d.ts.map +0 -1
  60. package/dist/examples/HeroSection.d.ts +0 -2
  61. package/dist/examples/HeroSection.d.ts.map +0 -1
  62. package/dist/examples/HeroSection.fixture.d.ts +0 -5
  63. package/dist/examples/HeroSection.fixture.d.ts.map +0 -1
  64. package/dist/test/setup.d.ts +0 -2
  65. package/dist/test/setup.d.ts.map +0 -1
  66. package/dist/utils/schema.d.ts +0 -28
  67. package/dist/utils/schema.d.ts.map +0 -1
  68. package/dist/utils/styles.d.ts +0 -3
  69. package/dist/utils/styles.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
  # ai-props
2
2
 
3
- [![npm version](https://badge.fury.io/js/ai-props.svg)](https://www.npmjs.com/package/ai-props)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3
+ AI-powered props primitives for intelligent component properties.
5
4
 
6
- A React component package that provides an AI component for generating and spreading AI-generated props to child components.
5
+ ## Overview
6
+
7
+ `ai-props` provides utilities for automatically generating component props using AI based on schema definitions. It's designed to work seamlessly with React components, Next.js, and other frameworks.
7
8
 
8
9
  ## Installation
9
10
 
@@ -11,412 +12,404 @@ A React component package that provides an AI component for generating and sprea
11
12
  npm install ai-props
12
13
  ```
13
14
 
14
- ## Usage
15
-
16
- The `AI` component mirrors the `generateObject` function from the `ai` package and spreads the generated object's properties to its children.
17
-
18
- ### Model Configuration
19
-
20
- The AI component supports both string-based OpenAI models and provider-specific model objects:
21
-
22
- ```tsx
23
- // Simple string-based OpenAI model (recommended for OpenAI)
24
- <AI
25
- model='gpt-4'
26
- schema={schema}
27
- prompt='Generate content'
28
- />
29
-
30
- // Provider-specific model object (required for other providers)
31
- import { anthropic } from '@ai-sdk/anthropic'
32
-
33
- const model = anthropic('claude-2')
34
- <AI
35
- model={model}
36
- schema={schema}
37
- prompt='Generate content'
38
- />
39
-
40
- ### Streaming Support
41
-
42
- The AI component supports real-time streaming of generated content, providing a more interactive user experience:
43
-
44
- ```tsx
45
- <AI
46
- model='gpt-4'
47
- stream={true}
48
- schema={{
49
- title: 'string',
50
- content: 'string'
51
- }}
52
- prompt='Generate an article about React'
53
- >
54
- {(props, { isStreaming }) => (
55
- <article className={isStreaming ? 'animate-pulse' : ''}>
56
- <h1>{props.title}</h1>
57
- <div>{props.content}</div>
58
- {isStreaming && (
59
- <div className='text-gray-500'>Generating content...</div>
60
- )}
61
- </article>
62
- )}
63
- </AI>
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { AI, generateProps } from 'ai-props'
19
+
20
+ // Define an AI-powered component schema
21
+ const UserCard = AI({
22
+ schema: {
23
+ name: 'User name',
24
+ bio: 'User biography',
25
+ avatar: 'Avatar URL',
26
+ },
27
+ defaults: {
28
+ avatar: '/default-avatar.png',
29
+ },
30
+ })
31
+
32
+ // Generate props with AI
33
+ const props = await UserCard({ name: 'John' })
34
+ // { name: 'John', bio: 'AI-generated bio...', avatar: '/default-avatar.png' }
64
35
  ```
65
36
 
66
- When using streaming:
67
- - Set `stream={true}` to enable real-time updates
68
- - Access streaming status via `isStreaming` in render prop
69
- - UI updates automatically as content arrives
70
- - Maintain type safety with your schema
71
- - Reduced time to first content display
72
-
73
- ### API Proxy Integration
74
-
75
- For enhanced security and control, you can route requests through your own API endpoint:
76
-
77
- ```tsx
78
- <AI
79
- model='gpt-4'
80
- apiEndpoint='/api/generate'
81
- headers={{
82
- 'Authorization': 'Bearer ${process.env.API_KEY}',
83
- 'X-Custom-Header': 'value'
84
- }}
85
- schema={schema}
86
- prompt='Generate content'
87
- />
37
+ ## Core Features
38
+
39
+ ### AI() Wrapper
40
+
41
+ Create AI-powered component wrappers that automatically fill in missing props:
42
+
43
+ ```typescript
44
+ import { AI } from 'ai-props'
45
+
46
+ const ProductCard = AI({
47
+ schema: {
48
+ title: 'Product title',
49
+ description: 'Product description',
50
+ price: 'Price (number)',
51
+ },
52
+ required: ['price'], // Required props won't be generated
53
+ exclude: ['internal'], // Exclude props from generation
54
+ })
55
+
56
+ // Use the component
57
+ const props = await ProductCard({ price: 99 })
88
58
  ```
89
59
 
90
- Your API endpoint should:
91
- - Accept the same parameters as the AI provider
92
- - Return compatible streaming or non-streaming responses
93
- - Handle authentication and rate limiting
94
- - Implement proper error handling
60
+ ### generateProps()
95
61
 
96
- Benefits of using an API proxy:
97
- - Keep API keys secure on your server
98
- - Add custom request validation
99
- - Implement usage tracking
100
- - Control model access and costs
101
- - Add custom error handling
62
+ Low-level function for direct prop generation:
102
63
 
103
- Example API endpoint implementation:
104
64
  ```typescript
105
- // pages/api/generate.ts
106
- import { OpenAIStream } from 'ai'
107
-
108
- export async function POST(req: Request) {
109
- const { prompt, schema, stream } = await req.json()
110
-
111
- const response = await fetch('https://api.openai.com/v1/chat/completions', {
112
- method: 'POST',
113
- headers: {
114
- 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
115
- 'Content-Type': 'application/json',
116
- },
117
- body: JSON.stringify({
118
- model: 'gpt-4',
119
- messages: [{ role: 'user', content: prompt }],
120
- stream: stream,
121
- }),
122
- })
123
-
124
- if (stream) {
125
- const stream = OpenAIStream(response)
126
- return new Response(stream)
127
- }
65
+ import { generateProps } from 'ai-props'
128
66
 
129
- const json = await response.json()
130
- return Response.json(json)
131
- }
67
+ const result = await generateProps({
68
+ schema: {
69
+ title: 'SEO-optimized page title',
70
+ description: 'Meta description',
71
+ keywords: ['Relevant keywords'],
72
+ },
73
+ context: { topic: 'AI-powered applications' },
74
+ })
75
+
76
+ console.log(result.props) // Generated props
77
+ console.log(result.cached) // Whether result came from cache
78
+ console.log(result.metadata) // Model info, duration, etc.
132
79
  ```
133
80
 
134
- ### Simplified Schema Interface
81
+ ### createAIComponent()
135
82
 
136
- You can define your schema using a simple object structure without importing Zod:
83
+ Create typed AI components:
137
84
 
138
- ```tsx
139
- import { AI } from 'ai-props'
85
+ ```typescript
86
+ import { createAIComponent } from 'ai-props'
140
87
 
141
- function MyComponent() {
142
- return (
143
- <AI
144
- schema={{
145
- productType: 'App | API | Marketplace | Platform | Packaged Service | Professional Service | Website',
146
- profile: {
147
- customer: 'ideal customer profile in 3-5 words',
148
- solution: 'describe the offer in 4-10 words'
149
- },
150
- description: 'website meta description',
151
- tags: ['SEO-optimized meta tags']
152
- }}
153
- prompt='Generate product details'
154
- >
155
- {(props) => (
156
- <article>
157
- <h1>{props.productType}</h1>
158
- <div>
159
- <p>Customer: {props.profile.customer}</p>
160
- <p>Solution: {props.profile.solution}</p>
161
- </div>
162
- <p>{props.description}</p>
163
- <ul>
164
- {props.tags.map((tag, i) => (
165
- <li key={i}>{tag}</li>
166
- ))}
167
- </ul>
168
- </article>
169
- )}
170
- </AI>
171
- )
88
+ interface ProductProps {
89
+ title: string
90
+ price: number
91
+ description: string
172
92
  }
93
+
94
+ const ProductCard = createAIComponent<ProductProps>({
95
+ schema: {
96
+ title: 'Product title',
97
+ price: 'Price (number)',
98
+ description: 'Product description',
99
+ },
100
+ })
101
+
102
+ const props = await ProductCard({})
103
+ // props is typed as ProductProps
173
104
  ```
174
105
 
175
- The simplified schema interface supports:
176
- - Pipe-separated strings (`'Option1 | Option2 | Option3'`) which are automatically converted to enums
177
- - Nested objects with type descriptions
178
- - Array types with description hints
106
+ ### createComponentFactory()
179
107
 
180
- ### Direct Zod Schema Usage
108
+ Create a factory for generating multiple instances:
181
109
 
182
- You can also use Zod schemas directly for more complex validation:
110
+ ```typescript
111
+ import { createComponentFactory } from 'ai-props'
183
112
 
184
- ```tsx
185
- import { AI } from 'ai-props'
186
- import { z } from 'zod'
113
+ const factory = createComponentFactory({
114
+ schema: {
115
+ name: 'Product name',
116
+ price: 'Price (number)',
117
+ },
118
+ })
119
+
120
+ // Generate a single instance
121
+ const product = await factory.generate({ category: 'electronics' })
122
+
123
+ // Generate multiple instances
124
+ const products = await factory.generateMany([
125
+ { category: 'electronics' },
126
+ { category: 'clothing' },
127
+ ])
128
+
129
+ // Generate with overrides
130
+ const custom = await factory.generateWith(
131
+ { category: 'tech' },
132
+ { price: 99 }
133
+ )
134
+ ```
187
135
 
188
- // Define your schema
189
- const schema = z.object({
190
- title: z.string(),
191
- description: z.string()
136
+ ### composeAIComponents()
137
+
138
+ Compose multiple schemas together:
139
+
140
+ ```typescript
141
+ import { composeAIComponents } from 'ai-props'
142
+
143
+ const FullProfile = composeAIComponents({
144
+ user: {
145
+ schema: { name: 'User name', bio: 'Biography' },
146
+ },
147
+ settings: {
148
+ schema: { theme: 'Theme preference', notifications: 'Notification pref' },
149
+ },
192
150
  })
193
151
 
194
- // Use the AI component
195
- function MyComponent() {
196
- return (
197
- <AI
198
- schema={schema}
199
- prompt='Generate a title and description for a blog post about React'
200
- >
201
- {(props) => (
202
- <article>
203
- <h1>{props.title}</h1>
204
- <p>{props.description}</p>
205
- </article>
206
- )}
207
- </AI>
208
- )
209
- }
152
+ const profile = await FullProfile({
153
+ user: { name: 'John' },
154
+ settings: {},
155
+ })
210
156
  ```
211
157
 
212
- ## Default Model Configuration
158
+ ## HOC Utilities
159
+
160
+ ### createPropsEnhancer()
213
161
 
214
- The AI component uses a default model configuration:
162
+ Create a props enhancer for any component system:
215
163
 
216
164
  ```typescript
217
- import { openai } from '@ai-sdk/openai'
218
- const model = openai('gpt-4o')
165
+ import { createPropsEnhancer } from 'ai-props'
166
+
167
+ const enhancer = createPropsEnhancer({
168
+ schema: {
169
+ title: 'Page title',
170
+ description: 'Page description',
171
+ },
172
+ defaults: { title: 'Default Title' },
173
+ })
174
+
175
+ const props = await enhancer({ description: 'My page' })
219
176
  ```
220
177
 
221
- You can override this by providing your own model configuration through props.
222
-
223
- ## Props
224
-
225
- The `AI` component accepts all props from the `generateObject` function:
226
-
227
- ### Required Props
228
- - `schema`: A Zod schema or Schema object defining the structure of the generated object. Supports:
229
- - Direct Zod schemas for complex validation
230
- - Simplified object syntax without Zod imports
231
- - Pipe-separated strings for automatic enum conversion (e.g., `'Option1 | Option2'`)
232
- - `prompt`: The prompt to send to the language model
233
-
234
- ### Optional Props
235
- - `output`: Type of output ('object' | 'array' | 'enum' | 'no-schema')
236
- - `schemaName`: Optional name for the output schema
237
- - `schemaDescription`: Optional description for the output schema
238
- - `mode`: Generation mode ('auto' | 'json' | 'tool'), defaults to 'auto'
239
- - `model`: Override the default model
240
- - `experimental_telemetry`: Optional telemetry configuration
241
- - `experimental_providerMetadata`: Additional provider-specific metadata
242
-
243
- ### Array Output Mode
244
-
245
- The `AI` component supports generating and rendering arrays of items using the `output='array'` prop. When using array output mode, you can also enable CSS Grid layout with the `cols` prop:
246
-
247
- ```tsx
248
- <AI
249
- schema={blogSchema}
250
- prompt='Generate 6 blog post previews'
251
- output='array'
252
- cols={3}
253
- gap='2rem'
254
- className='grid-container'
255
- itemClassName='grid-item'
256
- >
257
- {(props) => (
258
- <article>{/* Item content */}</article>
259
- )}
260
- </AI>
178
+ ### createAsyncPropsProvider()
179
+
180
+ Create an async props provider for SSR:
181
+
182
+ ```typescript
183
+ import { createAsyncPropsProvider } from 'ai-props'
184
+
185
+ const getPageProps = createAsyncPropsProvider({
186
+ schema: {
187
+ title: 'SEO title',
188
+ meta: { description: 'Meta description' },
189
+ },
190
+ })
191
+
192
+ // In getStaticProps or getServerSideProps
193
+ export async function getStaticProps() {
194
+ const props = await getPageProps.getProps({ slug: 'about' })
195
+ return { props }
196
+ }
261
197
  ```
262
198
 
263
- #### Grid Support Props
264
- - `cols`: Number of columns in the grid (default: 3)
265
- - `gap`: Gap between grid items (CSS gap value)
266
- - `className`: Class applied to the grid container
267
- - `itemClassName`: Class applied to each grid item
199
+ ### createBatchGenerator()
200
+
201
+ Generate props for multiple items efficiently:
268
202
 
269
- ### Styling Support
203
+ ```typescript
204
+ import { createBatchGenerator } from 'ai-props'
270
205
 
271
- The `AI` component integrates with `clsx` and `tailwind-merge` for flexible styling:
206
+ const batch = createBatchGenerator({
207
+ schema: { title: 'Item title', description: 'Description' },
208
+ concurrency: 3,
209
+ })
272
210
 
273
- ```tsx
274
- <AI
275
- className='max-w-7xl mx-auto px-4 py-16 grid-cols-1 md:grid-cols-2 lg:grid-cols-3'
276
- itemClassName='bg-white p-6 rounded-lg shadow-md h-full flex flex-col'
277
- >
278
- {/* Component content */}
279
- </AI>
211
+ const items = await batch.generate([
212
+ { id: 1, category: 'tech' },
213
+ { id: 2, category: 'science' },
214
+ ])
280
215
  ```
281
216
 
282
- Class names are merged using the `cn` utility, which combines `clsx` and `tailwind-merge` for conflict-free class composition.
217
+ ## Validation
283
218
 
284
- ### Examples
219
+ ### validateProps()
285
220
 
286
- #### Hero Section Example
221
+ Validate props against a schema:
287
222
 
288
- A waitlist landing page hero section for an AI-powered SaaS product:
223
+ ```typescript
224
+ import { validateProps } from 'ai-props'
289
225
 
290
- ```tsx
291
- import { AI } from 'ai-props'
226
+ const result = validateProps(
227
+ { name: 'John', age: '25' },
228
+ { name: 'Name', age: 'Age (number)' }
229
+ )
292
230
 
293
- const heroSchema = {
294
- productType: 'App | API | Marketplace | Platform',
295
- profile: {
296
- customer: 'ideal customer profile in 3-5 words',
297
- solution: 'describe the offer in 4-10 words'
298
- },
299
- description: 'website meta description',
300
- tags: ['SEO-optimized meta tags'],
301
- headline: 'compelling headline for AI SaaS product',
302
- subheadline: 'engaging subheadline explaining value proposition',
303
- ctaText: 'action-oriented button text',
304
- benefits: ['3-5 key benefits'],
305
- targetAudience: 'specific target audience description'
231
+ if (!result.valid) {
232
+ console.log(result.errors)
233
+ // [{ path: 'age', message: 'Expected number, got string' }]
306
234
  }
235
+ ```
307
236
 
308
- export function HeroSection() {
309
- return (
310
- <AI<typeof heroSchema>
311
- schema={heroSchema}
312
- prompt='Generate a hero section for an AI-powered SaaS product waitlist landing page'
313
- className='bg-gradient-to-br from-blue-50 to-indigo-50'
314
- >
315
- {(props) => (
316
- <div className='max-w-6xl mx-auto px-4 py-16'>
317
- <h1 className='text-5xl font-bold mb-4 bg-clip-text text-transparent bg-gradient-to-r from-blue-600 to-indigo-600'>
318
- {props.headline}
319
- </h1>
320
- <p className='text-xl text-gray-600 mb-8'>{props.subheadline}</p>
321
- <button className='bg-blue-600 text-white px-8 py-3 rounded-lg text-lg font-medium hover:bg-blue-700 transition-colors'>
322
- {props.ctaText}
323
- </button>
324
- <div className='mt-12'>
325
- <h2 className='text-2xl font-semibold mb-4'>Perfect for {props.targetAudience}</h2>
326
- <ul className='grid grid-cols-1 md:grid-cols-2 gap-4'>
327
- {props.benefits.map((benefit, index) => (
328
- <li key={index} className='flex items-start bg-white p-4 rounded-lg shadow-sm'>
329
- <span className='text-blue-500 mr-2'>✓</span>
330
- {benefit}
331
- </li>
332
- ))}
333
- </ul>
334
- </div>
335
- </div>
336
- )}
337
- </AI>
338
- )
339
- }
237
+ ### assertValidProps()
340
238
 
341
- #### Blog List Example
239
+ Assert props are valid (throws on error):
342
240
 
343
- A grid of blog post previews using array output mode:
241
+ ```typescript
242
+ import { assertValidProps } from 'ai-props'
344
243
 
345
- ```tsx
346
- import { AI } from 'ai-props'
244
+ assertValidProps(
245
+ { name: 'John', age: 25 },
246
+ { name: 'Name', age: 'Age (number)' }
247
+ )
248
+ ```
249
+
250
+ ### Other Validation Utilities
251
+
252
+ ```typescript
253
+ import {
254
+ hasRequiredProps,
255
+ getMissingProps,
256
+ isComplete,
257
+ getMissingFromSchema,
258
+ sanitizeProps,
259
+ mergeWithDefaults,
260
+ createValidator,
261
+ } from 'ai-props'
262
+
263
+ // Check required props
264
+ hasRequiredProps({ name: 'John' }, ['name', 'email']) // false
265
+
266
+ // Get missing props
267
+ getMissingProps({ name: 'John' }, ['name', 'email']) // ['email']
268
+
269
+ // Check schema completion
270
+ isComplete({ name: 'John' }, { name: 'Name', age: 'Age' }) // false
271
+
272
+ // Sanitize extra props
273
+ sanitizeProps({ name: 'John', extra: 'value' }, { name: 'Name' })
274
+ // { name: 'John' }
275
+
276
+ // Merge with defaults
277
+ mergeWithDefaults({ name: 'John' }, { age: 0 }, { name: 'Name', age: 'Age' })
278
+ // { name: 'John', age: 0 }
279
+
280
+ // Create reusable validator
281
+ const validate = createValidator({ name: 'Name', age: 'Age (number)' })
282
+ validate({ name: 'John', age: 25 }) // { valid: true, errors: [] }
283
+ ```
284
+
285
+ ## Caching
286
+
287
+ ### Cache Configuration
288
+
289
+ ```typescript
290
+ import { configureAIProps, configureCache, clearCache } from 'ai-props'
291
+
292
+ // Configure global settings
293
+ configureAIProps({
294
+ model: 'gpt-4',
295
+ cache: true,
296
+ cacheTTL: 5 * 60 * 1000, // 5 minutes
297
+ })
298
+
299
+ // Configure cache with custom TTL
300
+ configureCache(10 * 60 * 1000) // 10 minutes
301
+
302
+ // Clear all cached props
303
+ clearCache()
304
+ ```
305
+
306
+ ### Cache Classes
307
+
308
+ ```typescript
309
+ import { MemoryPropsCache, LRUPropsCache } from 'ai-props'
310
+
311
+ // Simple memory cache
312
+ const memCache = new MemoryPropsCache(5 * 60 * 1000)
313
+
314
+ // LRU cache with max entries
315
+ const lruCache = new LRUPropsCache(100, 5 * 60 * 1000)
316
+
317
+ // Cache operations
318
+ lruCache.set('key', { name: 'John' })
319
+ const entry = lruCache.get<{ name: string }>('key')
320
+ lruCache.delete('key')
321
+ lruCache.clear()
322
+ console.log(lruCache.size)
323
+ ```
324
+
325
+ ## Schema Type Hints
326
+
327
+ Use type hints in schema strings:
347
328
 
348
- const blogSchema = {
349
- productType: 'App | API | Marketplace | Platform',
350
- profile: {
351
- customer: 'ideal customer profile in 3-5 words',
352
- solution: 'describe the offer in 4-10 words'
329
+ ```typescript
330
+ const schema = {
331
+ name: 'User name', // string
332
+ age: 'User age (number)', // number
333
+ count: 'Item count (integer)', // integer
334
+ active: 'Is active (boolean)', // boolean
335
+ tags: ['Tag names'], // array
336
+ status: 'pending | active | done', // enum
337
+ profile: { // nested object
338
+ bio: 'User bio',
339
+ avatar: 'Avatar URL',
353
340
  },
354
- description: 'website meta description',
355
- tags: ['relevant topic tags'],
356
- title: 'engaging blog post title',
357
- excerpt: 'compelling 2-3 sentence excerpt',
358
- readTime: 'estimated read time',
359
- category: 'Blog | Tutorial | Case Study | News'
360
341
  }
342
+ ```
361
343
 
362
- export function BlogList() {
363
- return (
364
- <AI<typeof blogSchema>
365
- schema={blogSchema}
366
- prompt='Generate 6 blog post previews about AI and machine learning'
367
- output='array'
368
- cols={3}
369
- gap='2rem'
370
- className='max-w-7xl mx-auto px-4 py-16 grid-cols-1 md:grid-cols-2 lg:grid-cols-3'
371
- itemClassName='h-full'
372
- >
373
- {(props) => (
374
- <article className='bg-white p-6 rounded-lg shadow-md h-full flex flex-col'>
375
- <div className='text-sm text-gray-500 mb-2 flex items-center justify-between'>
376
- <span>{props.category}</span>
377
- <span>{props.readTime}</span>
378
- </div>
379
- <h2 className='text-xl font-semibold mb-3'>{props.title}</h2>
380
- <p className='text-gray-600 mb-4 flex-grow'>{props.excerpt}</p>
381
- <div className='flex flex-wrap gap-2 mt-auto'>
382
- {props.tags.map((tag, index) => (
383
- <span key={index} className='bg-gray-100 text-gray-600 px-3 py-1 rounded-full text-sm'>
384
- {tag}
385
- </span>
386
- ))}
387
- </div>
388
- </article>
389
- )}
390
- </AI>
391
- )
392
- }
344
+ ## Configuration
393
345
 
394
- ## Development
346
+ ```typescript
347
+ import { configureAIProps, getConfig, resetConfig } from 'ai-props'
348
+
349
+ // Configure globally
350
+ configureAIProps({
351
+ model: 'sonnet', // Default model
352
+ cache: true, // Enable caching
353
+ cacheTTL: 300000, // Cache TTL in ms
354
+ system: 'Custom prompt', // System prompt
355
+ generate: async (schema, context) => {
356
+ // Custom generator
357
+ return { /* generated props */ }
358
+ },
359
+ })
395
360
 
396
- This package uses:
397
- - Vite for building
398
- - Vitest for testing
399
- - React Cosmos for component development and testing
361
+ // Get current config
362
+ const config = getConfig()
400
363
 
401
- ## Dependencies
364
+ // Reset to defaults
365
+ resetConfig()
366
+ ```
402
367
 
403
- This package requires the following peer dependencies:
404
- - `react` (^18.2.0)
405
- - `react-dom` (^18.2.0)
406
- - `@types/react` (^18.2.0)
407
- - `@types/react-dom` (^18.2.0)
368
+ ## API Reference
408
369
 
409
- And the following runtime dependencies:
410
- - `ai` (^4.0.18)
411
- - `@ai-sdk/openai` (^1.0.8)
412
- - `clsx` (^2.1.1)
413
- - `tailwind-merge` (^2.5.5)
414
- - `zod` (^3.22.4)
370
+ ### Types
415
371
 
416
- Make sure to install these dependencies if they're not already in your project:
372
+ ```typescript
373
+ interface PropSchema {
374
+ [key: string]: string | string[] | PropSchema
375
+ }
417
376
 
418
- ```bash
419
- npm install ai @ai-sdk/openai clsx tailwind-merge zod
377
+ interface GeneratePropsOptions {
378
+ schema: PropSchema
379
+ context?: Record<string, unknown>
380
+ prompt?: string
381
+ model?: string
382
+ system?: string
383
+ }
384
+
385
+ interface GeneratePropsResult<T> {
386
+ props: T
387
+ cached: boolean
388
+ metadata: {
389
+ model: string
390
+ duration?: number
391
+ }
392
+ }
393
+
394
+ interface AIComponentOptions<P> {
395
+ schema: PropSchema
396
+ defaults?: Partial<P>
397
+ required?: (keyof P)[]
398
+ exclude?: (keyof P)[]
399
+ config?: AIPropsConfig
400
+ }
401
+
402
+ interface ValidationResult {
403
+ valid: boolean
404
+ errors: ValidationError[]
405
+ }
406
+
407
+ interface ValidationError {
408
+ path: string
409
+ message: string
410
+ expected?: string
411
+ received?: unknown
412
+ }
420
413
  ```
421
414
 
422
415
  ## License