@revenium/anthropic 1.0.5 → 1.0.6

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,12 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.0.6] - 2025-10-24
6
+
7
+ ### Added
8
+ - Comprehensive metadata fields table in README with practical use cases for all 11 fields
9
+ - New `getting_started.ts` example showing complete metadata integration
10
+
11
+ ### Changed
12
+ - Streamlined Getting Started tutorial with clearer step-by-step instructions
13
+ - Improved documentation with direct links to example files
14
+
5
15
  ## [1.0.5] - 2025-10-23
6
16
 
7
17
  ### Changed
8
- - Updated .gitignore to GitHub official standard for professional presentation
9
18
  - Improved .env.example with realistic key format examples (hak_, sk-ant-)
10
- - Created initial public repository structure
11
19
 
12
20
  ## [1.0.4] - 2025-10-21
13
21
 
@@ -52,6 +60,7 @@ All notable changes to this project will be documented in this file.
52
60
  - Configurable retry logic
53
61
  - Debug logging support
54
62
 
63
+ [1.0.6]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.6
55
64
  [1.0.5]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.5
56
65
  [1.0.4]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.4
57
66
  [1.0.3]: https://github.com/revenium/revenium-middleware-anthropic-node/releases/tag/v1.0.3
package/README.md CHANGED
@@ -21,30 +21,51 @@ Automatically track and meter your Anthropic Claude API usage with Revenium. Thi
21
21
 
22
22
  ## Getting Started
23
23
 
24
- **Installation:**
24
+ ### 1. Create Project Directory
25
25
 
26
26
  ```bash
27
- npm install @revenium/anthropic @anthropic-ai/sdk
27
+ # Create and navigate to project directory
28
+ mkdir my-anthropic-project
29
+ cd my-anthropic-project
30
+
31
+ # Initialize npm project
32
+ npm init -y
33
+
34
+ # Install dependencies
35
+ npm install @revenium/anthropic @anthropic-ai/sdk dotenv tsx
36
+ npm install --save-dev typescript @types/node
28
37
  ```
29
38
 
30
- **Quick Start:**
39
+ ### 2. Configure Environment Variables
31
40
 
32
- ```typescript
33
- import "@revenium/anthropic";
34
- import Anthropic from "@anthropic-ai/sdk";
41
+ Create a `.env` file:
35
42
 
36
- const client = new Anthropic();
37
- // Middleware automatically tracks all requests
43
+ ```bash
44
+ REVENIUM_METERING_API_KEY="hak_your_revenium_key"
45
+ ANTHROPIC_API_KEY="sk-ant-your_anthropic_key"
38
46
  ```
39
47
 
40
- **Environment Setup:**
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
+
50
+ ### 3. Run Your First Example
51
+
52
+ Run the [getting started example](https://github.com/revenium/revenium-middleware-anthropic-node/blob/HEAD/examples/getting_started.ts):
41
53
 
42
54
  ```bash
43
- export ANTHROPIC_API_KEY="sk-ant-your_anthropic_key"
44
- export REVENIUM_METERING_API_KEY="hak_your_revenium_key"
55
+ npx tsx node_modules/@revenium/anthropic/examples/getting_started.ts
45
56
  ```
46
57
 
47
- **For complete step-by-step setup, TypeScript configuration, and running examples, see [examples/README.md](https://github.com/revenium/revenium-middleware-anthropic-node/blob/HEAD/examples/README.md).**
58
+ Or with debug logging:
59
+
60
+ ```bash
61
+ # Linux/macOS
62
+ REVENIUM_DEBUG=true npx tsx node_modules/@revenium/anthropic/examples/getting_started.ts
63
+
64
+ # Windows (PowerShell)
65
+ $env:REVENIUM_DEBUG="true"; npx tsx node_modules/@revenium/anthropic/examples/getting_started.ts
66
+ ```
67
+
68
+ **For more examples and TypeScript patterns, see [examples/README.md](https://github.com/revenium/revenium-middleware-anthropic-node/blob/HEAD/examples/README.md).**
48
69
 
49
70
  ## Requirements
50
71
 
@@ -97,13 +118,19 @@ See [examples/advanced-features.ts](https://github.com/revenium/revenium-middlew
97
118
 
98
119
  Add business context to track usage by organization, user, task type, or custom fields. Pass a `usageMetadata` object with any of these optional fields:
99
120
 
100
- - **subscriber**: User ID, email, and credentials
101
- - **organizationId**: Organization or company identifier
102
- - **taskType**: Type of AI task (e.g., chat, analysis, generation)
103
- - **agent**: AI agent or bot identifier
104
- - **traceId**: Session or conversation tracking
105
- - **productId**: Your product or feature identifier
106
- - **responseQualityScore**: Custom quality metrics
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 |
107
134
 
108
135
  **Resources:**
109
136
  - [API Reference](https://revenium.readme.io/reference/meter_ai_completion) - Complete metadata field documentation
@@ -164,6 +191,14 @@ npm install
164
191
  npm run build
165
192
  ```
166
193
 
194
+ ### OpenRouter Users
195
+
196
+ **Note:** Revenium's automatic token cost calculation uses AI model names from the providers themselves (e.g., `claude-sonnet-4-20250514`).
197
+
198
+ If you are using a service like OpenRouter that changes model names (from `claude-sonnet-4-20250514` to `anthropic/claude-sonnet-4`), automatic cost calculations may not work properly in Revenium (though all other processing will work normally).
199
+
200
+ Supporting OpenRouter AI model names is something we're working on for the future. If this is critical for your use case, please use the 'provide feedback' button in the Help Center to let us know.
201
+
167
202
  ### Debug Mode
168
203
 
169
204
  Enable detailed logging to troubleshoot issues:
@@ -142,6 +142,7 @@ function buildReveniumPayload(data) {
142
142
  completionStartTime: completionStartTime,
143
143
  timeToFirstToken: data.timeToFirstToken || 0,
144
144
  traceId: data.metadata?.traceId,
145
+ responseQualityScore: data.metadata?.responseQualityScore, // Fixed: Now sending to Revenium
145
146
  middlewareSource: "nodejs",
146
147
  };
147
148
  }
@@ -68,7 +68,6 @@
68
68
  * credential: { name: 'api-key', value: 'sk-...' }
69
69
  * },
70
70
  * traceId: 'analysis-session-789',
71
- * taskId: 'task-001',
72
71
  * taskType: 'data-analysis',
73
72
  * organizationId: 'enterprise-client',
74
73
  * subscriptionId: 'premium-plan',
@@ -60,8 +60,7 @@ function validateUsageMetadata(metadata) {
60
60
  const validated = {};
61
61
  // Validate string fields
62
62
  const stringFields = [
63
- 'traceId', 'taskId', 'taskType', 'subscriberEmail', 'subscriberId',
64
- 'subscriberCredentialName', 'subscriberCredential', 'organizationId',
63
+ 'traceId', 'taskType', 'organizationId',
65
64
  'subscriptionId', 'productId', 'agent'
66
65
  ];
67
66
  for (const field of stringFields) {
@@ -61,8 +61,10 @@ function getMessagesPrototype() {
61
61
  * Patch Anthropic SDK by modifying prototype methods
62
62
  */
63
63
  function patchAnthropic() {
64
- if (patchingContext.isPatched)
64
+ if (patchingContext.isPatched) {
65
+ logger.debug('Anthropic SDK already patched, skipping duplicate initialization');
65
66
  return;
67
+ }
66
68
  try {
67
69
  // Access the Messages class prototype using sophisticated prototype access
68
70
  const messagesPrototype = getMessagesPrototype();
@@ -133,6 +133,7 @@ function buildReveniumPayload(data) {
133
133
  completionStartTime: completionStartTime,
134
134
  timeToFirstToken: data.timeToFirstToken || 0,
135
135
  traceId: data.metadata?.traceId,
136
+ responseQualityScore: data.metadata?.responseQualityScore, // Fixed: Now sending to Revenium
136
137
  middlewareSource: "nodejs",
137
138
  };
138
139
  }
@@ -67,7 +67,6 @@
67
67
  * credential: { name: 'api-key', value: 'sk-...' }
68
68
  * },
69
69
  * traceId: 'analysis-session-789',
70
- * taskId: 'task-001',
71
70
  * taskType: 'data-analysis',
72
71
  * organizationId: 'enterprise-client',
73
72
  * subscriptionId: 'premium-plan',
@@ -49,8 +49,7 @@ export function validateUsageMetadata(metadata) {
49
49
  const validated = {};
50
50
  // Validate string fields
51
51
  const stringFields = [
52
- 'traceId', 'taskId', 'taskType', 'subscriberEmail', 'subscriberId',
53
- 'subscriberCredentialName', 'subscriberCredential', 'organizationId',
52
+ 'traceId', 'taskType', 'organizationId',
54
53
  'subscriptionId', 'productId', 'agent'
55
54
  ];
56
55
  for (const field of stringFields) {
@@ -53,8 +53,10 @@ function getMessagesPrototype() {
53
53
  * Patch Anthropic SDK by modifying prototype methods
54
54
  */
55
55
  export function patchAnthropic() {
56
- if (patchingContext.isPatched)
56
+ if (patchingContext.isPatched) {
57
+ logger.debug('Anthropic SDK already patched, skipping duplicate initialization');
57
58
  return;
59
+ }
58
60
  try {
59
61
  // Access the Messages class prototype using sophisticated prototype access
60
62
  const messagesPrototype = getMessagesPrototype();
@@ -67,7 +67,6 @@
67
67
  * credential: { name: 'api-key', value: 'sk-...' }
68
68
  * },
69
69
  * traceId: 'analysis-session-789',
70
- * taskId: 'task-001',
71
70
  * taskType: 'data-analysis',
72
71
  * organizationId: 'enterprise-client',
73
72
  * subscriptionId: 'premium-plan',
@@ -98,8 +98,6 @@ export interface UsageMetadata {
98
98
  subscriber?: Subscriber;
99
99
  /** Unique identifier for conversation/session tracking across multiple requests */
100
100
  traceId?: string;
101
- /** Identifier for specific AI task grouping within a trace */
102
- taskId?: string;
103
101
  /** Classification of AI operation (e.g., 'customer-support', 'content-generation', 'code-review') */
104
102
  taskType?: string;
105
103
  /** Customer organization identifier for multi-tenant applications */
@@ -290,6 +288,8 @@ export interface ReveniumPayload {
290
288
  timeToFirstToken: number;
291
289
  /** Optional trace identifier for request correlation */
292
290
  traceId?: string;
291
+ /** Quality score of the AI response (0.0-1.0) for performance tracking */
292
+ responseQualityScore?: number;
293
293
  /** Source identifier for the middleware */
294
294
  middlewareSource: string;
295
295
  }
@@ -0,0 +1,18 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Read(//Users/daithi/git/rev/git/revenium-middleware-anthropic-node/**)",
5
+ "Bash(npm init:*)",
6
+ "Bash(npm install:*)",
7
+ "Bash(cp:*)",
8
+ "Bash(npx tsx:*)",
9
+ "WebFetch(domain:revenium.readme.io)",
10
+ "Bash(tee:*)",
11
+ "Bash(npm run clean:*)",
12
+ "Bash(npm run build:*)",
13
+ "Bash(node -e \"require(''@revenium/anthropic''); console.log(''✅ Option A (Auto-init) - Import works'')\")"
14
+ ],
15
+ "deny": [],
16
+ "ask": []
17
+ }
18
+ }
@@ -70,6 +70,7 @@ Demonstrates the three ways to initialize the Revenium middleware:
70
70
  - **Manual configuration** - Use `configure()` for custom settings
71
71
 
72
72
  **Key Features:**
73
+
73
74
  - TypeScript module augmentation for native `usageMetadata` support
74
75
  - Full type safety with IntelliSense
75
76
  - Interface validation using `satisfies` operator
@@ -87,8 +88,9 @@ Demonstrates advanced Anthropic SDK features with automatic tracking:
87
88
  - **Error handling** - Comprehensive error handling patterns
88
89
 
89
90
  **Key Features:**
91
+
90
92
  - Type-safe event handling and stream processing
91
- - Advanced metadata patterns with interface extensions
93
+ - Advanced metadata patterns with custom fields support
92
94
  - Generic functions with type constraints
93
95
  - Custom logger integration
94
96
 
@@ -141,6 +143,7 @@ import Anthropic from "@anthropic-ai/sdk";
141
143
  **Problem:** `REVENIUM_METERING_API_KEY` or `ANTHROPIC_API_KEY` not found
142
144
 
143
145
  **Solutions:**
146
+
144
147
  - Ensure `.env` file is in project root
145
148
  - Check variable names match exactly
146
149
  - Verify you're importing `dotenv/config` before the middleware
@@ -7,7 +7,7 @@
7
7
  * • Manual tracking for custom scenarios with full type safety
8
8
  * • Comprehensive error handling with typed error responses
9
9
  * • Generic functions with type constraints
10
- * • Advanced metadata patterns with interface extensions
10
+ * • Advanced metadata patterns with custom fields support
11
11
  * • Type-safe event handling and stream processing
12
12
  *
13
13
  * All features leverage TypeScript's type system for maximum safety and IntelliSense.
@@ -30,29 +30,11 @@ import type {
30
30
 
31
31
  import { trackUsageAsync, getStatus, setLogger } from "@revenium/anthropic";
32
32
 
33
- // =============================================================================
34
- // ADVANCED TYPESCRIPT TYPE DEFINITIONS
35
- // =============================================================================
36
-
37
- /**
38
- * Extended metadata interface for advanced scenarios
39
- */
40
- interface AdvancedUsageMetadata extends UsageMetadata {
41
- /** Session identifier for multi-turn conversations */
42
- readonly sessionId?: string;
43
- /** User role for RBAC scenarios */
44
- readonly userRole?: "admin" | "user" | "guest";
45
- /** Feature being used */
46
- readonly feature?: "chat" | "completion" | "analysis" | "generation";
47
- /** Request priority for resource allocation */
48
- readonly priority?: "low" | "normal" | "high";
49
- }
50
-
51
33
  /**
52
34
  * Streaming event types with full type safety
53
35
  */
54
36
  type StreamEvent =
55
- | { type: "start"; timestamp: Date; metadata: AdvancedUsageMetadata }
37
+ | { type: "start"; timestamp: Date; metadata: UsageMetadata }
56
38
  | { type: "content"; content: string; timestamp: Date }
57
39
  | { type: "complete"; totalTokens: number; duration: number; timestamp: Date }
58
40
  | { type: "error"; error: string; timestamp: Date };
@@ -113,7 +95,7 @@ async function demonstrateAdvancedFeatures(): Promise<void> {
113
95
  );
114
96
 
115
97
  // Create strongly typed metadata with satisfies operator
116
- const advancedMetadata: AdvancedUsageMetadata = {
98
+ const advancedMetadata: UsageMetadata = {
117
99
  subscriber: {
118
100
  id: "artist-456",
119
101
  email: "artist@creative-studio.com",
@@ -126,12 +108,8 @@ async function demonstrateAdvancedFeatures(): Promise<void> {
126
108
  productId: "story-generator-pro",
127
109
  taskType: "creative-writing",
128
110
  agent: "storyteller-v2",
129
- // Advanced metadata extensions
130
- sessionId: `session_${Date.now()}`,
131
- userRole: "user",
132
- feature: "generation",
133
- priority: "normal",
134
- } satisfies AdvancedUsageMetadata;
111
+ traceId: `session_${Date.now()}`,
112
+ } satisfies UsageMetadata;
135
113
 
136
114
  // Type-safe streaming with event tracking
137
115
  const streamEvents: StreamEvent[] = [];
@@ -258,16 +236,13 @@ async function demonstrateAdvancedFeatures(): Promise<void> {
258
236
  "\nExample 3: Educational content with different metadata pattern..."
259
237
  );
260
238
 
261
- const educationalMetadata: AdvancedUsageMetadata = {
239
+ const educationalMetadata: UsageMetadata = {
262
240
  subscriber: { id: "student-789" },
263
241
  organizationId: "green-tech-edu",
264
242
  productId: "sustainability-tutor",
265
243
  taskType: "educational-query",
266
- sessionId: `edu_session_${Date.now()}`,
267
- userRole: "guest",
268
- feature: "analysis",
269
- priority: "low",
270
- } satisfies AdvancedUsageMetadata;
244
+ traceId: `edu_session_${Date.now()}`,
245
+ } satisfies UsageMetadata;
271
246
 
272
247
  const stream2 = await anthropic.messages.create({
273
248
  model: "claude-3-5-sonnet-latest",
@@ -308,7 +283,7 @@ async function demonstrateAdvancedFeatures(): Promise<void> {
308
283
  console.log("Example 4: Weather tool with advanced TypeScript patterns...");
309
284
 
310
285
  // Create tool-specific metadata with type safety
311
- const toolMetadata: AdvancedUsageMetadata = {
286
+ const toolMetadata: UsageMetadata = {
312
287
  subscriber: {
313
288
  id: "weather-user-456",
314
289
  email: "user@weather-app.com",
@@ -317,11 +292,8 @@ async function demonstrateAdvancedFeatures(): Promise<void> {
317
292
  productId: "smart-weather-assistant",
318
293
  taskType: "tool-usage",
319
294
  agent: "weather-bot-v3",
320
- sessionId: `weather_${Date.now()}`,
321
- userRole: "user",
322
- feature: "chat",
323
- priority: "normal",
324
- } satisfies AdvancedUsageMetadata;
295
+ traceId: `weather_${Date.now()}`,
296
+ } satisfies UsageMetadata;
325
297
 
326
298
  const toolStream = await anthropic.messages.create({
327
299
  model: "claude-3-5-sonnet-latest",
@@ -391,7 +363,6 @@ async function demonstrateAdvancedFeatures(): Promise<void> {
391
363
  console.log(" • Type-safe metadata with satisfies operator");
392
364
  console.log(" • Strongly typed event handling and streaming");
393
365
  console.log(" • Custom logger implementation with typed interfaces");
394
- console.log(" • Advanced metadata patterns with interface extensions");
395
366
  console.log(" • Comprehensive error handling with typed responses");
396
367
  console.log(" • Generic functions with type constraints");
397
368
  console.log(" • Full IntelliSense support throughout\n");
@@ -461,9 +432,7 @@ function checkEnvironment(): void {
461
432
  console.error(" REVENIUM_METERING_API_KEY=hak_your_api_key");
462
433
  console.error(" ANTHROPIC_API_KEY=sk-ant-your_anthropic_key");
463
434
  console.error("\nOptional (uses defaults if not set):");
464
- console.error(
465
- " REVENIUM_METERING_BASE_URL=https://api.revenium.io"
466
- );
435
+ console.error(" REVENIUM_METERING_BASE_URL=https://api.revenium.io");
467
436
  console.error(" REVENIUM_DEBUG=true # For detailed logging");
468
437
  process.exit(1);
469
438
  }
@@ -480,7 +449,6 @@ if (require.main === module) {
480
449
  );
481
450
  console.log("\nTypeScript Features Demonstrated:");
482
451
  console.log(" • Type-safe streaming with event handling");
483
- console.log(" • Advanced metadata patterns with interface extensions");
484
452
  console.log(" • Custom logger implementation with typed interfaces");
485
453
  console.log(" • Manual tracking with full type safety");
486
454
  console.log(" • Comprehensive error handling with typed responses");
@@ -23,7 +23,7 @@ import "dotenv/config";
23
23
  import "@revenium/anthropic";
24
24
  import Anthropic from "@anthropic-ai/sdk";
25
25
 
26
- // Import types for full TypeScript support
26
+ // Import types and functions for full TypeScript support
27
27
  import type {
28
28
  UsageMetadata,
29
29
  ReveniumConfig,
@@ -31,6 +31,9 @@ import type {
31
31
  MiddlewareStatus,
32
32
  } from "@revenium/anthropic";
33
33
 
34
+ // Import initialization and configuration functions
35
+ import { initialize, getStatus, configure, getConfig } from "@revenium/anthropic";
36
+
34
37
  async function demonstrateBasicUsage() {
35
38
  console.log("Revenium Anthropic Middleware - Basic Usage Examples\n");
36
39
 
@@ -42,16 +45,14 @@ async function demonstrateBasicUsage() {
42
45
  "Just import the middleware - it auto-configures from environment variables\n"
43
46
  );
44
47
 
45
- // Simply import the middleware - auto-initialization happens automatically
46
- await import("@revenium/anthropic");
47
-
48
+ // The middleware was already imported at the top of the file - auto-initialization happens automatically
48
49
  const anthropic = new Anthropic();
49
50
 
50
51
  try {
51
52
  // Example 1: Basic request without metadata (still tracked automatically)
52
53
  console.log("Example 1: Basic request without metadata...");
53
54
  const basicResponse = await anthropic.messages.create({
54
- model: "claude-sonnet-4-20250514",
55
+ model: "claude-3-5-sonnet-latest",
55
56
  max_tokens: 50,
56
57
  messages: [
57
58
  { role: "user", content: "What is the capital of France? Be concise." },
@@ -72,7 +73,7 @@ async function demonstrateBasicUsage() {
72
73
  // Example 2: Request with rich metadata for enhanced tracking
73
74
  console.log("Example 2: Request with rich metadata...");
74
75
  const metadataResponse = await anthropic.messages.create({
75
- model: "claude-sonnet-4-20250514",
76
+ model: "claude-3-5-sonnet-latest",
76
77
  max_tokens: 80,
77
78
  messages: [
78
79
  { role: "user", content: "Explain quantum computing in one sentence." },
@@ -130,9 +131,6 @@ async function demonstrateExplicitInitialization() {
130
131
  );
131
132
 
132
133
  try {
133
- // Import initialization functions
134
- const { initialize, getStatus } = await import("@revenium/anthropic");
135
-
136
134
  // Explicitly initialize with clear error feedback
137
135
  initialize();
138
136
  console.log("✓ Explicit initialization successful!");
@@ -148,7 +146,7 @@ async function demonstrateExplicitInitialization() {
148
146
  // Now use Anthropic with guaranteed tracking
149
147
  const anthropic = new Anthropic();
150
148
  const response = await anthropic.messages.create({
151
- model: "claude-sonnet-4-20250514",
149
+ model: "claude-3-5-sonnet-latest",
152
150
  max_tokens: 60,
153
151
  messages: [
154
152
  {
@@ -190,17 +188,13 @@ async function demonstrateManualConfiguration() {
190
188
  console.log("Option C: Manual Configuration (Full Control)");
191
189
 
192
190
  try {
193
- // Import configuration function
194
- const { configure, getConfig } = await import("@revenium/anthropic");
195
-
196
191
  // Manual configuration with all options
197
192
  configure({
198
193
  // Required: Revenium API configuration
199
194
  reveniumApiKey:
200
195
  process.env.REVENIUM_METERING_API_KEY || "hak_your_api_key_here",
201
196
  reveniumBaseUrl:
202
- process.env.REVENIUM_METERING_BASE_URL ||
203
- "https://api.revenium.io",
197
+ process.env.REVENIUM_METERING_BASE_URL || "https://api.revenium.io",
204
198
 
205
199
  // Optional: Anthropic API key (can also be set in Anthropic client)
206
200
  anthropicApiKey: process.env.ANTHROPIC_API_KEY,
@@ -228,7 +222,7 @@ async function demonstrateManualConfiguration() {
228
222
  });
229
223
 
230
224
  const response = await anthropic.messages.create({
231
- model: "claude-sonnet-4-20250514",
225
+ model: "claude-3-5-sonnet-latest",
232
226
  max_tokens: 80,
233
227
  messages: [
234
228
  {
@@ -285,9 +279,7 @@ function checkEnvironment() {
285
279
  console.error(" REVENIUM_METERING_API_KEY=hak_your_api_key");
286
280
  console.error(" ANTHROPIC_API_KEY=sk-ant-your_anthropic_key");
287
281
  console.error("\nOptional (uses defaults if not set):");
288
- console.error(
289
- " REVENIUM_METERING_BASE_URL=https://api.revenium.io"
290
- );
282
+ console.error(" REVENIUM_METERING_BASE_URL=https://api.revenium.io");
291
283
  console.error(" REVENIUM_DEBUG=true # For detailed logging");
292
284
  process.exit(1);
293
285
  }
@@ -0,0 +1,50 @@
1
+ import 'dotenv/config';
2
+ import '@revenium/anthropic';
3
+ import Anthropic from '@anthropic-ai/sdk';
4
+
5
+ async function main() {
6
+ // Create Anthropic client
7
+ const anthropic = new Anthropic();
8
+
9
+ // Chat completion with metadata
10
+ const response = await anthropic.messages.create({
11
+ model: 'claude-3-5-sonnet-latest',
12
+ max_tokens: 2000,
13
+ messages: [
14
+ { role: 'user', content: 'Please verify you are ready to assist me.' }
15
+ ],
16
+
17
+ /* Optional metadata for advanced reporting, lineage tracking, and cost allocation
18
+ usageMetadata: {
19
+ // User identification
20
+ subscriber: {
21
+ id: 'user-123',
22
+ email: 'user@example.com',
23
+ credential: {
24
+ name: 'api-key-prod',
25
+ value: 'key-abc-123'
26
+ }
27
+ },
28
+
29
+ // Organization & billing
30
+ organizationId: 'my-customers-name',
31
+ subscriptionId: 'plan-enterprise-2024',
32
+
33
+ // Product & task tracking
34
+ productId: 'my-product',
35
+ taskType: 'doc-summary',
36
+ agent: 'customer-support',
37
+
38
+ // Session tracking
39
+ traceId: 'session-' + Date.now(),
40
+
41
+ // Quality metrics
42
+ responseQualityScore: 0.95
43
+ }
44
+ */
45
+ });
46
+
47
+ console.log('Response:', response.content[0]?.text);
48
+ }
49
+
50
+ main().catch(console.error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revenium/anthropic",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Transparent TypeScript middleware for automatic Revenium usage tracking with Anthropic Claude AI",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",