feat: Add database table for model context length configuration (#477)

* feat: add database table for model context length configuration

- Add model_context table with provider/model/context_limit fields
- Implement UPSERT endpoint for model context configuration
- Add priority lookup: database > config.yaml > custom_providers > cache
- Add frontend click-to-edit UI in ChatInput with tooltip
- Add i18n support for context editing dialog (all 8 locales)
- Use context_limit field consistently across frontend and backend

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: use useMessage() composable instead of window.$message in ChatInput

- Remove incorrect NMessage import (not a component)
- Use useMessage() composable from naive-ui
- Replace window.$message?.xxx() with message.xxx()
- Fixes TypeScript build errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ekko
2026-05-06 15:05:44 +08:00
committed by GitHub
parent f338aeea18
commit 479e1feef6
14 changed files with 406 additions and 3 deletions
@@ -2,6 +2,8 @@ import { resolve, join } from 'path'
import { homedir } from 'os'
import { readFileSync, existsSync, statSync } from 'fs'
import yaml from 'js-yaml'
import { getDb } from '../../db'
import { MODEL_CONTEXT_TABLE } from '../../db/hermes/schemas'
const HERMES_BASE = resolve(homedir(), '.hermes')
const MODELS_DEV_CACHE = resolve(HERMES_BASE, 'models_dev_cache.json')
@@ -234,6 +236,25 @@ function lookupContextFromCache(modelName: string, provider: string | null): num
* 3. models_dev_cache.json, scoped to model.provider when configured
* 4. DEFAULT_CONTEXT_LENGTH (200K hardcoded fallback)
*/
/**
* 从数据库 model_context 表查找上下文长度(最高优先级)
*/
function lookupContextFromDatabase(modelName: string, provider: string | null): number | null {
const db = getDb()
if (!db) return null
try {
// 尝试精确匹配 provider 和 model
const row = db
.prepare(`SELECT context_limit FROM ${MODEL_CONTEXT_TABLE} WHERE provider = ? AND model = ?`)
.get(provider || 'default', modelName) as { context_limit: number } | undefined
return row?.context_limit || null
} catch {
return null
}
}
export function getModelContextLength(profile?: string): number {
const profileDir = getProfileDir(profile)
const config = loadConfig(profileDir)
@@ -242,12 +263,17 @@ export function getModelContextLength(profile?: string): number {
const model = getDefaultModel(config)
if (!model) return DEFAULT_CONTEXT_LENGTH
const provider = getDefaultProvider(config)
// 0. Database model_context table (highest priority)
const dbCtx = lookupContextFromDatabase(model, provider)
if (dbCtx && dbCtx > 0) return dbCtx
// 1. Global context_length override in config.yaml
const configCtx = getConfigContextLength(config)
if (configCtx && configCtx > 0) return configCtx
// 2. Custom provider context_length
const provider = getDefaultProvider(config)
const customCtx = lookupCustomProviderContextLength(config, model, provider)
if (customCtx && customCtx > 0) return customCtx