Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95d7ff1299 |
Generated
+1
@@ -5544,6 +5544,7 @@ dependencies = [
|
|||||||
"dirs 5.0.1",
|
"dirs 5.0.1",
|
||||||
"futures",
|
"futures",
|
||||||
"reqwest 0.12.28",
|
"reqwest 0.12.28",
|
||||||
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ reqwest.workspace = true
|
|||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
uuid.workspace = true
|
uuid.workspace = true
|
||||||
dirs.workspace = true
|
dirs.workspace = true
|
||||||
|
rusqlite.workspace = true
|
||||||
xianren-core = { path = "../../crates/core" }
|
xianren-core = { path = "../../crates/core" }
|
||||||
xianren-engine = { path = "../../crates/engine" }
|
xianren-engine = { path = "../../crates/engine" }
|
||||||
xianren-download = { path = "../../crates/download" }
|
xianren-download = { path = "../../crates/download" }
|
||||||
|
|||||||
@@ -217,10 +217,12 @@ pub fn list_conversations(state: State<'_, App>) -> Result<Vec<xianren_core::Con
|
|||||||
pub fn create_conversation(
|
pub fn create_conversation(
|
||||||
state: State<'_, App>,
|
state: State<'_, App>,
|
||||||
title: String,
|
title: String,
|
||||||
|
model_id: Option<String>,
|
||||||
) -> Result<xianren_core::Conversation, String> {
|
) -> Result<xianren_core::Conversation, String> {
|
||||||
let id = uuid::Uuid::new_v4().to_string();
|
let id = uuid::Uuid::new_v4().to_string();
|
||||||
let db = state.core.db.lock().unwrap();
|
let db = state.core.db.lock().unwrap();
|
||||||
sessions_db::create_conversation(&db, &id, &title, None, None).map_err(|e| e.to_string())?;
|
sessions_db::create_conversation(&db, &id, &title, model_id.as_deref(), None)
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
sessions_db::get_conversation(&db, &id)
|
sessions_db::get_conversation(&db, &id)
|
||||||
.map_err(|e| e.to_string())?
|
.map_err(|e| e.to_string())?
|
||||||
.ok_or_else(|| "conversation not found".to_string())
|
.ok_or_else(|| "conversation not found".to_string())
|
||||||
@@ -481,6 +483,9 @@ pub async fn chat_send(
|
|||||||
)
|
)
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
}
|
}
|
||||||
|
// 始终把当前使用的模型写回会话,编辑/重新生成依赖它
|
||||||
|
sessions_db::update_conversation_model(&db, &payload.conversation_id, &payload.model_id)
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
let user_message_id = sessions_db::add_message(
|
let user_message_id = sessions_db::add_message(
|
||||||
&db,
|
&db,
|
||||||
&payload.conversation_id,
|
&payload.conversation_id,
|
||||||
@@ -724,6 +729,21 @@ fn estimate_tokens(text: &str) -> usize {
|
|||||||
score / 4 + 1
|
score / 4 + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 解析会话使用的模型:优先会话记录;未记录时若本地只有一个模型则自动使用,否则提示。
|
||||||
|
fn resolve_conversation_model(
|
||||||
|
db: &rusqlite::Connection,
|
||||||
|
conversation: &xianren_core::Conversation,
|
||||||
|
) -> Result<String, String> {
|
||||||
|
if let Some(id) = &conversation.model_id {
|
||||||
|
return Ok(id.clone());
|
||||||
|
}
|
||||||
|
let all = models_db::list(db).map_err(|e| e.to_string())?;
|
||||||
|
if all.len() == 1 {
|
||||||
|
return Ok(all[0].id.clone());
|
||||||
|
}
|
||||||
|
Err("会话未记录模型:请先在该会话发送一条消息,或重新选择模型后重试".into())
|
||||||
|
}
|
||||||
|
|
||||||
/// 重新生成某条助手回复:旧内容存入版本历史,截断后重新生成。
|
/// 重新生成某条助手回复:旧内容存入版本历史,截断后重新生成。
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn regenerate_message(
|
pub async fn regenerate_message(
|
||||||
@@ -768,10 +788,7 @@ pub async fn regenerate_message(
|
|||||||
images: m.images.clone(),
|
images: m.images.clone(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let model_id = conversation
|
let model_id = resolve_conversation_model(&db, &conversation)?;
|
||||||
.model_id
|
|
||||||
.clone()
|
|
||||||
.ok_or_else(|| "conversation has no model".to_string())?;
|
|
||||||
let model = models_db::get(&db, &model_id)
|
let model = models_db::get(&db, &model_id)
|
||||||
.map_err(|e| e.to_string())?
|
.map_err(|e| e.to_string())?
|
||||||
.ok_or_else(|| "model not found".to_string())?;
|
.ok_or_else(|| "model not found".to_string())?;
|
||||||
@@ -835,10 +852,7 @@ pub async fn edit_message(
|
|||||||
images: m.images,
|
images: m.images,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let model_id = conversation
|
let model_id = resolve_conversation_model(&db, &conversation)?;
|
||||||
.model_id
|
|
||||||
.clone()
|
|
||||||
.ok_or_else(|| "conversation has no model".to_string())?;
|
|
||||||
let model = models_db::get(&db, &model_id)
|
let model = models_db::get(&db, &model_id)
|
||||||
.map_err(|e| e.to_string())?
|
.map_err(|e| e.to_string())?
|
||||||
.ok_or_else(|| "model not found".to_string())?;
|
.ok_or_else(|| "model not found".to_string())?;
|
||||||
|
|||||||
@@ -85,6 +85,14 @@ pub fn touch_conversation(db: &Connection, id: &str) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_conversation_model(db: &Connection, id: &str, model_id: &str) -> Result<()> {
|
||||||
|
db.execute(
|
||||||
|
"UPDATE conversations SET model_id = ?1 WHERE id = ?2",
|
||||||
|
params![model_id, id],
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn delete_conversation(db: &Connection, id: &str) -> Result<()> {
|
pub fn delete_conversation(db: &Connection, id: &str) -> Result<()> {
|
||||||
db.execute("DELETE FROM conversations WHERE id = ?1", params![id])?;
|
db.execute("DELETE FROM conversations WHERE id = ?1", params![id])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
+2
-2
@@ -194,8 +194,8 @@ export const api = {
|
|||||||
settingsSet: (key: string, value: string) =>
|
settingsSet: (key: string, value: string) =>
|
||||||
invoke<void>("settings_set", { key, value }),
|
invoke<void>("settings_set", { key, value }),
|
||||||
listConversations: () => invoke<Conversation[]>("list_conversations"),
|
listConversations: () => invoke<Conversation[]>("list_conversations"),
|
||||||
createConversation: (title: string) =>
|
createConversation: (title: string, modelId?: string) =>
|
||||||
invoke<Conversation>("create_conversation", { title }),
|
invoke<Conversation>("create_conversation", { title, modelId: modelId ?? null }),
|
||||||
deleteConversation: (id: string) =>
|
deleteConversation: (id: string) =>
|
||||||
invoke<void>("delete_conversation", { id }),
|
invoke<void>("delete_conversation", { id }),
|
||||||
getMessages: (conversationId: string) =>
|
getMessages: (conversationId: string) =>
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ export default function ChatPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleNewConversation() {
|
async function handleNewConversation() {
|
||||||
const conv = await api.createConversation("新会话");
|
const conv = await api.createConversation("新会话", selectedModelId || undefined);
|
||||||
setActiveConvId(conv.id);
|
setActiveConvId(conv.id);
|
||||||
setMessages([]);
|
setMessages([]);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|||||||
Reference in New Issue
Block a user