@anthropic-ai/sdk 0.6.1 → 0.6.7

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 (265) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/README.md +16 -6
  3. package/_shims/MultipartBody.d.ts +9 -0
  4. package/_shims/MultipartBody.d.ts.map +1 -0
  5. package/_shims/MultipartBody.js +16 -0
  6. package/_shims/MultipartBody.js.map +1 -0
  7. package/_shims/MultipartBody.mjs +12 -0
  8. package/_shims/MultipartBody.mjs.map +1 -0
  9. package/_shims/README.md +46 -0
  10. package/{src/_shims/ReadableStream.node.ts → _shims/auto/runtime-bun.d.ts} +2 -3
  11. package/_shims/auto/runtime-bun.d.ts.map +1 -0
  12. package/_shims/auto/runtime-bun.js +21 -0
  13. package/_shims/auto/runtime-bun.js.map +1 -0
  14. package/_shims/auto/runtime-bun.mjs +2 -0
  15. package/_shims/auto/runtime-bun.mjs.map +1 -0
  16. package/_shims/auto/runtime-node.d.ts +5 -0
  17. package/_shims/auto/runtime-node.d.ts.map +1 -0
  18. package/_shims/auto/runtime-node.js +21 -0
  19. package/_shims/auto/runtime-node.js.map +1 -0
  20. package/_shims/auto/runtime-node.mjs +2 -0
  21. package/_shims/auto/runtime-node.mjs.map +1 -0
  22. package/_shims/auto/runtime.d.ts +5 -0
  23. package/_shims/auto/runtime.d.ts.map +1 -0
  24. package/_shims/auto/runtime.js +21 -0
  25. package/_shims/auto/runtime.js.map +1 -0
  26. package/_shims/auto/runtime.mjs +2 -0
  27. package/_shims/auto/runtime.mjs.map +1 -0
  28. package/_shims/auto/types-node.d.ts +5 -0
  29. package/_shims/auto/types-node.d.ts.map +1 -0
  30. package/_shims/auto/types-node.js +21 -0
  31. package/_shims/auto/types-node.js.map +1 -0
  32. package/_shims/auto/types-node.mjs +2 -0
  33. package/_shims/auto/types-node.mjs.map +1 -0
  34. package/_shims/auto/types.d.ts +101 -0
  35. package/{src/_shims/ReadableStream.js → _shims/auto/types.js} +0 -2
  36. package/_shims/{ReadableStream.js → auto/types.mjs} +0 -2
  37. package/_shims/bun-runtime.d.ts +6 -0
  38. package/_shims/bun-runtime.d.ts.map +1 -0
  39. package/_shims/bun-runtime.js +14 -0
  40. package/_shims/bun-runtime.js.map +1 -0
  41. package/_shims/bun-runtime.mjs +10 -0
  42. package/_shims/bun-runtime.mjs.map +1 -0
  43. package/_shims/index.d.ts +81 -0
  44. package/_shims/index.js +13 -0
  45. package/_shims/index.mjs +7 -0
  46. package/_shims/manual-types.d.ts +12 -0
  47. package/_shims/manual-types.js +3 -0
  48. package/_shims/manual-types.mjs +3 -0
  49. package/_shims/node-runtime.d.ts +3 -0
  50. package/_shims/node-runtime.d.ts.map +1 -0
  51. package/_shims/node-runtime.js +89 -0
  52. package/_shims/node-runtime.js.map +1 -0
  53. package/_shims/node-runtime.mjs +56 -0
  54. package/_shims/node-runtime.mjs.map +1 -0
  55. package/_shims/node-types.d.ts +42 -0
  56. package/_shims/node-types.js +3 -0
  57. package/_shims/node-types.mjs +3 -0
  58. package/_shims/registry.d.ts +37 -0
  59. package/_shims/registry.d.ts.map +1 -0
  60. package/_shims/registry.js +41 -0
  61. package/_shims/registry.js.map +1 -0
  62. package/_shims/registry.mjs +37 -0
  63. package/_shims/registry.mjs.map +1 -0
  64. package/_shims/web-runtime.d.ts +5 -0
  65. package/_shims/web-runtime.d.ts.map +1 -0
  66. package/_shims/web-runtime.js +78 -0
  67. package/_shims/web-runtime.js.map +1 -0
  68. package/_shims/web-runtime.mjs +71 -0
  69. package/_shims/web-runtime.mjs.map +1 -0
  70. package/_shims/web-types.d.ts +83 -0
  71. package/_shims/web-types.js +3 -0
  72. package/_shims/web-types.mjs +3 -0
  73. package/core.d.ts +172 -216
  74. package/core.d.ts.map +1 -1
  75. package/core.js +701 -729
  76. package/core.js.map +1 -1
  77. package/core.mjs +694 -681
  78. package/core.mjs.map +1 -1
  79. package/error.d.ts +32 -32
  80. package/error.d.ts.map +1 -1
  81. package/error.js +105 -106
  82. package/error.js.map +1 -1
  83. package/error.mjs +101 -91
  84. package/error.mjs.map +1 -1
  85. package/index.d.mts +110 -117
  86. package/index.d.ts +110 -117
  87. package/index.d.ts.map +1 -1
  88. package/index.js +107 -160
  89. package/index.js.map +1 -1
  90. package/index.mjs +84 -105
  91. package/index.mjs.map +1 -1
  92. package/package.json +36 -21
  93. package/resource.d.ts +10 -10
  94. package/resource.js +12 -12
  95. package/resource.mjs +10 -10
  96. package/resources/completions.d.ts +136 -142
  97. package/resources/completions.d.ts.map +1 -1
  98. package/resources/completions.js +9 -14
  99. package/resources/completions.js.map +1 -1
  100. package/resources/completions.mjs +6 -11
  101. package/resources/completions.mjs.map +1 -1
  102. package/resources/index.d.ts +2 -9
  103. package/resources/index.d.ts.map +1 -1
  104. package/resources/index.js +5 -10
  105. package/resources/index.js.map +1 -1
  106. package/resources/index.mjs +2 -2
  107. package/resources/index.mjs.map +1 -1
  108. package/resources/top-level.d.ts +1 -1
  109. package/resources/top-level.js +3 -3
  110. package/resources/top-level.mjs +1 -1
  111. package/shims/node.d.ts +29 -0
  112. package/shims/node.d.ts.map +1 -0
  113. package/shims/node.js +31 -0
  114. package/shims/node.js.map +1 -0
  115. package/shims/node.mjs +5 -0
  116. package/shims/node.mjs.map +1 -0
  117. package/shims/web.d.ts +26 -0
  118. package/shims/web.d.ts.map +1 -0
  119. package/shims/web.js +31 -0
  120. package/shims/web.js.map +1 -0
  121. package/shims/web.mjs +5 -0
  122. package/shims/web.mjs.map +1 -0
  123. package/src/_shims/MultipartBody.ts +9 -0
  124. package/src/_shims/README.md +46 -0
  125. package/src/_shims/auto/runtime-bun.ts +4 -0
  126. package/src/_shims/auto/runtime-node.ts +4 -0
  127. package/src/_shims/auto/runtime.ts +4 -0
  128. package/src/_shims/auto/types-node.ts +4 -0
  129. package/src/_shims/auto/types.d.ts +101 -0
  130. package/src/_shims/auto/types.js +3 -0
  131. package/src/_shims/auto/types.mjs +3 -0
  132. package/src/_shims/bun-runtime.ts +14 -0
  133. package/src/_shims/index.d.ts +81 -0
  134. package/src/_shims/index.js +13 -0
  135. package/src/_shims/index.mjs +7 -0
  136. package/src/_shims/manual-types.d.ts +12 -0
  137. package/src/_shims/manual-types.js +3 -0
  138. package/src/_shims/manual-types.mjs +3 -0
  139. package/src/_shims/node-runtime.ts +81 -0
  140. package/src/_shims/node-types.d.ts +42 -0
  141. package/src/_shims/node-types.js +3 -0
  142. package/src/_shims/node-types.mjs +3 -0
  143. package/src/_shims/registry.ts +67 -0
  144. package/src/_shims/web-runtime.ts +103 -0
  145. package/src/_shims/web-types.d.ts +83 -0
  146. package/src/_shims/web-types.js +3 -0
  147. package/src/_shims/web-types.mjs +3 -0
  148. package/src/core.ts +124 -61
  149. package/src/error.ts +20 -8
  150. package/src/index.ts +27 -22
  151. package/src/resources/completions.ts +11 -11
  152. package/src/resources/index.ts +0 -1
  153. package/src/shims/node.ts +50 -0
  154. package/src/shims/web.ts +50 -0
  155. package/src/streaming.ts +166 -56
  156. package/src/tsconfig.json +11 -0
  157. package/src/uploads.ts +11 -15
  158. package/src/version.ts +1 -1
  159. package/streaming.d.ts +11 -8
  160. package/streaming.d.ts.map +1 -1
  161. package/streaming.js +300 -192
  162. package/streaming.js.map +1 -1
  163. package/streaming.mjs +296 -188
  164. package/streaming.mjs.map +1 -1
  165. package/uploads.d.ts +23 -39
  166. package/uploads.d.ts.map +1 -1
  167. package/uploads.js +111 -157
  168. package/uploads.js.map +1 -1
  169. package/uploads.mjs +107 -133
  170. package/uploads.mjs.map +1 -1
  171. package/version.d.ts +2 -2
  172. package/version.js +4 -4
  173. package/version.mjs +2 -2
  174. package/_shims/ReadableStream.d.ts +0 -38
  175. package/_shims/ReadableStream.mjs +0 -7
  176. package/_shims/ReadableStream.node.d.ts +0 -6
  177. package/_shims/ReadableStream.node.d.ts.map +0 -1
  178. package/_shims/ReadableStream.node.js +0 -14
  179. package/_shims/ReadableStream.node.js.map +0 -1
  180. package/_shims/ReadableStream.node.mjs +0 -3
  181. package/_shims/ReadableStream.node.mjs.map +0 -1
  182. package/_shims/agent.d.ts +0 -9
  183. package/_shims/agent.d.ts.map +0 -1
  184. package/_shims/agent.js +0 -14
  185. package/_shims/agent.js.map +0 -1
  186. package/_shims/agent.mjs +0 -10
  187. package/_shims/agent.mjs.map +0 -1
  188. package/_shims/agent.node.d.ts +0 -7
  189. package/_shims/agent.node.d.ts.map +0 -1
  190. package/_shims/agent.node.js +0 -28
  191. package/_shims/agent.node.js.map +0 -1
  192. package/_shims/agent.node.mjs +0 -16
  193. package/_shims/agent.node.mjs.map +0 -1
  194. package/_shims/fetch.d.ts +0 -59
  195. package/_shims/fetch.js +0 -13
  196. package/_shims/fetch.mjs +0 -15
  197. package/_shims/fetch.node.d.ts +0 -63
  198. package/_shims/fetch.node.js +0 -12
  199. package/_shims/fetch.node.mjs +0 -14
  200. package/_shims/fileFromPath.d.ts +0 -22
  201. package/_shims/fileFromPath.d.ts.map +0 -1
  202. package/_shims/fileFromPath.js +0 -16
  203. package/_shims/fileFromPath.js.map +0 -1
  204. package/_shims/fileFromPath.mjs +0 -12
  205. package/_shims/fileFromPath.mjs.map +0 -1
  206. package/_shims/fileFromPath.node.d.ts +0 -17
  207. package/_shims/fileFromPath.node.d.ts.map +0 -1
  208. package/_shims/fileFromPath.node.js +0 -17
  209. package/_shims/fileFromPath.node.js.map +0 -1
  210. package/_shims/fileFromPath.node.mjs +0 -13
  211. package/_shims/fileFromPath.node.mjs.map +0 -1
  212. package/_shims/formdata.d.ts +0 -43
  213. package/_shims/formdata.js +0 -17
  214. package/_shims/formdata.mjs +0 -20
  215. package/_shims/formdata.node.d.ts +0 -45
  216. package/_shims/formdata.node.js +0 -11
  217. package/_shims/formdata.node.mjs +0 -9
  218. package/_shims/getMultipartRequestOptions.d.ts +0 -10
  219. package/_shims/getMultipartRequestOptions.d.ts.map +0 -1
  220. package/_shims/getMultipartRequestOptions.js +0 -12
  221. package/_shims/getMultipartRequestOptions.js.map +0 -1
  222. package/_shims/getMultipartRequestOptions.mjs +0 -8
  223. package/_shims/getMultipartRequestOptions.mjs.map +0 -1
  224. package/_shims/getMultipartRequestOptions.node.d.ts +0 -10
  225. package/_shims/getMultipartRequestOptions.node.d.ts.map +0 -1
  226. package/_shims/getMultipartRequestOptions.node.js +0 -22
  227. package/_shims/getMultipartRequestOptions.node.js.map +0 -1
  228. package/_shims/getMultipartRequestOptions.node.mjs +0 -18
  229. package/_shims/getMultipartRequestOptions.node.mjs.map +0 -1
  230. package/_shims/node-readable.d.ts +0 -23
  231. package/_shims/node-readable.d.ts.map +0 -1
  232. package/_shims/node-readable.js +0 -11
  233. package/_shims/node-readable.js.map +0 -1
  234. package/_shims/node-readable.mjs +0 -7
  235. package/_shims/node-readable.mjs.map +0 -1
  236. package/_shims/node-readable.node.d.ts +0 -8
  237. package/_shims/node-readable.node.d.ts.map +0 -1
  238. package/_shims/node-readable.node.js +0 -9
  239. package/_shims/node-readable.node.js.map +0 -1
  240. package/_shims/node-readable.node.mjs +0 -5
  241. package/_shims/node-readable.node.mjs.map +0 -1
  242. package/src/_shims/ReadableStream.d.ts +0 -38
  243. package/src/_shims/ReadableStream.mjs +0 -7
  244. package/src/_shims/agent.node.ts +0 -22
  245. package/src/_shims/agent.ts +0 -12
  246. package/src/_shims/fetch.d.ts +0 -59
  247. package/src/_shims/fetch.deno.ts +0 -23
  248. package/src/_shims/fetch.js +0 -13
  249. package/src/_shims/fetch.mjs +0 -15
  250. package/src/_shims/fetch.node.d.ts +0 -63
  251. package/src/_shims/fetch.node.js +0 -12
  252. package/src/_shims/fetch.node.mjs +0 -14
  253. package/src/_shims/fileFromPath.node.ts +0 -29
  254. package/src/_shims/fileFromPath.ts +0 -29
  255. package/src/_shims/formdata.d.ts +0 -43
  256. package/src/_shims/formdata.deno.ts +0 -16
  257. package/src/_shims/formdata.js +0 -17
  258. package/src/_shims/formdata.mjs +0 -20
  259. package/src/_shims/formdata.node.d.ts +0 -45
  260. package/src/_shims/formdata.node.js +0 -11
  261. package/src/_shims/formdata.node.mjs +0 -9
  262. package/src/_shims/getMultipartRequestOptions.node.ts +0 -25
  263. package/src/_shims/getMultipartRequestOptions.ts +0 -14
  264. package/src/_shims/node-readable.node.ts +0 -10
  265. package/src/_shims/node-readable.ts +0 -30
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Disclaimer: modules in _shims aren't intended to be imported by SDK users.
3
+ */
4
+ export type Agent = any;
5
+
6
+ declare const _fetch: typeof fetch;
7
+ export { _fetch as fetch };
8
+
9
+ type _Request = Request;
10
+ export { _Request as Request };
11
+
12
+ type _RequestInfo = RequestInfo;
13
+ export { type _RequestInfo as RequestInfo };
14
+
15
+ type _RequestInit = RequestInit;
16
+ export { type _RequestInit as RequestInit };
17
+
18
+ type _Response = Response;
19
+ export { _Response as Response };
20
+
21
+ type _ResponseInit = ResponseInit;
22
+ export { type _ResponseInit as ResponseInit };
23
+
24
+ type _ResponseType = ResponseType;
25
+ export { type _ResponseType as ResponseType };
26
+
27
+ type _BodyInit = BodyInit;
28
+ export { type _BodyInit as BodyInit };
29
+
30
+ type _Headers = Headers;
31
+ export { _Headers as Headers };
32
+
33
+ type _HeadersInit = HeadersInit;
34
+ export { type _HeadersInit as HeadersInit };
35
+
36
+ type EndingType = 'native' | 'transparent';
37
+
38
+ export interface BlobPropertyBag {
39
+ endings?: EndingType;
40
+ type?: string;
41
+ }
42
+
43
+ export interface FilePropertyBag extends BlobPropertyBag {
44
+ lastModified?: number;
45
+ }
46
+
47
+ export type FileFromPathOptions = Omit<FilePropertyBag, 'lastModified'>;
48
+
49
+ type _FormData = FormData;
50
+ declare const _FormData: typeof FormData;
51
+ export { _FormData as FormData };
52
+
53
+ type _File = File;
54
+ declare const _File: typeof File;
55
+ export { _File as File };
56
+
57
+ type _Blob = Blob;
58
+ declare const _Blob: typeof Blob;
59
+ export { _Blob as Blob };
60
+
61
+ export declare class Readable {
62
+ readable: boolean;
63
+ readonly readableEnded: boolean;
64
+ readonly readableFlowing: boolean | null;
65
+ readonly readableHighWaterMark: number;
66
+ readonly readableLength: number;
67
+ readonly readableObjectMode: boolean;
68
+ destroyed: boolean;
69
+ read(size?: number): any;
70
+ pause(): this;
71
+ resume(): this;
72
+ isPaused(): boolean;
73
+ destroy(error?: Error): this;
74
+ [Symbol.asyncIterator](): AsyncIterableIterator<any>;
75
+ }
76
+
77
+ export declare class FsReadStream extends Readable {
78
+ path: {}; // node type is string | Buffer
79
+ }
80
+
81
+ type _ReadableStream<R = any> = ReadableStream<R>;
82
+ declare const _ReadableStream: typeof ReadableStream;
83
+ export { _ReadableStream as ReadableStream };
@@ -0,0 +1,3 @@
1
+ /**
2
+ * Disclaimer: modules in _shims aren't intended to be imported by SDK users.
3
+ */
@@ -0,0 +1,3 @@
1
+ /**
2
+ * Disclaimer: modules in _shims aren't intended to be imported by SDK users.
3
+ */
package/src/core.ts CHANGED
@@ -1,15 +1,23 @@
1
1
  import { VERSION } from './version';
2
2
  import { Stream } from './streaming';
3
- import { APIError, APIConnectionError, APIConnectionTimeoutError, APIUserAbortError } from './error';
4
- import type { Readable } from './_shims/node-readable';
5
- import { getDefaultAgent, type Agent } from './_shims/agent';
6
3
  import {
4
+ AnthropicError,
5
+ APIError,
6
+ APIConnectionError,
7
+ APIConnectionTimeoutError,
8
+ APIUserAbortError,
9
+ } from './error';
10
+ import {
11
+ kind as shimsKind,
12
+ type Readable,
13
+ getDefaultAgent,
14
+ type Agent,
7
15
  fetch,
8
- isPolyfilled as fetchIsPolyfilled,
9
16
  type RequestInfo,
10
17
  type RequestInit,
11
18
  type Response,
12
- } from './_shims/fetch.js';
19
+ type HeadersInit,
20
+ } from './_shims/index';
13
21
  export { type Response };
14
22
  import { isMultipartBody } from './uploads';
15
23
  export {
@@ -34,9 +42,11 @@ type APIResponseProps = {
34
42
  async function defaultParseResponse<T>(props: APIResponseProps): Promise<T> {
35
43
  const { response } = props;
36
44
  if (props.options.stream) {
45
+ debug('response', response.status, response.url, response.headers, response.body);
46
+
37
47
  // Note: there is an invariant here that isn't represented in the type system
38
48
  // that if you set `stream: true` the response type must also be `Stream<T>`
39
- return new Stream(response, props.controller) as any;
49
+ return Stream.fromSSEResponse(response, props.controller) as any;
40
50
  }
41
51
 
42
52
  const contentType = response.headers.get('content-type');
@@ -51,7 +61,7 @@ async function defaultParseResponse<T>(props: APIResponseProps): Promise<T> {
51
61
  // TODO handle blob, arraybuffer, other content types, etc.
52
62
  const text = await response.text();
53
63
  debug('response', response.status, response.url, response.headers, text);
54
- return text as T;
64
+ return text as any as T;
55
65
  }
56
66
 
57
67
  /**
@@ -83,6 +93,12 @@ export class APIPromise<T> extends Promise<T> {
83
93
  *
84
94
  * If you want to parse the response body but still get the `Response`
85
95
  * instance, you can use {@link withResponse()}.
96
+ *
97
+ * 👋 Getting the wrong TypeScript type for `Response`?
98
+ * Try setting `"moduleResolution": "NodeNext"` if you can,
99
+ * or add one of these imports before your first `import … from '@anthropic-ai/sdk'`:
100
+ * - `import '@anthropic-ai/sdk/shims/node'` (if you're running on Node)
101
+ * - `import '@anthropic-ai/sdk/shims/web'` (otherwise)
86
102
  */
87
103
  asResponse(): Promise<Response> {
88
104
  return this.responsePromise.then((p) => p.response);
@@ -92,6 +108,13 @@ export class APIPromise<T> extends Promise<T> {
92
108
  *
93
109
  * If you just want to get the raw `Response` instance without parsing it,
94
110
  * you can use {@link asResponse()}.
111
+ *
112
+ *
113
+ * 👋 Getting the wrong TypeScript type for `Response`?
114
+ * Try setting `"moduleResolution": "NodeNext"` if you can,
115
+ * or add one of these imports before your first `import … from '@anthropic-ai/sdk'`:
116
+ * - `import '@anthropic-ai/sdk/shims/node'` (if you're running on Node)
117
+ * - `import '@anthropic-ai/sdk/shims/web'` (otherwise)
95
118
  */
96
119
  async withResponse(): Promise<{ data: T; response: Response }> {
97
120
  const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
@@ -153,7 +176,7 @@ export abstract class APIClient {
153
176
  this.fetch = overridenFetch ?? fetch;
154
177
  }
155
178
 
156
- protected authHeaders(): Headers {
179
+ protected authHeaders(opts: FinalRequestOptions): Headers {
157
180
  return {};
158
181
  }
159
182
 
@@ -165,13 +188,13 @@ export abstract class APIClient {
165
188
  * Authorization: 'Bearer 123',
166
189
  * }
167
190
  */
168
- protected defaultHeaders(): Headers {
191
+ protected defaultHeaders(opts: FinalRequestOptions): Headers {
169
192
  return {
170
193
  Accept: 'application/json',
171
194
  'Content-Type': 'application/json',
172
195
  'User-Agent': this.getUserAgent(),
173
196
  ...getPlatformHeaders(),
174
- ...this.authHeaders(),
197
+ ...this.authHeaders(opts),
175
198
  };
176
199
  }
177
200
 
@@ -272,11 +295,11 @@ export abstract class APIClient {
272
295
 
273
296
  const reqHeaders: Record<string, string> = {
274
297
  ...(contentLength && { 'Content-Length': contentLength }),
275
- ...this.defaultHeaders(),
298
+ ...this.defaultHeaders(options),
276
299
  ...headers,
277
300
  };
278
301
  // let builtin fetch set the Content-Type for multipart bodies
279
- if (isMultipartBody(options.body) && !fetchIsPolyfilled) {
302
+ if (isMultipartBody(options.body) && shimsKind !== 'node') {
280
303
  delete reqHeaders['Content-Type'];
281
304
  }
282
305
 
@@ -304,7 +327,19 @@ export abstract class APIClient {
304
327
  * This is useful for cases where you want to add certain headers based off of
305
328
  * the request properties, e.g. `method` or `url`.
306
329
  */
307
- protected async prepareRequest(request: RequestInit, { url }: { url: string }): Promise<void> {}
330
+ protected async prepareRequest(
331
+ request: RequestInit,
332
+ { url, options }: { url: string; options: FinalRequestOptions },
333
+ ): Promise<void> {}
334
+
335
+ protected parseHeaders(headers: HeadersInit | null | undefined): Record<string, string> {
336
+ return (
337
+ !headers ? {}
338
+ : Symbol.iterator in headers ?
339
+ Object.fromEntries(Array.from(headers as Iterable<string[]>).map((header) => [...header]))
340
+ : { ...headers }
341
+ );
342
+ }
308
343
 
309
344
  protected makeStatusError(
310
345
  status: number | undefined,
@@ -333,7 +368,7 @@ export abstract class APIClient {
333
368
 
334
369
  const { req, url, timeout } = this.buildRequest(options);
335
370
 
336
- await this.prepareRequest(req, { url });
371
+ await this.prepareRequest(req, { url, options });
337
372
 
338
373
  debug('request', url, options, req.headers);
339
374
 
@@ -364,7 +399,7 @@ export abstract class APIClient {
364
399
  return this.retryRequest(options, retriesRemaining, responseHeaders);
365
400
  }
366
401
 
367
- const errText = await response.text().catch(() => 'Unknown');
402
+ const errText = await response.text().catch((e) => castToError(e).message);
368
403
  const errJSON = safeJSON(errText);
369
404
  const errMessage = errJSON ? undefined : errText;
370
405
 
@@ -385,7 +420,7 @@ export abstract class APIClient {
385
420
  return new PagePromise<PageClass, Item>(this, request, Page);
386
421
  }
387
422
 
388
- buildURL<Req>(path: string, query: Req | undefined): string {
423
+ buildURL<Req extends Record<string, unknown>>(path: string, query: Req | null | undefined): string {
389
424
  const url =
390
425
  isAbsoluteURL(path) ?
391
426
  new URL(path)
@@ -413,7 +448,7 @@ export abstract class APIClient {
413
448
  if (value === null) {
414
449
  return `${encodeURIComponent(key)}=`;
415
450
  }
416
- throw new Error(
451
+ throw new AnthropicError(
417
452
  `Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`,
418
453
  );
419
454
  })
@@ -431,11 +466,14 @@ export abstract class APIClient {
431
466
 
432
467
  const timeout = setTimeout(() => controller.abort(), ms);
433
468
 
434
- return this.getRequestClient()
435
- .fetch(url, { signal: controller.signal as any, ...options })
436
- .finally(() => {
437
- clearTimeout(timeout);
438
- });
469
+ return (
470
+ this.getRequestClient()
471
+ // use undefined this binding; fetch errors if bound to something else in browser/cloudflare
472
+ .fetch.call(undefined, url, { signal: controller.signal as any, ...options })
473
+ .finally(() => {
474
+ clearTimeout(timeout);
475
+ })
476
+ );
439
477
  }
440
478
 
441
479
  protected getRequestClient(): RequestClient {
@@ -450,6 +488,9 @@ export abstract class APIClient {
450
488
  if (shouldRetryHeader === 'true') return true;
451
489
  if (shouldRetryHeader === 'false') return false;
452
490
 
491
+ // Retry on request timeouts.
492
+ if (response.status === 408) return true;
493
+
453
494
  // Retry on lock timeouts.
454
495
  if (response.status === 409) return true;
455
496
 
@@ -470,32 +511,37 @@ export abstract class APIClient {
470
511
  retriesRemaining -= 1;
471
512
 
472
513
  // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
473
- //
474
- // TODO: we may want to handle the case where the header is using the http-date syntax: "Retry-After: <http-date>".
475
- // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After#syntax for details.
476
- const retryAfter = parseInt(responseHeaders?.['retry-after'] || '');
514
+ let timeoutMillis: number | undefined;
515
+ const retryAfterHeader = responseHeaders?.['retry-after'];
516
+ if (retryAfterHeader) {
517
+ const timeoutSeconds = parseInt(retryAfterHeader);
518
+ if (!Number.isNaN(timeoutSeconds)) {
519
+ timeoutMillis = timeoutSeconds * 1000;
520
+ } else {
521
+ timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
522
+ }
523
+ }
477
524
 
478
- const maxRetries = options.maxRetries ?? this.maxRetries;
479
- const timeout = this.calculateRetryTimeoutSeconds(retriesRemaining, retryAfter, maxRetries) * 1000;
480
- await sleep(timeout);
525
+ // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
526
+ // just do what it says, but otherwise calculate a default
527
+ if (
528
+ !timeoutMillis ||
529
+ !Number.isInteger(timeoutMillis) ||
530
+ timeoutMillis <= 0 ||
531
+ timeoutMillis > 60 * 1000
532
+ ) {
533
+ const maxRetries = options.maxRetries ?? this.maxRetries;
534
+ timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
535
+ }
536
+ await sleep(timeoutMillis);
481
537
 
482
538
  return this.makeRequest(options, retriesRemaining);
483
539
  }
484
540
 
485
- private calculateRetryTimeoutSeconds(
486
- retriesRemaining: number,
487
- retryAfter: number,
488
- maxRetries: number,
489
- ): number {
541
+ private calculateDefaultRetryTimeoutMillis(retriesRemaining: number, maxRetries: number): number {
490
542
  const initialRetryDelay = 0.5;
491
543
  const maxRetryDelay = 2;
492
544
 
493
- // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
494
- // just do what it says.
495
- if (Number.isInteger(retryAfter) && retryAfter <= 60) {
496
- return retryAfter;
497
- }
498
-
499
545
  const numRetries = maxRetries - retriesRemaining;
500
546
 
501
547
  // Apply exponential backoff, but not more than the max.
@@ -504,7 +550,7 @@ export abstract class APIClient {
504
550
  // Apply some jitter, plus-or-minus half a second.
505
551
  const jitter = Math.random() - 0.5;
506
552
 
507
- return sleepSeconds + jitter;
553
+ return (sleepSeconds + jitter) * 1000;
508
554
  }
509
555
 
510
556
  private getUserAgent(): string {
@@ -563,10 +609,10 @@ export abstract class AbstractPage<Item> implements AsyncIterable<Item> {
563
609
  return this.nextPageInfo() != null;
564
610
  }
565
611
 
566
- async getNextPage(): Promise<AbstractPage<Item>> {
612
+ async getNextPage(): Promise<this> {
567
613
  const nextInfo = this.nextPageInfo();
568
614
  if (!nextInfo) {
569
- throw new Error(
615
+ throw new AnthropicError(
570
616
  'No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.',
571
617
  );
572
618
  }
@@ -576,7 +622,7 @@ export abstract class AbstractPage<Item> implements AsyncIterable<Item> {
576
622
  } else if ('url' in nextInfo) {
577
623
  const params = [...Object.entries(nextOptions.query || {}), ...nextInfo.url.searchParams.entries()];
578
624
  for (const [key, value] of params) {
579
- nextInfo.url.searchParams.set(key, value);
625
+ nextInfo.url.searchParams.set(key, value as any);
580
626
  }
581
627
  nextOptions.query = undefined;
582
628
  nextOptions.path = nextInfo.url.toString();
@@ -702,7 +748,7 @@ const requestOptionsKeys: KeysEnum<RequestOptions> = {
702
748
  idempotencyKey: true,
703
749
  };
704
750
 
705
- export const isRequestOptions = (obj: unknown): obj is RequestOptions => {
751
+ export const isRequestOptions = (obj: unknown): obj is RequestOptions<Record<string, unknown> | Readable> => {
706
752
  return (
707
753
  typeof obj === 'object' &&
708
754
  obj !== null &&
@@ -888,14 +934,14 @@ const isAbsoluteURL = (url: string): boolean => {
888
934
  return startsWithSchemeRegexp.test(url);
889
935
  };
890
936
 
891
- const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
937
+ export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
892
938
 
893
939
  const validatePositiveInteger = (name: string, n: unknown): number => {
894
940
  if (typeof n !== 'number' || !Number.isInteger(n)) {
895
- throw new Error(`${name} must be an integer`);
941
+ throw new AnthropicError(`${name} must be an integer`);
896
942
  }
897
943
  if (n < 0) {
898
- throw new Error(`${name} must be a positive integer`);
944
+ throw new AnthropicError(`${name} must be a positive integer`);
899
945
  }
900
946
  return n;
901
947
  };
@@ -906,7 +952,7 @@ export const castToError = (err: any): Error => {
906
952
  };
907
953
 
908
954
  export const ensurePresent = <T>(value: T | null | undefined): T => {
909
- if (value == null) throw new Error(`Expected a value to be given but received ${value} instead.`);
955
+ if (value == null) throw new AnthropicError(`Expected a value to be given but received ${value} instead.`);
910
956
  return value;
911
957
  };
912
958
 
@@ -929,14 +975,14 @@ export const coerceInteger = (value: unknown): number => {
929
975
  if (typeof value === 'number') return Math.round(value);
930
976
  if (typeof value === 'string') return parseInt(value, 10);
931
977
 
932
- throw new Error(`Could not coerce ${value} (type: ${typeof value}) into a number`);
978
+ throw new AnthropicError(`Could not coerce ${value} (type: ${typeof value}) into a number`);
933
979
  };
934
980
 
935
981
  export const coerceFloat = (value: unknown): number => {
936
982
  if (typeof value === 'number') return value;
937
983
  if (typeof value === 'string') return parseFloat(value);
938
984
 
939
- throw new Error(`Could not coerce ${value} (type: ${typeof value}) into a number`);
985
+ throw new AnthropicError(`Could not coerce ${value} (type: ${typeof value}) into a number`);
940
986
  };
941
987
 
942
988
  export const coerceBoolean = (value: unknown): boolean => {
@@ -1015,16 +1061,33 @@ export const isHeadersProtocol = (headers: any): headers is HeadersProtocol => {
1015
1061
  return typeof headers?.get === 'function';
1016
1062
  };
1017
1063
 
1018
- export const getHeader = (headers: HeadersLike, key: string): string | null | undefined => {
1019
- const lowerKey = key.toLowerCase();
1020
- if (isHeadersProtocol(headers)) return headers.get(key) || headers.get(lowerKey);
1021
- const value = headers[key] || headers[lowerKey];
1022
- if (Array.isArray(value)) {
1023
- if (value.length <= 1) return value[0];
1024
- console.warn(`Received ${value.length} entries for the ${key} header, using the first entry.`);
1025
- return value[0];
1064
+ export const getRequiredHeader = (headers: HeadersLike, header: string): string => {
1065
+ const lowerCasedHeader = header.toLowerCase();
1066
+ if (isHeadersProtocol(headers)) {
1067
+ // to deal with the case where the header looks like Stainless-Event-Id
1068
+ const intercapsHeader =
1069
+ header[0]?.toUpperCase() +
1070
+ header.substring(1).replace(/([^\w])(\w)/g, (_m, g1, g2) => g1 + g2.toUpperCase());
1071
+ for (const key of [header, lowerCasedHeader, header.toUpperCase(), intercapsHeader]) {
1072
+ const value = headers.get(key);
1073
+ if (value) {
1074
+ return value;
1075
+ }
1076
+ }
1026
1077
  }
1027
- return value;
1078
+
1079
+ for (const [key, value] of Object.entries(headers)) {
1080
+ if (key.toLowerCase() === lowerCasedHeader) {
1081
+ if (Array.isArray(value)) {
1082
+ if (value.length <= 1) return value[0];
1083
+ console.warn(`Received ${value.length} entries for the ${header} header, using the first entry.`);
1084
+ return value[0];
1085
+ }
1086
+ return value;
1087
+ }
1088
+ }
1089
+
1090
+ throw new Error(`Could not find ${header} header`);
1028
1091
  };
1029
1092
 
1030
1093
  /**
@@ -1040,5 +1103,5 @@ export const toBase64 = (str: string | null | undefined): string => {
1040
1103
  return btoa(str);
1041
1104
  }
1042
1105
 
1043
- throw new Error('Cannot generate b64 string; Expected `Buffer` or `btoa` to be defined');
1106
+ throw new AnthropicError('Cannot generate b64 string; Expected `Buffer` or `btoa` to be defined');
1044
1107
  };
package/src/error.ts CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  import { castToError, Headers } from './core';
4
4
 
5
- export class APIError extends Error {
5
+ export class AnthropicError extends Error {}
6
+
7
+ export class APIError extends AnthropicError {
6
8
  readonly status: number | undefined;
7
9
  readonly headers: Headers | undefined;
8
10
  readonly error: Object | undefined;
@@ -13,20 +15,30 @@ export class APIError extends Error {
13
15
  message: string | undefined,
14
16
  headers: Headers | undefined,
15
17
  ) {
16
- super(APIError.makeMessage(error, message));
18
+ super(`${APIError.makeMessage(status, error, message)}`);
17
19
  this.status = status;
18
20
  this.headers = headers;
19
21
  this.error = error;
20
22
  }
21
23
 
22
- private static makeMessage(error: any, message: string | undefined) {
23
- return (
24
+ private static makeMessage(status: number | undefined, error: any, message: string | undefined) {
25
+ const msg =
24
26
  error?.message ?
25
27
  typeof error.message === 'string' ? error.message
26
28
  : JSON.stringify(error.message)
27
29
  : error ? JSON.stringify(error)
28
- : message || 'Unknown error occurred'
29
- );
30
+ : message;
31
+
32
+ if (status && msg) {
33
+ return `${status} ${msg}`;
34
+ }
35
+ if (status) {
36
+ return `${status} status code (no body)`;
37
+ }
38
+ if (msg) {
39
+ return msg;
40
+ }
41
+ return '(no status code or body)';
30
42
  }
31
43
 
32
44
  static generate(
@@ -97,8 +109,8 @@ export class APIConnectionError extends APIError {
97
109
  }
98
110
 
99
111
  export class APIConnectionTimeoutError extends APIConnectionError {
100
- constructor() {
101
- super({ message: 'Request timed out.' });
112
+ constructor({ message }: { message?: string } = {}) {
113
+ super({ message: message ?? 'Request timed out.' });
102
114
  }
103
115
  }
104
116
 
package/src/index.ts CHANGED
@@ -1,17 +1,22 @@
1
1
  // File generated from our OpenAPI spec by Stainless.
2
2
 
3
3
  import * as Core from './core';
4
- import * as API from './resources/index';
5
4
  import * as Errors from './error';
6
- import type { Agent } from './_shims/agent';
5
+ import { type Agent } from './_shims/index';
7
6
  import * as Uploads from './uploads';
7
+ import * as API from "./pic-ai/sdk/resources/index";
8
8
 
9
9
  export interface ClientOptions {
10
10
  /**
11
- * Defaults to process.env["ANTHROPIC_API_KEY"]. Set it to null if you want to send unauthenticated requests.
11
+ * Defaults to process.env['ANTHROPIC_API_KEY'].
12
12
  */
13
13
  apiKey?: string | null;
14
14
 
15
+ /**
16
+ * Defaults to process.env['ANTHROPIC_AUTH_TOKEN'].
17
+ */
18
+ authToken?: string | null;
19
+
15
20
  /**
16
21
  * Override the default base URL for the API, e.g., "https://api.example.com/v2/"
17
22
  */
@@ -65,21 +70,20 @@ export interface ClientOptions {
65
70
  * param to `undefined` in request options.
66
71
  */
67
72
  defaultQuery?: Core.DefaultQuery;
68
-
69
- authToken?: string | null;
70
73
  }
71
74
 
72
75
  /** API Client for interfacing with the Anthropic API. */
73
76
  export class Anthropic extends Core.APIClient {
74
77
  apiKey: string | null;
75
- authToken?: string | null;
78
+ authToken: string | null;
76
79
 
77
80
  private _options: ClientOptions;
78
81
 
79
82
  /**
80
83
  * API Client for interfacing with the Anthropic API.
81
84
  *
82
- * @param {string | null} [opts.apiKey=process.env['ANTHROPIC_API_KEY']] - The API Key to send to the API.
85
+ * @param {string | null} [opts.apiKey==process.env['ANTHROPIC_API_KEY'] ?? null]
86
+ * @param {string | null} [opts.authToken==process.env['ANTHROPIC_AUTH_TOKEN'] ?? null]
83
87
  * @param {string} [opts.baseURL] - Override the default base URL for the API.
84
88
  * @param {number} [opts.timeout=10 minutes] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
85
89
  * @param {number} [opts.httpAgent] - An HTTP agent used to manage HTTP(s) connections.
@@ -87,20 +91,17 @@ export class Anthropic extends Core.APIClient {
87
91
  * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
88
92
  * @param {Core.Headers} opts.defaultHeaders - Default headers to include with every request to the API.
89
93
  * @param {Core.DefaultQuery} opts.defaultQuery - Default query parameters to include with every request to the API.
90
- * @param {string | null} [opts.authToken]
91
94
  */
92
95
  constructor({
93
96
  apiKey = Core.readEnv('ANTHROPIC_API_KEY') ?? null,
94
97
  authToken = Core.readEnv('ANTHROPIC_AUTH_TOKEN') ?? null,
95
98
  ...opts
96
99
  }: ClientOptions = {}) {
97
- undefined;
98
-
99
100
  const options: ClientOptions = {
100
101
  apiKey,
101
102
  authToken,
102
- baseURL: `https://api.anthropic.com`,
103
103
  ...opts,
104
+ baseURL: opts.baseURL ?? `https://api.anthropic.com`,
104
105
  };
105
106
 
106
107
  super({
@@ -122,9 +123,9 @@ export class Anthropic extends Core.APIClient {
122
123
  return this._options.defaultQuery;
123
124
  }
124
125
 
125
- protected override defaultHeaders(): Core.Headers {
126
+ protected override defaultHeaders(opts: Core.FinalRequestOptions): Core.Headers {
126
127
  return {
127
- ...super.defaultHeaders(),
128
+ ...super.defaultHeaders(opts),
128
129
  'anthropic-version': '2023-06-01',
129
130
  ...this._options.defaultHeaders,
130
131
  };
@@ -150,26 +151,28 @@ export class Anthropic extends Core.APIClient {
150
151
  );
151
152
  }
152
153
 
153
- protected override authHeaders(): Core.Headers {
154
- const apiKeyHeader = this.apiKeyHeader();
155
- if (apiKeyHeader != null && !Core.isEmptyObj(apiKeyHeader)) {
156
- return apiKeyHeader;
154
+ protected override authHeaders(opts: Core.FinalRequestOptions): Core.Headers {
155
+ const apiKeyAuth = this.apiKeyAuth(opts);
156
+ const bearerAuth = this.bearerAuth(opts);
157
+
158
+ if (apiKeyAuth != null && !Core.isEmptyObj(apiKeyAuth)) {
159
+ return apiKeyAuth;
157
160
  }
158
- const authTokenBearer = this.authTokenBearer();
159
- if (authTokenBearer != null && !Core.isEmptyObj(authTokenBearer)) {
160
- return authTokenBearer;
161
+
162
+ if (bearerAuth != null && !Core.isEmptyObj(bearerAuth)) {
163
+ return bearerAuth;
161
164
  }
162
165
  return {};
163
166
  }
164
167
 
165
- protected apiKeyHeader(): Core.Headers {
168
+ protected apiKeyAuth(opts: Core.FinalRequestOptions): Core.Headers {
166
169
  if (this.apiKey == null) {
167
170
  return {};
168
171
  }
169
172
  return { 'X-Api-Key': this.apiKey };
170
173
  }
171
174
 
172
- protected authTokenBearer(): Core.Headers {
175
+ protected bearerAuth(opts: Core.FinalRequestOptions): Core.Headers {
173
176
  if (this.authToken == null) {
174
177
  return {};
175
178
  }
@@ -180,6 +183,7 @@ export class Anthropic extends Core.APIClient {
180
183
  static HUMAN_PROMPT = '\n\nHuman:';
181
184
  static AI_PROMPT = '\n\nAssistant:';
182
185
 
186
+ static AnthropicError = Errors.AnthropicError;
183
187
  static APIError = Errors.APIError;
184
188
  static APIConnectionError = Errors.APIConnectionError;
185
189
  static APIConnectionTimeoutError = Errors.APIConnectionTimeoutError;
@@ -197,6 +201,7 @@ export class Anthropic extends Core.APIClient {
197
201
  export const { HUMAN_PROMPT, AI_PROMPT } = Anthropic;
198
202
 
199
203
  export const {
204
+ AnthropicError,
200
205
  APIError,
201
206
  APIConnectionError,
202
207
  APIConnectionTimeoutError,