From d4316f5e3d52c020f7ac9952cb0e31397175faaa Mon Sep 17 00:00:00 2001 From: Eddie Date: Mon, 23 Dec 2024 18:25:51 -0300 Subject: [PATCH] File Tools --- .../chains/generic_chain/generic_prompts.rs | 10 ++++++--- .../shinkai-node/src/managers/tool_router.rs | 21 +++++++++++++++++-- .../v2_api/api_v2_commands_app_files.rs | 20 +++++++++++++----- .../src/api_v2/api_v2_handlers_app_files.rs | 8 +++---- .../src/tools/deno_tools.rs | 14 +++++++------ 5 files changed, 53 insertions(+), 20 deletions(-) diff --git a/shinkai-bin/shinkai-node/src/llm_provider/execution/chains/generic_chain/generic_prompts.rs b/shinkai-bin/shinkai-node/src/llm_provider/execution/chains/generic_chain/generic_prompts.rs index cd911773a..e35b480de 100644 --- a/shinkai-bin/shinkai-node/src/llm_provider/execution/chains/generic_chain/generic_prompts.rs +++ b/shinkai-bin/shinkai-node/src/llm_provider/execution/chains/generic_chain/generic_prompts.rs @@ -58,10 +58,14 @@ impl JobPromptGenerator { } } - let current_files = Node::v2_api_list_app_files_internal(get_app_folder_path(node_env, job_id)); + let folder = get_app_folder_path(node_env, job_id); + let current_files = Node::v2_api_list_app_files_internal(folder.clone(), true); if let Ok(current_files) = current_files { - let content = format!("Current files: {:?}", current_files); - prompt.add_content(content, SubPromptType::ExtraContext, 97); + prompt.add_content( + format!("Current files: {}", current_files.join(", ")), + SubPromptType::ExtraContext, + 97, + ); } } diff --git a/shinkai-bin/shinkai-node/src/managers/tool_router.rs b/shinkai-bin/shinkai-node/src/managers/tool_router.rs index 63f704a7b..2fb5ce447 100644 --- a/shinkai-bin/shinkai-node/src/managers/tool_router.rs +++ b/shinkai-bin/shinkai-node/src/managers/tool_router.rs @@ -5,6 +5,7 @@ use std::time::Instant; use crate::llm_provider::error::LLMProviderError; use crate::llm_provider::execution::chains::inference_chain_trait::{FunctionCall, InferenceChainContextTrait}; +use crate::network::v2_api::api_v2_commands_app_files::get_app_folder_path; use crate::network::Node; use crate::tools::tool_definitions::definition_generation::{generate_tool_definitions, get_rust_tools}; use crate::tools::tool_execution::execution_header_generator::generate_execution_environment; @@ -621,6 +622,14 @@ async def run(c: CONFIG, p: INPUTS) -> OUTPUT: .await .map_err(|e| ToolError::ExecutionError(e.to_string()))?; + let folder = get_app_folder_path(node_env.clone(), context.full_job().job_id().to_string()); + let mounts = Node::v2_api_list_app_files_internal(folder.clone(), true); + if let Err(e) = mounts { + eprintln!("Failed to list app files: {:?}", e); + return Err(LLMProviderError::FunctionExecutionError(format!("{:?}", e))); + } + let mounts = Some(mounts.unwrap_or_default()); + let result = python_tool .run( envs, @@ -635,7 +644,7 @@ async def run(c: CONFIG, p: INPUTS) -> OUTPUT: node_name, false, None, - None, + mounts, ) .map_err(|e| LLMProviderError::FunctionExecutionError(e.to_string()))?; let result_str = serde_json::to_string(&result) @@ -692,6 +701,14 @@ async def run(c: CONFIG, p: INPUTS) -> OUTPUT: .await .map_err(|e| ToolError::ExecutionError(e.to_string()))?; + let folder = get_app_folder_path(node_env.clone(), context.full_job().job_id().to_string()); + let mounts = Node::v2_api_list_app_files_internal(folder.clone(), true); + if let Err(e) = mounts { + eprintln!("Failed to list app files: {:?}", e); + return Err(LLMProviderError::FunctionExecutionError(format!("{:?}", e))); + } + let mounts = Some(mounts.unwrap_or_default()); + let result = deno_tool .run( envs, @@ -706,7 +723,7 @@ async def run(c: CONFIG, p: INPUTS) -> OUTPUT: node_name, false, Some(tool_id), - None, + mounts, ) .map_err(|e| LLMProviderError::FunctionExecutionError(e.to_string()))?; let result_str = serde_json::to_string(&result) diff --git a/shinkai-bin/shinkai-node/src/network/v2_api/api_v2_commands_app_files.rs b/shinkai-bin/shinkai-node/src/network/v2_api/api_v2_commands_app_files.rs index 9de40931c..6f73eb17e 100644 --- a/shinkai-bin/shinkai-node/src/network/v2_api/api_v2_commands_app_files.rs +++ b/shinkai-bin/shinkai-node/src/network/v2_api/api_v2_commands_app_files.rs @@ -6,6 +6,7 @@ use async_channel::Sender; use reqwest::StatusCode; use serde_json::Value; use shinkai_sqlite::SqliteManager; +use shinkai_tools_primitives::tools::shinkai_tool::ShinkaiTool; use std::path::PathBuf; use std::sync::Arc; @@ -15,7 +16,7 @@ use shinkai_http_api::node_api_router::APIError; pub fn get_app_folder_path(node_env: NodeEnvironment, app_id: String) -> PathBuf { let mut origin_path: PathBuf = PathBuf::from(node_env.node_storage_path.clone().unwrap_or_default()); origin_path.push("app_files"); - origin_path.push(app_id); + origin_path.push(ShinkaiTool::convert_to_path(&app_id)); origin_path } @@ -143,7 +144,7 @@ impl Node { return Ok(()); } let app_folder_path = get_app_folder_path(node_env, app_id); - let result = Self::v2_api_list_app_files_internal(app_folder_path); + let result = Self::v2_api_list_app_files_internal(app_folder_path, false); match result { Ok(file_list) => { let _ = res @@ -160,7 +161,7 @@ impl Node { } } - pub fn v2_api_list_app_files_internal(app_folder_path: PathBuf) -> Result, APIError> { + pub fn v2_api_list_app_files_internal(app_folder_path: PathBuf, absolute: bool) -> Result, APIError> { let files = std::fs::read_dir(&app_folder_path); if let Err(err) = files { let api_error = APIError { @@ -175,8 +176,17 @@ impl Node { let files = files.unwrap(); for file in files { if let Ok(file) = file { - let file_name = file.file_name().to_string_lossy().to_string(); - file_list.push(file_name); + if absolute { + file_list.push( + file.path() + .canonicalize() + .unwrap_or(file.path()) + .to_string_lossy() + .to_string(), + ); + } else { + file_list.push(file.file_name().to_string_lossy().to_string()); + } } } Ok(file_list) diff --git a/shinkai-libs/shinkai-http-api/src/api_v2/api_v2_handlers_app_files.rs b/shinkai-libs/shinkai-http-api/src/api_v2/api_v2_handlers_app_files.rs index c16a5b274..08e1bf909 100644 --- a/shinkai-libs/shinkai-http-api/src/api_v2/api_v2_handlers_app_files.rs +++ b/shinkai-libs/shinkai-http-api/src/api_v2/api_v2_handlers_app_files.rs @@ -31,8 +31,8 @@ pub fn app_files_routes( .and(warp::query::>()) .and_then(get_file_handler); - let update_file_route = warp::path("app_file") - .and(warp::patch()) + let update_file_route = warp::path("patch_app_file") + .and(warp::post()) .and(with_sender(node_commands_sender.clone())) .and(warp::header::("authorization")) .and(warp::header::("x-shinkai-tool-id")) @@ -156,8 +156,8 @@ pub async fn upload_file_handler( // } #[utoipa::path( - patch, - path = "/v2/app_file", + post, + path = "/v2/patch_app_file", request_body = UpdateFileRequest, responses( (status = 200, description = "Successfully updated file", body = Value), diff --git a/shinkai-libs/shinkai-tools-primitives/src/tools/deno_tools.rs b/shinkai-libs/shinkai-tools-primitives/src/tools/deno_tools.rs index b23bc8dd2..01d9bfe95 100644 --- a/shinkai-libs/shinkai-tools-primitives/src/tools/deno_tools.rs +++ b/shinkai-libs/shinkai-tools-primitives/src/tools/deno_tools.rs @@ -221,6 +221,13 @@ impl DenoTool { code_files.insert(format!("{}.ts", file_name), file_code.clone()); }); + let mount_files = mounts + .clone() + .unwrap_or_default() + .iter() + .map(|mount| PathBuf::from(mount)) + .collect(); + // Setup the engine with the code files and config let tool = DenoRunner::new( CodeFiles { @@ -235,12 +242,7 @@ impl DenoTool { code_id: "".to_string(), storage: full_path.clone(), assets_files, - mount_files: mounts - .clone() - .unwrap_or_default() - .iter() - .map(|mount| PathBuf::from(mount)) - .collect(), + mount_files, }, deno_binary_path: PathBuf::from( env::var("SHINKAI_TOOLS_RUNNER_DENO_BINARY_PATH")