feat: 添加 VEO3 场景写作工具并优化文件处理逻辑

- 创建 VEO3SceneWriterTool 页面组件,集成聊天界面和文件选择功能
- 添加 veo3SceneWriterService 服务层,封装与 Rust 后端的通信逻辑
- 实现 Tauri 命令支持,调用 veo3-scene-writer crate
- 更新工具数据配置,添加 VEO3 场景写作工具
- 优化文件处理逻辑:JSON/TXT 文件读取内容作为消息,图片文件作为附件
- 支持多种文本格式:.json, .txt, .md, .yaml, .yml, .toml
- 提供专业的影视场景提示词生成功能
This commit is contained in:
imeepos
2025-08-18 10:14:01 +08:00
parent 9ba62d9e06
commit e2a1f43e85
7 changed files with 984 additions and 8 deletions

View File

@@ -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,