@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,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Temporal Error Types
|
|
3
|
+
* Custom error classes for temporal decision-making components
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Base error class for temporal components
|
|
8
|
+
*/
|
|
9
|
+
export class TemporalError extends Error {
|
|
10
|
+
constructor(message, code, context = {}) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = 'TemporalError';
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.context = context;
|
|
15
|
+
Error.captureStackTrace(this, this.constructor);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Error for human perception time calculations
|
|
21
|
+
*/
|
|
22
|
+
export class PerceptionTimeError extends TemporalError {
|
|
23
|
+
constructor(message, context = {}) {
|
|
24
|
+
super(message, 'PERCEPTION_TIME_ERROR', context);
|
|
25
|
+
this.name = 'PerceptionTimeError';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Error for sequential decision context
|
|
31
|
+
*/
|
|
32
|
+
export class SequentialContextError extends TemporalError {
|
|
33
|
+
constructor(message, context = {}) {
|
|
34
|
+
super(message, 'SEQUENTIAL_CONTEXT_ERROR', context);
|
|
35
|
+
this.name = 'SequentialContextError';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Error for multi-scale aggregation
|
|
41
|
+
*/
|
|
42
|
+
export class MultiScaleError extends TemporalError {
|
|
43
|
+
constructor(message, context = {}) {
|
|
44
|
+
super(message, 'MULTI_SCALE_ERROR', context);
|
|
45
|
+
this.name = 'MultiScaleError';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Error for temporal batch optimization
|
|
51
|
+
*/
|
|
52
|
+
export class TemporalBatchError extends TemporalError {
|
|
53
|
+
constructor(message, context = {}) {
|
|
54
|
+
super(message, 'TEMPORAL_BATCH_ERROR', context);
|
|
55
|
+
this.name = 'TemporalBatchError';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Temporal Note Pruner
|
|
3
|
+
*
|
|
4
|
+
* Prunes irrelevant or low-weight notes to keep prompt context manageable.
|
|
5
|
+
*
|
|
6
|
+
* Research context:
|
|
7
|
+
* - Temporal aggregation research shows older notes should decay
|
|
8
|
+
* - Attention-based weighting shows some notes are more relevant than others
|
|
9
|
+
* - Context compression research shows pruning improves efficiency
|
|
10
|
+
*
|
|
11
|
+
* This implements note pruning based on:
|
|
12
|
+
* - Recency (exponential decay)
|
|
13
|
+
* - Relevance (salience, action, novelty)
|
|
14
|
+
* - Weight thresholds
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// Import calculateAttentionWeight directly (now exported from temporal-decision.mjs)
|
|
18
|
+
import { calculateAttentionWeight } from './temporal-decision.mjs';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Prune temporal notes based on relevance and weight
|
|
22
|
+
*
|
|
23
|
+
* @param {import('./index.mjs').TemporalNote[]} notes - Temporal notes
|
|
24
|
+
* @param {Object} options - Pruning options
|
|
25
|
+
* @param {number} [options.maxNotes=10] - Maximum notes to keep
|
|
26
|
+
* @param {number} [options.minWeight=0.1] - Minimum weight threshold
|
|
27
|
+
* @param {number} [options.currentTime] - Current time (default: Date.now())
|
|
28
|
+
* @param {number} [options.windowSize=10000] - Window size for weight calculation
|
|
29
|
+
* @returns {import('./index.mjs').TemporalNote[]} Pruned notes
|
|
30
|
+
*/
|
|
31
|
+
export function pruneTemporalNotes(notes, options = {}) {
|
|
32
|
+
const {
|
|
33
|
+
maxNotes = 10,
|
|
34
|
+
minWeight = 0.1,
|
|
35
|
+
currentTime = Date.now(),
|
|
36
|
+
windowSize = 10000
|
|
37
|
+
} = options;
|
|
38
|
+
|
|
39
|
+
if (notes.length === 0) return [];
|
|
40
|
+
|
|
41
|
+
const startTime = notes[0].timestamp || currentTime;
|
|
42
|
+
|
|
43
|
+
// Calculate weights for all notes
|
|
44
|
+
const weightedNotes = notes.map(note => {
|
|
45
|
+
const elapsed = note.elapsed || (note.timestamp - startTime);
|
|
46
|
+
const weight = calculateAttentionWeight(note, {
|
|
47
|
+
elapsed,
|
|
48
|
+
windowSize,
|
|
49
|
+
scaleName: 'medium'
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
note,
|
|
54
|
+
weight,
|
|
55
|
+
relevance: calculateRelevance(note, currentTime, startTime)
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Filter by minimum weight
|
|
60
|
+
const aboveThreshold = weightedNotes.filter(w => w.weight >= minWeight);
|
|
61
|
+
|
|
62
|
+
// Sort by weight (descending)
|
|
63
|
+
const sorted = aboveThreshold.sort((a, b) => b.weight - a.weight);
|
|
64
|
+
|
|
65
|
+
// Take top N
|
|
66
|
+
const pruned = sorted.slice(0, maxNotes).map(w => w.note);
|
|
67
|
+
|
|
68
|
+
return pruned;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Calculate relevance score for a note
|
|
73
|
+
*/
|
|
74
|
+
function calculateRelevance(note, currentTime, startTime) {
|
|
75
|
+
let relevance = 1.0;
|
|
76
|
+
|
|
77
|
+
// Recency (exponential decay)
|
|
78
|
+
const age = currentTime - (note.timestamp || startTime);
|
|
79
|
+
const recency = Math.pow(0.9, age / 10000); // Decay over 10s
|
|
80
|
+
relevance *= recency;
|
|
81
|
+
|
|
82
|
+
// Salience (importance)
|
|
83
|
+
const score = note.score || note.gameState?.score || 5;
|
|
84
|
+
if (score >= 8 || score <= 2) {
|
|
85
|
+
relevance *= 1.5; // High/low scores are more relevant
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Issues increase relevance
|
|
89
|
+
if (note.issues && note.issues.length > 0) {
|
|
90
|
+
relevance *= 1.2;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// User actions increase relevance
|
|
94
|
+
if (note.step?.includes('interaction') || note.step?.includes('click')) {
|
|
95
|
+
relevance *= 1.3;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Context changes increase relevance
|
|
99
|
+
if (note.observation?.includes('change') || note.observation?.includes('new')) {
|
|
100
|
+
relevance *= 1.2;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return relevance;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Propagate notes forward with decay
|
|
108
|
+
*
|
|
109
|
+
* @param {import('./index.mjs').TemporalNote[]} notes - Temporal notes
|
|
110
|
+
* @param {Object} options - Propagation options
|
|
111
|
+
* @param {number} [options.currentTime] - Current time
|
|
112
|
+
* @param {number} [options.relevanceThreshold=0.2] - Minimum relevance to keep
|
|
113
|
+
* @returns {import('./index.mjs').TemporalNote[]} Propagated notes with updated weights
|
|
114
|
+
*/
|
|
115
|
+
export function propagateNotes(notes, options = {}) {
|
|
116
|
+
const {
|
|
117
|
+
currentTime = Date.now(),
|
|
118
|
+
relevanceThreshold = 0.2
|
|
119
|
+
} = options;
|
|
120
|
+
|
|
121
|
+
if (notes.length === 0) return [];
|
|
122
|
+
|
|
123
|
+
const startTime = notes[0].timestamp || currentTime;
|
|
124
|
+
|
|
125
|
+
return notes
|
|
126
|
+
.map(note => {
|
|
127
|
+
const relevance = calculateRelevance(note, currentTime, startTime);
|
|
128
|
+
const weight = Math.pow(0.9, (currentTime - (note.timestamp || startTime)) / 10000);
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
...note,
|
|
132
|
+
weight,
|
|
133
|
+
relevance,
|
|
134
|
+
propagated: true
|
|
135
|
+
};
|
|
136
|
+
})
|
|
137
|
+
.filter(note => note.relevance >= relevanceThreshold)
|
|
138
|
+
.sort((a, b) => b.relevance - a.relevance);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Select top-weighted notes for prompt inclusion
|
|
143
|
+
*
|
|
144
|
+
* @param {import('./index.mjs').TemporalNote[]} notes - Temporal notes
|
|
145
|
+
* @param {Object} options - Selection options
|
|
146
|
+
* @param {number} [options.topN=5] - Number of top notes to select
|
|
147
|
+
* @returns {import('./index.mjs').TemporalNote[]} Top-weighted notes
|
|
148
|
+
*/
|
|
149
|
+
export function selectTopWeightedNotes(notes, options = {}) {
|
|
150
|
+
const { topN = 5 } = options;
|
|
151
|
+
|
|
152
|
+
if (notes.length === 0) return [];
|
|
153
|
+
|
|
154
|
+
const currentTime = Date.now();
|
|
155
|
+
const startTime = notes[0].timestamp || currentTime;
|
|
156
|
+
|
|
157
|
+
const weighted = notes.map(note => {
|
|
158
|
+
const elapsed = note.elapsed || (note.timestamp - startTime);
|
|
159
|
+
const weight = calculateAttentionWeight(note, {
|
|
160
|
+
elapsed,
|
|
161
|
+
windowSize: 10000,
|
|
162
|
+
scaleName: 'medium'
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
return { note, weight };
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
return weighted
|
|
169
|
+
.sort((a, b) => b.weight - a.weight)
|
|
170
|
+
.slice(0, topN)
|
|
171
|
+
.map(w => w.note);
|
|
172
|
+
}
|
|
173
|
+
|