agents-config 1.0.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 (90) hide show
  1. package/AGENTS.md +490 -0
  2. package/LICENSE +21 -0
  3. package/README.md +254 -0
  4. package/adapters/claude.template.md +77 -0
  5. package/adapters/codex.template.md +72 -0
  6. package/adapters/copilot.template.md +68 -0
  7. package/adapters/cursor.template.md +69 -0
  8. package/adapters/gemini.template.md +73 -0
  9. package/adapters/windsurf.template.md +81 -0
  10. package/bin/agents-init.js +699 -0
  11. package/bin/postinstall.js +28 -0
  12. package/instructions/development-standards.instructions.md +47 -0
  13. package/instructions/github-issue.instructions.md +324 -0
  14. package/instructions/github-release-notes.instructions.md +888 -0
  15. package/instructions/mui.instructions.md +50 -0
  16. package/instructions/storybook.instructions.md +55 -0
  17. package/instructions/web-interface-guidelines.instructions.md +331 -0
  18. package/package.json +56 -0
  19. package/prompts/create-pr.prompt.md +78 -0
  20. package/prompts/scaffold-component.prompt.md +57 -0
  21. package/rules/accessibility.md +36 -0
  22. package/rules/component-architecture.md +34 -0
  23. package/rules/gemini.md +547 -0
  24. package/rules/mui.md +491 -0
  25. package/rules/react-19-compiler.md +26 -0
  26. package/rules/spec-driven-development.md +36 -0
  27. package/rules/supabase.md +40 -0
  28. package/rules/tailwind-v4.md +29 -0
  29. package/rules/three-js-react.md +76 -0
  30. package/rules/web-performance.md +29 -0
  31. package/schemas/agents-project.schema.json +78 -0
  32. package/skills/accessibility-audit/SKILL.md +39 -0
  33. package/skills/integrate-gemini/SKILL.md +124 -0
  34. package/skills/scaffold-component/SKILL.md +77 -0
  35. package/skills/vercel-react-best-practices/AGENTS.md +2719 -0
  36. package/skills/vercel-react-best-practices/SKILL.md +125 -0
  37. package/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  38. package/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
  39. package/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  40. package/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
  41. package/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
  42. package/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  43. package/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  44. package/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  45. package/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  46. package/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  47. package/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  48. package/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  49. package/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  50. package/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
  51. package/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
  52. package/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  53. package/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
  54. package/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  55. package/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  56. package/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  57. package/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  58. package/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  59. package/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  60. package/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  61. package/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  62. package/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  63. package/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  64. package/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  65. package/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  66. package/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  67. package/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  68. package/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  69. package/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  70. package/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  71. package/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  72. package/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  73. package/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  74. package/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  75. package/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  76. package/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  77. package/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  78. package/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  79. package/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  80. package/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  81. package/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  82. package/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  83. package/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
  84. package/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  85. package/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
  86. package/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
  87. package/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
  88. package/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  89. package/skills/workflows/sdd-workflow.md +49 -0
  90. package/skills/workflows/setup-orchestration.md +18 -0
@@ -0,0 +1,34 @@
1
+ ---
2
+ description: Standardized directory and file structure for React components in this workspace.
3
+ ---
4
+
5
+ **OBJECTIVE:**
6
+ Maintaining a consistent, scalable, and discoverable component architecture.
7
+
8
+ **REASON:**
9
+ As the project grows, a standardized folder structure prevents "file sprawl" and makes it easier to locate styles, tests, and assets related to a specific component.
10
+
11
+ **DESCRIPTION:**
12
+ The "Folder-per-Component" pattern used throughout the `src/components` directory.
13
+
14
+ **INSTRUCTIONS:**
15
+
16
+ ### Directory Structure
17
+ - **Component Folders**: Every major component should live in its own folder under `src/components/`.
18
+ - **Primary File**: The main component file must be named `ComponentName.tsx` (PascalCase).
19
+ - **Associated Files**: Styles, local assets, and sub-components should reside within the same component folder.
20
+
21
+ Example:
22
+ ```
23
+ src/components/Hero/
24
+ ├── Hero.tsx
25
+ ├── Hero.css (if not using Tailwind)
26
+ └── HeroBackground.tsx (local child component)
27
+ ```
28
+
29
+ ### Exports
30
+ - **Named Exports**: Prefer named exports for components to ensure better IDE support and tree-shaking.
31
+ - **Clear Boundaries**: Avoid importing local child components (e.g., `HeroBackground`) from outside their parent's folder. If a component is reused elsewhere, move it to the root of `src/components/`.
32
+
33
+ ### Prop Types
34
+ - **Interfaces over Types**: Use `interface` for component props to allow for better extensibility and cleaner error messages.
@@ -0,0 +1,547 @@
1
+ # Google Gemini AI Integration Rules
2
+
3
+ **Purpose**: Architectural constraints, security requirements, and UX patterns for integrating Google Gemini API into React applications.
4
+
5
+ **Related Skill**: [integrate_gemini](../skills/integrate_gemini/SKILL.md)
6
+
7
+ ---
8
+
9
+ ## AI Integration Philosophy
10
+
11
+ ### When to Use AI Features
12
+
13
+ **Use Gemini when**:
14
+ - Generating creative content (text, summaries, translations)
15
+ - Providing conversational interfaces
16
+ - Analyzing user-provided content
17
+ - Offering intelligent suggestions or recommendations
18
+ - Processing natural language queries
19
+
20
+ **Don't Use Gemini when**:
21
+ - Deterministic logic is required (use regular code)
22
+ - Real-time responses are critical (< 100ms)
23
+ - Offline functionality is needed
24
+ - Simple rule-based logic suffices
25
+ - User expects instant, predictable results
26
+
27
+ ### Human-in-the-Loop Principle
28
+
29
+ **Rule**: AI should augment, not replace, human decision-making.
30
+
31
+ ```tsx
32
+ // ✅ Good: AI suggests, user decides
33
+ <SuggestionList
34
+ suggestions={aiSuggestions}
35
+ onAccept={handleAccept}
36
+ onReject={handleReject}
37
+ onEdit={handleEdit}
38
+ />
39
+
40
+ // ❌ Bad: AI acts without user confirmation
41
+ useEffect(() => {
42
+ if (aiResponse) {
43
+ saveToDatabase(aiResponse); // No user review!
44
+ }
45
+ }, [aiResponse]);
46
+ ```
47
+
48
+ ### Graceful Degradation
49
+
50
+ **Rule**: Application must function without AI when it fails.
51
+
52
+ ```tsx
53
+ // ✅ Good: Fallback when AI unavailable
54
+ const content = aiGenerated || defaultContent;
55
+
56
+ // ❌ Bad: Broken UI when AI fails
57
+ {aiGenerated && <Content>{aiGenerated}</Content>}
58
+ ```
59
+
60
+ ---
61
+
62
+ ## Security & Safety Rules
63
+
64
+ ### API Key Security
65
+
66
+ **MUST**: Never expose API keys in client-side code.
67
+
68
+ ```tsx
69
+ // ✅ Good: Environment variable
70
+ const apiKey = import.meta.env.VITE_GEMINI_API_KEY;
71
+
72
+ // ❌ CRITICAL: Hardcoded key
73
+ const apiKey = "AIzaSyD..."; // NEVER DO THIS
74
+ ```
75
+
76
+ **MUST**: Use server-side proxy for production.
77
+
78
+ ```tsx
79
+ // ✅ Good: Server-side API route
80
+ const response = await fetch('/api/gemini', {
81
+ method: 'POST',
82
+ body: JSON.stringify({ prompt }),
83
+ });
84
+
85
+ // ❌ Bad: Direct client-side API call in production
86
+ const genAI = new GoogleGenerativeAI(apiKey);
87
+ ```
88
+
89
+ ### Prompt Injection Prevention
90
+
91
+ **Rule**: Sanitize and validate all user inputs before sending to Gemini.
92
+
93
+ ```tsx
94
+ // ✅ Good: Input validation
95
+ const sanitizedPrompt = prompt
96
+ .trim()
97
+ .slice(0, MAX_PROMPT_LENGTH)
98
+ .replace(/[<>]/g, ''); // Remove potential injection chars
99
+
100
+ // ❌ Bad: Raw user input
101
+ const response = await model.generateContent(userInput);
102
+ ```
103
+
104
+ ### Content Safety
105
+
106
+ **Rule**: Implement content filtering for user-facing AI responses.
107
+
108
+ ```tsx
109
+ // ✅ Good: Safety settings
110
+ const model = genAI.getGenerativeModel({
111
+ model: "gemini-pro",
112
+ safetySettings: [
113
+ {
114
+ category: HarmCategory.HARM_CATEGORY_HARASSMENT,
115
+ threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
116
+ },
117
+ {
118
+ category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
119
+ threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
120
+ },
121
+ ],
122
+ });
123
+ ```
124
+
125
+ **Rule**: Handle safety blocks gracefully.
126
+
127
+ ```tsx
128
+ // ✅ Good: Safety block handling
129
+ if (result.response.promptFeedback?.blockReason) {
130
+ setError('Content was blocked for safety reasons. Please rephrase your request.');
131
+ return;
132
+ }
133
+ ```
134
+
135
+ ---
136
+
137
+ ## UX Requirements
138
+
139
+ ### Streaming Response Pattern
140
+
141
+ **MUST**: Use streaming for all text generation over 50 words.
142
+
143
+ ```tsx
144
+ // ✅ Good: Streaming for better UX
145
+ const result = await model.generateContentStream(prompt);
146
+ for await (const chunk of result.stream) {
147
+ setText(prev => prev + chunk.text());
148
+ }
149
+
150
+ // ❌ Bad: Blocking until complete response
151
+ const result = await model.generateContent(prompt);
152
+ setText(result.response.text());
153
+ ```
154
+
155
+ ### Loading States
156
+
157
+ **MUST**: Show loading indicators during AI generation.
158
+
159
+ ```tsx
160
+ // ✅ Good: Clear loading state
161
+ {isLoading && (
162
+ <div role="status" aria-live="polite">
163
+ <Spinner />
164
+ <span>Generating response...</span>
165
+ </div>
166
+ )}
167
+
168
+ // ❌ Bad: No feedback during generation
169
+ {response && <div>{response}</div>}
170
+ ```
171
+
172
+ ### Streaming UI States
173
+
174
+ **MUST**: Use `aria-live` for streaming content.
175
+
176
+ ```tsx
177
+ // ✅ Good: Accessible streaming
178
+ <div aria-live="polite" aria-atomic="false">
179
+ {streamingText}
180
+ </div>
181
+
182
+ // ❌ Bad: Screen reader can't track updates
183
+ <div>{streamingText}</div>
184
+ ```
185
+
186
+ ### Error Handling UX
187
+
188
+ **MUST**: Provide actionable error messages with retry options.
189
+
190
+ ```tsx
191
+ // ✅ Good: User-friendly error handling
192
+ {error && (
193
+ <Alert severity="error">
194
+ <AlertTitle>Unable to generate response</AlertTitle>
195
+ {error.message}
196
+ <Button onClick={handleRetry}>Try Again</Button>
197
+ </Alert>
198
+ )}
199
+
200
+ // ❌ Bad: Technical error dump
201
+ {error && <div>Error: {error.toString()}</div>}
202
+ ```
203
+
204
+ ### AI Attribution
205
+
206
+ **MUST**: Clearly indicate AI-generated content.
207
+
208
+ ```tsx
209
+ // ✅ Good: Clear attribution
210
+ <div>
211
+ <p>{aiContent}</p>
212
+ <small>Generated by AI • Please verify accuracy</small>
213
+ </div>
214
+
215
+ // ❌ Bad: No indication content is AI-generated
216
+ <div>{aiContent}</div>
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Performance Rules
222
+
223
+ ### Response Caching
224
+
225
+ **Rule**: Cache responses for identical prompts.
226
+
227
+ ```tsx
228
+ // ✅ Good: Cache frequent queries
229
+ const cacheKey = hashPrompt(prompt);
230
+ const cached = cache.get(cacheKey);
231
+ if (cached) return cached;
232
+
233
+ const response = await generateContent(prompt);
234
+ cache.set(cacheKey, response, { ttl: 3600 });
235
+ ```
236
+
237
+ ### Rate Limiting
238
+
239
+ **MUST**: Implement client-side rate limiting to prevent quota exhaustion.
240
+
241
+ ```tsx
242
+ // ✅ Good: Rate limit user requests
243
+ const rateLimiter = new RateLimiter({
244
+ maxRequests: 10,
245
+ windowMs: 60000, // 10 requests per minute
246
+ });
247
+
248
+ if (!rateLimiter.check(userId)) {
249
+ throw new Error('Rate limit exceeded. Please try again later.');
250
+ }
251
+ ```
252
+
253
+ ### Timeout Handling
254
+
255
+ **MUST**: Set reasonable timeouts for AI requests.
256
+
257
+ ```tsx
258
+ // ✅ Good: Timeout protection
259
+ const controller = new AbortController();
260
+ const timeoutId = setTimeout(() => controller.abort(), 30000);
261
+
262
+ try {
263
+ const response = await fetch('/api/gemini', {
264
+ signal: controller.signal,
265
+ });
266
+ } catch (error) {
267
+ if (error.name === 'AbortError') {
268
+ setError('Request timed out. Please try again.');
269
+ }
270
+ } finally {
271
+ clearTimeout(timeoutId);
272
+ }
273
+ ```
274
+
275
+ ### Token Optimization
276
+
277
+ **Rule**: Minimize token usage for cost and performance.
278
+
279
+ ```tsx
280
+ // ✅ Good: Concise system instructions
281
+ const systemInstruction = "Summarize in 2-3 sentences.";
282
+
283
+ // ❌ Bad: Verbose, wasteful prompting
284
+ const systemInstruction = `
285
+ Please provide a comprehensive summary of the following text.
286
+ Make sure to include all key points and important details.
287
+ The summary should be well-structured and easy to read.
288
+ Please keep it concise but informative.
289
+ `;
290
+ ```
291
+
292
+ ---
293
+
294
+ ## Ethical Guidelines
295
+
296
+ ### Transparency
297
+
298
+ **MUST**: Users must know they're interacting with AI.
299
+
300
+ ```tsx
301
+ // ✅ Good: Clear AI disclosure
302
+ <Chatbot>
303
+ <Header>AI Assistant</Header>
304
+ <Disclaimer>
305
+ This is an AI chatbot. Responses may contain errors.
306
+ </Disclaimer>
307
+ </Chatbot>
308
+
309
+ // ❌ Bad: Misleading as human
310
+ <Chatbot>
311
+ <Header>Customer Support</Header>
312
+ </Chatbot>
313
+ ```
314
+
315
+ ### Bias Awareness
316
+
317
+ **Rule**: Acknowledge potential AI biases in documentation.
318
+
319
+ ```tsx
320
+ // ✅ Good: Bias disclaimer
321
+ <TermsOfService>
322
+ AI-generated content may reflect biases present in training data.
323
+ Use critical judgment when evaluating suggestions.
324
+ </TermsOfService>
325
+ ```
326
+
327
+ ### Data Privacy
328
+
329
+ **MUST**: Inform users about data sent to Gemini API.
330
+
331
+ ```tsx
332
+ // ✅ Good: Privacy notice
333
+ <PrivacyNotice>
334
+ Your input will be sent to Google's Gemini API for processing.
335
+ <Link to="/privacy">Learn more about data handling</Link>
336
+ </PrivacyNotice>
337
+ ```
338
+
339
+ **MUST**: Respect user consent for data sharing.
340
+
341
+ ```tsx
342
+ // ✅ Good: Opt-in consent
343
+ const [aiConsent, setAiConsent] = useState(false);
344
+
345
+ if (!aiConsent) {
346
+ return <ConsentDialog onAccept={() => setAiConsent(true)} />;
347
+ }
348
+ ```
349
+
350
+ ### Content Responsibility
351
+
352
+ **Rule**: Verify critical AI-generated content before using.
353
+
354
+ ```tsx
355
+ // ✅ Good: Verification step for critical content
356
+ <GeneratedContent>
357
+ {content}
358
+ <Warning>
359
+ This content was AI-generated and should be reviewed for accuracy.
360
+ </Warning>
361
+ <Button onClick={handleVerify}>Mark as Verified</Button>
362
+ </GeneratedContent>
363
+ ```
364
+
365
+ ---
366
+
367
+ ## Anti-Patterns
368
+
369
+ ### ❌ Blocking UI During Generation
370
+
371
+ ```tsx
372
+ // ❌ Bad: Freezes entire UI
373
+ const response = await model.generateContent(longPrompt);
374
+ setContent(response);
375
+
376
+ // ✅ Good: Non-blocking with streaming
377
+ const stream = await model.generateContentStream(longPrompt);
378
+ for await (const chunk of stream) {
379
+ setContent(prev => prev + chunk.text());
380
+ }
381
+ ```
382
+
383
+ ### ❌ No Loading Indicators
384
+
385
+ ```tsx
386
+ // ❌ Bad: Silent loading
387
+ const handleGenerate = async () => {
388
+ const result = await generateAI(prompt);
389
+ setResult(result);
390
+ };
391
+
392
+ // ✅ Good: Clear feedback
393
+ const handleGenerate = async () => {
394
+ setLoading(true);
395
+ try {
396
+ const result = await generateAI(prompt);
397
+ setResult(result);
398
+ } finally {
399
+ setLoading(false);
400
+ }
401
+ };
402
+ ```
403
+
404
+ ### ❌ Hardcoded Prompts
405
+
406
+ ```tsx
407
+ // ❌ Bad: Inflexible hardcoded prompts
408
+ const prompt = "Write a blog post about React";
409
+
410
+ // ✅ Good: Configurable prompt templates
411
+ const prompt = promptTemplate
412
+ .replace('{{topic}}', topic)
413
+ .replace('{{tone}}', tone)
414
+ .replace('{{length}}', length);
415
+ ```
416
+
417
+ ### ❌ No Error Recovery
418
+
419
+ ```tsx
420
+ // ❌ Bad: Crash on error
421
+ const result = await model.generateContent(prompt);
422
+ setText(result.text());
423
+
424
+ // ✅ Good: Graceful error handling
425
+ try {
426
+ const result = await model.generateContent(prompt);
427
+ setText(result.text());
428
+ } catch (error) {
429
+ setError(error);
430
+ setText(fallbackContent);
431
+ }
432
+ ```
433
+
434
+ ### ❌ Missing AI Attribution
435
+
436
+ ```tsx
437
+ // ❌ Bad: Presented as human-written
438
+ <ArticleContent>{aiGeneratedText}</ArticleContent>
439
+
440
+ // ✅ Good: Clear AI attribution
441
+ <ArticleContent>
442
+ {aiGeneratedText}
443
+ <Attribution>Content generated with AI assistance</Attribution>
444
+ </ArticleContent>
445
+ ```
446
+
447
+ ### ❌ Infinite Retry Loops
448
+
449
+ ```tsx
450
+ // ❌ Bad: Unlimited retries
451
+ const generateWithRetry = async () => {
452
+ try {
453
+ return await generate();
454
+ } catch {
455
+ return generateWithRetry(); // Infinite loop!
456
+ }
457
+ };
458
+
459
+ // ✅ Good: Limited retry attempts
460
+ const generateWithRetry = async (maxRetries = 3) => {
461
+ for (let i = 0; i < maxRetries; i++) {
462
+ try {
463
+ return await generate();
464
+ } catch (error) {
465
+ if (i === maxRetries - 1) throw error;
466
+ await sleep(1000 * Math.pow(2, i)); // Exponential backoff
467
+ }
468
+ }
469
+ };
470
+ ```
471
+
472
+ ---
473
+
474
+ ## Testing Considerations
475
+
476
+ ### Mock AI Responses
477
+
478
+ **Rule**: Mock Gemini API in tests for reliability.
479
+
480
+ ```tsx
481
+ // ✅ Good: Mocked AI for tests
482
+ jest.mock('@google/generative-ai', () => ({
483
+ GoogleGenerativeAI: jest.fn().mockImplementation(() => ({
484
+ getGenerativeModel: () => ({
485
+ generateContent: async () => ({
486
+ response: { text: () => 'Mocked AI response' },
487
+ }),
488
+ }),
489
+ })),
490
+ }));
491
+ ```
492
+
493
+ ### Test Error Scenarios
494
+
495
+ **Rule**: Test all AI failure modes.
496
+
497
+ ```tsx
498
+ // ✅ Good: Comprehensive error testing
499
+ describe('AI Generation', () => {
500
+ it('handles network errors', async () => {
501
+ mockAPI.mockRejectedValue(new NetworkError());
502
+ await expect(generate()).rejects.toThrow();
503
+ });
504
+
505
+ it('handles rate limiting', async () => {
506
+ mockAPI.mockRejectedValue(new RateLimitError());
507
+ // Assert error UI shown
508
+ });
509
+
510
+ it('handles content blocking', async () => {
511
+ mockAPI.mockResolvedValue({ blockReason: 'SAFETY' });
512
+ // Assert safety message shown
513
+ });
514
+ });
515
+ ```
516
+
517
+ ---
518
+
519
+ ## Related Resources
520
+
521
+ - [Google Gemini API Documentation](https://ai.google.dev/docs)
522
+ - [Generative AI Safety Guidelines](https://ai.google.dev/gemini-api/docs/safety-settings)
523
+ - [Best Practices for Prompting](https://ai.google.dev/gemini-api/docs/prompting-strategies)
524
+ - [Rate Limits and Quotas](https://ai.google.dev/gemini-api/docs/quota)
525
+ - [Responsible AI Practices](https://ai.google.dev/responsible)
526
+
527
+ ---
528
+
529
+ ## Integration Checklist
530
+
531
+ Before deploying Gemini integration:
532
+
533
+ - [ ] API keys stored securely (environment variables, never hardcoded)
534
+ - [ ] Safety settings configured
535
+ - [ ] Rate limiting implemented
536
+ - [ ] Timeout handling in place
537
+ - [ ] Loading states for all AI operations
538
+ - [ ] Error handling with user-friendly messages
539
+ - [ ] Retry logic with exponential backoff
540
+ - [ ] AI attribution visible on all generated content
541
+ - [ ] Privacy notice provided to users
542
+ - [ ] Content verification workflow for critical use cases
543
+ - [ ] Streaming implemented for long-form content
544
+ - [ ] Accessible ARIA labels for dynamic content
545
+ - [ ] Response caching for repeated queries
546
+ - [ ] Tests covering error scenarios
547
+ - [ ] Monitoring/logging for AI requests