/**
 * @fileoverview ClinicalTrials.gov REST API v2 client with retry, rate limiting, and timeout.
 * @module services/clinical-trials/clinical-trials-service
 */
import type { Context } from '@cyanheads/mcp-ts-core';
import { type ServerConfig } from '../../config/server-config.js';
import { type FieldIndexEntry } from './field-search.js';
import type { FieldNode, FieldValueStats, PagedStudiesResponse, SearchParams, Study } from './types.js';
/** Constructor options for overriding retry/backoff/validation behavior (primarily for tests). */
export interface ClinicalTrialsServiceOptions {
    baseBackoffMs?: number;
    maxBackoffMs?: number;
    maxRetries?: number;
    /**
     * Whether to validate `fields` against the cached metadata index before
     * making API calls. Defaults to true; lazy-fetches /studies/metadata on
     * first use, then caches the index in-memory.
     */
    validateFieldsLocally?: boolean;
}
export declare class ClinicalTrialsService {
    private readonly baseUrl;
    private readonly timeoutMs;
    private readonly maxPageSize;
    private readonly maxRetries;
    private readonly baseBackoffMs;
    private readonly maxBackoffMs;
    private readonly validateFieldsLocally;
    private lastRequestAt;
    private fieldIndexPromise;
    constructor(config: ServerConfig, options?: ClinicalTrialsServiceOptions);
    /** Search studies with query, filters, pagination, and field selection. */
    searchStudies(params: SearchParams, ctx: Context): Promise<PagedStudiesResponse>;
    /** Fetch a single study by NCT ID. */
    getStudy(nctId: string, ctx: Context): Promise<Study>;
    /** Fetch multiple studies by NCT IDs in a single request. Returns identification and results section data. */
    getStudiesBatch(nctIds: string[], ctx: Context): Promise<Study[]>;
    /** Get field definitions (metadata tree) from the data model. */
    getMetadata(includeIndexedOnly: boolean, ctx: Context): Promise<FieldNode[]>;
    /** Get field value statistics for the specified fields. */
    getFieldValues(fields: string[], ctx: Context): Promise<FieldValueStats[]>;
    /**
     * Mark each stat as multi-valued by checking the metadata node `type` for an
     * array marker (`[]`, e.g. `Phase[]`, `text[]`) — the durable source of
     * cardinality. Note: the stat's own `type` (`ENUM`/`STRING`) is the value
     * domain, not the array marker, so the metadata node type is the only signal.
     * Reuses the cached field index (no round-trip); fails open silently if the
     * metadata index is unavailable.
     */
    private annotateMultiValued;
    /**
     * Search the field model by keyword, returning ranked matches with paths and
     * types plus the pre-cap match total for accurate truncation disclosure.
     */
    searchFieldDefinitions(query: string, limit: number, ctx: Context): Promise<{
        entries: FieldIndexEntry[];
        total: number;
    }>;
    /** Lazy-load and memoize the flattened field index from /studies/metadata. */
    private getFieldIndex;
    /**
     * Apply unambiguous fixes (whitespace, case-only) to field names before
     * validation. Returns the corrected list — anything still invalid falls
     * through to validateFields and surfaces the structured did-you-mean error.
     * Logs corrections via ctx.log.notice so operators can spot recurring LLM
     * mistakes without forcing a tool-call round-trip.
     */
    private normalizeFields;
    /** Reject invalid field names locally with did-you-mean suggestions. */
    private validateFields;
    private buildSearchQuery;
    private throttle;
    private fetchJson;
}
/** Initialize the ClinicalTrials service. Call from createApp setup(). */
export declare function initClinicalTrialsService(): void;
/** Get the initialized ClinicalTrials service instance. */
export declare function getClinicalTrialsService(): ClinicalTrialsService;
//# sourceMappingURL=clinical-trials-service.d.ts.map