jest-fuzzy 0.1.2 → 0.1.3
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 +55 -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 +89 -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 +81 -0
- package/dist/esm/utils/imageUtils.js.map +1 -0
- package/package.json +1 -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,56 @@ 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
|
+
|
|
179
229
|
## Configuration
|
|
180
230
|
|
|
181
231
|
### API Keys
|
|
@@ -245,11 +295,11 @@ pleasant weather conditions, while the second describes heavy rainfall.
|
|
|
245
295
|
await expect(response).toSatisfy("mentions the user's name 'John'");
|
|
246
296
|
```
|
|
247
297
|
|
|
248
|
-
2. **Provide context when the comparison needs domain knowledge:**
|
|
298
|
+
2. **Provide additional context when the comparison needs domain knowledge:**
|
|
249
299
|
|
|
250
300
|
```typescript
|
|
251
301
|
await expect("42").toSemanticallyMatch("The answer", {
|
|
252
|
-
|
|
302
|
+
additionalContext: "Testing a Hitchhiker's Guide to the Galaxy trivia bot",
|
|
253
303
|
});
|
|
254
304
|
```
|
|
255
305
|
|
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;AAE7D,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,CAoCpB"}
|