import type { RequestInit, RequestInfo, BodyInit } from './internal/builtin-types';
import type { HTTPMethod, PromiseOrValue, MergedRequestInit, FinalizedRequestInit } from './internal/types';
import { validatePositiveInteger, isAbsoluteURL, safeJSON } from './internal/utils/values';
import { sleep } from './internal/utils/sleep';
export type { Logger, LogLevel } from './internal/utils/log';
import { castToError, isAbortError } from './internal/errors';
import type { APIResponseProps } from './internal/parse';
import { getPlatformHeaders } from './internal/detect-platform';
import {
  armAbandonmentBackstop,
  registerRequestSignalCleanup,
  releaseRequestSignal,
} from './internal/request-signal';
import * as Shims from './internal/shims';
import * as Opts from './internal/request-options';
import {
  endApiCallSpan,
  getTracer,
  guardTracing,
  injectTraceHeaders,
  recordAttempt,
  resolveOpenTelemetryOptions,
  type ApiCallResult,
  type OpenTelemetryOptions,
  type ResolvedOpenTelemetryOptions,
} from './internal/tracing';
export type {
  OpenTelemetryOptions,
  OpenTelemetryRequestOptions,
  OpenTelemetryTracesOptions,
  ResolvedOpenTelemetryOptions,
} from './internal/tracing';
import { stringifyQuery } from './internal/utils/query';
import { context, trace, type Span, type Tracer } from '@opentelemetry/api';
import { VERSION } from './version';
import * as Errors from './core/error';
import type { AccessTokenProvider } from './lib/credentials/types';
import { OAUTH_API_BETA_HEADER } from './lib/credentials/types';
import { TokenCache } from './lib/credentials/token-cache';
import { setAnthropicSpanAttributes, takeTraceHeaders, withoutTraceHeaders } from './lib/internal/tracing';
import { defaultCredentials, resolveCredentialsFromConfig } from './lib/credentials/credential-chain';
import type { AnthropicConfig } from './core/credentials';
import {
  type Middleware,
  isFetchOriginError,
  isRetryableError,
  wrapFetchWithMiddleware,
} from './core/middleware';
export type { Middleware, MiddlewareContext, MiddlewareNext } from './core/middleware';
export type { APIRequest } from './core/api';
import * as Pagination from './core/pagination';
import {
  type BidirectionalPageCursor,
  type BidirectionalPageCursorParams,
  BidirectionalPageCursorResponse,
  type Page,
  type PageCursor,
  type PageCursorParams,
  PageCursorResponse,
  type PageParams,
  PageResponse,
  type ReportPageCursor,
  type ReportPageCursorParams,
  ReportPageCursorResponse,
  type TokenPage,
  type TokenPageParams,
  TokenPageResponse,
} from './core/pagination';
import * as Uploads from './core/uploads';
import * as API from './resources/index';
import { APIPromise } from './core/api-promise';
import {
  DeletedFile,
  FileDeleteParams,
  FileDownloadParams,
  FileListParams,
  FileMetadata,
  FileMetadataPageCursor,
  FileRetrieveMetadataParams,
  FileUploadParams,
  Files,
} from './resources/files';
import {
  CapabilitySupport,
  ContextManagementCapability,
  EffortCapability,
  ModelCapabilities,
  ModelInfo,
  ModelInfosPage,
  ModelLine,
  ModelListParams,
  ModelRetrieveParams,
  Models,
  ServerToolsCapability,
  ThinkingCapability,
  ThinkingTypes,
} from './resources/models';
import {
  AnthropicBeta,
  Beta,
  BetaAPIError,
  BetaAuthenticationError,
  BetaBillingError,
  BetaCurrency,
  BetaError,
  BetaErrorResponse,
  BetaGatewayTimeoutError,
  BetaInvalidRequestError,
  BetaMonetaryAmount,
  BetaNotFoundError,
  BetaOverloadedError,
  BetaPermissionError,
  BetaRateLimitError,
} from './resources/beta/beta';
import {
  AssistantMessageParam,
  Base64ImageSource,
  Base64PDFSource,
  BashCodeExecutionOutputBlock,
  BashCodeExecutionOutputBlockParam,
  BashCodeExecutionResultBlock,
  BashCodeExecutionResultBlockParam,
  BashCodeExecutionToolResultBlock,
  BashCodeExecutionToolResultBlockParam,
  BashCodeExecutionToolResultError,
  BashCodeExecutionToolResultErrorCode,
  BashCodeExecutionToolResultErrorParam,
  BrowserClickTarget,
  BrowserCloseTabConfig,
  BrowserCloseTabInput,
  BrowserCloseTabToolUseBlock,
  BrowserCoordinateTarget,
  BrowserDoubleClickConfig,
  BrowserDoubleClickInput,
  BrowserDoubleClickToolUseBlock,
  BrowserFileUploadConfig,
  BrowserFileUploadInput,
  BrowserFileUploadToolUseBlock,
  BrowserFindConfig,
  BrowserFindInput,
  BrowserFindToolUseBlock,
  BrowserFormInputConfig,
  BrowserFormInputInput,
  BrowserFormInputToolUseBlock,
  BrowserFormInputValue,
  BrowserGetPageTextConfig,
  BrowserGetPageTextInput,
  BrowserGetPageTextToolUseBlock,
  BrowserHoldKeyConfig,
  BrowserHoldKeyInput,
  BrowserHoldKeyToolUseBlock,
  BrowserHoverConfig,
  BrowserHoverInput,
  BrowserHoverToolUseBlock,
  BrowserJavascriptExecConfig,
  BrowserJavascriptExecInput,
  BrowserJavascriptExecToolUseBlock,
  BrowserKeyConfig,
  BrowserKeyInput,
  BrowserKeyToolUseBlock,
  BrowserLeftClickConfig,
  BrowserLeftClickDragConfig,
  BrowserLeftClickDragInput,
  BrowserLeftClickDragToolUseBlock,
  BrowserLeftClickInput,
  BrowserLeftClickToolUseBlock,
  BrowserLeftMouseDownConfig,
  BrowserLeftMouseDownInput,
  BrowserLeftMouseDownToolUseBlock,
  BrowserLeftMouseUpConfig,
  BrowserLeftMouseUpInput,
  BrowserLeftMouseUpToolUseBlock,
  BrowserListTabsConfig,
  BrowserListTabsInput,
  BrowserListTabsToolUseBlock,
  BrowserMemberInput,
  BrowserMemberName,
  BrowserMiddleClickConfig,
  BrowserMiddleClickInput,
  BrowserMiddleClickToolUseBlock,
  BrowserMouseMoveConfig,
  BrowserMouseMoveInput,
  BrowserMouseMoveToolUseBlock,
  BrowserNavigateConfig,
  BrowserNavigateInput,
  BrowserNavigateToolUseBlock,
  BrowserNewTabConfig,
  BrowserNewTabInput,
  BrowserNewTabToolUseBlock,
  BrowserReadConsoleConfig,
  BrowserReadConsoleInput,
  BrowserReadConsoleToolUseBlock,
  BrowserReadNetworkConfig,
  BrowserReadNetworkInput,
  BrowserReadNetworkToolUseBlock,
  BrowserReadPageConfig,
  BrowserReadPageFilter,
  BrowserReadPageInput,
  BrowserReadPageToolUseBlock,
  BrowserRefTarget,
  BrowserRightClickConfig,
  BrowserRightClickInput,
  BrowserRightClickToolUseBlock,
  BrowserScreenshotConfig,
  BrowserScreenshotInput,
  BrowserScreenshotToolUseBlock,
  BrowserScrollConfig,
  BrowserScrollDirection,
  BrowserScrollInput,
  BrowserScrollToConfig,
  BrowserScrollToInput,
  BrowserScrollToToolUseBlock,
  BrowserScrollToolUseBlock,
  BrowserStateBlockParam,
  BrowserStateChange,
  BrowserStateChangeDownloadCompleted,
  BrowserStateChangeDownloadFailed,
  BrowserStateChangeDownloadStarted,
  BrowserStateChangeTabOpened,
  BrowserStateTabEntry,
  BrowserSwitchTabConfig,
  BrowserSwitchTabInput,
  BrowserSwitchTabToolUseBlock,
  BrowserToolUseBlock,
  BrowserToolset20260801,
  BrowserToolsetConfigs,
  BrowserTripleClickConfig,
  BrowserTripleClickInput,
  BrowserTripleClickToolUseBlock,
  BrowserTypeConfig,
  BrowserTypeInput,
  BrowserTypeToolUseBlock,
  BrowserWaitConfig,
  BrowserWaitInput,
  BrowserWaitToolUseBlock,
  BrowserZoomConfig,
  BrowserZoomInput,
  BrowserZoomToolUseBlock,
  CacheControlEphemeral,
  CacheCreation,
  CacheMissMessagesChanged,
  CacheMissModelChanged,
  CacheMissPreviousMessageNotFound,
  CacheMissReason,
  CacheMissSystemChanged,
  CacheMissToolsChanged,
  CacheMissUnavailable,
  CitationCharLocation,
  CitationCharLocationParam,
  CitationContentBlockLocation,
  CitationContentBlockLocationParam,
  CitationPageLocation,
  CitationPageLocationParam,
  CitationSearchResultLocationParam,
  CitationWebSearchResultLocationParam,
  CitationsConfig,
  CitationsConfigParam,
  CitationsDelta,
  CitationsSearchResultLocation,
  CitationsWebSearchResultLocation,
  ClientToolUnion,
  CodeExecutionOutputBlock,
  CodeExecutionOutputBlockParam,
  CodeExecutionResultBlock,
  CodeExecutionResultBlockParam,
  CodeExecutionTool20250522,
  CodeExecutionTool20250825,
  CodeExecutionTool20260120,
  CodeExecutionTool20260521,
  CodeExecutionToolResultBlock,
  CodeExecutionToolResultBlockContent,
  CodeExecutionToolResultBlockParam,
  CodeExecutionToolResultBlockParamContent,
  CodeExecutionToolResultError,
  CodeExecutionToolResultErrorCode,
  CodeExecutionToolResultErrorParam,
  ComputerCursorPositionConfig,
  ComputerCursorPositionInput,
  ComputerCursorPositionToolUseBlock,
  ComputerDoubleClickConfig,
  ComputerDoubleClickInput,
  ComputerDoubleClickToolUseBlock,
  ComputerHoldKeyConfig,
  ComputerHoldKeyInput,
  ComputerHoldKeyToolUseBlock,
  ComputerKeyConfig,
  ComputerKeyInput,
  ComputerKeyToolUseBlock,
  ComputerLeftClickConfig,
  ComputerLeftClickDragConfig,
  ComputerLeftClickDragInput,
  ComputerLeftClickDragToolUseBlock,
  ComputerLeftClickInput,
  ComputerLeftClickToolUseBlock,
  ComputerLeftMouseDownConfig,
  ComputerLeftMouseDownInput,
  ComputerLeftMouseDownToolUseBlock,
  ComputerLeftMouseUpConfig,
  ComputerLeftMouseUpInput,
  ComputerLeftMouseUpToolUseBlock,
  ComputerMemberInput,
  ComputerMemberName,
  ComputerMiddleClickConfig,
  ComputerMiddleClickInput,
  ComputerMiddleClickToolUseBlock,
  ComputerMouseMoveConfig,
  ComputerMouseMoveInput,
  ComputerMouseMoveToolUseBlock,
  ComputerRightClickConfig,
  ComputerRightClickInput,
  ComputerRightClickToolUseBlock,
  ComputerScreenshotConfig,
  ComputerScreenshotInput,
  ComputerScreenshotToolUseBlock,
  ComputerScrollConfig,
  ComputerScrollDirection,
  ComputerScrollInput,
  ComputerScrollToolUseBlock,
  ComputerToolUseBlock,
  ComputerToolset20260801,
  ComputerToolsetConfigs,
  ComputerTripleClickConfig,
  ComputerTripleClickInput,
  ComputerTripleClickToolUseBlock,
  ComputerTypeConfig,
  ComputerTypeInput,
  ComputerTypeToolUseBlock,
  ComputerWaitConfig,
  ComputerWaitInput,
  ComputerWaitToolUseBlock,
  ComputerZoomConfig,
  ComputerZoomInput,
  ComputerZoomToolUseBlock,
  Container,
  ContainerParams,
  ContainerSkill,
  ContainerUploadBlock,
  ContainerUploadBlockParam,
  ContentBlock,
  ContentBlockDeltaEvent,
  ContentBlockParam,
  ContentBlockStartEvent,
  ContentBlockStopEvent,
  ContentBlockSource,
  ContentBlockSourceContent,
  Diagnostics,
  DiagnosticsParam,
  DirectCaller,
  DocumentBlock,
  DocumentBlockParam,
  EncryptedCodeExecutionResultBlock,
  EncryptedCodeExecutionResultBlockParam,
  FileDocumentSource,
  FileImageSource,
  ImageBlockParam,
  ImageTransformationsParam,
  InputJSONDelta,
  JSONOutputFormat,
  MemoryTool20250818,
  Message,
  MessageContentParam,
  MessageStreamParams,
  MessageCountTokensParams,
  MessageCountTokensTool,
  MessageCreateParams,
  MessageCreateParamsContainer,
  MessageCreateParamsNonStreaming,
  MessageCreateParamsStreaming,
  MessageDeltaEvent,
  MessageDeltaUsage,
  MessageParam,
  MessageStartEvent,
  MessageStopEvent,
  MessageStreamEvent,
  MessageTokensCount,
  Messages,
  Metadata,
  Model,
  OutputConfig,
  OutputTokensDetails,
  PlainTextSource,
  RawContentBlockDelta,
  RawContentBlockDeltaEvent,
  RawContentBlockStartEvent,
  RawContentBlockStopEvent,
  RawMessageDeltaEvent,
  RawMessageStartEvent,
  RawMessageStopEvent,
  RawMessageStreamEvent,
  RedactedThinkingBlock,
  RedactedThinkingBlockParam,
  RefusalStopDetails,
  ResponseBrowserCloseTabToolUseBlock,
  ResponseBrowserDoubleClickToolUseBlock,
  ResponseBrowserFileUploadToolUseBlock,
  ResponseBrowserFindToolUseBlock,
  ResponseBrowserFormInputToolUseBlock,
  ResponseBrowserGetPageTextToolUseBlock,
  ResponseBrowserHoldKeyToolUseBlock,
  ResponseBrowserHoverToolUseBlock,
  ResponseBrowserJavascriptExecToolUseBlock,
  ResponseBrowserKeyToolUseBlock,
  ResponseBrowserLeftClickDragToolUseBlock,
  ResponseBrowserLeftClickToolUseBlock,
  ResponseBrowserLeftMouseDownToolUseBlock,
  ResponseBrowserLeftMouseUpToolUseBlock,
  ResponseBrowserListTabsToolUseBlock,
  ResponseBrowserMiddleClickToolUseBlock,
  ResponseBrowserMouseMoveToolUseBlock,
  ResponseBrowserNavigateToolUseBlock,
  ResponseBrowserNewTabToolUseBlock,
  ResponseBrowserReadConsoleToolUseBlock,
  ResponseBrowserReadNetworkToolUseBlock,
  ResponseBrowserReadPageToolUseBlock,
  ResponseBrowserRightClickToolUseBlock,
  ResponseBrowserScreenshotToolUseBlock,
  ResponseBrowserScrollToToolUseBlock,
  ResponseBrowserScrollToolUseBlock,
  ResponseBrowserSwitchTabToolUseBlock,
  ResponseBrowserToolUseBlock,
  ResponseBrowserTripleClickToolUseBlock,
  ResponseBrowserTypeToolUseBlock,
  ResponseBrowserWaitToolUseBlock,
  ResponseBrowserZoomToolUseBlock,
  ResponseComputerCursorPositionToolUseBlock,
  ResponseComputerDoubleClickToolUseBlock,
  ResponseComputerHoldKeyToolUseBlock,
  ResponseComputerKeyToolUseBlock,
  ResponseComputerLeftClickDragToolUseBlock,
  ResponseComputerLeftClickToolUseBlock,
  ResponseComputerLeftMouseDownToolUseBlock,
  ResponseComputerLeftMouseUpToolUseBlock,
  ResponseComputerMiddleClickToolUseBlock,
  ResponseComputerMouseMoveToolUseBlock,
  ResponseComputerRightClickToolUseBlock,
  ResponseComputerScreenshotToolUseBlock,
  ResponseComputerScrollToolUseBlock,
  ResponseComputerToolUseBlock,
  ResponseComputerTripleClickToolUseBlock,
  ResponseComputerTypeToolUseBlock,
  ResponseComputerWaitToolUseBlock,
  ResponseComputerZoomToolUseBlock,
  ResponseToolUseBlockUnion,
  SearchResultBlockParam,
  ServerToolCaller,
  ServerToolCaller20260120,
  ServerToolUsage,
  ServerToolUseBlock,
  ServerToolUseBlockParam,
  SignatureDelta,
  SkillParams,
  StopReason,
  SystemMessageParam,
  TextBlock,
  TextBlockParam,
  TextCitation,
  TextCitationParam,
  TextDelta,
  TextEditorCodeExecutionCreateResultBlock,
  TextEditorCodeExecutionCreateResultBlockParam,
  TextEditorCodeExecutionStrReplaceResultBlock,
  TextEditorCodeExecutionStrReplaceResultBlockParam,
  TextEditorCodeExecutionToolResultBlock,
  TextEditorCodeExecutionToolResultBlockParam,
  TextEditorCodeExecutionToolResultError,
  TextEditorCodeExecutionToolResultErrorCode,
  TextEditorCodeExecutionToolResultErrorParam,
  TextEditorCodeExecutionViewResultBlock,
  TextEditorCodeExecutionViewResultBlockParam,
  ThinkingBlock,
  ThinkingBlockParam,
  ThinkingConfigAdaptive,
  ThinkingConfigBetweenTools,
  ThinkingConfigDisabled,
  ThinkingConfigEnabled,
  ThinkingConfigParam,
  ThinkingDelta,
  Tool,
  ToolBash20250124,
  ToolChoice,
  ToolChoiceAny,
  ToolChoiceAuto,
  ToolChoiceNone,
  ToolChoiceTool,
  ToolReferenceBlock,
  ToolReferenceBlockParam,
  ToolResultBlockParam,
  ToolSearchToolBm25_20251119,
  ToolSearchToolRegex20251119,
  ToolSearchToolResultBlock,
  ToolSearchToolResultBlockParam,
  ToolSearchToolResultError,
  ToolSearchToolResultErrorCode,
  ToolSearchToolResultErrorParam,
  ToolSearchToolSearchResultBlock,
  ToolSearchToolSearchResultBlockParam,
  ToolTextEditor20250124,
  ToolTextEditor20250429,
  ToolTextEditor20250728,
  ToolUnion,
  ToolUseBlock,
  ToolUseBlockParam,
  ToolUseCaller,
  ToolsetToolUseBlock,
  URLImageSource,
  URLPDFSource,
  Usage,
  UserLocation,
  UserMessageParam,
  WebFetchBlock,
  WebFetchBlockParam,
  WebFetchTool20250910,
  WebFetchTool20260209,
  WebFetchTool20260309,
  WebFetchTool20260318,
  WebFetchToolResultBlock,
  WebFetchToolResultBlockParam,
  WebFetchToolResultErrorBlock,
  WebFetchToolResultErrorBlockParam,
  WebFetchToolResultErrorCode,
  WebFetchURLSourceAll,
  WebFetchURLSourceExcept,
  WebFetchURLSourceNone,
  WebFetchURLSourceOnly,
  WebFetchURLSourceToolReference,
  WebFetchURLSources,
  WebSearchResultBlock,
  WebSearchResultBlockParam,
  WebSearchTool20250305,
  WebSearchTool20260209,
  WebSearchTool20260318,
  WebSearchToolRequestError,
  WebSearchToolResultBlock,
  WebSearchToolResultBlockContent,
  WebSearchToolResultBlockParam,
  WebSearchToolResultBlockParamContent,
  WebSearchToolResultError,
  WebSearchToolResultErrorCode,
} from './resources/messages/messages';
import { Organization, OrganizationInfo, OrganizationRole } from './resources/organization/organization';
import {
  DeletedSkill,
  Skill,
  SkillCreateParams,
  SkillDeleteParams,
  SkillListParams,
  SkillRetrieveParams,
  SkillSource,
  Skills,
  SkillsPageCursor,
} from './resources/skills/skills';
import {
  DeletedUserProfile,
  UserProfile,
  UserProfileAccessType,
  UserProfileCreateParams,
  UserProfileCyberProgram,
  UserProfileCyberRequirements,
  UserProfileCyberTier,
  UserProfileDeleteParams,
  UserProfileEfsFeature,
  UserProfileEfsProgram,
  UserProfileExternalUserAccountStatus,
  UserProfileExternalUserDetails,
  UserProfileExternalUserDetailsParams,
  UserProfileExternalUserEntityType,
  UserProfileListOrder,
  UserProfileListOrderBy,
  UserProfileListParams,
  UserProfileProgramStatus,
  UserProfilePrograms,
  UserProfileRetrieveParams,
  UserProfileUpdateParams,
  UserProfiles,
  UserProfilesPageCursor,
} from './resources/user-profiles/user-profiles';
import { type Fetch } from './internal/builtin-types';
import { isRunningInBrowser } from './internal/detect-platform';
import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
import { FinalRequestOptions, RequestOptions } from './internal/request-options';
import { readEnv } from './internal/utils/env';
import {
  type LogLevel,
  type Logger,
  debugLogRequestDetails,
  defaultLogLevel,
  loggerFor,
  parseLogLevel,
} from './internal/utils/log';
import { isEmptyObj } from './internal/utils/values';
import { checkNever, CREDENTIAL_OPTIONS, type CredentialOption } from './internal/utils/values';

/**
 * Shared auth state. A `withOptions()` clone receives the parent's instance
 * (unless the caller overrides auth options) so a clone created before lazy
 * resolution settles observes the same provider/tokenCache/error/extraHeaders
 * as the parent rather than starting an independent resolution.
 */
type AuthState = {
  provider: AccessTokenProvider | null;
  tokenCache: TokenCache | null;
  resolution: Promise<void> | null;
  error: unknown;
  extraHeaders: Record<string, string>;
  /**
   * `base_url` from the resolved profile/config, normalized (no trailing
   * slash). Stored on the shared auth state so `withOptions()` clones created
   * before lazy resolution settles can still adopt it on their first request.
   */
  baseURL?: string | undefined;
};

/**
 * Per-request auth flags, keyed by the FinalRequestOptions object so
 * caller-owned options aren't mutated.
 */
type RequestAuthFlags = {
  usedTokenCache: boolean;
  didRefreshFor401: boolean;
};

type InternalClientOptions = ClientOptions & {
  __auth?: AuthState | undefined;
  __baseURLIsExplicit?: boolean | undefined;
};

export type ApiKeySetter = () => Promise<string>;

let warnedOfKeyAndTokenInEnv = false;

type Credential =
  | { [Name in CredentialOption]: { type: Name; value: NonNullable<ClientOptions[Name]> } }[CredentialOption]
  | { type: 'defaultChain' };

export interface ClientOptions {
  /**
   * API key used for authentication.
   *
   * - Accepts either a static string or an async function that resolves to a string.
   * - Sent as `Authorization: Bearer <key>`.
   * - Mutually exclusive with `authToken`, `credentials`, `config`, and `profile`.
   * - Defaults to process.env['ANTHROPIC_API_KEY'], which is not read when one of those options is passed.
   * - When a function is provided, it is invoked before each request so you can rotate
   *   or refresh credentials at runtime.
   * - The function must return a non-empty string; otherwise an AnthropicError is thrown.
   * - If the function throws, the error is wrapped in an AnthropicError with the original
   *   error available as `cause`.
   */
  apiKey?: string | ApiKeySetter | null | undefined;

  /**
   * Defaults to process.env['ANTHROPIC_AUTH_TOKEN'].
   *
   * The environment variable is not used when `apiKey`, `credentials`,
   * `config`, or `profile` is passed, or when `ANTHROPIC_API_KEY` is set, which
   * logs a warning once per process. Mutually exclusive with those options.
   */
  authToken?: string | null | undefined;

  /**
   * An {@link AccessTokenProvider} for OAuth/workload-identity authentication.
   *
   * When set, the provider is wrapped in a {@link TokenCache} and used for
   * Bearer token auth on every request. Mutually exclusive with `apiKey`,
   * `authToken`, `config`, and `profile`.
   *
   * If none of these options is passed (and neither `ANTHROPIC_API_KEY` nor
   * `ANTHROPIC_AUTH_TOKEN` is set), the client resolves credentials on the
   * first request, from the first of these: the profile `ANTHROPIC_PROFILE`
   * names, which is an error if it does not exist; the workload identity
   * federation variables; the active profile on disk, which is the one the
   * `active_config` file names, otherwise `default`.
   */
  credentials?: AccessTokenProvider | null | undefined;

  /**
   * An {@link AnthropicConfig} object to resolve credentials from directly,
   * bypassing config-file and environment-variable lookup.
   *
   * Mutually exclusive with `apiKey`, `authToken`, `credentials`, and
   * `profile`. For `oidc_federation`, the SDK performs the jwt-bearer exchange
   * in-process; for `user_oauth`, `authentication.credentials_path` must point
   * at the credentials file.
   */
  config?: AnthropicConfig | null | undefined;

  /**
   * Name of a profile to load from `<config_dir>/configs/<profile>.json`.
   *
   * Selects a profile as the `ANTHROPIC_PROFILE` environment variable does, but
   * for this client instance only. As an explicit constructor argument it takes
   * precedence over every credential in the environment, so a profile that
   * does not exist is an error. Mutually exclusive with `apiKey`, `authToken`,
   * `credentials`, and `config`.
   */
  profile?: string | null | undefined;

  /**
   * Defaults to process.env['ANTHROPIC_WEBHOOK_SIGNING_KEY'].
   */
  webhookKey?: string | null | undefined;

  /**
   * Override the default base URL for the API, e.g., "https://api.example.com/v2/"
   *
   * Defaults to process.env['ANTHROPIC_BASE_URL'].
   */
  baseURL?: string | null | undefined;

  /**
   * The maximum amount of time (in milliseconds) that the client should wait for a response
   * from the server before timing out a single request.
   *
   * Note that request timeouts are retried by default, so in a worst-case scenario you may wait
   * much longer than this timeout before the promise succeeds or fails.
   *
   * @unit milliseconds
   */
  timeout?: number | undefined;
  /**
   * Additional `RequestInit` options to be passed to `fetch` calls.
   * Properties will be overridden by per-request `fetchOptions`.
   */
  fetchOptions?: MergedRequestInit | undefined;

  /**
   * Specify a custom `fetch` function implementation.
   *
   * If not provided, we expect that `fetch` is defined globally.
   */
  fetch?: Fetch | undefined;

  /**
   * {@link Middleware} functions that wrap every HTTP request made by the
   * client.
   *
   * Middleware runs per HTTP attempt, including retries. It observes the
   * canonical Anthropic-shaped request and response on every backend: on
   * clients for third-party backends (Bedrock, Vertex, Foundry), the
   * backend's URL/body rewriting, request signing, and response
   * normalization happen inside `next`.
   */
  middleware?: ReadonlyArray<Middleware> | undefined;

  /**
   * The maximum number of times that the client will retry a request in case of a
   * temporary failure, like a network error or a 5XX error from the server.
   *
   * @default 2
   */
  maxRetries?: number | undefined;

  /**
   * Default headers to include with every request to the API.
   *
   * These can be removed in individual requests by explicitly setting the
   * header to `null` in request options.
   */
  defaultHeaders?: HeadersLike | undefined;

  /**
   * Default query parameters to include with every request to the API.
   *
   * These can be removed in individual requests by explicitly setting the
   * param to `undefined` in request options.
   */
  defaultQuery?: Record<string, string | undefined> | undefined;

  /**
   * By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers.
   * Only set this option to `true` if you understand the risks and have appropriate mitigations in place.
   */
  dangerouslyAllowBrowser?: boolean | undefined;

  /**
   * OpenTelemetry tracing of this client's API calls. Each API call emits a span when
   * the application has registered a tracer provider with the OpenTelemetry API.
   *
   * `false`, short for `{ traces: false }`, disables the spans.
   * `propagation: false` keeps the spans and sends no trace context with the requests.
   *
   * A client without this option reads its environment variables once, when it is constructed:
   * `ANTHROPIC_OPEN_TELEMETRY` set to `false` disables the spans,
   * `ANTHROPIC_OPEN_TELEMETRY_PROPAGATION` set to `false` turns `propagation` off, and
   * `ANTHROPIC_OPEN_TELEMETRY_TRACES_CONTENT_MODE` and
   * `ANTHROPIC_OPEN_TELEMETRY_TRACES_MAX_CONTENT_BYTES` give `traces.contentMode` and
   * `traces.maxContentBytes`. A client with this option does not read them: a field that the
   * option leaves unset has its default.
   *
   * A `withOptions()` copy without its own `openTelemetry` option keeps this client's settled one.
   * A copy with its own option uses that in place of this client's whole option, so it keeps none
   * of this client's fields. Spread {@link BaseAnthropic.openTelemetry} into the copy's option to
   * keep them.
   */
  openTelemetry?: OpenTelemetryOptions | false | undefined;

  /**
   * Set the log level.
   *
   * Defaults to process.env['ANTHROPIC_LOG'] or 'warn' if it isn't set.
   */
  logLevel?: LogLevel | undefined;

  /**
   * Set the logger.
   *
   * Defaults to globalThis.console.
   */
  logger?: Logger | undefined;
}

/**
 * Base class for Anthropic API clients.
 */
export class BaseAnthropic {
  apiKey: string | null;
  authToken: string | null;
  webhookKey: string | null;

  /**
   * The active credential provider. Default credential resolution runs once
   * at construction time. If it fails, the error is surfaced on every
   * request and the client must be reconstructed — there is no retry path.
   *
   * Clones returned by {@link withOptions} share the parent's auth state
   * (provider, token cache, pending resolution, and any resolution error)
   * unless the caller passes an explicit `apiKey`, `authToken`,
   * `credentials`, `config`, or `profile` override.
   */
  get credentials(): AccessTokenProvider | null {
    return this._authState.provider;
  }
  private _authState: AuthState;
  /**
   * Whether `baseURL` was chosen by the caller (constructor arg or env var)
   * rather than derived. Non-explicit base URLs may be replaced — by a
   * profile-supplied host, or by re-derivation in `withOptions()` clones.
   * Subclasses that derive their own base URL should correct this after
   * `super()`, since the base constructor can't tell a derived value apart.
   */
  protected _baseURLIsExplicit: boolean;
  private _requestAuthFlags = new WeakMap<FinalRequestOptions, RequestAuthFlags>();

  baseURL: string;
  maxRetries: number;
  timeout: number;
  logger: Logger;
  logLevel: LogLevel | undefined;
  fetchOptions: MergedRequestInit | undefined;
  middleware: ReadonlyArray<Middleware>;

  private fetch: Fetch;
  #encoder: Opts.RequestEncoder;
  #apiKeyFunction: ApiKeySetter | null;
  #openTelemetry: ResolvedOpenTelemetryOptions;

  /**
   * The `openTelemetry` option as this client settled it when it was constructed: `propagation` and
   * each field of `traces` from the option, or else its default. A client constructed without the
   * option has what the environment variables said. One constructed with `openTelemetry: false` has
   * `traces.enabled: false` here.
   *
   * The value is frozen. It is a valid `openTelemetry` option, so a copy of this client can change
   * one setting and keep the others:
   *
   * ```ts
   * const { openTelemetry } = client;
   * client.withOptions({
   *   openTelemetry: { ...openTelemetry, traces: { ...openTelemetry.traces, contentMode: 'content' } },
   * });
   * ```
   */
  get openTelemetry(): ResolvedOpenTelemetryOptions {
    return this.#openTelemetry;
  }

  /**
   * The tracer that starts the call spans of this client's API calls, or `undefined` when the
   * client's spans are disabled.
   * @internal
   */
  _tracer: Tracer | undefined;

  /**
   * The options this client was constructed with, from which `withOptions()` builds its clone.
   * @internal
   */
  _options: ClientOptions;

  /**
   * The `gen_ai.provider.name` of this client's spans: the platform that serves its requests.
   * The clients for third-party platforms override it.
   * @internal
   */
  _genAIProviderName: string = 'anthropic';

  /**
   * The instrumentation scope of this client's spans: the version of the package that the client
   * is from, and for the client of another platform the platform's name, which the scope's name
   * ends with. The clients for other platforms override it. The constructor calls it.
   * @internal
   */
  _instrumentationScope(): { version: string; platform?: string | undefined } {
    return { version: VERSION };
  }

  /**
   * API Client for interfacing with the Anthropic API.
   *
   * @param {string | null | undefined} [opts.apiKey=process.env['ANTHROPIC_API_KEY'] ?? null]
   * @param {string | null | undefined} [opts.authToken=process.env['ANTHROPIC_AUTH_TOKEN'] ?? null]
   * @param {string | null | undefined} [opts.webhookKey=process.env['ANTHROPIC_WEBHOOK_SIGNING_KEY'] ?? null]
   * @param {string} [opts.baseURL=process.env['ANTHROPIC_BASE_URL'] ?? https://api.anthropic.com] - Override the default base URL for the API.
   * @param {number} [opts.timeout=10 minutes] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
   * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
   * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
   * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
   * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API.
   * @param {Record<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
   * @param {boolean} [opts.dangerouslyAllowBrowser=false] - By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers.
   */
  constructor({
    baseURL = readEnv('ANTHROPIC_BASE_URL'),
    apiKey,
    authToken,
    webhookKey = readEnv('ANTHROPIC_WEBHOOK_SIGNING_KEY') ?? null,
    ...opts
  }: ClientOptions = {}) {
    const given: ClientOptions = { apiKey, authToken, ...opts };
    const passed = CREDENTIAL_OPTIONS.filter((name) => given[name] != null);
    if (passed.length > 1) {
      const list = (names: readonly string[]) => names.map((name) => `\`${name}\``).join(', ');
      throw new TypeError(`Pass at most one of ${list(CREDENTIAL_OPTIONS)}. Received ${list(passed)}.`);
    }
    const [passedName] = passed;
    // A credential passed in code is the client's only one, so the environment
    // is not read for another. `null` keeps that option's variable unread.
    const env =
      passedName != null ? null : (
        {
          apiKey: apiKey === undefined ? readEnv('ANTHROPIC_API_KEY') : undefined,
          authToken: authToken === undefined ? readEnv('ANTHROPIC_AUTH_TOKEN') : undefined,
        }
      );
    const credential: Credential =
      passedName != null ? ({ type: passedName, value: given[passedName] } as Credential)
      : env?.apiKey != null ? { type: 'apiKey', value: env.apiKey }
      : env?.authToken != null ? { type: 'authToken', value: env.authToken }
      : { type: 'defaultChain' };
    const options: ClientOptions = {
      apiKey: credential.type === 'apiKey' ? credential.value : null,
      authToken: credential.type === 'authToken' ? credential.value : null,
      webhookKey,
      ...opts,
      baseURL: baseURL || `https://api.anthropic.com`,
    };

    if (!options.dangerouslyAllowBrowser && isRunningInBrowser()) {
      throw new Errors.AnthropicError(
        "It looks like you're running in a browser-like environment.\n\nThis is disabled by default, as it risks exposing your secret API credentials to attackers.\nIf you understand the risks and have appropriate mitigations in place,\nyou can set the `dangerouslyAllowBrowser` option to `true`, e.g.,\n\nnew Anthropic({ apiKey, dangerouslyAllowBrowser: true });\n",
      );
    }

    this.baseURL = options.baseURL!;
    // After destructuring, `baseURL` is the constructor arg or
    // ANTHROPIC_BASE_URL — both count as an explicit choice that a profile
    // base_url must not override. A falsy value means we fell through to the
    // hardcoded default above and a profile may supply the host. withOptions()
    // propagates the parent's flag via __baseURLIsExplicit so a non-overriding
    // clone doesn't mistake the inherited baseURL for a caller-supplied one.
    this._baseURLIsExplicit = (opts as InternalClientOptions).__baseURLIsExplicit ?? !!baseURL;
    this.timeout = options.timeout ?? BaseAnthropic.DEFAULT_TIMEOUT /* 10 minutes */;
    this.logger = options.logger ?? console;
    // Set default logLevel early so that we can log a warning in parseLogLevel.
    this.logLevel = defaultLogLevel;
    this.logLevel =
      parseLogLevel(options.logLevel, 'ClientOptions.logLevel', loggerFor(this)) ??
      parseLogLevel(readEnv('ANTHROPIC_LOG'), "process.env['ANTHROPIC_LOG']", loggerFor(this)) ??
      defaultLogLevel;
    if (env?.apiKey != null && env.authToken != null && !warnedOfKeyAndTokenInEnv) {
      warnedOfKeyAndTokenInEnv = true;
      loggerFor(this).warn(
        'Anthropic: ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are both set. Using ANTHROPIC_API_KEY.',
      );
    }
    this.fetchOptions = options.fetchOptions;
    this.maxRetries = validatePositiveInteger('maxRetries', options.maxRetries ?? 2);
    const scope = this._instrumentationScope();
    this.#openTelemetry = resolveOpenTelemetryOptions(options.openTelemetry);
    options.openTelemetry = this.#openTelemetry;
    this._tracer = guardTracing(this, () => getTracer(this.#openTelemetry, scope.version, scope.platform));
    this.fetch = options.fetch ?? Shims.getDefaultFetch();
    this.#encoder = Opts.FallbackEncoder;

    this.middleware = [...(options.middleware ?? [])];

    const customHeadersEnv = readEnv('ANTHROPIC_CUSTOM_HEADERS');
    if (customHeadersEnv) {
      const parsed: Record<string, string> = {};
      for (const line of customHeadersEnv.split('\n')) {
        const colon = line.indexOf(':');
        if (colon >= 0) {
          parsed[line.substring(0, colon).trim()] = line.substring(colon + 1).trim();
        }
      }
      options.defaultHeaders = { ...parsed, ...options.defaultHeaders };
    }

    const inherited = (opts as InternalClientOptions).__auth;
    // Never persist the internal __auth handle on _options — it's a
    // one-shot constructor signal, and leaking it through _options would
    // cause withOptions() to spread a stale value into clones.
    delete (options as InternalClientOptions).__auth;
    delete (options as InternalClientOptions).__baseURLIsExplicit;
    this._options = options;

    this.apiKey = typeof options.apiKey === 'string' ? options.apiKey : null;
    this.#apiKeyFunction = typeof options.apiKey === 'function' ? options.apiKey : null;
    this.authToken = options.authToken ?? null;
    this.webhookKey = webhookKey;

    if (inherited) {
      this._authState = inherited;
      if (!this._baseURLIsExplicit && inherited.baseURL) {
        this.baseURL = inherited.baseURL;
      }
    } else {
      this._authState = { provider: null, tokenCache: null, resolution: null, error: null, extraHeaders: {} };

      switch (credential.type) {
        case 'apiKey':
        case 'authToken':
          break;
        case 'credentials':
          this._authState.provider = credential.value;
          this._authState.tokenCache = this._makeTokenCache(credential.value);
          break;
        case 'config': {
          const result = resolveCredentialsFromConfig(credential.value, this._credentialResolverOptions());
          this._authState.provider = result.provider;
          this._authState.tokenCache = this._makeTokenCache(result.provider);
          this._authState.extraHeaders = result.extraHeaders;
          this._applyCredentialBaseURL(result.baseURL);
          break;
        }
        case 'profile':
          this._authState.resolution = this._resolveDefaultCredentials(credential.value);
          break;
        case 'defaultChain':
          if (this._shouldResolveDefaultCredentials()) {
            // No explicit auth provided — lazily resolve from the credential
            // chain on first request. Errors are captured into _auth.error and
            // surfaced on first use rather than as an unhandled rejection.
            this._authState.resolution = this._resolveDefaultCredentials();
          }
          break;
        default:
          checkNever(credential);
      }
    }
  }

  /**
   * Whether to lazily resolve auth from the default credential chain when no
   * explicit auth is configured. Called once from the constructor, so
   * overrides must not depend on subclass instance state. Subclasses that
   * bring their own auth scheme return false so unrelated local credentials
   * are never resolved or allowed to supply a base URL.
   */
  protected _shouldResolveDefaultCredentials(): boolean {
    return true;
  }

  /**
   * Stores a profile/config-supplied base URL on the shared auth state and, if
   * the caller did not pin `baseURL` via constructor option or env, adopts it
   * as this client's outbound API host. Precedence: ctor opt > env > profile >
   * hardcoded default.
   */
  private _applyCredentialBaseURL(baseURL: string | undefined): void {
    if (!baseURL) return;
    const normalized = baseURL.replace(/\/+$/, '');
    this._authState.baseURL = normalized;
    if (!this._baseURLIsExplicit) {
      this.baseURL = normalized;
    }
  }

  /**
   * Options bag passed into the credential chain. `baseURL` here is only the
   * fallback host for the token-exchange POST when the config itself omits
   * `base_url`; the chain returns the config's own `base_url` (if any) on
   * {@link CredentialResult.baseURL}, which {@link _applyCredentialBaseURL}
   * then adopts for outbound API requests. The two are deliberately decoupled
   * so this fallback never round-trips into precedence.
   */
  private _credentialResolverOptions() {
    return {
      baseURL: this.baseURL,
      fetch: this._credentialsFetch(),
      userAgent: this.getUserAgent(),
      onCacheWriteError: (err: unknown) => {
        loggerFor(this).debug('credential cache write failed (best-effort)', err);
      },
      onSafetyWarning: (msg: string) => {
        loggerFor(this).warn(msg);
      },
    };
  }

  /**
   * A `Fetch` for first-party credential token-exchange requests (OIDC
   * federation jwt-bearer grants, user-OAuth refresh grants) that routes
   * through this client's middleware chain, so middleware observes token
   * traffic like any other request. Only client-level middleware applies:
   * a minted token is shared across requests, so attributing the exchange
   * to any one request's per-request middleware would be arbitrary. For the
   * same reason, `ctx.options` is undefined for these requests.
   */
  private _credentialsFetch(): Fetch {
    return wrapFetchWithMiddleware(this.fetch, this.middleware, undefined, this);
  }

  private _makeTokenCache(provider: AccessTokenProvider): TokenCache {
    return new TokenCache(provider, (err) => {
      loggerFor(this).debug('advisory token refresh failed; serving cached token', err);
    });
  }

  /**
   * Create a new client instance re-using the same options given to the
   * current client with optional overriding.
   *
   * Passing `apiKey`, `authToken`, `credentials`, `config`, or `profile`
   * replaces the current client's credential, whatever its kind. With none of
   * them passed, the new client keeps it. Either way it keeps
   * `defaultHeaders`, including an `X-Api-Key` or `Authorization` set there.
   */
  withOptions(options: Partial<ClientOptions>): this {
    // Left in, an `undefined` would overwrite the inherited credential and
    // send the clone back to the environment.
    options = { ...options };
    for (const name of CREDENTIAL_OPTIONS) {
      if (options[name] === undefined) delete options[name];
    }
    // `null` counts here: it clears a credential, so the clone can't share.
    const overridesAuth = CREDENTIAL_OPTIONS.some((name) => name in options);
    const replacesCredential = CREDENTIAL_OPTIONS.some((name) => options[name] != null);
    const internal: InternalClientOptions = {
      ...this._options,
      // Only forward baseURL when the caller (or env) explicitly chose it.
      // For a non-explicit parent, this.baseURL may have been mutated to the
      // profile-resolved host; pinning that as the clone's options.baseURL
      // would make _options on the clone misreport caller intent and would
      // leave the clone stuck on the parent's host across an auth override.
      // The clone instead receives the construction-time value via
      // ...this._options above and re-adopts the profile host through the
      // shared _authState.baseURL + __baseURLIsExplicit=false path.
      ...(this._baseURLIsExplicit ? { baseURL: this.baseURL } : {}),
      maxRetries: this.maxRetries,
      timeout: this.timeout,
      logger: this.logger,
      logLevel: this.logLevel,
      fetch: this.fetch,
      fetchOptions: this.fetchOptions,
      middleware: this.middleware,
      apiKey: this.apiKey ?? this.#apiKeyFunction,
      authToken: this.authToken,
      webhookKey: this.webhookKey,
      // Left in, the inherited credential would trip the mutual-exclusion check.
      ...(replacesCredential ? Object.fromEntries(CREDENTIAL_OPTIONS.map((name) => [name, null])) : {}),
      ...options,
      openTelemetry: options.openTelemetry ?? this.#openTelemetry,
      // Always set __auth so any stale value from ...this._options is
      // overwritten. undefined means "build fresh auth from these options".
      __auth: overridesAuth ? undefined : this._authState,
      __baseURLIsExplicit: 'baseURL' in options ? true : this._baseURLIsExplicit,
    };
    return new (this.constructor as any as new (props: ClientOptions) => typeof this)(internal);
  }

  /**
   * Lazily resolves credentials from config files or environment variables.
   * Called once from the constructor when no explicit auth is provided, or
   * when an explicit `profile` was passed (in which case a missing/unresolved
   * profile is surfaced as an error instead of falling through to "no auth").
   * The returned promise is stored and awaited on the first request.
   */
  private async _resolveDefaultCredentials(profile?: string): Promise<void> {
    try {
      const result = await defaultCredentials(this._credentialResolverOptions(), profile);
      if (result) {
        this._authState.provider = result.provider;
        this._authState.tokenCache = this._makeTokenCache(result.provider);
        this._authState.extraHeaders = result.extraHeaders;
        this._applyCredentialBaseURL(result.baseURL);
      } else if (profile != null) {
        throw new Errors.AnthropicError(
          `Profile "${profile}" could not be resolved (no <config_dir>/configs/${profile}.json found).`,
        );
      }
    } catch (err) {
      this._authState.error = err;
    } finally {
      this._authState.resolution = null;
    }
  }

  /**
   * Check whether the base URL is set to its default.
   *
   * A profile-supplied `base_url` counts as an override here: a profile that
   * pins a non-default host is declaring "this whole client targets deployment
   * X", so per-endpoint {@link RequestOptions.defaultBaseURL} hints must not
   * silently route individual calls back to production. No generated resource
   * currently sets `defaultBaseURL`, so this is documenting intent for when
   * one does.
   */
  #baseURLOverridden(): boolean {
    return this.baseURL !== 'https://api.anthropic.com';
  }

  protected defaultQuery(): Record<string, string | undefined> | undefined {
    return this._options.defaultQuery;
  }

  protected validateHeaders({ values, nulls }: NullableHeaders) {
    if (values.get('x-api-key') || values.get('authorization')) {
      return;
    }
    if (this._authState.error) {
      throw this._authState.error;
    }
    if (this._authState.tokenCache || this._authState.resolution) {
      return; // auth will be injected per-request via authHeaders
    }

    if (this.apiKey && values.get('authorization')) {
      return;
    }
    if (nulls.has('authorization')) {
      return;
    }

    if (this.authToken && values.get('authorization')) {
      return;
    }
    if (nulls.has('authorization')) {
      return;
    }

    throw new Error(
      'Could not resolve authentication method. Expected one of apiKey, authToken, credentials, config, or profile to be set. Or for the "Authorization" header to be explicitly omitted',
    );
  }

  private _authFlags(opts: FinalRequestOptions): RequestAuthFlags {
    let flags = this._requestAuthFlags.get(opts);
    if (!flags) {
      flags = { usedTokenCache: false, didRefreshFor401: false };
      this._requestAuthFlags.set(opts, flags);
    }
    return flags;
  }

  protected async authHeaders(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
    // Wait for lazy credential resolution if it's in progress. If it failed,
    // return no auth headers — validateHeaders surfaces the stored error
    // after the explicit-header escape hatch has had a chance to apply.
    if (this._authState.resolution) {
      await this._authState.resolution;
    }
    if (this._authState.error) {
      return undefined;
    }
    if (this.#apiKeyFunction && this.apiKey == null) {
      let apiKey: string;
      try {
        apiKey = await this.#apiKeyFunction();
      } catch (err) {
        throw new Errors.AnthropicError(`The \`apiKey\` function failed: ${castToError(err).message}`, {
          cause: err,
        });
      }
      if (!apiKey) {
        throw new Errors.AnthropicError(
          `The \`apiKey\` function must return a non-empty string. It returned ${JSON.stringify(apiKey)}.`,
        );
      }
      return buildHeaders([{ Authorization: `Bearer ${apiKey}` }]);
    }
    // If we have a token cache and no API key is set, use token auth
    if (this._authState.tokenCache && this.apiKey == null) {
      const token = await this._authState.tokenCache.getToken();
      this._authFlags(opts).usedTokenCache = true;
      return buildHeaders([{ Authorization: `Bearer ${token}` }]);
    }
    return buildHeaders([await this.bearerAuth(opts), await this.apiKeyAuth(opts)]);
  }

  protected async apiKeyAuth(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
    if (this.apiKey == null) {
      return undefined;
    }
    return buildHeaders([{ Authorization: `Bearer ${this.apiKey}` }]);
  }

  protected async bearerAuth(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
    if (this.authToken == null) {
      return undefined;
    }
    return buildHeaders([{ Authorization: `Bearer ${this.authToken}` }]);
  }

  protected stringifyQuery(query: object | Record<string, unknown>): string {
    return stringifyQuery(query);
  }

  protected getUserAgent(): string {
    return `Anthropic/JS ${VERSION}`;
  }

  protected makeStatusError(
    status: number,
    error: Object,
    message: string | undefined,
    headers: Headers,
  ): Errors.APIError {
    return Errors.APIError.generate(status, error, message, headers);
  }

  buildURL(
    path: string,
    query: Record<string, unknown> | null | undefined,
    defaultBaseURL?: string | undefined,
  ): string {
    const baseURL = (!this.#baseURLOverridden() && defaultBaseURL) || this.baseURL;
    const url =
      isAbsoluteURL(path) ?
        new URL(path)
      : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));

    const defaultQuery = this.defaultQuery();
    const pathQuery = Object.fromEntries(url.searchParams);
    if (!isEmptyObj(defaultQuery) || !isEmptyObj(pathQuery)) {
      query = { ...pathQuery, ...defaultQuery, ...query };
    }

    if (typeof query === 'object' && query && !Array.isArray(query)) {
      url.search = this.stringifyQuery(query);
    }

    return url.toString();
  }

  _calculateNonstreamingTimeout(maxTokens: number): number {
    const defaultTimeout = 10 * 60;
    const expectedTimeout = (60 * 60 * maxTokens) / 128_000;
    if (expectedTimeout > defaultTimeout) {
      throw new Errors.AnthropicError(
        'Streaming is required for operations that may take longer than 10 minutes. ' +
          'See https://github.com/anthropics/anthropic-sdk-typescript#streaming-responses for more details',
      );
    }
    return defaultTimeout * 1000;
  }

  /**
   * Used as a callback for mutating the given `FinalRequestOptions` object.
   */
  protected async prepareOptions(options: FinalRequestOptions): Promise<void> {}

  /**
   * Used as a callback for mutating the given `RequestInit` object.
   *
   * This is useful for cases where you want to add certain headers based off of
   * the request properties, e.g. `method` or `url`.
   *
   * Runs after all middleware (including {@link backendMiddleware}),
   * immediately before each underlying fetch call, so it sees exactly what
   * goes over the wire, except the trace-context headers of a traced call
   * (`traceparent`, `tracestate`, `baggage`, and any other that the registered
   * propagator writes): the client sets them again after this hook, so that a
   * signature does not cover them. Middleware may replay a request by calling
   * `next()` more than once, so this hook can run multiple times per attempt:
   * overrides must be idempotent and overwrite headers from a previous
   * invocation rather than append to them.
   */
  protected async prepareRequest(
    request: RequestInit,
    { url, options }: { url: string; options: FinalRequestOptions },
  ): Promise<void> {
    // Append auth-derived headers when using token auth. Done here (after all
    // header merging) rather than in authHeaders() so we append to any existing
    // anthropic-beta values instead of being overwritten by later header sources.
    if (this._authState.tokenCache && this.apiKey == null) {
      // Normalize to a Headers instance — custom fetch impls or polyfills can
      // hand back arrays / plain objects, and silently dropping the beta
      // header in that case would surface as a confusing server-side 4xx.
      const headers = request.headers instanceof Headers ? request.headers : new Headers(request.headers);
      for (const [k, v] of Object.entries(this._authState.extraHeaders)) {
        if (!headers.has(k)) headers.set(k, v);
      }
      const existing = headers
        .get('anthropic-beta')
        ?.split(',')
        .map((s) => s.trim());
      if (!existing?.includes(OAUTH_API_BETA_HEADER)) {
        headers.set('anthropic-beta', [...(existing ?? []), OAUTH_API_BETA_HEADER].join(','));
      }
      request.headers = headers;
    }
  }

  /**
   * Internal {@link Middleware} composed innermost in the chain — inside both
   * client-level and per-request middleware, immediately around the underlying
   * `fetch`. Subclasses for third-party backends override this to adapt the
   * canonical Anthropic-shaped request to the backend's wire shape (URL/body
   * rewriting, request signing) and to normalize the wire response back to the
   * canonical shape (e.g. AWS EventStream to SSE).
   *
   * Running inside the user's middleware means user middleware always observes
   * canonical Anthropic-shaped traffic, and the adaptation re-runs (e.g.
   * re-signs) on every `next()` invocation, covering whatever the middleware
   * mutated. It does not see the trace-context headers of a traced call: see
   * {@link prepareRequest}.
   *
   * Errors thrown here follow the middleware error policy: they propagate to
   * the caller as-is — no retries, no `APIConnectionError` wrapping — unless
   * retryable (see {@link Middleware}); throw a `RetryableError` to opt into
   * the retry path.
   */
  protected backendMiddleware(): ReadonlyArray<Middleware> {
    return [];
  }

  get<Rsp>(path: string, opts?: PromiseOrValue<RequestOptions>): APIPromise<Rsp> {
    return this.methodRequest('get', path, opts);
  }

  post<Rsp>(path: string, opts?: PromiseOrValue<RequestOptions>): APIPromise<Rsp> {
    return this.methodRequest('post', path, opts);
  }

  patch<Rsp>(path: string, opts?: PromiseOrValue<RequestOptions>): APIPromise<Rsp> {
    return this.methodRequest('patch', path, opts);
  }

  put<Rsp>(path: string, opts?: PromiseOrValue<RequestOptions>): APIPromise<Rsp> {
    return this.methodRequest('put', path, opts);
  }

  delete<Rsp>(path: string, opts?: PromiseOrValue<RequestOptions>): APIPromise<Rsp> {
    return this.methodRequest('delete', path, opts);
  }

  private methodRequest<Rsp>(
    method: HTTPMethod,
    path: string,
    opts?: PromiseOrValue<RequestOptions>,
  ): APIPromise<Rsp> {
    return this.request(
      Promise.resolve(opts).then((opts) => {
        return { method, path, ...opts };
      }),
    );
  }

  request<Rsp>(
    options: PromiseOrValue<FinalRequestOptions>,
    remainingRetries: number | null = null,
  ): APIPromise<Rsp> {
    if (!this._tracer) {
      return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
    }
    return new APIPromise(this, this.makeTracedRequest(options, remainingRetries));
  }

  /**
   * Makes the request inside the call span that the SDK method started and passed in the options
   * (`__span`). The span ends here when the call fails, and otherwise when the application has
   * read the response body: see `APIPromise`.
   */
  private async makeTracedRequest(
    optionsInput: PromiseOrValue<FinalRequestOptions>,
    retriesRemaining: number | null,
  ): Promise<APIResponseProps> {
    const options = await optionsInput;
    const span = options.__span?.span;
    if (!span) {
      return this.makeRequest(options, retriesRemaining, undefined);
    }
    try {
      return await context.with(trace.setSpan(context.active(), span), () =>
        this.makeRequest(options, retriesRemaining, undefined, span),
      );
    } catch (error) {
      const result: ApiCallResult = { status: 'error', options, error };
      setAnthropicSpanAttributes(this, span, result);
      guardTracing(this, () => endApiCallSpan(span, result));
      throw error;
    }
  }

  private async makeRequest(
    optionsInput: PromiseOrValue<FinalRequestOptions>,
    retriesRemaining: number | null,
    retryOfRequestLogID: string | undefined,
    span?: Span | undefined,
  ): Promise<APIResponseProps> {
    const options = await optionsInput;
    let maxRetries = validatePositiveInteger('maxRetries', options.maxRetries ?? this.maxRetries);
    if (this.isStreamBody(options.body)) {
      maxRetries = 0;
    }
    if (retriesRemaining == null) {
      retriesRemaining = maxRetries;
      // Top-level call: reset per-request auth flags so a reused options object
      // (via client.request(opts)) doesn't carry stale 401-refresh state.
      this._requestAuthFlags.delete(options);
    }

    await this.prepareOptions(options);

    const { req, url, timeout } = await this.buildRequest(options, {
      retryCount: maxRetries - retriesRemaining,
    });

    /** Not an API request ID, just for correlating local log entries. */
    const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
    const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
    if (span && this.openTelemetry.propagation) {
      req.headers = guardTracing(this, () => injectTraceHeaders(span, req.headers)) ?? req.headers;
    }
    const startTime = Date.now();

    if (options.signal?.aborted) {
      throw new Errors.APIUserAbortError();
    }

    const controller = new AbortController();
    const response = await this.fetchWithTimeout(url, req, timeout, controller, options, {
      requestLogID,
      retryOfRequestLogID,
    }).catch(castToError);
    const headersTime = Date.now();

    if (response instanceof globalThis.Error) {
      releaseRequestSignal(controller);
      const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
      if (options.signal?.aborted) {
        throw new Errors.APIUserAbortError();
      }
      // detect native connection timeout errors
      // deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
      // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
      // others do not provide enough information to distinguish timeouts from other connection errors
      const isTimeout =
        isAbortError(response) ||
        /timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));

      // Errors thrown by middleware (user middleware and the backend adaptation
      // alike) propagate to the caller as-is — no retries, no APIConnectionError
      // wrapping — except retryable errors (timeouts/aborts, APIConnectionErrors,
      // and RetryableErrors, directly or in the `cause` chain), which stay on the
      // retry path.
      const hasMiddleware =
        this.middleware.length > 0 || !!options.middleware?.length || this.backendMiddleware().length > 0;
      if (hasMiddleware && !isTimeout && !isRetryableError(response)) {
        loggerFor(this).info(`[${requestLogID}] middleware error (not retryable)`);
        debugLogRequestDetails(loggerFor(this), `[${requestLogID}] middleware error (not retryable)`, {
          retryOfRequestLogID,
          url,
          durationMs: headersTime - startTime,
          message: response.message,
        });
        throw response;
      }
      if (retriesRemaining) {
        loggerFor(this).info(
          `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`,
        );
        debugLogRequestDetails(
          loggerFor(this),
          `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`,
          {
            retryOfRequestLogID,
            url,
            durationMs: headersTime - startTime,
            message: response.message,
          },
        );
        return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID, span);
      }
      loggerFor(this).info(
        `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`,
      );
      debugLogRequestDetails(
        loggerFor(this),
        `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`,
        {
          retryOfRequestLogID,
          url,
          durationMs: headersTime - startTime,
          message: response.message,
        },
      );
      if (isTimeout) {
        throw new Errors.APIConnectionTimeoutError();
      }
      // a retryable middleware-origin error is still the caller's error: once retries are
      // exhausted it propagates as-is rather than wrapped in APIConnectionError
      if (hasMiddleware && !isFetchOriginError(response)) {
        throw response;
      }
      throw new Errors.APIConnectionError({ cause: response });
    }

    const specialHeaders = [...response.headers.entries()]
      .filter(([name]) => name === 'request-id' || name === 'anthropic-workspace-id')
      .map(([name, value]) => ', ' + name + ': ' + JSON.stringify(value))
      .join('');
    const responseInfo = `[${requestLogID}${retryLogStr}${specialHeaders}] ${req.method} ${url} ${
      response.ok ? 'succeeded' : 'failed'
    } with status ${response.status} in ${headersTime - startTime}ms`;

    if (!response.ok) {
      const shouldRetry = await this.shouldRetry(response, options);
      if (retriesRemaining && shouldRetry) {
        const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;

        // We don't need the body of this response.
        await Shims.CancelReadableStream(response.body);
        releaseRequestSignal(controller);
        loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
        debugLogRequestDetails(loggerFor(this), `[${requestLogID}] response error (${retryMessage})`, {
          retryOfRequestLogID,
          url: response.url,
          status: response.status,
          headers: response.headers,
          durationMs: headersTime - startTime,
        });
        return this.retryRequest(
          options,
          retriesRemaining,
          retryOfRequestLogID ?? requestLogID,
          span,
          response.headers,
        );
      }

      const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;

      loggerFor(this).info(`${responseInfo} - ${retryMessage}`);

      const errText = await response.text().catch((err: any) => castToError(err).message);
      const errJSON = safeJSON(errText) as any;
      const errMessage = errJSON ? undefined : errText;

      debugLogRequestDetails(loggerFor(this), `[${requestLogID}] response error (${retryMessage})`, {
        retryOfRequestLogID,
        url: response.url,
        status: response.status,
        headers: response.headers,
        message: errMessage,
        durationMs: Date.now() - startTime,
      });

      releaseRequestSignal(controller);
      const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
      throw err;
    }

    loggerFor(this).info(responseInfo);
    debugLogRequestDetails(loggerFor(this), `[${requestLogID}] response start`, {
      retryOfRequestLogID,
      url: response.url,
      status: response.status,
      headers: response.headers,
      durationMs: headersTime - startTime,
    });

    armAbandonmentBackstop(response.body ?? response, controller);
    return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
  }

  getAPIList<Item, PageClass extends Pagination.AbstractPage<Item> = Pagination.AbstractPage<Item>>(
    path: string,
    Page: new (...args: any[]) => PageClass,
    opts?: PromiseOrValue<RequestOptions>,
  ): Pagination.PagePromise<PageClass, Item> {
    return this.requestAPIList(
      Page,
      opts && 'then' in opts ?
        opts.then((opts) => ({ method: 'get', path, ...opts }))
      : { method: 'get', path, ...opts },
    );
  }

  requestAPIList<
    Item = unknown,
    PageClass extends Pagination.AbstractPage<Item> = Pagination.AbstractPage<Item>,
  >(
    Page: new (...args: ConstructorParameters<typeof Pagination.AbstractPage>) => PageClass,
    options: PromiseOrValue<FinalRequestOptions>,
  ): Pagination.PagePromise<PageClass, Item> {
    if (!this._tracer) {
      const request = this.makeRequest(options, null, undefined);
      return new Pagination.PagePromise<PageClass, Item>(this as any as Anthropic, request, Page);
    }
    const request = this.makeTracedRequest(options, null);
    return new Pagination.PagePromise<PageClass, Item>(this as any as Anthropic, request, Page);
  }

  async fetchWithTimeout(
    url: RequestInfo,
    init: RequestInit | undefined,
    ms: number,
    controller: AbortController,
    requestOptions?: FinalRequestOptions | undefined,
    logCtx?: { requestLogID: string; retryOfRequestLogID?: string | undefined } | undefined,
  ): Promise<Response> {
    const { signal, method, ...options } = init || {};
    // Avoid creating a closure over `this`, `init`, or `options` to prevent memory leaks.
    // An arrow function like `() => controller.abort()` captures the surrounding scope,
    // which includes the request body and other large objects. When the user passes a
    // long-lived AbortSignal, the listener prevents those objects from being GC'd for
    // the lifetime of the signal. Using `.bind()` only retains a reference to the
    // controller itself.
    const abort = this._makeAbort(controller);
    if (signal) {
      signal.addEventListener('abort', abort, { once: true });
      registerRequestSignalCleanup(controller, signal, abort);
    }

    const isReadableBody =
      ((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) ||
      (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);

    const fetchOptions: RequestInit = {
      signal: controller.signal as any,
      ...(isReadableBody ? { duplex: 'half' } : {}),
      method: 'GET',
      ...options,
    };
    if (method) {
      // Custom methods like 'patch' need to be uppercased
      // See https://github.com/nodejs/undici/issues/2294
      fetchOptions.method = method.toUpperCase();
    }

    // Arm the timeout around the underlying fetch only, not the middleware
    // chain — middleware can take arbitrarily long (or call `next` more than
    // once), and each inner-fetch invocation gets its own `ms` timer.
    const baseFetch = this.fetch;
    const timedFetch: Fetch = async (innerUrl, innerInit) => {
      const timeout = setTimeout(abort, ms);
      try {
        return await baseFetch.call(undefined, innerUrl, innerInit);
      } finally {
        clearTimeout(timeout);
      }
    };

    // Prepare the request (auth signing and other `prepareRequest` hooks) as
    // the innermost step, after any middleware — including the backend
    // middleware, so it sees exactly what goes over the wire, except the trace
    // headers. Runs per inner-fetch invocation, so a request middleware rewrote
    // — or replayed via a second `next()` call — is prepared fresh each time.
    // Preparation is outside the timeout timer, matching its pre-middleware
    // behavior.
    const innerFetch: Fetch =
      requestOptions === undefined ? timedFetch : (
        async (innerUrl, innerInit = {}) => {
          const innerUrlStr =
            typeof innerUrl === 'string' ? innerUrl
            : innerUrl instanceof URL ? innerUrl.href
            : innerUrl.url;
          innerInit.headers =
            innerInit.headers instanceof Headers ? innerInit.headers : new Headers(innerInit.headers);

          let traceHeaders: Array<[string, string]> = [];
          if (requestOptions.__span) {
            innerInit.headers = new Headers(innerInit.headers);
            traceHeaders = takeTraceHeaders(innerInit.headers);
          }
          await this.prepareRequest(innerInit, { url: innerUrlStr, options: requestOptions });
          if (traceHeaders.length) {
            innerInit.headers = buildHeaders([innerInit.headers, traceHeaders]).values;
          }
          const call = requestOptions.__span;
          if (call) {
            guardTracing(this, () =>
              recordAttempt(
                call,
                innerInit.method ?? 'GET',
                innerUrlStr,
                this.openTelemetry.traces.contentMode === 'content',
              ),
            );
          }

          if (logCtx) {
            debugLogRequestDetails(loggerFor(this), `[${logCtx.requestLogID}] sending request`, {
              retryOfRequestLogID: logCtx.retryOfRequestLogID,
              method: innerInit.method,
              url: innerUrlStr,
              options: requestOptions,
              headers: innerInit.headers,
            });
          }

          return timedFetch(innerUrl, innerInit);
        }
      );

    const requestMiddleware = requestOptions?.middleware;
    const backendMiddleware =
      requestOptions?.__span ? this.backendMiddleware().map(withoutTraceHeaders) : this.backendMiddleware();
    const allMiddleware =
      requestMiddleware?.length || backendMiddleware.length ?
        [...this.middleware, ...(requestMiddleware ?? []), ...backendMiddleware]
      : this.middleware;
    return await wrapFetchWithMiddleware(innerFetch, allMiddleware, requestOptions, this)(url, fetchOptions);
  }

  private async shouldRetry(response: Response, options: FinalRequestOptions): Promise<boolean> {
    // Reactive refresh: on a 401 from a request that used the token cache,
    // invalidate and retry once. Only fires when this specific request was
    // bearer-authenticated (not when an apiKey was used) and only once per
    // request — a second 401 after refresh falls through to the normal
    // retry policy below (which treats 4xx as non-retryable).
    const flags = this._authFlags(options);
    if (
      response.status === 401 &&
      this._authState.tokenCache &&
      flags.usedTokenCache &&
      !flags.didRefreshFor401
    ) {
      flags.didRefreshFor401 = true;
      this._authState.tokenCache.invalidate();
      return true;
    }

    // Note this is not a standard header.
    const shouldRetryHeader = response.headers.get('x-should-retry');

    // If the server explicitly says whether or not to retry, obey.
    if (shouldRetryHeader === 'true') return true;
    if (shouldRetryHeader === 'false') return false;

    // Retry on request timeouts.
    if (response.status === 408) return true;

    // Retry on lock timeouts.
    if (response.status === 409) return true;

    // Retry on rate limits.
    if (response.status === 429) return true;

    // Retry internal errors.
    if (response.status >= 500) return true;

    return false;
  }

  private async retryRequest(
    options: FinalRequestOptions,
    retriesRemaining: number,
    requestLogID: string,
    span: Span | undefined,
    responseHeaders?: Headers | undefined,
  ): Promise<APIResponseProps> {
    let timeoutMillis: number | undefined;

    // Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it.
    const retryAfterMillisHeader = responseHeaders?.get('retry-after-ms');
    if (retryAfterMillisHeader) {
      const timeoutMs = parseFloat(retryAfterMillisHeader);
      if (!Number.isNaN(timeoutMs)) {
        timeoutMillis = timeoutMs;
      }
    }

    // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
    const retryAfterHeader = responseHeaders?.get('retry-after');
    if (retryAfterHeader && !timeoutMillis) {
      const timeoutSeconds = parseFloat(retryAfterHeader);
      if (!Number.isNaN(timeoutSeconds)) {
        timeoutMillis = timeoutSeconds * 1000;
      } else {
        timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
      }
    }

    // If the API asks us to wait a certain amount of time, do what it says, as long as it's a positive delay that
    // one timer can represent (setTimeout fires after 1ms for anything above 2^31 - 1). Otherwise (no header, an
    // unparseable value, zero/negative, a date in the past) calculate a default.
    if (timeoutMillis === undefined || !(timeoutMillis > 0 && timeoutMillis <= 2 ** 31 - 1)) {
      const maxRetries = options.maxRetries ?? this.maxRetries;
      timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
    }
    await sleep(timeoutMillis, options.signal ?? undefined);

    return this.makeRequest(options, retriesRemaining - 1, requestLogID, span);
  }

  private calculateDefaultRetryTimeoutMillis(retriesRemaining: number, maxRetries: number): number {
    const initialRetryDelay = 0.5;
    const maxRetryDelay = 8.0;

    const numRetries = maxRetries - retriesRemaining;

    // Apply exponential backoff, but not more than the max.
    const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);

    // Apply some jitter, take up to at most 25 percent of the retry time.
    const jitter = 1 - Math.random() * 0.25;

    return sleepSeconds * jitter * 1000;
  }

  public calculateNonstreamingTimeout(maxTokens: number, maxNonstreamingTokens?: number): number {
    const maxTime = 60 * 60 * 1000; // 60 minutes
    const defaultTime = 60 * 10 * 1000; // 10 minutes

    const expectedTime = (maxTime * maxTokens) / 128000;
    if (expectedTime > defaultTime || (maxNonstreamingTokens != null && maxTokens > maxNonstreamingTokens)) {
      throw new Errors.AnthropicError(
        'Streaming is required for operations that may take longer than 10 minutes. See https://github.com/anthropics/anthropic-sdk-typescript#long-requests for more details',
      );
    }

    return defaultTime;
  }

  async buildRequest(
    inputOptions: FinalRequestOptions,
    { retryCount = 0 }: { retryCount?: number } = {},
  ): Promise<{ req: FinalizedRequestInit; url: string; timeout: number }> {
    const options = { ...inputOptions };
    const { method, path, query, defaultBaseURL } = options;

    // Lazy credential resolution may carry a profile-supplied baseURL. Await
    // it before building the request URL so the very first request — and
    // requests on withOptions() clones created before resolution settled —
    // hit the profile's host rather than the hardcoded default.
    if (this._authState.resolution) {
      await this._authState.resolution;
    }
    if (!this._baseURLIsExplicit && this._authState.baseURL && this.baseURL !== this._authState.baseURL) {
      this.baseURL = this._authState.baseURL;
    }

    const url = this.buildURL(path!, query as Record<string, unknown>, defaultBaseURL);
    if ('timeout' in options) validatePositiveInteger('timeout', options.timeout);
    options.timeout = options.timeout ?? this.timeout;
    const { bodyHeaders, body } = this.buildBody({ options });
    const reqHeaders = await this.buildHeaders({
      options: inputOptions,
      method,
      bodyHeaders,
      retryCount,
      timeout: options.timeout,
    });

    const req: FinalizedRequestInit = {
      method,
      headers: reqHeaders,
      ...(options.signal && { signal: options.signal }),
      ...((globalThis as any).ReadableStream &&
        body instanceof (globalThis as any).ReadableStream && { duplex: 'half' }),
      ...(body && { body }),
      ...((this.fetchOptions as any) ?? {}),
      ...((options.fetchOptions as any) ?? {}),
    };

    return { req, url, timeout: options.timeout };
  }

  private async buildHeaders({
    options,
    method,
    bodyHeaders,
    retryCount,
    timeout,
  }: {
    options: FinalRequestOptions;
    method: HTTPMethod;
    bodyHeaders: HeadersLike;
    retryCount: number;
    timeout: number;
  }): Promise<Headers> {
    const headers = buildHeaders([
      {
        Accept: 'application/json',
        'User-Agent': this.getUserAgent(),
        'X-Stainless-Retry-Count': String(retryCount),
        'X-Stainless-Timeout': String(Math.trunc(timeout / 1000)),
        ...getPlatformHeaders(),
        ...(this._options.dangerouslyAllowBrowser ?
          { 'anthropic-dangerous-direct-browser-access': 'true' }
        : undefined),
        'anthropic-version': '2026-10-21',
      },
      await this.authHeaders(options),
      this._options.defaultHeaders,
      bodyHeaders,
      options.headers,
    ]);

    this.validateHeaders(headers);

    return headers.values;
  }

  private _makeAbort(controller: AbortController) {
    // note: we can't just inline this method inside `fetchWithTimeout()` because then the closure
    //       would capture all request options, and cause a memory leak.
    return () => controller.abort();
  }

  private buildBody({ options: { body, headers: rawHeaders } }: { options: FinalRequestOptions }): {
    bodyHeaders: HeadersLike;
    body: BodyInit | undefined;
  } {
    if (!body) {
      return { bodyHeaders: undefined, body: undefined };
    }
    const headers = buildHeaders([rawHeaders]);
    if (
      // Pass raw type verbatim
      ArrayBuffer.isView(body) ||
      body instanceof ArrayBuffer ||
      body instanceof DataView ||
      (typeof body === 'string' &&
        // Preserve legacy string encoding behavior for now
        headers.values.has('content-type')) ||
      // `Blob` is superset of `File`
      ((globalThis as any).Blob && body instanceof (globalThis as any).Blob) ||
      // `FormData` -> `multipart/form-data`
      body instanceof FormData ||
      // `URLSearchParams` -> `application/x-www-form-urlencoded`
      body instanceof URLSearchParams ||
      // Send chunked stream (each chunk has own `length`)
      ((globalThis as any).ReadableStream && body instanceof (globalThis as any).ReadableStream)
    ) {
      return { bodyHeaders: undefined, body: body as BodyInit };
    } else if (this.isStreamBody(body)) {
      return { bodyHeaders: undefined, body: Shims.ReadableStreamFrom(body as AsyncIterable<Uint8Array>) };
    } else if (
      typeof body === 'object' &&
      headers.values.get('content-type') === 'application/x-www-form-urlencoded'
    ) {
      return {
        bodyHeaders: { 'content-type': 'application/x-www-form-urlencoded' },
        body: this.stringifyQuery(body),
      };
    } else {
      return this.#encoder({ body, headers });
    }
  }

  /**
   * Whether `body` is sent as a stream, which can be read only once:
   * a `ReadableStream`, an async iterable or an iterator.
   */
  private isStreamBody(body: unknown): boolean {
    if ((globalThis as any).ReadableStream && body instanceof (globalThis as any).ReadableStream) {
      return true;
    }
    return (
      typeof body === 'object' &&
      body !== null &&
      (Symbol.asyncIterator in body ||
        (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))
    );
  }

  static Anthropic = this;
  static DEFAULT_TIMEOUT = 600000; // 10 minutes

  static AnthropicError = Errors.AnthropicError;
  static APIError = Errors.APIError;
  static APIConnectionError = Errors.APIConnectionError;
  static APIConnectionTimeoutError = Errors.APIConnectionTimeoutError;
  static APIUserAbortError = Errors.APIUserAbortError;
  static NotFoundError = Errors.NotFoundError;
  static ConflictError = Errors.ConflictError;
  static RateLimitError = Errors.RateLimitError;
  static BadRequestError = Errors.BadRequestError;
  static AuthenticationError = Errors.AuthenticationError;
  static InternalServerError = Errors.InternalServerError;
  static PermissionDeniedError = Errors.PermissionDeniedError;
  static UnprocessableEntityError = Errors.UnprocessableEntityError;

  static toFile = Uploads.toFile;
}

/**
 * API Client for interfacing with the Anthropic API.
 */
export class Anthropic extends BaseAnthropic {
  messages: API.Messages = new API.Messages(this);
  models: API.Models = new API.Models(this);
  files: API.Files = new API.Files(this);
  skills: API.Skills = new API.Skills(this);
  userProfiles: API.UserProfiles = new API.UserProfiles(this);
  organization: API.Organization = new API.Organization(this);
  beta: API.Beta = new API.Beta(this);
}

Anthropic.Messages = Messages;
Anthropic.Models = Models;
Anthropic.Files = Files;
Anthropic.Skills = Skills;
Anthropic.UserProfiles = UserProfiles;
Anthropic.Organization = Organization;
Anthropic.Beta = Beta;

export declare namespace Anthropic {
  export type RequestOptions = Opts.RequestOptions;
  export type FinalRequestOptions = Opts.FinalRequestOptions;

  export type { ApiKeySetter };

  export { type Page as Page, type PageParams as PageParams, type PageResponse as PageResponse };

  export {
    type TokenPage as TokenPage,
    type TokenPageParams as TokenPageParams,
    type TokenPageResponse as TokenPageResponse,
  };

  export {
    type PageCursor as PageCursor,
    type PageCursorParams as PageCursorParams,
    type PageCursorResponse as PageCursorResponse,
  };

  export {
    type BidirectionalPageCursor as BidirectionalPageCursor,
    type BidirectionalPageCursorParams as BidirectionalPageCursorParams,
    type BidirectionalPageCursorResponse as BidirectionalPageCursorResponse,
  };

  export {
    type ReportPageCursor as ReportPageCursor,
    type ReportPageCursorParams as ReportPageCursorParams,
    type ReportPageCursorResponse as ReportPageCursorResponse,
  };

  export {
    Messages as Messages,
    type AssistantMessageParam as AssistantMessageParam,
    type Base64ImageSource as Base64ImageSource,
    type Base64PDFSource as Base64PDFSource,
    type BashCodeExecutionOutputBlock as BashCodeExecutionOutputBlock,
    type BashCodeExecutionOutputBlockParam as BashCodeExecutionOutputBlockParam,
    type BashCodeExecutionResultBlock as BashCodeExecutionResultBlock,
    type BashCodeExecutionResultBlockParam as BashCodeExecutionResultBlockParam,
    type BashCodeExecutionToolResultBlock as BashCodeExecutionToolResultBlock,
    type BashCodeExecutionToolResultBlockParam as BashCodeExecutionToolResultBlockParam,
    type BashCodeExecutionToolResultError as BashCodeExecutionToolResultError,
    type BashCodeExecutionToolResultErrorCode as BashCodeExecutionToolResultErrorCode,
    type BashCodeExecutionToolResultErrorParam as BashCodeExecutionToolResultErrorParam,
    type BrowserClickTarget as BrowserClickTarget,
    type BrowserCloseTabConfig as BrowserCloseTabConfig,
    type BrowserCloseTabInput as BrowserCloseTabInput,
    type BrowserCloseTabToolUseBlock as BrowserCloseTabToolUseBlock,
    type BrowserCoordinateTarget as BrowserCoordinateTarget,
    type BrowserDoubleClickConfig as BrowserDoubleClickConfig,
    type BrowserDoubleClickInput as BrowserDoubleClickInput,
    type BrowserDoubleClickToolUseBlock as BrowserDoubleClickToolUseBlock,
    type BrowserFileUploadConfig as BrowserFileUploadConfig,
    type BrowserFileUploadInput as BrowserFileUploadInput,
    type BrowserFileUploadToolUseBlock as BrowserFileUploadToolUseBlock,
    type BrowserFindConfig as BrowserFindConfig,
    type BrowserFindInput as BrowserFindInput,
    type BrowserFindToolUseBlock as BrowserFindToolUseBlock,
    type BrowserFormInputConfig as BrowserFormInputConfig,
    type BrowserFormInputInput as BrowserFormInputInput,
    type BrowserFormInputToolUseBlock as BrowserFormInputToolUseBlock,
    type BrowserFormInputValue as BrowserFormInputValue,
    type BrowserGetPageTextConfig as BrowserGetPageTextConfig,
    type BrowserGetPageTextInput as BrowserGetPageTextInput,
    type BrowserGetPageTextToolUseBlock as BrowserGetPageTextToolUseBlock,
    type BrowserHoldKeyConfig as BrowserHoldKeyConfig,
    type BrowserHoldKeyInput as BrowserHoldKeyInput,
    type BrowserHoldKeyToolUseBlock as BrowserHoldKeyToolUseBlock,
    type BrowserHoverConfig as BrowserHoverConfig,
    type BrowserHoverInput as BrowserHoverInput,
    type BrowserHoverToolUseBlock as BrowserHoverToolUseBlock,
    type BrowserJavascriptExecConfig as BrowserJavascriptExecConfig,
    type BrowserJavascriptExecInput as BrowserJavascriptExecInput,
    type BrowserJavascriptExecToolUseBlock as BrowserJavascriptExecToolUseBlock,
    type BrowserKeyConfig as BrowserKeyConfig,
    type BrowserKeyInput as BrowserKeyInput,
    type BrowserKeyToolUseBlock as BrowserKeyToolUseBlock,
    type BrowserLeftClickConfig as BrowserLeftClickConfig,
    type BrowserLeftClickDragConfig as BrowserLeftClickDragConfig,
    type BrowserLeftClickDragInput as BrowserLeftClickDragInput,
    type BrowserLeftClickDragToolUseBlock as BrowserLeftClickDragToolUseBlock,
    type BrowserLeftClickInput as BrowserLeftClickInput,
    type BrowserLeftClickToolUseBlock as BrowserLeftClickToolUseBlock,
    type BrowserLeftMouseDownConfig as BrowserLeftMouseDownConfig,
    type BrowserLeftMouseDownInput as BrowserLeftMouseDownInput,
    type BrowserLeftMouseDownToolUseBlock as BrowserLeftMouseDownToolUseBlock,
    type BrowserLeftMouseUpConfig as BrowserLeftMouseUpConfig,
    type BrowserLeftMouseUpInput as BrowserLeftMouseUpInput,
    type BrowserLeftMouseUpToolUseBlock as BrowserLeftMouseUpToolUseBlock,
    type BrowserListTabsConfig as BrowserListTabsConfig,
    type BrowserListTabsInput as BrowserListTabsInput,
    type BrowserListTabsToolUseBlock as BrowserListTabsToolUseBlock,
    type BrowserMemberInput as BrowserMemberInput,
    type BrowserMemberName as BrowserMemberName,
    type BrowserMiddleClickConfig as BrowserMiddleClickConfig,
    type BrowserMiddleClickInput as BrowserMiddleClickInput,
    type BrowserMiddleClickToolUseBlock as BrowserMiddleClickToolUseBlock,
    type BrowserMouseMoveConfig as BrowserMouseMoveConfig,
    type BrowserMouseMoveInput as BrowserMouseMoveInput,
    type BrowserMouseMoveToolUseBlock as BrowserMouseMoveToolUseBlock,
    type BrowserNavigateConfig as BrowserNavigateConfig,
    type BrowserNavigateInput as BrowserNavigateInput,
    type BrowserNavigateToolUseBlock as BrowserNavigateToolUseBlock,
    type BrowserNewTabConfig as BrowserNewTabConfig,
    type BrowserNewTabInput as BrowserNewTabInput,
    type BrowserNewTabToolUseBlock as BrowserNewTabToolUseBlock,
    type BrowserReadConsoleConfig as BrowserReadConsoleConfig,
    type BrowserReadConsoleInput as BrowserReadConsoleInput,
    type BrowserReadConsoleToolUseBlock as BrowserReadConsoleToolUseBlock,
    type BrowserReadNetworkConfig as BrowserReadNetworkConfig,
    type BrowserReadNetworkInput as BrowserReadNetworkInput,
    type BrowserReadNetworkToolUseBlock as BrowserReadNetworkToolUseBlock,
    type BrowserReadPageConfig as BrowserReadPageConfig,
    type BrowserReadPageFilter as BrowserReadPageFilter,
    type BrowserReadPageInput as BrowserReadPageInput,
    type BrowserReadPageToolUseBlock as BrowserReadPageToolUseBlock,
    type BrowserRefTarget as BrowserRefTarget,
    type BrowserRightClickConfig as BrowserRightClickConfig,
    type BrowserRightClickInput as BrowserRightClickInput,
    type BrowserRightClickToolUseBlock as BrowserRightClickToolUseBlock,
    type BrowserScreenshotConfig as BrowserScreenshotConfig,
    type BrowserScreenshotInput as BrowserScreenshotInput,
    type BrowserScreenshotToolUseBlock as BrowserScreenshotToolUseBlock,
    type BrowserScrollConfig as BrowserScrollConfig,
    type BrowserScrollDirection as BrowserScrollDirection,
    type BrowserScrollInput as BrowserScrollInput,
    type BrowserScrollToConfig as BrowserScrollToConfig,
    type BrowserScrollToInput as BrowserScrollToInput,
    type BrowserScrollToToolUseBlock as BrowserScrollToToolUseBlock,
    type BrowserScrollToolUseBlock as BrowserScrollToolUseBlock,
    type BrowserStateBlockParam as BrowserStateBlockParam,
    type BrowserStateChange as BrowserStateChange,
    type BrowserStateChangeDownloadCompleted as BrowserStateChangeDownloadCompleted,
    type BrowserStateChangeDownloadFailed as BrowserStateChangeDownloadFailed,
    type BrowserStateChangeDownloadStarted as BrowserStateChangeDownloadStarted,
    type BrowserStateChangeTabOpened as BrowserStateChangeTabOpened,
    type BrowserStateTabEntry as BrowserStateTabEntry,
    type BrowserSwitchTabConfig as BrowserSwitchTabConfig,
    type BrowserSwitchTabInput as BrowserSwitchTabInput,
    type BrowserSwitchTabToolUseBlock as BrowserSwitchTabToolUseBlock,
    type BrowserToolUseBlock as BrowserToolUseBlock,
    type BrowserToolset20260801 as BrowserToolset20260801,
    type BrowserToolsetConfigs as BrowserToolsetConfigs,
    type BrowserTripleClickConfig as BrowserTripleClickConfig,
    type BrowserTripleClickInput as BrowserTripleClickInput,
    type BrowserTripleClickToolUseBlock as BrowserTripleClickToolUseBlock,
    type BrowserTypeConfig as BrowserTypeConfig,
    type BrowserTypeInput as BrowserTypeInput,
    type BrowserTypeToolUseBlock as BrowserTypeToolUseBlock,
    type BrowserWaitConfig as BrowserWaitConfig,
    type BrowserWaitInput as BrowserWaitInput,
    type BrowserWaitToolUseBlock as BrowserWaitToolUseBlock,
    type BrowserZoomConfig as BrowserZoomConfig,
    type BrowserZoomInput as BrowserZoomInput,
    type BrowserZoomToolUseBlock as BrowserZoomToolUseBlock,
    type CacheControlEphemeral as CacheControlEphemeral,
    type CacheCreation as CacheCreation,
    type CacheMissMessagesChanged as CacheMissMessagesChanged,
    type CacheMissModelChanged as CacheMissModelChanged,
    type CacheMissPreviousMessageNotFound as CacheMissPreviousMessageNotFound,
    type CacheMissReason as CacheMissReason,
    type CacheMissSystemChanged as CacheMissSystemChanged,
    type CacheMissToolsChanged as CacheMissToolsChanged,
    type CacheMissUnavailable as CacheMissUnavailable,
    type CitationCharLocation as CitationCharLocation,
    type CitationCharLocationParam as CitationCharLocationParam,
    type CitationContentBlockLocation as CitationContentBlockLocation,
    type CitationContentBlockLocationParam as CitationContentBlockLocationParam,
    type CitationPageLocation as CitationPageLocation,
    type CitationPageLocationParam as CitationPageLocationParam,
    type CitationSearchResultLocationParam as CitationSearchResultLocationParam,
    type CitationWebSearchResultLocationParam as CitationWebSearchResultLocationParam,
    type CitationsConfig as CitationsConfig,
    type CitationsConfigParam as CitationsConfigParam,
    type CitationsDelta as CitationsDelta,
    type CitationsSearchResultLocation as CitationsSearchResultLocation,
    type CitationsWebSearchResultLocation as CitationsWebSearchResultLocation,
    type ClientToolUnion as ClientToolUnion,
    type CodeExecutionOutputBlock as CodeExecutionOutputBlock,
    type CodeExecutionOutputBlockParam as CodeExecutionOutputBlockParam,
    type CodeExecutionResultBlock as CodeExecutionResultBlock,
    type CodeExecutionResultBlockParam as CodeExecutionResultBlockParam,
    type CodeExecutionTool20250522 as CodeExecutionTool20250522,
    type CodeExecutionTool20250825 as CodeExecutionTool20250825,
    type CodeExecutionTool20260120 as CodeExecutionTool20260120,
    type CodeExecutionTool20260521 as CodeExecutionTool20260521,
    type CodeExecutionToolResultBlock as CodeExecutionToolResultBlock,
    type CodeExecutionToolResultBlockContent as CodeExecutionToolResultBlockContent,
    type CodeExecutionToolResultBlockParam as CodeExecutionToolResultBlockParam,
    type CodeExecutionToolResultBlockParamContent as CodeExecutionToolResultBlockParamContent,
    type CodeExecutionToolResultError as CodeExecutionToolResultError,
    type CodeExecutionToolResultErrorCode as CodeExecutionToolResultErrorCode,
    type CodeExecutionToolResultErrorParam as CodeExecutionToolResultErrorParam,
    type ComputerCursorPositionConfig as ComputerCursorPositionConfig,
    type ComputerCursorPositionInput as ComputerCursorPositionInput,
    type ComputerCursorPositionToolUseBlock as ComputerCursorPositionToolUseBlock,
    type ComputerDoubleClickConfig as ComputerDoubleClickConfig,
    type ComputerDoubleClickInput as ComputerDoubleClickInput,
    type ComputerDoubleClickToolUseBlock as ComputerDoubleClickToolUseBlock,
    type ComputerHoldKeyConfig as ComputerHoldKeyConfig,
    type ComputerHoldKeyInput as ComputerHoldKeyInput,
    type ComputerHoldKeyToolUseBlock as ComputerHoldKeyToolUseBlock,
    type ComputerKeyConfig as ComputerKeyConfig,
    type ComputerKeyInput as ComputerKeyInput,
    type ComputerKeyToolUseBlock as ComputerKeyToolUseBlock,
    type ComputerLeftClickConfig as ComputerLeftClickConfig,
    type ComputerLeftClickDragConfig as ComputerLeftClickDragConfig,
    type ComputerLeftClickDragInput as ComputerLeftClickDragInput,
    type ComputerLeftClickDragToolUseBlock as ComputerLeftClickDragToolUseBlock,
    type ComputerLeftClickInput as ComputerLeftClickInput,
    type ComputerLeftClickToolUseBlock as ComputerLeftClickToolUseBlock,
    type ComputerLeftMouseDownConfig as ComputerLeftMouseDownConfig,
    type ComputerLeftMouseDownInput as ComputerLeftMouseDownInput,
    type ComputerLeftMouseDownToolUseBlock as ComputerLeftMouseDownToolUseBlock,
    type ComputerLeftMouseUpConfig as ComputerLeftMouseUpConfig,
    type ComputerLeftMouseUpInput as ComputerLeftMouseUpInput,
    type ComputerLeftMouseUpToolUseBlock as ComputerLeftMouseUpToolUseBlock,
    type ComputerMemberInput as ComputerMemberInput,
    type ComputerMemberName as ComputerMemberName,
    type ComputerMiddleClickConfig as ComputerMiddleClickConfig,
    type ComputerMiddleClickInput as ComputerMiddleClickInput,
    type ComputerMiddleClickToolUseBlock as ComputerMiddleClickToolUseBlock,
    type ComputerMouseMoveConfig as ComputerMouseMoveConfig,
    type ComputerMouseMoveInput as ComputerMouseMoveInput,
    type ComputerMouseMoveToolUseBlock as ComputerMouseMoveToolUseBlock,
    type ComputerRightClickConfig as ComputerRightClickConfig,
    type ComputerRightClickInput as ComputerRightClickInput,
    type ComputerRightClickToolUseBlock as ComputerRightClickToolUseBlock,
    type ComputerScreenshotConfig as ComputerScreenshotConfig,
    type ComputerScreenshotInput as ComputerScreenshotInput,
    type ComputerScreenshotToolUseBlock as ComputerScreenshotToolUseBlock,
    type ComputerScrollConfig as ComputerScrollConfig,
    type ComputerScrollDirection as ComputerScrollDirection,
    type ComputerScrollInput as ComputerScrollInput,
    type ComputerScrollToolUseBlock as ComputerScrollToolUseBlock,
    type ComputerToolUseBlock as ComputerToolUseBlock,
    type ComputerToolset20260801 as ComputerToolset20260801,
    type ComputerToolsetConfigs as ComputerToolsetConfigs,
    type ComputerTripleClickConfig as ComputerTripleClickConfig,
    type ComputerTripleClickInput as ComputerTripleClickInput,
    type ComputerTripleClickToolUseBlock as ComputerTripleClickToolUseBlock,
    type ComputerTypeConfig as ComputerTypeConfig,
    type ComputerTypeInput as ComputerTypeInput,
    type ComputerTypeToolUseBlock as ComputerTypeToolUseBlock,
    type ComputerWaitConfig as ComputerWaitConfig,
    type ComputerWaitInput as ComputerWaitInput,
    type ComputerWaitToolUseBlock as ComputerWaitToolUseBlock,
    type ComputerZoomConfig as ComputerZoomConfig,
    type ComputerZoomInput as ComputerZoomInput,
    type ComputerZoomToolUseBlock as ComputerZoomToolUseBlock,
    type Container as Container,
    type ContainerParams as ContainerParams,
    type ContainerSkill as ContainerSkill,
    type ContainerUploadBlock as ContainerUploadBlock,
    type ContainerUploadBlockParam as ContainerUploadBlockParam,
    type ContentBlock as ContentBlock,
    type ContentBlockDeltaEvent as ContentBlockDeltaEvent,
    type ContentBlockParam as ContentBlockParam,
    type ContentBlockStartEvent as ContentBlockStartEvent,
    type ContentBlockStopEvent as ContentBlockStopEvent,
    type ContentBlockSource as ContentBlockSource,
    type ContentBlockSourceContent as ContentBlockSourceContent,
    type Diagnostics as Diagnostics,
    type DiagnosticsParam as DiagnosticsParam,
    type DirectCaller as DirectCaller,
    type DocumentBlock as DocumentBlock,
    type DocumentBlockParam as DocumentBlockParam,
    type EncryptedCodeExecutionResultBlock as EncryptedCodeExecutionResultBlock,
    type EncryptedCodeExecutionResultBlockParam as EncryptedCodeExecutionResultBlockParam,
    type FileDocumentSource as FileDocumentSource,
    type FileImageSource as FileImageSource,
    type ImageBlockParam as ImageBlockParam,
    type ImageTransformationsParam as ImageTransformationsParam,
    type InputJSONDelta as InputJSONDelta,
    type JSONOutputFormat as JSONOutputFormat,
    type MemoryTool20250818 as MemoryTool20250818,
    type Message as Message,
    type MessageContentParam as MessageContentParam,
    type MessageCountTokensTool as MessageCountTokensTool,
    type MessageCreateParamsContainer as MessageCreateParamsContainer,
    type MessageDeltaEvent as MessageDeltaEvent,
    type MessageDeltaUsage as MessageDeltaUsage,
    type MessageParam as MessageParam,
    type MessageStartEvent as MessageStartEvent,
    type MessageStopEvent as MessageStopEvent,
    type MessageStreamEvent as MessageStreamEvent,
    type MessageTokensCount as MessageTokensCount,
    type Metadata as Metadata,
    type Model as Model,
    type OutputConfig as OutputConfig,
    type OutputTokensDetails as OutputTokensDetails,
    type PlainTextSource as PlainTextSource,
    type RawContentBlockDelta as RawContentBlockDelta,
    type RawContentBlockDeltaEvent as RawContentBlockDeltaEvent,
    type RawContentBlockStartEvent as RawContentBlockStartEvent,
    type RawContentBlockStopEvent as RawContentBlockStopEvent,
    type RawMessageDeltaEvent as RawMessageDeltaEvent,
    type RawMessageStartEvent as RawMessageStartEvent,
    type RawMessageStopEvent as RawMessageStopEvent,
    type RawMessageStreamEvent as RawMessageStreamEvent,
    type RedactedThinkingBlock as RedactedThinkingBlock,
    type RedactedThinkingBlockParam as RedactedThinkingBlockParam,
    type RefusalStopDetails as RefusalStopDetails,
    type SearchResultBlockParam as SearchResultBlockParam,
    type ServerToolCaller as ServerToolCaller,
    type ServerToolCaller20260120 as ServerToolCaller20260120,
    type ServerToolUsage as ServerToolUsage,
    type ServerToolUseBlock as ServerToolUseBlock,
    type ServerToolUseBlockParam as ServerToolUseBlockParam,
    type SignatureDelta as SignatureDelta,
    type SkillParams as SkillParams,
    type StopReason as StopReason,
    type SystemMessageParam as SystemMessageParam,
    type TextBlock as TextBlock,
    type TextBlockParam as TextBlockParam,
    type TextCitation as TextCitation,
    type TextCitationParam as TextCitationParam,
    type TextDelta as TextDelta,
    type TextEditorCodeExecutionCreateResultBlock as TextEditorCodeExecutionCreateResultBlock,
    type TextEditorCodeExecutionCreateResultBlockParam as TextEditorCodeExecutionCreateResultBlockParam,
    type TextEditorCodeExecutionStrReplaceResultBlock as TextEditorCodeExecutionStrReplaceResultBlock,
    type TextEditorCodeExecutionStrReplaceResultBlockParam as TextEditorCodeExecutionStrReplaceResultBlockParam,
    type TextEditorCodeExecutionToolResultBlock as TextEditorCodeExecutionToolResultBlock,
    type TextEditorCodeExecutionToolResultBlockParam as TextEditorCodeExecutionToolResultBlockParam,
    type TextEditorCodeExecutionToolResultError as TextEditorCodeExecutionToolResultError,
    type TextEditorCodeExecutionToolResultErrorCode as TextEditorCodeExecutionToolResultErrorCode,
    type TextEditorCodeExecutionToolResultErrorParam as TextEditorCodeExecutionToolResultErrorParam,
    type TextEditorCodeExecutionViewResultBlock as TextEditorCodeExecutionViewResultBlock,
    type TextEditorCodeExecutionViewResultBlockParam as TextEditorCodeExecutionViewResultBlockParam,
    type ThinkingBlock as ThinkingBlock,
    type ThinkingBlockParam as ThinkingBlockParam,
    type ThinkingConfigAdaptive as ThinkingConfigAdaptive,
    type ThinkingConfigBetweenTools as ThinkingConfigBetweenTools,
    type ThinkingConfigDisabled as ThinkingConfigDisabled,
    type ThinkingConfigEnabled as ThinkingConfigEnabled,
    type ThinkingConfigParam as ThinkingConfigParam,
    type ThinkingDelta as ThinkingDelta,
    type Tool as Tool,
    type ToolBash20250124 as ToolBash20250124,
    type ToolChoice as ToolChoice,
    type ToolChoiceAny as ToolChoiceAny,
    type ToolChoiceAuto as ToolChoiceAuto,
    type ToolChoiceNone as ToolChoiceNone,
    type ToolChoiceTool as ToolChoiceTool,
    type ToolReferenceBlock as ToolReferenceBlock,
    type ToolReferenceBlockParam as ToolReferenceBlockParam,
    type ToolResultBlockParam as ToolResultBlockParam,
    type ToolSearchToolBm25_20251119 as ToolSearchToolBm25_20251119,
    type ToolSearchToolRegex20251119 as ToolSearchToolRegex20251119,
    type ToolSearchToolResultBlock as ToolSearchToolResultBlock,
    type ToolSearchToolResultBlockParam as ToolSearchToolResultBlockParam,
    type ToolSearchToolResultError as ToolSearchToolResultError,
    type ToolSearchToolResultErrorCode as ToolSearchToolResultErrorCode,
    type ToolSearchToolResultErrorParam as ToolSearchToolResultErrorParam,
    type ToolSearchToolSearchResultBlock as ToolSearchToolSearchResultBlock,
    type ToolSearchToolSearchResultBlockParam as ToolSearchToolSearchResultBlockParam,
    type ToolTextEditor20250124 as ToolTextEditor20250124,
    type ToolTextEditor20250429 as ToolTextEditor20250429,
    type ToolTextEditor20250728 as ToolTextEditor20250728,
    type ToolUnion as ToolUnion,
    type ToolUseBlock as ToolUseBlock,
    type ToolUseBlockParam as ToolUseBlockParam,
    type ToolUseCaller as ToolUseCaller,
    type ToolsetToolUseBlock as ToolsetToolUseBlock,
    type URLImageSource as URLImageSource,
    type URLPDFSource as URLPDFSource,
    type Usage as Usage,
    type UserLocation as UserLocation,
    type UserMessageParam as UserMessageParam,
    type WebFetchBlock as WebFetchBlock,
    type WebFetchBlockParam as WebFetchBlockParam,
    type WebFetchTool20250910 as WebFetchTool20250910,
    type WebFetchTool20260209 as WebFetchTool20260209,
    type WebFetchTool20260309 as WebFetchTool20260309,
    type WebFetchTool20260318 as WebFetchTool20260318,
    type WebFetchToolResultBlock as WebFetchToolResultBlock,
    type WebFetchToolResultBlockParam as WebFetchToolResultBlockParam,
    type WebFetchToolResultErrorBlock as WebFetchToolResultErrorBlock,
    type WebFetchToolResultErrorBlockParam as WebFetchToolResultErrorBlockParam,
    type WebFetchToolResultErrorCode as WebFetchToolResultErrorCode,
    type WebFetchURLSourceAll as WebFetchURLSourceAll,
    type WebFetchURLSourceExcept as WebFetchURLSourceExcept,
    type WebFetchURLSourceNone as WebFetchURLSourceNone,
    type WebFetchURLSourceOnly as WebFetchURLSourceOnly,
    type WebFetchURLSourceToolReference as WebFetchURLSourceToolReference,
    type WebFetchURLSources as WebFetchURLSources,
    type WebSearchResultBlock as WebSearchResultBlock,
    type WebSearchResultBlockParam as WebSearchResultBlockParam,
    type WebSearchTool20250305 as WebSearchTool20250305,
    type WebSearchTool20260209 as WebSearchTool20260209,
    type WebSearchTool20260318 as WebSearchTool20260318,
    type WebSearchToolRequestError as WebSearchToolRequestError,
    type WebSearchToolResultBlock as WebSearchToolResultBlock,
    type WebSearchToolResultBlockContent as WebSearchToolResultBlockContent,
    type WebSearchToolResultBlockParam as WebSearchToolResultBlockParam,
    type WebSearchToolResultBlockParamContent as WebSearchToolResultBlockParamContent,
    type WebSearchToolResultError as WebSearchToolResultError,
    type WebSearchToolResultErrorCode as WebSearchToolResultErrorCode,
    type ResponseToolUseBlockUnion as ResponseToolUseBlockUnion,
    type ResponseBrowserToolUseBlock as ResponseBrowserToolUseBlock,
    type ResponseBrowserCloseTabToolUseBlock as ResponseBrowserCloseTabToolUseBlock,
    type ResponseBrowserDoubleClickToolUseBlock as ResponseBrowserDoubleClickToolUseBlock,
    type ResponseBrowserFileUploadToolUseBlock as ResponseBrowserFileUploadToolUseBlock,
    type ResponseBrowserFindToolUseBlock as ResponseBrowserFindToolUseBlock,
    type ResponseBrowserFormInputToolUseBlock as ResponseBrowserFormInputToolUseBlock,
    type ResponseBrowserGetPageTextToolUseBlock as ResponseBrowserGetPageTextToolUseBlock,
    type ResponseBrowserHoldKeyToolUseBlock as ResponseBrowserHoldKeyToolUseBlock,
    type ResponseBrowserHoverToolUseBlock as ResponseBrowserHoverToolUseBlock,
    type ResponseBrowserJavascriptExecToolUseBlock as ResponseBrowserJavascriptExecToolUseBlock,
    type ResponseBrowserKeyToolUseBlock as ResponseBrowserKeyToolUseBlock,
    type ResponseBrowserLeftClickDragToolUseBlock as ResponseBrowserLeftClickDragToolUseBlock,
    type ResponseBrowserLeftClickToolUseBlock as ResponseBrowserLeftClickToolUseBlock,
    type ResponseBrowserLeftMouseDownToolUseBlock as ResponseBrowserLeftMouseDownToolUseBlock,
    type ResponseBrowserLeftMouseUpToolUseBlock as ResponseBrowserLeftMouseUpToolUseBlock,
    type ResponseBrowserListTabsToolUseBlock as ResponseBrowserListTabsToolUseBlock,
    type ResponseBrowserMiddleClickToolUseBlock as ResponseBrowserMiddleClickToolUseBlock,
    type ResponseBrowserMouseMoveToolUseBlock as ResponseBrowserMouseMoveToolUseBlock,
    type ResponseBrowserNavigateToolUseBlock as ResponseBrowserNavigateToolUseBlock,
    type ResponseBrowserNewTabToolUseBlock as ResponseBrowserNewTabToolUseBlock,
    type ResponseBrowserReadConsoleToolUseBlock as ResponseBrowserReadConsoleToolUseBlock,
    type ResponseBrowserReadNetworkToolUseBlock as ResponseBrowserReadNetworkToolUseBlock,
    type ResponseBrowserReadPageToolUseBlock as ResponseBrowserReadPageToolUseBlock,
    type ResponseBrowserRightClickToolUseBlock as ResponseBrowserRightClickToolUseBlock,
    type ResponseBrowserScreenshotToolUseBlock as ResponseBrowserScreenshotToolUseBlock,
    type ResponseBrowserScrollToToolUseBlock as ResponseBrowserScrollToToolUseBlock,
    type ResponseBrowserScrollToolUseBlock as ResponseBrowserScrollToolUseBlock,
    type ResponseBrowserSwitchTabToolUseBlock as ResponseBrowserSwitchTabToolUseBlock,
    type ResponseBrowserTripleClickToolUseBlock as ResponseBrowserTripleClickToolUseBlock,
    type ResponseBrowserTypeToolUseBlock as ResponseBrowserTypeToolUseBlock,
    type ResponseBrowserWaitToolUseBlock as ResponseBrowserWaitToolUseBlock,
    type ResponseBrowserZoomToolUseBlock as ResponseBrowserZoomToolUseBlock,
    type ResponseComputerToolUseBlock as ResponseComputerToolUseBlock,
    type ResponseComputerCursorPositionToolUseBlock as ResponseComputerCursorPositionToolUseBlock,
    type ResponseComputerDoubleClickToolUseBlock as ResponseComputerDoubleClickToolUseBlock,
    type ResponseComputerHoldKeyToolUseBlock as ResponseComputerHoldKeyToolUseBlock,
    type ResponseComputerKeyToolUseBlock as ResponseComputerKeyToolUseBlock,
    type ResponseComputerLeftClickDragToolUseBlock as ResponseComputerLeftClickDragToolUseBlock,
    type ResponseComputerLeftClickToolUseBlock as ResponseComputerLeftClickToolUseBlock,
    type ResponseComputerLeftMouseDownToolUseBlock as ResponseComputerLeftMouseDownToolUseBlock,
    type ResponseComputerLeftMouseUpToolUseBlock as ResponseComputerLeftMouseUpToolUseBlock,
    type ResponseComputerMiddleClickToolUseBlock as ResponseComputerMiddleClickToolUseBlock,
    type ResponseComputerMouseMoveToolUseBlock as ResponseComputerMouseMoveToolUseBlock,
    type ResponseComputerRightClickToolUseBlock as ResponseComputerRightClickToolUseBlock,
    type ResponseComputerScreenshotToolUseBlock as ResponseComputerScreenshotToolUseBlock,
    type ResponseComputerScrollToolUseBlock as ResponseComputerScrollToolUseBlock,
    type ResponseComputerTripleClickToolUseBlock as ResponseComputerTripleClickToolUseBlock,
    type ResponseComputerTypeToolUseBlock as ResponseComputerTypeToolUseBlock,
    type ResponseComputerWaitToolUseBlock as ResponseComputerWaitToolUseBlock,
    type ResponseComputerZoomToolUseBlock as ResponseComputerZoomToolUseBlock,
    type MessageCreateParams as MessageCreateParams,
    type MessageCreateParamsNonStreaming as MessageCreateParamsNonStreaming,
    type MessageCreateParamsStreaming as MessageCreateParamsStreaming,
    type MessageStreamParams as MessageStreamParams,
    type MessageCountTokensParams as MessageCountTokensParams,
  };

  export {
    Models as Models,
    type CapabilitySupport as CapabilitySupport,
    type ContextManagementCapability as ContextManagementCapability,
    type EffortCapability as EffortCapability,
    type ModelCapabilities as ModelCapabilities,
    type ModelInfo as ModelInfo,
    type ModelLine as ModelLine,
    type ServerToolsCapability as ServerToolsCapability,
    type ThinkingCapability as ThinkingCapability,
    type ThinkingTypes as ThinkingTypes,
    type ModelInfosPage as ModelInfosPage,
    type ModelRetrieveParams as ModelRetrieveParams,
    type ModelListParams as ModelListParams,
  };

  export {
    Files as Files,
    type DeletedFile as DeletedFile,
    type FileMetadata as FileMetadata,
    type FileMetadataPageCursor as FileMetadataPageCursor,
    type FileListParams as FileListParams,
    type FileDeleteParams as FileDeleteParams,
    type FileDownloadParams as FileDownloadParams,
    type FileRetrieveMetadataParams as FileRetrieveMetadataParams,
    type FileUploadParams as FileUploadParams,
  };

  export {
    Skills as Skills,
    type DeletedSkill as DeletedSkill,
    type Skill as Skill,
    type SkillSource as SkillSource,
    type SkillsPageCursor as SkillsPageCursor,
    type SkillCreateParams as SkillCreateParams,
    type SkillRetrieveParams as SkillRetrieveParams,
    type SkillListParams as SkillListParams,
    type SkillDeleteParams as SkillDeleteParams,
  };

  export {
    UserProfiles as UserProfiles,
    type DeletedUserProfile as DeletedUserProfile,
    type UserProfile as UserProfile,
    type UserProfileAccessType as UserProfileAccessType,
    type UserProfileCyberProgram as UserProfileCyberProgram,
    type UserProfileCyberRequirements as UserProfileCyberRequirements,
    type UserProfileCyberTier as UserProfileCyberTier,
    type UserProfileEfsFeature as UserProfileEfsFeature,
    type UserProfileEfsProgram as UserProfileEfsProgram,
    type UserProfileExternalUserAccountStatus as UserProfileExternalUserAccountStatus,
    type UserProfileExternalUserDetails as UserProfileExternalUserDetails,
    type UserProfileExternalUserDetailsParams as UserProfileExternalUserDetailsParams,
    type UserProfileExternalUserEntityType as UserProfileExternalUserEntityType,
    type UserProfileListOrder as UserProfileListOrder,
    type UserProfileListOrderBy as UserProfileListOrderBy,
    type UserProfileProgramStatus as UserProfileProgramStatus,
    type UserProfilePrograms as UserProfilePrograms,
    type UserProfilesPageCursor as UserProfilesPageCursor,
    type UserProfileCreateParams as UserProfileCreateParams,
    type UserProfileRetrieveParams as UserProfileRetrieveParams,
    type UserProfileUpdateParams as UserProfileUpdateParams,
    type UserProfileListParams as UserProfileListParams,
    type UserProfileDeleteParams as UserProfileDeleteParams,
  };

  export {
    Organization as Organization,
    type OrganizationInfo as OrganizationInfo,
    type OrganizationRole as OrganizationRole,
  };

  export {
    Beta as Beta,
    type AnthropicBeta as AnthropicBeta,
    type BetaAPIError as BetaAPIError,
    type BetaAuthenticationError as BetaAuthenticationError,
    type BetaBillingError as BetaBillingError,
    type BetaCurrency as BetaCurrency,
    type BetaError as BetaError,
    type BetaErrorResponse as BetaErrorResponse,
    type BetaGatewayTimeoutError as BetaGatewayTimeoutError,
    type BetaInvalidRequestError as BetaInvalidRequestError,
    type BetaMonetaryAmount as BetaMonetaryAmount,
    type BetaNotFoundError as BetaNotFoundError,
    type BetaOverloadedError as BetaOverloadedError,
    type BetaPermissionError as BetaPermissionError,
    type BetaRateLimitError as BetaRateLimitError,
  };

  export type APIErrorObject = API.APIErrorObject;
  export type AuthenticationError = API.AuthenticationError;
  export type BillingError = API.BillingError;
  export type ErrorObject = API.ErrorObject;
  export type ErrorResponse = API.ErrorResponse;
  export type ErrorType = API.ErrorType;
  export type GatewayTimeoutError = API.GatewayTimeoutError;
  export type InvalidRequestError = API.InvalidRequestError;
  export type NotFoundError = API.NotFoundError;
  export type OverloadedError = API.OverloadedError;
  export type PermissionError = API.PermissionError;
  export type RateLimitError = API.RateLimitError;
}
