jest-fuzzy 0.1.2 → 0.1.4
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 +65 -5
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/matchers/index.d.ts +1 -0
- package/dist/cjs/matchers/index.d.ts.map +1 -1
- package/dist/cjs/matchers/index.js +3 -1
- package/dist/cjs/matchers/index.js.map +1 -1
- package/dist/cjs/matchers/toSemanticallyMatch.js +1 -1
- package/dist/cjs/matchers/toSemanticallyMatch.js.map +1 -1
- package/dist/cjs/matchers/toVisuallyMatch.d.ts +3 -0
- package/dist/cjs/matchers/toVisuallyMatch.d.ts.map +1 -0
- package/dist/cjs/matchers/toVisuallyMatch.js +62 -0
- package/dist/cjs/matchers/toVisuallyMatch.js.map +1 -0
- package/dist/cjs/providers/anthropic.d.ts +2 -1
- package/dist/cjs/providers/anthropic.d.ts.map +1 -1
- package/dist/cjs/providers/anthropic.js +46 -0
- package/dist/cjs/providers/anthropic.js.map +1 -1
- package/dist/cjs/providers/google.d.ts +2 -1
- package/dist/cjs/providers/google.d.ts.map +1 -1
- package/dist/cjs/providers/google.js +39 -0
- package/dist/cjs/providers/google.js.map +1 -1
- package/dist/cjs/providers/openai.d.ts +2 -1
- package/dist/cjs/providers/openai.d.ts.map +1 -1
- package/dist/cjs/providers/openai.js +46 -0
- package/dist/cjs/providers/openai.js.map +1 -1
- package/dist/cjs/types.d.ts +13 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/utils/imageUtils.d.ts +8 -0
- package/dist/cjs/utils/imageUtils.d.ts.map +1 -0
- package/dist/cjs/utils/imageUtils.js +172 -0
- package/dist/cjs/utils/imageUtils.js.map +1 -0
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/matchers/index.d.ts +1 -0
- package/dist/esm/matchers/index.d.ts.map +1 -1
- package/dist/esm/matchers/index.js +1 -0
- package/dist/esm/matchers/index.js.map +1 -1
- package/dist/esm/matchers/toSemanticallyMatch.js +1 -1
- package/dist/esm/matchers/toSemanticallyMatch.js.map +1 -1
- package/dist/esm/matchers/toVisuallyMatch.d.ts +3 -0
- package/dist/esm/matchers/toVisuallyMatch.d.ts.map +1 -0
- package/dist/esm/matchers/toVisuallyMatch.js +59 -0
- package/dist/esm/matchers/toVisuallyMatch.js.map +1 -0
- package/dist/esm/providers/anthropic.d.ts +2 -1
- package/dist/esm/providers/anthropic.d.ts.map +1 -1
- package/dist/esm/providers/anthropic.js +46 -0
- package/dist/esm/providers/anthropic.js.map +1 -1
- package/dist/esm/providers/google.d.ts +2 -1
- package/dist/esm/providers/google.d.ts.map +1 -1
- package/dist/esm/providers/google.js +39 -0
- package/dist/esm/providers/google.js.map +1 -1
- package/dist/esm/providers/openai.d.ts +2 -1
- package/dist/esm/providers/openai.d.ts.map +1 -1
- package/dist/esm/providers/openai.js +46 -0
- package/dist/esm/providers/openai.js.map +1 -1
- package/dist/esm/types.d.ts +13 -1
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/utils/imageUtils.d.ts +8 -0
- package/dist/esm/utils/imageUtils.d.ts.map +1 -0
- package/dist/esm/utils/imageUtils.js +131 -0
- package/dist/esm/utils/imageUtils.js.map +1 -0
- package/package.json +10 -1
package/README.md
CHANGED
|
@@ -122,7 +122,7 @@ await expect("Hello! How can I help you today?").toSemanticallyMatch(
|
|
|
122
122
|
| Option | Type | Default | Description |
|
|
123
123
|
| ----------- | ----------------------- | --------- | ------------------------------------------ |
|
|
124
124
|
| `threshold` | `"strict"` \| `"loose"` | `"loose"` | How strictly to judge semantic equivalence |
|
|
125
|
-
| `
|
|
125
|
+
| `additionalContext` | `string` | - | Additional context to help the LLM judge |
|
|
126
126
|
|
|
127
127
|
**Examples:**
|
|
128
128
|
|
|
@@ -137,9 +137,9 @@ await expect(response).toSemanticallyMatch("The capital of France is Paris", {
|
|
|
137
137
|
threshold: "strict",
|
|
138
138
|
});
|
|
139
139
|
|
|
140
|
-
// With context
|
|
140
|
+
// With additional context
|
|
141
141
|
await expect("Paris").toSemanticallyMatch("The capital of France", {
|
|
142
|
-
|
|
142
|
+
additionalContext: "Testing a geography Q&A bot asking about France's capital",
|
|
143
143
|
});
|
|
144
144
|
|
|
145
145
|
// Negation
|
|
@@ -176,6 +176,66 @@ await expect(response).not.toSatisfy(
|
|
|
176
176
|
);
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
+
### `toVisuallyMatch(description, options?)`
|
|
180
|
+
|
|
181
|
+
Tests whether an image matches the given description using vision-capable LLMs.
|
|
182
|
+
|
|
183
|
+
**Supported inputs:**
|
|
184
|
+
|
|
185
|
+
- File path: `"./images/button.png"`
|
|
186
|
+
- URL: `"https://example.com/image.jpg"`
|
|
187
|
+
- Base64 string: `"iVBORw0KGgo..."`
|
|
188
|
+
- Buffer: `fs.readFileSync("./image.png")`
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
await expect("./screenshot.png").toVisuallyMatch("a login form with email and password fields");
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Options:**
|
|
195
|
+
|
|
196
|
+
| Option | Type | Default | Description |
|
|
197
|
+
| ----------- | ---------------------------------------------------------- | --------- | -------------------------------------------- |
|
|
198
|
+
| `threshold` | `"strict"` \| `"loose"` | `"loose"` | How strictly to judge the visual match |
|
|
199
|
+
| `additionalContext` | `string` | - | Additional context to help the LLM judge |
|
|
200
|
+
| `mimeType` | `"image/jpeg"` \| `"image/png"` \| `"image/gif"` \| `"image/webp"` | auto | Override MIME type detection |
|
|
201
|
+
|
|
202
|
+
**Examples:**
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
import { readFileSync } from "fs";
|
|
206
|
+
|
|
207
|
+
// File path
|
|
208
|
+
await expect("./tests/screenshot.png").toVisuallyMatch("a blue button with white text");
|
|
209
|
+
|
|
210
|
+
// Buffer
|
|
211
|
+
const imageBuffer = readFileSync("./tests/chart.png");
|
|
212
|
+
await expect(imageBuffer).toVisuallyMatch("a bar chart showing sales data");
|
|
213
|
+
|
|
214
|
+
// With additional context
|
|
215
|
+
await expect("./tests/ui.png").toVisuallyMatch("shows an error state", {
|
|
216
|
+
additionalContext: "Testing error handling in a form validation component",
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// With strict threshold
|
|
220
|
+
await expect("./tests/error-dialog.png").toVisuallyMatch(
|
|
221
|
+
"a dialog box with a red error icon and a 'Retry' button",
|
|
222
|
+
{ threshold: "strict" }
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// Negation
|
|
226
|
+
await expect("./tests/dashboard.png").not.toVisuallyMatch("contains sensitive user data");
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Large Image Handling:**
|
|
230
|
+
|
|
231
|
+
Images larger than 4MB are automatically resized to fit within API limits. This requires the optional `sharp` dependency:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
npm install sharp
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
If `sharp` is not installed and an image exceeds the size limit, a helpful error message will guide you to install it.
|
|
238
|
+
|
|
179
239
|
## Configuration
|
|
180
240
|
|
|
181
241
|
### API Keys
|
|
@@ -245,11 +305,11 @@ pleasant weather conditions, while the second describes heavy rainfall.
|
|
|
245
305
|
await expect(response).toSatisfy("mentions the user's name 'John'");
|
|
246
306
|
```
|
|
247
307
|
|
|
248
|
-
2. **Provide context when the comparison needs domain knowledge:**
|
|
308
|
+
2. **Provide additional context when the comparison needs domain knowledge:**
|
|
249
309
|
|
|
250
310
|
```typescript
|
|
251
311
|
await expect("42").toSemanticallyMatch("The answer", {
|
|
252
|
-
|
|
312
|
+
additionalContext: "Testing a Hitchhiker's Guide to the Galaxy trivia bot",
|
|
253
313
|
});
|
|
254
314
|
```
|
|
255
315
|
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { configure, getConfig, getProvider } from "./config.js";
|
|
2
|
-
import type { JestFuzzyConfig, SemanticMatchOptions, ModelName, ApiKeys, LLMProvider } from "./types.js";
|
|
2
|
+
import type { JestFuzzyConfig, SemanticMatchOptions, VisualMatchOptions, ModelName, ApiKeys, LLMProvider } from "./types.js";
|
|
3
3
|
export { configure, getConfig, getProvider };
|
|
4
|
-
export type { JestFuzzyConfig, SemanticMatchOptions, ModelName, ApiKeys, LLMProvider, };
|
|
4
|
+
export type { JestFuzzyConfig, SemanticMatchOptions, VisualMatchOptions, ModelName, ApiKeys, LLMProvider, };
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAIhE,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,SAAS,EACT,OAAO,EACP,WAAW,EACZ,MAAM,YAAY,CAAC;AAWpB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;AAC7C,YAAY,EACV,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,SAAS,EACT,OAAO,EACP,WAAW,GACZ,CAAC"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -7,11 +7,13 @@ Object.defineProperty(exports, "getConfig", { enumerable: true, get: function ()
|
|
|
7
7
|
Object.defineProperty(exports, "getProvider", { enumerable: true, get: function () { return config_js_1.getProvider; } });
|
|
8
8
|
const toSemanticallyMatch_js_1 = require("./matchers/toSemanticallyMatch.js");
|
|
9
9
|
const toSatisfy_js_1 = require("./matchers/toSatisfy.js");
|
|
10
|
+
const toVisuallyMatch_js_1 = require("./matchers/toVisuallyMatch.js");
|
|
10
11
|
// Register matchers with Jest
|
|
11
12
|
if (typeof expect !== "undefined" && expect.extend) {
|
|
12
13
|
expect.extend({
|
|
13
14
|
toSemanticallyMatch: toSemanticallyMatch_js_1.toSemanticallyMatch,
|
|
14
15
|
toSatisfy: toSatisfy_js_1.toSatisfy,
|
|
16
|
+
toVisuallyMatch: toVisuallyMatch_js_1.toVisuallyMatch,
|
|
15
17
|
});
|
|
16
18
|
}
|
|
17
19
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,2CAAgE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,2CAAgE;AAsBvD,0FAtBA,qBAAS,OAsBA;AAAE,0FAtBA,qBAAS,OAsBA;AAAE,4FAtBA,uBAAW,OAsBA;AArB1C,8EAAwE;AACxE,0DAAoD;AACpD,sEAAgE;AAUhE,8BAA8B;AAC9B,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;IACnD,MAAM,CAAC,MAAM,CAAC;QACZ,mBAAmB,EAAnB,4CAAmB;QACnB,SAAS,EAAT,wBAAS;QACT,eAAe,EAAf,oCAAe;KAChB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/matchers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/matchers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toSatisfy = exports.toSemanticallyMatch = void 0;
|
|
3
|
+
exports.toVisuallyMatch = exports.toSatisfy = exports.toSemanticallyMatch = void 0;
|
|
4
4
|
var toSemanticallyMatch_js_1 = require("./toSemanticallyMatch.js");
|
|
5
5
|
Object.defineProperty(exports, "toSemanticallyMatch", { enumerable: true, get: function () { return toSemanticallyMatch_js_1.toSemanticallyMatch; } });
|
|
6
6
|
var toSatisfy_js_1 = require("./toSatisfy.js");
|
|
7
7
|
Object.defineProperty(exports, "toSatisfy", { enumerable: true, get: function () { return toSatisfy_js_1.toSatisfy; } });
|
|
8
|
+
var toVisuallyMatch_js_1 = require("./toVisuallyMatch.js");
|
|
9
|
+
Object.defineProperty(exports, "toVisuallyMatch", { enumerable: true, get: function () { return toVisuallyMatch_js_1.toVisuallyMatch; } });
|
|
8
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/matchers/index.ts"],"names":[],"mappings":";;;AAAA,mEAA+D;AAAtD,6HAAA,mBAAmB,OAAA;AAC5B,+CAA2C;AAAlC,yGAAA,SAAS,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/matchers/index.ts"],"names":[],"mappings":";;;AAAA,mEAA+D;AAAtD,6HAAA,mBAAmB,OAAA;AAC5B,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAClB,2DAAuD;AAA9C,qHAAA,eAAe,OAAA"}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.toSemanticallyMatch = toSemanticallyMatch;
|
|
4
4
|
const config_js_1 = require("../config.js");
|
|
5
5
|
function buildPrompt(received, expected, options) {
|
|
6
|
-
const contextLine = options.
|
|
6
|
+
const contextLine = options.additionalContext ? `Additional Context: ${options.additionalContext}\n` : "";
|
|
7
7
|
const threshold = options.threshold ?? "loose";
|
|
8
8
|
return `Do these two texts have the same semantic meaning?
|
|
9
9
|
${contextLine}Strictness: ${threshold}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toSemanticallyMatch.js","sourceRoot":"","sources":["../../../src/matchers/toSemanticallyMatch.ts"],"names":[],"mappings":";;AAoBA,kDAqCC;AAxDD,4CAA2C;AAE3C,SAAS,WAAW,CAClB,QAAgB,EAChB,QAAgB,EAChB,OAA6B;IAE7B,MAAM,WAAW,GAAG,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"toSemanticallyMatch.js","sourceRoot":"","sources":["../../../src/matchers/toSemanticallyMatch.ts"],"names":[],"mappings":";;AAoBA,kDAqCC;AAxDD,4CAA2C;AAE3C,SAAS,WAAW,CAClB,QAAgB,EAChB,QAAgB,EAChB,OAA6B;IAE7B,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,uBAAuB,OAAO,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1G,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC;IAE/C,OAAO;EACP,WAAW,eAAe,SAAS;;WAE1B,QAAQ;WACR,QAAQ;;6EAE0D,CAAC;AAC9E,CAAC;AAEM,KAAK,UAAU,mBAAmB,CAEvC,QAAiB,EACjB,QAAgB,EAChB,UAAgC,EAAE;IAElC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO;YACL,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,GAAG,EAAE,CACZ,kCAAkC,OAAO,QAAQ,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE;SACnF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,IAAA,uBAAW,GAAE,CAAC;IACrC,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAExD,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE9D,OAAO;YACL,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,GAAG,EAAE;gBACZ,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,aAAa,QAAQ,gCAAgC,QAAQ,uBAAuB,WAAW,EAAE,CAAC;gBAC3G,CAAC;qBAAM,CAAC;oBACN,OAAO,aAAa,QAAQ,4BAA4B,QAAQ,uBAAuB,WAAW,EAAE,CAAC;gBACvG,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,GAAG,EAAE,CACZ,sCAAsC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SACjG,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { VisualMatchOptions, MatcherResult } from "../types.js";
|
|
2
|
+
export declare function toVisuallyMatch(this: jest.MatcherContext, received: unknown, description: string, options?: VisualMatchOptions): Promise<MatcherResult>;
|
|
3
|
+
//# sourceMappingURL=toVisuallyMatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toVisuallyMatch.d.ts","sourceRoot":"","sources":["../../../src/matchers/toVisuallyMatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAa,MAAM,aAAa,CAAC;AAiBhF,wBAAsB,eAAe,CACnC,IAAI,EAAE,IAAI,CAAC,cAAc,EACzB,QAAQ,EAAE,OAAO,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,aAAa,CAAC,CAkDxB"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toVisuallyMatch = toVisuallyMatch;
|
|
4
|
+
const config_js_1 = require("../config.js");
|
|
5
|
+
const imageUtils_js_1 = require("../utils/imageUtils.js");
|
|
6
|
+
function buildPrompt(description, options) {
|
|
7
|
+
const contextLine = options.additionalContext ? `Additional Context: ${options.additionalContext}\n` : "";
|
|
8
|
+
const threshold = options.threshold ?? "loose";
|
|
9
|
+
return `Does this image match the following description?
|
|
10
|
+
|
|
11
|
+
Description: "${description}"
|
|
12
|
+
|
|
13
|
+
${contextLine}Strictness: ${threshold}
|
|
14
|
+
|
|
15
|
+
Return verdict=true if the image matches the description, false otherwise.`;
|
|
16
|
+
}
|
|
17
|
+
async function toVisuallyMatch(received, description, options = {}) {
|
|
18
|
+
if (typeof received !== "string" && !Buffer.isBuffer(received)) {
|
|
19
|
+
return {
|
|
20
|
+
pass: false,
|
|
21
|
+
message: () => `Expected a string (file path, URL, or base64) or Buffer but received ${typeof received}`,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
let imageData;
|
|
25
|
+
try {
|
|
26
|
+
imageData = await (0, imageUtils_js_1.normalizeImageInput)(received, options.mimeType);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
return {
|
|
30
|
+
pass: false,
|
|
31
|
+
message: () => `Failed to process image: ${error instanceof Error ? error.message : String(error)}`,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const provider = await (0, config_js_1.getProvider)();
|
|
35
|
+
const prompt = buildPrompt(description, options);
|
|
36
|
+
try {
|
|
37
|
+
const { verdict, explanation } = await provider.judgeImage(imageData, prompt);
|
|
38
|
+
return {
|
|
39
|
+
pass: verdict,
|
|
40
|
+
message: () => {
|
|
41
|
+
const inputDesc = typeof received === "string"
|
|
42
|
+
? received.length > 50
|
|
43
|
+
? `${received.slice(0, 50)}...`
|
|
44
|
+
: received
|
|
45
|
+
: "[Buffer]";
|
|
46
|
+
if (verdict) {
|
|
47
|
+
return `Expected image (${inputDesc}) NOT to visually match "${description}"\n\nLLM reasoning: ${explanation}`;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
return `Expected image (${inputDesc}) to visually match "${description}"\n\nLLM reasoning: ${explanation}`;
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
return {
|
|
57
|
+
pass: false,
|
|
58
|
+
message: () => `Failed to evaluate visual match: ${error instanceof Error ? error.message : String(error)}`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=toVisuallyMatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toVisuallyMatch.js","sourceRoot":"","sources":["../../../src/matchers/toVisuallyMatch.ts"],"names":[],"mappings":";;AAiBA,0CAuDC;AAvED,4CAA2C;AAC3C,0DAA6D;AAE7D,SAAS,WAAW,CAAC,WAAmB,EAAE,OAA2B;IACnE,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,uBAAuB,OAAO,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1G,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC;IAE/C,OAAO;;gBAEO,WAAW;;EAEzB,WAAW,eAAe,SAAS;;2EAEsC,CAAC;AAC5E,CAAC;AAEM,KAAK,UAAU,eAAe,CAEnC,QAAiB,EACjB,WAAmB,EACnB,UAA8B,EAAE;IAEhC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/D,OAAO;YACL,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,GAAG,EAAE,CACZ,wEAAwE,OAAO,QAAQ,EAAE;SAC5F,CAAC;IACJ,CAAC;IAED,IAAI,SAAoB,CAAC;IACzB,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,IAAA,mCAAmB,EAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,GAAG,EAAE,CACZ,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SACvF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,IAAA,uBAAW,GAAE,CAAC;IACrC,MAAM,MAAM,GAAG,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAE9E,OAAO;YACL,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,GAAG,EAAE;gBACZ,MAAM,SAAS,GACb,OAAO,QAAQ,KAAK,QAAQ;oBAC1B,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE;wBACpB,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK;wBAC/B,CAAC,CAAC,QAAQ;oBACZ,CAAC,CAAC,UAAU,CAAC;gBAEjB,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,mBAAmB,SAAS,4BAA4B,WAAW,uBAAuB,WAAW,EAAE,CAAC;gBACjH,CAAC;qBAAM,CAAC;oBACN,OAAO,mBAAmB,SAAS,wBAAwB,WAAW,uBAAuB,WAAW,EAAE,CAAC;gBAC7G,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,GAAG,EAAE,CACZ,oCAAoC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SAC/F,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { LLMProvider, JudgmentResult } from "../types.js";
|
|
1
|
+
import type { LLMProvider, JudgmentResult, ImageData } from "../types.js";
|
|
2
2
|
export declare class AnthropicProvider implements LLMProvider {
|
|
3
3
|
private apiKey;
|
|
4
4
|
private constructor();
|
|
5
5
|
static create(apiKey?: string): Promise<AnthropicProvider>;
|
|
6
6
|
judge(prompt: string): Promise<JudgmentResult>;
|
|
7
|
+
judgeImage(imageData: ImageData, prompt: string): Promise<JudgmentResult>;
|
|
7
8
|
}
|
|
8
9
|
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAoB1E,qBAAa,iBAAkB,YAAW,WAAW;IACnD,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO;WAIM,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAW1D,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAoC9C,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CAkDhF"}
|
|
@@ -61,6 +61,52 @@ class AnthropicProvider {
|
|
|
61
61
|
const parsed = JSON.parse(text);
|
|
62
62
|
return { verdict: parsed.verdict, explanation: parsed.explanation };
|
|
63
63
|
}
|
|
64
|
+
async judgeImage(imageData, prompt) {
|
|
65
|
+
const response = await fetch(ANTHROPIC_API_URL, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: {
|
|
68
|
+
"content-type": "application/json",
|
|
69
|
+
"x-api-key": this.apiKey,
|
|
70
|
+
"anthropic-version": "2023-06-01",
|
|
71
|
+
"anthropic-beta": "structured-outputs-2025-11-13",
|
|
72
|
+
},
|
|
73
|
+
body: JSON.stringify({
|
|
74
|
+
model: "claude-haiku-4-5",
|
|
75
|
+
max_tokens: 1024,
|
|
76
|
+
messages: [
|
|
77
|
+
{
|
|
78
|
+
role: "user",
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: "image",
|
|
82
|
+
source: {
|
|
83
|
+
type: "base64",
|
|
84
|
+
media_type: imageData.mediaType,
|
|
85
|
+
data: imageData.base64,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{ type: "text", text: prompt },
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
output_format: {
|
|
93
|
+
type: "json_schema",
|
|
94
|
+
schema: JUDGMENT_SCHEMA,
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
97
|
+
});
|
|
98
|
+
if (!response.ok) {
|
|
99
|
+
const errorText = await response.text();
|
|
100
|
+
throw new Error(`jest-fuzzy: Anthropic API error (${response.status}): ${errorText}`);
|
|
101
|
+
}
|
|
102
|
+
const data = (await response.json());
|
|
103
|
+
const text = data.content?.[0]?.text;
|
|
104
|
+
if (!text) {
|
|
105
|
+
throw new Error("jest-fuzzy: Anthropic API returned no content");
|
|
106
|
+
}
|
|
107
|
+
const parsed = JSON.parse(text);
|
|
108
|
+
return { verdict: parsed.verdict, explanation: parsed.explanation };
|
|
109
|
+
}
|
|
64
110
|
}
|
|
65
111
|
exports.AnthropicProvider = AnthropicProvider;
|
|
66
112
|
//# sourceMappingURL=anthropic.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/providers/anthropic.ts"],"names":[],"mappings":";;;AAEA,MAAM,iBAAiB,GAAG,uCAAuC,CAAC;AAElE,MAAM,eAAe,GAAG;IACtB,IAAI,EAAE,QAAiB;IACvB,UAAU,EAAE;QACV,OAAO,EAAE;YACP,IAAI,EAAE,SAAkB;YACxB,WAAW,EAAE,qDAAqD;SACnE;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAiB;YACvB,WAAW,EAAE,oCAAoC;SAClD;KACF;IACD,QAAQ,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC;IACpC,oBAAoB,EAAE,KAAK;CAC5B,CAAC;AAEF,MAAa,iBAAiB;IACpB,MAAM,CAAS;IAEvB,YAAoB,MAAc;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAe;QACjC,MAAM,GAAG,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QACpD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,0DAA0D;gBACxD,gHAAgH,CACnH,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAc;QACxB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,iBAAiB,EAAE;YAC9C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,WAAW,EAAE,IAAI,CAAC,MAAM;gBACxB,mBAAmB,EAAE,YAAY;gBACjC,gBAAgB,EAAE,+BAA+B;aAClD;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,kBAAkB;gBACzB,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;gBAC7C,aAAa,EAAE;oBACb,IAAI,EAAE,aAAa;oBACnB,MAAM,EAAE,eAAe;iBACxB;aACF,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,oCAAoC,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;QACxF,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA2C,CAAC;QAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QAErC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA8C,CAAC;QAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;IACtE,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/providers/anthropic.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { LLMProvider, JudgmentResult } from "../types.js";
|
|
1
|
+
import type { LLMProvider, JudgmentResult, ImageData } from "../types.js";
|
|
2
2
|
export declare class GoogleProvider implements LLMProvider {
|
|
3
3
|
private apiKey;
|
|
4
4
|
private constructor();
|
|
5
5
|
static create(apiKey?: string): Promise<GoogleProvider>;
|
|
6
6
|
judge(prompt: string): Promise<JudgmentResult>;
|
|
7
|
+
judgeImage(imageData: ImageData, prompt: string): Promise<JudgmentResult>;
|
|
7
8
|
}
|
|
8
9
|
//# sourceMappingURL=google.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../../src/providers/google.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../../src/providers/google.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAmB1E,qBAAa,cAAe,YAAW,WAAW;IAChD,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO;WAIM,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAWvD,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAuC9C,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CA8ChF"}
|
|
@@ -60,6 +60,45 @@ class GoogleProvider {
|
|
|
60
60
|
const parsed = JSON.parse(text);
|
|
61
61
|
return { verdict: parsed.verdict, explanation: parsed.explanation };
|
|
62
62
|
}
|
|
63
|
+
async judgeImage(imageData, prompt) {
|
|
64
|
+
const url = `${GEMINI_API_URL}?key=${this.apiKey}`;
|
|
65
|
+
const response = await fetch(url, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: {
|
|
68
|
+
"Content-Type": "application/json",
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify({
|
|
71
|
+
contents: [
|
|
72
|
+
{
|
|
73
|
+
parts: [
|
|
74
|
+
{ text: prompt },
|
|
75
|
+
{
|
|
76
|
+
inline_data: {
|
|
77
|
+
mime_type: imageData.mediaType,
|
|
78
|
+
data: imageData.base64,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
generationConfig: {
|
|
85
|
+
responseMimeType: "application/json",
|
|
86
|
+
responseSchema: JUDGMENT_SCHEMA,
|
|
87
|
+
},
|
|
88
|
+
}),
|
|
89
|
+
});
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
const errorText = await response.text();
|
|
92
|
+
throw new Error(`jest-fuzzy: Google API error (${response.status}): ${errorText}`);
|
|
93
|
+
}
|
|
94
|
+
const data = (await response.json());
|
|
95
|
+
const text = data.candidates?.[0]?.content?.parts?.[0]?.text;
|
|
96
|
+
if (!text) {
|
|
97
|
+
throw new Error("jest-fuzzy: Google API returned no content");
|
|
98
|
+
}
|
|
99
|
+
const parsed = JSON.parse(text);
|
|
100
|
+
return { verdict: parsed.verdict, explanation: parsed.explanation };
|
|
101
|
+
}
|
|
63
102
|
}
|
|
64
103
|
exports.GoogleProvider = GoogleProvider;
|
|
65
104
|
//# sourceMappingURL=google.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../../src/providers/google.ts"],"names":[],"mappings":";;;AAEA,MAAM,cAAc,GAAG,0FAA0F,CAAC;AAElH,MAAM,eAAe,GAAG;IACtB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,qDAAqD;SACnE;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,oCAAoC;SAClD;KACF;IACD,QAAQ,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC;CACrC,CAAC;AAEF,MAAa,cAAc;IACjB,MAAM,CAAS;IAEvB,YAAoB,MAAc;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAe;QACjC,MAAM,GAAG,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QACjD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,gEAAgE;gBAC9D,0GAA0G,CAC7G,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAc;QACxB,MAAM,GAAG,GAAG,GAAG,cAAc,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;QAEnD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,QAAQ,EAAE;oBACR;wBACE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;qBAC1B;iBACF;gBACD,gBAAgB,EAAE;oBAChB,gBAAgB,EAAE,kBAAkB;oBACpC,cAAc,EAAE,eAAe;iBAChC;aACF,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,iCAAiC,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAElC,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QAE7D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA8C,CAAC;QAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;IACtE,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../../src/providers/google.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { LLMProvider, JudgmentResult } from "../types.js";
|
|
1
|
+
import type { LLMProvider, JudgmentResult, ImageData } from "../types.js";
|
|
2
2
|
export declare class OpenAIProvider implements LLMProvider {
|
|
3
3
|
private apiKey;
|
|
4
4
|
private constructor();
|
|
5
5
|
static create(apiKey?: string): Promise<OpenAIProvider>;
|
|
6
6
|
judge(prompt: string): Promise<JudgmentResult>;
|
|
7
|
+
judgeImage(imageData: ImageData, prompt: string): Promise<JudgmentResult>;
|
|
7
8
|
}
|
|
8
9
|
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/providers/openai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/providers/openai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAoB1E,qBAAa,cAAe,YAAW,WAAW;IAChD,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO;WAIM,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAWvD,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAwC9C,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CAoDhF"}
|
|
@@ -63,6 +63,52 @@ class OpenAIProvider {
|
|
|
63
63
|
const parsed = JSON.parse(text);
|
|
64
64
|
return { verdict: parsed.verdict, explanation: parsed.explanation };
|
|
65
65
|
}
|
|
66
|
+
async judgeImage(imageData, prompt) {
|
|
67
|
+
const response = await fetch(OPENAI_API_URL, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: {
|
|
70
|
+
"Content-Type": "application/json",
|
|
71
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
72
|
+
},
|
|
73
|
+
body: JSON.stringify({
|
|
74
|
+
model: "gpt-4o-mini",
|
|
75
|
+
max_output_tokens: 1024,
|
|
76
|
+
input: [
|
|
77
|
+
{
|
|
78
|
+
role: "user",
|
|
79
|
+
content: [
|
|
80
|
+
{ type: "text", text: prompt },
|
|
81
|
+
{
|
|
82
|
+
type: "image_url",
|
|
83
|
+
image_url: {
|
|
84
|
+
url: `data:${imageData.mediaType};base64,${imageData.base64}`,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
text: {
|
|
91
|
+
format: {
|
|
92
|
+
type: "json_schema",
|
|
93
|
+
name: "judgment",
|
|
94
|
+
strict: true,
|
|
95
|
+
schema: JUDGMENT_SCHEMA,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
});
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
const errorText = await response.text();
|
|
102
|
+
throw new Error(`jest-fuzzy: OpenAI API error (${response.status}): ${errorText}`);
|
|
103
|
+
}
|
|
104
|
+
const data = (await response.json());
|
|
105
|
+
const text = data.output?.[0]?.content?.[0]?.text;
|
|
106
|
+
if (!text) {
|
|
107
|
+
throw new Error("jest-fuzzy: OpenAI API returned no content");
|
|
108
|
+
}
|
|
109
|
+
const parsed = JSON.parse(text);
|
|
110
|
+
return { verdict: parsed.verdict, explanation: parsed.explanation };
|
|
111
|
+
}
|
|
66
112
|
}
|
|
67
113
|
exports.OpenAIProvider = OpenAIProvider;
|
|
68
114
|
//# sourceMappingURL=openai.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/providers/openai.ts"],"names":[],"mappings":";;;AAEA,MAAM,cAAc,GAAG,qCAAqC,CAAC;AAE7D,MAAM,eAAe,GAAG;IACtB,IAAI,EAAE,QAAiB;IACvB,UAAU,EAAE;QACV,OAAO,EAAE;YACP,IAAI,EAAE,SAAkB;YACxB,WAAW,EAAE,qDAAqD;SACnE;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAiB;YACvB,WAAW,EAAE,oCAAoC;SAClD;KACF;IACD,QAAQ,EAAE,CAAC,SAAS,EAAE,aAAa,CAAU;IAC7C,oBAAoB,EAAE,KAAK;CAC5B,CAAC;AAEF,MAAa,cAAc;IACjB,MAAM,CAAS;IAEvB,YAAoB,MAAc;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAe;QACjC,MAAM,GAAG,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QACjD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CACb,oDAAoD;gBAClD,0GAA0G,CAC7G,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAc;QACxB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,cAAc,EAAE;YAC3C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aACvC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,aAAa;gBACpB,iBAAiB,EAAE,IAAI;gBACvB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;gBAC1C,IAAI,EAAE;oBACJ,MAAM,EAAE;wBACN,IAAI,EAAE,aAAa;wBACnB,IAAI,EAAE,UAAU;wBAChB,MAAM,EAAE,IAAI;wBACZ,MAAM,EAAE,eAAe;qBACxB;iBACF;aACF,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,iCAAiC,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAElC,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QAElD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA8C,CAAC;QAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;IACtE,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/providers/openai.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export type ModelName = "claude-haiku-4-5" | "gemini-3-flash-preview" | "gpt-5-nano";
|
|
2
|
+
export type ImageMediaType = "image/jpeg" | "image/png" | "image/gif" | "image/webp";
|
|
3
|
+
export interface ImageData {
|
|
4
|
+
base64: string;
|
|
5
|
+
mediaType: ImageMediaType;
|
|
6
|
+
}
|
|
2
7
|
export interface ApiKeys {
|
|
3
8
|
anthropic?: string;
|
|
4
9
|
google?: string;
|
|
@@ -10,7 +15,12 @@ export interface JestFuzzyConfig {
|
|
|
10
15
|
}
|
|
11
16
|
export interface SemanticMatchOptions {
|
|
12
17
|
threshold?: "strict" | "loose";
|
|
13
|
-
|
|
18
|
+
additionalContext?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface VisualMatchOptions {
|
|
21
|
+
threshold?: "strict" | "loose";
|
|
22
|
+
additionalContext?: string;
|
|
23
|
+
mimeType?: ImageMediaType;
|
|
14
24
|
}
|
|
15
25
|
export interface JudgmentResult {
|
|
16
26
|
verdict: boolean;
|
|
@@ -18,6 +28,7 @@ export interface JudgmentResult {
|
|
|
18
28
|
}
|
|
19
29
|
export interface LLMProvider {
|
|
20
30
|
judge(prompt: string): Promise<JudgmentResult>;
|
|
31
|
+
judgeImage(imageData: ImageData, prompt: string): Promise<JudgmentResult>;
|
|
21
32
|
}
|
|
22
33
|
export interface MatcherResult {
|
|
23
34
|
pass: boolean;
|
|
@@ -28,6 +39,7 @@ declare global {
|
|
|
28
39
|
interface Matchers<R> {
|
|
29
40
|
toSemanticallyMatch(expected: string, options?: SemanticMatchOptions): Promise<R>;
|
|
30
41
|
toSatisfy(criteria: string): Promise<R>;
|
|
42
|
+
toVisuallyMatch(description: string, options?: VisualMatchOptions): Promise<R>;
|
|
31
43
|
}
|
|
32
44
|
}
|
|
33
45
|
}
|
package/dist/cjs/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,kBAAkB,GAClB,wBAAwB,GACxB,YAAY,CAAC;AAEjB,MAAM,WAAW,OAAO;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,kBAAkB,GAClB,wBAAwB,GACxB,YAAY,CAAC;AAEjB,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;AAErF,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC/C,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC3E;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,MAAM,CAAC;CACvB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,IAAI,CAAC;QACb,UAAU,QAAQ,CAAC,CAAC;YAClB,mBAAmB,CACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,CAAC,CAAC,CAAC;YACd,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACxC,eAAe,CACb,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,CAAC,CAAC,CAAC;SACf;KACF;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ImageMediaType, ImageData } from "../types.js";
|
|
2
|
+
export declare function isUrl(input: string): boolean;
|
|
3
|
+
export declare function isFilePath(input: string): boolean;
|
|
4
|
+
export declare function detectMimeTypeFromBase64(base64: string): ImageMediaType | null;
|
|
5
|
+
export declare function isBase64Image(input: string): boolean;
|
|
6
|
+
export declare function detectMimeTypeFromExtension(path: string): ImageMediaType | null;
|
|
7
|
+
export declare function normalizeImageInput(input: string | Buffer, mimeTypeOverride?: ImageMediaType): Promise<ImageData>;
|
|
8
|
+
//# sourceMappingURL=imageUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imageUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/imageUtils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAqE7D,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAO5C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjD;AASD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAK9E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAe/E;AAED,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,gBAAgB,CAAC,EAAE,cAAc,GAChC,OAAO,CAAC,SAAS,CAAC,CA4CpB"}
|