mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-25 14:53:32 +08:00
fix(server): include configured role models (#1024)
This commit is contained in:
parent
e2e164da69
commit
b7f1dd6d80
@ -48,6 +48,7 @@ let originalAnthropicModel: string | undefined
|
|||||||
let originalAnthropicDefaultHaikuModel: string | undefined
|
let originalAnthropicDefaultHaikuModel: string | undefined
|
||||||
let originalAnthropicDefaultSonnetModel: string | undefined
|
let originalAnthropicDefaultSonnetModel: string | undefined
|
||||||
let originalAnthropicDefaultOpusModel: string | undefined
|
let originalAnthropicDefaultOpusModel: string | undefined
|
||||||
|
let originalAnthropicDefaultFableModel: string | undefined
|
||||||
|
|
||||||
async function setup() {
|
async function setup() {
|
||||||
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'claude-test-'))
|
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'claude-test-'))
|
||||||
@ -66,6 +67,7 @@ async function setup() {
|
|||||||
originalAnthropicDefaultHaikuModel = process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL
|
originalAnthropicDefaultHaikuModel = process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL
|
||||||
originalAnthropicDefaultSonnetModel = process.env.ANTHROPIC_DEFAULT_SONNET_MODEL
|
originalAnthropicDefaultSonnetModel = process.env.ANTHROPIC_DEFAULT_SONNET_MODEL
|
||||||
originalAnthropicDefaultOpusModel = process.env.ANTHROPIC_DEFAULT_OPUS_MODEL
|
originalAnthropicDefaultOpusModel = process.env.ANTHROPIC_DEFAULT_OPUS_MODEL
|
||||||
|
originalAnthropicDefaultFableModel = process.env.ANTHROPIC_DEFAULT_FABLE_MODEL
|
||||||
process.env.CLAUDE_CONFIG_DIR = tmpDir
|
process.env.CLAUDE_CONFIG_DIR = tmpDir
|
||||||
process.env.HOME = tmpDir
|
process.env.HOME = tmpDir
|
||||||
process.env.USERPROFILE = tmpDir
|
process.env.USERPROFILE = tmpDir
|
||||||
@ -77,6 +79,7 @@ async function setup() {
|
|||||||
delete process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL
|
delete process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL
|
||||||
delete process.env.ANTHROPIC_DEFAULT_SONNET_MODEL
|
delete process.env.ANTHROPIC_DEFAULT_SONNET_MODEL
|
||||||
delete process.env.ANTHROPIC_DEFAULT_OPUS_MODEL
|
delete process.env.ANTHROPIC_DEFAULT_OPUS_MODEL
|
||||||
|
delete process.env.ANTHROPIC_DEFAULT_FABLE_MODEL
|
||||||
clearKeychainCache()
|
clearKeychainCache()
|
||||||
primeKeychainCacheFromPrefetch(null)
|
primeKeychainCacheFromPrefetch(null)
|
||||||
clearOpenAIOAuthTokenCache()
|
clearOpenAIOAuthTokenCache()
|
||||||
@ -162,6 +165,12 @@ async function teardown() {
|
|||||||
delete process.env.ANTHROPIC_DEFAULT_OPUS_MODEL
|
delete process.env.ANTHROPIC_DEFAULT_OPUS_MODEL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (originalAnthropicDefaultFableModel !== undefined) {
|
||||||
|
process.env.ANTHROPIC_DEFAULT_FABLE_MODEL = originalAnthropicDefaultFableModel
|
||||||
|
} else {
|
||||||
|
delete process.env.ANTHROPIC_DEFAULT_FABLE_MODEL
|
||||||
|
}
|
||||||
|
|
||||||
await fs.rm(tmpDir, { recursive: true, force: true })
|
await fs.rm(tmpDir, { recursive: true, force: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,6 +685,31 @@ describe('Models API', () => {
|
|||||||
expect(ids.filter((id: string) => id === 'deepseek-v4-pro')).toHaveLength(1)
|
expect(ids.filter((id: string) => id === 'deepseek-v4-pro')).toHaveLength(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('GET /api/models should merge user settings model roles with runtime env and include Fable', async () => {
|
||||||
|
await new SettingsService().updateUserSettings({
|
||||||
|
env: {
|
||||||
|
ANTHROPIC_MODEL: 'claude-opus-4-8',
|
||||||
|
ANTHROPIC_DEFAULT_HAIKU_MODEL: 'claude-haiku-4-5-20251001',
|
||||||
|
ANTHROPIC_DEFAULT_SONNET_MODEL: 'claude-sonnet-4-6',
|
||||||
|
ANTHROPIC_DEFAULT_OPUS_MODEL: 'claude-opus-4-8',
|
||||||
|
ANTHROPIC_DEFAULT_FABLE_MODEL: 'claude-fable-5',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
process.env.ANTHROPIC_MODEL = 'claude-opus-4-8'
|
||||||
|
|
||||||
|
const { req, url, segments } = makeRequest('GET', '/api/models')
|
||||||
|
const res = await handleModelsApi(req, url, segments)
|
||||||
|
|
||||||
|
expect(res.status).toBe(200)
|
||||||
|
const body = await res.json()
|
||||||
|
expect(body.models.map((model: { id: string }) => model.id)).toEqual([
|
||||||
|
'claude-opus-4-8',
|
||||||
|
'claude-haiku-4-5-20251001',
|
||||||
|
'claude-sonnet-4-6',
|
||||||
|
'claude-fable-5',
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
it('GET /api/models/current should return default model when not set', async () => {
|
it('GET /api/models/current should return default model when not set', async () => {
|
||||||
const { req, url, segments } = makeRequest('GET', '/api/models/current')
|
const { req, url, segments } = makeRequest('GET', '/api/models/current')
|
||||||
const res = await handleModelsApi(req, url, segments)
|
const res = await handleModelsApi(req, url, segments)
|
||||||
|
|||||||
@ -95,6 +95,7 @@ function buildProviderModelList(models: {
|
|||||||
haiku: string
|
haiku: string
|
||||||
sonnet: string
|
sonnet: string
|
||||||
opus: string
|
opus: string
|
||||||
|
fable?: string
|
||||||
}): ApiModelInfo[] {
|
}): ApiModelInfo[] {
|
||||||
const modelList: ApiModelInfo[] = []
|
const modelList: ApiModelInfo[] = []
|
||||||
|
|
||||||
@ -128,6 +129,14 @@ function buildProviderModelList(models: {
|
|||||||
context: '',
|
context: '',
|
||||||
}
|
}
|
||||||
: null)
|
: null)
|
||||||
|
addUniqueModel(modelList, models.fable
|
||||||
|
? {
|
||||||
|
id: models.fable,
|
||||||
|
name: models.fable,
|
||||||
|
description: 'Fable model',
|
||||||
|
context: '',
|
||||||
|
}
|
||||||
|
: null)
|
||||||
|
|
||||||
return modelList
|
return modelList
|
||||||
}
|
}
|
||||||
@ -170,12 +179,20 @@ async function getGrokModelList(): Promise<ApiModelInfo[]> {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEnvConfiguredAnthropicModels(): ApiModelInfo[] {
|
function getConfiguredAnthropicModels(settingsEnv: Record<string, unknown>): ApiModelInfo[] {
|
||||||
|
const resolveModel = (key: string): string => {
|
||||||
|
const runtimeValue = process.env[key]?.trim()
|
||||||
|
if (runtimeValue) return runtimeValue
|
||||||
|
const settingsValue = settingsEnv[key]
|
||||||
|
return typeof settingsValue === 'string' ? settingsValue.trim() : ''
|
||||||
|
}
|
||||||
|
|
||||||
return buildProviderModelList({
|
return buildProviderModelList({
|
||||||
main: process.env.ANTHROPIC_MODEL?.trim() || '',
|
main: resolveModel('ANTHROPIC_MODEL'),
|
||||||
haiku: process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL?.trim() || '',
|
haiku: resolveModel('ANTHROPIC_DEFAULT_HAIKU_MODEL'),
|
||||||
sonnet: process.env.ANTHROPIC_DEFAULT_SONNET_MODEL?.trim() || '',
|
sonnet: resolveModel('ANTHROPIC_DEFAULT_SONNET_MODEL'),
|
||||||
opus: process.env.ANTHROPIC_DEFAULT_OPUS_MODEL?.trim() || '',
|
opus: resolveModel('ANTHROPIC_DEFAULT_OPUS_MODEL'),
|
||||||
|
fable: resolveModel('ANTHROPIC_DEFAULT_FABLE_MODEL'),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +205,11 @@ async function getOpenAIAuthModels(): Promise<ApiModelInfo[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getStandaloneModelList(): Promise<ApiModelInfo[]> {
|
async function getStandaloneModelList(): Promise<ApiModelInfo[]> {
|
||||||
const models = [...getEnvConfiguredAnthropicModels()]
|
const settings = await settingsService.getUserSettings()
|
||||||
|
const settingsEnv = settings.env && typeof settings.env === 'object' && !Array.isArray(settings.env)
|
||||||
|
? settings.env as Record<string, unknown>
|
||||||
|
: {}
|
||||||
|
const models = [...getConfiguredAnthropicModels(settingsEnv)]
|
||||||
|
|
||||||
if (models.length === 0) {
|
if (models.length === 0) {
|
||||||
models.push(...DEFAULT_MODELS)
|
models.push(...DEFAULT_MODELS)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user