adaptive-memory-multi-model-router 2.8.0 → 2.9.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/README.md CHANGED
@@ -177,57 +177,88 @@ A3M Router combines multi-signal routing, semantic caching, and load balancing t
177
177
 
178
178
  ### Routing Signals
179
179
 
180
+ A3M Router uses **multi-signal heuristic scoring** — 12 keyword signals across 5 dimensions — to classify query complexity and route to the cheapest capable model. No ML model weights. No GPU required. <1ms latency.
181
+
180
182
  ```
181
183
  User Query
182
184
 
183
- ┌─────────────────────────────────────────┐
184
- 5-Signal Complexity Scoring (0.0–1.0)
185
- │ │
186
- 1. Domain Detection
187
- legal/medical/finance/security/
188
- architecture/ML research
189
-
190
- 2. Task Indicators
191
- code / math / creative / multilingual
192
-
193
- 3. Query Structure
194
- length + clauses + qualifiers
195
-
196
- 4. Action Verb Intensity
197
- expert(+0.20) / mid(+0.10) /
198
- simple(-0.10)
199
-
200
- 5. Specificity
201
- multi-step + detailed requirements
202
-
203
- ├─────────────────────────────────────────┤
204
- Tier: free ← 0.19 | cheap ← 0.44 |
205
- mid 0.64 | premium → 1.0
206
- ├─────────────────────────────────────────┤
207
- Pick cheapest available model in tier
208
- + 2 fallback models
209
- + adaptive quality scores from history
210
- └─────────────────────────────────────────┘
185
+ ┌──────────────────────────────────────────────────────────────┐
186
+ 12-Keyword Signal Extraction
187
+ ├──────────────────────────────────────────────────────────────┤
188
+
189
+ Signal 1: Domain Detection (+0.35 max)
190
+ ┌────────────────────────────────────────────────────────┐
191
+ legal/contract/liability/clause → +0.35 │ │
192
+ medical/clinical/patient/diagnosis → +0.35
193
+ finance/investment/risk/portfolio +0.30
194
+ security/vulnerability/exploit → +0.35 │ │
195
+ architecture/system design → +0.25
196
+ ML/model/training/gradient → +0.25
197
+ └────────────────────────────────────────────────────────┘
198
+
199
+ Signal 2: Task Indicators (+0.25 max)
200
+ ┌────────────────────────────────────────────────────────┐
201
+ code/function/algorithm/debug → +0.25 │ │
202
+ │ math/calculate/equation/formula → +0.20
203
+ creative/story/poem → +0.10 │
204
+ translate/multilingual/language → +0.15 │ │
205
+ │ └────────────────────────────────────────────────────────┘ │
206
+
207
+ Signal 3: Query Structure (+0.20 max)
208
+ │ ┌────────────────────────────────────────────────────────┐ │
209
+ Length > 200 chars → +0.05 │
210
+ Multiple clauses (and/or/but) → +0.10
211
+ Qualifiers (explain, analyze) → +0.05
212
+ │ └────────────────────────────────────────────────────────┘ │
213
+ │ ↓ │
214
+ │ Signal 4: Action Verb Intensity (+0.20 max) │
215
+ │ ┌────────────────────────────────────────────────────────┐ │
216
+ │ │ Expert: design/architect/optimize → +0.20 │ │
217
+ │ │ Mid: analyze/review/evaluate → +0.10 │ │
218
+ │ │ Simple: what/who/when/where → -0.10 │ │
219
+ │ └────────────────────────────────────────────────────────┘ │
220
+ │ ↓ │
221
+ │ Signal 5: Multi-Step Detection (+0.15 max) │
222
+ │ ┌────────────────────────────────────────────────────────┐ │
223
+ │ │ "first...then...finally" → +0.15 │ │
224
+ │ │ "step 1, step 2, step 3" → +0.15 │ │
225
+ │ └────────────────────────────────────────────────────────┘ │
226
+ │ │
227
+ ├──────────────────────────────────────────────────────────────┤
228
+ │ Complexity Score → Tier Assignment │
229
+ │ │
230
+ │ 0.00 ────────── 0.19 ─────────── 0.44 ──────────── 1.00 │
231
+ │ ├─── free ─────|── cheap ───────|── mid ─────────| premium │
232
+ │ └── taste-1 ───┘ └── llama3.3 ──┘ └── gpt-4o-mini ┘ └──gpt4o│
233
+ │ $0 $0.20/M $0.60/M $2.50/M │
234
+ │ │
235
+ │ Route: Pick cheapest available model in tier │
236
+ │ Fallback: +2 fallback models if primary fails │
237
+ │ Quality: Adaptive scores from historical success rates │
238
+ └──────────────────────────────────────────────────────────────┘
211
239
 
212
- Result: { model, tier, cost, complexity, reasoning, fallbackModels }
240
+ Result: { model, tier, cost, complexity, reasoning[], fallbackModels[] }
213
241
  ```
214
242
 
215
243
  ### Complexity Examples
216
244
 
217
- | Query | Domain | Complexity | Tier | Model |
218
- |-------|--------|:----------:|:----:|-------|
219
- | "What is 2+2?" | | 0.10 | free | commandcode/taste-1 |
220
- | "Write a Python sort function" | coding | 0.33 | cheap | groq/llama-3.3-70b |
221
- | "Analyze economic implications of AI" | | 0.41 | cheap | groq/llama-3.3-70b |
222
- | "Review this contract for liability" | legal | 0.87 | premium | anthropic/claude-3.5-sonnet |
223
- | "Design a clinical trial for oncology" | medical | 1.00 | premium | openai/gpt-4o |
245
+ | Query | Signals Detected | Score | Tier | Route To |
246
+ |-------|------------------|:-----:|:----:|----------|
247
+ | "What is 2+2?" | Simple structure | 0.10 | free | taste-1 ($0) |
248
+ | "Write a Python sort" | code+0.25, simple-0.10 | 0.33 | cheap | llama-3.3-70b ($0.20/M) |
249
+ | "Analyze AI implications" | analyze+0.10 | 0.41 | cheap | llama-3.3-70b ($0.20/M) |
250
+ | "Review contract liability" | legal+0.35, review+0.10, long+0.05 | 0.87 | premium | claude-3.5-sonnet ($1.50/M) |
251
+ | "Design oncology trial" | medical+0.35, design+0.20, steps+0.15 | 1.00 | premium | gpt-4o ($2.50/M) |
252
+
253
+ ### Cost Savings by Query Type
254
+
224
255
  | Query Type | % Traffic | GPT-4o Only | A3M Routes To | A3M Cost | Savings |
225
- |-----------|:---------:|:-----------:|:-------------:|:--------:|:-------:|
226
- | Simple Q&A | 47% | $4.94 | CommandCode (free) | $0.00 | 100% |
227
- | Code gen | 15% | $4.88 | DeepSeek ($0.14/1M) | $0.17 | 97% |
228
- | Summarization | 18% | $7.20 | GPT-4o-mini ($0.15/1M) | $0.43 | 94% |
229
- | Reasoning | 12% | $8.70 | Claude Haiku ($0.80/1M) | $3.36 | 61% |
230
- | Expert | 8% | $8.40 | GPT-4o ($2.50/1M) | $8.40 | 0% |
256
+ |------------|:---------:|:-----------:|:-------------:|:--------:|:-------:|
257
+ | Simple Q&A | 47% | $4.94 | taste-1 (free) | $0.00 | **100%** |
258
+ | Code gen | 15% | $4.88 | deepseek ($0.14/M) | $0.17 | **97%** |
259
+ | Summarization | 18% | $7.20 | gpt-4o-mini ($0.15/M) | $0.43 | **94%** |
260
+ | Reasoning | 12% | $8.70 | claude-haiku ($0.80/M) | $3.36 | **61%** |
261
+ | Expert | 8% | $8.40 | gpt-4o ($2.50/M) | $8.40 | **0%** |
231
262
  | **Total** | **100%** | **$34.11** | — | **$12.36** | **64%** |
232
263
 
233
264
  | Monthly Queries | GPT-4o Only | A3M Router | You Save | Annualized |
package/dist/index.d.ts CHANGED
@@ -14,6 +14,8 @@ export { SemanticCache } from './cache/semanticCache';
14
14
  export { GuardrailEngine } from './security/guardrails';
15
15
  export { CostAnalytics } from './analytics/costAnalytics';
16
16
  export { createProxyServer } from './server/proxyServer';
17
+ export { Tracer, getTracer, createTracer, MetricsCollector, getMetrics, createMetricsCollector, observabilityMiddleware, observabilityPlugin, budgetAlertMiddleware, } from './observability';
18
+ export type { Span, Metric, RouteTrace, ObservabilityEvent } from './observability';
17
19
  import { getAvailableProviders, healthCheck } from './providers/providerConfig';
18
20
  import { MemoryTree } from './memory/memoryTree';
19
21
  export interface A3MRouterOptions {
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // A3M Router - Main Entry Point
3
3
  // Version: 2.0.0
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.createProxyServer = exports.CostAnalytics = exports.GuardrailEngine = exports.SemanticCache = exports.MODEL_COSTS = exports.estimateTokens = exports.countTokens = exports.MemoryTree = exports.createBudgetEnforcer = exports.BudgetExceededError = exports.BudgetEnforcer = exports.CostTracker = exports.saveConfig = exports.loadConfig = exports.findFastestAvailableProvider = exports.findCheapestAvailableProvider = exports.checkAllProviders = exports.healthCheck = exports.updateProvider = exports.deregisterProvider = exports.registerProvider = exports.getAvailableProviders = exports.DEFAULT_PROVIDERS = exports.PROVIDER_CONTEXT_LIMITS = exports.DEFAULT_PROVIDER_CONFIG = exports.DEFAULT_RETRY_CONFIG = exports.getDefaultRetryHandler = exports.createRetryHandler = exports.ProviderRetryHandler = exports.getProviderHealth = exports.updateModelProfile = exports.MODEL_PROFILES = exports.extractQueryFeatures = exports.recommendForTask = exports.routeBatch = exports.routeQuery = void 0;
5
+ exports.budgetAlertMiddleware = exports.observabilityPlugin = exports.observabilityMiddleware = exports.createMetricsCollector = exports.getMetrics = exports.MetricsCollector = exports.createTracer = exports.getTracer = exports.Tracer = exports.createProxyServer = exports.CostAnalytics = exports.GuardrailEngine = exports.SemanticCache = exports.MODEL_COSTS = exports.estimateTokens = exports.countTokens = exports.MemoryTree = exports.createBudgetEnforcer = exports.BudgetExceededError = exports.BudgetEnforcer = exports.CostTracker = exports.saveConfig = exports.loadConfig = exports.findFastestAvailableProvider = exports.findCheapestAvailableProvider = exports.checkAllProviders = exports.healthCheck = exports.updateProvider = exports.deregisterProvider = exports.registerProvider = exports.getAvailableProviders = exports.DEFAULT_PROVIDERS = exports.PROVIDER_CONTEXT_LIMITS = exports.DEFAULT_PROVIDER_CONFIG = exports.DEFAULT_RETRY_CONFIG = exports.getDefaultRetryHandler = exports.createRetryHandler = exports.ProviderRetryHandler = exports.getProviderHealth = exports.updateModelProfile = exports.MODEL_PROFILES = exports.extractQueryFeatures = exports.recommendForTask = exports.routeBatch = exports.routeQuery = void 0;
6
6
  exports.createA3MRouter = createA3MRouter;
7
7
  // ============================================================
8
8
  // ROUTING ENGINE
@@ -74,6 +74,19 @@ Object.defineProperty(exports, "CostAnalytics", { enumerable: true, get: functio
74
74
  var proxyServer_1 = require("./server/proxyServer");
75
75
  Object.defineProperty(exports, "createProxyServer", { enumerable: true, get: function () { return proxyServer_1.createProxyServer; } });
76
76
  // ============================================================
77
+ // OBSERVABILITY
78
+ // ============================================================
79
+ var observability_1 = require("./observability");
80
+ Object.defineProperty(exports, "Tracer", { enumerable: true, get: function () { return observability_1.Tracer; } });
81
+ Object.defineProperty(exports, "getTracer", { enumerable: true, get: function () { return observability_1.getTracer; } });
82
+ Object.defineProperty(exports, "createTracer", { enumerable: true, get: function () { return observability_1.createTracer; } });
83
+ Object.defineProperty(exports, "MetricsCollector", { enumerable: true, get: function () { return observability_1.MetricsCollector; } });
84
+ Object.defineProperty(exports, "getMetrics", { enumerable: true, get: function () { return observability_1.getMetrics; } });
85
+ Object.defineProperty(exports, "createMetricsCollector", { enumerable: true, get: function () { return observability_1.createMetricsCollector; } });
86
+ Object.defineProperty(exports, "observabilityMiddleware", { enumerable: true, get: function () { return observability_1.observabilityMiddleware; } });
87
+ Object.defineProperty(exports, "observabilityPlugin", { enumerable: true, get: function () { return observability_1.observabilityPlugin; } });
88
+ Object.defineProperty(exports, "budgetAlertMiddleware", { enumerable: true, get: function () { return observability_1.budgetAlertMiddleware; } });
89
+ // ============================================================
77
90
  // CONVENIENCE: Create a router instance
78
91
  // ============================================================
79
92
  const advancedRouter_2 = require("./routing/advancedRouter");
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export { Tracer, getTracer, createTracer } from './tracer';
3
+ export { MetricsCollector, getMetrics, createMetricsCollector } from './metrics';
4
+ export { observabilityMiddleware, observabilityPlugin, budgetAlertMiddleware, } from './middleware';
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ // Observability module exports
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.budgetAlertMiddleware = exports.observabilityPlugin = exports.observabilityMiddleware = exports.createMetricsCollector = exports.getMetrics = exports.MetricsCollector = exports.createTracer = exports.getTracer = exports.Tracer = void 0;
19
+ __exportStar(require("./types"), exports);
20
+ var tracer_1 = require("./tracer");
21
+ Object.defineProperty(exports, "Tracer", { enumerable: true, get: function () { return tracer_1.Tracer; } });
22
+ Object.defineProperty(exports, "getTracer", { enumerable: true, get: function () { return tracer_1.getTracer; } });
23
+ Object.defineProperty(exports, "createTracer", { enumerable: true, get: function () { return tracer_1.createTracer; } });
24
+ var metrics_1 = require("./metrics");
25
+ Object.defineProperty(exports, "MetricsCollector", { enumerable: true, get: function () { return metrics_1.MetricsCollector; } });
26
+ Object.defineProperty(exports, "getMetrics", { enumerable: true, get: function () { return metrics_1.getMetrics; } });
27
+ Object.defineProperty(exports, "createMetricsCollector", { enumerable: true, get: function () { return metrics_1.createMetricsCollector; } });
28
+ var middleware_1 = require("./middleware");
29
+ Object.defineProperty(exports, "observabilityMiddleware", { enumerable: true, get: function () { return middleware_1.observabilityMiddleware; } });
30
+ Object.defineProperty(exports, "observabilityPlugin", { enumerable: true, get: function () { return middleware_1.observabilityPlugin; } });
31
+ Object.defineProperty(exports, "budgetAlertMiddleware", { enumerable: true, get: function () { return middleware_1.budgetAlertMiddleware; } });
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":";AAAA,+BAA+B;;;;;;;;;;;;;;;;;AAE/B,0CAAwB;AACxB,mCAA2D;AAAlD,gGAAA,MAAM,OAAA;AAAE,mGAAA,SAAS,OAAA;AAAE,sGAAA,YAAY,OAAA;AACxC,qCAAiF;AAAxE,2GAAA,gBAAgB,OAAA;AAAE,qGAAA,UAAU,OAAA;AAAE,iHAAA,sBAAsB,OAAA;AAC7D,2CAIsB;AAHpB,qHAAA,uBAAuB,OAAA;AACvB,iHAAA,mBAAmB,OAAA;AACnB,mHAAA,qBAAqB,OAAA"}
@@ -0,0 +1,35 @@
1
+ import { Metric } from './types';
2
+ declare class MetricsCollector {
3
+ private counters;
4
+ private gauges;
5
+ private histograms;
6
+ private createdAt;
7
+ /**
8
+ * Increment counter
9
+ */
10
+ incrementCounter(name: string, labels?: Record<string, string>, value?: number): void;
11
+ /**
12
+ * Set gauge
13
+ */
14
+ setGauge(name: string, value: number, labels?: Record<string, string>): void;
15
+ /**
16
+ * Record histogram value
17
+ */
18
+ recordHistogram(name: string, value: number, labels?: Record<string, string>): void;
19
+ /**
20
+ * Get metrics in Prometheus format
21
+ */
22
+ getPrometheusMetrics(): string;
23
+ /**
24
+ * Get all metrics as Metric objects
25
+ */
26
+ getMetrics(): Metric[];
27
+ private extractLabels;
28
+ /**
29
+ * Clear metrics
30
+ */
31
+ reset(): void;
32
+ }
33
+ export declare function getMetrics(): MetricsCollector;
34
+ export declare function createMetricsCollector(): MetricsCollector;
35
+ export {};
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMetrics = getMetrics;
4
+ exports.createMetricsCollector = createMetricsCollector;
5
+ function formatLabels(labels) {
6
+ const parts = [];
7
+ for (const [key, value] of Object.entries(labels)) {
8
+ parts.push(`${key}="${value}"`);
9
+ }
10
+ return parts.join(',');
11
+ }
12
+ function metricKey(name, labels) {
13
+ if (!labels)
14
+ return name;
15
+ return `${name}{${formatLabels(labels)}}`;
16
+ }
17
+ class MetricsCollector {
18
+ counters = new Map();
19
+ gauges = new Map();
20
+ histograms = new Map();
21
+ createdAt = Date.now();
22
+ /**
23
+ * Increment counter
24
+ */
25
+ incrementCounter(name, labels, value = 1) {
26
+ const key = metricKey(name, labels);
27
+ this.counters.set(key, (this.counters.get(key) || 0) + value);
28
+ }
29
+ /**
30
+ * Set gauge
31
+ */
32
+ setGauge(name, value, labels) {
33
+ const key = metricKey(name, labels);
34
+ this.gauges.set(key, value);
35
+ }
36
+ /**
37
+ * Record histogram value
38
+ */
39
+ recordHistogram(name, value, labels) {
40
+ const key = metricKey(name, labels);
41
+ if (!this.histograms.has(name)) {
42
+ this.histograms.set(name, new Map());
43
+ }
44
+ const buckets = this.histograms.get(name);
45
+ const bucket = buckets.get(key) || { count: 0, sum: 0, min: Infinity, max: -Infinity };
46
+ bucket.count++;
47
+ bucket.sum += value;
48
+ bucket.min = Math.min(bucket.min, value);
49
+ bucket.max = Math.max(bucket.max, value);
50
+ buckets.set(key, bucket);
51
+ }
52
+ /**
53
+ * Get metrics in Prometheus format
54
+ */
55
+ getPrometheusMetrics() {
56
+ const lines = [];
57
+ const timestamp = Date.now();
58
+ lines.push('# HELP a3m_router_info A3M Router info');
59
+ lines.push('# TYPE a3m_router_info gauge');
60
+ lines.push('a3m_router_info{router_version="2.0.0"} 1');
61
+ // Counters
62
+ lines.push('');
63
+ lines.push('# HELP a3m_router_requests_total Total number of router requests');
64
+ lines.push('# TYPE a3m_router_requests_total counter');
65
+ for (const [key, value] of this.counters) {
66
+ if (key.startsWith('a3m_router_') || key.startsWith('a3m_')) {
67
+ lines.push(`${key} ${value} ${timestamp}`);
68
+ }
69
+ }
70
+ // Cache counters
71
+ for (const [key, value] of this.counters) {
72
+ if (key.startsWith('cache_')) {
73
+ lines.push(`${key} ${value} ${timestamp}`);
74
+ }
75
+ }
76
+ // Gauges
77
+ lines.push('');
78
+ lines.push('# HELP a3m_active_providers Number of active providers');
79
+ lines.push('# TYPE a3m_active_providers gauge');
80
+ for (const [key, value] of this.gauges) {
81
+ lines.push(`${key} ${value} ${timestamp}`);
82
+ }
83
+ // Histograms
84
+ lines.push('');
85
+ lines.push('# HELP a3m_request_latency_seconds Request latency in seconds');
86
+ lines.push('# TYPE a3m_request_latency_seconds histogram');
87
+ for (const [name, buckets] of this.histograms) {
88
+ if (name.includes('latency')) {
89
+ for (const [bucketKey, bucket] of buckets) {
90
+ const labelStr = bucketKey.includes('{') ? bucketKey.slice(name.length) : '';
91
+ lines.push(`${name}_sum${labelStr} ${bucket.sum} ${timestamp}`);
92
+ lines.push(`${name}_count${labelStr} ${bucket.count} ${timestamp}`);
93
+ }
94
+ }
95
+ }
96
+ lines.push('');
97
+ lines.push('# HELP a3m_request_cost_cents Request cost in cents');
98
+ lines.push('# TYPE a3m_request_cost_cents histogram');
99
+ for (const [name, buckets] of this.histograms) {
100
+ if (name.includes('cost')) {
101
+ for (const [bucketKey, bucket] of buckets) {
102
+ const labelStr = bucketKey.includes('{') ? bucketKey.slice(name.length) : '';
103
+ lines.push(`${name}_sum${labelStr} ${bucket.sum} ${timestamp}`);
104
+ lines.push(`${name}_count${labelStr} ${bucket.count} ${timestamp}`);
105
+ }
106
+ }
107
+ }
108
+ return lines.join('\n');
109
+ }
110
+ /**
111
+ * Get all metrics as Metric objects
112
+ */
113
+ getMetrics() {
114
+ const metrics = [];
115
+ const timestamp = Date.now();
116
+ for (const [key, value] of this.counters) {
117
+ metrics.push({
118
+ name: key,
119
+ value,
120
+ timestamp,
121
+ labels: this.extractLabels(key),
122
+ type: 'counter',
123
+ });
124
+ }
125
+ for (const [key, value] of this.gauges) {
126
+ metrics.push({
127
+ name: key,
128
+ value,
129
+ timestamp,
130
+ labels: this.extractLabels(key),
131
+ type: 'gauge',
132
+ });
133
+ }
134
+ for (const [name, buckets] of this.histograms) {
135
+ for (const [bucketKey, bucket] of buckets) {
136
+ metrics.push({
137
+ name: bucketKey,
138
+ value: bucket.count,
139
+ timestamp,
140
+ labels: this.extractLabels(bucketKey),
141
+ type: 'histogram',
142
+ });
143
+ }
144
+ }
145
+ return metrics;
146
+ }
147
+ extractLabels(metricKey) {
148
+ const labels = {};
149
+ const match = metricKey.match(/\{(.+)\}/);
150
+ if (match) {
151
+ const pairs = match[1].split(',');
152
+ for (const pair of pairs) {
153
+ const [key, value] = pair.split('=');
154
+ labels[key] = value.replace(/"/g, '');
155
+ }
156
+ }
157
+ return labels;
158
+ }
159
+ /**
160
+ * Clear metrics
161
+ */
162
+ reset() {
163
+ this.counters.clear();
164
+ this.gauges.clear();
165
+ this.histograms.clear();
166
+ this.createdAt = Date.now();
167
+ }
168
+ }
169
+ // Singleton instance
170
+ let metricsInstance = null;
171
+ function getMetrics() {
172
+ if (!metricsInstance) {
173
+ metricsInstance = new MetricsCollector();
174
+ }
175
+ return metricsInstance;
176
+ }
177
+ function createMetricsCollector() {
178
+ metricsInstance = new MetricsCollector();
179
+ return metricsInstance;
180
+ }
181
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/observability/metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ /**
3
+ * Express middleware for observability
4
+ * - Adds trace ID to all requests
5
+ * - Records request/response metrics
6
+ * - Attaches span context
7
+ */
8
+ export declare function observabilityMiddleware(req: Request, res: Response, next: NextFunction): void;
9
+ /**
10
+ * Fastify plugin for observability middleware
11
+ */
12
+ export declare function observabilityPlugin(instance: any, options: any, next: (err?: Error) => void): void;
13
+ /**
14
+ * Middleware for budget warning alerts
15
+ */
16
+ export declare function budgetAlertMiddleware(req: Request, res: Response, next: NextFunction): void;
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.observabilityMiddleware = observabilityMiddleware;
4
+ exports.observabilityPlugin = observabilityPlugin;
5
+ exports.budgetAlertMiddleware = budgetAlertMiddleware;
6
+ const tracer_1 = require("./tracer");
7
+ const metrics_1 = require("./metrics");
8
+ /**
9
+ * Express middleware for observability
10
+ * - Adds trace ID to all requests
11
+ * - Records request/response metrics
12
+ * - Attaches span context
13
+ */
14
+ function observabilityMiddleware(req, res, next) {
15
+ const tracer = (0, tracer_1.getTracer)();
16
+ const metrics = (0, metrics_1.getMetrics)();
17
+ // Generate or extract trace ID
18
+ const traceId = req.headers['x-trace-id'] || tracer.generateTraceId();
19
+ // Attach to request object
20
+ req.traceId = traceId;
21
+ req.spanId = null;
22
+ // Add trace ID to response headers
23
+ res.setHeader('X-Trace-ID', traceId);
24
+ // Start span for this request
25
+ const span = tracer.startSpan(`${req.method} ${req.path}`);
26
+ req.spanId = span.spanId;
27
+ req.span = span;
28
+ // Record start time for latency calculation
29
+ const startTime = Date.now();
30
+ // Hook into response finish
31
+ res.on('finish', () => {
32
+ const duration = Date.now() - startTime;
33
+ // End the span
34
+ tracer.endSpan(span.spanId, {
35
+ method: req.method,
36
+ path: req.path,
37
+ statusCode: res.statusCode,
38
+ durationMs: duration,
39
+ });
40
+ // Record metrics
41
+ const model = req.model || 'unknown';
42
+ const provider = req.provider || 'unknown';
43
+ const cacheHit = req.cacheHit || false;
44
+ const tier = req.tier || 'standard';
45
+ // Request counter
46
+ metrics.incrementCounter('a3m_router_requests_total', {
47
+ model,
48
+ provider,
49
+ tier,
50
+ cache_hit: String(cacheHit),
51
+ });
52
+ // Latency histogram (convert to seconds)
53
+ metrics.recordHistogram('a3m_request_latency_seconds', duration / 1000, {
54
+ model,
55
+ provider,
56
+ });
57
+ // Error counter
58
+ if (res.statusCode >= 400) {
59
+ metrics.incrementCounter('a3m_router_errors_total', {
60
+ provider,
61
+ error_type: res.statusCode >= 500 ? 'server_error' : 'client_error',
62
+ });
63
+ }
64
+ });
65
+ next();
66
+ }
67
+ /**
68
+ * Fastify plugin for observability middleware
69
+ */
70
+ function observabilityPlugin(instance, options, next) {
71
+ instance.addHook('onRequest', async (request, reply) => {
72
+ const tracer = (0, tracer_1.getTracer)();
73
+ const metrics = (0, metrics_1.getMetrics)();
74
+ const traceId = request.headers['x-trace-id'] || tracer.generateTraceId();
75
+ request.traceId = traceId;
76
+ reply.header('X-Trace-ID', traceId);
77
+ const span = tracer.startSpan(`${request.method} ${request.url}`);
78
+ request.spanId = span.spanId;
79
+ request.span = span;
80
+ request.startTime = Date.now();
81
+ });
82
+ instance.addHook('onResponse', async (request, reply) => {
83
+ const tracer = (0, tracer_1.getTracer)();
84
+ const metrics = (0, metrics_1.getMetrics)();
85
+ const duration = Date.now() - request.startTime;
86
+ if (request.spanId) {
87
+ tracer.endSpan(request.spanId, {
88
+ method: request.method,
89
+ path: request.url,
90
+ statusCode: reply.statusCode,
91
+ durationMs: duration,
92
+ });
93
+ }
94
+ const model = request.model || 'unknown';
95
+ const provider = request.provider || 'unknown';
96
+ const cacheHit = request.cacheHit || false;
97
+ const tier = request.tier || 'standard';
98
+ metrics.incrementCounter('a3m_router_requests_total', {
99
+ model,
100
+ provider,
101
+ tier,
102
+ cache_hit: String(cacheHit),
103
+ });
104
+ metrics.recordHistogram('a3m_request_latency_seconds', duration / 1000, {
105
+ model,
106
+ provider,
107
+ });
108
+ if (reply.statusCode >= 400) {
109
+ metrics.incrementCounter('a3m_router_errors_total', {
110
+ provider,
111
+ error_type: reply.statusCode >= 500 ? 'server_error' : 'client_error',
112
+ });
113
+ }
114
+ });
115
+ next();
116
+ }
117
+ /**
118
+ * Middleware for budget warning alerts
119
+ */
120
+ function budgetAlertMiddleware(req, res, next) {
121
+ const tracer = (0, tracer_1.getTracer)();
122
+ // Hook into cost tracking to emit budget warnings
123
+ tracer.on('route_complete', (trace) => {
124
+ // This would be connected to budget enforcement in practice
125
+ // For now just a placeholder for the event hook
126
+ });
127
+ next();
128
+ }
129
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/observability/middleware.ts"],"names":[],"mappings":"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"}