| 91 | * a final guard against patch round-trips (getConfig -> setConfig). |
| 92 | */ |
| 93 | export function applyEnvModelConfig(config: KimiConfig, env: Env = process.env): KimiConfig { |
| 94 | const model = trimmed(env['KIMI_MODEL_NAME']); |
| 95 | if (model === undefined) return config; |
| 96 | |
| 97 | const apiKey = trimmed(env['KIMI_MODEL_API_KEY']); |
| 98 | if (apiKey === undefined) { |
| 99 | fail('KIMI_MODEL_NAME is set but KIMI_MODEL_API_KEY is missing.'); |
| 100 | } |
| 101 | |
| 102 | const maxContextRaw = trimmed(env['KIMI_MODEL_MAX_CONTEXT_SIZE']); |
| 103 | const maxContextSize = |
| 104 | maxContextRaw === undefined |
| 105 | ? DEFAULT_MAX_CONTEXT_SIZE |
| 106 | : parsePositiveInt(maxContextRaw, 'KIMI_MODEL_MAX_CONTEXT_SIZE'); |
| 107 | |
| 108 | const type = parseProviderType(trimmed(env['KIMI_MODEL_PROVIDER_TYPE'])); |
| 109 | const baseUrl = trimmed(env['KIMI_MODEL_BASE_URL']) ?? DEFAULT_BASE_URL[type]; |
| 110 | |
| 111 | const provider: ProviderConfig = { |
| 112 | type, |
| 113 | apiKey, |
| 114 | ...(baseUrl !== undefined ? { baseUrl } : {}), |
| 115 | }; |
| 116 | |
| 117 | const maxOutputRaw = trimmed(env['KIMI_MODEL_MAX_OUTPUT_SIZE']); |
| 118 | const maxOutputSize = |
| 119 | maxOutputRaw !== undefined |
| 120 | ? parsePositiveInt(maxOutputRaw, 'KIMI_MODEL_MAX_OUTPUT_SIZE') |
| 121 | : undefined; |
| 122 | const capabilities = parseCapabilities(env['KIMI_MODEL_CAPABILITIES']) ?? DEFAULT_CAPABILITIES; |
| 123 | const displayName = trimmed(env['KIMI_MODEL_DISPLAY_NAME']); |
| 124 | const reasoningKey = trimmed(env['KIMI_MODEL_REASONING_KEY']); |
| 125 | const adaptiveThinking = parseBooleanVar( |
| 126 | env['KIMI_MODEL_ADAPTIVE_THINKING'], |
| 127 | 'KIMI_MODEL_ADAPTIVE_THINKING', |
| 128 | ); |
| 129 | |
| 130 | const alias: ModelAlias = { |
| 131 | provider: ENV_MODEL_PROVIDER_KEY, |
| 132 | model, |
| 133 | maxContextSize, |
| 134 | capabilities, |
| 135 | ...(displayName !== undefined ? { displayName } : {}), |
| 136 | ...(maxOutputSize !== undefined ? { maxOutputSize } : {}), |
| 137 | ...(reasoningKey !== undefined ? { reasoningKey } : {}), |
| 138 | ...(adaptiveThinking !== undefined ? { adaptiveThinking } : {}), |
| 139 | }; |
| 140 | |
| 141 | const thinkingEffort = trimmed(env['KIMI_MODEL_THINKING_EFFORT']); |
| 142 | const thinking: ThinkingConfig | undefined = |
| 143 | thinkingEffort !== undefined ? { ...config.thinking, effort: thinkingEffort } : config.thinking; |
| 144 | |
| 145 | const merged: KimiConfig = { |
| 146 | ...config, |
| 147 | providers: { ...config.providers, [ENV_MODEL_PROVIDER_KEY]: provider }, |
| 148 | models: { ...config.models, [ENV_MODEL_ALIAS_KEY]: alias }, |
| 149 | defaultModel: ENV_MODEL_ALIAS_KEY, |
| 150 | ...(thinking !== undefined ? { thinking } : {}), |