@revenium/anthropic 1.0.8 → 1.1.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.
- package/CHANGELOG.md +46 -1
- package/README.md +208 -49
- package/dist/cjs/config.js +80 -29
- package/dist/cjs/constants.js +45 -24
- package/dist/cjs/tracking.js +82 -20
- package/dist/cjs/types/anthropic-augmentation.js +0 -62
- package/dist/cjs/utils/prompt-extraction.js +158 -0
- package/dist/cjs/utils/summary-printer.js +189 -0
- package/dist/cjs/utils/trace-fields.js +117 -0
- package/dist/cjs/utils/validation.js +55 -23
- package/dist/cjs/wrapper.js +49 -41
- package/dist/esm/config.js +82 -31
- package/dist/esm/constants.js +44 -23
- package/dist/esm/tracking.js +82 -20
- package/dist/esm/types/anthropic-augmentation.js +0 -62
- package/dist/esm/utils/prompt-extraction.js +154 -0
- package/dist/esm/utils/summary-printer.js +186 -0
- package/dist/esm/utils/trace-fields.js +106 -0
- package/dist/esm/utils/validation.js +56 -24
- package/dist/esm/wrapper.js +55 -47
- package/dist/types/config.d.ts +2 -1
- package/dist/types/constants.d.ts +21 -0
- package/dist/types/types/anthropic-augmentation.d.ts +0 -92
- package/dist/types/types.d.ts +41 -198
- package/dist/types/utils/prompt-extraction.d.ts +10 -0
- package/dist/types/utils/summary-printer.d.ts +3 -0
- package/dist/types/utils/trace-fields.d.ts +10 -0
- package/examples/advanced.ts +128 -0
- package/examples/basic.ts +132 -0
- package/examples/getting_started.ts +6 -6
- package/examples/metadata.ts +58 -0
- package/package.json +4 -6
- package/examples/advanced-features.ts +0 -469
- package/examples/basic-usage.ts +0 -314
package/CHANGELOG.md
CHANGED
|
@@ -2,19 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.1.0] - 2026-01-20
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Prompt capture functionality with credential sanitization
|
|
10
|
+
- Environment variable: REVENIUM_CAPTURE_PROMPTS (default: false)
|
|
11
|
+
- Automatic redaction of sensitive credentials in captured prompts
|
|
12
|
+
|
|
13
|
+
### Security
|
|
14
|
+
|
|
15
|
+
- Added sanitization for API keys, tokens, passwords, and Bearer tokens in prompt data
|
|
16
|
+
|
|
17
|
+
## [1.0.9] - 2026-01-06
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Added terminal cost/metrics summary output after each API call
|
|
22
|
+
- Added distributed tracing support with 10 visualization fields
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Fixed config validation to use normalized values in setConfig()
|
|
27
|
+
- Fixed reveniumBaseUrl to be optional with default value
|
|
28
|
+
- Fixed teamId whitespace trimming to prevent cost lookup issues
|
|
29
|
+
- Fixed usage summary to print even when Revenium tracking fails
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- Improved error messages to use generic 'environment variable' wording
|
|
34
|
+
|
|
5
35
|
## [1.0.8] - 2025-11-07
|
|
6
36
|
|
|
7
37
|
### Fixed
|
|
38
|
+
|
|
8
39
|
- Fixed `anthropicApiKey` configuration parameter to honor config value before environment variable
|
|
9
40
|
- Fixed `failSilent=false` configuration to properly propagate tracking errors
|
|
10
41
|
- Fixed `maxRetries=0` handling to allow zero retries when explicitly configured
|
|
11
42
|
|
|
12
43
|
### Added
|
|
44
|
+
|
|
13
45
|
- Added `timeToFirstToken` metric tracking for streaming requests
|
|
14
46
|
- Added custom metadata field preservation beyond standard fields
|
|
15
47
|
- Added website link (www.revenium.ai) to README Support section
|
|
16
48
|
|
|
17
49
|
### Changed
|
|
50
|
+
|
|
18
51
|
- Updated Revenium API base URL from `api.revenium.io` to `api.revenium.ai`
|
|
19
52
|
- Updated Node.js requirement from 16+ to 18+
|
|
20
53
|
- Updated `.gitignore` to exclude `dist/` directory and `.env.test`
|
|
@@ -24,6 +57,7 @@ All notable changes to this project will be documented in this file.
|
|
|
24
57
|
## [1.0.7] - 2025-10-25
|
|
25
58
|
|
|
26
59
|
### Changed
|
|
60
|
+
|
|
27
61
|
- Updated all examples to use `claude-haiku-4-5` (validated Anthropic model identifier)
|
|
28
62
|
- Improved examples documentation with getting_started.ts reference
|
|
29
63
|
- Streamlined README by removing OpenRouter section for clarity
|
|
@@ -31,21 +65,25 @@ All notable changes to this project will be documented in this file.
|
|
|
31
65
|
## [1.0.6] - 2025-10-24
|
|
32
66
|
|
|
33
67
|
### Added
|
|
68
|
+
|
|
34
69
|
- Comprehensive metadata fields table in README with practical use cases for all 11 fields
|
|
35
70
|
- New `getting_started.ts` example showing complete metadata integration
|
|
36
71
|
|
|
37
72
|
### Changed
|
|
73
|
+
|
|
38
74
|
- Streamlined Getting Started tutorial with clearer step-by-step instructions
|
|
39
75
|
- Improved documentation with direct links to example files
|
|
40
76
|
|
|
41
77
|
## [1.0.5] - 2025-10-23
|
|
42
78
|
|
|
43
79
|
### Changed
|
|
44
|
-
|
|
80
|
+
|
|
81
|
+
- Improved .env.example with realistic key format examples (hak\_, sk-ant-)
|
|
45
82
|
|
|
46
83
|
## [1.0.4] - 2025-10-21
|
|
47
84
|
|
|
48
85
|
### Changed
|
|
86
|
+
|
|
49
87
|
- Simplified README documentation and consolidated examples
|
|
50
88
|
- Updated documentation links to use GitHub HEAD references
|
|
51
89
|
- Enhanced .gitignore setup instructions with industry-standard reference
|
|
@@ -53,16 +91,19 @@ All notable changes to this project will be documented in this file.
|
|
|
53
91
|
## [1.0.3] - 2025-10-17
|
|
54
92
|
|
|
55
93
|
### Changed
|
|
94
|
+
|
|
56
95
|
- Updated publishing documentation with validated release workflow
|
|
57
96
|
|
|
58
97
|
## [1.0.2] - 2025-10-16
|
|
59
98
|
|
|
60
99
|
### Changed
|
|
100
|
+
|
|
61
101
|
- Package maintenance and stability improvements
|
|
62
102
|
|
|
63
103
|
## [1.0.1] - 2025-10-15
|
|
64
104
|
|
|
65
105
|
### Changed
|
|
106
|
+
|
|
66
107
|
- Updated all package name references from `revenium-middleware-anthropic-node` to `@revenium/anthropic` throughout documentation
|
|
67
108
|
- Removed emojis from all documentation and examples for professional presentation
|
|
68
109
|
- Updated repository references to point to public repository
|
|
@@ -72,6 +113,7 @@ All notable changes to this project will be documented in this file.
|
|
|
72
113
|
## [1.0.0] - 2025-10-14
|
|
73
114
|
|
|
74
115
|
### Added
|
|
116
|
+
|
|
75
117
|
- Transparent middleware for Anthropic Claude usage tracking
|
|
76
118
|
- Automatic metadata integration with native TypeScript support
|
|
77
119
|
- Streaming support for real-time responses
|
|
@@ -86,6 +128,9 @@ All notable changes to this project will be documented in this file.
|
|
|
86
128
|
- Configurable retry logic
|
|
87
129
|
- Debug logging support
|
|
88
130
|
|
|
131
|
+
[1.0.9]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.9
|
|
132
|
+
[1.0.8]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.8
|
|
133
|
+
[1.0.7]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.7
|
|
89
134
|
[1.0.6]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.6
|
|
90
135
|
[1.0.5]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.5
|
|
91
136
|
[1.0.4]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.4
|
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@ Automatically track and meter your Anthropic Claude API usage with Revenium. Thi
|
|
|
12
12
|
|
|
13
13
|
- **Seamless Integration**: Drop-in replacement with zero code changes required
|
|
14
14
|
- **Complete Metering**: Track tokens, costs, and performance metrics automatically
|
|
15
|
+
- **Prompt Capture**: Optional capture of prompts and responses with automatic credential sanitization
|
|
15
16
|
- **Custom Metadata**: Add business context with native TypeScript support
|
|
16
17
|
- **Streaming Support**: Real-time streaming with comprehensive analytics
|
|
17
18
|
- **Tool Use Support**: Full support for Anthropic's function calling and tools
|
|
@@ -87,6 +88,112 @@ The middleware automatically captures:
|
|
|
87
88
|
- **Streaming Metrics**: Time to first token for streaming responses
|
|
88
89
|
- **Custom Metadata**: Business context you provide
|
|
89
90
|
|
|
91
|
+
## Terminal Summary Output
|
|
92
|
+
|
|
93
|
+
The middleware can print a usage summary to the terminal after each API request. This is useful for development, debugging, and cost monitoring.
|
|
94
|
+
|
|
95
|
+
### Configuration
|
|
96
|
+
|
|
97
|
+
Enable via environment variables:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Human-readable format (with emojis)
|
|
101
|
+
REVENIUM_PRINT_SUMMARY=true
|
|
102
|
+
|
|
103
|
+
# JSON format (for automation/log parsing)
|
|
104
|
+
REVENIUM_PRINT_SUMMARY=json
|
|
105
|
+
|
|
106
|
+
# Team ID for cost retrieval (optional)
|
|
107
|
+
REVENIUM_TEAM_ID=your-team-id
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Or configure programmatically:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { configure } from "@revenium/anthropic";
|
|
114
|
+
|
|
115
|
+
configure({
|
|
116
|
+
reveniumApiKey: "hak_your_key",
|
|
117
|
+
reveniumBaseUrl: "https://api.revenium.ai", // optional, this is the default
|
|
118
|
+
printSummary: "human", // or "json" or true
|
|
119
|
+
teamId: "your-team-id", // optional, for cost data
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Output Formats
|
|
124
|
+
|
|
125
|
+
**Human-readable format** (`printSummary: true` or `printSummary: 'human'`):
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
============================================================
|
|
129
|
+
📊 REVENIUM USAGE SUMMARY
|
|
130
|
+
============================================================
|
|
131
|
+
🤖 Model: claude-sonnet-4-20250514
|
|
132
|
+
🏢 Provider: Anthropic
|
|
133
|
+
⏱️ Duration: 1.23s
|
|
134
|
+
|
|
135
|
+
💬 Token Usage:
|
|
136
|
+
📥 Input Tokens: 150
|
|
137
|
+
📤 Output Tokens: 75
|
|
138
|
+
📊 Total Tokens: 225
|
|
139
|
+
|
|
140
|
+
💰 Cost: $0.001234
|
|
141
|
+
============================================================
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**JSON format** (`printSummary: 'json'`):
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"model": "claude-sonnet-4-20250514",
|
|
149
|
+
"provider": "Anthropic",
|
|
150
|
+
"durationSeconds": 1.23,
|
|
151
|
+
"inputTokenCount": 150,
|
|
152
|
+
"outputTokenCount": 75,
|
|
153
|
+
"totalTokenCount": 225,
|
|
154
|
+
"cost": 0.001234
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
> **Note**: Cost data requires `teamId` to be configured. Without it, the summary will show token usage but not cost.
|
|
159
|
+
>
|
|
160
|
+
> **Optional fields**: The JSON output may include additional fields depending on the context:
|
|
161
|
+
>
|
|
162
|
+
> - `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`.
|
|
163
|
+
> - `traceId`: The trace ID for request correlation (only present if `traceId` was provided in `usageMetadata`).
|
|
164
|
+
|
|
165
|
+
## Trace Visualization Fields
|
|
166
|
+
|
|
167
|
+
The middleware automatically captures trace visualization fields for distributed tracing and analytics:
|
|
168
|
+
|
|
169
|
+
| Field | Type | Description | Environment Variable |
|
|
170
|
+
| --------------------- | ------ | ------------------------------------------------------------------------------- | ---------------------------------- |
|
|
171
|
+
| `environment` | string | Deployment environment (production, staging, development) | `REVENIUM_ENVIRONMENT`, `NODE_ENV` |
|
|
172
|
+
| `operationType` | string | Operation classification (CHAT) - automatically detected | N/A (auto-detected) |
|
|
173
|
+
| `operationSubtype` | string | Additional detail (function_call, etc.) - automatically detected | N/A (auto-detected) |
|
|
174
|
+
| `retryNumber` | number | Retry attempt number (0 for first attempt, 1+ for retries) | `REVENIUM_RETRY_NUMBER` |
|
|
175
|
+
| `parentTransactionId` | string | Parent transaction reference for distributed tracing | `REVENIUM_PARENT_TRANSACTION_ID` |
|
|
176
|
+
| `transactionName` | string | Human-friendly operation label | `REVENIUM_TRANSACTION_NAME` |
|
|
177
|
+
| `region` | string | Cloud region (us-east-1, etc.) - auto-detected from AWS/Azure/GCP | `AWS_REGION`, `REVENIUM_REGION` |
|
|
178
|
+
| `credentialAlias` | string | Human-readable credential name | `REVENIUM_CREDENTIAL_ALIAS` |
|
|
179
|
+
| `traceType` | string | Categorical identifier (alphanumeric, hyphens, underscores only, max 128 chars) | `REVENIUM_TRACE_TYPE` |
|
|
180
|
+
| `traceName` | string | Human-readable label for trace instances (max 256 chars) | `REVENIUM_TRACE_NAME` |
|
|
181
|
+
|
|
182
|
+
**All trace visualization fields are optional.** The middleware will automatically detect and populate these fields when possible.
|
|
183
|
+
|
|
184
|
+
### Example Configuration
|
|
185
|
+
|
|
186
|
+
```env
|
|
187
|
+
REVENIUM_ENVIRONMENT=production
|
|
188
|
+
REVENIUM_REGION=us-east-1
|
|
189
|
+
REVENIUM_CREDENTIAL_ALIAS=Anthropic Production Key
|
|
190
|
+
REVENIUM_TRACE_TYPE=customer_support
|
|
191
|
+
REVENIUM_TRACE_NAME=Support Ticket #12345
|
|
192
|
+
REVENIUM_PARENT_TRANSACTION_ID=parent-txn-123
|
|
193
|
+
REVENIUM_TRANSACTION_NAME=Answer Customer Question
|
|
194
|
+
REVENIUM_RETRY_NUMBER=0
|
|
195
|
+
```
|
|
196
|
+
|
|
90
197
|
## Advanced Usage
|
|
91
198
|
|
|
92
199
|
### Initialization Options
|
|
@@ -119,75 +226,127 @@ See [examples/advanced-features.ts](https://github.com/revenium/revenium-middlew
|
|
|
119
226
|
|
|
120
227
|
Add business context to track usage by organization, user, task type, or custom fields. Pass a `usageMetadata` object with any of these optional fields:
|
|
121
228
|
|
|
122
|
-
| Field
|
|
123
|
-
|
|
124
|
-
| `traceId`
|
|
125
|
-
| `taskType`
|
|
126
|
-
| `subscriber.id`
|
|
127
|
-
| `subscriber.email`
|
|
128
|
-
| `subscriber.credential.name`
|
|
129
|
-
| `subscriber.credential.value` | Authentication credential value
|
|
130
|
-
| `organizationId`
|
|
131
|
-
| `subscriptionId`
|
|
132
|
-
| `productId`
|
|
133
|
-
| `agent`
|
|
134
|
-
| `responseQualityScore`
|
|
229
|
+
| Field | Description | Use Case |
|
|
230
|
+
| ----------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
|
|
231
|
+
| `traceId` | Unique identifier for session or conversation tracking | Link multiple API calls together for debugging, user session analytics, or distributed tracing across services |
|
|
232
|
+
| `taskType` | Type of AI task being performed | Categorize usage by workload (e.g., "chat", "code-generation", "doc-summary") for cost analysis and optimization |
|
|
233
|
+
| `subscriber.id` | Unique user identifier | Track individual user consumption for billing, rate limiting, or user analytics |
|
|
234
|
+
| `subscriber.email` | User email address | Identify users for support, compliance, or usage reports |
|
|
235
|
+
| `subscriber.credential.name` | Authentication credential name | Track which API key or service account made the request |
|
|
236
|
+
| `subscriber.credential.value` | Authentication credential value | Associate usage with specific credentials for security auditing |
|
|
237
|
+
| `organizationId` | Organization or company identifier | Multi-tenant cost allocation, usage quotas per organization |
|
|
238
|
+
| `subscriptionId` | Subscription plan identifier | Track usage against subscription limits, identify plan upgrade opportunities |
|
|
239
|
+
| `productId` | Your product or feature identifier | Attribute AI costs to specific features in your application (e.g., "chatbot", "email-assistant") |
|
|
240
|
+
| `agent` | AI agent or bot identifier | Distinguish between multiple AI agents or automation workflows in your system |
|
|
241
|
+
| `responseQualityScore` | Custom quality rating (0.0-1.0) | Track user satisfaction or automated quality metrics for model performance analysis |
|
|
135
242
|
|
|
136
243
|
**All metadata fields are optional.** Custom fields beyond the standard ones are automatically preserved and sent to Revenium.
|
|
137
244
|
|
|
138
245
|
**Resources:**
|
|
246
|
+
|
|
139
247
|
- [examples/advanced-features.ts](https://github.com/revenium/revenium-middleware-anthropic-node/blob/HEAD/examples/advanced-features.ts) - Working examples
|
|
140
248
|
|
|
141
249
|
## Metadata Fields
|
|
142
250
|
|
|
143
251
|
The middleware automatically sends the following fields to Revenium's `/meter/v2/ai/completions` endpoint:
|
|
144
252
|
|
|
145
|
-
| Field
|
|
146
|
-
|
|
147
|
-
| `stopReason`
|
|
148
|
-
| `costType`
|
|
149
|
-
| `isStreamed`
|
|
150
|
-
| `taskType`
|
|
151
|
-
| `agent`
|
|
152
|
-
| `operationType`
|
|
153
|
-
| `inputTokenCount`
|
|
154
|
-
| `outputTokenCount`
|
|
155
|
-
| `reasoningTokenCount`
|
|
156
|
-
| `cacheCreationTokenCount` | number
|
|
157
|
-
| `cacheReadTokenCount`
|
|
158
|
-
| `totalTokenCount`
|
|
159
|
-
| `organizationId`
|
|
160
|
-
| `productId`
|
|
161
|
-
| `subscriber`
|
|
162
|
-
| `subscriptionId`
|
|
163
|
-
| `model`
|
|
164
|
-
| `transactionId`
|
|
165
|
-
| `responseTime`
|
|
166
|
-
| `requestDuration`
|
|
167
|
-
| `provider`
|
|
168
|
-
| `requestTime`
|
|
169
|
-
| `completionStartTime`
|
|
170
|
-
| `timeToFirstToken`
|
|
171
|
-
| `traceId`
|
|
172
|
-
| `responseQualityScore`
|
|
173
|
-
| `middlewareSource`
|
|
174
|
-
| Custom Fields
|
|
253
|
+
| Field | Type | Source | Description |
|
|
254
|
+
| ------------------------- | ------- | ------------------ | ------------------------------------------------------------------------ |
|
|
255
|
+
| `stopReason` | string | Anthropic Response | Why completion stopped: "END", "MAX_TOKENS", "STOP_SEQUENCE", "TOOL_USE" |
|
|
256
|
+
| `costType` | string | Fixed | Always "AI" for AI completions |
|
|
257
|
+
| `isStreamed` | boolean | Request Type | Whether response was streamed |
|
|
258
|
+
| `taskType` | string | usageMetadata | Optional task categorization |
|
|
259
|
+
| `agent` | string | usageMetadata | Optional agent identifier |
|
|
260
|
+
| `operationType` | string | Fixed | Always "CHAT" for message completions |
|
|
261
|
+
| `inputTokenCount` | number | Anthropic Usage | Input tokens consumed |
|
|
262
|
+
| `outputTokenCount` | number | Anthropic Usage | Output tokens generated |
|
|
263
|
+
| `reasoningTokenCount` | number | Fixed | Always 0 (Anthropic doesn't report reasoning tokens) |
|
|
264
|
+
| `cacheCreationTokenCount` | number | Anthropic Usage | Tokens used for prompt caching creation |
|
|
265
|
+
| `cacheReadTokenCount` | number | Anthropic Usage | Tokens read from prompt cache |
|
|
266
|
+
| `totalTokenCount` | number | Calculated | Sum of input + output tokens |
|
|
267
|
+
| `organizationId` | string | usageMetadata | Optional organization identifier |
|
|
268
|
+
| `productId` | string | usageMetadata | Optional product identifier |
|
|
269
|
+
| `subscriber` | object | usageMetadata | Optional subscriber info (id, email, credential) |
|
|
270
|
+
| `subscriptionId` | string | usageMetadata | Optional subscription plan identifier |
|
|
271
|
+
| `model` | string | Request | Anthropic model used (e.g., "claude-3-5-haiku-20241022") |
|
|
272
|
+
| `transactionId` | string | Generated | Unique request identifier (UUID) |
|
|
273
|
+
| `responseTime` | string | Timestamp | ISO 8601 timestamp of response completion |
|
|
274
|
+
| `requestDuration` | number | Measured | Total request duration in milliseconds |
|
|
275
|
+
| `provider` | string | Fixed | Always "Anthropic" |
|
|
276
|
+
| `requestTime` | string | Timestamp | ISO 8601 timestamp when request started |
|
|
277
|
+
| `completionStartTime` | string | Timestamp | ISO 8601 timestamp when completion generation started |
|
|
278
|
+
| `timeToFirstToken` | number | Measured | Milliseconds from request start to first token (streaming only) |
|
|
279
|
+
| `traceId` | string | usageMetadata | Optional trace identifier for request correlation |
|
|
280
|
+
| `responseQualityScore` | number | usageMetadata | Optional quality rating (0.0-1.0) |
|
|
281
|
+
| `middlewareSource` | string | Fixed | Always "nodejs" to identify this middleware |
|
|
282
|
+
| Custom Fields | any | usageMetadata | Any additional fields in usageMetadata are preserved |
|
|
175
283
|
|
|
176
284
|
**Note:** Fields marked as "usageMetadata" come from the optional `usageMetadata` object you pass to `messages.create()`.
|
|
177
285
|
|
|
178
286
|
**Resources:**
|
|
287
|
+
|
|
179
288
|
- [API Reference](https://revenium.readme.io/reference/meter_ai_completion) - Complete metadata field documentation
|
|
180
289
|
|
|
181
290
|
## Configuration Options
|
|
182
291
|
|
|
183
292
|
### Environment Variables
|
|
184
293
|
|
|
185
|
-
| Variable | Required | Default
|
|
186
|
-
| ---------------------------- | -------- |
|
|
187
|
-
| `REVENIUM_METERING_API_KEY` | Yes | -
|
|
188
|
-
| `ANTHROPIC_API_KEY` | Yes | -
|
|
189
|
-
| `REVENIUM_METERING_BASE_URL` | No | `https://api.revenium.ai`
|
|
190
|
-
| `REVENIUM_DEBUG` | No | `false`
|
|
294
|
+
| Variable | Required | Default | Description |
|
|
295
|
+
| ---------------------------- | -------- | ------------------------- | ------------------------------------------ |
|
|
296
|
+
| `REVENIUM_METERING_API_KEY` | Yes | - | Your Revenium API key |
|
|
297
|
+
| `ANTHROPIC_API_KEY` | Yes | - | Anthropic Claude API key |
|
|
298
|
+
| `REVENIUM_METERING_BASE_URL` | No | `https://api.revenium.ai` | Revenium metering API base URL |
|
|
299
|
+
| `REVENIUM_DEBUG` | No | `false` | Enable debug logging (true/false) |
|
|
300
|
+
| `REVENIUM_CAPTURE_PROMPTS` | No | `false` | Capture prompts and responses (true/false) |
|
|
301
|
+
|
|
302
|
+
### Prompt Capture
|
|
303
|
+
|
|
304
|
+
The middleware can capture prompts and responses for analysis and debugging. This feature is **disabled by default** for privacy and performance.
|
|
305
|
+
|
|
306
|
+
#### Configuration
|
|
307
|
+
|
|
308
|
+
Enable via environment variable:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
REVENIUM_CAPTURE_PROMPTS=true
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Or configure programmatically:
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
import { configure } from "@revenium/anthropic";
|
|
318
|
+
|
|
319
|
+
configure({
|
|
320
|
+
reveniumApiKey: "hak_your_key",
|
|
321
|
+
capturePrompts: true,
|
|
322
|
+
});
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
#### Per-Request Control
|
|
326
|
+
|
|
327
|
+
Override the global setting for individual requests:
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
const response = await anthropic.messages.create(
|
|
331
|
+
{
|
|
332
|
+
model: "claude-3-5-sonnet-20241022",
|
|
333
|
+
max_tokens: 1024,
|
|
334
|
+
messages: [{ role: "user", content: "Hello!" }],
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
capturePrompts: true, // Enable for this request only
|
|
338
|
+
},
|
|
339
|
+
);
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
#### Security
|
|
343
|
+
|
|
344
|
+
All captured prompts are automatically sanitized to remove sensitive credentials including:
|
|
345
|
+
|
|
346
|
+
- API keys (sk-\*, sk-proj-\*, sk-ant-\*)
|
|
347
|
+
- Bearer tokens
|
|
348
|
+
- Passwords
|
|
349
|
+
- Generic tokens and api_key fields
|
|
191
350
|
|
|
192
351
|
### Manual Configuration
|
|
193
352
|
|
package/dist/cjs/config.js
CHANGED
|
@@ -16,27 +16,27 @@ const constants_1 = require("./constants");
|
|
|
16
16
|
*/
|
|
17
17
|
class ConsoleLogger {
|
|
18
18
|
isDebugEnabled() {
|
|
19
|
-
return process.env[constants_1.ENV_VARS.DEBUG] ===
|
|
19
|
+
return process.env[constants_1.ENV_VARS.DEBUG] === "true";
|
|
20
20
|
}
|
|
21
21
|
formatMessage(level, message, context) {
|
|
22
22
|
const timestamp = new Date().toISOString();
|
|
23
|
-
const prefix = `[${constants_1.LOGGING_CONFIG.MIDDLEWARE_NAME}${level ===
|
|
24
|
-
const contextStr = context ? ` ${JSON.stringify(context)}` :
|
|
23
|
+
const prefix = `[${constants_1.LOGGING_CONFIG.MIDDLEWARE_NAME}${level === "DEBUG" ? " Debug" : ""}]`;
|
|
24
|
+
const contextStr = context ? ` ${JSON.stringify(context)}` : "";
|
|
25
25
|
return `${timestamp} ${prefix} ${message}${contextStr}`;
|
|
26
26
|
}
|
|
27
27
|
debug(message, context) {
|
|
28
28
|
if (this.isDebugEnabled()) {
|
|
29
|
-
console.debug(this.formatMessage(
|
|
29
|
+
console.debug(this.formatMessage("DEBUG", message, context));
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
info(message, context) {
|
|
33
|
-
console.info(this.formatMessage(
|
|
33
|
+
console.info(this.formatMessage("INFO", message, context));
|
|
34
34
|
}
|
|
35
35
|
warn(message, context) {
|
|
36
|
-
console.warn(this.formatMessage(
|
|
36
|
+
console.warn(this.formatMessage("WARN", message, context));
|
|
37
37
|
}
|
|
38
38
|
error(message, context) {
|
|
39
|
-
console.error(this.formatMessage(
|
|
39
|
+
console.error(this.formatMessage("ERROR", message, context));
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
@@ -51,14 +51,32 @@ function loadConfigFromEnvironment() {
|
|
|
51
51
|
reveniumApiKey: process.env[constants_1.ENV_VARS.REVENIUM_API_KEY],
|
|
52
52
|
reveniumBaseUrl: process.env[constants_1.ENV_VARS.REVENIUM_BASE_URL],
|
|
53
53
|
anthropicApiKey: process.env[constants_1.ENV_VARS.ANTHROPIC_API_KEY],
|
|
54
|
-
debug: process.env[constants_1.ENV_VARS.DEBUG] ===
|
|
54
|
+
debug: process.env[constants_1.ENV_VARS.DEBUG] === "true",
|
|
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],
|
|
61
|
+
capturePrompts: process.env[constants_1.ENV_VARS.CAPTURE_PROMPTS],
|
|
59
62
|
};
|
|
60
63
|
return env;
|
|
61
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Parse printSummary environment variable value
|
|
67
|
+
*/
|
|
68
|
+
function parsePrintSummary(value) {
|
|
69
|
+
if (!value)
|
|
70
|
+
return undefined;
|
|
71
|
+
const lowerValue = value.toLowerCase();
|
|
72
|
+
if (lowerValue === "true" || lowerValue === "human")
|
|
73
|
+
return "human";
|
|
74
|
+
if (lowerValue === "json")
|
|
75
|
+
return "json";
|
|
76
|
+
if (lowerValue === "false")
|
|
77
|
+
return false;
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
62
80
|
/**
|
|
63
81
|
* Convert environment config to Revenium config
|
|
64
82
|
*/
|
|
@@ -67,15 +85,20 @@ function createConfigFromEnvironment(env) {
|
|
|
67
85
|
return null;
|
|
68
86
|
}
|
|
69
87
|
const apiTimeout = env.apiTimeout ? parseInt(env.apiTimeout, 10) : undefined;
|
|
70
|
-
const failSilent = env.failSilent !==
|
|
88
|
+
const failSilent = env.failSilent !== "false"; // Default to true
|
|
71
89
|
const maxRetries = env.maxRetries ? parseInt(env.maxRetries, 10) : undefined;
|
|
90
|
+
const printSummary = parsePrintSummary(env.printSummary);
|
|
91
|
+
const capturePrompts = env.capturePrompts === "true";
|
|
72
92
|
return {
|
|
73
93
|
reveniumApiKey: env.reveniumApiKey,
|
|
74
94
|
reveniumBaseUrl: env.reveniumBaseUrl || constants_1.DEFAULT_CONFIG.REVENIUM_BASE_URL,
|
|
75
95
|
anthropicApiKey: env.anthropicApiKey,
|
|
76
96
|
apiTimeout,
|
|
77
97
|
failSilent,
|
|
78
|
-
maxRetries
|
|
98
|
+
maxRetries,
|
|
99
|
+
printSummary,
|
|
100
|
+
teamId: env.teamId?.trim(),
|
|
101
|
+
capturePrompts,
|
|
79
102
|
};
|
|
80
103
|
}
|
|
81
104
|
/**
|
|
@@ -85,18 +108,18 @@ function validateConfig(config) {
|
|
|
85
108
|
const validation = (0, validation_1.validateReveniumConfig)(config);
|
|
86
109
|
if (!validation.isValid) {
|
|
87
110
|
// Log detailed validation errors
|
|
88
|
-
getLogger().error(
|
|
111
|
+
getLogger().error("Configuration validation failed", {
|
|
89
112
|
errors: validation.errors,
|
|
90
113
|
warnings: validation.warnings,
|
|
91
|
-
suggestions: validation.suggestions
|
|
114
|
+
suggestions: validation.suggestions,
|
|
92
115
|
});
|
|
93
116
|
// Create detailed error message
|
|
94
|
-
let errorMessage =
|
|
117
|
+
let errorMessage = "Configuration validation failed:\n";
|
|
95
118
|
validation.errors.forEach((error, index) => {
|
|
96
119
|
errorMessage += ` ${index + 1}. ${error}\n`;
|
|
97
120
|
});
|
|
98
121
|
if (validation.suggestions && validation.suggestions.length > 0) {
|
|
99
|
-
errorMessage +=
|
|
122
|
+
errorMessage += "\nSuggestions:\n";
|
|
100
123
|
validation.suggestions.forEach((suggestion) => {
|
|
101
124
|
errorMessage += ` • ${suggestion}\n`;
|
|
102
125
|
});
|
|
@@ -105,8 +128,8 @@ function validateConfig(config) {
|
|
|
105
128
|
}
|
|
106
129
|
// Log warnings if any
|
|
107
130
|
if (validation.warnings && validation.warnings.length > 0) {
|
|
108
|
-
getLogger().warn(
|
|
109
|
-
warnings: validation.warnings
|
|
131
|
+
getLogger().warn("Configuration warnings", {
|
|
132
|
+
warnings: validation.warnings,
|
|
110
133
|
});
|
|
111
134
|
}
|
|
112
135
|
}
|
|
@@ -123,14 +146,42 @@ function getConfig() {
|
|
|
123
146
|
}
|
|
124
147
|
/**
|
|
125
148
|
* Set the global configuration
|
|
149
|
+
* Uses the normalized config from validation (with defaults applied and fields trimmed)
|
|
126
150
|
*/
|
|
127
151
|
function setConfig(config) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
152
|
+
const validation = (0, validation_1.validateReveniumConfig)(config);
|
|
153
|
+
if (!validation.isValid) {
|
|
154
|
+
// Log detailed validation errors
|
|
155
|
+
getLogger().error("Configuration validation failed", {
|
|
156
|
+
errors: validation.errors,
|
|
157
|
+
warnings: validation.warnings,
|
|
158
|
+
suggestions: validation.suggestions,
|
|
159
|
+
});
|
|
160
|
+
// Create detailed error message
|
|
161
|
+
let errorMessage = "Configuration validation failed:\n";
|
|
162
|
+
validation.errors.forEach((error, index) => {
|
|
163
|
+
errorMessage += ` ${index + 1}. ${error}\n`;
|
|
164
|
+
});
|
|
165
|
+
if (validation.suggestions && validation.suggestions.length > 0) {
|
|
166
|
+
errorMessage += "\nSuggestions:\n";
|
|
167
|
+
validation.suggestions.forEach((suggestion) => {
|
|
168
|
+
errorMessage += ` • ${suggestion}\n`;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
throw new Error(errorMessage.trim());
|
|
172
|
+
}
|
|
173
|
+
// Log warnings if any
|
|
174
|
+
if (validation.warnings && validation.warnings.length > 0) {
|
|
175
|
+
getLogger().warn("Configuration warnings", {
|
|
176
|
+
warnings: validation.warnings,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
// Use the normalized config from validation (with defaults applied and fields trimmed)
|
|
180
|
+
globalConfig = validation.config;
|
|
181
|
+
globalLogger.debug("Revenium configuration updated", {
|
|
182
|
+
baseUrl: globalConfig.reveniumBaseUrl,
|
|
183
|
+
hasApiKey: !!globalConfig.reveniumApiKey,
|
|
184
|
+
hasAnthropicKey: !!globalConfig.anthropicApiKey,
|
|
134
185
|
});
|
|
135
186
|
}
|
|
136
187
|
/**
|
|
@@ -144,7 +195,7 @@ function getLogger() {
|
|
|
144
195
|
*/
|
|
145
196
|
function setLogger(logger) {
|
|
146
197
|
globalLogger = logger;
|
|
147
|
-
globalLogger.debug(
|
|
198
|
+
globalLogger.debug("Custom logger set for Revenium middleware");
|
|
148
199
|
}
|
|
149
200
|
/**
|
|
150
201
|
* Initialize configuration from environment variables
|
|
@@ -155,12 +206,12 @@ function initializeConfig() {
|
|
|
155
206
|
if (config) {
|
|
156
207
|
try {
|
|
157
208
|
setConfig(config);
|
|
158
|
-
globalLogger.debug(
|
|
209
|
+
globalLogger.debug("Revenium middleware initialized from environment variables");
|
|
159
210
|
return true;
|
|
160
211
|
}
|
|
161
212
|
catch (error) {
|
|
162
|
-
globalLogger.error(
|
|
163
|
-
error: error instanceof Error ? error.message : String(error)
|
|
213
|
+
globalLogger.error("Failed to initialize Revenium configuration", {
|
|
214
|
+
error: error instanceof Error ? error.message : String(error),
|
|
164
215
|
});
|
|
165
216
|
return false;
|
|
166
217
|
}
|
|
@@ -181,14 +232,14 @@ function getConfigStatus() {
|
|
|
181
232
|
hasConfig: false,
|
|
182
233
|
hasApiKey: false,
|
|
183
234
|
hasAnthropicKey: false,
|
|
184
|
-
baseUrl:
|
|
235
|
+
baseUrl: "",
|
|
185
236
|
};
|
|
186
237
|
}
|
|
187
238
|
return {
|
|
188
239
|
hasConfig: true,
|
|
189
240
|
hasApiKey: !!globalConfig.reveniumApiKey,
|
|
190
241
|
hasAnthropicKey: !!globalConfig.anthropicApiKey,
|
|
191
|
-
baseUrl: globalConfig.reveniumBaseUrl
|
|
242
|
+
baseUrl: globalConfig.reveniumBaseUrl,
|
|
192
243
|
};
|
|
193
244
|
}
|
|
194
245
|
/**
|