fix: harden provider recommendation safety
This commit is contained in:
123
src/utils/providerProfile.ts
Normal file
123
src/utils/providerProfile.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import {
|
||||
getGoalDefaultOpenAIModel,
|
||||
type RecommendationGoal,
|
||||
} from './providerRecommendation.ts'
|
||||
|
||||
export type ProviderProfile = 'openai' | 'ollama'
|
||||
|
||||
export type ProfileEnv = {
|
||||
OPENAI_BASE_URL?: string
|
||||
OPENAI_MODEL?: string
|
||||
OPENAI_API_KEY?: string
|
||||
}
|
||||
|
||||
export type ProfileFile = {
|
||||
profile: ProviderProfile
|
||||
env: ProfileEnv
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
export function sanitizeApiKey(
|
||||
key: string | null | undefined,
|
||||
): string | undefined {
|
||||
if (!key || key === 'SUA_CHAVE') return undefined
|
||||
return key
|
||||
}
|
||||
|
||||
export function buildOllamaProfileEnv(
|
||||
model: string,
|
||||
options: {
|
||||
baseUrl?: string | null
|
||||
getOllamaChatBaseUrl: (baseUrl?: string) => string
|
||||
},
|
||||
): ProfileEnv {
|
||||
return {
|
||||
OPENAI_BASE_URL: options.getOllamaChatBaseUrl(options.baseUrl ?? undefined),
|
||||
OPENAI_MODEL: model,
|
||||
}
|
||||
}
|
||||
|
||||
export function buildOpenAIProfileEnv(options: {
|
||||
goal: RecommendationGoal
|
||||
model?: string | null
|
||||
apiKey?: string | null
|
||||
processEnv?: NodeJS.ProcessEnv
|
||||
}): ProfileEnv | null {
|
||||
const processEnv = options.processEnv ?? process.env
|
||||
const key = sanitizeApiKey(options.apiKey ?? processEnv.OPENAI_API_KEY)
|
||||
if (!key) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
OPENAI_BASE_URL: processEnv.OPENAI_BASE_URL || 'https://api.openai.com/v1',
|
||||
OPENAI_MODEL: options.model || getGoalDefaultOpenAIModel(options.goal),
|
||||
OPENAI_API_KEY: key,
|
||||
}
|
||||
}
|
||||
|
||||
export function createProfileFile(
|
||||
profile: ProviderProfile,
|
||||
env: ProfileEnv,
|
||||
): ProfileFile {
|
||||
return {
|
||||
profile,
|
||||
env,
|
||||
createdAt: new Date().toISOString(),
|
||||
}
|
||||
}
|
||||
|
||||
export function selectAutoProfile(
|
||||
recommendedOllamaModel: string | null,
|
||||
): ProviderProfile {
|
||||
return recommendedOllamaModel ? 'ollama' : 'openai'
|
||||
}
|
||||
|
||||
export async function buildLaunchEnv(options: {
|
||||
profile: ProviderProfile
|
||||
persisted: ProfileFile | null
|
||||
goal: RecommendationGoal
|
||||
processEnv?: NodeJS.ProcessEnv
|
||||
getOllamaChatBaseUrl?: (baseUrl?: string) => string
|
||||
resolveOllamaDefaultModel?: (goal: RecommendationGoal) => Promise<string>
|
||||
}): Promise<NodeJS.ProcessEnv> {
|
||||
const processEnv = options.processEnv ?? process.env
|
||||
const persistedEnv =
|
||||
options.persisted?.profile === options.profile
|
||||
? options.persisted.env ?? {}
|
||||
: {}
|
||||
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...processEnv,
|
||||
CLAUDE_CODE_USE_OPENAI: '1',
|
||||
}
|
||||
|
||||
if (options.profile === 'ollama') {
|
||||
const getOllamaBaseUrl =
|
||||
options.getOllamaChatBaseUrl ?? (() => 'http://localhost:11434/v1')
|
||||
const resolveOllamaModel =
|
||||
options.resolveOllamaDefaultModel ?? (async () => 'llama3.1:8b')
|
||||
|
||||
env.OPENAI_BASE_URL = persistedEnv.OPENAI_BASE_URL || getOllamaBaseUrl()
|
||||
env.OPENAI_MODEL =
|
||||
persistedEnv.OPENAI_MODEL ||
|
||||
(await resolveOllamaModel(options.goal))
|
||||
|
||||
if (!processEnv.OPENAI_API_KEY || processEnv.OPENAI_API_KEY === 'SUA_CHAVE') {
|
||||
delete env.OPENAI_API_KEY
|
||||
}
|
||||
|
||||
return env
|
||||
}
|
||||
|
||||
env.OPENAI_BASE_URL =
|
||||
processEnv.OPENAI_BASE_URL ||
|
||||
persistedEnv.OPENAI_BASE_URL ||
|
||||
'https://api.openai.com/v1'
|
||||
env.OPENAI_MODEL =
|
||||
processEnv.OPENAI_MODEL ||
|
||||
persistedEnv.OPENAI_MODEL ||
|
||||
getGoalDefaultOpenAIModel(options.goal)
|
||||
env.OPENAI_API_KEY = processEnv.OPENAI_API_KEY || persistedEnv.OPENAI_API_KEY
|
||||
return env
|
||||
}
|
||||
Reference in New Issue
Block a user