diff --git a/Cargo.lock b/Cargo.lock index 2cf60aa..252db9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1042,9 +1042,9 @@ dependencies = [ name = "amico" version = "0.0.1" dependencies = [ - "amico-core", + "amico-core 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "amico-mods", - "amico-sdk", + "amico-sdk 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "anyhow", "colored", "cpal", @@ -1077,9 +1077,40 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "amico-core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69124ffec3a019204b9dc5a56449a468d28e0b4b3974f27def0f6a1ea85d325" +dependencies = [ + "anyhow", + "chrono", + "evenio", + "serde", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tokio_with_wasm", + "tracing", +] + [[package]] name = "amico-hal" -version = "0.0.1" +version = "0.0.2" +dependencies = [ + "cpal", + "hound", + "lame", + "rodio", + "thiserror 2.0.12", + "tokio", +] + +[[package]] +name = "amico-hal" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df54ab3c901b6482a7ea2d22094ef8eeef55d0ca137846ac8309df8c72bdb21f" dependencies = [ "cpal", "hound", @@ -1091,12 +1122,12 @@ dependencies = [ [[package]] name = "amico-mods" -version = "0.0.1" +version = "0.0.3" dependencies = [ "alloy", - "amico-core", - "amico-hal", - "amico-sdk", + "amico-core 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "amico-hal 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "amico-sdk 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "anyhow", "async-trait", "base64 0.22.1", @@ -1139,11 +1170,29 @@ dependencies = [ "tokio_with_wasm", ] +[[package]] +name = "amico-sdk" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30449bb561d77ac41acaddd31c57b85ab716b7a2549c435935156d442597d234" +dependencies = [ + "anyhow", + "async-trait", + "mcp-core", + "mcp-core-macros", + "rig-core", + "serde", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tokio_with_wasm", +] + [[package]] name = "amico-wasm" version = "0.0.1" dependencies = [ - "amico-core", + "amico-core 1.0.2", "anyhow", "async-trait", "console_error_panic_hook", diff --git a/Cargo.toml b/Cargo.toml index 053dde8..86acda7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,10 @@ nostr-sdk = "0.38.0" nostr = "0.38.0" chrono = { version = "0.4.41", features = ["serde"] } tokio_with_wasm = { version = "0.8.5", features = ["rt"] } + +# Released Amico crates +amico-core = "1.0.2" +amico-sdk = "1.0.0" + +# Dev releases +amico-hal = { version = "0.0.2", default-features = false } diff --git a/amico-hal/Cargo.toml b/amico-hal/Cargo.toml index d3cb390..2eb6ea3 100644 --- a/amico-hal/Cargo.toml +++ b/amico-hal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "amico-hal" -version = "0.0.1" +version = "0.0.2" edition = "2024" description = "The HAL of the Amico AI Agent Framework" repository = "https://github.com/AIMOverse/amico" diff --git a/amico-mods/Cargo.toml b/amico-mods/Cargo.toml index bc3160b..222770b 100644 --- a/amico-mods/Cargo.toml +++ b/amico-mods/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "amico-mods" -version = "0.0.1" +version = "0.0.3" edition = "2024" description = "The plugins of the Amico AI Agent Framework" repository = "https://github.com/AIMOverse/amico" @@ -23,11 +23,11 @@ std-cli-chatbot = [] std-audio-chatbot = ["dep:amico-hal", "amico-hal/os-common"] # Core plugins -std-core = ["amico-core", "chrono"] +std-core = ["chrono"] # Runtime -storage-fs = ["amico-core"] -storage-in-mem = ["amico-core"] +storage-fs = [] +storage-in-mem = [] # A2A features a2a = ["amico-sdk/a2a", "sodiumoxide", "base64"] @@ -70,9 +70,9 @@ full = [ ] [dependencies] -amico-sdk = { path = "../amico-sdk", default-features = false } -amico-hal = { path = "../amico-hal", default-features = false, optional = true } -amico-core = { path = "../amico-core", default-features = false, optional = true } +amico-sdk = { workspace = true } +amico-hal = { workspace = true, optional = true } +amico-core = { workspace = true } # Plugin-specific dependencies diff --git a/amico-mods/src/interface.rs b/amico-mods/src/interface.rs new file mode 100644 index 0000000..6bf35f2 --- /dev/null +++ b/amico-mods/src/interface.rs @@ -0,0 +1,54 @@ +use amico_core::{Agent, traits::Strategy}; + +/// A module is a plugin that can be applied to an agent. +pub trait Module { + /// Apply the module to an agent. + fn apply(&self, agent: &mut Agent); +} + +#[cfg(test)] +mod tests { + use amico_core::{ + Agent, + traits::{PhantomEvent, Strategy, System}, + }; + + use crate::Module; + + struct TestSystem; + + impl System for TestSystem { + fn register_to(self, mut registry: amico_core::world::HandlerRegistry) { + registry.register(|_: amico_core::ecs::Receiver| { + println!("inside TestSystem handler"); + }); + } + } + + struct TestStrategy; + + impl Strategy for TestStrategy { + async fn deliberate( + &mut self, + _agent_event: &amico_core::types::AgentEvent, + _sender: amico_core::world::ActionSender<'_>, + ) -> anyhow::Result<()> { + Ok(()) + } + } + + struct TestModule; + + impl Module for TestModule { + fn apply(&self, agent: &mut amico_core::Agent) { + println!("Applying TestModule"); + agent.add_system(TestSystem); + } + } + + #[tokio::test] + async fn test_build_agent_with_module() { + let mut agent = Agent::new(TestStrategy); + TestModule.apply(&mut agent); + } +} diff --git a/amico-mods/src/interface/mod.rs b/amico-mods/src/interface/mod.rs deleted file mode 100644 index a866635..0000000 --- a/amico-mods/src/interface/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod plugin; -pub use plugin::*; diff --git a/amico-mods/src/interface/plugin.rs b/amico-mods/src/interface/plugin.rs deleted file mode 100644 index b1b2070..0000000 --- a/amico-mods/src/interface/plugin.rs +++ /dev/null @@ -1,54 +0,0 @@ -use serde::{Deserialize, Serialize}; - -/// Every plugin must implement the `Plugin` trait to get necessary information. -pub trait Plugin { - fn info(&self) -> &'static PluginInfo; -} - -/// The information of a plugin -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -pub struct PluginInfo { - pub name: &'static str, - pub category: PluginCategory, -} - -/// The category of a plugin -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -pub enum PluginCategory { - // High level - Sensor, - Effector, - Service, - Api, - - // Low level - Embedding, - EventGenerator, - ActionSelector, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_impl_plugin() { - // Implement the interface - struct TestPlugin; - - impl Plugin for TestPlugin { - fn info(&self) -> &'static PluginInfo { - &PluginInfo { - name: "TestPlugin", - category: PluginCategory::Sensor, - } - } - } - - let plugin = TestPlugin; - assert_eq!(plugin.info().name, "TestPlugin"); - assert_eq!(plugin.info().category, PluginCategory::Sensor); - } -} diff --git a/amico-mods/src/lib.rs b/amico-mods/src/lib.rs index ff5f081..44d5887 100644 --- a/amico-mods/src/lib.rs +++ b/amico-mods/src/lib.rs @@ -1,5 +1,3 @@ -pub mod interface; -pub mod plugin_manager; pub mod runtime; pub mod std; @@ -11,3 +9,6 @@ pub mod a2a; #[cfg(feature = "aoe")] pub mod aoe; + +mod interface; +pub use interface::*; diff --git a/amico-mods/src/plugin_manager/loader.rs b/amico-mods/src/plugin_manager/loader.rs deleted file mode 100644 index c9c213d..0000000 --- a/amico-mods/src/plugin_manager/loader.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct PluginLoader; diff --git a/amico-mods/src/plugin_manager/mod.rs b/amico-mods/src/plugin_manager/mod.rs deleted file mode 100644 index 4ff6f92..0000000 --- a/amico-mods/src/plugin_manager/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod loader; - -pub use loader::*; diff --git a/amico-mods/src/std/ai/providers/rig.rs b/amico-mods/src/std/ai/providers/rig.rs index 0b67b7d..623fee5 100644 --- a/amico-mods/src/std/ai/providers/rig.rs +++ b/amico-mods/src/std/ai/providers/rig.rs @@ -6,7 +6,6 @@ use rig::{ use std::fmt::Debug; use super::rig_helpers::*; -use crate::interface::{Plugin, PluginCategory, PluginInfo}; /// Re-export providers from rig-core /// so that SDK users do not need to add `rig-core` as a dependency @@ -94,12 +93,3 @@ impl Model for RigProvider { provider_completion(self, &req.model, into_rig_request(req)).await } } - -impl Plugin for RigProvider { - fn info(&self) -> &'static PluginInfo { - &PluginInfo { - name: "StdOpenAIProvider", - category: PluginCategory::Service, - } - } -} diff --git a/amico-mods/src/std/ai/services/in_memory.rs b/amico-mods/src/std/ai/services/in_memory.rs index 25fde5b..b5ae025 100644 --- a/amico-mods/src/std/ai/services/in_memory.rs +++ b/amico-mods/src/std/ai/services/in_memory.rs @@ -1,4 +1,3 @@ -use crate::interface::{Plugin, PluginCategory, PluginInfo}; use amico::{ ai::{ completion::{Error, Model, ModelChoice, RequestBuilder, Session, SessionContext}, @@ -37,15 +36,6 @@ pub struct InMemoryService { pub history: Vec, } -impl Plugin for InMemoryService { - fn info(&self) -> &'static PluginInfo { - &PluginInfo { - name: "StdInMemoryService", - category: PluginCategory::Service, - } - } -} - impl Session for InMemoryService { type Model = M; @@ -135,6 +125,6 @@ impl Session for InMemoryService { impl IntoResourceMut> for InMemoryService { fn into_resource_mut(self) -> ResourceMut> { - ResourceMut::new(self.info().name, self) + ResourceMut::new("InMemoryService", self) } } diff --git a/amico/Cargo.toml b/amico/Cargo.toml index 56fb6b7..b2fef2d 100644 --- a/amico/Cargo.toml +++ b/amico/Cargo.toml @@ -7,9 +7,9 @@ repository = "https://github.com/AIMOverse/amico" license = "MIT OR Apache-2.0" [dependencies] -amico-core = { path = "../amico-core" } +amico-core = { workspace = true } tokio = { workspace = true, features = ["full"] } -amico-sdk = { path = "../amico-sdk" } +amico-sdk = { workspace = true } amico-mods = { path = "../amico-mods" } serde_json = { workspace = true } tracing = { workspace = true } diff --git a/amico/src/main.rs b/amico/src/main.rs index 6f0dd1b..80a4e14 100644 --- a/amico/src/main.rs +++ b/amico/src/main.rs @@ -3,7 +3,6 @@ use std::process; use amico::ai::completion::SessionBuilder; use amico::resource::{IntoResource, IntoResourceMut}; use amico_core::{Agent, OnFinish}; -use amico_mods::interface::Plugin; use amico_mods::runtime::storage::fs::FsStorage; use amico_mods::std::ai::providers::rig::{RigProvider, providers}; use amico_mods::std::ai::services::InMemoryService; @@ -132,7 +131,6 @@ async fn main() { println!("{}", wallet.get().pubkey_list()); println!(); - println!("Using service plugin: {}", service.info().name); println!("Tools enabled:\n{}", service.ctx.tools.describe()); let service_resource = service.into_resource_mut();