@aglyn/plugins-ai 1.0.0-beta.293 → 1.0.0-beta.296
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +17 -17
- package/src/lib/components/ai-job-links.d.ts +15 -2
- package/src/lib/components/ai-job-links.js +24 -3
- package/src/lib/components/ai-job-links.js.map +1 -1
- package/src/lib/components/ai-job-requests.d.ts +9 -0
- package/src/lib/components/ai-job-requests.js +34 -0
- package/src/lib/components/ai-job-requests.js.map +1 -1
- package/src/lib/components/ai-site-build-page.component.js +28 -2
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/components/assist-jobs-drawer.component.d.ts +7 -1
- package/src/lib/components/assist-jobs-drawer.component.js +20 -6
- package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
- package/src/lib/components/assist-page-change-card.component.d.ts +44 -0
- package/src/lib/components/assist-page-change-card.component.js +166 -0
- package/src/lib/components/assist-page-change-card.component.js.map +1 -0
- package/src/lib/components/assist-panel.component.d.ts +105 -1
- package/src/lib/components/assist-panel.component.js +224 -29
- package/src/lib/components/assist-panel.component.js.map +1 -1
- package/src/lib/jobs/ai-job-edit-step.d.ts +62 -16
- package/src/lib/jobs/ai-job-edit-step.js +172 -61
- package/src/lib/jobs/ai-job-edit-step.js.map +1 -1
- package/src/lib/jobs/ai-job-navigation-step.js +4 -2
- package/src/lib/jobs/ai-job-navigation-step.js.map +1 -1
- package/src/lib/model/ai-edit-job.d.ts +33 -16
- package/src/lib/model/ai-edit-job.js +50 -34
- package/src/lib/model/ai-edit-job.js.map +1 -1
- package/src/lib/model/ai-job-activity.d.ts +6 -11
- package/src/lib/model/ai-job-activity.js +8 -15
- package/src/lib/model/ai-job-activity.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +6 -0
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-site-inventory.d.ts +6 -0
- package/src/lib/model/ai-site-inventory.js.map +1 -1
- package/src/lib/model/assist-edit.d.ts +18 -1
- package/src/lib/model/assist-edit.js +7 -0
- package/src/lib/model/assist-edit.js.map +1 -1
- package/src/lib/model/assist-page-change.d.ts +86 -0
- package/src/lib/model/assist-page-change.js +86 -0
- package/src/lib/model/assist-page-change.js.map +1 -0
- package/src/lib/runtime/ai-eval.js +3 -1
- package/src/lib/runtime/ai-eval.js.map +1 -1
- package/src/lib/runtime/ai-node-tree.d.ts +5 -0
- package/src/lib/runtime/ai-node-tree.js +18 -3
- package/src/lib/runtime/ai-node-tree.js.map +1 -1
- package/src/lib/runtime/site-inventory.d.ts +8 -1
- package/src/lib/runtime/site-inventory.js +18 -0
- package/src/lib/runtime/site-inventory.js.map +1 -1
- package/src/lib/server/assist-build.js +2 -0
- package/src/lib/server/assist-build.js.map +1 -1
- package/src/lib/server/assist-chat.js +51 -2
- package/src/lib/server/assist-chat.js.map +1 -1
- package/src/lib/server/assist-edit.d.ts +54 -2
- package/src/lib/server/assist-edit.js +219 -30
- package/src/lib/server/assist-edit.js.map +1 -1
- package/src/lib/server/assist-page-change.d.ts +62 -0
- package/src/lib/server/assist-page-change.js +140 -0
- package/src/lib/server/assist-page-change.js.map +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-eval.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { HostTheme } from '@aglyn/shared-data-types'\nimport { validateStoredInteraction } from '@aglyn/aglyn/plugin-manager/interaction-step-checks'\nimport type { HostThemeSource } from '@aglyn/aglyn/app-utils/site-theme'\nimport {\n aiAutomationDraft,\n emptyAiAutomationRecords,\n type AiAutomationRecords,\n} from '../model/ai-automation-draft'\nimport type { ConsoleImportColumn } from '@aglyn/aglyn/plugin-manager/record-zone-props'\nimport { AI_BUILD_PLAN_CREATE_KINDS, type AiBuildPlanCreateKind } from '../model/ai-build-plan'\nimport {\n aiUnrestrictedPlanCapabilities,\n type AiPlanCapabilities,\n type AiPlanCreation,\n} from '../model/ai-plan-capabilities'\nimport {\n AI_EXPERIMENT_BODY_MAX_CHARS,\n AI_EXPERIMENT_HEADLINE_MAX_CHARS,\n AI_EXPERIMENT_LINE_MAX_CHARS,\n AI_EXPERIMENT_MAX_POINTS,\n AI_EXPERIMENT_NAME_MAX_CHARS,\n AI_EXPERIMENT_NEXT_MAX_CHARS,\n AI_EXPERIMENT_POINT_MAX_CHARS,\n AI_EXPERIMENT_RATIONALE_MAX_CHARS,\n aiExperimentVariantFields,\n checkAiExperimentExplanation,\n checkAiExperimentVariants,\n readAiExperimentResult,\n type AiExperimentArm,\n type AiExperimentTarget,\n type AiExperimentTask,\n} from '../model/ai-experiment'\nimport {\n parseAiExperimentExplanation,\n parseAiExperimentVariants,\n} from '../tools/ai-experiment-tool'\nimport type { AiSiteInventory } from '../model/ai-site-inventory'\nimport type { AiAutomationCapabilities } from '../model/ai-workflow-job'\nimport type { AiStepKind } from '../providers/catalog'\nimport type { AiEffort, AiUsage } from '../providers/contract'\nimport { aiComponentCheck } from '../jobs/ai-job-component-checks'\nimport { aiPlanTemplateTokenViolations } from '../jobs/ai-job-plan-conformance'\nimport { aiTemplateBindingCheck } from '../jobs/ai-job-template-step'\nimport type { AiJobPlan } from '../model/ai-jobs.types'\nimport {\n AI_TEMPLATE_SUBJECT_DEFINITIONS,\n aiTemplateAddressTokens,\n type AiTemplateSubject,\n type AiTemplateSubjectDefinition,\n} from '../model/ai-template-subjects'\nimport {\n aiProductMerchantWords,\n type AiProductCategory,\n type AiProductFacts,\n type AiProductPhotoRead,\n} from '../model/ai-products'\nimport type { AiRunRecord } from '../model/ai-automation-outline'\nimport { checkAiCatalog, checkAiCategories, checkAiProductCopy } from '../tools/ai-products-tool'\nimport type { AiCrmRecordKind, AiCrmTask } from '../model/ai-crm'\nimport {\n aiCrmEmailMergeFields,\n aiCrmImportFields,\n aiCrmRecordCheckContext,\n checkAiCrmEmail,\n checkAiCrmMapping,\n checkAiCrmRecord,\n} from '../tools/ai-crm-tool'\nimport { parseAiThemeToolInput } from '../tools/ai-theme-tool'\nimport {\n AI_AUTOMATION_OVERSIZE_CODES,\n AI_AUTOMATION_UNREADABLE_CODES,\n readAiAutomationAnswer,\n readAiWorkflowExplanation,\n} from '../tools/ai-workflow-tool'\nimport type { AiInsightTable } from '../model/ai-insight'\nimport { parseAiInsightAnswer } from '../tools/ai-insight-tool'\nimport { checkAiInsightAnswer } from './ai-insight-check'\nimport { aiDeviceAuditFindings, type AiDeviceAudit } from './ai-device-audit'\nimport {\n aiAnswerTree,\n aiDoctrinePlanCheck,\n aiDoctrineTreeCheck,\n aiDoctrineTreeContext,\n type AiGenerationCheckResult,\n type AiValidatedTree,\n} from './ai-doctrine'\nimport {\n AI_SEO_DESCRIPTION_MAX,\n AI_SEO_TITLE_MAX,\n aiPlanEmbedBriefViolations,\n detectOffVoiceCopy,\n detectPlaceholderCopy,\n detectPublishIntent,\n type AiAssetFacts,\n type AiCopyFraming,\n type AiDoctrineTree,\n type AiDoctrineViolation,\n} from './ai-doctrine-validators'\nimport { AI_TEXT_LIMITS, type AiOutputKind } from './ai-palette'\nimport { expandAiRepeatedItems } from './ai-repeated-items'\nimport type { AiAutomation } from '../model/ai-automation-format'\nimport type { HostFunction } from '@aglyn/aglyn/app-utils/functions'\nimport {\n checkAiLogicFunction,\n checkAiLogicVariable,\n type AiLogicSiteVariable,\n} from '../model/ai-logic-job'\nimport { aiEditJobOutline, type AiEditTargetKind } from '../model/ai-edit-job'\nimport {\n ASSIST_EDIT_MAX_INSERT_NODES,\n ASSIST_EDIT_MAX_OPS,\n checkAssistEditAnswer,\n parseAssistEditContext,\n} from '../server/assist-edit'\n\n/**\n * THE EVAL HARNESS (AGL-2937): the measure that gates every token lever.\n *\n * A token saved on a page the customer then has to fix costs more than the\n * token. So no lever ships on its token figure alone: each golden brief is\n * held to the same checks the doctrine holds a live answer to, and a kind's\n * pass rate and mean score must stay at or above its floor.\n *\n * A case is a golden brief for one output kind — the site it is built for,\n * the plan shape a good answer has, reference answers, and controls that\n * must fail. Every answer is scored on four checks:\n *\n * - **readable** — it reads as its kind: `validateAiNodeTree` admits the\n * tree, the plan parses, the fields and the copy are there;\n * - **rules** — no doctrine rule is broken (`ai-doctrine-validators.ts`),\n * nor any rule of the kind's own (a link to a page the answer was not\n * given, a title line on a blog body);\n * - **budget** — within the kind's measured budget: rule 17 for a document,\n * the length ceiling for copy;\n * - **rubric** — a grade against the brief for structure, copy fit and\n * reuse decisions, recorded from a stronger model on a live run.\n *\n * A document of a kind a site renders is also held to **responsive** (AGL-3020):\n * rendered at every device of the besigner's switcher, nothing runs past the\n * screen and no band keeps its desktop columns on a phone. It is measured in a\n * browser by `libs/plugins/ai/scripts/record-ai-page-axe.mts` and read back from that\n * recording, so it gates a pass without moving a score: a page that only works\n * on desktop does not pass, whatever its checks and grade average to.\n *\n * A planned kind's answer also carries the plan, held to the plan rules and\n * to the case's expected shape.\n *\n * Offline is the default and the only mode CI runs: answers and grades are\n * read from the fixtures under `tools/ai-eval/cases`, so a run costs nothing\n * and asserts the same verdicts every time. An answer marked `authored` was\n * written by hand as a reference and is graded by hand; one marked\n * `recorded` came from a live run. A live run spends real money and is\n * refused unless `AI_EVAL_LIVE=1` names it.\n */\n\n/** The output kinds the harness holds golden briefs for. */\nexport type AiEvalKind =\n | 'page'\n | 'template'\n | 'component'\n | 'layout'\n | 'form'\n | 'email'\n | 'section'\n | 'seo'\n | 'product'\n | 'catalog'\n | 'categories'\n | 'theme'\n | 'element'\n | 'blog'\n | 'text'\n | 'chat'\n | 'workflow'\n | 'insight'\n | 'crm'\n | 'experiment'\n | 'logic'\n | 'edit'\n\nexport const AI_EVAL_KINDS: readonly AiEvalKind[] = [\n 'page',\n 'template',\n 'component',\n 'layout',\n 'form',\n 'email',\n 'section',\n 'seo',\n 'product',\n 'catalog',\n 'categories',\n 'theme',\n 'element',\n 'blog',\n 'text',\n 'chat',\n 'workflow',\n 'insight',\n 'crm',\n 'experiment',\n 'logic',\n 'edit',\n]\n\n/** The document kind a tree kind is held to; a section rewrite is one reusable block. */\nexport const AI_EVAL_TREE_OUTPUT: Partial<Record<AiEvalKind, AiOutputKind>> = {\n page: 'page',\n template: 'template',\n component: 'component',\n layout: 'layout',\n form: 'form',\n email: 'email',\n section: 'component',\n}\n\n/**\n * Whether a kind's answer is a document a site renders, and so is held to\n * every device width (AGL-3020). An email is not: its column is fixed at 600px\n * by the medium, which rule 12 exempts it for.\n */\nexport function aiEvalRendersAtDeviceWidths(kind: AiEvalKind): boolean {\n const output = AI_EVAL_TREE_OUTPUT[kind]\n return output !== undefined && output !== 'email'\n}\n\n/**\n * The recorded device audit of an answer, or `null` when none was recorded\n * from it. The spec that scores the cases reads the recordings and answers\n * this; a scorer given none holds nothing to its widths.\n */\nexport type AiEvalAudits = (evalCase: AiEvalCase, answer: unknown) => AiDeviceAudit | null\n\n/** The checks an answer is scored on, beside its rubric. */\nexport type AiEvalCheck = 'readable' | 'rules' | 'budget' | 'plan' | 'responsive' | 'rubric'\n\n/** A grade against the brief, each criterion from 1 (fails) to 5 (excellent). */\nexport interface AiEvalRubric {\n /** Organized the way the brief needs, nothing missing, nothing extra. */\n structure: number\n /** The words fit the brief, the site and its audience, with no filler and no template placeholder (AGL-3827). */\n copy: number\n /** Reuses what the site lists before creating; `null` for a kind that places nothing. */\n reuse: number | null\n /** The model that graded it, or `authored` for a grade given by hand. */\n grader: string\n notes?: string\n}\n\n/** A plan's expected shape: what a good plan for the brief has. */\nexport interface AiEvalPlanShape {\n /** Screens planned, as `[min, max]`. */\n screens: [number, number]\n /** Inventory ids the plan must reuse. */\n reuse?: string[]\n /** The layout every planned screen renders inside. */\n layout?: string\n /** The most creations a good plan needs. */\n maxCreate?: number\n /** The kinds a creation may be. */\n createKinds?: AiBuildPlanCreateKind[]\n}\n\nexport interface AiEvalCandidate {\n /** `authored` for a reference written by hand; `recorded` for one a live run captured. */\n source: 'authored' | 'recorded'\n /**\n * `full` for an answer to the whole brief, the default; `plan` for the plan\n * alone, which a live run records for a planned kind whose generator has\n * not landed. A plan answer is held to the plan checks and its rubric, and\n * counts toward the plan step's score rather than the kind's floor.\n */\n scope?: 'full' | 'plan'\n /** The routing step and model a recorded answer came from; `null` for an authored one. */\n step: AiStepKind | null\n model: string | null\n effort: AiEffort | null\n /** The plan the plan step answered with, for a planned kind. */\n plan: unknown\n /**\n * The output as the kind's door answers: a tree tool's input (or the node\n * map itself), the copy as text, `{ title, description }` for search\n * fields, or the theme tool's input.\n */\n answer: unknown\n /** What a recorded answer spent; `null` for an authored one. */\n usage: AiUsage | null\n /**\n * A recorded answer's spend, one entry per metered exchange in the order\n * the job ran them — the plan, then every pass of its generation — with\n * the credits each came to as the machine meters a step (AGL-3030).\n * Absent on an authored answer, and on a recording that keeps its tokens\n * alone.\n */\n steps?: AiEvalRecordedStep[]\n /**\n * What a recorded product copy answer was written with of its product's\n * photo, as the products step reports it (AGL-3074): `read` when the\n * picture rode the request.\n */\n photo?: AiProductPhotoRead\n /**\n * What a recorded page was built as beside its tree (AGL-3073): its\n * screen's address and listing, and the layout it renders inside. Absent\n * on an authored answer, and on a recording made before it was kept.\n */\n screen?: AiEvalRecordedScreen\n /**\n * The grade, or `null` where the grader itself failed and there is none\n * (AGL-3143). An authored candidate always carries one.\n *\n * A brief's answer is bought before it is graded, so a grader that throws\n * would otherwise take the answer down with it and the run would pay\n * again for what it already had. The answer is kept and the grade is\n * marked missing instead of being invented: a fabricated 1/1 would read\n * as \"the model answered badly\" and pull the kind's floor down for\n * something the model never did, and the floors are the whole reason the\n * harness exists. An ungraded recording passes nothing — `rubric` is what\n * a score is taken from — so a missing grade can only read low, never\n * high, and the run that wrote it exits non-zero naming the throw.\n */\n rubric: AiEvalRubric | null\n note?: string\n /**\n * What the provider wrote when the answer ran out of ceiling (AGL-3143):\n * the bytes `answer` is only as much of as still parsed. Absent on every\n * recording but one whose answer was cut off. It is here because the\n * recording is the only place a live run's output outlives the run, and\n * it is what says whether the ceiling went on a runaway string or on a\n * decoding stall that wrote nothing usable. Never authored by hand.\n */\n rawOutput?: string\n}\n\n/** One metered exchange of a recorded job. */\nexport interface AiEvalRecordedStep {\n step: AiStepKind\n model: string\n usage: AiUsage\n estCostUsd: number\n /** What the machine meters it as: the billed cost in credits, rounded up per exchange. */\n credits: number\n}\n\n/**\n * A recorded page's screen, as the page step stored its draft. None of it is\n * a node of the page's tree: the address and the listing are fields of the\n * screen, the navigation entry is a proposal beside it, and the header, the\n * footer and the main landmark belong to the layout it renders inside.\n */\nexport interface AiEvalRecordedScreen {\n /** The draft's one-segment address, as the draft writer stored it. */\n slug: string\n /** The search title and description the draft holds; `null` where it holds none. */\n seoTitle: string | null\n seoDescription: string | null\n /** Whether a navigation entry for the page travels with it as a proposal. */\n nav: boolean\n /** The layout the draft renders inside; `null` for a page that renders inside none. */\n layout: AiEvalRecordedLayout | null\n}\n\n/** The layout a recorded page renders inside. */\nexport interface AiEvalRecordedLayout {\n id: string\n name: string\n /** `true` for a layout the job built before the page; `false` for one the site already had. */\n built: boolean\n /** Its tree as stored; `null` for a layout the case's site lists by name alone. */\n tree: { rootId: string; nodes: Record<string, unknown> } | null\n}\n\n/** An answer that must fail, and the checks it must fail. */\nexport interface AiEvalControl {\n why: string\n answer: unknown\n plan?: unknown\n fails: AiEvalCheck[]\n}\n\nexport interface AiEvalCase {\n id: string\n kind: AiEvalKind\n brief: string\n framing: AiCopyFraming\n /** The site the answer is built for; `null` for a brief that builds from none. */\n inventory: AiSiteInventory | null\n /**\n * The site's name as its visitors read it, where the case gives one\n * (AGL-3077): a recorded page's listing names the site by it. A case that\n * gives none is recorded on an untitled site.\n */\n siteName?: string\n /** Media library facts the image budget reads, by media id. */\n assets?: Record<string, AiAssetFacts>\n /** The documentation URLs a chat answer was grounded in; it may link only these. */\n docsUrls?: string[]\n /** Copy ceilings the brief sets, beside the kind's own. */\n maxChars?: number\n maxWords?: number\n /**\n * For an insight brief (AGL-2915): the tables the readers returned, which\n * every insight an answer writes is traced against.\n */\n tables?: AiInsightTable[]\n /**\n * For a product copy brief (AGL-2916): the product as its editor handed it\n * over, and the site's categories the request lists.\n */\n product?: { facts: AiProductFacts; categories: AiProductCategory[] }\n /** For a categories brief: the names of the categories the store already has. */\n existingCategoryNames?: string[]\n /** For a theme brief: the site's current theme and where it comes from. */\n siteTheme?: HostTheme\n themeSource?: HostThemeSource\n /**\n * For an automation brief (AGL-2919): what the workspace can run, and the\n * site's records the answer's words are looked up among. Absent, the\n * workspace runs everything and the site holds nothing.\n */\n automationCapabilities?: AiAutomationCapabilities\n automationRecords?: AiAutomationRecords\n /**\n * For an automation brief about a saved automation (AGL-3074): the action\n * as the site stores it, and for a run's diagnosis, what the run history\n * recorded of the failed run. Absent, the brief asks for a draft.\n */\n automation?: AiEvalAutomation\n /**\n * The media library assets of the case's site a recording reads\n * (AGL-3074), by media id: each the path of the file under\n * `tools/ai-eval/fixtures` that holds its bytes. A product's photo is\n * `media:<site id>/<media id>`, where the site is the inventory's, or\n * `AI_EVAL_SITE_ID` for a case that describes none.\n */\n media?: Record<string, string>\n /**\n * For a CRM brief (AGL-2917): what the job was asked, about which kind of\n * record, the facts the CRM reported for it, and a mapping's columns.\n */\n crm?: AiEvalCrmContext\n /**\n * For an A/B test brief (AGL-2914): which half of the step the brief asks\n * for, what the test varies, the copy under test, and — for a result — the\n * test's arms as the results reader published them.\n */\n experiment?: AiEvalExperiment\n /**\n * For a logic brief (AGL-3603): the site's variables and function names a\n * function's names are checked against, and the saved function a change or\n * an explanation starts from.\n */\n logic?: AiEvalLogic\n /**\n * For an edit brief (AGL-3616): the page or layout the change is asked of,\n * as its version stores it, which the outline the job shows the model is\n * read from and every op is held against.\n */\n edit?: AiEvalEdit\n /**\n * What the workspace may create on the case's site (AGL-3030): a brief\n * for a workspace that keeps no reusable components is held to the inline\n * doctrine, and its plan to what the workspace may create. Absent, the\n * doctrine applies whole.\n */\n capabilities?: AiPlanCapabilities\n /**\n * For a template brief (AGL-3433): whose page the template renders, which\n * holds its answers to the template step's own checks — the tokens that\n * page fills, and what the candidate's plan promised of them.\n */\n templateSubject?: AiTemplateSubject\n expected?: { plan?: AiEvalPlanShape }\n candidates: AiEvalCandidate[]\n controls: AiEvalControl[]\n}\n\n/** The site a case's job runs on when the case describes no inventory. */\nexport const AI_EVAL_SITE_ID = 'eval-site'\n\n/** What an automation brief's workspace can run when the case does not say: everything. */\nexport const AI_EVAL_AUTOMATION_CAPABILITIES: AiAutomationCapabilities = { crm: true, webhooks: true, bookings: true }\n\n/** A saved automation an automation brief asks about, as the workflow step reads one. */\nexport interface AiEvalAutomation {\n /** The action as `hosts/{hostId}/actions/{id}` holds it. */\n action: AiAutomation\n /** A failed run of it; given, the brief asks why that run failed. */\n run?: AiRunRecord\n}\n\n/** A logic brief, as the logic step is given one. */\nexport interface AiEvalLogic {\n variables: AiLogicSiteVariable[]\n functions: string[]\n saved?: HostFunction | null\n}\n\n/** An edit brief, as the edit step is given one: the document's kind and its stored node map. */\nexport interface AiEvalEdit {\n kind: AiEditTargetKind\n nodes: Record<string, unknown>\n}\n\n/** An A/B test brief, as the experiment step is given one. */\nexport interface AiEvalExperiment {\n task: AiExperimentTask\n /** What the test varies; a variants brief always names one. */\n target?: AiExperimentTarget\n /** The copy under test, as the surface handed it over. */\n subject?: string\n /** A result brief's test, and its arms as the results reader published them. */\n test?: string\n arms?: AiExperimentArm[]\n}\n\n/** A fixture file a case's media names: a relative path to a picture, never out of its folder. */\nconst AI_EVAL_MEDIA_FILE = /^(?!.*(?:^|\\/)\\.\\.?(?:\\/|$))[A-Za-z0-9][A-Za-z0-9._/-]*\\.(?:jpe?g|png|webp|gif|avif)$/\n\n/** What a CRM brief's answer is checked against, as the `crm` step checks it. */\nexport interface AiEvalCrmContext {\n task: AiCrmTask\n /** The record a `record` or `email` brief is about. */\n record?: AiCrmRecordKind\n /** The facts the CRM's reader reported: a record's, or an import's field catalog. */\n facts?: Record<string, unknown>\n /** A mapping brief's columns: each header and its shape. */\n columns?: ConsoleImportColumn[]\n}\n\n/** A kind's floor: the pass rate and the mean score its candidates may not fall below. */\nexport interface AiEvalFloor {\n passRate: number\n meanScore: number\n}\n\n/**\n * The floors, per kind. Every reference answer must pass, because each was\n * written to; the mean floor leaves room for a rubric grade of four on an\n * answer that passes every mechanical check. Recorded answers are held to\n * the same floors, and a lever that lowers a kind below its floor does not\n * ship.\n */\nexport const AI_EVAL_FLOORS: Readonly<Record<AiEvalKind, AiEvalFloor>> = {\n page: { passRate: 1, meanScore: 0.9 },\n template: { passRate: 1, meanScore: 0.9 },\n component: { passRate: 1, meanScore: 0.9 },\n layout: { passRate: 1, meanScore: 0.9 },\n form: { passRate: 1, meanScore: 0.9 },\n email: { passRate: 1, meanScore: 0.9 },\n section: { passRate: 1, meanScore: 0.9 },\n seo: { passRate: 1, meanScore: 0.9 },\n product: { passRate: 1, meanScore: 0.9 },\n catalog: { passRate: 1, meanScore: 0.9 },\n categories: { passRate: 1, meanScore: 0.9 },\n theme: { passRate: 1, meanScore: 0.9 },\n element: { passRate: 1, meanScore: 0.9 },\n blog: { passRate: 1, meanScore: 0.9 },\n text: { passRate: 1, meanScore: 0.9 },\n chat: { passRate: 1, meanScore: 0.9 },\n workflow: { passRate: 1, meanScore: 0.9 },\n insight: { passRate: 1, meanScore: 0.9 },\n crm: { passRate: 1, meanScore: 0.9 },\n experiment: { passRate: 1, meanScore: 0.9 },\n logic: { passRate: 1, meanScore: 0.9 },\n edit: { passRate: 1, meanScore: 0.9 },\n}\n\n/** A rubric passes at this mean, with no criterion below three. */\nexport const AI_EVAL_RUBRIC_PASS_MEAN = 3.5\n\n/** How long a blog body may run: the blog mode's output ceiling, at four characters a token. */\nexport const AI_EVAL_BLOG_MAX_CHARS = 8_000\n\n/** How long a job's copy may run when the brief implies no length: the text step's own rule. */\nexport const AI_EVAL_TEXT_MAX_WORDS = 150\n\n/** How long a chat answer may run: the chat door's output ceiling, at four characters a token. */\nexport const AI_EVAL_CHAT_MAX_CHARS = 4_000\n\nexport interface AiEvalScore {\n caseId: string\n kind: AiEvalKind\n source: AiEvalCandidate['source']\n scope: NonNullable<AiEvalCandidate['scope']>\n model: string | null\n /** A check that does not apply to the answer — the plan of an unplanned kind, the document of a plan answer — is `null`. */\n checks: Record<'rubric', boolean> & Record<Exclude<AiEvalCheck, 'rubric'>, boolean | null>\n /** The rubric's mean, from 0 (every criterion 1) to 1 (every criterion 5). */\n rubricScore: number\n /** The checks and the rubric, averaged: from 0 to 1. */\n score: number\n pass: boolean\n /** Why a check failed: violation codes and the kind's own findings. */\n findings: string[]\n}\n\ninterface Checked {\n readable: boolean\n rules: boolean\n budget: boolean\n findings: string[]\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst codes = (violations: readonly AiDoctrineViolation[]) =>\n violations.map((violation) => violation.code)\n\n// ── The kinds ─────────────────────────────────────────────────────────────\n\ninterface ReadTree {\n /** The answer as the check reads it: a page's repeated items drawn. */\n input: Record<string, unknown>\n declaresProps: boolean\n /** Why a page's repeated item could not be drawn; the tree is not read then. */\n undrawn: AiDoctrineViolation[] | null\n result: AiGenerationCheckResult<AiValidatedTree> | null\n}\n\n/**\n * The sections a page answer's plan lays out, by name, which a link on the\n * page may take a visitor to as the page step lets it (AGL-3097); empty for an\n * answer of another kind, or with no plan to read them from.\n */\nfunction planSections(evalCase: AiEvalCase, plan: unknown): string[] {\n const screens = evalCase.kind === 'page' && isRecord(plan) && Array.isArray(plan['screens']) ? plan['screens'] : []\n const sections = isRecord(screens[0]) && Array.isArray(screens[0]['sections']) ? screens[0]['sections'] : []\n return sections.flatMap((section: unknown) =>\n isRecord(section) && typeof section['name'] === 'string' ? [section['name']] : [],\n )\n}\n\nfunction readTree(evalCase: AiEvalCase, outputKind: AiOutputKind, answer: unknown, plan?: unknown): ReadTree {\n const inline = evalCase.capabilities?.reusableComponents === false\n let input = isRecord(answer) ? answer : { tree: answer }\n // A component answer that declares its properties binds them in its tree,\n // and is held to the component step's own checks as that step holds it\n // (AGL-3054).\n const declaresProps = evalCase.kind === 'component' && Array.isArray(input['props'])\n const sections = planSections(evalCase, plan)\n const subject = templateDefinition(evalCase)\n const check = aiDoctrineTreeCheck(\n outputKind,\n aiDoctrineTreeContext(evalCase.inventory, {\n ...(evalCase.assets ? { assets: evalCase.assets } : {}),\n framing: evalCase.framing,\n ...(inline ? { reusableComponents: false } : {}),\n ...(declaresProps ? { definesComponent: true } : {}),\n ...(sections.length ? { pageSections: sections } : {}),\n ...(subject ? { bindingTokens: aiTemplateAddressTokens(subject) } : {}),\n }),\n )\n // A page's repeated item written once is drawn into its copies first, as the\n // page step draws it, and refused as the page step refuses it (AGL-3053).\n if (evalCase.kind === 'page') {\n const drawn = expandAiRepeatedItems(aiAnswerTree(input), { inline, noun: 'page' })\n if (drawn.ok === false) return { input, declaresProps, undrawn: drawn.violations, result: null }\n if (drawn.items) input = { tree: drawn.tree }\n }\n return { input, declaresProps, undrawn: null, result: check(input) }\n}\n\n/**\n * The tree an answer of a tree kind is checked as — a page's repeated items\n * drawn into their copies — or `null` when it cannot be read as one. The\n * device audit renders exactly this tree (AGL-3020).\n */\nexport function aiEvalAnswerTree(evalCase: AiEvalCase, answer: unknown): AiValidatedTree | null {\n const outputKind = AI_EVAL_TREE_OUTPUT[evalCase.kind]\n return outputKind ? (readTree(evalCase, outputKind, answer).result?.value ?? null) : null\n}\n\n/** The subject a template case's page is for, whose tokens its answers bind. */\nfunction templateDefinition(evalCase: AiEvalCase): AiTemplateSubjectDefinition | null {\n return evalCase.kind === 'template' && evalCase.templateSubject\n ? AI_TEMPLATE_SUBJECT_DEFINITIONS[evalCase.templateSubject]\n : null\n}\n\nfunction checkTree(evalCase: AiEvalCase, outputKind: AiOutputKind, answer: unknown, plan?: unknown): Checked {\n const { input, declaresProps, undrawn, result } = readTree(evalCase, outputKind, answer, plan)\n if (undrawn || !result) {\n return { readable: false, rules: false, budget: false, findings: codes(undrawn ?? []) }\n }\n const subject = templateDefinition(evalCase)\n // A template answer is held to the template step's own checks, as that step\n // holds it: the tokens its page fills, and what its plan promised (AGL-3433).\n const templated = (tree: AiValidatedTree) =>\n subject\n ? [\n ...aiTemplateBindingCheck(subject)(tree),\n ...aiPlanTemplateTokenViolations(isRecord(plan) ? (plan as unknown as AiJobPlan) : null, subject, {\n rootId: tree.rootId,\n nodes: tree.nodes as unknown as AiDoctrineTree['nodes'],\n }),\n ]\n : []\n const violations = [\n ...result.violations,\n ...(declaresProps && result.value\n ? aiComponentCheck({ inventory: evalCase.inventory, plan: null, onProps: () => undefined })(result.value, input)\n : []),\n ...(result.value ? templated(result.value) : []),\n ]\n const budget = violations.filter((violation) => violation.rule === 17)\n const rules = violations.filter((violation) => violation.rule !== 17)\n return {\n readable: result.value !== null,\n rules: result.value !== null && rules.length === 0,\n budget: result.value !== null && budget.length === 0,\n findings: codes(violations),\n }\n}\n\nconst FENCE = /```/\nconst PREAMBLE = /^\\s*(?:sure|certainly|of course|here(?:'s| is| are))\\b/i\nconst QUOTED = /^\\s*[\"“'].*[\"”']\\s*$/s\nconst MARKUP = /<\\/?[a-z][^>]*>/i\n\nfunction words(text: string): number {\n return text.trim().split(/\\s+/).filter(Boolean).length\n}\n\n/** Copy answered as text: there, unwrapped, in the site's voice, within its ceiling. */\nfunction checkCopy(\n evalCase: AiEvalCase,\n answer: unknown,\n limits: { maxChars?: number; maxWords?: number },\n own: (text: string) => string[] = () => [],\n): Checked {\n if (typeof answer !== 'string' || !answer.trim()) {\n return { readable: false, rules: false, budget: false, findings: ['copy-missing'] }\n }\n const text = answer.trim()\n const unreadable = [\n ...(FENCE.test(text) ? ['copy-fenced'] : []),\n ...(PREAMBLE.test(text) ? ['copy-preamble'] : []),\n ...(QUOTED.test(text) ? ['copy-quoted'] : []),\n ]\n const broken = [\n ...codes(detectOffVoiceCopy([{ at: 'answer', text }], evalCase.framing)),\n // A chat answer may quote a binding token to explain it; copy for a page never shows one (AGL-3827).\n ...(evalCase.kind === 'chat' ? [] : codes(detectPlaceholderCopy([{ at: 'answer', text }]))),\n ...(MARKUP.test(text) ? ['copy-markup'] : []),\n ...own(text),\n ]\n const maxChars = evalCase.maxChars ?? limits.maxChars\n const maxWords = evalCase.maxWords ?? limits.maxWords\n const over = [\n ...(maxChars !== undefined && text.length > maxChars ? ['copy-over-chars'] : []),\n ...(maxWords !== undefined && words(text) > maxWords ? ['copy-over-words'] : []),\n ]\n return {\n readable: unreadable.length === 0,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...unreadable, ...broken, ...over],\n }\n}\n\nconst MARKDOWN_LINK = /\\[[^\\]]*\\]\\(([^)\\s]+)\\)/g\n\n/** A chat answer links only the documentation it was given and console paths. */\nfunction chatLinks(evalCase: AiEvalCase): (text: string) => string[] {\n const allowed = new Set(evalCase.docsUrls ?? [])\n return (text) =>\n [...text.matchAll(MARKDOWN_LINK)]\n .map((match) => match[1])\n .filter((url) => !url.startsWith('/') && !allowed.has(url))\n .map((url) => `chat-link-not-given:${url}`)\n}\n\nfunction checkBlog(evalCase: AiEvalCase, answer: unknown): Checked {\n const checked = checkCopy(evalCase, answer, { maxChars: AI_EVAL_BLOG_MAX_CHARS })\n if (typeof answer !== 'string') return checked\n const head = answer.trimStart()\n const extra = [\n ...(head.startsWith('---') ? ['blog-front-matter'] : []),\n ...(/^#\\s/.test(head) ? ['blog-title-line'] : []),\n ]\n return extra.length\n ? { ...checked, readable: false, findings: [...checked.findings, ...extra] }\n : checked\n}\n\nfunction checkSeo(evalCase: AiEvalCase, answer: unknown): Checked {\n const title = isRecord(answer) && typeof answer['title'] === 'string' ? answer['title'].trim() : ''\n const description =\n isRecord(answer) && typeof answer['description'] === 'string' ? answer['description'].trim() : ''\n if (!title || !description) {\n return { readable: false, rules: false, budget: false, findings: ['seo-field-missing'] }\n }\n const broken = [\n ...codes(detectPublishIntent(answer)),\n ...codes(\n detectOffVoiceCopy(\n [\n { at: 'title', text: title },\n { at: 'description', text: description },\n ],\n evalCase.framing,\n ),\n ),\n ...codes(\n detectPlaceholderCopy([\n { at: 'title', text: title },\n { at: 'description', text: description },\n ]),\n ),\n ...(MARKUP.test(title) || MARKUP.test(description) ? ['seo-markup'] : []),\n ]\n const over = [\n ...(title.length > AI_SEO_TITLE_MAX ? ['seo-title-over'] : []),\n ...(description.length > AI_SEO_DESCRIPTION_MAX ? ['seo-description-over'] : []),\n ]\n return {\n readable: true,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...broken, ...over],\n }\n}\n\n/** What a products check refuses an answer for, by the check it fails. */\nconst PRODUCTS_UNREADABLE = new Set(['type', 'missing', 'option-count'])\nconst PRODUCTS_OVER_BUDGET = new Set(['too-long', 'too-many', 'product-count'])\n\n/**\n * A products answer (AGL-2916), held by the check its generation is held by:\n * a product's copy, a catalog, or categories with discounts. A finding about\n * the answer's shape makes it unreadable, one about a length or a count is\n * over its budget, and every other one — a claim, a price, markup, a category\n * the request did not list — breaks a rule.\n */\nfunction checkProducts(evalCase: AiEvalCase, answer: unknown): Checked {\n if (!isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['products-not-a-call'] }\n }\n const result =\n evalCase.kind === 'product'\n ? checkAiProductCopy(answer, {\n categoryIds: (evalCase.product?.categories ?? []).map((category) => category.id),\n optionCount: evalCase.product?.facts.options.length ?? 0,\n merchantWords: evalCase.product ? aiProductMerchantWords(evalCase.product.facts) : evalCase.brief,\n })\n : evalCase.kind === 'catalog'\n ? checkAiCatalog(answer, { merchantWords: evalCase.brief })\n : checkAiCategories(answer, {\n existingCategoryNames: evalCase.existingCategoryNames ?? [],\n merchantWords: evalCase.brief,\n })\n const found = [...codes(result.violations), ...codes(detectPublishIntent(answer))]\n return {\n readable: !found.some((code) => PRODUCTS_UNREADABLE.has(code)),\n rules: !found.some((code) => !PRODUCTS_UNREADABLE.has(code) && !PRODUCTS_OVER_BUDGET.has(code)),\n budget: !found.some((code) => PRODUCTS_OVER_BUDGET.has(code)),\n findings: found,\n }\n}\n\nfunction checkTheme(evalCase: AiEvalCase, answer: unknown): Checked {\n if (!isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['theme-not-a-call'] }\n }\n const parse = parseAiThemeToolInput(answer)\n const changes = parse.changes.length + parse.components.length + (parse.resetComponents ? 1 : 0)\n const broken = [\n ...codes(detectPublishIntent(answer)),\n ...codes(detectOffVoiceCopy([{ at: 'summary', text: parse.summary }], evalCase.framing)),\n ]\n return {\n readable: changes > 0 && parse.dropped.length === 0,\n rules: broken.length === 0,\n budget: true,\n findings: [...parse.dropped.map((reason) => `theme-dropped:${reason}`), ...broken],\n }\n}\n\n/**\n * An automation (AGL-2919), or an explanation of one: read through the tool's\n * own reader, and an automation also made into the document the workflows\n * plugin stores and held to the Actions editor's validator.\n */\nfunction checkWorkflow(evalCase: AiEvalCase, answer: unknown): Checked {\n if (!isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['workflow-not-a-call'] }\n }\n const publish = codes(detectPublishIntent(answer))\n if ('summary' in answer) {\n const read = readAiWorkflowExplanation(answer)\n const lines = [\n String(answer['summary'] ?? ''),\n ...(Array.isArray(answer['points']) ? answer['points'] : []),\n ...(Array.isArray(answer['suggestions']) ? answer['suggestions'] : []),\n ].map(String)\n const offVoice = codes(\n detectOffVoiceCopy(lines.map((text, index) => ({ at: `line[${index}]`, text })), evalCase.framing),\n )\n const found = codes(read.violations)\n return {\n readable: !found.includes('explanation-shape'),\n rules: read.value !== null && publish.length === 0 && offVoice.length === 0,\n budget: true,\n findings: [...found, ...publish, ...offVoice],\n }\n }\n const capabilities = evalCase.automationCapabilities ?? AI_EVAL_AUTOMATION_CAPABILITIES\n const read = readAiAutomationAnswer(answer, capabilities)\n const found = codes(read.violations)\n const unreadable = found.filter((code) => AI_AUTOMATION_UNREADABLE_CODES.includes(code))\n const oversize = found.filter((code) => AI_AUTOMATION_OVERSIZE_CODES.includes(code))\n const broken = found.filter((code) => !unreadable.includes(code) && !oversize.includes(code))\n const invalid =\n read.value && !read.value.unsupported\n ? validateStoredInteraction(aiAutomationDraft(read.value, evalCase.automationRecords ?? emptyAiAutomationRecords()).action)\n : null\n return {\n readable: unreadable.length === 0,\n rules: broken.length === 0 && publish.length === 0 && invalid === null,\n budget: oversize.length === 0,\n findings: [...found, ...publish, ...(invalid ? [`workflow-invalid:${invalid}`] : [])],\n }\n}\n\n/**\n * An insight answer held to the trace (AGL-2915): readable when it is a\n * `submit_insights` call that keeps an insight, within the rules when no\n * insight is left out for its numbers, its citations or its words, and within\n * the budget when no insight runs long and there are no more than five.\n */\nfunction checkInsight(evalCase: AiEvalCase, answer: unknown): Checked {\n const parsed = parseAiInsightAnswer(answer)\n if (!parsed || !parsed.insights.length) {\n return { readable: false, rules: false, budget: false, findings: ['insight-no-answer'] }\n }\n const check = checkAiInsightAnswer(parsed, evalCase.tables ?? [])\n const findings = check.findings.map((finding) => finding.split(':')[0])\n const over = findings.filter((code) => code === 'insight-too-long' || code === 'insight-too-many')\n return {\n readable: check.kept.length > 0,\n rules: findings.length === over.length,\n budget: over.length === 0,\n findings: check.findings,\n }\n}\n\n/** The CRM findings that mean the answer could not be read as one, and the ones over a length. */\nconst CRM_UNREADABLE = new Set(['type', 'missing'])\nconst CRM_OVER = new Set(['too-long'])\n\n/**\n * A CRM answer, held by the checks the `crm` step holds it to (AGL-2917),\n * with rule 13 and the site's voice on everything a person reads.\n */\nfunction checkCrm(evalCase: AiEvalCase, answer: unknown): Checked {\n const context = evalCase.crm\n if (!context || !isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['crm-not-a-call'] }\n }\n const facts = context.facts ?? {}\n const kind = context.record ?? 'contact'\n const result =\n context.task === 'mapping'\n ? checkAiCrmMapping(answer, { columns: context.columns ?? [], fields: aiCrmImportFields(facts) })\n : context.task === 'email'\n ? checkAiCrmEmail(answer, { mergeFields: aiCrmEmailMergeFields(kind) })\n : checkAiCrmRecord(answer, aiCrmRecordCheckContext(kind, facts))\n const own = codes(result.violations)\n const read = (path: string[]): string => {\n let value: unknown = answer\n for (const key of path) value = isRecord(value) ? value[key] : undefined\n return typeof value === 'string' ? value : ''\n }\n const samples = [\n ['summary'],\n ['standing'],\n ['nextStep', 'title'],\n ['nextStep', 'reason'],\n ['stage', 'reason'],\n ['subject'],\n ['body'],\n ]\n .map((path) => ({ at: path.join('.'), text: read(path) }))\n .filter((sample) => sample.text)\n const broken = [\n ...codes(detectPublishIntent(answer)),\n ...codes(detectOffVoiceCopy(samples, evalCase.framing)),\n ...own.filter((code) => !CRM_UNREADABLE.has(code) && !CRM_OVER.has(code)),\n ]\n return {\n readable: !own.some((code) => CRM_UNREADABLE.has(code)),\n rules: broken.length === 0,\n budget: !own.some((code) => CRM_OVER.has(code)),\n findings: [...new Set([...own, ...broken])],\n }\n}\n\n/**\n * A logic answer (AGL-3603): an explanation as an automation's is checked; a\n * function or a variable through the step's own check, against the case's\n * site — the grammar, the names and a first run.\n */\nfunction checkLogic(evalCase: AiEvalCase, answer: unknown): Checked {\n if (!isRecord(answer)) return { readable: false, rules: false, budget: false, findings: ['logic-not-a-call'] }\n const site = evalCase.logic ?? { variables: [], functions: [] }\n if ('summary' in answer) {\n const read = readAiWorkflowExplanation(answer)\n const found = codes(read.violations)\n return { readable: !found.includes('explanation-shape'), rules: read.value !== null, budget: true, findings: found }\n }\n const context = { variables: site.variables, functions: site.functions, editing: site.saved?.name ?? null }\n const read = 'operations' in answer ? checkAiLogicFunction(answer, context) : checkAiLogicVariable(answer, context)\n const found = codes(read.violations)\n return {\n readable: !found.includes('logic-not-a-call'),\n rules: read.value !== null,\n budget: !found.includes('logic-size'),\n findings: found,\n }\n}\n\n/** The edit rung's own size limits, as the reasons its check gives for an op past one. */\nconst EDIT_OVER_LIMIT = /change limit|elements at once/\n\n/**\n * An edit answer (AGL-3616), held by the check the edit step holds it by:\n * the edit rung's closed world and palette validators, against the outline\n * the job shows the model of the case's document. Readable when a change\n * survives; a rule broken when any change was left out, or the answer says\n * it published; over budget past the rung's own limits.\n */\nfunction checkEdit(evalCase: AiEvalCase, answer: unknown): Checked {\n const brief = evalCase.edit\n if (!brief) return { readable: false, rules: false, budget: false, findings: ['edit-brief-missing'] }\n if (!isRecord(answer) || !Array.isArray(answer['ops'])) {\n return { readable: false, rules: false, budget: false, findings: ['edit-not-a-call'] }\n }\n const outline = aiEditJobOutline(brief.nodes)\n const context = outline ? parseAssistEditContext(outline) : null\n if (!context) return { readable: false, rules: false, budget: false, findings: ['edit-no-document'] }\n const checked = checkAssistEditAnswer(answer, {\n context,\n target: { kind: brief.kind, documentId: evalCase.id, versionId: evalCase.id, hostId: AI_EVAL_SITE_ID },\n })\n const ops = answer['ops'] as unknown[]\n const over =\n ops.length > ASSIST_EDIT_MAX_OPS ||\n ops.some((op) => isRecord(op) && Array.isArray(op['nodes']) && op['nodes'].length > ASSIST_EDIT_MAX_INSERT_NODES)\n const samples = (checked.value?.ops ?? []).flatMap((op) =>\n op.op === 'updateProps'\n ? Object.entries(op.props)\n .filter(([, value]) => typeof value === 'string' && value.trim())\n .map(([name, value]) => ({ at: `${op.nodeId}.${name}`, text: String(value) }))\n : [],\n )\n const left = checked.violations.filter((violation) => !EDIT_OVER_LIMIT.test(violation.message))\n const broken = [\n ...codes(detectPublishIntent(answer)),\n ...codes(detectOffVoiceCopy(samples, evalCase.framing)),\n ...left.map((violation) => `edit-left-out:${violation.message}`),\n ]\n return {\n readable: checked.value !== null,\n rules: broken.length === 0,\n budget: !over,\n findings: [...new Set([...broken, ...(over ? ['edit-over-limit'] : [])])],\n }\n}\n\n/** What an experiment answer is refused for, by the check it fails. */\nconst EXPERIMENT_RULE_FINDINGS = new Set([\n 'variant-carries-markup',\n 'variant-fills-another-targets-fields',\n 'variant-repeats-another',\n 'variant-has-no-copy',\n])\n\n/**\n * An A/B test answer (AGL-2914), held by the checks its step holds it by.\n *\n * A variants answer is readable when at least two variants survive, breaks a\n * rule when one carried markup, repeated another or answered a different\n * target, and is over budget when a field ran past the length the card\n * stores. A result answer is readable when an explanation survives its\n * reading, and breaks a rule when the reading had to take a winner out of it\n * — which is the whole point of the kind: an explanation that claims more\n * than the figures support does not pass here.\n */\nfunction checkExperiment(evalCase: AiEvalCase, answer: unknown): Checked {\n const brief = evalCase.experiment\n if (!brief) {\n return { readable: false, rules: false, budget: false, findings: ['experiment-brief-missing'] }\n }\n if (brief.task === 'variants') {\n const target: AiExperimentTarget = brief.target ?? 'screen'\n const parsed = parseAiExperimentVariants(answer)\n const checked = checkAiExperimentVariants(parsed, target)\n if (!parsed || !checked) {\n return { readable: false, rules: false, budget: false, findings: ['experiment-no-variants'] }\n }\n const fields = aiExperimentVariantFields(target)\n const over = parsed.variants.flatMap((variant) => [\n ...(variant.name.length > AI_EXPERIMENT_NAME_MAX_CHARS ? ['experiment-name-over'] : []),\n ...(variant.rationale.length > AI_EXPERIMENT_RATIONALE_MAX_CHARS ? ['experiment-rationale-over'] : []),\n ...fields.flatMap((field) =>\n String(variant[field] ?? '').length >\n (field === 'body' ? AI_EXPERIMENT_BODY_MAX_CHARS : AI_EXPERIMENT_LINE_MAX_CHARS)\n ? [`experiment-${field}-over`]\n : [],\n ),\n ])\n const samples = checked.proposal.variants.flatMap((variant) =>\n fields.map((field) => ({ at: `${variant.name}.${field}`, text: String(variant[field] ?? '') })),\n )\n const broken = [\n ...checked.findings.filter((finding) => EXPERIMENT_RULE_FINDINGS.has(finding)),\n ...codes(detectPublishIntent(answer)),\n ...codes(detectOffVoiceCopy(samples.filter((sample) => sample.text), evalCase.framing)),\n ]\n return {\n readable: true,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...new Set([...broken, ...over])],\n }\n }\n\n const reading = readAiExperimentResult(brief.test ?? '', brief.arms ?? [])\n const parsed = parseAiExperimentExplanation(answer)\n const explained = checkAiExperimentExplanation(parsed, reading)\n if (!parsed || !explained) {\n return { readable: false, rules: false, budget: false, findings: ['experiment-no-explanation'] }\n }\n const over = [\n ...(parsed.headline.length > AI_EXPERIMENT_HEADLINE_MAX_CHARS ? ['experiment-headline-over'] : []),\n ...(parsed.points.length > AI_EXPERIMENT_MAX_POINTS ? ['experiment-points-over'] : []),\n ...parsed.points.flatMap((point) =>\n point.length > AI_EXPERIMENT_POINT_MAX_CHARS ? ['experiment-point-over'] : [],\n ),\n ...(parsed.next.length > AI_EXPERIMENT_NEXT_MAX_CHARS ? ['experiment-next-over'] : []),\n ]\n const broken = [\n ...explained.findings,\n ...codes(detectPublishIntent(answer)),\n ...codes(\n detectOffVoiceCopy(\n [\n { at: 'headline', text: explained.headline },\n ...explained.points.map((point, index) => ({ at: `points.${index}`, text: point })),\n ],\n evalCase.framing,\n ),\n ),\n ]\n return {\n readable: true,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...new Set([...broken, ...over])],\n }\n}\n\n/** An answer held to its kind's checks; a page's links to the sections of the plan it was built from. */\nfunction checkAnswer(evalCase: AiEvalCase, answer: unknown, plan?: unknown): Checked {\n const outputKind = AI_EVAL_TREE_OUTPUT[evalCase.kind]\n if (outputKind) return checkTree(evalCase, outputKind, answer, plan)\n switch (evalCase.kind) {\n case 'seo':\n return checkSeo(evalCase, answer)\n case 'product':\n case 'catalog':\n case 'categories':\n return checkProducts(evalCase, answer)\n case 'theme':\n return checkTheme(evalCase, answer)\n case 'element':\n return checkCopy(evalCase, answer, { maxChars: AI_TEXT_LIMITS.body })\n case 'blog':\n return checkBlog(evalCase, answer)\n case 'text':\n return checkCopy(evalCase, answer, { maxWords: AI_EVAL_TEXT_MAX_WORDS })\n case 'chat':\n return checkCopy(evalCase, answer, { maxChars: AI_EVAL_CHAT_MAX_CHARS }, chatLinks(evalCase))\n case 'workflow':\n return checkWorkflow(evalCase, answer)\n case 'insight':\n return checkInsight(evalCase, answer)\n case 'crm':\n return checkCrm(evalCase, answer)\n case 'experiment':\n return checkExperiment(evalCase, answer)\n case 'logic':\n return checkLogic(evalCase, answer)\n case 'edit':\n return checkEdit(evalCase, answer)\n default:\n return { readable: false, rules: false, budget: false, findings: ['kind-unknown'] }\n }\n}\n\n/** The plan held to the plan rules, then to the shape the case expects. */\nexport function checkAiEvalPlan(\n evalCase: AiEvalCase,\n plan: unknown,\n): { pass: boolean; findings: string[] } {\n const shape = evalCase.expected?.plan\n if (!shape) return { pass: true, findings: [] }\n const result = aiDoctrinePlanCheck(evalCase.inventory, evalCase.framing, evalCase.capabilities ?? null)(\n isRecord(plan) ? plan : {},\n )\n if (!result.value) return { pass: false, findings: ['plan-unreadable', ...codes(result.violations)] }\n const value = result.value\n const shapeFindings = [\n ...(value.screens.length < shape.screens[0] || value.screens.length > shape.screens[1]\n ? [`plan-screens:${value.screens.length}`]\n : []),\n ...(shape.reuse ?? [])\n .filter((id) => !value.reuse.some((entry) => entry.id === id))\n .map((id) => `plan-reuse-missing:${id}`),\n ...(shape.layout\n ? value.screens\n .filter((screen) => screen.layout !== shape.layout)\n .map((screen) => `plan-layout:${screen.slug}`)\n : []),\n ...(shape.maxCreate !== undefined && value.create.length > shape.maxCreate\n ? [`plan-create:${value.create.length}`]\n : []),\n ...(shape.createKinds\n ? value.create\n .filter((entry) => !shape.createKinds?.includes(entry.kind))\n .map((entry) => `plan-create-kind:${entry.kind}`)\n : []),\n ]\n // The players a plan lists, against the brief it answers, as the plan step holds them (AGL-3433).\n const briefFindings = codes(aiPlanEmbedBriefViolations(value, evalCase.brief))\n const findings = [...codes(result.violations), ...briefFindings, ...shapeFindings]\n return { pass: findings.length === 0, findings }\n}\n\nconst clampGrade = (value: unknown): number | null => {\n if (value === null || value === undefined) return null\n const parsed = Number(value)\n return Number.isFinite(parsed) ? Math.min(5, Math.max(1, parsed)) : null\n}\n\n/** A rubric's mean and whether it passes: the mean at `AI_EVAL_RUBRIC_PASS_MEAN`, nothing under three. */\nexport function aiEvalRubricVerdict(rubric: AiEvalRubric | null | undefined): {\n mean: number\n pass: boolean\n} {\n const grades = [rubric?.structure, rubric?.copy, rubric?.reuse]\n .map(clampGrade)\n .filter((grade): grade is number => grade !== null)\n if (!grades.length) return { mean: 1, pass: false }\n const mean = grades.reduce((sum, grade) => sum + grade, 0) / grades.length\n return { mean, pass: mean >= AI_EVAL_RUBRIC_PASS_MEAN && Math.min(...grades) >= 3 }\n}\n\n/**\n * The widths a readable document of a rendered kind is held to, from its\n * recorded device audit: `null` when the answer is not such a document or no\n * audits were given; failing, with `widths-unrecorded`, when none was recorded\n * from this answer.\n */\nfunction checkWidths(\n evalCase: AiEvalCase,\n answer: unknown,\n checked: Checked | null,\n audits: AiEvalAudits | undefined,\n): { pass: boolean; findings: string[] } | null {\n if (!audits || !checked?.readable || !aiEvalRendersAtDeviceWidths(evalCase.kind)) return null\n const audit = audits(evalCase, answer)\n if (!audit) return { pass: false, findings: ['widths-unrecorded'] }\n const findings = aiDeviceAuditFindings(audit)\n return { pass: findings.length === 0, findings }\n}\n\n/** One answer to one golden brief, scored. */\nexport function scoreAiEvalCandidate(\n evalCase: AiEvalCase,\n candidate: AiEvalCandidate,\n audits?: AiEvalAudits,\n): AiEvalScore {\n const scope = candidate.scope ?? 'full'\n const checked = scope === 'full' ? checkAnswer(evalCase, candidate.answer, candidate.plan) : null\n const widths = checkWidths(evalCase, candidate.answer, checked, audits)\n const plan = evalCase.expected?.plan ? checkAiEvalPlan(evalCase, candidate.plan) : null\n const rubric = aiEvalRubricVerdict(candidate.rubric)\n const rubricScore = (rubric.mean - 1) / 4\n const parts = [\n ...(checked ? [checked.readable ? 1 : 0, checked.rules ? 1 : 0, checked.budget ? 1 : 0] : []),\n ...(plan ? [plan.pass ? 1 : 0] : []),\n rubricScore,\n ]\n const score = Math.round((parts.reduce((sum, part) => sum + part, 0) / parts.length) * 10_000) / 10_000\n const documentPasses = checked ? checked.readable && checked.rules && checked.budget : true\n return {\n caseId: evalCase.id,\n kind: evalCase.kind,\n source: candidate.source,\n scope,\n model: candidate.model,\n checks: {\n readable: checked ? checked.readable : null,\n rules: checked ? checked.rules : null,\n budget: checked ? checked.budget : null,\n plan: plan ? plan.pass : null,\n responsive: widths ? widths.pass : null,\n rubric: rubric.pass,\n },\n rubricScore: Math.round(rubricScore * 10_000) / 10_000,\n score,\n // A plan answer to a brief with no expected plan has nothing to pass.\n pass: documentPasses && (widths?.pass ?? true) && (plan?.pass ?? scope === 'full') && rubric.pass,\n findings: [...(checked?.findings ?? []), ...(widths?.findings ?? []), ...(plan?.findings ?? [])],\n }\n}\n\n/**\n * The checks a control failed; the harness requires every one it names. A\n * control whose widths were never recorded fails none of them.\n */\nexport function scoreAiEvalControl(\n evalCase: AiEvalCase,\n control: AiEvalControl,\n audits?: AiEvalAudits,\n): AiEvalCheck[] {\n // A control is the case's first answer with one thing wrong, built from its plan unless it carries its own.\n const checked = checkAnswer(evalCase, control.answer, control.plan ?? evalCase.candidates[0]?.plan)\n const widths = audits?.(evalCase, control.answer) ? checkWidths(evalCase, control.answer, checked, audits) : null\n const plan =\n control.plan !== undefined && evalCase.expected?.plan\n ? checkAiEvalPlan(evalCase, control.plan)\n : null\n return [\n ...(checked.readable ? [] : (['readable'] as const)),\n ...(checked.rules ? [] : (['rules'] as const)),\n ...(checked.budget ? [] : (['budget'] as const)),\n ...(plan && !plan.pass ? (['plan'] as const) : []),\n ...(widths && !widths.pass ? (['responsive'] as const) : []),\n ]\n}\n\nexport interface AiEvalKindSummary {\n kind: AiEvalKind\n candidates: number\n passed: number\n /** Passed over candidates; `null` with none, which is below every floor. */\n passRate: number | null\n meanScore: number | null\n floor: AiEvalFloor\n belowFloor: boolean\n}\n\n/** Every kind's pass rate and mean score against its floor; a kind with no candidate is below it. */\nexport function summarizeAiEval(scores: readonly AiEvalScore[]): AiEvalKindSummary[] {\n return AI_EVAL_KINDS.map((kind) => {\n const own = scores.filter((score) => score.kind === kind && score.scope === 'full')\n const passed = own.filter((score) => score.pass).length\n const passRate = own.length ? passed / own.length : null\n const meanScore = own.length\n ? Math.round((own.reduce((sum, score) => sum + score.score, 0) / own.length) * 10_000) / 10_000\n : null\n const floor = AI_EVAL_FLOORS[kind]\n return {\n kind,\n candidates: own.length,\n passed,\n passRate,\n meanScore,\n floor,\n belowFloor:\n passRate === null ||\n meanScore === null ||\n passRate < floor.passRate ||\n meanScore < floor.meanScore,\n }\n })\n}\n\n/** How the plans a planned kind's answers carry score, across every brief. */\nexport interface AiEvalPlanSummary {\n plans: number\n passed: number\n passRate: number | null\n}\n\n/**\n * The plan step's own score: every answer that carried a plan checked\n * against its brief's expected shape, whole answers and plan answers alike.\n */\nexport function summarizeAiEvalPlans(scores: readonly AiEvalScore[]): AiEvalPlanSummary {\n const plans = scores.filter((score) => score.checks.plan !== null)\n const passed = plans.filter((score) => score.checks.plan && score.checks.rubric).length\n return { plans: plans.length, passed, passRate: plans.length ? passed / plans.length : null }\n}\n\n/** A recording a live run wrote: the brief it answers, and the answer. */\nexport interface AiEvalRecording {\n caseId: string\n candidate: AiEvalCandidate\n}\n\n/** A recording file read and checked for shape; throws naming the field at fault. */\nexport function readAiEvalRecording(raw: unknown, file: string): AiEvalRecording {\n if (!isRecord(raw) || typeof raw['caseId'] !== 'string' || !isRecord(raw['candidate'])) {\n throw new Error(`${file}: a recording holds a caseId and a candidate`)\n }\n const candidate = raw['candidate'] as Record<string, unknown>\n // `null` says the grader failed and this answer was kept ungraded\n // (AGL-3143); a missing key is a recording written by something that does\n // not know what a grade is.\n if (candidate['source'] !== 'recorded' || !(isRecord(candidate['rubric']) || candidate['rubric'] === null)) {\n throw new Error(`${file}: a recording's candidate is recorded, and graded or explicitly ungraded`)\n }\n return raw as unknown as AiEvalRecording\n}\n\n// ── Reading a case file ───────────────────────────────────────────────────\n\n/** A case file read and checked for shape; throws naming the field at fault. */\nexport function readAiEvalCase(raw: unknown, file: string): AiEvalCase {\n const fail = (why: string): never => {\n throw new Error(`${file}: ${why}`)\n }\n if (!isRecord(raw)) return fail('not an object')\n const kind = raw['kind']\n if (typeof raw['id'] !== 'string' || !raw['id']) fail('no id')\n if (typeof kind !== 'string' || !(AI_EVAL_KINDS as readonly string[]).includes(kind)) {\n fail(`kind \"${String(kind)}\" is not one of ${AI_EVAL_KINDS.join(', ')}`)\n }\n if (typeof raw['brief'] !== 'string' || !raw['brief'].trim()) fail('no brief')\n if (raw['siteName'] !== undefined && (typeof raw['siteName'] !== 'string' || !raw['siteName'].trim())) {\n fail('siteName, where given, is the site’s name')\n }\n const automation = raw['automation']\n if (automation !== undefined) {\n const action = isRecord(automation) ? automation['action'] : undefined\n const problem = isRecord(action) ? validateStoredInteraction(action as unknown as AiAutomation) : 'it holds no action'\n if (problem) fail(`automation.action is not an action the Actions editor would save: ${problem}`)\n if (isRecord(automation) && automation['run'] !== undefined && !isRecord(automation['run'])) {\n fail('automation.run, where given, is what the run history recorded')\n }\n }\n const media = raw['media']\n if (media !== undefined) {\n if (!isRecord(media) || !Object.keys(media).length) fail('media, where given, names at least one asset')\n for (const [mediaId, file] of Object.entries(media as Record<string, unknown>)) {\n if (typeof file !== 'string' || !AI_EVAL_MEDIA_FILE.test(file)) {\n fail(`media.${mediaId} is not a picture's path under tools/ai-eval/fixtures`)\n }\n }\n }\n const candidates = raw['candidates']\n const controls = raw['controls']\n if (!Array.isArray(candidates) || !candidates.length) fail('no candidates')\n if (!Array.isArray(controls) || !controls.length) fail('no controls: every case proves it can fail')\n for (const [index, candidate] of (candidates as unknown[]).entries()) {\n if (!isRecord(candidate)) fail(`candidates[${index}] is not an object`)\n const source = (candidate as Record<string, unknown>)['source']\n if (source !== 'authored' && source !== 'recorded') {\n fail(`candidates[${index}].source is neither authored nor recorded`)\n }\n if (!isRecord((candidate as Record<string, unknown>)['rubric'])) {\n fail(`candidates[${index}] has no rubric`)\n }\n }\n for (const [index, control] of (controls as unknown[]).entries()) {\n const fails = isRecord(control) ? control['fails'] : undefined\n if (!Array.isArray(fails) || !fails.length) fail(`controls[${index}] names no check it fails`)\n }\n const templateSubject = raw['templateSubject']\n if (\n templateSubject !== undefined &&\n (raw['kind'] !== 'template' ||\n typeof templateSubject !== 'string' ||\n !(templateSubject in AI_TEMPLATE_SUBJECT_DEFINITIONS))\n ) {\n fail(`templateSubject, where given, is one of ${Object.keys(AI_TEMPLATE_SUBJECT_DEFINITIONS).join(', ')} on a template case`)\n }\n const capabilities =\n raw['capabilities'] === undefined ? undefined : readAiEvalCapabilities(raw['capabilities'], fail)\n return {\n framing: null,\n inventory: null,\n ...(raw as object),\n ...(capabilities ? { capabilities } : {}),\n } as AiEvalCase\n}\n\n/**\n * A case's capabilities read and checked for shape. A creation kind the case\n * leaves out may be created, so a case names only what its workspace lacks;\n * a Free workspace's case says so with `freeTaste`, which holds its plan to\n * the sections the Free wall pays for (AGL-3070).\n */\nfunction readAiEvalCapabilities(raw: unknown, fail: (why: string) => never): AiPlanCapabilities {\n if (!isRecord(raw) || typeof raw['reusableComponents'] !== 'boolean') {\n return fail('capabilities.reusableComponents is not true or false')\n }\n const create = isRecord(raw['create']) ? raw['create'] : {}\n const unrestricted = aiUnrestrictedPlanCapabilities()\n const entries: Array<[AiBuildPlanCreateKind, AiPlanCreation]> = AI_BUILD_PLAN_CREATE_KINDS.map((kind) => {\n const entry = create[kind]\n if (entry === undefined) return [kind, unrestricted.create[kind]]\n if (!isRecord(entry) || typeof entry['allowed'] !== 'boolean') {\n return fail(`capabilities.create.${kind}.allowed is not true or false`)\n }\n const left = entry['left']\n const reason = entry['reason']\n return [\n kind,\n {\n allowed: entry['allowed'],\n left: typeof left === 'number' ? left : null,\n reason: typeof reason === 'string' ? reason : null,\n },\n ]\n })\n for (const kind of Object.keys(create)) {\n if (!(AI_BUILD_PLAN_CREATE_KINDS as readonly string[]).includes(kind)) {\n fail(`capabilities.create.${kind} is not a creation kind`)\n }\n }\n if (raw['freeTaste'] !== undefined && typeof raw['freeTaste'] !== 'boolean') {\n return fail('capabilities.freeTaste is not true or false')\n }\n return {\n reusableComponents: raw['reusableComponents'],\n create: Object.fromEntries(entries) as AiPlanCapabilities['create'],\n ...(raw['freeTaste'] === true ? { freeTaste: true } : {}),\n }\n}\n"],"names":["validateStoredInteraction","aiAutomationDraft","emptyAiAutomationRecords","AI_BUILD_PLAN_CREATE_KINDS","aiUnrestrictedPlanCapabilities","AI_EXPERIMENT_BODY_MAX_CHARS","AI_EXPERIMENT_HEADLINE_MAX_CHARS","AI_EXPERIMENT_LINE_MAX_CHARS","AI_EXPERIMENT_MAX_POINTS","AI_EXPERIMENT_NAME_MAX_CHARS","AI_EXPERIMENT_NEXT_MAX_CHARS","AI_EXPERIMENT_POINT_MAX_CHARS","AI_EXPERIMENT_RATIONALE_MAX_CHARS","aiExperimentVariantFields","checkAiExperimentExplanation","checkAiExperimentVariants","readAiExperimentResult","parseAiExperimentExplanation","parseAiExperimentVariants","aiComponentCheck","aiPlanTemplateTokenViolations","aiTemplateBindingCheck","AI_TEMPLATE_SUBJECT_DEFINITIONS","aiTemplateAddressTokens","aiProductMerchantWords","checkAiCatalog","checkAiCategories","checkAiProductCopy","aiCrmEmailMergeFields","aiCrmImportFields","aiCrmRecordCheckContext","checkAiCrmEmail","checkAiCrmMapping","checkAiCrmRecord","parseAiThemeToolInput","AI_AUTOMATION_OVERSIZE_CODES","AI_AUTOMATION_UNREADABLE_CODES","readAiAutomationAnswer","readAiWorkflowExplanation","parseAiInsightAnswer","checkAiInsightAnswer","aiDeviceAuditFindings","aiAnswerTree","aiDoctrinePlanCheck","aiDoctrineTreeCheck","aiDoctrineTreeContext","AI_SEO_DESCRIPTION_MAX","AI_SEO_TITLE_MAX","aiPlanEmbedBriefViolations","detectOffVoiceCopy","detectPlaceholderCopy","detectPublishIntent","AI_TEXT_LIMITS","expandAiRepeatedItems","checkAiLogicFunction","checkAiLogicVariable","aiEditJobOutline","ASSIST_EDIT_MAX_INSERT_NODES","ASSIST_EDIT_MAX_OPS","checkAssistEditAnswer","parseAssistEditContext","AI_EVAL_KINDS","AI_EVAL_TREE_OUTPUT","page","template","component","layout","form","email","section","aiEvalRendersAtDeviceWidths","kind","output","undefined","AI_EVAL_SITE_ID","AI_EVAL_AUTOMATION_CAPABILITIES","crm","webhooks","bookings","AI_EVAL_MEDIA_FILE","AI_EVAL_FLOORS","passRate","meanScore","seo","product","catalog","categories","theme","element","blog","text","chat","workflow","insight","experiment","logic","edit","AI_EVAL_RUBRIC_PASS_MEAN","AI_EVAL_BLOG_MAX_CHARS","AI_EVAL_TEXT_MAX_WORDS","AI_EVAL_CHAT_MAX_CHARS","isRecord","value","Array","isArray","codes","violations","map","violation","code","planSections","evalCase","plan","screens","sections","flatMap","readTree","outputKind","answer","inline","capabilities","reusableComponents","input","tree","declaresProps","subject","templateDefinition","check","inventory","assets","framing","definesComponent","length","pageSections","bindingTokens","drawn","noun","ok","undrawn","result","items","aiEvalAnswerTree","templateSubject","checkTree","readable","rules","budget","findings","templated","rootId","nodes","onProps","filter","rule","FENCE","PREAMBLE","QUOTED","MARKUP","words","trim","split","Boolean","checkCopy","limits","own","unreadable","test","broken","at","maxChars","maxWords","over","MARKDOWN_LINK","chatLinks","allowed","Set","docsUrls","matchAll","match","url","startsWith","has","checkBlog","checked","head","trimStart","extra","checkSeo","title","description","PRODUCTS_UNREADABLE","PRODUCTS_OVER_BUDGET","checkProducts","categoryIds","category","id","optionCount","facts","options","merchantWords","brief","existingCategoryNames","found","some","checkTheme","parse","changes","components","resetComponents","summary","dropped","reason","checkWorkflow","publish","read","lines","String","offVoice","index","includes","automationCapabilities","oversize","invalid","unsupported","automationRecords","action","checkInsight","parsed","insights","tables","finding","kept","CRM_UNREADABLE","CRM_OVER","checkCrm","context","record","task","columns","fields","mergeFields","path","key","samples","join","sample","checkLogic","site","variables","functions","editing","saved","name","EDIT_OVER_LIMIT","checkEdit","outline","target","documentId","versionId","hostId","ops","op","Object","entries","props","nodeId","left","message","EXPERIMENT_RULE_FINDINGS","checkExperiment","variants","variant","rationale","field","proposal","reading","arms","explained","headline","points","point","next","checkAnswer","body","checkAiEvalPlan","shape","expected","pass","shapeFindings","reuse","entry","screen","slug","maxCreate","create","createKinds","briefFindings","clampGrade","Number","isFinite","Math","min","max","aiEvalRubricVerdict","rubric","grades","structure","copy","grade","mean","reduce","sum","checkWidths","audits","audit","scoreAiEvalCandidate","candidate","scope","widths","rubricScore","parts","score","round","part","documentPasses","caseId","source","model","checks","responsive","scoreAiEvalControl","control","candidates","summarizeAiEval","scores","passed","floor","belowFloor","summarizeAiEvalPlans","plans","readAiEvalRecording","raw","file","Error","readAiEvalCase","fail","why","automation","problem","media","keys","mediaId","controls","fails","readAiEvalCapabilities","unrestricted","fromEntries","freeTaste"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-eval.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { HostTheme } from '@aglyn/shared-data-types'\nimport { validateStoredInteraction } from '@aglyn/aglyn/plugin-manager/interaction-step-checks'\nimport type { HostThemeSource } from '@aglyn/aglyn/app-utils/site-theme'\nimport {\n aiAutomationDraft,\n emptyAiAutomationRecords,\n type AiAutomationRecords,\n} from '../model/ai-automation-draft'\nimport type { ConsoleImportColumn } from '@aglyn/aglyn/plugin-manager/record-zone-props'\nimport { AI_BUILD_PLAN_CREATE_KINDS, type AiBuildPlanCreateKind } from '../model/ai-build-plan'\nimport {\n aiUnrestrictedPlanCapabilities,\n type AiPlanCapabilities,\n type AiPlanCreation,\n} from '../model/ai-plan-capabilities'\nimport {\n AI_EXPERIMENT_BODY_MAX_CHARS,\n AI_EXPERIMENT_HEADLINE_MAX_CHARS,\n AI_EXPERIMENT_LINE_MAX_CHARS,\n AI_EXPERIMENT_MAX_POINTS,\n AI_EXPERIMENT_NAME_MAX_CHARS,\n AI_EXPERIMENT_NEXT_MAX_CHARS,\n AI_EXPERIMENT_POINT_MAX_CHARS,\n AI_EXPERIMENT_RATIONALE_MAX_CHARS,\n aiExperimentVariantFields,\n checkAiExperimentExplanation,\n checkAiExperimentVariants,\n readAiExperimentResult,\n type AiExperimentArm,\n type AiExperimentTarget,\n type AiExperimentTask,\n} from '../model/ai-experiment'\nimport {\n parseAiExperimentExplanation,\n parseAiExperimentVariants,\n} from '../tools/ai-experiment-tool'\nimport type { AiSiteInventory } from '../model/ai-site-inventory'\nimport type { AiAutomationCapabilities } from '../model/ai-workflow-job'\nimport type { AiStepKind } from '../providers/catalog'\nimport type { AiEffort, AiUsage } from '../providers/contract'\nimport { aiComponentCheck } from '../jobs/ai-job-component-checks'\nimport { aiPlanTemplateTokenViolations } from '../jobs/ai-job-plan-conformance'\nimport { aiTemplateBindingCheck } from '../jobs/ai-job-template-step'\nimport type { AiJobPlan } from '../model/ai-jobs.types'\nimport {\n AI_TEMPLATE_SUBJECT_DEFINITIONS,\n aiTemplateAddressTokens,\n type AiTemplateSubject,\n type AiTemplateSubjectDefinition,\n} from '../model/ai-template-subjects'\nimport {\n aiProductMerchantWords,\n type AiProductCategory,\n type AiProductFacts,\n type AiProductPhotoRead,\n} from '../model/ai-products'\nimport type { AiRunRecord } from '../model/ai-automation-outline'\nimport { checkAiCatalog, checkAiCategories, checkAiProductCopy } from '../tools/ai-products-tool'\nimport type { AiCrmRecordKind, AiCrmTask } from '../model/ai-crm'\nimport {\n aiCrmEmailMergeFields,\n aiCrmImportFields,\n aiCrmRecordCheckContext,\n checkAiCrmEmail,\n checkAiCrmMapping,\n checkAiCrmRecord,\n} from '../tools/ai-crm-tool'\nimport { parseAiThemeToolInput } from '../tools/ai-theme-tool'\nimport {\n AI_AUTOMATION_OVERSIZE_CODES,\n AI_AUTOMATION_UNREADABLE_CODES,\n readAiAutomationAnswer,\n readAiWorkflowExplanation,\n} from '../tools/ai-workflow-tool'\nimport type { AiInsightTable } from '../model/ai-insight'\nimport { parseAiInsightAnswer } from '../tools/ai-insight-tool'\nimport { checkAiInsightAnswer } from './ai-insight-check'\nimport { aiDeviceAuditFindings, type AiDeviceAudit } from './ai-device-audit'\nimport {\n aiAnswerTree,\n aiDoctrinePlanCheck,\n aiDoctrineTreeCheck,\n aiDoctrineTreeContext,\n type AiGenerationCheckResult,\n type AiValidatedTree,\n} from './ai-doctrine'\nimport {\n AI_SEO_DESCRIPTION_MAX,\n AI_SEO_TITLE_MAX,\n aiPlanEmbedBriefViolations,\n detectOffVoiceCopy,\n detectPlaceholderCopy,\n detectPublishIntent,\n type AiAssetFacts,\n type AiCopyFraming,\n type AiDoctrineTree,\n type AiDoctrineViolation,\n} from './ai-doctrine-validators'\nimport { AI_TEXT_LIMITS, type AiOutputKind } from './ai-palette'\nimport { expandAiRepeatedItems } from './ai-repeated-items'\nimport type { AiAutomation } from '../model/ai-automation-format'\nimport type { HostFunction } from '@aglyn/aglyn/app-utils/functions'\nimport {\n checkAiLogicFunction,\n checkAiLogicVariable,\n type AiLogicSiteVariable,\n} from '../model/ai-logic-job'\nimport { aiEditJobOutline, type AiEditTargetKind } from '../model/ai-edit-job'\nimport {\n ASSIST_EDIT_MAX_INSERT_NODES,\n ASSIST_EDIT_MAX_OPS,\n checkAssistEditAnswer,\n parseAssistEditContext,\n} from '../server/assist-edit'\n\n/**\n * THE EVAL HARNESS (AGL-2937): the measure that gates every token lever.\n *\n * A token saved on a page the customer then has to fix costs more than the\n * token. So no lever ships on its token figure alone: each golden brief is\n * held to the same checks the doctrine holds a live answer to, and a kind's\n * pass rate and mean score must stay at or above its floor.\n *\n * A case is a golden brief for one output kind — the site it is built for,\n * the plan shape a good answer has, reference answers, and controls that\n * must fail. Every answer is scored on four checks:\n *\n * - **readable** — it reads as its kind: `validateAiNodeTree` admits the\n * tree, the plan parses, the fields and the copy are there;\n * - **rules** — no doctrine rule is broken (`ai-doctrine-validators.ts`),\n * nor any rule of the kind's own (a link to a page the answer was not\n * given, a title line on a blog body);\n * - **budget** — within the kind's measured budget: rule 17 for a document,\n * the length ceiling for copy;\n * - **rubric** — a grade against the brief for structure, copy fit and\n * reuse decisions, recorded from a stronger model on a live run.\n *\n * A document of a kind a site renders is also held to **responsive** (AGL-3020):\n * rendered at every device of the besigner's switcher, nothing runs past the\n * screen and no band keeps its desktop columns on a phone. It is measured in a\n * browser by `libs/plugins/ai/scripts/record-ai-page-axe.mts` and read back from that\n * recording, so it gates a pass without moving a score: a page that only works\n * on desktop does not pass, whatever its checks and grade average to.\n *\n * A planned kind's answer also carries the plan, held to the plan rules and\n * to the case's expected shape.\n *\n * Offline is the default and the only mode CI runs: answers and grades are\n * read from the fixtures under `tools/ai-eval/cases`, so a run costs nothing\n * and asserts the same verdicts every time. An answer marked `authored` was\n * written by hand as a reference and is graded by hand; one marked\n * `recorded` came from a live run. A live run spends real money and is\n * refused unless `AI_EVAL_LIVE=1` names it.\n */\n\n/** The output kinds the harness holds golden briefs for. */\nexport type AiEvalKind =\n | 'page'\n | 'template'\n | 'component'\n | 'layout'\n | 'form'\n | 'email'\n | 'section'\n | 'seo'\n | 'product'\n | 'catalog'\n | 'categories'\n | 'theme'\n | 'element'\n | 'blog'\n | 'text'\n | 'chat'\n | 'workflow'\n | 'insight'\n | 'crm'\n | 'experiment'\n | 'logic'\n | 'edit'\n\nexport const AI_EVAL_KINDS: readonly AiEvalKind[] = [\n 'page',\n 'template',\n 'component',\n 'layout',\n 'form',\n 'email',\n 'section',\n 'seo',\n 'product',\n 'catalog',\n 'categories',\n 'theme',\n 'element',\n 'blog',\n 'text',\n 'chat',\n 'workflow',\n 'insight',\n 'crm',\n 'experiment',\n 'logic',\n 'edit',\n]\n\n/** The document kind a tree kind is held to; a section rewrite is one reusable block. */\nexport const AI_EVAL_TREE_OUTPUT: Partial<Record<AiEvalKind, AiOutputKind>> = {\n page: 'page',\n template: 'template',\n component: 'component',\n layout: 'layout',\n form: 'form',\n email: 'email',\n section: 'component',\n}\n\n/**\n * Whether a kind's answer is a document a site renders, and so is held to\n * every device width (AGL-3020). An email is not: its column is fixed at 600px\n * by the medium, which rule 12 exempts it for.\n */\nexport function aiEvalRendersAtDeviceWidths(kind: AiEvalKind): boolean {\n const output = AI_EVAL_TREE_OUTPUT[kind]\n return output !== undefined && output !== 'email'\n}\n\n/**\n * The recorded device audit of an answer, or `null` when none was recorded\n * from it. The spec that scores the cases reads the recordings and answers\n * this; a scorer given none holds nothing to its widths.\n */\nexport type AiEvalAudits = (evalCase: AiEvalCase, answer: unknown) => AiDeviceAudit | null\n\n/** The checks an answer is scored on, beside its rubric. */\nexport type AiEvalCheck = 'readable' | 'rules' | 'budget' | 'plan' | 'responsive' | 'rubric'\n\n/** A grade against the brief, each criterion from 1 (fails) to 5 (excellent). */\nexport interface AiEvalRubric {\n /** Organized the way the brief needs, nothing missing, nothing extra. */\n structure: number\n /** The words fit the brief, the site and its audience, with no filler and no template placeholder (AGL-3827). */\n copy: number\n /** Reuses what the site lists before creating; `null` for a kind that places nothing. */\n reuse: number | null\n /** The model that graded it, or `authored` for a grade given by hand. */\n grader: string\n notes?: string\n}\n\n/** A plan's expected shape: what a good plan for the brief has. */\nexport interface AiEvalPlanShape {\n /** Screens planned, as `[min, max]`. */\n screens: [number, number]\n /** Inventory ids the plan must reuse. */\n reuse?: string[]\n /** The layout every planned screen renders inside. */\n layout?: string\n /** The most creations a good plan needs. */\n maxCreate?: number\n /** The kinds a creation may be. */\n createKinds?: AiBuildPlanCreateKind[]\n}\n\nexport interface AiEvalCandidate {\n /** `authored` for a reference written by hand; `recorded` for one a live run captured. */\n source: 'authored' | 'recorded'\n /**\n * `full` for an answer to the whole brief, the default; `plan` for the plan\n * alone, which a live run records for a planned kind whose generator has\n * not landed. A plan answer is held to the plan checks and its rubric, and\n * counts toward the plan step's score rather than the kind's floor.\n */\n scope?: 'full' | 'plan'\n /** The routing step and model a recorded answer came from; `null` for an authored one. */\n step: AiStepKind | null\n model: string | null\n effort: AiEffort | null\n /** The plan the plan step answered with, for a planned kind. */\n plan: unknown\n /**\n * The output as the kind's door answers: a tree tool's input (or the node\n * map itself), the copy as text, `{ title, description }` for search\n * fields, or the theme tool's input.\n */\n answer: unknown\n /** What a recorded answer spent; `null` for an authored one. */\n usage: AiUsage | null\n /**\n * A recorded answer's spend, one entry per metered exchange in the order\n * the job ran them — the plan, then every pass of its generation — with\n * the credits each came to as the machine meters a step (AGL-3030).\n * Absent on an authored answer, and on a recording that keeps its tokens\n * alone.\n */\n steps?: AiEvalRecordedStep[]\n /**\n * What a recorded product copy answer was written with of its product's\n * photo, as the products step reports it (AGL-3074): `read` when the\n * picture rode the request.\n */\n photo?: AiProductPhotoRead\n /**\n * What a recorded page was built as beside its tree (AGL-3073): its\n * screen's address and listing, and the layout it renders inside. Absent\n * on an authored answer, and on a recording made before it was kept.\n */\n screen?: AiEvalRecordedScreen\n /**\n * The grade, or `null` where the grader itself failed and there is none\n * (AGL-3143). An authored candidate always carries one.\n *\n * A brief's answer is bought before it is graded, so a grader that throws\n * would otherwise take the answer down with it and the run would pay\n * again for what it already had. The answer is kept and the grade is\n * marked missing instead of being invented: a fabricated 1/1 would read\n * as \"the model answered badly\" and pull the kind's floor down for\n * something the model never did, and the floors are the whole reason the\n * harness exists. An ungraded recording passes nothing — `rubric` is what\n * a score is taken from — so a missing grade can only read low, never\n * high, and the run that wrote it exits non-zero naming the throw.\n */\n rubric: AiEvalRubric | null\n note?: string\n /**\n * What the provider wrote when the answer ran out of ceiling (AGL-3143):\n * the bytes `answer` is only as much of as still parsed. Absent on every\n * recording but one whose answer was cut off. It is here because the\n * recording is the only place a live run's output outlives the run, and\n * it is what says whether the ceiling went on a runaway string or on a\n * decoding stall that wrote nothing usable. Never authored by hand.\n */\n rawOutput?: string\n}\n\n/** One metered exchange of a recorded job. */\nexport interface AiEvalRecordedStep {\n step: AiStepKind\n model: string\n usage: AiUsage\n estCostUsd: number\n /** What the machine meters it as: the billed cost in credits, rounded up per exchange. */\n credits: number\n}\n\n/**\n * A recorded page's screen, as the page step stored its draft. None of it is\n * a node of the page's tree: the address and the listing are fields of the\n * screen, the navigation entry is a proposal beside it, and the header, the\n * footer and the main landmark belong to the layout it renders inside.\n */\nexport interface AiEvalRecordedScreen {\n /** The draft's one-segment address, as the draft writer stored it. */\n slug: string\n /** The search title and description the draft holds; `null` where it holds none. */\n seoTitle: string | null\n seoDescription: string | null\n /** Whether a navigation entry for the page travels with it as a proposal. */\n nav: boolean\n /** The layout the draft renders inside; `null` for a page that renders inside none. */\n layout: AiEvalRecordedLayout | null\n}\n\n/** The layout a recorded page renders inside. */\nexport interface AiEvalRecordedLayout {\n id: string\n name: string\n /** `true` for a layout the job built before the page; `false` for one the site already had. */\n built: boolean\n /** Its tree as stored; `null` for a layout the case's site lists by name alone. */\n tree: { rootId: string; nodes: Record<string, unknown> } | null\n}\n\n/** An answer that must fail, and the checks it must fail. */\nexport interface AiEvalControl {\n why: string\n answer: unknown\n plan?: unknown\n fails: AiEvalCheck[]\n}\n\nexport interface AiEvalCase {\n id: string\n kind: AiEvalKind\n brief: string\n framing: AiCopyFraming\n /** The site the answer is built for; `null` for a brief that builds from none. */\n inventory: AiSiteInventory | null\n /**\n * The site's name as its visitors read it, where the case gives one\n * (AGL-3077): a recorded page's listing names the site by it. A case that\n * gives none is recorded on an untitled site.\n */\n siteName?: string\n /** Media library facts the image budget reads, by media id. */\n assets?: Record<string, AiAssetFacts>\n /** The documentation URLs a chat answer was grounded in; it may link only these. */\n docsUrls?: string[]\n /** Copy ceilings the brief sets, beside the kind's own. */\n maxChars?: number\n maxWords?: number\n /**\n * For an insight brief (AGL-2915): the tables the readers returned, which\n * every insight an answer writes is traced against.\n */\n tables?: AiInsightTable[]\n /**\n * For a product copy brief (AGL-2916): the product as its editor handed it\n * over, and the site's categories the request lists.\n */\n product?: { facts: AiProductFacts; categories: AiProductCategory[] }\n /** For a categories brief: the names of the categories the store already has. */\n existingCategoryNames?: string[]\n /** For a theme brief: the site's current theme and where it comes from. */\n siteTheme?: HostTheme\n themeSource?: HostThemeSource\n /**\n * For an automation brief (AGL-2919): what the workspace can run, and the\n * site's records the answer's words are looked up among. Absent, the\n * workspace runs everything and the site holds nothing.\n */\n automationCapabilities?: AiAutomationCapabilities\n automationRecords?: AiAutomationRecords\n /**\n * For an automation brief about a saved automation (AGL-3074): the action\n * as the site stores it, and for a run's diagnosis, what the run history\n * recorded of the failed run. Absent, the brief asks for a draft.\n */\n automation?: AiEvalAutomation\n /**\n * The media library assets of the case's site a recording reads\n * (AGL-3074), by media id: each the path of the file under\n * `tools/ai-eval/fixtures` that holds its bytes. A product's photo is\n * `media:<site id>/<media id>`, where the site is the inventory's, or\n * `AI_EVAL_SITE_ID` for a case that describes none.\n */\n media?: Record<string, string>\n /**\n * For a CRM brief (AGL-2917): what the job was asked, about which kind of\n * record, the facts the CRM reported for it, and a mapping's columns.\n */\n crm?: AiEvalCrmContext\n /**\n * For an A/B test brief (AGL-2914): which half of the step the brief asks\n * for, what the test varies, the copy under test, and — for a result — the\n * test's arms as the results reader published them.\n */\n experiment?: AiEvalExperiment\n /**\n * For a logic brief (AGL-3603): the site's variables and function names a\n * function's names are checked against, and the saved function a change or\n * an explanation starts from.\n */\n logic?: AiEvalLogic\n /**\n * For an edit brief (AGL-3616): the page or layout the change is asked of,\n * as its version stores it, which the outline the job shows the model is\n * read from and every op is held against.\n */\n edit?: AiEvalEdit\n /**\n * What the workspace may create on the case's site (AGL-3030): a brief\n * for a workspace that keeps no reusable components is held to the inline\n * doctrine, and its plan to what the workspace may create. Absent, the\n * doctrine applies whole.\n */\n capabilities?: AiPlanCapabilities\n /**\n * For a template brief (AGL-3433): whose page the template renders, which\n * holds its answers to the template step's own checks — the tokens that\n * page fills, and what the candidate's plan promised of them.\n */\n templateSubject?: AiTemplateSubject\n expected?: { plan?: AiEvalPlanShape }\n candidates: AiEvalCandidate[]\n controls: AiEvalControl[]\n}\n\n/** The site a case's job runs on when the case describes no inventory. */\nexport const AI_EVAL_SITE_ID = 'eval-site'\n\n/** What an automation brief's workspace can run when the case does not say: everything. */\nexport const AI_EVAL_AUTOMATION_CAPABILITIES: AiAutomationCapabilities = { crm: true, webhooks: true, bookings: true }\n\n/** A saved automation an automation brief asks about, as the workflow step reads one. */\nexport interface AiEvalAutomation {\n /** The action as `hosts/{hostId}/actions/{id}` holds it. */\n action: AiAutomation\n /** A failed run of it; given, the brief asks why that run failed. */\n run?: AiRunRecord\n}\n\n/** A logic brief, as the logic step is given one. */\nexport interface AiEvalLogic {\n variables: AiLogicSiteVariable[]\n functions: string[]\n saved?: HostFunction | null\n}\n\n/** An edit brief, as the edit step is given one: the document's kind and its stored node map. */\nexport interface AiEvalEdit {\n kind: AiEditTargetKind\n nodes: Record<string, unknown>\n}\n\n/** An A/B test brief, as the experiment step is given one. */\nexport interface AiEvalExperiment {\n task: AiExperimentTask\n /** What the test varies; a variants brief always names one. */\n target?: AiExperimentTarget\n /** The copy under test, as the surface handed it over. */\n subject?: string\n /** A result brief's test, and its arms as the results reader published them. */\n test?: string\n arms?: AiExperimentArm[]\n}\n\n/** A fixture file a case's media names: a relative path to a picture, never out of its folder. */\nconst AI_EVAL_MEDIA_FILE = /^(?!.*(?:^|\\/)\\.\\.?(?:\\/|$))[A-Za-z0-9][A-Za-z0-9._/-]*\\.(?:jpe?g|png|webp|gif|avif)$/\n\n/** What a CRM brief's answer is checked against, as the `crm` step checks it. */\nexport interface AiEvalCrmContext {\n task: AiCrmTask\n /** The record a `record` or `email` brief is about. */\n record?: AiCrmRecordKind\n /** The facts the CRM's reader reported: a record's, or an import's field catalog. */\n facts?: Record<string, unknown>\n /** A mapping brief's columns: each header and its shape. */\n columns?: ConsoleImportColumn[]\n}\n\n/** A kind's floor: the pass rate and the mean score its candidates may not fall below. */\nexport interface AiEvalFloor {\n passRate: number\n meanScore: number\n}\n\n/**\n * The floors, per kind. Every reference answer must pass, because each was\n * written to; the mean floor leaves room for a rubric grade of four on an\n * answer that passes every mechanical check. Recorded answers are held to\n * the same floors, and a lever that lowers a kind below its floor does not\n * ship.\n */\nexport const AI_EVAL_FLOORS: Readonly<Record<AiEvalKind, AiEvalFloor>> = {\n page: { passRate: 1, meanScore: 0.9 },\n template: { passRate: 1, meanScore: 0.9 },\n component: { passRate: 1, meanScore: 0.9 },\n layout: { passRate: 1, meanScore: 0.9 },\n form: { passRate: 1, meanScore: 0.9 },\n email: { passRate: 1, meanScore: 0.9 },\n section: { passRate: 1, meanScore: 0.9 },\n seo: { passRate: 1, meanScore: 0.9 },\n product: { passRate: 1, meanScore: 0.9 },\n catalog: { passRate: 1, meanScore: 0.9 },\n categories: { passRate: 1, meanScore: 0.9 },\n theme: { passRate: 1, meanScore: 0.9 },\n element: { passRate: 1, meanScore: 0.9 },\n blog: { passRate: 1, meanScore: 0.9 },\n text: { passRate: 1, meanScore: 0.9 },\n chat: { passRate: 1, meanScore: 0.9 },\n workflow: { passRate: 1, meanScore: 0.9 },\n insight: { passRate: 1, meanScore: 0.9 },\n crm: { passRate: 1, meanScore: 0.9 },\n experiment: { passRate: 1, meanScore: 0.9 },\n logic: { passRate: 1, meanScore: 0.9 },\n edit: { passRate: 1, meanScore: 0.9 },\n}\n\n/** A rubric passes at this mean, with no criterion below three. */\nexport const AI_EVAL_RUBRIC_PASS_MEAN = 3.5\n\n/** How long a blog body may run: the blog mode's output ceiling, at four characters a token. */\nexport const AI_EVAL_BLOG_MAX_CHARS = 8_000\n\n/** How long a job's copy may run when the brief implies no length: the text step's own rule. */\nexport const AI_EVAL_TEXT_MAX_WORDS = 150\n\n/** How long a chat answer may run: the chat door's output ceiling, at four characters a token. */\nexport const AI_EVAL_CHAT_MAX_CHARS = 4_000\n\nexport interface AiEvalScore {\n caseId: string\n kind: AiEvalKind\n source: AiEvalCandidate['source']\n scope: NonNullable<AiEvalCandidate['scope']>\n model: string | null\n /** A check that does not apply to the answer — the plan of an unplanned kind, the document of a plan answer — is `null`. */\n checks: Record<'rubric', boolean> & Record<Exclude<AiEvalCheck, 'rubric'>, boolean | null>\n /** The rubric's mean, from 0 (every criterion 1) to 1 (every criterion 5). */\n rubricScore: number\n /** The checks and the rubric, averaged: from 0 to 1. */\n score: number\n pass: boolean\n /** Why a check failed: violation codes and the kind's own findings. */\n findings: string[]\n}\n\ninterface Checked {\n readable: boolean\n rules: boolean\n budget: boolean\n findings: string[]\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst codes = (violations: readonly AiDoctrineViolation[]) =>\n violations.map((violation) => violation.code)\n\n// ── The kinds ─────────────────────────────────────────────────────────────\n\ninterface ReadTree {\n /** The answer as the check reads it: a page's repeated items drawn. */\n input: Record<string, unknown>\n declaresProps: boolean\n /** Why a page's repeated item could not be drawn; the tree is not read then. */\n undrawn: AiDoctrineViolation[] | null\n result: AiGenerationCheckResult<AiValidatedTree> | null\n}\n\n/**\n * The sections a page answer's plan lays out, by name, which a link on the\n * page may take a visitor to as the page step lets it (AGL-3097); empty for an\n * answer of another kind, or with no plan to read them from.\n */\nfunction planSections(evalCase: AiEvalCase, plan: unknown): string[] {\n const screens = evalCase.kind === 'page' && isRecord(plan) && Array.isArray(plan['screens']) ? plan['screens'] : []\n const sections = isRecord(screens[0]) && Array.isArray(screens[0]['sections']) ? screens[0]['sections'] : []\n return sections.flatMap((section: unknown) =>\n isRecord(section) && typeof section['name'] === 'string' ? [section['name']] : [],\n )\n}\n\nfunction readTree(evalCase: AiEvalCase, outputKind: AiOutputKind, answer: unknown, plan?: unknown): ReadTree {\n const inline = evalCase.capabilities?.reusableComponents === false\n let input = isRecord(answer) ? answer : { tree: answer }\n // A component answer that declares its properties binds them in its tree,\n // and is held to the component step's own checks as that step holds it\n // (AGL-3054).\n const declaresProps = evalCase.kind === 'component' && Array.isArray(input['props'])\n const sections = planSections(evalCase, plan)\n const subject = templateDefinition(evalCase)\n const check = aiDoctrineTreeCheck(\n outputKind,\n aiDoctrineTreeContext(evalCase.inventory, {\n ...(evalCase.assets ? { assets: evalCase.assets } : {}),\n framing: evalCase.framing,\n ...(inline ? { reusableComponents: false } : {}),\n ...(declaresProps ? { definesComponent: true } : {}),\n ...(sections.length ? { pageSections: sections } : {}),\n ...(subject ? { bindingTokens: aiTemplateAddressTokens(subject) } : {}),\n }),\n )\n // A page's repeated item written once is drawn into its copies first, as the\n // page step draws it, and refused as the page step refuses it (AGL-3053).\n if (evalCase.kind === 'page') {\n const drawn = expandAiRepeatedItems(aiAnswerTree(input), { inline, noun: 'page' })\n if (drawn.ok === false) return { input, declaresProps, undrawn: drawn.violations, result: null }\n if (drawn.items) input = { tree: drawn.tree }\n }\n return { input, declaresProps, undrawn: null, result: check(input) }\n}\n\n/**\n * The tree an answer of a tree kind is checked as — a page's repeated items\n * drawn into their copies — or `null` when it cannot be read as one. The\n * device audit renders exactly this tree (AGL-3020).\n */\nexport function aiEvalAnswerTree(evalCase: AiEvalCase, answer: unknown): AiValidatedTree | null {\n const outputKind = AI_EVAL_TREE_OUTPUT[evalCase.kind]\n return outputKind ? (readTree(evalCase, outputKind, answer).result?.value ?? null) : null\n}\n\n/** The subject a template case's page is for, whose tokens its answers bind. */\nfunction templateDefinition(evalCase: AiEvalCase): AiTemplateSubjectDefinition | null {\n return evalCase.kind === 'template' && evalCase.templateSubject\n ? AI_TEMPLATE_SUBJECT_DEFINITIONS[evalCase.templateSubject]\n : null\n}\n\nfunction checkTree(evalCase: AiEvalCase, outputKind: AiOutputKind, answer: unknown, plan?: unknown): Checked {\n const { input, declaresProps, undrawn, result } = readTree(evalCase, outputKind, answer, plan)\n if (undrawn || !result) {\n return { readable: false, rules: false, budget: false, findings: codes(undrawn ?? []) }\n }\n const subject = templateDefinition(evalCase)\n // A template answer is held to the template step's own checks, as that step\n // holds it: the tokens its page fills, and what its plan promised (AGL-3433).\n const templated = (tree: AiValidatedTree) =>\n subject\n ? [\n ...aiTemplateBindingCheck(subject)(tree),\n ...aiPlanTemplateTokenViolations(isRecord(plan) ? (plan as unknown as AiJobPlan) : null, subject, {\n rootId: tree.rootId,\n nodes: tree.nodes as unknown as AiDoctrineTree['nodes'],\n }),\n ]\n : []\n const violations = [\n ...result.violations,\n ...(declaresProps && result.value\n ? aiComponentCheck({ inventory: evalCase.inventory, plan: null, onProps: () => undefined })(result.value, input)\n : []),\n ...(result.value ? templated(result.value) : []),\n ]\n const budget = violations.filter((violation) => violation.rule === 17)\n const rules = violations.filter((violation) => violation.rule !== 17)\n return {\n readable: result.value !== null,\n rules: result.value !== null && rules.length === 0,\n budget: result.value !== null && budget.length === 0,\n findings: codes(violations),\n }\n}\n\nconst FENCE = /```/\nconst PREAMBLE = /^\\s*(?:sure|certainly|of course|here(?:'s| is| are))\\b/i\nconst QUOTED = /^\\s*[\"“'].*[\"”']\\s*$/s\nconst MARKUP = /<\\/?[a-z][^>]*>/i\n\nfunction words(text: string): number {\n return text.trim().split(/\\s+/).filter(Boolean).length\n}\n\n/** Copy answered as text: there, unwrapped, in the site's voice, within its ceiling. */\nfunction checkCopy(\n evalCase: AiEvalCase,\n answer: unknown,\n limits: { maxChars?: number; maxWords?: number },\n own: (text: string) => string[] = () => [],\n): Checked {\n if (typeof answer !== 'string' || !answer.trim()) {\n return { readable: false, rules: false, budget: false, findings: ['copy-missing'] }\n }\n const text = answer.trim()\n const unreadable = [\n ...(FENCE.test(text) ? ['copy-fenced'] : []),\n ...(PREAMBLE.test(text) ? ['copy-preamble'] : []),\n ...(QUOTED.test(text) ? ['copy-quoted'] : []),\n ]\n const broken = [\n ...codes(detectOffVoiceCopy([{ at: 'answer', text }], evalCase.framing)),\n // A chat answer may quote a binding token to explain it; copy for a page never shows one (AGL-3827).\n ...(evalCase.kind === 'chat' ? [] : codes(detectPlaceholderCopy([{ at: 'answer', text }]))),\n ...(MARKUP.test(text) ? ['copy-markup'] : []),\n ...own(text),\n ]\n const maxChars = evalCase.maxChars ?? limits.maxChars\n const maxWords = evalCase.maxWords ?? limits.maxWords\n const over = [\n ...(maxChars !== undefined && text.length > maxChars ? ['copy-over-chars'] : []),\n ...(maxWords !== undefined && words(text) > maxWords ? ['copy-over-words'] : []),\n ]\n return {\n readable: unreadable.length === 0,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...unreadable, ...broken, ...over],\n }\n}\n\nconst MARKDOWN_LINK = /\\[[^\\]]*\\]\\(([^)\\s]+)\\)/g\n\n/** A chat answer links only the documentation it was given and console paths. */\nfunction chatLinks(evalCase: AiEvalCase): (text: string) => string[] {\n const allowed = new Set(evalCase.docsUrls ?? [])\n return (text) =>\n [...text.matchAll(MARKDOWN_LINK)]\n .map((match) => match[1])\n .filter((url) => !url.startsWith('/') && !allowed.has(url))\n .map((url) => `chat-link-not-given:${url}`)\n}\n\nfunction checkBlog(evalCase: AiEvalCase, answer: unknown): Checked {\n const checked = checkCopy(evalCase, answer, { maxChars: AI_EVAL_BLOG_MAX_CHARS })\n if (typeof answer !== 'string') return checked\n const head = answer.trimStart()\n const extra = [\n ...(head.startsWith('---') ? ['blog-front-matter'] : []),\n ...(/^#\\s/.test(head) ? ['blog-title-line'] : []),\n ]\n return extra.length\n ? { ...checked, readable: false, findings: [...checked.findings, ...extra] }\n : checked\n}\n\nfunction checkSeo(evalCase: AiEvalCase, answer: unknown): Checked {\n const title = isRecord(answer) && typeof answer['title'] === 'string' ? answer['title'].trim() : ''\n const description =\n isRecord(answer) && typeof answer['description'] === 'string' ? answer['description'].trim() : ''\n if (!title || !description) {\n return { readable: false, rules: false, budget: false, findings: ['seo-field-missing'] }\n }\n const broken = [\n ...codes(detectPublishIntent(answer)),\n ...codes(\n detectOffVoiceCopy(\n [\n { at: 'title', text: title },\n { at: 'description', text: description },\n ],\n evalCase.framing,\n ),\n ),\n ...codes(\n detectPlaceholderCopy([\n { at: 'title', text: title },\n { at: 'description', text: description },\n ]),\n ),\n ...(MARKUP.test(title) || MARKUP.test(description) ? ['seo-markup'] : []),\n ]\n const over = [\n ...(title.length > AI_SEO_TITLE_MAX ? ['seo-title-over'] : []),\n ...(description.length > AI_SEO_DESCRIPTION_MAX ? ['seo-description-over'] : []),\n ]\n return {\n readable: true,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...broken, ...over],\n }\n}\n\n/** What a products check refuses an answer for, by the check it fails. */\nconst PRODUCTS_UNREADABLE = new Set(['type', 'missing', 'option-count'])\nconst PRODUCTS_OVER_BUDGET = new Set(['too-long', 'too-many', 'product-count'])\n\n/**\n * A products answer (AGL-2916), held by the check its generation is held by:\n * a product's copy, a catalog, or categories with discounts. A finding about\n * the answer's shape makes it unreadable, one about a length or a count is\n * over its budget, and every other one — a claim, a price, markup, a category\n * the request did not list — breaks a rule.\n */\nfunction checkProducts(evalCase: AiEvalCase, answer: unknown): Checked {\n if (!isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['products-not-a-call'] }\n }\n const result =\n evalCase.kind === 'product'\n ? checkAiProductCopy(answer, {\n categoryIds: (evalCase.product?.categories ?? []).map((category) => category.id),\n optionCount: evalCase.product?.facts.options.length ?? 0,\n merchantWords: evalCase.product ? aiProductMerchantWords(evalCase.product.facts) : evalCase.brief,\n })\n : evalCase.kind === 'catalog'\n ? checkAiCatalog(answer, { merchantWords: evalCase.brief })\n : checkAiCategories(answer, {\n existingCategoryNames: evalCase.existingCategoryNames ?? [],\n merchantWords: evalCase.brief,\n })\n const found = [...codes(result.violations), ...codes(detectPublishIntent(answer))]\n return {\n readable: !found.some((code) => PRODUCTS_UNREADABLE.has(code)),\n rules: !found.some((code) => !PRODUCTS_UNREADABLE.has(code) && !PRODUCTS_OVER_BUDGET.has(code)),\n budget: !found.some((code) => PRODUCTS_OVER_BUDGET.has(code)),\n findings: found,\n }\n}\n\nfunction checkTheme(evalCase: AiEvalCase, answer: unknown): Checked {\n if (!isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['theme-not-a-call'] }\n }\n const parse = parseAiThemeToolInput(answer)\n const changes = parse.changes.length + parse.components.length + (parse.resetComponents ? 1 : 0)\n const broken = [\n ...codes(detectPublishIntent(answer)),\n ...codes(detectOffVoiceCopy([{ at: 'summary', text: parse.summary }], evalCase.framing)),\n ]\n return {\n readable: changes > 0 && parse.dropped.length === 0,\n rules: broken.length === 0,\n budget: true,\n findings: [...parse.dropped.map((reason) => `theme-dropped:${reason}`), ...broken],\n }\n}\n\n/**\n * An automation (AGL-2919), or an explanation of one: read through the tool's\n * own reader, and an automation also made into the document the workflows\n * plugin stores and held to the Actions editor's validator.\n */\nfunction checkWorkflow(evalCase: AiEvalCase, answer: unknown): Checked {\n if (!isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['workflow-not-a-call'] }\n }\n const publish = codes(detectPublishIntent(answer))\n if ('summary' in answer) {\n const read = readAiWorkflowExplanation(answer)\n const lines = [\n String(answer['summary'] ?? ''),\n ...(Array.isArray(answer['points']) ? answer['points'] : []),\n ...(Array.isArray(answer['suggestions']) ? answer['suggestions'] : []),\n ].map(String)\n const offVoice = codes(\n detectOffVoiceCopy(lines.map((text, index) => ({ at: `line[${index}]`, text })), evalCase.framing),\n )\n const found = codes(read.violations)\n return {\n readable: !found.includes('explanation-shape'),\n rules: read.value !== null && publish.length === 0 && offVoice.length === 0,\n budget: true,\n findings: [...found, ...publish, ...offVoice],\n }\n }\n const capabilities = evalCase.automationCapabilities ?? AI_EVAL_AUTOMATION_CAPABILITIES\n const read = readAiAutomationAnswer(answer, capabilities)\n const found = codes(read.violations)\n const unreadable = found.filter((code) => AI_AUTOMATION_UNREADABLE_CODES.includes(code))\n const oversize = found.filter((code) => AI_AUTOMATION_OVERSIZE_CODES.includes(code))\n const broken = found.filter((code) => !unreadable.includes(code) && !oversize.includes(code))\n const invalid =\n read.value && !read.value.unsupported\n ? validateStoredInteraction(aiAutomationDraft(read.value, evalCase.automationRecords ?? emptyAiAutomationRecords()).action)\n : null\n return {\n readable: unreadable.length === 0,\n rules: broken.length === 0 && publish.length === 0 && invalid === null,\n budget: oversize.length === 0,\n findings: [...found, ...publish, ...(invalid ? [`workflow-invalid:${invalid}`] : [])],\n }\n}\n\n/**\n * An insight answer held to the trace (AGL-2915): readable when it is a\n * `submit_insights` call that keeps an insight, within the rules when no\n * insight is left out for its numbers, its citations or its words, and within\n * the budget when no insight runs long and there are no more than five.\n */\nfunction checkInsight(evalCase: AiEvalCase, answer: unknown): Checked {\n const parsed = parseAiInsightAnswer(answer)\n if (!parsed || !parsed.insights.length) {\n return { readable: false, rules: false, budget: false, findings: ['insight-no-answer'] }\n }\n const check = checkAiInsightAnswer(parsed, evalCase.tables ?? [])\n const findings = check.findings.map((finding) => finding.split(':')[0])\n const over = findings.filter((code) => code === 'insight-too-long' || code === 'insight-too-many')\n return {\n readable: check.kept.length > 0,\n rules: findings.length === over.length,\n budget: over.length === 0,\n findings: check.findings,\n }\n}\n\n/** The CRM findings that mean the answer could not be read as one, and the ones over a length. */\nconst CRM_UNREADABLE = new Set(['type', 'missing'])\nconst CRM_OVER = new Set(['too-long'])\n\n/**\n * A CRM answer, held by the checks the `crm` step holds it to (AGL-2917),\n * with rule 13 and the site's voice on everything a person reads.\n */\nfunction checkCrm(evalCase: AiEvalCase, answer: unknown): Checked {\n const context = evalCase.crm\n if (!context || !isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['crm-not-a-call'] }\n }\n const facts = context.facts ?? {}\n const kind = context.record ?? 'contact'\n const result =\n context.task === 'mapping'\n ? checkAiCrmMapping(answer, { columns: context.columns ?? [], fields: aiCrmImportFields(facts) })\n : context.task === 'email'\n ? checkAiCrmEmail(answer, { mergeFields: aiCrmEmailMergeFields(kind) })\n : checkAiCrmRecord(answer, aiCrmRecordCheckContext(kind, facts))\n const own = codes(result.violations)\n const read = (path: string[]): string => {\n let value: unknown = answer\n for (const key of path) value = isRecord(value) ? value[key] : undefined\n return typeof value === 'string' ? value : ''\n }\n const samples = [\n ['summary'],\n ['standing'],\n ['nextStep', 'title'],\n ['nextStep', 'reason'],\n ['stage', 'reason'],\n ['subject'],\n ['body'],\n ]\n .map((path) => ({ at: path.join('.'), text: read(path) }))\n .filter((sample) => sample.text)\n const broken = [\n ...codes(detectPublishIntent(answer)),\n ...codes(detectOffVoiceCopy(samples, evalCase.framing)),\n ...own.filter((code) => !CRM_UNREADABLE.has(code) && !CRM_OVER.has(code)),\n ]\n return {\n readable: !own.some((code) => CRM_UNREADABLE.has(code)),\n rules: broken.length === 0,\n budget: !own.some((code) => CRM_OVER.has(code)),\n findings: [...new Set([...own, ...broken])],\n }\n}\n\n/**\n * A logic answer (AGL-3603): an explanation as an automation's is checked; a\n * function or a variable through the step's own check, against the case's\n * site — the grammar, the names and a first run.\n */\nfunction checkLogic(evalCase: AiEvalCase, answer: unknown): Checked {\n if (!isRecord(answer)) return { readable: false, rules: false, budget: false, findings: ['logic-not-a-call'] }\n const site = evalCase.logic ?? { variables: [], functions: [] }\n if ('summary' in answer) {\n const read = readAiWorkflowExplanation(answer)\n const found = codes(read.violations)\n return { readable: !found.includes('explanation-shape'), rules: read.value !== null, budget: true, findings: found }\n }\n const context = { variables: site.variables, functions: site.functions, editing: site.saved?.name ?? null }\n const read = 'operations' in answer ? checkAiLogicFunction(answer, context) : checkAiLogicVariable(answer, context)\n const found = codes(read.violations)\n return {\n readable: !found.includes('logic-not-a-call'),\n rules: read.value !== null,\n budget: !found.includes('logic-size'),\n findings: found,\n }\n}\n\n/** The edit rung's own size limits, as the reasons its check gives for an op past one. */\nconst EDIT_OVER_LIMIT = /change limit|elements at once/\n\n/**\n * An edit answer (AGL-3616), held by the check the edit step holds it by:\n * the edit rung's closed world and palette validators, against the outline\n * the job shows the model of the case's document. Readable when a change\n * survives; a rule broken when any change was left out, or the answer says\n * it published; over budget past the rung's own limits.\n */\nfunction checkEdit(evalCase: AiEvalCase, answer: unknown): Checked {\n const brief = evalCase.edit\n if (!brief) return { readable: false, rules: false, budget: false, findings: ['edit-brief-missing'] }\n if (!isRecord(answer) || !Array.isArray(answer['ops'])) {\n return { readable: false, rules: false, budget: false, findings: ['edit-not-a-call'] }\n }\n const outline = aiEditJobOutline(brief.nodes)\n const context = outline ? parseAssistEditContext(outline, { whole: true }) : null\n if (!context) return { readable: false, rules: false, budget: false, findings: ['edit-no-document'] }\n const checked = checkAssistEditAnswer(answer, {\n context,\n target: { kind: brief.kind, documentId: evalCase.id, versionId: evalCase.id, hostId: AI_EVAL_SITE_ID },\n })\n const ops = answer['ops'] as unknown[]\n const over =\n ops.length > ASSIST_EDIT_MAX_OPS ||\n ops.some((op) => isRecord(op) && Array.isArray(op['nodes']) && op['nodes'].length > ASSIST_EDIT_MAX_INSERT_NODES)\n const samples = (checked.value?.ops ?? []).flatMap((op) =>\n op.op === 'updateProps'\n ? Object.entries(op.props)\n .filter(([, value]) => typeof value === 'string' && value.trim())\n .map(([name, value]) => ({ at: `${op.nodeId}.${name}`, text: String(value) }))\n : [],\n )\n const left = checked.violations.filter((violation) => !EDIT_OVER_LIMIT.test(violation.message))\n const broken = [\n ...codes(detectPublishIntent(answer)),\n ...codes(detectOffVoiceCopy(samples, evalCase.framing)),\n ...left.map((violation) => `edit-left-out:${violation.message}`),\n ]\n return {\n readable: checked.value !== null,\n rules: broken.length === 0,\n budget: !over,\n findings: [...new Set([...broken, ...(over ? ['edit-over-limit'] : [])])],\n }\n}\n\n/** What an experiment answer is refused for, by the check it fails. */\nconst EXPERIMENT_RULE_FINDINGS = new Set([\n 'variant-carries-markup',\n 'variant-fills-another-targets-fields',\n 'variant-repeats-another',\n 'variant-has-no-copy',\n])\n\n/**\n * An A/B test answer (AGL-2914), held by the checks its step holds it by.\n *\n * A variants answer is readable when at least two variants survive, breaks a\n * rule when one carried markup, repeated another or answered a different\n * target, and is over budget when a field ran past the length the card\n * stores. A result answer is readable when an explanation survives its\n * reading, and breaks a rule when the reading had to take a winner out of it\n * — which is the whole point of the kind: an explanation that claims more\n * than the figures support does not pass here.\n */\nfunction checkExperiment(evalCase: AiEvalCase, answer: unknown): Checked {\n const brief = evalCase.experiment\n if (!brief) {\n return { readable: false, rules: false, budget: false, findings: ['experiment-brief-missing'] }\n }\n if (brief.task === 'variants') {\n const target: AiExperimentTarget = brief.target ?? 'screen'\n const parsed = parseAiExperimentVariants(answer)\n const checked = checkAiExperimentVariants(parsed, target)\n if (!parsed || !checked) {\n return { readable: false, rules: false, budget: false, findings: ['experiment-no-variants'] }\n }\n const fields = aiExperimentVariantFields(target)\n const over = parsed.variants.flatMap((variant) => [\n ...(variant.name.length > AI_EXPERIMENT_NAME_MAX_CHARS ? ['experiment-name-over'] : []),\n ...(variant.rationale.length > AI_EXPERIMENT_RATIONALE_MAX_CHARS ? ['experiment-rationale-over'] : []),\n ...fields.flatMap((field) =>\n String(variant[field] ?? '').length >\n (field === 'body' ? AI_EXPERIMENT_BODY_MAX_CHARS : AI_EXPERIMENT_LINE_MAX_CHARS)\n ? [`experiment-${field}-over`]\n : [],\n ),\n ])\n const samples = checked.proposal.variants.flatMap((variant) =>\n fields.map((field) => ({ at: `${variant.name}.${field}`, text: String(variant[field] ?? '') })),\n )\n const broken = [\n ...checked.findings.filter((finding) => EXPERIMENT_RULE_FINDINGS.has(finding)),\n ...codes(detectPublishIntent(answer)),\n ...codes(detectOffVoiceCopy(samples.filter((sample) => sample.text), evalCase.framing)),\n ]\n return {\n readable: true,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...new Set([...broken, ...over])],\n }\n }\n\n const reading = readAiExperimentResult(brief.test ?? '', brief.arms ?? [])\n const parsed = parseAiExperimentExplanation(answer)\n const explained = checkAiExperimentExplanation(parsed, reading)\n if (!parsed || !explained) {\n return { readable: false, rules: false, budget: false, findings: ['experiment-no-explanation'] }\n }\n const over = [\n ...(parsed.headline.length > AI_EXPERIMENT_HEADLINE_MAX_CHARS ? ['experiment-headline-over'] : []),\n ...(parsed.points.length > AI_EXPERIMENT_MAX_POINTS ? ['experiment-points-over'] : []),\n ...parsed.points.flatMap((point) =>\n point.length > AI_EXPERIMENT_POINT_MAX_CHARS ? ['experiment-point-over'] : [],\n ),\n ...(parsed.next.length > AI_EXPERIMENT_NEXT_MAX_CHARS ? ['experiment-next-over'] : []),\n ]\n const broken = [\n ...explained.findings,\n ...codes(detectPublishIntent(answer)),\n ...codes(\n detectOffVoiceCopy(\n [\n { at: 'headline', text: explained.headline },\n ...explained.points.map((point, index) => ({ at: `points.${index}`, text: point })),\n ],\n evalCase.framing,\n ),\n ),\n ]\n return {\n readable: true,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...new Set([...broken, ...over])],\n }\n}\n\n/** An answer held to its kind's checks; a page's links to the sections of the plan it was built from. */\nfunction checkAnswer(evalCase: AiEvalCase, answer: unknown, plan?: unknown): Checked {\n const outputKind = AI_EVAL_TREE_OUTPUT[evalCase.kind]\n if (outputKind) return checkTree(evalCase, outputKind, answer, plan)\n switch (evalCase.kind) {\n case 'seo':\n return checkSeo(evalCase, answer)\n case 'product':\n case 'catalog':\n case 'categories':\n return checkProducts(evalCase, answer)\n case 'theme':\n return checkTheme(evalCase, answer)\n case 'element':\n return checkCopy(evalCase, answer, { maxChars: AI_TEXT_LIMITS.body })\n case 'blog':\n return checkBlog(evalCase, answer)\n case 'text':\n return checkCopy(evalCase, answer, { maxWords: AI_EVAL_TEXT_MAX_WORDS })\n case 'chat':\n return checkCopy(evalCase, answer, { maxChars: AI_EVAL_CHAT_MAX_CHARS }, chatLinks(evalCase))\n case 'workflow':\n return checkWorkflow(evalCase, answer)\n case 'insight':\n return checkInsight(evalCase, answer)\n case 'crm':\n return checkCrm(evalCase, answer)\n case 'experiment':\n return checkExperiment(evalCase, answer)\n case 'logic':\n return checkLogic(evalCase, answer)\n case 'edit':\n return checkEdit(evalCase, answer)\n default:\n return { readable: false, rules: false, budget: false, findings: ['kind-unknown'] }\n }\n}\n\n/** The plan held to the plan rules, then to the shape the case expects. */\nexport function checkAiEvalPlan(\n evalCase: AiEvalCase,\n plan: unknown,\n): { pass: boolean; findings: string[] } {\n const shape = evalCase.expected?.plan\n if (!shape) return { pass: true, findings: [] }\n const result = aiDoctrinePlanCheck(evalCase.inventory, evalCase.framing, evalCase.capabilities ?? null)(\n isRecord(plan) ? plan : {},\n )\n if (!result.value) return { pass: false, findings: ['plan-unreadable', ...codes(result.violations)] }\n const value = result.value\n const shapeFindings = [\n ...(value.screens.length < shape.screens[0] || value.screens.length > shape.screens[1]\n ? [`plan-screens:${value.screens.length}`]\n : []),\n ...(shape.reuse ?? [])\n .filter((id) => !value.reuse.some((entry) => entry.id === id))\n .map((id) => `plan-reuse-missing:${id}`),\n ...(shape.layout\n ? value.screens\n .filter((screen) => screen.layout !== shape.layout)\n .map((screen) => `plan-layout:${screen.slug}`)\n : []),\n ...(shape.maxCreate !== undefined && value.create.length > shape.maxCreate\n ? [`plan-create:${value.create.length}`]\n : []),\n ...(shape.createKinds\n ? value.create\n .filter((entry) => !shape.createKinds?.includes(entry.kind))\n .map((entry) => `plan-create-kind:${entry.kind}`)\n : []),\n ]\n // The players a plan lists, against the brief it answers, as the plan step holds them (AGL-3433).\n const briefFindings = codes(aiPlanEmbedBriefViolations(value, evalCase.brief))\n const findings = [...codes(result.violations), ...briefFindings, ...shapeFindings]\n return { pass: findings.length === 0, findings }\n}\n\nconst clampGrade = (value: unknown): number | null => {\n if (value === null || value === undefined) return null\n const parsed = Number(value)\n return Number.isFinite(parsed) ? Math.min(5, Math.max(1, parsed)) : null\n}\n\n/** A rubric's mean and whether it passes: the mean at `AI_EVAL_RUBRIC_PASS_MEAN`, nothing under three. */\nexport function aiEvalRubricVerdict(rubric: AiEvalRubric | null | undefined): {\n mean: number\n pass: boolean\n} {\n const grades = [rubric?.structure, rubric?.copy, rubric?.reuse]\n .map(clampGrade)\n .filter((grade): grade is number => grade !== null)\n if (!grades.length) return { mean: 1, pass: false }\n const mean = grades.reduce((sum, grade) => sum + grade, 0) / grades.length\n return { mean, pass: mean >= AI_EVAL_RUBRIC_PASS_MEAN && Math.min(...grades) >= 3 }\n}\n\n/**\n * The widths a readable document of a rendered kind is held to, from its\n * recorded device audit: `null` when the answer is not such a document or no\n * audits were given; failing, with `widths-unrecorded`, when none was recorded\n * from this answer.\n */\nfunction checkWidths(\n evalCase: AiEvalCase,\n answer: unknown,\n checked: Checked | null,\n audits: AiEvalAudits | undefined,\n): { pass: boolean; findings: string[] } | null {\n if (!audits || !checked?.readable || !aiEvalRendersAtDeviceWidths(evalCase.kind)) return null\n const audit = audits(evalCase, answer)\n if (!audit) return { pass: false, findings: ['widths-unrecorded'] }\n const findings = aiDeviceAuditFindings(audit)\n return { pass: findings.length === 0, findings }\n}\n\n/** One answer to one golden brief, scored. */\nexport function scoreAiEvalCandidate(\n evalCase: AiEvalCase,\n candidate: AiEvalCandidate,\n audits?: AiEvalAudits,\n): AiEvalScore {\n const scope = candidate.scope ?? 'full'\n const checked = scope === 'full' ? checkAnswer(evalCase, candidate.answer, candidate.plan) : null\n const widths = checkWidths(evalCase, candidate.answer, checked, audits)\n const plan = evalCase.expected?.plan ? checkAiEvalPlan(evalCase, candidate.plan) : null\n const rubric = aiEvalRubricVerdict(candidate.rubric)\n const rubricScore = (rubric.mean - 1) / 4\n const parts = [\n ...(checked ? [checked.readable ? 1 : 0, checked.rules ? 1 : 0, checked.budget ? 1 : 0] : []),\n ...(plan ? [plan.pass ? 1 : 0] : []),\n rubricScore,\n ]\n const score = Math.round((parts.reduce((sum, part) => sum + part, 0) / parts.length) * 10_000) / 10_000\n const documentPasses = checked ? checked.readable && checked.rules && checked.budget : true\n return {\n caseId: evalCase.id,\n kind: evalCase.kind,\n source: candidate.source,\n scope,\n model: candidate.model,\n checks: {\n readable: checked ? checked.readable : null,\n rules: checked ? checked.rules : null,\n budget: checked ? checked.budget : null,\n plan: plan ? plan.pass : null,\n responsive: widths ? widths.pass : null,\n rubric: rubric.pass,\n },\n rubricScore: Math.round(rubricScore * 10_000) / 10_000,\n score,\n // A plan answer to a brief with no expected plan has nothing to pass.\n pass: documentPasses && (widths?.pass ?? true) && (plan?.pass ?? scope === 'full') && rubric.pass,\n findings: [...(checked?.findings ?? []), ...(widths?.findings ?? []), ...(plan?.findings ?? [])],\n }\n}\n\n/**\n * The checks a control failed; the harness requires every one it names. A\n * control whose widths were never recorded fails none of them.\n */\nexport function scoreAiEvalControl(\n evalCase: AiEvalCase,\n control: AiEvalControl,\n audits?: AiEvalAudits,\n): AiEvalCheck[] {\n // A control is the case's first answer with one thing wrong, built from its plan unless it carries its own.\n const checked = checkAnswer(evalCase, control.answer, control.plan ?? evalCase.candidates[0]?.plan)\n const widths = audits?.(evalCase, control.answer) ? checkWidths(evalCase, control.answer, checked, audits) : null\n const plan =\n control.plan !== undefined && evalCase.expected?.plan\n ? checkAiEvalPlan(evalCase, control.plan)\n : null\n return [\n ...(checked.readable ? [] : (['readable'] as const)),\n ...(checked.rules ? [] : (['rules'] as const)),\n ...(checked.budget ? [] : (['budget'] as const)),\n ...(plan && !plan.pass ? (['plan'] as const) : []),\n ...(widths && !widths.pass ? (['responsive'] as const) : []),\n ]\n}\n\nexport interface AiEvalKindSummary {\n kind: AiEvalKind\n candidates: number\n passed: number\n /** Passed over candidates; `null` with none, which is below every floor. */\n passRate: number | null\n meanScore: number | null\n floor: AiEvalFloor\n belowFloor: boolean\n}\n\n/** Every kind's pass rate and mean score against its floor; a kind with no candidate is below it. */\nexport function summarizeAiEval(scores: readonly AiEvalScore[]): AiEvalKindSummary[] {\n return AI_EVAL_KINDS.map((kind) => {\n const own = scores.filter((score) => score.kind === kind && score.scope === 'full')\n const passed = own.filter((score) => score.pass).length\n const passRate = own.length ? passed / own.length : null\n const meanScore = own.length\n ? Math.round((own.reduce((sum, score) => sum + score.score, 0) / own.length) * 10_000) / 10_000\n : null\n const floor = AI_EVAL_FLOORS[kind]\n return {\n kind,\n candidates: own.length,\n passed,\n passRate,\n meanScore,\n floor,\n belowFloor:\n passRate === null ||\n meanScore === null ||\n passRate < floor.passRate ||\n meanScore < floor.meanScore,\n }\n })\n}\n\n/** How the plans a planned kind's answers carry score, across every brief. */\nexport interface AiEvalPlanSummary {\n plans: number\n passed: number\n passRate: number | null\n}\n\n/**\n * The plan step's own score: every answer that carried a plan checked\n * against its brief's expected shape, whole answers and plan answers alike.\n */\nexport function summarizeAiEvalPlans(scores: readonly AiEvalScore[]): AiEvalPlanSummary {\n const plans = scores.filter((score) => score.checks.plan !== null)\n const passed = plans.filter((score) => score.checks.plan && score.checks.rubric).length\n return { plans: plans.length, passed, passRate: plans.length ? passed / plans.length : null }\n}\n\n/** A recording a live run wrote: the brief it answers, and the answer. */\nexport interface AiEvalRecording {\n caseId: string\n candidate: AiEvalCandidate\n}\n\n/** A recording file read and checked for shape; throws naming the field at fault. */\nexport function readAiEvalRecording(raw: unknown, file: string): AiEvalRecording {\n if (!isRecord(raw) || typeof raw['caseId'] !== 'string' || !isRecord(raw['candidate'])) {\n throw new Error(`${file}: a recording holds a caseId and a candidate`)\n }\n const candidate = raw['candidate'] as Record<string, unknown>\n // `null` says the grader failed and this answer was kept ungraded\n // (AGL-3143); a missing key is a recording written by something that does\n // not know what a grade is.\n if (candidate['source'] !== 'recorded' || !(isRecord(candidate['rubric']) || candidate['rubric'] === null)) {\n throw new Error(`${file}: a recording's candidate is recorded, and graded or explicitly ungraded`)\n }\n return raw as unknown as AiEvalRecording\n}\n\n// ── Reading a case file ───────────────────────────────────────────────────\n\n/** A case file read and checked for shape; throws naming the field at fault. */\nexport function readAiEvalCase(raw: unknown, file: string): AiEvalCase {\n const fail = (why: string): never => {\n throw new Error(`${file}: ${why}`)\n }\n if (!isRecord(raw)) return fail('not an object')\n const kind = raw['kind']\n if (typeof raw['id'] !== 'string' || !raw['id']) fail('no id')\n if (typeof kind !== 'string' || !(AI_EVAL_KINDS as readonly string[]).includes(kind)) {\n fail(`kind \"${String(kind)}\" is not one of ${AI_EVAL_KINDS.join(', ')}`)\n }\n if (typeof raw['brief'] !== 'string' || !raw['brief'].trim()) fail('no brief')\n if (raw['siteName'] !== undefined && (typeof raw['siteName'] !== 'string' || !raw['siteName'].trim())) {\n fail('siteName, where given, is the site’s name')\n }\n const automation = raw['automation']\n if (automation !== undefined) {\n const action = isRecord(automation) ? automation['action'] : undefined\n const problem = isRecord(action) ? validateStoredInteraction(action as unknown as AiAutomation) : 'it holds no action'\n if (problem) fail(`automation.action is not an action the Actions editor would save: ${problem}`)\n if (isRecord(automation) && automation['run'] !== undefined && !isRecord(automation['run'])) {\n fail('automation.run, where given, is what the run history recorded')\n }\n }\n const media = raw['media']\n if (media !== undefined) {\n if (!isRecord(media) || !Object.keys(media).length) fail('media, where given, names at least one asset')\n for (const [mediaId, file] of Object.entries(media as Record<string, unknown>)) {\n if (typeof file !== 'string' || !AI_EVAL_MEDIA_FILE.test(file)) {\n fail(`media.${mediaId} is not a picture's path under tools/ai-eval/fixtures`)\n }\n }\n }\n const candidates = raw['candidates']\n const controls = raw['controls']\n if (!Array.isArray(candidates) || !candidates.length) fail('no candidates')\n if (!Array.isArray(controls) || !controls.length) fail('no controls: every case proves it can fail')\n for (const [index, candidate] of (candidates as unknown[]).entries()) {\n if (!isRecord(candidate)) fail(`candidates[${index}] is not an object`)\n const source = (candidate as Record<string, unknown>)['source']\n if (source !== 'authored' && source !== 'recorded') {\n fail(`candidates[${index}].source is neither authored nor recorded`)\n }\n if (!isRecord((candidate as Record<string, unknown>)['rubric'])) {\n fail(`candidates[${index}] has no rubric`)\n }\n }\n for (const [index, control] of (controls as unknown[]).entries()) {\n const fails = isRecord(control) ? control['fails'] : undefined\n if (!Array.isArray(fails) || !fails.length) fail(`controls[${index}] names no check it fails`)\n }\n const templateSubject = raw['templateSubject']\n if (\n templateSubject !== undefined &&\n (raw['kind'] !== 'template' ||\n typeof templateSubject !== 'string' ||\n !(templateSubject in AI_TEMPLATE_SUBJECT_DEFINITIONS))\n ) {\n fail(`templateSubject, where given, is one of ${Object.keys(AI_TEMPLATE_SUBJECT_DEFINITIONS).join(', ')} on a template case`)\n }\n const capabilities =\n raw['capabilities'] === undefined ? undefined : readAiEvalCapabilities(raw['capabilities'], fail)\n return {\n framing: null,\n inventory: null,\n ...(raw as object),\n ...(capabilities ? { capabilities } : {}),\n } as AiEvalCase\n}\n\n/**\n * A case's capabilities read and checked for shape. A creation kind the case\n * leaves out may be created, so a case names only what its workspace lacks;\n * a Free workspace's case says so with `freeTaste`, which holds its plan to\n * the sections the Free wall pays for (AGL-3070).\n */\nfunction readAiEvalCapabilities(raw: unknown, fail: (why: string) => never): AiPlanCapabilities {\n if (!isRecord(raw) || typeof raw['reusableComponents'] !== 'boolean') {\n return fail('capabilities.reusableComponents is not true or false')\n }\n const create = isRecord(raw['create']) ? raw['create'] : {}\n const unrestricted = aiUnrestrictedPlanCapabilities()\n const entries: Array<[AiBuildPlanCreateKind, AiPlanCreation]> = AI_BUILD_PLAN_CREATE_KINDS.map((kind) => {\n const entry = create[kind]\n if (entry === undefined) return [kind, unrestricted.create[kind]]\n if (!isRecord(entry) || typeof entry['allowed'] !== 'boolean') {\n return fail(`capabilities.create.${kind}.allowed is not true or false`)\n }\n const left = entry['left']\n const reason = entry['reason']\n return [\n kind,\n {\n allowed: entry['allowed'],\n left: typeof left === 'number' ? left : null,\n reason: typeof reason === 'string' ? reason : null,\n },\n ]\n })\n for (const kind of Object.keys(create)) {\n if (!(AI_BUILD_PLAN_CREATE_KINDS as readonly string[]).includes(kind)) {\n fail(`capabilities.create.${kind} is not a creation kind`)\n }\n }\n if (raw['freeTaste'] !== undefined && typeof raw['freeTaste'] !== 'boolean') {\n return fail('capabilities.freeTaste is not true or false')\n }\n return {\n reusableComponents: raw['reusableComponents'],\n create: Object.fromEntries(entries) as AiPlanCapabilities['create'],\n ...(raw['freeTaste'] === true ? { freeTaste: true } : {}),\n }\n}\n"],"names":["validateStoredInteraction","aiAutomationDraft","emptyAiAutomationRecords","AI_BUILD_PLAN_CREATE_KINDS","aiUnrestrictedPlanCapabilities","AI_EXPERIMENT_BODY_MAX_CHARS","AI_EXPERIMENT_HEADLINE_MAX_CHARS","AI_EXPERIMENT_LINE_MAX_CHARS","AI_EXPERIMENT_MAX_POINTS","AI_EXPERIMENT_NAME_MAX_CHARS","AI_EXPERIMENT_NEXT_MAX_CHARS","AI_EXPERIMENT_POINT_MAX_CHARS","AI_EXPERIMENT_RATIONALE_MAX_CHARS","aiExperimentVariantFields","checkAiExperimentExplanation","checkAiExperimentVariants","readAiExperimentResult","parseAiExperimentExplanation","parseAiExperimentVariants","aiComponentCheck","aiPlanTemplateTokenViolations","aiTemplateBindingCheck","AI_TEMPLATE_SUBJECT_DEFINITIONS","aiTemplateAddressTokens","aiProductMerchantWords","checkAiCatalog","checkAiCategories","checkAiProductCopy","aiCrmEmailMergeFields","aiCrmImportFields","aiCrmRecordCheckContext","checkAiCrmEmail","checkAiCrmMapping","checkAiCrmRecord","parseAiThemeToolInput","AI_AUTOMATION_OVERSIZE_CODES","AI_AUTOMATION_UNREADABLE_CODES","readAiAutomationAnswer","readAiWorkflowExplanation","parseAiInsightAnswer","checkAiInsightAnswer","aiDeviceAuditFindings","aiAnswerTree","aiDoctrinePlanCheck","aiDoctrineTreeCheck","aiDoctrineTreeContext","AI_SEO_DESCRIPTION_MAX","AI_SEO_TITLE_MAX","aiPlanEmbedBriefViolations","detectOffVoiceCopy","detectPlaceholderCopy","detectPublishIntent","AI_TEXT_LIMITS","expandAiRepeatedItems","checkAiLogicFunction","checkAiLogicVariable","aiEditJobOutline","ASSIST_EDIT_MAX_INSERT_NODES","ASSIST_EDIT_MAX_OPS","checkAssistEditAnswer","parseAssistEditContext","AI_EVAL_KINDS","AI_EVAL_TREE_OUTPUT","page","template","component","layout","form","email","section","aiEvalRendersAtDeviceWidths","kind","output","undefined","AI_EVAL_SITE_ID","AI_EVAL_AUTOMATION_CAPABILITIES","crm","webhooks","bookings","AI_EVAL_MEDIA_FILE","AI_EVAL_FLOORS","passRate","meanScore","seo","product","catalog","categories","theme","element","blog","text","chat","workflow","insight","experiment","logic","edit","AI_EVAL_RUBRIC_PASS_MEAN","AI_EVAL_BLOG_MAX_CHARS","AI_EVAL_TEXT_MAX_WORDS","AI_EVAL_CHAT_MAX_CHARS","isRecord","value","Array","isArray","codes","violations","map","violation","code","planSections","evalCase","plan","screens","sections","flatMap","readTree","outputKind","answer","inline","capabilities","reusableComponents","input","tree","declaresProps","subject","templateDefinition","check","inventory","assets","framing","definesComponent","length","pageSections","bindingTokens","drawn","noun","ok","undrawn","result","items","aiEvalAnswerTree","templateSubject","checkTree","readable","rules","budget","findings","templated","rootId","nodes","onProps","filter","rule","FENCE","PREAMBLE","QUOTED","MARKUP","words","trim","split","Boolean","checkCopy","limits","own","unreadable","test","broken","at","maxChars","maxWords","over","MARKDOWN_LINK","chatLinks","allowed","Set","docsUrls","matchAll","match","url","startsWith","has","checkBlog","checked","head","trimStart","extra","checkSeo","title","description","PRODUCTS_UNREADABLE","PRODUCTS_OVER_BUDGET","checkProducts","categoryIds","category","id","optionCount","facts","options","merchantWords","brief","existingCategoryNames","found","some","checkTheme","parse","changes","components","resetComponents","summary","dropped","reason","checkWorkflow","publish","read","lines","String","offVoice","index","includes","automationCapabilities","oversize","invalid","unsupported","automationRecords","action","checkInsight","parsed","insights","tables","finding","kept","CRM_UNREADABLE","CRM_OVER","checkCrm","context","record","task","columns","fields","mergeFields","path","key","samples","join","sample","checkLogic","site","variables","functions","editing","saved","name","EDIT_OVER_LIMIT","checkEdit","outline","whole","target","documentId","versionId","hostId","ops","op","Object","entries","props","nodeId","left","message","EXPERIMENT_RULE_FINDINGS","checkExperiment","variants","variant","rationale","field","proposal","reading","arms","explained","headline","points","point","next","checkAnswer","body","checkAiEvalPlan","shape","expected","pass","shapeFindings","reuse","entry","screen","slug","maxCreate","create","createKinds","briefFindings","clampGrade","Number","isFinite","Math","min","max","aiEvalRubricVerdict","rubric","grades","structure","copy","grade","mean","reduce","sum","checkWidths","audits","audit","scoreAiEvalCandidate","candidate","scope","widths","rubricScore","parts","score","round","part","documentPasses","caseId","source","model","checks","responsive","scoreAiEvalControl","control","candidates","summarizeAiEval","scores","passed","floor","belowFloor","summarizeAiEvalPlans","plans","readAiEvalRecording","raw","file","Error","readAiEvalCase","fail","why","automation","problem","media","keys","mediaId","controls","fails","readAiEvalCapabilities","unrestricted","fromEntries","freeTaste"],"mappings":"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"}
|
|
@@ -203,6 +203,11 @@ export type AiNodePatchResult = {
|
|
|
203
203
|
* value grammar. The one difference is `required`: a patch is merged over the
|
|
204
204
|
* props the element already has, so a required prop the patch does not name
|
|
205
205
|
* is not missing.
|
|
206
|
+
*
|
|
207
|
+
* Styles belong to every element, so an element the palette does not list —
|
|
208
|
+
* one a plugin added since, or a marketplace one — can still be restyled:
|
|
209
|
+
* `sx` is held to the same key set and grammar whatever the element is. Its
|
|
210
|
+
* props cannot, because the palette is what they are checked against.
|
|
206
211
|
*/
|
|
207
212
|
export declare function validateAiNodePatch(componentId: string, patch: {
|
|
208
213
|
props?: unknown;
|
|
@@ -672,13 +672,28 @@ export function validateAiNodeTree(input, surface, context) {
|
|
|
672
672
|
* value grammar. The one difference is `required`: a patch is merged over the
|
|
673
673
|
* props the element already has, so a required prop the patch does not name
|
|
674
674
|
* is not missing.
|
|
675
|
+
*
|
|
676
|
+
* Styles belong to every element, so an element the palette does not list —
|
|
677
|
+
* one a plugin added since, or a marketplace one — can still be restyled:
|
|
678
|
+
* `sx` is held to the same key set and grammar whatever the element is. Its
|
|
679
|
+
* props cannot, because the palette is what they are checked against.
|
|
675
680
|
*/ export function validateAiNodePatch(componentId, patch, context) {
|
|
676
681
|
const entry = AI_PALETTE[componentId];
|
|
677
682
|
if (!entry) {
|
|
683
|
+
const props = isRecord(patch.props) ? patch.props : {};
|
|
684
|
+
if (Object.keys(props).length || patch.sx === undefined) {
|
|
685
|
+
return {
|
|
686
|
+
ok: false,
|
|
687
|
+
code: 'component',
|
|
688
|
+
error: `Component "${componentId}" is not in the palette`
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
const repairs = [];
|
|
678
692
|
return {
|
|
679
|
-
ok:
|
|
680
|
-
|
|
681
|
-
|
|
693
|
+
ok: true,
|
|
694
|
+
props: {},
|
|
695
|
+
sx: sanitizeSx(componentId, patch.sx, repairs),
|
|
696
|
+
repairs
|
|
682
697
|
};
|
|
683
698
|
}
|
|
684
699
|
const repairs = [];
|