diff --git a/Cargo.lock b/Cargo.lock index 5dafdc2..d356602 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,6 +96,7 @@ dependencies = [ "unicode-segmentation", "unicode-width", "urlencoding", + "uuid", ] [[package]] @@ -2945,6 +2946,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "uuid" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +dependencies = [ + "getrandom", +] + [[package]] name = "valuable" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index f5f788e..30045c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,7 @@ bitflags = "2.5.0" path-absolutize = "3.1.1" hnsw_rs = "0.3.0" rayon = "1.10.0" +uuid = { version = "1.9.1", features = ["v4"] } [dependencies.reqwest] version = "0.12.0" diff --git a/config.example.yaml b/config.example.yaml index 2f371dd..28b5992 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -34,7 +34,7 @@ document_loaders: docx: 'pandoc --to plain $1' # Load .docx file # xlsx: 'ssconvert $1 $2' # Load .xlsx file # html: 'pandoc --to plain $1' # Load .html file - # recursive_url: 'rag-crawler $1 $2.json' # Load websites, see https://github.com/sigoden/rag-crawler + # recursive_url: 'rag-crawler $1 $2' # Load websites, see https://github.com/sigoden/rag-crawler # ---- function-calling & agent ---- # Controls the function calling feature. For setup instructions, visit https://github.com/sigoden/llm-functions diff --git a/src/repl/mod.rs b/src/repl/mod.rs index 360af70..6c15002 100644 --- a/src/repl/mod.rs +++ b/src/repl/mod.rs @@ -10,7 +10,7 @@ use crate::client::chat_completion_streaming; use crate::config::{AssertState, Config, GlobalConfig, Input, StateFlags}; use crate::function::need_send_tool_results; use crate::render::render_error; -use crate::utils::{create_abort_signal, set_text, AbortSignal}; +use crate::utils::{create_abort_signal, set_text, temp_file, AbortSignal}; use anyhow::{bail, Context, Result}; use async_recursion::async_recursion; @@ -415,8 +415,7 @@ Type ".help" for additional help. .with_ansi_colors(true); if let Some(cmd) = config.read().buffer_editor() { - let temp_file = - env::temp_dir().join(format!("aichat-{}.txt", chrono::Utc::now().timestamp())); + let temp_file = temp_file("-repl-", ".txt"); let command = process::Command::new(cmd); editor = editor.with_buffer_editor(command, temp_file); } diff --git a/src/utils/command.rs b/src/utils/command.rs index 1a7de5b..3876f3d 100644 --- a/src/utils/command.rs +++ b/src/utils/command.rs @@ -98,10 +98,7 @@ pub fn run_loader_command(path: &str, extension: &str, loader_command: &str) -> anyhow!("Invalid rag document loader '{extension}': `{loader_command}`") })?; let mut use_stdout = true; - let outpath = env::temp_dir() - .join(format!("aichat-output-{}", sha256(path))) - .display() - .to_string(); + let outpath = temp_file("-output-", "").display().to_string(); let cmd_args: Vec<_> = cmd_args .into_iter() .map(|mut v| { diff --git a/src/utils/mod.rs b/src/utils/mod.rs index e36a54b..548c6f1 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -38,8 +38,8 @@ pub fn now() -> String { pub fn get_env_name(key: &str) -> String { format!( "{}_{}", - env!("CARGO_CRATE_NAME").to_ascii_uppercase(), - key.to_ascii_uppercase(), + env!("CARGO_CRATE_NAME").to_uppercase(), + key.to_uppercase(), ) } @@ -183,6 +183,14 @@ pub fn safe_join_path, T2: AsRef>( } } +pub fn temp_file(prefix: &str, suffix: &str) -> PathBuf { + env::temp_dir().join(format!( + "{}{prefix}{}{suffix}", + env!("CARGO_CRATE_NAME").to_lowercase(), + uuid::Uuid::new_v4() + )) +} + pub fn set_proxy( builder: reqwest::ClientBuilder, proxy: Option<&String>, diff --git a/src/utils/request.rs b/src/utils/request.rs index bc5388c..fadd3b8 100644 --- a/src/utils/request.rs +++ b/src/utils/request.rs @@ -3,7 +3,7 @@ use super::*; use anyhow::{bail, Result}; use http::header::CONTENT_TYPE; use lazy_static::lazy_static; -use std::{collections::HashMap, env, time::Duration}; +use std::{collections::HashMap, time::Duration}; use tokio::io::AsyncWriteExt; pub const URL_LOADER: &str = "url"; @@ -48,10 +48,7 @@ pub async fn fetch(loaders: &HashMap, path: &str) -> Result<(Str } let result = match loaders.get(&extension) { Some(loader_command) => { - let save_path = env::temp_dir() - .join(format!("aichat-download-{}.{extension}", sha256(path))) - .display() - .to_string(); + let save_path = temp_file("-download-", "").display().to_string(); let mut save_file = tokio::fs::File::create(&save_path).await?; let mut size = 0; while let Some(chunk) = res.chunk().await? {