ai-props 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 AI Primitives
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,307 @@
1
+ # ai-props
2
+
3
+ A React component package that provides an AI component for generating and spreading AI-generated props to child components.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install ai-props
9
+ ```
10
+
11
+ ## Dependencies
12
+
13
+ This package requires the following peer dependencies:
14
+ - `react` (^18.2.0)
15
+ - `react-dom` (^18.2.0)
16
+ - `@types/react` (^18.2.0)
17
+ - `@types/react-dom` (^18.2.0)
18
+
19
+ And the following runtime dependencies:
20
+ - `ai` (^4.0.18)
21
+ - `@ai-sdk/openai` (^1.0.8)
22
+ - `clsx` (^2.1.1)
23
+ - `tailwind-merge` (^2.5.5)
24
+ - `zod` (^3.22.4)
25
+
26
+ Make sure to install these dependencies if they're not already in your project:
27
+
28
+ ```bash
29
+ npm install ai @ai-sdk/openai clsx tailwind-merge zod
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ The `AI` component mirrors the `generateObject` function from the `ai` package, with a default model configuration. It spreads the generated object's properties to its children.
35
+
36
+ ### Simplified Schema Interface
37
+
38
+ You can define your schema using a simple object structure without importing Zod:
39
+
40
+ ```tsx
41
+ import { AI } from 'ai-props'
42
+
43
+ function MyComponent() {
44
+ return (
45
+ <AI
46
+ schema={{
47
+ productType: 'App | API | Marketplace | Platform | Packaged Service | Professional Service | Website',
48
+ profile: {
49
+ customer: 'ideal customer profile in 3-5 words',
50
+ solution: 'describe the offer in 4-10 words'
51
+ },
52
+ description: 'website meta description',
53
+ tags: ['SEO-optimized meta tags']
54
+ }}
55
+ prompt="Generate product details"
56
+ >
57
+ {(props) => (
58
+ <article>
59
+ <h1>{props.productType}</h1>
60
+ <div>
61
+ <p>Customer: {props.profile.customer}</p>
62
+ <p>Solution: {props.profile.solution}</p>
63
+ </div>
64
+ <p>{props.description}</p>
65
+ <ul>
66
+ {props.tags.map((tag, i) => (
67
+ <li key={i}>{tag}</li>
68
+ ))}
69
+ </ul>
70
+ </article>
71
+ )}
72
+ </AI>
73
+ )
74
+ }
75
+ ```
76
+
77
+ The simplified schema interface supports:
78
+ - Pipe-separated strings (`'Option1 | Option2 | Option3'`) which are automatically converted to enums
79
+ - Nested objects with type descriptions
80
+ - Array types with description hints
81
+
82
+ ### Direct Zod Schema Usage
83
+
84
+ You can also use Zod schemas directly for more complex validation:
85
+
86
+ ```tsx
87
+ import { AI } from 'ai-props'
88
+ import { z } from 'zod'
89
+
90
+ // Define your schema
91
+ const schema = z.object({
92
+ title: z.string(),
93
+ description: z.string()
94
+ })
95
+
96
+ // Use the AI component
97
+ function MyComponent() {
98
+ return (
99
+ <AI
100
+ schema={schema}
101
+ prompt="Generate a title and description for a blog post about React"
102
+ >
103
+ {(props) => (
104
+ <article>
105
+ <h1>{props.title}</h1>
106
+ <p>{props.description}</p>
107
+ </article>
108
+ )}
109
+ </AI>
110
+ )
111
+ }
112
+ ```
113
+
114
+ ## Default Model Configuration
115
+
116
+ The AI component uses a default model configuration:
117
+
118
+ ```typescript
119
+ import { openai } from '@ai-sdk/openai'
120
+ const model = openai('gpt-4o')
121
+ ```
122
+
123
+ You can override this by providing your own model configuration through props.
124
+
125
+ ## Props
126
+
127
+ The `AI` component accepts all props from the `generateObject` function:
128
+
129
+ ### Required Props
130
+ - `schema`: A Zod schema or Schema object defining the structure of the generated object. Supports:
131
+ - Direct Zod schemas for complex validation
132
+ - Simplified object syntax without Zod imports
133
+ - Pipe-separated strings for automatic enum conversion (e.g., `'Option1 | Option2'`)
134
+ - `prompt`: The prompt to send to the language model
135
+
136
+ ### Optional Props
137
+ - `output`: Type of output ('object' | 'array' | 'enum' | 'no-schema')
138
+ - `schemaName`: Optional name for the output schema
139
+ - `schemaDescription`: Optional description for the output schema
140
+ - `mode`: Generation mode ('auto' | 'json' | 'tool'), defaults to 'auto'
141
+ - `model`: Override the default model
142
+ - `experimental_telemetry`: Optional telemetry configuration
143
+ - `experimental_providerMetadata`: Additional provider-specific metadata
144
+
145
+ ### Array Output Mode
146
+
147
+ 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:
148
+
149
+ ```tsx
150
+ <AI
151
+ schema={blogSchema}
152
+ prompt="Generate 6 blog post previews"
153
+ output="array"
154
+ cols={3}
155
+ gap="2rem"
156
+ className="grid-container"
157
+ itemClassName="grid-item"
158
+ >
159
+ {(props) => (
160
+ <article>{/* Item content */}</article>
161
+ )}
162
+ </AI>
163
+ ```
164
+
165
+ #### Grid Support Props
166
+ - `cols`: Number of columns in the grid (default: 3)
167
+ - `gap`: Gap between grid items (CSS gap value)
168
+ - `className`: Class applied to the grid container
169
+ - `itemClassName`: Class applied to each grid item
170
+
171
+ ### Styling Support
172
+
173
+ The `AI` component integrates with `clsx` and `tailwind-merge` for flexible styling:
174
+
175
+ ```tsx
176
+ <AI
177
+ className="max-w-7xl mx-auto px-4 py-16 grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
178
+ itemClassName="bg-white p-6 rounded-lg shadow-md h-full flex flex-col"
179
+ >
180
+ {/* Component content */}
181
+ </AI>
182
+ ```
183
+
184
+ Class names are merged using the `cn` utility, which combines `clsx` and `tailwind-merge` for conflict-free class composition.
185
+
186
+ ### Examples
187
+
188
+ #### Hero Section Example
189
+
190
+ A waitlist landing page hero section for an AI-powered SaaS product:
191
+
192
+ ```tsx
193
+ import { AI } from 'ai-props'
194
+
195
+ const heroSchema = {
196
+ productType: 'App | API | Marketplace | Platform',
197
+ profile: {
198
+ customer: 'ideal customer profile in 3-5 words',
199
+ solution: 'describe the offer in 4-10 words'
200
+ },
201
+ description: 'website meta description',
202
+ tags: ['SEO-optimized meta tags'],
203
+ headline: 'compelling headline for AI SaaS product',
204
+ subheadline: 'engaging subheadline explaining value proposition',
205
+ ctaText: 'action-oriented button text',
206
+ benefits: ['3-5 key benefits'],
207
+ targetAudience: 'specific target audience description'
208
+ }
209
+
210
+ export function HeroSection() {
211
+ return (
212
+ <AI<typeof heroSchema>
213
+ schema={heroSchema}
214
+ prompt="Generate a hero section for an AI-powered SaaS product waitlist landing page"
215
+ className="bg-gradient-to-br from-blue-50 to-indigo-50"
216
+ >
217
+ {(props) => (
218
+ <div className="max-w-6xl mx-auto px-4 py-16">
219
+ <h1 className="text-5xl font-bold mb-4 bg-clip-text text-transparent bg-gradient-to-r from-blue-600 to-indigo-600">
220
+ {props.headline}
221
+ </h1>
222
+ <p className="text-xl text-gray-600 mb-8">{props.subheadline}</p>
223
+ <button className="bg-blue-600 text-white px-8 py-3 rounded-lg text-lg font-medium hover:bg-blue-700 transition-colors">
224
+ {props.ctaText}
225
+ </button>
226
+ <div className="mt-12">
227
+ <h2 className="text-2xl font-semibold mb-4">Perfect for {props.targetAudience}</h2>
228
+ <ul className="grid grid-cols-1 md:grid-cols-2 gap-4">
229
+ {props.benefits.map((benefit, index) => (
230
+ <li key={index} className="flex items-start bg-white p-4 rounded-lg shadow-sm">
231
+ <span className="text-blue-500 mr-2">✓</span>
232
+ {benefit}
233
+ </li>
234
+ ))}
235
+ </ul>
236
+ </div>
237
+ </div>
238
+ )}
239
+ </AI>
240
+ )
241
+ }
242
+ ```
243
+
244
+ #### Blog List Example
245
+
246
+ A grid of blog post previews using array output mode:
247
+
248
+ ```tsx
249
+ import { AI } from 'ai-props'
250
+
251
+ const blogSchema = {
252
+ productType: 'App | API | Marketplace | Platform',
253
+ profile: {
254
+ customer: 'ideal customer profile in 3-5 words',
255
+ solution: 'describe the offer in 4-10 words'
256
+ },
257
+ description: 'website meta description',
258
+ tags: ['relevant topic tags'],
259
+ title: 'engaging blog post title',
260
+ excerpt: 'compelling 2-3 sentence excerpt',
261
+ readTime: 'estimated read time',
262
+ category: 'Blog | Tutorial | Case Study | News'
263
+ }
264
+
265
+ export function BlogList() {
266
+ return (
267
+ <AI<typeof blogSchema>
268
+ schema={blogSchema}
269
+ prompt="Generate 6 blog post previews about AI and machine learning"
270
+ output="array"
271
+ cols={3}
272
+ gap="2rem"
273
+ className="max-w-7xl mx-auto px-4 py-16 grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
274
+ itemClassName="h-full"
275
+ >
276
+ {(props) => (
277
+ <article className="bg-white p-6 rounded-lg shadow-md h-full flex flex-col">
278
+ <div className="text-sm text-gray-500 mb-2 flex items-center justify-between">
279
+ <span>{props.category}</span>
280
+ <span>{props.readTime}</span>
281
+ </div>
282
+ <h2 className="text-xl font-semibold mb-3">{props.title}</h2>
283
+ <p className="text-gray-600 mb-4 flex-grow">{props.excerpt}</p>
284
+ <div className="flex flex-wrap gap-2 mt-auto">
285
+ {props.tags.map((tag, index) => (
286
+ <span key={index} className="bg-gray-100 text-gray-600 px-3 py-1 rounded-full text-sm">
287
+ {tag}
288
+ </span>
289
+ ))}
290
+ </div>
291
+ </article>
292
+ )}
293
+ </AI>
294
+ )
295
+ }
296
+ ```
297
+
298
+ ## Development
299
+
300
+ This package uses:
301
+ - Vite for building
302
+ - Vitest for testing
303
+ - React Cosmos for component development and testing
304
+
305
+ ## License
306
+
307
+ MIT
package/dist/AI.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ import { ReactNode } from 'react';
2
+ import { z } from 'zod';
3
+ import type { LanguageModelV1ProviderMetadata } from '@ai-sdk/provider';
4
+ import type { AttributeValue } from '@opentelemetry/api';
5
+ import type { SchemaObject } from './utils/schema';
6
+ declare const defaultModel: LanguageModelV1;
7
+ type TelemetrySettings = {
8
+ isEnabled?: boolean;
9
+ recordInputs?: boolean;
10
+ recordOutputs?: boolean;
11
+ functionId?: string;
12
+ metadata?: Record<string, AttributeValue>;
13
+ };
14
+ type AIProps<T> = {
15
+ children: (props: T) => ReactNode;
16
+ prompt: string;
17
+ schema: z.ZodSchema<T> | SchemaObject;
18
+ model?: typeof defaultModel;
19
+ output?: 'object' | 'array';
20
+ count?: number;
21
+ cols?: number;
22
+ gap?: string;
23
+ className?: string;
24
+ itemClassName?: string;
25
+ schemaName?: string;
26
+ schemaDescription?: string;
27
+ mode?: 'json';
28
+ experimental_telemetry?: TelemetrySettings;
29
+ experimental_providerMetadata?: LanguageModelV1ProviderMetadata;
30
+ };
31
+ export declare function AI<T>({ children, prompt, schema: rawSchema, model, output, count, cols, gap, className, itemClassName, schemaName, schemaDescription, mode, experimental_telemetry, experimental_providerMetadata, }: AIProps<T>): string | number | boolean | Iterable<ReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
32
+ export {};
33
+ //# sourceMappingURL=AI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AI.d.ts","sourceRoot":"","sources":["../src/AI.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuB,MAAM,OAAO,CAAA;AAGtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAIlD,QAAA,MAAM,YAAY,iBAAmB,CAAA;AAErC,KAAK,iBAAiB,GAAG;IACvB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;CAC1C,CAAA;AAED,KAAK,OAAO,CAAC,CAAC,IAAI;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,SAAS,CAAA;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,YAAY,CAAA;IACrC,KAAK,CAAC,EAAE,OAAO,YAAY,CAAA;IAC3B,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sBAAsB,CAAC,EAAE,iBAAiB,CAAA;IAC1C,6BAA6B,CAAC,EAAE,+BAA+B,CAAA;CAChE,CAAA;AAED,wBAAgB,EAAE,CAAC,CAAC,EAAE,EACpB,QAAQ,EACR,MAAM,EACN,MAAM,EAAE,SAAS,EACjB,KAAoB,EACpB,MAAiB,EACjB,KAAK,EACL,IAAI,EACJ,GAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,IAAa,EACb,sBAAsB,EACtB,6BAA6B,GAC9B,EAAE,OAAO,CAAC,CAAC,CAAC,gHA6DZ"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=AI.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AI.test.d.ts","sourceRoot":"","sources":["../src/AI.test.tsx"],"names":[],"mappings":""}