chore(8.0): final pre-RC1 sweep — API consistency, named errors, orphans, zero-cast codebase

This commit is contained in:
David Snelling 2026-06-11 14:51:00 -07:00
parent 970e08c466
commit 1f7e365a4e
237 changed files with 1951 additions and 49413 deletions

View file

@ -164,7 +164,9 @@ export class SmartCSVImporter {
relatedColumn: 'related|see also|links|references',
csvDelimiter: undefined as string | undefined,
csvHeaders: true,
onProgress: () => {},
// Annotated with the full callback signature so the merged opts type has
// a single callable shape (the no-op default narrowed the union).
onProgress: (() => {}) as NonNullable<SmartCSVOptions['onProgress']>,
...options
}
@ -379,7 +381,7 @@ export class SmartCSVImporter {
throughput: Math.round(rowsPerSecond * 10) / 10,
eta: Math.round(estimatedTimeRemaining),
phase: 'extracting'
} as any)
})
}
return {

View file

@ -161,15 +161,9 @@ export class SmartExcelImporter {
const opts = {
enableNeuralExtraction: true,
enableRelationshipInference: true,
// CONCEPT EXTRACTION PRODUCTION-READY:
// Type embeddings are now pre-computed at build time - zero runtime cost!
// All 42 noun types + 127 verb types instantly available
//
// Performance profile:
// - Type embeddings: INSTANT (pre-computed at build time, ~100KB in-memory)
// - Model loading: ~2-5 seconds (one-time, cached after first use)
// - Per-row extraction: ~50-200ms depending on definition length
// - 100 rows: ~5-20 seconds total (production ready)
// Type embeddings are pre-computed at build time (~100KB in-memory),
// so concept extraction costs no runtime embedding calls: model loading
// is a one-time ~2-5s, then ~50-200ms per row.
// - 1000 rows: ~50-200 seconds (disable if needed via enableConceptExtraction: false)
//
// Enabled by default for production use.
@ -179,7 +173,9 @@ export class SmartExcelImporter {
definitionColumn: 'definition|description|desc|details',
typeColumn: 'type|category|kind',
relatedColumn: 'related|see also|links',
onProgress: () => {},
// Annotated with the full callback signature so the merged opts type has
// a single callable shape (the no-op default narrowed the union).
onProgress: (() => {}) as NonNullable<SmartExcelOptions['onProgress']>,
...options
}
@ -489,7 +485,7 @@ export class SmartExcelImporter {
throughput: Math.round(rowsPerSecond * 10) / 10,
eta: Math.round(estimatedTimeRemaining),
phase: 'extracting'
} as any)
})
}
// Group rows by sheet for VFS extraction

View file

@ -133,7 +133,10 @@ export class SmartImportOrchestrator {
const startTime = Date.now()
const result: SmartImportResult = {
success: false,
extraction: null as any,
// Typed boundary: populated in the extraction phase below. If extraction
// throws, the error path returns with this still null (pre-existing
// contract — consumers check `success`/`errors` before reading it).
extraction: null as unknown as SmartExcelResult,
entityIds: [],
relationshipIds: [],
stats: {
@ -193,7 +196,9 @@ export class SmartImportOrchestrator {
const entityId = await this.brain.add({
data: extracted.entity.description,
type: extracted.entity.type,
subtype: (extracted.entity as any).subtype ?? options.defaultSubtype ?? 'imported',
subtype:
(extracted.entity as typeof extracted.entity & { subtype?: string })
.subtype ?? options.defaultSubtype ?? 'imported',
confidence: extracted.entity.confidence, // reserved field — dedicated param, not metadata
metadata: {
...extracted.entity.metadata,
@ -280,7 +285,9 @@ export class SmartImportOrchestrator {
from: extracted.entity.id,
to: toEntityId,
type: rel.type,
subtype: (rel as any).subtype ?? options.defaultSubtype ?? 'imported',
subtype:
(rel as typeof rel & { subtype?: string }).subtype ??
options.defaultSubtype ?? 'imported',
metadata: {
confidence: rel.confidence,
evidence: rel.evidence
@ -393,7 +400,8 @@ export class SmartImportOrchestrator {
const startTime = Date.now()
const result: SmartImportResult = {
success: false,
extraction: null as any,
// Typed boundary: populated after extraction (see importExcel).
extraction: null as unknown as SmartExcelResult,
entityIds: [],
relationshipIds: [],
stats: {
@ -413,7 +421,7 @@ export class SmartImportOrchestrator {
const pdfResult = await this.pdfImporter.extract(buffer, options)
// Convert PDF result to Excel-like format for processing
result.extraction = this.convertPDFToExcelFormat(pdfResult) as any
result.extraction = this.convertPDFToExcelFormat(pdfResult)
result.stats.rowsProcessed = pdfResult.sectionsProcessed
// Phase 2 & 3: Create entities and relationships
@ -470,7 +478,8 @@ export class SmartImportOrchestrator {
const startTime = Date.now()
const result: SmartImportResult = {
success: false,
extraction: null as any,
// Typed boundary: populated after extraction (see importExcel).
extraction: null as unknown as SmartExcelResult,
entityIds: [],
relationshipIds: [],
stats: {
@ -488,7 +497,7 @@ export class SmartImportOrchestrator {
const jsonResult = await this.jsonImporter.extract(data, options)
result.extraction = this.convertJSONToExcelFormat(jsonResult) as any
result.extraction = this.convertJSONToExcelFormat(jsonResult)
result.stats.rowsProcessed = jsonResult.nodesProcessed
await this.createEntitiesAndRelationships(result, options, onProgress)
@ -532,7 +541,8 @@ export class SmartImportOrchestrator {
const startTime = Date.now()
const result: SmartImportResult = {
success: false,
extraction: null as any,
// Typed boundary: populated after extraction (see importExcel).
extraction: null as unknown as SmartExcelResult,
entityIds: [],
relationshipIds: [],
stats: {
@ -550,7 +560,7 @@ export class SmartImportOrchestrator {
const mdResult = await this.markdownImporter.extract(markdown, options)
result.extraction = this.convertMarkdownToExcelFormat(mdResult) as any
result.extraction = this.convertMarkdownToExcelFormat(mdResult)
result.stats.rowsProcessed = mdResult.sectionsProcessed
await this.createEntitiesAndRelationships(result, options, onProgress)
@ -601,7 +611,9 @@ export class SmartImportOrchestrator {
const entityId = await this.brain.add({
data: extracted.entity.description,
type: extracted.entity.type,
subtype: (extracted.entity as any).subtype ?? options.defaultSubtype ?? 'imported',
subtype:
(extracted.entity as typeof extracted.entity & { subtype?: string })
.subtype ?? options.defaultSubtype ?? 'imported',
confidence: extracted.entity.confidence, // reserved field — dedicated param, not metadata
metadata: { ...extracted.entity.metadata, name: extracted.entity.name, importedFrom: 'smart-import' }
})
@ -637,7 +649,7 @@ export class SmartImportOrchestrator {
}
// Relationship subtype precedence: extractor → caller default → `'imported'` (7.30.1).
// `confidence` is a reserved top-level field — dedicated relate() param, not metadata
relationshipParams.push({ from: extracted.entity.id, to: toEntityId, type: rel.type, subtype: (rel as any).subtype ?? options.defaultSubtype ?? 'imported', confidence: rel.confidence, metadata: { evidence: rel.evidence } })
relationshipParams.push({ from: extracted.entity.id, to: toEntityId, type: rel.type, subtype: (rel as typeof rel & { subtype?: string }).subtype ?? options.defaultSubtype ?? 'imported', confidence: rel.confidence, metadata: { evidence: rel.evidence } })
} catch (error: any) {
result.errors.push(`Failed to prepare relationship: ${error.message}`)
}
@ -688,7 +700,7 @@ export class SmartImportOrchestrator {
rows,
entityMap: pdfResult.entityMap,
processingTime: pdfResult.processingTime,
stats: pdfResult.stats as any
stats: pdfResult.stats
}
}
@ -710,7 +722,7 @@ export class SmartImportOrchestrator {
rows,
entityMap: jsonResult.entityMap,
processingTime: jsonResult.processingTime,
stats: jsonResult.stats as any
stats: jsonResult.stats
}
}
@ -734,7 +746,7 @@ export class SmartImportOrchestrator {
rows,
entityMap: mdResult.entityMap,
processingTime: mdResult.processingTime,
stats: mdResult.stats as any
stats: mdResult.stats
}
}

View file

@ -176,7 +176,9 @@ export class SmartPDFImporter {
minParagraphLength: 50,
extractFromTables: true,
groupBy: 'document' as const,
onProgress: () => {},
// Annotated with the full callback signature so the merged opts type has
// a single callable shape (the no-op default narrowed the union).
onProgress: (() => {}) as NonNullable<SmartPDFOptions['onProgress']>,
...options
}
@ -274,7 +276,7 @@ export class SmartPDFImporter {
throughput: Math.round(sectionsPerSecond * 10) / 10,
eta: Math.round(estimatedTimeRemaining),
phase: 'extracting'
} as any)
})
}
const pagesProcessed = new Set(data.map(d => d._page)).size
@ -338,7 +340,7 @@ export class SmartPDFImporter {
* Process a single section
*/
private async processSection(
group: { id: string, type: string, items: Array<Record<string, any>> },
group: { id: string, type: 'page' | 'paragraph' | 'table', items: Array<Record<string, any>> },
options: SmartPDFOptions,
stats: SmartPDFResult['stats'],
entityMap: Map<string, string>
@ -444,7 +446,7 @@ export class SmartPDFImporter {
return {
sectionId: group.id,
sectionType: group.type as any,
sectionType: group.type,
entities,
relationships,
concepts,

View file

@ -69,13 +69,14 @@ export class ExcelHandler extends BaseFormatHandler {
const sheet = workbook.Sheets[sheetName]
if (!sheet) continue
// Convert sheet to JSON with headers
const sheetData = XLSX.utils.sheet_to_json(sheet, {
// Convert sheet to JSON with headers. `header: 1` makes xlsx return
// rows as arrays of raw cell values, typed via the generic overload.
const sheetData = XLSX.utils.sheet_to_json<unknown[]>(sheet, {
header: 1, // Get as array of arrays first
defval: null,
blankrows: false,
raw: false // Convert to formatted strings
}) as any[][]
})
if (sheetData.length === 0) continue

View file

@ -70,8 +70,20 @@ export class PDFHandler extends BaseFormatHandler {
const pdfDoc = await loadingTask.promise
// Extract metadata
// Extract metadata. pdfjs-dist types getMetadata().info as the bare
// `Object` type, so the well-known PDF document-information dictionary
// keys (PDF 32000-1:2008 §14.3.3) are surfaced via a structural type at
// this library boundary.
const metadata = await pdfDoc.getMetadata()
const documentInfo = metadata.info as {
Title?: string
Author?: string
Subject?: string
Creator?: string
Producer?: string
CreationDate?: string
ModDate?: string
} | undefined
const numPages = pdfDoc.numPages
// Report document loaded
@ -177,13 +189,13 @@ export class PDFHandler extends BaseFormatHandler {
textLength: totalTextLength,
tableCount: detectedTables,
pdfMetadata: {
title: (metadata.info as any)?.Title || null,
author: (metadata.info as any)?.Author || null,
subject: (metadata.info as any)?.Subject || null,
creator: (metadata.info as any)?.Creator || null,
producer: (metadata.info as any)?.Producer || null,
creationDate: (metadata.info as any)?.CreationDate || null,
modificationDate: (metadata.info as any)?.ModDate || null
title: documentInfo?.Title || null,
author: documentInfo?.Author || null,
subject: documentInfo?.Subject || null,
creator: documentInfo?.Creator || null,
producer: documentInfo?.Producer || null,
creationDate: documentInfo?.CreationDate || null,
modificationDate: documentInfo?.ModDate || null
}
}
),