@anthropic-ai/sdk 0.5.10 → 0.6.1
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 +59 -0
- package/README.md +49 -21
- package/_shims/ReadableStream.d.ts +38 -0
- package/_shims/ReadableStream.js +5 -0
- package/_shims/ReadableStream.mjs +7 -0
- package/_shims/ReadableStream.node.d.ts +6 -0
- package/_shims/ReadableStream.node.d.ts.map +1 -0
- package/_shims/ReadableStream.node.js +14 -0
- package/_shims/ReadableStream.node.js.map +1 -0
- package/_shims/ReadableStream.node.mjs +3 -0
- package/_shims/ReadableStream.node.mjs.map +1 -0
- package/_shims/fetch.d.ts +8 -1
- package/_shims/fetch.node.d.ts +11 -1
- package/_shims/formdata.js +9 -1
- package/_shims/formdata.mjs +10 -1
- package/core.d.ts +78 -29
- package/core.d.ts.map +1 -1
- package/core.js +191 -67
- package/core.js.map +1 -1
- package/core.mjs +185 -67
- package/core.mjs.map +1 -1
- package/index.d.mts +17 -1
- package/index.d.ts +17 -1
- package/index.d.ts.map +1 -1
- package/index.js +16 -3
- package/index.js.map +1 -1
- package/index.mjs +16 -3
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/resources/completions.d.ts +118 -189
- package/resources/completions.d.ts.map +1 -1
- package/resources/completions.js.map +1 -1
- package/resources/completions.mjs.map +1 -1
- package/resources/index.d.ts +7 -1
- package/resources/index.d.ts.map +1 -1
- package/resources/index.js.map +1 -1
- package/resources/index.mjs.map +1 -1
- package/src/_shims/ReadableStream.d.ts +38 -0
- package/src/_shims/ReadableStream.js +5 -0
- package/src/_shims/ReadableStream.mjs +7 -0
- package/src/_shims/ReadableStream.node.ts +6 -0
- package/src/_shims/fetch.d.ts +8 -1
- package/src/_shims/fetch.node.d.ts +11 -1
- package/src/_shims/formdata.js +9 -1
- package/src/_shims/formdata.mjs +10 -1
- package/src/core.ts +254 -89
- package/src/index.ts +19 -2
- package/src/resources/completions.ts +124 -200
- package/src/resources/index.ts +7 -1
- package/src/streaming.ts +9 -15
- package/src/version.ts +1 -1
- package/streaming.d.ts +3 -7
- package/streaming.d.ts.map +1 -1
- package/streaming.js +8 -5
- package/streaming.js.map +1 -1
- package/streaming.mjs +7 -4
- package/streaming.mjs.map +1 -1
- package/version.d.ts +1 -1
- package/version.d.ts.map +1 -1
- package/version.js +1 -1
- package/version.js.map +1 -1
- package/version.mjs +1 -1
- package/version.mjs.map +1 -1
package/src/core.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type RequestInit,
|
|
11
11
|
type Response,
|
|
12
12
|
} from './_shims/fetch.js';
|
|
13
|
+
export { type Response };
|
|
13
14
|
import { isMultipartBody } from './uploads';
|
|
14
15
|
export {
|
|
15
16
|
maybeMultipartFormRequestOptions,
|
|
@@ -22,6 +23,106 @@ const MAX_RETRIES = 2;
|
|
|
22
23
|
|
|
23
24
|
export type Fetch = (url: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
24
25
|
|
|
26
|
+
type PromiseOrValue<T> = T | Promise<T>;
|
|
27
|
+
|
|
28
|
+
type APIResponseProps = {
|
|
29
|
+
response: Response;
|
|
30
|
+
options: FinalRequestOptions;
|
|
31
|
+
controller: AbortController;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
async function defaultParseResponse<T>(props: APIResponseProps): Promise<T> {
|
|
35
|
+
const { response } = props;
|
|
36
|
+
if (props.options.stream) {
|
|
37
|
+
// Note: there is an invariant here that isn't represented in the type system
|
|
38
|
+
// that if you set `stream: true` the response type must also be `Stream<T>`
|
|
39
|
+
return new Stream(response, props.controller) as any;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const contentType = response.headers.get('content-type');
|
|
43
|
+
if (contentType?.includes('application/json')) {
|
|
44
|
+
const json = await response.json();
|
|
45
|
+
|
|
46
|
+
debug('response', response.status, response.url, response.headers, json);
|
|
47
|
+
|
|
48
|
+
return json as T;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// TODO handle blob, arraybuffer, other content types, etc.
|
|
52
|
+
const text = await response.text();
|
|
53
|
+
debug('response', response.status, response.url, response.headers, text);
|
|
54
|
+
return text as T;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* A subclass of `Promise` providing additional helper methods
|
|
59
|
+
* for interacting with the SDK.
|
|
60
|
+
*/
|
|
61
|
+
export class APIPromise<T> extends Promise<T> {
|
|
62
|
+
private parsedPromise: Promise<T> | undefined;
|
|
63
|
+
|
|
64
|
+
constructor(
|
|
65
|
+
private responsePromise: Promise<APIResponseProps>,
|
|
66
|
+
private parseResponse: (props: APIResponseProps) => PromiseOrValue<T> = defaultParseResponse,
|
|
67
|
+
) {
|
|
68
|
+
super((resolve) => {
|
|
69
|
+
// this is maybe a bit weird but this has to be a no-op to not implicitly
|
|
70
|
+
// parse the response body; instead .then, .catch, .finally are overridden
|
|
71
|
+
// to parse the response
|
|
72
|
+
resolve(null as any);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
_thenUnwrap<U>(transform: (data: T) => U): APIPromise<U> {
|
|
77
|
+
return new APIPromise(this.responsePromise, async (props) => transform(await this.parseResponse(props)));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Gets the raw `Response` instance instead of parsing the response
|
|
82
|
+
* data.
|
|
83
|
+
*
|
|
84
|
+
* If you want to parse the response body but still get the `Response`
|
|
85
|
+
* instance, you can use {@link withResponse()}.
|
|
86
|
+
*/
|
|
87
|
+
asResponse(): Promise<Response> {
|
|
88
|
+
return this.responsePromise.then((p) => p.response);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Gets the parsed response data and the raw `Response` instance.
|
|
92
|
+
*
|
|
93
|
+
* If you just want to get the raw `Response` instance without parsing it,
|
|
94
|
+
* you can use {@link asResponse()}.
|
|
95
|
+
*/
|
|
96
|
+
async withResponse(): Promise<{ data: T; response: Response }> {
|
|
97
|
+
const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
|
|
98
|
+
return { data, response };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private parse(): Promise<T> {
|
|
102
|
+
if (!this.parsedPromise) {
|
|
103
|
+
this.parsedPromise = this.responsePromise.then(this.parseResponse);
|
|
104
|
+
}
|
|
105
|
+
return this.parsedPromise;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
override then<TResult1 = T, TResult2 = never>(
|
|
109
|
+
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
|
|
110
|
+
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,
|
|
111
|
+
): Promise<TResult1 | TResult2> {
|
|
112
|
+
return this.parse().then(onfulfilled, onrejected);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
override catch<TResult = never>(
|
|
116
|
+
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null,
|
|
117
|
+
): Promise<T | TResult> {
|
|
118
|
+
return this.parse().catch(onrejected);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
override finally(onfinally?: (() => void) | undefined | null): Promise<T> {
|
|
122
|
+
return this.parse().finally(onfinally);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
25
126
|
export abstract class APIClient {
|
|
26
127
|
baseURL: string;
|
|
27
128
|
maxRetries: number;
|
|
@@ -34,7 +135,7 @@ export abstract class APIClient {
|
|
|
34
135
|
constructor({
|
|
35
136
|
baseURL,
|
|
36
137
|
maxRetries,
|
|
37
|
-
timeout =
|
|
138
|
+
timeout = 600000, // 10 minutes
|
|
38
139
|
httpAgent,
|
|
39
140
|
fetch: overridenFetch,
|
|
40
141
|
}: {
|
|
@@ -85,27 +186,39 @@ export abstract class APIClient {
|
|
|
85
186
|
return `stainless-node-retry-${uuid4()}`;
|
|
86
187
|
}
|
|
87
188
|
|
|
88
|
-
get<Req extends {}, Rsp>(path: string, opts?: RequestOptions<Req
|
|
89
|
-
return this.
|
|
189
|
+
get<Req extends {}, Rsp>(path: string, opts?: PromiseOrValue<RequestOptions<Req>>): APIPromise<Rsp> {
|
|
190
|
+
return this.methodRequest('get', path, opts);
|
|
90
191
|
}
|
|
91
|
-
|
|
92
|
-
|
|
192
|
+
|
|
193
|
+
post<Req extends {}, Rsp>(path: string, opts?: PromiseOrValue<RequestOptions<Req>>): APIPromise<Rsp> {
|
|
194
|
+
return this.methodRequest('post', path, opts);
|
|
93
195
|
}
|
|
94
|
-
|
|
95
|
-
|
|
196
|
+
|
|
197
|
+
patch<Req extends {}, Rsp>(path: string, opts?: PromiseOrValue<RequestOptions<Req>>): APIPromise<Rsp> {
|
|
198
|
+
return this.methodRequest('patch', path, opts);
|
|
96
199
|
}
|
|
97
|
-
|
|
98
|
-
|
|
200
|
+
|
|
201
|
+
put<Req extends {}, Rsp>(path: string, opts?: PromiseOrValue<RequestOptions<Req>>): APIPromise<Rsp> {
|
|
202
|
+
return this.methodRequest('put', path, opts);
|
|
99
203
|
}
|
|
100
|
-
|
|
101
|
-
|
|
204
|
+
|
|
205
|
+
delete<Req extends {}, Rsp>(path: string, opts?: PromiseOrValue<RequestOptions<Req>>): APIPromise<Rsp> {
|
|
206
|
+
return this.methodRequest('delete', path, opts);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private methodRequest<Req extends {}, Rsp>(
|
|
210
|
+
method: HTTPMethod,
|
|
211
|
+
path: string,
|
|
212
|
+
opts?: PromiseOrValue<RequestOptions<Req>>,
|
|
213
|
+
): APIPromise<Rsp> {
|
|
214
|
+
return this.request(Promise.resolve(opts).then((opts) => ({ method, path, ...opts })));
|
|
102
215
|
}
|
|
103
216
|
|
|
104
217
|
getAPIList<Item, PageClass extends AbstractPage<Item> = AbstractPage<Item>>(
|
|
105
218
|
path: string,
|
|
106
219
|
Page: new (...args: any[]) => PageClass,
|
|
107
220
|
opts?: RequestOptions<any>,
|
|
108
|
-
): PagePromise<PageClass> {
|
|
221
|
+
): PagePromise<PageClass, Item> {
|
|
109
222
|
return this.requestAPIList(Page, { method: 'get', path, ...opts });
|
|
110
223
|
}
|
|
111
224
|
|
|
@@ -141,7 +254,10 @@ export abstract class APIClient {
|
|
|
141
254
|
const timeout = options.timeout ?? this.timeout;
|
|
142
255
|
const httpAgent = options.httpAgent ?? this.httpAgent ?? getDefaultAgent(url);
|
|
143
256
|
const minAgentTimeout = timeout + 1000;
|
|
144
|
-
if (
|
|
257
|
+
if (
|
|
258
|
+
typeof (httpAgent as any)?.options?.timeout === 'number' &&
|
|
259
|
+
minAgentTimeout > ((httpAgent as any).options.timeout ?? 0)
|
|
260
|
+
) {
|
|
145
261
|
// Allow any given request to bump our agent active socket timeout.
|
|
146
262
|
// This may seem strange, but leaking active sockets should be rare and not particularly problematic,
|
|
147
263
|
// and without mutating agent we would need to create more of them.
|
|
@@ -199,14 +315,27 @@ export abstract class APIClient {
|
|
|
199
315
|
return APIError.generate(status, error, message, headers);
|
|
200
316
|
}
|
|
201
317
|
|
|
202
|
-
|
|
203
|
-
options: FinalRequestOptions<Req
|
|
204
|
-
|
|
205
|
-
):
|
|
318
|
+
request<Req extends {}, Rsp>(
|
|
319
|
+
options: PromiseOrValue<FinalRequestOptions<Req>>,
|
|
320
|
+
remainingRetries: number | null = null,
|
|
321
|
+
): APIPromise<Rsp> {
|
|
322
|
+
return new APIPromise(this.makeRequest(options, remainingRetries));
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
private async makeRequest(
|
|
326
|
+
optionsInput: PromiseOrValue<FinalRequestOptions>,
|
|
327
|
+
retriesRemaining: number | null,
|
|
328
|
+
): Promise<APIResponseProps> {
|
|
329
|
+
const options = await optionsInput;
|
|
330
|
+
if (retriesRemaining == null) {
|
|
331
|
+
retriesRemaining = options.maxRetries ?? this.maxRetries;
|
|
332
|
+
}
|
|
333
|
+
|
|
206
334
|
const { req, url, timeout } = this.buildRequest(options);
|
|
335
|
+
|
|
207
336
|
await this.prepareRequest(req, { url });
|
|
208
337
|
|
|
209
|
-
|
|
338
|
+
debug('request', url, options, req.headers);
|
|
210
339
|
|
|
211
340
|
if (options.signal?.aborted) {
|
|
212
341
|
throw new APIUserAbortError();
|
|
@@ -239,48 +368,21 @@ export abstract class APIClient {
|
|
|
239
368
|
const errJSON = safeJSON(errText);
|
|
240
369
|
const errMessage = errJSON ? undefined : errText;
|
|
241
370
|
|
|
242
|
-
|
|
371
|
+
debug('response', response.status, url, responseHeaders, errMessage);
|
|
243
372
|
|
|
244
373
|
const err = this.makeStatusError(response.status, errJSON, errMessage, responseHeaders);
|
|
245
374
|
throw err;
|
|
246
375
|
}
|
|
247
376
|
|
|
248
|
-
|
|
249
|
-
// Note: there is an invariant here that isn't represented in the type system
|
|
250
|
-
// that if you set `stream: true` the response type must also be `Stream<T>`
|
|
251
|
-
return new Stream(response, controller) as any;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const contentType = response.headers.get('content-type');
|
|
255
|
-
if (contentType?.includes('application/json')) {
|
|
256
|
-
const json = await response.json();
|
|
257
|
-
|
|
258
|
-
if (typeof json === 'object' && json != null) {
|
|
259
|
-
/** @deprecated – we expect to change this interface in the near future. */
|
|
260
|
-
Object.defineProperty(json, 'responseHeaders', {
|
|
261
|
-
enumerable: false,
|
|
262
|
-
writable: false,
|
|
263
|
-
value: responseHeaders,
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
this.debug('response', response.status, url, responseHeaders, json);
|
|
268
|
-
|
|
269
|
-
return json as APIResponse<Rsp>;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// TODO handle blob, arraybuffer, other content types, etc.
|
|
273
|
-
const text = response.text();
|
|
274
|
-
this.debug('response', response.status, url, responseHeaders, text);
|
|
275
|
-
return text as Promise<any>;
|
|
377
|
+
return { response, options, controller };
|
|
276
378
|
}
|
|
277
379
|
|
|
278
380
|
requestAPIList<Item = unknown, PageClass extends AbstractPage<Item> = AbstractPage<Item>>(
|
|
279
381
|
Page: new (...args: ConstructorParameters<typeof AbstractPage>) => PageClass,
|
|
280
382
|
options: FinalRequestOptions,
|
|
281
|
-
): PagePromise<PageClass> {
|
|
282
|
-
const
|
|
283
|
-
return new PagePromise(this,
|
|
383
|
+
): PagePromise<PageClass, Item> {
|
|
384
|
+
const request = this.makeRequest(options, null);
|
|
385
|
+
return new PagePromise<PageClass, Item>(this, request, Page);
|
|
284
386
|
}
|
|
285
387
|
|
|
286
388
|
buildURL<Req>(path: string, query: Req | undefined): string {
|
|
@@ -360,11 +462,11 @@ export abstract class APIClient {
|
|
|
360
462
|
return false;
|
|
361
463
|
}
|
|
362
464
|
|
|
363
|
-
private async retryRequest
|
|
364
|
-
options: FinalRequestOptions
|
|
465
|
+
private async retryRequest(
|
|
466
|
+
options: FinalRequestOptions,
|
|
365
467
|
retriesRemaining: number,
|
|
366
468
|
responseHeaders?: Headers | undefined,
|
|
367
|
-
): Promise<
|
|
469
|
+
): Promise<APIResponseProps> {
|
|
368
470
|
retriesRemaining -= 1;
|
|
369
471
|
|
|
370
472
|
// About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
|
@@ -377,7 +479,7 @@ export abstract class APIClient {
|
|
|
377
479
|
const timeout = this.calculateRetryTimeoutSeconds(retriesRemaining, retryAfter, maxRetries) * 1000;
|
|
378
480
|
await sleep(timeout);
|
|
379
481
|
|
|
380
|
-
return this.
|
|
482
|
+
return this.makeRequest(options, retriesRemaining);
|
|
381
483
|
}
|
|
382
484
|
|
|
383
485
|
private calculateRetryTimeoutSeconds(
|
|
@@ -408,12 +510,6 @@ export abstract class APIClient {
|
|
|
408
510
|
private getUserAgent(): string {
|
|
409
511
|
return `${this.constructor.name}/JS ${VERSION}`;
|
|
410
512
|
}
|
|
411
|
-
|
|
412
|
-
private debug(action: string, ...args: any[]) {
|
|
413
|
-
if (typeof process !== 'undefined' && process.env['DEBUG'] === 'true') {
|
|
414
|
-
console.log(`${this.constructor.name}:DEBUG:${action}`, ...args);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
513
|
}
|
|
418
514
|
|
|
419
515
|
export class APIResource {
|
|
@@ -443,9 +539,14 @@ export abstract class AbstractPage<Item> implements AsyncIterable<Item> {
|
|
|
443
539
|
#client: APIClient;
|
|
444
540
|
protected options: FinalRequestOptions;
|
|
445
541
|
|
|
446
|
-
|
|
542
|
+
protected response: Response;
|
|
543
|
+
protected body: unknown;
|
|
544
|
+
|
|
545
|
+
constructor(client: APIClient, response: Response, body: unknown, options: FinalRequestOptions) {
|
|
447
546
|
this.#client = client;
|
|
448
547
|
this.options = options;
|
|
548
|
+
this.response = response;
|
|
549
|
+
this.body = body;
|
|
449
550
|
}
|
|
450
551
|
|
|
451
552
|
/**
|
|
@@ -502,35 +603,33 @@ export abstract class AbstractPage<Item> implements AsyncIterable<Item> {
|
|
|
502
603
|
}
|
|
503
604
|
}
|
|
504
605
|
|
|
606
|
+
/**
|
|
607
|
+
* This subclass of Promise will resolve to an instantiated Page once the request completes.
|
|
608
|
+
*
|
|
609
|
+
* It also implements AsyncIterable to allow auto-paginating iteration on an unawaited list call, eg:
|
|
610
|
+
*
|
|
611
|
+
* for await (const item of client.items.list()) {
|
|
612
|
+
* console.log(item)
|
|
613
|
+
* }
|
|
614
|
+
*/
|
|
505
615
|
export class PagePromise<
|
|
506
616
|
PageClass extends AbstractPage<Item>,
|
|
507
617
|
Item = ReturnType<PageClass['getPaginatedItems']>[number],
|
|
508
618
|
>
|
|
509
|
-
extends
|
|
619
|
+
extends APIPromise<PageClass>
|
|
510
620
|
implements AsyncIterable<Item>
|
|
511
621
|
{
|
|
512
|
-
/**
|
|
513
|
-
* This subclass of Promise will resolve to an instantiated Page once the request completes.
|
|
514
|
-
*/
|
|
515
622
|
constructor(
|
|
516
623
|
client: APIClient,
|
|
517
|
-
|
|
518
|
-
options: FinalRequestOptions,
|
|
624
|
+
request: Promise<APIResponseProps>,
|
|
519
625
|
Page: new (...args: ConstructorParameters<typeof AbstractPage>) => PageClass,
|
|
520
626
|
) {
|
|
521
|
-
super(
|
|
522
|
-
|
|
627
|
+
super(
|
|
628
|
+
request,
|
|
629
|
+
async (props) => new Page(client, props.response, await defaultParseResponse(props), props.options),
|
|
523
630
|
);
|
|
524
631
|
}
|
|
525
632
|
|
|
526
|
-
/**
|
|
527
|
-
* Enable subclassing Promise.
|
|
528
|
-
* Ref: https://stackoverflow.com/a/60328122
|
|
529
|
-
*/
|
|
530
|
-
static get [Symbol.species]() {
|
|
531
|
-
return Promise;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
633
|
/**
|
|
535
634
|
* Allow auto-paginating iteration on an unawaited list call, eg:
|
|
536
635
|
*
|
|
@@ -617,11 +716,6 @@ export type FinalRequestOptions<Req extends {} = Record<string, unknown> | Reada
|
|
|
617
716
|
path: string;
|
|
618
717
|
};
|
|
619
718
|
|
|
620
|
-
export type APIResponse<T> = T & {
|
|
621
|
-
/** @deprecated - we plan to add a different way to access raw response information shortly. */
|
|
622
|
-
responseHeaders: Headers;
|
|
623
|
-
};
|
|
624
|
-
|
|
625
719
|
declare const Deno: any;
|
|
626
720
|
declare const EdgeRuntime: any;
|
|
627
721
|
type Arch = 'x32' | 'x64' | 'arm' | 'arm64' | `other:${string}` | 'unknown';
|
|
@@ -635,12 +729,13 @@ type PlatformName =
|
|
|
635
729
|
| 'Android'
|
|
636
730
|
| `Other:${string}`
|
|
637
731
|
| 'Unknown';
|
|
732
|
+
type Browser = 'ie' | 'edge' | 'chrome' | 'firefox' | 'safari';
|
|
638
733
|
type PlatformProperties = {
|
|
639
734
|
'X-Stainless-Lang': 'js';
|
|
640
735
|
'X-Stainless-Package-Version': string;
|
|
641
736
|
'X-Stainless-OS': PlatformName;
|
|
642
737
|
'X-Stainless-Arch': Arch;
|
|
643
|
-
'X-Stainless-Runtime': 'node' | 'deno' | 'edge' | 'unknown';
|
|
738
|
+
'X-Stainless-Runtime': 'node' | 'deno' | 'edge' | `browser:${Browser}` | 'unknown';
|
|
644
739
|
'X-Stainless-Runtime-Version': string;
|
|
645
740
|
};
|
|
646
741
|
const getPlatformProperties = (): PlatformProperties => {
|
|
@@ -675,7 +770,20 @@ const getPlatformProperties = (): PlatformProperties => {
|
|
|
675
770
|
'X-Stainless-Runtime-Version': process.version,
|
|
676
771
|
};
|
|
677
772
|
}
|
|
678
|
-
|
|
773
|
+
|
|
774
|
+
const browserInfo = getBrowserInfo();
|
|
775
|
+
if (browserInfo) {
|
|
776
|
+
return {
|
|
777
|
+
'X-Stainless-Lang': 'js',
|
|
778
|
+
'X-Stainless-Package-Version': VERSION,
|
|
779
|
+
'X-Stainless-OS': 'Unknown',
|
|
780
|
+
'X-Stainless-Arch': 'unknown',
|
|
781
|
+
'X-Stainless-Runtime': `browser:${browserInfo.browser}`,
|
|
782
|
+
'X-Stainless-Runtime-Version': browserInfo.version,
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// TODO add support for Cloudflare workers, etc.
|
|
679
787
|
return {
|
|
680
788
|
'X-Stainless-Lang': 'js',
|
|
681
789
|
'X-Stainless-Package-Version': VERSION,
|
|
@@ -686,6 +794,44 @@ const getPlatformProperties = (): PlatformProperties => {
|
|
|
686
794
|
};
|
|
687
795
|
};
|
|
688
796
|
|
|
797
|
+
type BrowserInfo = {
|
|
798
|
+
browser: Browser;
|
|
799
|
+
version: string;
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
declare const navigator: { userAgent: string } | undefined;
|
|
803
|
+
|
|
804
|
+
// Note: modified from https://github.com/JS-DevTools/host-environment/blob/b1ab79ecde37db5d6e163c050e54fe7d287d7c92/src/isomorphic.browser.ts
|
|
805
|
+
function getBrowserInfo(): BrowserInfo | null {
|
|
806
|
+
if (typeof navigator === 'undefined' || !navigator) {
|
|
807
|
+
return null;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// NOTE: The order matters here!
|
|
811
|
+
const browserPatterns = [
|
|
812
|
+
{ key: 'edge' as const, pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
|
|
813
|
+
{ key: 'ie' as const, pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
|
|
814
|
+
{ key: 'ie' as const, pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ },
|
|
815
|
+
{ key: 'chrome' as const, pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
|
|
816
|
+
{ key: 'firefox' as const, pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
|
|
817
|
+
{ key: 'safari' as const, pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ },
|
|
818
|
+
];
|
|
819
|
+
|
|
820
|
+
// Find the FIRST matching browser
|
|
821
|
+
for (const { key, pattern } of browserPatterns) {
|
|
822
|
+
const match = pattern.exec(navigator.userAgent);
|
|
823
|
+
if (match) {
|
|
824
|
+
const major = match[1] || 0;
|
|
825
|
+
const minor = match[2] || 0;
|
|
826
|
+
const patch = match[3] || 0;
|
|
827
|
+
|
|
828
|
+
return { browser: key, version: `${major}.${minor}.${patch}` };
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
return null;
|
|
833
|
+
}
|
|
834
|
+
|
|
689
835
|
const normalizeArch = (arch: string): Arch => {
|
|
690
836
|
// Node docs:
|
|
691
837
|
// - https://nodejs.org/api/process.html#processarch
|
|
@@ -767,14 +913,16 @@ export const ensurePresent = <T>(value: T | null | undefined): T => {
|
|
|
767
913
|
/**
|
|
768
914
|
* Read an environment variable.
|
|
769
915
|
*
|
|
770
|
-
* Will return
|
|
916
|
+
* Will return undefined if the environment variable doesn't exist or cannot be accessed.
|
|
771
917
|
*/
|
|
772
918
|
export const readEnv = (env: string): string | undefined => {
|
|
773
|
-
if (typeof process
|
|
774
|
-
return undefined;
|
|
919
|
+
if (typeof process !== 'undefined') {
|
|
920
|
+
return process.env?.[env] ?? undefined;
|
|
775
921
|
}
|
|
776
|
-
|
|
777
|
-
|
|
922
|
+
if (typeof Deno !== 'undefined') {
|
|
923
|
+
return Deno.env?.get?.(env);
|
|
924
|
+
}
|
|
925
|
+
return undefined;
|
|
778
926
|
};
|
|
779
927
|
|
|
780
928
|
export const coerceInteger = (value: unknown): number => {
|
|
@@ -830,6 +978,12 @@ export function hasOwn(obj: Object, key: string): boolean {
|
|
|
830
978
|
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
831
979
|
}
|
|
832
980
|
|
|
981
|
+
export function debug(action: string, ...args: any[]) {
|
|
982
|
+
if (typeof process !== 'undefined' && process.env['DEBUG'] === 'true') {
|
|
983
|
+
console.log(`Anthropic:DEBUG:${action}`, ...args);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
833
987
|
/**
|
|
834
988
|
* https://stackoverflow.com/a/2117523
|
|
835
989
|
*/
|
|
@@ -841,6 +995,17 @@ const uuid4 = () => {
|
|
|
841
995
|
});
|
|
842
996
|
};
|
|
843
997
|
|
|
998
|
+
export const isRunningInBrowser = () => {
|
|
999
|
+
return (
|
|
1000
|
+
// @ts-ignore
|
|
1001
|
+
typeof window !== 'undefined' &&
|
|
1002
|
+
// @ts-ignore
|
|
1003
|
+
typeof window.document !== 'undefined' &&
|
|
1004
|
+
// @ts-ignore
|
|
1005
|
+
typeof navigator !== 'undefined'
|
|
1006
|
+
);
|
|
1007
|
+
};
|
|
1008
|
+
|
|
844
1009
|
export interface HeadersProtocol {
|
|
845
1010
|
get: (header: string) => string | null | undefined;
|
|
846
1011
|
}
|
package/src/index.ts
CHANGED
|
@@ -69,13 +69,26 @@ export interface ClientOptions {
|
|
|
69
69
|
authToken?: string | null;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
/**
|
|
72
|
+
/** API Client for interfacing with the Anthropic API. */
|
|
73
73
|
export class Anthropic extends Core.APIClient {
|
|
74
74
|
apiKey: string | null;
|
|
75
75
|
authToken?: string | null;
|
|
76
76
|
|
|
77
77
|
private _options: ClientOptions;
|
|
78
78
|
|
|
79
|
+
/**
|
|
80
|
+
* API Client for interfacing with the Anthropic API.
|
|
81
|
+
*
|
|
82
|
+
* @param {string | null} [opts.apiKey=process.env['ANTHROPIC_API_KEY']] - The API Key to send to the API.
|
|
83
|
+
* @param {string} [opts.baseURL] - Override the default base URL for the API.
|
|
84
|
+
* @param {number} [opts.timeout=10 minutes] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
|
|
85
|
+
* @param {number} [opts.httpAgent] - An HTTP agent used to manage HTTP(s) connections.
|
|
86
|
+
* @param {Core.Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
|
|
87
|
+
* @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
|
|
88
|
+
* @param {Core.Headers} opts.defaultHeaders - Default headers to include with every request to the API.
|
|
89
|
+
* @param {Core.DefaultQuery} opts.defaultQuery - Default query parameters to include with every request to the API.
|
|
90
|
+
* @param {string | null} [opts.authToken]
|
|
91
|
+
*/
|
|
79
92
|
constructor({
|
|
80
93
|
apiKey = Core.readEnv('ANTHROPIC_API_KEY') ?? null,
|
|
81
94
|
authToken = Core.readEnv('ANTHROPIC_AUTH_TOKEN') ?? null,
|
|
@@ -92,7 +105,7 @@ export class Anthropic extends Core.APIClient {
|
|
|
92
105
|
|
|
93
106
|
super({
|
|
94
107
|
baseURL: options.baseURL!,
|
|
95
|
-
timeout: options.timeout
|
|
108
|
+
timeout: options.timeout ?? 600000 /* 10 minutes */,
|
|
96
109
|
httpAgent: options.httpAgent,
|
|
97
110
|
maxRetries: options.maxRetries,
|
|
98
111
|
fetch: options.fetch,
|
|
@@ -206,9 +219,13 @@ export namespace Anthropic {
|
|
|
206
219
|
export import toFile = Uploads.toFile;
|
|
207
220
|
export import fileFromPath = Uploads.fileFromPath;
|
|
208
221
|
|
|
222
|
+
export import RequestOptions = Core.RequestOptions;
|
|
223
|
+
|
|
209
224
|
export import Completions = API.Completions;
|
|
210
225
|
export import Completion = API.Completion;
|
|
211
226
|
export import CompletionCreateParams = API.CompletionCreateParams;
|
|
227
|
+
export import CompletionCreateParamsNonStreaming = API.CompletionCreateParamsNonStreaming;
|
|
228
|
+
export import CompletionCreateParamsStreaming = API.CompletionCreateParamsStreaming;
|
|
212
229
|
}
|
|
213
230
|
|
|
214
231
|
export default Anthropic;
|