diff --git a/README.md b/README.md index 6dfbb9d2..913a7158 100644 --- a/README.md +++ b/README.md @@ -25,15 +25,17 @@ The full API of this library can be found in [api.md](api.md). import Anthropic from '@anthropic-ai/sdk'; const anthropic = new Anthropic({ - apiKey: 'my api key', // defaults to process.env["ANTHROPIC_API_KEY"] + apiKey: process.env['ANTHROPIC_API_KEY'], // This is the default and can be omitted }); async function main() { - const completion = await anthropic.completions.create({ + const message = await anthropic.messages.create({ + max_tokens: 1024, + messages: [{ role: 'user', content: 'How does a court case get to the supreme court?' }], model: 'claude-2.1', - max_tokens_to_sample: 300, - prompt: `${Anthropic.HUMAN_PROMPT} how does a court case get to the Supreme Court?${Anthropic.AI_PROMPT}`, }); + + console.log(message.content); } main(); @@ -48,14 +50,14 @@ import Anthropic from '@anthropic-ai/sdk'; const anthropic = new Anthropic(); -const stream = await anthropic.completions.create({ - prompt: `${Anthropic.HUMAN_PROMPT} Your prompt here${Anthropic.AI_PROMPT}`, +const stream = await anthropic.messages.create({ + max_tokens: 1024, + messages: [{ role: 'user', content: 'your prompt here' }], model: 'claude-2.1', stream: true, - max_tokens_to_sample: 300, }); -for await (const completion of stream) { - console.log(completion.completion); +for await (const messageStreamEvent of stream) { + console.log(messageStreamEvent.type); } ``` @@ -71,16 +73,16 @@ This library includes TypeScript definitions for all request params and response import Anthropic from '@anthropic-ai/sdk'; const anthropic = new Anthropic({ - apiKey: 'my api key', // defaults to process.env["ANTHROPIC_API_KEY"] + apiKey: process.env['ANTHROPIC_API_KEY'], // This is the default and can be omitted }); async function main() { - const params: Anthropic.CompletionCreateParams = { - prompt: `${Anthropic.HUMAN_PROMPT} how does a court case get to the Supreme Court?${Anthropic.AI_PROMPT}`, - max_tokens_to_sample: 300, + const params: Anthropic.MessageCreateParams = { + max_tokens: 1024, + messages: [{ role: 'user', content: 'Where can I get a good coffee in my neighbourhood?' }], model: 'claude-2.1', }; - const completion: Anthropic.Completion = await anthropic.completions.create(params); + const message: Anthropic.Message = await anthropic.messages.create(params); } main(); @@ -104,7 +106,7 @@ import Anthropic from '@anthropic-ai/sdk'; const anthropic = new Anthropic(); async function main() { - const stream = anthropic.beta.messages + const stream = anthropic.messages .stream({ model: 'claude-2.1', max_tokens: 1024, @@ -126,9 +128,9 @@ async function main() { main(); ``` -Streaming with `client.beta.messages.stream(...)` exposes [various helpers for your convenience](helpers.md) including event handlers and accumulation. +Streaming with `client.messages.stream(...)` exposes [various helpers for your convenience](helpers.md) including event handlers and accumulation. -Alternatively, you can use `client.beta.messages.create({ ..., stream: true })` which only returns an async iterable of the events in the stream and thus uses less memory (it does not build up a final message object for you). +Alternatively, you can use `client.messages.create({ ..., stream: true })` which only returns an async iterable of the events in the stream and thus uses less memory (it does not build up a final message object for you). ## Handling errors @@ -139,10 +141,10 @@ a subclass of `APIError` will be thrown: ```ts async function main() { - const completion = await anthropic.completions + const message = await anthropic.messages .create({ - prompt: `${Anthropic.HUMAN_PROMPT} Your prompt here${Anthropic.AI_PROMPT}`, - max_tokens_to_sample: 300, + max_tokens: 1024, + messages: [{ role: 'user', content: 'your prompt here' }], model: 'claude-2.1', }) .catch((err) => { @@ -188,16 +190,9 @@ const anthropic = new Anthropic({ }); // Or, configure per-request: -await anthropic.completions.create( - { - prompt: `${Anthropic.HUMAN_PROMPT} Can you help me effectively ask for a raise at work?${Anthropic.AI_PROMPT}`, - max_tokens_to_sample: 300, - model: 'claude-2.1', - }, - { - maxRetries: 5, - }, -); +await anthropic.messages.create({ max_tokens: 1024, messages: [{ role: 'user', content: 'Can you help me effectively ask for a raise at work?' }], model: 'claude-2.1' }, { + maxRetries: 5, +}); ``` ### Timeouts @@ -212,16 +207,9 @@ const anthropic = new Anthropic({ }); // Override per-request: -await anthropic.completions.create( - { - prompt: `${Anthropic.HUMAN_PROMPT} Where can I get a good coffee in my neighbourhood?${Anthropic.AI_PROMPT}`, - max_tokens_to_sample: 300, - model: 'claude-2.1', - }, - { - timeout: 5 * 1000, - }, -); +await anthropic.messages.create({ max_tokens: 1024, messages: [{ role: 'user', content: 'Where can I get a good coffee in my neighbourhood?' }], model: 'claude-2.1' }, { + timeout: 5 * 1000, +}); ``` On timeout, an `APIConnectionTimeoutError` is thrown. @@ -241,11 +229,11 @@ import Anthropic from '@anthropic-ai/sdk'; const anthropic = new Anthropic(); -const completion = await anthropic.completions.create( +const message = await anthropic.messages.create( { - max_tokens_to_sample: 300, + max_tokens: 1024, + messages: [{ role: 'user', content: 'Where can I get a good coffee in my neighbourhood?' }], model: 'claude-2.1', - prompt: `${Anthropic.HUMAN_PROMPT} Where can I get a good coffee in my neighbourhood?${Anthropic.AI_PROMPT}`, }, { headers: { 'anthropic-version': 'My-Custom-Value' } }, ); @@ -263,19 +251,25 @@ You can also use the `.withResponse()` method to get the raw `Response` along wi ```ts const anthropic = new Anthropic(); -const response = await anthropic.completions +const response = await anthropic.messages .create({ - prompt: `${Anthropic.HUMAN_PROMPT} Can you help me effectively ask for a raise at work?${Anthropic.AI_PROMPT}`, - max_tokens_to_sample: 300, + max_tokens: 1024, + messages: [{ role: 'user', content: 'Where can I get a good coffee in my neighbourhood?' }], model: 'claude-2.1', }) .asResponse(); console.log(response.headers.get('X-My-Header')); -console.log(response.raw.statusText); // access the underlying Response object +console.log(response.statusText); // access the underlying Response object -// parses the response body, returning an object if the API responds with JSON -const completion: Completions.Completion = await response.parse(); -console.log(completion.completion); +const { data: message, response: raw } = await anthropic.messages + .create({ + max_tokens: 1024, + messages: [{ role: 'user', content: 'Where can I get a good coffee in my neighbourhood?' }], + model: 'claude-2.1', + }) + .withResponse(); +console.log(raw.headers.get('X-My-Header')); +console.log(message.content); ``` ## Customizing the fetch client @@ -325,7 +319,6 @@ If you would like to disable or customize this behavior, for example to use the ```ts import http from 'http'; -import Anthropic from '@anthropic-ai/sdk'; import HttpsProxyAgent from 'https-proxy-agent'; // Configure the default for all requests: @@ -334,17 +327,10 @@ const anthropic = new Anthropic({ }); // Override per-request: -await anthropic.completions.create( - { - prompt: `${Anthropic.HUMAN_PROMPT} How does a court case get to the Supreme Court?${Anthropic.AI_PROMPT}`, - max_tokens_to_sample: 300, - model: 'claude-2.1', - }, - { - baseURL: 'http://localhost:8080/test-api', - httpAgent: new http.Agent({ keepAlive: false }), - }, -); +await anthropic.messages.create({ max_tokens: 1024, messages: [{ role: 'user', content: 'Where can I get a good coffee in my neighbourhood?' }], model: 'claude-2.1' }, { + baseURL: 'http://localhost:8080/test-api', + httpAgent: new http.Agent({ keepAlive: false }), +}) ``` ## Semantic Versioning diff --git a/api.md b/api.md index b3685e6e..7006dbce 100644 --- a/api.md +++ b/api.md @@ -10,28 +10,26 @@ Methods: - client.completions.create({ ...params }) -> Completion -# Beta - -## Messages +# Messages Types: -- ContentBlock -- ContentBlockDeltaEvent -- ContentBlockStartEvent -- ContentBlockStopEvent -- Message -- MessageDeltaEvent -- MessageDeltaUsage -- MessageParam -- MessageStartEvent -- MessageStopEvent -- MessageStreamEvent -- TextBlock -- TextDelta -- Usage +- ContentBlock +- ContentBlockDeltaEvent +- ContentBlockStartEvent +- ContentBlockStopEvent +- Message +- MessageDeltaEvent +- MessageDeltaUsage +- MessageParam +- MessageStartEvent +- MessageStopEvent +- MessageStreamEvent +- TextBlock +- TextDelta +- Usage Methods: -- client.beta.messages.create({ ...params }) -> Message -- client.beta.messages.stream(body, options?) -> MessageStream +- client.messages.create({ ...params }) -> Message +- client.messages.stream(body, options?) -> MessageStream diff --git a/examples/streaming.ts b/examples/streaming.ts index beaaba13..a359b5b8 100755 --- a/examples/streaming.ts +++ b/examples/streaming.ts @@ -5,7 +5,7 @@ import Anthropic from '@anthropic-ai/sdk'; const client = new Anthropic(); // gets API Key from environment variable ANTHROPIC_API_KEY async function main() { - const stream = client.beta.messages + const stream = client.messages .stream({ messages: [ { diff --git a/helpers.md b/helpers.md index 2ee6b8f6..859d9442 100644 --- a/helpers.md +++ b/helpers.md @@ -3,14 +3,14 @@ ## Streaming Responses ```ts -anthropic.beta.messages.stream({ … }, options?): MessageStream +anthropic.messages.stream({ … }, options?): MessageStream ``` -`anthropic.beta.messages.stream()` returns a `MessageStream`, which emits events, has an async +`anthropic.messages.stream()` returns a `MessageStream`, which emits events, has an async iterator, and exposes helper methods to accumulate stream events into a convenient shape and make it easy to reason about the conversation. -Alternatively, you can use `anthropic.beta.messages.create({ stream: true, … })` which returns an async +Alternatively, you can use `anthropic.messages.create({ stream: true, … })` which returns an async iterable of the chunks in the stream and uses less memory (most notably, it does not accumulate a message object for you). diff --git a/packages/vertex-sdk/README.md b/packages/vertex-sdk/README.md index 6975aa04..6f09d6d7 100644 --- a/packages/vertex-sdk/README.md +++ b/packages/vertex-sdk/README.md @@ -28,7 +28,7 @@ import { AnthropicVertex } from '@anthropic-ai/vertex-sdk'; const client = new AnthropicVertex(); async function main() { - const result = await client.beta.messages.create({ + const result = await client.messages.create({ messages: [ { role: 'user', diff --git a/packages/vertex-sdk/examples/vertex.ts b/packages/vertex-sdk/examples/vertex.ts index 41434412..f8bfacef 100644 --- a/packages/vertex-sdk/examples/vertex.ts +++ b/packages/vertex-sdk/examples/vertex.ts @@ -7,7 +7,7 @@ import { AnthropicVertex } from '@anthropic-ai/vertex-sdk'; const client = new AnthropicVertex(); async function main() { - const result = await client.beta.messages.create({ + const result = await client.messages.create({ messages: [ { role: 'user', diff --git a/packages/vertex-sdk/scripts/postprocess-dist-package-json.cjs b/packages/vertex-sdk/scripts/postprocess-dist-package-json.cjs index 12a41324..0645ae09 100644 --- a/packages/vertex-sdk/scripts/postprocess-dist-package-json.cjs +++ b/packages/vertex-sdk/scripts/postprocess-dist-package-json.cjs @@ -4,7 +4,7 @@ const pkgJson = require('../dist/package.json'); for (const dep in pkgJson.dependencies) { // ensure we point to NPM instead of a local directory if (dep === '@anthropic-ai/sdk') { - pkgJson.dependencies[dep] = '^0'; + pkgJson.dependencies[dep] = '^0.14'; } } diff --git a/packages/vertex-sdk/src/client.ts b/packages/vertex-sdk/src/client.ts index 617083bc..5897175f 100644 --- a/packages/vertex-sdk/src/client.ts +++ b/packages/vertex-sdk/src/client.ts @@ -70,7 +70,7 @@ export class AnthropicVertex extends Core.APIClient { this._authClientPromise = this._auth.getClient(); } - beta: Resources.Beta = new Resources.Beta(this); + messages: Resources.Messages = new Resources.Messages(this); protected override defaultQuery(): Core.DefaultQuery | undefined { return this._options.defaultQuery; diff --git a/src/index.ts b/src/index.ts index 6c3c4955..30263e32 100644 --- a/src/index.ts +++ b/src/index.ts @@ -121,7 +121,7 @@ export class Anthropic extends Core.APIClient { } completions: API.Completions = new API.Completions(this); - beta: API.Beta = new API.Beta(this); + messages: API.Messages = new API.Messages(this); protected override defaultQuery(): Core.DefaultQuery | undefined { return this._options.defaultQuery; @@ -236,7 +236,25 @@ export namespace Anthropic { export import CompletionCreateParamsNonStreaming = API.CompletionCreateParamsNonStreaming; export import CompletionCreateParamsStreaming = API.CompletionCreateParamsStreaming; - export import Beta = API.Beta; + export import Messages = API.Messages; + export import ContentBlock = API.ContentBlock; + export import ContentBlockDeltaEvent = API.ContentBlockDeltaEvent; + export import ContentBlockStartEvent = API.ContentBlockStartEvent; + export import ContentBlockStopEvent = API.ContentBlockStopEvent; + export import Message = API.Message; + export import MessageDeltaEvent = API.MessageDeltaEvent; + export import MessageDeltaUsage = API.MessageDeltaUsage; + export import MessageParam = API.MessageParam; + export import MessageStartEvent = API.MessageStartEvent; + export import MessageStopEvent = API.MessageStopEvent; + export import MessageStreamEvent = API.MessageStreamEvent; + export import TextBlock = API.TextBlock; + export import TextDelta = API.TextDelta; + export import Usage = API.Usage; + export import MessageCreateParams = API.MessageCreateParams; + export import MessageCreateParamsNonStreaming = API.MessageCreateParamsNonStreaming; + export import MessageCreateParamsStreaming = API.MessageCreateParamsStreaming; + export import MessageStreamParams = API.MessageStreamParams; } export default Anthropic; diff --git a/src/lib/MessageStream.ts b/src/lib/MessageStream.ts index 351cb944..0ffdd5be 100644 --- a/src/lib/MessageStream.ts +++ b/src/lib/MessageStream.ts @@ -8,7 +8,7 @@ import { MessageParam, MessageCreateParams, MessageStreamParams, -} from '@anthropic-ai/sdk/resources/beta/messages'; +} from '@anthropic-ai/sdk/resources/messages'; import { type ReadableStream } from '@anthropic-ai/sdk/_shims/index'; import { Stream } from '@anthropic-ai/sdk/streaming'; diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts deleted file mode 100644 index 8dafcaf3..00000000 --- a/src/resources/beta/beta.ts +++ /dev/null @@ -1,30 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -import { APIResource } from '@anthropic-ai/sdk/resource'; -import * as MessagesAPI from '@anthropic-ai/sdk/resources/beta/messages'; - -export class Beta extends APIResource { - messages: MessagesAPI.Messages = new MessagesAPI.Messages(this._client); -} - -export namespace Beta { - export import Messages = MessagesAPI.Messages; - export import ContentBlock = MessagesAPI.ContentBlock; - export import ContentBlockDeltaEvent = MessagesAPI.ContentBlockDeltaEvent; - export import ContentBlockStartEvent = MessagesAPI.ContentBlockStartEvent; - export import ContentBlockStopEvent = MessagesAPI.ContentBlockStopEvent; - export import Message = MessagesAPI.Message; - export import MessageDeltaEvent = MessagesAPI.MessageDeltaEvent; - export import MessageDeltaUsage = MessagesAPI.MessageDeltaUsage; - export import MessageParam = MessagesAPI.MessageParam; - export import MessageStartEvent = MessagesAPI.MessageStartEvent; - export import MessageStopEvent = MessagesAPI.MessageStopEvent; - export import MessageStreamEvent = MessagesAPI.MessageStreamEvent; - export import TextBlock = MessagesAPI.TextBlock; - export import TextDelta = MessagesAPI.TextDelta; - export import Usage = MessagesAPI.Usage; - export import MessageCreateParams = MessagesAPI.MessageCreateParams; - export import MessageCreateParamsNonStreaming = MessagesAPI.MessageCreateParamsNonStreaming; - export import MessageCreateParamsStreaming = MessagesAPI.MessageCreateParamsStreaming; - export import MessageStreamParams = MessagesAPI.MessageStreamParams; -} diff --git a/src/resources/beta/index.ts b/src/resources/beta/index.ts deleted file mode 100644 index 54305259..00000000 --- a/src/resources/beta/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -export { Beta } from './beta'; -export { - ContentBlock, - ContentBlockDeltaEvent, - ContentBlockStartEvent, - ContentBlockStopEvent, - Message, - MessageDeltaEvent, - MessageDeltaUsage, - MessageParam, - MessageStartEvent, - MessageStopEvent, - MessageStreamEvent, - TextBlock, - TextDelta, - Usage, - MessageCreateParams, - MessageCreateParamsNonStreaming, - MessageCreateParamsStreaming, - MessageStreamParams, - Messages, -} from './messages'; diff --git a/src/resources/index.ts b/src/resources/index.ts index d1bfa08c..4a53acb8 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -1,6 +1,5 @@ // File generated from our OpenAPI spec by Stainless. -export { Beta } from './beta/beta'; export { Completion, CompletionCreateParams, @@ -8,3 +7,24 @@ export { CompletionCreateParamsStreaming, Completions, } from './completions'; +export { + ContentBlock, + ContentBlockDeltaEvent, + ContentBlockStartEvent, + ContentBlockStopEvent, + Message, + MessageDeltaEvent, + MessageDeltaUsage, + MessageParam, + MessageStartEvent, + MessageStopEvent, + MessageStreamEvent, + TextBlock, + TextDelta, + Usage, + MessageCreateParams, + MessageCreateParamsNonStreaming, + MessageCreateParamsStreaming, + MessageStreamParams, + Messages, +} from './messages'; diff --git a/src/resources/beta/messages.ts b/src/resources/messages.ts similarity index 96% rename from src/resources/beta/messages.ts rename to src/resources/messages.ts index c759b716..b8531904 100644 --- a/src/resources/beta/messages.ts +++ b/src/resources/messages.ts @@ -5,7 +5,7 @@ import { APIPromise } from '@anthropic-ai/sdk/core'; import { APIResource } from '@anthropic-ai/sdk/resource'; import { MessageStream } from '@anthropic-ai/sdk/lib/MessageStream'; export { MessageStream } from '@anthropic-ai/sdk/lib/MessageStream'; -import * as MessagesAPI from '@anthropic-ai/sdk/resources/beta/messages'; +import * as MessagesAPI from '@anthropic-ai/sdk/resources/messages'; import { Stream } from '@anthropic-ai/sdk/streaming'; export class Messages extends APIResource { @@ -17,10 +17,6 @@ export class Messages extends APIResource { * * Messages can be used for either single queries to the model or for multi-turn * conversations. - * - * The Messages API is currently in beta. During beta, you must send the - * `anthropic-beta: messages-2023-12-15` header in your requests. If you are using - * our client SDKs, this is handled for you automatically. */ create(body: MessageCreateParamsNonStreaming, options?: Core.RequestOptions): APIPromise; create( @@ -39,7 +35,6 @@ export class Messages extends APIResource { body, timeout: 600000, ...options, - headers: { 'Anthropic-Beta': 'messages-2023-12-15', ...options?.headers }, stream: body.stream ?? false, }) as APIPromise | APIPromise>; } @@ -314,9 +309,6 @@ export interface MessageCreateParamsBase { * { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } * ``` * - * During beta, the Messages API only accepts content blocks of type `"text"`, and - * at most one block per message. - * * See our * [guide to prompt design](https://docs.anthropic.com/claude/docs/introduction-to-prompt-design) * for more details on how to best construct prompts. @@ -510,9 +502,6 @@ export interface MessageStreamParams { * { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } * ``` * - * During beta, the Messages API only accepts content blocks of type `"text"`, and - * at most one block per message. - * * See our * [guide to prompt design](https://docs.anthropic.com/claude/docs/introduction-to-prompt-design) * for more details on how to best construct prompts. diff --git a/tests/api-resources/beta/MessageStream.test.ts b/tests/api-resources/MessageStream.test.ts similarity index 98% rename from tests/api-resources/beta/MessageStream.test.ts rename to tests/api-resources/MessageStream.test.ts index 132242de..552771af 100644 --- a/tests/api-resources/beta/MessageStream.test.ts +++ b/tests/api-resources/MessageStream.test.ts @@ -1,7 +1,7 @@ import { PassThrough } from 'stream'; import { Response } from 'node-fetch'; import Anthropic, { APIUserAbortError } from '@anthropic-ai/sdk'; -import { Message, MessageStreamEvent } from '@anthropic-ai/sdk/resources/beta'; +import { Message, MessageStreamEvent } from '@anthropic-ai/sdk/resources/messages'; import { type RequestInfo, type RequestInit } from '@anthropic-ai/sdk/_shims/index'; type Fetch = (req: string | RequestInfo, init?: RequestInit) => Promise; @@ -126,7 +126,7 @@ describe('MessageStream class', () => { }), ); - const stream = anthropic.beta.messages.stream({ + const stream = anthropic.messages.stream({ max_tokens: 1024, model: 'claude-2.1', messages: [{ role: 'user', content: 'Say hello there!' }], @@ -311,7 +311,7 @@ describe('MessageStream class', () => { const anthropic = new Anthropic({ apiKey: '...', fetch }); - const stream = anthropic.beta.messages.stream({ + const stream = anthropic.messages.stream({ max_tokens: 1024, model: 'claude-2.1', messages: [{ role: 'user', content: 'Say hello there!' }], diff --git a/tests/api-resources/beta/messages.test.ts b/tests/api-resources/messages.test.ts similarity index 91% rename from tests/api-resources/beta/messages.test.ts rename to tests/api-resources/messages.test.ts index f1caecd0..ac2b1c96 100644 --- a/tests/api-resources/beta/messages.test.ts +++ b/tests/api-resources/messages.test.ts @@ -10,7 +10,7 @@ const anthropic = new Anthropic({ describe('resource messages', () => { test('create: only required params', async () => { - const responsePromise = anthropic.beta.messages.create({ + const responsePromise = anthropic.messages.create({ max_tokens: 1024, messages: [{ role: 'user', content: 'In one sentence, what is good about the color blue?' }], model: 'claude-2.1', @@ -25,7 +25,7 @@ describe('resource messages', () => { }); test('create: required and optional params', async () => { - const response = await anthropic.beta.messages.create({ + const response = await anthropic.messages.create({ max_tokens: 1024, messages: [{ role: 'user', content: 'In one sentence, what is good about the color blue?' }], model: 'claude-2.1',