// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 // The test double of the AI gateway for the documents module: a deterministic reader, standing in for a // model behind `platform.ai.respond` of the fake platform. // // It answers the extraction request exactly as a well-behaved model would: it finds the page's text // between the tags the prompt names, takes every `label: value` line as a field, and quotes the line // itself. It never sees an image, never invents a word, and returns the same lines for the same text, // so a test (or the offline eval) that runs it measures the module's own code -- the request it builds, // the schema it parses, the verification, the cache, the proposals -- and not a model. import { PAGE_TEXT_CLOSE, PAGE_TEXT_OPEN } from "@app/modules/documents" import type { FakeChatReply } from "@conusai-kit/testing/fake-platform" const FIELD = /^\s*([^::]+?)\s*[::]\s*(\S.*?)\s*$/u const MAX_LABEL_CHARS = 60 const MAX_LABEL_WORDS = 6 const MAX_LINE_CHARS = 2_000 export interface ReadLineOfModel { label: string value: string quote: string } /** * The fields a reader of two line shapes finds in a page's text: `label: value`, and a table row * `first cell | other cells`, whose label is the first cell and whose value is the rest, as the prompt * asks a model to read it. The first row of a block of rows is the table's header, which names the * columns and is not a field. */ export function keyValueLines(text: string): ReadLineOfModel[] { const found: ReadLineOfModel[] = [] let inTable = false for (const line of text.split("\n")) { if (line.includes(" | ")) { const header = !inTable inTable = true const [label, ...rest] = line.split(" | ").map((cell) => cell.trim()) if (!header && label && rest.length > 0 && rest.every((cell) => cell !== "") && line.length <= MAX_LINE_CHARS) { found.push({ label, value: rest.join(" | "), quote: line.trim() }) } continue } inTable = false const match = FIELD.exec(line) if (!match) continue const label = match[1] as string const value = match[2] as string if (label.length > MAX_LABEL_CHARS || label.split(/\s+/u).length > MAX_LABEL_WORDS) continue if (line.length > MAX_LINE_CHARS) continue found.push({ label, value, quote: line.trim() }) } return found } type Part = { type?: string; text?: string } /** The page text of an extraction request: what lies between the prompt's tags in the user's message. */ export function pageTextOf(request: Record): string | undefined { const messages = (request.messages ?? []) as Array<{ role?: string; content?: string | Part[] }> const user = [...messages].reverse().find((message) => message.role === "user") const content = user?.content const text = typeof content === "string" ? content : (content ?? []).map((part) => part.text ?? "").join("\n") const from = text.indexOf(PAGE_TEXT_OPEN) const to = text.lastIndexOf(PAGE_TEXT_CLOSE) return from < 0 || to < from ? undefined : text.slice(from + PAGE_TEXT_OPEN.length + 1, to - 1) } /** What an extraction request is answered with by the deterministic reader. */ export const deterministicModel = (request: Record): FakeChatReply => { const text = pageTextOf(request) return { content: JSON.stringify({ lines: text === undefined ? [] : keyValueLines(text) }) } }