优化: token分项显示(in/cache/out/reasoning)+ 详情面板 + base前置
token分项(各计费不同,不显 total):df-ai 解析 provider cache/reasoning(openai_compat prompt_cache_hit/miss/reasoning_tokens + anthropic cache_read/creation)+ TokenUsage 加字段(全构造点)+ AiMessage/AiCompleted/DB V39(ai_messages 加 cache_hit/miss/reasoning 列)+ message_repo 映射(持久化)+ 前端 MessageList 显 in·cache·out·reason(in=cache_miss 全价,reasoning 有才显)+ 点击 token 弹详情面板(完整 usage+缓存命中率+model)+ df-miniapp 同步 base前置(提升 prompt cache 命中率):chat.rs aug 拼 base 后(4处)+ knowledge_inject 知识拼 base 后(固定 base 前缀,cache 命中) 附修:replace_conversation 原 13 列 INSERT 丢消息级 token → 改 18 列
This commit is contained in:
@@ -45,7 +45,7 @@ pub fn run(conn: &Connection) -> Result<()> {
|
||||
// 什么数据库、Redis 在哪、有没有 MQ"的基础设施上下文。
|
||||
// V33 = 审批重启恢复:ai_conversations 加 pending_approvals TEXT 列,持久化挂起审批快照,
|
||||
// 重启后从 DB 恢复 pending_approvals 内存态,使待审批不丢。
|
||||
let steps: [(i32, fn(&Connection) -> Result<()>); 38] = [
|
||||
let steps: [(i32, fn(&Connection) -> Result<()>); 39] = [
|
||||
(1, migrate_v1),
|
||||
(2, migrate_v2),
|
||||
(3, migrate_v3),
|
||||
@@ -84,6 +84,7 @@ pub fn run(conn: &Connection) -> Result<()> {
|
||||
(36, migrate_v36),
|
||||
(37, migrate_v37),
|
||||
(38, migrate_v38),
|
||||
(39, migrate_v39),
|
||||
];
|
||||
|
||||
for (version, migrate_fn) in steps {
|
||||
@@ -1157,6 +1158,32 @@ fn migrate_v38(conn: &Connection) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// V39: ai_messages 加 prompt_cache_hit_tokens / prompt_cache_miss_tokens / reasoning_tokens 列
|
||||
///
|
||||
/// token 分项显示(2026-08-02):各 provider 计费不同(deepseek cache 命中低价/未命中全价/
|
||||
/// 输出价高/reasoning 隐藏输出),前端 in/cache/out/reason 分项展示 + 详情面板。
|
||||
/// - prompt_cache_hit_tokens:缓存命中(deepseek prompt_cache_hit / anthropic cache_read)
|
||||
/// - prompt_cache_miss_tokens:未命中全价(deepseek prompt_cache_miss / anthropic cache_creation)
|
||||
/// - reasoning_tokens:思考(deepseek-reasoner/o1 reasoning_tokens)
|
||||
/// 三列均 nullable,老消息 NULL → None(向前兼容,非 cache provider 恒 0)。
|
||||
fn migrate_v39(conn: &Connection) -> Result<()> {
|
||||
if !column_exists(conn, "ai_messages", "prompt_cache_hit_tokens") {
|
||||
conn.execute("ALTER TABLE ai_messages ADD COLUMN prompt_cache_hit_tokens INTEGER", [])?;
|
||||
tracing::info!("v39: ai_messages 加 prompt_cache_hit_tokens 列");
|
||||
}
|
||||
if !column_exists(conn, "ai_messages", "prompt_cache_miss_tokens") {
|
||||
conn.execute("ALTER TABLE ai_messages ADD COLUMN prompt_cache_miss_tokens INTEGER", [])?;
|
||||
tracing::info!("v39: ai_messages 加 prompt_cache_miss_tokens 列");
|
||||
}
|
||||
if !column_exists(conn, "ai_messages", "reasoning_tokens") {
|
||||
conn.execute("ALTER TABLE ai_messages ADD COLUMN reasoning_tokens INTEGER", [])?;
|
||||
tracing::info!("v39: ai_messages 加 reasoning_tokens 列");
|
||||
}
|
||||
conn.execute("INSERT INTO schema_version (version) VALUES (?)", [39])?;
|
||||
tracing::info!("迁移 v39 完成: ai_messages 加 cache/reasoning 分项 token 列");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// V21 建表 SQL — 消息拆分存储 ai_messages 表
|
||||
///
|
||||
/// 与 V9_SQL 中的 ai_messages 镜像(V9 给新库,此 const 给老库 V21 迁移用 IF NOT EXISTS)。
|
||||
@@ -1178,6 +1205,9 @@ CREATE TABLE IF NOT EXISTS ai_messages (
|
||||
created_at TEXT NOT NULL,
|
||||
prompt_tokens INTEGER,
|
||||
completion_tokens INTEGER,
|
||||
prompt_cache_hit_tokens INTEGER,
|
||||
prompt_cache_miss_tokens INTEGER,
|
||||
reasoning_tokens INTEGER,
|
||||
UNIQUE(conversation_id, seq)
|
||||
);
|
||||
|
||||
@@ -1438,6 +1468,9 @@ CREATE TABLE IF NOT EXISTS ai_messages (
|
||||
created_at TEXT NOT NULL,
|
||||
prompt_tokens INTEGER,
|
||||
completion_tokens INTEGER,
|
||||
prompt_cache_hit_tokens INTEGER,
|
||||
prompt_cache_miss_tokens INTEGER,
|
||||
reasoning_tokens INTEGER,
|
||||
UNIQUE(conversation_id, seq)
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user