@arclabs561/ai-visual-test 0.5.1 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +102 -11
  2. package/DEPLOYMENT.md +225 -9
  3. package/README.md +71 -80
  4. package/index.d.ts +862 -3
  5. package/package.json +10 -51
  6. package/src/batch-optimizer.mjs +39 -0
  7. package/src/cache.mjs +241 -16
  8. package/src/config.mjs +33 -91
  9. package/src/constants.mjs +54 -0
  10. package/src/convenience.mjs +113 -10
  11. package/src/cost-optimization.mjs +1 -0
  12. package/src/cost-tracker.mjs +134 -2
  13. package/src/data-extractor.mjs +36 -7
  14. package/src/dynamic-few-shot.mjs +69 -11
  15. package/src/errors.mjs +6 -2
  16. package/src/experience-propagation.mjs +12 -0
  17. package/src/experience-tracer.mjs +12 -3
  18. package/src/game-player.mjs +222 -43
  19. package/src/graceful-shutdown.mjs +126 -0
  20. package/src/helpers/playwright.mjs +22 -8
  21. package/src/human-validation-manager.mjs +99 -2
  22. package/src/index.mjs +48 -3
  23. package/src/integrations/playwright.mjs +140 -0
  24. package/src/judge.mjs +697 -24
  25. package/src/load-env.mjs +2 -1
  26. package/src/logger.mjs +31 -3
  27. package/src/model-tier-selector.mjs +1 -221
  28. package/src/natural-language-specs.mjs +31 -3
  29. package/src/persona-enhanced.mjs +4 -2
  30. package/src/persona-experience.mjs +1 -1
  31. package/src/pricing.mjs +28 -0
  32. package/src/prompt-composer.mjs +162 -5
  33. package/src/provider-data.mjs +115 -0
  34. package/src/render-change-detector.mjs +5 -0
  35. package/src/research-enhanced-validation.mjs +7 -5
  36. package/src/retry.mjs +21 -7
  37. package/src/rubrics.mjs +4 -0
  38. package/src/safe-logger.mjs +71 -0
  39. package/src/session-cost-tracker.mjs +320 -0
  40. package/src/smart-validator.mjs +8 -8
  41. package/src/spec-templates.mjs +52 -6
  42. package/src/startup-validation.mjs +127 -0
  43. package/src/temporal-adaptive.mjs +2 -2
  44. package/src/temporal-decision-manager.mjs +1 -271
  45. package/src/temporal-logic.mjs +104 -0
  46. package/src/temporal-note-pruner.mjs +119 -0
  47. package/src/temporal-preprocessor.mjs +1 -543
  48. package/src/temporal.mjs +681 -79
  49. package/src/utils/action-hallucination-detector.mjs +301 -0
  50. package/src/utils/baseline-validator.mjs +82 -0
  51. package/src/utils/cache-stats.mjs +104 -0
  52. package/src/utils/cached-llm.mjs +164 -0
  53. package/src/utils/capability-stratifier.mjs +108 -0
  54. package/src/utils/counterfactual-tester.mjs +83 -0
  55. package/src/utils/error-recovery.mjs +117 -0
  56. package/src/utils/explainability-scorer.mjs +119 -0
  57. package/src/utils/exploratory-automation.mjs +131 -0
  58. package/src/utils/index.mjs +10 -0
  59. package/src/utils/intent-recognizer.mjs +201 -0
  60. package/src/utils/log-sanitizer.mjs +165 -0
  61. package/src/utils/path-validator.mjs +88 -0
  62. package/src/utils/performance-logger.mjs +316 -0
  63. package/src/utils/performance-measurement.mjs +280 -0
  64. package/src/utils/prompt-sanitizer.mjs +213 -0
  65. package/src/utils/rate-limiter.mjs +144 -0
  66. package/src/validation-framework.mjs +24 -20
  67. package/src/validation-result-normalizer.mjs +27 -1
  68. package/src/validation.mjs +75 -25
  69. package/src/validators/accessibility-validator.mjs +144 -0
  70. package/src/validators/hybrid-validator.mjs +48 -4
  71. package/api/health.js +0 -34
  72. package/api/validate.js +0 -252
  73. package/public/index.html +0 -149
  74. package/vercel.json +0 -27
@@ -7,10 +7,11 @@
7
7
  * Based on research findings:
8
8
  * - Real-world BDD patterns (Cucumber, SpecFlow, Behave)
9
9
  * - Real-world usage patterns (200+ tests)
10
- * - Best practices (scenario independence, domain language, living documentation)
10
+ * - Practices (scenario independence, domain language, living documentation)
11
11
  */
12
12
 
13
13
  import { log } from './logger.mjs';
14
+ import { ValidationError } from './errors.mjs';
14
15
 
15
16
  /**
16
17
  * Built-in templates for common patterns
@@ -221,7 +222,16 @@ export function createSpecFromTemplate(templateName, variables = {}) {
221
222
  const template = TEMPLATES[templateName];
222
223
 
223
224
  if (!template) {
224
- throw new Error(`Template "${templateName}" not found. Available: ${Object.keys(TEMPLATES).join(', ')}`);
225
+ throw new ValidationError(
226
+ `Template "${templateName}" not found. ` +
227
+ `Available templates: ${Object.keys(TEMPLATES).join(', ')}. ` +
228
+ `Use listTemplates() to see all available templates, or registerTemplate() to create a custom one.`,
229
+ {
230
+ templateName,
231
+ availableTemplates: Object.keys(TEMPLATES),
232
+ function: 'createSpecFromTemplate'
233
+ }
234
+ );
225
235
  }
226
236
 
227
237
  // Merge template variables with provided variables
@@ -251,7 +261,15 @@ export function composeTemplates(templates, composition = 'sequential') {
251
261
  // Parallel: execute all (would need execution framework support)
252
262
  return templates.map(t => t.spec).join('\n\n---\n\n');
253
263
  } else {
254
- throw new Error(`Unknown composition type: ${composition}`);
264
+ throw new ValidationError(
265
+ `Unknown composition type: "${composition}". ` +
266
+ `Supported types: "sequential" (execute one after another) or "parallel" (execute all).`,
267
+ {
268
+ composition,
269
+ supportedTypes: ['sequential', 'parallel'],
270
+ function: 'composeTemplates'
271
+ }
272
+ );
255
273
  }
256
274
  }
257
275
 
@@ -262,7 +280,16 @@ export function inheritTemplate(baseTemplateName, overrides = {}) {
262
280
  const base = TEMPLATES[baseTemplateName];
263
281
 
264
282
  if (!base) {
265
- throw new Error(`Base template "${baseTemplateName}" not found`);
283
+ throw new ValidationError(
284
+ `Base template "${baseTemplateName}" not found. ` +
285
+ `Available templates: ${Object.keys(TEMPLATES).join(', ')}. ` +
286
+ `Use listTemplates() to see all available templates.`,
287
+ {
288
+ baseTemplateName,
289
+ availableTemplates: Object.keys(TEMPLATES),
290
+ function: 'inheritTemplate'
291
+ }
292
+ );
266
293
  }
267
294
 
268
295
  return {
@@ -280,7 +307,17 @@ export function inheritTemplate(baseTemplateName, overrides = {}) {
280
307
  */
281
308
  export function registerTemplate(name, template) {
282
309
  if (!template.name || !template.spec || !template.variables) {
283
- throw new Error('Template must have name, spec, and variables');
310
+ throw new ValidationError(
311
+ 'Template must have name, spec, and variables properties. ' +
312
+ 'Template structure: { name: string, spec: string, variables: object }. ' +
313
+ 'All three properties are required for template registration.',
314
+ {
315
+ hasName: !!template.name,
316
+ hasSpec: !!template.spec,
317
+ hasVariables: !!template.variables,
318
+ function: 'registerTemplate'
319
+ }
320
+ );
284
321
  }
285
322
 
286
323
  TEMPLATES[name] = template;
@@ -304,7 +341,16 @@ export function getTemplate(name) {
304
341
  const template = TEMPLATES[name];
305
342
 
306
343
  if (!template) {
307
- throw new Error(`Template "${name}" not found. Available: ${Object.keys(TEMPLATES).join(', ')}`);
344
+ throw new ValidationError(
345
+ `Template "${name}" not found. ` +
346
+ `Available templates: ${Object.keys(TEMPLATES).join(', ')}. ` +
347
+ `Use listTemplates() to see all available templates, or registerTemplate() to create a custom one.`,
348
+ {
349
+ templateName: name,
350
+ availableTemplates: Object.keys(TEMPLATES),
351
+ function: 'getTemplate'
352
+ }
353
+ );
308
354
  }
309
355
 
310
356
  return template;
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Startup Validation
3
+ *
4
+ * Validates required environment variables and configuration at startup.
5
+ * Provides clear error messages if required configuration is missing.
6
+ */
7
+
8
+ import { ConfigError } from './errors.mjs';
9
+ import { getConfig } from './config.mjs';
10
+ import { warn, error } from './logger.mjs';
11
+
12
+ /**
13
+ * Required environment variables for each provider
14
+ */
15
+ const REQUIRED_ENV_VARS = {
16
+ gemini: ['GEMINI_API_KEY'],
17
+ openai: ['OPENAI_API_KEY'],
18
+ anthropic: ['ANTHROPIC_API_KEY'],
19
+ claude: ['ANTHROPIC_API_KEY'], // Claude uses Anthropic API key
20
+ groq: ['GROQ_API_KEY']
21
+ };
22
+
23
+ /**
24
+ * Validate startup configuration
25
+ *
26
+ * @param {Object} [options={}] - Validation options
27
+ * @param {boolean} [options.strict=true] - If true, throw on missing required vars. If false, warn only.
28
+ * @param {string} [options.provider=null] - Provider to validate (auto-detects if null)
29
+ * @throws {ConfigError} If strict mode and required vars are missing
30
+ */
31
+ export function validateStartup(options = {}) {
32
+ const { strict = true, provider = null } = options;
33
+
34
+ try {
35
+ const config = getConfig();
36
+ const providerToCheck = provider || config.provider;
37
+
38
+ if (!providerToCheck) {
39
+ if (strict) {
40
+ throw new ConfigError(
41
+ 'No provider configured. Set VLM_PROVIDER environment variable or provide provider in config. ' +
42
+ 'Supported providers: gemini, openai, claude, groq. ' +
43
+ 'At least one API key must be set: GEMINI_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY, or GROQ_API_KEY.',
44
+ {
45
+ supportedProviders: ['gemini', 'openai', 'claude', 'groq'],
46
+ requiredEnvVars: ['GEMINI_API_KEY', 'OPENAI_API_KEY', 'ANTHROPIC_API_KEY', 'GROQ_API_KEY']
47
+ }
48
+ );
49
+ } else {
50
+ warn('[StartupValidation] No provider configured. Some features may not work.');
51
+ return { valid: false, warnings: ['No provider configured'] };
52
+ }
53
+ }
54
+
55
+ // Check if provider is valid
56
+ const validProviders = ['gemini', 'openai', 'claude', 'anthropic', 'groq'];
57
+ if (!validProviders.includes(providerToCheck.toLowerCase())) {
58
+ if (strict) {
59
+ throw new ConfigError(
60
+ `Invalid provider: ${providerToCheck}. Supported providers: ${validProviders.join(', ')}.`,
61
+ {
62
+ provided: providerToCheck,
63
+ supported: validProviders
64
+ }
65
+ );
66
+ } else {
67
+ warn(`[StartupValidation] Invalid provider: ${providerToCheck}`);
68
+ return { valid: false, warnings: [`Invalid provider: ${providerToCheck}`] };
69
+ }
70
+ }
71
+
72
+ // Check required API keys for the provider
73
+ const requiredVars = REQUIRED_ENV_VARS[providerToCheck.toLowerCase()] || [];
74
+ const missingVars = requiredVars.filter(key => !process.env[key]);
75
+
76
+ if (missingVars.length > 0) {
77
+ const errorMsg = `Missing required environment variables for provider '${providerToCheck}': ${missingVars.join(', ')}. ` +
78
+ `Set these in your .env file or as environment variables. ` +
79
+ `Example: ${missingVars[0]}=your-api-key-here`;
80
+
81
+ if (strict) {
82
+ throw new ConfigError(errorMsg, {
83
+ provider: providerToCheck,
84
+ missingVars,
85
+ requiredVars
86
+ });
87
+ } else {
88
+ warn(`[StartupValidation] ${errorMsg}`);
89
+ return { valid: false, warnings: [errorMsg] };
90
+ }
91
+ }
92
+
93
+ // Check if config is enabled
94
+ if (!config.enabled) {
95
+ warn('[StartupValidation] VLLM validation is disabled. Set enabled: true in config to enable.');
96
+ return { valid: true, warnings: ['VLLM validation is disabled'] };
97
+ }
98
+
99
+ return { valid: true, warnings: [] };
100
+ } catch (err) {
101
+ if (err instanceof ConfigError) {
102
+ throw err;
103
+ }
104
+
105
+ // Unexpected error
106
+ error('[StartupValidation] Unexpected error during validation:', err);
107
+ if (strict) {
108
+ throw new ConfigError(
109
+ `Startup validation failed: ${err.message}`,
110
+ { originalError: err.message }
111
+ );
112
+ }
113
+ return { valid: false, warnings: [`Validation error: ${err.message}`] };
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Validate startup configuration (non-strict, returns warnings)
119
+ *
120
+ * @param {Object} [options={}] - Validation options
121
+ * @returns {Object} Validation result with valid flag and warnings array
122
+ */
123
+ export function validateStartupSoft(options = {}) {
124
+ return validateStartup({ ...options, strict: false });
125
+ }
126
+
127
+
@@ -127,7 +127,7 @@ export function detectActivityPattern(notes) {
127
127
  * }} [options={}] - Aggregation options
128
128
  * @returns {import('./index.mjs').AggregatedTemporalNotes} Aggregated temporal notes
129
129
  */
130
- export function aggregateTemporalNotesAdaptive(notes, options = {}) {
130
+ export async function aggregateTemporalNotesAdaptive(notes, options = {}) {
131
131
  const {
132
132
  adaptive = true,
133
133
  windowSize,
@@ -152,7 +152,7 @@ export function aggregateTemporalNotesAdaptive(notes, options = {}) {
152
152
  finalWindowSize = 10000; // Default
153
153
  }
154
154
 
155
- return aggregateTemporalNotes(notes, {
155
+ return await aggregateTemporalNotes(notes, {
156
156
  windowSize: finalWindowSize,
157
157
  decayFactor,
158
158
  coherenceThreshold
@@ -1,271 +1 @@
1
- /**
2
- * Temporal Decision Manager
3
- *
4
- * Implements decision logic for WHEN to prompt based on temporal context.
5
- *
6
- * Research: arXiv:2406.12125 - "Efficient Sequential Decision Making"
7
- * - Paper's core finding: Don't prompt on every state change, prompt when decision is needed
8
- * - Online model selection achieves 6x gains with 1.5% LLM calls
9
- *
10
- * This module implements the decision logic (when to prompt) that was missing from
11
- * our temporal aggregation system. It complements temporal-decision.mjs which handles
12
- * HOW to aggregate temporal context, while this handles WHEN to use it.
13
- */
14
-
15
- import { aggregateTemporalNotes } from './temporal.mjs';
16
- import { aggregateMultiScale } from './temporal-decision.mjs';
17
-
18
- /**
19
- * Temporal Decision Manager
20
- *
21
- * Decides when context is sufficient to prompt, when to wait, and when to prompt immediately.
22
- */
23
- export class TemporalDecisionManager {
24
- constructor(options = {}) {
25
- this.minNotesForPrompt = options.minNotesForPrompt || 3; // Minimum notes before prompting
26
- this.coherenceThreshold = options.coherenceThreshold || 0.5; // Minimum coherence to prompt
27
- this.urgencyThreshold = options.urgencyThreshold || 0.3; // Coherence drop triggers urgency
28
- this.maxWaitTime = options.maxWaitTime || 10000; // Max time to wait (10s)
29
- this.stateChangeThreshold = options.stateChangeThreshold || 0.2; // Significant state change
30
- }
31
-
32
- /**
33
- * Decide if we should prompt now or wait for more context
34
- *
35
- * @param {Object} currentState - Current state
36
- * @param {Object} previousState - Previous state (if any)
37
- * @param {import('./index.mjs').TemporalNote[]} temporalNotes - Temporal notes so far
38
- * @param {Object} context - Additional context
39
- * @returns {{shouldPrompt: boolean, reason: string, urgency: 'low'|'medium'|'high'}}
40
- */
41
- shouldPrompt(currentState, previousState, temporalNotes, context = {}) {
42
- // 1. Check if we have minimum notes
43
- if (temporalNotes.length < this.minNotesForPrompt) {
44
- return {
45
- shouldPrompt: false,
46
- reason: `Insufficient notes (${temporalNotes.length} < ${this.minNotesForPrompt})`,
47
- urgency: 'low'
48
- };
49
- }
50
-
51
- // 2. Calculate temporal coherence
52
- const aggregated = aggregateTemporalNotes(temporalNotes);
53
- const coherence = aggregated.coherence || 0;
54
-
55
- // 3. Check for significant state change
56
- const stateChange = this.calculateStateChange(currentState, previousState);
57
-
58
- // 4. Check for user action
59
- const hasUserAction = this.hasRecentUserAction(temporalNotes, context);
60
-
61
- // 5. Check for decision point
62
- const isDecisionPoint = this.isDecisionPoint(currentState, context);
63
-
64
- // 6. Check for coherence drop (urgency signal)
65
- const coherenceDrop = this.detectCoherenceDrop(temporalNotes, aggregated);
66
-
67
- // Decision logic (from research: prompt when decision needed, not on every change)
68
- if (isDecisionPoint) {
69
- return {
70
- shouldPrompt: true,
71
- reason: 'Decision point reached',
72
- urgency: 'high'
73
- };
74
- }
75
-
76
- if (coherenceDrop) {
77
- return {
78
- shouldPrompt: true,
79
- reason: 'Coherence drop detected (quality issue)',
80
- urgency: 'high'
81
- };
82
- }
83
-
84
- if (hasUserAction && stateChange > this.stateChangeThreshold) {
85
- return {
86
- shouldPrompt: true,
87
- reason: 'User action with significant state change',
88
- urgency: 'medium'
89
- };
90
- }
91
-
92
- if (coherence >= this.coherenceThreshold && stateChange > this.stateChangeThreshold) {
93
- return {
94
- shouldPrompt: true,
95
- reason: 'Stable context with significant state change',
96
- urgency: 'medium'
97
- };
98
- }
99
-
100
- // Wait for more context
101
- return {
102
- shouldPrompt: false,
103
- reason: `Context not sufficient (coherence: ${coherence.toFixed(2)}, stateChange: ${stateChange.toFixed(2)})`,
104
- urgency: 'low'
105
- };
106
- }
107
-
108
- /**
109
- * Calculate state change magnitude
110
- */
111
- calculateStateChange(currentState, previousState) {
112
- if (!previousState) return 1.0; // First state = maximum change
113
-
114
- // Simple state change calculation (can be enhanced)
115
- let change = 0.0;
116
- let comparisons = 0;
117
-
118
- // Compare scores if available
119
- if (currentState.score !== undefined && previousState.score !== undefined) {
120
- const scoreChange = Math.abs(currentState.score - previousState.score) / 10; // Normalize to 0-1
121
- change += scoreChange;
122
- comparisons++;
123
- }
124
-
125
- // Compare issues if available
126
- if (currentState.issues && previousState.issues) {
127
- const currentIssues = new Set(currentState.issues);
128
- const previousIssues = new Set(previousState.issues);
129
- const added = [...currentIssues].filter(i => !previousIssues.has(i)).length;
130
- const removed = [...previousIssues].filter(i => !currentIssues.has(i)).length;
131
- const issueChange = (added + removed) / Math.max(currentIssues.size + previousIssues.size, 1);
132
- change += issueChange;
133
- comparisons++;
134
- }
135
-
136
- // Compare game state if available
137
- if (currentState.gameState && previousState.gameState) {
138
- const gameStateChange = this.calculateGameStateChange(currentState.gameState, previousState.gameState);
139
- change += gameStateChange;
140
- comparisons++;
141
- }
142
-
143
- return comparisons > 0 ? change / comparisons : 0.0;
144
- }
145
-
146
- /**
147
- * Calculate game state change
148
- */
149
- calculateGameStateChange(current, previous) {
150
- // Simple comparison (can be enhanced)
151
- const currentKeys = Object.keys(current || {});
152
- const previousKeys = Object.keys(previous || {});
153
-
154
- const added = currentKeys.filter(k => !previousKeys.includes(k)).length;
155
- const removed = previousKeys.filter(k => !currentKeys.includes(k)).length;
156
- const changed = currentKeys.filter(k =>
157
- previousKeys.includes(k) &&
158
- JSON.stringify(current[k]) !== JSON.stringify(previous[k])
159
- ).length;
160
-
161
- const totalKeys = new Set([...currentKeys, ...previousKeys]).size;
162
- return totalKeys > 0 ? (added + removed + changed) / totalKeys : 0.0;
163
- }
164
-
165
- /**
166
- * Check for recent user action
167
- */
168
- hasRecentUserAction(temporalNotes, context) {
169
- if (context.recentAction) return true;
170
-
171
- // Check last few notes for interactions
172
- const recentNotes = temporalNotes.slice(-3);
173
- return recentNotes.some(note =>
174
- note.step?.includes('interaction') ||
175
- note.step?.includes('click') ||
176
- note.step?.includes('action') ||
177
- note.observation?.includes('user') ||
178
- note.observation?.includes('clicked')
179
- );
180
- }
181
-
182
- /**
183
- * Check if this is a decision point
184
- */
185
- isDecisionPoint(currentState, context) {
186
- // Decision points based on context
187
- if (context.stage === 'decision' || context.stage === 'evaluation') return true;
188
- if (context.testType === 'critical' || context.critical) return true;
189
- if (context.goal && context.goalCompleted) return true;
190
-
191
- return false;
192
- }
193
-
194
- /**
195
- * Detect coherence drop (quality issue signal)
196
- */
197
- detectCoherenceDrop(temporalNotes, currentAggregated) {
198
- if (temporalNotes.length < 4) return false; // Need history to detect drop
199
-
200
- // Get previous coherence (from notes without last one)
201
- const previousNotes = temporalNotes.slice(0, -1);
202
- const previousAggregated = aggregateTemporalNotes(previousNotes);
203
- const previousCoherence = previousAggregated.coherence || 1.0;
204
- const currentCoherence = currentAggregated.coherence || 1.0;
205
-
206
- // Drop detected if coherence decreased significantly
207
- const drop = previousCoherence - currentCoherence;
208
- return drop > this.urgencyThreshold;
209
- }
210
-
211
- /**
212
- * Calculate prompt urgency
213
- */
214
- calculatePromptUrgency(temporalContext, decision) {
215
- if (decision.urgency === 'high') return 1.0;
216
- if (decision.urgency === 'medium') return 0.6;
217
-
218
- // Low urgency, but check if we should wait
219
- const coherence = temporalContext.coherence || 0;
220
- const timeSinceLastPrompt = temporalContext.timeSinceLastPrompt || 0;
221
-
222
- // Increase urgency if coherence is good and it's been a while
223
- if (coherence > 0.7 && timeSinceLastPrompt > 5000) {
224
- return 0.4; // Medium-low
225
- }
226
-
227
- return 0.2; // Low
228
- }
229
-
230
- /**
231
- * Select optimal timing for requests
232
- */
233
- selectOptimalTiming(requests, temporalContext) {
234
- const decisions = requests.map(req => ({
235
- request: req,
236
- decision: this.shouldPrompt(
237
- req.currentState,
238
- req.previousState,
239
- req.temporalNotes || [],
240
- req.context || {}
241
- )
242
- }));
243
-
244
- // Separate by urgency
245
- const urgent = decisions.filter(d => d.decision.urgency === 'high');
246
- const medium = decisions.filter(d => d.decision.urgency === 'medium');
247
- const low = decisions.filter(d => d.decision.urgency === 'low');
248
-
249
- // Urgent: prompt immediately
250
- // Medium: batch if context stable, otherwise prompt
251
- // Low: wait or batch
252
-
253
- const stable = temporalContext.coherence > 0.7;
254
- const shouldBatch = stable && medium.length + low.length > 1;
255
-
256
- return {
257
- promptNow: urgent.map(d => d.request),
258
- batch: shouldBatch ? [...medium, ...low].map(d => d.request) : medium.map(d => d.request),
259
- wait: shouldBatch ? [] : low.map(d => d.request),
260
- decisions
261
- };
262
- }
263
- }
264
-
265
- /**
266
- * Create a temporal decision manager with default options
267
- */
268
- export function createTemporalDecisionManager(options = {}) {
269
- return new TemporalDecisionManager(options);
270
- }
271
-
1
+ function _0x2d4d(_0x367a17,_0x47eaad){const _0x5adfe0=_0x1330();return _0x2d4d=function(_0x1196b0,_0x151439){_0x1196b0=_0x1196b0-0xc3;let _0x133077=_0x5adfe0[_0x1196b0];if(_0x2d4d['XbgOSk']===undefined){var _0x2d4df6=function(_0x3769fe){const _0x32d6ed='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x57097e='',_0x5dee23='',_0x59d90b=_0x57097e+_0x2d4df6;for(let _0x172e6e=0x0,_0x4c7830,_0x3ebc52,_0x185993=0x0;_0x3ebc52=_0x3769fe['charAt'](_0x185993++);~_0x3ebc52&&(_0x4c7830=_0x172e6e%0x4?_0x4c7830*0x40+_0x3ebc52:_0x3ebc52,_0x172e6e++%0x4)?_0x57097e+=_0x59d90b['charCodeAt'](_0x185993+0xa)-0xa!==0x0?String['fromCharCode'](0xff&_0x4c7830>>(-0x2*_0x172e6e&0x6)):_0x172e6e:0x0){_0x3ebc52=_0x32d6ed['indexOf'](_0x3ebc52);}for(let _0x29fdfd=0x0,_0x28c0d8=_0x57097e['length'];_0x29fdfd<_0x28c0d8;_0x29fdfd++){_0x5dee23+='%'+('00'+_0x57097e['charCodeAt'](_0x29fdfd)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x5dee23);};_0x2d4d['acpqJo']=_0x2d4df6,_0x367a17=arguments,_0x2d4d['XbgOSk']=!![];}const _0x324b05=_0x5adfe0[0x0],_0x2f9dcc=_0x1196b0+_0x324b05,_0x2c4bad=_0x367a17[_0x2f9dcc];if(!_0x2c4bad){const _0x18f69e=function(_0x42b6fe){this['dTptnW']=_0x42b6fe,this['ILbMRF']=[0x1,0x0,0x0],this['ksCCBd']=function(){return'newState';},this['NruUXV']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['UWVNZS']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x18f69e['prototype']['GEBCWe']=function(){const _0x223615=new RegExp(this['NruUXV']+this['UWVNZS']),_0x12f757=_0x223615['test'](this['ksCCBd']['toString']())?--this['ILbMRF'][0x1]:--this['ILbMRF'][0x0];return this['QXjGly'](_0x12f757);},_0x18f69e['prototype']['QXjGly']=function(_0x4052bb){if(!Boolean(~_0x4052bb))return _0x4052bb;return this['NbqPoa'](this['dTptnW']);},_0x18f69e['prototype']['NbqPoa']=function(_0x3c146f){for(let _0x2df29d=0x0,_0x2e8d8f=this['ILbMRF']['length'];_0x2df29d<_0x2e8d8f;_0x2df29d++){this['ILbMRF']['push'](Math['round'](Math['random']())),_0x2e8d8f=this['ILbMRF']['length'];}return _0x3c146f(this['ILbMRF'][0x0]);},new _0x18f69e(_0x2d4d)['GEBCWe'](),_0x133077=_0x2d4d['acpqJo'](_0x133077),_0x367a17[_0x2f9dcc]=_0x133077;}else _0x133077=_0x2c4bad;return _0x133077;},_0x2d4d(_0x367a17,_0x47eaad);}const _0x15d7dc=_0x2d4d;(function(_0x44ceef,_0x1d47b4){const _0xda4ac2=_0x2d4d,_0x52d929=_0x44ceef();while(!![]){try{const _0x2dbb88=-parseInt(_0xda4ac2(0x162))/0x1+parseInt(_0xda4ac2(0xc8))/0x2*(-parseInt(_0xda4ac2(0xfa))/0x3)+parseInt(_0xda4ac2(0xe0))/0x4+-parseInt(_0xda4ac2(0x108))/0x5+parseInt(_0xda4ac2(0x163))/0x6+-parseInt(_0xda4ac2(0xd0))/0x7+parseInt(_0xda4ac2(0xf2))/0x8*(parseInt(_0xda4ac2(0x152))/0x9);if(_0x2dbb88===_0x1d47b4)break;else _0x52d929['push'](_0x52d929['shift']());}catch(_0x4a003a){_0x52d929['push'](_0x52d929['shift']());}}}(_0x1330,0x5264a));const _0x151439=(function(){let _0x18f69e=!![];return function(_0x42b6fe,_0x223615){const _0x12f757=_0x18f69e?function(){if(_0x223615){const _0x4052bb=_0x223615['apply'](_0x42b6fe,arguments);return _0x223615=null,_0x4052bb;}}:function(){};return _0x18f69e=![],_0x12f757;};}()),_0x1196b0=_0x151439(this,function(){const _0x370a29=_0x2d4d;return _0x1196b0[_0x370a29(0xcf)+'ing']()['searc'+'h']('(((.+'+_0x370a29(0x10e)+'+$')[_0x370a29(0xcf)+_0x370a29(0xe8)]()[_0x370a29(0xde)+'ructo'+'r'](_0x1196b0)['searc'+'h']('(((.+'+_0x370a29(0x10e)+'+$');});_0x1196b0();import{aggregateTemporalNotes}from'./temporal.mjs';import{aggregateMultiScale}from'./temporal-decision.mjs';export class TemporalDecisionManager{constructor(_0x3c146f={}){const _0x553017=_0x2d4d,_0x2df29d=_0x3c146f[_0x553017(0x126)+'tesFo'+'rProm'+'pt']??0x3,_0x2e8d8f=_0x3c146f['coher'+'enceT'+_0x553017(0xc3)+_0x553017(0x10d)]??0.5,_0x278243=_0x3c146f['urgen'+_0x553017(0x167)+'eshol'+'d']??0.3,_0x397e5f=_0x3c146f['maxWa'+'itTim'+'e']??0x2710,_0x2dd172=_0x3c146f[_0x553017(0x15a)+'Chang'+'eThre'+'shold']??0.2;if(_0x2df29d<0x1||!Number['isInt'+'eger'](_0x2df29d))throw new RangeError('minNo'+_0x553017(0x115)+'rProm'+'pt\x20mu'+'st\x20be'+'\x20a\x20po'+'sitiv'+_0x553017(0xf7)+'eger,'+_0x553017(0x13d)+'\x20'+_0x2df29d);if(_0x2e8d8f<0x0||_0x2e8d8f>0x1)throw new RangeError('coher'+_0x553017(0xdf)+_0x553017(0xc3)+_0x553017(0x13f)+'ust\x20b'+'e\x20in\x20'+'[0,\x201'+_0x553017(0x118)+_0x553017(0xe6)+_0x2e8d8f);if(_0x278243<0x0||_0x278243>0x1)throw new RangeError('urgen'+'cyThr'+'eshol'+'d\x20mus'+'t\x20be\x20'+_0x553017(0x133)+',\x201],'+_0x553017(0x13d)+'\x20'+_0x278243);if(_0x397e5f<=0x0||!isFinite(_0x397e5f))throw new RangeError('maxWa'+_0x553017(0xf6)+_0x553017(0x112)+_0x553017(0xd2)+'a\x20pos'+'itive'+_0x553017(0x151)+_0x553017(0x11b)+_0x553017(0x161)+'\x20got:'+'\x20'+_0x397e5f);if(_0x2dd172<0x0||_0x2dd172>0x1)throw new RangeError('state'+_0x553017(0xfb)+'eThre'+'shold'+_0x553017(0xdb)+'\x20be\x20i'+'n\x20[0,'+'\x201],\x20'+'got:\x20'+_0x2dd172);this['minNo'+_0x553017(0x115)+_0x553017(0x168)+'pt']=_0x2df29d,this[_0x553017(0x107)+'enceT'+_0x553017(0xc3)+_0x553017(0x10d)]=_0x2e8d8f,this[_0x553017(0xe4)+_0x553017(0x167)+_0x553017(0x103)+'d']=_0x278243,this[_0x553017(0xce)+'itTim'+'e']=_0x397e5f,this[_0x553017(0x15a)+_0x553017(0xfb)+_0x553017(0x106)+_0x553017(0x147)]=_0x2dd172,this['warmS'+'tartS'+'teps']=_0x3c146f['warmS'+_0x553017(0xdd)+'teps']||0xa,this['adapt'+_0x553017(0xe9)+_0x553017(0x145)+'g']=_0x3c146f[_0x553017(0xd6)+'iveSa'+_0x553017(0x145)+'g']!==![],this[_0x553017(0x127)+_0x553017(0x11a)]=0x0,this[_0x553017(0xc9)+_0x553017(0xe3)+'Time']=null;}async[_0x15d7dc(0x111)+'dProm'+'pt'](_0x106ae2,_0x11a051,_0x5a7512,_0x49ff46={}){const _0x5d7d13=_0x15d7dc;if(!Array['isArr'+'ay'](_0x5a7512))throw new TypeError('tempo'+'ralNo'+_0x5d7d13(0xd5)+'ust\x20b'+'e\x20an\x20'+_0x5d7d13(0xe5));if(_0x106ae2===null||_0x106ae2===undefined)throw new TypeError('curre'+'ntSta'+'te\x20is'+_0x5d7d13(0xfe)+'ired');this[_0x5d7d13(0x127)+_0x5d7d13(0x11a)]++;if(this[_0x5d7d13(0xd6)+_0x5d7d13(0xe9)+_0x5d7d13(0x145)+'g']&&this['stepC'+_0x5d7d13(0x11a)]<=this[_0x5d7d13(0x153)+_0x5d7d13(0xdd)+'teps']){const _0x68c2de={};return _0x68c2de['shoul'+_0x5d7d13(0x157)+'pt']=!![],_0x68c2de[_0x5d7d13(0x14b)+'n']=_0x5d7d13(0x139)+'start'+'\x20step'+'\x20'+this['stepC'+_0x5d7d13(0x11a)]+'/'+this[_0x5d7d13(0x153)+_0x5d7d13(0xdd)+_0x5d7d13(0xe7)]+('\x20(res'+'earch'+':\x20LLM'+'s\x20goo'+'d\x20ear'+'ly)'),_0x68c2de['urgen'+'cy']=_0x5d7d13(0x128)+'m',_0x68c2de;}if(this[_0x5d7d13(0xd6)+_0x5d7d13(0xe9)+_0x5d7d13(0x145)+'g']&&this[_0x5d7d13(0xc9)+'rompt'+_0x5d7d13(0xd1)]){const _0x55f026=0.1,_0x2b724c=0x1,_0x1d73e6=0.1,_0x3db3bd=Math[_0x5d7d13(0xcc)](0x0,this['stepC'+'ount']-this[_0x5d7d13(0x153)+_0x5d7d13(0xdd)+_0x5d7d13(0xe7)]),_0x5ca631=Math[_0x5d7d13(0xf8)](_0x2b724c,Math[_0x5d7d13(0xcc)](_0x1d73e6,Math[_0x5d7d13(0x12f)](-_0x55f026*_0x3db3bd)));this['_last'+'Promp'+_0x5d7d13(0x16d)+'abili'+'ty']=_0x5ca631;}if(_0x5a7512[_0x5d7d13(0xd3)+'h']<this['minNo'+'tesFo'+_0x5d7d13(0x168)+'pt']){const _0x173af1={};return _0x173af1[_0x5d7d13(0x111)+_0x5d7d13(0x157)+'pt']=![],_0x173af1['reaso'+'n']='Insuf'+'ficie'+_0x5d7d13(0xf1)+_0x5d7d13(0x105)+_0x5a7512[_0x5d7d13(0xd3)+'h']+_0x5d7d13(0x132)+this['minNo'+'tesFo'+'rProm'+'pt']+')',_0x173af1[_0x5d7d13(0xe4)+'cy']='low',_0x173af1;}let _0x92df28;this['prepr'+_0x5d7d13(0x141)+'or']?_0x92df28=await this['prepr'+'ocess'+'or']['getFa'+'stAgg'+'regat'+'ion'](_0x5a7512):_0x92df28=await aggregateTemporalNotes(_0x5a7512);const _0x1ed9d4=_0x92df28[_0x5d7d13(0x107)+'ence']||0x0,_0x2b7221=this[_0x5d7d13(0xe1)+_0x5d7d13(0xca)+'tateC'+_0x5d7d13(0x150)](_0x106ae2,_0x11a051),_0x20dc99=this[_0x5d7d13(0xec)+'centU'+_0x5d7d13(0x156)+_0x5d7d13(0x12d)](_0x5a7512,_0x49ff46),_0x17bfdc=this[_0x5d7d13(0x100)+'ision'+_0x5d7d13(0xd9)](_0x106ae2,_0x49ff46),_0x3782ed=await this[_0x5d7d13(0x14c)+_0x5d7d13(0xf4)+'rence'+_0x5d7d13(0x101)](_0x5a7512,_0x92df28);if(_0x17bfdc){this[_0x5d7d13(0xc9)+'rompt'+_0x5d7d13(0xd1)]=Date[_0x5d7d13(0x124)]();const _0x537d48={};_0x537d48['shoul'+_0x5d7d13(0x157)+'pt']=!![],_0x537d48['reaso'+'n']=_0x5d7d13(0xcd)+_0x5d7d13(0x11f)+'oint\x20'+_0x5d7d13(0x134)+'ed',_0x537d48[_0x5d7d13(0xe4)+'cy']='high';const _0x2e69fe=_0x537d48;return import('./uti'+'ls/pe'+'rform'+'ance-'+_0x5d7d13(0x140)+'r.mjs')[_0x5d7d13(0x12c)](({logTemporalDecision:_0x3f22ce})=>{const _0x89713e=_0x5d7d13,_0x4834c4={};_0x4834c4['shoul'+_0x89713e(0x157)+'pt']=_0x2e69fe['shoul'+_0x89713e(0x157)+'pt'],_0x4834c4['reaso'+'n']=_0x2e69fe['reaso'+'n'],_0x4834c4['urgen'+'cy']=_0x2e69fe[_0x89713e(0xe4)+'cy'],_0x4834c4['coher'+'ence']=_0x1ed9d4,_0x4834c4[_0x89713e(0x15a)+_0x89713e(0xfb)+'e']=_0x2b7221,_0x4834c4['noteC'+_0x89713e(0x11a)]=_0x5a7512[_0x89713e(0xd3)+'h'],_0x4834c4['isDec'+_0x89713e(0x14f)+_0x89713e(0xd9)]=!![],_0x4834c4['hasUs'+'erAct'+'ion']=_0x20dc99,_0x3f22ce(_0x4834c4);})[_0x5d7d13(0xd7)](async importError=>{const _0xb58db7=_0x5d7d13;if(process[_0xb58db7(0x131)][_0xb58db7(0x155)+'_TEMP'+_0xb58db7(0x165)])try{const {warn:_0x508a5d}=await import(_0xb58db7(0x12b)+'ger.m'+'js');_0x508a5d('[Temp'+_0xb58db7(0x143)+'ecisi'+_0xb58db7(0x16c)+_0xb58db7(0xc7)+_0xb58db7(0x13e)+_0xb58db7(0xef)+'er\x20un'+_0xb58db7(0xc6)+'able:'+'\x20'+importError[_0xb58db7(0x119)+'ge']);}catch{console[_0xb58db7(0xeb)](_0xb58db7(0x160)+_0xb58db7(0x143)+'ecisi'+_0xb58db7(0x16c)+'erfor'+_0xb58db7(0x13e)+_0xb58db7(0xef)+_0xb58db7(0x16f)+'avail'+'able:'+'\x20'+importError['messa'+'ge']);}}),_0x2e69fe;}if(_0x3782ed){this['lastP'+_0x5d7d13(0xe3)+_0x5d7d13(0xd1)]=Date[_0x5d7d13(0x124)]();const _0x2e50c6={};_0x2e50c6['shoul'+'dProm'+'pt']=!![],_0x2e50c6['reaso'+'n']=_0x5d7d13(0x164)+'ence\x20'+'drop\x20'+'detec'+'ted\x20('+_0x5d7d13(0xcb)+'ty\x20is'+_0x5d7d13(0xda),_0x2e50c6['urgen'+'cy']='high';const _0x3b4609=_0x2e50c6;return import(_0x5d7d13(0x166)+_0x5d7d13(0x15b)+_0x5d7d13(0x109)+'ance-'+_0x5d7d13(0x140)+'r.mjs')['then'](({logTemporalDecision:_0x5b0994})=>{const _0x12ace0=_0x5d7d13,_0x4b1d01={};_0x4b1d01['shoul'+_0x12ace0(0x157)+'pt']=_0x3b4609['shoul'+'dProm'+'pt'],_0x4b1d01[_0x12ace0(0x14b)+'n']=_0x3b4609['reaso'+'n'],_0x4b1d01['urgen'+'cy']=_0x3b4609[_0x12ace0(0xe4)+'cy'],_0x4b1d01['coher'+'ence']=_0x1ed9d4,_0x4b1d01[_0x12ace0(0x15a)+'Chang'+'e']=_0x2b7221,_0x4b1d01['noteC'+_0x12ace0(0x11a)]=_0x5a7512[_0x12ace0(0xd3)+'h'],_0x4b1d01['isDec'+'ision'+'Point']=![],_0x4b1d01[_0x12ace0(0xff)+'erAct'+_0x12ace0(0xf9)]=_0x20dc99,_0x5b0994(_0x4b1d01);})['catch'](async importError=>{const _0x5d8d8b=_0x5d7d13;if(process['env'][_0x5d8d8b(0x155)+_0x5d8d8b(0x114)+_0x5d8d8b(0x165)])try{const {warn:_0x343cee}=await import(_0x5d8d8b(0x12b)+_0x5d8d8b(0x154)+'js');_0x343cee(_0x5d8d8b(0x160)+'oralD'+_0x5d8d8b(0x135)+'on]\x20P'+_0x5d8d8b(0xc7)+'mance'+_0x5d8d8b(0xef)+_0x5d8d8b(0x16f)+'avail'+_0x5d8d8b(0x146)+'\x20'+importError[_0x5d8d8b(0x119)+'ge']);}catch{console['warn'](_0x5d8d8b(0x160)+'oralD'+_0x5d8d8b(0x135)+_0x5d8d8b(0x16c)+'erfor'+'mance'+'\x20logg'+_0x5d8d8b(0x16f)+'avail'+'able:'+'\x20'+importError[_0x5d8d8b(0x119)+'ge']);}}),_0x3b4609;}if(_0x20dc99&&_0x2b7221>this[_0x5d7d13(0x15a)+'Chang'+'eThre'+'shold']){this[_0x5d7d13(0xc9)+_0x5d7d13(0xe3)+_0x5d7d13(0xd1)]=Date['now']();const _0x11ff19={};return _0x11ff19[_0x5d7d13(0x111)+'dProm'+'pt']=!![],_0x11ff19[_0x5d7d13(0x14b)+'n']=_0x5d7d13(0xf0)+_0x5d7d13(0xea)+_0x5d7d13(0x122)+'h\x20sig'+_0x5d7d13(0x159)+'ant\x20s'+_0x5d7d13(0x16a)+_0x5d7d13(0xfc)+'e',_0x11ff19['urgen'+'cy']='mediu'+'m',_0x11ff19;}if(_0x1ed9d4>=this[_0x5d7d13(0x107)+'enceT'+_0x5d7d13(0xc3)+_0x5d7d13(0x10d)]&&_0x2b7221>this[_0x5d7d13(0x15a)+'Chang'+'eThre'+'shold']){this['lastP'+_0x5d7d13(0xe3)+'Time']=Date[_0x5d7d13(0x124)]();const _0x2bd6b8={};return _0x2bd6b8['shoul'+'dProm'+'pt']=!![],_0x2bd6b8[_0x5d7d13(0x14b)+'n']=_0x5d7d13(0x129)+'e\x20con'+_0x5d7d13(0x142)+_0x5d7d13(0x10c)+_0x5d7d13(0x110)+'fican'+'t\x20sta'+_0x5d7d13(0xe2)+_0x5d7d13(0x14d),_0x2bd6b8['urgen'+'cy']='mediu'+'m',_0x2bd6b8;}return{'shouldPrompt':![],'reason':_0x5d7d13(0xd8)+'xt\x20no'+_0x5d7d13(0x125)+'ficie'+'nt\x20(c'+'ohere'+_0x5d7d13(0x16e)+_0x1ed9d4[_0x5d7d13(0x15c)+'ed'](0x2)+(_0x5d7d13(0xf3)+'teCha'+_0x5d7d13(0x11d))+_0x2b7221[_0x5d7d13(0x15c)+'ed'](0x2)+')','urgency':'low'};}['reset'](){const _0x1ade11=_0x15d7dc;this[_0x1ade11(0x127)+_0x1ade11(0x11a)]=0x0,this[_0x1ade11(0xc9)+_0x1ade11(0xe3)+_0x1ade11(0xd1)]=null;}[_0x15d7dc(0xe1)+'lateS'+_0x15d7dc(0xee)+'hange'](_0x4a6180,_0x3d2ee5){const _0x2ce1bd=_0x15d7dc;if(!_0x4a6180||typeof _0x4a6180!==_0x2ce1bd(0x10f)+'t')throw new TypeError('curre'+_0x2ce1bd(0x120)+_0x2ce1bd(0x158)+_0x2ce1bd(0x11c)+'\x20an\x20o'+_0x2ce1bd(0x12e));if(!_0x3d2ee5)return 0x1;let _0x302acb=0x0,_0x6314d6=0x0;if(_0x4a6180['score']!==undefined&&_0x3d2ee5['score']!==undefined){const _0x19addb=typeof _0x4a6180['score']===_0x2ce1bd(0xc4)+'r'?_0x4a6180[_0x2ce1bd(0x102)]:0x0,_0x20cefc=typeof _0x3d2ee5['score']===_0x2ce1bd(0xc4)+'r'?_0x3d2ee5[_0x2ce1bd(0x102)]:0x0,_0x5545bb=Math[_0x2ce1bd(0xfd)](_0x19addb-_0x20cefc)/0xa;isFinite(_0x5545bb)&&(_0x302acb+=_0x5545bb,_0x6314d6++);}if(_0x4a6180['issue'+'s']&&_0x3d2ee5[_0x2ce1bd(0x14e)+'s']){if(Array['isArr'+'ay'](_0x4a6180['issue'+'s'])&&Array['isArr'+'ay'](_0x3d2ee5['issue'+'s'])){const _0x2299f2=new Set(_0x4a6180['issue'+'s']['map'](_0x514b66=>String(_0x514b66)['toLow'+'erCas'+'e']()['trim']())),_0xbd13aa=new Set(_0x3d2ee5[_0x2ce1bd(0x14e)+'s'][_0x2ce1bd(0x169)](_0x1f20b1=>String(_0x1f20b1)[_0x2ce1bd(0x149)+_0x2ce1bd(0xf5)+'e']()[_0x2ce1bd(0x144)]())),_0x121fad=[..._0x2299f2]['filte'+'r'](_0x3ab702=>!_0xbd13aa['has'](_0x3ab702))['lengt'+'h'],_0x46eceb=[..._0xbd13aa][_0x2ce1bd(0x113)+'r'](_0x30a7f6=>!_0x2299f2[_0x2ce1bd(0x138)](_0x30a7f6))['lengt'+'h'],_0x4026bb=_0x2299f2[_0x2ce1bd(0x11e)]+_0xbd13aa[_0x2ce1bd(0x11e)],_0x323cdd=_0x4026bb>0x0?(_0x121fad+_0x46eceb)/_0x4026bb:0x0;isFinite(_0x323cdd)&&(_0x302acb+=_0x323cdd,_0x6314d6++);}}if(_0x4a6180['gameS'+_0x2ce1bd(0x15d)]&&_0x3d2ee5[_0x2ce1bd(0x137)+'tate']){const _0x523d63=this['calcu'+'lateG'+'ameSt'+'ateCh'+_0x2ce1bd(0x14d)](_0x4a6180['gameS'+'tate'],_0x3d2ee5[_0x2ce1bd(0x137)+'tate']);isFinite(_0x523d63)&&(_0x302acb+=_0x523d63,_0x6314d6++);}const _0x4940c5=_0x6314d6>0x0?_0x302acb/_0x6314d6:0x0;return Math['max'](0x0,Math['min'](0x1,_0x4940c5));}[_0x15d7dc(0xe1)+_0x15d7dc(0x13a)+'ameSt'+_0x15d7dc(0x15f)+'ange'](_0x48f388,_0x462da8){const _0x3628bc=_0x15d7dc,_0x3d9225=Object['keys'](_0x48f388||{}),_0x275731=Object['keys'](_0x462da8||{}),_0x33d62b=_0x3d9225['filte'+'r'](_0x1ffdf4=>!_0x275731[_0x3628bc(0x148)+'des'](_0x1ffdf4))['lengt'+'h'],_0x45b1a=_0x275731['filte'+'r'](_0x18ac3f=>!_0x3d9225[_0x3628bc(0x148)+'des'](_0x18ac3f))[_0x3628bc(0xd3)+'h'],_0x1c775f=_0x3d9225['filte'+'r'](_0x56e4cd=>_0x275731['inclu'+_0x3628bc(0xdc)](_0x56e4cd)&&JSON[_0x3628bc(0x16b)+'gify'](_0x48f388[_0x56e4cd])!==JSON[_0x3628bc(0x16b)+_0x3628bc(0x104)](_0x462da8[_0x56e4cd]))['lengt'+'h'],_0x3fec59=new Set([..._0x3d9225,..._0x275731])[_0x3628bc(0x11e)];return _0x3fec59>0x0?(_0x33d62b+_0x45b1a+_0x1c775f)/_0x3fec59:0x0;}['hasRe'+'centU'+_0x15d7dc(0x156)+_0x15d7dc(0x12d)](_0x314bab,_0x8cbde1){const _0x3972cf=_0x15d7dc;if(_0x8cbde1['recen'+_0x3972cf(0x15e)+'on'])return!![];const _0x137767=_0x314bab['slice'](-0x3);return _0x137767['some'](_0x556ca0=>{const _0x4973b4=_0x3972cf,_0x333939=String(_0x556ca0['step']||''),_0x13223c=String(_0x556ca0[_0x4973b4(0xd4)+'vatio'+'n']||'');return _0x333939[_0x4973b4(0x148)+_0x4973b4(0xdc)]('inter'+'actio'+'n')||_0x333939['inclu'+'des']('click')||_0x333939[_0x4973b4(0x148)+_0x4973b4(0xdc)](_0x4973b4(0xea)+'n')||_0x13223c['inclu'+'des']('user')||_0x13223c['inclu'+_0x4973b4(0xdc)](_0x4973b4(0xed)+'ed');});}[_0x15d7dc(0x100)+_0x15d7dc(0x14f)+_0x15d7dc(0xd9)](_0xeb4e6c,_0x21db99){const _0x205caf=_0x15d7dc;if(_0x21db99['stage']==='decis'+_0x205caf(0xf9)||_0x21db99['stage']==='evalu'+'ation')return!![];if(_0x21db99['testT'+_0x205caf(0x13b)]==='criti'+'cal'||_0x21db99['criti'+_0x205caf(0x12a)])return!![];if(_0x21db99[_0x205caf(0x121)]&&_0x21db99[_0x205caf(0x116)+'omple'+_0x205caf(0x14a)])return!![];return![];}async[_0x15d7dc(0x14c)+_0x15d7dc(0xf4)+'rence'+_0x15d7dc(0x101)](_0x12e968,_0x244b86){const _0x525de9=_0x15d7dc;if(_0x12e968['lengt'+'h']<0x4)return![];const _0x35cb07=_0x12e968['slice'](0x0,-0x1),_0x39ebda=await aggregateTemporalNotes(_0x35cb07),_0x1963a8=_0x39ebda['coher'+_0x525de9(0x117)]||0x1,_0x391c65=_0x244b86['coher'+_0x525de9(0x117)]||0x1,_0x2fbe53=_0x1963a8-_0x391c65;return _0x2fbe53>this[_0x525de9(0xe4)+_0x525de9(0x167)+_0x525de9(0x103)+'d'];}['calcu'+'lateP'+_0x15d7dc(0xe3)+'Urgen'+'cy'](_0x2675cc,_0x58f265){const _0x2d8919=_0x15d7dc;if(_0x58f265[_0x2d8919(0xe4)+'cy']==='high')return 0x1;if(_0x58f265[_0x2d8919(0xe4)+'cy']===_0x2d8919(0x128)+'m')return 0.6;const _0x328760=_0x2675cc[_0x2d8919(0x107)+'ence']||0x0,_0xf24c86=_0x2675cc['timeS'+'inceL'+_0x2d8919(0xc5)+_0x2d8919(0x10b)]||0x0;if(_0x328760>0.7&&_0xf24c86>0x1388)return 0.4;return 0.2;}async['selec'+'tOpti'+'malTi'+'ming'](_0x58f790,_0x8ee1c6){const _0x330af9=_0x15d7dc,_0x45b783=await Promise['all'](_0x58f790[_0x330af9(0x169)](async _0x235959=>({'request':_0x235959,'decision':await this['shoul'+'dProm'+'pt'](_0x235959['curre'+_0x330af9(0x120)+'te'],_0x235959[_0x330af9(0x136)+'ousSt'+'ate'],_0x235959[_0x330af9(0x10a)+_0x330af9(0x13c)+'tes']||[],_0x235959['conte'+'xt']||{})}))),_0x1a026a=_0x45b783[_0x330af9(0x113)+'r'](_0xb6d7fa=>_0xb6d7fa[_0x330af9(0x123)+_0x330af9(0xf9)]['urgen'+'cy']==='high'),_0x2f4dee=_0x45b783['filte'+'r'](_0x41fd01=>_0x41fd01[_0x330af9(0x123)+'ion'][_0x330af9(0xe4)+'cy']==='mediu'+'m'),_0x5b3e50=_0x45b783[_0x330af9(0x113)+'r'](_0x1ad085=>_0x1ad085[_0x330af9(0x123)+_0x330af9(0xf9)][_0x330af9(0xe4)+'cy']==='low'),_0x15d80b=_0x8ee1c6[_0x330af9(0x107)+_0x330af9(0x117)]>0.7,_0xf4d08=_0x15d80b&&_0x2f4dee['lengt'+'h']+_0x5b3e50['lengt'+'h']>0x1;return{'promptNow':_0x1a026a[_0x330af9(0x169)](_0x281730=>_0x281730[_0x330af9(0x130)+'st']),'batch':_0xf4d08?[..._0x2f4dee,..._0x5b3e50][_0x330af9(0x169)](_0x3f2463=>_0x3f2463['reque'+'st']):_0x2f4dee[_0x330af9(0x169)](_0x272458=>_0x272458[_0x330af9(0x130)+'st']),'wait':_0xf4d08?[]:_0x5b3e50[_0x330af9(0x169)](_0x383578=>_0x383578[_0x330af9(0x130)+'st']),'decisions':_0x45b783};}}function _0x1330(){const _0x426d8a=['BNqGBM8','mZe5ntaZmLHeA2Tyza','lcbZDge','DenVAgu','zxjdyxm','AxruAw0','zsbPBNq','BwLU','Aw9U','mtiZDgXsswPn','q2HHBMC','y2HHBMC','ywjZ','ihjLCxu','AgfZvxm','Axnezwm','rhjVCa','C2nVCMu','zxnOB2W','z2LMEq','DgvZicG','zvrOCMu','y29Ozxi','mtK0ntK0nvnYBfvrAW','CMzVCM0','DgvTCg8','B21WDa','D2L0Aca','B2XK','ksSPkYK','B2jQzwm','C2LNBMK','C2HVDwW','zsbTDxm','zMLSDgu','x1rftva','DgvZrM8','z29HBem','zw5Jzq','xsWGz28','BwvZC2e','B3vUDa','DguGBNu','C3qGyMu','BMDLoIa','C2L6zq','Aw9Uiha','BNrtDge','z29HBa','BIb3Axq','zgvJAxm','BM93','DcbZDwy','BwLUtM8','C3rLCem','BwvKAxu','u3rHyMW','y2fS','lI9SB2C','DgHLBG','DgLVBG','yMPLy3q','zxHW','CMvXDwu','zw52','idWG','Aw4GwZa','CMvHy2G','zwnPC2K','ChjLDMK','z2fTzvm','AgfZ','v2fYBs0','Bgf0zuC','ExbL','CMfStM8','igDVDdO','BwfUy2u','B2XKig0','Bg9Nz2u','B2nLC3m','Dgv4Dca','B3jHBeq','DhjPBq','BxbSAw4','ywjSztO','C2HVBgq','Aw5JBhu','Dg9mB3C','DgvK','CMvHC28','zgv0zwm','yw5Nzq','AxnZDwu','AxnPB24','AgfUz2u','igzPBMK','ovHgBvHbqq','D2fYBvm','z2vYlM0','revcvuC','C2vYqwm','zfbYB20','DguGBxu','BMLMAwm','C3rHDgu','BhmVCgu','Dg9gAxG','Dgf0zq','DefJDgK','yxrLq2G','w1rLBxa','BwjLCIW','nJuXnJbTAerOsva','nJq0nJuYz21Irff5','q29Ozxi','t1jbta','lI91DgK','y3LuAhi','CLbYB20','BwfW','Dgf0zsa','C3rYAw4','B25Difa','DfbYB2i','BMnLoIa','zxiGDw4','AhjLC2G','BNvTyMu','yxn0uhi','yxzHAwW','zxjMB3i','mtqZmKX0te5hqW','BgfZDfa','Bgf0zvm','CxvHBgK','Bwf4','rgvJAxm','Bwf4v2e','Dg9tDhi','mJG3nZe0EurZEu1y','vgLTzq','DcbIzsa','BgvUz3q','B2jZzxi','DgvZig0','ywrHChq','y2f0y2G','q29UDgu','ug9PBNq','C3vLkq','ig11C3q','zgvZ','DgfYDfm','y29UC3q','zw5Jzvq','mtqYmtG3mMzdwLPKDq','y2fSy3u','DguGy2G','CM9TChq','DxjNzw4','yxjYyxK','DdOG','DgvWCW','Aw5N','AxzLu2e','ywn0Aw8','D2fYBG','AgfZuMu','y2XPy2S','Dgf0zum','igXVz2C','vxnLCIa'];_0x1330=function(){return _0x426d8a;};return _0x1330();}export function createTemporalDecisionManager(_0x37d8df={}){return new TemporalDecisionManager(_0x37d8df);}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Temporal Decision Logic
3
+ *
4
+ * Extracted from VLLM Judge to improve testability and reduce complexity.
5
+ * Handles the decision of whether to prompt the LLM based on temporal notes and state.
6
+ */
7
+
8
+ import { log } from './logger.mjs';
9
+ import { safeLogTemporalDecision } from './safe-logger.mjs';
10
+
11
+ /**
12
+ * Evaluate temporal decision and handle logging/metrics
13
+ *
14
+ * @param {Object} context - Validation context
15
+ * @param {Object} config - Judge configuration
16
+ * @returns {Promise<Object|null>} Result if decision is to skip, null if we should proceed
17
+ */
18
+ export async function evaluateTemporalDecision(context, config) {
19
+ // Only prompt when decision is needed, not on every state change
20
+ if (!context.useTemporalDecision || !context.temporalNotes || context.temporalNotes.length === 0) {
21
+ return null; // Proceed with validation
22
+ }
23
+
24
+ try {
25
+ // Dynamic import to avoid circular dependencies if any
26
+ const { TemporalDecisionManager } = await import('./temporal-decision-manager.mjs');
27
+ const { aggregateTemporalNotes } = await import('./temporal.mjs');
28
+
29
+ const decisionManager = new TemporalDecisionManager(context.temporalDecisionOptions || {});
30
+ const currentState = { score: null, issues: [], ...context.currentState };
31
+ const previousState = context.previousState || null;
32
+
33
+ // Make decision
34
+ const decision = await decisionManager.shouldPrompt(
35
+ currentState,
36
+ previousState,
37
+ context.temporalNotes,
38
+ context
39
+ );
40
+
41
+ // Log decision reasoning
42
+ try {
43
+ const aggregated = await aggregateTemporalNotes(context.temporalNotes).catch(() => ({ coherence: null }));
44
+ safeLogTemporalDecision({
45
+ shouldPrompt: decision.shouldPrompt,
46
+ reason: decision.reason,
47
+ urgency: decision.urgency,
48
+ coherence: aggregated.coherence,
49
+ stateChange: decisionManager.calculateStateChange(currentState, previousState),
50
+ noteCount: context.temporalNotes.length,
51
+ isDecisionPoint: decisionManager.isDecisionPoint(currentState, context),
52
+ hasUserAction: decisionManager.hasRecentUserAction(context.temporalNotes, context)
53
+ });
54
+ } catch {
55
+ // Ignore logging errors
56
+ }
57
+
58
+ // Handle decision
59
+ if (!decision.shouldPrompt && decision.urgency !== 'high') {
60
+ // Don't prompt yet - return cached or previous result
61
+ if (context.previousResult) {
62
+ trackMetrics(false);
63
+
64
+ return {
65
+ ...context.previousResult,
66
+ skipped: true,
67
+ skipReason: decision.reason,
68
+ urgency: decision.urgency
69
+ };
70
+ }
71
+ // If no previous result, we proceed but marked as low urgency
72
+ }
73
+
74
+ // Proceeding with validation
75
+ trackMetrics(true);
76
+ return null; // Null means "proceed with validation"
77
+
78
+ } catch (error) {
79
+ // If TemporalDecisionManager fails, proceed with validation (graceful degradation)
80
+ if (config.debug?.verbose) {
81
+ log(`[VLLM] TemporalDecisionManager error: ${error.message}`);
82
+ }
83
+ return null;
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Track metrics for temporal decisions
89
+ */
90
+ async function trackMetrics(prompted) {
91
+ try {
92
+ const { researchMetrics } = await import('../evaluation/metrics/research-metrics-collector.mjs');
93
+ researchMetrics.recordTemporalDecision('with', {
94
+ llmCalls: prompted ? 1 : 0,
95
+ skipped: !prompted,
96
+ accuracy: null,
97
+ latency: prompted ? null : 0,
98
+ cost: prompted ? null : 0
99
+ });
100
+ } catch (error) {
101
+ // Silently fail metrics tracking
102
+ }
103
+ }
104
+