@wundam/orchex 1.0.0-rc.2 → 1.0.0-rc.21

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 (98) hide show
  1. package/README.md +59 -18
  2. package/dist/cloud-executor.d.ts +71 -0
  3. package/dist/cloud-executor.js +335 -0
  4. package/dist/cloud-sync.d.ts +8 -0
  5. package/dist/cloud-sync.js +52 -0
  6. package/dist/config.d.ts +30 -4
  7. package/dist/config.js +61 -2
  8. package/dist/context-builder.d.ts +2 -0
  9. package/dist/context-builder.js +11 -3
  10. package/dist/cost.js +1 -1
  11. package/dist/entitlements/jwt.d.ts +7 -0
  12. package/dist/entitlements/jwt.js +78 -0
  13. package/dist/entitlements/resolve.d.ts +17 -0
  14. package/dist/entitlements/resolve.js +49 -0
  15. package/dist/entitlements/types.d.ts +21 -0
  16. package/dist/entitlements/types.js +4 -0
  17. package/dist/executors/base.d.ts +1 -1
  18. package/dist/executors/bedrock-executor.d.ts +39 -0
  19. package/dist/executors/bedrock-executor.js +197 -0
  20. package/dist/executors/index.d.ts +1 -0
  21. package/dist/executors/index.js +24 -1
  22. package/dist/index.js +468 -23
  23. package/dist/intelligence/index.d.ts +44 -0
  24. package/dist/intelligence/index.js +160 -0
  25. package/dist/key-cache.d.ts +31 -0
  26. package/dist/key-cache.js +84 -0
  27. package/dist/login-helpers.d.ts +25 -0
  28. package/dist/login-helpers.js +54 -0
  29. package/dist/manifest.js +18 -1
  30. package/dist/mcp-instructions.d.ts +1 -0
  31. package/dist/mcp-instructions.js +84 -0
  32. package/dist/mcp-resources.d.ts +8 -0
  33. package/dist/mcp-resources.js +420 -0
  34. package/dist/model-cache.d.ts +18 -0
  35. package/dist/model-cache.js +62 -0
  36. package/dist/model-validator.d.ts +20 -0
  37. package/dist/model-validator.js +125 -0
  38. package/dist/orchestrator.d.ts +14 -0
  39. package/dist/orchestrator.js +191 -32
  40. package/dist/setup/ide-registry.d.ts +13 -0
  41. package/dist/setup/ide-registry.js +51 -0
  42. package/dist/setup/index.d.ts +1 -0
  43. package/dist/setup/index.js +111 -0
  44. package/dist/tier-gating.js +0 -16
  45. package/dist/tiers.d.ts +35 -5
  46. package/dist/tiers.js +39 -3
  47. package/dist/tools.d.ts +6 -1
  48. package/dist/tools.js +852 -95
  49. package/dist/types.d.ts +71 -60
  50. package/dist/types.js +3 -0
  51. package/dist/waves.d.ts +1 -1
  52. package/dist/waves.js +29 -2
  53. package/package.json +41 -5
  54. package/src/entitlements/public-key.pem +9 -0
  55. package/dist/intelligence/anti-pattern-detector.d.ts +0 -117
  56. package/dist/intelligence/anti-pattern-detector.js +0 -327
  57. package/dist/intelligence/budget-enforcer.d.ts +0 -119
  58. package/dist/intelligence/budget-enforcer.js +0 -226
  59. package/dist/intelligence/context-optimizer.d.ts +0 -111
  60. package/dist/intelligence/context-optimizer.js +0 -282
  61. package/dist/intelligence/cost-tracker.d.ts +0 -114
  62. package/dist/intelligence/cost-tracker.js +0 -183
  63. package/dist/intelligence/deliverable-extractor.d.ts +0 -134
  64. package/dist/intelligence/deliverable-extractor.js +0 -909
  65. package/dist/intelligence/dependency-inferrer.d.ts +0 -87
  66. package/dist/intelligence/dependency-inferrer.js +0 -403
  67. package/dist/intelligence/diagnostics.d.ts +0 -33
  68. package/dist/intelligence/diagnostics.js +0 -64
  69. package/dist/intelligence/error-analyzer.d.ts +0 -7
  70. package/dist/intelligence/error-analyzer.js +0 -76
  71. package/dist/intelligence/file-chunker.d.ts +0 -15
  72. package/dist/intelligence/file-chunker.js +0 -64
  73. package/dist/intelligence/fix-stream-manager.d.ts +0 -59
  74. package/dist/intelligence/fix-stream-manager.js +0 -212
  75. package/dist/intelligence/heuristics.d.ts +0 -23
  76. package/dist/intelligence/heuristics.js +0 -124
  77. package/dist/intelligence/learning-engine.d.ts +0 -157
  78. package/dist/intelligence/learning-engine.js +0 -433
  79. package/dist/intelligence/learning-feedback.d.ts +0 -96
  80. package/dist/intelligence/learning-feedback.js +0 -202
  81. package/dist/intelligence/pattern-analyzer.d.ts +0 -35
  82. package/dist/intelligence/pattern-analyzer.js +0 -189
  83. package/dist/intelligence/plan-parser.d.ts +0 -124
  84. package/dist/intelligence/plan-parser.js +0 -498
  85. package/dist/intelligence/planner.d.ts +0 -29
  86. package/dist/intelligence/planner.js +0 -86
  87. package/dist/intelligence/self-healer.d.ts +0 -16
  88. package/dist/intelligence/self-healer.js +0 -84
  89. package/dist/intelligence/slicing-metrics.d.ts +0 -62
  90. package/dist/intelligence/slicing-metrics.js +0 -202
  91. package/dist/intelligence/slicing-templates.d.ts +0 -81
  92. package/dist/intelligence/slicing-templates.js +0 -420
  93. package/dist/intelligence/split-suggester.d.ts +0 -69
  94. package/dist/intelligence/split-suggester.js +0 -176
  95. package/dist/intelligence/stream-generator.d.ts +0 -90
  96. package/dist/intelligence/stream-generator.js +0 -452
  97. package/dist/telemetry/telemetry-types.d.ts +0 -85
  98. package/dist/telemetry/telemetry-types.js +0 -1
@@ -1,433 +0,0 @@
1
- /**
2
- * Learning engine for adaptive threshold adjustment in Orchex Learn.
3
- * Correlates context characteristics with execution success and adapts thresholds.
4
- */
5
- import * as fs from 'fs/promises';
6
- import * as path from 'path';
7
- import { createLogger } from '../logging.js';
8
- const log = createLogger('learning-engine');
9
- /** Default thresholds before learning */
10
- export const DEFAULT_THRESHOLDS = {
11
- maxOwnsCount: {
12
- code: 4,
13
- docs: 6,
14
- tutorial: 3,
15
- 'integration-guide': 3,
16
- test: 4,
17
- migration: 3,
18
- 'api-reference': 4,
19
- other: 4,
20
- },
21
- maxReadsCount: {
22
- code: 4,
23
- docs: 3,
24
- tutorial: 4,
25
- 'integration-guide': 4,
26
- test: 5,
27
- migration: 4,
28
- 'api-reference': 3,
29
- other: 4,
30
- },
31
- maxContextTokens: {
32
- code: 140000,
33
- docs: 80000,
34
- tutorial: 100000,
35
- 'integration-guide': 100000,
36
- test: 140000,
37
- migration: 160000,
38
- 'api-reference': 80000,
39
- other: 100000,
40
- },
41
- globalSoftLimit: 140000,
42
- globalHardLimit: 180000,
43
- sampleCount: 0,
44
- confidence: 'low',
45
- lastUpdated: new Date().toISOString(),
46
- version: 1,
47
- };
48
- /** Minimum samples required for learning */
49
- export const MIN_SAMPLES_FOR_LEARNING = 20;
50
- /** Minimum samples for high confidence */
51
- export const HIGH_CONFIDENCE_THRESHOLD = 100;
52
- /** Minimum samples for medium confidence */
53
- export const MEDIUM_CONFIDENCE_THRESHOLD = 50;
54
- /**
55
- * Determine confidence level from sample count.
56
- */
57
- export function getConfidenceLevel(sampleCount) {
58
- if (sampleCount >= HIGH_CONFIDENCE_THRESHOLD)
59
- return 'high';
60
- if (sampleCount >= MEDIUM_CONFIDENCE_THRESHOLD)
61
- return 'medium';
62
- return 'low';
63
- }
64
- /**
65
- * Categorize a stream based on its name and plan.
66
- * Order matters: more specific patterns before general ones.
67
- * Returns 'code' as default since most uncategorized streams are implementation work.
68
- */
69
- export function categorizeStream(name, plan) {
70
- const text = `${name} ${plan ?? ''}`.toLowerCase();
71
- // Test streams (most specific)
72
- if (text.includes('test') || text.includes('spec'))
73
- return 'test';
74
- // Migration streams (includes refactor/restructure patterns)
75
- if (text.includes('migration') ||
76
- text.includes('migrate') ||
77
- text.includes('refactor') ||
78
- text.includes('restructure')) {
79
- return 'migration';
80
- }
81
- // Integration guides (check before generic 'guide' match)
82
- if (text.includes('integration') && (text.includes('guide') || text.includes('doc')))
83
- return 'integration-guide';
84
- // Tutorials (explicit 'tutorial' keyword or 'getting-started')
85
- if (text.includes('tutorial') || text.includes('getting-started') || text.includes('getting started'))
86
- return 'tutorial';
87
- // API reference
88
- if (text.includes('api') && (text.includes('ref') || text.includes('doc')))
89
- return 'api-reference';
90
- // Documentation (includes user-guide, generic guide, doc, readme, md)
91
- if (text.includes('doc') || text.includes('readme') || text.includes('md') || text.includes('guide'))
92
- return 'docs';
93
- // Default to code - most streams without specific keywords are implementation work
94
- return 'code';
95
- }
96
- /**
97
- * Correlate context characteristics with success from telemetry events.
98
- */
99
- export function correlateContextWithSuccess(events, minSamples = MIN_SAMPLES_FOR_LEARNING) {
100
- const correlations = [];
101
- const insights = [];
102
- // Filter to stream events with context data
103
- const streamEvents = events.filter(e => (e.eventType === 'stream_complete' || e.eventType === 'stream_failed') &&
104
- e.contextTokensEstimated !== undefined);
105
- if (streamEvents.length < minSamples) {
106
- return {
107
- correlations: [],
108
- suggestedThresholds: {},
109
- insights: [`Not enough data for learning. Have ${streamEvents.length}, need ${minSamples} samples.`],
110
- hasEnoughData: false,
111
- };
112
- }
113
- // Calculate overall success rate
114
- const successCount = streamEvents.filter(e => e.eventType === 'stream_complete').length;
115
- const overallSuccessRate = successCount / streamEvents.length;
116
- insights.push(`Overall success rate: ${(overallSuccessRate * 100).toFixed(1)}% (${successCount}/${streamEvents.length})`);
117
- // Analyze context size buckets
118
- const contextBuckets = analyzeContextSizeBuckets(streamEvents);
119
- if (contextBuckets.optimalRange) {
120
- correlations.push({
121
- factor: 'contextTokens',
122
- successRate: contextBuckets.optimalSuccessRate,
123
- sampleSize: contextBuckets.optimalSampleSize,
124
- threshold: contextBuckets.optimalRange.max,
125
- recommendation: `Optimal context size: ${contextBuckets.optimalRange.min.toLocaleString()}-${contextBuckets.optimalRange.max.toLocaleString()} tokens (${(contextBuckets.optimalSuccessRate * 100).toFixed(1)}% success)`,
126
- });
127
- insights.push(correlations[correlations.length - 1].recommendation);
128
- }
129
- // Analyze budget violations
130
- const violationAnalysis = analyzeViolations(streamEvents);
131
- if (violationAnalysis.softViolationSuccessRate !== undefined) {
132
- correlations.push({
133
- factor: 'softViolation',
134
- successRate: violationAnalysis.softViolationSuccessRate,
135
- sampleSize: violationAnalysis.softViolationCount,
136
- threshold: 0,
137
- recommendation: violationAnalysis.softViolationSuccessRate < 0.7
138
- ? 'Soft limit violations have low success rate - consider lowering soft limit'
139
- : 'Soft limit violations acceptable - current threshold is appropriate',
140
- });
141
- }
142
- // Generate suggested thresholds
143
- const suggestedThresholds = generateSuggestedThresholds(correlations, contextBuckets, streamEvents.length);
144
- return {
145
- correlations,
146
- suggestedThresholds,
147
- insights,
148
- hasEnoughData: true,
149
- };
150
- }
151
- function analyzeContextSizeBuckets(events) {
152
- // Define buckets by token count
153
- const buckets = [
154
- { min: 0, max: 50000 },
155
- { min: 50000, max: 100000 },
156
- { min: 100000, max: 150000 },
157
- { min: 150000, max: 200000 },
158
- ];
159
- let bestBucket = buckets[0];
160
- let bestSuccessRate = 0;
161
- let bestSampleSize = 0;
162
- for (const bucket of buckets) {
163
- const bucketEvents = events.filter(e => e.contextTokensEstimated !== undefined &&
164
- e.contextTokensEstimated >= bucket.min &&
165
- e.contextTokensEstimated < bucket.max);
166
- if (bucketEvents.length >= 5) { // Minimum 5 samples per bucket
167
- const successCount = bucketEvents.filter(e => e.eventType === 'stream_complete').length;
168
- const successRate = successCount / bucketEvents.length;
169
- if (successRate > bestSuccessRate) {
170
- bestSuccessRate = successRate;
171
- bestBucket = bucket;
172
- bestSampleSize = bucketEvents.length;
173
- }
174
- }
175
- }
176
- return {
177
- optimalRange: bestSampleSize >= 5 ? bestBucket : undefined,
178
- optimalSuccessRate: bestSuccessRate,
179
- optimalSampleSize: bestSampleSize,
180
- };
181
- }
182
- function analyzeViolations(events) {
183
- const softViolations = events.filter(e => e.budgetViolationType === 'soft');
184
- const hardViolations = events.filter(e => e.budgetViolationType === 'hard');
185
- return {
186
- softViolationCount: softViolations.length,
187
- softViolationSuccessRate: softViolations.length >= 5
188
- ? softViolations.filter(e => e.eventType === 'stream_complete').length / softViolations.length
189
- : undefined,
190
- hardViolationCount: hardViolations.length,
191
- hardViolationSuccessRate: hardViolations.length >= 5
192
- ? hardViolations.filter(e => e.eventType === 'stream_complete').length / hardViolations.length
193
- : undefined,
194
- };
195
- }
196
- function generateSuggestedThresholds(correlations, bucketAnalysis, sampleCount) {
197
- const suggestions = {
198
- sampleCount,
199
- confidence: getConfidenceLevel(sampleCount),
200
- lastUpdated: new Date().toISOString(),
201
- version: 1,
202
- };
203
- // Suggest global limits based on optimal bucket
204
- if (bucketAnalysis.optimalRange) {
205
- suggestions.globalSoftLimit = bucketAnalysis.optimalRange.max;
206
- suggestions.globalHardLimit = Math.round(bucketAnalysis.optimalRange.max * 1.3);
207
- }
208
- return suggestions;
209
- }
210
- /**
211
- * Update thresholds based on learning results.
212
- */
213
- export function updateThresholds(current, learningResult, learningRate = 0.3) {
214
- if (!learningResult.hasEnoughData) {
215
- return current;
216
- }
217
- const updated = { ...current };
218
- const suggestions = learningResult.suggestedThresholds;
219
- // Apply learning with rate control
220
- if (suggestions.globalSoftLimit !== undefined) {
221
- updated.globalSoftLimit = Math.round(current.globalSoftLimit * (1 - learningRate) +
222
- suggestions.globalSoftLimit * learningRate);
223
- }
224
- if (suggestions.globalHardLimit !== undefined) {
225
- updated.globalHardLimit = Math.round(current.globalHardLimit * (1 - learningRate) +
226
- suggestions.globalHardLimit * learningRate);
227
- }
228
- if (suggestions.sampleCount !== undefined) {
229
- updated.sampleCount = suggestions.sampleCount;
230
- }
231
- if (suggestions.confidence !== undefined) {
232
- updated.confidence = suggestions.confidence;
233
- }
234
- updated.lastUpdated = new Date().toISOString();
235
- return updated;
236
- }
237
- /**
238
- * Get the path for learned thresholds storage.
239
- */
240
- function getThresholdsPath(projectDir) {
241
- return path.join(projectDir, '.orchex', 'learn', 'thresholds.json');
242
- }
243
- /**
244
- * Save learned thresholds to project directory.
245
- */
246
- export async function saveLearnedThresholds(projectDir, thresholds) {
247
- const filePath = getThresholdsPath(projectDir);
248
- const dir = path.dirname(filePath);
249
- await fs.mkdir(dir, { recursive: true });
250
- await fs.writeFile(filePath, JSON.stringify(thresholds, null, 2), 'utf-8');
251
- }
252
- /**
253
- * Load learned thresholds from project directory.
254
- */
255
- export async function loadLearnedThresholds(projectDir) {
256
- const filePath = getThresholdsPath(projectDir);
257
- try {
258
- const content = await fs.readFile(filePath, 'utf-8');
259
- const parsed = JSON.parse(content);
260
- // Validate version and structure
261
- if (parsed.version !== 1) {
262
- log.warn({ version: parsed.version }, 'unknown_thresholds_version');
263
- return null;
264
- }
265
- return parsed;
266
- }
267
- catch {
268
- // File doesn't exist or is invalid
269
- return null;
270
- }
271
- }
272
- /**
273
- * Get thresholds for a project, falling back to defaults.
274
- */
275
- export async function getThresholds(projectDir) {
276
- const loaded = await loadLearnedThresholds(projectDir);
277
- return loaded ?? { ...DEFAULT_THRESHOLDS };
278
- }
279
- /**
280
- * Get recommended limit for a stream category.
281
- */
282
- export function getRecommendedLimit(thresholds, category, limitType) {
283
- switch (limitType) {
284
- case 'owns':
285
- return thresholds.maxOwnsCount[category] ?? DEFAULT_THRESHOLDS.maxOwnsCount.other;
286
- case 'reads':
287
- return thresholds.maxReadsCount[category] ?? DEFAULT_THRESHOLDS.maxReadsCount.other;
288
- case 'tokens':
289
- return thresholds.maxContextTokens[category] ?? thresholds.globalSoftLimit;
290
- }
291
- }
292
- function getEventsPath(projectDir) {
293
- return path.join(projectDir, '.orchex', 'learn', 'events.jsonl');
294
- }
295
- /**
296
- * Convert a stream result to a TelemetryEvent for learning.
297
- */
298
- export function streamResultToTelemetryEvent(result, provider, model) {
299
- return {
300
- id: `learn-${Date.now()}-${result.id}`,
301
- sessionHash: 'local',
302
- eventType: result.status === 'complete' ? 'stream_complete' : 'stream_failed',
303
- timestamp: new Date().toISOString(),
304
- durationMs: result.executionTimeMs,
305
- success: result.status === 'complete',
306
- tokensInput: result.tokensUsed?.input,
307
- tokensOutput: result.tokensUsed?.output,
308
- provider,
309
- model,
310
- contextTokensEstimated: result.contextMetrics?.estimatedTokens,
311
- contextBudgetUtilization: result.contextMetrics?.budgetUtilization,
312
- budgetViolationType: result.contextMetrics?.violationType,
313
- };
314
- }
315
- /**
316
- * Append telemetry events to the local events file (.orchex/learn/events.jsonl).
317
- * Uses JSONL (one JSON object per line) for append-friendly storage.
318
- */
319
- export async function appendLocalEvents(projectDir, events) {
320
- if (events.length === 0)
321
- return;
322
- const filePath = getEventsPath(projectDir);
323
- const dir = path.dirname(filePath);
324
- await fs.mkdir(dir, { recursive: true });
325
- const lines = events.map(e => JSON.stringify(e)).join('\n') + '\n';
326
- await fs.appendFile(filePath, lines, 'utf-8');
327
- }
328
- /**
329
- * Load all local telemetry events from the JSONL file.
330
- * Skips malformed lines silently.
331
- */
332
- export async function loadLocalEvents(projectDir) {
333
- const filePath = getEventsPath(projectDir);
334
- try {
335
- const content = await fs.readFile(filePath, 'utf-8');
336
- const events = [];
337
- for (const line of content.split('\n')) {
338
- if (!line.trim())
339
- continue;
340
- try {
341
- events.push(JSON.parse(line));
342
- }
343
- catch {
344
- // Skip malformed lines
345
- }
346
- }
347
- return events;
348
- }
349
- catch {
350
- // File doesn't exist
351
- return [];
352
- }
353
- }
354
- // ============================================================================
355
- // LE.2: Learning cycle — correlate, update, persist
356
- // ============================================================================
357
- /**
358
- * Run a complete learning cycle: load events → correlate → update → save.
359
- * Returns the learning result (or null if not enough data).
360
- * This is the main entry point called after an orchestration completes.
361
- */
362
- export async function runLearningCycle(projectDir) {
363
- const events = await loadLocalEvents(projectDir);
364
- if (events.length < MIN_SAMPLES_FOR_LEARNING) {
365
- log.debug({ eventCount: events.length, minRequired: MIN_SAMPLES_FOR_LEARNING }, 'learning_skipped_insufficient_data');
366
- return null;
367
- }
368
- const learningResult = correlateContextWithSuccess(events);
369
- if (!learningResult.hasEnoughData) {
370
- log.debug({ insights: learningResult.insights }, 'learning_insufficient_context_data');
371
- return learningResult;
372
- }
373
- // Load current thresholds and apply learning
374
- const current = await getThresholds(projectDir);
375
- const updated = updateThresholds(current, learningResult);
376
- // Persist updated thresholds
377
- await saveLearnedThresholds(projectDir, updated);
378
- log.info({
379
- sampleCount: updated.sampleCount,
380
- confidence: updated.confidence,
381
- globalSoftLimit: updated.globalSoftLimit,
382
- globalHardLimit: updated.globalHardLimit,
383
- }, 'learning_cycle_completed');
384
- return learningResult;
385
- }
386
- // ============================================================================
387
- // LE.4: Cloud aggregation — run learning on telemetry store events
388
- // ============================================================================
389
- /**
390
- * Run learning cycle from telemetry store events (cloud mode).
391
- * Aggregates across all users for global threshold learning.
392
- */
393
- export async function runCloudLearningCycle(events, projectDir) {
394
- if (events.length < MIN_SAMPLES_FOR_LEARNING) {
395
- return null;
396
- }
397
- const learningResult = correlateContextWithSuccess(events);
398
- if (!learningResult.hasEnoughData) {
399
- return learningResult;
400
- }
401
- const current = await getThresholds(projectDir);
402
- const updated = updateThresholds(current, learningResult);
403
- await saveLearnedThresholds(projectDir, updated);
404
- log.info({
405
- sampleCount: updated.sampleCount,
406
- confidence: updated.confidence,
407
- source: 'cloud_aggregation',
408
- }, 'cloud_learning_cycle_completed');
409
- return learningResult;
410
- }
411
- /**
412
- * Format a learning report for display.
413
- */
414
- export function formatLearningReport(result) {
415
- const lines = ['=== Learning Report ===', ''];
416
- if (!result.hasEnoughData) {
417
- lines.push('Insufficient data for learning.');
418
- lines.push(...result.insights);
419
- return lines.join('\n');
420
- }
421
- lines.push('Insights:');
422
- for (const insight of result.insights) {
423
- lines.push(` • ${insight}`);
424
- }
425
- if (result.correlations.length > 0) {
426
- lines.push('', 'Correlations:');
427
- for (const corr of result.correlations) {
428
- lines.push(` • ${corr.factor}: ${(corr.successRate * 100).toFixed(1)}% success (n=${corr.sampleSize})`);
429
- lines.push(` → ${corr.recommendation}`);
430
- }
431
- }
432
- return lines.join('\n');
433
- }
@@ -1,96 +0,0 @@
1
- /**
2
- * Learning feedback module for adaptive heuristic adjustment.
3
- * Analyzes execution history to improve slicing thresholds.
4
- */
5
- import type { StreamCategory } from './learning-engine.js';
6
- /**
7
- * Heuristic thresholds for stream validation.
8
- */
9
- export interface HeuristicThresholds {
10
- /** Maximum recommended owns count */
11
- maxOwnsCount: number;
12
- /** Maximum recommended reads count */
13
- maxReadsCount: number;
14
- /** Maximum "and" conjunctions in plan */
15
- maxPlanAndCount: number;
16
- /** Maximum expected output tokens */
17
- maxOutputTokens: number;
18
- /** Minimum acceptable success rate */
19
- minSuccessRate: number;
20
- }
21
- /**
22
- * A suggested threshold adjustment based on learning.
23
- */
24
- export interface ThresholdAdjustment {
25
- /** Field being adjusted */
26
- field: keyof HeuristicThresholds;
27
- /** Previous value */
28
- oldValue: number;
29
- /** Suggested new value */
30
- newValue: number;
31
- /** Reason for adjustment */
32
- reason: string;
33
- /** Confidence in the adjustment */
34
- confidence: 'high' | 'medium' | 'low';
35
- }
36
- /**
37
- * Metrics for a stream category (from execution history).
38
- */
39
- export interface CategoryMetrics {
40
- /** Category name */
41
- category: StreamCategory;
42
- /** Total executions */
43
- totalExecutions: number;
44
- /** Successful completions */
45
- successCount: number;
46
- /** Failures */
47
- failureCount: number;
48
- /** Timeout failures specifically */
49
- timeoutCount: number;
50
- /** Average owns count for this category */
51
- avgOwnsCount: number;
52
- /** Average reads count for this category */
53
- avgReadsCount: number;
54
- /** Average output tokens */
55
- avgOutputTokens: number;
56
- /** Success rate (0-1) */
57
- successRate: number;
58
- }
59
- /**
60
- * Default heuristic thresholds (conservative starting point).
61
- */
62
- export declare const DEFAULT_THRESHOLDS: HeuristicThresholds;
63
- /**
64
- * Minimum samples required before learning from a category.
65
- */
66
- export declare const MIN_CATEGORY_SAMPLES = 5;
67
- /**
68
- * Minimum total samples before suggesting adjustments.
69
- */
70
- export declare const MIN_TOTAL_SAMPLES = 20;
71
- /**
72
- * Learn from execution metrics and suggest threshold adjustments.
73
- *
74
- * @param metrics - Map of category to execution metrics
75
- * @param currentThresholds - Current threshold values
76
- * @param minSamples - Minimum samples required for learning
77
- * @returns Array of suggested threshold adjustments
78
- */
79
- export declare function learnFromMetrics(metrics: Map<string, CategoryMetrics>, currentThresholds?: HeuristicThresholds, minSamples?: number): ThresholdAdjustment[];
80
- /**
81
- * Apply adjustments to thresholds with learning rate control.
82
- *
83
- * @param currentThresholds - Current threshold values
84
- * @param adjustments - Suggested adjustments
85
- * @param learningRate - How much to move toward suggested values (0-1)
86
- * @returns Updated thresholds
87
- */
88
- export declare function applyAdjustments(currentThresholds: HeuristicThresholds, adjustments: ThresholdAdjustment[], learningRate?: number): HeuristicThresholds;
89
- /**
90
- * Format adjustments as a human-readable report.
91
- */
92
- export declare function formatAdjustmentsReport(adjustments: ThresholdAdjustment[]): string;
93
- /**
94
- * Generate insights from category metrics.
95
- */
96
- export declare function generateCategoryInsights(metrics: Map<string, CategoryMetrics>): string[];