export type ModelRef = { /** Provider/model string (e.g. "openai/gpt-4o-mini"). */ id: string; /** Optional model variant annotation. */ variant?: string; }; export type SmartfetchOptions = { binaryDir?: string; /** * Dedicated model(s) for secondary-model summarization. * Each entry is tried in order; the first to return usable text is used. */ webfetchModels?: ModelRef[]; /** * Getter for the host's `small_model` from the already-loaded merged * OpenCode config. Read once into memory at plugin construction; the * getter only keeps the value in sync when the host config hook fires * after tool construction. Never touches disk. */ smallModelRef?: () => string | undefined; /** Explorer agent model id, resolved from in-memory config at construction. */ explorerModel?: string; /** Librarian agent model id, resolved from in-memory config at construction. */ librarianModel?: string; }; export type SecondaryModel = { providerID: string; modelID: string; /** Optional model variant passed at the body level. */ variant?: string; }; export type RedirectStep = { from: string; to: string; status: number; }; export type CachedFetch = { requestedUrl: string; finalUrl: string; statusCode: number; contentType: string; charset?: string; etag?: string; lastModified?: string; contentLength?: number; filename?: string; canonicalUrl?: string; headings?: string[]; title?: string; rawContent: string; markdown: string; text: string; html: string; extractedMain: boolean; usedLlmsTxt: boolean; sourceKind: 'llms_txt' | 'html' | 'text'; upgradedToHttps: boolean; redirectChain: RedirectStep[]; truncated: boolean; wordCount: number; qualitySignals?: string[]; llmsProbeError?: string; llmsProbeTruncated?: boolean; cacheRevalidated?: boolean; upstreamStatusCode?: number; cacheHit?: boolean; decodedCharset?: string; decodeFallback?: boolean; decodeWarning?: string; secondaryModelInputTruncated?: boolean; secondaryModelInputChars?: number; secondaryModelSourceChars?: number; }; export type BinaryFetch = { requestedUrl: string; finalUrl: string; statusCode: number; contentType: string; charset?: string; etag?: string; lastModified?: string; contentLength?: number; filename?: string; canonicalUrl?: string; redirectChain: RedirectStep[]; upgradedToHttps: boolean; truncated: boolean; binary: true; binaryKind: 'image' | 'audio' | 'video' | 'pdf' | 'binary'; downloadLimitBytes?: number; metadataOnly?: boolean; data?: Uint8Array; llmsProbeError?: string; llmsProbeTruncated?: boolean; cacheRevalidated?: boolean; upstreamStatusCode?: number; cacheHit?: boolean; }; export type FetchResult = CachedFetch | BinaryFetch; export type DecodedBody = { text: string; decodedCharset: string; decodeFallback: boolean; decodeWarning?: string; }; export type ExtractedContent = { title?: string; rawContent: string; markdown: string; text: string; html: string; extractedMain: boolean; canonicalUrl?: string; headings?: string[]; }; export type FetchWithRedirectsResult = { blockedRedirect: true; redirectUrl: string; statusCode: number; redirectChain: RedirectStep[]; } | { response: Response; finalUrl: string; redirectChain: RedirectStep[]; }; export type LlmsProbeResult = { url: string; statusCode: number; redirectChain: RedirectStep[]; text: string; headers: { contentType?: string; charset?: string; etag?: string; lastModified?: string; contentLength?: number; filename?: string; }; truncated: boolean; decodedCharset: string; decodeFallback: boolean; decodeWarning?: string; upgradedToHttps: boolean; } | { error?: string; };