visual-ai-assertions 0.4.0 → 0.6.0
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/README.md +12 -11
- package/dist/index.cjs +179 -130
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -10
- package/dist/index.d.ts +13 -10
- package/dist/index.js +179 -129
- package/dist/index.js.map +1 -1
- package/package.json +20 -12
package/README.md
CHANGED
|
@@ -98,9 +98,8 @@ const ai = visualAI();
|
|
|
98
98
|
|
|
99
99
|
// Explicit configuration
|
|
100
100
|
const ai = visualAI({
|
|
101
|
-
provider: "anthropic", // optional — auto-inferred from model or API key
|
|
102
|
-
apiKey: "sk-...", // optional, defaults to provider env var
|
|
103
101
|
model: "claude-sonnet-4-6", // optional, sensible defaults per provider
|
|
102
|
+
apiKey: "sk-...", // optional, defaults to provider env var
|
|
104
103
|
debug: true, // optional, logs prompts/responses to stderr
|
|
105
104
|
maxTokens: 4096, // optional, default 4096
|
|
106
105
|
reasoningEffort: "high", // optional, "low" | "medium" | "high" | "xhigh"
|
|
@@ -109,7 +108,6 @@ const ai = visualAI({
|
|
|
109
108
|
|
|
110
109
|
// Use constants for IDE autocomplete
|
|
111
110
|
const ai = visualAI({
|
|
112
|
-
provider: Provider.ANTHROPIC,
|
|
113
111
|
model: Model.Anthropic.SONNET_4_6,
|
|
114
112
|
});
|
|
115
113
|
```
|
|
@@ -389,21 +387,24 @@ The `VisualAIKnownError` union and `isVisualAIKnownError()` helper are useful wh
|
|
|
389
387
|
|
|
390
388
|
### Optional Configuration
|
|
391
389
|
|
|
392
|
-
| Variable
|
|
393
|
-
|
|
|
394
|
-
| `
|
|
395
|
-
| `
|
|
396
|
-
| `
|
|
397
|
-
| `
|
|
390
|
+
| Variable | Description |
|
|
391
|
+
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
392
|
+
| `VISUAL_AI_MODEL` | Default model when `model` is not set in config. Overrides the provider's default model. |
|
|
393
|
+
| `VISUAL_AI_DEBUG` | Enable error diagnostic logging to stderr. Does **not** enable prompt/response logging. Use `"true"` or `"1"`. |
|
|
394
|
+
| `VISUAL_AI_DEBUG_PROMPT` | Enable prompt-only debug logging to stderr. Use `"true"` or `"1"`. |
|
|
395
|
+
| `VISUAL_AI_DEBUG_RESPONSE` | Enable response-only debug logging to stderr. Use `"true"` or `"1"`. |
|
|
396
|
+
| `VISUAL_AI_REASONING_EFFORT` | Default reasoning effort when `reasoningEffort` is not set in config. Use `"low"`, `"medium"`, `"high"`, or `"xhigh"`. |
|
|
397
|
+
| `VISUAL_AI_TRACK_USAGE` | Enable usage tracking (token counts and cost) to stderr. Use `"true"` or `"1"`. |
|
|
398
398
|
|
|
399
399
|
## Configuration
|
|
400
400
|
|
|
401
401
|
| Option | Type | Default | Description |
|
|
402
402
|
| ----------------- | ------- | ---------------- | ----------------------------------------------------------------------------- |
|
|
403
|
-
| `provider` | string | auto-inferred | `"anthropic"` `"openai"` `"google"` — inferred from model name or API key |
|
|
404
403
|
| `apiKey` | string | env var | API key for the provider |
|
|
405
404
|
| `model` | string | provider default | Model to use |
|
|
406
|
-
| `debug` | boolean | `false` |
|
|
405
|
+
| `debug` | boolean | `false` | Enable error diagnostic logging to stderr |
|
|
406
|
+
| `debugPrompt` | boolean | `false` | Log prompts to stderr |
|
|
407
|
+
| `debugResponse` | boolean | `false` | Log responses to stderr |
|
|
407
408
|
| `maxTokens` | number | `4096` | Max tokens for AI response |
|
|
408
409
|
| `reasoningEffort` | string | `undefined` | `"low"` `"medium"` `"high"` `"xhigh"` — controls how deeply the model reasons |
|
|
409
410
|
| `trackUsage` | boolean | `false` | Log token usage and estimated cost to stderr |
|
package/dist/index.cjs
CHANGED
|
@@ -46,7 +46,6 @@ __export(index_exports, {
|
|
|
46
46
|
Provider: () => Provider,
|
|
47
47
|
StatementResultSchema: () => StatementResultSchema,
|
|
48
48
|
UsageInfoSchema: () => UsageInfoSchema,
|
|
49
|
-
VALID_PROVIDERS: () => VALID_PROVIDERS,
|
|
50
49
|
VisualAIAssertionError: () => VisualAIAssertionError,
|
|
51
50
|
VisualAIAuthError: () => VisualAIAuthError,
|
|
52
51
|
VisualAIConfigError: () => VisualAIConfigError,
|
|
@@ -79,6 +78,8 @@ var Model = {
|
|
|
79
78
|
OpenAI: {
|
|
80
79
|
GPT_5_4: "gpt-5.4",
|
|
81
80
|
GPT_5_4_PRO: "gpt-5.4-pro",
|
|
81
|
+
GPT_5_4_MINI: "gpt-5.4-mini",
|
|
82
|
+
GPT_5_4_NANO: "gpt-5.4-nano",
|
|
82
83
|
GPT_5_2: "gpt-5.2",
|
|
83
84
|
GPT_5_MINI: "gpt-5-mini"
|
|
84
85
|
},
|
|
@@ -89,7 +90,7 @@ var Model = {
|
|
|
89
90
|
};
|
|
90
91
|
var DEFAULT_MODELS = {
|
|
91
92
|
[Provider.ANTHROPIC]: Model.Anthropic.SONNET_4_6,
|
|
92
|
-
[Provider.OPENAI]: Model.OpenAI.
|
|
93
|
+
[Provider.OPENAI]: Model.OpenAI.GPT_5_4_MINI,
|
|
93
94
|
[Provider.GOOGLE]: Model.Google.GEMINI_3_FLASH_PREVIEW
|
|
94
95
|
};
|
|
95
96
|
var DEFAULT_MAX_TOKENS = 4096;
|
|
@@ -99,6 +100,11 @@ var MODEL_TO_PROVIDER = new Map([
|
|
|
99
100
|
...Object.values(Model.Google).map((m) => [m, Provider.GOOGLE])
|
|
100
101
|
]);
|
|
101
102
|
var VALID_PROVIDERS = Object.values(Provider);
|
|
103
|
+
var PROVIDER_DEFAULT_REASONING = {
|
|
104
|
+
openai: "medium",
|
|
105
|
+
anthropic: "off",
|
|
106
|
+
google: "off"
|
|
107
|
+
};
|
|
102
108
|
var Content = {
|
|
103
109
|
/** Detects Lorem ipsum, TODO, TBD, and similar placeholder text */
|
|
104
110
|
PLACEHOLDER_TEXT: "placeholder-text",
|
|
@@ -726,23 +732,6 @@ function inferProviderFromModel(model) {
|
|
|
726
732
|
return prefixMatch?.[1];
|
|
727
733
|
}
|
|
728
734
|
function resolveProvider(config) {
|
|
729
|
-
if (config.provider) {
|
|
730
|
-
if (!VALID_PROVIDERS.includes(config.provider)) {
|
|
731
|
-
throw new VisualAIConfigError(
|
|
732
|
-
`Unknown provider: "${config.provider}". Supported: ${VALID_PROVIDERS.join(", ")}`
|
|
733
|
-
);
|
|
734
|
-
}
|
|
735
|
-
return config.provider;
|
|
736
|
-
}
|
|
737
|
-
const envProvider = process.env.VISUAL_AI_PROVIDER;
|
|
738
|
-
if (envProvider) {
|
|
739
|
-
if (VALID_PROVIDERS.includes(envProvider)) {
|
|
740
|
-
return envProvider;
|
|
741
|
-
}
|
|
742
|
-
throw new VisualAIConfigError(
|
|
743
|
-
`Invalid VISUAL_AI_PROVIDER: "${envProvider}". Supported: ${VALID_PROVIDERS.join(", ")}`
|
|
744
|
-
);
|
|
745
|
-
}
|
|
746
735
|
const model = config.model ?? process.env.VISUAL_AI_MODEL;
|
|
747
736
|
if (model) {
|
|
748
737
|
const inferred = inferProviderFromModel(model);
|
|
@@ -756,7 +745,7 @@ function resolveProvider(config) {
|
|
|
756
745
|
const detected = apiKeyProviderMap.find(([key]) => process.env[key]);
|
|
757
746
|
if (detected) return detected[1];
|
|
758
747
|
throw new VisualAIConfigError(
|
|
759
|
-
"
|
|
748
|
+
"Cannot determine provider. Set a model name (config or VISUAL_AI_MODEL) or an API key env variable (ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY)."
|
|
760
749
|
);
|
|
761
750
|
}
|
|
762
751
|
function parseBooleanEnv(envName, value) {
|
|
@@ -768,13 +757,27 @@ function parseBooleanEnv(envName, value) {
|
|
|
768
757
|
`Invalid ${envName} value: "${value}". Use "true", "1", "false", or "0".`
|
|
769
758
|
);
|
|
770
759
|
}
|
|
760
|
+
var VALID_REASONING_EFFORTS = ["low", "medium", "high", "xhigh"];
|
|
761
|
+
function parseReasoningEffortEnv(envName, value) {
|
|
762
|
+
if (value === void 0 || value === "") return void 0;
|
|
763
|
+
const lower = value.toLowerCase();
|
|
764
|
+
if (VALID_REASONING_EFFORTS.includes(lower)) return lower;
|
|
765
|
+
throw new VisualAIConfigError(
|
|
766
|
+
`Invalid ${envName} value: "${value}". Use "low", "medium", "high", or "xhigh".`
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
var debugDeprecationWarned = false;
|
|
771
770
|
function resolveConfig(config) {
|
|
772
771
|
const provider = resolveProvider(config);
|
|
773
772
|
const model = config.model ?? process.env.VISUAL_AI_MODEL ?? DEFAULT_MODELS[provider];
|
|
774
|
-
const
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
773
|
+
const debug = config.debug ?? parseBooleanEnv("VISUAL_AI_DEBUG", process.env.VISUAL_AI_DEBUG) ?? false;
|
|
774
|
+
const debugPrompt = config.debugPrompt ?? parseBooleanEnv("VISUAL_AI_DEBUG_PROMPT", process.env.VISUAL_AI_DEBUG_PROMPT) ?? false;
|
|
775
|
+
const debugResponse = config.debugResponse ?? parseBooleanEnv("VISUAL_AI_DEBUG_RESPONSE", process.env.VISUAL_AI_DEBUG_RESPONSE) ?? false;
|
|
776
|
+
if (debug && !debugPrompt && !debugResponse && !debugDeprecationWarned) {
|
|
777
|
+
debugDeprecationWarned = true;
|
|
778
|
+
process.stderr.write(
|
|
779
|
+
`[visual-ai-assertions] Warning: VISUAL_AI_DEBUG no longer enables prompt/response logging. Use VISUAL_AI_DEBUG_PROMPT=true and/or VISUAL_AI_DEBUG_RESPONSE=true instead.
|
|
780
|
+
`
|
|
778
781
|
);
|
|
779
782
|
}
|
|
780
783
|
return {
|
|
@@ -782,8 +785,10 @@ function resolveConfig(config) {
|
|
|
782
785
|
apiKey: config.apiKey,
|
|
783
786
|
model,
|
|
784
787
|
maxTokens: config.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
785
|
-
reasoningEffort: config.reasoningEffort,
|
|
786
|
-
debug
|
|
788
|
+
reasoningEffort: config.reasoningEffort ?? parseReasoningEffortEnv("VISUAL_AI_REASONING_EFFORT", process.env.VISUAL_AI_REASONING_EFFORT),
|
|
789
|
+
debug,
|
|
790
|
+
debugPrompt,
|
|
791
|
+
debugResponse,
|
|
787
792
|
trackUsage: config.trackUsage ?? parseBooleanEnv("VISUAL_AI_TRACK_USAGE", process.env.VISUAL_AI_TRACK_USAGE) ?? false
|
|
788
793
|
};
|
|
789
794
|
}
|
|
@@ -815,6 +820,14 @@ var PRICING_TABLE = {
|
|
|
815
820
|
inputPricePerToken: 1.75 / PER_MILLION,
|
|
816
821
|
outputPricePerToken: 14 / PER_MILLION
|
|
817
822
|
},
|
|
823
|
+
[`${Provider.OPENAI}:${Model.OpenAI.GPT_5_4_MINI}`]: {
|
|
824
|
+
inputPricePerToken: 0.75 / PER_MILLION,
|
|
825
|
+
outputPricePerToken: 4.5 / PER_MILLION
|
|
826
|
+
},
|
|
827
|
+
[`${Provider.OPENAI}:${Model.OpenAI.GPT_5_4_NANO}`]: {
|
|
828
|
+
inputPricePerToken: 0.2 / PER_MILLION,
|
|
829
|
+
outputPricePerToken: 1.25 / PER_MILLION
|
|
830
|
+
},
|
|
818
831
|
[`${Provider.OPENAI}:${Model.OpenAI.GPT_5_MINI}`]: {
|
|
819
832
|
inputPricePerToken: 0.25 / PER_MILLION,
|
|
820
833
|
outputPricePerToken: 2 / PER_MILLION
|
|
@@ -836,8 +849,9 @@ function calculateCost(provider, model, inputTokens, outputTokens) {
|
|
|
836
849
|
}
|
|
837
850
|
|
|
838
851
|
// src/core/debug.ts
|
|
839
|
-
function debugLog(config, label, data) {
|
|
840
|
-
|
|
852
|
+
function debugLog(config, label, data, kind = "error") {
|
|
853
|
+
const enabled = kind === "prompt" ? config.debugPrompt : kind === "response" ? config.debugResponse : config.debug;
|
|
854
|
+
if (enabled) {
|
|
841
855
|
process.stderr.write(`[visual-ai-assertions] ${label}: ${data}
|
|
842
856
|
`);
|
|
843
857
|
}
|
|
@@ -845,8 +859,9 @@ function debugLog(config, label, data) {
|
|
|
845
859
|
function usageLog(config, method, usage) {
|
|
846
860
|
if (!config.trackUsage) return;
|
|
847
861
|
const costStr = usage.estimatedCost !== void 0 ? `$${usage.estimatedCost.toFixed(6)}` : "unknown";
|
|
862
|
+
const reasoningStr = config.reasoningEffort ? `reasoning: ${config.reasoningEffort}` : `reasoning: ${PROVIDER_DEFAULT_REASONING[config.provider]} (provider default)`;
|
|
848
863
|
process.stderr.write(
|
|
849
|
-
`[visual-ai-assertions] ${method} usage: ${usage.inputTokens} input + ${usage.outputTokens} output tokens (${costStr}) in ${usage.durationSeconds?.toFixed(3) ?? "0.000"}s [${config.model}]
|
|
864
|
+
`[visual-ai-assertions] ${method} usage: ${usage.inputTokens} input + ${usage.outputTokens} output tokens (${costStr}) in ${usage.durationSeconds?.toFixed(3) ?? "0.000"}s [${config.model}, ${reasoningStr}]
|
|
850
865
|
`
|
|
851
866
|
);
|
|
852
867
|
}
|
|
@@ -862,6 +877,28 @@ function processUsage(method, rawUsage, durationSeconds, config) {
|
|
|
862
877
|
usageLog(config, method, usage);
|
|
863
878
|
return usage;
|
|
864
879
|
}
|
|
880
|
+
var MAX_RAW_RESPONSE_PREVIEW = 500;
|
|
881
|
+
function formatError(error) {
|
|
882
|
+
if (error instanceof VisualAIResponseParseError) {
|
|
883
|
+
const truncated = error.rawResponse.length > MAX_RAW_RESPONSE_PREVIEW ? error.rawResponse.slice(0, MAX_RAW_RESPONSE_PREVIEW) + "..." : error.rawResponse;
|
|
884
|
+
return `${error.name} (${error.code}): ${error.message}. Raw (truncated): ${truncated}`;
|
|
885
|
+
}
|
|
886
|
+
if (error instanceof VisualAIError) {
|
|
887
|
+
return `${error.name} (${error.code}): ${error.message}`;
|
|
888
|
+
}
|
|
889
|
+
if (error instanceof Error) {
|
|
890
|
+
return `${error.name}: ${error.message}`;
|
|
891
|
+
}
|
|
892
|
+
return String(error);
|
|
893
|
+
}
|
|
894
|
+
async function withErrorDebug(config, method, fn) {
|
|
895
|
+
try {
|
|
896
|
+
return await fn();
|
|
897
|
+
} catch (error) {
|
|
898
|
+
debugLog(config, `${method} error`, formatError(error), "error");
|
|
899
|
+
throw error;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
865
902
|
async function timedSendMessage(driver, images, prompt) {
|
|
866
903
|
const start = performance.now();
|
|
867
904
|
const response = await driver.sendMessage(images, prompt);
|
|
@@ -1190,16 +1227,18 @@ function visualAI(config = {}) {
|
|
|
1190
1227
|
if (elements.length === 0) {
|
|
1191
1228
|
throw new VisualAIConfigError(`At least one element is required for ${methodName}()`);
|
|
1192
1229
|
}
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1230
|
+
return withErrorDebug(resolvedConfig, methodName, async () => {
|
|
1231
|
+
const img = await normalizeImage(image);
|
|
1232
|
+
const prompt = buildElementsVisibilityPrompt(elements, visible, options);
|
|
1233
|
+
debugLog(resolvedConfig, `${methodName} prompt`, prompt, "prompt");
|
|
1234
|
+
const response = await timedSendMessage(driver, [img], prompt);
|
|
1235
|
+
debugLog(resolvedConfig, `${methodName} response`, response.text, "response");
|
|
1236
|
+
const result = parseCheckResponse(response.text);
|
|
1237
|
+
return {
|
|
1238
|
+
...result,
|
|
1239
|
+
usage: processUsage(methodName, response.usage, response.durationSeconds, resolvedConfig)
|
|
1240
|
+
};
|
|
1241
|
+
});
|
|
1203
1242
|
}
|
|
1204
1243
|
return {
|
|
1205
1244
|
async check(image, statements, options) {
|
|
@@ -1207,61 +1246,64 @@ function visualAI(config = {}) {
|
|
|
1207
1246
|
if (stmts.length === 0) {
|
|
1208
1247
|
throw new VisualAIConfigError("At least one statement is required for check()");
|
|
1209
1248
|
}
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1249
|
+
return withErrorDebug(resolvedConfig, "check", async () => {
|
|
1250
|
+
const img = await normalizeImage(image);
|
|
1251
|
+
const prompt = buildCheckPrompt(stmts, { instructions: options?.instructions });
|
|
1252
|
+
debugLog(resolvedConfig, "check prompt", prompt, "prompt");
|
|
1253
|
+
const response = await timedSendMessage(driver, [img], prompt);
|
|
1254
|
+
debugLog(resolvedConfig, "check response", response.text, "response");
|
|
1255
|
+
const result = parseCheckResponse(response.text);
|
|
1256
|
+
return {
|
|
1257
|
+
...result,
|
|
1258
|
+
usage: processUsage("check", response.usage, response.durationSeconds, resolvedConfig)
|
|
1259
|
+
};
|
|
1260
|
+
});
|
|
1220
1261
|
},
|
|
1221
1262
|
async ask(image, userPrompt, options) {
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1263
|
+
return withErrorDebug(resolvedConfig, "ask", async () => {
|
|
1264
|
+
const img = await normalizeImage(image);
|
|
1265
|
+
const prompt = buildAskPrompt(userPrompt, { instructions: options?.instructions });
|
|
1266
|
+
debugLog(resolvedConfig, "ask prompt", prompt, "prompt");
|
|
1267
|
+
const response = await timedSendMessage(driver, [img], prompt);
|
|
1268
|
+
debugLog(resolvedConfig, "ask response", response.text, "response");
|
|
1269
|
+
const result = parseAskResponse(response.text);
|
|
1270
|
+
return {
|
|
1271
|
+
...result,
|
|
1272
|
+
usage: processUsage("ask", response.usage, response.durationSeconds, resolvedConfig)
|
|
1273
|
+
};
|
|
1274
|
+
});
|
|
1232
1275
|
},
|
|
1233
1276
|
async compare(imageA, imageB, options) {
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
if (!resolvedConfig.debug) {
|
|
1277
|
+
return withErrorDebug(resolvedConfig, "compare", async () => {
|
|
1278
|
+
const [imgA, imgB] = await Promise.all([normalizeImage(imageA), normalizeImage(imageB)]);
|
|
1279
|
+
const prompt = buildComparePrompt({
|
|
1280
|
+
userPrompt: options?.prompt,
|
|
1281
|
+
instructions: options?.instructions
|
|
1282
|
+
});
|
|
1283
|
+
debugLog(resolvedConfig, "compare prompt", prompt, "prompt");
|
|
1284
|
+
const response = await timedSendMessage(driver, [imgA, imgB], prompt);
|
|
1285
|
+
debugLog(resolvedConfig, "compare response", response.text, "response");
|
|
1286
|
+
const supportsAnnotatedDiff = resolvedConfig.provider === "google" && resolvedConfig.model === Model.Google.GEMINI_3_FLASH_PREVIEW;
|
|
1287
|
+
const effectiveDiffImage = options?.diffImage ?? (supportsAnnotatedDiff ? true : false);
|
|
1288
|
+
let diffImage;
|
|
1289
|
+
if (effectiveDiffImage) {
|
|
1290
|
+
try {
|
|
1291
|
+
diffImage = await generateAiDiff(imgA, imgB, resolvedConfig.model, driver);
|
|
1292
|
+
} catch (err) {
|
|
1293
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1252
1294
|
process.stderr.write(
|
|
1253
1295
|
`[visual-ai-assertions] warning: diff generation failed: ${msg}
|
|
1254
1296
|
`
|
|
1255
1297
|
);
|
|
1256
1298
|
}
|
|
1257
1299
|
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
};
|
|
1300
|
+
const result = parseCompareResponse(response.text);
|
|
1301
|
+
return {
|
|
1302
|
+
...result,
|
|
1303
|
+
...diffImage ? { diffImage } : {},
|
|
1304
|
+
usage: processUsage("compare", response.usage, response.durationSeconds, resolvedConfig)
|
|
1305
|
+
};
|
|
1306
|
+
});
|
|
1265
1307
|
},
|
|
1266
1308
|
elementsVisible(image, elements, options) {
|
|
1267
1309
|
return checkElementsVisibility(image, elements, true, options);
|
|
@@ -1270,57 +1312,65 @@ function visualAI(config = {}) {
|
|
|
1270
1312
|
return checkElementsVisibility(image, elements, false, options);
|
|
1271
1313
|
},
|
|
1272
1314
|
async accessibility(image, options) {
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1315
|
+
return withErrorDebug(resolvedConfig, "accessibility", async () => {
|
|
1316
|
+
const img = await normalizeImage(image);
|
|
1317
|
+
const prompt = buildAccessibilityPrompt(options);
|
|
1318
|
+
debugLog(resolvedConfig, "accessibility prompt", prompt, "prompt");
|
|
1319
|
+
const response = await timedSendMessage(driver, [img], prompt);
|
|
1320
|
+
debugLog(resolvedConfig, "accessibility response", response.text, "response");
|
|
1321
|
+
const result = parseCheckResponse(response.text);
|
|
1322
|
+
return {
|
|
1323
|
+
...result,
|
|
1324
|
+
usage: processUsage(
|
|
1325
|
+
"accessibility",
|
|
1326
|
+
response.usage,
|
|
1327
|
+
response.durationSeconds,
|
|
1328
|
+
resolvedConfig
|
|
1329
|
+
)
|
|
1330
|
+
};
|
|
1331
|
+
});
|
|
1288
1332
|
},
|
|
1289
1333
|
async layout(image, options) {
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1334
|
+
return withErrorDebug(resolvedConfig, "layout", async () => {
|
|
1335
|
+
const img = await normalizeImage(image);
|
|
1336
|
+
const prompt = buildLayoutPrompt(options);
|
|
1337
|
+
debugLog(resolvedConfig, "layout prompt", prompt, "prompt");
|
|
1338
|
+
const response = await timedSendMessage(driver, [img], prompt);
|
|
1339
|
+
debugLog(resolvedConfig, "layout response", response.text, "response");
|
|
1340
|
+
const result = parseCheckResponse(response.text);
|
|
1341
|
+
return {
|
|
1342
|
+
...result,
|
|
1343
|
+
usage: processUsage("layout", response.usage, response.durationSeconds, resolvedConfig)
|
|
1344
|
+
};
|
|
1345
|
+
});
|
|
1300
1346
|
},
|
|
1301
1347
|
async pageLoad(image, options) {
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1348
|
+
return withErrorDebug(resolvedConfig, "pageLoad", async () => {
|
|
1349
|
+
const img = await normalizeImage(image);
|
|
1350
|
+
const prompt = buildPageLoadPrompt(options);
|
|
1351
|
+
debugLog(resolvedConfig, "pageLoad prompt", prompt, "prompt");
|
|
1352
|
+
const response = await timedSendMessage(driver, [img], prompt);
|
|
1353
|
+
debugLog(resolvedConfig, "pageLoad response", response.text, "response");
|
|
1354
|
+
const result = parseCheckResponse(response.text);
|
|
1355
|
+
return {
|
|
1356
|
+
...result,
|
|
1357
|
+
usage: processUsage("pageLoad", response.usage, response.durationSeconds, resolvedConfig)
|
|
1358
|
+
};
|
|
1359
|
+
});
|
|
1312
1360
|
},
|
|
1313
1361
|
async content(image, options) {
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1362
|
+
return withErrorDebug(resolvedConfig, "content", async () => {
|
|
1363
|
+
const img = await normalizeImage(image);
|
|
1364
|
+
const prompt = buildContentPrompt(options);
|
|
1365
|
+
debugLog(resolvedConfig, "content prompt", prompt, "prompt");
|
|
1366
|
+
const response = await timedSendMessage(driver, [img], prompt);
|
|
1367
|
+
debugLog(resolvedConfig, "content response", response.text, "response");
|
|
1368
|
+
const result = parseCheckResponse(response.text);
|
|
1369
|
+
return {
|
|
1370
|
+
...result,
|
|
1371
|
+
usage: processUsage("content", response.usage, response.durationSeconds, resolvedConfig)
|
|
1372
|
+
};
|
|
1373
|
+
});
|
|
1324
1374
|
}
|
|
1325
1375
|
};
|
|
1326
1376
|
}
|
|
@@ -1397,7 +1447,6 @@ function assertVisualCompareResult(result, label) {
|
|
|
1397
1447
|
Provider,
|
|
1398
1448
|
StatementResultSchema,
|
|
1399
1449
|
UsageInfoSchema,
|
|
1400
|
-
VALID_PROVIDERS,
|
|
1401
1450
|
VisualAIAssertionError,
|
|
1402
1451
|
VisualAIAuthError,
|
|
1403
1452
|
VisualAIConfigError,
|