feat: 自定义 OpenAI 兼容上游聚合 + 权重/并发调度
- custom provider:把任意 v1 端点当账号(base_url+key),按 model id 路由, 直连不走代理;支持 images/generations、images/edits、Sora 式异步视频 - 调度器全局权重优先 + 每账号并发感知(上游账号可配并发,其余系统固定) - 后台:添加/编辑上游、自定义模型表单(每档普通/代理价,留空=不支持)、 账号权重/并发列与导入权重 - grok-video / nano-banana-2(runway) 写入硬编码目录(开源自带); 去掉 540p,Adobe 视频最低 720p - UI:SelectMenu 与输入框等高、测试耗时改用秒 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -290,29 +290,29 @@ func parseCreditsConfig(buf []byte) (remaining int, resetUnix string, ok bool) {
|
||||
return 0, "", false
|
||||
}
|
||||
|
||||
func scanConfigMessage(msg []byte) (remaining int, resetUnix string, ok bool) {
|
||||
var remF float32
|
||||
haveRem := false
|
||||
func scanConfigMessage(msg []byte) (used int, resetUnix string, ok bool) {
|
||||
var usedF float32
|
||||
seen := false
|
||||
for len(msg) > 0 {
|
||||
fn, wt, val, rest, good := readField(msg)
|
||||
if !good {
|
||||
break
|
||||
}
|
||||
msg = rest
|
||||
seen = true
|
||||
switch {
|
||||
case fn == 1 && wt == 5: // float32 remaining credits
|
||||
remF = float32FromLE(val)
|
||||
haveRem = true
|
||||
case fn == 1 && wt == 5: // float32 credits USED this period
|
||||
usedF = float32FromLE(val)
|
||||
case fn == 5 && wt == 2: // reset timestamp message { #1 varint=seconds }
|
||||
if sec, sok := firstVarint(val); sok {
|
||||
resetUnix = strconv.FormatInt(sec, 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
if haveRem {
|
||||
return int(remF), resetUnix, true
|
||||
}
|
||||
return 0, resetUnix, false
|
||||
// A valid config message may OMIT field #1 when used == 0 (proto3 drops zero
|
||||
// scalars) — a full-quota account. So as long as the message had any field,
|
||||
// treat it as parsed with used defaulting to 0 (= 100 remaining).
|
||||
return int(usedF), resetUnix, seen
|
||||
}
|
||||
|
||||
// readField reads one protobuf field: returns (fieldNum, wireType, value, rest, ok).
|
||||
|
||||
Reference in New Issue
Block a user