import type { SmolConfig } from "smoltalk"; /** The providers that run a model on this machine rather than over the * network: the MLX server behind `agency local serve`, and llama.cpp * inside this process. */ export declare const LOCAL_PROVIDERS: string[]; /** How a local model samples when a call names no temperature and its * catalog entry names no sampling of its own. The local backends default * to 0, which picks the single likeliest token every step: the same * prompt then gives the same reply every time, and a model that starts * going in circles cannot get out of them. Hosted providers sample at * 1.0, but on top of samplers of their own; on the MLX server, 1.0 with * nothing else is sampling from the whole distribution, which a small * 4-bit model turns into noise. A catalog entry carries what its model * card asks for (`localSamplingFor`); this is the fallback for a model * the catalog does not know. */ export declare const DEFAULT_LOCAL_TEMPERATURE = 0.7; export declare const DEFAULT_LOCAL_TOP_P = 0.95; export type ThinkingOption = { enabled: boolean; budgetTokens?: number; }; export type ReasoningEffort = "low" | "medium" | "high"; /** A program's limits on a reply that goes in circles, for the MLX chat * server's watcher: how many second thoughts and how many repeats of one * sentence it allows, and whether the answer is watched as well as the * thinking. A field left out keeps the server's own setting. */ export type ReplyLimits = { hedgeLimit?: number; repeatLimit?: number; limitAnswers?: boolean; }; /** Two option objects combined field by field, the second winning where * both set a field. A branch default and a call's own value combine this * way, so a call that sets one field keeps the branch's others. A `null` * object, and a `null` field, count as absent: Agency has no undefined, * and its optional fields arrive as null. */ export declare function mergeFields(base: T | null | undefined, over: T | null | undefined): T | undefined; /** The request fields the MLX chat server reads for the limits. */ export declare function mlxReplyLimitAttributes(limits: ReplyLimits, attributes?: Record): Record; /** Tokens of thinking for each `reasoningEffort` on a local model: the * budgets the Google client uses for the same efforts, so "low" means the * same amount of thinking whichever provider answers. */ export declare const EFFORT_BUDGETS: Record; /** The local backend a call goes to, or undefined for a hosted one. A * `.gguf` path with no provider named is llama.cpp: that is the provider * smoltalk infers for it, and the call should get the local defaults * whether or not the provider was spelled out. */ export declare function localProviderOf(config: Partial): "mlx" | "llama-cpp" | undefined; /** The one thinking setting a call amounts to. A `thinking` option is * taken as written. A `reasoningEffort` alone means thinking on, with the * effort's budget. Undefined when the call said nothing. */ export declare function thinkingFor(thinking: ThinkingOption | undefined, effort: ReasoningEffort | undefined): ThinkingOption | undefined; /** The request fields the MLX chat server reads for a call's thinking * setting. `chat_template_kwargs` is mlx_lm's own, handed to the model's * chat template: Qwen and Gemma templates read `enable_thinking`, and * gpt-oss's reads `reasoning_effort` and has no switch. `reasoning_budget` * is Agency's chat server's: the most tokens the model may think for * before it is made to answer. */ export declare function mlxThinkingAttributes(thinking: ThinkingOption, effort: ReasoningEffort | undefined, attributes?: Record): Record; /** A call's config as the runtime assembles it: smoltalk's fields plus * `replyLimits`, which is Agency's own and never reaches smoltalk. */ export type LocalCallConfig = Partial & { replyLimits?: ReplyLimits | null; }; /** A call's config with the choices a hosted provider makes on its own * made explicit for a local one. A call to a hosted provider is returned * as it is: sending those providers a temperature they did not ask for * is refused by some of their reasoning models. * * The sampling comes from the model's catalog entry when it has one, else * the local default. llama.cpp reads the temperature, `thinking`, and * `reasoningEffort` from the config itself, with the same budgets, and * the cut-offs from `rawAttributes` under node-llama-cpp's own names. The * MLX server is reached through smoltalk's OpenAI-shaped client, which * sends none of the sampling settings, so they go in `rawAttributes`, * which that client copies into the request as they are, along with the * thinking fields and the reply limits. * * `defaultModel` is the model the run was started for. A draft model or a * chat wrapper named for it in `metadata` is for that model only, so a * call that names another model does not carry them. */ export declare function withLocalDefaults(config: LocalCallConfig, defaultModel?: string): Partial;