fix: use 1m fallback for unknown model context
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
---
|
||||
date: 2026-11-05
|
||||
pr: pending
|
||||
feature: Unknown model context fallback
|
||||
impact: When no model context length can be resolved, the Web UI estimates it as 1000000 tokens instead of 256000. Explicit settings and model metadata retain priority.
|
||||
---
|
||||
|
||||
This estimate also affects Web UI compression thresholds for models with no
|
||||
known context length. It does not change the model provider's actual limit.
|
||||
@@ -1415,7 +1415,7 @@ export default {
|
||||
customType: 'Custom',
|
||||
provider: 'Provider',
|
||||
contextLength: 'Context Length',
|
||||
contextLengthPlaceholder: 'e.g. 256000 (optional)',
|
||||
contextLengthPlaceholder: 'Optional; estimated as 1000000 when unknown',
|
||||
apiMode: 'API Mode',
|
||||
local: 'Local ({host})',
|
||||
selectProviderRequired: 'Please select a provider',
|
||||
|
||||
@@ -1415,7 +1415,7 @@ export default {
|
||||
customType: '自定义',
|
||||
provider: 'Provider',
|
||||
contextLength: '上下文长度',
|
||||
contextLengthPlaceholder: '例如 256000(可选)',
|
||||
contextLengthPlaceholder: '可选;未知时按 1000000 估算',
|
||||
apiMode: 'API 模式',
|
||||
local: '本地 ({host})',
|
||||
selectProviderRequired: '请选择 Provider',
|
||||
|
||||
@@ -9,7 +9,7 @@ import { getCompatibleCustomProviders } from './custom-providers-compat'
|
||||
|
||||
const HERMES_BASE = detectHermesHome()
|
||||
const MODELS_DEV_CACHE = resolve(HERMES_BASE, 'models_dev_cache.json')
|
||||
const DEFAULT_CONTEXT_LENGTH = 256_000
|
||||
const DEFAULT_CONTEXT_LENGTH = 1_000_000
|
||||
|
||||
export interface ModelContextLengthOptions {
|
||||
profile?: string
|
||||
|
||||
@@ -59,6 +59,11 @@ describe('getModelContextLength', () => {
|
||||
homeDir = ''
|
||||
})
|
||||
|
||||
it('uses one million tokens when no model context is available', async () => {
|
||||
const { getModelContextLength } = await loadModelContext()
|
||||
expect(getModelContextLength()).toBe(1_000_000)
|
||||
})
|
||||
|
||||
it('does not borrow a same-named model context from another provider when the configured provider is uncached', async () => {
|
||||
writeConfig(`model:\n default: gpt-5.5\n provider: openai-codex\n`)
|
||||
writeModelsCache({
|
||||
@@ -71,7 +76,7 @@ describe('getModelContextLength', () => {
|
||||
|
||||
const { getModelContextLength } = await loadModelContext()
|
||||
|
||||
expect(getModelContextLength()).toBe(256_000)
|
||||
expect(getModelContextLength()).toBe(1_000_000)
|
||||
})
|
||||
|
||||
it('does not scan other providers when the configured provider exists without that model', async () => {
|
||||
@@ -91,7 +96,7 @@ describe('getModelContextLength', () => {
|
||||
|
||||
const { getModelContextLength } = await loadModelContext()
|
||||
|
||||
expect(getModelContextLength()).toBe(256_000)
|
||||
expect(getModelContextLength()).toBe(1_000_000)
|
||||
})
|
||||
|
||||
it('uses the configured provider cache entry when the provider matches', async () => {
|
||||
@@ -250,14 +255,14 @@ describe('getModelContextLength', () => {
|
||||
writeModelsCache({
|
||||
deepseek: {
|
||||
models: {
|
||||
'deepseek-v4-pro': { limit: { context: 1_000_000 } },
|
||||
'deepseek-v4-pro': { limit: { context: 1_050_000 } },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const { getModelContextLength } = await loadModelContext()
|
||||
|
||||
expect(getModelContextLength()).toBe(256_000)
|
||||
expect(getModelContextLength()).toBe(1_000_000)
|
||||
})
|
||||
|
||||
it('does not trust custom:name alone when the matched custom provider entry points at an unknown proxy url', async () => {
|
||||
@@ -265,14 +270,14 @@ describe('getModelContextLength', () => {
|
||||
writeModelsCache({
|
||||
deepseek: {
|
||||
models: {
|
||||
'deepseek-v4-pro': { limit: { context: 1_000_000 } },
|
||||
'deepseek-v4-pro': { limit: { context: 1_050_000 } },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const { getModelContextLength } = await loadModelContext()
|
||||
|
||||
expect(getModelContextLength()).toBe(256_000)
|
||||
expect(getModelContextLength()).toBe(1_000_000)
|
||||
})
|
||||
|
||||
it('does not fall through to a unique global match after a resolved custom:name provider misses in its scoped cache provider', async () => {
|
||||
@@ -285,14 +290,14 @@ describe('getModelContextLength', () => {
|
||||
},
|
||||
deepseek: {
|
||||
models: {
|
||||
'deepseek-v4-pro': { limit: { context: 1_000_000 } },
|
||||
'deepseek-v4-pro': { limit: { context: 1_050_000 } },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const { getModelContextLength } = await loadModelContext()
|
||||
|
||||
expect(getModelContextLength()).toBe(256_000)
|
||||
expect(getModelContextLength()).toBe(1_000_000)
|
||||
})
|
||||
|
||||
it('allows a unique global model-name fallback for unresolved custom providers', async () => {
|
||||
@@ -330,14 +335,14 @@ describe('getModelContextLength', () => {
|
||||
writeModelsCache({
|
||||
vercel: {
|
||||
models: {
|
||||
'openai/gpt-5': { limit: { context: 1_000_000 } },
|
||||
'openai/gpt-5': { limit: { context: 1_050_000 } },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const { getModelContextLength } = await loadModelContext()
|
||||
|
||||
expect(getModelContextLength()).toBe(256_000)
|
||||
expect(getModelContextLength()).toBe(1_000_000)
|
||||
})
|
||||
|
||||
it('does not guess across multiple cache providers when a custom provider remains unresolved', async () => {
|
||||
@@ -345,7 +350,7 @@ describe('getModelContextLength', () => {
|
||||
writeModelsCache({
|
||||
deepseek: {
|
||||
models: {
|
||||
'shared-model': { limit: { context: 1_000_000 } },
|
||||
'shared-model': { limit: { context: 1_050_000 } },
|
||||
},
|
||||
},
|
||||
openai: {
|
||||
@@ -357,6 +362,6 @@ describe('getModelContextLength', () => {
|
||||
|
||||
const { getModelContextLength } = await loadModelContext()
|
||||
|
||||
expect(getModelContextLength()).toBe(256_000)
|
||||
expect(getModelContextLength()).toBe(1_000_000)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user