Skip to content

Decision

Extends Helper

Asserts statements about the current page with a decision model.

Decision models (like Jev or Clef) do not generate text. They read the page state and return the probability that a statement is true. A statement passes when its probability reaches the configured confidence.

I.decide('top level navigation is available');
I.decide([
'checkout form has all required fields',
'success message is shown',
'submit button enabled',
'cancel button present',
]);
I.decideVisually('sidebar is shown');

The model receives the page URL, title and ARIA snapshot. Helpers without ARIA snapshots (anything but Playwright) send minified HTML instead. decideVisually also sends a screenshot, so it requires a model with image input.

This helper must be enabled together with a web helper (Playwright, Puppeteer, WebDriver).

Decision model is created with the OpenRouter provider from @openrouter/ai-sdk-provider and configured in the ai.decisionModel section of the config:

import { createOpenRouter } from '@openrouter/ai-sdk-provider'
const openrouter = createOpenRouter({
apiKey: process.env.OPENROUTER_API_KEY,
})
export default {
ai: {
decisionModel: {
model: openrouter.evaluationModel('typesafe/jev-1.13'),
confidence: 0.8,
},
},
helpers: {
Playwright: { url: 'http://localhost' },
Decision: {},
},
}
  • model - decision model used by decide.
  • confidence (default: 0.7) - minimal probability, between 0 and 1, for a statement to pass.
  • timeout (default: 15000) - request timeout in ms.
  • maxLength (default: 12000) - maximal length of ARIA snapshot or HTML sent to the model.

decideVisually uses a separate decision model with image input, configured as visualModel:

decisionModel: {
model: openrouter.evaluationModel('typesafe/jev-1.13'),
visualModel: openrouter.evaluationModel('cloudflare/clef'),
},

The helper has one option:

  • mode (default: assert) - how decisions are executed:
    • assert - request the model and fail the step when a statement is not confirmed.
    • report - request the model but never fail, even on API errors. Results and errors are added to the step as a comment.
    • skip - do not request the model, every decision passes.
Decision: { mode: process.env.CI ? 'assert' : 'skip' }

Decisions work without the --ai flag. Browse all decision models at OpenRouter.

  • config

Asserts that a statement (or each of statements) is true for the current page. The decision model receives page URL, title and ARIA snapshot. Multiple statements are checked in a single request and all of them must pass.

I.decide('user is logged in');
I.decide(['submit button enabled', 'cancel button present']);
const probability = await I.decide('cart is empty');

Returns Promise<(number | Array<number> | undefined)> probability of each statement, undefined in skip mode.

Asserts that a statement (or each of statements) is true for the current page using a screenshot. The decision model receives page URL, title, ARIA snapshot and a screenshot. Requires visualModel with image input. Experimental.

I.decideVisually('sidebar is shown');
I.decideVisually(['logo is in the header', 'page uses dark theme']);

Returns Promise<(number | Array<number> | undefined)> probability of each statement, undefined in skip mode.