Skip to content

Commit fddc045

Browse files
authored
Merge pull request #13 from xieisabug/sidebar
增加Sidebar
2 parents 96d8f3c + 34fe153 commit fddc045

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+4110
-179
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"@tauri-apps/plugin-fs": "^2.4.1",
5454
"@tauri-apps/plugin-global-shortcut": "^2.3.0",
5555
"@tauri-apps/plugin-notification": "~2",
56+
"@tauri-apps/plugin-opener": "^2.5.3",
5657
"@tauri-apps/plugin-shell": "^2.3.0",
5758
"@tauri-apps/plugin-updater": "~2.9.0",
5859
"class-variance-authority": "^0.7.1",

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ rmcp = { version = "0.8", features = [
6868
tracing = "0.1"
6969
tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] }
7070
tauri-plugin-notification = "2"
71-
syntect = "5.3.0"
71+
syntect = { version = "5.3.0", features = ["dump-load"] }
7272
# ACP (Agent Client Protocol) SDK
7373
agent-client-protocol = { version = "0.9", git = "https://github.com/agentclientprotocol/rust-sdk" }
7474

src-tauri/assets/syntaxes.bin

989 KB
Binary file not shown.

src-tauri/assets/themes.bin

57 KB
Binary file not shown.

src-tauri/capabilities/migrated.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"preview_vue",
1818
"artifact_preview",
1919
"artifact_collections",
20-
"artifact"
20+
"artifact",
21+
"sidebar"
2122
],
2223
"permissions": [
2324
"core:default",
@@ -46,6 +47,7 @@
4647
"core:window:allow-destroy",
4748
"core:window:allow-start-dragging",
4849
"opener:allow-open-url",
50+
"opener:allow-default-urls",
4951
"dialog:allow-open",
5052
"dialog:allow-save",
5153
"dialog:allow-message",
@@ -64,4 +66,4 @@
6466
"autostart:allow-is-enabled",
6567
"updater:default"
6668
]
67-
}
69+
}

src-tauri/capabilities/mobile.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
]
2828
},
2929
"opener:allow-open-url",
30+
"opener:allow-default-urls",
3031
"dialog:allow-open",
3132
"dialog:allow-save",
3233
"dialog:allow-message",
@@ -36,4 +37,4 @@
3637
"clipboard-manager:allow-write-text",
3738
"notification:default"
3839
]
39-
}
40+
}

src-tauri/src/api/ai_api.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,22 @@ pub async fn cancel_ai(
11261126
warn!(conversation_id, error = %e, "failed to cancel MCP tool calls for conversation");
11271127
}
11281128

1129+
// 更新所有正在进行中的消息的 finish_time
1130+
if let Ok(db) = ConversationDatabase::new(&app_handle) {
1131+
if let Ok(message_repo) = db.message_repo() {
1132+
match message_repo.finish_pending_messages(conversation_id) {
1133+
Ok(count) => {
1134+
if count > 0 {
1135+
debug!(conversation_id, count, "finished pending messages on cancel");
1136+
}
1137+
}
1138+
Err(e) => {
1139+
warn!(conversation_id, error = %e, "failed to finish pending messages on cancel");
1140+
}
1141+
}
1142+
}
1143+
}
1144+
11291145
// Send cancellation event to both ask and chat_ui windows
11301146
let cancel_event = crate::api::ai::events::ConversationEvent {
11311147
r#type: "conversation_cancel".to_string(),

src-tauri/src/api/assistant_api.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::{
55
AssistantModel, AssistantModelConfig, AssistantPrompt, AssistantPromptParam,
66
},
77
conversation_db::ConversationDatabase,
8+
llm_db::LLMDatabase,
89
},
910
utils::share_utils::{
1011
compress_assistant_data, decompress_assistant_data, AssistantShareData, ModelConfigShare,
@@ -536,6 +537,38 @@ pub fn get_assistant_field_value(
536537
.ok_or_else(|| format!("Field '{}' not found", field_name))
537538
}
538539

540+
#[tauri::command]
541+
#[instrument(skip(app_handle), fields(assistant_id))]
542+
pub fn get_acp_working_directory(
543+
app_handle: tauri::AppHandle,
544+
assistant_id: i64,
545+
) -> Result<String, String> {
546+
let assistant_db = AssistantDatabase::new(&app_handle).map_err(|e| e.to_string())?;
547+
let assistant = assistant_db.get_assistant(assistant_id).map_err(|e| e.to_string())?;
548+
549+
if assistant.assistant_type != Some(4) {
550+
return Err("Assistant is not ACP type".to_string());
551+
}
552+
553+
let model_configs =
554+
assistant_db.get_assistant_model_configs(assistant_id).map_err(|e| e.to_string())?;
555+
let provider_configs = if let Some(model) = assistant_db
556+
.get_assistant_model(assistant_id)
557+
.map_err(|e| e.to_string())?
558+
.first()
559+
{
560+
let llm_db = LLMDatabase::new(&app_handle).map_err(|e| e.to_string())?;
561+
llm_db.get_llm_provider_config(model.provider_id).map_err(|e| e.to_string())?
562+
} else {
563+
Vec::new()
564+
};
565+
566+
let acp_config =
567+
crate::api::ai::acp::extract_acp_config(&model_configs, &provider_configs).map_err(|e| e.to_string())?;
568+
569+
Ok(acp_config.working_directory.display().to_string())
570+
}
571+
539572
// MCP Configuration Commands
540573

541574
#[tauri::command]
@@ -693,6 +726,7 @@ pub async fn update_assistant_model_config_value(
693726
.map_err(|e| e.to_string())?;
694727
}
695728

729+
let _ = app_handle.emit("assistant_list_changed", ());
696730
Ok(())
697731
}
698732

src-tauri/src/api/conversation_api.rs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -460,14 +460,31 @@ pub async fn fork_conversation(
460460
.map_err(|e| e.to_string())?
461461
.ok_or_else(|| "Conversation not found".to_string())?;
462462

463-
// 获取原对话的所有消息
463+
// 获取原对话的所有消息(包含附件)
464464
let message_repo = db.message_repo().unwrap();
465465
let all_messages_with_attachments =
466466
message_repo.list_by_conversation_id(conversation_id).map_err(|e| e.to_string())?;
467467

468-
// 提取消息部分
469-
let all_messages: Vec<Message> =
470-
all_messages_with_attachments.iter().map(|(message, _)| message.clone()).collect();
468+
// 构建消息ID到附件列表的映射
469+
let mut attachment_map: HashMap<i64, Vec<MessageAttachment>> = HashMap::new();
470+
for (message, attachment) in &all_messages_with_attachments {
471+
if let Some(att) = attachment {
472+
attachment_map.entry(message.id).or_default().push(att.clone());
473+
}
474+
}
475+
476+
// 提取消息部分(去重,因为一条消息可能有多个附件导致多行)
477+
let mut seen_ids = std::collections::HashSet::new();
478+
let all_messages: Vec<Message> = all_messages_with_attachments
479+
.iter()
480+
.filter_map(|(message, _)| {
481+
if seen_ids.insert(message.id) {
482+
Some(message.clone())
483+
} else {
484+
None
485+
}
486+
})
487+
.collect();
471488

472489
// 找到目标消息的位置
473490
let target_message_index = all_messages
@@ -501,14 +518,29 @@ pub async fn fork_conversation(
501518
let created_conversation =
502519
conversation_repo.create(&new_conversation).map_err(|e| e.to_string())?;
503520

504-
// 复制消息到新对话
521+
// 获取附件仓库
522+
let attachment_repo = db.attachment_repo().map_err(|e| e.to_string())?;
523+
524+
// 复制消息到新对话,并复制对应的附件
505525
for message in messages_to_copy {
526+
let old_message_id = message.id;
527+
506528
let mut new_message = message.clone();
507529
new_message.id = 0;
508530
new_message.conversation_id = created_conversation.id;
509531
new_message.created_time = chrono::Utc::now();
510532

511-
message_repo.create(&new_message).map_err(|e| e.to_string())?;
533+
let created_message = message_repo.create(&new_message).map_err(|e| e.to_string())?;
534+
535+
// 复制该消息的所有附件
536+
if let Some(attachments) = attachment_map.get(&old_message_id) {
537+
for attachment in attachments {
538+
let mut new_attachment = attachment.clone();
539+
new_attachment.id = 0;
540+
new_attachment.message_id = created_message.id;
541+
attachment_repo.create(&new_attachment).map_err(|e| e.to_string())?;
542+
}
543+
}
512544
}
513545

514546
Ok(created_conversation.id)

0 commit comments

Comments
 (0)