@revenium/anthropic 1.0.2 → 1.0.4
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 +52 -0
- package/LICENSE +20 -20
- package/README.md +456 -806
- package/examples/README.md +179 -0
- package/examples/advanced-features.ts +501 -0
- package/examples/basic-usage.ts +322 -0
- package/package.json +84 -82
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Revenium Anthropic Middleware - Examples
|
|
2
|
+
|
|
3
|
+
**TypeScript-first** examples demonstrating automatic Revenium usage tracking with the Anthropic SDK.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### 1. Install Dependencies
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @revenium/anthropic @anthropic-ai/sdk dotenv
|
|
11
|
+
npm install -D typescript tsx @types/node # For TypeScript
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### 2. Environment Setup
|
|
15
|
+
|
|
16
|
+
Create a `.env` file in your project root:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Required
|
|
20
|
+
REVENIUM_METERING_API_KEY=hak_your_revenium_api_key
|
|
21
|
+
ANTHROPIC_API_KEY=sk-ant-your_anthropic_api_key
|
|
22
|
+
|
|
23
|
+
# Optional
|
|
24
|
+
REVENIUM_METERING_BASE_URL=https://api.revenium.io/meter
|
|
25
|
+
REVENIUM_DEBUG=false
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 3. Run Examples
|
|
29
|
+
|
|
30
|
+
**If you cloned from GitHub:**
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Run included examples directly
|
|
34
|
+
npm run example:basic
|
|
35
|
+
npm run example:advanced
|
|
36
|
+
|
|
37
|
+
# Or use tsx directly
|
|
38
|
+
npx tsx examples/basic-usage.ts
|
|
39
|
+
npx tsx examples/advanced-features.ts
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**If you installed via npm:**
|
|
43
|
+
|
|
44
|
+
Examples are included in your `node_modules/@revenium/anthropic/examples/` directory:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx tsx node_modules/@revenium/anthropic/examples/basic-usage.ts
|
|
48
|
+
npx tsx node_modules/@revenium/anthropic/examples/advanced-features.ts
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Available Examples
|
|
52
|
+
|
|
53
|
+
### `basic-usage.ts` - Initialization Methods
|
|
54
|
+
|
|
55
|
+
Demonstrates the three ways to initialize the Revenium middleware:
|
|
56
|
+
|
|
57
|
+
- **Auto-initialization** (Recommended) - Import and go, uses environment variables
|
|
58
|
+
- **Explicit initialization** - Call `initialize()` for error handling control
|
|
59
|
+
- **Manual configuration** - Use `configure()` for custom settings
|
|
60
|
+
|
|
61
|
+
**Key Features:**
|
|
62
|
+
- TypeScript module augmentation for native `usageMetadata` support
|
|
63
|
+
- Full type safety with IntelliSense
|
|
64
|
+
- Interface validation using `satisfies` operator
|
|
65
|
+
- Comprehensive error handling patterns
|
|
66
|
+
|
|
67
|
+
**See the file for complete code examples.**
|
|
68
|
+
|
|
69
|
+
### `advanced-features.ts` - Streaming, Tools, and Manual Tracking
|
|
70
|
+
|
|
71
|
+
Demonstrates advanced Anthropic SDK features with automatic tracking:
|
|
72
|
+
|
|
73
|
+
- **Streaming responses** - Real-time response tracking with type safety
|
|
74
|
+
- **Tool use (function calling)** - Function calls with metadata tracking
|
|
75
|
+
- **Manual tracking** - Custom tracking for edge cases
|
|
76
|
+
- **Error handling** - Comprehensive error handling patterns
|
|
77
|
+
|
|
78
|
+
**Key Features:**
|
|
79
|
+
- Type-safe event handling and stream processing
|
|
80
|
+
- Advanced metadata patterns with interface extensions
|
|
81
|
+
- Generic functions with type constraints
|
|
82
|
+
- Custom logger integration
|
|
83
|
+
|
|
84
|
+
**See the file for complete code examples.**
|
|
85
|
+
|
|
86
|
+
## TypeScript Configuration
|
|
87
|
+
|
|
88
|
+
Ensure your `tsconfig.json` includes:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"compilerOptions": {
|
|
93
|
+
"target": "ES2020",
|
|
94
|
+
"module": "ESNext",
|
|
95
|
+
"moduleResolution": "node",
|
|
96
|
+
"esModuleInterop": true,
|
|
97
|
+
"allowSyntheticDefaultImports": true,
|
|
98
|
+
"strict": true,
|
|
99
|
+
"skipLibCheck": true
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Requirements
|
|
105
|
+
|
|
106
|
+
- **Node.js 16+** with TypeScript support
|
|
107
|
+
- **TypeScript 4.5+** for module augmentation features
|
|
108
|
+
- **Valid Revenium API key** (starts with `hak_`)
|
|
109
|
+
- **Valid Anthropic API key** (starts with `sk-ant-`)
|
|
110
|
+
|
|
111
|
+
## Troubleshooting
|
|
112
|
+
|
|
113
|
+
### Module Augmentation Not Working
|
|
114
|
+
|
|
115
|
+
**Problem:** TypeScript doesn't recognize `usageMetadata` in Anthropic SDK calls
|
|
116
|
+
|
|
117
|
+
**Solution:**
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// ❌ Wrong - missing module augmentation import
|
|
121
|
+
import { configure } from "@revenium/anthropic";
|
|
122
|
+
|
|
123
|
+
// ✅ Correct - import for module augmentation
|
|
124
|
+
import "@revenium/anthropic";
|
|
125
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Environment Variables Not Loading
|
|
129
|
+
|
|
130
|
+
**Problem:** `REVENIUM_METERING_API_KEY` or `ANTHROPIC_API_KEY` not found
|
|
131
|
+
|
|
132
|
+
**Solutions:**
|
|
133
|
+
- Ensure `.env` file is in project root
|
|
134
|
+
- Check variable names match exactly
|
|
135
|
+
- Verify you're importing `dotenv/config` before the middleware
|
|
136
|
+
- Check API keys have correct prefixes (`hak_` for Revenium, `sk-ant-` for Anthropic)
|
|
137
|
+
|
|
138
|
+
### TypeScript Compilation Errors
|
|
139
|
+
|
|
140
|
+
**Problem:** Module resolution or import errors
|
|
141
|
+
|
|
142
|
+
**Solution:** Verify your `tsconfig.json` settings:
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"compilerOptions": {
|
|
147
|
+
"moduleResolution": "node",
|
|
148
|
+
"esModuleInterop": true,
|
|
149
|
+
"allowSyntheticDefaultImports": true,
|
|
150
|
+
"strict": true
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### IntelliSense Not Working
|
|
156
|
+
|
|
157
|
+
**Solutions:**
|
|
158
|
+
1. Restart TypeScript language server in your IDE
|
|
159
|
+
2. Ensure `@revenium/anthropic` is imported at the top
|
|
160
|
+
3. Verify `@anthropic-ai/sdk` types are installed
|
|
161
|
+
4. Check TypeScript version is 4.5 or higher
|
|
162
|
+
|
|
163
|
+
### Debug Mode
|
|
164
|
+
|
|
165
|
+
Enable detailed logging to troubleshoot issues:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# In .env file
|
|
169
|
+
REVENIUM_DEBUG=true
|
|
170
|
+
|
|
171
|
+
# Then run examples
|
|
172
|
+
npm run example:basic
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Additional Resources
|
|
176
|
+
|
|
177
|
+
- **Main Documentation**: See root [README.md](https://github.com/revenium/revenium-middleware-anthropic-node/blob/HEAD/README.md)
|
|
178
|
+
- **API Reference**: Full TypeScript types and JSDoc in the package
|
|
179
|
+
- **Issues**: [Report bugs](https://github.com/revenium/revenium-middleware-anthropic-node/issues)
|
|
@@ -0,0 +1,501 @@
|
|
|
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 interface extensions
|
|
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
|
+
// 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
|
+
/**
|
|
52
|
+
* Streaming event types with full type safety
|
|
53
|
+
*/
|
|
54
|
+
type StreamEvent =
|
|
55
|
+
| { type: "start"; timestamp: Date; metadata: AdvancedUsageMetadata }
|
|
56
|
+
| { type: "content"; content: string; timestamp: Date }
|
|
57
|
+
| { type: "complete"; totalTokens: number; duration: number; timestamp: Date }
|
|
58
|
+
| { type: "error"; error: string; timestamp: Date };
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Custom logger implementation for advanced scenarios
|
|
62
|
+
*/
|
|
63
|
+
class AdvancedLogger implements Logger {
|
|
64
|
+
private context: Record<string, unknown> = {};
|
|
65
|
+
|
|
66
|
+
setContext(context: Record<string, unknown>): void {
|
|
67
|
+
this.context = { ...this.context, ...context };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
debug(message: string, data?: Record<string, unknown>): void {
|
|
71
|
+
console.log(`[DEBUG] ${message}`, { ...this.context, ...data });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
info(message: string, data?: Record<string, unknown>): void {
|
|
75
|
+
console.log(`[INFO] ${message}`, { ...this.context, ...data });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
warn(message: string, data?: Record<string, unknown>): void {
|
|
79
|
+
console.warn(`[WARN] ${message}`, { ...this.context, ...data });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
error(message: string, data?: Record<string, unknown>): void {
|
|
83
|
+
console.error(`[ERROR] ${message}`, { ...this.context, ...data });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function demonstrateAdvancedFeatures(): Promise<void> {
|
|
88
|
+
console.log("Revenium Anthropic Middleware - Advanced TypeScript Features\n");
|
|
89
|
+
|
|
90
|
+
// Initialize custom logger with type safety
|
|
91
|
+
const logger = new AdvancedLogger();
|
|
92
|
+
logger.setContext({
|
|
93
|
+
service: "advanced-features-demo",
|
|
94
|
+
version: "1.0.0",
|
|
95
|
+
environment: "development",
|
|
96
|
+
});
|
|
97
|
+
setLogger(logger);
|
|
98
|
+
|
|
99
|
+
const anthropic = new Anthropic();
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
// =============================================================================
|
|
103
|
+
// ADVANCED TYPESCRIPT PATTERNS WITH STREAMING
|
|
104
|
+
// =============================================================================
|
|
105
|
+
console.log("Advanced TypeScript Streaming Patterns");
|
|
106
|
+
console.log(
|
|
107
|
+
"Type-safe streaming with event handling and metadata validation\n"
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Example 1: Type-safe streaming with advanced metadata
|
|
111
|
+
console.log(
|
|
112
|
+
"Example 1: Creative writing with advanced metadata patterns..."
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// Create strongly typed metadata with satisfies operator
|
|
116
|
+
const advancedMetadata: AdvancedUsageMetadata = {
|
|
117
|
+
subscriber: {
|
|
118
|
+
id: "artist-456",
|
|
119
|
+
email: "artist@creative-studio.com",
|
|
120
|
+
credential: {
|
|
121
|
+
name: "creative-api-key",
|
|
122
|
+
value: "creative-key-789",
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
organizationId: "creative-ai-studio",
|
|
126
|
+
productId: "story-generator-pro",
|
|
127
|
+
taskType: "creative-writing",
|
|
128
|
+
agent: "storyteller-v2",
|
|
129
|
+
// Advanced metadata extensions
|
|
130
|
+
sessionId: `session_${Date.now()}`,
|
|
131
|
+
userRole: "user",
|
|
132
|
+
feature: "generation",
|
|
133
|
+
priority: "normal",
|
|
134
|
+
} satisfies AdvancedUsageMetadata;
|
|
135
|
+
|
|
136
|
+
// Type-safe streaming with event tracking
|
|
137
|
+
const streamEvents: StreamEvent[] = [];
|
|
138
|
+
const startTime = new Date();
|
|
139
|
+
|
|
140
|
+
streamEvents.push({
|
|
141
|
+
type: "start",
|
|
142
|
+
timestamp: startTime,
|
|
143
|
+
metadata: advancedMetadata,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const stream1 = await anthropic.messages.create({
|
|
147
|
+
model: "claude-3-5-sonnet-latest",
|
|
148
|
+
max_tokens: 150,
|
|
149
|
+
messages: [
|
|
150
|
+
{
|
|
151
|
+
role: "user",
|
|
152
|
+
content: "Write a short story about a robot learning to paint.",
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
stream: true,
|
|
156
|
+
usageMetadata: advancedMetadata, // Fully typed with module augmentation
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
console.log("Streaming response:");
|
|
160
|
+
let content1 = "";
|
|
161
|
+
let tokenCount = 0;
|
|
162
|
+
|
|
163
|
+
for await (const event of stream1) {
|
|
164
|
+
if (
|
|
165
|
+
event.type === "content_block_delta" &&
|
|
166
|
+
event.delta.type === "text_delta"
|
|
167
|
+
) {
|
|
168
|
+
process.stdout.write(event.delta.text);
|
|
169
|
+
content1 += event.delta.text;
|
|
170
|
+
tokenCount++;
|
|
171
|
+
|
|
172
|
+
// Add streaming event with type safety
|
|
173
|
+
streamEvents.push({
|
|
174
|
+
type: "content",
|
|
175
|
+
content: event.delta.text,
|
|
176
|
+
timestamp: new Date(),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Complete streaming event tracking
|
|
182
|
+
const endTime = new Date();
|
|
183
|
+
streamEvents.push({
|
|
184
|
+
type: "complete",
|
|
185
|
+
totalTokens: tokenCount,
|
|
186
|
+
duration: endTime.getTime() - startTime.getTime(),
|
|
187
|
+
timestamp: endTime,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
if (!content1.trim()) throw new Error("No content received from stream");
|
|
191
|
+
console.log("\nStream 1 completed with type-safe event tracking");
|
|
192
|
+
console.log(
|
|
193
|
+
`Events captured: ${streamEvents.length}, Duration: ${
|
|
194
|
+
endTime.getTime() - startTime.getTime()
|
|
195
|
+
}ms\n`
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
// =============================================================================
|
|
199
|
+
// ADVANCED MANUAL TRACKING WITH TYPE SAFETY
|
|
200
|
+
// =============================================================================
|
|
201
|
+
console.log("Advanced Manual Tracking with TypeScript");
|
|
202
|
+
console.log(
|
|
203
|
+
"Demonstrating manual tracking with full type safety and validation\n"
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
// Example 2: Manual tracking with type-safe data
|
|
207
|
+
console.log("Example 2: Manual tracking with custom metrics...");
|
|
208
|
+
|
|
209
|
+
const now = new Date();
|
|
210
|
+
const trackingData: TrackingData = {
|
|
211
|
+
requestId: `manual_${Date.now()}`,
|
|
212
|
+
model: "claude-3-5-sonnet-latest",
|
|
213
|
+
inputTokens: 25,
|
|
214
|
+
outputTokens: 150,
|
|
215
|
+
duration: 2500,
|
|
216
|
+
isStreamed: false,
|
|
217
|
+
requestTime: new Date(now.getTime() - 2500), // 2.5 seconds ago
|
|
218
|
+
responseTime: now,
|
|
219
|
+
metadata: {
|
|
220
|
+
subscriber: { id: "manual-user-123" },
|
|
221
|
+
organizationId: "manual-tracking-org",
|
|
222
|
+
productId: "custom-analytics",
|
|
223
|
+
taskType: "manual-analysis",
|
|
224
|
+
} satisfies UsageMetadata,
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// Type-safe manual tracking
|
|
228
|
+
try {
|
|
229
|
+
trackUsageAsync(trackingData); // Note: this function is synchronous
|
|
230
|
+
console.log("Manual tracking completed successfully");
|
|
231
|
+
console.log(
|
|
232
|
+
`Tracked: ${
|
|
233
|
+
trackingData.inputTokens + trackingData.outputTokens
|
|
234
|
+
} tokens, ${trackingData.duration}ms duration\n`
|
|
235
|
+
);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
const errorMessage =
|
|
238
|
+
error instanceof Error ? error.message : String(error);
|
|
239
|
+
console.log(`Manual tracking failed: ${errorMessage}\n`);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// =============================================================================
|
|
243
|
+
// SERVICE STATUS WITH TYPE SAFETY
|
|
244
|
+
// =============================================================================
|
|
245
|
+
console.log("Service Status and Health Check");
|
|
246
|
+
console.log("Type-safe middleware status monitoring\n");
|
|
247
|
+
|
|
248
|
+
const status: MiddlewareStatus = getStatus();
|
|
249
|
+
console.log("Middleware Status:", {
|
|
250
|
+
initialized: status.initialized,
|
|
251
|
+
patched: status.patched,
|
|
252
|
+
hasConfig: status.hasConfig,
|
|
253
|
+
configValid: status.initialized && status.patched && status.hasConfig,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// Example 3: Educational content with different metadata pattern
|
|
257
|
+
console.log(
|
|
258
|
+
"\nExample 3: Educational content with different metadata pattern..."
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
const educationalMetadata: AdvancedUsageMetadata = {
|
|
262
|
+
subscriber: { id: "student-789" },
|
|
263
|
+
organizationId: "green-tech-edu",
|
|
264
|
+
productId: "sustainability-tutor",
|
|
265
|
+
taskType: "educational-query",
|
|
266
|
+
sessionId: `edu_session_${Date.now()}`,
|
|
267
|
+
userRole: "guest",
|
|
268
|
+
feature: "analysis",
|
|
269
|
+
priority: "low",
|
|
270
|
+
} satisfies AdvancedUsageMetadata;
|
|
271
|
+
|
|
272
|
+
const stream2 = await anthropic.messages.create({
|
|
273
|
+
model: "claude-3-5-sonnet-latest",
|
|
274
|
+
max_tokens: 100,
|
|
275
|
+
messages: [
|
|
276
|
+
{
|
|
277
|
+
role: "user",
|
|
278
|
+
content: "Explain three benefits of renewable energy.",
|
|
279
|
+
},
|
|
280
|
+
],
|
|
281
|
+
stream: true,
|
|
282
|
+
usageMetadata: educationalMetadata, // Fully typed
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
console.log("Educational response:");
|
|
286
|
+
let content2 = "";
|
|
287
|
+
for await (const event of stream2) {
|
|
288
|
+
if (
|
|
289
|
+
event.type === "content_block_delta" &&
|
|
290
|
+
event.delta.type === "text_delta"
|
|
291
|
+
) {
|
|
292
|
+
process.stdout.write(event.delta.text);
|
|
293
|
+
content2 += event.delta.text;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (!content2.trim()) throw new Error("No content received from stream");
|
|
298
|
+
console.log("\nStream 2 completed with educational metadata pattern\n");
|
|
299
|
+
|
|
300
|
+
// =============================================================================
|
|
301
|
+
// ADVANCED TOOL USE WITH TYPESCRIPT PATTERNS
|
|
302
|
+
// =============================================================================
|
|
303
|
+
console.log("Advanced Tool Use with TypeScript Patterns");
|
|
304
|
+
console.log(
|
|
305
|
+
"Tool usage with strongly typed metadata and comprehensive tracking\n"
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
console.log("Example 4: Weather tool with advanced TypeScript patterns...");
|
|
309
|
+
|
|
310
|
+
// Create tool-specific metadata with type safety
|
|
311
|
+
const toolMetadata: AdvancedUsageMetadata = {
|
|
312
|
+
subscriber: {
|
|
313
|
+
id: "weather-user-456",
|
|
314
|
+
email: "user@weather-app.com",
|
|
315
|
+
},
|
|
316
|
+
organizationId: "weather-services-inc",
|
|
317
|
+
productId: "smart-weather-assistant",
|
|
318
|
+
taskType: "tool-usage",
|
|
319
|
+
agent: "weather-bot-v3",
|
|
320
|
+
sessionId: `weather_${Date.now()}`,
|
|
321
|
+
userRole: "user",
|
|
322
|
+
feature: "chat",
|
|
323
|
+
priority: "normal",
|
|
324
|
+
} satisfies AdvancedUsageMetadata;
|
|
325
|
+
|
|
326
|
+
const toolStream = await anthropic.messages.create({
|
|
327
|
+
model: "claude-3-5-sonnet-latest",
|
|
328
|
+
max_tokens: 200,
|
|
329
|
+
tools: [
|
|
330
|
+
{
|
|
331
|
+
name: "get_weather",
|
|
332
|
+
description: "Get current weather for a location",
|
|
333
|
+
input_schema: {
|
|
334
|
+
type: "object",
|
|
335
|
+
properties: {
|
|
336
|
+
location: {
|
|
337
|
+
type: "string",
|
|
338
|
+
description: "City and state, e.g. San Francisco, CA",
|
|
339
|
+
},
|
|
340
|
+
units: {
|
|
341
|
+
type: "string",
|
|
342
|
+
enum: ["celsius", "fahrenheit"],
|
|
343
|
+
description: "Temperature units",
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
required: ["location"],
|
|
347
|
+
},
|
|
348
|
+
},
|
|
349
|
+
],
|
|
350
|
+
messages: [
|
|
351
|
+
{
|
|
352
|
+
role: "user",
|
|
353
|
+
content: "What's the weather like in New York? Use the weather tool.",
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
stream: true,
|
|
357
|
+
usageMetadata: toolMetadata, // Using strongly typed metadata
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
console.log("Tool use streaming response:");
|
|
361
|
+
let toolContent = "";
|
|
362
|
+
for await (const event of toolStream) {
|
|
363
|
+
if (
|
|
364
|
+
event.type === "content_block_delta" &&
|
|
365
|
+
event.delta.type === "text_delta"
|
|
366
|
+
) {
|
|
367
|
+
process.stdout.write(event.delta.text);
|
|
368
|
+
toolContent += event.delta.text;
|
|
369
|
+
} else if (
|
|
370
|
+
event.type === "content_block_start" &&
|
|
371
|
+
event.content_block.type === "tool_use"
|
|
372
|
+
) {
|
|
373
|
+
console.log(`\nTool called: ${event.content_block.name}`);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (!toolContent.trim())
|
|
378
|
+
throw new Error("No content received from tool stream");
|
|
379
|
+
console.log(
|
|
380
|
+
"\nTool streaming completed with advanced TypeScript patterns\n"
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
// =============================================================================
|
|
384
|
+
// SUMMARY AND TYPESCRIPT BENEFITS
|
|
385
|
+
// =============================================================================
|
|
386
|
+
console.log("Advanced TypeScript Features Summary");
|
|
387
|
+
console.log("All examples completed successfully with full type safety!\n");
|
|
388
|
+
|
|
389
|
+
console.log("TypeScript Benefits Demonstrated:");
|
|
390
|
+
console.log(" • Module augmentation for native usageMetadata support");
|
|
391
|
+
console.log(" • Type-safe metadata with satisfies operator");
|
|
392
|
+
console.log(" • Strongly typed event handling and streaming");
|
|
393
|
+
console.log(" • Custom logger implementation with typed interfaces");
|
|
394
|
+
console.log(" • Advanced metadata patterns with interface extensions");
|
|
395
|
+
console.log(" • Comprehensive error handling with typed responses");
|
|
396
|
+
console.log(" • Generic functions with type constraints");
|
|
397
|
+
console.log(" • Full IntelliSense support throughout\n");
|
|
398
|
+
|
|
399
|
+
console.log("Middleware Status Summary:");
|
|
400
|
+
const finalStatus = getStatus();
|
|
401
|
+
console.log(` • Initialized: ${finalStatus.initialized}`);
|
|
402
|
+
console.log(` • Patched: ${finalStatus.patched}`);
|
|
403
|
+
console.log(` • Has Config: ${finalStatus.hasConfig}`);
|
|
404
|
+
console.log(
|
|
405
|
+
` • All Systems: ${
|
|
406
|
+
finalStatus.initialized && finalStatus.patched && finalStatus.hasConfig
|
|
407
|
+
? "Operational"
|
|
408
|
+
: "Check Configuration"
|
|
409
|
+
}\n`
|
|
410
|
+
);
|
|
411
|
+
|
|
412
|
+
console.log("Next Steps:");
|
|
413
|
+
console.log(" • Review comprehensive JSDoc in your IDE");
|
|
414
|
+
console.log(
|
|
415
|
+
" • Check the TypeScript-first examples/README.md for more patterns"
|
|
416
|
+
);
|
|
417
|
+
console.log(
|
|
418
|
+
" • Implement custom metadata extensions for your use case\n"
|
|
419
|
+
);
|
|
420
|
+
} catch (error) {
|
|
421
|
+
// Comprehensive TypeScript error handling
|
|
422
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
423
|
+
console.error("Advanced TypeScript features demo failed:", errorMessage);
|
|
424
|
+
|
|
425
|
+
// Type-safe error analysis
|
|
426
|
+
if (error && typeof error === "object" && "status" in error) {
|
|
427
|
+
const httpError = error as { status: number; message?: string };
|
|
428
|
+
if (httpError.status >= 400) {
|
|
429
|
+
console.error(
|
|
430
|
+
`HTTP ${httpError.status} Error - API connectivity issue`
|
|
431
|
+
);
|
|
432
|
+
console.error("Check your API keys and network connectivity");
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Log final status even on error
|
|
437
|
+
const errorStatus = getStatus();
|
|
438
|
+
console.error("Final Middleware Status:", {
|
|
439
|
+
initialized: errorStatus.initialized,
|
|
440
|
+
patched: errorStatus.patched,
|
|
441
|
+
hasConfig: errorStatus.hasConfig,
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
throw error;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Type-safe environment validation
|
|
450
|
+
*/
|
|
451
|
+
function checkEnvironment(): void {
|
|
452
|
+
const required = ["REVENIUM_METERING_API_KEY", "ANTHROPIC_API_KEY"];
|
|
453
|
+
const missing = required.filter((key) => !process.env[key]);
|
|
454
|
+
|
|
455
|
+
if (missing.length > 0) {
|
|
456
|
+
console.error(
|
|
457
|
+
"Missing required environment variables for advanced TypeScript features:"
|
|
458
|
+
);
|
|
459
|
+
missing.forEach((key) => console.error(` • ${key}`));
|
|
460
|
+
console.error("\nSet them in a .env file in the project root:");
|
|
461
|
+
console.error(" REVENIUM_METERING_API_KEY=hak_your_api_key");
|
|
462
|
+
console.error(" ANTHROPIC_API_KEY=sk-ant-your_anthropic_key");
|
|
463
|
+
console.error("\nOptional (uses defaults if not set):");
|
|
464
|
+
console.error(
|
|
465
|
+
" REVENIUM_METERING_BASE_URL=https://api.revenium.io/meter/v2"
|
|
466
|
+
);
|
|
467
|
+
console.error(" REVENIUM_DEBUG=true # For detailed logging");
|
|
468
|
+
process.exit(1);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Run the TypeScript demonstration
|
|
473
|
+
if (require.main === module) {
|
|
474
|
+
checkEnvironment();
|
|
475
|
+
|
|
476
|
+
demonstrateAdvancedFeatures()
|
|
477
|
+
.then(() => {
|
|
478
|
+
console.log(
|
|
479
|
+
"\nAdvanced TypeScript Features Demo Completed Successfully!"
|
|
480
|
+
);
|
|
481
|
+
console.log("\nTypeScript Features Demonstrated:");
|
|
482
|
+
console.log(" • Type-safe streaming with event handling");
|
|
483
|
+
console.log(" • Advanced metadata patterns with interface extensions");
|
|
484
|
+
console.log(" • Custom logger implementation with typed interfaces");
|
|
485
|
+
console.log(" • Manual tracking with full type safety");
|
|
486
|
+
console.log(" • Comprehensive error handling with typed responses");
|
|
487
|
+
console.log(" • Module augmentation for native usageMetadata support");
|
|
488
|
+
console.log(" • Generic functions with type constraints");
|
|
489
|
+
console.log(" • Full IntelliSense support throughout");
|
|
490
|
+
console.log(
|
|
491
|
+
"\nNext: Check examples/README.md for more TypeScript patterns!"
|
|
492
|
+
);
|
|
493
|
+
console.log(
|
|
494
|
+
"\nTip: Set REVENIUM_DEBUG=true in .env file for detailed tracking logs"
|
|
495
|
+
);
|
|
496
|
+
})
|
|
497
|
+
.catch((error) => {
|
|
498
|
+
console.error("\nAdvanced TypeScript features demo failed:", error);
|
|
499
|
+
process.exit(1);
|
|
500
|
+
});
|
|
501
|
+
}
|