@nextsparkjs/plugin-ai 0.1.0-beta.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 (34) hide show
  1. package/.env.example +79 -0
  2. package/README.md +529 -0
  3. package/api/README.md +65 -0
  4. package/api/ai-history/[id]/route.ts +112 -0
  5. package/api/embeddings/route.ts +129 -0
  6. package/api/generate/route.ts +160 -0
  7. package/docs/01-getting-started/01-introduction.md +237 -0
  8. package/docs/01-getting-started/02-installation.md +447 -0
  9. package/docs/01-getting-started/03-configuration.md +416 -0
  10. package/docs/02-features/01-text-generation.md +523 -0
  11. package/docs/02-features/02-embeddings.md +241 -0
  12. package/docs/02-features/03-ai-history.md +549 -0
  13. package/docs/03-advanced-usage/01-core-utilities.md +500 -0
  14. package/docs/04-use-cases/01-content-generation.md +453 -0
  15. package/entities/ai-history/ai-history.config.ts +123 -0
  16. package/entities/ai-history/ai-history.fields.ts +330 -0
  17. package/entities/ai-history/messages/en.json +56 -0
  18. package/entities/ai-history/messages/es.json +56 -0
  19. package/entities/ai-history/migrations/001_ai_history_table.sql +167 -0
  20. package/entities/ai-history/migrations/002_ai_history_metas.sql +103 -0
  21. package/lib/ai-history-meta-service.ts +379 -0
  22. package/lib/ai-history-service.ts +391 -0
  23. package/lib/ai-sdk.ts +7 -0
  24. package/lib/core-utils.ts +217 -0
  25. package/lib/plugin-env.ts +252 -0
  26. package/lib/sanitize.ts +122 -0
  27. package/lib/save-example.ts +237 -0
  28. package/lib/server-env.ts +104 -0
  29. package/package.json +23 -0
  30. package/plugin.config.ts +55 -0
  31. package/public/docs/login-404-error.png +0 -0
  32. package/tsconfig.json +47 -0
  33. package/tsconfig.tsbuildinfo +1 -0
  34. package/types/ai.types.ts +51 -0
@@ -0,0 +1,549 @@
1
+ # AI History
2
+
3
+ ## Overview
4
+
5
+ **AI History** is an audit trail system that tracks every AI operation in your application. It provides complete visibility into AI usage, costs, performance, and outcomes.
6
+
7
+ **Key Benefits:**
8
+ - **Cost Tracking** - Monitor token usage and spending across all AI operations
9
+ - **Performance Monitoring** - Track response times and success rates
10
+ - **Audit Trail** - Complete record of all AI interactions
11
+ - **Entity Linking** - Connect AI operations to application entities
12
+ - **Debugging** - Investigate issues and optimize prompts
13
+
14
+ ## Database Schema
15
+
16
+ ### AI History Table
17
+
18
+ ```sql
19
+ CREATE TABLE ai_history (
20
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
21
+ user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
22
+
23
+ -- Operation details
24
+ operation VARCHAR(50) NOT NULL, -- 'generate', 'refine', 'analyze', etc.
25
+ status VARCHAR(20) NOT NULL, -- 'pending', 'processing', 'completed', 'failed'
26
+
27
+ -- AI configuration
28
+ model VARCHAR(100) NOT NULL,
29
+ provider VARCHAR(50), -- 'openai', 'anthropic', 'ollama'
30
+
31
+ -- Token usage and costs
32
+ tokens_used INTEGER DEFAULT 0,
33
+ tokens_input INTEGER, -- Prompt tokens
34
+ tokens_output INTEGER, -- Completion tokens
35
+ credits_used DECIMAL(10,4) DEFAULT 0,
36
+ estimated_cost DECIMAL(10,6) DEFAULT 0,
37
+ balance_after DECIMAL(10,4),
38
+
39
+ -- Entity relationship (polymorphic)
40
+ related_entity_type VARCHAR(100), -- 'products', 'articles', 'clients'
41
+ related_entity_id UUID,
42
+
43
+ -- Timestamps
44
+ created_at TIMESTAMP DEFAULT NOW(),
45
+ updated_at TIMESTAMP DEFAULT NOW(),
46
+ completed_at TIMESTAMP
47
+ );
48
+ ```
49
+
50
+ ### AI History Metadata Table
51
+
52
+ ```sql
53
+ CREATE TABLE ai_history_metas (
54
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
55
+ entity_id UUID REFERENCES ai_history(id) ON DELETE CASCADE,
56
+ meta_key VARCHAR(255) NOT NULL,
57
+ meta_value TEXT,
58
+ created_at TIMESTAMP DEFAULT NOW()
59
+ );
60
+ ```
61
+
62
+ **Flexible Metadata:**
63
+ - `sourceOperationId` - Link to original operation
64
+ - `userInstruction` - Original user input
65
+ - `systemPrompt` - System prompt used
66
+ - `parameters` - JSON of generation parameters
67
+ - Custom fields as needed
68
+
69
+ ## AI History Service
70
+
71
+ ### Import
72
+
73
+ ```typescript
74
+ import { AIHistoryService } from '@/contents/plugins/ai/lib/ai-history-service'
75
+ ```
76
+
77
+ ### Operation Lifecycle
78
+
79
+ **1. Start Operation**
80
+
81
+ ```typescript
82
+ const historyId = await AIHistoryService.startOperation({
83
+ userId: 'user-id',
84
+ operation: 'generate',
85
+ model: 'gpt-4o-mini',
86
+ provider: 'openai',
87
+ relatedEntityType: 'products',
88
+ relatedEntityId: 'product-uuid'
89
+ })
90
+ ```
91
+
92
+ **2. Update Status (Optional)**
93
+
94
+ ```typescript
95
+ await AIHistoryService.updateToProcessing(historyId)
96
+ ```
97
+
98
+ **3. Complete Operation**
99
+
100
+ ```typescript
101
+ await AIHistoryService.completeOperation({
102
+ historyId,
103
+ tokensUsed: 250,
104
+ tokensInput: 100,
105
+ tokensOutput: 150,
106
+ creditsUsed: 0,
107
+ estimatedCost: 0.00045,
108
+ balanceAfter: 10.50,
109
+ userId: 'user-id',
110
+ metas: {
111
+ userInstruction: 'Generate product description',
112
+ systemPrompt: 'You are a product copywriter...',
113
+ resultLength: 500
114
+ }
115
+ })
116
+ ```
117
+
118
+ **4. Fail Operation (If Error)**
119
+
120
+ ```typescript
121
+ await AIHistoryService.failOperation({
122
+ historyId,
123
+ errorMessage: 'Rate limit exceeded',
124
+ tokensUsed: 50 // Partial tokens before failure
125
+ })
126
+ ```
127
+
128
+ ### Methods Reference
129
+
130
+ #### `startOperation(params)`
131
+
132
+ **Parameters:**
133
+ ```typescript
134
+ {
135
+ userId: string // Required
136
+ operation: AIOperation // 'generate' | 'refine' | 'analyze' | 'chat' | 'completion' | 'other'
137
+ model: string // Model name (e.g., 'gpt-4o-mini')
138
+ provider?: AIProvider // 'openai' | 'anthropic' | 'ollama'
139
+ relatedEntityType?: string // Entity type (e.g., 'products')
140
+ relatedEntityId?: string // Entity ID
141
+ }
142
+ ```
143
+
144
+ **Returns:** `Promise<string>` - History record ID
145
+
146
+ **Usage:**
147
+ ```typescript
148
+ const historyId = await AIHistoryService.startOperation({
149
+ userId: session.user.id,
150
+ operation: 'generate',
151
+ model: 'llama3.2:3b',
152
+ provider: 'ollama'
153
+ })
154
+ ```
155
+
156
+ #### `completeOperation(params)`
157
+
158
+ **Parameters:**
159
+ ```typescript
160
+ {
161
+ historyId: string // Required: ID from startOperation
162
+ tokensUsed: number // Total tokens
163
+ tokensInput?: number // Input tokens (optional but recommended)
164
+ tokensOutput?: number // Output tokens (optional but recommended)
165
+ creditsUsed: number // Credits deducted (if using credit system)
166
+ estimatedCost: number // Cost in USD
167
+ balanceAfter: number // User balance after operation
168
+ userId: string // Required for metadata
169
+ metas?: Record<string, any> // Optional metadata
170
+ }
171
+ ```
172
+
173
+ **Returns:** `Promise<void>`
174
+
175
+ **Usage:**
176
+ ```typescript
177
+ await AIHistoryService.completeOperation({
178
+ historyId,
179
+ tokensUsed: result.usage.totalTokens,
180
+ tokensInput: result.usage.inputTokens,
181
+ tokensOutput: result.usage.outputTokens,
182
+ creditsUsed: 0,
183
+ estimatedCost: 0.00045,
184
+ balanceAfter: user.balance,
185
+ userId: session.user.id,
186
+ metas: {
187
+ temperature: 0.7,
188
+ maxTokens: 500,
189
+ responseLength: result.text.length
190
+ }
191
+ })
192
+ ```
193
+
194
+ #### `failOperation(params)`
195
+
196
+ **Parameters:**
197
+ ```typescript
198
+ {
199
+ historyId: string // Required
200
+ errorMessage: string // Error description
201
+ tokensUsed?: number // Partial tokens if any
202
+ }
203
+ ```
204
+
205
+ **Returns:** `Promise<void>`
206
+
207
+ **Usage:**
208
+ ```typescript
209
+ try {
210
+ // AI operation
211
+ } catch (error) {
212
+ await AIHistoryService.failOperation({
213
+ historyId,
214
+ errorMessage: error.message,
215
+ tokensUsed: partialTokens
216
+ })
217
+ }
218
+ ```
219
+
220
+ ## Entity Linking
221
+
222
+ ### Link Operation to Entity
223
+
224
+ **During Creation:**
225
+ ```typescript
226
+ const historyId = await AIHistoryService.startOperation({
227
+ userId: 'user-id',
228
+ operation: 'analyze',
229
+ model: 'claude-3-5-haiku-20241022',
230
+ relatedEntityType: 'clients',
231
+ relatedEntityId: clientId
232
+ })
233
+ ```
234
+
235
+ **After Creation (via API):**
236
+ ```bash
237
+ PATCH /api/v1/plugin/ai/ai-history/:id
238
+
239
+ {
240
+ "relatedEntityType": "products",
241
+ "relatedEntityId": "product-uuid"
242
+ }
243
+ ```
244
+
245
+ ### Use Cases
246
+
247
+ **1. Product Content Generation**
248
+ ```typescript
249
+ // Generate product description
250
+ const historyId = await AIHistoryService.startOperation({
251
+ userId: session.user.id,
252
+ operation: 'generate',
253
+ model: 'gpt-4o-mini',
254
+ relatedEntityType: 'products',
255
+ relatedEntityId: productId
256
+ })
257
+
258
+ // ... generate content ...
259
+
260
+ // Link shows which product this content was generated for
261
+ ```
262
+
263
+ **2. Client Analysis**
264
+ ```typescript
265
+ // Analyze client data
266
+ const historyId = await AIHistoryService.startOperation({
267
+ userId: session.user.id,
268
+ operation: 'analyze',
269
+ model: 'claude-3-5-sonnet-20241022',
270
+ relatedEntityType: 'clients',
271
+ relatedEntityId: clientId
272
+ })
273
+
274
+ // History linked to specific client
275
+ ```
276
+
277
+ **3. Content Auditing**
278
+ ```typescript
279
+ // Audit article content
280
+ const historyId = await AIHistoryService.startOperation({
281
+ userId: session.user.id,
282
+ operation: 'analyze',
283
+ model: 'gpt-4o',
284
+ relatedEntityType: 'articles',
285
+ relatedEntityId: articleId
286
+ })
287
+
288
+ // Track which articles have been audited
289
+ ```
290
+
291
+ ## Querying History
292
+
293
+ ### Get User's History
294
+
295
+ ```typescript
296
+ const history = await AIHistoryService.getUserHistory(userId, {
297
+ limit: 50,
298
+ offset: 0
299
+ })
300
+ ```
301
+
302
+ ### Filter by Operation
303
+
304
+ ```typescript
305
+ const generations = await query(`
306
+ SELECT * FROM ai_history
307
+ WHERE user_id = $1
308
+ AND operation = 'generate'
309
+ ORDER BY created_at DESC
310
+ LIMIT 50
311
+ `, [userId])
312
+ ```
313
+
314
+ ### Calculate Total Costs
315
+
316
+ ```typescript
317
+ const result = await queryOne(`
318
+ SELECT
319
+ SUM(estimated_cost) as total_cost,
320
+ SUM(tokens_used) as total_tokens,
321
+ COUNT(*) as operation_count
322
+ FROM ai_history
323
+ WHERE user_id = $1
324
+ AND created_at >= NOW() - INTERVAL '30 days'
325
+ `, [userId])
326
+
327
+ console.log(`Monthly cost: $${result.total_cost}`)
328
+ console.log(`Total tokens: ${result.total_tokens}`)
329
+ console.log(`Operations: ${result.operation_count}`)
330
+ ```
331
+
332
+ ### Group by Model
333
+
334
+ ```typescript
335
+ const modelStats = await query(`
336
+ SELECT
337
+ model,
338
+ COUNT(*) as usage_count,
339
+ SUM(estimated_cost) as total_cost,
340
+ AVG(tokens_used) as avg_tokens
341
+ FROM ai_history
342
+ WHERE user_id = $1
343
+ GROUP BY model
344
+ ORDER BY usage_count DESC
345
+ `, [userId])
346
+ ```
347
+
348
+ ## Dashboard Integration
349
+
350
+ ### AI History Entity
351
+
352
+ The AI History entity is automatically available in the dashboard:
353
+
354
+ **Routes:**
355
+ - `/dashboard/ai-history` - List view
356
+ - `/dashboard/ai-history/:id` - Detail view
357
+
358
+ **Features:**
359
+ - Searchable by operation, model, provider, entity type
360
+ - Sortable by date, cost, status, tokens
361
+ - Filterable by status, operation, provider
362
+ - Bulk delete operations
363
+
364
+ ### Permissions
365
+
366
+ ```typescript
367
+ permissions: {
368
+ read: ['admin', 'colaborator'], // Users see their own via RLS
369
+ create: ['admin', 'colaborator'], // Created by API
370
+ update: ['admin'], // Immutable (admin only)
371
+ delete: ['admin', 'colaborator'] // Users can delete own history
372
+ }
373
+ ```
374
+
375
+ ## Real-World Example
376
+
377
+ ### Complete Content Generation Flow
378
+
379
+ ```typescript
380
+ export async function generateProductDescription(productId: string) {
381
+ const session = await auth()
382
+ if (!session?.user) throw new Error('Unauthorized')
383
+
384
+ // 1. Start operation tracking
385
+ const historyId = await AIHistoryService.startOperation({
386
+ userId: session.user.id,
387
+ operation: 'generate',
388
+ model: 'gpt-4o-mini',
389
+ provider: 'openai',
390
+ relatedEntityType: 'products',
391
+ relatedEntityId: productId
392
+ })
393
+
394
+ try {
395
+ // 2. Update status
396
+ await AIHistoryService.updateToProcessing(historyId)
397
+
398
+ // 3. Get product data
399
+ const product = await getProduct(productId)
400
+
401
+ // 4. Generate content
402
+ const result = await generateText({
403
+ model: openai('gpt-4o-mini'),
404
+ prompt: `Generate a compelling product description for: ${product.name}`,
405
+ maxTokens: 300
406
+ })
407
+
408
+ // 5. Calculate cost
409
+ const tokens = {
410
+ input: result.usage.inputTokens,
411
+ output: result.usage.outputTokens,
412
+ total: result.usage.totalTokens
413
+ }
414
+ const cost = calculateCost(tokens, { input: 0.00015, output: 0.0006 })
415
+
416
+ // 6. Complete operation
417
+ await AIHistoryService.completeOperation({
418
+ historyId,
419
+ tokensUsed: tokens.total,
420
+ tokensInput: tokens.input,
421
+ tokensOutput: tokens.output,
422
+ creditsUsed: 0,
423
+ estimatedCost: cost,
424
+ balanceAfter: session.user.balance,
425
+ userId: session.user.id,
426
+ metas: {
427
+ productName: product.name,
428
+ promptTemplate: 'product-description-v1',
429
+ generatedLength: result.text.length
430
+ }
431
+ })
432
+
433
+ // 7. Return result
434
+ return {
435
+ description: result.text,
436
+ cost,
437
+ tokens,
438
+ historyId
439
+ }
440
+
441
+ } catch (error) {
442
+ // 8. Handle failure
443
+ await AIHistoryService.failOperation({
444
+ historyId,
445
+ errorMessage: error.message
446
+ })
447
+ throw error
448
+ }
449
+ }
450
+ ```
451
+
452
+ ## Metadata Examples
453
+
454
+ ### Store Custom Data
455
+
456
+ ```typescript
457
+ await AIHistoryService.completeOperation({
458
+ historyId,
459
+ // ... other params
460
+ metas: {
461
+ // Prompt information
462
+ userInstruction: 'Write a blog post about AI',
463
+ systemPrompt: 'You are a technical writer...',
464
+
465
+ // Generation parameters
466
+ temperature: 0.7,
467
+ maxTokens: 1000,
468
+ model: 'gpt-4o-mini',
469
+
470
+ // Results
471
+ responseLength: 850,
472
+ responseQuality: 'high',
473
+
474
+ // Context
475
+ sourceDocument: 'outline-v3.md',
476
+ targetAudience: 'developers',
477
+
478
+ // Custom fields
479
+ campaignId: 'summer-2024',
480
+ approved: false
481
+ }
482
+ })
483
+ ```
484
+
485
+ ### Query Metadata
486
+
487
+ ```typescript
488
+ // Find all operations with specific metadata
489
+ const operations = await query(`
490
+ SELECT h.*
491
+ FROM ai_history h
492
+ JOIN ai_history_metas m ON h.id = m.entity_id
493
+ WHERE h.user_id = $1
494
+ AND m.meta_key = 'campaignId'
495
+ AND m.meta_value = 'summer-2024'
496
+ `, [userId])
497
+ ```
498
+
499
+ ## Performance Optimization
500
+
501
+ ### Index for Common Queries
502
+
503
+ ```sql
504
+ -- Index for user queries
505
+ CREATE INDEX idx_ai_history_user_date
506
+ ON ai_history(user_id, created_at DESC);
507
+
508
+ -- Index for entity relationships
509
+ CREATE INDEX idx_ai_history_entity
510
+ ON ai_history(related_entity_type, related_entity_id);
511
+
512
+ -- Index for status tracking
513
+ CREATE INDEX idx_ai_history_status
514
+ ON ai_history(status, created_at);
515
+ ```
516
+
517
+ ### Pagination
518
+
519
+ ```typescript
520
+ async function getUserHistoryPaginated(
521
+ userId: string,
522
+ page: number = 1,
523
+ pageSize: number = 50
524
+ ) {
525
+ const offset = (page - 1) * pageSize
526
+
527
+ return await query(`
528
+ SELECT * FROM ai_history
529
+ WHERE user_id = $1
530
+ ORDER BY created_at DESC
531
+ LIMIT $2 OFFSET $3
532
+ `, [userId, pageSize, offset])
533
+ }
534
+ ```
535
+
536
+ ## Best Practices
537
+
538
+ 1. **Always Track Operations** - Even failed ones provide valuable data
539
+ 2. **Use Meaningful Operation Names** - Make it easy to filter and analyze
540
+ 3. **Link to Entities** - Connect AI work to business objects
541
+ 4. **Store Relevant Metadata** - Helps with debugging and optimization
542
+ 5. **Monitor Costs** - Set up alerts for unusual spending
543
+ 6. **Clean Old Data** - Archive or delete history after retention period
544
+
545
+ ## Next Steps
546
+
547
+ - **[Text Generation](./01-text-generation.md)** - Generate AI content
548
+ - **[Core Utilities](../04-advanced-usage/01-core-utilities.md)** - Use in custom endpoints
549
+ - **[Custom Endpoints](../04-advanced-usage/02-custom-endpoints.md)** - Build with history tracking