Merge remote-tracking branch 'origin/main' into fix/v1397-tz

This commit is contained in:
Marc-André Bombeck committed 2026-10-01 10:59:51 +02:00
commit ada490c7e9
57 files changed
+1485 -99

No files matched your search

@@ -229,11 +229,15 @@ describe("POST /api/labs/ocr/extract — vision PDF rasterization", () => {
vi.mocked(rasterizePdf).mockResolvedValue({
ok: true,
images: [{ mediaType: "image/jpeg", dataBase64: "cGFnZQ==" }],
pageCount: 1,
});
vi.mocked(runOcrExtraction).mockResolvedValue({ rows: [] } as never);
const res = await POST(pdfReq());
expect(res.status).toBe(200);
// The whole PDF was read: no coverage note on the response.
const whole = (await res.json()) as { data: Record<string, unknown> };
expect(whole.data).not.toHaveProperty("pageCoverage");
expect(rasterizePdf).toHaveBeenCalledOnce();
// The rendered page images flow through as `input_image`s; no native PDF
// document block is sent for a non-Anthropic provider.
@@ -245,6 +249,26 @@ describe("POST /api/labs/ocr/extract — vision PDF rasterization", () => {
);
});
it("says on the response when only the first pages of a long PDF were read", async () => {
const tenPages = Array.from({ length: 10 }, () => ({
mediaType: "image/jpeg" as const,
dataBase64: "cGFnZQ==",
}));
vi.mocked(rasterizePdf).mockResolvedValue({
ok: true,
images: tenPages,
pageCount: 23,
});
vi.mocked(runOcrExtraction).mockResolvedValue({ rows: [] } as never);
const res = await POST(pdfReq());
expect(res.status).toBe(200);
const body = (await res.json()) as {
data: { pageCoverage?: { read: number; total: number } };
};
expect(body.data.pageCoverage).toEqual({ read: 10, total: 23 });
});
it("hands the slot back when the upload is not an image or PDF", async () => {
const form = new FormData();
form.append(
+16 -1
View File
@@ -374,6 +374,7 @@ async function handleVisionExtract(
dataBase64: string;
}[];
let documents: { mediaType: "application/pdf"; dataBase64: string }[];
let pageCoverage: { read: number; total: number } | undefined;
if (mime === "application/pdf") {
if (pick.pdfSupported) {
@@ -404,6 +405,20 @@ async function handleVisionExtract(
}
images = raster.images;
documents = [];
// A PDF longer than the page cap is read from its first pages only.
// That used to live in the wide event alone; the person reviewing the
// rows is the one who needs to know the rest of the report was not
// read.
if (raster.pageCount > raster.images.length) {
pageCoverage = {
read: raster.images.length,
total: raster.pageCount,
};
annotate({
action: { name: "labs.ocr.pagesCapped" },
meta: { read: raster.images.length, total: raster.pageCount },
});
}
}
} else {
images = [{ mediaType: mime, dataBase64: buffer.toString("base64") }];
@@ -431,7 +446,7 @@ async function handleVisionExtract(
0,
{ servedBy: pick.entry.providerType, reservedOwner: reservation.owner },
);
return apiSuccess(result);
return apiSuccess(pageCoverage ? { ...result, pageCoverage } : result);
} catch (err) {
// Provider/extraction failure — the call may still have burned tokens, so
// reconcile against the reserved estimate rather than refunding in full.