import { type EndpointLayer, type ResolvedEndpoint } from './endpoints.js'; import OpenAI from 'openai'; import type { AgentConfig } from './types.js'; export interface ProviderDef { name: string; displayName: string; /** Suggested endpoint. Always overridable by --base-url, config, or baseURLEnv. */ baseURL: string; apiKeyEnv: string; defaultModel: string; extraHeaders?: Record; /** Env var that overrides baseURL, for self-hosted or relocated endpoints. */ baseURLEnv?: string; /** True when the user declared this provider rather than it shipping with KONECK. */ userDefined?: boolean; } /** * Providers the user declares themselves, for anything KONECK does not ship with — OpenRouter, * a company gateway, a vendor that launched last week. Declared entries behave exactly like * built-in ones: they appear in --list-providers and the /connect picker, take part in * credential inference, and can carry the extra headers some gateways require. * * ~/.koneck/providers.json * { * "openrouter": { * "baseURL": "https://openrouter.ai/api/v1", * "apiKeyEnv": "OPENROUTER_API_KEY", * "defaultModel": "anthropic/claude-sonnet-4.5", * "extraHeaders": { "HTTP-Referer": "https://example.com", "X-Title": "KONECK" } * } * } * * A name matching a built-in overrides it, which is how a permanently relocated endpoint is * pinned without setting an env var in every shell. */ export declare function userProvidersPath(home?: string): string; /** Reads and validates declared providers. A malformed file is skipped, never fatal. */ export declare function readUserProviders(home?: string): Record; /** * The endpoint in force for a provider, with the provider's own definition supplying the fallbacks. * * The TUI had this inline, so the browser had nothing to call and reached for the registry's * suggested address instead — which quietly discards a saved per-provider endpoint, the exact thing * `/endpoint` exists to set. endpoints.ts stays free of dependencies, which is why the definition * is looked up here and handed to it rather than read from inside it. */ export declare function endpointForProvider(provider: string, layers: readonly EndpointLayer[]): ResolvedEndpoint; /** Persists a declared provider, merging it into the running registry immediately. */ export declare function addUserProvider(def: Omit, home?: string): ProviderDef; /** * Forgets a declared provider. * * Only a declared one: a built-in cannot be removed, and a declaration that was shadowing a * built-in leaves the built-in behind rather than a hole where a provider used to be. Returns * whether anything was actually removed, so an interface can say so. */ export declare function removeUserProvider(name: string, home?: string): boolean; export declare const PROVIDERS: Record; /** * What KONECK ships with, taken before anything declared is merged over the top. * * A declaration may deliberately shadow a built-in — that is how a permanently relocated endpoint * gets pinned. Withdrawing the declaration then has to put the built-in back, and since the merge * below overwrites in place there would otherwise be nothing left to put back. */ export declare const BUILT_INS: Readonly>; export declare function useDeclaredProviders(home?: string): void; export declare function resolveProvider(name: string, baseURLOverride?: string): ProviderDef; /** * Whether an endpoint needs a credential at all. * * This began as "is it loopback", which was too narrow by exactly one case: the machine next to * you. Reported from a real setup — Ollama on 10.147.20.121, reachable, serving, no auth — where * KONECK threw "No API key found", the model list came back empty, and nothing said why. * * Two things make a credential unnecessary, and either is enough. The address is private, so * whatever is answering is on a network you control and is not a paid API; or the provider is a * self-hosted runtime, which serves without auth wherever it happens to run. A hosted gateway on * a public address still has to be given a key. */ export declare function isPrivateHost(url: string): boolean; /** * Whether this provider serves models from its own hardware. * * Not the same question as "does it need a credential", and conflating them was wrong in both * directions. A gateway listening on localhost — OmniRoute on port 20128, say — needs no key and * runs nothing: it forwards to somebody's cloud, and its models are billed like anybody else's. * Calling those "local" understates the bill. Meanwhile a genuine runtime reached across a LAN is * local in the only sense that matters — nobody is charging per token — whatever its address. * * So this asks what KIND of thing is at the other end, not where it is. */ export declare function servesOwnWeights(providerName: string): boolean; /** * The environment variable that would hold a key for this provider, known or not. * * A provider nobody declared still deserves a real name to export. Answering `KONECK_API_KEY` for * everything unknown told two different people to set the same variable for two different * endpoints, and the advice was wrong for both. */ export declare function keyEnvFor(providerName: string): string; /** Whether this endpoint can be used without a credential. */ export declare function needsNoCredential(def: ProviderDef): boolean; /** * Whether the model is being served from a machine on your own network. * * Decided from the address, not the provider's name. A LAN Ollama reached through a provider slot * called "omni" is still a LAN Ollama with Ollama's 4,096-token default — and while this was * judged by name, that setup got neither the smaller window nor the warning about it, so * compaction planned around a window the server was quietly truncating. */ export declare function servesLocally(providerName: string, baseURL: string): boolean; /** Providers whose API key is present in the environment. */ export declare function providersWithCredentials(): string[]; /** * The provider to use when nothing is configured. Inferred from which credential is actually * present rather than defaulting to one vendor. Undefined when nothing is set, or when several * keys are present and the choice is genuinely the user's. */ export declare function inferProvider(): string | undefined; /** * Which credential a request will actually use, and enough of it to recognise — never the key. * * Added after a failure that could not be diagnosed from anything KONECK printed. The same model * worked in the terminal and failed in the browser with a credentials error from the gateway. The * requests were captured on both sides and were identical: same model, same sixteen tools, same * max_tokens, same headers. So the difference was the key in play, and nothing anywhere said which * key that was or where it came from — the one fact that would have ended the search. * * A fingerprint rather than a secret: the length, the last four characters, and eight hex of a * SHA-256. Enough to say "the terminal and the browser are using different keys" at a glance, and * useless to anyone who reads it. */ export interface KeyProvenance { /** Where it came from, in the words a reader needs: an env var is named, a file is named. */ source: string; /** Recognisable, not reusable. */ fingerprint: string; found: boolean; } export declare function keyProvenance(def: ProviderDef, override?: string, stateHome?: string): KeyProvenance; /** Recognisable, not reusable: length, last four, and a short digest. */ export declare function fingerprintOf(key: string): string; export declare function getApiKey(def: ProviderDef, override?: string, /** * Where the credential store lives, for tests. Without it a test asserting precedence reads the * real one — and a test that reaches into somebody's actual credentials is the same mistake as a * test that wrote a fiction into their model-status file. */ stateHome?: string): string; export declare function listProviders(): string; /** * An API client for whichever provider the config names. * * Lives here rather than in the engine because that is where everything it needs already is. * From the engine it dragged the whole agent — ts-morph, execa, the tool layer — behind any * caller that only wanted to list models. */ export declare function buildClient(config: AgentConfig): OpenAI; //# sourceMappingURL=providers.d.ts.map