From bf7c1fdaf3476d5c43079e8a0789ed0dd0c807a6 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Tue, 28 May 2024 20:23:56 +0100
Subject: [PATCH 1/8] docs(readme): add bundle size badge (#426)
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index a9db9e9b..86321dde 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Anthropic TypeScript API Library
-[![NPM version](https://img.shields.io/npm/v/@anthropic-ai/sdk.svg)](https://npmjs.org/package/@anthropic-ai/sdk)
+[![NPM version](https://img.shields.io/npm/v/@anthropic-ai/sdk.svg)](https://npmjs.org/package/@anthropic-ai/sdk) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/@anthropic-ai/sdk)
This library provides convenient access to the Anthropic REST API from server-side TypeScript or JavaScript.
From 1e367e4020fa4691c565c89bdfba40c2f6060871 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Thu, 30 May 2024 11:36:15 +0100
Subject: [PATCH 2/8] feat(api/types): add stream event type aliases with a Raw
prefix (#428)
this change is mainly for consistency with the Python SDK as there is a
distinct difference between `Raw` and non-`Raw` types, see this PR for
more details: https://github.com/anthropics/anthropic-sdk-python/pull/528
---
api.md | 10 +++
src/index.ts | 7 ++
src/resources/beta/tools/index.ts | 3 +
src/resources/beta/tools/messages.ts | 59 ++++++++------
src/resources/beta/tools/tools.ts | 3 +
src/resources/index.ts | 7 ++
src/resources/messages.ts | 117 ++++++++++++++++-----------
7 files changed, 133 insertions(+), 73 deletions(-)
diff --git a/api.md b/api.md
index 12150d07..b6da31bc 100644
--- a/api.md
+++ b/api.md
@@ -16,6 +16,13 @@ Types:
- MessageStartEvent
- MessageStopEvent
- MessageStreamEvent
+- RawContentBlockDeltaEvent
+- RawContentBlockStartEvent
+- RawContentBlockStopEvent
+- RawMessageDeltaEvent
+- RawMessageStartEvent
+- RawMessageStopEvent
+- RawMessageStreamEvent
- TextBlock
- TextBlockParam
- TextDelta
@@ -35,6 +42,9 @@ Methods:
Types:
- InputJsonDelta
+- RawToolsBetaContentBlockDeltaEvent
+- RawToolsBetaContentBlockStartEvent
+- RawToolsBetaMessageStreamEvent
- Tool
- ToolResultBlockParam
- ToolUseBlock
diff --git a/src/index.ts b/src/index.ts
index 481f800f..ea5552cc 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -249,6 +249,13 @@ export namespace Anthropic {
export import MessageStartEvent = API.MessageStartEvent;
export import MessageStopEvent = API.MessageStopEvent;
export import MessageStreamEvent = API.MessageStreamEvent;
+ export import RawContentBlockDeltaEvent = API.RawContentBlockDeltaEvent;
+ export import RawContentBlockStartEvent = API.RawContentBlockStartEvent;
+ export import RawContentBlockStopEvent = API.RawContentBlockStopEvent;
+ export import RawMessageDeltaEvent = API.RawMessageDeltaEvent;
+ export import RawMessageStartEvent = API.RawMessageStartEvent;
+ export import RawMessageStopEvent = API.RawMessageStopEvent;
+ export import RawMessageStreamEvent = API.RawMessageStreamEvent;
export import TextBlock = API.TextBlock;
export import TextBlockParam = API.TextBlockParam;
export import TextDelta = API.TextDelta;
diff --git a/src/resources/beta/tools/index.ts b/src/resources/beta/tools/index.ts
index fb831369..7a43efaa 100644
--- a/src/resources/beta/tools/index.ts
+++ b/src/resources/beta/tools/index.ts
@@ -2,6 +2,9 @@
export {
InputJsonDelta,
+ RawToolsBetaContentBlockDeltaEvent,
+ RawToolsBetaContentBlockStartEvent,
+ RawToolsBetaMessageStreamEvent,
Tool,
ToolResultBlockParam,
ToolUseBlock,
diff --git a/src/resources/beta/tools/messages.ts b/src/resources/beta/tools/messages.ts
index 8be4ba82..31269911 100644
--- a/src/resources/beta/tools/messages.ts
+++ b/src/resources/beta/tools/messages.ts
@@ -23,22 +23,22 @@ export class Messages extends APIResource {
create(
body: MessageCreateParamsStreaming,
options?: Core.RequestOptions,
- ): APIPromise>;
+ ): APIPromise>;
create(
body: MessageCreateParamsBase,
options?: Core.RequestOptions,
- ): APIPromise | ToolsBetaMessage>;
+ ): APIPromise | ToolsBetaMessage>;
create(
body: MessageCreateParams,
options?: Core.RequestOptions,
- ): APIPromise | APIPromise> {
+ ): APIPromise | APIPromise> {
return this._client.post('/v1/messages?beta=tools', {
body,
timeout: 600000,
...options,
headers: { 'anthropic-beta': 'tools-2024-05-16', ...options?.headers },
stream: body.stream ?? false,
- }) as APIPromise | APIPromise>;
+ }) as APIPromise | APIPromise>;
}
/**
@@ -55,6 +55,30 @@ export interface InputJsonDelta {
type: 'input_json_delta';
}
+export interface RawToolsBetaContentBlockDeltaEvent {
+ delta: MessagesAPI.TextDelta | InputJsonDelta;
+
+ index: number;
+
+ type: 'content_block_delta';
+}
+
+export interface RawToolsBetaContentBlockStartEvent {
+ content_block: MessagesAPI.TextBlock | ToolUseBlock;
+
+ index: number;
+
+ type: 'content_block_start';
+}
+
+export type RawToolsBetaMessageStreamEvent =
+ | MessagesAPI.RawMessageStartEvent
+ | MessagesAPI.RawMessageDeltaEvent
+ | MessagesAPI.RawMessageStopEvent
+ | RawToolsBetaContentBlockStartEvent
+ | RawToolsBetaContentBlockDeltaEvent
+ | MessagesAPI.RawContentBlockStopEvent;
+
export interface Tool {
/**
* [JSON schema](https://json-schema.org/) for this tool's input.
@@ -124,21 +148,9 @@ export interface ToolUseBlockParam {
export type ToolsBetaContentBlock = MessagesAPI.TextBlock | ToolUseBlock;
-export interface ToolsBetaContentBlockDeltaEvent {
- delta: MessagesAPI.TextDelta | InputJsonDelta;
-
- index: number;
-
- type: 'content_block_delta';
-}
+export type ToolsBetaContentBlockDeltaEvent = RawToolsBetaContentBlockDeltaEvent;
-export interface ToolsBetaContentBlockStartEvent {
- content_block: MessagesAPI.TextBlock | ToolUseBlock;
-
- index: number;
-
- type: 'content_block_start';
-}
+export type ToolsBetaContentBlockStartEvent = RawToolsBetaContentBlockStartEvent;
export interface ToolsBetaMessage {
/**
@@ -253,13 +265,7 @@ export interface ToolsBetaMessageParam {
role: 'user' | 'assistant';
}
-export type ToolsBetaMessageStreamEvent =
- | MessagesAPI.MessageStartEvent
- | MessagesAPI.MessageDeltaEvent
- | MessagesAPI.MessageStopEvent
- | ToolsBetaContentBlockStartEvent
- | ToolsBetaContentBlockDeltaEvent
- | MessagesAPI.ContentBlockStopEvent;
+export type ToolsBetaMessageStreamEvent = RawToolsBetaMessageStreamEvent;
export type MessageCreateParams = MessageCreateParamsNonStreaming | MessageCreateParamsStreaming;
@@ -890,6 +896,9 @@ export namespace MessageStreamParams {
export namespace Messages {
export import InputJsonDelta = ToolsMessagesAPI.InputJsonDelta;
+ export import RawToolsBetaContentBlockDeltaEvent = ToolsMessagesAPI.RawToolsBetaContentBlockDeltaEvent;
+ export import RawToolsBetaContentBlockStartEvent = ToolsMessagesAPI.RawToolsBetaContentBlockStartEvent;
+ export import RawToolsBetaMessageStreamEvent = ToolsMessagesAPI.RawToolsBetaMessageStreamEvent;
export import Tool = ToolsMessagesAPI.Tool;
export import ToolResultBlockParam = ToolsMessagesAPI.ToolResultBlockParam;
export import ToolUseBlock = ToolsMessagesAPI.ToolUseBlock;
diff --git a/src/resources/beta/tools/tools.ts b/src/resources/beta/tools/tools.ts
index f3bd8009..6522ce69 100644
--- a/src/resources/beta/tools/tools.ts
+++ b/src/resources/beta/tools/tools.ts
@@ -10,6 +10,9 @@ export class Tools extends APIResource {
export namespace Tools {
export import Messages = MessagesAPI.Messages;
export import InputJsonDelta = MessagesAPI.InputJsonDelta;
+ export import RawToolsBetaContentBlockDeltaEvent = MessagesAPI.RawToolsBetaContentBlockDeltaEvent;
+ export import RawToolsBetaContentBlockStartEvent = MessagesAPI.RawToolsBetaContentBlockStartEvent;
+ export import RawToolsBetaMessageStreamEvent = MessagesAPI.RawToolsBetaMessageStreamEvent;
export import Tool = MessagesAPI.Tool;
export import ToolResultBlockParam = MessagesAPI.ToolResultBlockParam;
export import ToolUseBlock = MessagesAPI.ToolUseBlock;
diff --git a/src/resources/index.ts b/src/resources/index.ts
index 360cb01e..8a2302f3 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -21,6 +21,13 @@ export {
MessageStartEvent,
MessageStopEvent,
MessageStreamEvent,
+ RawContentBlockDeltaEvent,
+ RawContentBlockStartEvent,
+ RawContentBlockStopEvent,
+ RawMessageDeltaEvent,
+ RawMessageStartEvent,
+ RawMessageStopEvent,
+ RawMessageStreamEvent,
TextBlock,
TextBlockParam,
TextDelta,
diff --git a/src/resources/messages.ts b/src/resources/messages.ts
index 9fa36f14..439e3bdc 100644
--- a/src/resources/messages.ts
+++ b/src/resources/messages.ts
@@ -22,21 +22,21 @@ export class Messages extends APIResource {
create(
body: MessageCreateParamsStreaming,
options?: Core.RequestOptions,
- ): APIPromise>;
+ ): APIPromise>;
create(
body: MessageCreateParamsBase,
options?: Core.RequestOptions,
- ): APIPromise | Message>;
+ ): APIPromise | Message>;
create(
body: MessageCreateParams,
options?: Core.RequestOptions,
- ): APIPromise | APIPromise> {
+ ): APIPromise | APIPromise> {
return this._client.post('/v1/messages', {
body,
timeout: 600000,
...options,
stream: body.stream ?? false,
- }) as APIPromise | APIPromise>;
+ }) as APIPromise | APIPromise>;
}
/**
@@ -49,27 +49,11 @@ export class Messages extends APIResource {
export type ContentBlock = TextBlock;
-export interface ContentBlockDeltaEvent {
- delta: TextDelta;
+export type ContentBlockDeltaEvent = RawContentBlockDeltaEvent;
- index: number;
+export type ContentBlockStartEvent = RawContentBlockStartEvent;
- type: 'content_block_delta';
-}
-
-export interface ContentBlockStartEvent {
- content_block: TextBlock;
-
- index: number;
-
- type: 'content_block_start';
-}
-
-export interface ContentBlockStopEvent {
- index: number;
-
- type: 'content_block_stop';
-}
+export type ContentBlockStopEvent = RawContentBlockStopEvent;
export interface ImageBlockParam {
source: ImageBlockParam.Source;
@@ -189,8 +173,51 @@ export interface Message {
usage: Usage;
}
-export interface MessageDeltaEvent {
- delta: MessageDeltaEvent.Delta;
+export type MessageDeltaEvent = RawMessageDeltaEvent;
+
+export interface MessageDeltaUsage {
+ /**
+ * The cumulative number of output tokens which were used.
+ */
+ output_tokens: number;
+}
+
+export interface MessageParam {
+ content: string | Array;
+
+ role: 'user' | 'assistant';
+}
+
+export type MessageStartEvent = RawMessageStartEvent;
+
+export type MessageStopEvent = RawMessageStopEvent;
+
+export type MessageStreamEvent = RawMessageStreamEvent;
+
+export interface RawContentBlockDeltaEvent {
+ delta: TextDelta;
+
+ index: number;
+
+ type: 'content_block_delta';
+}
+
+export interface RawContentBlockStartEvent {
+ content_block: TextBlock;
+
+ index: number;
+
+ type: 'content_block_start';
+}
+
+export interface RawContentBlockStopEvent {
+ index: number;
+
+ type: 'content_block_stop';
+}
+
+export interface RawMessageDeltaEvent {
+ delta: RawMessageDeltaEvent.Delta;
type: 'message_delta';
@@ -211,7 +238,7 @@ export interface MessageDeltaEvent {
usage: MessageDeltaUsage;
}
-export namespace MessageDeltaEvent {
+export namespace RawMessageDeltaEvent {
export interface Delta {
stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | null;
@@ -219,36 +246,23 @@ export namespace MessageDeltaEvent {
}
}
-export interface MessageDeltaUsage {
- /**
- * The cumulative number of output tokens which were used.
- */
- output_tokens: number;
-}
-
-export interface MessageParam {
- content: string | Array;
-
- role: 'user' | 'assistant';
-}
-
-export interface MessageStartEvent {
+export interface RawMessageStartEvent {
message: Message;
type: 'message_start';
}
-export interface MessageStopEvent {
+export interface RawMessageStopEvent {
type: 'message_stop';
}
-export type MessageStreamEvent =
- | MessageStartEvent
- | MessageDeltaEvent
- | MessageStopEvent
- | ContentBlockStartEvent
- | ContentBlockDeltaEvent
- | ContentBlockStopEvent;
+export type RawMessageStreamEvent =
+ | RawMessageStartEvent
+ | RawMessageDeltaEvent
+ | RawMessageStopEvent
+ | RawContentBlockStartEvent
+ | RawContentBlockDeltaEvent
+ | RawContentBlockStopEvent;
export interface TextBlock {
text: string;
@@ -718,6 +732,13 @@ export namespace Messages {
export import MessageStartEvent = MessagesAPI.MessageStartEvent;
export import MessageStopEvent = MessagesAPI.MessageStopEvent;
export import MessageStreamEvent = MessagesAPI.MessageStreamEvent;
+ export import RawContentBlockDeltaEvent = MessagesAPI.RawContentBlockDeltaEvent;
+ export import RawContentBlockStartEvent = MessagesAPI.RawContentBlockStartEvent;
+ export import RawContentBlockStopEvent = MessagesAPI.RawContentBlockStopEvent;
+ export import RawMessageDeltaEvent = MessagesAPI.RawMessageDeltaEvent;
+ export import RawMessageStartEvent = MessagesAPI.RawMessageStartEvent;
+ export import RawMessageStopEvent = MessagesAPI.RawMessageStopEvent;
+ export import RawMessageStreamEvent = MessagesAPI.RawMessageStreamEvent;
export import TextBlock = MessagesAPI.TextBlock;
export import TextBlockParam = MessagesAPI.TextBlockParam;
export import TextDelta = MessagesAPI.TextDelta;
From 2decf85e7471932dad98c21d4ed2d476ab1588a6 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Thu, 30 May 2024 16:31:40 +0100
Subject: [PATCH 3/8] feat(api): tool use is GA and available on 3P (#429)
---
.stats.yml | 4 +-
api.md | 33 +-
src/index.ts | 8 +-
src/resources/beta/beta.ts | 12 -
src/resources/beta/index.ts | 4 -
src/resources/beta/tools/index.ts | 24 -
src/resources/beta/tools/messages.ts | 916 ------------------
src/resources/beta/tools/tools.ts | 30 -
src/resources/index.ts | 6 +-
src/resources/messages.ts | 202 +++-
.../api-resources/beta/tools/messages.test.ts | 77 --
tests/api-resources/messages.test.ts | 36 +
12 files changed, 247 insertions(+), 1105 deletions(-)
delete mode 100644 src/resources/beta/beta.ts
delete mode 100644 src/resources/beta/index.ts
delete mode 100644 src/resources/beta/tools/index.ts
delete mode 100644 src/resources/beta/tools/messages.ts
delete mode 100644 src/resources/beta/tools/tools.ts
delete mode 100644 tests/api-resources/beta/tools/messages.test.ts
diff --git a/.stats.yml b/.stats.yml
index e3a48530..660e6d2d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
-configured_endpoints: 3
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-11e9f674e1fe0eb85a713c2852de663254d4e9254dea701008dcd605a04987d5.yml
+configured_endpoints: 2
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-4f6df1026ffeed840bbfada906ac51144508d1e1b099084c593aa9bac97a3362.yml
diff --git a/api.md b/api.md
index b6da31bc..7c732d1d 100644
--- a/api.md
+++ b/api.md
@@ -9,6 +9,7 @@ Types:
- ContentBlockStartEvent
- ContentBlockStopEvent
- ImageBlockParam
+- InputJsonDelta
- Message
- MessageDeltaEvent
- MessageDeltaUsage
@@ -26,37 +27,13 @@ Types:
- TextBlock
- TextBlockParam
- TextDelta
+- Tool
+- ToolResultBlockParam
+- ToolUseBlock
+- ToolUseBlockParam
- Usage
Methods:
- client.messages.create({ ...params }) -> Message
- client.messages.stream(body, options?) -> MessageStream
-
-# Beta
-
-## Tools
-
-### Messages
-
-Types:
-
-- InputJsonDelta
-- RawToolsBetaContentBlockDeltaEvent
-- RawToolsBetaContentBlockStartEvent
-- RawToolsBetaMessageStreamEvent
-- Tool
-- ToolResultBlockParam
-- ToolUseBlock
-- ToolUseBlockParam
-- ToolsBetaContentBlock
-- ToolsBetaContentBlockDeltaEvent
-- ToolsBetaContentBlockStartEvent
-- ToolsBetaMessage
-- ToolsBetaMessageParam
-- ToolsBetaMessageStreamEvent
-
-Methods:
-
-- client.beta.tools.messages.create({ ...params }) -> ToolsBetaMessage
-- client.beta.tools.messages.stream(body, options?) -> ToolsBetaMessageStream
diff --git a/src/index.ts b/src/index.ts
index ea5552cc..65c0bc20 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -122,7 +122,6 @@ export class Anthropic extends Core.APIClient {
completions: API.Completions = new API.Completions(this);
messages: API.Messages = new API.Messages(this);
- beta: API.Beta = new API.Beta(this);
protected override defaultQuery(): Core.DefaultQuery | undefined {
return this._options.defaultQuery;
@@ -242,6 +241,7 @@ export namespace Anthropic {
export import ContentBlockStartEvent = API.ContentBlockStartEvent;
export import ContentBlockStopEvent = API.ContentBlockStopEvent;
export import ImageBlockParam = API.ImageBlockParam;
+ export import InputJsonDelta = API.InputJsonDelta;
export import Message = API.Message;
export import MessageDeltaEvent = API.MessageDeltaEvent;
export import MessageDeltaUsage = API.MessageDeltaUsage;
@@ -259,13 +259,15 @@ export namespace Anthropic {
export import TextBlock = API.TextBlock;
export import TextBlockParam = API.TextBlockParam;
export import TextDelta = API.TextDelta;
+ export import Tool = API.Tool;
+ export import ToolResultBlockParam = API.ToolResultBlockParam;
+ export import ToolUseBlock = API.ToolUseBlock;
+ export import ToolUseBlockParam = API.ToolUseBlockParam;
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 import Beta = API.Beta;
}
export default Anthropic;
diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts
deleted file mode 100644
index 6e73e5ae..00000000
--- a/src/resources/beta/beta.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '@anthropic-ai/sdk/resource';
-import * as ToolsAPI from '@anthropic-ai/sdk/resources/beta/tools/tools';
-
-export class Beta extends APIResource {
- tools: ToolsAPI.Tools = new ToolsAPI.Tools(this._client);
-}
-
-export namespace Beta {
- export import Tools = ToolsAPI.Tools;
-}
diff --git a/src/resources/beta/index.ts b/src/resources/beta/index.ts
deleted file mode 100644
index 670f3861..00000000
--- a/src/resources/beta/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export { Beta } from './beta';
-export { Tools } from './tools/index';
diff --git a/src/resources/beta/tools/index.ts b/src/resources/beta/tools/index.ts
deleted file mode 100644
index 7a43efaa..00000000
--- a/src/resources/beta/tools/index.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-export {
- InputJsonDelta,
- RawToolsBetaContentBlockDeltaEvent,
- RawToolsBetaContentBlockStartEvent,
- RawToolsBetaMessageStreamEvent,
- Tool,
- ToolResultBlockParam,
- ToolUseBlock,
- ToolUseBlockParam,
- ToolsBetaContentBlock,
- ToolsBetaContentBlockDeltaEvent,
- ToolsBetaContentBlockStartEvent,
- ToolsBetaMessage,
- ToolsBetaMessageParam,
- ToolsBetaMessageStreamEvent,
- MessageCreateParams,
- MessageCreateParamsNonStreaming,
- MessageCreateParamsStreaming,
- MessageStreamParams,
- Messages,
-} from './messages';
-export { Tools } from './tools';
diff --git a/src/resources/beta/tools/messages.ts b/src/resources/beta/tools/messages.ts
deleted file mode 100644
index 31269911..00000000
--- a/src/resources/beta/tools/messages.ts
+++ /dev/null
@@ -1,916 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import * as Core from '@anthropic-ai/sdk/core';
-import { APIPromise } from '@anthropic-ai/sdk/core';
-import { APIResource } from '@anthropic-ai/sdk/resource';
-import { ToolsBetaMessageStream } from '@anthropic-ai/sdk/lib/ToolsBetaMessageStream';
-export { ToolsBetaMessageStream } from '@anthropic-ai/sdk/lib/ToolsBetaMessageStream';
-import * as ToolsMessagesAPI from '@anthropic-ai/sdk/resources/beta/tools/messages';
-import * as MessagesAPI from '@anthropic-ai/sdk/resources/messages';
-import { Stream } from '@anthropic-ai/sdk/streaming';
-
-export class Messages extends APIResource {
- /**
- * Create a Message.
- *
- * Send a structured list of input messages with text and/or image content, and the
- * model will generate the next message in the conversation.
- *
- * The Messages API can be used for either single queries or stateless multi-turn
- * conversations.
- */
- create(body: MessageCreateParamsNonStreaming, options?: Core.RequestOptions): APIPromise;
- create(
- body: MessageCreateParamsStreaming,
- options?: Core.RequestOptions,
- ): APIPromise>;
- create(
- body: MessageCreateParamsBase,
- options?: Core.RequestOptions,
- ): APIPromise | ToolsBetaMessage>;
- create(
- body: MessageCreateParams,
- options?: Core.RequestOptions,
- ): APIPromise | APIPromise> {
- return this._client.post('/v1/messages?beta=tools', {
- body,
- timeout: 600000,
- ...options,
- headers: { 'anthropic-beta': 'tools-2024-05-16', ...options?.headers },
- stream: body.stream ?? false,
- }) as APIPromise | APIPromise>;
- }
-
- /**
- * Create a Message stream
- */
- stream(body: MessageStreamParams, options?: Core.RequestOptions): ToolsBetaMessageStream {
- return ToolsBetaMessageStream.createMessage(this, body, options);
- }
-}
-
-export interface InputJsonDelta {
- partial_json: string;
-
- type: 'input_json_delta';
-}
-
-export interface RawToolsBetaContentBlockDeltaEvent {
- delta: MessagesAPI.TextDelta | InputJsonDelta;
-
- index: number;
-
- type: 'content_block_delta';
-}
-
-export interface RawToolsBetaContentBlockStartEvent {
- content_block: MessagesAPI.TextBlock | ToolUseBlock;
-
- index: number;
-
- type: 'content_block_start';
-}
-
-export type RawToolsBetaMessageStreamEvent =
- | MessagesAPI.RawMessageStartEvent
- | MessagesAPI.RawMessageDeltaEvent
- | MessagesAPI.RawMessageStopEvent
- | RawToolsBetaContentBlockStartEvent
- | RawToolsBetaContentBlockDeltaEvent
- | MessagesAPI.RawContentBlockStopEvent;
-
-export interface Tool {
- /**
- * [JSON schema](https://json-schema.org/) for this tool's input.
- *
- * This defines the shape of the `input` that your tool accepts and that the model
- * will produce.
- */
- input_schema: Tool.InputSchema;
-
- name: string;
-
- /**
- * Description of what this tool does.
- *
- * Tool descriptions should be as detailed as possible. The more information that
- * the model has about what the tool is and how to use it, the better it will
- * perform. You can use natural language descriptions to reinforce important
- * aspects of the tool input JSON schema.
- */
- description?: string;
-}
-
-export namespace Tool {
- /**
- * [JSON schema](https://json-schema.org/) for this tool's input.
- *
- * This defines the shape of the `input` that your tool accepts and that the model
- * will produce.
- */
- export interface InputSchema {
- type: 'object';
-
- properties?: unknown | null;
- [k: string]: unknown;
- }
-}
-
-export interface ToolResultBlockParam {
- tool_use_id: string;
-
- type: 'tool_result';
-
- content?: Array;
-
- is_error?: boolean;
-}
-
-export interface ToolUseBlock {
- id: string;
-
- input: unknown;
-
- name: string;
-
- type: 'tool_use';
-}
-
-export interface ToolUseBlockParam {
- id: string;
-
- input: unknown;
-
- name: string;
-
- type: 'tool_use';
-}
-
-export type ToolsBetaContentBlock = MessagesAPI.TextBlock | ToolUseBlock;
-
-export type ToolsBetaContentBlockDeltaEvent = RawToolsBetaContentBlockDeltaEvent;
-
-export type ToolsBetaContentBlockStartEvent = RawToolsBetaContentBlockStartEvent;
-
-export interface ToolsBetaMessage {
- /**
- * Unique object identifier.
- *
- * The format and length of IDs may change over time.
- */
- id: string;
-
- /**
- * Content generated by the model.
- *
- * This is an array of content blocks, each of which has a `type` that determines
- * its shape. Currently, the only `type` in responses is `"text"`.
- *
- * Example:
- *
- * ```json
- * [{ "type": "text", "text": "Hi, I'm Claude." }]
- * ```
- *
- * If the request input `messages` ended with an `assistant` turn, then the
- * response `content` will continue directly from that last turn. You can use this
- * to constrain the model's output.
- *
- * For example, if the input `messages` were:
- *
- * ```json
- * [
- * {
- * "role": "user",
- * "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun"
- * },
- * { "role": "assistant", "content": "The best answer is (" }
- * ]
- * ```
- *
- * Then the response `content` might be:
- *
- * ```json
- * [{ "type": "text", "text": "B)" }]
- * ```
- */
- content: Array;
-
- /**
- * The model that handled the request.
- */
- model: string;
-
- /**
- * Conversational role of the generated message.
- *
- * This will always be `"assistant"`.
- */
- role: 'assistant';
-
- /**
- * The reason that we stopped.
- *
- * This may be one the following values:
- *
- * - `"end_turn"`: the model reached a natural stopping point
- * - `"max_tokens"`: we exceeded the requested `max_tokens` or the model's maximum
- * - `"stop_sequence"`: one of your provided custom `stop_sequences` was generated
- * - `"tool_use"`: (tools beta only) the model invoked one or more tools
- *
- * In non-streaming mode this value is always non-null. In streaming mode, it is
- * null in the `message_start` event and non-null otherwise.
- */
- stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | null;
-
- /**
- * Which custom stop sequence was generated, if any.
- *
- * This value will be a non-null string if one of your custom stop sequences was
- * generated.
- */
- stop_sequence: string | null;
-
- /**
- * Object type.
- *
- * For Messages, this is always `"message"`.
- */
- type: 'message';
-
- /**
- * Billing and rate-limit usage.
- *
- * Anthropic's API bills and rate-limits by token counts, as tokens represent the
- * underlying cost to our systems.
- *
- * Under the hood, the API transforms requests into a format suitable for the
- * model. The model's output then goes through a parsing stage before becoming an
- * API response. As a result, the token counts in `usage` will not match one-to-one
- * with the exact visible content of an API request or response.
- *
- * For example, `output_tokens` will be non-zero, even for an empty string response
- * from Claude.
- */
- usage: MessagesAPI.Usage;
-}
-
-export interface ToolsBetaMessageParam {
- content:
- | string
- | Array<
- MessagesAPI.TextBlockParam | MessagesAPI.ImageBlockParam | ToolUseBlockParam | ToolResultBlockParam
- >;
-
- role: 'user' | 'assistant';
-}
-
-export type ToolsBetaMessageStreamEvent = RawToolsBetaMessageStreamEvent;
-
-export type MessageCreateParams = MessageCreateParamsNonStreaming | MessageCreateParamsStreaming;
-
-export interface MessageCreateParamsBase {
- /**
- * The maximum number of tokens to generate before stopping.
- *
- * Note that our models may stop _before_ reaching this maximum. This parameter
- * only specifies the absolute maximum number of tokens to generate.
- *
- * Different models have different maximum values for this parameter. See
- * [models](https://docs.anthropic.com/en/docs/models-overview) for details.
- */
- max_tokens: number;
-
- /**
- * Input messages.
- *
- * Our models are trained to operate on alternating `user` and `assistant`
- * conversational turns. When creating a new `Message`, you specify the prior
- * conversational turns with the `messages` parameter, and the model then generates
- * the next `Message` in the conversation.
- *
- * Each input message must be an object with a `role` and `content`. You can
- * specify a single `user`-role message, or you can include multiple `user` and
- * `assistant` messages. The first message must always use the `user` role.
- *
- * If the final message uses the `assistant` role, the response content will
- * continue immediately from the content in that message. This can be used to
- * constrain part of the model's response.
- *
- * Example with a single `user` message:
- *
- * ```json
- * [{ "role": "user", "content": "Hello, Claude" }]
- * ```
- *
- * Example with multiple conversational turns:
- *
- * ```json
- * [
- * { "role": "user", "content": "Hello there." },
- * { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" },
- * { "role": "user", "content": "Can you explain LLMs in plain English?" }
- * ]
- * ```
- *
- * Example with a partially-filled response from Claude:
- *
- * ```json
- * [
- * {
- * "role": "user",
- * "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun"
- * },
- * { "role": "assistant", "content": "The best answer is (" }
- * ]
- * ```
- *
- * Each input message `content` may be either a single `string` or an array of
- * content blocks, where each block has a specific `type`. Using a `string` for
- * `content` is shorthand for an array of one content block of type `"text"`. The
- * following input messages are equivalent:
- *
- * ```json
- * { "role": "user", "content": "Hello, Claude" }
- * ```
- *
- * ```json
- * { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] }
- * ```
- *
- * Starting with Claude 3 models, you can also send image content blocks:
- *
- * ```json
- * {
- * "role": "user",
- * "content": [
- * {
- * "type": "image",
- * "source": {
- * "type": "base64",
- * "media_type": "image/jpeg",
- * "data": "/9j/4AAQSkZJRg..."
- * }
- * },
- * { "type": "text", "text": "What is in this image?" }
- * ]
- * }
- * ```
- *
- * We currently support the `base64` source type for images, and the `image/jpeg`,
- * `image/png`, `image/gif`, and `image/webp` media types.
- *
- * See [examples](https://docs.anthropic.com/en/api/messages-examples) for more
- * input examples.
- *
- * Note that if you want to include a
- * [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use
- * the top-level `system` parameter — there is no `"system"` role for input
- * messages in the Messages API.
- */
- messages: Array;
-
- /**
- * The model that will complete your prompt.
- *
- * See [models](https://docs.anthropic.com/en/docs/models-overview) for additional
- * details and options.
- */
- model: string;
-
- /**
- * An object describing metadata about the request.
- */
- metadata?: MessageCreateParams.Metadata;
-
- /**
- * Custom text sequences that will cause the model to stop generating.
- *
- * Our models will normally stop when they have naturally completed their turn,
- * which will result in a response `stop_reason` of `"end_turn"`.
- *
- * If you want the model to stop generating when it encounters custom strings of
- * text, you can use the `stop_sequences` parameter. If the model encounters one of
- * the custom sequences, the response `stop_reason` value will be `"stop_sequence"`
- * and the response `stop_sequence` value will contain the matched stop sequence.
- */
- stop_sequences?: Array;
-
- /**
- * Whether to incrementally stream the response using server-sent events.
- *
- * See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for
- * details.
- */
- stream?: boolean;
-
- /**
- * System prompt.
- *
- * A system prompt is a way of providing context and instructions to Claude, such
- * as specifying a particular goal or role. See our
- * [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts).
- */
- system?: string;
-
- /**
- * Amount of randomness injected into the response.
- *
- * Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0`
- * for analytical / multiple choice, and closer to `1.0` for creative and
- * generative tasks.
- *
- * Note that even with `temperature` of `0.0`, the results will not be fully
- * deterministic.
- */
- temperature?: number;
-
- /**
- * How the model should use the provided tools. The model can use a specific tool,
- * any available tool, or decide by itself.
- */
- tool_choice?:
- | MessageCreateParams.ToolChoiceAuto
- | MessageCreateParams.ToolChoiceAny
- | MessageCreateParams.ToolChoiceTool;
-
- /**
- * [beta] Definitions of tools that the model may use.
- *
- * If you include `tools` in your API request, the model may return `tool_use`
- * content blocks that represent the model's use of those tools. You can then run
- * those tools using the tool input generated by the model and then optionally
- * return results back to the model using `tool_result` content blocks.
- *
- * Each tool definition includes:
- *
- * - `name`: Name of the tool.
- * - `description`: Optional, but strongly-recommended description of the tool.
- * - `input_schema`: [JSON schema](https://json-schema.org/) for the tool `input`
- * shape that the model will produce in `tool_use` output content blocks.
- *
- * For example, if you defined `tools` as:
- *
- * ```json
- * [
- * {
- * "name": "get_stock_price",
- * "description": "Get the current stock price for a given ticker symbol.",
- * "input_schema": {
- * "type": "object",
- * "properties": {
- * "ticker": {
- * "type": "string",
- * "description": "The stock ticker symbol, e.g. AAPL for Apple Inc."
- * }
- * },
- * "required": ["ticker"]
- * }
- * }
- * ]
- * ```
- *
- * And then asked the model "What's the S&P 500 at today?", the model might produce
- * `tool_use` content blocks in the response like this:
- *
- * ```json
- * [
- * {
- * "type": "tool_use",
- * "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV",
- * "name": "get_stock_price",
- * "input": { "ticker": "^GSPC" }
- * }
- * ]
- * ```
- *
- * You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an
- * input, and return the following back to the model in a subsequent `user`
- * message:
- *
- * ```json
- * [
- * {
- * "type": "tool_result",
- * "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV",
- * "content": "259.75 USD"
- * }
- * ]
- * ```
- *
- * Tools can be used for workflows that include running client-side tools and
- * functions, or more generally whenever you want the model to produce a particular
- * JSON structure of output.
- *
- * See our [beta guide](https://docs.anthropic.com/en/docs/tool-use) for more
- * details.
- */
- tools?: Array;
-
- /**
- * Only sample from the top K options for each subsequent token.
- *
- * Used to remove "long tail" low probability responses.
- * [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277).
- *
- * Recommended for advanced use cases only. You usually only need to use
- * `temperature`.
- */
- top_k?: number;
-
- /**
- * Use nucleus sampling.
- *
- * In nucleus sampling, we compute the cumulative distribution over all the options
- * for each subsequent token in decreasing probability order and cut it off once it
- * reaches a particular probability specified by `top_p`. You should either alter
- * `temperature` or `top_p`, but not both.
- *
- * Recommended for advanced use cases only. You usually only need to use
- * `temperature`.
- */
- top_p?: number;
-}
-
-export namespace MessageCreateParams {
- /**
- * An object describing metadata about the request.
- */
- export interface Metadata {
- /**
- * An external identifier for the user who is associated with the request.
- *
- * This should be a uuid, hash value, or other opaque identifier. Anthropic may use
- * this id to help detect abuse. Do not include any identifying information such as
- * name, email address, or phone number.
- */
- user_id?: string | null;
- }
-
- /**
- * The model will automatically decide whether to use tools.
- */
- export interface ToolChoiceAuto {
- type: 'auto';
- }
-
- /**
- * The model will use any available tools.
- */
- export interface ToolChoiceAny {
- type: 'any';
- }
-
- /**
- * The model will use the specified tool with `tool_choice.name`.
- */
- export interface ToolChoiceTool {
- /**
- * The name of the tool to use.
- */
- name: string;
-
- type: 'tool';
- }
-
- export type MessageCreateParamsNonStreaming = ToolsMessagesAPI.MessageCreateParamsNonStreaming;
- export type MessageCreateParamsStreaming = ToolsMessagesAPI.MessageCreateParamsStreaming;
-}
-
-export interface MessageCreateParamsNonStreaming extends MessageCreateParamsBase {
- /**
- * Whether to incrementally stream the response using server-sent events.
- *
- * See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for
- * details.
- */
- stream?: false;
-}
-
-export interface MessageCreateParamsStreaming extends MessageCreateParamsBase {
- /**
- * Whether to incrementally stream the response using server-sent events.
- *
- * See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for
- * details.
- */
- stream: true;
-}
-
-export interface MessageStreamParams {
- /**
- * The maximum number of tokens to generate before stopping.
- *
- * Note that our models may stop _before_ reaching this maximum. This parameter
- * only specifies the absolute maximum number of tokens to generate.
- *
- * Different models have different maximum values for this parameter. See
- * [models](https://docs.anthropic.com/en/docs/models-overview) for details.
- */
- max_tokens: number;
-
- /**
- * Input messages.
- *
- * Our models are trained to operate on alternating `user` and `assistant`
- * conversational turns. When creating a new `Message`, you specify the prior
- * conversational turns with the `messages` parameter, and the model then generates
- * the next `Message` in the conversation.
- *
- * Each input message must be an object with a `role` and `content`. You can
- * specify a single `user`-role message, or you can include multiple `user` and
- * `assistant` messages. The first message must always use the `user` role.
- *
- * If the final message uses the `assistant` role, the response content will
- * continue immediately from the content in that message. This can be used to
- * constrain part of the model's response.
- *
- * Example with a single `user` message:
- *
- * ```json
- * [{ "role": "user", "content": "Hello, Claude" }]
- * ```
- *
- * Example with multiple conversational turns:
- *
- * ```json
- * [
- * { "role": "user", "content": "Hello there." },
- * { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" },
- * { "role": "user", "content": "Can you explain LLMs in plain English?" }
- * ]
- * ```
- *
- * Example with a partially-filled response from Claude:
- *
- * ```json
- * [
- * {
- * "role": "user",
- * "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun"
- * },
- * { "role": "assistant", "content": "The best answer is (" }
- * ]
- * ```
- *
- * Each input message `content` may be either a single `string` or an array of
- * content blocks, where each block has a specific `type`. Using a `string` for
- * `content` is shorthand for an array of one content block of type `"text"`. The
- * following input messages are equivalent:
- *
- * ```json
- * { "role": "user", "content": "Hello, Claude" }
- * ```
- *
- * ```json
- * { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] }
- * ```
- *
- * Starting with Claude 3 models, you can also send image content blocks:
- *
- * ```json
- * {
- * "role": "user",
- * "content": [
- * {
- * "type": "image",
- * "source": {
- * "type": "base64",
- * "media_type": "image/jpeg",
- * "data": "/9j/4AAQSkZJRg..."
- * }
- * },
- * { "type": "text", "text": "What is in this image?" }
- * ]
- * }
- * ```
- *
- * We currently support the `base64` source type for images, and the `image/jpeg`,
- * `image/png`, `image/gif`, and `image/webp` media types.
- *
- * See [examples](https://docs.anthropic.com/en/api/messages-examples) for more
- * input examples.
- *
- * Note that if you want to include a
- * [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use
- * the top-level `system` parameter — there is no `"system"` role for input
- * messages in the Messages API.
- */
- messages: Array;
-
- /**
- * The model that will complete your prompt.
- *
- * See [models](https://docs.anthropic.com/en/docs/models-overview) for additional
- * details and options.
- */
- model: string;
-
- /**
- * An object describing metadata about the request.
- */
- metadata?: MessageStreamParams.Metadata;
-
- /**
- * Custom text sequences that will cause the model to stop generating.
- *
- * Our models will normally stop when they have naturally completed their turn,
- * which will result in a response `stop_reason` of `"end_turn"`.
- *
- * If you want the model to stop generating when it encounters custom strings of
- * text, you can use the `stop_sequences` parameter. If the model encounters one of
- * the custom sequences, the response `stop_reason` value will be `"stop_sequence"`
- * and the response `stop_sequence` value will contain the matched stop sequence.
- */
- stop_sequences?: Array;
-
- /**
- * System prompt.
- *
- * A system prompt is a way of providing context and instructions to Claude, such
- * as specifying a particular goal or role. See our
- * [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts).
- */
- system?: string;
-
- /**
- * Amount of randomness injected into the response.
- *
- * Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0`
- * for analytical / multiple choice, and closer to `1.0` for creative and
- * generative tasks.
- *
- * Note that even with `temperature` of `0.0`, the results will not be fully
- * deterministic.
- */
- temperature?: number;
-
- /**
- * How the model should use the provided tools. The model can use a specific tool,
- * any available tool, or decide by itself.
- */
- tool_choice?:
- | MessageStreamParams.ToolChoiceAuto
- | MessageStreamParams.ToolChoiceAny
- | MessageStreamParams.ToolChoiceTool;
-
- /**
- * [beta] Definitions of tools that the model may use.
- *
- * If you include `tools` in your API request, the model may return `tool_use`
- * content blocks that represent the model's use of those tools. You can then run
- * those tools using the tool input generated by the model and then optionally
- * return results back to the model using `tool_result` content blocks.
- *
- * Each tool definition includes:
- *
- * - `name`: Name of the tool.
- * - `description`: Optional, but strongly-recommended description of the tool.
- * - `input_schema`: [JSON schema](https://json-schema.org/) for the tool `input`
- * shape that the model will produce in `tool_use` output content blocks.
- *
- * For example, if you defined `tools` as:
- *
- * ```json
- * [
- * {
- * "name": "get_stock_price",
- * "description": "Get the current stock price for a given ticker symbol.",
- * "input_schema": {
- * "type": "object",
- * "properties": {
- * "ticker": {
- * "type": "string",
- * "description": "The stock ticker symbol, e.g. AAPL for Apple Inc."
- * }
- * },
- * "required": ["ticker"]
- * }
- * }
- * ]
- * ```
- *
- * And then asked the model "What's the S&P 500 at today?", the model might produce
- * `tool_use` content blocks in the response like this:
- *
- * ```json
- * [
- * {
- * "type": "tool_use",
- * "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV",
- * "name": "get_stock_price",
- * "input": { "ticker": "^GSPC" }
- * }
- * ]
- * ```
- *
- * You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an
- * input, and return the following back to the model in a subsequent `user`
- * message:
- *
- * ```json
- * [
- * {
- * "type": "tool_result",
- * "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV",
- * "content": "259.75 USD"
- * }
- * ]
- * ```
- *
- * Tools can be used for workflows that include running client-side tools and
- * functions, or more generally whenever you want the model to produce a particular
- * JSON structure of output.
- *
- * See our [beta guide](https://docs.anthropic.com/en/docs/tool-use) for more
- * details.
- */
- tools?: Array;
-
- /**
- * Only sample from the top K options for each subsequent token.
- *
- * Used to remove "long tail" low probability responses.
- * [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277).
- *
- * Recommended for advanced use cases only. You usually only need to use
- * `temperature`.
- */
- top_k?: number;
-
- /**
- * Use nucleus sampling.
- *
- * In nucleus sampling, we compute the cumulative distribution over all the options
- * for each subsequent token in decreasing probability order and cut it off once it
- * reaches a particular probability specified by `top_p`. You should either alter
- * `temperature` or `top_p`, but not both.
- *
- * Recommended for advanced use cases only. You usually only need to use
- * `temperature`.
- */
- top_p?: number;
-}
-
-export namespace MessageStreamParams {
- /**
- * An object describing metadata about the request.
- */
- export interface Metadata {
- /**
- * An external identifier for the user who is associated with the request.
- *
- * This should be a uuid, hash value, or other opaque identifier. Anthropic may use
- * this id to help detect abuse. Do not include any identifying information such as
- * name, email address, or phone number.
- */
- user_id?: string | null;
- }
-
- /**
- * The model will automatically decide whether to use tools.
- */
- export interface ToolChoiceAuto {
- type: 'auto';
- }
-
- /**
- * The model will use any available tools.
- */
- export interface ToolChoiceAny {
- type: 'any';
- }
-
- /**
- * The model will use the specified tool with `tool_choice.name`.
- */
- export interface ToolChoiceTool {
- /**
- * The name of the tool to use.
- */
- name: string;
-
- type: 'tool';
- }
-}
-
-export namespace Messages {
- export import InputJsonDelta = ToolsMessagesAPI.InputJsonDelta;
- export import RawToolsBetaContentBlockDeltaEvent = ToolsMessagesAPI.RawToolsBetaContentBlockDeltaEvent;
- export import RawToolsBetaContentBlockStartEvent = ToolsMessagesAPI.RawToolsBetaContentBlockStartEvent;
- export import RawToolsBetaMessageStreamEvent = ToolsMessagesAPI.RawToolsBetaMessageStreamEvent;
- export import Tool = ToolsMessagesAPI.Tool;
- export import ToolResultBlockParam = ToolsMessagesAPI.ToolResultBlockParam;
- export import ToolUseBlock = ToolsMessagesAPI.ToolUseBlock;
- export import ToolUseBlockParam = ToolsMessagesAPI.ToolUseBlockParam;
- export import ToolsBetaContentBlock = ToolsMessagesAPI.ToolsBetaContentBlock;
- export import ToolsBetaContentBlockDeltaEvent = ToolsMessagesAPI.ToolsBetaContentBlockDeltaEvent;
- export import ToolsBetaContentBlockStartEvent = ToolsMessagesAPI.ToolsBetaContentBlockStartEvent;
- export import ToolsBetaMessage = ToolsMessagesAPI.ToolsBetaMessage;
- export import ToolsBetaMessageParam = ToolsMessagesAPI.ToolsBetaMessageParam;
- export import ToolsBetaMessageStreamEvent = ToolsMessagesAPI.ToolsBetaMessageStreamEvent;
- export import MessageCreateParams = ToolsMessagesAPI.MessageCreateParams;
- export import MessageCreateParamsNonStreaming = ToolsMessagesAPI.MessageCreateParamsNonStreaming;
- export import MessageCreateParamsStreaming = ToolsMessagesAPI.MessageCreateParamsStreaming;
- export import MessageStreamParams = ToolsMessagesAPI.MessageStreamParams;
-}
diff --git a/src/resources/beta/tools/tools.ts b/src/resources/beta/tools/tools.ts
deleted file mode 100644
index 6522ce69..00000000
--- a/src/resources/beta/tools/tools.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { APIResource } from '@anthropic-ai/sdk/resource';
-import * as MessagesAPI from '@anthropic-ai/sdk/resources/beta/tools/messages';
-
-export class Tools extends APIResource {
- messages: MessagesAPI.Messages = new MessagesAPI.Messages(this._client);
-}
-
-export namespace Tools {
- export import Messages = MessagesAPI.Messages;
- export import InputJsonDelta = MessagesAPI.InputJsonDelta;
- export import RawToolsBetaContentBlockDeltaEvent = MessagesAPI.RawToolsBetaContentBlockDeltaEvent;
- export import RawToolsBetaContentBlockStartEvent = MessagesAPI.RawToolsBetaContentBlockStartEvent;
- export import RawToolsBetaMessageStreamEvent = MessagesAPI.RawToolsBetaMessageStreamEvent;
- export import Tool = MessagesAPI.Tool;
- export import ToolResultBlockParam = MessagesAPI.ToolResultBlockParam;
- export import ToolUseBlock = MessagesAPI.ToolUseBlock;
- export import ToolUseBlockParam = MessagesAPI.ToolUseBlockParam;
- export import ToolsBetaContentBlock = MessagesAPI.ToolsBetaContentBlock;
- export import ToolsBetaContentBlockDeltaEvent = MessagesAPI.ToolsBetaContentBlockDeltaEvent;
- export import ToolsBetaContentBlockStartEvent = MessagesAPI.ToolsBetaContentBlockStartEvent;
- export import ToolsBetaMessage = MessagesAPI.ToolsBetaMessage;
- export import ToolsBetaMessageParam = MessagesAPI.ToolsBetaMessageParam;
- export import ToolsBetaMessageStreamEvent = MessagesAPI.ToolsBetaMessageStreamEvent;
- 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/index.ts b/src/resources/index.ts
index 8a2302f3..84f839d1 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -1,6 +1,5 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-export { Beta } from './beta/beta';
export {
Completion,
CompletionCreateParams,
@@ -14,6 +13,7 @@ export {
ContentBlockStartEvent,
ContentBlockStopEvent,
ImageBlockParam,
+ InputJsonDelta,
Message,
MessageDeltaEvent,
MessageDeltaUsage,
@@ -31,6 +31,10 @@ export {
TextBlock,
TextBlockParam,
TextDelta,
+ Tool,
+ ToolResultBlockParam,
+ ToolUseBlock,
+ ToolUseBlockParam,
Usage,
MessageCreateParams,
MessageCreateParamsNonStreaming,
diff --git a/src/resources/messages.ts b/src/resources/messages.ts
index 439e3bdc..d9604596 100644
--- a/src/resources/messages.ts
+++ b/src/resources/messages.ts
@@ -47,7 +47,7 @@ export class Messages extends APIResource {
}
}
-export type ContentBlock = TextBlock;
+export type ContentBlock = TextBlock | ToolUseBlock;
export type ContentBlockDeltaEvent = RawContentBlockDeltaEvent;
@@ -71,6 +71,12 @@ export namespace ImageBlockParam {
}
}
+export interface InputJsonDelta {
+ partial_json: string;
+
+ type: 'input_json_delta';
+}
+
export interface Message {
/**
* Unique object identifier.
@@ -83,7 +89,7 @@ export interface Message {
* Content generated by the model.
*
* This is an array of content blocks, each of which has a `type` that determines
- * its shape. Currently, the only `type` in responses is `"text"`.
+ * its shape.
*
* Example:
*
@@ -113,7 +119,7 @@ export interface Message {
* [{ "type": "text", "text": "B)" }]
* ```
*/
- content: Array;
+ content: Array;
/**
* The model that handled the request.
@@ -135,11 +141,12 @@ export interface Message {
* - `"end_turn"`: the model reached a natural stopping point
* - `"max_tokens"`: we exceeded the requested `max_tokens` or the model's maximum
* - `"stop_sequence"`: one of your provided custom `stop_sequences` was generated
+ * - `"tool_use"`: the model invoked one or more tools
*
* In non-streaming mode this value is always non-null. In streaming mode, it is
* null in the `message_start` event and non-null otherwise.
*/
- stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | null;
+ stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | null;
/**
* Which custom stop sequence was generated, if any.
@@ -183,7 +190,7 @@ export interface MessageDeltaUsage {
}
export interface MessageParam {
- content: string | Array;
+ content: string | Array;
role: 'user' | 'assistant';
}
@@ -195,7 +202,7 @@ export type MessageStopEvent = RawMessageStopEvent;
export type MessageStreamEvent = RawMessageStreamEvent;
export interface RawContentBlockDeltaEvent {
- delta: TextDelta;
+ delta: TextDelta | InputJsonDelta;
index: number;
@@ -203,7 +210,7 @@ export interface RawContentBlockDeltaEvent {
}
export interface RawContentBlockStartEvent {
- content_block: TextBlock;
+ content_block: TextBlock | ToolUseBlock;
index: number;
@@ -240,7 +247,7 @@ export interface RawMessageDeltaEvent {
export namespace RawMessageDeltaEvent {
export interface Delta {
- stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | null;
+ stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | null;
stop_sequence: string | null;
}
@@ -282,6 +289,73 @@ export interface TextDelta {
type: 'text_delta';
}
+export interface Tool {
+ /**
+ * [JSON schema](https://json-schema.org/) for this tool's input.
+ *
+ * This defines the shape of the `input` that your tool accepts and that the model
+ * will produce.
+ */
+ input_schema: Tool.InputSchema;
+
+ name: string;
+
+ /**
+ * Description of what this tool does.
+ *
+ * Tool descriptions should be as detailed as possible. The more information that
+ * the model has about what the tool is and how to use it, the better it will
+ * perform. You can use natural language descriptions to reinforce important
+ * aspects of the tool input JSON schema.
+ */
+ description?: string;
+}
+
+export namespace Tool {
+ /**
+ * [JSON schema](https://json-schema.org/) for this tool's input.
+ *
+ * This defines the shape of the `input` that your tool accepts and that the model
+ * will produce.
+ */
+ export interface InputSchema {
+ type: 'object';
+
+ properties?: unknown | null;
+ [k: string]: unknown;
+ }
+}
+
+export interface ToolResultBlockParam {
+ tool_use_id: string;
+
+ type: 'tool_result';
+
+ content?: Array;
+
+ is_error?: boolean;
+}
+
+export interface ToolUseBlock {
+ id: string;
+
+ input: unknown;
+
+ name: string;
+
+ type: 'tool_use';
+}
+
+export interface ToolUseBlockParam {
+ id: string;
+
+ input: unknown;
+
+ name: string;
+
+ type: 'tool_use';
+}
+
export interface Usage {
/**
* The number of input tokens which were used.
@@ -459,6 +533,87 @@ export interface MessageCreateParamsBase {
*/
temperature?: number;
+ /**
+ * How the model should use the provided tools. The model can use a specific tool,
+ * any available tool, or decide by itself.
+ */
+ tool_choice?:
+ | MessageCreateParams.ToolChoiceAuto
+ | MessageCreateParams.ToolChoiceAny
+ | MessageCreateParams.ToolChoiceTool;
+
+ /**
+ * Definitions of tools that the model may use.
+ *
+ * If you include `tools` in your API request, the model may return `tool_use`
+ * content blocks that represent the model's use of those tools. You can then run
+ * those tools using the tool input generated by the model and then optionally
+ * return results back to the model using `tool_result` content blocks.
+ *
+ * Each tool definition includes:
+ *
+ * - `name`: Name of the tool.
+ * - `description`: Optional, but strongly-recommended description of the tool.
+ * - `input_schema`: [JSON schema](https://json-schema.org/) for the tool `input`
+ * shape that the model will produce in `tool_use` output content blocks.
+ *
+ * For example, if you defined `tools` as:
+ *
+ * ```json
+ * [
+ * {
+ * "name": "get_stock_price",
+ * "description": "Get the current stock price for a given ticker symbol.",
+ * "input_schema": {
+ * "type": "object",
+ * "properties": {
+ * "ticker": {
+ * "type": "string",
+ * "description": "The stock ticker symbol, e.g. AAPL for Apple Inc."
+ * }
+ * },
+ * "required": ["ticker"]
+ * }
+ * }
+ * ]
+ * ```
+ *
+ * And then asked the model "What's the S&P 500 at today?", the model might produce
+ * `tool_use` content blocks in the response like this:
+ *
+ * ```json
+ * [
+ * {
+ * "type": "tool_use",
+ * "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV",
+ * "name": "get_stock_price",
+ * "input": { "ticker": "^GSPC" }
+ * }
+ * ]
+ * ```
+ *
+ * You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an
+ * input, and return the following back to the model in a subsequent `user`
+ * message:
+ *
+ * ```json
+ * [
+ * {
+ * "type": "tool_result",
+ * "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV",
+ * "content": "259.75 USD"
+ * }
+ * ]
+ * ```
+ *
+ * Tools can be used for workflows that include running client-side tools and
+ * functions, or more generally whenever you want the model to produce a particular
+ * JSON structure of output.
+ *
+ * See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details.
+ */
+ tools?: Array;
+
/**
* Only sample from the top K options for each subsequent token.
*
@@ -499,6 +654,32 @@ export namespace MessageCreateParams {
user_id?: string | null;
}
+ /**
+ * The model will automatically decide whether to use tools.
+ */
+ export interface ToolChoiceAuto {
+ type: 'auto';
+ }
+
+ /**
+ * The model will use any available tools.
+ */
+ export interface ToolChoiceAny {
+ type: 'any';
+ }
+
+ /**
+ * The model will use the specified tool with `tool_choice.name`.
+ */
+ export interface ToolChoiceTool {
+ /**
+ * The name of the tool to use.
+ */
+ name: string;
+
+ type: 'tool';
+ }
+
export type MessageCreateParamsNonStreaming = MessagesAPI.MessageCreateParamsNonStreaming;
export type MessageCreateParamsStreaming = MessagesAPI.MessageCreateParamsStreaming;
}
@@ -725,6 +906,7 @@ export namespace Messages {
export import ContentBlockStartEvent = MessagesAPI.ContentBlockStartEvent;
export import ContentBlockStopEvent = MessagesAPI.ContentBlockStopEvent;
export import ImageBlockParam = MessagesAPI.ImageBlockParam;
+ export import InputJsonDelta = MessagesAPI.InputJsonDelta;
export import Message = MessagesAPI.Message;
export import MessageDeltaEvent = MessagesAPI.MessageDeltaEvent;
export import MessageDeltaUsage = MessagesAPI.MessageDeltaUsage;
@@ -742,6 +924,10 @@ export namespace Messages {
export import TextBlock = MessagesAPI.TextBlock;
export import TextBlockParam = MessagesAPI.TextBlockParam;
export import TextDelta = MessagesAPI.TextDelta;
+ export import Tool = MessagesAPI.Tool;
+ export import ToolResultBlockParam = MessagesAPI.ToolResultBlockParam;
+ export import ToolUseBlock = MessagesAPI.ToolUseBlock;
+ export import ToolUseBlockParam = MessagesAPI.ToolUseBlockParam;
export import Usage = MessagesAPI.Usage;
export import MessageCreateParams = MessagesAPI.MessageCreateParams;
export import MessageCreateParamsNonStreaming = MessagesAPI.MessageCreateParamsNonStreaming;
diff --git a/tests/api-resources/beta/tools/messages.test.ts b/tests/api-resources/beta/tools/messages.test.ts
deleted file mode 100644
index 71eccab6..00000000
--- a/tests/api-resources/beta/tools/messages.test.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import Anthropic from '@anthropic-ai/sdk';
-import { Response } from 'node-fetch';
-
-const anthropic = new Anthropic({
- apiKey: 'my-anthropic-api-key',
- baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
-});
-
-describe('resource messages', () => {
- test('create: only required params', async () => {
- const responsePromise = anthropic.beta.tools.messages.create({
- max_tokens: 1024,
- messages: [{ role: 'user', content: 'Hello, world' }],
- model: 'claude-3-opus-20240229',
- });
- 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);
- });
-
- test('create: required and optional params', async () => {
- const response = await anthropic.beta.tools.messages.create({
- max_tokens: 1024,
- messages: [{ role: 'user', content: 'Hello, world' }],
- model: 'claude-3-opus-20240229',
- metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' },
- stop_sequences: ['string', 'string', 'string'],
- stream: false,
- system: "Today's date is 2024-01-01.",
- temperature: 1,
- tool_choice: { type: 'auto' },
- tools: [
- {
- description: 'Get the current weather in a given location',
- name: 'x',
- input_schema: {
- type: 'object',
- properties: {
- location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' },
- unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' },
- },
- },
- },
- {
- description: 'Get the current weather in a given location',
- name: 'x',
- input_schema: {
- type: 'object',
- properties: {
- location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' },
- unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' },
- },
- },
- },
- {
- description: 'Get the current weather in a given location',
- name: 'x',
- input_schema: {
- type: 'object',
- properties: {
- location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' },
- unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' },
- },
- },
- },
- ],
- top_k: 5,
- top_p: 0.7,
- });
- });
-});
diff --git a/tests/api-resources/messages.test.ts b/tests/api-resources/messages.test.ts
index 0d51e2db..e1c23c77 100644
--- a/tests/api-resources/messages.test.ts
+++ b/tests/api-resources/messages.test.ts
@@ -34,6 +34,42 @@ describe('resource messages', () => {
stream: false,
system: "Today's date is 2024-01-01.",
temperature: 1,
+ tool_choice: { type: 'auto' },
+ tools: [
+ {
+ description: 'Get the current weather in a given location',
+ name: 'x',
+ input_schema: {
+ type: 'object',
+ properties: {
+ location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' },
+ unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' },
+ },
+ },
+ },
+ {
+ description: 'Get the current weather in a given location',
+ name: 'x',
+ input_schema: {
+ type: 'object',
+ properties: {
+ location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' },
+ unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' },
+ },
+ },
+ },
+ {
+ description: 'Get the current weather in a given location',
+ name: 'x',
+ input_schema: {
+ type: 'object',
+ properties: {
+ location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' },
+ unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' },
+ },
+ },
+ },
+ ],
top_k: 5,
top_p: 0.7,
});
From 4c83bb111735cd513c09d5ed57a5cb0888534afd Mon Sep 17 00:00:00 2001
From: Robert Craigie
Date: Thu, 30 May 2024 14:15:51 +0100
Subject: [PATCH 4/8] feat(streaming): add tools support
---
examples/tools-streaming.ts | 2 +-
examples/tools.ts | 10 +-
src/lib/MessageStream.ts | 36 +-
src/lib/ToolsBetaMessageStream.ts | 561 ----------------------
src/resources/messages.ts | 196 +-------
tests/api-resources/MessageStream.test.ts | 53 +-
6 files changed, 82 insertions(+), 776 deletions(-)
delete mode 100644 src/lib/ToolsBetaMessageStream.ts
diff --git a/examples/tools-streaming.ts b/examples/tools-streaming.ts
index 11d9589f..96d9cbdc 100644
--- a/examples/tools-streaming.ts
+++ b/examples/tools-streaming.ts
@@ -7,7 +7,7 @@ import { inspect } from 'util';
const client = new Anthropic();
async function main() {
- const stream = client.beta.tools.messages
+ const stream = client.messages
.stream({
messages: [
{
diff --git a/examples/tools.ts b/examples/tools.ts
index b4887a24..b237043b 100644
--- a/examples/tools.ts
+++ b/examples/tools.ts
@@ -6,11 +6,11 @@ import assert from 'node:assert';
const client = new Anthropic(); // gets API Key from environment variable ANTHROPIC_API_KEY
async function main() {
- const userMessage: Anthropic.Beta.Tools.ToolsBetaMessageParam = {
+ const userMessage: Anthropic.MessageParam = {
role: 'user',
content: 'What is the weather in SF?',
};
- const tools: Anthropic.Beta.Tools.Tool[] = [
+ const tools: Anthropic.Tool[] = [
{
name: 'get_weather',
description: 'Get the weather for a specific location',
@@ -21,7 +21,7 @@ async function main() {
},
];
- const message = await client.beta.tools.messages.create({
+ const message = await client.messages.create({
model: 'claude-3-opus-20240229',
max_tokens: 1024,
messages: [userMessage],
@@ -33,11 +33,11 @@ async function main() {
assert(message.stop_reason === 'tool_use');
const tool = message.content.find(
- (content): content is Anthropic.Beta.Tools.ToolUseBlock => content.type === 'tool_use',
+ (content): content is Anthropic.ToolUseBlock => content.type === 'tool_use',
);
assert(tool);
- const result = await client.beta.tools.messages.create({
+ const result = await client.messages.create({
model: 'claude-3-opus-20240229',
max_tokens: 1024,
messages: [
diff --git a/src/lib/MessageStream.ts b/src/lib/MessageStream.ts
index cf90bda6..5fb629fe 100644
--- a/src/lib/MessageStream.ts
+++ b/src/lib/MessageStream.ts
@@ -7,15 +7,18 @@ import {
MessageStreamEvent,
MessageParam,
MessageCreateParams,
- MessageStreamParams,
+ MessageCreateParamsBase,
} from '@anthropic-ai/sdk/resources/messages';
import { type ReadableStream } from '@anthropic-ai/sdk/_shims/index';
import { Stream } from '@anthropic-ai/sdk/streaming';
+import { TextBlock } from '@anthropic-ai/sdk/resources';
+import { partialParse } from '../_vendor/partial-json-parser/parser';
export interface MessageStreamEvents {
connect: () => void;
streamEvent: (event: MessageStreamEvent, snapshot: Message) => void;
text: (textDelta: string, textSnapshot: string) => void;
+ inputJson: (jsonDelta: string, jsonSnapshot: unknown) => void;
message: (message: Message) => void;
contentBlock: (content: ContentBlock) => void;
finalMessage: (message: Message) => void;
@@ -29,6 +32,8 @@ type MessageStreamEventListeners = {
once?: boolean;
}[];
+const JSON_BUF_PROPERTY = '__json_buf';
+
export class MessageStream implements AsyncIterable {
messages: MessageParam[] = [];
receivedMessages: Message[] = [];
@@ -85,7 +90,7 @@ export class MessageStream implements AsyncIterable {
static createMessage(
messages: Messages,
- params: MessageStreamParams,
+ params: MessageCreateParamsBase,
options?: Core.RequestOptions,
): MessageStream {
const runner = new MessageStream();
@@ -264,7 +269,7 @@ export class MessageStream implements AsyncIterable {
}
const textBlocks = this.receivedMessages
.at(-1)!
- .content.filter((block) => block.type === 'text')
+ .content.filter((block): block is TextBlock => block.type === 'text')
.map((block) => block.text);
if (textBlocks.length === 0) {
throw new AnthropicError('stream ended without producing a content block with type=text');
@@ -369,8 +374,13 @@ export class MessageStream implements AsyncIterable {
switch (event.type) {
case 'content_block_delta': {
- if (event.delta.type === 'text_delta') {
- this._emit('text', event.delta.text, messageSnapshot.content.at(-1)!.text || '');
+ const content = messageSnapshot.content.at(-1)!;
+ if (event.delta.type === 'text_delta' && content.type === 'text') {
+ this._emit('text', event.delta.text, content.text || '');
+ } else if (event.delta.type === 'input_json_delta' && content.type === 'tool_use') {
+ if (content.input) {
+ this._emit('inputJson', event.delta.partial_json, content.input);
+ }
}
break;
}
@@ -459,6 +469,22 @@ export class MessageStream implements AsyncIterable {
const snapshotContent = snapshot.content.at(event.index);
if (snapshotContent?.type === 'text' && event.delta.type === 'text_delta') {
snapshotContent.text += event.delta.text;
+ } else if (snapshotContent?.type === 'tool_use' && event.delta.type === 'input_json_delta') {
+ // we need to keep track of the raw JSON string as well so that we can
+ // re-parse it for each delta, for now we just store it as an untyped
+ // non-enumerable property on the snapshot
+ let jsonBuf = (snapshotContent as any)[JSON_BUF_PROPERTY] || '';
+ jsonBuf += event.delta.partial_json;
+
+ Object.defineProperty(snapshotContent, JSON_BUF_PROPERTY, {
+ value: jsonBuf,
+ enumerable: false,
+ writable: true,
+ });
+
+ if (jsonBuf) {
+ snapshotContent.input = partialParse(jsonBuf);
+ }
}
return snapshot;
}
diff --git a/src/lib/ToolsBetaMessageStream.ts b/src/lib/ToolsBetaMessageStream.ts
deleted file mode 100644
index 7c1612e9..00000000
--- a/src/lib/ToolsBetaMessageStream.ts
+++ /dev/null
@@ -1,561 +0,0 @@
-import * as Core from '@anthropic-ai/sdk/core';
-import { AnthropicError, APIUserAbortError } from '@anthropic-ai/sdk/error';
-import {
- ToolsBetaContentBlock,
- Messages,
- ToolsBetaMessage,
- ToolsBetaMessageStreamEvent,
- ToolsBetaMessageParam,
- MessageCreateParams,
- MessageCreateParamsBase,
-} from '@anthropic-ai/sdk/resources/beta/tools/messages';
-import { type ReadableStream } from '@anthropic-ai/sdk/_shims/index';
-import { Stream } from '@anthropic-ai/sdk/streaming';
-import { TextBlock } from '@anthropic-ai/sdk/resources';
-import { partialParse } from '../_vendor/partial-json-parser/parser';
-
-export interface MessageStreamEvents {
- connect: () => void;
- streamEvent: (event: ToolsBetaMessageStreamEvent, snapshot: ToolsBetaMessage) => void;
- text: (textDelta: string, textSnapshot: string) => void;
- inputJson: (jsonDelta: string, jsonSnapshot: unknown) => void;
- message: (message: ToolsBetaMessage) => void;
- contentBlock: (content: ToolsBetaContentBlock) => void;
- finalMessage: (message: ToolsBetaMessage) => void;
- error: (error: AnthropicError) => void;
- abort: (error: APIUserAbortError) => void;
- end: () => void;
-}
-
-type MessageStreamEventListeners = {
- listener: MessageStreamEvents[Event];
- once?: boolean;
-}[];
-
-const JSON_BUF_PROPERTY = '__json_buf';
-
-export class ToolsBetaMessageStream implements AsyncIterable {
- messages: ToolsBetaMessageParam[] = [];
- receivedMessages: ToolsBetaMessage[] = [];
- #currentMessageSnapshot: ToolsBetaMessage | undefined;
-
- controller: AbortController = new AbortController();
-
- #connectedPromise: Promise;
- #resolveConnectedPromise: () => void = () => {};
- #rejectConnectedPromise: (error: AnthropicError) => void = () => {};
-
- #endPromise: Promise;
- #resolveEndPromise: () => void = () => {};
- #rejectEndPromise: (error: AnthropicError) => void = () => {};
-
- #listeners: { [Event in keyof MessageStreamEvents]?: MessageStreamEventListeners } = {};
-
- #ended = false;
- #errored = false;
- #aborted = false;
- #catchingPromiseCreated = false;
-
- constructor() {
- this.#connectedPromise = new Promise((resolve, reject) => {
- this.#resolveConnectedPromise = resolve;
- this.#rejectConnectedPromise = reject;
- });
-
- this.#endPromise = new Promise((resolve, reject) => {
- this.#resolveEndPromise = resolve;
- this.#rejectEndPromise = reject;
- });
-
- // Don't let these promises cause unhandled rejection errors.
- // we will manually cause an unhandled rejection error later
- // if the user hasn't registered any error listener or called
- // any promise-returning method.
- this.#connectedPromise.catch(() => {});
- this.#endPromise.catch(() => {});
- }
-
- /**
- * Intended for use on the frontend, consuming a stream produced with
- * `.toReadableStream()` on the backend.
- *
- * Note that messages sent to the model do not appear in `.on('message')`
- * in this context.
- */
- static fromReadableStream(stream: ReadableStream): ToolsBetaMessageStream {
- const runner = new ToolsBetaMessageStream();
- runner._run(() => runner._fromReadableStream(stream));
- return runner;
- }
-
- static createMessage(
- messages: Messages,
- params: MessageCreateParamsBase,
- options?: Core.RequestOptions,
- ): ToolsBetaMessageStream {
- const runner = new ToolsBetaMessageStream();
- for (const message of params.messages) {
- runner._addMessageParam(message);
- }
- runner._run(() =>
- runner._createMessage(
- messages,
- { ...params, stream: true },
- { ...options, headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' } },
- ),
- );
- return runner;
- }
-
- protected _run(executor: () => Promise) {
- executor().then(() => {
- this._emitFinal();
- this._emit('end');
- }, this.#handleError);
- }
-
- protected _addMessageParam(message: ToolsBetaMessageParam) {
- this.messages.push(message);
- }
-
- protected _addMessage(message: ToolsBetaMessage, emit = true) {
- this.receivedMessages.push(message);
- if (emit) {
- this._emit('message', message);
- }
- }
-
- protected async _createMessage(
- messages: Messages,
- params: MessageCreateParams,
- options?: Core.RequestOptions,
- ): Promise {
- const signal = options?.signal;
- if (signal) {
- if (signal.aborted) this.controller.abort();
- signal.addEventListener('abort', () => this.controller.abort());
- }
- this.#beginRequest();
- const stream = await messages.create(
- { ...params, stream: true },
- { ...options, signal: this.controller.signal },
- );
- this._connected();
- for await (const event of stream) {
- this.#addStreamEvent(event);
- }
- if (stream.controller.signal?.aborted) {
- throw new APIUserAbortError();
- }
- this.#endRequest();
- }
-
- protected _connected() {
- if (this.ended) return;
- this.#resolveConnectedPromise();
- this._emit('connect');
- }
-
- get ended(): boolean {
- return this.#ended;
- }
-
- get errored(): boolean {
- return this.#errored;
- }
-
- get aborted(): boolean {
- return this.#aborted;
- }
-
- abort() {
- this.controller.abort();
- }
-
- /**
- * Adds the listener function to the end of the listeners array for the event.
- * No checks are made to see if the listener has already been added. Multiple calls passing
- * the same combination of event and listener will result in the listener being added, and
- * called, multiple times.
- * @returns this MessageStream, so that calls can be chained
- */
- on(event: Event, listener: MessageStreamEvents[Event]): this {
- const listeners: MessageStreamEventListeners =
- this.#listeners[event] || (this.#listeners[event] = []);
- listeners.push({ listener });
- return this;
- }
-
- /**
- * Removes the specified listener from the listener array for the event.
- * off() will remove, at most, one instance of a listener from the listener array. If any single
- * listener has been added multiple times to the listener array for the specified event, then
- * off() must be called multiple times to remove each instance.
- * @returns this MessageStream, so that calls can be chained
- */
- off(event: Event, listener: MessageStreamEvents[Event]): this {
- const listeners = this.#listeners[event];
- if (!listeners) return this;
- const index = listeners.findIndex((l) => l.listener === listener);
- if (index >= 0) listeners.splice(index, 1);
- return this;
- }
-
- /**
- * Adds a one-time listener function for the event. The next time the event is triggered,
- * this listener is removed and then invoked.
- * @returns this MessageStream, so that calls can be chained
- */
- once(event: Event, listener: MessageStreamEvents[Event]): this {
- const listeners: MessageStreamEventListeners =
- this.#listeners[event] || (this.#listeners[event] = []);
- listeners.push({ listener, once: true });
- return this;
- }
-
- /**
- * This is similar to `.once()`, but returns a Promise that resolves the next time
- * the event is triggered, instead of calling a listener callback.
- * @returns a Promise that resolves the next time given event is triggered,
- * or rejects if an error is emitted. (If you request the 'error' event,
- * returns a promise that resolves with the error).
- *
- * Example:
- *
- * const message = await stream.emitted('message') // rejects if the stream errors
- */
- emitted(
- event: Event,
- ): Promise<
- Parameters extends [infer Param] ? Param
- : Parameters extends [] ? void
- : Parameters
- > {
- return new Promise((resolve, reject) => {
- this.#catchingPromiseCreated = true;
- if (event !== 'error') this.once('error', reject);
- this.once(event, resolve as any);
- });
- }
-
- async done(): Promise {
- this.#catchingPromiseCreated = true;
- await this.#endPromise;
- }
-
- get currentMessage(): ToolsBetaMessage | undefined {
- return this.#currentMessageSnapshot;
- }
-
- #getFinalMessage(): ToolsBetaMessage {
- if (this.receivedMessages.length === 0) {
- throw new AnthropicError('stream ended without producing a Message with role=assistant');
- }
- return this.receivedMessages.at(-1)!;
- }
-
- /**
- * @returns a promise that resolves with the the final assistant Message response,
- * or rejects if an error occurred or the stream ended prematurely without producing a Message.
- */
- async finalMessage(): Promise {
- await this.done();
- return this.#getFinalMessage();
- }
-
- #getFinalText(): string {
- if (this.receivedMessages.length === 0) {
- throw new AnthropicError('stream ended without producing a Message with role=assistant');
- }
- const textBlocks = this.receivedMessages
- .at(-1)!
- .content.filter((block): block is TextBlock => block.type === 'text')
- .map((block) => block.text);
- if (textBlocks.length === 0) {
- throw new AnthropicError('stream ended without producing a content block with type=text');
- }
- return textBlocks.join(' ');
- }
-
- /**
- * @returns a promise that resolves with the the final assistant Message's text response, concatenated
- * together if there are more than one text blocks.
- * Rejects if an error occurred or the stream ended prematurely without producing a Message.
- */
- async finalText(): Promise {
- await this.done();
- return this.#getFinalText();
- }
-
- #handleError = (error: unknown) => {
- this.#errored = true;
- if (error instanceof Error && error.name === 'AbortError') {
- error = new APIUserAbortError();
- }
- if (error instanceof APIUserAbortError) {
- this.#aborted = true;
- return this._emit('abort', error);
- }
- if (error instanceof AnthropicError) {
- return this._emit('error', error);
- }
- if (error instanceof Error) {
- const anthropicError: AnthropicError = new AnthropicError(error.message);
- // @ts-ignore
- anthropicError.cause = error;
- return this._emit('error', anthropicError);
- }
- return this._emit('error', new AnthropicError(String(error)));
- };
-
- protected _emit(
- event: Event,
- ...args: Parameters
- ) {
- // make sure we don't emit any MessageStreamEvents after end
- if (this.#ended) return;
-
- if (event === 'end') {
- this.#ended = true;
- this.#resolveEndPromise();
- }
-
- const listeners: MessageStreamEventListeners | undefined = this.#listeners[event];
- if (listeners) {
- this.#listeners[event] = listeners.filter((l) => !l.once) as any;
- listeners.forEach(({ listener }: any) => listener(...args));
- }
-
- if (event === 'abort') {
- const error = args[0] as APIUserAbortError;
- if (!this.#catchingPromiseCreated && !listeners?.length) {
- Promise.reject(error);
- }
- this.#rejectConnectedPromise(error);
- this.#rejectEndPromise(error);
- this._emit('end');
- return;
- }
-
- if (event === 'error') {
- // NOTE: _emit('error', error) should only be called from #handleError().
-
- const error = args[0] as AnthropicError;
- if (!this.#catchingPromiseCreated && !listeners?.length) {
- // Trigger an unhandled rejection if the user hasn't registered any error handlers.
- // If you are seeing stack traces here, make sure to handle errors via either:
- // - runner.on('error', () => ...)
- // - await runner.done()
- // - await runner.final...()
- // - etc.
- Promise.reject(error);
- }
- this.#rejectConnectedPromise(error);
- this.#rejectEndPromise(error);
- this._emit('end');
- }
- }
-
- protected _emitFinal() {
- const finalMessage = this.receivedMessages.at(-1);
- if (finalMessage) {
- this._emit('finalMessage', this.#getFinalMessage());
- }
- }
-
- #beginRequest() {
- if (this.ended) return;
- this.#currentMessageSnapshot = undefined;
- }
- #addStreamEvent(event: ToolsBetaMessageStreamEvent) {
- if (this.ended) return;
- const messageSnapshot = this.#accumulateMessage(event);
- this._emit('streamEvent', event, messageSnapshot);
-
- switch (event.type) {
- case 'content_block_delta': {
- const content = messageSnapshot.content.at(-1)!;
- if (event.delta.type === 'text_delta' && content.type === 'text') {
- this._emit('text', event.delta.text, content.text || '');
- } else if (event.delta.type === 'input_json_delta' && content.type === 'tool_use') {
- if (content.input) {
- this._emit('inputJson', event.delta.partial_json, content.input);
- }
- }
- break;
- }
- case 'message_stop': {
- this._addMessageParam(messageSnapshot);
- this._addMessage(messageSnapshot, true);
- break;
- }
- case 'content_block_stop': {
- this._emit('contentBlock', messageSnapshot.content.at(-1)!);
- break;
- }
- case 'message_start': {
- this.#currentMessageSnapshot = messageSnapshot;
- break;
- }
- case 'content_block_start':
- case 'message_delta':
- break;
- }
- }
- #endRequest(): ToolsBetaMessage {
- if (this.ended) {
- throw new AnthropicError(`stream has ended, this shouldn't happen`);
- }
- const snapshot = this.#currentMessageSnapshot;
- if (!snapshot) {
- throw new AnthropicError(`request ended without sending any chunks`);
- }
- this.#currentMessageSnapshot = undefined;
- return snapshot;
- }
-
- protected async _fromReadableStream(
- readableStream: ReadableStream,
- options?: Core.RequestOptions,
- ): Promise {
- const signal = options?.signal;
- if (signal) {
- if (signal.aborted) this.controller.abort();
- signal.addEventListener('abort', () => this.controller.abort());
- }
- this.#beginRequest();
- this._connected();
- const stream = Stream.fromReadableStream(readableStream, this.controller);
- for await (const event of stream) {
- this.#addStreamEvent(event);
- }
- if (stream.controller.signal?.aborted) {
- throw new APIUserAbortError();
- }
- this.#endRequest();
- }
-
- /**
- * Mutates this.#currentMessage with the current event. Handling the accumulation of multiple messages
- * will be needed to be handled by the caller, this method will throw if you try to accumulate for multiple
- * messages.
- */
- #accumulateMessage(event: ToolsBetaMessageStreamEvent): ToolsBetaMessage {
- let snapshot = this.#currentMessageSnapshot;
-
- if (event.type === 'message_start') {
- if (snapshot) {
- throw new AnthropicError(`Unexpected event order, got ${event.type} before receiving "message_stop"`);
- }
- return event.message;
- }
-
- if (!snapshot) {
- throw new AnthropicError(`Unexpected event order, got ${event.type} before "message_start"`);
- }
-
- switch (event.type) {
- case 'message_stop':
- return snapshot;
- case 'message_delta':
- snapshot.stop_reason = event.delta.stop_reason;
- snapshot.stop_sequence = event.delta.stop_sequence;
- snapshot.usage.output_tokens = event.usage.output_tokens;
- return snapshot;
- case 'content_block_start':
- snapshot.content.push(event.content_block);
- return snapshot;
- case 'content_block_delta': {
- const snapshotContent = snapshot.content.at(event.index);
- if (snapshotContent?.type === 'text' && event.delta.type === 'text_delta') {
- snapshotContent.text += event.delta.text;
- } else if (snapshotContent?.type === 'tool_use' && event.delta.type === 'input_json_delta') {
- // we need to keep track of the raw JSON string as well so that we can
- // re-parse it for each delta, for now we just store it as an untyped
- // non-enumerable property on the snapshot
- let jsonBuf = (snapshotContent as any)[JSON_BUF_PROPERTY] || '';
- jsonBuf += event.delta.partial_json;
-
- Object.defineProperty(snapshotContent, JSON_BUF_PROPERTY, {
- value: jsonBuf,
- enumerable: false,
- writable: true,
- });
-
- if (jsonBuf) {
- snapshotContent.input = partialParse(jsonBuf);
- }
- }
- return snapshot;
- }
- case 'content_block_stop':
- return snapshot;
- }
- }
-
- [Symbol.asyncIterator](): AsyncIterator {
- const pushQueue: ToolsBetaMessageStreamEvent[] = [];
- const readQueue: {
- resolve: (chunk: ToolsBetaMessageStreamEvent | undefined) => void;
- reject: (error: unknown) => void;
- }[] = [];
- let done = false;
-
- this.on('streamEvent', (event) => {
- const reader = readQueue.shift();
- if (reader) {
- reader.resolve(event);
- } else {
- pushQueue.push(event);
- }
- });
-
- this.on('end', () => {
- done = true;
- for (const reader of readQueue) {
- reader.resolve(undefined);
- }
- readQueue.length = 0;
- });
-
- this.on('abort', (err) => {
- done = true;
- for (const reader of readQueue) {
- reader.reject(err);
- }
- readQueue.length = 0;
- });
-
- this.on('error', (err) => {
- done = true;
- for (const reader of readQueue) {
- reader.reject(err);
- }
- readQueue.length = 0;
- });
-
- return {
- next: async (): Promise> => {
- if (!pushQueue.length) {
- if (done) {
- return { value: undefined, done: true };
- }
- return new Promise((resolve, reject) =>
- readQueue.push({ resolve, reject }),
- ).then((chunk) => (chunk ? { value: chunk, done: false } : { value: undefined, done: true }));
- }
- const chunk = pushQueue.shift()!;
- return { value: chunk, done: false };
- },
- return: async () => {
- this.abort();
- return { value: undefined, done: true };
- },
- };
- }
-
- toReadableStream(): ReadableStream {
- const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller);
- return stream.toReadableStream();
- }
-}
diff --git a/src/resources/messages.ts b/src/resources/messages.ts
index d9604596..b4fabb66 100644
--- a/src/resources/messages.ts
+++ b/src/resources/messages.ts
@@ -704,201 +704,7 @@ export interface MessageCreateParamsStreaming extends MessageCreateParamsBase {
stream: true;
}
-export interface MessageStreamParams {
- /**
- * The maximum number of tokens to generate before stopping.
- *
- * Note that our models may stop _before_ reaching this maximum. This parameter
- * only specifies the absolute maximum number of tokens to generate.
- *
- * Different models have different maximum values for this parameter. See
- * [models](https://docs.anthropic.com/en/docs/models-overview) for details.
- */
- max_tokens: number;
-
- /**
- * Input messages.
- *
- * Our models are trained to operate on alternating `user` and `assistant`
- * conversational turns. When creating a new `Message`, you specify the prior
- * conversational turns with the `messages` parameter, and the model then generates
- * the next `Message` in the conversation.
- *
- * Each input message must be an object with a `role` and `content`. You can
- * specify a single `user`-role message, or you can include multiple `user` and
- * `assistant` messages. The first message must always use the `user` role.
- *
- * If the final message uses the `assistant` role, the response content will
- * continue immediately from the content in that message. This can be used to
- * constrain part of the model's response.
- *
- * Example with a single `user` message:
- *
- * ```json
- * [{ "role": "user", "content": "Hello, Claude" }]
- * ```
- *
- * Example with multiple conversational turns:
- *
- * ```json
- * [
- * { "role": "user", "content": "Hello there." },
- * { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" },
- * { "role": "user", "content": "Can you explain LLMs in plain English?" }
- * ]
- * ```
- *
- * Example with a partially-filled response from Claude:
- *
- * ```json
- * [
- * {
- * "role": "user",
- * "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun"
- * },
- * { "role": "assistant", "content": "The best answer is (" }
- * ]
- * ```
- *
- * Each input message `content` may be either a single `string` or an array of
- * content blocks, where each block has a specific `type`. Using a `string` for
- * `content` is shorthand for an array of one content block of type `"text"`. The
- * following input messages are equivalent:
- *
- * ```json
- * { "role": "user", "content": "Hello, Claude" }
- * ```
- *
- * ```json
- * { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] }
- * ```
- *
- * Starting with Claude 3 models, you can also send image content blocks:
- *
- * ```json
- * {
- * "role": "user",
- * "content": [
- * {
- * "type": "image",
- * "source": {
- * "type": "base64",
- * "media_type": "image/jpeg",
- * "data": "/9j/4AAQSkZJRg..."
- * }
- * },
- * { "type": "text", "text": "What is in this image?" }
- * ]
- * }
- * ```
- *
- * We currently support the `base64` source type for images, and the `image/jpeg`,
- * `image/png`, `image/gif`, and `image/webp` media types.
- *
- * See [examples](https://docs.anthropic.com/en/api/messages-examples) for more
- * input examples.
- *
- * Note that if you want to include a
- * [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use
- * the top-level `system` parameter — there is no `"system"` role for input
- * messages in the Messages API.
- */
- messages: Array;
-
- /**
- * The model that will complete your prompt.
- *
- * See [models](https://docs.anthropic.com/en/docs/models-overview) for additional
- * details and options.
- */
- model:
- | (string & {})
- | 'claude-3-opus-20240229'
- | 'claude-3-sonnet-20240229'
- | 'claude-3-haiku-20240307'
- | 'claude-2.1'
- | 'claude-2.0'
- | 'claude-instant-1.2';
-
- /**
- * An object describing metadata about the request.
- */
- metadata?: MessageStreamParams.Metadata;
-
- /**
- * Custom text sequences that will cause the model to stop generating.
- *
- * Our models will normally stop when they have naturally completed their turn,
- * which will result in a response `stop_reason` of `"end_turn"`.
- *
- * If you want the model to stop generating when it encounters custom strings of
- * text, you can use the `stop_sequences` parameter. If the model encounters one of
- * the custom sequences, the response `stop_reason` value will be `"stop_sequence"`
- * and the response `stop_sequence` value will contain the matched stop sequence.
- */
- stop_sequences?: Array;
-
- /**
- * System prompt.
- *
- * A system prompt is a way of providing context and instructions to Claude, such
- * as specifying a particular goal or role. See our
- * [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts).
- */
- system?: string;
-
- /**
- * Amount of randomness injected into the response.
- *
- * Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0`
- * for analytical / multiple choice, and closer to `1.0` for creative and
- * generative tasks.
- *
- * Note that even with `temperature` of `0.0`, the results will not be fully
- * deterministic.
- */
- temperature?: number;
-
- /**
- * Only sample from the top K options for each subsequent token.
- *
- * Used to remove "long tail" low probability responses.
- * [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277).
- *
- * Recommended for advanced use cases only. You usually only need to use
- * `temperature`.
- */
- top_k?: number;
-
- /**
- * Use nucleus sampling.
- *
- * In nucleus sampling, we compute the cumulative distribution over all the options
- * for each subsequent token in decreasing probability order and cut it off once it
- * reaches a particular probability specified by `top_p`. You should either alter
- * `temperature` or `top_p`, but not both.
- *
- * Recommended for advanced use cases only. You usually only need to use
- * `temperature`.
- */
- top_p?: number;
-}
-
-export namespace MessageStreamParams {
- /**
- * An object describing metadata about the request.
- */
- export interface Metadata {
- /**
- * An external identifier for the user who is associated with the request.
- *
- * This should be a uuid, hash value, or other opaque identifier. Anthropic may use
- * this id to help detect abuse. Do not include any identifying information such as
- * name, email address, or phone number.
- */
- user_id?: string | null;
- }
-}
+export type MessageStreamParams = MessageCreateParamsBase;
export namespace Messages {
export import ContentBlock = MessagesAPI.ContentBlock;
diff --git a/tests/api-resources/MessageStream.test.ts b/tests/api-resources/MessageStream.test.ts
index 35cf5c1d..81b9c81e 100644
--- a/tests/api-resources/MessageStream.test.ts
+++ b/tests/api-resources/MessageStream.test.ts
@@ -6,6 +6,10 @@ import { type RequestInfo, type RequestInit } from '@anthropic-ai/sdk/_shims/ind
type Fetch = (req: string | RequestInfo, init?: RequestInit) => Promise;
+function assertNever(x: never): never {
+ throw new Error(`unreachable: ${x}`);
+}
+
async function* messageIterable(message: Message): AsyncGenerator {
yield {
type: 'message_start',
@@ -17,16 +21,39 @@ async function* messageIterable(message: Message): AsyncGenerator {
);
for await (const event of stream) {
- if (event.type === 'content_block_delta' && event.delta.text.includes('He')) {
+ if (
+ event.type === 'content_block_delta' &&
+ event.delta.type == 'text_delta' &&
+ event.delta.text.includes('He')
+ ) {
break;
}
}
@@ -386,7 +417,11 @@ describe('MessageStream class', () => {
async function runStream() {
for await (const event of stream) {
- if (event.type === 'content_block_delta' && event.delta.text.includes('He')) {
+ if (
+ event.type === 'content_block_delta' &&
+ event.delta.type === 'text_delta' &&
+ event.delta.text.includes('He')
+ ) {
break;
}
}
From 0ef0e39a870541bbe800b03c1bdcf88eb6e1350c Mon Sep 17 00:00:00 2001
From: Robert Craigie
Date: Thu, 30 May 2024 15:52:41 +0100
Subject: [PATCH 5/8] docs(helpers): mention inputJson event
---
helpers.md | 4 ++++
src/lib/MessageStream.ts | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/helpers.md b/helpers.md
index 859d9442..53fb049a 100644
--- a/helpers.md
+++ b/helpers.md
@@ -35,6 +35,10 @@ returns an accumulated `Message` which is progressively built-up over events.
The event fired when a text delta is sent by the API. The second parameter returns a `textSnapshot`.
+#### `.on('inputJson', (patialJson: string, jsonSnapshot: unknown) => …)`
+
+The event fired when a json delta is sent by the API. The second parameter returns a `jsonSnapshot`.
+
#### `.on('message', (message: Message) => …)`
The event fired when a message is done being streamed by the API. Corresponds to the `message_stop` SSE event.
diff --git a/src/lib/MessageStream.ts b/src/lib/MessageStream.ts
index 5fb629fe..072cca7f 100644
--- a/src/lib/MessageStream.ts
+++ b/src/lib/MessageStream.ts
@@ -18,7 +18,7 @@ export interface MessageStreamEvents {
connect: () => void;
streamEvent: (event: MessageStreamEvent, snapshot: Message) => void;
text: (textDelta: string, textSnapshot: string) => void;
- inputJson: (jsonDelta: string, jsonSnapshot: unknown) => void;
+ inputJson: (partialJson: string, jsonSnapshot: unknown) => void;
message: (message: Message) => void;
contentBlock: (content: ContentBlock) => void;
finalMessage: (message: Message) => void;
From 91fc61ae7246705d26e96a95dae38b46e9ad9290 Mon Sep 17 00:00:00 2001
From: Robert Craigie
Date: Thu, 30 May 2024 16:41:47 +0100
Subject: [PATCH 6/8] feat(bedrock): support tools
(this is an empty commit to trigger a release)
---
packages/bedrock-sdk/build | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/bedrock-sdk/build b/packages/bedrock-sdk/build
index cbffa1fe..4f14ea52 100644
--- a/packages/bedrock-sdk/build
+++ b/packages/bedrock-sdk/build
@@ -28,6 +28,7 @@ npm exec tsc-multi
# No way to get that from index.ts because it would cause compile errors
# when building .mjs
DIST_PATH=./dist node ../../scripts/utils/fix-index-exports.cjs
+
# with "moduleResolution": "nodenext", if ESM resolves to index.d.ts,
# it'll have TS errors on the default import. But if it resolves to
# index.d.mts the default import will work (even though both files have
From acf0aa7571425c8582740616e24883c2ec65218b Mon Sep 17 00:00:00 2001
From: Robert Craigie
Date: Thu, 30 May 2024 16:42:08 +0100
Subject: [PATCH 7/8] feat(vertex): support tools
(this is an empty commit to trigger a release)
---
packages/vertex-sdk/build | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/vertex-sdk/build b/packages/vertex-sdk/build
index 23c1d98d..3bb0ece2 100644
--- a/packages/vertex-sdk/build
+++ b/packages/vertex-sdk/build
@@ -28,6 +28,7 @@ npm exec tsc-multi
# No way to get that from index.ts because it would cause compile errors
# when building .mjs
DIST_PATH=./dist node ../../scripts/utils/fix-index-exports.cjs
+
# with "moduleResolution": "nodenext", if ESM resolves to index.d.ts,
# it'll have TS errors on the default import. But if it resolves to
# index.d.mts the default import will work (even though both files have
From 54d3b0d30acf0f8c47dd2143397482cb50d4e042 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Thu, 30 May 2024 16:42:40 +0100
Subject: [PATCH 8/8] chore: release main
---
.release-please-manifest.json | 6 +++---
CHANGELOG.md | 18 ++++++++++++++++++
package.json | 2 +-
packages/bedrock-sdk/CHANGELOG.md | 8 ++++++++
packages/bedrock-sdk/package.json | 2 +-
packages/bedrock-sdk/yarn.lock | 2 +-
packages/vertex-sdk/CHANGELOG.md | 8 ++++++++
packages/vertex-sdk/package.json | 2 +-
packages/vertex-sdk/yarn.lock | 2 +-
src/version.ts | 2 +-
10 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index d720f938..89dad034 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,5 +1,5 @@
{
- ".": "0.21.1",
- "packages/vertex-sdk": "0.3.7",
- "packages/bedrock-sdk": "0.9.8"
+ ".": "0.22.0",
+ "packages/vertex-sdk": "0.4.0",
+ "packages/bedrock-sdk": "0.10.0"
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ed0fc8cb..e7d513f9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,23 @@
# Changelog
+## 0.22.0 (2024-05-30)
+
+Full Changelog: [sdk-v0.21.1...sdk-v0.22.0](https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.21.1...sdk-v0.22.0)
+
+### Features
+
+* **api/types:** add stream event type aliases with a Raw prefix ([#428](https://github.com/anthropics/anthropic-sdk-typescript/issues/428)) ([1e367e4](https://github.com/anthropics/anthropic-sdk-typescript/commit/1e367e4020fa4691c565c89bdfba40c2f6060871))
+* **api:** tool use is GA and available on 3P ([#429](https://github.com/anthropics/anthropic-sdk-typescript/issues/429)) ([2decf85](https://github.com/anthropics/anthropic-sdk-typescript/commit/2decf85e7471932dad98c21d4ed2d476ab1588a6))
+* **bedrock:** support tools ([91fc61a](https://github.com/anthropics/anthropic-sdk-typescript/commit/91fc61ae7246705d26e96a95dae38b46e9ad9290))
+* **streaming:** add tools support ([4c83bb1](https://github.com/anthropics/anthropic-sdk-typescript/commit/4c83bb111735cd513c09d5ed57a5cb0888534afd))
+* **vertex:** support tools ([acf0aa7](https://github.com/anthropics/anthropic-sdk-typescript/commit/acf0aa7571425c8582740616e24883c2ec65218b))
+
+
+### Documentation
+
+* **helpers:** mention inputJson event ([0ef0e39](https://github.com/anthropics/anthropic-sdk-typescript/commit/0ef0e39a870541bbe800b03c1bdcf88eb6e1350c))
+* **readme:** add bundle size badge ([#426](https://github.com/anthropics/anthropic-sdk-typescript/issues/426)) ([bf7c1fd](https://github.com/anthropics/anthropic-sdk-typescript/commit/bf7c1fdaf3476d5c43079e8a0789ed0dd0c807a6))
+
## 0.21.1 (2024-05-21)
Full Changelog: [sdk-v0.21.0...sdk-v0.21.1](https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.21.0...sdk-v0.21.1)
diff --git a/package.json b/package.json
index c824f04c..d82ffe5d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@anthropic-ai/sdk",
- "version": "0.21.1",
+ "version": "0.22.0",
"description": "The official TypeScript library for the Anthropic API",
"author": "Anthropic ",
"types": "dist/index.d.ts",
diff --git a/packages/bedrock-sdk/CHANGELOG.md b/packages/bedrock-sdk/CHANGELOG.md
index 67bf510b..44b37edb 100644
--- a/packages/bedrock-sdk/CHANGELOG.md
+++ b/packages/bedrock-sdk/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 0.10.0 (2024-05-30)
+
+Full Changelog: [bedrock-sdk-v0.9.8...bedrock-sdk-v0.10.0](https://github.com/anthropics/anthropic-sdk-typescript/compare/bedrock-sdk-v0.9.8...bedrock-sdk-v0.10.0)
+
+### Features
+
+* **bedrock:** support tools ([91fc61a](https://github.com/anthropics/anthropic-sdk-typescript/commit/91fc61ae7246705d26e96a95dae38b46e9ad9290))
+
## 0.9.8 (2024-05-16)
Full Changelog: [bedrock-sdk-v0.9.7...bedrock-sdk-v0.9.8](https://github.com/anthropics/anthropic-sdk-typescript/compare/bedrock-sdk-v0.9.7...bedrock-sdk-v0.9.8)
diff --git a/packages/bedrock-sdk/package.json b/packages/bedrock-sdk/package.json
index 6f9bc2af..019cf65e 100644
--- a/packages/bedrock-sdk/package.json
+++ b/packages/bedrock-sdk/package.json
@@ -1,6 +1,6 @@
{
"name": "@anthropic-ai/bedrock-sdk",
- "version": "0.9.8",
+ "version": "0.10.0",
"description": "The official TypeScript library for the Anthropic Bedrock API",
"author": "Anthropic ",
"types": "dist/index.d.ts",
diff --git a/packages/bedrock-sdk/yarn.lock b/packages/bedrock-sdk/yarn.lock
index 0fbffaa4..bb918660 100644
--- a/packages/bedrock-sdk/yarn.lock
+++ b/packages/bedrock-sdk/yarn.lock
@@ -17,7 +17,7 @@
"@anthropic-ai/sdk@file:../../dist":
# x-release-please-start-version
- version "0.21.1"
+ version "0.22.0"
# x-release-please-end-version
dependencies:
"@types/node" "^18.11.18"
diff --git a/packages/vertex-sdk/CHANGELOG.md b/packages/vertex-sdk/CHANGELOG.md
index 15f519e3..69906369 100644
--- a/packages/vertex-sdk/CHANGELOG.md
+++ b/packages/vertex-sdk/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 0.4.0 (2024-05-30)
+
+Full Changelog: [vertex-sdk-v0.3.7...vertex-sdk-v0.4.0](https://github.com/anthropics/anthropic-sdk-typescript/compare/vertex-sdk-v0.3.7...vertex-sdk-v0.4.0)
+
+### Features
+
+* **vertex:** support tools ([acf0aa7](https://github.com/anthropics/anthropic-sdk-typescript/commit/acf0aa7571425c8582740616e24883c2ec65218b))
+
## 0.3.7 (2024-05-16)
Full Changelog: [vertex-sdk-v0.3.6...vertex-sdk-v0.3.7](https://github.com/anthropics/anthropic-sdk-typescript/compare/vertex-sdk-v0.3.6...vertex-sdk-v0.3.7)
diff --git a/packages/vertex-sdk/package.json b/packages/vertex-sdk/package.json
index ac26e5d6..de7a10de 100644
--- a/packages/vertex-sdk/package.json
+++ b/packages/vertex-sdk/package.json
@@ -1,6 +1,6 @@
{
"name": "@anthropic-ai/vertex-sdk",
- "version": "0.3.7",
+ "version": "0.4.0",
"description": "The official TypeScript library for the Anthropic Vertex API",
"author": "Anthropic ",
"types": "dist/index.d.ts",
diff --git a/packages/vertex-sdk/yarn.lock b/packages/vertex-sdk/yarn.lock
index fb6ca458..f5179bb8 100644
--- a/packages/vertex-sdk/yarn.lock
+++ b/packages/vertex-sdk/yarn.lock
@@ -17,7 +17,7 @@
"@anthropic-ai/sdk@file:../../dist":
# x-release-please-start-version
- version "0.21.1"
+ version "0.22.0"
# x-release-please-end-version
dependencies:
"@types/node" "^18.11.18"
diff --git a/src/version.ts b/src/version.ts
index 64a9ac62..db66d332 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '0.21.1'; // x-release-please-version
+export const VERSION = '0.22.0'; // x-release-please-version