bugsink mcp and claude subagents - documentation and test fixes
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 19m11s
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 19m11s
This commit is contained in:
@@ -44,12 +44,12 @@ The ai-usage subagent understands:
|
||||
|
||||
## Key Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/services/aiService.server.ts` | Gemini API integration |
|
||||
| `src/services/flyerProcessingService.server.ts` | Flyer extraction pipeline |
|
||||
| `src/schemas/flyer.schemas.ts` | Zod schemas for AI output validation |
|
||||
| `src/types/ai.types.ts` | TypeScript types for AI responses |
|
||||
| File | Purpose |
|
||||
| ----------------------------------------------- | ------------------------------------ |
|
||||
| `src/services/aiService.server.ts` | Gemini API integration |
|
||||
| `src/services/flyerProcessingService.server.ts` | Flyer extraction pipeline |
|
||||
| `src/schemas/flyer.schemas.ts` | Zod schemas for AI output validation |
|
||||
| `src/types/ai.types.ts` | TypeScript types for AI responses |
|
||||
|
||||
## Example Requests
|
||||
|
||||
@@ -95,6 +95,7 @@ const processedImages = await imageProcessor.prepareForAI(uploadedFile);
|
||||
### 2. Prompt Construction
|
||||
|
||||
The extraction prompt includes:
|
||||
|
||||
- System instructions for the AI model
|
||||
- Expected output schema (JSON)
|
||||
- Examples of correct extraction
|
||||
@@ -103,11 +104,7 @@ The extraction prompt includes:
|
||||
### 3. API Call
|
||||
|
||||
```typescript
|
||||
const response = await aiService.extractFlyerData(
|
||||
processedImages,
|
||||
storeContext,
|
||||
extractionOptions
|
||||
);
|
||||
const response = await aiService.extractFlyerData(processedImages, storeContext, extractionOptions);
|
||||
```
|
||||
|
||||
### 4. Response Validation
|
||||
@@ -131,6 +128,7 @@ const normalizedItems = normalizeExtractedItems(validatedItems);
|
||||
**Symptoms**: Same item priced differently on different extractions.
|
||||
|
||||
**Solution**: Improve prompt with explicit price format examples:
|
||||
|
||||
```
|
||||
"Price formats to recognize:
|
||||
- $X.XX (regular price)
|
||||
@@ -145,6 +143,7 @@ const normalizedItems = normalizeExtractedItems(validatedItems);
|
||||
**Symptoms**: Flyers with many items on one page have missing extractions.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Split page into quadrants for separate extraction
|
||||
2. Increase token limit for response
|
||||
3. Use structured grid-based prompting
|
||||
@@ -154,18 +153,23 @@ const normalizedItems = normalizeExtractedItems(validatedItems);
|
||||
**Symptoms**: `429 Too Many Requests` errors during bulk uploads.
|
||||
|
||||
**Solution**: Implement request queuing:
|
||||
|
||||
```typescript
|
||||
// Add to job queue instead of direct call
|
||||
await flyerQueue.add('extract', {
|
||||
flyerId,
|
||||
images,
|
||||
}, {
|
||||
attempts: 3,
|
||||
backoff: {
|
||||
type: 'exponential',
|
||||
delay: 2000,
|
||||
await flyerQueue.add(
|
||||
'extract',
|
||||
{
|
||||
flyerId,
|
||||
images,
|
||||
},
|
||||
});
|
||||
{
|
||||
attempts: 3,
|
||||
backoff: {
|
||||
type: 'exponential',
|
||||
delay: 2000,
|
||||
},
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
### Issue: Hallucinated Items
|
||||
@@ -173,6 +177,7 @@ await flyerQueue.add('extract', {
|
||||
**Symptoms**: Items extracted that don't exist in the flyer.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Add confidence scoring to extraction
|
||||
2. Request bounding box coordinates for verification
|
||||
3. Add post-extraction validation against image
|
||||
@@ -227,31 +232,34 @@ For each item:
|
||||
|
||||
### Metrics to Track
|
||||
|
||||
| Metric | Description | Target |
|
||||
|--------|-------------|--------|
|
||||
| Extraction success rate | % of flyers processed without error | >95% |
|
||||
| Items per flyer | Average items extracted | Varies by store |
|
||||
| Price accuracy | Match rate vs manual verification | >98% |
|
||||
| Response time | Time from upload to extraction complete | <30s |
|
||||
| Metric | Description | Target |
|
||||
| ----------------------- | --------------------------------------- | --------------- |
|
||||
| Extraction success rate | % of flyers processed without error | >95% |
|
||||
| Items per flyer | Average items extracted | Varies by store |
|
||||
| Price accuracy | Match rate vs manual verification | >98% |
|
||||
| Response time | Time from upload to extraction complete | <30s |
|
||||
|
||||
### Logging
|
||||
|
||||
```typescript
|
||||
log.info({
|
||||
flyerId,
|
||||
itemCount: extractedItems.length,
|
||||
processingTime: duration,
|
||||
modelVersion: response.model,
|
||||
tokenUsage: response.usage,
|
||||
}, 'Flyer extraction completed');
|
||||
log.info(
|
||||
{
|
||||
flyerId,
|
||||
itemCount: extractedItems.length,
|
||||
processingTime: duration,
|
||||
modelVersion: response.model,
|
||||
tokenUsage: response.usage,
|
||||
},
|
||||
'Flyer extraction completed',
|
||||
);
|
||||
```
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| `VITE_GOOGLE_GENAI_API_KEY` | Gemini API key (production) |
|
||||
| `VITE_GOOGLE_GENAI_API_KEY_TEST` | Gemini API key (test) |
|
||||
| Variable | Purpose |
|
||||
| -------------------------------- | --------------------------- |
|
||||
| `VITE_GOOGLE_GENAI_API_KEY` | Gemini API key (production) |
|
||||
| `VITE_GOOGLE_GENAI_API_KEY_TEST` | Gemini API key (test) |
|
||||
|
||||
**Note**: Use separate API keys for production and test to avoid rate limit conflicts and enable separate billing tracking.
|
||||
|
||||
@@ -260,6 +268,7 @@ log.info({
|
||||
### Unit Tests
|
||||
|
||||
Mock the Gemini API response:
|
||||
|
||||
```typescript
|
||||
vi.mock('@google/generative-ai', () => ({
|
||||
GoogleGenerativeAI: vi.fn().mockImplementation(() => ({
|
||||
@@ -277,6 +286,7 @@ vi.mock('@google/generative-ai', () => ({
|
||||
### Integration Tests
|
||||
|
||||
Use recorded responses for deterministic testing:
|
||||
|
||||
```typescript
|
||||
// Save real API responses to fixtures
|
||||
const fixtureResponse = await fs.readFile('fixtures/gemini-response.json');
|
||||
|
||||
Reference in New Issue
Block a user