fix: 三端联调测试 2 P0 + 6 P1 + 2 P2 修复
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

P0-1: SaaS relay 模型别名解析 — "glm-4-flash" → "glm-4-flash-250414" (resolve_model)
P0-2: config.rs interpolate_env_vars UTF-8 修复 (chars 迭代器替代 bytes as char)
      + DB 启动编码检查 + docker-compose UTF-8 编码参数

P1-3: UI 模型选择器覆盖 Agent 默认模型 (model_override 全链路: TS→Tauri→Rust kernel)
P1-6: 知识搜索管道修复 — seed_knowledge 创建 chunks + 默认分类 (seed/uploaded/distillation)
P1-7: 用量限额从当前 Plan 读取 (非 stale usage 表)
P1-8: relay 双维度配额检查 (relay_requests + input_tokens)

P2-9: SSE 路径 token 计数修复 — 流结束检测替代固定 500ms sleep + billing increment
This commit is contained in:
iven
2026-04-14 00:17:08 +08:00
parent 0903a0d652
commit 4c3136890b
13 changed files with 234 additions and 49 deletions

View File

@@ -465,22 +465,25 @@ impl SaaSConfig {
/// 替换 TOML 配置文件中的 `${ENV_VAR}` 模式为环境变量值
/// 未设置的环境变量保留原文,后续数据库连接或 JWT 初始化时会报明确错误
///
/// 注意: 使用 chars() 迭代器而非 bytes() 来正确处理多字节 UTF-8 字符(如中文),
/// 避免将多字节 UTF-8 序列的每个字节单独 `as char` 导致编码损坏。
fn interpolate_env_vars(content: &str) -> String {
let mut result = String::with_capacity(content.len());
let bytes = content.as_bytes();
let chars: Vec<char> = content.chars().collect();
let mut i = 0;
while i < bytes.len() {
if i + 1 < bytes.len() && bytes[i] == b'$' && bytes[i + 1] == b'{' {
while i < chars.len() {
if i + 1 < chars.len() && chars[i] == '$' && chars[i + 1] == '{' {
let start = i + 2;
let mut end = start;
while end < bytes.len()
&& (bytes[end].is_ascii_alphanumeric() || bytes[end] == b'_')
while end < chars.len()
&& (chars[end].is_ascii_alphanumeric() || chars[end] == '_')
{
end += 1;
}
if end < bytes.len() && bytes[end] == b'}' {
let var_name = std::str::from_utf8(&bytes[start..end]).unwrap_or("");
match std::env::var(var_name) {
if end < chars.len() && chars[end] == '}' {
let var_name: String = chars[start..end].iter().collect();
match std::env::var(&var_name) {
Ok(val) => {
tracing::debug!("Config: ${{{}}} → resolved ({} bytes)", var_name, val.len());
result.push_str(&val);
@@ -492,11 +495,11 @@ fn interpolate_env_vars(content: &str) -> String {
}
i = end + 1;
} else {
result.push(bytes[i] as char);
result.push(chars[i]);
i += 1;
}
} else {
result.push(bytes[i] as char);
result.push(chars[i]);
i += 1;
}
}