/** * Shared bring-your-own-key (BYOK) provider config for the Copilot SDK. * * Both the agent executor (`defaults.executor.config.provider`) and the LLM * judge graders (`defaults.judge_provider`) point the underlying Copilot SDK * session at a custom, OpenAI-compatible endpoint. They share this one * implementation so the validation and secret-handling hardening lives in a * single place and can't drift between the two call sites. * * Credentials are referenced indirectly by environment-variable name * (`apiKeyEnv` / `bearerTokenEnv`); literal secrets are intentionally not * accepted, so keys never live in the spec or in persisted run artifacts. */ import type { ProviderConfig as CopilotProviderConfig } from "@github/copilot-sdk"; /** * A vally-owned mirror of the Copilot SDK's `ProviderConfig`, extended with the * `apiKeyEnv` / `bearerTokenEnv` env-indirection. The named variables are read * from the environment of the vally process at run time. */ export interface CopilotSdkProviderConfig { /** Provider type. Defaults to `"openai"` for OpenAI-compatible APIs. */ type?: "openai" | "azure" | "anthropic"; /** API endpoint URL (absolute `http`/`https`). */ baseUrl: string; /** Wire protocol (openai/azure only). Defaults to `"completions"`. */ wireApi?: "completions" | "responses"; /** Transport for the OpenAI Responses API (`wireApi: "responses"`). Defaults to `"http"`. */ transport?: "http" | "websockets"; /** Name of an environment variable to read the API key from at run time. */ apiKeyEnv?: string; /** * Name of an environment variable to read a bearer token from at run time * (Authorization header). Takes precedence over {@link apiKeyEnv} when both * resolve to a value. */ bearerTokenEnv?: string; /** Azure-specific options. */ azure?: { /** API version. Defaults to the SDK default (e.g. `"2024-10-21"`). */ apiVersion?: string; }; /** Extra HTTP headers to include on outbound provider requests. */ headers?: Record; /** * Well-known model name the runtime uses to look up agent configuration and * default token limits. Falls back to the caller-supplied model. */ modelId?: string; /** * Model name sent to the provider API for inference, when it differs from * {@link modelId} (e.g. an Azure deployment name). Falls back to * {@link modelId}, then the caller-supplied model. */ wireModel?: string; /** Overrides the resolved model's default max prompt tokens. */ maxPromptTokens?: number; /** Overrides the resolved model's default max output tokens. */ maxOutputTokens?: number; } /** Read an environment variable that a provider config references, failing loudly when unset. */ export declare function readRequiredEnv(name: string, field: string): string; /** * Map a vally {@link CopilotSdkProviderConfig} to the Copilot SDK's * `ProviderConfig`, resolving `apiKeyEnv` / `bearerTokenEnv` from the * environment here so keys never live in the spec. A bearer token takes * precedence, so when `bearerTokenEnv` is set `apiKeyEnv` is not resolved at all. * * `labelPrefix` names the config path for error messages (e.g. * `"defaults.executor.config.provider"` or `"defaults.judge_provider"`). * * Returns the mapped provider plus the resolved secrets so the caller can * register them with its error redactor. * * Residual risk: the resolved credential is handed to the SDK; whether it writes * `SessionConfig.provider` into session-log dirs or span attributes is internal * to that dependency. Prefer short-lived credentials and treat those dirs as * sensitive. */ export declare function mapCopilotProvider(provider: CopilotSdkProviderConfig, labelPrefix: string): { provider: CopilotProviderConfig; secrets: string[]; }; /** * Validate a {@link CopilotSdkProviderConfig} (BYOK) block. Structural shape * only — secret resolution happens at run time. Throws on the first problem * found. `label` names the config path for error messages. */ export declare function validateCopilotProviderConfig(value: unknown, label: string): void; /** * Redact secrets in place from a caught error before it propagates. `secrets` * are heuristically gated (short values are skipped to avoid over-redaction); * `exactSecrets` are explicitly-known credentials redacted by exact match * regardless of length. Walks the `cause` chain and `AggregateError.errors` * (with a cycle guard) so a secret in a wrapped error can't escape. Shared by * the executor and the LLM judge so both harden identically. */ export declare function redactProviderErrorInPlace(err: unknown, secrets: readonly string[], exactSecrets?: readonly string[], seen?: Set): void; /** The one accepted provider-source value. */ export declare const COPILOT_ENV_SOURCE = "copilot-env"; /** Global gate that opts a run into env-sourced judge BYOK without editing the spec. */ export declare const JUDGE_PROVIDER_SOURCE_ENV = "VALLY_JUDGE_PROVIDER_SOURCE"; /** * Opt-in selector that resolves the judge provider from ambient * `COPILOT_PROVIDER_*` variables at run time (mirroring Copilot CLI), instead of * a declarative block. Kept a distinct shape so the spec never carries literal * secrets and the opt-in stays explicit. */ export interface CopilotEnvProviderSource { source: typeof COPILOT_ENV_SOURCE; } /** A judge provider is either a declarative block or the env-source selector. */ export type JudgeProviderSpec = CopilotSdkProviderConfig | CopilotEnvProviderSource; /** True when a judge provider spec is the env-source selector rather than a mapping. */ export declare function isEnvProviderSource(value: JudgeProviderSpec | undefined): value is CopilotEnvProviderSource; /** * Validate a `judge_provider` value, which may be either the declarative mapping * or the `{ source: "copilot-env" }` selector. The two forms are mutually * exclusive — a `source` selector must not carry inline provider fields. */ export declare function validateJudgeProviderSpec(value: unknown, label: string): void; /** * Apply the {@link JUDGE_PROVIDER_SOURCE_ENV} gate to a spec's `judge_provider`. * Env-sourced BYOK is opt-in only: it activates when the spec uses the selector * or the gate is set — never from the mere presence of `COPILOT_PROVIDER_*`. The * gate and a declarative mapping are mutually exclusive (fails closed). */ export declare function resolveJudgeProviderSelector(specValue: JudgeProviderSpec | undefined, env?: NodeJS.ProcessEnv): JudgeProviderSpec | undefined; /** * Return a copy of `env` with all `COPILOT_PROVIDER_*` variables removed. The * comparison is case-insensitive because Windows environment-variable names are * case-insensitive — an ambient `Copilot_Provider_Base_Url` there is still read * by the SDK subprocess as `COPILOT_PROVIDER_BASE_URL`, so it must be scrubbed * to preserve the opt-in guarantee. */ export declare function stripProviderEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv; /** * Resolve a Copilot SDK provider from ambient `COPILOT_PROVIDER_*` variables, * mirroring Copilot CLI's `buildProviderConfigFromEnv()`. Unlike the declarative * mapping, these variables hold the *literal* key/token values (not env-var * names), so this is only ever invoked behind the explicit opt-in. * * Fails closed: with no `COPILOT_PROVIDER_BASE_URL` there is nothing to resolve, * which under an active selector is a misconfiguration rather than a fallback. * Returns the mapped provider plus the resolved secrets for error redaction. * * `modelId`/`wireModel` are omitted when their env vars are unset, so the SDK * applies its own fallback (→ `SessionConfig.model`, i.e. the judge model), * matching the declarative path rather than forcing the judge model as the wire * model. */ export declare function buildProviderFromEnv(env?: NodeJS.ProcessEnv): { provider: CopilotProviderConfig; secrets: string[]; }; /** * Resolve a judge provider spec (declarative mapping or env-source selector) into * the SDK provider plus its secrets, reading credentials at this SDK boundary. */ export declare function resolveJudgeProvider(spec: JudgeProviderSpec, label: string): { provider: CopilotProviderConfig; secrets: string[]; }; //# sourceMappingURL=copilot-provider.d.ts.map