@arclabs561/ai-visual-test 0.5.1
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/.secretsignore.example +20 -0
- package/CHANGELOG.md +360 -0
- package/CONTRIBUTING.md +63 -0
- package/DEPLOYMENT.md +80 -0
- package/LICENSE +22 -0
- package/README.md +142 -0
- package/SECURITY.md +108 -0
- package/api/health.js +34 -0
- package/api/validate.js +252 -0
- package/index.d.ts +1221 -0
- package/package.json +112 -0
- package/public/index.html +149 -0
- package/src/batch-optimizer.mjs +451 -0
- package/src/bias-detector.mjs +370 -0
- package/src/bias-mitigation.mjs +233 -0
- package/src/cache.mjs +433 -0
- package/src/config.mjs +268 -0
- package/src/constants.mjs +80 -0
- package/src/context-compressor.mjs +350 -0
- package/src/convenience.mjs +617 -0
- package/src/cost-tracker.mjs +257 -0
- package/src/cross-modal-consistency.mjs +170 -0
- package/src/data-extractor.mjs +232 -0
- package/src/dynamic-few-shot.mjs +140 -0
- package/src/dynamic-prompts.mjs +361 -0
- package/src/ensemble/index.mjs +53 -0
- package/src/ensemble-judge.mjs +366 -0
- package/src/error-handler.mjs +67 -0
- package/src/errors.mjs +167 -0
- package/src/experience-propagation.mjs +128 -0
- package/src/experience-tracer.mjs +487 -0
- package/src/explanation-manager.mjs +299 -0
- package/src/feedback-aggregator.mjs +248 -0
- package/src/game-goal-prompts.mjs +478 -0
- package/src/game-player.mjs +548 -0
- package/src/hallucination-detector.mjs +155 -0
- package/src/helpers/playwright.mjs +80 -0
- package/src/human-validation-manager.mjs +516 -0
- package/src/index.mjs +364 -0
- package/src/judge.mjs +929 -0
- package/src/latency-aware-batch-optimizer.mjs +192 -0
- package/src/load-env.mjs +159 -0
- package/src/logger.mjs +55 -0
- package/src/metrics.mjs +187 -0
- package/src/model-tier-selector.mjs +221 -0
- package/src/multi-modal/index.mjs +36 -0
- package/src/multi-modal-fusion.mjs +190 -0
- package/src/multi-modal.mjs +524 -0
- package/src/natural-language-specs.mjs +1071 -0
- package/src/pair-comparison.mjs +277 -0
- package/src/persona/index.mjs +42 -0
- package/src/persona-enhanced.mjs +200 -0
- package/src/persona-experience.mjs +572 -0
- package/src/position-counterbalance.mjs +140 -0
- package/src/prompt-composer.mjs +375 -0
- package/src/render-change-detector.mjs +583 -0
- package/src/research-enhanced-validation.mjs +436 -0
- package/src/retry.mjs +152 -0
- package/src/rubrics.mjs +231 -0
- package/src/score-tracker.mjs +277 -0
- package/src/smart-validator.mjs +447 -0
- package/src/spec-config.mjs +106 -0
- package/src/spec-templates.mjs +347 -0
- package/src/specs/index.mjs +38 -0
- package/src/temporal/index.mjs +102 -0
- package/src/temporal-adaptive.mjs +163 -0
- package/src/temporal-batch-optimizer.mjs +222 -0
- package/src/temporal-constants.mjs +69 -0
- package/src/temporal-context.mjs +49 -0
- package/src/temporal-decision-manager.mjs +271 -0
- package/src/temporal-decision.mjs +669 -0
- package/src/temporal-errors.mjs +58 -0
- package/src/temporal-note-pruner.mjs +173 -0
- package/src/temporal-preprocessor.mjs +543 -0
- package/src/temporal-prompt-formatter.mjs +219 -0
- package/src/temporal-validation.mjs +159 -0
- package/src/temporal.mjs +415 -0
- package/src/type-guards.mjs +311 -0
- package/src/uncertainty-reducer.mjs +470 -0
- package/src/utils/index.mjs +175 -0
- package/src/validation-framework.mjs +321 -0
- package/src/validation-result-normalizer.mjs +64 -0
- package/src/validation.mjs +243 -0
- package/src/validators/accessibility-programmatic.mjs +345 -0
- package/src/validators/accessibility-validator.mjs +223 -0
- package/src/validators/batch-validator.mjs +143 -0
- package/src/validators/hybrid-validator.mjs +268 -0
- package/src/validators/index.mjs +34 -0
- package/src/validators/prompt-builder.mjs +218 -0
- package/src/validators/rubric.mjs +85 -0
- package/src/validators/state-programmatic.mjs +260 -0
- package/src/validators/state-validator.mjs +291 -0
- package/vercel.json +27 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type Guards and Runtime Type Validation
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe runtime checks and type narrowing utilities.
|
|
5
|
+
* These functions enable better static analysis and runtime safety.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { ValidationError } from './errors.mjs';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Type guard: Check if value is a non-null object
|
|
12
|
+
*
|
|
13
|
+
* @template T
|
|
14
|
+
* @param {unknown} value - Value to check
|
|
15
|
+
* @returns {value is Record<string, T>} True if value is a non-null object
|
|
16
|
+
*/
|
|
17
|
+
export function isObject(value) {
|
|
18
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Type guard: Check if value is a string
|
|
23
|
+
*
|
|
24
|
+
* @param {unknown} value - Value to check
|
|
25
|
+
* @returns {value is string} True if value is a string
|
|
26
|
+
*/
|
|
27
|
+
export function isString(value) {
|
|
28
|
+
return typeof value === 'string';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Type guard: Check if value is a number
|
|
33
|
+
*
|
|
34
|
+
* @param {unknown} value - Value to check
|
|
35
|
+
* @returns {value is number} True if value is a number
|
|
36
|
+
*/
|
|
37
|
+
export function isNumber(value) {
|
|
38
|
+
return typeof value === 'number' && !isNaN(value);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Type guard: Check if value is a positive integer
|
|
43
|
+
*
|
|
44
|
+
* @param {unknown} value - Value to check
|
|
45
|
+
* @returns {value is number} True if value is a positive integer
|
|
46
|
+
*/
|
|
47
|
+
export function isPositiveInteger(value) {
|
|
48
|
+
return isNumber(value) && Number.isInteger(value) && value > 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Type guard: Check if value is a non-empty string
|
|
53
|
+
*
|
|
54
|
+
* @param {unknown} value - Value to check
|
|
55
|
+
* @returns {value is string} True if value is a non-empty string
|
|
56
|
+
*/
|
|
57
|
+
export function isNonEmptyString(value) {
|
|
58
|
+
return isString(value) && value.length > 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Type guard: Check if value is an array
|
|
63
|
+
*
|
|
64
|
+
* @template T
|
|
65
|
+
* @param {unknown} value - Value to check
|
|
66
|
+
* @returns {value is T[]} True if value is an array
|
|
67
|
+
*/
|
|
68
|
+
export function isArray(value) {
|
|
69
|
+
return Array.isArray(value);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Type guard: Check if value is a function
|
|
74
|
+
*
|
|
75
|
+
* @param {unknown} value - Value to check
|
|
76
|
+
* @returns {value is Function} True if value is a function
|
|
77
|
+
*/
|
|
78
|
+
export function isFunction(value) {
|
|
79
|
+
return typeof value === 'function';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Type guard: Check if value is a Promise
|
|
84
|
+
*
|
|
85
|
+
* @template T
|
|
86
|
+
* @param {unknown} value - Value to check
|
|
87
|
+
* @returns {value is Promise<T>} True if value is a Promise
|
|
88
|
+
*/
|
|
89
|
+
export function isPromise(value) {
|
|
90
|
+
return value instanceof Promise || (isObject(value) && isFunction(value.then));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Type guard: Check if value is a ValidationResult
|
|
95
|
+
*
|
|
96
|
+
* @param {unknown} value - Value to check
|
|
97
|
+
* @returns {value is import('./index.mjs').ValidationResult} True if value is a ValidationResult
|
|
98
|
+
*/
|
|
99
|
+
export function isValidationResult(value) {
|
|
100
|
+
if (!isObject(value)) return false;
|
|
101
|
+
return (
|
|
102
|
+
typeof value.enabled === 'boolean' &&
|
|
103
|
+
typeof value.provider === 'string' &&
|
|
104
|
+
(value.score === null || isNumber(value.score)) &&
|
|
105
|
+
isArray(value.issues)
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Type guard: Check if value is a ValidationContext
|
|
111
|
+
*
|
|
112
|
+
* @param {unknown} value - Value to check
|
|
113
|
+
* @returns {value is import('./index.mjs').ValidationContext} True if value is a ValidationContext
|
|
114
|
+
*/
|
|
115
|
+
export function isValidationContext(value) {
|
|
116
|
+
if (value === null || value === undefined) return true; // Optional
|
|
117
|
+
if (!isObject(value)) return false;
|
|
118
|
+
|
|
119
|
+
// Check optional properties
|
|
120
|
+
if (value.viewport !== undefined) {
|
|
121
|
+
if (!isObject(value.viewport) ||
|
|
122
|
+
!isNumber(value.viewport.width) ||
|
|
123
|
+
!isNumber(value.viewport.height)) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (value.timeout !== undefined && !isNumber(value.timeout)) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (value.useCache !== undefined && typeof value.useCache !== 'boolean') {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (value.promptBuilder !== undefined && !isFunction(value.promptBuilder)) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Type guard: Check if value is a Persona
|
|
145
|
+
*
|
|
146
|
+
* @param {unknown} value - Value to check
|
|
147
|
+
* @returns {value is import('./index.mjs').Persona} True if value is a Persona
|
|
148
|
+
*/
|
|
149
|
+
export function isPersona(value) {
|
|
150
|
+
if (!isObject(value)) return false;
|
|
151
|
+
return (
|
|
152
|
+
isNonEmptyString(value.name) &&
|
|
153
|
+
isNonEmptyString(value.perspective) &&
|
|
154
|
+
isArray(value.focus)
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Type guard: Check if value is a TemporalNote
|
|
160
|
+
*
|
|
161
|
+
* @param {unknown} value - Value to check
|
|
162
|
+
* @returns {value is import('./index.mjs').TemporalNote} True if value is a TemporalNote
|
|
163
|
+
*/
|
|
164
|
+
export function isTemporalNote(value) {
|
|
165
|
+
if (!isObject(value)) return false;
|
|
166
|
+
|
|
167
|
+
// All properties are optional, but if present must be correct type
|
|
168
|
+
if (value.timestamp !== undefined && !isNumber(value.timestamp)) return false;
|
|
169
|
+
if (value.elapsed !== undefined && !isNumber(value.elapsed)) return false;
|
|
170
|
+
if (value.score !== undefined && value.score !== null && !isNumber(value.score)) return false;
|
|
171
|
+
if (value.observation !== undefined && !isString(value.observation)) return false;
|
|
172
|
+
if (value.step !== undefined && !isString(value.step)) return false;
|
|
173
|
+
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Assert that value is a non-null object, throw if not
|
|
179
|
+
*
|
|
180
|
+
* @template T
|
|
181
|
+
* @param {unknown} value - Value to assert
|
|
182
|
+
* @param {string} [name='value'] - Name for error message
|
|
183
|
+
* @returns {asserts value is Record<string, T>}
|
|
184
|
+
* @throws {ValidationError} If value is not an object
|
|
185
|
+
*/
|
|
186
|
+
export function assertObject(value, name = 'value') {
|
|
187
|
+
if (!isObject(value)) {
|
|
188
|
+
throw new ValidationError(`${name} must be an object`, null, {
|
|
189
|
+
received: typeof value
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Assert that value is a string, throw if not
|
|
196
|
+
*
|
|
197
|
+
* @param {unknown} value - Value to assert
|
|
198
|
+
* @param {string} [name='value'] - Name for error message
|
|
199
|
+
* @returns {asserts value is string}
|
|
200
|
+
* @throws {ValidationError} If value is not a string
|
|
201
|
+
*/
|
|
202
|
+
export function assertString(value, name = 'value') {
|
|
203
|
+
if (!isString(value)) {
|
|
204
|
+
throw new ValidationError(`${name} must be a string`, null, {
|
|
205
|
+
received: typeof value
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Assert that value is a non-empty string, throw if not
|
|
212
|
+
*
|
|
213
|
+
* @param {unknown} value - Value to assert
|
|
214
|
+
* @param {string} [name='value'] - Name for error message
|
|
215
|
+
* @returns {asserts value is string}
|
|
216
|
+
* @throws {ValidationError} If value is not a non-empty string
|
|
217
|
+
*/
|
|
218
|
+
export function assertNonEmptyString(value, name = 'value') {
|
|
219
|
+
assertString(value, name);
|
|
220
|
+
if (value.length === 0) {
|
|
221
|
+
throw new ValidationError(`${name} cannot be empty`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Assert that value is a number, throw if not
|
|
227
|
+
*
|
|
228
|
+
* @param {unknown} value - Value to assert
|
|
229
|
+
* @param {string} [name='value'] - Name for error message
|
|
230
|
+
* @returns {asserts value is number}
|
|
231
|
+
* @throws {ValidationError} If value is not a number
|
|
232
|
+
*/
|
|
233
|
+
export function assertNumber(value, name = 'value') {
|
|
234
|
+
if (!isNumber(value)) {
|
|
235
|
+
throw new ValidationError(`${name} must be a number`, null, {
|
|
236
|
+
received: typeof value
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Assert that value is an array, throw if not
|
|
243
|
+
*
|
|
244
|
+
* @template T
|
|
245
|
+
* @param {unknown} value - Value to assert
|
|
246
|
+
* @param {string} [name='value'] - Name for error message
|
|
247
|
+
* @returns {asserts value is T[]}
|
|
248
|
+
* @throws {ValidationError} If value is not an array
|
|
249
|
+
*/
|
|
250
|
+
export function assertArray(value, name = 'value') {
|
|
251
|
+
if (!isArray(value)) {
|
|
252
|
+
throw new ValidationError(`${name} must be an array`, null, {
|
|
253
|
+
received: typeof value
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Assert that value is a function, throw if not
|
|
260
|
+
*
|
|
261
|
+
* @param {unknown} value - Value to assert
|
|
262
|
+
* @param {string} [name='value'] - Name for error message
|
|
263
|
+
* @returns {asserts value is Function}
|
|
264
|
+
* @throws {ValidationError} If value is not a function
|
|
265
|
+
*/
|
|
266
|
+
export function assertFunction(value, name = 'value') {
|
|
267
|
+
if (!isFunction(value)) {
|
|
268
|
+
throw new ValidationError(`${name} must be a function`, null, {
|
|
269
|
+
received: typeof value
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Narrow type to specific keys of an object
|
|
276
|
+
*
|
|
277
|
+
* @template T
|
|
278
|
+
* @template K
|
|
279
|
+
* @param {T} obj - Object to narrow
|
|
280
|
+
* @param {K[]} keys - Keys to pick
|
|
281
|
+
* @returns {Pick<T, K>} Object with only specified keys
|
|
282
|
+
*/
|
|
283
|
+
export function pick(obj, keys) {
|
|
284
|
+
assertObject(obj, 'obj');
|
|
285
|
+
assertArray(keys, 'keys');
|
|
286
|
+
|
|
287
|
+
const result = {};
|
|
288
|
+
for (const key of keys) {
|
|
289
|
+
if (key in obj) {
|
|
290
|
+
result[key] = obj[key];
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return result;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Type-safe property access with default
|
|
298
|
+
*
|
|
299
|
+
* @template T
|
|
300
|
+
* @template D
|
|
301
|
+
* @param {T} obj - Object to access
|
|
302
|
+
* @param {string} key - Property key
|
|
303
|
+
* @param {D} defaultValue - Default value if property doesn't exist
|
|
304
|
+
* @returns {T[keyof T] | D} Property value or default
|
|
305
|
+
*/
|
|
306
|
+
export function getProperty(obj, key, defaultValue) {
|
|
307
|
+
assertObject(obj, 'obj');
|
|
308
|
+
assertString(key, 'key');
|
|
309
|
+
return key in obj && obj[key] !== undefined ? obj[key] : defaultValue;
|
|
310
|
+
}
|
|
311
|
+
|