diff --git a/.stats.yml b/.stats.yml
index 239e17b7..c809f63b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
configured_endpoints: 21
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-fd67aea6883f1ee9e46f31a42d3940f0acb1749e787055bd9b9f278b20fa53ec.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-75f0573c3d6d79650bcbd8b1b4fcf93ce146d567afeb1061cd4afccf8d1d6799.yml
diff --git a/api.md b/api.md
index d4a311ad..6d080680 100644
--- a/api.md
+++ b/api.md
@@ -84,7 +84,7 @@ Methods:
- client.messages.batches.list({ ...params }) -> MessageBatchesPage
- client.messages.batches.delete(messageBatchId) -> DeletedMessageBatch
- client.messages.batches.cancel(messageBatchId) -> MessageBatch
-- client.messages.batches.results(messageBatchId) -> Response
+- client.messages.batches.results(messageBatchId) -> JSONLDecoder<MessageBatchIndividualResponse>
# Models
@@ -191,4 +191,4 @@ Methods:
- client.beta.messages.batches.list({ ...params }) -> BetaMessageBatchesPage
- client.beta.messages.batches.delete(messageBatchId, { ...params }) -> BetaDeletedMessageBatch
- client.beta.messages.batches.cancel(messageBatchId, { ...params }) -> BetaMessageBatch
-- client.beta.messages.batches.results(messageBatchId, { ...params }) -> Response
+- client.beta.messages.batches.results(messageBatchId, { ...params }) -> JSONLDecoder<BetaMessageBatchIndividualResponse>
diff --git a/src/internal/decoders/jsonl.ts b/src/internal/decoders/jsonl.ts
new file mode 100644
index 00000000..15751255
--- /dev/null
+++ b/src/internal/decoders/jsonl.ts
@@ -0,0 +1,41 @@
+import { AnthropicError } from '../../error';
+import { ReadableStreamToAsyncIterable } from '../stream-utils';
+import { type Response } from '../../_shims/index';
+import { LineDecoder, type Bytes } from './line';
+
+export class JSONLDecoder {
+ controller: AbortController;
+
+ constructor(
+ private iterator: AsyncIterableIterator,
+ controller: AbortController,
+ ) {
+ this.controller = controller;
+ }
+
+ private async *decoder(): AsyncIterator {
+ const lineDecoder = new LineDecoder();
+ for await (const chunk of this.iterator) {
+ for (const line of lineDecoder.decode(chunk)) {
+ yield JSON.parse(line);
+ }
+ }
+
+ for (const line of lineDecoder.flush()) {
+ yield JSON.parse(line);
+ }
+ }
+
+ [Symbol.asyncIterator](): AsyncIterator {
+ return this.decoder();
+ }
+
+ static fromResponse(response: Response, controller: AbortController): JSONLDecoder {
+ if (!response.body) {
+ controller.abort();
+ throw new AnthropicError(`Attempted to iterate over a response with no body`);
+ }
+
+ return new JSONLDecoder(ReadableStreamToAsyncIterable(response.body), controller);
+ }
+}
diff --git a/src/resources/beta/messages/batches.ts b/src/resources/beta/messages/batches.ts
index a6b5997e..2baa2933 100644
--- a/src/resources/beta/messages/batches.ts
+++ b/src/resources/beta/messages/batches.ts
@@ -7,7 +7,7 @@ import * as BetaAPI from '../beta';
import * as MessagesAPI from '../../messages/messages';
import * as MessagesMessagesAPI from './messages';
import { Page, type PageParams } from '../../../pagination';
-import { type Response } from '../../../_shims/index';
+import { JSONLDecoder } from '../../../internal/decoders/jsonl';
export class Batches extends APIResource {
/**
@@ -160,26 +160,31 @@ export class Batches extends APIResource {
messageBatchId: string,
params?: BatchResultsParams,
options?: Core.RequestOptions,
- ): Core.APIPromise;
- results(messageBatchId: string, options?: Core.RequestOptions): Core.APIPromise;
+ ): Core.APIPromise>;
+ results(
+ messageBatchId: string,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise>;
results(
messageBatchId: string,
params: BatchResultsParams | Core.RequestOptions = {},
options?: Core.RequestOptions,
- ): Core.APIPromise {
+ ): Core.APIPromise> {
if (isRequestOptions(params)) {
return this.results(messageBatchId, {}, params);
}
const { betas } = params;
- return this._client.get(`/v1/messages/batches/${messageBatchId}/results?beta=true`, {
- ...options,
- headers: {
- 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString(),
- Accept: 'application/binary',
- ...options?.headers,
- },
- __binaryResponse: true,
- });
+ return this._client
+ .get(`/v1/messages/batches/${messageBatchId}/results?beta=true`, {
+ ...options,
+ headers: {
+ 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString(),
+ Accept: 'application/x-jsonl',
+ ...options?.headers,
+ },
+ __binaryResponse: true,
+ })
+ ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller));
}
}
diff --git a/src/resources/messages/batches.ts b/src/resources/messages/batches.ts
index 3425262a..1ffac7b3 100644
--- a/src/resources/messages/batches.ts
+++ b/src/resources/messages/batches.ts
@@ -6,7 +6,7 @@ import * as Core from '../../core';
import * as Shared from '../shared';
import * as MessagesAPI from './messages';
import { Page, type PageParams } from '../../pagination';
-import { type Response } from '../../_shims/index';
+import { JSONLDecoder } from '../../internal/decoders/jsonl';
export class Batches extends APIResource {
/**
@@ -79,12 +79,17 @@ export class Batches extends APIResource {
* in the Message Batch. Results are not guaranteed to be in the same order as
* requests. Use the `custom_id` field to match results to requests.
*/
- results(messageBatchId: string, options?: Core.RequestOptions): Core.APIPromise {
- return this._client.get(`/v1/messages/batches/${messageBatchId}/results`, {
- ...options,
- headers: { Accept: 'application/binary', ...options?.headers },
- __binaryResponse: true,
- });
+ results(
+ messageBatchId: string,
+ options?: Core.RequestOptions,
+ ): Core.APIPromise> {
+ return this._client
+ .get(`/v1/messages/batches/${messageBatchId}/results`, {
+ ...options,
+ headers: { Accept: 'application/x-jsonl', ...options?.headers },
+ __binaryResponse: true,
+ })
+ ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller));
}
}
diff --git a/tests/api-resources/beta/messages/batches.test.ts b/tests/api-resources/beta/messages/batches.test.ts
index 595d45b9..a0c1ce2b 100644
--- a/tests/api-resources/beta/messages/batches.test.ts
+++ b/tests/api-resources/beta/messages/batches.test.ts
@@ -190,14 +190,28 @@ describe('resource batches', () => {
).rejects.toThrow(Anthropic.NotFoundError);
});
- test('results: request options instead of params are passed correctly', async () => {
+ // Prism doesn't support JSONL responses yet
+ test.skip('results', async () => {
+ const responsePromise = client.beta.messages.batches.results('message_batch_id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism doesn't support JSONL responses yet
+ test.skip('results: request options instead of params are passed correctly', async () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.beta.messages.batches.results('message_batch_id', { path: '/_stainless_unknown_path' }),
).rejects.toThrow(Anthropic.NotFoundError);
});
- test('results: request options and params are passed correctly', async () => {
+ // Prism doesn't support JSONL responses yet
+ test.skip('results: request options and params are passed correctly', async () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.beta.messages.batches.results(
diff --git a/tests/api-resources/messages/batches.test.ts b/tests/api-resources/messages/batches.test.ts
index 784b3143..fdf10664 100644
--- a/tests/api-resources/messages/batches.test.ts
+++ b/tests/api-resources/messages/batches.test.ts
@@ -155,7 +155,20 @@ describe('resource batches', () => {
).rejects.toThrow(Anthropic.NotFoundError);
});
- test('results: request options instead of params are passed correctly', async () => {
+ // Prism doesn't support JSONL responses yet
+ test.skip('results', async () => {
+ const responsePromise = client.messages.batches.results('message_batch_id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ // Prism doesn't support JSONL responses yet
+ test.skip('results: request options instead of params are passed correctly', async () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.messages.batches.results('message_batch_id', { path: '/_stainless_unknown_path' }),