import type { Mode, ProviderId, ReasoningPreference } from "../types.js"; import type { ExaSearchType, SearchProviderId } from "../tools/web/types.js"; import type { CustomProviderDef } from "../llm/custom-providers.js"; export type ProviderCategory = "local" | "free-cloud" | "paid-cloud"; /** Endpoint URLs for one provider plus the sticky active choice. */ export interface ProviderEndpoints { urls: string[]; activeIndex: number; disabledUrls?: string[] | undefined; } /** Same ceiling as API keys, so both editors behave identically. */ export declare const MAX_PROVIDER_ENDPOINTS = 10; /** * Providers whose base URL is user-supplied. `modal` requires one (endpoints * are per-workspace); `lightning` treats it as an override of the shared * gateway, e.g. to point at a private Lightning Inference deployment. */ export declare const endpointProviders: readonly ProviderId[]; export declare function providerUsesEndpoints(provider: ProviderId): boolean; export type LearnedVisionEntry = boolean | { vision: boolean; at: string; }; export interface LearnedRouteEntry { readonly at: string; readonly controlDialect?: string | undefined; readonly vision?: boolean | undefined; readonly reasoning?: boolean | undefined; readonly reasoningMandatory?: boolean | undefined; readonly acceptedEfforts?: readonly string[] | undefined; readonly rejectedFields?: readonly string[] | undefined; readonly contextTokens?: number | undefined; readonly maxOutputTokens?: number | undefined; } export interface ClaiConfig { defaultProvider: ProviderId; defaultModel: string; defaultMode: Mode; providerModels: Partial>; allowAlwaysTools: string[]; pentestAuthorized: boolean; sandboxRoots: string[]; ollamaHost: string; /** * @deprecated Superseded by `providerEndpoints.modal`. Still read once so * configs written before multi-endpoint support keep working. */ modalBaseUrl: string; /** * Endpoint URLs per provider, with a sticky active index — the same shape as * multi-key storage. Used by providers whose base URL belongs to the user * (Modal, one URL per deployed endpoint) or is overridable (Lightning AI, * whose default is the shared gateway). */ providerEndpoints: Partial>; telemetry: boolean; lastUpdateCheck: number; thinking: ReasoningPreference; /** When true, exclude paid-cloud providers from the fallback chain. */ freeOnly: boolean; /** When true, try other configured providers after the selected provider fails. */ providerFallback: boolean; /** When true, suppress non-essential outbound calls (update check). */ offline: boolean; /** When true, the agent only accepts ```tool / XML / Kimi sentinel tool calls. */ parserStrict: boolean; /** When true, suppress writing chat history (in-memory only). */ privateMode: boolean; /** Max number of session records kept in JSONL history (0 = unlimited). */ historyRetentionLimit: number; /** When true, fs.read/list/search must stay within sandboxRoots ∪ {cwd, $HOME}. */ sandboxReads: boolean; /** Active search provider used by the web.search tool. */ activeSearchProvider: SearchProviderId; /** Exa retrieval strategy (`type`) applied when Exa is the active provider. */ exaSearchType: ExaSearchType; /** When true, bypass the OS keychain and always use plaintext file storage. */ disableKeychain: boolean; /** Permissions mode for auto-confirming tool calls ("default" or "allow-all"). */ permissions?: "default" | "allow-all"; learnedVisionCapabilities: Record; learnedRouteCapabilities?: Record; /** * Tool calling protocol: * - auto (default): native when dialect supports it, text fallback otherwise * - native: prefer native; still text-fallback on tools-unsupported * - text: force legacy fenced tool protocol */ toolCalling?: "auto" | "native" | "text"; /** E1: auto-compact at softCompactTokenBudget before the hard 100k ceiling. */ softEarlyCompact?: boolean; /** @deprecated Legacy soft trigger; migrated to autoCompactRequestTokens. */ softCompactTokenBudget?: number; /** Total estimated request tokens that trigger auto-compaction. */ autoCompactRequestTokens?: number; /** E2: max chars of fs.read/list/search body kept in model context (full on disk). */ fsPassthroughCapChars?: number; /** E3: lower maxTokens on tool steps vs legacy 32k fixed. */ adaptiveMaxTokens?: boolean; /** E4: advisory notices for free-cloud + large context / repeated failures. */ freeTierContextGuard?: boolean; /** E4: token estimate that triggers a free-tier large-context notice. */ freeTierWarnTokens?: number; /** E4: consecutive free-tier failures before a stronger switch-model notice. */ freeTierFailThreshold?: number; /** E5: collapse identical tool result bodies within a turn to a pointer. */ toolResultDedup?: boolean; /** E6: omit long fence-protocol tool encyclopedia when native tools are active. */ slimNativePrompt?: boolean; /** * Durable per-route model-window overrides, keyed `provider:model`. Set via * the footer ctx-limit chip; survives history navigation and restarts. */ contextLimitTokens?: Record; /** User-defined OpenAI-compatible providers (added via /provider picker). */ customProviders?: CustomProviderDef[]; } /** * Best-effort classification for the built-in providers. Some "free-cloud" * providers have paid tiers too — the label reflects what the default keys * usually buy you. Users who set up paid OpenAI/Anthropic keys can flip * freeOnly off to opt back into them. */ export declare const providerCategory: Record; /** * Resolve the category for any provider id (built-in or custom). Custom * providers default to "paid-cloud" so `/freeonly` keeps them out of the * fallback chain unless the user explicitly switched to one. */ export declare function resolveProviderCategory(provider: ProviderId): ProviderCategory; export declare function getConfig(): ClaiConfig; /** All custom provider defs stored in config. */ export declare function getCustomProviders(): CustomProviderDef[]; /** True when `id` matches a user-defined custom provider (sync, reads config). */ export declare function isCustomProviderIdSync(id: string | ProviderId): boolean; /** Resolve a custom definition by id (sync). */ export declare function findCustomProviderDefSync(id: string | ProviderId): CustomProviderDef | undefined; /** Persist a new custom provider definition. Throws on duplicate id. */ export declare function addCustomProvider(def: CustomProviderDef): CustomProviderDef; /** Remove a custom provider definition (does not touch its stored keys). */ export declare function removeCustomProvider(id: string): boolean; export declare function updateConfig(patch: Partial): ClaiConfig; export declare function setDefaultProvider(provider: ProviderId): ClaiConfig; export declare function setDefaultMode(mode: Mode): ClaiConfig; export declare function setProviderModel(provider: ProviderId, model: string): ClaiConfig; /** * Every stored endpoint URL for a provider plus the sticky active index. * A pre-multi-endpoint `modalBaseUrl` is folded in as the single entry so old * configs keep working without a migration step. */ export declare function getProviderEndpoints(provider: ProviderId): ProviderEndpoints; /** Replace the whole list (endpoint editor Save). Empty list clears it. */ export declare function setProviderEndpoints(provider: ProviderId, urls: readonly string[], activeIndex?: number, disabledUrls?: readonly string[]): ProviderEndpoints; /** * Add one endpoint and make it active. Re-adding a known URL just activates it, * which doubles as the CLI's way to switch endpoints. */ export declare function appendProviderEndpoint(provider: ProviderId, url: string): { endpoints: ProviderEndpoints; added: boolean; }; export declare function setActiveProviderEndpoint(provider: ProviderId, index: number): ProviderEndpoints; export declare function setProviderEndpointDisabled(provider: ProviderId, url: string, disabled: boolean): ProviderEndpoints; /** * The base URL a request should use. The provider's env override wins so a * shell can retarget clai without rewriting config; otherwise the sticky active * entry. Returns "" when nothing is configured — providers that require one * turn that into an actionable error, and Lightning falls back to its gateway. */ export declare function getActiveProviderEndpoint(provider: ProviderId): string; export declare function getProviderModel(provider: ProviderId): string; /** * True when the user (or a migration) actually persisted this key. Defaults are * resolved by Conf, so a resolved value alone cannot prove intent — the raw file * is the only honest source for migration decisions. */ export declare function hasExplicitConfigKey(key: keyof ClaiConfig): boolean; export declare function getConfigPath(): string; export declare function setThinking(patch: Partial): ClaiConfig; export declare function getActiveSearchProvider(): SearchProviderId; export declare function setActiveSearchProvider(id: SearchProviderId): ClaiConfig; export declare function getExaSearchType(): ExaSearchType; export declare function setExaSearchType(type: ExaSearchType): ClaiConfig;