@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 +53 -1
- package/README.md +174 -21
- package/dist/cjs/config.js +55 -7
- package/dist/cjs/constants.js +39 -24
- package/dist/cjs/tracking.js +107 -20
- package/dist/cjs/types/anthropic-augmentation.js +0 -62
- package/dist/cjs/utils/summary-printer.js +189 -0
- package/dist/cjs/utils/trace-fields.js +117 -0
- package/dist/cjs/utils/validation.js +58 -26
- package/dist/cjs/wrapper.js +54 -40
- package/dist/esm/config.js +55 -7
- package/dist/esm/constants.js +38 -23
- package/dist/esm/tracking.js +107 -20
- package/dist/esm/types/anthropic-augmentation.js +0 -62
- package/dist/esm/utils/summary-printer.js +186 -0
- package/dist/esm/utils/trace-fields.js +106 -0
- package/dist/esm/utils/validation.js +59 -27
- package/dist/esm/wrapper.js +60 -46
- package/dist/types/config.d.ts +1 -0
- package/dist/types/constants.d.ts +16 -1
- package/dist/types/types/anthropic-augmentation.d.ts +0 -92
- package/dist/types/types.d.ts +28 -196
- package/dist/types/utils/summary-printer.d.ts +3 -0
- package/dist/types/utils/trace-fields.d.ts +10 -0
- package/examples/README.md +3 -3
- 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 +7 -6
- package/examples/.claude/settings.local.json +0 -24
- package/examples/advanced-features.ts +0 -469
- package/examples/basic-usage.ts +0 -314
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import "@revenium/anthropic";
|
|
3
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
4
|
+
import { UsageMetadata } from "@revenium/anthropic";
|
|
5
|
+
|
|
6
|
+
async function main() {
|
|
7
|
+
console.log("Revenium Anthropic Middleware - Metadata Example\n");
|
|
8
|
+
const anthropic = new Anthropic();
|
|
9
|
+
try {
|
|
10
|
+
const metadata: UsageMetadata = {
|
|
11
|
+
subscriber: {
|
|
12
|
+
id: "user-123",
|
|
13
|
+
email: "user@example.com",
|
|
14
|
+
credential: { name: "api-key", value: "key-123" },
|
|
15
|
+
},
|
|
16
|
+
traceId: "trace-123",
|
|
17
|
+
taskType: "task-123",
|
|
18
|
+
organizationId: "org-123",
|
|
19
|
+
subscriptionId: "sub-123",
|
|
20
|
+
productId: "prod-123",
|
|
21
|
+
agent: "agent-123",
|
|
22
|
+
responseQualityScore: 0.95,
|
|
23
|
+
};
|
|
24
|
+
const response = await anthropic.messages.create({
|
|
25
|
+
model: "claude-haiku-4-5",
|
|
26
|
+
max_tokens: 50,
|
|
27
|
+
messages: [
|
|
28
|
+
{ role: "user", content: "What is the capital of France? Be concise." },
|
|
29
|
+
],
|
|
30
|
+
usageMetadata: metadata,
|
|
31
|
+
tools: [
|
|
32
|
+
{
|
|
33
|
+
name: "get_weather",
|
|
34
|
+
description: "Get weather for a location",
|
|
35
|
+
input_schema: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
location: { type: "string" },
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const textResponse =
|
|
46
|
+
response.content[0].type === "text"
|
|
47
|
+
? response.content[0].text
|
|
48
|
+
: "Non-text response";
|
|
49
|
+
console.log("RESPONSE: \n", textResponse);
|
|
50
|
+
console.log(
|
|
51
|
+
`Tokens: ${response.usage?.input_tokens} input + ${response.usage?.output_tokens} output\n`
|
|
52
|
+
);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error("Error: ", error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
main().catch(console.error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revenium/anthropic",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
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",
|
|
@@ -24,10 +24,9 @@
|
|
|
24
24
|
"build:types": "tsc -p tsconfig.types.json",
|
|
25
25
|
"fix-esm": "node scripts/fix-esm-imports.js",
|
|
26
26
|
"dev": "tsc --watch",
|
|
27
|
-
"
|
|
28
|
-
"example": "npm run build && tsx examples/basic
|
|
29
|
-
"example:
|
|
30
|
-
"example:advanced": "npm run build && tsx examples/advanced-features.ts",
|
|
27
|
+
"example": "npm run build && tsx examples/basic.ts",
|
|
28
|
+
"example:basic": "npm run build && tsx examples/basic.ts",
|
|
29
|
+
"example:advanced": "npm run build && tsx examples/advanced.ts",
|
|
31
30
|
"clean": "rimraf dist",
|
|
32
31
|
"prepublishOnly": "npm run clean && npm run build"
|
|
33
32
|
},
|
|
@@ -73,12 +72,14 @@
|
|
|
73
72
|
"dist/esm/**/*.js",
|
|
74
73
|
"dist/types/**/*.d.ts",
|
|
75
74
|
"examples/**/*",
|
|
75
|
+
"!examples/.claude/**",
|
|
76
|
+
"!examples/**/*.log",
|
|
76
77
|
"README.md",
|
|
77
78
|
"CHANGELOG.md",
|
|
78
79
|
"LICENSE"
|
|
79
80
|
],
|
|
80
81
|
"sideEffects": false,
|
|
81
82
|
"engines": {
|
|
82
|
-
"node": ">=
|
|
83
|
+
"node": ">=18.0.0"
|
|
83
84
|
}
|
|
84
85
|
}
|
|
@@ -1,24 +0,0 @@
|
|
|
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
|
-
"Bash(for section in \"Features\" \"Package Migration\" \"Getting Started\" \"Advanced Usage\" \"Configuration Options\" \"Troubleshooting\" \"Requirements\" \"Documentation\" \"Contributing\" \"Code of Conduct\" \"Security\" \"License\" \"Support\" \"Development\")",
|
|
15
|
-
"Bash(do)",
|
|
16
|
-
"Bash(echo:*)",
|
|
17
|
-
"Bash(done)",
|
|
18
|
-
"Bash(grep:*)",
|
|
19
|
-
"Bash(gitleaks detect:*)"
|
|
20
|
-
],
|
|
21
|
-
"deny": [],
|
|
22
|
-
"ask": []
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,469 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Revenium Anthropic Middleware - Advanced TypeScript Features Example
|
|
3
|
-
*
|
|
4
|
-
* This example demonstrates advanced TypeScript patterns and features:
|
|
5
|
-
* • Streaming responses with type-safe real-time tracking
|
|
6
|
-
* • Tool use (function calling) with strongly typed metadata
|
|
7
|
-
* • Manual tracking for custom scenarios with full type safety
|
|
8
|
-
* • Comprehensive error handling with typed error responses
|
|
9
|
-
* • Generic functions with type constraints
|
|
10
|
-
* • Advanced metadata patterns with custom fields support
|
|
11
|
-
* • Type-safe event handling and stream processing
|
|
12
|
-
*
|
|
13
|
-
* All features leverage TypeScript's type system for maximum safety and IntelliSense.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
// Load environment variables from .env file
|
|
17
|
-
import "dotenv/config";
|
|
18
|
-
|
|
19
|
-
// Import for module augmentation - enables native usageMetadata support
|
|
20
|
-
import "@revenium/anthropic";
|
|
21
|
-
import Anthropic from "@anthropic-ai/sdk";
|
|
22
|
-
|
|
23
|
-
// Import types for advanced TypeScript patterns
|
|
24
|
-
import type {
|
|
25
|
-
UsageMetadata,
|
|
26
|
-
TrackingData,
|
|
27
|
-
MiddlewareStatus,
|
|
28
|
-
Logger,
|
|
29
|
-
} from "@revenium/anthropic";
|
|
30
|
-
|
|
31
|
-
import { trackUsageAsync, getStatus, setLogger } from "@revenium/anthropic";
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Streaming event types with full type safety
|
|
35
|
-
*/
|
|
36
|
-
type StreamEvent =
|
|
37
|
-
| { type: "start"; timestamp: Date; metadata: UsageMetadata }
|
|
38
|
-
| { type: "content"; content: string; timestamp: Date }
|
|
39
|
-
| { type: "complete"; totalTokens: number; duration: number; timestamp: Date }
|
|
40
|
-
| { type: "error"; error: string; timestamp: Date };
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Custom logger implementation for advanced scenarios
|
|
44
|
-
*/
|
|
45
|
-
class AdvancedLogger implements Logger {
|
|
46
|
-
private context: Record<string, unknown> = {};
|
|
47
|
-
|
|
48
|
-
setContext(context: Record<string, unknown>): void {
|
|
49
|
-
this.context = { ...this.context, ...context };
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
debug(message: string, data?: Record<string, unknown>): void {
|
|
53
|
-
console.log(`[DEBUG] ${message}`, { ...this.context, ...data });
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
info(message: string, data?: Record<string, unknown>): void {
|
|
57
|
-
console.log(`[INFO] ${message}`, { ...this.context, ...data });
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
warn(message: string, data?: Record<string, unknown>): void {
|
|
61
|
-
console.warn(`[WARN] ${message}`, { ...this.context, ...data });
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
error(message: string, data?: Record<string, unknown>): void {
|
|
65
|
-
console.error(`[ERROR] ${message}`, { ...this.context, ...data });
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async function demonstrateAdvancedFeatures(): Promise<void> {
|
|
70
|
-
console.log("Revenium Anthropic Middleware - Advanced TypeScript Features\n");
|
|
71
|
-
|
|
72
|
-
// Initialize custom logger with type safety
|
|
73
|
-
const logger = new AdvancedLogger();
|
|
74
|
-
logger.setContext({
|
|
75
|
-
service: "advanced-features-demo",
|
|
76
|
-
version: "1.0.0",
|
|
77
|
-
environment: "development",
|
|
78
|
-
});
|
|
79
|
-
setLogger(logger);
|
|
80
|
-
|
|
81
|
-
const anthropic = new Anthropic();
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
// =============================================================================
|
|
85
|
-
// ADVANCED TYPESCRIPT PATTERNS WITH STREAMING
|
|
86
|
-
// =============================================================================
|
|
87
|
-
console.log("Advanced TypeScript Streaming Patterns");
|
|
88
|
-
console.log(
|
|
89
|
-
"Type-safe streaming with event handling and metadata validation\n"
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
// Example 1: Type-safe streaming with advanced metadata
|
|
93
|
-
console.log(
|
|
94
|
-
"Example 1: Creative writing with advanced metadata patterns..."
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
// Create strongly typed metadata with satisfies operator
|
|
98
|
-
const advancedMetadata: UsageMetadata = {
|
|
99
|
-
subscriber: {
|
|
100
|
-
id: "artist-456",
|
|
101
|
-
email: "artist@creative-studio.com",
|
|
102
|
-
credential: {
|
|
103
|
-
name: "creative-api-key",
|
|
104
|
-
value: "creative-key-789",
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
organizationId: "creative-ai-studio",
|
|
108
|
-
productId: "story-generator-pro",
|
|
109
|
-
taskType: "creative-writing",
|
|
110
|
-
agent: "storyteller-v2",
|
|
111
|
-
traceId: `session_${Date.now()}`,
|
|
112
|
-
} satisfies UsageMetadata;
|
|
113
|
-
|
|
114
|
-
// Type-safe streaming with event tracking
|
|
115
|
-
const streamEvents: StreamEvent[] = [];
|
|
116
|
-
const startTime = new Date();
|
|
117
|
-
|
|
118
|
-
streamEvents.push({
|
|
119
|
-
type: "start",
|
|
120
|
-
timestamp: startTime,
|
|
121
|
-
metadata: advancedMetadata,
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
const stream1 = await anthropic.messages.create({
|
|
125
|
-
model: "claude-haiku-4-5",
|
|
126
|
-
max_tokens: 150,
|
|
127
|
-
messages: [
|
|
128
|
-
{
|
|
129
|
-
role: "user",
|
|
130
|
-
content: "Write a short story about a robot learning to paint.",
|
|
131
|
-
},
|
|
132
|
-
],
|
|
133
|
-
stream: true,
|
|
134
|
-
usageMetadata: advancedMetadata, // Fully typed with module augmentation
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
console.log("Streaming response:");
|
|
138
|
-
let content1 = "";
|
|
139
|
-
let tokenCount = 0;
|
|
140
|
-
|
|
141
|
-
for await (const event of stream1) {
|
|
142
|
-
if (
|
|
143
|
-
event.type === "content_block_delta" &&
|
|
144
|
-
event.delta.type === "text_delta"
|
|
145
|
-
) {
|
|
146
|
-
process.stdout.write(event.delta.text);
|
|
147
|
-
content1 += event.delta.text;
|
|
148
|
-
tokenCount++;
|
|
149
|
-
|
|
150
|
-
// Add streaming event with type safety
|
|
151
|
-
streamEvents.push({
|
|
152
|
-
type: "content",
|
|
153
|
-
content: event.delta.text,
|
|
154
|
-
timestamp: new Date(),
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Complete streaming event tracking
|
|
160
|
-
const endTime = new Date();
|
|
161
|
-
streamEvents.push({
|
|
162
|
-
type: "complete",
|
|
163
|
-
totalTokens: tokenCount,
|
|
164
|
-
duration: endTime.getTime() - startTime.getTime(),
|
|
165
|
-
timestamp: endTime,
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
if (!content1.trim()) throw new Error("No content received from stream");
|
|
169
|
-
console.log("\nStream 1 completed with type-safe event tracking");
|
|
170
|
-
console.log(
|
|
171
|
-
`Events captured: ${streamEvents.length}, Duration: ${
|
|
172
|
-
endTime.getTime() - startTime.getTime()
|
|
173
|
-
}ms\n`
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
// =============================================================================
|
|
177
|
-
// ADVANCED MANUAL TRACKING WITH TYPE SAFETY
|
|
178
|
-
// =============================================================================
|
|
179
|
-
console.log("Advanced Manual Tracking with TypeScript");
|
|
180
|
-
console.log(
|
|
181
|
-
"Demonstrating manual tracking with full type safety and validation\n"
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
// Example 2: Manual tracking with type-safe data
|
|
185
|
-
console.log("Example 2: Manual tracking with custom metrics...");
|
|
186
|
-
|
|
187
|
-
const now = new Date();
|
|
188
|
-
const trackingData: TrackingData = {
|
|
189
|
-
requestId: `manual_${Date.now()}`,
|
|
190
|
-
model: "claude-haiku-4-5",
|
|
191
|
-
inputTokens: 25,
|
|
192
|
-
outputTokens: 150,
|
|
193
|
-
duration: 2500,
|
|
194
|
-
isStreamed: false,
|
|
195
|
-
requestTime: new Date(now.getTime() - 2500), // 2.5 seconds ago
|
|
196
|
-
responseTime: now,
|
|
197
|
-
metadata: {
|
|
198
|
-
subscriber: { id: "manual-user-123" },
|
|
199
|
-
organizationId: "manual-tracking-org",
|
|
200
|
-
productId: "custom-analytics",
|
|
201
|
-
taskType: "manual-analysis",
|
|
202
|
-
} satisfies UsageMetadata,
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
// Type-safe manual tracking
|
|
206
|
-
try {
|
|
207
|
-
trackUsageAsync(trackingData); // Note: this function is synchronous
|
|
208
|
-
console.log("Manual tracking completed successfully");
|
|
209
|
-
console.log(
|
|
210
|
-
`Tracked: ${
|
|
211
|
-
trackingData.inputTokens + trackingData.outputTokens
|
|
212
|
-
} tokens, ${trackingData.duration}ms duration\n`
|
|
213
|
-
);
|
|
214
|
-
} catch (error) {
|
|
215
|
-
const errorMessage =
|
|
216
|
-
error instanceof Error ? error.message : String(error);
|
|
217
|
-
console.log(`Manual tracking failed: ${errorMessage}\n`);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// =============================================================================
|
|
221
|
-
// SERVICE STATUS WITH TYPE SAFETY
|
|
222
|
-
// =============================================================================
|
|
223
|
-
console.log("Service Status and Health Check");
|
|
224
|
-
console.log("Type-safe middleware status monitoring\n");
|
|
225
|
-
|
|
226
|
-
const status: MiddlewareStatus = getStatus();
|
|
227
|
-
console.log("Middleware Status:", {
|
|
228
|
-
initialized: status.initialized,
|
|
229
|
-
patched: status.patched,
|
|
230
|
-
hasConfig: status.hasConfig,
|
|
231
|
-
configValid: status.initialized && status.patched && status.hasConfig,
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
// Example 3: Educational content with different metadata pattern
|
|
235
|
-
console.log(
|
|
236
|
-
"\nExample 3: Educational content with different metadata pattern..."
|
|
237
|
-
);
|
|
238
|
-
|
|
239
|
-
const educationalMetadata: UsageMetadata = {
|
|
240
|
-
subscriber: { id: "student-789" },
|
|
241
|
-
organizationId: "green-tech-edu",
|
|
242
|
-
productId: "sustainability-tutor",
|
|
243
|
-
taskType: "educational-query",
|
|
244
|
-
traceId: `edu_session_${Date.now()}`,
|
|
245
|
-
} satisfies UsageMetadata;
|
|
246
|
-
|
|
247
|
-
const stream2 = await anthropic.messages.create({
|
|
248
|
-
model: "claude-haiku-4-5",
|
|
249
|
-
max_tokens: 100,
|
|
250
|
-
messages: [
|
|
251
|
-
{
|
|
252
|
-
role: "user",
|
|
253
|
-
content: "Explain three benefits of renewable energy.",
|
|
254
|
-
},
|
|
255
|
-
],
|
|
256
|
-
stream: true,
|
|
257
|
-
usageMetadata: educationalMetadata, // Fully typed
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
console.log("Educational response:");
|
|
261
|
-
let content2 = "";
|
|
262
|
-
for await (const event of stream2) {
|
|
263
|
-
if (
|
|
264
|
-
event.type === "content_block_delta" &&
|
|
265
|
-
event.delta.type === "text_delta"
|
|
266
|
-
) {
|
|
267
|
-
process.stdout.write(event.delta.text);
|
|
268
|
-
content2 += event.delta.text;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
if (!content2.trim()) throw new Error("No content received from stream");
|
|
273
|
-
console.log("\nStream 2 completed with educational metadata pattern\n");
|
|
274
|
-
|
|
275
|
-
// =============================================================================
|
|
276
|
-
// ADVANCED TOOL USE WITH TYPESCRIPT PATTERNS
|
|
277
|
-
// =============================================================================
|
|
278
|
-
console.log("Advanced Tool Use with TypeScript Patterns");
|
|
279
|
-
console.log(
|
|
280
|
-
"Tool usage with strongly typed metadata and comprehensive tracking\n"
|
|
281
|
-
);
|
|
282
|
-
|
|
283
|
-
console.log("Example 4: Weather tool with advanced TypeScript patterns...");
|
|
284
|
-
|
|
285
|
-
// Create tool-specific metadata with type safety
|
|
286
|
-
const toolMetadata: UsageMetadata = {
|
|
287
|
-
subscriber: {
|
|
288
|
-
id: "weather-user-456",
|
|
289
|
-
email: "user@weather-app.com",
|
|
290
|
-
},
|
|
291
|
-
organizationId: "weather-services-inc",
|
|
292
|
-
productId: "smart-weather-assistant",
|
|
293
|
-
taskType: "tool-usage",
|
|
294
|
-
agent: "weather-bot-v3",
|
|
295
|
-
traceId: `weather_${Date.now()}`,
|
|
296
|
-
} satisfies UsageMetadata;
|
|
297
|
-
|
|
298
|
-
const toolStream = await anthropic.messages.create({
|
|
299
|
-
model: "claude-haiku-4-5",
|
|
300
|
-
max_tokens: 200,
|
|
301
|
-
tools: [
|
|
302
|
-
{
|
|
303
|
-
name: "get_weather",
|
|
304
|
-
description: "Get current weather for a location",
|
|
305
|
-
input_schema: {
|
|
306
|
-
type: "object",
|
|
307
|
-
properties: {
|
|
308
|
-
location: {
|
|
309
|
-
type: "string",
|
|
310
|
-
description: "City and state, e.g. San Francisco, CA",
|
|
311
|
-
},
|
|
312
|
-
units: {
|
|
313
|
-
type: "string",
|
|
314
|
-
enum: ["celsius", "fahrenheit"],
|
|
315
|
-
description: "Temperature units",
|
|
316
|
-
},
|
|
317
|
-
},
|
|
318
|
-
required: ["location"],
|
|
319
|
-
},
|
|
320
|
-
},
|
|
321
|
-
],
|
|
322
|
-
messages: [
|
|
323
|
-
{
|
|
324
|
-
role: "user",
|
|
325
|
-
content: "What's the weather like in New York? Use the weather tool.",
|
|
326
|
-
},
|
|
327
|
-
],
|
|
328
|
-
stream: true,
|
|
329
|
-
usageMetadata: toolMetadata, // Using strongly typed metadata
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
console.log("Tool use streaming response:");
|
|
333
|
-
let toolContent = "";
|
|
334
|
-
for await (const event of toolStream) {
|
|
335
|
-
if (
|
|
336
|
-
event.type === "content_block_delta" &&
|
|
337
|
-
event.delta.type === "text_delta"
|
|
338
|
-
) {
|
|
339
|
-
process.stdout.write(event.delta.text);
|
|
340
|
-
toolContent += event.delta.text;
|
|
341
|
-
} else if (
|
|
342
|
-
event.type === "content_block_start" &&
|
|
343
|
-
event.content_block.type === "tool_use"
|
|
344
|
-
) {
|
|
345
|
-
console.log(`\nTool called: ${event.content_block.name}`);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
if (!toolContent.trim())
|
|
350
|
-
throw new Error("No content received from tool stream");
|
|
351
|
-
console.log(
|
|
352
|
-
"\nTool streaming completed with advanced TypeScript patterns\n"
|
|
353
|
-
);
|
|
354
|
-
|
|
355
|
-
// =============================================================================
|
|
356
|
-
// SUMMARY AND TYPESCRIPT BENEFITS
|
|
357
|
-
// =============================================================================
|
|
358
|
-
console.log("Advanced TypeScript Features Summary");
|
|
359
|
-
console.log("All examples completed successfully with full type safety!\n");
|
|
360
|
-
|
|
361
|
-
console.log("TypeScript Benefits Demonstrated:");
|
|
362
|
-
console.log(" • Module augmentation for native usageMetadata support");
|
|
363
|
-
console.log(" • Type-safe metadata with satisfies operator");
|
|
364
|
-
console.log(" • Strongly typed event handling and streaming");
|
|
365
|
-
console.log(" • Custom logger implementation with typed interfaces");
|
|
366
|
-
console.log(" • Comprehensive error handling with typed responses");
|
|
367
|
-
console.log(" • Generic functions with type constraints");
|
|
368
|
-
console.log(" • Full IntelliSense support throughout\n");
|
|
369
|
-
|
|
370
|
-
console.log("Middleware Status Summary:");
|
|
371
|
-
const finalStatus = getStatus();
|
|
372
|
-
console.log(` • Initialized: ${finalStatus.initialized}`);
|
|
373
|
-
console.log(` • Patched: ${finalStatus.patched}`);
|
|
374
|
-
console.log(` • Has Config: ${finalStatus.hasConfig}`);
|
|
375
|
-
console.log(
|
|
376
|
-
` • All Systems: ${
|
|
377
|
-
finalStatus.initialized && finalStatus.patched && finalStatus.hasConfig
|
|
378
|
-
? "Operational"
|
|
379
|
-
: "Check Configuration"
|
|
380
|
-
}\n`
|
|
381
|
-
);
|
|
382
|
-
|
|
383
|
-
console.log("Next Steps:");
|
|
384
|
-
console.log(" • Review comprehensive JSDoc in your IDE");
|
|
385
|
-
console.log(
|
|
386
|
-
" • Check the TypeScript-first examples/README.md for more patterns"
|
|
387
|
-
);
|
|
388
|
-
console.log(
|
|
389
|
-
" • Implement custom metadata extensions for your use case\n"
|
|
390
|
-
);
|
|
391
|
-
} catch (error) {
|
|
392
|
-
// Comprehensive TypeScript error handling
|
|
393
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
394
|
-
console.error("Advanced TypeScript features demo failed:", errorMessage);
|
|
395
|
-
|
|
396
|
-
// Type-safe error analysis
|
|
397
|
-
if (error && typeof error === "object" && "status" in error) {
|
|
398
|
-
const httpError = error as { status: number; message?: string };
|
|
399
|
-
if (httpError.status >= 400) {
|
|
400
|
-
console.error(
|
|
401
|
-
`HTTP ${httpError.status} Error - API connectivity issue`
|
|
402
|
-
);
|
|
403
|
-
console.error("Check your API keys and network connectivity");
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// Log final status even on error
|
|
408
|
-
const errorStatus = getStatus();
|
|
409
|
-
console.error("Final Middleware Status:", {
|
|
410
|
-
initialized: errorStatus.initialized,
|
|
411
|
-
patched: errorStatus.patched,
|
|
412
|
-
hasConfig: errorStatus.hasConfig,
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
throw error;
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
/**
|
|
420
|
-
* Type-safe environment validation
|
|
421
|
-
*/
|
|
422
|
-
function checkEnvironment(): void {
|
|
423
|
-
const required = ["REVENIUM_METERING_API_KEY", "ANTHROPIC_API_KEY"];
|
|
424
|
-
const missing = required.filter((key) => !process.env[key]);
|
|
425
|
-
|
|
426
|
-
if (missing.length > 0) {
|
|
427
|
-
console.error(
|
|
428
|
-
"Missing required environment variables for advanced TypeScript features:"
|
|
429
|
-
);
|
|
430
|
-
missing.forEach((key) => console.error(` • ${key}`));
|
|
431
|
-
console.error("\nSet them in a .env file in the project root:");
|
|
432
|
-
console.error(" REVENIUM_METERING_API_KEY=hak_your_api_key");
|
|
433
|
-
console.error(" ANTHROPIC_API_KEY=sk-ant-your_anthropic_key");
|
|
434
|
-
console.error("\nOptional (uses defaults if not set):");
|
|
435
|
-
console.error(" REVENIUM_METERING_BASE_URL=https://api.revenium.io");
|
|
436
|
-
console.error(" REVENIUM_DEBUG=true # For detailed logging");
|
|
437
|
-
process.exit(1);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
// Run the TypeScript demonstration
|
|
442
|
-
if (require.main === module) {
|
|
443
|
-
checkEnvironment();
|
|
444
|
-
|
|
445
|
-
demonstrateAdvancedFeatures()
|
|
446
|
-
.then(() => {
|
|
447
|
-
console.log(
|
|
448
|
-
"\nAdvanced TypeScript Features Demo Completed Successfully!"
|
|
449
|
-
);
|
|
450
|
-
console.log("\nTypeScript Features Demonstrated:");
|
|
451
|
-
console.log(" • Type-safe streaming with event handling");
|
|
452
|
-
console.log(" • Custom logger implementation with typed interfaces");
|
|
453
|
-
console.log(" • Manual tracking with full type safety");
|
|
454
|
-
console.log(" • Comprehensive error handling with typed responses");
|
|
455
|
-
console.log(" • Module augmentation for native usageMetadata support");
|
|
456
|
-
console.log(" • Generic functions with type constraints");
|
|
457
|
-
console.log(" • Full IntelliSense support throughout");
|
|
458
|
-
console.log(
|
|
459
|
-
"\nNext: Check examples/README.md for more TypeScript patterns!"
|
|
460
|
-
);
|
|
461
|
-
console.log(
|
|
462
|
-
"\nTip: Set REVENIUM_DEBUG=true in .env file for detailed tracking logs"
|
|
463
|
-
);
|
|
464
|
-
})
|
|
465
|
-
.catch((error) => {
|
|
466
|
-
console.error("\nAdvanced TypeScript features demo failed:", error);
|
|
467
|
-
process.exit(1);
|
|
468
|
-
});
|
|
469
|
-
}
|