This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
// What an extracted line is, as the proposal that carries it and as the reviewer sees it.
|
||||
|
||||
import { z } from "zod"
|
||||
import { LINE_NOTES, LINE_STATUSES, LINE_VERIFICATIONS } from "./constants.js"
|
||||
|
||||
/** The proposal target this module contributes to `proposals.targets`: the writer of approved lines. */
|
||||
export const LINE_TARGET_KEY = "documents.line"
|
||||
|
||||
/** The `files.processors` key and the job it names. */
|
||||
export const PROCESSOR_KEY = "documents.ocr"
|
||||
export const OCR_JOB = "documents.ocr"
|
||||
|
||||
/** The audit events of this module, declared in its manifest. */
|
||||
export const EXPORT_CREATED = "documents.export_created"
|
||||
export const LINE_EDITED = "documents.line_edited"
|
||||
|
||||
/** The content types the module reads. Spreadsheets are the customer's own extraction, not the template's. */
|
||||
export const READABLE_CONTENT_TYPES = ["application/pdf", "image/png", "image/jpeg"] as const
|
||||
|
||||
/**
|
||||
* The change a proposal carries and approval writes. `lineKey` is derived from the document and the
|
||||
* line's position, so an extraction retried after a crash adds nothing a person already decided.
|
||||
*/
|
||||
export const lineChangeSchema = z
|
||||
.object({
|
||||
lineKey: z.string().regex(/^[0-9a-f]{64}$/, "a lower-case hex SHA-256"),
|
||||
label: z.string().min(1).max(200),
|
||||
value: z.string().min(1).max(2_000),
|
||||
page: z.number().int().min(1),
|
||||
/** Where the line sits in the document's reading order: what a review and an export sort by. */
|
||||
position: z.number().int().min(0),
|
||||
quote: z.string().min(1).max(2_000),
|
||||
/** The reader's confidence in the words the line was read from, 0 to 1; a reviewer sorts by it. */
|
||||
confidence: z.number().min(0).max(1),
|
||||
/** `needs_review` when the quote was not found on the page it cites (see `LINE_VERIFICATIONS`). */
|
||||
verification: z.enum(LINE_VERIFICATIONS),
|
||||
/** Why a reviewer should look at the line besides `verification`; absent when there is nothing to add. */
|
||||
note: z.enum(LINE_NOTES).optional(),
|
||||
/** True once a reviewer has corrected the label or the value (the proposals module records who and when). */
|
||||
edited: z.boolean(),
|
||||
})
|
||||
.strict()
|
||||
|
||||
export type LineChange = z.output<typeof lineChangeSchema>
|
||||
|
||||
/**
|
||||
* What a model is asked to return for one page: the line schema above, cut to the fields a model can
|
||||
* know. The page is the question's, not the answer's (a model that cites a page may cite the wrong
|
||||
* one), the position and the key are the code's, and a confidence is measured from the reader, not
|
||||
* asked of the model. The JSON Schema sent to the gateway is derived from this.
|
||||
*/
|
||||
export const modelLineSchema = lineChangeSchema.pick({ label: true, value: true, quote: true }).strict()
|
||||
|
||||
export const MAX_MODEL_LINES = 200
|
||||
|
||||
export const modelLinesSchema = z.object({ lines: z.array(modelLineSchema).max(MAX_MODEL_LINES) }).strict()
|
||||
|
||||
export type ModelLines = z.output<typeof modelLinesSchema>
|
||||
|
||||
/** One line as the review screen shows it: the change, where it was read, and what was decided. */
|
||||
export const lineViewSchema = z.object({
|
||||
/** The proposal's id: it is what approve, reject and edit are called with. */
|
||||
lineId: z.string(),
|
||||
/** The proposal version the reviewer saw; approval pins to it to prevent approving a later edit. */
|
||||
expectedVersion: z.number().int().min(1),
|
||||
status: z.enum(LINE_STATUSES),
|
||||
label: z.string(),
|
||||
value: z.string(),
|
||||
page: z.number().int(),
|
||||
quote: z.string(),
|
||||
box: z.object({ x: z.number(), y: z.number(), width: z.number(), height: z.number() }).nullable(),
|
||||
confidence: z.number(),
|
||||
verification: z.enum(LINE_VERIFICATIONS),
|
||||
note: z.enum(LINE_NOTES).nullable(),
|
||||
/** The reader's stable id of the block the quote sits in (`p{page}-b{n}`), when the reader gave one. */
|
||||
blockId: z.string().nullable(),
|
||||
edited: z.boolean(),
|
||||
/** The model and version that produced the line: the disclosure Art. 50 asks for sits beside it. */
|
||||
model: z.string(),
|
||||
promptVersion: z.string(),
|
||||
decidedAt: z.string().nullable(),
|
||||
})
|
||||
|
||||
export type LineView = z.output<typeof lineViewSchema>
|
||||
Reference in New Issue
Block a user