/** * Provider Types (DESIGN.md §5, PRD FR-001, FR-004, NFR-004, NFR-010). * * This module defines the static shape of a Provider: a stable ID, the * set of Capabilities it advertises, and a factory that produces an * Adapter bound to a Provider context. No transport, no I/O, no * credential reads occur outside Capability invocation. * * Phase 2 (P2-01) declares only the Search Capability; Phase 3 (P3-01) * adds the `vision?: VisionCapability` slot on `ProviderAdapter` and * declares the matching descriptor metadata. Quota and diagnostics * attach to the `ProviderAdapter` interface in later phases. The * `ProviderCapability` union already enumerates them so descriptor * metadata stays forward-compatible. * * `BUILT_IN_PROVIDER_DESCRIPTORS` is intentionally empty in this stub * file; the production registry waits for P2-05, after both real * Search Adapters exist. Selection functions and tests operate on * explicit descriptor lists through `getProviderDescriptor` and * `getConfiguredProviderDescriptors`. */ import type { SearchCapability } from "../capabilities/search.js"; import type { VisionCapability } from "../capabilities/vision.js"; import type { QuotaCapability } from "../capabilities/quota.js"; import type { DiagnosticsCapability } from "../capabilities/diagnostics.js"; import type { RepositoryCapability } from "../capabilities/repository.js"; import type { ReaderCapability } from "../capabilities/reader.js"; import type { CrawlCapability } from "../capabilities/crawl.js"; import type { MapCapability } from "../capabilities/map.js"; import type { ResearchCapability } from "../capabilities/research.js"; import type { ScienceCapability } from "../capabilities/science.js"; import type { MiniMaxTransportDeps } from "./minimax/coding-plan-client.js"; /** * Built-in Provider IDs. Adding a new Provider is a Phase 2+ decision; * new entries must come with a real Adapter and conformance coverage. */ export declare const PROVIDER_IDS: readonly ["zai", "minimax", "tavily", "exa", "brave", "firecrawl", "parallel", "perplexity", "jina", "you", "linkup", "spider", "bocha", "searchapi", "kagi", "arxiv", "openalex", "crossref", "pubmed", "europepmc"]; export type ProviderId = (typeof PROVIDER_IDS)[number]; /** * The set of Capability names a Provider may advertise. Phase 2 * declares the full union so descriptor metadata stays forward-compatible * with Phase 3+ Adapters, but only `search` is wired into the * `ProviderAdapter` shape today. * * P6-06 adds `repository-exploration`: a descriptor advertises it iff * the Adapter it creates supplies `adapter.repository`. Z.AI advertises * it (P6-04 supplies the handle); MiniMax does not and remains free of * repository credential, transport, and fallback work until it ships * its own Adapter and conformance fixtures. * * Reader Migration Ticket 04 adds `reader`: a descriptor advertises it * iff the Adapter it creates supplies `adapter.reader`. Z.AI advertises * it (Ticket 03 supplies the handle); MiniMax does not. * * Tavily integration adds `crawl`, `map`, and `research`: a descriptor * advertises each iff the Adapter it creates supplies the matching * slot. The Tavily descriptor advertises all three; the `crawl?` / * `map?` / `research?` slots arrive on `ProviderAdapter` alongside * their capability contracts. */ export type ProviderCapability = "search" | "vision.interpret-image" | "vision.ui-artifact" | "vision.extract-text" | "vision.diagnose-error" | "vision.diagram" | "vision.chart" | "vision.diff" | "vision.video" | "quota" | "diagnostics" | "repository-exploration" | "reader" | "crawl" | "map" | "research" | "science.search" | "science.get"; /** * Runtime mirror of {@link ProviderCapability} for validation surfaces * that must check membership at runtime (e.g. the config routing key). * The `satisfies` check keeps array and union in lockstep at compile * time. */ export declare const PROVIDER_CAPABILITIES: readonly ["search", "vision.interpret-image", "vision.ui-artifact", "vision.extract-text", "vision.diagnose-error", "vision.diagram", "vision.chart", "vision.diff", "vision.video", "quota", "diagnostics", "repository-exploration", "reader", "crawl", "map", "research"]; /** * Injected Provider context. Adapters capture but do not immediately * inspect this; credential resolution and transport construction happen * only inside Capability invocation after validation. */ export interface ProviderContext { readonly env: NodeJS.ProcessEnv; } /** * Provider Adapter contract (Phase 3 shape). Each Capability that the * Provider supports becomes a property on this interface. Phase 4 adds * `quota?: QuotaCapability` and `diagnostics?: DiagnosticsCapability`. * Phase 6 adds `repository?: RepositoryCapability` (P6-04), and P6-06 * advertises `repository-exploration` in descriptor metadata so * Provider selection and Doctor inventory derive from a single source * of truth — the slot here is the implementation handle the future * Explorer layer (P6-05+) reaches through. * * Reader Migration Ticket 03 added `reader?: ReaderCapability`. Ticket * 04 advertised `reader` in descriptor metadata and cut the * `commands/read.ts` handler over to dispatch through this handle. */ export interface ProviderAdapter { readonly id: ProviderId; readonly search?: SearchCapability; readonly vision?: VisionCapability; readonly quota?: QuotaCapability; readonly diagnostics?: DiagnosticsCapability; readonly repository?: RepositoryCapability; readonly reader?: ReaderCapability; readonly crawl?: CrawlCapability; readonly map?: MapCapability; readonly research?: ResearchCapability; /** * Science capability slot. The five scholarly suppliers (arxiv, * openalex, crossref, pubmed, europepmc) expose search+get through * this single slot; `adapterSlotFor` maps both `science.search` and * `science.get` here. Adapters ship in later tickets; the seat exists * now so the preflight slot check has a named target. */ readonly science?: ScienceCapability; } /** * Provider Descriptor. `capabilities()` and `isConfigured()` construct * no Adapter or transport. `create()` is side-effect-free: it captures * the injected environment but shall not read credentials, inspect * media, construct a transport, or perform I/O. Credential resolution * and transport construction are allowed only inside Capability * invocation after validation. * * `credentialEnvVars` is the optional provider-fallback surface * (Provider Fallback Tech Plan §"Per-handler refactor pattern" / * execution-log "Flag carried to ticket 02"). It lists the * environment-variable names this Provider reads to decide it is * configured. The provider-fallback executor consumes it to construct * a Provider-specific `ConfigurationError` message (e.g. "Set * Z_AI_API_KEY.") on exhaustion and under the kill-switch, instead of * the generic "Set the required API key." fallback. The field is * OPTIONAL for backward compatibility with test doubles that pre-date * the field; the executor falls back to the generic message when it is * absent. Each built-in Provider supplies the matching list; the * `PROVIDER_FALLBACK_CREDENTIAL_MESSAGE` constant documents the * fallback wording. */ export interface ProviderDescriptor { readonly id: ProviderId; /** * Whether the Provider is ready to serve the given capability under * the injected environment. The optional `capabilityId` enables * capability-aware configuration (8J.1): a Provider like Jina AI that * supports keyless Reader but requires a key for Search/Research can * report `true` for Reader without a key and `false` for the others. * * Callers that omit `capabilityId` (e.g. `getConfiguredProviderDescriptors` * for the Doctor listing) get the Provider's global readiness — whether * it can serve ANY capability — so a keyless-capable Provider still * appears in the listing. */ isConfigured(env: NodeJS.ProcessEnv, capabilityId?: ProviderCapability): boolean; capabilities(): ReadonlySet; create(context: ProviderContext): ProviderAdapter; /** * The environment-variable names this Provider reads to determine it * is configured. Empty / undefined means the executor should use the * generic fallback message. */ readonly credentialEnvVars?: readonly string[]; } /** * Provider-neutral fallback message the executor uses when the * effective descriptor does not expose `credentialEnvVars` (or the * list is empty). Kept as a module-level constant so it stays a * single source of truth for the executor and the dispatch-level * error redaction passes it through unchanged. */ export declare const PROVIDER_FALLBACK_CREDENTIAL_MESSAGE = "Set the required API key."; /** * Built-in Provider registry (types-module stub). The production list * lives in `registry.ts` (real Adapter factories, no circular import); * this module-level list carries ONLY the adapter-less science seats so * `getProviderDescriptor` here can resolve them without importing the * adapter modules (which import this module). Tests inject descriptor * lists explicitly through the optional `descriptors` parameter; * production wiring uses `providers/registry.ts`. */ export declare const BUILT_IN_PROVIDER_DESCRIPTORS: readonly ProviderDescriptor[]; /** * Look up a descriptor by ID. Throws when the ID is unknown. The * optional `descriptors` parameter lets tests inject doubles; production * uses the static built-in list. */ export declare function getProviderDescriptor(id: ProviderId, descriptors?: readonly ProviderDescriptor[]): ProviderDescriptor; /** * Return the descriptors that are configured for the given environment. * Configuration is purely metadata-driven and never constructs an * Adapter. */ export declare function getConfiguredProviderDescriptors(env: NodeJS.ProcessEnv, descriptors?: readonly ProviderDescriptor[]): readonly ProviderDescriptor[]; /** * Narrow UTCP client surface used by Adapters. Production code passes * `UtcpClient.create()` factories wrapped to this shape; tests inject * doubles with the same surface. */ export interface UtcpClientPort { registerManual(template: unknown): Promise<{ success: boolean; errors: string[]; }>; getTools(): Promise; callTool(name: string, args: Record): Promise; } /** * Z.AI MCP client options. `noCache` and `disableRetry` arrive in P2-03 * so Adapters can hand policy to shared execution. `env` (T2b) carries the resolved * credential view from the descriptor's `create(context)` so the real * `ZaiMcpClient` authorises with a file-configured key rather than * ambient state; tests inject fakes that ignore this field. */ export interface ZaiMcpClientOptions { readonly enableVision?: boolean; readonly noCache?: boolean; readonly disableRetry?: boolean; readonly env?: NodeJS.ProcessEnv; } /** * Legacy Z.AI search parameters as accepted by `ZaiMcpClient.webSearch`. * Preserved by the Adapter so legacy cache keys remain reconstructible. */ export interface LegacyZaiSearchParams { query: string; count?: number; domainFilter?: string; recencyFilter?: "oneDay" | "oneWeek" | "oneMonth" | "oneYear" | "noLimit"; contentSize?: "medium" | "high"; location?: "cn" | "us"; } /** Result envelope produced by `ZaiMcpClient.webSearch`. */ export interface WebSearchResult { refer: string; title: string; link: string; media: string; content: string; icon: string; publish_date?: string; } /** * Legacy direct Z.AI search client surface used while P2-03 ships. P2-03 * replaces this with a real Adapter; P2-05 removes it. */ export interface LegacySearchClientPort { webSearch(params: LegacyZaiSearchParams): Promise; close(): Promise; } /** * Injectable fetch response for quota transports (duck-typed). The * injected fetch returns this minimal shape so tests pass a plain object * without depending on the DOM `Response` type. */ export interface ProviderQuotaFetchResponse { readonly ok: boolean; readonly status: number; text(): Promise; json(): Promise; } export type ProviderQuotaFetch = (input: string | URL, init: Record) => Promise; /** * Injectable fetch response for image transports (duck-typed). Extends * {@link ProviderQuotaFetchResponse} with the two fields an image * transport reads beyond JSON body parsing: `headers` (for MIME * detection via `Content-Type`) and `arrayBuffer` (for the raw bytes). * * Production `fetch` returns the global `Response`, which exposes both * fields and therefore satisfies this interface; tests inject doubles * that match. Quota and JSON-only transports continue to consume the * narrower {@link ProviderQuotaFetchResponse} — they don't need these * fields and their fakes shouldn't be forced to provide them. */ export interface ProviderImageFetchResponse extends ProviderQuotaFetchResponse { readonly headers: { get(name: string): string | null; }; arrayBuffer(): Promise; } export type ProviderImageFetch = (input: string | URL, init: Record) => Promise; /** * Return the ambient global fetch narrowed to a provider-specific function * type. Centralizes the `fetch as unknown as T` double-cast so it appears * once instead of being repeated in every provider client. * * The cast is structurally safe: production `fetch` returns a `Response` * that satisfies every provider fetch interface above; tests inject * compatible doubles via `deps.fetch`. */ export declare function getGlobalFetch Promise = typeof fetch>(): T; /** Dependencies the Phase 2 Search wiring would inject into the registry. */ export interface SearchDependencies { clientFactory(options: ZaiMcpClientOptions): LegacySearchClientPort; } /** * Narrow surface a Z.AI Search Adapter uses from `ZaiMcpClient`. The * Adapter only invokes raw tools; cache and retry policy live in shared * execution. `listTools` is the tool-discovery surface the Z.AI * diagnostics capability probes (DESIGN.md §14). */ export interface ZaiAdapterClientPort { callToolRaw(name: string, args: Record): Promise; listTools(): Promise; close(): Promise; } /** Dependencies the Z.AI Search Adapter accepts through injection. */ export interface ZaiAdapterDependencies { clientFactory(options: ZaiMcpClientOptions): ZaiAdapterClientPort; /** Optional Z.AI quota-monitor transport injection (tests). */ readonly quotaFetch?: ProviderQuotaFetch; readonly quotaSetTimeout?: typeof setTimeout; readonly quotaClearTimeout?: typeof clearTimeout; /** * Optional Repository Capability close-bound override in * milliseconds (P6-04A). When omitted, the production default of * 2000 ms (matching `ZaiMcpClient.close`) applies. Tests inject a * shorter bound to keep the never-resolving-close test bounded * below the production default. */ readonly repositoryCloseTimeoutMs?: number; /** * Optional Reader Capability close-bound override in milliseconds * (Reader Migration Ticket 03). When omitted, the production * default of 2000 ms (matching `ZaiMcpClient.close`) applies. Tests * inject a shorter bound to keep the never-resolving-close test * bounded below the production default. Mirrors the repository * seam. */ readonly readerCloseTimeoutMs?: number; } /** * Dependencies the MiniMax Adapter accepts. The unified `transport` * seam carries `fetch` and timer injection; tests pass a single fake * that drives every direct-transport call site (search, vision, quota, * diagnostics, image fetch). */ export interface MiniMaxAdapterDependencies { readonly transport?: MiniMaxTransportDeps; /** * Optional injection point for the specialized-vision support check * (`MiniMaxAdapterDependencies.isSpecializedVisionOperationSupported`). * Production never sets this; tests pass a forced-support function so * the routing branch can be exercised deterministically without * flipping a compiled registry attestation. When omitted, the Adapter * delegates to the compiled conformance registry query. */ readonly isSpecializedVisionOperationSupported?: (operation: import("./minimax/vision-conformance.js").SpecializedVisionOperation) => boolean; } /** * Build the Z.AI Provider Descriptor. Phase 2 returns a stub that * advertises the search Capability; P2-03 supplies the real Adapter. * P3-01 extends the capability set with every current Vision operation * so descriptor metadata advertises the Capability before any Adapter * is constructed; the real `vision` slot arrives in P3-03. * * The stub keeps the Provider registerable from day one while the * Search Adapter is implemented in P2-03. Throwing inside `create()` * surfaces the unfinished Adapter during testing rather than silently * failing later. */ export declare function createZaiDescriptor(dependencies?: ZaiAdapterDependencies): ProviderDescriptor; /** * Build the MiniMax Provider Descriptor. Phase 2 returns a stub that * advertises the search Capability; P2-04 supplies the real Adapter. * P3-01 advertises the general `vision.interpret-image` Capability * while leaving every specialized operation out until Phase 5 * attests individual specialized mappings. */ export declare function createMiniMaxDescriptor(dependencies?: MiniMaxAdapterDependencies): ProviderDescriptor; /** arXiv supplier seat. Keyless — no credential model exists. */ export declare function createArxivDescriptor(): ProviderDescriptor; /** OpenAlex supplier seat. Keyless; optional `OPENALEX_API_KEY` upgrade. */ export declare function createOpenalexDescriptor(): ProviderDescriptor; /** Crossref supplier seat. Keyless (mailto is politeness, not a credential). */ export declare function createCrossrefDescriptor(): ProviderDescriptor; /** PubMed supplier seat. Keyless 3 r/s; free `NCBI_API_KEY` lifts to 10 r/s. */ export declare function createPubmedDescriptor(): ProviderDescriptor; /** Europe PMC supplier seat. Keyless — no credential model exists. */ export declare function createEuropepmcDescriptor(): ProviderDescriptor; //# sourceMappingURL=types.d.ts.map