llm-assert 1.0.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 +335 -0
- package/dist/cache/cache-manager.d.ts +15 -0
- package/dist/cache/cache-manager.d.ts.map +1 -0
- package/dist/cache/cache-manager.js +39 -0
- package/dist/cache/cache-manager.js.map +1 -0
- package/dist/cache/file-cache.d.ts +13 -0
- package/dist/cache/file-cache.d.ts.map +1 -0
- package/dist/cache/file-cache.js +90 -0
- package/dist/cache/file-cache.js.map +1 -0
- package/dist/config/config-loader.d.ts +6 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +46 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/config/defaults.d.ts +15 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +15 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/core/assertion-result.d.ts +26 -0
- package/dist/core/assertion-result.d.ts.map +1 -0
- package/dist/core/assertion-result.js +38 -0
- package/dist/core/assertion-result.js.map +1 -0
- package/dist/core/assertion-runner.d.ts +29 -0
- package/dist/core/assertion-runner.d.ts.map +1 -0
- package/dist/core/assertion-runner.js +82 -0
- package/dist/core/assertion-runner.js.map +1 -0
- package/dist/core/llm-expect.d.ts +16 -0
- package/dist/core/llm-expect.d.ts.map +1 -0
- package/dist/core/llm-expect.js +111 -0
- package/dist/core/llm-expect.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/jest-matchers.d.ts +18 -0
- package/dist/integrations/jest-matchers.d.ts.map +1 -0
- package/dist/integrations/jest-matchers.js +54 -0
- package/dist/integrations/jest-matchers.js.map +1 -0
- package/dist/integrations/vitest-matchers.d.ts +2 -0
- package/dist/integrations/vitest-matchers.d.ts.map +1 -0
- package/dist/integrations/vitest-matchers.js +54 -0
- package/dist/integrations/vitest-matchers.js.map +1 -0
- package/dist/matchers/factual.d.ts +2 -0
- package/dist/matchers/factual.d.ts.map +1 -0
- package/dist/matchers/factual.js +26 -0
- package/dist/matchers/factual.js.map +1 -0
- package/dist/matchers/hallucination.d.ts +2 -0
- package/dist/matchers/hallucination.d.ts.map +1 -0
- package/dist/matchers/hallucination.js +28 -0
- package/dist/matchers/hallucination.js.map +1 -0
- package/dist/matchers/index.d.ts +8 -0
- package/dist/matchers/index.d.ts.map +1 -0
- package/dist/matchers/index.js +18 -0
- package/dist/matchers/index.js.map +1 -0
- package/dist/matchers/relevance.d.ts +2 -0
- package/dist/matchers/relevance.d.ts.map +1 -0
- package/dist/matchers/relevance.js +23 -0
- package/dist/matchers/relevance.js.map +1 -0
- package/dist/matchers/safety.d.ts +2 -0
- package/dist/matchers/safety.d.ts.map +1 -0
- package/dist/matchers/safety.js +25 -0
- package/dist/matchers/safety.js.map +1 -0
- package/dist/matchers/satisfy.d.ts +2 -0
- package/dist/matchers/satisfy.d.ts.map +1 -0
- package/dist/matchers/satisfy.js +23 -0
- package/dist/matchers/satisfy.js.map +1 -0
- package/dist/matchers/sentiment.d.ts +2 -0
- package/dist/matchers/sentiment.d.ts.map +1 -0
- package/dist/matchers/sentiment.js +24 -0
- package/dist/matchers/sentiment.js.map +1 -0
- package/dist/matchers/tone.d.ts +2 -0
- package/dist/matchers/tone.d.ts.map +1 -0
- package/dist/matchers/tone.js +24 -0
- package/dist/matchers/tone.js.map +1 -0
- package/dist/providers/anthropic-provider.d.ts +8 -0
- package/dist/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/providers/anthropic-provider.js +100 -0
- package/dist/providers/anthropic-provider.js.map +1 -0
- package/dist/providers/base-provider.d.ts +23 -0
- package/dist/providers/base-provider.d.ts.map +1 -0
- package/dist/providers/base-provider.js +22 -0
- package/dist/providers/base-provider.js.map +1 -0
- package/dist/providers/index.d.ts +4 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +23 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/ollama-provider.d.ts +9 -0
- package/dist/providers/ollama-provider.d.ts.map +1 -0
- package/dist/providers/ollama-provider.js +67 -0
- package/dist/providers/ollama-provider.js.map +1 -0
- package/dist/providers/openai-provider.d.ts +8 -0
- package/dist/providers/openai-provider.d.ts.map +1 -0
- package/dist/providers/openai-provider.js +106 -0
- package/dist/providers/openai-provider.js.map +1 -0
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +12 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +18 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 llm-assert contributors
|
|
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,335 @@
|
|
|
1
|
+
# llm-assert
|
|
2
|
+
|
|
3
|
+
> Semantic AI assertions for Jest and Vitest. Test LLM outputs with `expect()`-style syntax.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/llm-assert)
|
|
6
|
+
[](https://github.com/llm-assert/llm-assert/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
import { llmExpect } from "llm-assert";
|
|
10
|
+
|
|
11
|
+
test("customer service reply is relevant and professional", async () => {
|
|
12
|
+
const reply = await getAIResponse("How do I get a refund?");
|
|
13
|
+
await llmExpect(reply).toBeRelevantTo("refund policy");
|
|
14
|
+
await llmExpect(reply).toMatchTone("professional and empathetic");
|
|
15
|
+
await llmExpect(reply).not.toContainHallucination({ context: refundDocs });
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Why llm-assert?
|
|
20
|
+
|
|
21
|
+
Testing AI outputs is hard. You can't use `expect(output).toBe("exact string")` when the response varies every time. Existing tools are either Python-only, platform-specific, or require a separate CLI workflow.
|
|
22
|
+
|
|
23
|
+
**llm-assert** drops into your existing Jest or Vitest test suite with zero friction:
|
|
24
|
+
|
|
25
|
+
- **Familiar API** -- if you know `expect().toBe()`, you know `llmExpect().toBeRelevantTo()`
|
|
26
|
+
- **Zero config to start** -- set `OPENAI_API_KEY` and go
|
|
27
|
+
- **No vendor lock-in** -- supports OpenAI, Anthropic, and free local models via Ollama
|
|
28
|
+
- **Cost-aware** -- built-in caching so you don't burn API credits on every test run
|
|
29
|
+
- **Production-ready** -- clear error messages, timeout handling, per-assertion overrides
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install llm-assert --save-dev
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Set your API key:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
export OPENAI_API_KEY=sk-...
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or use Ollama for free local inference (no API key needed):
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Install Ollama from https://ollama.ai, then:
|
|
47
|
+
ollama pull llama3
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
`llmExpect()` works with any test runner. It throws on failure, which Jest/Vitest catch automatically:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { llmExpect } from "llm-assert";
|
|
56
|
+
|
|
57
|
+
test("AI summary is relevant", async () => {
|
|
58
|
+
const summary = await myAI.summarize(article);
|
|
59
|
+
await llmExpect(summary).toBeRelevantTo("climate change");
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
No setup file needed. No custom matchers to register. Just import and use.
|
|
64
|
+
|
|
65
|
+
## All Assertions
|
|
66
|
+
|
|
67
|
+
### `toBeRelevantTo(topic: string)`
|
|
68
|
+
|
|
69
|
+
Checks if the text is semantically relevant to a topic.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
await llmExpect("We process refunds within 5-7 days.").toBeRelevantTo("refund policy");
|
|
73
|
+
// PASSES
|
|
74
|
+
|
|
75
|
+
await llmExpect("Our office is in New York.").toBeRelevantTo("refund policy");
|
|
76
|
+
// FAILS -- not relevant
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### `toMatchTone(tone: string)`
|
|
80
|
+
|
|
81
|
+
Checks if the text matches an expected tone.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
await llmExpect("Dear customer, we sincerely apologize.").toMatchTone("professional, empathetic");
|
|
85
|
+
// PASSES
|
|
86
|
+
|
|
87
|
+
await llmExpect("lol idk just deal with it").toMatchTone("professional");
|
|
88
|
+
// FAILS
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `toContainHallucination(options?)`
|
|
92
|
+
|
|
93
|
+
Checks for fabricated information. Typically used with `.not`:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
const context = "Our company was founded in 2015 in Austin, Texas.";
|
|
97
|
+
const response = "The company was founded in 2015 in Austin, Texas by John Smith.";
|
|
98
|
+
|
|
99
|
+
await llmExpect(response).not.toContainHallucination({ context });
|
|
100
|
+
// FAILS -- "John Smith" is hallucinated
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### `toBeFactuallyCorrect(options?)`
|
|
104
|
+
|
|
105
|
+
Checks factual accuracy against context or general knowledge.
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
await llmExpect("Water boils at 100°C at sea level.").toBeFactuallyCorrect();
|
|
109
|
+
// PASSES
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### `toSatisfy(criteria: string)`
|
|
113
|
+
|
|
114
|
+
The flexible escape hatch. Pass any natural language criteria:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
await llmExpect(response).toSatisfy("contains a call-to-action and mentions pricing");
|
|
118
|
+
await llmExpect(response).toSatisfy("is written in valid markdown format");
|
|
119
|
+
await llmExpect(response).toSatisfy("answers the question without being condescending");
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### `toHaveSentiment(sentiment: string)`
|
|
123
|
+
|
|
124
|
+
Checks the emotional sentiment.
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
await llmExpect("This product is amazing!").toHaveSentiment("positive");
|
|
128
|
+
await llmExpect("I'm very disappointed.").toHaveSentiment("negative");
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### `toBeSafe(options?)`
|
|
132
|
+
|
|
133
|
+
Checks for harmful content (hate speech, PII leakage, prompt injection, etc.):
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
await llmExpect(response).toBeSafe();
|
|
137
|
+
|
|
138
|
+
// With custom categories:
|
|
139
|
+
await llmExpect(response).toBeSafe({
|
|
140
|
+
categories: ["pii_leakage", "prompt_injection"],
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Negation
|
|
145
|
+
|
|
146
|
+
All matchers support `.not`:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
await llmExpect(response).not.toContainHallucination({ context });
|
|
150
|
+
await llmExpect(response).not.toMatchTone("aggressive");
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Configuration
|
|
154
|
+
|
|
155
|
+
### Programmatic (recommended for test setups)
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// jest.setup.ts or vitest.setup.ts
|
|
159
|
+
import { configureLLMAssert } from "llm-assert";
|
|
160
|
+
|
|
161
|
+
configureLLMAssert({
|
|
162
|
+
provider: "openai", // "openai" | "anthropic" | "ollama"
|
|
163
|
+
model: "gpt-4o-mini",
|
|
164
|
+
cache: true,
|
|
165
|
+
verbose: false,
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Environment variables
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
LLM_ASSERT_PROVIDER=openai
|
|
173
|
+
LLM_ASSERT_MODEL=gpt-4o-mini
|
|
174
|
+
OPENAI_API_KEY=sk-...
|
|
175
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
176
|
+
LLM_ASSERT_CACHE=true
|
|
177
|
+
LLM_ASSERT_VERBOSE=false
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Per-assertion overrides
|
|
181
|
+
|
|
182
|
+
Every matcher accepts an options object:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
await llmExpect(text).toBeRelevantTo("topic", {
|
|
186
|
+
threshold: 0.9, // stricter than default 0.7
|
|
187
|
+
model: "gpt-4o", // use a better model for this check
|
|
188
|
+
provider: "anthropic", // use a different provider
|
|
189
|
+
timeout: 60000, // longer timeout
|
|
190
|
+
cache: false, // skip cache for this assertion
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Providers
|
|
195
|
+
|
|
196
|
+
### OpenAI (default)
|
|
197
|
+
|
|
198
|
+
Uses `gpt-4o-mini` by default. Set `OPENAI_API_KEY` or pass via config.
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
configureLLMAssert({ provider: "openai", model: "gpt-4o" });
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Anthropic
|
|
205
|
+
|
|
206
|
+
Uses `claude-sonnet-4-20250514` by default. Set `ANTHROPIC_API_KEY`.
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
configureLLMAssert({ provider: "anthropic" });
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Ollama (free, local)
|
|
213
|
+
|
|
214
|
+
No API key needed. Requires [Ollama](https://ollama.ai) running locally.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
configureLLMAssert({
|
|
218
|
+
provider: "ollama",
|
|
219
|
+
model: "llama3",
|
|
220
|
+
ollamaBaseUrl: "http://localhost:11434", // default
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Caching
|
|
225
|
+
|
|
226
|
+
By default, `llm-assert` caches LLM responses to avoid redundant API calls. Cache is stored in `.llm-assert-cache/` and keyed on: assertion type + input text + criteria + model name.
|
|
227
|
+
|
|
228
|
+
Add `.llm-assert-cache/` to your `.gitignore`.
|
|
229
|
+
|
|
230
|
+
Cache entries expire after 7 days. Clear manually:
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
import { clearLLMAssertCache } from "llm-assert";
|
|
234
|
+
await clearLLMAssertCache();
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Jest Integration
|
|
238
|
+
|
|
239
|
+
### Option 1: Use `llmExpect()` directly (no setup needed)
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import { llmExpect } from "llm-assert";
|
|
243
|
+
|
|
244
|
+
test("AI response quality", async () => {
|
|
245
|
+
await llmExpect(response).toBeRelevantTo("topic");
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Option 2: Extend Jest's `expect` with `toLLMMatch`
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
// jest.setup.ts
|
|
253
|
+
import "llm-assert/jest";
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
```javascript
|
|
257
|
+
// jest.config.js
|
|
258
|
+
module.exports = {
|
|
259
|
+
setupFilesAfterSetup: ["./jest.setup.ts"],
|
|
260
|
+
};
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
// In your tests:
|
|
265
|
+
await expect(response).toLLMMatch({
|
|
266
|
+
relevantTo: "refund policy",
|
|
267
|
+
tone: "professional",
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Vitest Integration
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
// vitest.setup.ts
|
|
275
|
+
import "llm-assert/vitest";
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Error Messages
|
|
279
|
+
|
|
280
|
+
Failed assertions produce clear, actionable errors:
|
|
281
|
+
|
|
282
|
+
```
|
|
283
|
+
LLMAssertionError: toBeRelevantTo
|
|
284
|
+
|
|
285
|
+
Expected: text to be relevant to "refund policy"
|
|
286
|
+
Received: "Our office hours are 9am to 5pm Monday through Friday."
|
|
287
|
+
|
|
288
|
+
Score: 0.15 / 0.70 (threshold)
|
|
289
|
+
Reasoning: The text discusses office hours, which is unrelated to
|
|
290
|
+
refund policies, return processes, or money-back guarantees.
|
|
291
|
+
|
|
292
|
+
Provider: openai (gpt-4o-mini)
|
|
293
|
+
Cached: false
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## API Reference
|
|
297
|
+
|
|
298
|
+
### Functions
|
|
299
|
+
|
|
300
|
+
| Function | Description |
|
|
301
|
+
|----------|-------------|
|
|
302
|
+
| `llmExpect(text)` | Create a semantic assertion on text |
|
|
303
|
+
| `configureLLMAssert(config)` | Set global configuration |
|
|
304
|
+
| `defineConfig(config)` | Helper for config files |
|
|
305
|
+
| `clearLLMAssertCache()` | Clear all cached results |
|
|
306
|
+
|
|
307
|
+
### Types
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
interface LLMAssertConfig {
|
|
311
|
+
provider: string; // "openai" | "anthropic" | "ollama"
|
|
312
|
+
model: string; // model name
|
|
313
|
+
apiKey?: string; // API key
|
|
314
|
+
ollamaBaseUrl?: string; // Ollama URL (default: http://localhost:11434)
|
|
315
|
+
defaultThreshold: number; // global threshold (default: 0.7)
|
|
316
|
+
timeout: number; // ms (default: 30000)
|
|
317
|
+
maxRetries: number; // retry count (default: 2)
|
|
318
|
+
cache: boolean; // enable caching (default: true)
|
|
319
|
+
cacheDir: string; // cache directory (default: .llm-assert-cache)
|
|
320
|
+
cacheTTL: number; // cache TTL in ms (default: 7 days)
|
|
321
|
+
verbose: boolean; // verbose logging (default: false)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
interface AssertionOptions {
|
|
325
|
+
threshold?: number;
|
|
326
|
+
model?: string;
|
|
327
|
+
provider?: string;
|
|
328
|
+
cache?: boolean;
|
|
329
|
+
timeout?: number;
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## License
|
|
334
|
+
|
|
335
|
+
MIT
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class CacheManager {
|
|
2
|
+
private fileCache;
|
|
3
|
+
constructor();
|
|
4
|
+
get(assertionType: string, actual: string, criteria: string, model: string): Promise<{
|
|
5
|
+
score: number;
|
|
6
|
+
pass: boolean;
|
|
7
|
+
reasoning: string;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
} | null>;
|
|
10
|
+
set(assertionType: string, actual: string, criteria: string, model: string, data: Record<string, unknown>): Promise<void>;
|
|
11
|
+
clear(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare function getCacheManager(): CacheManager;
|
|
14
|
+
export declare function clearLLMAssertCache(): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=cache-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-manager.d.ts","sourceRoot":"","sources":["../../src/cache/cache-manager.ts"],"names":[],"mappings":"AAKA,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAY;;IAMvB,GAAG,CACP,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAOxF,GAAG,CACP,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC;IAKV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED,wBAAgB,eAAe,IAAI,YAAY,CAK9C;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAGzD"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CacheManager = void 0;
|
|
4
|
+
exports.getCacheManager = getCacheManager;
|
|
5
|
+
exports.clearLLMAssertCache = clearLLMAssertCache;
|
|
6
|
+
const file_cache_1 = require("./file-cache");
|
|
7
|
+
const hash_1 = require("../utils/hash");
|
|
8
|
+
let cacheInstance = null;
|
|
9
|
+
class CacheManager {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.fileCache = new file_cache_1.FileCache();
|
|
12
|
+
}
|
|
13
|
+
async get(assertionType, actual, criteria, model) {
|
|
14
|
+
const key = (0, hash_1.computeHash)(assertionType, actual, criteria, model);
|
|
15
|
+
const entry = await this.fileCache.get(key);
|
|
16
|
+
if (!entry)
|
|
17
|
+
return null;
|
|
18
|
+
return entry.data;
|
|
19
|
+
}
|
|
20
|
+
async set(assertionType, actual, criteria, model, data) {
|
|
21
|
+
const key = (0, hash_1.computeHash)(assertionType, actual, criteria, model);
|
|
22
|
+
await this.fileCache.set(key, data);
|
|
23
|
+
}
|
|
24
|
+
async clear() {
|
|
25
|
+
await this.fileCache.clear();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.CacheManager = CacheManager;
|
|
29
|
+
function getCacheManager() {
|
|
30
|
+
if (!cacheInstance) {
|
|
31
|
+
cacheInstance = new CacheManager();
|
|
32
|
+
}
|
|
33
|
+
return cacheInstance;
|
|
34
|
+
}
|
|
35
|
+
async function clearLLMAssertCache() {
|
|
36
|
+
const cache = getCacheManager();
|
|
37
|
+
await cache.clear();
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=cache-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-manager.js","sourceRoot":"","sources":["../../src/cache/cache-manager.ts"],"names":[],"mappings":";;;AAwCA,0CAKC;AAED,kDAGC;AAlDD,6CAAyC;AACzC,wCAA4C;AAE5C,IAAI,aAAa,GAAwB,IAAI,CAAC;AAE9C,MAAa,YAAY;IAGvB;QACE,IAAI,CAAC,SAAS,GAAG,IAAI,sBAAS,EAAE,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,GAAG,CACP,aAAqB,EACrB,MAAc,EACd,QAAgB,EAChB,KAAa;QAEb,MAAM,GAAG,GAAG,IAAA,kBAAW,EAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,OAAO,KAAK,CAAC,IAAmF,CAAC;IACnG,CAAC;IAED,KAAK,CAAC,GAAG,CACP,aAAqB,EACrB,MAAc,EACd,QAAgB,EAChB,KAAa,EACb,IAA6B;QAE7B,MAAM,GAAG,GAAG,IAAA,kBAAW,EAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAChE,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;CACF;AAjCD,oCAiCC;AAED,SAAgB,eAAe;IAC7B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,aAAa,GAAG,IAAI,YAAY,EAAE,CAAC;IACrC,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAEM,KAAK,UAAU,mBAAmB;IACvC,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface CacheEntry {
|
|
2
|
+
timestamp: number;
|
|
3
|
+
data: Record<string, unknown>;
|
|
4
|
+
}
|
|
5
|
+
export declare class FileCache {
|
|
6
|
+
private getDir;
|
|
7
|
+
private ensureDir;
|
|
8
|
+
private filePath;
|
|
9
|
+
get(key: string): Promise<CacheEntry | null>;
|
|
10
|
+
set(key: string, data: Record<string, unknown>): Promise<void>;
|
|
11
|
+
clear(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=file-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-cache.d.ts","sourceRoot":"","sources":["../../src/cache/file-cache.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,QAAQ;IAIV,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAoB5C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAW7B"}
|
|
@@ -0,0 +1,90 @@
|
|
|
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.FileCache = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const config_loader_1 = require("../config/config-loader");
|
|
40
|
+
class FileCache {
|
|
41
|
+
getDir() {
|
|
42
|
+
return path.resolve((0, config_loader_1.getConfig)().cacheDir);
|
|
43
|
+
}
|
|
44
|
+
ensureDir() {
|
|
45
|
+
const dir = this.getDir();
|
|
46
|
+
if (!fs.existsSync(dir)) {
|
|
47
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
filePath(key) {
|
|
51
|
+
return path.join(this.getDir(), `${key}.json`);
|
|
52
|
+
}
|
|
53
|
+
async get(key) {
|
|
54
|
+
const fp = this.filePath(key);
|
|
55
|
+
try {
|
|
56
|
+
if (!fs.existsSync(fp))
|
|
57
|
+
return null;
|
|
58
|
+
const raw = fs.readFileSync(fp, 'utf-8');
|
|
59
|
+
const entry = JSON.parse(raw);
|
|
60
|
+
// Check TTL
|
|
61
|
+
const ttl = (0, config_loader_1.getConfig)().cacheTTL;
|
|
62
|
+
if (Date.now() - entry.timestamp > ttl) {
|
|
63
|
+
fs.unlinkSync(fp);
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return entry;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async set(key, data) {
|
|
73
|
+
this.ensureDir();
|
|
74
|
+
const entry = { timestamp: Date.now(), data };
|
|
75
|
+
fs.writeFileSync(this.filePath(key), JSON.stringify(entry, null, 2));
|
|
76
|
+
}
|
|
77
|
+
async clear() {
|
|
78
|
+
const dir = this.getDir();
|
|
79
|
+
if (fs.existsSync(dir)) {
|
|
80
|
+
const files = fs.readdirSync(dir);
|
|
81
|
+
for (const file of files) {
|
|
82
|
+
if (file.endsWith('.json')) {
|
|
83
|
+
fs.unlinkSync(path.join(dir, file));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.FileCache = FileCache;
|
|
90
|
+
//# sourceMappingURL=file-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-cache.js","sourceRoot":"","sources":["../../src/cache/file-cache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAC7B,2DAAoD;AAOpD,MAAa,SAAS;IACZ,MAAM;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,IAAA,yBAAS,GAAE,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAEO,SAAS;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAEO,QAAQ,CAAC,GAAW;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YACzC,MAAM,KAAK,GAAe,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAE1C,YAAY;YACZ,MAAM,GAAG,GAAG,IAAA,yBAAS,GAAE,CAAC,QAAQ,CAAC;YACjC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;gBACvC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBAClB,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,IAA6B;QAClD,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,MAAM,KAAK,GAAe,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC;QAC1D,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1B,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC3B,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;CACF;AArDD,8BAqDC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { LLMAssertConfig } from './defaults';
|
|
2
|
+
export declare function configureLLMAssert(config: Partial<LLMAssertConfig>): void;
|
|
3
|
+
export declare function defineConfig(config: Partial<LLMAssertConfig>): Partial<LLMAssertConfig>;
|
|
4
|
+
export declare function getConfig(): LLMAssertConfig;
|
|
5
|
+
export declare function resetConfig(): void;
|
|
6
|
+
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/config/config-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAkB,MAAM,YAAY,CAAC;AAI7D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAEzE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAEvF;AAED,wBAAgB,SAAS,IAAI,eAAe,CAQ3C;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureLLMAssert = configureLLMAssert;
|
|
4
|
+
exports.defineConfig = defineConfig;
|
|
5
|
+
exports.getConfig = getConfig;
|
|
6
|
+
exports.resetConfig = resetConfig;
|
|
7
|
+
const defaults_1 = require("./defaults");
|
|
8
|
+
let userConfig = {};
|
|
9
|
+
function configureLLMAssert(config) {
|
|
10
|
+
userConfig = { ...config };
|
|
11
|
+
}
|
|
12
|
+
function defineConfig(config) {
|
|
13
|
+
return config;
|
|
14
|
+
}
|
|
15
|
+
function getConfig() {
|
|
16
|
+
// Priority: programmatic > env vars > defaults
|
|
17
|
+
const envConfig = loadEnvConfig();
|
|
18
|
+
return {
|
|
19
|
+
...defaults_1.DEFAULT_CONFIG,
|
|
20
|
+
...envConfig,
|
|
21
|
+
...userConfig,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function resetConfig() {
|
|
25
|
+
userConfig = {};
|
|
26
|
+
}
|
|
27
|
+
function loadEnvConfig() {
|
|
28
|
+
const env = {};
|
|
29
|
+
if (process.env.LLM_ASSERT_PROVIDER) {
|
|
30
|
+
env.provider = process.env.LLM_ASSERT_PROVIDER;
|
|
31
|
+
}
|
|
32
|
+
if (process.env.LLM_ASSERT_MODEL) {
|
|
33
|
+
env.model = process.env.LLM_ASSERT_MODEL;
|
|
34
|
+
}
|
|
35
|
+
if (process.env.LLM_ASSERT_API_KEY) {
|
|
36
|
+
env.apiKey = process.env.LLM_ASSERT_API_KEY;
|
|
37
|
+
}
|
|
38
|
+
if (process.env.LLM_ASSERT_CACHE) {
|
|
39
|
+
env.cache = process.env.LLM_ASSERT_CACHE === 'true';
|
|
40
|
+
}
|
|
41
|
+
if (process.env.LLM_ASSERT_VERBOSE) {
|
|
42
|
+
env.verbose = process.env.LLM_ASSERT_VERBOSE === 'true';
|
|
43
|
+
}
|
|
44
|
+
return env;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=config-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/config/config-loader.ts"],"names":[],"mappings":";;AAIA,gDAEC;AAED,oCAEC;AAED,8BAQC;AAED,kCAEC;AAxBD,yCAA6D;AAE7D,IAAI,UAAU,GAA6B,EAAE,CAAC;AAE9C,SAAgB,kBAAkB,CAAC,MAAgC;IACjE,UAAU,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED,SAAgB,YAAY,CAAC,MAAgC;IAC3D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,SAAS;IACvB,+CAA+C;IAC/C,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;IAClC,OAAO;QACL,GAAG,yBAAc;QACjB,GAAG,SAAS;QACZ,GAAG,UAAU;KACd,CAAC;AACJ,CAAC;AAED,SAAgB,WAAW;IACzB,UAAU,GAAG,EAAE,CAAC;AAClB,CAAC;AAED,SAAS,aAAa;IACpB,MAAM,GAAG,GAA6B,EAAE,CAAC;IAEzC,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;QACpC,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACjD,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACjC,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC3C,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;QACnC,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAC9C,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACjC,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,MAAM,CAAC;IACtD,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;QACnC,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,CAAC;IAC1D,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface LLMAssertConfig {
|
|
2
|
+
provider: string;
|
|
3
|
+
model: string;
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
ollamaBaseUrl?: string;
|
|
6
|
+
defaultThreshold: number;
|
|
7
|
+
timeout: number;
|
|
8
|
+
maxRetries: number;
|
|
9
|
+
cache: boolean;
|
|
10
|
+
cacheDir: string;
|
|
11
|
+
cacheTTL: number;
|
|
12
|
+
verbose: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare const DEFAULT_CONFIG: LLMAssertConfig;
|
|
15
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,cAAc,EAAE,eAU5B,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_CONFIG = void 0;
|
|
4
|
+
exports.DEFAULT_CONFIG = {
|
|
5
|
+
provider: 'openai',
|
|
6
|
+
model: 'gpt-4o-mini',
|
|
7
|
+
defaultThreshold: 0.7,
|
|
8
|
+
timeout: 30000,
|
|
9
|
+
maxRetries: 2,
|
|
10
|
+
cache: true,
|
|
11
|
+
cacheDir: '.llm-assert-cache',
|
|
12
|
+
cacheTTL: 7 * 24 * 60 * 60 * 1000, // 7 days in ms
|
|
13
|
+
verbose: false,
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":";;;AAca,QAAA,cAAc,GAAoB;IAC7C,QAAQ,EAAE,QAAQ;IAClB,KAAK,EAAE,aAAa;IACpB,gBAAgB,EAAE,GAAG;IACrB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,CAAC;IACb,KAAK,EAAE,IAAI;IACX,QAAQ,EAAE,mBAAmB;IAC7B,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,eAAe;IAClD,OAAO,EAAE,KAAK;CACf,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface AssertionResult {
|
|
2
|
+
assertionType: string;
|
|
3
|
+
score: number;
|
|
4
|
+
pass: boolean;
|
|
5
|
+
reasoning: string;
|
|
6
|
+
threshold: number;
|
|
7
|
+
actual: string;
|
|
8
|
+
expected: string;
|
|
9
|
+
provider: string;
|
|
10
|
+
model: string;
|
|
11
|
+
cached: boolean;
|
|
12
|
+
extra?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
export declare class LLMAssertionError extends Error {
|
|
15
|
+
readonly assertionType: string;
|
|
16
|
+
readonly score: number;
|
|
17
|
+
readonly threshold: number;
|
|
18
|
+
readonly reasoning: string;
|
|
19
|
+
readonly actual: string;
|
|
20
|
+
readonly expected: string;
|
|
21
|
+
readonly provider: string;
|
|
22
|
+
readonly model: string;
|
|
23
|
+
readonly cached: boolean;
|
|
24
|
+
constructor(result: AssertionResult);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=assertion-result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertion-result.d.ts","sourceRoot":"","sources":["../../src/core/assertion-result.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,SAAgB,aAAa,EAAE,MAAM,CAAC;IACtC,SAAgB,KAAK,EAAE,MAAM,CAAC;IAC9B,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,KAAK,EAAE,MAAM,CAAC;IAC9B,SAAgB,MAAM,EAAE,OAAO,CAAC;gBAEpB,MAAM,EAAE,eAAe;CAcpC"}
|