From fa67472177ce761c4ac41fdb548f1cbba1ab7794 Mon Sep 17 00:00:00 2001 From: Cormanz Date: Mon, 29 May 2023 12:36:59 -0400 Subject: [PATCH 1/7] Implement Programmatic Init APIs --- src/{ => api}/config/default.rs | 0 src/{ => api}/config/mod.rs | 27 ++++--------- src/api/mod.rs | 5 +++ src/api/smartgpt.rs | 35 +++++++++++++++++ src/auto/agents/worker/mod.rs | 4 +- src/auto/classify.rs | 6 +-- src/auto/mod.rs | 69 ++------------------------------- src/llms/chatgpt.rs | 11 ++++++ src/llms/mod.rs | 16 ++++++++ src/main.rs | 34 ++-------------- src/memory/mod.rs | 4 ++ src/plugin.rs | 22 +++++++++-- 12 files changed, 109 insertions(+), 124 deletions(-) rename src/{ => api}/config/default.rs (100%) rename src/{ => api}/config/mod.rs (87%) create mode 100644 src/api/mod.rs create mode 100644 src/api/smartgpt.rs diff --git a/src/config/default.rs b/src/api/config/default.rs similarity index 100% rename from src/config/default.rs rename to src/api/config/default.rs diff --git a/src/config/mod.rs b/src/api/config/mod.rs similarity index 87% rename from src/config/mod.rs rename to src/api/config/mod.rs index 58cf10f..d1f6ea6 100644 --- a/src/config/mod.rs +++ b/src/api/config/mod.rs @@ -4,7 +4,7 @@ use colored::Colorize; use serde::{Serialize, Deserialize}; use serde_json::Value; -use crate::{CommandContext, LLM, Plugin, create_browse, create_google, create_filesystem, create_wolfram, create_news, LLMProvider, create_model_chatgpt, Agents, LLMModel, create_model_llama, AgentInfo, MemoryProvider, create_memory_local, create_memory_qdrant, MemorySystem, create_memory_redis, create_assets, PluginStore, create_brainstorm}; +use crate::{CommandContext, LLM, Plugin, create_browse, create_google, create_filesystem, create_wolfram, create_news, LLMProvider, create_model_chatgpt, Agents, LLMModel, create_model_llama, AgentInfo, MemoryProvider, create_memory_local, create_memory_qdrant, MemorySystem, create_memory_redis, create_assets, PluginStore, create_brainstorm, SmartGPT}; mod default; pub use default::*; @@ -72,16 +72,7 @@ pub struct Llm { pub enum AutoType { #[serde(rename = "runner")] Runner { task: String - }, - #[serde(rename = "assistant")] Assistant { - #[serde(rename = "assistant token limit")] token_limit: Option - }, -} - -pub struct ProgramInfo { - pub personality: String, - pub auto_type: AutoType, - pub context: Arc> + } } pub fn list_plugins() -> Vec { @@ -111,7 +102,7 @@ pub fn create_memory_providers() -> Vec> { ] } -pub fn create_llm_model(agent: HashMap) -> Result, Box> { +fn create_llm_model(agent: HashMap) -> Result, Box> { let (model_name, model_config) = agent.iter().next().ok_or(NoLLMError)?; let providers = create_llm_providers(); let llm_provider = providers.iter() @@ -122,7 +113,7 @@ pub fn create_llm_model(agent: HashMap) -> Result) -> Result, Box> { +fn create_memory_model(agent: HashMap) -> Result, Box> { let (model_name, model_config) = agent.iter().next().ok_or(NoLLMError)?; let providers = create_memory_providers(); let memory_provider = providers.iter() @@ -146,7 +137,7 @@ pub fn create_agent(agent: AgentConfig) -> Result> { }) } -pub fn load_config(config: &str) -> Result> { +pub fn load_config(config: &str) -> Result> { let config: Config = serde_yaml::from_str(config)?; let plugins = list_plugins(); @@ -163,11 +154,8 @@ pub fn load_config(config: &str) -> Result> { } let mut context = CommandContext { - auto_type: config.auto_type.clone(), - tool_out: vec![], - variables: HashMap::new(), assets: HashMap::new(), - plugin_data: PluginStore(HashMap::new()), + plugin_data: PluginStore::new(), plugins: vec![], disabled_tools: config.disabled_tools, agents: Agents { @@ -189,9 +177,8 @@ pub fn load_config(config: &str) -> Result> { } } - Ok(ProgramInfo { + Ok(SmartGPT { personality: config.personality, - auto_type: config.auto_type.clone(), context: Arc::new(Mutex::new(context)) }) } \ No newline at end of file diff --git a/src/api/mod.rs b/src/api/mod.rs new file mode 100644 index 0000000..b350f6f --- /dev/null +++ b/src/api/mod.rs @@ -0,0 +1,5 @@ +mod config; +mod smartgpt; + +pub use config::*; +pub use smartgpt::*; \ No newline at end of file diff --git a/src/api/smartgpt.rs b/src/api/smartgpt.rs new file mode 100644 index 0000000..059cafc --- /dev/null +++ b/src/api/smartgpt.rs @@ -0,0 +1,35 @@ +use std::{sync::{Mutex, Arc}, collections::HashMap, error::Error, vec}; + +use serde::Serialize; +use serde_json::Value; + +use crate::{CommandContext, PluginStore, Agents, AgentInfo, LLMProvider, LLMModel, LLM, ChatGPTProvider, ChatGPTConfig, memory_from_provider, LocalProvider}; + +pub struct SmartGPT { + pub personality: String, + pub context: Arc> +} + +impl SmartGPT { + fn create() -> Result<(), Box> { + let smartgpt = SmartGPT { + personality: "A superintelligent AI".to_string(), + context: Arc::new(Mutex::new(CommandContext { + agents: Agents::same(|| Ok(AgentInfo { + llm: LLM::from_provider(ChatGPTProvider, ChatGPTConfig { + api_key: "X".to_string(), + ..Default::default() + })?, + observations: memory_from_provider(LocalProvider, Value::Null)?, + reflections: memory_from_provider(LocalProvider, Value::Null)? + }))?, + plugin_data: PluginStore::new(), + assets: HashMap::new(), + plugins: vec![], + disabled_tools: vec![] + })) + }; + + Ok(()) + } +} \ No newline at end of file diff --git a/src/auto/agents/worker/mod.rs b/src/auto/agents/worker/mod.rs index 6b0b523..413ba86 100644 --- a/src/auto/agents/worker/mod.rs +++ b/src/auto/agents/worker/mod.rs @@ -1,5 +1,5 @@ use std::{error::Error}; -use crate::{ProgramInfo, AgentInfo}; +use crate::{SmartGPT, AgentInfo}; use serde::Serialize; mod adept; @@ -12,7 +12,7 @@ pub use actor::*; pub use methodical::*; pub use tools::*; -pub fn run_employee(program: &mut ProgramInfo, task: &str, personality: &str) -> Result> { +pub fn run_employee(program: &mut SmartGPT, task: &str, personality: &str) -> Result> { let mut context = program.context.lock().unwrap(); /*let refine_info = refine(&mut context, &|context| &mut context.agents.planner, task)?; diff --git a/src/auto/classify.rs b/src/auto/classify.rs index 5c1fb04..8d44415 100644 --- a/src/auto/classify.rs +++ b/src/auto/classify.rs @@ -2,7 +2,7 @@ use std::error::Error; use serde::{Serialize, Deserialize}; -use crate::{ProgramInfo, Message}; +use crate::{SmartGPT, Message}; use super::try_parse_json; @@ -15,8 +15,8 @@ pub struct Classification { classification: String, } -pub fn is_task(program: &mut ProgramInfo, task: &str) -> Result> { - let ProgramInfo { +pub fn is_task(program: &mut SmartGPT, task: &str) -> Result> { + let SmartGPT { context, .. } = program; let mut context = context.lock().unwrap(); diff --git a/src/auto/mod.rs b/src/auto/mod.rs index 80c2059..89c8ae6 100644 --- a/src/auto/mod.rs +++ b/src/auto/mod.rs @@ -5,7 +5,7 @@ use json5; use colored::Colorize; -use crate::{LLM, ProgramInfo, Message }; +use crate::{LLM, SmartGPT, Message }; use self::{responses::{ask_for_responses}, classify::is_task, agents::{processing::find_text_between_braces, worker::run_employee}}; @@ -14,8 +14,8 @@ mod run; mod responses; mod classify; -pub fn run_task_auto(program: &mut ProgramInfo, task: &str) -> Result> { - let ProgramInfo { +pub fn run_task_auto(program: &mut SmartGPT, task: &str) -> Result> { + let SmartGPT { context, .. } = program; let context = context.lock().unwrap(); @@ -25,69 +25,6 @@ pub fn run_task_auto(program: &mut ProgramInfo, task: &str) -> Result) -> Result> { - let ProgramInfo { - context, .. - } = program; - - let token_limit_final: u16 = token_limit.unwrap_or(400u16); - - let context = context.lock().unwrap(); - - let mut new_messages = messages.to_vec(); - new_messages.push(Message::User(format!( -r#"Summarize the conversation."#))); - - let conversation_context = match messages.len() { - 0 => "No conversation context.".to_string(), - _ => context.agents.fast.llm.model.get_response_sync( - &new_messages, Some(300), None - )? - }; - - drop(context); - if is_task(program, request)? { - println!("{}", "Running task...".green()); - - let ProgramInfo { - context, .. - } = program; - let context = context.lock().unwrap(); - - let mut task = request.trim().to_string(); - task = format!( -"Given this relevant conversation context: {conversation_context} - -{task}"); - - drop(context); - - Ok(run_employee(program, &task.clone(), &program.personality.clone())?) - } else { - let ProgramInfo { - context, .. - } = program; - let mut context = context.lock().unwrap(); - - context.agents.fast.llm.prompt.clear(); - context.agents.fast.llm.message_history.clear(); - - context.agents.fast.llm.prompt.push(Message::System(format!( -r#"Respond in this conversation context: - -{conversation_context}"# - ))); - - context.agents.fast.llm.message_history.push(Message::User(request.to_string())); - - context.agents.fast.llm.model.get_response_sync( - &context.agents.fast.llm.get_messages(), - Some(token_limit_final), - None - ) - } -} - #[derive(Debug, Clone)] pub struct CannotParseError; diff --git a/src/llms/chatgpt.rs b/src/llms/chatgpt.rs index 0305e39..ec784c5 100644 --- a/src/llms/chatgpt.rs +++ b/src/llms/chatgpt.rs @@ -79,6 +79,17 @@ pub struct ChatGPTConfig { #[serde(rename = "embedding model")] pub embedding_model: Option, } +impl Default for ChatGPTConfig { + fn default() -> Self { + ChatGPTConfig { + api_key: "Invalid API Key".to_string(), + model: None, + api_base: None, + embedding_model: None + } + } +} + pub struct ChatGPTProvider; #[async_trait] diff --git a/src/llms/mod.rs b/src/llms/mod.rs index 41ca5bc..eacf813 100644 --- a/src/llms/mod.rs +++ b/src/llms/mod.rs @@ -3,6 +3,7 @@ mod local; pub use chatgpt::*; pub use local::*; +use serde::Serialize; use tokio::runtime::Runtime; use std::{error::Error, fmt::Display}; @@ -121,6 +122,21 @@ pub struct LLM { } impl LLM { + pub fn from_provider(provider: impl LLMProvider, config: T) -> Result> { + let model = provider.create(serde_json::to_value(config)?)?; + + Ok(Self::new(model)) + } + + pub fn new(model: Box) -> LLM { + LLM { + prompt: vec![], + end_prompt: vec![], + message_history: vec![], + model + } + } + pub fn get_tokens_remaining(&self, messages: &[Message]) -> Result> { self.model.get_tokens_remaining(messages) } diff --git a/src/main.rs b/src/main.rs index 7358bc5..59e66f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ mod plugins; mod tools; mod chunk; mod llms; -mod config; +mod api; mod runner; mod memory; mod auto; @@ -17,13 +17,13 @@ pub use plugins::*; pub use tools::*; pub use chunk::*; pub use llms::*; -pub use config::*; +pub use api::*; pub use runner::*; pub use memory::*; use serde::{Deserialize, Serialize}; -use crate::auto::{run_task_auto, run_assistant_auto}; +use crate::auto::run_task_auto; #[derive(Serialize, Deserialize)] pub struct NewEndGoal { @@ -60,7 +60,6 @@ fn main() -> Result<(), Box> { print!("\x1B[2J\x1B[1;1H"); println!("{}: {}", "Personality".blue(), program.personality); - println!("{}: {:?}", "Type".blue(), program.auto_type.clone()); println!("{}:", "Plugins".blue()); let mut exit_dependency_error = false; @@ -110,32 +109,7 @@ fn main() -> Result<(), Box> { drop(context); - match program.auto_type.clone() { - AutoType::Assistant { token_limit } => { - let mut messages: Vec = vec![]; - let stdin = io::stdin(); - loop { - println!("{}", "> User".yellow()); - - let mut input = String::new(); - stdin.read_line(&mut input).unwrap(); - - println!(); - - let response = run_assistant_auto(&mut program, &messages, &input, token_limit)?; - - messages.push(Message::User(input)); - messages.push(Message::Assistant(response.clone())); - - println!("{}", "> Assistant".yellow()); - println!("{}", response); - println!(); - } - }, - AutoType::Runner { task } => { - run_task_auto(&mut program, &task)?; - } - } + run_task_auto(&mut program, "Write an essay on the Rust programming language.")?; Ok(()) } \ No newline at end of file diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 35b5d68..f749dce 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -134,6 +134,10 @@ pub trait MemorySystem : Send + Sync { } } +pub fn memory_from_provider(provider: impl MemoryProvider, config: T) -> Result, Box> { + provider.create(serde_json::to_value(config)?) +} + #[async_trait] pub trait MemoryProvider { fn is_enabled(&self) -> bool; diff --git a/src/plugin.rs b/src/plugin.rs index c570b85..d91c4e9 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -35,6 +35,12 @@ pub trait PluginData: Any + Send + Sync { pub struct PluginStore(pub HashMap>); +impl PluginStore { + pub fn new() -> Self { + Self(HashMap::new()) + } +} + pub struct EndGoals { pub end_goal: usize, pub end_goals: Vec @@ -59,13 +65,23 @@ pub struct Agents { pub fast: AgentInfo } +impl Agents { + pub fn same(init: impl Fn() -> Result>) -> Result> { + Ok( + Agents { + static_agent: init()?, + planner: init()?, + dynamic: init()?, + fast: init()? + } + ) + } +} + pub struct CommandContext { - pub auto_type: AutoType, pub plugin_data: PluginStore, pub agents: Agents, pub plugins: Vec, - pub variables: HashMap, - pub tool_out: Vec, pub disabled_tools: Vec, pub assets: HashMap } From 6aa42fdbdc552f7dbb3b29608d15466f49a9c6c1 Mon Sep 17 00:00:00 2001 From: Cormanz Date: Mon, 29 May 2023 17:48:24 -0400 Subject: [PATCH 2/7] Implement Running Tasks via API --- src/api/smartgpt.rs | 12 +++++++++-- src/auto/agents/worker/adept.rs | 28 ++++++++++++++++++------ src/auto/agents/worker/methodical.rs | 20 ++++++++++++++--- src/auto/agents/worker/mod.rs | 32 ++++++++++++++++++---------- src/auto/agents/worker/tools.rs | 7 ++++-- src/auto/agents/worker/updates.rs | 24 +++++++++++++++++++++ src/auto/classify.rs | 4 ++-- src/auto/mod.rs | 30 +++++++++++++++++++++----- src/main.rs | 14 +++++++----- src/plugin.rs | 2 +- src/plugins/assets/mod.rs | 2 +- 11 files changed, 137 insertions(+), 38 deletions(-) create mode 100644 src/auto/agents/worker/updates.rs diff --git a/src/api/smartgpt.rs b/src/api/smartgpt.rs index 059cafc..6c46a31 100644 --- a/src/api/smartgpt.rs +++ b/src/api/smartgpt.rs @@ -3,8 +3,7 @@ use std::{sync::{Mutex, Arc}, collections::HashMap, error::Error, vec}; use serde::Serialize; use serde_json::Value; -use crate::{CommandContext, PluginStore, Agents, AgentInfo, LLMProvider, LLMModel, LLM, ChatGPTProvider, ChatGPTConfig, memory_from_provider, LocalProvider}; - +use crate::{CommandContext, PluginStore, Agents, AgentInfo, LLMProvider, LLMModel, LLM, ChatGPTProvider, ChatGPTConfig, memory_from_provider, LocalProvider, auto::{run_auto, Action, DisallowedAction, Update}}; pub struct SmartGPT { pub personality: String, pub context: Arc> @@ -32,4 +31,13 @@ impl SmartGPT { Ok(()) } + + pub fn run_task( + &mut self, + task: &str, + allow_action: &impl Fn(&Action) -> Result<(), DisallowedAction>, + listen_to_update: &impl Fn(&Update) -> Result<(), Box> + ) -> Result> { + run_auto(self, task, allow_action, listen_to_update) + } } \ No newline at end of file diff --git a/src/auto/agents/worker/adept.rs b/src/auto/agents/worker/adept.rs index 8308682..42ce93e 100644 --- a/src/auto/agents/worker/adept.rs +++ b/src/auto/agents/worker/adept.rs @@ -2,7 +2,9 @@ use std::{error::Error, ops::Deref, fmt::Display}; use colored::Colorize; use serde::{Serialize, Deserialize}; -use crate::{CommandContext, AgentInfo, Message, auto::{try_parse_json, agents::{worker::{log_yaml, run_method_agent}}}, ScriptValue}; +use crate::{CommandContext, AgentInfo, Message, auto::{try_parse_json, agents::{worker::{log_yaml, run_method_agent}}, run::Action, DisallowedAction, DynamicUpdate}, ScriptValue}; + +use super::Update; #[derive(Debug, Clone)] pub struct NoDecisionTypeError(pub String); @@ -62,7 +64,9 @@ pub fn get_response( get_agent: &impl Fn(&mut CommandContext) -> &mut AgentInfo, get_planner_agent: &impl Fn(&mut CommandContext) -> &mut AgentInfo, thoughts: &BrainThoughts, - personality: &str + personality: &str, + allow_action: &impl Fn(&Action) -> Result<(), DisallowedAction>, + listen_to_update: &impl Fn(&Update) -> Result<(), Box> ) -> Result> { match thoughts.decision.decision_type.deref() { "spawn_agent" => { @@ -79,7 +83,7 @@ pub fn get_response( ); } - let out = run_method_agent(context, get_agent, get_planner_agent, &instruction, &desire, data, personality)?; + let out = run_method_agent(context, get_agent, get_planner_agent, &instruction, &desire, data, personality, allow_action, listen_to_update)?; println!("\n{out}\n"); Ok(out) }, @@ -101,7 +105,9 @@ pub fn run_brain_agent( context: &mut CommandContext, get_agent: &impl Fn(&mut CommandContext) -> &mut AgentInfo, task: &str, - personality: &str + personality: &str, + allow_action: &impl Fn(&Action) -> Result<(), DisallowedAction>, + listen_to_update: &impl Fn(&Update) -> Result<(), Box> ) -> Result> { let agent = get_agent(context); @@ -128,6 +134,8 @@ Respond in this JSON format: agent.llm.message_history.push(Message::Assistant(plan.raw)); let plan = plan.data; + listen_to_update(&Update::DynamicAgent(DynamicUpdate::Plan(plan.plan.clone())))?; + log_yaml(&plan)?; agent.llm.message_history.push(Message::User(format!(r#" @@ -170,6 +178,8 @@ Respond in this exact JSON format exactly, with every field in order: agent.llm.message_history.push(Message::Assistant(thoughts.raw)); let thoughts = thoughts.data; + listen_to_update(&Update::DynamicAgent(DynamicUpdate::Thoughts(thoughts.clone())))?; + log_yaml(&thoughts)?; drop(agent); @@ -178,7 +188,9 @@ Respond in this exact JSON format exactly, with every field in order: &|ctx| &mut ctx.agents.static_agent, &|ctx| &mut ctx.agents.planner, &thoughts, - &personality + &personality, + allow_action, + listen_to_update )?; if thoughts.decision.decision_type == "final_response" { @@ -228,6 +240,8 @@ You may only provide these assets when spawning agents. agent.llm.message_history.push(Message::Assistant(thoughts.raw)); let thoughts = thoughts.data; + listen_to_update(&Update::DynamicAgent(DynamicUpdate::Thoughts(thoughts.clone())))?; + log_yaml(&thoughts)?; response = get_response( @@ -235,7 +249,9 @@ You may only provide these assets when spawning agents. &|ctx| &mut ctx.agents.static_agent, &|ctx| &mut ctx.agents.planner, &thoughts, - &personality + &personality, + allow_action, + listen_to_update )?; if thoughts.decision.decision_type == "final_response" { diff --git a/src/auto/agents/worker/methodical.rs b/src/auto/agents/worker/methodical.rs index e61dee8..005e675 100644 --- a/src/auto/agents/worker/methodical.rs +++ b/src/auto/agents/worker/methodical.rs @@ -3,7 +3,7 @@ use std::{error::Error, collections::{HashSet}}; use colored::Colorize; use serde::{Serialize, Deserialize}; -use crate::{CommandContext, AgentInfo, Message, auto::{run::Action, try_parse_json, agents::worker::create_tool_list}, Weights, Tool}; +use crate::{CommandContext, AgentInfo, Message, auto::{run::Action, try_parse_json, agents::worker::create_tool_list, DisallowedAction, StaticUpdate, Update, NamedAsset}, Weights, Tool}; use super::{log_yaml, use_tool}; @@ -95,7 +95,9 @@ pub fn run_method_agent( task: &str, desire: &str, assets: Option, - personality: &str + personality: &str, + allow_action: &impl Fn(&Action) -> Result<(), DisallowedAction>, + listen_to_update: &impl Fn(&Update) -> Result<(), Box> ) -> Result> { let tools: Vec<&Tool> = context.plugins.iter() .flat_map(|plugin| &plugin.tools) @@ -201,6 +203,8 @@ Respond in this JSON format: let plan = plan.data; log_yaml(&plan)?; + listen_to_update(&Update::StaticAgent(StaticUpdate::Plan(plan.clone())))?; + let prompt = planner.llm.prompt.clone(); let message_history = planner.llm.message_history.clone(); @@ -258,6 +262,9 @@ action: drop(agent); + listen_to_update(&Update::StaticAgent(StaticUpdate::Thoughts(thoughts.clone())))?; + allow_action(&thoughts.action)?; + let out = use_tool(context, &|context| &mut context.agents.fast, thoughts.action.clone()); println!(); @@ -266,6 +273,7 @@ action: let agent = get_agent(context); println!("{out}"); + listen_to_update(&Update::StaticAgent(StaticUpdate::ActionResults(out.clone())))?; agent.llm.message_history.push(Message::User(out)); let tokens = agent.llm.get_tokens_remaining(&agent.llm.get_messages())?; @@ -297,11 +305,17 @@ action: .map(|asset| asset.to_string()) .collect::>(); + let changed_assets: Vec = changed_assets.iter() + .map(|asset| NamedAsset(asset.clone(), context.assets[asset].clone())) + .collect(); + + listen_to_update(&Update::StaticAgent(StaticUpdate::AddedAssets(changed_assets.clone())))?; + let asset_str = if changed_assets.len() == 0 { format!("No assets changed.") } else { changed_assets .iter() - .map(|el| format!("## Asset `{el}`\n{}", context.assets[el])) + .map(|el| format!("## Asset `{}`\n{}", el.0, el.1)) .collect::>() .join("\n") }; diff --git a/src/auto/agents/worker/mod.rs b/src/auto/agents/worker/mod.rs index 413ba86..9514ac9 100644 --- a/src/auto/agents/worker/mod.rs +++ b/src/auto/agents/worker/mod.rs @@ -1,26 +1,36 @@ use std::{error::Error}; -use crate::{SmartGPT, AgentInfo}; +use crate::{SmartGPT, AgentInfo, auto::{run::Action, DisallowedAction}}; use serde::Serialize; mod adept; mod actor; mod methodical; mod tools; +mod updates; pub use adept::*; pub use actor::*; pub use methodical::*; pub use tools::*; - -pub fn run_employee(program: &mut SmartGPT, task: &str, personality: &str) -> Result> { - let mut context = program.context.lock().unwrap(); - - /*let refine_info = refine(&mut context, &|context| &mut context.agents.planner, task)?; - log_yaml(&refine_info)?; - - let task = &refine_info.task;*/ - - let response = run_brain_agent(&mut context, &|ctx| &mut ctx.agents.dynamic, task, personality)?; +pub use updates::*; + +pub fn run_worker( + smartgpt: &mut SmartGPT, + task: &str, + personality: &str, + allow_action: &impl Fn(&Action) -> Result<(), DisallowedAction>, + listen_to_update: &impl Fn(&Update) -> Result<(), Box> +) -> Result> { + let mut context = smartgpt.context.lock().unwrap(); + + let response = run_brain_agent( + &mut context, + &|ctx| &mut ctx.agents.dynamic, + task, + personality, + allow_action, + listen_to_update + )?; Ok(response) } diff --git a/src/auto/agents/worker/tools.rs b/src/auto/agents/worker/tools.rs index 5cecb46..087934d 100644 --- a/src/auto/agents/worker/tools.rs +++ b/src/auto/agents/worker/tools.rs @@ -1,10 +1,13 @@ +use std::mem::discriminant; + use crate::{Tool, ToolArgument, ToolType}; pub fn create_filtered_tool_list(header: &str, tools: &[&Tool], tool_type: ToolType) -> String { let mut prompt = header.to_string(); for tool in tools { - if tool.tool_type != tool_type { + // Compares if the tool types are the same, not the values of the tool types + if discriminant(&tool.tool_type) == discriminant(&tool_type) { continue; } @@ -29,6 +32,6 @@ pub fn create_filtered_tool_list(header: &str, tools: &[&Tool], tool_type: ToolT pub fn create_tool_list(tools: &[&Tool]) -> String { vec![ create_filtered_tool_list("Resources", tools, ToolType::Resource), - create_filtered_tool_list("Resources", tools, ToolType::Action) + create_filtered_tool_list("Actions", tools, ToolType::Action { needs_permission: false }) ].join("\n\n") } \ No newline at end of file diff --git a/src/auto/agents/worker/updates.rs b/src/auto/agents/worker/updates.rs new file mode 100644 index 0000000..6ab593e --- /dev/null +++ b/src/auto/agents/worker/updates.rs @@ -0,0 +1,24 @@ +use super::{BrainThoughts, MethodicalPlan, MethodicalThoughts}; + +#[derive(Clone, Debug)] +pub struct NamedAsset(pub String, pub String); + +#[derive(Clone, Debug)] +pub enum DynamicUpdate { + Plan(String), + Thoughts(BrainThoughts) +} + +#[derive(Clone, Debug)] +pub enum StaticUpdate { + Plan(MethodicalPlan), + Thoughts(MethodicalThoughts), + ActionResults(String), + AddedAssets(Vec) +} + +#[derive(Clone, Debug)] +pub enum Update { + DynamicAgent(DynamicUpdate), + StaticAgent(StaticUpdate) +} \ No newline at end of file diff --git a/src/auto/classify.rs b/src/auto/classify.rs index 8d44415..d4542f6 100644 --- a/src/auto/classify.rs +++ b/src/auto/classify.rs @@ -15,10 +15,10 @@ pub struct Classification { classification: String, } -pub fn is_task(program: &mut SmartGPT, task: &str) -> Result> { +pub fn is_task(smartgpt: &mut SmartGPT, task: &str) -> Result> { let SmartGPT { context, .. - } = program; + } = smartgpt; let mut context = context.lock().unwrap(); context.agents.fast.llm.clear_history(); diff --git a/src/auto/mod.rs b/src/auto/mod.rs index 89c8ae6..7ac3cb1 100644 --- a/src/auto/mod.rs +++ b/src/auto/mod.rs @@ -5,24 +5,44 @@ use json5; use colored::Colorize; -use crate::{LLM, SmartGPT, Message }; +use crate::{LLM, SmartGPT}; -use self::{responses::{ask_for_responses}, classify::is_task, agents::{processing::find_text_between_braces, worker::run_employee}}; +use self::{agents::{processing::find_text_between_braces, worker::run_worker}}; mod agents; mod run; mod responses; mod classify; -pub fn run_task_auto(program: &mut SmartGPT, task: &str) -> Result> { +pub use run::{Action}; +pub use agents::worker::*; + +#[derive(Debug)] +pub struct DisallowedAction(Box); + +impl Error for DisallowedAction {} +impl Display for DisallowedAction { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "DisallowedAction(")?; + write!(f, "{}", self.0); + write!(f, ")") + } +} + +pub fn run_auto( + smartgpt: &mut SmartGPT, + task: &str, + allow_action: &impl Fn(&Action) -> Result<(), DisallowedAction>, + listen_to_update: &impl Fn(&Update) -> Result<(), Box> +) -> Result> { let SmartGPT { context, .. - } = program; + } = smartgpt; let context = context.lock().unwrap(); drop(context); - Ok(run_employee(program, task.clone(), &program.personality.clone())?) + Ok(run_worker(smartgpt, task.clone(), &smartgpt.personality.clone(), allow_action, listen_to_update)?) } #[derive(Debug, Clone)] diff --git a/src/main.rs b/src/main.rs index 59e66f2..f411dce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,7 +23,7 @@ pub use memory::*; use serde::{Deserialize, Serialize}; -use crate::auto::run_task_auto; +use crate::auto::run_auto; #[derive(Serialize, Deserialize)] pub struct NewEndGoal { @@ -56,15 +56,15 @@ fn main() -> Result<(), Box> { } }; - let mut program = load_config(&config)?; + let mut smartgpt = load_config(&config)?; print!("\x1B[2J\x1B[1;1H"); - println!("{}: {}", "Personality".blue(), program.personality); + println!("{}: {}", "Personality".blue(), smartgpt.personality); println!("{}:", "Plugins".blue()); let mut exit_dependency_error = false; - let context = program.context.lock().unwrap(); + let context = smartgpt.context.lock().unwrap(); for plugin in &context.plugins { for dependency in &plugin.dependencies { @@ -109,7 +109,11 @@ fn main() -> Result<(), Box> { drop(context); - run_task_auto(&mut program, "Write an essay on the Rust programming language.")?; + smartgpt.run_task( + "Write an essay on the Rust programming language.", + &|_| Ok(()), + &|_| Ok(()) + )?; Ok(()) } \ No newline at end of file diff --git a/src/plugin.rs b/src/plugin.rs index d91c4e9..d261efc 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -164,7 +164,7 @@ impl ToolArgument { #[derive(Clone, Eq, PartialEq)] pub enum ToolType { Resource, - Action + Action { needs_permission: bool } } pub struct Tool { diff --git a/src/plugins/assets/mod.rs b/src/plugins/assets/mod.rs index 5e18572..13e7301 100644 --- a/src/plugins/assets/mod.rs +++ b/src/plugins/assets/mod.rs @@ -45,7 +45,7 @@ pub fn create_assets() -> Plugin { ToolArgument::new("lines", r#"[ "line 1", "line 2" ]"#) ], run: Box::new(SaveAssetImpl), - tool_type: ToolType::Action + tool_type: ToolType::Action { needs_permission: false } } ] } From 2f816c32ea1e31774dc79429464be8e95e7808bd Mon Sep 17 00:00:00 2001 From: Cormanz Date: Mon, 29 May 2023 18:33:08 -0400 Subject: [PATCH 3/7] Separation of Logs --- src/auto/agents/worker/adept.rs | 13 ------ src/auto/agents/worker/methodical.rs | 29 ++++-------- src/auto/agents/worker/updates.rs | 6 ++- src/log.rs | 67 ++++++++++++++++++++++++++++ src/main.rs | 6 ++- 5 files changed, 83 insertions(+), 38 deletions(-) create mode 100644 src/log.rs diff --git a/src/auto/agents/worker/adept.rs b/src/auto/agents/worker/adept.rs index 42ce93e..5929ac0 100644 --- a/src/auto/agents/worker/adept.rs +++ b/src/auto/agents/worker/adept.rs @@ -84,7 +84,6 @@ pub fn get_response( } let out = run_method_agent(context, get_agent, get_planner_agent, &instruction, &desire, data, personality, allow_action, listen_to_update)?; - println!("\n{out}\n"); Ok(out) }, "brainstorm" => { @@ -128,16 +127,12 @@ Respond in this JSON format: ``` "#).trim().to_string())); - println!("{}\n", "Dynamic Agent".blue().bold()); - let plan = try_parse_json::(&agent.llm, 2, Some(1000), Some(0.3))?; agent.llm.message_history.push(Message::Assistant(plan.raw)); let plan = plan.data; listen_to_update(&Update::DynamicAgent(DynamicUpdate::Plan(plan.plan.clone())))?; - log_yaml(&plan)?; - agent.llm.message_history.push(Message::User(format!(r#" Your goal is to complete the task by spawning agents to complete smaller subtasks. Focus on using thoughts, reasoning, and self-criticism to complete your goals. @@ -172,16 +167,12 @@ Respond in this exact JSON format exactly, with every field in order: }} ```"#, plan.plan))); - println!("{}\n", "Dynamic Agent".blue().bold()); - let thoughts = try_parse_json::(&agent.llm, 2, Some(1000), Some(0.3))?; agent.llm.message_history.push(Message::Assistant(thoughts.raw)); let thoughts = thoughts.data; listen_to_update(&Update::DynamicAgent(DynamicUpdate::Thoughts(thoughts.clone())))?; - log_yaml(&thoughts)?; - drop(agent); let mut response = get_response( context, @@ -234,16 +225,12 @@ You may only provide these assets when spawning agents. ``` "#).trim().to_string())); - println!("{}\n", "Dynamic Agent".blue().bold()); - let thoughts = try_parse_json::(&agent.llm, 2, Some(1000), Some(0.5))?; agent.llm.message_history.push(Message::Assistant(thoughts.raw)); let thoughts = thoughts.data; listen_to_update(&Update::DynamicAgent(DynamicUpdate::Thoughts(thoughts.clone())))?; - log_yaml(&thoughts)?; - response = get_response( context, &|ctx| &mut ctx.agents.static_agent, diff --git a/src/auto/agents/worker/methodical.rs b/src/auto/agents/worker/methodical.rs index 005e675..5d65511 100644 --- a/src/auto/agents/worker/methodical.rs +++ b/src/auto/agents/worker/methodical.rs @@ -58,7 +58,10 @@ pub struct Memories { pub observations: Vec } -pub fn add_memories(agent: &mut AgentInfo) -> Result<(), Box> { +pub fn add_memories( + agent: &mut AgentInfo, + listen_to_update: &impl Fn(&Update) -> Result<(), Box> +) -> Result<(), Box> { agent.llm.message_history.push(Message::User(format!(r#" Please summarize all important actions you took out. Please also summarize all observations of information you have collected. @@ -79,7 +82,7 @@ Respond in this JSON format: "#).trim().to_string())); let memories = try_parse_json::(&agent.llm, 2, Some(700), Some(0.5))?.data; - log_yaml(&memories)?; + listen_to_update(&Update::StaticAgent(StaticUpdate::SavedMemories(memories.clone())))?; for memory in memories.actions.iter().chain(memories.observations.iter()) { agent.observations.store_memory_sync(&agent.llm, memory)?; @@ -138,8 +141,6 @@ Personality: let data = assets.unwrap_or(format!("No assets.")); - println!("{} {}\n", "Static Agent".yellow().bold(), "| Plan".white()); - planner.llm.prompt.push(Message::User(format!(r#" {tools} @@ -201,8 +202,6 @@ Respond in this JSON format: let plan = try_parse_json::(&planner.llm, 2, Some(600), Some(0.3))?; planner.llm.message_history.push(Message::Assistant(plan.raw)); let plan = plan.data; - log_yaml(&plan)?; - listen_to_update(&Update::StaticAgent(StaticUpdate::Plan(plan.clone())))?; let prompt = planner.llm.prompt.clone(); @@ -216,15 +215,9 @@ Respond in this JSON format: for (_ind, step) in plan.steps.iter().enumerate() { let agent = get_agent(context); - - println!(); - println!("{} {}\n", "Static Agent".yellow().bold(), "| Selecting Step".white()); - let step_text = serde_yaml::to_string(&step)?; - println!("{}", step_text); - println!(); - println!("{} {}\n", "Static Agent".yellow().bold(), "| Running Step".white()); + listen_to_update(&Update::StaticAgent(StaticUpdate::SelectedStep(step.clone())))?; agent.llm.message_history.push(Message::User(format!(r#" Now you will carry out the next step: @@ -258,8 +251,6 @@ action: agent.llm.message_history.push(Message::Assistant(thoughts.raw)); let thoughts = thoughts.data; - log_yaml(&thoughts)?; - drop(agent); listen_to_update(&Update::StaticAgent(StaticUpdate::Thoughts(thoughts.clone())))?; @@ -267,18 +258,16 @@ action: let out = use_tool(context, &|context| &mut context.agents.fast, thoughts.action.clone()); - println!(); match out { Ok(out) => { let agent = get_agent(context); - println!("{out}"); listen_to_update(&Update::StaticAgent(StaticUpdate::ActionResults(out.clone())))?; agent.llm.message_history.push(Message::User(out)); let tokens = agent.llm.get_tokens_remaining(&agent.llm.get_messages())?; if tokens < 1200 { - match add_memories(agent) { + match add_memories(agent, listen_to_update) { Ok(_) => {}, Err(_) => { agent.llm.crop_to_tokens_remaining(1000)?; @@ -294,13 +283,11 @@ action: } let agent = get_agent(context); - add_memories(agent)?; + add_memories(agent, listen_to_update)?; let cloned_assets = context.assets.clone(); let assets_after: HashSet<&String> = cloned_assets.keys().collect(); - println!("{assets_before:?}, {assets_after:?}"); - let changed_assets = assets_after.difference(&assets_before) .map(|asset| asset.to_string()) .collect::>(); diff --git a/src/auto/agents/worker/updates.rs b/src/auto/agents/worker/updates.rs index 6ab593e..6505198 100644 --- a/src/auto/agents/worker/updates.rs +++ b/src/auto/agents/worker/updates.rs @@ -1,4 +1,4 @@ -use super::{BrainThoughts, MethodicalPlan, MethodicalThoughts}; +use super::{BrainThoughts, MethodicalPlan, MethodicalThoughts, MethodicalStep, Memories}; #[derive(Clone, Debug)] pub struct NamedAsset(pub String, pub String); @@ -12,9 +12,11 @@ pub enum DynamicUpdate { #[derive(Clone, Debug)] pub enum StaticUpdate { Plan(MethodicalPlan), + SelectedStep(MethodicalStep), Thoughts(MethodicalThoughts), ActionResults(String), - AddedAssets(Vec) + AddedAssets(Vec), + SavedMemories(Memories) } #[derive(Clone, Debug)] diff --git a/src/log.rs b/src/log.rs new file mode 100644 index 0000000..f2f1432 --- /dev/null +++ b/src/log.rs @@ -0,0 +1,67 @@ +use std::error::Error; + +use colored::Colorize; + +use crate::auto::{Update, DynamicUpdate, StaticUpdate, log_yaml, NamedAsset}; + +pub fn log_update(update: &Update) -> Result<(), Box> { + match update { + Update::DynamicAgent(update) => { + match update { + DynamicUpdate::Plan(plan) => { + println!("{} | {}", "Dynamic Agent".blue().bold(), "Created Plan".white()); + println!(); + println!("{plan}"); + println!(); + }, + DynamicUpdate::Thoughts(thoughts) => { + println!("{} | {}", "Dynamic Agent".blue().bold(), "Made Decision".white()); + println!(); + log_yaml(&thoughts)?; + println!(); + } + } + }, + Update::StaticAgent(update) => { + match update { + StaticUpdate::Plan(plan) => { + println!("{} | {}", "Static Agent".yellow().bold(), "Created Plan".white()); + println!(); + log_yaml(&plan)?; + println!(); + }, + StaticUpdate::SelectedStep(step) => { + println!("{} | {}", "Static Agent".yellow().bold(), "Selected Step".white()); + println!(); + log_yaml(&step)?; + println!(); + }, + StaticUpdate::Thoughts(thoughts) => { + println!("{} | {}", "Static Agent".yellow().bold(), "Running Step".white()); + println!(); + log_yaml(&thoughts)?; + println!(); + }, + StaticUpdate::ActionResults(out) => { + println!("{} | {}", "Static Agent".yellow().bold(), "Ran Action".white()); + println!(); + println!("{out}"); + println!(); + }, + StaticUpdate::AddedAssets(assets) => { + println!("{} | {}", "Static Agent".yellow().bold(), "Added Assets".white()); + println!(); + for NamedAsset(name, content) in assets { + println!("{} {}", ">".white(), name.bold()); + println!("{content}"); + println!(); + } + println!(); + }, + _ => {} + } + } + } + + Ok(()) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index f411dce..07d7a4a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ mod api; mod runner; mod memory; mod auto; +mod log; pub use plugin::*; pub use plugins::*; @@ -20,10 +21,11 @@ pub use llms::*; pub use api::*; pub use runner::*; pub use memory::*; +pub use log::*; use serde::{Deserialize, Serialize}; -use crate::auto::run_auto; +use crate::auto::{run_auto, DynamicUpdate, Update, log_yaml, StaticUpdate, NamedAsset}; #[derive(Serialize, Deserialize)] pub struct NewEndGoal { @@ -112,7 +114,7 @@ fn main() -> Result<(), Box> { smartgpt.run_task( "Write an essay on the Rust programming language.", &|_| Ok(()), - &|_| Ok(()) + &log_update )?; Ok(()) From 5f36c8fea308b10d7f6b1391c2f4c9e4fbbb59d2 Mon Sep 17 00:00:00 2001 From: Cormanz Date: Mon, 29 May 2023 19:03:30 -0400 Subject: [PATCH 4/7] Create lib.rs --- src/api/smartgpt.rs | 22 ------------------- src/auto/agents/worker/methodical.rs | 7 ++---- src/lib.rs | 20 +++++++++++++++++ src/log.rs | 1 - src/main.rs | 33 ++-------------------------- 5 files changed, 24 insertions(+), 59 deletions(-) create mode 100644 src/lib.rs diff --git a/src/api/smartgpt.rs b/src/api/smartgpt.rs index 6c46a31..ef73d8a 100644 --- a/src/api/smartgpt.rs +++ b/src/api/smartgpt.rs @@ -10,28 +10,6 @@ pub struct SmartGPT { } impl SmartGPT { - fn create() -> Result<(), Box> { - let smartgpt = SmartGPT { - personality: "A superintelligent AI".to_string(), - context: Arc::new(Mutex::new(CommandContext { - agents: Agents::same(|| Ok(AgentInfo { - llm: LLM::from_provider(ChatGPTProvider, ChatGPTConfig { - api_key: "X".to_string(), - ..Default::default() - })?, - observations: memory_from_provider(LocalProvider, Value::Null)?, - reflections: memory_from_provider(LocalProvider, Value::Null)? - }))?, - plugin_data: PluginStore::new(), - assets: HashMap::new(), - plugins: vec![], - disabled_tools: vec![] - })) - }; - - Ok(()) - } - pub fn run_task( &mut self, task: &str, diff --git a/src/auto/agents/worker/methodical.rs b/src/auto/agents/worker/methodical.rs index 5d65511..5dca312 100644 --- a/src/auto/agents/worker/methodical.rs +++ b/src/auto/agents/worker/methodical.rs @@ -168,9 +168,10 @@ Do not specify arguments. Do not "repeat steps". Keep your plan at as low steps as possible. - Keep your plan as concise as possible! +Make sure the last step in your plan uses `save_asset`. + Respond in this JSON format: ```json {{ @@ -240,10 +241,6 @@ Respond in this JSON format: "args": {{}} }} }} -thoughts: thoughts -action: - tool: tool - args: {{}} ``` "#).trim().to_string())); diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..0644231 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,20 @@ +mod plugin; +mod plugins; +mod tools; +mod chunk; +mod llms; +mod api; +mod runner; +mod memory; +mod auto; +mod log; + +pub use plugin::*; +pub use plugins::*; +pub use tools::*; +pub use chunk::*; +pub use llms::*; +pub use api::*; +pub use runner::*; +pub use memory::*; +pub use log::*; \ No newline at end of file diff --git a/src/log.rs b/src/log.rs index f2f1432..b4681cb 100644 --- a/src/log.rs +++ b/src/log.rs @@ -1,7 +1,6 @@ use std::error::Error; use colored::Colorize; - use crate::auto::{Update, DynamicUpdate, StaticUpdate, log_yaml, NamedAsset}; pub fn log_update(update: &Update) -> Result<(), Box> { diff --git a/src/main.rs b/src/main.rs index 07d7a4a..06d37a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,36 +1,7 @@ -use std::{error::Error, fmt::Display, process, fs, io}; - +use std::{error::Error, fmt::Display, process, fs}; use colored::Colorize; -mod plugin; -mod plugins; -mod tools; -mod chunk; -mod llms; -mod api; -mod runner; -mod memory; -mod auto; -mod log; - -pub use plugin::*; -pub use plugins::*; -pub use tools::*; -pub use chunk::*; -pub use llms::*; -pub use api::*; -pub use runner::*; -pub use memory::*; -pub use log::*; - -use serde::{Deserialize, Serialize}; - -use crate::auto::{run_auto, DynamicUpdate, Update, log_yaml, StaticUpdate, NamedAsset}; - -#[derive(Serialize, Deserialize)] -pub struct NewEndGoal { - #[serde(rename = "new end goal")] new_end_goal: String -} +pub use smartgpt::*; #[derive(Debug, Clone)] pub struct NoThoughtError; From 7f56d59c2c88a5e14505d8c8f16c12a7fd8246e8 Mon Sep 17 00:00:00 2001 From: Cormanz Date: Mon, 29 May 2023 19:25:14 -0400 Subject: [PATCH 5/7] Implement SmartGPT API --- src/api/smartgpt.rs | 22 ++++++++++++++++++++++ src/auto/mod.rs | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/api/smartgpt.rs b/src/api/smartgpt.rs index ef73d8a..6c46a31 100644 --- a/src/api/smartgpt.rs +++ b/src/api/smartgpt.rs @@ -10,6 +10,28 @@ pub struct SmartGPT { } impl SmartGPT { + fn create() -> Result<(), Box> { + let smartgpt = SmartGPT { + personality: "A superintelligent AI".to_string(), + context: Arc::new(Mutex::new(CommandContext { + agents: Agents::same(|| Ok(AgentInfo { + llm: LLM::from_provider(ChatGPTProvider, ChatGPTConfig { + api_key: "X".to_string(), + ..Default::default() + })?, + observations: memory_from_provider(LocalProvider, Value::Null)?, + reflections: memory_from_provider(LocalProvider, Value::Null)? + }))?, + plugin_data: PluginStore::new(), + assets: HashMap::new(), + plugins: vec![], + disabled_tools: vec![] + })) + }; + + Ok(()) + } + pub fn run_task( &mut self, task: &str, diff --git a/src/auto/mod.rs b/src/auto/mod.rs index 7ac3cb1..36f7b28 100644 --- a/src/auto/mod.rs +++ b/src/auto/mod.rs @@ -24,7 +24,7 @@ impl Error for DisallowedAction {} impl Display for DisallowedAction { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "DisallowedAction(")?; - write!(f, "{}", self.0); + write!(f, "{}", self.0)?; write!(f, ")") } } From 1c19a95c409fc053894247025c62ae7a0b2e4c8f Mon Sep 17 00:00:00 2001 From: Cormanz Date: Mon, 29 May 2023 19:28:06 -0400 Subject: [PATCH 6/7] Add Cargo Metadata --- Cargo.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 6c6c180..11653e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,13 @@ name = "smartgpt" version = "0.1.0" edition = "2021" +license = "MIT" +description = "A crate that provides LLMs with the ability to complete complex tasks using plugins." +homepage = "https://smartgpt.dev" +repository = "https://github.com/Cormanz/smartgpt" +documentation = "https://corman.gitbook.io/smartgpt/" +keywords = [ "llm", "agent", "autogpt" ] +readme = "README.md" [dependencies] async-openai = "0.10.2" From 927360243abea9ae5465cfd165cd4310607c9c29 Mon Sep 17 00:00:00 2001 From: Cormanz Date: Mon, 29 May 2023 19:30:20 -0400 Subject: [PATCH 7/7] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 63a09c2..3579d0b 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Currently, testing with SmartGPT is primarily being done with GPT3.5, and occasi SmartGPT is an **incredibly experimental** application. The goal is to unlock maximum potential out of LLMs, and stability is sacrificed for this. Backwards compatibility is a fever dream here. However, SmartGPT is also housing some of the most innovative ideas and experiments in the AutoGPT space right now, and although most are unsuccessful, a few hit the dart-board and stick. -## Cargo Quickstart +## Quickstart 1. Install [`cargo`](https://doc.rust-lang.org/cargo/getting-started/installation.html), preferably the latest stable version. @@ -49,7 +49,7 @@ SmartGPT is an **incredibly experimental** application. The goal is to unlock ma 4. Adjust the config to your liking, and execute it once again. -If you want more information, [read the documentation](https://corman.gitbook.io/smartgpt/installation). +If you want more information, or would like to use SmartGPT as a crate in your own projects, [read the documentation](https://corman.gitbook.io/smartgpt/installation). # How SmartGPT Works