@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.
Files changed (63) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +49 -21
  3. package/_shims/ReadableStream.d.ts +38 -0
  4. package/_shims/ReadableStream.js +5 -0
  5. package/_shims/ReadableStream.mjs +7 -0
  6. package/_shims/ReadableStream.node.d.ts +6 -0
  7. package/_shims/ReadableStream.node.d.ts.map +1 -0
  8. package/_shims/ReadableStream.node.js +14 -0
  9. package/_shims/ReadableStream.node.js.map +1 -0
  10. package/_shims/ReadableStream.node.mjs +3 -0
  11. package/_shims/ReadableStream.node.mjs.map +1 -0
  12. package/_shims/fetch.d.ts +8 -1
  13. package/_shims/fetch.node.d.ts +11 -1
  14. package/_shims/formdata.js +9 -1
  15. package/_shims/formdata.mjs +10 -1
  16. package/core.d.ts +78 -29
  17. package/core.d.ts.map +1 -1
  18. package/core.js +191 -67
  19. package/core.js.map +1 -1
  20. package/core.mjs +185 -67
  21. package/core.mjs.map +1 -1
  22. package/index.d.mts +17 -1
  23. package/index.d.ts +17 -1
  24. package/index.d.ts.map +1 -1
  25. package/index.js +16 -3
  26. package/index.js.map +1 -1
  27. package/index.mjs +16 -3
  28. package/index.mjs.map +1 -1
  29. package/package.json +1 -1
  30. package/resources/completions.d.ts +118 -189
  31. package/resources/completions.d.ts.map +1 -1
  32. package/resources/completions.js.map +1 -1
  33. package/resources/completions.mjs.map +1 -1
  34. package/resources/index.d.ts +7 -1
  35. package/resources/index.d.ts.map +1 -1
  36. package/resources/index.js.map +1 -1
  37. package/resources/index.mjs.map +1 -1
  38. package/src/_shims/ReadableStream.d.ts +38 -0
  39. package/src/_shims/ReadableStream.js +5 -0
  40. package/src/_shims/ReadableStream.mjs +7 -0
  41. package/src/_shims/ReadableStream.node.ts +6 -0
  42. package/src/_shims/fetch.d.ts +8 -1
  43. package/src/_shims/fetch.node.d.ts +11 -1
  44. package/src/_shims/formdata.js +9 -1
  45. package/src/_shims/formdata.mjs +10 -1
  46. package/src/core.ts +254 -89
  47. package/src/index.ts +19 -2
  48. package/src/resources/completions.ts +124 -200
  49. package/src/resources/index.ts +7 -1
  50. package/src/streaming.ts +9 -15
  51. package/src/version.ts +1 -1
  52. package/streaming.d.ts +3 -7
  53. package/streaming.d.ts.map +1 -1
  54. package/streaming.js +8 -5
  55. package/streaming.js.map +1 -1
  56. package/streaming.mjs +7 -4
  57. package/streaming.mjs.map +1 -1
  58. package/version.d.ts +1 -1
  59. package/version.d.ts.map +1 -1
  60. package/version.js +1 -1
  61. package/version.js.map +1 -1
  62. package/version.mjs +1 -1
  63. 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 = 60 * 1000, // 60s
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>): Promise<Rsp> {
89
- return this.request({ method: 'get', path, ...opts });
189
+ get<Req extends {}, Rsp>(path: string, opts?: PromiseOrValue<RequestOptions<Req>>): APIPromise<Rsp> {
190
+ return this.methodRequest('get', path, opts);
90
191
  }
91
- post<Req extends {}, Rsp>(path: string, opts?: RequestOptions<Req>): Promise<Rsp> {
92
- return this.request({ method: 'post', path, ...opts });
192
+
193
+ post<Req extends {}, Rsp>(path: string, opts?: PromiseOrValue<RequestOptions<Req>>): APIPromise<Rsp> {
194
+ return this.methodRequest('post', path, opts);
93
195
  }
94
- patch<Req extends {}, Rsp>(path: string, opts?: RequestOptions<Req>): Promise<Rsp> {
95
- return this.request({ method: 'patch', path, ...opts });
196
+
197
+ patch<Req extends {}, Rsp>(path: string, opts?: PromiseOrValue<RequestOptions<Req>>): APIPromise<Rsp> {
198
+ return this.methodRequest('patch', path, opts);
96
199
  }
97
- put<Req extends {}, Rsp>(path: string, opts?: RequestOptions<Req>): Promise<Rsp> {
98
- return this.request({ method: 'put', path, ...opts });
200
+
201
+ put<Req extends {}, Rsp>(path: string, opts?: PromiseOrValue<RequestOptions<Req>>): APIPromise<Rsp> {
202
+ return this.methodRequest('put', path, opts);
99
203
  }
100
- delete<Req extends {}, Rsp>(path: string, opts?: RequestOptions<Req>): Promise<Rsp> {
101
- return this.request({ method: 'delete', path, ...opts });
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 ((httpAgent as any)?.options && minAgentTimeout > ((httpAgent as any).options.timeout ?? 0)) {
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
- async request<Req extends {}, Rsp>(
203
- options: FinalRequestOptions<Req>,
204
- retriesRemaining = options.maxRetries ?? this.maxRetries,
205
- ): Promise<APIResponse<Rsp>> {
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
- this.debug('request', url, options, req.headers);
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
- this.debug('response', response.status, url, responseHeaders, errMessage);
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
- if (options.stream) {
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 requestPromise = this.request(options) as Promise<APIResponse<unknown>>;
283
- return new PagePromise(this, requestPromise, options, Page);
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<Req extends {}, Rsp>(
364
- options: FinalRequestOptions<Req>,
465
+ private async retryRequest(
466
+ options: FinalRequestOptions,
365
467
  retriesRemaining: number,
366
468
  responseHeaders?: Headers | undefined,
367
- ): Promise<Rsp> {
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.request(options, retriesRemaining);
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
- constructor(client: APIClient, response: APIResponse<unknown>, options: FinalRequestOptions) {
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 Promise<PageClass>
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
- requestPromise: Promise<APIResponse<unknown>>,
518
- options: FinalRequestOptions,
624
+ request: Promise<APIResponseProps>,
519
625
  Page: new (...args: ConstructorParameters<typeof AbstractPage>) => PageClass,
520
626
  ) {
521
- super((resolve, reject) =>
522
- requestPromise.then((response) => resolve(new Page(client, response, options))).catch(reject),
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
- // TODO add support for Cloudflare workers, browsers, etc.
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 an empty string if the environment variable doesn't exist or cannot be accessed.
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 === 'undefined') {
774
- return undefined;
919
+ if (typeof process !== 'undefined') {
920
+ return process.env?.[env] ?? undefined;
775
921
  }
776
-
777
- return process.env[env] ?? undefined;
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
- /** Instantiate the API Client. */
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;