@bernierllc/anthropic-client 1.0.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/README.md +283 -0
- package/dist/AnthropicClient.d.ts +17 -0
- package/dist/AnthropicClient.d.ts.map +1 -0
- package/dist/AnthropicClient.js +288 -0
- package/dist/AnthropicClient.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# @bernierllc/anthropic-client
|
|
2
|
+
|
|
3
|
+
Type-safe Anthropic Claude API client with automatic rate limiting, retry logic, streaming support, and cost tracking.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @bernierllc/anthropic-client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Type-safe API**: Full TypeScript support with strict typing
|
|
14
|
+
- **Multiple Claude Models**: Support for Claude 3 Opus, Sonnet, Haiku, and Sonnet 3.5
|
|
15
|
+
- **Streaming Support**: Real-time streaming responses with chunk callbacks
|
|
16
|
+
- **Rate Limiting**: Built-in rate limiting to respect API quotas
|
|
17
|
+
- **Automatic Retries**: Exponential backoff retry logic for failed requests
|
|
18
|
+
- **Cost Tracking**: Automatic tracking of token usage and costs
|
|
19
|
+
- **Comprehensive Logging**: Integration with @bernierllc/logger
|
|
20
|
+
- **Error Handling**: Structured error responses for robust error handling
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
### Basic Completion
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { AnthropicClient, ClaudeModel } from '@bernierllc/anthropic-client';
|
|
28
|
+
|
|
29
|
+
const client = new AnthropicClient({
|
|
30
|
+
apiKey: process.env.ANTHROPIC_API_KEY!
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const result = await client.complete('Explain quantum computing in simple terms', {
|
|
34
|
+
model: ClaudeModel.SONNET,
|
|
35
|
+
maxTokens: 1024,
|
|
36
|
+
temperature: 0.7
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (result.success) {
|
|
40
|
+
console.log('Response:', result.content);
|
|
41
|
+
console.log('Tokens used:', result.usage?.totalTokens);
|
|
42
|
+
console.log('Cost:', `$${result.cost?.totalCost.toFixed(6)}`);
|
|
43
|
+
} else {
|
|
44
|
+
console.error('Error:', result.error);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Streaming Response
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
const result = await client.stream(
|
|
52
|
+
'Write a short story about space exploration',
|
|
53
|
+
(chunk) => {
|
|
54
|
+
// Process each chunk as it arrives
|
|
55
|
+
process.stdout.write(chunk);
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
model: ClaudeModel.OPUS,
|
|
59
|
+
maxTokens: 2000
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
console.log('\n\nTotal tokens:', result.usage?.totalTokens);
|
|
64
|
+
console.log('Total cost:', `$${result.cost?.totalCost.toFixed(6)}`);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Custom Configuration
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
const client = new AnthropicClient({
|
|
71
|
+
apiKey: process.env.ANTHROPIC_API_KEY!,
|
|
72
|
+
defaultModel: ClaudeModel.HAIKU,
|
|
73
|
+
maxRetries: 5,
|
|
74
|
+
rateLimit: {
|
|
75
|
+
requestsPerMinute: 100,
|
|
76
|
+
tokensPerMinute: 50000
|
|
77
|
+
},
|
|
78
|
+
enableLogging: true
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Disable Rate Limiting
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
const client = new AnthropicClient({
|
|
86
|
+
apiKey: process.env.ANTHROPIC_API_KEY!,
|
|
87
|
+
rateLimit: null // Disable rate limiting
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Usage Tracking
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// Make multiple requests
|
|
95
|
+
await client.complete('First request');
|
|
96
|
+
await client.complete('Second request');
|
|
97
|
+
await client.complete('Third request');
|
|
98
|
+
|
|
99
|
+
// Get aggregated usage statistics
|
|
100
|
+
const usage = client.getUsage();
|
|
101
|
+
console.log('Total requests:', usage.totalRequests);
|
|
102
|
+
console.log('Total tokens:', usage.totalTokens);
|
|
103
|
+
console.log('Total cost:', `$${usage.totalCost.toFixed(6)}`);
|
|
104
|
+
console.log('Requests by model:', usage.requestsByModel);
|
|
105
|
+
|
|
106
|
+
// Reset usage statistics
|
|
107
|
+
client.resetUsage();
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Rate Limit Status
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const status = client.getRateLimitStatus();
|
|
114
|
+
|
|
115
|
+
if (status) {
|
|
116
|
+
console.log('Requests remaining:', status.requestsRemaining);
|
|
117
|
+
console.log('Reset time:', status.resetTime);
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## API Reference
|
|
122
|
+
|
|
123
|
+
### AnthropicClient
|
|
124
|
+
|
|
125
|
+
#### Constructor
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
new AnthropicClient(config: AnthropicClientConfig)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Config Options:**
|
|
132
|
+
|
|
133
|
+
- `apiKey` (string, required): Your Anthropic API key
|
|
134
|
+
- `defaultModel` (ClaudeModel, optional): Default model to use (default: `ClaudeModel.SONNET`)
|
|
135
|
+
- `maxRetries` (number, optional): Maximum number of retry attempts (default: 3)
|
|
136
|
+
- `rateLimit` (object | null, optional): Rate limiting configuration or null to disable (default: 50 requests/minute)
|
|
137
|
+
- `requestsPerMinute` (number): Maximum requests per minute
|
|
138
|
+
- `tokensPerMinute` (number): Maximum tokens per minute (not enforced by current rate limiter)
|
|
139
|
+
- `enableLogging` (boolean, optional): Enable detailed logging (default: true)
|
|
140
|
+
|
|
141
|
+
#### Methods
|
|
142
|
+
|
|
143
|
+
##### complete(prompt: string, options?: CompletionOptions): Promise<CompletionResult>
|
|
144
|
+
|
|
145
|
+
Send a completion request to Claude.
|
|
146
|
+
|
|
147
|
+
**Options:**
|
|
148
|
+
|
|
149
|
+
- `model` (ClaudeModel): Model to use for this request
|
|
150
|
+
- `maxTokens` (number): Maximum tokens to generate (default: 1024)
|
|
151
|
+
- `temperature` (number): Sampling temperature (0-1)
|
|
152
|
+
- `topP` (number): Nucleus sampling parameter
|
|
153
|
+
- `topK` (number): Top-k sampling parameter
|
|
154
|
+
- `stopSequences` (string[]): Sequences that stop generation
|
|
155
|
+
- `systemPrompt` (string): System prompt to use
|
|
156
|
+
- `metadata` (Record<string, unknown>): Additional metadata
|
|
157
|
+
|
|
158
|
+
**Returns:** `CompletionResult` object with:
|
|
159
|
+
|
|
160
|
+
- `success` (boolean): Whether the request succeeded
|
|
161
|
+
- `content` (string | undefined): Generated text
|
|
162
|
+
- `usage` (object | undefined): Token usage information
|
|
163
|
+
- `cost` (object | undefined): Cost breakdown
|
|
164
|
+
- `model` (string | undefined): Model used
|
|
165
|
+
- `stopReason` (string | undefined): Why generation stopped
|
|
166
|
+
- `error` (string | undefined): Error message if failed
|
|
167
|
+
|
|
168
|
+
##### stream(prompt: string, onChunk: StreamChunkCallback, options?: CompletionOptions): Promise<CompletionResult>
|
|
169
|
+
|
|
170
|
+
Stream a completion response from Claude.
|
|
171
|
+
|
|
172
|
+
**Parameters:**
|
|
173
|
+
|
|
174
|
+
- `prompt` (string): The prompt to send
|
|
175
|
+
- `onChunk` (function): Callback function called for each text chunk
|
|
176
|
+
- `options` (CompletionOptions): Same options as `complete()`
|
|
177
|
+
|
|
178
|
+
**Returns:** `CompletionResult` with the complete response
|
|
179
|
+
|
|
180
|
+
##### getUsage(): UsageStats
|
|
181
|
+
|
|
182
|
+
Get cumulative usage statistics.
|
|
183
|
+
|
|
184
|
+
**Returns:**
|
|
185
|
+
|
|
186
|
+
- `totalRequests` (number): Total number of requests made
|
|
187
|
+
- `totalInputTokens` (number): Total input tokens used
|
|
188
|
+
- `totalOutputTokens` (number): Total output tokens generated
|
|
189
|
+
- `totalTokens` (number): Total tokens (input + output)
|
|
190
|
+
- `totalCost` (number): Total cost in USD
|
|
191
|
+
- `requestsByModel` (Record<string, number>): Request count by model
|
|
192
|
+
|
|
193
|
+
##### resetUsage(): void
|
|
194
|
+
|
|
195
|
+
Reset all usage statistics to zero.
|
|
196
|
+
|
|
197
|
+
##### getRateLimitStatus(): RateLimitStatus | null
|
|
198
|
+
|
|
199
|
+
Get current rate limit status.
|
|
200
|
+
|
|
201
|
+
**Returns:**
|
|
202
|
+
|
|
203
|
+
- `requestsRemaining` (number): Requests remaining in current window
|
|
204
|
+
- `tokensRemaining` (number): Tokens remaining (not implemented)
|
|
205
|
+
- `resetTime` (Date): When the rate limit window resets
|
|
206
|
+
|
|
207
|
+
Returns `null` if rate limiting is disabled.
|
|
208
|
+
|
|
209
|
+
## Claude Models
|
|
210
|
+
|
|
211
|
+
The following models are supported:
|
|
212
|
+
|
|
213
|
+
- `ClaudeModel.OPUS` - claude-3-opus-20240229 (most capable, highest cost)
|
|
214
|
+
- `ClaudeModel.SONNET` - claude-3-sonnet-20240229 (balanced performance and cost)
|
|
215
|
+
- `ClaudeModel.SONNET_3_5` - claude-3-5-sonnet-20241022 (latest Sonnet version)
|
|
216
|
+
- `ClaudeModel.HAIKU` - claude-3-haiku-20240307 (fastest, lowest cost)
|
|
217
|
+
|
|
218
|
+
## Cost Tracking
|
|
219
|
+
|
|
220
|
+
The client automatically tracks costs based on current Anthropic pricing:
|
|
221
|
+
|
|
222
|
+
| Model | Input Cost (per 1M tokens) | Output Cost (per 1M tokens) |
|
|
223
|
+
|-------|---------------------------|------------------------------|
|
|
224
|
+
| Opus | $15.00 | $75.00 |
|
|
225
|
+
| Sonnet | $3.00 | $15.00 |
|
|
226
|
+
| Sonnet 3.5 | $3.00 | $15.00 |
|
|
227
|
+
| Haiku | $0.25 | $1.25 |
|
|
228
|
+
|
|
229
|
+
## Error Handling
|
|
230
|
+
|
|
231
|
+
The client uses structured error responses:
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
const result = await client.complete('test prompt');
|
|
235
|
+
|
|
236
|
+
if (!result.success) {
|
|
237
|
+
console.error('Request failed:', result.error);
|
|
238
|
+
// Handle error appropriately
|
|
239
|
+
} else {
|
|
240
|
+
// Process successful response
|
|
241
|
+
console.log(result.content);
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Integration
|
|
246
|
+
|
|
247
|
+
- **Logger**: Integrated with @bernierllc/logger for structured logging
|
|
248
|
+
- **Retry Policy**: Uses @bernierllc/retry-policy for exponential backoff
|
|
249
|
+
- **Docs-Suite**: Ready - Full TypeDoc documentation available
|
|
250
|
+
- **NeverHub**: Optional - Can emit AI usage events when integrated
|
|
251
|
+
|
|
252
|
+
## Development
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# Install dependencies
|
|
256
|
+
npm install
|
|
257
|
+
|
|
258
|
+
# Run tests
|
|
259
|
+
npm test
|
|
260
|
+
|
|
261
|
+
# Run tests with coverage
|
|
262
|
+
npm run test:coverage
|
|
263
|
+
|
|
264
|
+
# Build
|
|
265
|
+
npm run build
|
|
266
|
+
|
|
267
|
+
# Lint
|
|
268
|
+
npm run lint
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
Copyright (c) 2025 Bernier LLC
|
|
274
|
+
|
|
275
|
+
This file is licensed to the client under a limited-use license.
|
|
276
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
277
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
278
|
+
|
|
279
|
+
## See Also
|
|
280
|
+
|
|
281
|
+
- [@bernierllc/logger](../logger) - Structured logging
|
|
282
|
+
- [@bernierllc/retry-policy](../retry-policy) - Retry logic with exponential backoff
|
|
283
|
+
- [Anthropic API Documentation](https://docs.anthropic.com/) - Official API documentation
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AnthropicClientConfig, CompletionOptions, CompletionResult, StreamChunkCallback, UsageStats, RateLimitStatus } from './types';
|
|
2
|
+
export declare class AnthropicClient {
|
|
3
|
+
private client;
|
|
4
|
+
private logger;
|
|
5
|
+
private rateLimiter;
|
|
6
|
+
private config;
|
|
7
|
+
private stats;
|
|
8
|
+
constructor(config: AnthropicClientConfig);
|
|
9
|
+
complete(prompt: string, options?: CompletionOptions): Promise<CompletionResult>;
|
|
10
|
+
stream(prompt: string, onChunk: StreamChunkCallback, options?: CompletionOptions): Promise<CompletionResult>;
|
|
11
|
+
getUsage(): UsageStats;
|
|
12
|
+
getRateLimitStatus(): RateLimitStatus | null;
|
|
13
|
+
resetUsage(): void;
|
|
14
|
+
private updateStats;
|
|
15
|
+
private sleep;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=AnthropicClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnthropicClient.d.ts","sourceRoot":"","sources":["../src/AnthropicClient.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EACV,eAAe,EAGhB,MAAM,SAAS,CAAC;AA2CjB,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,KAAK,CAOX;gBAEU,MAAM,EAAE,qBAAqB;IA0CnC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAiHpF,MAAM,CACV,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,mBAAmB,EAC5B,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC;IA0F5B,QAAQ,IAAI,UAAU;IAOtB,kBAAkB,IAAI,eAAe,GAAG,IAAI;IAkB5C,UAAU,IAAI,IAAI;IAYlB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,KAAK;CAGd"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AnthropicClient = void 0;
|
|
7
|
+
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
8
|
+
const logger_1 = require("@bernierllc/logger");
|
|
9
|
+
const retry_policy_1 = require("@bernierllc/retry-policy");
|
|
10
|
+
const types_1 = require("./types");
|
|
11
|
+
class SimpleRateLimiter {
|
|
12
|
+
constructor(maxRequests, windowMs) {
|
|
13
|
+
this.maxRequests = maxRequests;
|
|
14
|
+
this.windowMs = windowMs;
|
|
15
|
+
this.requests = [];
|
|
16
|
+
}
|
|
17
|
+
tryAcquire() {
|
|
18
|
+
const now = Date.now();
|
|
19
|
+
this.requests = this.requests.filter(time => now - time < this.windowMs);
|
|
20
|
+
if (this.requests.length < this.maxRequests) {
|
|
21
|
+
this.requests.push(now);
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
getWaitTime() {
|
|
27
|
+
if (this.requests.length === 0)
|
|
28
|
+
return 0;
|
|
29
|
+
const oldestRequest = Math.min(...this.requests);
|
|
30
|
+
const waitTime = this.windowMs - (Date.now() - oldestRequest);
|
|
31
|
+
return Math.max(0, waitTime);
|
|
32
|
+
}
|
|
33
|
+
getRemainingRequests() {
|
|
34
|
+
const now = Date.now();
|
|
35
|
+
this.requests = this.requests.filter(time => now - time < this.windowMs);
|
|
36
|
+
return Math.max(0, this.maxRequests - this.requests.length);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
class AnthropicClient {
|
|
40
|
+
constructor(config) {
|
|
41
|
+
this.rateLimiter = null;
|
|
42
|
+
this.stats = {
|
|
43
|
+
totalRequests: 0,
|
|
44
|
+
totalInputTokens: 0,
|
|
45
|
+
totalOutputTokens: 0,
|
|
46
|
+
totalTokens: 0,
|
|
47
|
+
totalCost: 0,
|
|
48
|
+
requestsByModel: {}
|
|
49
|
+
};
|
|
50
|
+
if (!config.apiKey) {
|
|
51
|
+
throw new Error('API key is required');
|
|
52
|
+
}
|
|
53
|
+
this.config = {
|
|
54
|
+
apiKey: config.apiKey,
|
|
55
|
+
maxRetries: config.maxRetries ?? 3,
|
|
56
|
+
rateLimit: config.rateLimit === null ? null : (config.rateLimit ?? {
|
|
57
|
+
requestsPerMinute: 50,
|
|
58
|
+
tokensPerMinute: 40000
|
|
59
|
+
}),
|
|
60
|
+
defaultModel: config.defaultModel ?? types_1.ClaudeModel.SONNET,
|
|
61
|
+
enableLogging: config.enableLogging ?? true
|
|
62
|
+
};
|
|
63
|
+
this.client = new sdk_1.default({ apiKey: this.config.apiKey });
|
|
64
|
+
this.logger = new logger_1.Logger({
|
|
65
|
+
level: this.config.enableLogging ? logger_1.LogLevel.INFO : logger_1.LogLevel.ERROR,
|
|
66
|
+
transports: [
|
|
67
|
+
new logger_1.ConsoleTransport({
|
|
68
|
+
level: this.config.enableLogging ? logger_1.LogLevel.INFO : logger_1.LogLevel.ERROR
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
});
|
|
72
|
+
if (this.config.rateLimit) {
|
|
73
|
+
this.rateLimiter = new SimpleRateLimiter(this.config.rateLimit.requestsPerMinute, 60000);
|
|
74
|
+
}
|
|
75
|
+
this.logger.info('AnthropicClient initialized', {
|
|
76
|
+
model: this.config.defaultModel,
|
|
77
|
+
rateLimit: this.config.rateLimit
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
async complete(prompt, options = {}) {
|
|
81
|
+
const model = options.model ?? this.config.defaultModel;
|
|
82
|
+
const maxTokens = options.maxTokens ?? 1024;
|
|
83
|
+
this.logger.debug('Starting completion request', { model, promptLength: prompt.length });
|
|
84
|
+
let attempt = 0;
|
|
85
|
+
let lastError = null;
|
|
86
|
+
while (attempt < this.config.maxRetries) {
|
|
87
|
+
try {
|
|
88
|
+
if (this.rateLimiter && !this.rateLimiter.tryAcquire()) {
|
|
89
|
+
const waitTime = this.rateLimiter.getWaitTime();
|
|
90
|
+
this.logger.warn('Rate limit reached, waiting', { waitTime });
|
|
91
|
+
await this.sleep(waitTime);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const response = await this.client.messages.create({
|
|
95
|
+
model,
|
|
96
|
+
max_tokens: maxTokens,
|
|
97
|
+
messages: [{ role: 'user', content: prompt }],
|
|
98
|
+
system: options.systemPrompt,
|
|
99
|
+
temperature: options.temperature,
|
|
100
|
+
top_p: options.topP,
|
|
101
|
+
top_k: options.topK,
|
|
102
|
+
stop_sequences: options.stopSequences,
|
|
103
|
+
metadata: options.metadata
|
|
104
|
+
});
|
|
105
|
+
const content = response.content
|
|
106
|
+
.filter((block) => block.type === 'text')
|
|
107
|
+
.map((block) => ('text' in block ? block.text : ''))
|
|
108
|
+
.join('');
|
|
109
|
+
const inputTokens = response.usage.input_tokens;
|
|
110
|
+
const outputTokens = response.usage.output_tokens;
|
|
111
|
+
const totalTokens = inputTokens + outputTokens;
|
|
112
|
+
const pricing = types_1.MODEL_PRICING[model];
|
|
113
|
+
const inputCost = (inputTokens / 1000000) * pricing.input;
|
|
114
|
+
const outputCost = (outputTokens / 1000000) * pricing.output;
|
|
115
|
+
const totalCost = inputCost + outputCost;
|
|
116
|
+
this.updateStats(model, inputTokens, outputTokens, totalCost);
|
|
117
|
+
this.logger.info('Completion successful', {
|
|
118
|
+
model,
|
|
119
|
+
inputTokens,
|
|
120
|
+
outputTokens,
|
|
121
|
+
totalCost: totalCost.toFixed(6)
|
|
122
|
+
});
|
|
123
|
+
return {
|
|
124
|
+
success: true,
|
|
125
|
+
content,
|
|
126
|
+
usage: {
|
|
127
|
+
inputTokens,
|
|
128
|
+
outputTokens,
|
|
129
|
+
totalTokens
|
|
130
|
+
},
|
|
131
|
+
cost: {
|
|
132
|
+
inputCost,
|
|
133
|
+
outputCost,
|
|
134
|
+
totalCost
|
|
135
|
+
},
|
|
136
|
+
model,
|
|
137
|
+
stopReason: response.stop_reason || undefined
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
lastError = error;
|
|
142
|
+
attempt++;
|
|
143
|
+
if (attempt < this.config.maxRetries && (0, retry_policy_1.shouldRetry)(attempt, error)) {
|
|
144
|
+
const delay = (0, retry_policy_1.calculateRetryDelay)(attempt, {
|
|
145
|
+
initialDelayMs: 1000,
|
|
146
|
+
maxDelayMs: 30000,
|
|
147
|
+
jitter: true
|
|
148
|
+
});
|
|
149
|
+
this.logger.warn('Request failed, retrying', {
|
|
150
|
+
attempt,
|
|
151
|
+
delay,
|
|
152
|
+
error: error.message
|
|
153
|
+
});
|
|
154
|
+
await this.sleep(delay);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (lastError) {
|
|
162
|
+
this.logger.error('Completion failed after retries', lastError, {
|
|
163
|
+
attempts: attempt
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
success: false,
|
|
168
|
+
error: lastError?.message ?? 'Unknown error'
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
async stream(prompt, onChunk, options = {}) {
|
|
172
|
+
const model = options.model ?? this.config.defaultModel;
|
|
173
|
+
const maxTokens = options.maxTokens ?? 1024;
|
|
174
|
+
this.logger.debug('Starting streaming request', { model, promptLength: prompt.length });
|
|
175
|
+
try {
|
|
176
|
+
if (this.rateLimiter && !this.rateLimiter.tryAcquire()) {
|
|
177
|
+
const waitTime = this.rateLimiter.getWaitTime();
|
|
178
|
+
this.logger.warn('Rate limit reached, waiting', { waitTime });
|
|
179
|
+
await this.sleep(waitTime);
|
|
180
|
+
}
|
|
181
|
+
const stream = await this.client.messages.create({
|
|
182
|
+
model,
|
|
183
|
+
max_tokens: maxTokens,
|
|
184
|
+
messages: [{ role: 'user', content: prompt }],
|
|
185
|
+
system: options.systemPrompt,
|
|
186
|
+
temperature: options.temperature,
|
|
187
|
+
top_p: options.topP,
|
|
188
|
+
top_k: options.topK,
|
|
189
|
+
stop_sequences: options.stopSequences,
|
|
190
|
+
stream: true
|
|
191
|
+
});
|
|
192
|
+
let fullContent = '';
|
|
193
|
+
let inputTokens = 0;
|
|
194
|
+
let outputTokens = 0;
|
|
195
|
+
let stopReason = '';
|
|
196
|
+
for await (const event of stream) {
|
|
197
|
+
if (event.type === 'content_block_delta') {
|
|
198
|
+
if (event.delta.type === 'text_delta') {
|
|
199
|
+
const chunk = event.delta.text;
|
|
200
|
+
fullContent += chunk;
|
|
201
|
+
await onChunk(chunk);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else if (event.type === 'message_start') {
|
|
205
|
+
inputTokens = event.message.usage.input_tokens;
|
|
206
|
+
}
|
|
207
|
+
else if (event.type === 'message_delta') {
|
|
208
|
+
outputTokens = event.usage.output_tokens;
|
|
209
|
+
stopReason = event.delta.stop_reason || '';
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const totalTokens = inputTokens + outputTokens;
|
|
213
|
+
const pricing = types_1.MODEL_PRICING[model];
|
|
214
|
+
const inputCost = (inputTokens / 1000000) * pricing.input;
|
|
215
|
+
const outputCost = (outputTokens / 1000000) * pricing.output;
|
|
216
|
+
const totalCost = inputCost + outputCost;
|
|
217
|
+
this.updateStats(model, inputTokens, outputTokens, totalCost);
|
|
218
|
+
this.logger.info('Streaming completed', {
|
|
219
|
+
model,
|
|
220
|
+
inputTokens,
|
|
221
|
+
outputTokens,
|
|
222
|
+
totalCost: totalCost.toFixed(6)
|
|
223
|
+
});
|
|
224
|
+
return {
|
|
225
|
+
success: true,
|
|
226
|
+
content: fullContent,
|
|
227
|
+
usage: {
|
|
228
|
+
inputTokens,
|
|
229
|
+
outputTokens,
|
|
230
|
+
totalTokens
|
|
231
|
+
},
|
|
232
|
+
cost: {
|
|
233
|
+
inputCost,
|
|
234
|
+
outputCost,
|
|
235
|
+
totalCost
|
|
236
|
+
},
|
|
237
|
+
model,
|
|
238
|
+
stopReason
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
this.logger.error('Streaming failed', error);
|
|
243
|
+
return {
|
|
244
|
+
success: false,
|
|
245
|
+
error: error.message
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
getUsage() {
|
|
250
|
+
return { ...this.stats };
|
|
251
|
+
}
|
|
252
|
+
getRateLimitStatus() {
|
|
253
|
+
if (!this.rateLimiter) {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
const requestsRemaining = this.rateLimiter.getRemainingRequests();
|
|
257
|
+
const resetTime = new Date(Date.now() + this.rateLimiter.getWaitTime());
|
|
258
|
+
return {
|
|
259
|
+
requestsRemaining,
|
|
260
|
+
tokensRemaining: 0,
|
|
261
|
+
resetTime
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
resetUsage() {
|
|
265
|
+
this.stats = {
|
|
266
|
+
totalRequests: 0,
|
|
267
|
+
totalInputTokens: 0,
|
|
268
|
+
totalOutputTokens: 0,
|
|
269
|
+
totalTokens: 0,
|
|
270
|
+
totalCost: 0,
|
|
271
|
+
requestsByModel: {}
|
|
272
|
+
};
|
|
273
|
+
this.logger.info('Usage statistics reset');
|
|
274
|
+
}
|
|
275
|
+
updateStats(model, inputTokens, outputTokens, cost) {
|
|
276
|
+
this.stats.totalRequests++;
|
|
277
|
+
this.stats.totalInputTokens += inputTokens;
|
|
278
|
+
this.stats.totalOutputTokens += outputTokens;
|
|
279
|
+
this.stats.totalTokens += inputTokens + outputTokens;
|
|
280
|
+
this.stats.totalCost += cost;
|
|
281
|
+
this.stats.requestsByModel[model] = (this.stats.requestsByModel[model] || 0) + 1;
|
|
282
|
+
}
|
|
283
|
+
sleep(ms) {
|
|
284
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
exports.AnthropicClient = AnthropicClient;
|
|
288
|
+
//# sourceMappingURL=AnthropicClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnthropicClient.js","sourceRoot":"","sources":["../src/AnthropicClient.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,cAAc,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.AnthropicClient = void 0;
|
|
18
|
+
var AnthropicClient_1 = require("./AnthropicClient");
|
|
19
|
+
Object.defineProperty(exports, "AnthropicClient", { enumerable: true, get: function () { return AnthropicClient_1.AnthropicClient; } });
|
|
20
|
+
__exportStar(require("./types"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAQA,qDAAoD;AAA3C,kHAAA,eAAe,OAAA;AACxB,0CAAwB"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export declare enum ClaudeModel {
|
|
2
|
+
OPUS = "claude-3-opus-20240229",
|
|
3
|
+
SONNET = "claude-3-sonnet-20240229",
|
|
4
|
+
HAIKU = "claude-3-haiku-20240307",
|
|
5
|
+
SONNET_3_5 = "claude-3-5-sonnet-20241022"
|
|
6
|
+
}
|
|
7
|
+
export interface ModelPricing {
|
|
8
|
+
input: number;
|
|
9
|
+
output: number;
|
|
10
|
+
}
|
|
11
|
+
export declare const MODEL_PRICING: Record<ClaudeModel, ModelPricing>;
|
|
12
|
+
export interface AnthropicClientConfig {
|
|
13
|
+
apiKey: string;
|
|
14
|
+
maxRetries?: number;
|
|
15
|
+
rateLimit?: {
|
|
16
|
+
requestsPerMinute: number;
|
|
17
|
+
tokensPerMinute: number;
|
|
18
|
+
} | null;
|
|
19
|
+
defaultModel?: ClaudeModel;
|
|
20
|
+
enableLogging?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface CompletionOptions {
|
|
23
|
+
model?: ClaudeModel;
|
|
24
|
+
maxTokens?: number;
|
|
25
|
+
temperature?: number;
|
|
26
|
+
topP?: number;
|
|
27
|
+
topK?: number;
|
|
28
|
+
stopSequences?: string[];
|
|
29
|
+
systemPrompt?: string;
|
|
30
|
+
metadata?: Record<string, unknown>;
|
|
31
|
+
}
|
|
32
|
+
export interface CompletionResult {
|
|
33
|
+
success: boolean;
|
|
34
|
+
content?: string;
|
|
35
|
+
usage?: {
|
|
36
|
+
inputTokens: number;
|
|
37
|
+
outputTokens: number;
|
|
38
|
+
totalTokens: number;
|
|
39
|
+
};
|
|
40
|
+
cost?: {
|
|
41
|
+
inputCost: number;
|
|
42
|
+
outputCost: number;
|
|
43
|
+
totalCost: number;
|
|
44
|
+
};
|
|
45
|
+
model?: string;
|
|
46
|
+
stopReason?: string;
|
|
47
|
+
error?: string;
|
|
48
|
+
}
|
|
49
|
+
export type StreamChunkCallback = (chunk: string) => void | Promise<void>;
|
|
50
|
+
export interface UsageStats {
|
|
51
|
+
totalRequests: number;
|
|
52
|
+
totalInputTokens: number;
|
|
53
|
+
totalOutputTokens: number;
|
|
54
|
+
totalTokens: number;
|
|
55
|
+
totalCost: number;
|
|
56
|
+
requestsByModel: Record<string, number>;
|
|
57
|
+
}
|
|
58
|
+
export interface RateLimitStatus {
|
|
59
|
+
requestsRemaining: number;
|
|
60
|
+
tokensRemaining: number;
|
|
61
|
+
resetTime: Date;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAWA,oBAAY,WAAW;IACrB,IAAI,2BAA2B;IAC/B,MAAM,6BAA6B;IACnC,KAAK,4BAA4B;IACjC,UAAU,+BAA+B;CAC1C;AAKD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,WAAW,EAAE,YAAY,CAK3D,CAAC;AAKF,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE;QACV,iBAAiB,EAAE,MAAM,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;KACzB,GAAG,IAAI,CAAC;IACT,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAKD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAKD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,IAAI,CAAC,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAK1E,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAKD,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,IAAI,CAAC;CACjB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MODEL_PRICING = exports.ClaudeModel = void 0;
|
|
4
|
+
var ClaudeModel;
|
|
5
|
+
(function (ClaudeModel) {
|
|
6
|
+
ClaudeModel["OPUS"] = "claude-3-opus-20240229";
|
|
7
|
+
ClaudeModel["SONNET"] = "claude-3-sonnet-20240229";
|
|
8
|
+
ClaudeModel["HAIKU"] = "claude-3-haiku-20240307";
|
|
9
|
+
ClaudeModel["SONNET_3_5"] = "claude-3-5-sonnet-20241022";
|
|
10
|
+
})(ClaudeModel || (exports.ClaudeModel = ClaudeModel = {}));
|
|
11
|
+
exports.MODEL_PRICING = {
|
|
12
|
+
[ClaudeModel.OPUS]: { input: 15.0, output: 75.0 },
|
|
13
|
+
[ClaudeModel.SONNET]: { input: 3.0, output: 15.0 },
|
|
14
|
+
[ClaudeModel.HAIKU]: { input: 0.25, output: 1.25 },
|
|
15
|
+
[ClaudeModel.SONNET_3_5]: { input: 3.0, output: 15.0 }
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAWA,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,8CAA+B,CAAA;IAC/B,kDAAmC,CAAA;IACnC,gDAAiC,CAAA;IACjC,wDAAyC,CAAA;AAC3C,CAAC,EALW,WAAW,2BAAX,WAAW,QAKtB;AAaY,QAAA,aAAa,GAAsC;IAC9D,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IACjD,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IAClD,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;IAClD,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;CACvD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bernierllc/anthropic-client",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Type-safe Anthropic Claude API client with automatic rate limiting, retry logic, streaming support, and cost tracking",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
12
|
+
"keywords": [
|
|
13
|
+
"anthropic",
|
|
14
|
+
"claude",
|
|
15
|
+
"ai",
|
|
16
|
+
"api",
|
|
17
|
+
"rate-limiting",
|
|
18
|
+
"retry",
|
|
19
|
+
"streaming",
|
|
20
|
+
"cost-tracking",
|
|
21
|
+
"bernierllc"
|
|
22
|
+
],
|
|
23
|
+
"author": "Bernier LLC",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/bernier-llc/tools"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@anthropic-ai/sdk": "^0.30.1",
|
|
31
|
+
"@bernierllc/logger": "^1.0.1",
|
|
32
|
+
"@bernierllc/retry-policy": "^0.1.3"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/jest": "^29.5.14",
|
|
36
|
+
"@types/node": "^20.0.0",
|
|
37
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
38
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
39
|
+
"eslint": "^8.0.0",
|
|
40
|
+
"jest": "^29.5.0",
|
|
41
|
+
"rimraf": "^5.0.0",
|
|
42
|
+
"ts-jest": "^29.4.0",
|
|
43
|
+
"typescript": "^5.0.0"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.0.0"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc",
|
|
50
|
+
"dev": "tsc --watch",
|
|
51
|
+
"test": "jest",
|
|
52
|
+
"test:watch": "jest --watch",
|
|
53
|
+
"test:coverage": "jest --coverage",
|
|
54
|
+
"test:run": "jest --passWithNoTests",
|
|
55
|
+
"lint": "eslint src/**/*.ts",
|
|
56
|
+
"clean": "rimraf dist"
|
|
57
|
+
}
|
|
58
|
+
}
|