/** * ADR-0027: Capability readiness probe. Validates the Alibaba Cloud docmind * credential by calling QueryDocParserStatus with a dummy id — a 400 (bad * request) means the credential is valid (the API accepted auth but rejected * the id); a 401/403 means the credential is bad. */ import { classifyNetworkFailure, type NetworkFailureCategory } from "../connections/networkFailure.js"; export interface CapabilityReadinessInput { readonly endpoint: string; readonly accessKeyId: string; readonly accessKeySecret: string; } export type CapabilityReadinessProbe = (input: CapabilityReadinessInput) => Promise; export class CapabilityReadinessError extends Error { constructor( readonly code: "capability_readiness_unsupported" | "capability_readiness_unreachable" | "capability_readiness_rejected", message: string, readonly category: NetworkFailureCategory | "configuration" | "http", readonly upstreamStatus?: number, ) { super(message); this.name = "CapabilityReadinessError"; } } /** * Probe the Alibaba Cloud docmind credential. We call QueryDocParserStatus * with a dummy id. The API will return: * - 400 (InvalidParameter) → credential valid, just a bad id → probe passes * - 401/403 (InvalidAccessKey/Forbidden) → credential invalid → probe fails * - network error → unreachable */ export const probeDocmindCredential: CapabilityReadinessProbe = async (input) => { const url = `https://${input.endpoint}/?Action=QueryDocParserStatus&Id=probe-test&Version=2022-07-11`; const authHeader = makeBasicAuth(input.accessKeyId, input.accessKeySecret); let response: Response; try { response = await fetch(url, { method: "GET", headers: { authorization: authHeader, accept: "application/json" }, redirect: "manual", signal: AbortSignal.timeout(10_000), }); } catch (error) { throw new CapabilityReadinessError( "capability_readiness_unreachable", "docmind credential readiness check could not reach the API", classifyNetworkFailure(error), ); } await response.body?.cancel(); if (response.status === 401 || response.status === 403) { throw new CapabilityReadinessError( "capability_readiness_rejected", `docmind credential rejected: status ${response.status}`, "http", response.status, ); } }; function makeBasicAuth(accessKeyId: string, accessKeySecret: string): string { const credentials = Buffer.from(`${accessKeyId}:${accessKeySecret}`).toString("base64"); return `Basic ${credentials}`; }