mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-07-03 14:09:06 +02:00
c7b824f9ab
Signed-off-by: Daniel <845765@qq.com>
93 lines
2.8 KiB
Go
93 lines
2.8 KiB
Go
// SiYuan - Refactor your thinking
|
|
// Copyright (c) 2020-present, b3log.org
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package agent
|
|
|
|
import (
|
|
"embed"
|
|
"encoding/json"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
//go:embed models.json
|
|
var modelsJSON embed.FS
|
|
|
|
// modelMetaEntry 对应 models.json 中单个模型的值对象,目前仅含 contextLength。
|
|
type modelMetaEntry struct {
|
|
ContextLength int `json:"contextLength"`
|
|
}
|
|
|
|
var (
|
|
modelContextOnce sync.Once
|
|
modelContextLimit map[string]int
|
|
)
|
|
|
|
// loadModelContext 惰性解析嵌入的 models.json,构建「模型名 → 上下文窗口」映射。
|
|
// models.json 顶层含一个保留的 _meta 元数据对象,解析时跳过它(其值结构与模型条目不同)。
|
|
func loadModelContext() map[string]int {
|
|
modelContextOnce.Do(func() {
|
|
raw, err := modelsJSON.ReadFile("models.json")
|
|
if err != nil {
|
|
return
|
|
}
|
|
var decoded map[string]json.RawMessage
|
|
if err := json.Unmarshal(raw, &decoded); err != nil {
|
|
return
|
|
}
|
|
result := make(map[string]int, len(decoded))
|
|
for name, value := range decoded {
|
|
if name == "_meta" {
|
|
continue
|
|
}
|
|
var entry modelMetaEntry
|
|
if err := json.Unmarshal(value, &entry); err != nil {
|
|
continue
|
|
}
|
|
if entry.ContextLength > 0 {
|
|
// key 转小写存储,使匹配大小写不敏感(用户填写 Baichuan4-Turbo / baichuan4-turbo 均可命中)。
|
|
result[strings.ToLower(name)] = entry.ContextLength
|
|
}
|
|
}
|
|
modelContextLimit = result
|
|
})
|
|
return modelContextLimit
|
|
}
|
|
|
|
// GetModelContextLimit 返回模型的上下文窗口大小(单位:token)。未知模型返回 0。
|
|
// 匹配大小写不敏感(表 key 与查询参数均转小写)。
|
|
// 匹配顺序:先按完整模型名精确查找;再按「末段」(去掉 provider 前缀)查找,
|
|
// 兼容用户填写带前缀的 id(如 z-ai/glm-4.6)。表本身以末段为 key,故末段匹配即直接命中。
|
|
func GetModelContextLimit(model string) int {
|
|
if model == "" {
|
|
return 0
|
|
}
|
|
table := loadModelContext()
|
|
if table == nil {
|
|
return 0
|
|
}
|
|
lower := strings.ToLower(model)
|
|
if limit, ok := table[lower]; ok {
|
|
return limit
|
|
}
|
|
if idx := strings.LastIndexByte(lower, '/'); idx >= 0 {
|
|
if limit, ok := table[lower[idx+1:]]; ok {
|
|
return limit
|
|
}
|
|
}
|
|
return 0
|
|
}
|