import type { LLMRequest } from "../schema" import * as ProviderShared from "../protocols/shared" export interface EndpointInput { readonly request: LLMRequest readonly body: Body } export type EndpointPart = string | ((input: EndpointInput) => string) /** * Declarative URL construction for one route. * * `Endpoint` carries URL construction for one route. Routes with a canonical * host put `baseURL` here; provider helpers can override it by configuring the * route before selecting a model. * * `path` may be a string or a function of `EndpointInput`, for routes whose * URL embeds the model id, region, or another body field (e.g. Bedrock, * Gemini). */ export interface Endpoint { readonly baseURL?: string readonly path: EndpointPart readonly query?: Record } export type EndpointPatch = Partial> /** Construct an `Endpoint` from a path string or path function. */ export const path = (value: EndpointPart, options: Omit, "path"> = {}): Endpoint => ({ ...options, path: value, }) export const merge = (base: Endpoint, patch: EndpointPatch): Endpoint => ({ ...base, ...patch, baseURL: patch.baseURL ?? base.baseURL, path: patch.path ?? base.path, query: patch.query === undefined ? base.query : { ...base.query, ...patch.query }, }) const renderPart = (part: EndpointPart, input: EndpointInput) => typeof part === "function" ? part(input) : part export const render = (endpoint: Endpoint, input: EndpointInput) => { const url = new URL(`${ProviderShared.trimBaseUrl(endpoint.baseURL ?? "")}${renderPart(endpoint.path, input)}`) for (const [key, value] of Object.entries(endpoint.query ?? {})) url.searchParams.set(key, value) return url } export * as Endpoint from "./endpoint"