fix: label system overhaul - sync dual storage, fix suggestions
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 53s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 53s
- Replace broken upsert (nbScope ?? '') with findFirst+create for null notebookId - Remove aggressive orphan cleanup that deleted notebook labels after save - Add syncNoteLabels() to update both Note.labels JSON and labelRelations - Fix createNote, updateNote, auto-labeling to use syncNoteLabels - Add fallback: suggestFromExistingLabels → suggestNewLabels if empty - Lower confidence threshold 0.6→0.3, max suggestions 3→5 - Case-insensitive label matching in suggestions Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -55,10 +55,12 @@ export class ContextualAutoTagService {
|
||||
|
||||
// CASE 1: Notebook has existing labels → suggest from them (IA2)
|
||||
if (notebook.labels.length > 0) {
|
||||
return await this.suggestFromExistingLabels(noteContent, notebook, language)
|
||||
const existing = await this.suggestFromExistingLabels(noteContent, notebook, language)
|
||||
if (existing.length > 0) return existing
|
||||
// Fallback: no existing label matched → suggest new ones too
|
||||
}
|
||||
|
||||
// CASE 2: Notebook has NO labels → suggest NEW labels to create
|
||||
// CASE 2: No labels in notebook (or none matched) → suggest NEW labels
|
||||
return await this.suggestNewLabels(noteContent, notebook, language)
|
||||
}
|
||||
|
||||
@@ -126,20 +128,23 @@ export class ContextualAutoTagService {
|
||||
return []
|
||||
}
|
||||
|
||||
// Filter and map suggestions
|
||||
// Filter and map suggestions (case-insensitive)
|
||||
const lowerAvailable = availableLabels.map((l: string) => l.toLowerCase())
|
||||
const suggestions = suggestionsArray
|
||||
.filter((s: any) => {
|
||||
// Must be in available labels
|
||||
return availableLabels.includes(s.label) && s.confidence > 0.6
|
||||
return s.label && lowerAvailable.includes(s.label.toLowerCase()) && (s.confidence || 0) > 0.3
|
||||
})
|
||||
.map((s: any) => ({
|
||||
label: s.label,
|
||||
.map((s: any) => {
|
||||
const originalLabel = availableLabels.find((l: string) => l.toLowerCase() === s.label.toLowerCase()) || s.label
|
||||
return {
|
||||
label: originalLabel,
|
||||
confidence: Math.round(s.confidence * 100),
|
||||
reasoning: s.reasoning || '',
|
||||
isNewLabel: false,
|
||||
}))
|
||||
}
|
||||
})
|
||||
.sort((a: any, b: any) => b.confidence - a.confidence)
|
||||
.slice(0, 3) // Max 3 suggestions
|
||||
.slice(0, 5)
|
||||
|
||||
return suggestions as LabelSuggestion[]
|
||||
} catch (error) {
|
||||
@@ -213,7 +218,7 @@ export class ContextualAutoTagService {
|
||||
// Filter and map suggestions
|
||||
const suggestions = suggestionsArray
|
||||
.filter((s: any) => {
|
||||
return s.label && s.label.length > 0 && s.confidence > 0.6
|
||||
return s.label && s.label.length > 0 && (s.confidence || 0) > 0.3
|
||||
})
|
||||
.map((s: any) => ({
|
||||
label: s.label,
|
||||
@@ -222,7 +227,7 @@ export class ContextualAutoTagService {
|
||||
isNewLabel: true, // Mark as new label suggestion
|
||||
}))
|
||||
.sort((a: any, b: any) => b.confidence - a.confidence)
|
||||
.slice(0, 3) // Max 3 suggestions
|
||||
.slice(0, 5)
|
||||
|
||||
return suggestions as LabelSuggestion[]
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user