Add AI price verification feature

When enabled, AI verifies every scraped price to ensure accuracy.
This catches issues like scraped "savings" amounts instead of actual prices.

- Add ai_verification_enabled column to users table
- Create verification prompt and functions for Anthropic, OpenAI, Ollama
- Integrate verification step into scraper after traditional scraping
- Add verification toggle to Settings page (separate from AI extraction)
- AI verification is independent of AI extraction fallback

Flow: Traditional scraping -> AI verification (if enabled) -> AI extraction fallback (if no price found)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
clucraft 2026-01-23 09:24:17 -05:00
parent 7afa3ccec3
commit dc4e7b9665
6 changed files with 278 additions and 4 deletions

View file

@ -47,6 +47,7 @@ export default function Settings() {
// AI state
const [aiSettings, setAISettings] = useState<AISettings | null>(null);
const [aiEnabled, setAIEnabled] = useState(false);
const [aiVerificationEnabled, setAIVerificationEnabled] = useState(false);
const [aiProvider, setAIProvider] = useState<'anthropic' | 'openai' | 'ollama'>('anthropic');
const [anthropicApiKey, setAnthropicApiKey] = useState('');
const [openaiApiKey, setOpenaiApiKey] = useState('');
@ -97,6 +98,7 @@ export default function Settings() {
// Populate AI fields with actual values
setAISettings(aiRes.data);
setAIEnabled(aiRes.data.ai_enabled);
setAIVerificationEnabled(aiRes.data.ai_verification_enabled ?? false);
if (aiRes.data.ai_provider) {
setAIProvider(aiRes.data.ai_provider);
}
@ -353,6 +355,7 @@ export default function Settings() {
try {
const response = await settingsApi.updateAI({
ai_enabled: aiEnabled,
ai_verification_enabled: aiVerificationEnabled,
ai_provider: aiProvider,
anthropic_api_key: anthropicApiKey || undefined,
openai_api_key: openaiApiKey || undefined,
@ -360,6 +363,7 @@ export default function Settings() {
ollama_model: aiProvider === 'ollama' ? ollamaModel || null : undefined,
});
setAISettings(response.data);
setAIVerificationEnabled(response.data.ai_verification_enabled ?? false);
setAnthropicApiKey('');
setOpenaiApiKey('');
setSuccess('AI settings saved successfully');
@ -1287,7 +1291,20 @@ export default function Settings() {
/>
</div>
{aiEnabled && (
<div className="settings-toggle">
<div className="settings-toggle-label">
<span className="settings-toggle-title">Enable AI Verification</span>
<span className="settings-toggle-description">
Verify all scraped prices with AI to ensure accuracy
</span>
</div>
<button
className={`toggle-switch ${aiVerificationEnabled ? 'active' : ''}`}
onClick={() => setAIVerificationEnabled(!aiVerificationEnabled)}
/>
</div>
{(aiEnabled || aiVerificationEnabled) && (
<>
<div className="settings-form-group">
<label>AI Provider</label>