Node
Instala @dragon708/docmind-node y @dragon708/docmind-shared. analyzeFile, extractText, extractMetadata, convertToHtml, runOcr, extractStructuredData, getCapabilities y explainAnalysisPlan aceptan rutas, URLs file: u objetos DetectFileKindInput / NodeAnalyzeInput (bytes + name / mimeType).
NodeAnalyzeOptions (resumen):
signal— abortar.pdf— se reenvía a@dragon708/docmind-pdf(p. ej.ocr: "off" | "auto" | "force",ocrLangs).ocr—{ langs?, signal? }para Tesseract (imágenes y rutas relacionadas).docx—{ include?: AnalyzeDocxIncludeFlags, html?: DocxToHtmlOptions }. Siincludeactivastructure,headings,tables,blocks,pagesApproxoembeddedImages,analyzeFile,extractText,convertToHtmlyrunOcrfusionan Mammoth con extractores OOXML/ZIP de@dragon708/docmind-docx.extractMetadatasigue siendo stub para DOCX. Pasadocx: { include: … }aexplainAnalysisPlanpara ver pasos tipodocx_ooxml_parallelen el plan.
Uint8Array + nombre (shape del playground)
Coincide con src/lib/docmind-server.ts: la subida se lee a Uint8Array y se pasa como:
import { analyzeFile } from "@dragon708/docmind-node";
import type { DetectFileKindInput } from "@dragon708/docmind-shared";
async function analizarBytes(
data: Uint8Array,
name?: string,
mimeType?: string,
) {
const input = { data, name, mimeType } as DetectFileKindInput;
return analyzeFile(input, {
pdf: { ocr: "auto", ocrLangs: "eng" },
ocr: { langs: "eng" },
});
}extractText y el valor por defecto de OCR en PDF
extractText en @dragon708/docmind-node pasa por withPdfOcrDefaultOff: si omites options.pdf.ocr, el PDF se trata con ocr: "off" (solo rutas nativas / PDF.js). Los PDF escaneados pueden devolver text vacío aunque needsOCR sea true.
Pasa explícitamente pdf: { ocr: "auto" | "force", ocrLangs?, maxPages?, ocrStrategy? } para alinear con analyzeFile. En el playground, las acciones extract-text, convert-html y extract-structured mapean ocrMode (y tope de páginas / estrategia) a pdf.ocr en extractServerText / convertServerToHtml / extractServerStructuredData (src/lib/docmind-server.ts).
Esbozo de handler multipart
Igual que POST /api/analyze: leer a Uint8Array, reenviar name y type. Mapear ocrMode a pdf.ocr para analyze, explain-plan, extractText, convertToHtml y extractStructuredData si quieres el mismo comportamiento que el playground.
import { analyzeFile, extractText } from "@dragon708/docmind-node";
import type { DetectFileKindInput } from "@dragon708/docmind-shared";
export async function POST(req: Request) {
const form = await req.formData();
const file = form.get("file");
if (!(file instanceof File)) {
return new Response("Missing file", { status: 400 });
}
const ocrMode = String(form.get("ocrMode") ?? "auto");
const pdfOcr =
ocrMode === "off" || ocrMode === "auto" || ocrMode === "force"
? ocrMode
: "auto";
const data = new Uint8Array(await file.arrayBuffer());
const input = {
data,
name: file.name || undefined,
mimeType: file.type || undefined,
} as DetectFileKindInput;
const lang = String(form.get("language") ?? "").trim();
const pdfOpts = {
ocr: pdfOcr,
...(lang ? { ocrLangs: lang } : {}),
};
const action = String(form.get("action") ?? "analyze");
if (action === "extract-text") {
const textResult = await extractText(input, {
pdf: pdfOpts,
...(lang ? { ocr: { langs: lang } } : {}),
});
return Response.json(textResult);
}
const result = await analyzeFile(input, {
pdf: pdfOpts,
...(lang ? { ocr: { langs: lang } } : {}),
});
return Response.json(result);
}Epic 1 — getCapabilities / explainAnalysisPlan
Usa el mismo NodeAnalyzeInput (o ruta) que para analyzeFile. Pasa NodeAnalyzeOptions.pdf / ocr para que explainAnalysisPlan refleje la política OCR del PDF y el idioma.
import { getCapabilities, explainAnalysisPlan } from "@dragon708/docmind-node";
const caps = await getCapabilities(input);
const plan = await explainAnalysisPlan(input, {
intent: "analyzeFile",
pdf: { ocr: "auto", ocrLangs: "eng" },
ocr: { langs: "eng" },
docx: { include: { structure: true, pagesApprox: true } },
});Alternativas
readFileToInput("/ruta/al/archivo.pdf")cuando ya tienes ruta en disco.bufferToInput(buffer, "nombre.pdf")cuando tienes unBufferde Node.
Next.js / Vercel
Si expones @dragon708/docmind-node (o PDF/OCR) con un Route Handler de Next.js en Vercel u otro host serverless, configura outputFileTracingIncludes (y alinea serverExternalPackages) para que los workers de PDF.js y los ficheros satélite de Tesseract entren en el bundle de la función. En este playground, next.config.ts usa la clave /api/analyze; replica los mismos globs en cualquier otra ruta con el mismo stack. Guía detallada: Instalación — Next.js y Vercel (PDF.js y Tesseract).
Para extractMarkdown en servidor / .docx / PDF → Markdown, externaliza también @dragon708/docmind-markdown, mammoth, turndown y turndown-plugin-gfm para que Turbopack no rompa la resolución dinámica: Instalación — DOCX y Markdown en servidor (Turbopack). Mejor @dragon708/docmind-markdown ≥ 1.2.2, que empaqueta los conversores de servidor anidados dentro del paquete.