ai-props 0.1.0 → 0.1.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 CHANGED
@@ -1,5 +1,8 @@
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)
5
+
3
6
  A React component package that provides an AI component for generating and spreading AI-generated props to child components.
4
7
 
5
8
  ## Installation
@@ -8,30 +11,125 @@ A React component package that provides an AI component for generating and sprea
8
11
  npm install ai-props
9
12
  ```
10
13
 
11
- ## Dependencies
14
+ ## Usage
12
15
 
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)
16
+ The `AI` component mirrors the `generateObject` function from the `ai` package and spreads the generated object's properties to its children.
18
17
 
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)
18
+ ### Model Configuration
25
19
 
26
- Make sure to install these dependencies if they're not already in your project:
20
+ The AI component supports both string-based OpenAI models and provider-specific model objects:
27
21
 
28
- ```bash
29
- npm install ai @ai-sdk/openai clsx tailwind-merge zod
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>
30
64
  ```
31
65
 
32
- ## Usage
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
33
74
 
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.
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
+ />
88
+ ```
89
+
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
95
+
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
102
+
103
+ Example API endpoint implementation:
104
+ ```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
+ }
128
+
129
+ const json = await response.json()
130
+ return Response.json(json)
131
+ }
132
+ ```
35
133
 
36
134
  ### Simplified Schema Interface
37
135
 
@@ -52,7 +150,7 @@ function MyComponent() {
52
150
  description: 'website meta description',
53
151
  tags: ['SEO-optimized meta tags']
54
152
  }}
55
- prompt="Generate product details"
153
+ prompt='Generate product details'
56
154
  >
57
155
  {(props) => (
58
156
  <article>
@@ -98,7 +196,7 @@ function MyComponent() {
98
196
  return (
99
197
  <AI
100
198
  schema={schema}
101
- prompt="Generate a title and description for a blog post about React"
199
+ prompt='Generate a title and description for a blog post about React'
102
200
  >
103
201
  {(props) => (
104
202
  <article>
@@ -144,17 +242,17 @@ The `AI` component accepts all props from the `generateObject` function:
144
242
 
145
243
  ### Array Output Mode
146
244
 
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:
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:
148
246
 
149
247
  ```tsx
150
248
  <AI
151
249
  schema={blogSchema}
152
- prompt="Generate 6 blog post previews"
153
- output="array"
250
+ prompt='Generate 6 blog post previews'
251
+ output='array'
154
252
  cols={3}
155
- gap="2rem"
156
- className="grid-container"
157
- itemClassName="grid-item"
253
+ gap='2rem'
254
+ className='grid-container'
255
+ itemClassName='grid-item'
158
256
  >
159
257
  {(props) => (
160
258
  <article>{/* Item content */}</article>
@@ -174,8 +272,8 @@ The `AI` component integrates with `clsx` and `tailwind-merge` for flexible styl
174
272
 
175
273
  ```tsx
176
274
  <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"
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'
179
277
  >
180
278
  {/* Component content */}
181
279
  </AI>
@@ -211,24 +309,24 @@ export function HeroSection() {
211
309
  return (
212
310
  <AI<typeof heroSchema>
213
311
  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"
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'
216
314
  >
217
315
  {(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">
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'>
220
318
  {props.headline}
221
319
  </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">
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'>
224
322
  {props.ctaText}
225
323
  </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">
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'>
229
327
  {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>
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>
232
330
  {benefit}
233
331
  </li>
234
332
  ))}
@@ -239,7 +337,6 @@ export function HeroSection() {
239
337
  </AI>
240
338
  )
241
339
  }
242
- ```
243
340
 
244
341
  #### Blog List Example
245
342
 
@@ -266,24 +363,24 @@ export function BlogList() {
266
363
  return (
267
364
  <AI<typeof blogSchema>
268
365
  schema={blogSchema}
269
- prompt="Generate 6 blog post previews about AI and machine learning"
270
- output="array"
366
+ prompt='Generate 6 blog post previews about AI and machine learning'
367
+ output='array'
271
368
  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"
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'
275
372
  >
276
373
  {(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">
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'>
279
376
  <span>{props.category}</span>
280
377
  <span>{props.readTime}</span>
281
378
  </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">
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'>
285
382
  {props.tags.map((tag, index) => (
286
- <span key={index} className="bg-gray-100 text-gray-600 px-3 py-1 rounded-full text-sm">
383
+ <span key={index} className='bg-gray-100 text-gray-600 px-3 py-1 rounded-full text-sm'>
287
384
  {tag}
288
385
  </span>
289
386
  ))}
@@ -293,7 +390,6 @@ export function BlogList() {
293
390
  </AI>
294
391
  )
295
392
  }
296
- ```
297
393
 
298
394
  ## Development
299
395
 
@@ -302,6 +398,27 @@ This package uses:
302
398
  - Vitest for testing
303
399
  - React Cosmos for component development and testing
304
400
 
401
+ ## Dependencies
402
+
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)
408
+
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)
415
+
416
+ Make sure to install these dependencies if they're not already in your project:
417
+
418
+ ```bash
419
+ npm install ai @ai-sdk/openai clsx tailwind-merge zod
420
+ ```
421
+
305
422
  ## License
306
423
 
307
424
  MIT
package/dist/AI.d.ts CHANGED
@@ -1,33 +1,27 @@
1
- import { ReactNode } from 'react';
2
1
  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>;
2
+ import { type SchemaObject } from './utils/schema';
3
+ type ModelType = string | {
4
+ provider: string;
5
+ model: string;
13
6
  };
14
- type AIProps<T> = {
15
- children: (props: T) => ReactNode;
16
- prompt: string;
7
+ interface AIProps<T extends Record<string, unknown>, O extends 'object' | 'array' = 'object'> {
17
8
  schema: z.ZodSchema<T> | SchemaObject;
18
- model?: typeof defaultModel;
19
- output?: 'object' | 'array';
9
+ prompt: string;
10
+ model?: ModelType;
11
+ output?: O;
20
12
  count?: number;
21
13
  cols?: number;
22
- gap?: string;
14
+ mode?: 'json';
15
+ stream?: boolean;
16
+ apiEndpoint?: string;
17
+ headers?: Record<string, string>;
18
+ experimental_telemetry?: boolean;
19
+ experimental_providerMetadata?: boolean;
23
20
  className?: string;
24
21
  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;
22
+ gap?: string;
23
+ children: (props: O extends 'array' ? T[] : T) => React.ReactNode;
24
+ }
25
+ export declare function AI<T extends Record<string, unknown>, O extends 'object' | 'array' = 'object'>({ children, prompt, schema: rawSchema, model, output, count, cols, mode, stream, apiEndpoint, headers, experimental_telemetry, experimental_providerMetadata, className, itemClassName, gap, }: AIProps<T, O>): string | number | boolean | Iterable<import("react").ReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
32
26
  export {};
33
27
  //# sourceMappingURL=AI.d.ts.map
package/dist/AI.d.ts.map CHANGED
@@ -1 +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"}
1
+ {"version":3,"file":"AI.d.ts","sourceRoot":"","sources":["../src/AI.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,OAAO,EAAuC,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAEvF,KAAK,SAAS,GAAG,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE7D,UAAU,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,QAAQ,GAAG,OAAO,GAAG,QAAQ;IAC1F,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,YAAY,CAAA;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,MAAM,CAAC,EAAE,CAAC,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,6BAA6B,CAAC,EAAE,OAAO,CAAA;IACvC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,SAAS,OAAO,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,SAAS,CAAA;CAClE;AAMD,wBAAgB,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,QAAQ,GAAG,OAAO,GAAG,QAAQ,EAAE,EAC7F,QAAQ,EACR,MAAM,EACN,MAAM,EAAE,SAAS,EACjB,KAAe,EACf,MAAsB,EACtB,KAAK,EACL,IAAI,EACJ,IAAa,EACb,MAAc,EACd,WAAW,EACX,OAAO,EACP,sBAAsB,EACtB,6BAA6B,EAC7B,SAAS,EACT,aAAa,EACb,GAAY,GACb,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,gIAoGf"}