diff --git a/.changeset/cuddly-clouds-agree.md b/.changeset/cuddly-clouds-agree.md new file mode 100644 index 00000000000..a0ff8276824 --- /dev/null +++ b/.changeset/cuddly-clouds-agree.md @@ -0,0 +1,12 @@ +--- +"@effect/ai-anthropic": patch +--- + +Fix several issues in the generated OpenAPI models for the Anthropic AI provider +package. + +The OpenAPI specification that Anthropic maintains for its API is apparently +[incorrect](https://github.com/anthropics/anthropic-sdk-typescript/issues/605). +Some properties which are marked as nullable but required are sometimes not +returned by the API. This fixes the schemas associated with some of those +properties, though others may exist / be found that require manual adjustment. diff --git a/packages/ai/anthropic/scripts/generate.sh b/packages/ai/anthropic/scripts/generate.sh index 4ff50d83e51..0d31916cc53 100755 --- a/packages/ai/anthropic/scripts/generate.sh +++ b/packages/ai/anthropic/scripts/generate.sh @@ -1,10 +1,30 @@ -#!/usr/bin/env sh -mkdir -p tmp +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) + +temp_dir=$(mktemp -d) + +cleanup() { + rm -rf "$temp_dir" +} + +trap cleanup EXIT + + anthropic_stats_url="https://raw.githubusercontent.com/anthropics/anthropic-sdk-typescript/refs/heads/main/.stats.yml" -openapi_spec_url=$(curl -sSL $anthropic_stats_url | yq '.openapi_spec_url') -curl $openapi_spec_url > tmp/anthropic.yaml + +openapi_spec_url="$(curl -sSL $anthropic_stats_url | yq ".openapi_spec_url")" + +curl "${openapi_spec_url}" > "${temp_dir}/anthropic.yaml" + echo "/** * @since 1.0.0 */" > src/Generated.ts -pnpm openapi-gen -s tmp/anthropic.yaml >> src/Generated.ts + +pnpm openapi-gen -s "${temp_dir}/anthropic.yaml" >> src/Generated.ts + pnpm eslint --fix src/Generated.ts + +git apply --reject --whitespace=fix "${SCRIPT_DIR}/generated.patch" diff --git a/packages/ai/anthropic/scripts/generated.patch b/packages/ai/anthropic/scripts/generated.patch new file mode 100644 index 00000000000..7a5d1b0c775 --- /dev/null +++ b/packages/ai/anthropic/scripts/generated.patch @@ -0,0 +1,217 @@ +diff --git a/packages/ai/anthropic/src/Generated.ts b/packages/ai/anthropic/src/Generated.ts +index 7c30bea99..644ad429a 100644 +--- a/packages/ai/anthropic/src/Generated.ts ++++ b/packages/ai/anthropic/src/Generated.ts +@@ -14,27 +14,26 @@ export class MessagesPostParams extends S.Struct({ + "anthropic-version": S.optionalWith(S.String, { nullable: true }) + }) {} + +-export class Model extends S.Union( +- S.String, +- S.Literal("claude-3-7-sonnet-latest"), +- S.Literal("claude-3-7-sonnet-20250219"), +- S.Literal("claude-3-5-haiku-latest"), +- S.Literal("claude-3-5-haiku-20241022"), +- S.Literal("claude-sonnet-4-20250514"), +- S.Literal("claude-sonnet-4-0"), +- S.Literal("claude-4-sonnet-20250514"), +- S.Literal("claude-3-5-sonnet-latest"), +- S.Literal("claude-3-5-sonnet-20241022"), +- S.Literal("claude-3-5-sonnet-20240620"), +- S.Literal("claude-opus-4-0"), +- S.Literal("claude-opus-4-20250514"), +- S.Literal("claude-4-opus-20250514"), +- S.Literal("claude-3-opus-latest"), +- S.Literal("claude-3-opus-20240229"), +- S.Literal("claude-3-sonnet-20240229"), +- S.Literal("claude-3-haiku-20240307"), +- S.Literal("claude-2.1"), +- S.Literal("claude-2.0") ++export class Model extends S.Literal( ++ "claude-3-7-sonnet-latest", ++ "claude-3-7-sonnet-20250219", ++ "claude-3-5-haiku-latest", ++ "claude-3-5-haiku-20241022", ++ "claude-sonnet-4-20250514", ++ "claude-sonnet-4-0", ++ "claude-4-sonnet-20250514", ++ "claude-3-5-sonnet-latest", ++ "claude-3-5-sonnet-20241022", ++ "claude-3-5-sonnet-20240620", ++ "claude-opus-4-0", ++ "claude-opus-4-20250514", ++ "claude-4-opus-20250514", ++ "claude-3-opus-latest", ++ "claude-3-opus-20240229", ++ "claude-3-sonnet-20240229", ++ "claude-3-haiku-20240307", ++ "claude-2.1", ++ "claude-2.0" + ) {} + + export class CacheControlEphemeralType extends S.Literal("ephemeral") {} +@@ -397,14 +396,14 @@ export class WebSearchTool20250305 extends S.Struct({ + "allowed_domains": S.optionalWith(S.Union(S.Array(S.String), S.Null), { nullable: true }), + "blocked_domains": S.optionalWith(S.Union(S.Array(S.String), S.Null), { nullable: true }), + "cache_control": S.optionalWith(S.Union(CacheControlEphemeral, S.Null), { nullable: true }), +- "max_uses": S.optionalWith(S.Union(S.Int.pipe(S.greaterThan(undefined)), S.Null), { nullable: true }), ++ "max_uses": S.optionalWith(S.Union(S.Int.pipe(S.greaterThan(0)), S.Null), { nullable: true }), + "name": WebSearchTool20250305Name, + "type": WebSearchTool20250305Type, + "user_location": S.optionalWith(S.Union(UserLocation, S.Null), { nullable: true }) + }) {} + + export class CreateMessageParams extends S.Class("CreateMessageParams")({ +- "model": Model, ++ "model": S.Union(S.String, Model), + "messages": S.Array(InputMessage), + "max_tokens": S.Int.pipe(S.greaterThanOrEqualTo(1)), + "metadata": S.optionalWith(Metadata, { nullable: true }), +@@ -473,19 +472,16 @@ export class ResponseWebSearchResultLocationCitation extends S.Struct({ + export class ResponseTextBlockType extends S.Literal("text") {} + + export class ResponseTextBlock extends S.Struct({ +- "citations": S.NullOr( +- S.Union( +- S.Array( +- S.Union( +- ResponseCharLocationCitation, +- ResponsePageLocationCitation, +- ResponseContentBlockLocationCitation, +- ResponseWebSearchResultLocationCitation +- ) +- ), +- S.Null ++ "citations": S.optional(S.NullOr( ++ S.Array( ++ S.Union( ++ ResponseCharLocationCitation, ++ ResponsePageLocationCitation, ++ ResponseContentBlockLocationCitation, ++ ResponseWebSearchResultLocationCitation ++ ) + ) +- ), ++ )), + "text": S.String.pipe(S.minLength(0), S.maxLength(5000000)), + "type": ResponseTextBlockType + }) {} +@@ -574,7 +570,7 @@ export class Usage extends S.Struct({ + "cache_read_input_tokens": S.NullOr(S.Union(S.Int.pipe(S.greaterThanOrEqualTo(0)), S.Null)), + "input_tokens": S.Int.pipe(S.greaterThanOrEqualTo(0)), + "output_tokens": S.Int.pipe(S.greaterThanOrEqualTo(0)), +- "server_tool_use": S.NullOr(S.Union(ServerToolUsage, S.Null)), ++ "server_tool_use": S.optional(S.NullOr(ServerToolUsage)), + "service_tier": S.NullOr(S.Union(UsageServiceTierEnum, S.Null)) + }) {} + +@@ -583,7 +579,7 @@ export class Message extends S.Class("Message")({ + "type": MessageType, + "role": MessageRole, + "content": S.Array(ContentBlock), +- "model": Model, ++ "model": S.Union(S.String, Model), + "stop_reason": S.Union(StopReason, S.Null), + "stop_sequence": S.NullOr(S.Union(S.String, S.Null)), + "usage": Usage +@@ -675,7 +671,7 @@ export class CompletePostParams extends S.Struct({ + }) {} + + export class CompletionRequest extends S.Class("CompletionRequest")({ +- "model": Model, ++ "model": S.Union(S.String, Model), + "prompt": S.String.pipe(S.minLength(1)), + "max_tokens_to_sample": S.Int.pipe(S.greaterThanOrEqualTo(1)), + "stop_sequences": S.optionalWith(S.Array(S.String), { nullable: true }), +@@ -691,7 +687,7 @@ export class CompletionResponseType extends S.Literal("completion") {} + export class CompletionResponse extends S.Class("CompletionResponse")({ + "completion": S.String, + "id": S.String, +- "model": Model, ++ "model": S.Union(S.String, Model), + "stop_reason": S.Union(S.String, S.Null), + "type": CompletionResponseType + }) {} +@@ -812,7 +808,7 @@ export class MessagesCountTokensPostParams extends S.Struct({ + + export class CountMessageTokensParams extends S.Class("CountMessageTokensParams")({ + "messages": S.Array(InputMessage), +- "model": Model, ++ "model": S.Union(S.String, Model), + "system": S.optionalWith(S.Union(S.String, S.Array(RequestTextBlock)), { nullable: true }), + "thinking": S.optionalWith(ThinkingConfigParam, { nullable: true }), + "tool_choice": S.optionalWith(ToolChoice, { nullable: true }), +@@ -1405,7 +1401,7 @@ export class BetaWebSearchTool20250305 extends S.Struct({ + "allowed_domains": S.optionalWith(S.Union(S.Array(S.String), S.Null), { nullable: true }), + "blocked_domains": S.optionalWith(S.Union(S.Array(S.String), S.Null), { nullable: true }), + "cache_control": S.optionalWith(S.Union(BetaCacheControlEphemeral, S.Null), { nullable: true }), +- "max_uses": S.optionalWith(S.Union(S.Int.pipe(S.greaterThan(undefined)), S.Null), { nullable: true }), ++ "max_uses": S.optionalWith(S.Union(S.Int.pipe(S.greaterThan(0)), S.Null), { nullable: true }), + "name": BetaWebSearchTool20250305Name, + "type": BetaWebSearchTool20250305Type, + "user_location": S.optionalWith(S.Union(BetaUserLocation, S.Null), { nullable: true }) +@@ -1422,7 +1418,7 @@ export class BetaCodeExecutionTool20250522 extends S.Struct({ + }) {} + + export class BetaCreateMessageParams extends S.Class("BetaCreateMessageParams")({ +- "model": Model, ++ "model": S.Union(S.String, Model), + "messages": S.Array(BetaInputMessage), + "container": S.optionalWith(S.Union(S.String, S.Null), { nullable: true }), + "max_tokens": S.Int.pipe(S.greaterThanOrEqualTo(1)), +@@ -1506,19 +1502,16 @@ export class BetaResponseWebSearchResultLocationCitation extends S.Struct({ + export class BetaResponseTextBlockType extends S.Literal("text") {} + + export class BetaResponseTextBlock extends S.Struct({ +- "citations": S.NullOr( +- S.Union( +- S.Array( +- S.Union( +- BetaResponseCharLocationCitation, +- BetaResponsePageLocationCitation, +- BetaResponseContentBlockLocationCitation, +- BetaResponseWebSearchResultLocationCitation +- ) +- ), +- S.Null ++ "citations": S.optional(S.NullOr( ++ S.Array( ++ S.Union( ++ BetaResponseCharLocationCitation, ++ BetaResponsePageLocationCitation, ++ BetaResponseContentBlockLocationCitation, ++ BetaResponseWebSearchResultLocationCitation ++ ) + ) +- ), ++ )), + "text": S.String.pipe(S.minLength(0), S.maxLength(5000000)), + "type": BetaResponseTextBlockType + }) {} +@@ -1675,7 +1668,7 @@ export class BetaUsage extends S.Struct({ + "cache_read_input_tokens": S.NullOr(S.Union(S.Int.pipe(S.greaterThanOrEqualTo(0)), S.Null)), + "input_tokens": S.Int.pipe(S.greaterThanOrEqualTo(0)), + "output_tokens": S.Int.pipe(S.greaterThanOrEqualTo(0)), +- "server_tool_use": S.NullOr(S.Union(BetaServerToolUsage, S.Null)), ++ "server_tool_use": S.optional(S.NullOr(BetaServerToolUsage)), + "service_tier": S.NullOr(S.Union(BetaUsageServiceTierEnum, S.Null)) + }) {} + +@@ -1689,7 +1682,7 @@ export class BetaMessage extends S.Class("BetaMessage")({ + "type": BetaMessageType, + "role": BetaMessageRole, + "content": S.Array(BetaContentBlock), +- "model": Model, ++ "model": S.Union(S.String, Model), + "stop_reason": S.Union(BetaStopReason, S.Null), + "stop_sequence": S.NullOr(S.Union(S.String, S.Null)), + "usage": BetaUsage, +@@ -1907,7 +1900,7 @@ export class BetaCountMessageTokensParams + extends S.Class("BetaCountMessageTokensParams")({ + "mcp_servers": S.optionalWith(S.Array(BetaRequestMCPServerURLDefinition).pipe(S.maxItems(20)), { nullable: true }), + "messages": S.Array(BetaInputMessage), +- "model": Model, ++ "model": S.Union(S.String, Model), + "system": S.optionalWith(S.Union(S.String, S.Array(BetaRequestTextBlock)), { nullable: true }), + "thinking": S.optionalWith(BetaThinkingConfigParam, { nullable: true }), + "tool_choice": S.optionalWith(BetaToolChoice, { nullable: true }), diff --git a/packages/ai/anthropic/src/Generated.ts b/packages/ai/anthropic/src/Generated.ts index c0c1534cff4..644ad429aed 100644 --- a/packages/ai/anthropic/src/Generated.ts +++ b/packages/ai/anthropic/src/Generated.ts @@ -14,26 +14,26 @@ export class MessagesPostParams extends S.Struct({ "anthropic-version": S.optionalWith(S.String, { nullable: true }) }) {} -export class Model extends S.Union( - S.Literal("claude-3-7-sonnet-latest"), - S.Literal("claude-3-7-sonnet-20250219"), - S.Literal("claude-3-5-haiku-latest"), - S.Literal("claude-3-5-haiku-20241022"), - S.Literal("claude-sonnet-4-20250514"), - S.Literal("claude-sonnet-4-0"), - S.Literal("claude-4-sonnet-20250514"), - S.Literal("claude-3-5-sonnet-latest"), - S.Literal("claude-3-5-sonnet-20241022"), - S.Literal("claude-3-5-sonnet-20240620"), - S.Literal("claude-opus-4-0"), - S.Literal("claude-opus-4-20250514"), - S.Literal("claude-4-opus-20250514"), - S.Literal("claude-3-opus-latest"), - S.Literal("claude-3-opus-20240229"), - S.Literal("claude-3-sonnet-20240229"), - S.Literal("claude-3-haiku-20240307"), - S.Literal("claude-2.1"), - S.Literal("claude-2.0") +export class Model extends S.Literal( + "claude-3-7-sonnet-latest", + "claude-3-7-sonnet-20250219", + "claude-3-5-haiku-latest", + "claude-3-5-haiku-20241022", + "claude-sonnet-4-20250514", + "claude-sonnet-4-0", + "claude-4-sonnet-20250514", + "claude-3-5-sonnet-latest", + "claude-3-5-sonnet-20241022", + "claude-3-5-sonnet-20240620", + "claude-opus-4-0", + "claude-opus-4-20250514", + "claude-4-opus-20250514", + "claude-3-opus-latest", + "claude-3-opus-20240229", + "claude-3-sonnet-20240229", + "claude-3-haiku-20240307", + "claude-2.1", + "claude-2.0" ) {} export class CacheControlEphemeralType extends S.Literal("ephemeral") {} @@ -472,19 +472,16 @@ export class ResponseWebSearchResultLocationCitation extends S.Struct({ export class ResponseTextBlockType extends S.Literal("text") {} export class ResponseTextBlock extends S.Struct({ - "citations": S.NullOr( - S.Union( - S.Array( - S.Union( - ResponseCharLocationCitation, - ResponsePageLocationCitation, - ResponseContentBlockLocationCitation, - ResponseWebSearchResultLocationCitation - ) - ), - S.Null + "citations": S.optional(S.NullOr( + S.Array( + S.Union( + ResponseCharLocationCitation, + ResponsePageLocationCitation, + ResponseContentBlockLocationCitation, + ResponseWebSearchResultLocationCitation + ) ) - ), + )), "text": S.String.pipe(S.minLength(0), S.maxLength(5000000)), "type": ResponseTextBlockType }) {} @@ -573,7 +570,7 @@ export class Usage extends S.Struct({ "cache_read_input_tokens": S.NullOr(S.Union(S.Int.pipe(S.greaterThanOrEqualTo(0)), S.Null)), "input_tokens": S.Int.pipe(S.greaterThanOrEqualTo(0)), "output_tokens": S.Int.pipe(S.greaterThanOrEqualTo(0)), - "server_tool_use": S.NullOr(S.Union(ServerToolUsage, S.Null)), + "server_tool_use": S.optional(S.NullOr(ServerToolUsage)), "service_tier": S.NullOr(S.Union(UsageServiceTierEnum, S.Null)) }) {} @@ -1505,19 +1502,16 @@ export class BetaResponseWebSearchResultLocationCitation extends S.Struct({ export class BetaResponseTextBlockType extends S.Literal("text") {} export class BetaResponseTextBlock extends S.Struct({ - "citations": S.NullOr( - S.Union( - S.Array( - S.Union( - BetaResponseCharLocationCitation, - BetaResponsePageLocationCitation, - BetaResponseContentBlockLocationCitation, - BetaResponseWebSearchResultLocationCitation - ) - ), - S.Null + "citations": S.optional(S.NullOr( + S.Array( + S.Union( + BetaResponseCharLocationCitation, + BetaResponsePageLocationCitation, + BetaResponseContentBlockLocationCitation, + BetaResponseWebSearchResultLocationCitation + ) ) - ), + )), "text": S.String.pipe(S.minLength(0), S.maxLength(5000000)), "type": BetaResponseTextBlockType }) {} @@ -1674,7 +1668,7 @@ export class BetaUsage extends S.Struct({ "cache_read_input_tokens": S.NullOr(S.Union(S.Int.pipe(S.greaterThanOrEqualTo(0)), S.Null)), "input_tokens": S.Int.pipe(S.greaterThanOrEqualTo(0)), "output_tokens": S.Int.pipe(S.greaterThanOrEqualTo(0)), - "server_tool_use": S.NullOr(S.Union(BetaServerToolUsage, S.Null)), + "server_tool_use": S.optional(S.NullOr(BetaServerToolUsage)), "service_tier": S.NullOr(S.Union(BetaUsageServiceTierEnum, S.Null)) }) {}