diff --git a/files/proxy_identities_test.csv b/files/proxy_identities_test.csv new file mode 100644 index 000000000..cf1de5469 --- /dev/null +++ b/files/proxy_identities_test.csv @@ -0,0 +1,3 @@ +identity1,127.0.0.1:8000,127.0.0.1:8001 +identity2,127.0.0.1:8002,127.0.0.1:8003 +identity3,127.0.0.1:8004,127.0.0.1:8005 \ No newline at end of file diff --git a/src/db/mod.rs b/src/db/mod.rs index ba4efe448..cdf447d2e 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -12,4 +12,5 @@ pub mod db_toolkits; pub mod db_utils; pub mod db_retry; pub mod db_files_transmission; -pub mod db_job_queue; \ No newline at end of file +pub mod db_job_queue; +pub mod db_proxy; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 59c4fef3e..564f7fd1f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ use crate::utils::qr_code_setup::generate_qr_codes; use async_channel::{bounded, Receiver, Sender}; use ed25519_dalek::{PublicKey as SignaturePublicKey, SecretKey as SignatureStaticKey}; use network::Node; +use network::node::NodeProxyMode; use shinkai_message_primitives::shinkai_message::shinkai_message_schemas::{IdentityPermissions, RegistrationCodeType}; use shinkai_message_primitives::shinkai_utils::encryption::{ encryption_public_key_to_string, encryption_secret_key_to_string, @@ -112,7 +113,7 @@ fn main() { db_path, node_env.first_device_needs_registration_code, initial_agent, - None // TODO: Add a way to pass proxy settings from env + NodeProxyMode::NoProxy // TODO: Add a way to pass proxy settings from env ) .await }), diff --git a/src/network/mod.rs b/src/network/mod.rs index 2ff4b0b52..7f0b981d8 100644 --- a/src/network/mod.rs +++ b/src/network/mod.rs @@ -5,4 +5,5 @@ pub mod node_internal_commands; pub mod node_api_commands; pub mod node_local_commands; pub mod node_api; -pub mod node_error; \ No newline at end of file +pub mod node_error; +pub mod node_proxy; \ No newline at end of file diff --git a/src/network/node.rs b/src/network/node.rs index 702be8a05..6ed92d11c 100644 --- a/src/network/node.rs +++ b/src/network/node.rs @@ -5,6 +5,7 @@ use core::panic; use ed25519_dalek::{PublicKey as SignaturePublicKey, SecretKey as SignatureStaticKey}; use futures::{future::FutureExt, pin_mut, prelude::*, select}; use log::{debug, error, info, trace, warn}; +use serde::{Deserialize, Serialize}; use shinkai_message_primitives::schemas::agents::serialized_agent::SerializedAgent; use shinkai_message_primitives::schemas::inbox_name::InboxNameError; use shinkai_message_primitives::schemas::shinkai_name::ShinkaiName; @@ -41,6 +42,7 @@ use crate::schemas::smart_inbox::SmartInbox; use super::node_api::{APIError, APIUseRegistrationCodeSuccessResponse}; use super::node_error::NodeError; +use super::node_proxy::NodeProxyMode; pub enum NodeCommand { Shutdown, @@ -222,36 +224,6 @@ pub enum NodeCommand { // A type alias for a string that represents a profile name. type ProfileName = String; -pub enum NodeProxyMode { - // Node acts as a proxy, holds identities it proxies for - // and a flag indicating if it allows new identities - // if the flag is also then it will also clean up saved identities - IsProxy(ProxyMode), - // Node is being proxied, holds its proxy's identity - IsProxied(ProxyIdentity), - // Node is not using a proxy - NoProxy, -} - -#[derive(Clone, Debug)] -pub struct ProxyMode { - // Flag indicating if new identities can be added - pub allow_new_identities: bool, - // Starting node identities - pub proxy_node_identities: HashMap, -} - -#[derive(Clone, Debug)] -pub struct ProxyIdentity { - // Address of the API proxy - pub api_peer: SocketAddr, - // Address of the TCP proxy - pub tcp_peer: SocketAddr, - // Name of the proxied node - // Or the name of my identity proxied - pub shinkai_name: ShinkaiName, -} - // The `Node` struct represents a single node in the network. pub struct Node { // The mode of the node @@ -799,13 +771,13 @@ impl Node { ); // Extract sender's public keys and verify the signature - let sender_profile_name_string = ShinkaiName::from_shinkai_message_only_using_sender_node_name(&message) + let sender_node_name_string = ShinkaiName::from_shinkai_message_only_using_sender_node_name(&message) .unwrap() .get_node_name(); let sender_identity = maybe_identity_manager .lock() .await - .external_profile_to_global_identity(&sender_profile_name_string) + .external_profile_to_global_identity(&sender_node_name_string) .await .unwrap(); @@ -816,7 +788,7 @@ impl Node { ShinkaiLogLevel::Debug, &format!( "{} > Sender Profile Name: {:?}", - receiver_address, sender_profile_name_string + receiver_address, sender_node_name_string ), ); shinkai_log( @@ -836,8 +808,24 @@ impl Node { ); // TODO(Nico): split this part depending on Proxy Mode - - // Save to db + // If we are a proxy, we need to check if the message is for one of our proxied identities + + // TODO: add handle_based_on_message_content_and_encryption back + Ok(()) + } + + pub async fn handle_message_no_proxy( + message: ShinkaiMessage, + sender_node_name_string: String, + // sender_identity: GlobalIdentity, + my_encryption_secret_key: EncryptionStaticKey, + my_signature_secret_key: SignatureStaticKey, + my_node_profile_name: String, + maybe_db: Arc>, + maybe_identity_manager: Arc>, + receiver_address: SocketAddr, + unsafe_sender_address: SocketAddr, + ) -> Result<(), NodeError> { { Node::save_to_db( false, @@ -853,7 +841,7 @@ impl Node { message.clone(), sender_identity.node_encryption_public_key, sender_identity.addr.clone().unwrap(), - sender_profile_name_string, + sender_node_name_string, &my_encryption_secret_key, &my_signature_secret_key, &my_node_profile_name, @@ -864,4 +852,16 @@ impl Node { ) .await } + + pub async fn proxied_handle_message( + message: ShinkaiMessage, + sender_node_name_string: String, + maybe_db: Arc>, + unsafe_sender_address: SocketAddr, + ) -> Result<(), NodeError> { + // check if the message is for one of our proxied identities + // if so then send it to the proxied identity + // + Ok(()) + } } diff --git a/src/network/node_api_commands.rs b/src/network/node_api_commands.rs index 8514d1c0b..c5ed3f039 100644 --- a/src/network/node_api_commands.rs +++ b/src/network/node_api_commands.rs @@ -3,7 +3,7 @@ use std::{convert::TryInto, sync::Arc}; use super::{ node_api::{APIError, APIUseRegistrationCodeSuccessResponse}, node_error::NodeError, - Node, + Node, node_proxy::NodeProxyMode, }; use crate::{ db::db_errors::ShinkaiDBError, @@ -44,7 +44,8 @@ use shinkai_message_primitives::{ clone_static_secret_key, decrypt_with_chacha20poly1305, encryption_public_key_to_string, encryption_secret_key_to_string, string_to_encryption_public_key, EncryptionMethod, }, - signatures::{clone_signature_secret_key, signature_public_key_to_string, string_to_signature_public_key}, shinkai_logging::{shinkai_log, ShinkaiLogOption, ShinkaiLogLevel}, + shinkai_logging::{shinkai_log, ShinkaiLogLevel, ShinkaiLogOption}, + signatures::{clone_signature_secret_key, signature_public_key_to_string, string_to_signature_public_key}, }, }; use std::pin::Pin; @@ -715,7 +716,11 @@ impl Node { shinkai_log( ShinkaiLogOption::Identity, ShinkaiLogLevel::Info, - format!("registration code usage> first device needs registration code?: {:?}", self.first_device_needs_registration_code).as_str(), + format!( + "registration code usage> first device needs registration code?: {:?}", + self.first_device_needs_registration_code + ) + .as_str(), ); let main_profile_exists = match db.main_profile_exists(self.node_profile_name.get_node_name().as_str()) { @@ -735,7 +740,11 @@ impl Node { shinkai_log( ShinkaiLogOption::Identity, ShinkaiLogLevel::Debug, - format!("registration code usage> main_profile_exists: {:?}", main_profile_exists).as_str(), + format!( + "registration code usage> main_profile_exists: {:?}", + main_profile_exists + ) + .as_str(), ); if self.first_device_needs_registration_code == false { @@ -917,7 +926,7 @@ impl Node { if main_profile_exists == false && self.initial_agent.is_some() { std::mem::drop(identity_manager); self.internal_add_agent(self.initial_agent.clone().unwrap()).await?; - } + } let success_response = APIUseRegistrationCodeSuccessResponse { message: success, @@ -1641,8 +1650,11 @@ impl Node { ShinkaiLogLevel::Debug, format!( "api_add_file_to_inbox_with_symmetric_key> filename: {}, hex_blake3_hash: {}, decrypted_file.len(): {}", - filename, hex_blake3_hash, decrypted_file.len() - ).as_str() + filename, + hex_blake3_hash, + decrypted_file.len() + ) + .as_str(), ); match self @@ -1668,6 +1680,91 @@ impl Node { } } + // TODO: move to new file node_proxy.rs + pub async fn handle_send_message( + &self, + potentially_encrypted_msg: ShinkaiMessage, + res: Sender>, + ) -> Result<(), NodeError> { + match &self.proxy_mode { + NodeProxyMode::IsProxied(_) => { + // I received the message! so we are already good + self.api_handle_send_onionized_message(potentially_encrypted_msg, res) + .await + } + NodeProxyMode::IsProxy(_) => { + // send_msg_handler API -> Node + // Check who is the receiver + // Check that the receiver is part of the identities + // Send the message to the receiver using our stored Addr + let recipient_node = ShinkaiName::from_shinkai_message_only_using_recipient_node_name( + &potentially_encrypted_msg.clone(), + ); + match recipient_node { + Ok(recipient_node_name) => { + let result = self.db.lock().await.get_proxied_identity(&recipient_node_name); + match result { + Ok(Some(proxied_identity)) => { + let api_peer = proxied_identity.api_peer; + let client = reqwest::Client::new(); + let res = client + .post(format!("http://{}:{}/v1/send", api_peer.ip(), api_peer.port())) + .json(&potentially_encrypted_msg) + .send() + .await; + match res { + Ok(response) => { + if response.status().is_success() { + Ok(()) + } else { + Err(NodeError { + message: format!( + "Failed to send message to peer: {}", + response.status() + ), + }) + } + } + Err(err) => Err(NodeError { + message: format!("Failed to send message to peer: {}", err), + }), + } + } + Ok(None) => { + shinkai_log( + ShinkaiLogOption::Node, + ShinkaiLogLevel::Debug, + format!("No proxied identity found for node: {}", recipient_node_name).as_str(), + ); + Ok(()) + } + Err(err) => { + shinkai_log( + ShinkaiLogOption::Node, + ShinkaiLogLevel::Error, + format!("Error getting proxied identity: {}", err).as_str(), + ); + Ok(()) + } + } + } + Err(_) => { + shinkai_log( + ShinkaiLogOption::Node, + ShinkaiLogLevel::Error, + "Error getting recipient node name from message", + ); + return Ok(()); + } + } + } + NodeProxyMode::NoProxy => { + self.api_handle_send_onionized_message(potentially_encrypted_msg, res) + .await + } + } + } + pub async fn api_handle_send_onionized_message( &self, potentially_encrypted_msg: ShinkaiMessage, diff --git a/src/network/node_proxy.rs b/src/network/node_proxy.rs new file mode 100644 index 000000000..60989ba26 --- /dev/null +++ b/src/network/node_proxy.rs @@ -0,0 +1,37 @@ +use std::{collections::HashMap, net::SocketAddr}; + +use serde::{Serialize, Deserialize}; +use shinkai_message_primitives::schemas::shinkai_name::ShinkaiName; + + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum NodeProxyMode { + // Node acts as a proxy, holds identities it proxies for + // and a flag indicating if it allows new identities + // if the flag is also then it will also clean up saved identities + IsProxy(IsProxyConf), + // Node is being proxied, holds its proxy's identity + IsProxied(ProxyIdentity), + // Node is not using a proxy + NoProxy, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct IsProxyConf { + // Flag indicating if new identities can be added + pub allow_new_identities: bool, + // Starting node identities + pub proxy_node_identities: HashMap, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ProxyIdentity { + // Address of the API proxy + pub api_peer: SocketAddr, + // Address of the TCP proxy + pub tcp_peer: SocketAddr, + // Name of the proxied node + // Or the name of my identity proxied + pub shinkai_name: ShinkaiName, +} + diff --git a/src/utils/clap.rs b/src/utils/clap.rs new file mode 100644 index 000000000..67e56ca7a --- /dev/null +++ b/src/utils/clap.rs @@ -0,0 +1,49 @@ +use clap::{App, Arg, ArgMatches}; + +pub fn setup_cli() -> ArgMatches<'static> { + App::new("Shinkai") + .version("1.0") + .author("Nico , Rob ") + .about("Shinkai Node Application") + .arg( + Arg::with_name("NODE_PROXY_MODE") + .short("p") + .long("proxy-mode") + .value_name("MODE") + .help("Sets the node proxy mode") + .takes_value(true), + ) + .arg( + Arg::with_name("ALLOW_NEW_IDENTITIES") + .short("a") + .long("allow-new-identities") + .value_name("FLAG") + .help("Sets the flag indicating if new identities can be added") + .takes_value(true), + ) + .arg( + Arg::with_name("PROXY_API_PEER") + .short("api") + .long("api-peer") + .value_name("ADDRESS") + .help("Sets the address of the API proxy") + .takes_value(true), + ) + .arg( + Arg::with_name("PROXY_TCP_PEER") + .short("tcp") + .long("tcp-peer") + .value_name("ADDRESS") + .help("Sets the address of the TCP proxy") + .takes_value(true), + ) + .arg( + Arg::with_name("SHINKAI_NAME") + .short("n") + .long("name") + .value_name("NAME") + .help("Sets the Shinkai name") + .takes_value(true), + ) + .get_matches() +} \ No newline at end of file diff --git a/src/utils/environment.rs b/src/utils/environment.rs index bdfcb2cdb..7f355cb59 100644 --- a/src/utils/environment.rs +++ b/src/utils/environment.rs @@ -1,10 +1,15 @@ +use std::collections::HashMap; use std::env; +use std::fs::File; use std::net::{IpAddr, SocketAddr}; use std::str::FromStr; -use shinkai_message_primitives::schemas::agents::serialized_agent::{SerializedAgent, AgentLLMInterface}; +use csv::ReaderBuilder; +use shinkai_message_primitives::schemas::agents::serialized_agent::{AgentLLMInterface, SerializedAgent}; use shinkai_message_primitives::schemas::shinkai_name::ShinkaiName; +use crate::network::node::{IsProxyConf, NodeProxyMode, ProxyIdentity}; + #[derive(Debug, Clone)] pub struct NodeEnvironment { pub global_identity_name: String, @@ -16,6 +21,75 @@ pub struct NodeEnvironment { pub first_device_needs_registration_code: bool, } +pub fn fetch_node_proxy_mode() -> NodeProxyMode { + let proxy_mode: String = env::var("NODE_PROXY_MODE").unwrap_or_else(|_| "NoProxy".to_string()); + + match proxy_mode.as_str() { + "IsProxy" => { + let allow_new_identities: bool = env::var("ALLOW_NEW_IDENTITIES") + .unwrap_or_else(|_| "false".to_string()) + .parse() + .expect("Failed to parse allow new identities flag"); + + let mut proxy_node_identities: HashMap = HashMap::new(); + + // Get the path of the CSV file from the environment variable + let csv_file_path: String = env::var("PROXY_IDENTITIES_CSV_PATH") + .unwrap_or_else(|_| "proxy_identities.csv".to_string()); + + // Read the CSV file + let file = File::open(&csv_file_path) + .expect(&format!("Could not open {} with content: identity, address_tcp, address_api", csv_file_path)); + let mut reader = ReaderBuilder::new().has_headers(false).from_reader(file); + + + // Parse the identities from the CSV file + for result in reader.records() { + let record = result.expect("Failed to read record"); + let identity = record[0].to_string(); + let tcp_peer: SocketAddr = record[1].parse().expect("Failed to parse TCP peer address"); + let api_peer: SocketAddr = record[2].parse().expect("Failed to parse API peer address"); + let shinkai_name = ShinkaiName::new(identity.clone()).expect("Failed to parse Shinkai name"); + + proxy_node_identities.insert( + identity, + ProxyIdentity { + api_peer, + tcp_peer, + shinkai_name, + }, + ); + } + + NodeProxyMode::IsProxy(IsProxyConf { + allow_new_identities, + proxy_node_identities, + }) + } + "IsProxied" => { + let api_peer: SocketAddr = env::var("PROXY_API_PEER") + .unwrap_or_else(|_| "0.0.0.0:9550".to_string()) + .parse() + .expect("Failed to parse API peer address"); + + let tcp_peer: SocketAddr = env::var("PROXY_TCP_PEER") + .unwrap_or_else(|_| "0.0.0.0:9552".to_string()) + .parse() + .expect("Failed to parse TCP peer address"); + + let shinkai_name: ShinkaiName = + ShinkaiName::new(env::var("GLOBAL_IDENTITY_NAME").unwrap()).expect("Failed to parse Shinkai name"); + + NodeProxyMode::IsProxied(ProxyIdentity { + api_peer, + tcp_peer, + shinkai_name, + }) + } + _ => NodeProxyMode::NoProxy, + } +} + pub fn fetch_agent_env(global_identity: String) -> Option { // Agent let initial_agent_name: String = env::var("INITIAL_AGENT_NAME") @@ -39,20 +113,17 @@ pub fn fetch_agent_env(global_identity: String) -> Option { .expect("Failed to parse agent model e.g. openai:chatgpt3-turbo"); if initial_agent_name.is_empty() - || initial_agent_api_key.is_empty() - || initial_agent_url.is_empty() - || initial_agent_model.is_empty() { + || initial_agent_api_key.is_empty() + || initial_agent_url.is_empty() + || initial_agent_model.is_empty() + { return None; } let model: Result = AgentLLMInterface::from_str(&initial_agent_model); let agent = SerializedAgent { id: initial_agent_name.clone(), - full_identity_name: ShinkaiName::new(format!( - "{}/main/agent/{}", - global_identity, initial_agent_name - )) - .unwrap(), + full_identity_name: ShinkaiName::new(format!("{}/main/agent/{}", global_identity, initial_agent_name)).unwrap(), perform_locally: false, external_url: Some(initial_agent_url), api_key: Some(initial_agent_api_key), diff --git a/tests/agent_integration_tests.rs b/tests/agent_integration_tests.rs index 5e2a2bfd5..0acb75b38 100644 --- a/tests/agent_integration_tests.rs +++ b/tests/agent_integration_tests.rs @@ -14,7 +14,7 @@ use shinkai_message_primitives::shinkai_utils::signatures::{ }; use shinkai_message_primitives::shinkai_utils::utils::hash_string; use shinkai_node::agent::agent; -use shinkai_node::network::node::NodeCommand; +use shinkai_node::network::node::{NodeCommand, NodeProxyMode}; use shinkai_node::network::node_api::APIError; use shinkai_node::network::Node; use std::fs; @@ -133,7 +133,7 @@ fn node_agent_registration() { node1_db_path, true, Some(agent), - None, + NodeProxyMode::NoProxy, ); let node1_handler = tokio::spawn(async move { diff --git a/tests/node_fetch_proxy_mode_tests.rs b/tests/node_fetch_proxy_mode_tests.rs new file mode 100644 index 000000000..d2efbe1dc --- /dev/null +++ b/tests/node_fetch_proxy_mode_tests.rs @@ -0,0 +1,73 @@ +mod utils; +use shinkai_node::{network::node::NodeProxyMode, utils::environment::fetch_node_proxy_mode}; + +#[cfg(test)] +mod tests { + use shinkai_message_primitives::schemas::shinkai_name::ShinkaiName; + + use super::*; + use std::env; + + #[test] + fn test_fetch_node_proxy_mode() { + // Set the environment variables + env::set_var("NODE_PROXY_MODE", "IsProxy"); + env::set_var("ALLOW_NEW_IDENTITIES", "true"); + env::set_var("PROXY_IDENTITIES_CSV_PATH", "./files/proxy_identities_test.csv"); + + // Call the function + let proxy_mode = fetch_node_proxy_mode(); + + // Check the result + match proxy_mode { + NodeProxyMode::IsProxy(conf) => { + assert!(conf.allow_new_identities); + assert_eq!(conf.proxy_node_identities.len(), 3); + assert!(conf.proxy_node_identities.contains_key("identity1")); + assert!(conf.proxy_node_identities.contains_key("identity2")); + assert!(conf.proxy_node_identities.contains_key("identity3")); + } + _ => panic!("Expected IsProxy mode"), + } + } + + #[test] + fn test_fetch_node_is_proxied_mode() { + // Set the environment variables + env::set_var("NODE_PROXY_MODE", "IsProxied"); + env::set_var("PROXY_API_PEER", "127.0.0.1:9550"); + env::set_var("PROXY_TCP_PEER", "127.0.0.1:9552"); + env::set_var("GLOBAL_IDENTITY_NAME", "@@node1.shinkai"); + + // Call the function + let proxy_mode = fetch_node_proxy_mode(); + + // Check the result + match proxy_mode { + NodeProxyMode::IsProxied(conf) => { + assert_eq!(conf.api_peer, "127.0.0.1:9550".parse().unwrap()); + assert_eq!(conf.tcp_peer, "127.0.0.1:9552".parse().unwrap()); + assert_eq!( + conf.shinkai_name, + ShinkaiName::new("@@node1.shinkai".to_string()).unwrap() + ); + } + _ => panic!("Expected IsProxied mode"), + } + } + + #[test] + fn test_fetch_node_no_proxy_mode() { + // Set the environment variables + env::set_var("NODE_PROXY_MODE", "SomeOtherMode"); + + // Call the function + let proxy_mode = fetch_node_proxy_mode(); + + // Check the result + match proxy_mode { + NodeProxyMode::NoProxy => assert!(true), + _ => panic!("Expected NoProxy mode"), + } + } +} diff --git a/tests/node_integration_tests.rs b/tests/node_integration_tests.rs index 1e2664a24..7ee7fa3a8 100644 --- a/tests/node_integration_tests.rs +++ b/tests/node_integration_tests.rs @@ -17,7 +17,7 @@ use shinkai_message_primitives::shinkai_utils::signatures::{ unsafe_deterministic_signature_keypair, }; use shinkai_message_primitives::shinkai_utils::utils::hash_string; -use shinkai_node::network::node::NodeCommand; +use shinkai_node::network::node::{NodeCommand, NodeProxyMode}; use shinkai_node::network::node_api::APIError; use shinkai_node::network::Node; use std::fs; @@ -98,7 +98,7 @@ fn subidentity_registration() { node1_db_path, true, None, - None + NodeProxyMode::NoProxy ); let addr2 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081); @@ -112,7 +112,7 @@ fn subidentity_registration() { node2_db_path, true, None, - None + NodeProxyMode::NoProxy ); // Printing diff --git a/tests/node_retrying_tests.rs b/tests/node_retrying_tests.rs index e7b7cb4d6..7a861ee07 100644 --- a/tests/node_retrying_tests.rs +++ b/tests/node_retrying_tests.rs @@ -12,7 +12,7 @@ use shinkai_message_primitives::shinkai_utils::signatures::{ }; use shinkai_message_primitives::shinkai_utils::utils::hash_string; use shinkai_node::agent::agent; -use shinkai_node::network::node::NodeCommand; +use shinkai_node::network::node::{NodeCommand, NodeProxyMode}; use shinkai_node::network::node_api::APIError; use shinkai_node::network::Node; use std::fs; @@ -92,7 +92,7 @@ fn node_retrying_test() { node1_db_path, true, None, - None + NodeProxyMode::NoProxy ); let addr2 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081); @@ -106,7 +106,7 @@ fn node_retrying_test() { node2_db_path, true, None, - None + NodeProxyMode::NoProxy ); eprintln!("Starting nodes"); diff --git a/tests/utils/test_boilerplate.rs b/tests/utils/test_boilerplate.rs index 60618f896..b87f3cd23 100644 --- a/tests/utils/test_boilerplate.rs +++ b/tests/utils/test_boilerplate.rs @@ -20,7 +20,7 @@ use shinkai_message_primitives::shinkai_utils::signatures::{ unsafe_deterministic_signature_keypair, }; use shinkai_message_primitives::shinkai_utils::utils::hash_string; -use shinkai_node::network::node::NodeCommand; +use shinkai_node::network::node::{NodeCommand, NodeProxyMode}; use shinkai_node::network::node_api::APIError; use shinkai_node::network::Node; use std::fs; @@ -90,7 +90,7 @@ where node1_db_path, false, None, - None + NodeProxyMode::NoProxy, ); eprintln!("Starting Node");