feat: 添加 VEO3 场景写作工具并优化文件处理逻辑
- 创建 VEO3SceneWriterTool 页面组件,集成聊天界面和文件选择功能 - 添加 veo3SceneWriterService 服务层,封装与 Rust 后端的通信逻辑 - 实现 Tauri 命令支持,调用 veo3-scene-writer crate - 更新工具数据配置,添加 VEO3 场景写作工具 - 优化文件处理逻辑:JSON/TXT 文件读取内容作为消息,图片文件作为附件 - 支持多种文本格式:.json, .txt, .md, .yaml, .yml, .toml - 提供专业的影视场景提示词生成功能
This commit is contained in:
@@ -198,13 +198,24 @@ impl Veo3SceneWriter {
|
||||
message: &str,
|
||||
attachment_paths: Vec<&str>
|
||||
) -> Result<String, Box<dyn std::error::Error>> {
|
||||
// 处理文件内容,分离文本文件和图片文件
|
||||
let (text_content, image_attachments) = self.process_attachments(attachment_paths).await?;
|
||||
|
||||
// 构建完整消息,包含文本文件内容
|
||||
let mut full_message = if text_content.is_empty() {
|
||||
message.to_string()
|
||||
} else {
|
||||
format!("{}\n\n附件内容:\n{}", message, text_content)
|
||||
};
|
||||
|
||||
// 构建包含历史记录的完整消息
|
||||
let full_message = self.build_message_with_history(message);
|
||||
full_message = self.build_message_with_history(&full_message);
|
||||
|
||||
let mut request = MessageRequest::with_agent(&full_message, &self.agent_id);
|
||||
|
||||
for path in attachment_paths {
|
||||
request = request.attach(Attachment::new(path));
|
||||
// 只添加图片附件到请求中
|
||||
for path in image_attachments {
|
||||
request = request.attach(Attachment::new(&path));
|
||||
}
|
||||
|
||||
let response = self.sdk.send_message(request).await?;
|
||||
@@ -215,6 +226,45 @@ impl Veo3SceneWriter {
|
||||
Ok(response.content)
|
||||
}
|
||||
|
||||
/// 处理附件,分离文本文件和图片文件
|
||||
async fn process_attachments(
|
||||
&self,
|
||||
attachment_paths: Vec<&str>
|
||||
) -> Result<(String, Vec<String>), Box<dyn std::error::Error>> {
|
||||
let mut text_content = Vec::new();
|
||||
let mut image_attachments = Vec::new();
|
||||
|
||||
for path in attachment_paths {
|
||||
let path_lower = path.to_lowercase();
|
||||
|
||||
// 检查文件扩展名
|
||||
if path_lower.ends_with(".json") || path_lower.ends_with(".txt") ||
|
||||
path_lower.ends_with(".md") || path_lower.ends_with(".yaml") ||
|
||||
path_lower.ends_with(".yml") || path_lower.ends_with(".toml") {
|
||||
// 读取文本文件内容
|
||||
match std::fs::read_to_string(path) {
|
||||
Ok(content) => {
|
||||
let file_name = std::path::Path::new(path)
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.unwrap_or("unknown");
|
||||
text_content.push(format!("=== {} ===\n{}", file_name, content));
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("读取文件失败 {}: {}", path, e);
|
||||
text_content.push(format!("=== {} ===\n[文件读取失败: {}]", path, e));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 图片文件或其他文件,作为附件处理
|
||||
image_attachments.push(path.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
let combined_text = text_content.join("\n\n");
|
||||
Ok((combined_text, image_attachments))
|
||||
}
|
||||
|
||||
/// 发送带单个附件的消息
|
||||
pub async fn send_message_with_attachment(
|
||||
&mut self,
|
||||
@@ -357,13 +407,24 @@ impl Veo3ActorDefine {
|
||||
message: &str,
|
||||
attachment_paths: Vec<&str>
|
||||
) -> Result<String, Box<dyn std::error::Error>> {
|
||||
// 处理文件内容,分离文本文件和图片文件
|
||||
let (text_content, image_attachments) = self.process_attachments(attachment_paths).await?;
|
||||
|
||||
// 构建完整消息,包含文本文件内容
|
||||
let mut full_message = if text_content.is_empty() {
|
||||
message.to_string()
|
||||
} else {
|
||||
format!("{}\n\n附件内容:\n{}", message, text_content)
|
||||
};
|
||||
|
||||
// 构建包含历史记录的完整消息
|
||||
let full_message = self.build_message_with_history(message);
|
||||
full_message = self.build_message_with_history(&full_message);
|
||||
|
||||
let mut request = MessageRequest::with_agent(&full_message, &self.agent_id);
|
||||
|
||||
for path in attachment_paths {
|
||||
request = request.attach(Attachment::new(path));
|
||||
// 只添加图片附件到请求中
|
||||
for path in image_attachments {
|
||||
request = request.attach(Attachment::new(&path));
|
||||
}
|
||||
|
||||
let response = self.sdk.send_message(request).await?;
|
||||
@@ -374,6 +435,45 @@ impl Veo3ActorDefine {
|
||||
Ok(response.content)
|
||||
}
|
||||
|
||||
/// 处理附件,分离文本文件和图片文件
|
||||
async fn process_attachments(
|
||||
&self,
|
||||
attachment_paths: Vec<&str>
|
||||
) -> Result<(String, Vec<String>), Box<dyn std::error::Error>> {
|
||||
let mut text_content = Vec::new();
|
||||
let mut image_attachments = Vec::new();
|
||||
|
||||
for path in attachment_paths {
|
||||
let path_lower = path.to_lowercase();
|
||||
|
||||
// 检查文件扩展名
|
||||
if path_lower.ends_with(".json") || path_lower.ends_with(".txt") ||
|
||||
path_lower.ends_with(".md") || path_lower.ends_with(".yaml") ||
|
||||
path_lower.ends_with(".yml") || path_lower.ends_with(".toml") {
|
||||
// 读取文本文件内容
|
||||
match std::fs::read_to_string(path) {
|
||||
Ok(content) => {
|
||||
let file_name = std::path::Path::new(path)
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.unwrap_or("unknown");
|
||||
text_content.push(format!("=== {} ===\n{}", file_name, content));
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("读取文件失败 {}: {}", path, e);
|
||||
text_content.push(format!("=== {} ===\n[文件读取失败: {}]", path, e));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 图片文件或其他文件,作为附件处理
|
||||
image_attachments.push(path.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
let combined_text = text_content.join("\n\n");
|
||||
Ok((combined_text, image_attachments))
|
||||
}
|
||||
|
||||
/// 发送带单个附件的消息
|
||||
pub async fn send_message_with_attachment(
|
||||
&mut self,
|
||||
|
||||
Reference in New Issue
Block a user