debug: add diagnostic logging for label suggestion flow
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 42s

Log key points in /api/ai/tags and ContextualAutoTagService to trace
where label suggestions fail: notebook lookup, AI raw response,
JSON parsing, filtered results.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-27 00:18:20 +02:00
parent 6ff8088cc2
commit 295bc29786
2 changed files with 15 additions and 4 deletions

View File

@@ -31,6 +31,7 @@ export async function POST(req: NextRequest) {
// If notebookId is provided, use contextual suggestions (IA2) // If notebookId is provided, use contextual suggestions (IA2)
if (notebookId) { if (notebookId) {
try { try {
console.log('[/api/ai/tags] contextual request — notebookId:', notebookId, 'content length:', content.length)
const suggestions = await contextualAutoTagService.suggestLabels( const suggestions = await contextualAutoTagService.suggestLabels(
content, content,
notebookId, notebookId,
@@ -38,6 +39,8 @@ export async function POST(req: NextRequest) {
language language
); );
console.log('[/api/ai/tags] suggestions:', suggestions.length, suggestions.map(s => `${s.label}(${s.confidence})`))
const convertedTags = suggestions.map(s => ({ const convertedTags = suggestions.map(s => ({
tag: s.label, tag: s.label,
confidence: s.confidence, confidence: s.confidence,

View File

@@ -50,12 +50,16 @@ export class ContextualAutoTagService {
}) })
if (!notebook) { if (!notebook) {
console.log('[ContextualAutoTag] notebook not found for id:', notebookId)
return [] return []
} }
console.log('[ContextualAutoTag] notebook:', notebook.name, 'labels:', notebook.labels.map((l: any) => l.name))
// CASE 1: Notebook has existing labels → suggest from them (IA2) // CASE 1: Notebook has existing labels → suggest from them (IA2)
if (notebook.labels.length > 0) { if (notebook.labels.length > 0) {
const existing = await this.suggestFromExistingLabels(noteContent, notebook, language) const existing = await this.suggestFromExistingLabels(noteContent, notebook, language)
console.log('[ContextualAutoTag] existing label suggestions:', existing.length)
if (existing.length > 0) return existing if (existing.length > 0) return existing
// Fallback: no existing label matched → suggest new ones too // Fallback: no existing label matched → suggest new ones too
} }
@@ -83,6 +87,7 @@ export class ContextualAutoTagService {
// Use generateText with JSON response // Use generateText with JSON response
const response = await provider.generateText(prompt) const response = await provider.generateText(prompt)
console.log('[ContextualAutoTag] AI raw response (existing):', response?.substring(0, 300))
// Improved JSON parsing with multiple fallback strategies // Improved JSON parsing with multiple fallback strategies
let parsed: any let parsed: any
@@ -111,7 +116,7 @@ export class ContextualAutoTagService {
cleanedJson = cleanedJson.replace(/([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g, '$1"$2":') cleanedJson = cleanedJson.replace(/([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g, '$1"$2":')
parsed = JSON.parse(cleanedJson) parsed = JSON.parse(cleanedJson)
} else { } else {
console.error(' Could not extract JSON from response') console.error('[ContextualAutoTag] Could not extract JSON from response')
return [] return []
} }
} }
@@ -124,7 +129,7 @@ export class ContextualAutoTagService {
} else if (Array.isArray(parsed)) { } else if (Array.isArray(parsed)) {
suggestionsArray = parsed suggestionsArray = parsed
} else { } else {
console.error(' Invalid response structure:', parsed) console.error('[ContextualAutoTag] Invalid response structure:', parsed)
return [] return []
} }
@@ -146,6 +151,7 @@ export class ContextualAutoTagService {
.sort((a: any, b: any) => b.confidence - a.confidence) .sort((a: any, b: any) => b.confidence - a.confidence)
.slice(0, 5) .slice(0, 5)
console.log('[ContextualAutoTag] filtered existing suggestions:', suggestions.length, suggestions.map((s: any) => `${s.label}(${s.confidence})`))
return suggestions as LabelSuggestion[] return suggestions as LabelSuggestion[]
} catch (error) { } catch (error) {
console.error('Failed to suggest labels:', error) console.error('Failed to suggest labels:', error)
@@ -170,6 +176,7 @@ export class ContextualAutoTagService {
// Use generateText with JSON response // Use generateText with JSON response
const response = await provider.generateText(prompt) const response = await provider.generateText(prompt)
console.log('[ContextualAutoTag] AI raw response (new):', response?.substring(0, 300))
// Improved JSON parsing with multiple fallback strategies // Improved JSON parsing with multiple fallback strategies
let parsed: any let parsed: any
@@ -198,7 +205,7 @@ export class ContextualAutoTagService {
cleanedJson = cleanedJson.replace(/([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g, '$1"$2":') cleanedJson = cleanedJson.replace(/([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g, '$1"$2":')
parsed = JSON.parse(cleanedJson) parsed = JSON.parse(cleanedJson)
} else { } else {
console.error(' Could not extract JSON from response') console.error('[ContextualAutoTag] Could not extract JSON from new-labels response')
return [] return []
} }
} }
@@ -211,7 +218,7 @@ export class ContextualAutoTagService {
} else if (Array.isArray(parsed)) { } else if (Array.isArray(parsed)) {
suggestionsArray = parsed suggestionsArray = parsed
} else { } else {
console.error('❌ Invalid response structure:', parsed) console.error('[ContextualAutoTag] Invalid new-labels response structure:', parsed)
return [] return []
} }
@@ -229,6 +236,7 @@ export class ContextualAutoTagService {
.sort((a: any, b: any) => b.confidence - a.confidence) .sort((a: any, b: any) => b.confidence - a.confidence)
.slice(0, 5) .slice(0, 5)
console.log('[ContextualAutoTag] new label suggestions:', suggestions.length, suggestions.map((s: any) => `${s.label}(${s.confidence})`))
return suggestions as LabelSuggestion[] return suggestions as LabelSuggestion[]
} catch (error) { } catch (error) {
console.error('❌ Failed to suggest new labels:', error) console.error('❌ Failed to suggest new labels:', error)