jest-fuzzy 0.1.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/LICENSE +21 -0
- package/README.md +249 -0
- package/dist/cjs/config.d.ts +5 -0
- package/dist/cjs/config.d.ts.map +1 -0
- package/dist/cjs/config.js +38 -0
- package/dist/cjs/config.js.map +1 -0
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +17 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/matchers/index.d.ts +3 -0
- package/dist/cjs/matchers/index.d.ts.map +1 -0
- package/dist/cjs/matchers/index.js +8 -0
- package/dist/cjs/matchers/index.js.map +1 -0
- package/dist/cjs/matchers/toSatisfy.d.ts +3 -0
- package/dist/cjs/matchers/toSatisfy.d.ts.map +1 -0
- package/dist/cjs/matchers/toSatisfy.js +43 -0
- package/dist/cjs/matchers/toSatisfy.js.map +1 -0
- package/dist/cjs/matchers/toSemanticallyMatch.d.ts +3 -0
- package/dist/cjs/matchers/toSemanticallyMatch.d.ts.map +1 -0
- package/dist/cjs/matchers/toSemanticallyMatch.js +46 -0
- package/dist/cjs/matchers/toSemanticallyMatch.js.map +1 -0
- package/dist/cjs/providers/anthropic.d.ts +8 -0
- package/dist/cjs/providers/anthropic.d.ts.map +1 -0
- package/dist/cjs/providers/anthropic.js +94 -0
- package/dist/cjs/providers/anthropic.js.map +1 -0
- package/dist/cjs/providers/google.d.ts +8 -0
- package/dist/cjs/providers/google.d.ts.map +1 -0
- package/dist/cjs/providers/google.js +90 -0
- package/dist/cjs/providers/google.js.map +1 -0
- package/dist/cjs/providers/index.d.ts +8 -0
- package/dist/cjs/providers/index.d.ts.map +1 -0
- package/dist/cjs/providers/index.js +23 -0
- package/dist/cjs/providers/index.js.map +1 -0
- package/dist/cjs/providers/openai.d.ts +8 -0
- package/dist/cjs/providers/openai.d.ts.map +1 -0
- package/dist/cjs/providers/openai.js +97 -0
- package/dist/cjs/providers/openai.js.map +1 -0
- package/dist/cjs/types.d.ts +28 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/config.d.ts +5 -0
- package/dist/esm/config.d.ts.map +1 -0
- package/dist/esm/config.js +33 -0
- package/dist/esm/config.js.map +1 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/matchers/index.d.ts +3 -0
- package/dist/esm/matchers/index.d.ts.map +1 -0
- package/dist/esm/matchers/index.js +3 -0
- package/dist/esm/matchers/index.js.map +1 -0
- package/dist/esm/matchers/toSatisfy.d.ts +3 -0
- package/dist/esm/matchers/toSatisfy.d.ts.map +1 -0
- package/dist/esm/matchers/toSatisfy.js +40 -0
- package/dist/esm/matchers/toSatisfy.js.map +1 -0
- package/dist/esm/matchers/toSemanticallyMatch.d.ts +3 -0
- package/dist/esm/matchers/toSemanticallyMatch.d.ts.map +1 -0
- package/dist/esm/matchers/toSemanticallyMatch.js +43 -0
- package/dist/esm/matchers/toSemanticallyMatch.js.map +1 -0
- package/dist/esm/providers/anthropic.d.ts +8 -0
- package/dist/esm/providers/anthropic.d.ts.map +1 -0
- package/dist/esm/providers/anthropic.js +57 -0
- package/dist/esm/providers/anthropic.js.map +1 -0
- package/dist/esm/providers/google.d.ts +8 -0
- package/dist/esm/providers/google.d.ts.map +1 -0
- package/dist/esm/providers/google.js +53 -0
- package/dist/esm/providers/google.js.map +1 -0
- package/dist/esm/providers/index.d.ts +8 -0
- package/dist/esm/providers/index.d.ts.map +1 -0
- package/dist/esm/providers/index.js +17 -0
- package/dist/esm/providers/index.js.map +1 -0
- package/dist/esm/providers/openai.d.ts +8 -0
- package/dist/esm/providers/openai.d.ts.map +1 -0
- package/dist/esm/providers/openai.js +60 -0
- package/dist/esm/providers/openai.js.map +1 -0
- package/dist/esm/types.d.ts +28 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Christian Cantrell
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# jest-fuzzy
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/jest-fuzzy)
|
|
4
|
+
[](https://github.com/example/jest-fuzzy/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
LLM-powered fuzzy matchers for Jest.
|
|
7
|
+
|
|
8
|
+
## Why?
|
|
9
|
+
|
|
10
|
+
Testing non-deterministic outputs (like LLM responses, generated content, or natural language) with exact string matching is brittle. `jest-fuzzy` extends Jest with semantic matchers that use lightweight LLMs to judge whether outputs match expectations.
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
// Instead of this (brittle):
|
|
14
|
+
expect(response).toBe("Hello! How can I help you today?");
|
|
15
|
+
|
|
16
|
+
// Do this (flexible):
|
|
17
|
+
await expect(response).toSemanticallyMatch("Hi, how may I assist you?");
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install jest-fuzzy --save-dev
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Install the SDK for your preferred LLM provider:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# For Claude (default)
|
|
30
|
+
npm install @anthropic-ai/sdk
|
|
31
|
+
|
|
32
|
+
# For Gemini
|
|
33
|
+
npm install @google/generative-ai
|
|
34
|
+
|
|
35
|
+
# For OpenAI
|
|
36
|
+
npm install openai
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
**1. Set your API key:**
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
export ANTHROPIC_API_KEY=your-key-here
|
|
45
|
+
# or GOOGLE_API_KEY for Gemini
|
|
46
|
+
# or OPENAI_API_KEY for OpenAI
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**2. Register the matchers in your Jest setup file:**
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// jest.setup.ts
|
|
53
|
+
import { configure } from "jest-fuzzy";
|
|
54
|
+
|
|
55
|
+
configure({
|
|
56
|
+
model: "claude-haiku-4-5", // optional, this is the default
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or simply import for defaults (Claude):
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
// jest.setup.ts
|
|
64
|
+
import "jest-fuzzy";
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**3. Reference the setup file in your Jest config:**
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
// jest.config.js
|
|
71
|
+
module.exports = {
|
|
72
|
+
setupFilesAfterEnv: ["./jest.setup.ts"],
|
|
73
|
+
};
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**4. Use the matchers in your tests:**
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
describe("chatbot", () => {
|
|
80
|
+
it("responds with a greeting", async () => {
|
|
81
|
+
const response = await chatbot.greet();
|
|
82
|
+
await expect(response).toSemanticallyMatch("Hello, how can I help?");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("provides helpful responses", async () => {
|
|
86
|
+
const response = await chatbot.answer("What is 2+2?");
|
|
87
|
+
await expect(response).toSatisfy("contains the number 4 and is polite");
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## API Reference
|
|
93
|
+
|
|
94
|
+
### `configure(options?)`
|
|
95
|
+
|
|
96
|
+
Configures jest-fuzzy with your preferred model.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { configure } from "jest-fuzzy";
|
|
100
|
+
|
|
101
|
+
configure({
|
|
102
|
+
model: "claude-haiku-4-5", // or "gemini-3-flash-preview" or "gpt-5-nano"
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
| Option | Type | Default | Description |
|
|
107
|
+
|--------|------|---------|-------------|
|
|
108
|
+
| `model` | `string` | `"claude-haiku-4-5"` | The LLM model to use for judging |
|
|
109
|
+
|
|
110
|
+
### `toSemanticallyMatch(expected, options?)`
|
|
111
|
+
|
|
112
|
+
Tests whether the received string has the same semantic meaning as the expected string.
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
await expect("Hello! How can I help you today?").toSemanticallyMatch(
|
|
116
|
+
"Hi, how may I assist you?"
|
|
117
|
+
);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Options:**
|
|
121
|
+
|
|
122
|
+
| Option | Type | Default | Description |
|
|
123
|
+
|--------|------|---------|-------------|
|
|
124
|
+
| `threshold` | `"strict"` \| `"loose"` | `"loose"` | How strictly to judge semantic equivalence |
|
|
125
|
+
| `context` | `string` | - | Additional context to help the LLM judge |
|
|
126
|
+
|
|
127
|
+
**Examples:**
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// Basic usage
|
|
131
|
+
await expect("The sky is blue").toSemanticallyMatch("The color of the sky is blue");
|
|
132
|
+
|
|
133
|
+
// With strict threshold
|
|
134
|
+
await expect(response).toSemanticallyMatch("The capital of France is Paris", {
|
|
135
|
+
threshold: "strict",
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// With context
|
|
139
|
+
await expect("Paris").toSemanticallyMatch("The capital of France", {
|
|
140
|
+
context: "Testing a geography Q&A bot asking about France's capital",
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Negation
|
|
144
|
+
await expect("I love sunny weather").not.toSemanticallyMatch("I hate sunny weather");
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### `toSatisfy(criteria)`
|
|
148
|
+
|
|
149
|
+
Tests whether the received string satisfies the given natural language criteria.
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
await expect(summary).toSatisfy(
|
|
153
|
+
"mentions climate change and includes at least one statistic"
|
|
154
|
+
);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Examples:**
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Testing content
|
|
161
|
+
await expect(article).toSatisfy("discusses renewable energy");
|
|
162
|
+
|
|
163
|
+
// Testing tone
|
|
164
|
+
await expect(response).toSatisfy("is polite and professional in tone");
|
|
165
|
+
|
|
166
|
+
// Testing structure
|
|
167
|
+
await expect(output).toSatisfy("is valid JSON containing a 'name' field");
|
|
168
|
+
|
|
169
|
+
// Testing safety
|
|
170
|
+
await expect(response).not.toSatisfy("contains profanity or offensive language");
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Configuration
|
|
174
|
+
|
|
175
|
+
### Environment Variables
|
|
176
|
+
|
|
177
|
+
Set the API key for your chosen model:
|
|
178
|
+
|
|
179
|
+
| Model | Environment Variable |
|
|
180
|
+
|-------|---------------------|
|
|
181
|
+
| `claude-haiku-4-5` | `ANTHROPIC_API_KEY` |
|
|
182
|
+
| `gemini-3-flash-preview` | `GOOGLE_API_KEY` |
|
|
183
|
+
| `gpt-5-nano` | `OPENAI_API_KEY` |
|
|
184
|
+
|
|
185
|
+
### Supported Models
|
|
186
|
+
|
|
187
|
+
| Model ID | Provider | Description |
|
|
188
|
+
|----------|----------|-------------|
|
|
189
|
+
| `claude-haiku-4-5` | Anthropic | Fast, cost-effective Claude model (default) |
|
|
190
|
+
| `gemini-3-flash-preview` | Google | Fast Gemini model |
|
|
191
|
+
| `gpt-5-nano` | OpenAI | Lightweight GPT model |
|
|
192
|
+
|
|
193
|
+
## TypeScript Support
|
|
194
|
+
|
|
195
|
+
jest-fuzzy includes full TypeScript support. The matchers are automatically typed when you import the library:
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import "jest-fuzzy";
|
|
199
|
+
|
|
200
|
+
// Types are automatically available
|
|
201
|
+
await expect("hello").toSemanticallyMatch("hi");
|
|
202
|
+
await expect("hello").toSatisfy("is a greeting");
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Error Messages
|
|
206
|
+
|
|
207
|
+
When tests fail, jest-fuzzy includes the LLM's reasoning to help you understand why:
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
Expected "The weather is nice" to semantically match "It's raining heavily"
|
|
211
|
+
|
|
212
|
+
LLM reasoning: These statements have opposite meanings. The first indicates
|
|
213
|
+
pleasant weather conditions, while the second describes heavy rainfall.
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Best Practices
|
|
217
|
+
|
|
218
|
+
1. **Use semantic matching for equivalent meanings**, not for checking specific content:
|
|
219
|
+
```typescript
|
|
220
|
+
// Good: checking semantic equivalence
|
|
221
|
+
await expect(greeting).toSemanticallyMatch("Hello, how can I help?");
|
|
222
|
+
|
|
223
|
+
// Better for specific content: use toSatisfy
|
|
224
|
+
await expect(response).toSatisfy("mentions the user's name 'John'");
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
2. **Provide context when the comparison needs domain knowledge:**
|
|
228
|
+
```typescript
|
|
229
|
+
await expect("42").toSemanticallyMatch("The answer", {
|
|
230
|
+
context: "Testing a Hitchhiker's Guide to the Galaxy trivia bot",
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
3. **Use `threshold: "strict"` when precision matters:**
|
|
235
|
+
```typescript
|
|
236
|
+
await expect(legalText).toSemanticallyMatch(expectedDisclaimer, {
|
|
237
|
+
threshold: "strict",
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
4. **Consider test runtime:** Each matcher makes an API call, so use them judiciously in large test suites.
|
|
242
|
+
|
|
243
|
+
## Author
|
|
244
|
+
|
|
245
|
+
[Christian Cantrell](https://christiancantrell.com)
|
|
246
|
+
|
|
247
|
+
## License
|
|
248
|
+
|
|
249
|
+
MIT
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { JestFuzzyConfig, LLMProvider } from "./types.js";
|
|
2
|
+
export declare function configure(config?: JestFuzzyConfig): void;
|
|
3
|
+
export declare function getConfig(): Required<JestFuzzyConfig>;
|
|
4
|
+
export declare function getProvider(): Promise<LLMProvider>;
|
|
5
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAa,WAAW,EAAE,MAAM,YAAY,CAAC;AAY1E,wBAAgB,SAAS,CAAC,MAAM,GAAE,eAAoB,GAAG,IAAI,CAQ5D;AAED,wBAAgB,SAAS,IAAI,QAAQ,CAAC,eAAe,CAAC,CAIrD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAaxD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configure = configure;
|
|
4
|
+
exports.getConfig = getConfig;
|
|
5
|
+
exports.getProvider = getProvider;
|
|
6
|
+
const index_js_1 = require("./providers/index.js");
|
|
7
|
+
const DEFAULT_MODEL = "claude-haiku-4-5";
|
|
8
|
+
let currentConfig = {
|
|
9
|
+
model: DEFAULT_MODEL,
|
|
10
|
+
};
|
|
11
|
+
let providerInstance = null;
|
|
12
|
+
let providerPromise = null;
|
|
13
|
+
function configure(config = {}) {
|
|
14
|
+
currentConfig = {
|
|
15
|
+
model: config.model ?? DEFAULT_MODEL,
|
|
16
|
+
};
|
|
17
|
+
// Reset provider so it will be re-created with new config
|
|
18
|
+
providerInstance = null;
|
|
19
|
+
providerPromise = null;
|
|
20
|
+
}
|
|
21
|
+
function getConfig() {
|
|
22
|
+
return {
|
|
23
|
+
model: currentConfig.model ?? DEFAULT_MODEL,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async function getProvider() {
|
|
27
|
+
if (providerInstance) {
|
|
28
|
+
return providerInstance;
|
|
29
|
+
}
|
|
30
|
+
if (!providerPromise) {
|
|
31
|
+
providerPromise = (0, index_js_1.createProvider)(getConfig().model).then((provider) => {
|
|
32
|
+
providerInstance = provider;
|
|
33
|
+
return provider;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return providerPromise;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":";;AAYA,8BAQC;AAED,8BAIC;AAED,kCAaC;AAxCD,mDAAsD;AAEtD,MAAM,aAAa,GAAc,kBAAkB,CAAC;AAEpD,IAAI,aAAa,GAAoB;IACnC,KAAK,EAAE,aAAa;CACrB,CAAC;AAEF,IAAI,gBAAgB,GAAuB,IAAI,CAAC;AAChD,IAAI,eAAe,GAAgC,IAAI,CAAC;AAExD,SAAgB,SAAS,CAAC,SAA0B,EAAE;IACpD,aAAa,GAAG;QACd,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,aAAa;KACrC,CAAC;IAEF,0DAA0D;IAC1D,gBAAgB,GAAG,IAAI,CAAC;IACxB,eAAe,GAAG,IAAI,CAAC;AACzB,CAAC;AAED,SAAgB,SAAS;IACvB,OAAO;QACL,KAAK,EAAE,aAAa,CAAC,KAAK,IAAI,aAAa;KAC5C,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,WAAW;IAC/B,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,eAAe,GAAG,IAAA,yBAAc,EAAC,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;YACpE,gBAAgB,GAAG,QAAQ,CAAC;YAC5B,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { configure, getConfig, getProvider } from "./config.js";
|
|
2
|
+
import type { JestFuzzyConfig, SemanticMatchOptions, ModelName, LLMProvider } from "./types.js";
|
|
3
|
+
export { configure, getConfig, getProvider };
|
|
4
|
+
export type { JestFuzzyConfig, SemanticMatchOptions, ModelName, LLMProvider, };
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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;AAGhE,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EACpB,SAAS,EACT,WAAW,EACZ,MAAM,YAAY,CAAC;AAUpB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;AAC7C,YAAY,EACV,eAAe,EACf,oBAAoB,EACpB,SAAS,EACT,WAAW,GACZ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getProvider = exports.getConfig = exports.configure = void 0;
|
|
4
|
+
const config_js_1 = require("./config.js");
|
|
5
|
+
Object.defineProperty(exports, "configure", { enumerable: true, get: function () { return config_js_1.configure; } });
|
|
6
|
+
Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return config_js_1.getConfig; } });
|
|
7
|
+
Object.defineProperty(exports, "getProvider", { enumerable: true, get: function () { return config_js_1.getProvider; } });
|
|
8
|
+
const toSemanticallyMatch_js_1 = require("./matchers/toSemanticallyMatch.js");
|
|
9
|
+
const toSatisfy_js_1 = require("./matchers/toSatisfy.js");
|
|
10
|
+
// Register matchers with Jest
|
|
11
|
+
if (typeof expect !== "undefined" && expect.extend) {
|
|
12
|
+
expect.extend({
|
|
13
|
+
toSemanticallyMatch: toSemanticallyMatch_js_1.toSemanticallyMatch,
|
|
14
|
+
toSatisfy: toSatisfy_js_1.toSatisfy,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,2CAAgE;AAkBvD,0FAlBA,qBAAS,OAkBA;AAAE,0FAlBA,qBAAS,OAkBA;AAAE,4FAlBA,uBAAW,OAkBA;AAjB1C,8EAAwE;AACxE,0DAAoD;AAQpD,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;KACV,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toSatisfy = exports.toSemanticallyMatch = void 0;
|
|
4
|
+
var toSemanticallyMatch_js_1 = require("./toSemanticallyMatch.js");
|
|
5
|
+
Object.defineProperty(exports, "toSemanticallyMatch", { enumerable: true, get: function () { return toSemanticallyMatch_js_1.toSemanticallyMatch; } });
|
|
6
|
+
var toSatisfy_js_1 = require("./toSatisfy.js");
|
|
7
|
+
Object.defineProperty(exports, "toSatisfy", { enumerable: true, get: function () { return toSatisfy_js_1.toSatisfy; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toSatisfy.d.ts","sourceRoot":"","sources":["../../../src/matchers/toSatisfy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAYjD,wBAAsB,SAAS,CAC7B,IAAI,EAAE,IAAI,CAAC,cAAc,EACzB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC,CAgCxB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toSatisfy = toSatisfy;
|
|
4
|
+
const config_js_1 = require("../config.js");
|
|
5
|
+
function buildPrompt(received, criteria) {
|
|
6
|
+
return `Does the following text satisfy the given criteria?
|
|
7
|
+
|
|
8
|
+
Text: "${received}"
|
|
9
|
+
Criteria: ${criteria}
|
|
10
|
+
|
|
11
|
+
Return verdict=true if the text satisfies the criteria, false otherwise.`;
|
|
12
|
+
}
|
|
13
|
+
async function toSatisfy(received, criteria) {
|
|
14
|
+
if (typeof received !== "string") {
|
|
15
|
+
return {
|
|
16
|
+
pass: false,
|
|
17
|
+
message: () => `Expected a string but received ${typeof received}: ${JSON.stringify(received)}`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const provider = await (0, config_js_1.getProvider)();
|
|
21
|
+
const prompt = buildPrompt(received, criteria);
|
|
22
|
+
try {
|
|
23
|
+
const { verdict, explanation } = await provider.judge(prompt);
|
|
24
|
+
return {
|
|
25
|
+
pass: verdict,
|
|
26
|
+
message: () => {
|
|
27
|
+
if (verdict) {
|
|
28
|
+
return `Expected "${received}" NOT to satisfy "${criteria}"\n\nLLM reasoning: ${explanation}`;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
return `Expected "${received}" to satisfy "${criteria}"\n\nLLM reasoning: ${explanation}`;
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
return {
|
|
38
|
+
pass: false,
|
|
39
|
+
message: () => `Failed to evaluate criteria: ${error instanceof Error ? error.message : String(error)}`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=toSatisfy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toSatisfy.js","sourceRoot":"","sources":["../../../src/matchers/toSatisfy.ts"],"names":[],"mappings":";;AAYA,8BAoCC;AA/CD,4CAA2C;AAE3C,SAAS,WAAW,CAAC,QAAgB,EAAE,QAAgB;IACrD,OAAO;;SAEA,QAAQ;YACL,QAAQ;;yEAEqD,CAAC;AAC1E,CAAC;AAEM,KAAK,UAAU,SAAS,CAE7B,QAAiB,EACjB,QAAgB;IAEhB,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,CAAC,CAAC;IAE/C,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,qBAAqB,QAAQ,uBAAuB,WAAW,EAAE,CAAC;gBAChG,CAAC;qBAAM,CAAC;oBACN,OAAO,aAAa,QAAQ,iBAAiB,QAAQ,uBAAuB,WAAW,EAAE,CAAC;gBAC5F,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,GAAG,EAAE,CACZ,gCAAgC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SAC3F,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { SemanticMatchOptions, MatcherResult } from "../types.js";
|
|
2
|
+
export declare function toSemanticallyMatch(this: jest.MatcherContext, received: unknown, expected: string, options?: SemanticMatchOptions): Promise<MatcherResult>;
|
|
3
|
+
//# sourceMappingURL=toSemanticallyMatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toSemanticallyMatch.d.ts","sourceRoot":"","sources":["../../../src/matchers/toSemanticallyMatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAoBvE,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,CAAC,cAAc,EACzB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,CAgCxB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toSemanticallyMatch = toSemanticallyMatch;
|
|
4
|
+
const config_js_1 = require("../config.js");
|
|
5
|
+
function buildPrompt(received, expected, options) {
|
|
6
|
+
const contextLine = options.context ? `Context: ${options.context}\n` : "";
|
|
7
|
+
const threshold = options.threshold ?? "loose";
|
|
8
|
+
return `Do these two texts have the same semantic meaning?
|
|
9
|
+
${contextLine}Strictness: ${threshold}
|
|
10
|
+
|
|
11
|
+
Text A: "${received}"
|
|
12
|
+
Text B: "${expected}"
|
|
13
|
+
|
|
14
|
+
Return verdict=true if they have the same semantic meaning, false otherwise.`;
|
|
15
|
+
}
|
|
16
|
+
async function toSemanticallyMatch(received, expected, options = {}) {
|
|
17
|
+
if (typeof received !== "string") {
|
|
18
|
+
return {
|
|
19
|
+
pass: false,
|
|
20
|
+
message: () => `Expected a string but received ${typeof received}: ${JSON.stringify(received)}`,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const provider = await (0, config_js_1.getProvider)();
|
|
24
|
+
const prompt = buildPrompt(received, expected, options);
|
|
25
|
+
try {
|
|
26
|
+
const { verdict, explanation } = await provider.judge(prompt);
|
|
27
|
+
return {
|
|
28
|
+
pass: verdict,
|
|
29
|
+
message: () => {
|
|
30
|
+
if (verdict) {
|
|
31
|
+
return `Expected "${received}" NOT to semantically match "${expected}"\n\nLLM reasoning: ${explanation}`;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
return `Expected "${received}" to semantically match "${expected}"\n\nLLM reasoning: ${explanation}`;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return {
|
|
41
|
+
pass: false,
|
|
42
|
+
message: () => `Failed to evaluate semantic match: ${error instanceof Error ? error.message : String(error)}`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=toSemanticallyMatch.js.map
|
|
@@ -0,0 +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,OAAO,CAAC,CAAC,CAAC,YAAY,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,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,8 @@
|
|
|
1
|
+
import type { LLMProvider, JudgmentResult } from "../types.js";
|
|
2
|
+
export declare class AnthropicProvider implements LLMProvider {
|
|
3
|
+
private client;
|
|
4
|
+
private constructor();
|
|
5
|
+
static create(): Promise<AnthropicProvider>;
|
|
6
|
+
judge(prompt: string): Promise<JudgmentResult>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -0,0 +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;AAqB/D,qBAAa,iBAAkB,YAAW,WAAW;IACnD,OAAO,CAAC,MAAM,CAAM;IAEpB,OAAO;WAIM,MAAM,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAoB3C,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CAyBrD"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.AnthropicProvider = void 0;
|
|
37
|
+
const JUDGMENT_SCHEMA = {
|
|
38
|
+
type: "json_schema",
|
|
39
|
+
schema: {
|
|
40
|
+
type: "object",
|
|
41
|
+
properties: {
|
|
42
|
+
verdict: {
|
|
43
|
+
type: "boolean",
|
|
44
|
+
description: "true if the condition is satisfied, false otherwise",
|
|
45
|
+
},
|
|
46
|
+
explanation: {
|
|
47
|
+
type: "string",
|
|
48
|
+
description: "Brief explanation of the reasoning",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
required: ["verdict", "explanation"],
|
|
52
|
+
additionalProperties: false,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
class AnthropicProvider {
|
|
56
|
+
client;
|
|
57
|
+
constructor(client) {
|
|
58
|
+
this.client = client;
|
|
59
|
+
}
|
|
60
|
+
static async create() {
|
|
61
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
62
|
+
if (!apiKey) {
|
|
63
|
+
throw new Error("jest-fuzzy: Missing ANTHROPIC_API_KEY environment variable for claude-haiku-4-5 model");
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const module = await Promise.resolve().then(() => __importStar(require("@anthropic-ai/sdk")));
|
|
67
|
+
const Anthropic = module.default;
|
|
68
|
+
const client = new Anthropic({ apiKey });
|
|
69
|
+
return new AnthropicProvider(client);
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
throw new Error("jest-fuzzy: To use claude-haiku-4-5, install @anthropic-ai/sdk");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async judge(prompt) {
|
|
76
|
+
try {
|
|
77
|
+
const response = await this.client.beta.messages.create({
|
|
78
|
+
model: "claude-haiku-4-5",
|
|
79
|
+
max_tokens: 1024,
|
|
80
|
+
betas: ["structured-outputs-2025-11-13"],
|
|
81
|
+
messages: [{ role: "user", content: prompt }],
|
|
82
|
+
output_format: JUDGMENT_SCHEMA,
|
|
83
|
+
});
|
|
84
|
+
const text = response.content[0].text;
|
|
85
|
+
const parsed = JSON.parse(text);
|
|
86
|
+
return { verdict: parsed.verdict, explanation: parsed.explanation };
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
throw new Error(`jest-fuzzy: LLM API call failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.AnthropicProvider = AnthropicProvider;
|
|
94
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/providers/anthropic.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,MAAM,eAAe,GAAG;IACtB,IAAI,EAAE,aAAsB;IAC5B,MAAM,EAAE;QACN,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,IAAI,EAAE,SAAkB;gBACxB,WAAW,EAAE,qDAAqD;aACnE;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAiB;gBACvB,WAAW,EAAE,oCAAoC;aAClD;SACF;QACD,QAAQ,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC;QACpC,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAEF,MAAa,iBAAiB;IACpB,MAAM,CAAM;IAEpB,YAAoB,MAAW;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM;QACjB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,uFAAuF,CACxF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,wDAAa,mBAAmB,GAAC,CAAC;YACjD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC;YACjC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;YACzC,OAAO,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAc;QACxB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACtD,KAAK,EAAE,kBAAkB;gBACzB,UAAU,EAAE,IAAI;gBAChB,KAAK,EAAE,CAAC,+BAA+B,CAAC;gBACxC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;gBAC7C,aAAa,EAAE,eAAe;aAC/B,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACtC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAG7B,CAAC;YAEF,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;QACtE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,oCACE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AApDD,8CAoDC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LLMProvider, JudgmentResult } from "../types.js";
|
|
2
|
+
export declare class GoogleProvider implements LLMProvider {
|
|
3
|
+
private model;
|
|
4
|
+
private constructor();
|
|
5
|
+
static create(): Promise<GoogleProvider>;
|
|
6
|
+
judge(prompt: string): Promise<JudgmentResult>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=google.d.ts.map
|
|
@@ -0,0 +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;AAE/D,qBAAa,cAAe,YAAW,WAAW;IAChD,OAAO,CAAC,KAAK,CAAM;IAEnB,OAAO;WAIM,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;IAyCxC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CAcrD"}
|