From 5d2b183b6dc4f13395f9e6805d936ec2140c57d0 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] 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, });