/** * Custom model/provider config file handle and validation. */ import type { Api, ModelSpec } from "@oh-my-pi/pi-ai/types"; import { type ModelKind } from "@oh-my-pi/pi-catalog/types"; import { ConfigFile } from "./config-file.js"; import type { ModelsConfig, ProviderAuthMode, ProviderDiscovery } from "./models-config-schema.js"; export type ProviderValidationMode = "models-config" | "runtime-register"; export interface ProviderValidationModel { id: string; api?: Api; kind?: ModelKind; contextWindow?: number; supportsTools?: boolean; maxTokens?: number; } export interface ProviderValidationConfig { baseUrl?: string; headers?: Record; apiKey?: string; api?: Api; auth?: ProviderAuthMode; oauthConfigured?: boolean; discovery?: ProviderDiscovery; compat?: ModelSpec["compat"]; remoteCompaction?: unknown; disableStrictTools?: boolean; guardrailIdentifier?: string; requestMetadata?: Record; modelOverrides?: Record; models: ProviderValidationModel[]; } export declare function validateProviderConfiguration(providerName: string, config: ProviderValidationConfig, mode: ProviderValidationMode): void; /** Unknown keys are diagnostic only: keep newer-release configuration intact. */ export declare function getUnknownCompatKeys(config: ModelsConfig): string[]; export declare const ModelsConfigFile: ConfigFile<{ providers?: Record | undefined; maxTokensField?: "max_completion_tokens" | "max_tokens" | undefined; openRouterRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; qwenTemplateReasoningEffort?: boolean | undefined; reasoningContentField?: "reasoning" | "reasoning_content" | "reasoning_text" | undefined; reasoningEffortMap?: { high?: string | undefined; low?: string | undefined; max?: string | undefined; medium?: string | undefined; minimal?: string | undefined; xhigh?: string | undefined; } | undefined; replayUnsignedThinking?: boolean | undefined; requiresAssistantAfterToolResult?: boolean | undefined; requiresAssistantContentForToolCalls?: boolean | undefined; requiresMistralToolIds?: boolean | undefined; requiresReasoningContentForToolCalls?: boolean | undefined; requiresThinkingAsText?: boolean | undefined; requiresThinkingPresence?: boolean | undefined; requiresToolResultId?: boolean | undefined; requiresToolResultName?: boolean | undefined; statefulResponses?: boolean | undefined; streamIdleTimeoutMs?: number | undefined; streamMarkupHealingPattern?: "dsml" | "kimi" | "qwen" | "thinking" | undefined; strictResponsesPairing?: boolean | undefined; stripImageInput?: boolean | undefined; supportsConfigurationUpdate?: boolean | undefined; supportsContextManagement?: boolean | undefined; supportsDeveloperRole?: boolean | undefined; supportsEagerToolInputStreaming?: boolean | undefined; supportsForcedToolChoice?: boolean | undefined; supportsImageDetailOriginal?: boolean | undefined; supportsLongPromptCacheRetention?: boolean | undefined; supportsMultipleSystemMessages?: boolean | undefined; supportsReasoningEffort?: boolean | undefined; supportsReasoningParams?: boolean | undefined; supportsReasoningSummary?: boolean | undefined; supportsSteering?: boolean | undefined; supportsStore?: boolean | undefined; supportsStrictMode?: boolean | undefined; supportsToolChoice?: boolean | undefined; supportsUsageInStreaming?: boolean | undefined; thinkingFormat?: "openai" | "openrouter" | "qwen" | "qwen-chat-template" | "zai" | undefined; toolStrictMode?: "all_strict" | "none" | undefined; vercelGatewayRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; whenThinking?: { allowAnthropicHeaderOverrides?: boolean | undefined; allowsSyntheticReasoningContentForToolCalls?: boolean | undefined; alwaysSendMaxTokens?: boolean | undefined; bedrockMessagesApi?: boolean | undefined; cacheControlFormat?: "anthropic" | undefined; disableReasoningOnForcedToolChoice?: boolean | undefined; disableReasoningOnToolChoice?: boolean | undefined; disableReasoningWithTools?: boolean | undefined; extraBody?: Record | undefined; maxTokensField?: "max_completion_tokens" | "max_tokens" | undefined; openRouterRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; qwenTemplateReasoningEffort?: boolean | undefined; reasoningContentField?: "reasoning" | "reasoning_content" | "reasoning_text" | undefined; reasoningEffortMap?: { high?: string | undefined; low?: string | undefined; max?: string | undefined; medium?: string | undefined; minimal?: string | undefined; xhigh?: string | undefined; } | undefined; replayUnsignedThinking?: boolean | undefined; requiresAssistantAfterToolResult?: boolean | undefined; requiresAssistantContentForToolCalls?: boolean | undefined; requiresMistralToolIds?: boolean | undefined; requiresReasoningContentForToolCalls?: boolean | undefined; requiresThinkingAsText?: boolean | undefined; requiresThinkingPresence?: boolean | undefined; requiresToolResultId?: boolean | undefined; requiresToolResultName?: boolean | undefined; statefulResponses?: boolean | undefined; streamIdleTimeoutMs?: number | undefined; streamMarkupHealingPattern?: "dsml" | "kimi" | "qwen" | "thinking" | undefined; strictResponsesPairing?: boolean | undefined; stripImageInput?: boolean | undefined; supportsConfigurationUpdate?: boolean | undefined; supportsContextManagement?: boolean | undefined; supportsDeveloperRole?: boolean | undefined; supportsEagerToolInputStreaming?: boolean | undefined; supportsForcedToolChoice?: boolean | undefined; supportsImageDetailOriginal?: boolean | undefined; supportsLongPromptCacheRetention?: boolean | undefined; supportsMultipleSystemMessages?: boolean | undefined; supportsReasoningEffort?: boolean | undefined; supportsReasoningParams?: boolean | undefined; supportsReasoningSummary?: boolean | undefined; supportsSteering?: boolean | undefined; supportsStore?: boolean | undefined; supportsStrictMode?: boolean | undefined; supportsToolChoice?: boolean | undefined; supportsUsageInStreaming?: boolean | undefined; thinkingFormat?: "openai" | "openrouter" | "qwen" | "qwen-chat-template" | "zai" | undefined; toolStrictMode?: "all_strict" | "none" | undefined; vercelGatewayRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; } | undefined; } & { promptCacheMaximumCheckpoints?: number | undefined; promptCacheMinimumTokens?: number | undefined; promptCacheMode?: "automatic" | "explicit" | "none" | undefined; supportsLongPromptCacheRetention?: boolean | undefined; supportsThinkingBindingControls?: boolean | undefined; }) | undefined; disableStrictTools?: boolean | undefined; discovery?: { advertisedReasoning?: boolean | undefined; injectV1?: boolean | undefined; timeoutMs?: number | undefined; type: "apple-foundation-models" | "litellm" | "llama.cpp" | "lm-studio" | "ollama" | "openai-models-list" | "proxy"; } | undefined; guardrailIdentifier?: string | undefined; guardrailTrace?: "disabled" | "enabled" | "enabled_full" | undefined; guardrailVersion?: string | undefined; headers?: Record | undefined; modelOverrides?: Record | undefined; maxTokensField?: "max_completion_tokens" | "max_tokens" | undefined; openRouterRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; qwenTemplateReasoningEffort?: boolean | undefined; reasoningContentField?: "reasoning" | "reasoning_content" | "reasoning_text" | undefined; reasoningEffortMap?: { high?: string | undefined; low?: string | undefined; max?: string | undefined; medium?: string | undefined; minimal?: string | undefined; xhigh?: string | undefined; } | undefined; replayUnsignedThinking?: boolean | undefined; requiresAssistantAfterToolResult?: boolean | undefined; requiresAssistantContentForToolCalls?: boolean | undefined; requiresMistralToolIds?: boolean | undefined; requiresReasoningContentForToolCalls?: boolean | undefined; requiresThinkingAsText?: boolean | undefined; requiresThinkingPresence?: boolean | undefined; requiresToolResultId?: boolean | undefined; requiresToolResultName?: boolean | undefined; statefulResponses?: boolean | undefined; streamIdleTimeoutMs?: number | undefined; streamMarkupHealingPattern?: "dsml" | "kimi" | "qwen" | "thinking" | undefined; strictResponsesPairing?: boolean | undefined; stripImageInput?: boolean | undefined; supportsConfigurationUpdate?: boolean | undefined; supportsContextManagement?: boolean | undefined; supportsDeveloperRole?: boolean | undefined; supportsEagerToolInputStreaming?: boolean | undefined; supportsForcedToolChoice?: boolean | undefined; supportsImageDetailOriginal?: boolean | undefined; supportsLongPromptCacheRetention?: boolean | undefined; supportsMultipleSystemMessages?: boolean | undefined; supportsReasoningEffort?: boolean | undefined; supportsReasoningParams?: boolean | undefined; supportsReasoningSummary?: boolean | undefined; supportsSteering?: boolean | undefined; supportsStore?: boolean | undefined; supportsStrictMode?: boolean | undefined; supportsToolChoice?: boolean | undefined; supportsUsageInStreaming?: boolean | undefined; thinkingFormat?: "openai" | "openrouter" | "qwen" | "qwen-chat-template" | "zai" | undefined; toolStrictMode?: "all_strict" | "none" | undefined; vercelGatewayRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; whenThinking?: { allowAnthropicHeaderOverrides?: boolean | undefined; allowsSyntheticReasoningContentForToolCalls?: boolean | undefined; alwaysSendMaxTokens?: boolean | undefined; bedrockMessagesApi?: boolean | undefined; cacheControlFormat?: "anthropic" | undefined; disableReasoningOnForcedToolChoice?: boolean | undefined; disableReasoningOnToolChoice?: boolean | undefined; disableReasoningWithTools?: boolean | undefined; extraBody?: Record | undefined; maxTokensField?: "max_completion_tokens" | "max_tokens" | undefined; openRouterRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; qwenTemplateReasoningEffort?: boolean | undefined; reasoningContentField?: "reasoning" | "reasoning_content" | "reasoning_text" | undefined; reasoningEffortMap?: { high?: string | undefined; low?: string | undefined; max?: string | undefined; medium?: string | undefined; minimal?: string | undefined; xhigh?: string | undefined; } | undefined; replayUnsignedThinking?: boolean | undefined; requiresAssistantAfterToolResult?: boolean | undefined; requiresAssistantContentForToolCalls?: boolean | undefined; requiresMistralToolIds?: boolean | undefined; requiresReasoningContentForToolCalls?: boolean | undefined; requiresThinkingAsText?: boolean | undefined; requiresThinkingPresence?: boolean | undefined; requiresToolResultId?: boolean | undefined; requiresToolResultName?: boolean | undefined; statefulResponses?: boolean | undefined; streamIdleTimeoutMs?: number | undefined; streamMarkupHealingPattern?: "dsml" | "kimi" | "qwen" | "thinking" | undefined; strictResponsesPairing?: boolean | undefined; stripImageInput?: boolean | undefined; supportsConfigurationUpdate?: boolean | undefined; supportsContextManagement?: boolean | undefined; supportsDeveloperRole?: boolean | undefined; supportsEagerToolInputStreaming?: boolean | undefined; supportsForcedToolChoice?: boolean | undefined; supportsImageDetailOriginal?: boolean | undefined; supportsLongPromptCacheRetention?: boolean | undefined; supportsMultipleSystemMessages?: boolean | undefined; supportsReasoningEffort?: boolean | undefined; supportsReasoningParams?: boolean | undefined; supportsReasoningSummary?: boolean | undefined; supportsSteering?: boolean | undefined; supportsStore?: boolean | undefined; supportsStrictMode?: boolean | undefined; supportsToolChoice?: boolean | undefined; supportsUsageInStreaming?: boolean | undefined; thinkingFormat?: "openai" | "openrouter" | "qwen" | "qwen-chat-template" | "zai" | undefined; toolStrictMode?: "all_strict" | "none" | undefined; vercelGatewayRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; } | undefined; } & { promptCacheMaximumCheckpoints?: number | undefined; promptCacheMinimumTokens?: number | undefined; promptCacheMode?: "automatic" | "explicit" | "none" | undefined; supportsLongPromptCacheRetention?: boolean | undefined; supportsThinkingBindingControls?: boolean | undefined; }) | undefined; contextPromotionTarget?: string | undefined; contextWindow?: number | undefined; cost?: { cacheRead?: number | undefined; cacheWrite?: number | undefined; input?: number | undefined; output?: number | undefined; } | undefined; headers?: Record | undefined; imageCountBudget?: number | undefined; imageInputDecoder?: "stb" | undefined; input?: ("image" | "text")[] | undefined; kind?: "chat" | "embedding" | "image" | "judge" | "rerank" | "stt" | "tiny" | "tts" | "video" | undefined; maxContextWindow?: number | undefined; maxTokens?: number | undefined; name?: string | undefined; omitMaxOutputTokens?: boolean | undefined; preferWebsockets?: boolean | undefined; premiumMultiplier?: number | undefined; promptCache?: { long?: number | undefined; short?: number | undefined; } | undefined; reasoning?: boolean | undefined; remoteCompaction?: { api?: "anthropic-messages" | "azure-openai-responses" | "bedrock-converse-stream" | "google-gemini-cli" | "google-generative-ai" | "google-vertex" | "openai-codex-responses" | "openai-completions" | "openai-decisions" | "openai-responses" | "openrouter-decisions" | "typesafe" | "workers-ai-systemone" | undefined; enabled?: boolean | undefined; endpoint?: string | undefined; model?: string | undefined; streamingEndpoint?: string | undefined; v2Endpoint?: string | undefined; v2StreamingEnabled?: boolean | undefined; } | undefined; supportsTools?: boolean | undefined; thinking?: { mode: any; efforts: any; defaultLevel?: any; effortMap?: any; supportsDisplay?: any; requiresEffort?: any; } | undefined; tokenizer?: "cl100k" | "claude-v3" | "claude-v47" | "claude-v5" | "claude-v5-sonnet" | "deepseek-v3" | "glm5" | "kimi-k2" | "o200k" | "qwen3" | undefined; }> | undefined; models?: { api?: string | undefined; baseUrl?: string | undefined; compactionModel?: string | undefined; compat?: ({ allowAnthropicHeaderOverrides?: boolean | undefined; allowsSyntheticReasoningContentForToolCalls?: boolean | undefined; alwaysSendMaxTokens?: boolean | undefined; bedrockMessagesApi?: boolean | undefined; cacheControlFormat?: "anthropic" | undefined; disableReasoningOnForcedToolChoice?: boolean | undefined; disableReasoningOnToolChoice?: boolean | undefined; disableReasoningWithTools?: boolean | undefined; extraBody?: Record | undefined; maxTokensField?: "max_completion_tokens" | "max_tokens" | undefined; openRouterRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; qwenTemplateReasoningEffort?: boolean | undefined; reasoningContentField?: "reasoning" | "reasoning_content" | "reasoning_text" | undefined; reasoningEffortMap?: { high?: string | undefined; low?: string | undefined; max?: string | undefined; medium?: string | undefined; minimal?: string | undefined; xhigh?: string | undefined; } | undefined; replayUnsignedThinking?: boolean | undefined; requiresAssistantAfterToolResult?: boolean | undefined; requiresAssistantContentForToolCalls?: boolean | undefined; requiresMistralToolIds?: boolean | undefined; requiresReasoningContentForToolCalls?: boolean | undefined; requiresThinkingAsText?: boolean | undefined; requiresThinkingPresence?: boolean | undefined; requiresToolResultId?: boolean | undefined; requiresToolResultName?: boolean | undefined; statefulResponses?: boolean | undefined; streamIdleTimeoutMs?: number | undefined; streamMarkupHealingPattern?: "dsml" | "kimi" | "qwen" | "thinking" | undefined; strictResponsesPairing?: boolean | undefined; stripImageInput?: boolean | undefined; supportsConfigurationUpdate?: boolean | undefined; supportsContextManagement?: boolean | undefined; supportsDeveloperRole?: boolean | undefined; supportsEagerToolInputStreaming?: boolean | undefined; supportsForcedToolChoice?: boolean | undefined; supportsImageDetailOriginal?: boolean | undefined; supportsLongPromptCacheRetention?: boolean | undefined; supportsMultipleSystemMessages?: boolean | undefined; supportsReasoningEffort?: boolean | undefined; supportsReasoningParams?: boolean | undefined; supportsReasoningSummary?: boolean | undefined; supportsSteering?: boolean | undefined; supportsStore?: boolean | undefined; supportsStrictMode?: boolean | undefined; supportsToolChoice?: boolean | undefined; supportsUsageInStreaming?: boolean | undefined; thinkingFormat?: "openai" | "openrouter" | "qwen" | "qwen-chat-template" | "zai" | undefined; toolStrictMode?: "all_strict" | "none" | undefined; vercelGatewayRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; whenThinking?: { allowAnthropicHeaderOverrides?: boolean | undefined; allowsSyntheticReasoningContentForToolCalls?: boolean | undefined; alwaysSendMaxTokens?: boolean | undefined; bedrockMessagesApi?: boolean | undefined; cacheControlFormat?: "anthropic" | undefined; disableReasoningOnForcedToolChoice?: boolean | undefined; disableReasoningOnToolChoice?: boolean | undefined; disableReasoningWithTools?: boolean | undefined; extraBody?: Record | undefined; maxTokensField?: "max_completion_tokens" | "max_tokens" | undefined; openRouterRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; qwenTemplateReasoningEffort?: boolean | undefined; reasoningContentField?: "reasoning" | "reasoning_content" | "reasoning_text" | undefined; reasoningEffortMap?: { high?: string | undefined; low?: string | undefined; max?: string | undefined; medium?: string | undefined; minimal?: string | undefined; xhigh?: string | undefined; } | undefined; replayUnsignedThinking?: boolean | undefined; requiresAssistantAfterToolResult?: boolean | undefined; requiresAssistantContentForToolCalls?: boolean | undefined; requiresMistralToolIds?: boolean | undefined; requiresReasoningContentForToolCalls?: boolean | undefined; requiresThinkingAsText?: boolean | undefined; requiresThinkingPresence?: boolean | undefined; requiresToolResultId?: boolean | undefined; requiresToolResultName?: boolean | undefined; statefulResponses?: boolean | undefined; streamIdleTimeoutMs?: number | undefined; streamMarkupHealingPattern?: "dsml" | "kimi" | "qwen" | "thinking" | undefined; strictResponsesPairing?: boolean | undefined; stripImageInput?: boolean | undefined; supportsConfigurationUpdate?: boolean | undefined; supportsContextManagement?: boolean | undefined; supportsDeveloperRole?: boolean | undefined; supportsEagerToolInputStreaming?: boolean | undefined; supportsForcedToolChoice?: boolean | undefined; supportsImageDetailOriginal?: boolean | undefined; supportsLongPromptCacheRetention?: boolean | undefined; supportsMultipleSystemMessages?: boolean | undefined; supportsReasoningEffort?: boolean | undefined; supportsReasoningParams?: boolean | undefined; supportsReasoningSummary?: boolean | undefined; supportsSteering?: boolean | undefined; supportsStore?: boolean | undefined; supportsStrictMode?: boolean | undefined; supportsToolChoice?: boolean | undefined; supportsUsageInStreaming?: boolean | undefined; thinkingFormat?: "openai" | "openrouter" | "qwen" | "qwen-chat-template" | "zai" | undefined; toolStrictMode?: "all_strict" | "none" | undefined; vercelGatewayRouting?: { only?: string[] | undefined; order?: string[] | undefined; } | undefined; } | undefined; } & { promptCacheMaximumCheckpoints?: number | undefined; promptCacheMinimumTokens?: number | undefined; promptCacheMode?: "automatic" | "explicit" | "none" | undefined; supportsLongPromptCacheRetention?: boolean | undefined; supportsThinkingBindingControls?: boolean | undefined; }) | undefined; contextPromotionTarget?: string | undefined; contextWindow?: number | undefined; cost?: { cacheRead: number; cacheWrite: number; input: number; output: number; } | undefined; headers?: Record | undefined; id: string; imageCountBudget?: number | undefined; imageInputDecoder?: "stb" | undefined; input?: ("image" | "text")[] | undefined; kind?: "chat" | "embedding" | "image" | "judge" | "rerank" | "stt" | "tiny" | "tts" | "video" | undefined; maxContextWindow?: number | undefined; maxTokens?: number | undefined; name?: string | undefined; omitMaxOutputTokens?: boolean | undefined; preferWebsockets?: boolean | undefined; premiumMultiplier?: number | undefined; promptCache?: { long?: number | undefined; short?: number | undefined; } | undefined; reasoning?: boolean | undefined; remoteCompaction?: { api?: "anthropic-messages" | "azure-openai-responses" | "bedrock-converse-stream" | "google-gemini-cli" | "google-generative-ai" | "google-vertex" | "openai-codex-responses" | "openai-completions" | "openai-decisions" | "openai-responses" | "openrouter-decisions" | "typesafe" | "workers-ai-systemone" | undefined; enabled?: boolean | undefined; endpoint?: string | undefined; model?: string | undefined; streamingEndpoint?: string | undefined; v2Endpoint?: string | undefined; v2StreamingEnabled?: boolean | undefined; } | undefined; supportsTools?: boolean | undefined; thinking?: { mode: any; efforts: any; defaultLevel?: any; effortMap?: any; supportsDisplay?: any; requiresEffort?: any; } | undefined; tokenizer?: "cl100k" | "claude-v3" | "claude-v47" | "claude-v5" | "claude-v5-sonnet" | "deepseek-v3" | "glm5" | "kimi-k2" | "o200k" | "qwen3" | undefined; }[] | undefined; remoteCompaction?: { api?: "anthropic-messages" | "azure-openai-responses" | "bedrock-converse-stream" | "google-gemini-cli" | "google-generative-ai" | "google-vertex" | "openai-codex-responses" | "openai-completions" | "openai-decisions" | "openai-responses" | "openrouter-decisions" | "typesafe" | "workers-ai-systemone" | undefined; enabled?: boolean | undefined; endpoint?: string | undefined; model?: string | undefined; streamingEndpoint?: string | undefined; v2Endpoint?: string | undefined; v2StreamingEnabled?: boolean | undefined; } | undefined; requestMetadata?: Record | undefined; transport?: "pi-native" | undefined; }> | undefined; }>;