@revenium/anthropic 1.0.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.
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Configuration constants for Revenium Anthropic middleware
3
+ * Centralizes all magic numbers and default values
4
+ */
5
+ /**
6
+ * Default configuration values
7
+ */
8
+ export const DEFAULT_CONFIG = {
9
+ /** Default Revenium API base URL */
10
+ REVENIUM_BASE_URL: 'https://api.revenium.io/meter',
11
+ /** Default API timeout in milliseconds */
12
+ API_TIMEOUT: 5000,
13
+ /** Default maximum retries for failed API calls */
14
+ MAX_RETRIES: 3,
15
+ /** Default fail silent behavior */
16
+ FAIL_SILENT: true,
17
+ /** Minimum allowed API timeout */
18
+ MIN_API_TIMEOUT: 1000,
19
+ /** Maximum allowed API timeout */
20
+ MAX_API_TIMEOUT: 60000,
21
+ /** Maximum allowed retry attempts */
22
+ MAX_RETRY_ATTEMPTS: 10,
23
+ /** Warning threshold for low API timeout */
24
+ LOW_TIMEOUT_WARNING_THRESHOLD: 3000,
25
+ };
26
+ /**
27
+ * Circuit breaker configuration constants
28
+ */
29
+ export const CIRCUIT_BREAKER_CONFIG = {
30
+ /** Default number of failures before opening circuit */
31
+ FAILURE_THRESHOLD: 5,
32
+ /** Default recovery timeout in milliseconds (30 seconds) */
33
+ RECOVERY_TIMEOUT: 30000,
34
+ /** Default number of successful calls needed to close circuit */
35
+ SUCCESS_THRESHOLD: 3,
36
+ /** Default time window for counting failures (1 minute) */
37
+ TIME_WINDOW: 60000,
38
+ /** Maximum failure history size to prevent memory leaks */
39
+ MAX_FAILURE_HISTORY_SIZE: 1000,
40
+ /** Periodic cleanup interval (5 minutes) */
41
+ CLEANUP_INTERVAL: 300000,
42
+ /** Cleanup trigger threshold for failures array size */
43
+ CLEANUP_SIZE_THRESHOLD: 100,
44
+ };
45
+ /**
46
+ * Retry configuration constants
47
+ */
48
+ export const RETRY_CONFIG = {
49
+ /** Base delay for exponential backoff in milliseconds */
50
+ BASE_DELAY: 1000,
51
+ /** Maximum delay for exponential backoff */
52
+ MAX_DELAY: 5000,
53
+ /** Jitter factor for randomizing delays */
54
+ JITTER_FACTOR: 0.1,
55
+ };
56
+ /**
57
+ * Validation constants
58
+ */
59
+ export const VALIDATION_CONFIG = {
60
+ /** Minimum API key length */
61
+ MIN_API_KEY_LENGTH: 20,
62
+ /** Required API key prefix for Revenium */
63
+ REVENIUM_API_KEY_PREFIX: 'hak_',
64
+ /** Required API key prefix for Anthropic */
65
+ ANTHROPIC_API_KEY_PREFIX: 'sk-ant-',
66
+ /** Maximum tokens warning threshold */
67
+ HIGH_MAX_TOKENS_THRESHOLD: 4096,
68
+ /** Temperature range */
69
+ MIN_TEMPERATURE: 0,
70
+ MAX_TEMPERATURE: 1,
71
+ /** Response quality score range */
72
+ MIN_QUALITY_SCORE: 0,
73
+ MAX_QUALITY_SCORE: 1,
74
+ /** API timeout constraints */
75
+ MIN_API_TIMEOUT: 1000,
76
+ MAX_API_TIMEOUT: 60000,
77
+ LOW_TIMEOUT_WARNING_THRESHOLD: 3000,
78
+ /** Retry constraints */
79
+ MAX_RETRY_ATTEMPTS: 10,
80
+ };
81
+ /**
82
+ * Logging constants
83
+ */
84
+ export const LOGGING_CONFIG = {
85
+ /** Middleware name for log prefixes */
86
+ MIDDLEWARE_NAME: 'Revenium',
87
+ /** User agent string for API requests */
88
+ USER_AGENT: 'revenium-middleware-anthropic-node/1.0.0',
89
+ /** Debug environment variable name */
90
+ DEBUG_ENV_VAR: 'REVENIUM_DEBUG',
91
+ };
92
+ /**
93
+ * Environment variable names
94
+ */
95
+ export const ENV_VARS = {
96
+ /** Revenium API key */
97
+ REVENIUM_API_KEY: 'REVENIUM_METERING_API_KEY',
98
+ /** Revenium base URL */
99
+ REVENIUM_BASE_URL: 'REVENIUM_METERING_BASE_URL',
100
+ /** Anthropic API key */
101
+ ANTHROPIC_API_KEY: 'ANTHROPIC_API_KEY',
102
+ /** Debug mode */
103
+ DEBUG: 'REVENIUM_DEBUG',
104
+ /** Log level */
105
+ LOG_LEVEL: 'REVENIUM_LOG_LEVEL',
106
+ /** API timeout */
107
+ API_TIMEOUT: 'REVENIUM_API_TIMEOUT',
108
+ /** Fail silent mode */
109
+ FAIL_SILENT: 'REVENIUM_FAIL_SILENT',
110
+ /** Maximum retries */
111
+ MAX_RETRIES: 'REVENIUM_MAX_RETRIES',
112
+ };
113
+ /**
114
+ * API endpoints
115
+ */
116
+ export const API_ENDPOINTS = {
117
+ /** Revenium AI completions endpoint */
118
+ AI_COMPLETIONS: '/v2/ai/completions',
119
+ };
120
+ /**
121
+ * Anthropic model patterns
122
+ */
123
+ export const ANTHROPIC_PATTERNS = {
124
+ /** Pattern to identify Claude models */
125
+ CLAUDE_MODEL_PATTERN: /claude/i,
126
+ /** Known Anthropic stop reasons */
127
+ STOP_REASONS: {
128
+ END_TURN: 'end_turn',
129
+ MAX_TOKENS: 'max_tokens',
130
+ STOP_SEQUENCE: 'stop_sequence',
131
+ TOOL_USE: 'tool_use',
132
+ },
133
+ /** Revenium stop reason mappings */
134
+ REVENIUM_STOP_REASON_MAP: {
135
+ 'end_turn': 'END',
136
+ 'max_tokens': 'TOKEN_LIMIT',
137
+ 'stop_sequence': 'END_SEQUENCE',
138
+ 'tool_use': 'END',
139
+ },
140
+ };
141
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Modern Revenium Anthropic Middleware
3
+ * Clean architecture without backward compatibility constraints
4
+ */
5
+ // Import type augmentations to extend Anthropic types with usageMetadata
6
+ import "./types/anthropic-augmentation.js";
7
+ import { initializeConfig, getLogger, setConfig, getConfig, getConfigStatus, } from "./config.js";
8
+ import { patchAnthropic, unpatchAnthropic, isAnthropicPatched, } from "./wrapper.js";
9
+ import { trackUsageAsync } from "./tracking.js";
10
+ import { getCircuitBreakerStats, resetCircuitBreaker, } from "./utils/circuit-breaker.js";
11
+ // Export configuration functions
12
+ export { setConfig, setLogger, getLogger, getConfig, getConfigStatus, validateCurrentConfig, } from "./config.js";
13
+ // Export wrapper control functions
14
+ export { patchAnthropic, unpatchAnthropic, isAnthropicPatched, } from "./wrapper.js";
15
+ // Export tracking functions
16
+ export { sendReveniumMetrics, trackUsageAsync, extractUsageFromStream, } from "./tracking.js";
17
+ // Export utility functions
18
+ export { getCircuitBreakerStats, resetCircuitBreaker, canExecuteRequest, } from "./utils/circuit-breaker.js";
19
+ export { validateReveniumConfig, validateAnthropicMessageParams, validateUsageMetadata, } from "./utils/validation.js";
20
+ /**
21
+ * Initialize the Revenium middleware with configuration from environment variables
22
+ * This function can be called explicitly for better error handling and control
23
+ *
24
+ *
25
+ *
26
+ */
27
+ // Global logger
28
+ const logger = getLogger();
29
+ export function initialize() {
30
+ const initialized = initializeConfig();
31
+ if (!initialized) {
32
+ throw new Error("Failed to initialize Revenium middleware: missing required environment variables. " +
33
+ "Set REVENIUM_METERING_API_KEY or call configure() with manual configuration.");
34
+ }
35
+ try {
36
+ patchAnthropic();
37
+ logger.info("Revenium Anthropic middleware initialized successfully");
38
+ logger.debug("Environment variables found and configuration loaded");
39
+ }
40
+ catch (patchError) {
41
+ const errorMessage = patchError instanceof Error ? patchError.message : String(patchError);
42
+ throw new Error(`Failed to patch Anthropic SDK: ${errorMessage}`);
43
+ }
44
+ }
45
+ /**
46
+ * Auto-initialization with graceful fallback
47
+ * Attempts to initialize automatically but doesn't throw on failure
48
+ */
49
+ function autoInitialize() {
50
+ try {
51
+ initialize();
52
+ }
53
+ catch (error) {
54
+ // Log debug message but don't throw - allow manual configuration later
55
+ logger.debug("Auto-initialization failed, manual configuration required", {
56
+ error: error instanceof Error ? error.message : String(error),
57
+ suggestion: "Call initialize() or configure() explicitly for detailed error information",
58
+ });
59
+ }
60
+ }
61
+ // Perform auto-initialization with graceful fallback
62
+ autoInitialize();
63
+ /**
64
+ * Manual initialization with custom configuration
65
+ */
66
+ export function configure(config) {
67
+ setConfig(config);
68
+ patchAnthropic();
69
+ getLogger().info("Revenium Anthropic middleware configured successfully");
70
+ }
71
+ /**
72
+ * Check if the middleware is properly initialized
73
+ */
74
+ export function isInitialized() {
75
+ return isAnthropicPatched() && !!getConfig();
76
+ }
77
+ /**
78
+ * Get comprehensive middleware status
79
+ */
80
+ export function getStatus() {
81
+ const configStatus = getConfigStatus();
82
+ const circuitBreakerStats = getCircuitBreakerStats();
83
+ let anthropicVersion;
84
+ try {
85
+ // Try to get Anthropic version - use dynamic require for compatibility
86
+ const anthropicPackage = globalThis.require?.("@anthropic-ai/sdk/package.json");
87
+ anthropicVersion = anthropicPackage?.version;
88
+ }
89
+ catch {
90
+ // Ignore if we can't get the version
91
+ }
92
+ return {
93
+ initialized: isInitialized(),
94
+ patched: isAnthropicPatched(),
95
+ hasConfig: configStatus.hasConfig,
96
+ anthropicVersion,
97
+ circuitBreakerState: circuitBreakerStats.state,
98
+ };
99
+ }
100
+ /**
101
+ * Manually track an Anthropic API call (for cases where auto-patching isn't used)
102
+ */
103
+ export function trackAnthropicCall(trackingData) {
104
+ return trackUsageAsync(trackingData);
105
+ }
106
+ /**
107
+ * Reset middleware to initial state (useful for testing)
108
+ */
109
+ export function reset() {
110
+ try {
111
+ unpatchAnthropic();
112
+ resetCircuitBreaker();
113
+ logger.debug("Middleware reset completed");
114
+ }
115
+ catch (error) {
116
+ logger.error("Error during middleware reset", {
117
+ error: error instanceof Error ? error.message : String(error),
118
+ });
119
+ }
120
+ }
121
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Tracking implementation for Anthropic middleware with resilience patterns
3
+ */
4
+ import fetch from "node-fetch";
5
+ import { getConfig, getLogger } from "./config.js";
6
+ import { executeWithCircuitBreaker } from "./utils/circuit-breaker.js";
7
+ import { withRetry, ReveniumApiError, createErrorContext, handleError, } from "./utils/error-handling.js";
8
+ import { DEFAULT_CONFIG, API_ENDPOINTS, LOGGING_CONFIG, ANTHROPIC_PATTERNS, } from "./constants.js";
9
+ // Global logger
10
+ const logger = getLogger();
11
+ /**
12
+ * Send tracking data to Revenium API with resilience patterns
13
+ */
14
+ export async function sendReveniumMetrics(data) {
15
+ const config = getConfig();
16
+ if (!config)
17
+ throw new Error("Revenium configuration not available");
18
+ const requestId = data.requestId;
19
+ logger.debug("Preparing to send metrics to Revenium", {
20
+ requestId,
21
+ model: data.model,
22
+ inputTokens: data.inputTokens,
23
+ outputTokens: data.outputTokens,
24
+ duration: data.duration,
25
+ isStreamed: data.isStreamed,
26
+ });
27
+ // Build payload using exact structure from working implementations
28
+ const payload = buildReveniumPayload(data);
29
+ // Create request options
30
+ const requestOptions = {
31
+ method: "POST",
32
+ headers: {
33
+ "Content-Type": "application/json",
34
+ "x-api-key": config.reveniumApiKey,
35
+ "User-Agent": LOGGING_CONFIG.USER_AGENT,
36
+ },
37
+ body: JSON.stringify(payload),
38
+ timeout: config.apiTimeout || DEFAULT_CONFIG.API_TIMEOUT,
39
+ };
40
+ // Add abort signal for timeout
41
+ const controller = new AbortController();
42
+ const timeoutId = setTimeout(() => controller.abort(), requestOptions.timeout);
43
+ requestOptions.signal = controller.signal;
44
+ // Handle abort signal errors to prevent unhandled error events
45
+ controller.signal.addEventListener("abort", () => {
46
+ // Silently handle abort - this is expected behavior for timeouts
47
+ });
48
+ try {
49
+ // Execute with circuit breaker and retry logic
50
+ await executeWithCircuitBreaker(async () => {
51
+ return withRetry(async () => {
52
+ logger.debug("Sending request to Revenium API", {
53
+ requestId,
54
+ url: `${config.reveniumBaseUrl}${API_ENDPOINTS.AI_COMPLETIONS}`,
55
+ payloadSize: requestOptions.body.length,
56
+ });
57
+ let response;
58
+ try {
59
+ response = await fetch(`${config.reveniumBaseUrl}${API_ENDPOINTS.AI_COMPLETIONS}`, requestOptions);
60
+ }
61
+ catch (fetchError) {
62
+ // Handle AbortError and other fetch errors
63
+ if (fetchError instanceof Error && fetchError.name === "AbortError") {
64
+ throw new Error(`Request timeout after ${requestOptions.timeout}ms`);
65
+ }
66
+ throw fetchError;
67
+ }
68
+ if (!response.ok) {
69
+ const responseText = await response
70
+ .text()
71
+ .catch(() => "Unable to read response");
72
+ const errorContext = createErrorContext()
73
+ .withRequestId(requestId)
74
+ .withModel(data.model)
75
+ .withStatus(response.status)
76
+ .with("responseBody", responseText)
77
+ .build();
78
+ throw new ReveniumApiError(`Revenium API error: ${response.status} ${response.statusText}`, response.status, responseText, errorContext);
79
+ }
80
+ logger.debug("Successfully sent metrics to Revenium", {
81
+ requestId,
82
+ status: response.status,
83
+ duration: data.duration,
84
+ });
85
+ return response;
86
+ }, config.maxRetries || DEFAULT_CONFIG.MAX_RETRIES);
87
+ });
88
+ }
89
+ catch (error) {
90
+ const errorContext = createErrorContext()
91
+ .withRequestId(requestId)
92
+ .withModel(data.model)
93
+ .withDuration(data.duration)
94
+ .build();
95
+ handleError(error, logger, errorContext);
96
+ // Always fail silently for tracking errors to prevent breaking user's application
97
+ // Tracking errors should never break the user's main application flow
98
+ }
99
+ finally {
100
+ clearTimeout(timeoutId);
101
+ }
102
+ }
103
+ /**
104
+ * Build Revenium payload from tracking data
105
+ */
106
+ function buildReveniumPayload(data) {
107
+ const now = new Date().toISOString();
108
+ const requestTime = data.requestTime.toISOString();
109
+ const completionStartTime = data.responseTime.toISOString();
110
+ return {
111
+ stopReason: getStopReason(data.stopReason),
112
+ costType: "AI",
113
+ isStreamed: data.isStreamed,
114
+ taskType: data.metadata?.taskType,
115
+ agent: data.metadata?.agent,
116
+ operationType: "CHAT",
117
+ inputTokenCount: data.inputTokens,
118
+ outputTokenCount: data.outputTokens,
119
+ reasoningTokenCount: 0, // Anthropic doesn't currently have reasoning tokens
120
+ cacheCreationTokenCount: data.cacheCreationTokens || 0,
121
+ cacheReadTokenCount: data.cacheReadTokens || 0,
122
+ totalTokenCount: data.inputTokens + data.outputTokens,
123
+ organizationId: data.metadata?.organizationId,
124
+ productId: data.metadata?.productId,
125
+ subscriber: data.metadata?.subscriber, // Pass through nested subscriber object directly
126
+ subscriptionId: data.metadata?.subscriptionId,
127
+ model: data.model,
128
+ transactionId: data.requestId,
129
+ responseTime: now,
130
+ requestDuration: Math.round(data.duration),
131
+ provider: "Anthropic",
132
+ requestTime: requestTime,
133
+ completionStartTime: completionStartTime,
134
+ timeToFirstToken: data.timeToFirstToken || 0,
135
+ traceId: data.metadata?.traceId,
136
+ middlewareSource: "nodejs",
137
+ };
138
+ }
139
+ /**
140
+ * Normalize stop reason for Revenium API
141
+ */
142
+ function getStopReason(stopReason) {
143
+ if (!stopReason)
144
+ return "END";
145
+ // Use predefined mapping from constants
146
+ return (ANTHROPIC_PATTERNS.REVENIUM_STOP_REASON_MAP[stopReason] || "END");
147
+ }
148
+ /**
149
+ * Fire-and-forget async tracking wrapper
150
+ * Ensures tracking never blocks the main application flow
151
+ */
152
+ export function trackUsageAsync(trackingData) {
153
+ const config = getConfig();
154
+ if (!config)
155
+ return logger.warn("Revenium configuration not available - skipping tracking", {
156
+ requestId: trackingData.requestId,
157
+ });
158
+ // Run tracking in background without awaiting
159
+ sendReveniumMetrics(trackingData)
160
+ .then(() => {
161
+ logger.debug("Revenium tracking completed successfully", {
162
+ requestId: trackingData.requestId,
163
+ model: trackingData.model,
164
+ totalTokens: trackingData.inputTokens + trackingData.outputTokens,
165
+ });
166
+ })
167
+ .catch((error) => {
168
+ const errorContext = createErrorContext()
169
+ .withRequestId(trackingData.requestId)
170
+ .withModel(trackingData.model)
171
+ .build();
172
+ logger.warn("Revenium tracking failed", {
173
+ error: error instanceof Error ? error.message : String(error),
174
+ requestId: trackingData.requestId,
175
+ context: errorContext,
176
+ });
177
+ });
178
+ }
179
+ /**
180
+ * Extract usage data from Anthropic response
181
+ */
182
+ export function extractUsageFromResponse(response) {
183
+ const usage = response.usage || {};
184
+ return {
185
+ inputTokens: usage.input_tokens || 0,
186
+ outputTokens: usage.output_tokens || 0,
187
+ cacheCreationTokens: usage.cache_creation_input_tokens,
188
+ cacheReadTokens: usage.cache_read_input_tokens,
189
+ stopReason: response.stop_reason,
190
+ };
191
+ }
192
+ /**
193
+ * Extract usage data from streaming chunks
194
+ */
195
+ export function extractUsageFromStream(chunks) {
196
+ let inputTokens = 0;
197
+ let outputTokens = 0;
198
+ let cacheCreationTokens;
199
+ let cacheReadTokens;
200
+ let stopReason;
201
+ for (const chunk of chunks) {
202
+ let usage = null;
203
+ // According to Anthropic docs, usage data appears in:
204
+ // 1. message_start event: chunk.message.usage (initial token count)
205
+ // 2. message_delta event: chunk.usage (final token count)
206
+ // 3. Direct usage field on chunk
207
+ if (chunk?.type === "message_start" && chunk?.message?.usage) {
208
+ usage = chunk?.message?.usage;
209
+ }
210
+ else if (chunk?.usage) {
211
+ usage = chunk?.usage;
212
+ }
213
+ else if (chunk?.delta?.usage) {
214
+ usage = chunk?.delta?.usage;
215
+ }
216
+ //Verify usage with optional chaining
217
+ // Use the highest token counts found (message_delta should have final counts)
218
+ if (usage?.input_tokens) {
219
+ inputTokens = Math.max(inputTokens, usage?.input_tokens);
220
+ }
221
+ if (usage?.output_tokens) {
222
+ outputTokens = Math.max(outputTokens, usage?.output_tokens);
223
+ }
224
+ if (usage?.cache_creation_input_tokens) {
225
+ cacheCreationTokens = usage?.cache_creation_input_tokens;
226
+ }
227
+ if (usage?.cache_read_input_tokens) {
228
+ cacheReadTokens = usage?.cache_read_input_tokens;
229
+ }
230
+ // Extract stop reason from delta
231
+ if (chunk?.delta?.stop_reason) {
232
+ stopReason = chunk?.delta?.stop_reason;
233
+ }
234
+ }
235
+ return {
236
+ inputTokens,
237
+ outputTokens,
238
+ cacheCreationTokens,
239
+ cacheReadTokens,
240
+ stopReason,
241
+ };
242
+ }
243
+ //# sourceMappingURL=tracking.js.map
@@ -0,0 +1,86 @@
1
+ /**
2
+ * TypeScript module augmentation for Anthropic SDK
3
+ *
4
+ * This file extends Anthropic's existing types to include the usageMetadata field
5
+ * through TypeScript's declaration merging feature. This allows developers to
6
+ * use usageMetadata directly in Anthropic API calls without type casting or
7
+ * TypeScript errors.
8
+ *
9
+ * ## What is Module Augmentation?
10
+ *
11
+ * Module augmentation is a TypeScript feature that allows you to extend existing
12
+ * interfaces from external libraries. When you import this middleware, TypeScript
13
+ * automatically recognizes the usageMetadata field as a valid parameter.
14
+ *
15
+ * ## Benefits:
16
+ * - **Type Safety**: Full IntelliSense support for usageMetadata
17
+ * - **No Type Casting**: Use usageMetadata directly without `as any`
18
+ * - **Automatic Validation**: TypeScript validates the structure at compile time
19
+ * - **Better Developer Experience**: Auto-completion and error detection
20
+ *
21
+ * ## Usage Examples:
22
+ *
23
+ * ### Basic Usage:
24
+ * ```typescript
25
+ * import 'revenium-middleware-anthropic-node';
26
+ * import Anthropic from '@anthropic-ai/sdk';
27
+ *
28
+ * const anthropic = new Anthropic();
29
+ *
30
+ * const response = await anthropic.messages.create({
31
+ * model: 'claude-3-5-sonnet-latest',
32
+ * max_tokens: 1024,
33
+ * messages: [{ role: 'user', content: 'Hello!' }],
34
+ * usageMetadata: { // TypeScript recognizes this natively
35
+ * subscriber: { id: 'user-123', email: 'user@example.com' },
36
+ * organizationId: 'my-company',
37
+ * taskType: 'customer-support',
38
+ * traceId: 'session-abc-123'
39
+ * }
40
+ * });
41
+ * ```
42
+ *
43
+ * ### Streaming Usage:
44
+ * ```typescript
45
+ * const stream = await anthropic.messages.stream({
46
+ * model: 'claude-3-5-sonnet-latest',
47
+ * max_tokens: 1024,
48
+ * messages: [{ role: 'user', content: 'Generate a report' }],
49
+ * usageMetadata: {
50
+ * taskType: 'content-generation',
51
+ * productId: 'report-generator',
52
+ * responseQualityScore: 0.95
53
+ * }
54
+ * });
55
+ * ```
56
+ *
57
+ * ### Advanced Usage with All Fields:
58
+ * ```typescript
59
+ * const response = await anthropic.messages.create({
60
+ * model: 'claude-3-5-sonnet-latest',
61
+ * max_tokens: 2048,
62
+ * messages: [{ role: 'user', content: 'Complex analysis task' }],
63
+ * usageMetadata: {
64
+ * subscriber: {
65
+ * id: 'user-456',
66
+ * email: 'analyst@company.com',
67
+ * credential: { name: 'api-key', value: 'sk-...' }
68
+ * },
69
+ * traceId: 'analysis-session-789',
70
+ * taskId: 'task-001',
71
+ * taskType: 'data-analysis',
72
+ * organizationId: 'enterprise-client',
73
+ * subscriptionId: 'premium-plan',
74
+ * productId: 'analytics-suite',
75
+ * agent: 'data-analyst-bot',
76
+ * responseQualityScore: 0.98,
77
+ * customField: 'custom-value' // Extensible with custom fields
78
+ * }
79
+ * });
80
+ * ```
81
+ *
82
+ * @public
83
+ * @since 1.1.0
84
+ */
85
+ export {};
86
+ //# sourceMappingURL=anthropic-augmentation.js.map
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Type definitions for Anthropic middleware
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map