@revenium/anthropic 1.0.7 → 1.0.9

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/CHANGELOG.md CHANGED
@@ -2,9 +2,50 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.0.9] - 2026-01-06
6
+
7
+ ### Added
8
+
9
+ - Added terminal cost/metrics summary output after each API call
10
+ - Added distributed tracing support with 10 visualization fields
11
+
12
+ ### Fixed
13
+
14
+ - Fixed config validation to use normalized values in setConfig()
15
+ - Fixed reveniumBaseUrl to be optional with default value
16
+ - Fixed teamId whitespace trimming to prevent cost lookup issues
17
+ - Fixed usage summary to print even when Revenium tracking fails
18
+
19
+ ### Changed
20
+
21
+ - Improved error messages to use generic 'environment variable' wording
22
+
23
+ ## [1.0.8] - 2025-11-07
24
+
25
+ ### Fixed
26
+
27
+ - Fixed `anthropicApiKey` configuration parameter to honor config value before environment variable
28
+ - Fixed `failSilent=false` configuration to properly propagate tracking errors
29
+ - Fixed `maxRetries=0` handling to allow zero retries when explicitly configured
30
+
31
+ ### Added
32
+
33
+ - Added `timeToFirstToken` metric tracking for streaming requests
34
+ - Added custom metadata field preservation beyond standard fields
35
+ - Added website link (www.revenium.ai) to README Support section
36
+
37
+ ### Changed
38
+
39
+ - Updated Revenium API base URL from `api.revenium.io` to `api.revenium.ai`
40
+ - Updated Node.js requirement from 16+ to 18+
41
+ - Updated `.gitignore` to exclude `dist/` directory and `.env.test`
42
+ - Excluded `.claude/` directory and `*.log` files from npm package
43
+ - Removed `package-lock.json` from public repository allowlist
44
+
5
45
  ## [1.0.7] - 2025-10-25
6
46
 
7
47
  ### Changed
48
+
8
49
  - Updated all examples to use `claude-haiku-4-5` (validated Anthropic model identifier)
9
50
  - Improved examples documentation with getting_started.ts reference
10
51
  - Streamlined README by removing OpenRouter section for clarity
@@ -12,21 +53,25 @@ All notable changes to this project will be documented in this file.
12
53
  ## [1.0.6] - 2025-10-24
13
54
 
14
55
  ### Added
56
+
15
57
  - Comprehensive metadata fields table in README with practical use cases for all 11 fields
16
58
  - New `getting_started.ts` example showing complete metadata integration
17
59
 
18
60
  ### Changed
61
+
19
62
  - Streamlined Getting Started tutorial with clearer step-by-step instructions
20
63
  - Improved documentation with direct links to example files
21
64
 
22
65
  ## [1.0.5] - 2025-10-23
23
66
 
24
67
  ### Changed
25
- - Improved .env.example with realistic key format examples (hak_, sk-ant-)
68
+
69
+ - Improved .env.example with realistic key format examples (hak\_, sk-ant-)
26
70
 
27
71
  ## [1.0.4] - 2025-10-21
28
72
 
29
73
  ### Changed
74
+
30
75
  - Simplified README documentation and consolidated examples
31
76
  - Updated documentation links to use GitHub HEAD references
32
77
  - Enhanced .gitignore setup instructions with industry-standard reference
@@ -34,16 +79,19 @@ All notable changes to this project will be documented in this file.
34
79
  ## [1.0.3] - 2025-10-17
35
80
 
36
81
  ### Changed
82
+
37
83
  - Updated publishing documentation with validated release workflow
38
84
 
39
85
  ## [1.0.2] - 2025-10-16
40
86
 
41
87
  ### Changed
88
+
42
89
  - Package maintenance and stability improvements
43
90
 
44
91
  ## [1.0.1] - 2025-10-15
45
92
 
46
93
  ### Changed
94
+
47
95
  - Updated all package name references from `revenium-middleware-anthropic-node` to `@revenium/anthropic` throughout documentation
48
96
  - Removed emojis from all documentation and examples for professional presentation
49
97
  - Updated repository references to point to public repository
@@ -53,6 +101,7 @@ All notable changes to this project will be documented in this file.
53
101
  ## [1.0.0] - 2025-10-14
54
102
 
55
103
  ### Added
104
+
56
105
  - Transparent middleware for Anthropic Claude usage tracking
57
106
  - Automatic metadata integration with native TypeScript support
58
107
  - Streaming support for real-time responses
@@ -67,6 +116,9 @@ All notable changes to this project will be documented in this file.
67
116
  - Configurable retry logic
68
117
  - Debug logging support
69
118
 
119
+ [1.0.9]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.9
120
+ [1.0.8]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.8
121
+ [1.0.7]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.7
70
122
  [1.0.6]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.6
71
123
  [1.0.5]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.5
72
124
  [1.0.4]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.4
package/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@revenium/anthropic.svg)](https://www.npmjs.com/package/@revenium/anthropic)
4
4
  [![Node Versions](https://img.shields.io/node/v/@revenium/anthropic.svg)](https://www.npmjs.com/package/@revenium/anthropic)
5
5
  [![Documentation](https://img.shields.io/badge/docs-revenium.io-blue)](https://docs.revenium.io)
6
+ [![Website](https://img.shields.io/badge/website-revenium.ai-blue)](https://www.revenium.ai)
6
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
8
 
8
9
  Automatically track and meter your Anthropic Claude API usage with Revenium. This middleware provides seamless integration with **Anthropic Claude SDK**, requiring minimal code changes and featuring native TypeScript support.
@@ -45,7 +46,7 @@ REVENIUM_METERING_API_KEY="hak_your_revenium_key"
45
46
  ANTHROPIC_API_KEY="sk-ant-your_anthropic_key"
46
47
  ```
47
48
 
48
- > **Note**: `REVENIUM_METERING_BASE_URL` defaults to `https://api.revenium.io` and doesn't need to be set unless using a different environment.
49
+ > **Note**: `REVENIUM_METERING_BASE_URL` defaults to `https://api.revenium.ai` and doesn't need to be set unless using a different environment.
49
50
 
50
51
  ### 3. Run Your First Example
51
52
 
@@ -86,6 +87,111 @@ The middleware automatically captures:
86
87
  - **Streaming Metrics**: Time to first token for streaming responses
87
88
  - **Custom Metadata**: Business context you provide
88
89
 
90
+ ## Terminal Summary Output
91
+
92
+ The middleware can print a usage summary to the terminal after each API request. This is useful for development, debugging, and cost monitoring.
93
+
94
+ ### Configuration
95
+
96
+ Enable via environment variables:
97
+
98
+ ```bash
99
+ # Human-readable format (with emojis)
100
+ REVENIUM_PRINT_SUMMARY=true
101
+
102
+ # JSON format (for automation/log parsing)
103
+ REVENIUM_PRINT_SUMMARY=json
104
+
105
+ # Team ID for cost retrieval (optional)
106
+ REVENIUM_TEAM_ID=your-team-id
107
+ ```
108
+
109
+ Or configure programmatically:
110
+
111
+ ```typescript
112
+ import { configure } from "@revenium/anthropic";
113
+
114
+ configure({
115
+ reveniumApiKey: "hak_your_key",
116
+ reveniumBaseUrl: "https://api.revenium.ai", // optional, this is the default
117
+ printSummary: "human", // or "json" or true
118
+ teamId: "your-team-id", // optional, for cost data
119
+ });
120
+ ```
121
+
122
+ ### Output Formats
123
+
124
+ **Human-readable format** (`printSummary: true` or `printSummary: 'human'`):
125
+
126
+ ```
127
+ ============================================================
128
+ 📊 REVENIUM USAGE SUMMARY
129
+ ============================================================
130
+ 🤖 Model: claude-sonnet-4-20250514
131
+ 🏢 Provider: Anthropic
132
+ ⏱️ Duration: 1.23s
133
+
134
+ 💬 Token Usage:
135
+ 📥 Input Tokens: 150
136
+ 📤 Output Tokens: 75
137
+ 📊 Total Tokens: 225
138
+
139
+ 💰 Cost: $0.001234
140
+ ============================================================
141
+ ```
142
+
143
+ **JSON format** (`printSummary: 'json'`):
144
+
145
+ ```json
146
+ {
147
+ "model": "claude-sonnet-4-20250514",
148
+ "provider": "Anthropic",
149
+ "durationSeconds": 1.23,
150
+ "inputTokenCount": 150,
151
+ "outputTokenCount": 75,
152
+ "totalTokenCount": 225,
153
+ "cost": 0.001234
154
+ }
155
+ ```
156
+
157
+ > **Note**: Cost data requires `teamId` to be configured. Without it, the summary will show token usage but not cost.
158
+ >
159
+ > **Optional fields**: The JSON output may include additional fields depending on the context:
160
+ > - `costStatus`: `"pending"` (when `teamId` is set but cost is not yet available) or `"unavailable"` (when `teamId` is not configured). Only present when `cost` is `null`.
161
+ > - `traceId`: The trace ID for request correlation (only present if `traceId` was provided in `usageMetadata`).
162
+
163
+ ## Trace Visualization Fields
164
+
165
+ The middleware automatically captures trace visualization fields for distributed tracing and analytics:
166
+
167
+ | Field | Type | Description | Environment Variable |
168
+ | --------------------- | ------ | ------------------------------------------------------------------------------- | ---------------------------------- |
169
+ | `environment` | string | Deployment environment (production, staging, development) | `REVENIUM_ENVIRONMENT`, `NODE_ENV` |
170
+ | `operationType` | string | Operation classification (CHAT) - automatically detected | N/A (auto-detected) |
171
+ | `operationSubtype` | string | Additional detail (function_call, etc.) - automatically detected | N/A (auto-detected) |
172
+ | `retryNumber` | number | Retry attempt number (0 for first attempt, 1+ for retries) | `REVENIUM_RETRY_NUMBER` |
173
+ | `parentTransactionId` | string | Parent transaction reference for distributed tracing | `REVENIUM_PARENT_TRANSACTION_ID` |
174
+ | `transactionName` | string | Human-friendly operation label | `REVENIUM_TRANSACTION_NAME` |
175
+ | `region` | string | Cloud region (us-east-1, etc.) - auto-detected from AWS/Azure/GCP | `AWS_REGION`, `REVENIUM_REGION` |
176
+ | `credentialAlias` | string | Human-readable credential name | `REVENIUM_CREDENTIAL_ALIAS` |
177
+ | `traceType` | string | Categorical identifier (alphanumeric, hyphens, underscores only, max 128 chars) | `REVENIUM_TRACE_TYPE` |
178
+ | `traceName` | string | Human-readable label for trace instances (max 256 chars) | `REVENIUM_TRACE_NAME` |
179
+
180
+ **All trace visualization fields are optional.** The middleware will automatically detect and populate these fields when possible.
181
+
182
+ ### Example Configuration
183
+
184
+ ```env
185
+ REVENIUM_ENVIRONMENT=production
186
+ REVENIUM_REGION=us-east-1
187
+ REVENIUM_CREDENTIAL_ALIAS=Anthropic Production Key
188
+ REVENIUM_TRACE_TYPE=customer_support
189
+ REVENIUM_TRACE_NAME=Support Ticket #12345
190
+ REVENIUM_PARENT_TRANSACTION_ID=parent-txn-123
191
+ REVENIUM_TRANSACTION_NAME=Answer Customer Question
192
+ REVENIUM_RETRY_NUMBER=0
193
+ ```
194
+
89
195
  ## Advanced Usage
90
196
 
91
197
  ### Initialization Options
@@ -118,33 +224,77 @@ See [examples/advanced-features.ts](https://github.com/revenium/revenium-middlew
118
224
 
119
225
  Add business context to track usage by organization, user, task type, or custom fields. Pass a `usageMetadata` object with any of these optional fields:
120
226
 
121
- | Field | Description | Use Case |
122
- |-------|-------------|----------|
123
- | `traceId` | Unique identifier for session or conversation tracking | Link multiple API calls together for debugging, user session analytics, or distributed tracing across services |
124
- | `taskType` | Type of AI task being performed | Categorize usage by workload (e.g., "chat", "code-generation", "doc-summary") for cost analysis and optimization |
125
- | `subscriber.id` | Unique user identifier | Track individual user consumption for billing, rate limiting, or user analytics |
126
- | `subscriber.email` | User email address | Identify users for support, compliance, or usage reports |
127
- | `subscriber.credential.name` | Authentication credential name | Track which API key or service account made the request |
128
- | `subscriber.credential.value` | Authentication credential value | Associate usage with specific credentials for security auditing |
129
- | `organizationId` | Organization or company identifier | Multi-tenant cost allocation, usage quotas per organization |
130
- | `subscriptionId` | Subscription plan identifier | Track usage against subscription limits, identify plan upgrade opportunities |
131
- | `productId` | Your product or feature identifier | Attribute AI costs to specific features in your application (e.g., "chatbot", "email-assistant") |
132
- | `agent` | AI agent or bot identifier | Distinguish between multiple AI agents or automation workflows in your system |
133
- | `responseQualityScore` | Custom quality rating (0.0-1.0) | Track user satisfaction or automated quality metrics for model performance analysis |
227
+ | Field | Description | Use Case |
228
+ | ----------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
229
+ | `traceId` | Unique identifier for session or conversation tracking | Link multiple API calls together for debugging, user session analytics, or distributed tracing across services |
230
+ | `taskType` | Type of AI task being performed | Categorize usage by workload (e.g., "chat", "code-generation", "doc-summary") for cost analysis and optimization |
231
+ | `subscriber.id` | Unique user identifier | Track individual user consumption for billing, rate limiting, or user analytics |
232
+ | `subscriber.email` | User email address | Identify users for support, compliance, or usage reports |
233
+ | `subscriber.credential.name` | Authentication credential name | Track which API key or service account made the request |
234
+ | `subscriber.credential.value` | Authentication credential value | Associate usage with specific credentials for security auditing |
235
+ | `organizationId` | Organization or company identifier | Multi-tenant cost allocation, usage quotas per organization |
236
+ | `subscriptionId` | Subscription plan identifier | Track usage against subscription limits, identify plan upgrade opportunities |
237
+ | `productId` | Your product or feature identifier | Attribute AI costs to specific features in your application (e.g., "chatbot", "email-assistant") |
238
+ | `agent` | AI agent or bot identifier | Distinguish between multiple AI agents or automation workflows in your system |
239
+ | `responseQualityScore` | Custom quality rating (0.0-1.0) | Track user satisfaction or automated quality metrics for model performance analysis |
240
+
241
+ **All metadata fields are optional.** Custom fields beyond the standard ones are automatically preserved and sent to Revenium.
242
+
243
+ **Resources:**
244
+
245
+ - [examples/advanced-features.ts](https://github.com/revenium/revenium-middleware-anthropic-node/blob/HEAD/examples/advanced-features.ts) - Working examples
246
+
247
+ ## Metadata Fields
248
+
249
+ The middleware automatically sends the following fields to Revenium's `/meter/v2/ai/completions` endpoint:
250
+
251
+ | Field | Type | Source | Description |
252
+ | ------------------------- | ------- | ------------------ | ------------------------------------------------------------------------ |
253
+ | `stopReason` | string | Anthropic Response | Why completion stopped: "END", "MAX_TOKENS", "STOP_SEQUENCE", "TOOL_USE" |
254
+ | `costType` | string | Fixed | Always "AI" for AI completions |
255
+ | `isStreamed` | boolean | Request Type | Whether response was streamed |
256
+ | `taskType` | string | usageMetadata | Optional task categorization |
257
+ | `agent` | string | usageMetadata | Optional agent identifier |
258
+ | `operationType` | string | Fixed | Always "CHAT" for message completions |
259
+ | `inputTokenCount` | number | Anthropic Usage | Input tokens consumed |
260
+ | `outputTokenCount` | number | Anthropic Usage | Output tokens generated |
261
+ | `reasoningTokenCount` | number | Fixed | Always 0 (Anthropic doesn't report reasoning tokens) |
262
+ | `cacheCreationTokenCount` | number | Anthropic Usage | Tokens used for prompt caching creation |
263
+ | `cacheReadTokenCount` | number | Anthropic Usage | Tokens read from prompt cache |
264
+ | `totalTokenCount` | number | Calculated | Sum of input + output tokens |
265
+ | `organizationId` | string | usageMetadata | Optional organization identifier |
266
+ | `productId` | string | usageMetadata | Optional product identifier |
267
+ | `subscriber` | object | usageMetadata | Optional subscriber info (id, email, credential) |
268
+ | `subscriptionId` | string | usageMetadata | Optional subscription plan identifier |
269
+ | `model` | string | Request | Anthropic model used (e.g., "claude-3-5-haiku-20241022") |
270
+ | `transactionId` | string | Generated | Unique request identifier (UUID) |
271
+ | `responseTime` | string | Timestamp | ISO 8601 timestamp of response completion |
272
+ | `requestDuration` | number | Measured | Total request duration in milliseconds |
273
+ | `provider` | string | Fixed | Always "Anthropic" |
274
+ | `requestTime` | string | Timestamp | ISO 8601 timestamp when request started |
275
+ | `completionStartTime` | string | Timestamp | ISO 8601 timestamp when completion generation started |
276
+ | `timeToFirstToken` | number | Measured | Milliseconds from request start to first token (streaming only) |
277
+ | `traceId` | string | usageMetadata | Optional trace identifier for request correlation |
278
+ | `responseQualityScore` | number | usageMetadata | Optional quality rating (0.0-1.0) |
279
+ | `middlewareSource` | string | Fixed | Always "nodejs" to identify this middleware |
280
+ | Custom Fields | any | usageMetadata | Any additional fields in usageMetadata are preserved |
281
+
282
+ **Note:** Fields marked as "usageMetadata" come from the optional `usageMetadata` object you pass to `messages.create()`.
134
283
 
135
284
  **Resources:**
285
+
136
286
  - [API Reference](https://revenium.readme.io/reference/meter_ai_completion) - Complete metadata field documentation
137
287
 
138
288
  ## Configuration Options
139
289
 
140
290
  ### Environment Variables
141
291
 
142
- | Variable | Required | Default | Description |
143
- | ---------------------------- | -------- | -------------------------- | --------------------------------- |
144
- | `REVENIUM_METERING_API_KEY` | Yes | - | Your Revenium API key |
145
- | `ANTHROPIC_API_KEY` | Yes | - | Anthropic Claude API key |
146
- | `REVENIUM_METERING_BASE_URL` | No | `https://api.revenium.io` | Revenium metering API base URL |
147
- | `REVENIUM_DEBUG` | No | `false` | Enable debug logging (true/false) |
292
+ | Variable | Required | Default | Description |
293
+ | ---------------------------- | -------- | ------------------------- | --------------------------------- |
294
+ | `REVENIUM_METERING_API_KEY` | Yes | - | Your Revenium API key |
295
+ | `ANTHROPIC_API_KEY` | Yes | - | Anthropic Claude API key |
296
+ | `REVENIUM_METERING_BASE_URL` | No | `https://api.revenium.ai` | Revenium metering API base URL |
297
+ | `REVENIUM_DEBUG` | No | `false` | Enable debug logging (true/false) |
148
298
 
149
299
  ### Manual Configuration
150
300
 
@@ -234,7 +384,9 @@ The middleware never blocks your application - if Revenium tracking fails, your
234
384
 
235
385
  ## Documentation
236
386
 
237
- For detailed documentation, visit [docs.revenium.io](https://docs.revenium.io)
387
+ For detailed documentation, visit [docs.revenium.io](https://docs.revenium.io).
388
+ For contributor lifecycle, validation, and provider metadata, see
389
+ [docs/standardization/README.md](https://github.com/revenium/revenium-middleware-anthropic-node/blob/HEAD/docs/standardization/README.md).
238
390
 
239
391
  ## Contributing
240
392
 
@@ -256,6 +408,7 @@ This project is licensed under the MIT License - see the [LICENSE](https://githu
256
408
 
257
409
  For issues, feature requests, or contributions:
258
410
 
411
+ - **Website**: [www.revenium.ai](https://www.revenium.ai)
259
412
  - **GitHub Repository**: [revenium/revenium-middleware-anthropic-node](https://github.com/revenium/revenium-middleware-anthropic-node)
260
413
  - **Issues**: [Report bugs or request features](https://github.com/revenium/revenium-middleware-anthropic-node/issues)
261
414
  - **Documentation**: [docs.revenium.io](https://docs.revenium.io)
@@ -55,10 +55,27 @@ function loadConfigFromEnvironment() {
55
55
  logLevel: process.env[constants_1.ENV_VARS.LOG_LEVEL],
56
56
  apiTimeout: process.env[constants_1.ENV_VARS.API_TIMEOUT],
57
57
  failSilent: process.env[constants_1.ENV_VARS.FAIL_SILENT],
58
- maxRetries: process.env[constants_1.ENV_VARS.MAX_RETRIES]
58
+ maxRetries: process.env[constants_1.ENV_VARS.MAX_RETRIES],
59
+ printSummary: process.env[constants_1.ENV_VARS.PRINT_SUMMARY],
60
+ teamId: process.env[constants_1.ENV_VARS.TEAM_ID]
59
61
  };
60
62
  return env;
61
63
  }
64
+ /**
65
+ * Parse printSummary environment variable value
66
+ */
67
+ function parsePrintSummary(value) {
68
+ if (!value)
69
+ return undefined;
70
+ const lowerValue = value.toLowerCase();
71
+ if (lowerValue === 'true' || lowerValue === 'human')
72
+ return 'human';
73
+ if (lowerValue === 'json')
74
+ return 'json';
75
+ if (lowerValue === 'false')
76
+ return false;
77
+ return undefined;
78
+ }
62
79
  /**
63
80
  * Convert environment config to Revenium config
64
81
  */
@@ -69,13 +86,16 @@ function createConfigFromEnvironment(env) {
69
86
  const apiTimeout = env.apiTimeout ? parseInt(env.apiTimeout, 10) : undefined;
70
87
  const failSilent = env.failSilent !== 'false'; // Default to true
71
88
  const maxRetries = env.maxRetries ? parseInt(env.maxRetries, 10) : undefined;
89
+ const printSummary = parsePrintSummary(env.printSummary);
72
90
  return {
73
91
  reveniumApiKey: env.reveniumApiKey,
74
92
  reveniumBaseUrl: env.reveniumBaseUrl || constants_1.DEFAULT_CONFIG.REVENIUM_BASE_URL,
75
93
  anthropicApiKey: env.anthropicApiKey,
76
94
  apiTimeout,
77
95
  failSilent,
78
- maxRetries
96
+ maxRetries,
97
+ printSummary,
98
+ teamId: env.teamId?.trim()
79
99
  };
80
100
  }
81
101
  /**
@@ -123,14 +143,42 @@ function getConfig() {
123
143
  }
124
144
  /**
125
145
  * Set the global configuration
146
+ * Uses the normalized config from validation (with defaults applied and fields trimmed)
126
147
  */
127
148
  function setConfig(config) {
128
- validateConfig(config);
129
- globalConfig = config;
149
+ const validation = (0, validation_1.validateReveniumConfig)(config);
150
+ if (!validation.isValid) {
151
+ // Log detailed validation errors
152
+ getLogger().error('Configuration validation failed', {
153
+ errors: validation.errors,
154
+ warnings: validation.warnings,
155
+ suggestions: validation.suggestions
156
+ });
157
+ // Create detailed error message
158
+ let errorMessage = 'Configuration validation failed:\n';
159
+ validation.errors.forEach((error, index) => {
160
+ errorMessage += ` ${index + 1}. ${error}\n`;
161
+ });
162
+ if (validation.suggestions && validation.suggestions.length > 0) {
163
+ errorMessage += '\nSuggestions:\n';
164
+ validation.suggestions.forEach((suggestion) => {
165
+ errorMessage += ` • ${suggestion}\n`;
166
+ });
167
+ }
168
+ throw new Error(errorMessage.trim());
169
+ }
170
+ // Log warnings if any
171
+ if (validation.warnings && validation.warnings.length > 0) {
172
+ getLogger().warn('Configuration warnings', {
173
+ warnings: validation.warnings
174
+ });
175
+ }
176
+ // Use the normalized config from validation (with defaults applied and fields trimmed)
177
+ globalConfig = validation.config;
130
178
  globalLogger.debug('Revenium configuration updated', {
131
- baseUrl: config.reveniumBaseUrl,
132
- hasApiKey: !!config.reveniumApiKey,
133
- hasAnthropicKey: !!config.anthropicApiKey
179
+ baseUrl: globalConfig.reveniumBaseUrl,
180
+ hasApiKey: !!globalConfig.reveniumApiKey,
181
+ hasAnthropicKey: !!globalConfig.anthropicApiKey
134
182
  });
135
183
  }
136
184
  /**
@@ -4,13 +4,13 @@
4
4
  * Centralizes all magic numbers and default values
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.ANTHROPIC_PATTERNS = exports.API_ENDPOINTS = exports.ENV_VARS = exports.LOGGING_CONFIG = exports.VALIDATION_CONFIG = exports.RETRY_CONFIG = exports.CIRCUIT_BREAKER_CONFIG = exports.DEFAULT_CONFIG = void 0;
7
+ exports.ANTHROPIC_PATTERNS = exports.API_ENDPOINTS = exports.SUMMARY_PRINTER_CONFIG = exports.ENV_VARS = exports.LOGGING_CONFIG = exports.VALIDATION_CONFIG = exports.RETRY_CONFIG = exports.CIRCUIT_BREAKER_CONFIG = exports.DEFAULT_CONFIG = void 0;
8
8
  /**
9
9
  * Default configuration values
10
10
  */
11
11
  exports.DEFAULT_CONFIG = {
12
12
  /** Default Revenium API base URL */
13
- REVENIUM_BASE_URL: 'https://api.revenium.io',
13
+ REVENIUM_BASE_URL: "https://api.revenium.ai",
14
14
  /** Default API timeout in milliseconds */
15
15
  API_TIMEOUT: 5000,
16
16
  /** Default maximum retries for failed API calls */
@@ -63,9 +63,9 @@ exports.VALIDATION_CONFIG = {
63
63
  /** Minimum API key length */
64
64
  MIN_API_KEY_LENGTH: 20,
65
65
  /** Required API key prefix for Revenium */
66
- REVENIUM_API_KEY_PREFIX: 'hak_',
66
+ REVENIUM_API_KEY_PREFIX: "hak_",
67
67
  /** Required API key prefix for Anthropic */
68
- ANTHROPIC_API_KEY_PREFIX: 'sk-ant-',
68
+ ANTHROPIC_API_KEY_PREFIX: "sk-ant-",
69
69
  /** Maximum tokens warning threshold */
70
70
  HIGH_MAX_TOKENS_THRESHOLD: 4096,
71
71
  /** Temperature range */
@@ -86,39 +86,54 @@ exports.VALIDATION_CONFIG = {
86
86
  */
87
87
  exports.LOGGING_CONFIG = {
88
88
  /** Middleware name for log prefixes */
89
- MIDDLEWARE_NAME: 'Revenium',
89
+ MIDDLEWARE_NAME: "Revenium",
90
90
  /** User agent string for API requests */
91
- USER_AGENT: 'revenium-middleware-anthropic-node/1.0.0',
91
+ USER_AGENT: "revenium-middleware-anthropic-node/1.0.0",
92
92
  /** Debug environment variable name */
93
- DEBUG_ENV_VAR: 'REVENIUM_DEBUG',
93
+ DEBUG_ENV_VAR: "REVENIUM_DEBUG",
94
94
  };
95
95
  /**
96
96
  * Environment variable names
97
97
  */
98
98
  exports.ENV_VARS = {
99
99
  /** Revenium API key */
100
- REVENIUM_API_KEY: 'REVENIUM_METERING_API_KEY',
100
+ REVENIUM_API_KEY: "REVENIUM_METERING_API_KEY",
101
101
  /** Revenium base URL */
102
- REVENIUM_BASE_URL: 'REVENIUM_METERING_BASE_URL',
102
+ REVENIUM_BASE_URL: "REVENIUM_METERING_BASE_URL",
103
103
  /** Anthropic API key */
104
- ANTHROPIC_API_KEY: 'ANTHROPIC_API_KEY',
104
+ ANTHROPIC_API_KEY: "ANTHROPIC_API_KEY",
105
105
  /** Debug mode */
106
- DEBUG: 'REVENIUM_DEBUG',
106
+ DEBUG: "REVENIUM_DEBUG",
107
107
  /** Log level */
108
- LOG_LEVEL: 'REVENIUM_LOG_LEVEL',
108
+ LOG_LEVEL: "REVENIUM_LOG_LEVEL",
109
109
  /** API timeout */
110
- API_TIMEOUT: 'REVENIUM_API_TIMEOUT',
110
+ API_TIMEOUT: "REVENIUM_API_TIMEOUT",
111
111
  /** Fail silent mode */
112
- FAIL_SILENT: 'REVENIUM_FAIL_SILENT',
112
+ FAIL_SILENT: "REVENIUM_FAIL_SILENT",
113
113
  /** Maximum retries */
114
- MAX_RETRIES: 'REVENIUM_MAX_RETRIES',
114
+ MAX_RETRIES: "REVENIUM_MAX_RETRIES",
115
+ /** Print summary mode (true/false/human/json) */
116
+ PRINT_SUMMARY: "REVENIUM_PRINT_SUMMARY",
117
+ /** Team ID for cost metrics retrieval */
118
+ TEAM_ID: "REVENIUM_TEAM_ID",
119
+ };
120
+ /**
121
+ * Summary printer configuration
122
+ */
123
+ exports.SUMMARY_PRINTER_CONFIG = {
124
+ /** Maximum number of retries when fetching cost metrics */
125
+ MAX_RETRIES: 3,
126
+ /** Delay between retries in milliseconds */
127
+ RETRY_DELAY: 2000,
128
+ /** Fetch timeout in milliseconds (prevents hung requests from keeping Node process alive) */
129
+ FETCH_TIMEOUT: 10000,
115
130
  };
116
131
  /**
117
132
  * API endpoints
118
133
  */
119
134
  exports.API_ENDPOINTS = {
120
135
  /** Revenium AI completions endpoint */
121
- AI_COMPLETIONS: '/meter/v2/ai/completions',
136
+ AI_COMPLETIONS: "/meter/v2/ai/completions",
122
137
  };
123
138
  /**
124
139
  * Anthropic model patterns
@@ -128,17 +143,17 @@ exports.ANTHROPIC_PATTERNS = {
128
143
  CLAUDE_MODEL_PATTERN: /claude/i,
129
144
  /** Known Anthropic stop reasons */
130
145
  STOP_REASONS: {
131
- END_TURN: 'end_turn',
132
- MAX_TOKENS: 'max_tokens',
133
- STOP_SEQUENCE: 'stop_sequence',
134
- TOOL_USE: 'tool_use',
146
+ END_TURN: "end_turn",
147
+ MAX_TOKENS: "max_tokens",
148
+ STOP_SEQUENCE: "stop_sequence",
149
+ TOOL_USE: "tool_use",
135
150
  },
136
151
  /** Revenium stop reason mappings */
137
152
  REVENIUM_STOP_REASON_MAP: {
138
- 'end_turn': 'END',
139
- 'max_tokens': 'TOKEN_LIMIT',
140
- 'stop_sequence': 'END_SEQUENCE',
141
- 'tool_use': 'END',
153
+ end_turn: "END",
154
+ max_tokens: "TOKEN_LIMIT",
155
+ stop_sequence: "END_SEQUENCE",
156
+ tool_use: "END",
142
157
  },
143
158
  };
144
159
  //# sourceMappingURL=constants.js.map