import {z} from 'zod' export type GlobalHeaderValue = {is_secret?: boolean | undefined, value: string}; export type OAuthMetadataSource = 'autodiscovery' | 'provided'; export type ExtendedOAuthServerMetadata = {issuer: string, authorization_endpoint?: (string | null) | undefined, token_endpoint: string, registration_endpoint?: (string | null) | undefined, scopes_supported?: (Array | null) | undefined, response_types_supported?: Array | undefined, response_modes_supported?: (Array | null) | undefined, grant_types_supported?: (Array | null) | undefined, token_endpoint_auth_methods_supported?: (Array | null) | undefined, token_endpoint_auth_signing_alg_values_supported?: (Array | null) | undefined, service_documentation?: (string | null) | undefined, ui_locales_supported?: (Array | null) | undefined, op_policy_uri?: (string | null) | undefined, op_tos_uri?: (string | null) | undefined, revocation_endpoint?: (string | null) | undefined, revocation_endpoint_auth_methods_supported?: (Array | null) | undefined, revocation_endpoint_auth_signing_alg_values_supported?: (Array | null) | undefined, introspection_endpoint?: (string | null) | undefined, introspection_endpoint_auth_methods_supported?: (Array | null) | undefined, introspection_endpoint_auth_signing_alg_values_supported?: (Array | null) | undefined, code_challenge_methods_supported?: (Array | null) | undefined, client_id_metadata_document_supported?: (boolean | null) | undefined, authorization_response_iss_parameter_supported?: (boolean | null) | undefined, authorization_grant_profiles_supported?: (Array | null) | undefined, x_source?: (OAuthMetadataSource | null) | undefined, x_resource_url?: (string | null) | undefined, x_scope?: (string | null) | undefined}; export type PublicResourceVisibility = 'shared_org' | 'shared_workspace' | 'private'; export type ConnectorAuthenticationHeader = {name: string, is_required?: boolean | undefined, is_secret?: boolean | undefined}; export type AuthData = {client_id: string, client_secret?: (string | null) | undefined, client_scopes?: (Array | null) | undefined}; export type OAuth2AuthorizationCodeAuthMethod = {method_type?: 'oauth2' | undefined, headers?: (Array | null) | undefined, grant_type?: 'authorization_code' | undefined, auth_data: AuthData, oauth2_server_metadata?: (ExtendedOAuthServerMetadata | null) | undefined}; export type OAuth2TokenEndpointAuthMethod = 'client_secret_post' | 'client_secret_basic' | 'private_key_jwt'; export type OAuth2ClientCredentialsAuthMethod = {method_type?: 'oauth2' | undefined, headers?: (Array | null) | undefined, grant_type: 'client_credentials', token_endpoint_auth_method: OAuth2TokenEndpointAuthMethod, oauth2_server_metadata: ExtendedOAuthServerMetadata}; export type OAuth2AuthMethod = OAuth2AuthorizationCodeAuthMethod | OAuth2ClientCredentialsAuthMethod; export type BearerAuthMethod = {method_type?: 'bearer' | undefined, headers?: (Array | null) | undefined}; export type NoneAuthMethod = {method_type?: 'none' | undefined, headers?: (Array | null) | undefined}; export type CreateConnectorRequest = {headers?: ({[key: string]: unknown} | null) | undefined, global_headers?: {[key: string]: GlobalHeaderValue} | undefined, oauth2_server_metadata?: (ExtendedOAuthServerMetadata | null) | undefined, oauth2_server_metadata_url?: (string | null) | undefined, name: string, title?: (string | null) | undefined, description: string, icon_url?: (string | null) | undefined, server: string, visibility?: PublicResourceVisibility | undefined, auth_methods?: (Array | null) | undefined, system_prompt?: (string | null) | undefined, protocol?: 'mcp' | undefined}; export type CreateHTTPConnectorRequest = {headers?: ({[key: string]: unknown} | null) | undefined, global_headers?: {[key: string]: GlobalHeaderValue} | undefined, oauth2_server_metadata?: (ExtendedOAuthServerMetadata | null) | undefined, oauth2_server_metadata_url?: (string | null) | undefined, name: string, title?: (string | null) | undefined, description: string, icon_url?: (string | null) | undefined, server: string, visibility?: PublicResourceVisibility | undefined, auth_methods?: (Array | null) | undefined, system_prompt?: (string | null) | undefined, protocol: 'http'}; export type CreateApiV1ConnectorsArgs = {body: CreateConnectorRequest | CreateHTTPConnectorRequest}; export type CreateApiV1ConnectorsOptions = {baseUrl?: string | undefined, ApiKey?: string | undefined, fetch?: typeof fetch | undefined}; export const loggingCapability = z.object({}); export const promptsCapability = z.object({listChanged: z.boolean().nullable().optional()}); export const resourcesCapability = z.object({subscribe: z.boolean().nullable().optional(), listChanged: z.boolean().nullable().optional()}); export const toolsCapability = z.object({listChanged: z.boolean().nullable().optional()}); export const completionsCapability = z.object({}); export const tasksListCapability = z.object({}); export const tasksCancelCapability = z.object({}); export const tasksCallCapability = z.object({}); export const tasksToolsCapability = z.object({call: tasksCallCapability.nullable().optional()}); export const serverTasksRequestsCapability = z.object({tools: tasksToolsCapability.nullable().optional()}); export const serverTasksCapability = z.object({list: tasksListCapability.nullable().optional(), cancel: tasksCancelCapability.nullable().optional(), requests: serverTasksRequestsCapability.nullable().optional()}); export const serverCapabilities = z.object({experimental: z.record(z.string(), z.record(z.string(), z.unknown())).nullable().optional(), logging: loggingCapability.nullable().optional(), prompts: promptsCapability.nullable().optional(), resources: resourcesCapability.nullable().optional(), tools: toolsCapability.nullable().optional(), completions: completionsCapability.nullable().optional(), extensions: z.record(z.string(), z.record(z.string(), z.unknown())).nullable().optional(), tasks: serverTasksCapability.nullable().optional()}); export const mCPServerRepository = z.object({url: z.string(), source: z.string(), subfolder: z.string().nullable().optional()}); export const mCPServerIcon = z.object({src: z.string(), mimeType: z.string().nullable().optional(), sizes: z.array(z.string()).nullable().optional(), theme: z.enum(["light", "dark"]).nullable().optional()}); export const mCPServerRemoteHeader = z.object({name: z.string(), description: z.string(), isRequired: z.boolean().nullable().optional(), isSecret: z.boolean().nullable().optional(), default: z.string().nullable().optional(), choices: z.array(z.string()).nullable().optional()}); export const mCPServerAuthenticationRequirement = z.object({required: z.boolean(), schemes: z.array(z.string()).optional()}); export const mCPServerRemote = z.object({type: z.enum(["streamable-http", "sse"]), url: z.string(), supportedProtocolVersions: z.array(z.string()).nullable().optional(), headers: z.array(mCPServerRemoteHeader).nullable().optional(), authentication: mCPServerAuthenticationRequirement.nullable().optional()}); export const samplingContextCapability = z.object({}); export const samplingToolsCapability = z.object({}); export const samplingCapability = z.object({context: samplingContextCapability.nullable().optional(), tools: samplingToolsCapability.nullable().optional()}); export const formElicitationCapability = z.object({}); export const urlElicitationCapability = z.object({}); export const elicitationCapability = z.object({form: formElicitationCapability.nullable().optional(), url: urlElicitationCapability.nullable().optional()}); export const rootsCapability = z.object({listChanged: z.boolean().nullable().optional()}); export const tasksCreateMessageCapability = z.object({}); export const tasksSamplingCapability = z.object({createMessage: tasksCreateMessageCapability.nullable().optional()}); export const tasksCreateElicitationCapability = z.object({}); export const tasksElicitationCapability = z.object({create: tasksCreateElicitationCapability.nullable().optional()}); export const clientTasksRequestsCapability = z.object({sampling: tasksSamplingCapability.nullable().optional(), elicitation: tasksElicitationCapability.nullable().optional()}); export const clientTasksCapability = z.object({list: tasksListCapability.nullable().optional(), cancel: tasksCancelCapability.nullable().optional(), requests: clientTasksRequestsCapability.nullable().optional()}); export const clientCapabilities = z.object({experimental: z.record(z.string(), z.record(z.string(), z.unknown())).nullable().optional(), sampling: samplingCapability.nullable().optional(), elicitation: elicitationCapability.nullable().optional(), roots: rootsCapability.nullable().optional(), extensions: z.record(z.string(), z.record(z.string(), z.unknown())).nullable().optional(), tasks: clientTasksCapability.nullable().optional()}); export const annotations = z.object({audience: z.array(z.enum(["user", "assistant"])).nullable().optional(), priority: z.number().gte(0).lte(1).nullable().optional(), lastModified: z.string().nullable().optional()}); export const mCPResource = z.object({name: z.string(), title: z.string().nullable().optional(), uri: z.string(), description: z.string().nullable().optional(), mimeType: z.string().nullable().optional(), size: z.number().int().nullable().optional(), icons: z.array(mCPServerIcon).nullable().optional(), annotations: annotations.nullable().optional(), _meta: z.record(z.string(), z.unknown()).nullable().optional()}).and(z.record(z.string(), z.unknown())); export const toolExecution = z.object({taskSupport: z.enum(["forbidden", "optional", "required"]).nullable().optional()}); export const toolAnnotations = z.object({title: z.string().nullable().optional(), readOnlyHint: z.boolean().nullable().optional(), destructiveHint: z.boolean().nullable().optional(), idempotentHint: z.boolean().nullable().optional(), openWorldHint: z.boolean().nullable().optional()}); export const mCPUIToolMeta = z.object({resourceUri: z.string().nullable().optional(), visibility: z.array(z.enum(["model", "app"])).nullable().optional()}).and(z.record(z.string(), z.unknown())); export const turbineToolLocale = z.object({name: z.record(z.string(), z.string()).nullable().optional(), description: z.record(z.string(), z.string()).nullable().optional(), usage_sentence: z.record(z.string(), z.string()).nullable().optional(), working_description: z.record(z.string(), z.string()).nullable().optional(), done_description: z.record(z.string(), z.string()).nullable().optional()}); export const toolType = z.enum(["rag", "image", "code", "event"]); export const turbineToolMeta = z.object({locale: turbineToolLocale.nullable().optional(), tool_type: toolType.nullable().optional(), timeout: z.number().nullable().optional(), private_execution: z.boolean().nullable().optional()}); export const mCPToolMeta = z.object({ui: mCPUIToolMeta.nullable().optional(), "ai.mistral/turbine": turbineToolMeta.nullable().optional()}).and(z.record(z.string(), z.unknown())); export const mCPServerCardTool = z.object({name: z.string(), title: z.string().nullable().optional(), description: z.string().nullable().optional(), inputSchema: z.record(z.string(), z.unknown()), execution: toolExecution.nullable().optional(), outputSchema: z.record(z.string(), z.unknown()).nullable().optional(), icons: z.array(mCPServerIcon).nullable().optional(), annotations: toolAnnotations.nullable().optional(), _meta: mCPToolMeta.nullable().optional()}).and(z.record(z.string(), z.unknown())); export const promptArgument = z.object({name: z.string(), title: z.string().nullable().optional(), description: z.string().nullable().optional(), required: z.boolean().nullable().optional()}); export const mCPPrompt = z.object({name: z.string(), title: z.string().nullable().optional(), description: z.string().nullable().optional(), arguments: z.array(promptArgument).nullable().optional(), icons: z.array(mCPServerIcon).nullable().optional(), _meta: z.record(z.string(), z.unknown()).nullable().optional()}).and(z.record(z.string(), z.unknown())); export const serverLocale = z.object({name: z.record(z.string(), z.string()).nullable().optional(), description: z.record(z.string(), z.string()).nullable().optional(), usage_sentence: z.record(z.string(), z.string()).nullable().optional(), working_description: z.record(z.string(), z.string()).nullable().optional(), done_description: z.record(z.string(), z.string()).nullable().optional()}); export const turbineMeta = z.object({system_prompt_name: z.string().nullable().optional(), locale: serverLocale.nullable().optional()}); export const mCPServerCardMeta = z.object({"ai.mistral/turbine": turbineMeta.nullable().optional()}).and(z.record(z.string(), z.unknown())); export const mCPServerCard = z.object({$schema: z.string().nullable().optional(), name: z.string(), version: z.string(), capabilities: serverCapabilities.optional(), title: z.string().nullable().optional(), description: z.string().nullable().optional(), websiteUrl: z.string().nullable().optional(), repository: mCPServerRepository.nullable().optional(), icons: z.array(mCPServerIcon).nullable().optional(), remotes: z.array(mCPServerRemote).nullable().optional(), requires: clientCapabilities.nullable().optional(), resources: z.union([z.literal("dynamic"), z.array(mCPResource)]).nullable().optional(), tools: z.union([z.literal("dynamic"), z.array(mCPServerCardTool)]).nullable().optional(), prompts: z.union([z.literal("dynamic"), z.array(mCPPrompt)]).nullable().optional(), _meta: mCPServerCardMeta.nullable().optional()}).and(z.record(z.string(), z.unknown())); export const consumerType = z.enum(["user", "org", "workspace", "system"]); export const resourceVisibility = z.enum(["shared_global", "shared_org", "shared_workspace", "private"]); export const connectorLocale = z.object({name: z.record(z.string(), z.string()), description: z.record(z.string(), z.string()), usage_sentence: z.record(z.string(), z.string())}); export const authenticationType = z.enum(["oauth2", "bearer", "none", "github_app", "slack_app"]); export const connectorAuthenticationHeader = z.object({name: z.string(), is_required: z.boolean().optional(), is_secret: z.boolean().optional()}); export const globalHeaderValue = z.object({is_secret: z.boolean().optional(), value: z.string()}); export const oAuth2GrantType = z.enum(["authorization_code", "client_credentials"]); export const oAuth2TokenEndpointAuthMethod = z.enum(["client_secret_post", "client_secret_basic", "private_key_jwt"]); export const oAuthMetadataSource = z.enum(["autodiscovery", "provided"]); export const extendedOAuthServerMetadata = z.object({issuer: z.string().min(1), authorization_endpoint: z.string().min(1).nullable().optional(), token_endpoint: z.string().min(1), registration_endpoint: z.string().min(1).nullable().optional(), scopes_supported: z.array(z.string()).nullable().optional(), response_types_supported: z.array(z.string()).optional(), response_modes_supported: z.array(z.string()).nullable().optional(), grant_types_supported: z.array(z.string()).nullable().optional(), token_endpoint_auth_methods_supported: z.array(z.string()).nullable().optional(), token_endpoint_auth_signing_alg_values_supported: z.array(z.string()).nullable().optional(), service_documentation: z.string().min(1).nullable().optional(), ui_locales_supported: z.array(z.string()).nullable().optional(), op_policy_uri: z.string().min(1).nullable().optional(), op_tos_uri: z.string().min(1).nullable().optional(), revocation_endpoint: z.string().min(1).nullable().optional(), revocation_endpoint_auth_methods_supported: z.array(z.string()).nullable().optional(), revocation_endpoint_auth_signing_alg_values_supported: z.array(z.string()).nullable().optional(), introspection_endpoint: z.string().min(1).nullable().optional(), introspection_endpoint_auth_methods_supported: z.array(z.string()).nullable().optional(), introspection_endpoint_auth_signing_alg_values_supported: z.array(z.string()).nullable().optional(), code_challenge_methods_supported: z.array(z.string()).nullable().optional(), client_id_metadata_document_supported: z.boolean().nullable().optional(), authorization_response_iss_parameter_supported: z.boolean().nullable().optional(), authorization_grant_profiles_supported: z.array(z.string()).nullable().optional(), x_source: oAuthMetadataSource.nullable().optional(), x_resource_url: z.string().nullable().optional(), x_scope: z.string().nullable().optional()}); export const publicAuthenticationMethod = z.object({method_type: authenticationType, headers: z.array(connectorAuthenticationHeader).nullable().optional(), global_headers: z.record(z.string(), globalHeaderValue).optional(), has_default_credentials: z.boolean(), grant_type: oAuth2GrantType.nullable().optional(), token_endpoint_auth_method: oAuth2TokenEndpointAuthMethod.nullable().optional(), oauth2_server_metadata: extendedOAuthServerMetadata.nullable().optional()}); export const toolProperties = z.object({read_only: z.boolean().nullable()}); export const logicalExpression: z.ZodType = z.object({type: z.enum(["and", "or"]), expressions: z.array(z.union([z.array(z.string()), z.lazy(() => logicalExpression), toolProperties]))}); export const toolExecutionConfiguration = z.object({requires_confirmation: z.union([z.array(z.string()), logicalExpression, toolProperties]).nullable().optional(), skip_confirmation: z.union([z.array(z.string()), logicalExpression, toolProperties]).nullable().optional(), include: z.array(z.string()).nullable().optional(), exclude: z.array(z.string()).nullable().optional()}); export const connectionPreference = z.object({name: z.string(), tool_configuration: toolExecutionConfiguration, is_default: z.boolean().nullable().optional(), consumer_type: consumerType.nullable().optional()}); export const authStatus = z.enum(["valid", "invalid", "error"]); export const hTTPStatus = z.union([z.literal(100), z.literal(101), z.literal(102), z.literal(103), z.literal(200), z.literal(201), z.literal(202), z.literal(203), z.literal(204), z.literal(205), z.literal(206), z.literal(207), z.literal(208), z.literal(226), z.literal(300), z.literal(301), z.literal(302), z.literal(303), z.literal(304), z.literal(305), z.literal(307), z.literal(308), z.literal(400), z.literal(401), z.literal(402), z.literal(403), z.literal(404), z.literal(405), z.literal(406), z.literal(407), z.literal(408), z.literal(409), z.literal(410), z.literal(411), z.literal(412), z.literal(413), z.literal(414), z.literal(415), z.literal(416), z.literal(417), z.literal(418), z.literal(421), z.literal(422), z.literal(423), z.literal(424), z.literal(425), z.literal(426), z.literal(428), z.literal(429), z.literal(431), z.literal(451), z.literal(500), z.literal(501), z.literal(502), z.literal(503), z.literal(504), z.literal(505), z.literal(506), z.literal(507), z.literal(508), z.literal(510), z.literal(511)]); export const credentialsStatusErrorReason = z.enum(["oauth expired", "oauth near expiry", "empty credentials", "blank bearer token", "unparsable credentials", "you need to reconnect", "oauth refresh error", "MCP server unreachable", "MCP server timed out", "MCP server error", "unknown error"]); export const credentialsStatus = z.object({status_type: authStatus, last_checked_at: z.string().nullable().optional(), error_http_code: hTTPStatus.nullable().optional(), error_message: credentialsStatusErrorReason.nullable().optional()}); export const authenticationConfiguration = z.object({name: z.string(), title: z.string().nullable().optional(), authentication_type: authenticationType, scope: consumerType, status: credentialsStatus.nullable().optional(), is_default: z.boolean().optional(), creator_id: z.string().nullable().optional()}); export const connectorToolLocale = z.object({name: z.record(z.string(), z.string()), description: z.record(z.string(), z.string()), usage_sentence: z.record(z.string(), z.string())}); export const executionConfig = z.object({type: z.string()}).and(z.record(z.string(), z.unknown())); export const connectorTool = z.object({id: z.string(), name: z.string(), description: z.string(), system_prompt: z.string().nullable().optional(), locale: connectorToolLocale.nullable().optional(), jsonschema: z.record(z.string(), z.unknown()).nullable().optional(), execution_config: executionConfig.nullable(), visibility: resourceVisibility, created_at: z.string(), modified_at: z.string(), active: z.boolean().nullable().optional()}); export const connectionConfigType = z.enum(["mcp", "turbine", "eolienne"]); export const publicConnectionConfig = z.object({type: connectionConfigType.optional(), base_url: z.string().nullable().optional(), headers: z.record(z.string(), z.string()).nullable().optional(), signed: z.boolean().nullable().optional()}); export const toolTypes = z.literal("function"); export const function = z.object({name: z.string(), description: z.string().optional(), strict: z.boolean().optional(), parameters: z.record(z.string(), z.unknown())}); export const tool = z.object({type: toolTypes.optional(), function: function}); export const publicExecutionConnectionConfig = z.object({type: connectionConfigType, server: z.string().nullable().optional(), name: z.string().nullable().optional(), id: z.string().nullable().optional(), tool_configuration: toolExecutionConfiguration.nullable().optional(), hosted_internally: z.boolean().optional()}); export const publicExecutionConnector = z.object({id: z.string(), name: z.string(), connection_config: publicExecutionConnectionConfig.nullable()}); export const executionTool = z.object({name: z.string(), integration_id: z.string(), execution_config: executionConfig.nullable()}); export const publicConnectorExecutionData = z.object({integrations: z.array(publicExecutionConnector), tools: z.array(executionTool)}); export const publicExecutionEnv = z.object({tools: z.array(tool), tool_execution_data: publicConnectorExecutionData, errors: z.array(z.string())}); export const mCPConnector = z.object({id: z.string(), name: z.string(), title: z.string().nullable().optional(), description: z.string(), created_at: z.string(), modified_at: z.string(), server: z.string().nullable().optional(), icon_url: z.string().nullable().optional(), server_card: mCPServerCard.nullable().optional(), owner_id: z.string().nullable().optional(), owner_type: consumerType, visibility: resourceVisibility, creator_id: z.string().nullable().optional(), locale: connectorLocale.nullable().optional(), system_prompt: z.string().nullable().optional(), supported_auth_methods: z.array(publicAuthenticationMethod).nullable().optional(), connection_preferences: z.array(connectionPreference).nullable().optional(), connection_credentials: z.array(authenticationConfiguration).nullable().optional(), blocked_by: z.array(consumerType).optional(), private_tool_execution: z.boolean(), supports_mcp: z.boolean(), mistral: z.boolean().optional(), is_authenticated: z.boolean().nullable().optional(), tools: z.array(connectorTool).nullable().optional(), connection_config: publicConnectionConfig.nullable().optional(), execution_env: publicExecutionEnv.nullable().optional(), protocol: z.literal("mcp")}); export const hTTPConnector = z.object({id: z.string(), name: z.string(), title: z.string().nullable().optional(), description: z.string(), created_at: z.string(), modified_at: z.string(), server: z.string().nullable().optional(), icon_url: z.string().nullable().optional(), server_card: mCPServerCard.nullable().optional(), owner_id: z.string().nullable().optional(), owner_type: consumerType, visibility: resourceVisibility, creator_id: z.string().nullable().optional(), locale: connectorLocale.nullable().optional(), system_prompt: z.string().nullable().optional(), supported_auth_methods: z.array(publicAuthenticationMethod).nullable().optional(), connection_preferences: z.array(connectionPreference).nullable().optional(), connection_credentials: z.array(authenticationConfiguration).nullable().optional(), blocked_by: z.array(consumerType).optional(), private_tool_execution: z.boolean(), supports_mcp: z.boolean(), mistral: z.boolean().optional(), is_authenticated: z.boolean().nullable().optional(), tools: z.array(connectorTool).nullable().optional(), connection_config: publicConnectionConfig.nullable().optional(), execution_env: publicExecutionEnv.nullable().optional(), protocol: z.literal("http")}); export const connector = z.discriminatedUnion("protocol", [mCPConnector, hTTPConnector]); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Create a new connector. * * POST /v1/connectors */ export const createApiV1Connectors = async (args: CreateApiV1ConnectorsArgs, options?: CreateApiV1ConnectorsOptions) => { const {baseUrl = "https://api.mistral.ai", fetch: fetchFn = fetch, ApiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (ApiKey !== undefined) headers.set('authorization', `Bearer ${ApiKey}`) const url = `${baseUrl.replace(/\/+$/, '')}/v1/connectors${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(connector, await res.json()) };