ai.matey.middleware 0.2.0

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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/caching.js +226 -0
  3. package/dist/cjs/caching.js.map +1 -0
  4. package/dist/cjs/conversation-history.js +213 -0
  5. package/dist/cjs/conversation-history.js.map +1 -0
  6. package/dist/cjs/cost-tracking.js +355 -0
  7. package/dist/cjs/cost-tracking.js.map +1 -0
  8. package/dist/cjs/index.js +37 -0
  9. package/dist/cjs/index.js.map +1 -0
  10. package/dist/cjs/logging.js +174 -0
  11. package/dist/cjs/logging.js.map +1 -0
  12. package/dist/cjs/opentelemetry.js +499 -0
  13. package/dist/cjs/opentelemetry.js.map +1 -0
  14. package/dist/cjs/retry.js +205 -0
  15. package/dist/cjs/retry.js.map +1 -0
  16. package/dist/cjs/security.js +175 -0
  17. package/dist/cjs/security.js.map +1 -0
  18. package/dist/cjs/telemetry.js +216 -0
  19. package/dist/cjs/telemetry.js.map +1 -0
  20. package/dist/cjs/transform.js +284 -0
  21. package/dist/cjs/transform.js.map +1 -0
  22. package/dist/cjs/validation.js +506 -0
  23. package/dist/cjs/validation.js.map +1 -0
  24. package/dist/esm/caching.js +221 -0
  25. package/dist/esm/caching.js.map +1 -0
  26. package/dist/esm/conversation-history.js +207 -0
  27. package/dist/esm/conversation-history.js.map +1 -0
  28. package/dist/esm/cost-tracking.js +347 -0
  29. package/dist/esm/cost-tracking.js.map +1 -0
  30. package/dist/esm/index.js +21 -0
  31. package/dist/esm/index.js.map +1 -0
  32. package/dist/esm/logging.js +171 -0
  33. package/dist/esm/logging.js.map +1 -0
  34. package/dist/esm/opentelemetry.js +458 -0
  35. package/dist/esm/opentelemetry.js.map +1 -0
  36. package/dist/esm/retry.js +198 -0
  37. package/dist/esm/retry.js.map +1 -0
  38. package/dist/esm/security.js +169 -0
  39. package/dist/esm/security.js.map +1 -0
  40. package/dist/esm/telemetry.js +210 -0
  41. package/dist/esm/telemetry.js.map +1 -0
  42. package/dist/esm/transform.js +272 -0
  43. package/dist/esm/transform.js.map +1 -0
  44. package/dist/esm/validation.js +494 -0
  45. package/dist/esm/validation.js.map +1 -0
  46. package/dist/types/caching.d.ts +98 -0
  47. package/dist/types/caching.d.ts.map +1 -0
  48. package/dist/types/conversation-history.d.ts +188 -0
  49. package/dist/types/conversation-history.d.ts.map +1 -0
  50. package/dist/types/cost-tracking.d.ts +262 -0
  51. package/dist/types/cost-tracking.d.ts.map +1 -0
  52. package/dist/types/index.d.ts +20 -0
  53. package/dist/types/index.d.ts.map +1 -0
  54. package/dist/types/logging.d.ts +82 -0
  55. package/dist/types/logging.d.ts.map +1 -0
  56. package/dist/types/opentelemetry.d.ts +219 -0
  57. package/dist/types/opentelemetry.d.ts.map +1 -0
  58. package/dist/types/retry.d.ts +86 -0
  59. package/dist/types/retry.d.ts.map +1 -0
  60. package/dist/types/security.d.ts +120 -0
  61. package/dist/types/security.d.ts.map +1 -0
  62. package/dist/types/telemetry.d.ts +120 -0
  63. package/dist/types/telemetry.d.ts.map +1 -0
  64. package/dist/types/transform.d.ts +184 -0
  65. package/dist/types/transform.d.ts.map +1 -0
  66. package/dist/types/validation.d.ts +356 -0
  67. package/dist/types/validation.d.ts.map +1 -0
  68. package/package.json +203 -0
  69. package/readme.md +103 -0
@@ -0,0 +1,347 @@
1
+ /**
2
+ * Cost Tracking Middleware
3
+ *
4
+ * Track and monitor API costs across different providers.
5
+ * Essential for production deployments to control spending.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * In-memory cost storage
11
+ */
12
+ export class InMemoryCostStorage {
13
+ costs = [];
14
+ record(cost) {
15
+ this.costs.push(cost);
16
+ return Promise.resolve();
17
+ }
18
+ getTotal(startTime, endTime) {
19
+ return Promise.resolve(this.filterCosts(startTime, endTime).reduce((sum, c) => sum + c.totalCost, 0));
20
+ }
21
+ getByProvider(startTime, endTime) {
22
+ const result = new Map();
23
+ for (const cost of this.filterCosts(startTime, endTime)) {
24
+ const current = result.get(cost.provider) || 0;
25
+ result.set(cost.provider, current + cost.totalCost);
26
+ }
27
+ return Promise.resolve(result);
28
+ }
29
+ getByModel(startTime, endTime) {
30
+ const result = new Map();
31
+ for (const cost of this.filterCosts(startTime, endTime)) {
32
+ const current = result.get(cost.model) || 0;
33
+ result.set(cost.model, current + cost.totalCost);
34
+ }
35
+ return Promise.resolve(result);
36
+ }
37
+ clear() {
38
+ this.costs = [];
39
+ return Promise.resolve();
40
+ }
41
+ filterCosts(startTime, endTime) {
42
+ return this.costs.filter((c) => {
43
+ if (startTime && c.timestamp < startTime) {
44
+ return false;
45
+ }
46
+ if (endTime && c.timestamp > endTime) {
47
+ return false;
48
+ }
49
+ return true;
50
+ });
51
+ }
52
+ /**
53
+ * Get all cost records (for debugging/export)
54
+ */
55
+ getAllCosts() {
56
+ return [...this.costs];
57
+ }
58
+ }
59
+ /**
60
+ * Default pricing for common providers (as of 2024)
61
+ * Prices in USD per 1M tokens
62
+ */
63
+ export const DEFAULT_PRICING = {
64
+ // Anthropic Claude
65
+ anthropic: {
66
+ inputCostPer1M: 3.0,
67
+ outputCostPer1M: 15.0,
68
+ },
69
+ 'anthropic:claude-3-opus': {
70
+ inputCostPer1M: 15.0,
71
+ outputCostPer1M: 75.0,
72
+ },
73
+ 'anthropic:claude-3-sonnet': {
74
+ inputCostPer1M: 3.0,
75
+ outputCostPer1M: 15.0,
76
+ },
77
+ 'anthropic:claude-3-haiku': {
78
+ inputCostPer1M: 0.25,
79
+ outputCostPer1M: 1.25,
80
+ },
81
+ // OpenAI
82
+ openai: {
83
+ inputCostPer1M: 10.0,
84
+ outputCostPer1M: 30.0,
85
+ },
86
+ 'openai:gpt-4': {
87
+ inputCostPer1M: 30.0,
88
+ outputCostPer1M: 60.0,
89
+ },
90
+ 'openai:gpt-4-turbo': {
91
+ inputCostPer1M: 10.0,
92
+ outputCostPer1M: 30.0,
93
+ },
94
+ 'openai:gpt-3.5-turbo': {
95
+ inputCostPer1M: 0.5,
96
+ outputCostPer1M: 1.5,
97
+ },
98
+ // Google Gemini
99
+ gemini: {
100
+ inputCostPer1M: 0.125,
101
+ outputCostPer1M: 0.375,
102
+ },
103
+ 'gemini:gemini-pro': {
104
+ inputCostPer1M: 0.5,
105
+ outputCostPer1M: 1.5,
106
+ },
107
+ // Mistral
108
+ mistral: {
109
+ inputCostPer1M: 1.0,
110
+ outputCostPer1M: 3.0,
111
+ },
112
+ // DeepSeek
113
+ deepseek: {
114
+ inputCostPer1M: 0.14,
115
+ outputCostPer1M: 0.28,
116
+ },
117
+ // Groq (very low cost)
118
+ groq: {
119
+ inputCostPer1M: 0.05,
120
+ outputCostPer1M: 0.1,
121
+ },
122
+ // Local/Free providers
123
+ ollama: {
124
+ inputCostPer1M: 0,
125
+ outputCostPer1M: 0,
126
+ },
127
+ lmstudio: {
128
+ inputCostPer1M: 0,
129
+ outputCostPer1M: 0,
130
+ },
131
+ };
132
+ /**
133
+ * Calculate cost for a request/response
134
+ */
135
+ export function calculateCost(usage, provider, model, config) {
136
+ // Find pricing for this provider/model
137
+ let pricing;
138
+ // Check model-specific pricing first
139
+ if (config.models) {
140
+ for (const modelPricing of config.models) {
141
+ if (typeof modelPricing.model === 'string') {
142
+ if (model === modelPricing.model || model.includes(modelPricing.model)) {
143
+ pricing = modelPricing.pricing;
144
+ break;
145
+ }
146
+ }
147
+ else if (modelPricing.model instanceof RegExp) {
148
+ if (modelPricing.model.test(model)) {
149
+ pricing = modelPricing.pricing;
150
+ break;
151
+ }
152
+ }
153
+ }
154
+ }
155
+ // Fall back to provider pricing
156
+ if (!pricing && config.providers) {
157
+ const providerKey = `${provider}:${model}`;
158
+ pricing = config.providers[providerKey] || config.providers[provider];
159
+ }
160
+ // Fall back to default pricing
161
+ if (!pricing) {
162
+ const providerKey = `${provider}:${model}`;
163
+ pricing = DEFAULT_PRICING[providerKey] || DEFAULT_PRICING[provider];
164
+ }
165
+ // If still no pricing, use zero cost
166
+ if (!pricing) {
167
+ pricing = { inputCostPer1M: 0, outputCostPer1M: 0 };
168
+ }
169
+ // Calculate costs
170
+ const inputCost = (usage.promptTokens / 1_000_000) * pricing.inputCostPer1M;
171
+ const outputCost = (usage.completionTokens / 1_000_000) * pricing.outputCostPer1M;
172
+ const totalCost = inputCost + outputCost;
173
+ return {
174
+ provider,
175
+ model,
176
+ inputTokens: usage.promptTokens,
177
+ outputTokens: usage.completionTokens,
178
+ totalTokens: usage.totalTokens,
179
+ inputCost,
180
+ outputCost,
181
+ totalCost,
182
+ timestamp: Date.now(),
183
+ requestId: '',
184
+ };
185
+ }
186
+ /**
187
+ * Create cost tracking middleware
188
+ *
189
+ * @param config - Cost tracking configuration
190
+ * @returns Middleware function
191
+ *
192
+ * @example Basic Usage
193
+ * ```typescript
194
+ * import { createCostTrackingMiddleware } from 'ai.matey';
195
+ *
196
+ * const costTracking = createCostTrackingMiddleware({
197
+ * logCosts: true,
198
+ * onCost: (cost) => {
199
+ * console.log(`Request cost: $${cost.totalCost.toFixed(6)}`);
200
+ * }
201
+ * });
202
+ *
203
+ * bridge.use(costTracking);
204
+ * ```
205
+ *
206
+ * @example With Custom Pricing
207
+ * ```typescript
208
+ * const costTracking = createCostTrackingMiddleware({
209
+ * providers: {
210
+ * 'anthropic': {
211
+ * inputCostPer1M: 3.0,
212
+ * outputCostPer1M: 15.0
213
+ * }
214
+ * },
215
+ * models: [
216
+ * {
217
+ * model: /gpt-4-turbo/,
218
+ * pricing: {
219
+ * inputCostPer1M: 10.0,
220
+ * outputCostPer1M: 30.0
221
+ * }
222
+ * }
223
+ * ]
224
+ * });
225
+ * ```
226
+ *
227
+ * @example With Thresholds
228
+ * ```typescript
229
+ * const costTracking = createCostTrackingMiddleware({
230
+ * requestThreshold: 0.10, // Warn if request costs > $0.10
231
+ * hourlyThreshold: 10.00, // Warn if hourly cost > $10
232
+ * dailyThreshold: 100.00, // Warn if daily cost > $100
233
+ * onThresholdExceeded: (cost, threshold) => {
234
+ * console.warn(`Cost threshold exceeded: $${cost.totalCost} > $${threshold}`);
235
+ * }
236
+ * });
237
+ * ```
238
+ */
239
+ export function createCostTrackingMiddleware(config = {}) {
240
+ const storage = config.storage || new InMemoryCostStorage();
241
+ return async (context, next) => {
242
+ // Execute request
243
+ const response = await next();
244
+ // Calculate cost if usage is available
245
+ if (response.usage) {
246
+ const provider = context.request.metadata?.provenance?.backend || 'unknown';
247
+ const model = context.request.parameters?.model || 'unknown';
248
+ const cost = calculateCost(response.usage, provider, model, config);
249
+ cost.requestId = context.request.metadata?.requestId || '';
250
+ cost.metadata = context.request.metadata?.custom;
251
+ // Store cost
252
+ await storage.record(cost);
253
+ // Check thresholds
254
+ if (config.requestThreshold && cost.totalCost > config.requestThreshold) {
255
+ await config.onThresholdExceeded?.(cost, config.requestThreshold);
256
+ }
257
+ if (config.hourlyThreshold) {
258
+ const hourAgo = Date.now() - 60 * 60 * 1000;
259
+ const hourTotal = await storage.getTotal(hourAgo);
260
+ if (hourTotal > config.hourlyThreshold) {
261
+ await config.onThresholdExceeded?.(cost, config.hourlyThreshold);
262
+ }
263
+ }
264
+ if (config.dailyThreshold) {
265
+ const dayAgo = Date.now() - 24 * 60 * 60 * 1000;
266
+ const dayTotal = await storage.getTotal(dayAgo);
267
+ if (dayTotal > config.dailyThreshold) {
268
+ await config.onThresholdExceeded?.(cost, config.dailyThreshold);
269
+ }
270
+ }
271
+ // Log cost if configured
272
+ if (config.logCosts) {
273
+ console.warn(`[Cost] ${provider}/${model}: $${cost.totalCost.toFixed(6)} ` +
274
+ `(${cost.inputTokens} in, ${cost.outputTokens} out)`);
275
+ }
276
+ // Call callback
277
+ await config.onCost?.(cost);
278
+ // Include in metadata if configured
279
+ if (config.includeInMetadata) {
280
+ return {
281
+ ...response,
282
+ metadata: {
283
+ ...response.metadata,
284
+ custom: {
285
+ ...(response.metadata?.custom || {}),
286
+ cost,
287
+ },
288
+ },
289
+ };
290
+ }
291
+ }
292
+ return response;
293
+ };
294
+ }
295
+ /**
296
+ * Create streaming cost tracking middleware
297
+ *
298
+ * Note: For streaming, cost is calculated at the end when usage is available
299
+ */
300
+ export function createStreamingCostTrackingMiddleware(config = {}) {
301
+ const storage = config.storage || new InMemoryCostStorage();
302
+ return async (context, next) => {
303
+ const stream = await next();
304
+ // Wrap stream to track usage
305
+ async function* wrappedStream() {
306
+ let usage;
307
+ for await (const chunk of stream) {
308
+ yield chunk;
309
+ // Capture usage from done chunk
310
+ if (chunk.type === 'done' && chunk.usage) {
311
+ usage = chunk.usage;
312
+ }
313
+ }
314
+ // Calculate cost after stream completes
315
+ if (usage) {
316
+ const provider = context.request.metadata?.provenance?.backend || 'unknown';
317
+ const model = context.request.parameters?.model || 'unknown';
318
+ const cost = calculateCost(usage, provider, model, config);
319
+ cost.requestId = context.request.metadata?.requestId || '';
320
+ cost.metadata = context.request.metadata?.custom;
321
+ await storage.record(cost);
322
+ if (config.logCosts) {
323
+ console.warn(`[Cost] ${provider}/${model}: $${cost.totalCost.toFixed(6)} ` +
324
+ `(${cost.inputTokens} in, ${cost.outputTokens} out)`);
325
+ }
326
+ await config.onCost?.(cost);
327
+ }
328
+ }
329
+ return wrappedStream();
330
+ };
331
+ }
332
+ /**
333
+ * Get cost statistics from storage
334
+ */
335
+ export async function getCostStats(storage, hours = 24) {
336
+ const since = Date.now() - hours * 60 * 60 * 1000;
337
+ const total = await storage.getTotal(since);
338
+ const byProvider = await storage.getByProvider(since);
339
+ const byModel = await storage.getByModel(since);
340
+ return {
341
+ period: `Last ${hours} hours`,
342
+ total,
343
+ byProvider: Object.fromEntries(byProvider),
344
+ byModel: Object.fromEntries(byModel),
345
+ };
346
+ }
347
+ //# sourceMappingURL=cost-tracking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-tracking.js","sourceRoot":"","sources":["../../src/cost-tracking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * AI Matey Middleware
3
+ *
4
+ * Consolidated package containing all middleware components.
5
+ * Middleware provides cross-cutting concerns like caching, retry,
6
+ * logging, and security for the AI adapter system.
7
+ *
8
+ * @module ai.matey.middleware
9
+ */
10
+ // Middleware components
11
+ export * from './caching.js';
12
+ export * from './conversation-history.js';
13
+ export * from './cost-tracking.js';
14
+ export * from './logging.js';
15
+ export * from './opentelemetry.js';
16
+ export * from './retry.js';
17
+ export * from './security.js';
18
+ export * from './telemetry.js';
19
+ export * from './transform.js';
20
+ export * from './validation.js';
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wBAAwB;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Logging Middleware
3
+ *
4
+ * Logs requests, responses, and errors with configurable levels and sanitization.
5
+ *
6
+ * @module
7
+ */
8
+ // ============================================================================
9
+ // Default Logger
10
+ // ============================================================================
11
+ /**
12
+ * Default console logger.
13
+ */
14
+ const defaultLogger = {
15
+ debug: (message, data) => {
16
+ // eslint-disable-next-line no-console
17
+ console.debug(message, data !== undefined ? data : '');
18
+ },
19
+ info: (message, data) => {
20
+ // eslint-disable-next-line no-console
21
+ console.info(message, data !== undefined ? data : '');
22
+ },
23
+ warn: (message, data) => {
24
+ console.warn(message, data !== undefined ? data : '');
25
+ },
26
+ error: (message, data) => {
27
+ console.error(message, data !== undefined ? data : '');
28
+ },
29
+ };
30
+ // ============================================================================
31
+ // Sanitization
32
+ // ============================================================================
33
+ /**
34
+ * Sanitize sensitive data from objects.
35
+ */
36
+ function sanitizeData(data) {
37
+ if (data === null || data === undefined) {
38
+ return data;
39
+ }
40
+ if (typeof data !== 'object') {
41
+ return data;
42
+ }
43
+ if (Array.isArray(data)) {
44
+ return data.map(sanitizeData);
45
+ }
46
+ const sanitized = {};
47
+ const sensitiveKeys = ['apiKey', 'api_key', 'authorization', 'token', 'secret', 'password'];
48
+ for (const [key, value] of Object.entries(data)) {
49
+ const lowerKey = key.toLowerCase();
50
+ if (sensitiveKeys.some((sensitive) => lowerKey.includes(sensitive))) {
51
+ sanitized[key] = '[REDACTED]';
52
+ }
53
+ else if (typeof value === 'object' && value !== null) {
54
+ sanitized[key] = sanitizeData(value);
55
+ }
56
+ else {
57
+ sanitized[key] = value;
58
+ }
59
+ }
60
+ return sanitized;
61
+ }
62
+ /**
63
+ * Sanitize request for logging.
64
+ */
65
+ function sanitizeRequest(request, shouldSanitize) {
66
+ if (!shouldSanitize) {
67
+ return request;
68
+ }
69
+ return sanitizeData(request);
70
+ }
71
+ /**
72
+ * Sanitize response for logging.
73
+ */
74
+ function sanitizeResponse(response, shouldSanitize) {
75
+ if (!shouldSanitize) {
76
+ return response;
77
+ }
78
+ return sanitizeData(response);
79
+ }
80
+ // ============================================================================
81
+ // Log Level Comparison
82
+ // ============================================================================
83
+ const LOG_LEVELS = {
84
+ debug: 0,
85
+ info: 1,
86
+ warn: 2,
87
+ error: 3,
88
+ };
89
+ function shouldLog(currentLevel, targetLevel) {
90
+ return LOG_LEVELS[targetLevel] >= LOG_LEVELS[currentLevel];
91
+ }
92
+ // ============================================================================
93
+ // Middleware Factory
94
+ // ============================================================================
95
+ /**
96
+ * Create logging middleware.
97
+ *
98
+ * Logs requests, responses, and errors at configurable levels.
99
+ *
100
+ * @param config Logging configuration
101
+ * @returns Logging middleware
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const logging = createLoggingMiddleware({
106
+ * level: 'info',
107
+ * logRequests: true,
108
+ * logResponses: true,
109
+ * sanitize: true
110
+ * });
111
+ *
112
+ * bridge.use(logging);
113
+ * ```
114
+ */
115
+ export function createLoggingMiddleware(config = {}) {
116
+ const { level = 'info', logRequests = true, logResponses = true, logErrors = true, sanitize = true, logger = defaultLogger, prefix = '[Bridge]', } = config;
117
+ return async (context, next) => {
118
+ const startTime = Date.now();
119
+ const requestId = context.request.metadata.requestId;
120
+ // Log request
121
+ if (logRequests && shouldLog(level, 'debug')) {
122
+ logger.debug(`${prefix} Request ${requestId}`, {
123
+ model: context.request.parameters?.model,
124
+ messages: context.request.messages.length,
125
+ stream: context.request.stream,
126
+ frontend: context.request.metadata.provenance?.frontend,
127
+ backend: context.request.metadata.provenance?.backend,
128
+ });
129
+ if (shouldLog(level, 'debug')) {
130
+ logger.debug(`${prefix} Request details ${requestId}`, {
131
+ request: sanitizeRequest(context.request, sanitize),
132
+ });
133
+ }
134
+ }
135
+ try {
136
+ // Call next middleware/handler
137
+ const response = await next();
138
+ // Calculate duration
139
+ const duration = Date.now() - startTime;
140
+ // Log response
141
+ if (logResponses && shouldLog(level, 'info')) {
142
+ logger.info(`${prefix} Response ${requestId}`, {
143
+ duration: `${duration}ms`,
144
+ finishReason: response.finishReason,
145
+ tokens: response.usage?.totalTokens,
146
+ backend: response.metadata.provenance?.backend,
147
+ });
148
+ if (shouldLog(level, 'debug')) {
149
+ logger.debug(`${prefix} Response details ${requestId}`, {
150
+ response: sanitizeResponse(response, sanitize),
151
+ });
152
+ }
153
+ }
154
+ return response;
155
+ }
156
+ catch (error) {
157
+ const duration = Date.now() - startTime;
158
+ // Log error
159
+ if (logErrors && shouldLog(level, 'error')) {
160
+ logger.error(`${prefix} Error ${requestId}`, {
161
+ duration: `${duration}ms`,
162
+ error: error instanceof Error ? error.message : String(error),
163
+ stack: error instanceof Error ? error.stack : undefined,
164
+ });
165
+ }
166
+ // Re-throw error
167
+ throw error;
168
+ }
169
+ };
170
+ }
171
+ //# sourceMappingURL=logging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.js","sourceRoot":"","sources":["../../src/logging.ts"],"names":[],"mappings":"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"}