/**
* llmindex.io — vision OCR templates: generated SVG scenes, hostile but unambiguous
* Author: Simon-Pierre Boucher
* Contact: contact@spboucher.ai
* License: Proprietary — © Simon-Pierre Boucher, all rights reserved
*
* Multimodal reading under load: the target string is embedded in a generated
* scene among decoy strings, noise strokes, rotation and low-contrast patches.
* The character set excludes visually ambiguous glyphs (0/O, 1/l/I, 5/S, 8/B,
* 2/Z) so a perfect reader can always answer with certainty — difficulty comes
* from clutter and selection, never from unfair glyph ambiguity.
* The worker rasterizes `svg` to PNG; the prompt text never contains the code.
*/
import { ANSWER_FORMAT_INSTRUCTIONS } from '../answer';
import type { Rng } from '../rng';
import type { ItemTemplate } from '../types';
/** Unambiguous charset (no 0/O/Q, 1/I/l, 2/Z, 5/S, 8/B, 6/G). */
const GLYPHS = 'ACDEFHJKMNPRTUVWXY3479';
function code(rng: Rng, len: number): string {
let out = '';
for (let i = 0; i < len; i++) out += GLYPHS[rng.int(0, GLYPHS.length - 1)];
return out;
}
const PALETTE = [
{ name: 'red', fill: '#d92626' },
{ name: 'blue', fill: '#2563eb' },
{ name: 'green', fill: '#16a34a' },
{ name: 'orange', fill: '#ea8a1a' },
{ name: 'purple', fill: '#9333ea' },
] as const;
function noise(rng: Rng, w: number, h: number, n: number): string {
let out = '';
for (let i = 0; i < n; i++) {
out += ``;
}
return out;
}
export const visionCodeHunt: ItemTemplate = {
id: 'vision.ocr.code-hunt-v1',
domain: 'vision_ocr',
description:
'Transcribe the one code printed in a named color among rotated decoy codes, noise strokes and a low-contrast patch; unambiguous glyph set.',
paramSpace: 22 ** 8 * 5 * 4 ** 6,
render(rng: Rng, perturbSeed: string) {
const W = 560;
const H = 320;
const colors = rng.shuffle(PALETTE).slice(0, 4);
const target = colors[0]!;
const targetCode = code(rng, rng.int(6, 8));
const cells = rng.shuffle([
{ x: 90, y: 70 },
{ x: 360, y: 60 },
{ x: 120, y: 180 },
{ x: 390, y: 200 },
{ x: 240, y: 270 },
{ x: 250, y: 130 },
]);
let texts = '';
colors.forEach((c, i) => {
const cell = cells[i]!;
const isTarget = i === 0;
const value = isTarget ? targetCode : code(rng, rng.int(6, 8));
const rot = rng.int(-35, 35);
const size = isTarget ? rng.int(20, 26) : rng.int(20, 30);
const opacity = isTarget && rng.next() < 0.4 ? 0.55 : 1; // low-contrast twist
texts += `${value}`;
});
// extra black decoys
for (let i = 4; i < 6; i++) {
const cell = cells[i]!;
texts += `${code(rng, 7)}`;
}
const svg =
``;
return {
templateId: this.id,
domain: this.domain,
prompt:
`The image contains several printed codes in different colors, with noise. ` +
`Transcribe EXACTLY the code printed in ${target.name.toUpperCase()}. ` +
`It uses only digits and uppercase letters.\n\n${ANSWER_FORMAT_INSTRUCTIONS}`,
answerKey: targetCode,
grading: 'exact' as const,
perturbSeed,
svg,
};
},
};
export const visionTableRead: ItemTemplate = {
id: 'vision.ocr.table-read-v1',
domain: 'vision_ocr',
description:
'Read a rendered mini-table and compute a small aggregate (sum/max of a column subset) — OCR plus grounded arithmetic.',
paramSpace: 22 ** 4 * 90 ** 8 * 3,
render(rng: Rng, perturbSeed: string) {
const W = 520;
const H = 300;
const nRows = rng.int(5, 7);
const rows = Array.from({ length: nRows }, () => ({
id: code(rng, 4),
qty: rng.int(11, 97),
grade: rng.pick(['A', 'C', 'D'] as const),
}));
const targetGrade = rng.pick(['A', 'C', 'D'] as const);
if (!rows.some((r) => r.grade === targetGrade)) rows[rng.int(0, nRows - 1)]!.grade = targetGrade;
const mode = rng.pick(['sum', 'max'] as const);
const matched = rows.filter((r) => r.grade === targetGrade).map((r) => r.qty);
const answer = mode === 'sum' ? matched.reduce((a, b) => a + b, 0) : Math.max(...matched);
let body = '';
rows.forEach((r, i) => {
const y = 80 + i * 30;
body +=
`${r.id}` +
`${r.qty}` +
`${r.grade}`;
});
const svg =
``;
return {
templateId: this.id,
domain: this.domain,
prompt:
`The image shows a table with columns ID, QTY, GRADE. ` +
`Compute the ${mode === 'sum' ? 'SUM' : 'MAXIMUM'} of QTY over the rows whose GRADE is "${targetGrade}". ` +
`Answer with the number only.\n\n${ANSWER_FORMAT_INSTRUCTIONS}`,
answerKey: String(answer),
grading: 'numeric' as const,
perturbSeed,
svg,
};
},
};