From d8eac7b8bb5d05873b6bbf86e6d94fb0f174f758 Mon Sep 17 00:00:00 2001 From: Archer Date: Fri, 6 Jun 2025 13:20:50 +0800 Subject: [PATCH 1/7] rename MCP methods --- amico-sdk/src/ai/services/completion.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/amico-sdk/src/ai/services/completion.rs b/amico-sdk/src/ai/services/completion.rs index 391e6e3..75030f9 100644 --- a/amico-sdk/src/ai/services/completion.rs +++ b/amico-sdk/src/ai/services/completion.rs @@ -18,17 +18,13 @@ pub trait CompletionService { type Model: CompletionModel; /// A service should be built from a context - fn from(context: ServiceContext) -> Self - where - Self: Sized; + fn from(context: ServiceContext) -> Self; /// Generates text based on a prompt. fn generate_text( &mut self, prompt: String, - ) -> impl Future> + Send - where - Self: Sized; + ) -> impl Future> + Send; } #[async_trait] @@ -139,17 +135,21 @@ where self } - /// Add a MCP tool to the Service. + /// Add a MCP tool to the Service by definition. #[cfg(feature = "mcp-client")] - pub fn mcp_tool(mut self, mcp_tool: mcp_core::types::Tool, mcp_client: McpClient) -> Self { + pub fn mcp_tool_definition( + mut self, + tool_definition: mcp_core::types::Tool, + mcp_client: McpClient, + ) -> Self { self.tool_list - .push(McpTool::from_mcp_server(mcp_tool, mcp_client).into()); + .push(McpTool::from_mcp_server(tool_definition, mcp_client).into()); self } /// Add all MCP tools from a server to the Service. #[cfg(feature = "mcp-client")] - pub async fn add_tools_from_server(mut self, mcp_client: McpClient) -> anyhow::Result { + pub async fn mcp_tools_from_server(mut self, mcp_client: McpClient) -> anyhow::Result { mcp_client .list_tools(None, None) .await? @@ -163,8 +163,9 @@ where Ok(self) } + /// Add a MCP tool to the Service by name. #[cfg(feature = "mcp-client")] - pub async fn mcp_tool_name( + pub async fn mcp_tool( mut self, tool_name: String, mcp_client: McpClient, From c525ac55f150e9c507ccba4f230cb76dda67b106 Mon Sep 17 00:00:00 2001 From: Archer Date: Fri, 6 Jun 2025 13:48:02 +0800 Subject: [PATCH 2/7] refactor completion service --- amico-mods/src/std/ai/providers/rig.rs | 14 +--- .../src/std/ai/providers/rig_helpers.rs | 9 +- amico-mods/src/std/ai/services/in_memory.rs | 24 +++--- amico-sdk/src/ai/completion/error.rs | 14 ++++ amico-sdk/src/ai/completion/mod.rs | 7 ++ .../completion.rs => completion/model.rs} | 59 ++++++------- .../completion.rs => completion/session.rs} | 84 +++++++++---------- amico-sdk/src/ai/errors.rs | 23 ----- amico-sdk/src/ai/mod.rs | 3 +- amico-sdk/src/ai/models/embedding.rs | 1 - amico-sdk/src/ai/models/mod.rs | 4 - amico-sdk/src/ai/services/mod.rs | 3 - amico/src/engine/systems.rs | 2 +- amico/src/main.rs | 4 +- 14 files changed, 107 insertions(+), 144 deletions(-) create mode 100644 amico-sdk/src/ai/completion/error.rs create mode 100644 amico-sdk/src/ai/completion/mod.rs rename amico-sdk/src/ai/{models/completion.rs => completion/model.rs} (75%) rename amico-sdk/src/ai/{services/completion.rs => completion/session.rs} (81%) delete mode 100644 amico-sdk/src/ai/models/embedding.rs delete mode 100644 amico-sdk/src/ai/models/mod.rs delete mode 100644 amico-sdk/src/ai/services/mod.rs diff --git a/amico-mods/src/std/ai/providers/rig.rs b/amico-mods/src/std/ai/providers/rig.rs index 6fa9d32..0b67b7d 100644 --- a/amico-mods/src/std/ai/providers/rig.rs +++ b/amico-mods/src/std/ai/providers/rig.rs @@ -1,7 +1,4 @@ -use amico::ai::{ - errors::CompletionModelError, - models::{CompletionModel, CompletionRequest, ModelChoice}, -}; +use amico::ai::completion::{Error as CompletionError, Model, ModelChoice, Request}; use rig::{ completion::{self as rc, CompletionModel as _}, providers as rp, @@ -22,7 +19,7 @@ async fn provider_completion( provider: &RigProvider, model_name: &str, request: rc::CompletionRequest, -) -> Result { +) -> Result { match provider { RigProvider::Anthropic(client) => client .completion_model(model_name) @@ -91,12 +88,9 @@ impl RigProvider { } } -impl CompletionModel for RigProvider { +impl Model for RigProvider { #[doc = " Completes a prompt with the provider."] - async fn completion( - &self, - req: &CompletionRequest, - ) -> Result { + async fn completion(&self, req: &Request) -> Result { provider_completion(self, &req.model, into_rig_request(req)).await } } diff --git a/amico-mods/src/std/ai/providers/rig_helpers.rs b/amico-mods/src/std/ai/providers/rig_helpers.rs index 6169518..4cd0a6a 100644 --- a/amico-mods/src/std/ai/providers/rig_helpers.rs +++ b/amico-mods/src/std/ai/providers/rig_helpers.rs @@ -1,7 +1,6 @@ use amico::ai::{ - errors::CompletionModelError, + completion::{ModelChoice, Request}, message::Message, - models::{CompletionRequest, ModelChoice}, tool::ToolDefinition, }; use rig::{OneOrMany, completion as rc, message as rm}; @@ -46,8 +45,8 @@ pub fn into_amico_choice(response: rc::CompletionResponse) -> ModelChoice } /// Convert `rig`'s `CompletionError` into `amico`'s `CompletionModelError` -pub fn into_amico_err(error: rc::CompletionError) -> CompletionModelError { - CompletionModelError::ProviderError(error.to_string()) +pub fn into_amico_err(error: rc::CompletionError) -> amico::ai::completion::Error { + amico::ai::completion::Error::Model(error.to_string()) } /// Convert `amico`'s `Tool` into `rig`'s `ToolDefinition` @@ -60,7 +59,7 @@ pub fn into_rig_tool_def(def: &ToolDefinition) -> rig::completion::ToolDefinitio } /// Convert `amico`'s `CompletionRequest` into `rig`'s -pub fn into_rig_request(request: &CompletionRequest) -> rc::CompletionRequest { +pub fn into_rig_request(request: &Request) -> rc::CompletionRequest { // Documented in `rig-core`: // The very last message will always be the prompt (hense why there is *always* one) diff --git a/amico-mods/src/std/ai/services/in_memory.rs b/amico-mods/src/std/ai/services/in_memory.rs index 5730465..67e035a 100644 --- a/amico-mods/src/std/ai/services/in_memory.rs +++ b/amico-mods/src/std/ai/services/in_memory.rs @@ -1,10 +1,8 @@ use crate::interface::{Plugin, PluginCategory, PluginInfo}; use amico::{ ai::{ - errors::ServiceError, + completion::{Error, Model, ModelChoice, RequestBuilder, Session, SessionContext}, message::Message, - models::{CompletionModel, CompletionRequestBuilder, ModelChoice}, - services::ServiceContext, }, resource::{IntoResourceMut, ResourceMut}, }; @@ -31,15 +29,15 @@ fn debug_history(history: &[Message]) -> String { } #[derive(Debug)] -pub struct InMemoryService { +pub struct InMemoryService { /// The context config for the service - pub ctx: ServiceContext, + pub ctx: SessionContext, /// In-memory Chat history storage pub history: Vec, } -impl Plugin for InMemoryService { +impl Plugin for InMemoryService { fn info(&self) -> &'static PluginInfo { &PluginInfo { name: "StdInMemoryService", @@ -48,31 +46,31 @@ impl Plugin for InMemoryService { } } -impl amico::ai::services::CompletionService for InMemoryService { +impl Session for InMemoryService { type Model = M; - fn from(context: ServiceContext) -> Self { + fn from(context: SessionContext) -> Self { Self { ctx: context, history: Vec::new(), } } - async fn generate_text(&mut self, prompt: String) -> Result { + async fn generate_text(&mut self, prompt: String) -> Result { // Append the new user prompt to chat history. self.history.push(Message::User(prompt)); // Generate the final text loop { // Call the LLM API wrapper with the current prompt and chat history. - let request = CompletionRequestBuilder::from_ctx(&self.ctx) + let request = RequestBuilder::from_ctx(&self.ctx) // We've already added the user prompt to the history, so no need to add it again // .prompt(prompt.clone()) .history(self.history.clone()) .build(); // Call the LLM API wrapper with the current prompt and chat history. - match self.ctx.completion_model.completion(&request).await { + match self.ctx.model.completion(&request).await { // When a plain message is received, update the chat history and return the response. Ok(ModelChoice::Message(msg)) => { tracing::debug!("Received message response: {}", msg); @@ -128,14 +126,14 @@ impl amico::ai::services::CompletionService for InMem // Handle potential errors from the API call. Err(err) => { tracing::error!("Provider error: {}", err); - return Err(ServiceError::CompletionModelError(err)); + return Err(Error::Model(err.to_string())); } } } } } -impl IntoResourceMut> for InMemoryService { +impl IntoResourceMut> for InMemoryService { fn into_resource_mut(self) -> ResourceMut> { ResourceMut::new(self.info().name, self) } diff --git a/amico-sdk/src/ai/completion/error.rs b/amico-sdk/src/ai/completion/error.rs new file mode 100644 index 0000000..6ffc169 --- /dev/null +++ b/amico-sdk/src/ai/completion/error.rs @@ -0,0 +1,14 @@ +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("Model error: {0}")] + Model(String), + + #[error("Model name {0} is not available")] + ModelNameNotAvailable(String), + + #[error("Bad response: {0}")] + BadResponse(String), + + #[error("Tool error: {0}")] + Tool(String), +} diff --git a/amico-sdk/src/ai/completion/mod.rs b/amico-sdk/src/ai/completion/mod.rs new file mode 100644 index 0000000..32f5564 --- /dev/null +++ b/amico-sdk/src/ai/completion/mod.rs @@ -0,0 +1,7 @@ +mod error; +mod model; +mod session; + +pub use error::*; +pub use model::*; +pub use session::*; diff --git a/amico-sdk/src/ai/models/completion.rs b/amico-sdk/src/ai/completion/model.rs similarity index 75% rename from amico-sdk/src/ai/models/completion.rs rename to amico-sdk/src/ai/completion/model.rs index af4dc87..4832a5a 100644 --- a/amico-sdk/src/ai/models/completion.rs +++ b/amico-sdk/src/ai/completion/model.rs @@ -1,50 +1,41 @@ use async_trait::async_trait; use serde::{Deserialize, Serialize}; -use crate::ai::errors::CompletionModelError; -use crate::ai::{message::Message, services::ServiceContext, tool::ToolDefinition}; +use crate::ai::{ + completion::{Error, SessionContext}, + message::Message, + tool::ToolDefinition, +}; /// Trait for completion models. -pub trait CompletionModel { +pub trait Model { /// Completes a prompt with the provider. fn completion( &self, - request: &CompletionRequest, - ) -> impl Future> + Send; + request: &Request, + ) -> impl Future> + Send; } #[async_trait] -pub trait CompletionModelDyn { - async fn completion_dyn( - &self, - request: &CompletionRequest, - ) -> Result; +pub trait ModelDyn { + async fn completion_dyn(&self, request: &Request) -> Result; } #[async_trait(?Send)] -pub trait CompletionModelLocal { - async fn completion_local( - &self, - request: &CompletionRequest, - ) -> Result; +pub trait ModelLocal { + async fn completion_local(&self, request: &Request) -> Result; } #[async_trait] -impl CompletionModelDyn for T { - async fn completion_dyn( - &self, - request: &CompletionRequest, - ) -> Result { +impl ModelDyn for T { + async fn completion_dyn(&self, request: &Request) -> Result { self.completion(request).await } } #[async_trait(?Send)] -impl CompletionModelLocal for T { - async fn completion_local( - &self, - request: &CompletionRequest, - ) -> Result { +impl ModelLocal for T { + async fn completion_local(&self, request: &Request) -> Result { self.completion(request).await } } @@ -59,7 +50,7 @@ pub enum ModelChoice { /// Chat completion request schema #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] -pub struct CompletionRequest { +pub struct Request { /// The prompt to complete pub prompt: String, /// The model's name to use @@ -76,7 +67,7 @@ pub struct CompletionRequest { pub tools: Vec, } -impl Default for CompletionRequest { +impl Default for Request { /// Creates a default `CompletionRequest` with empty fields fn default() -> Self { Self { @@ -94,22 +85,22 @@ impl Default for CompletionRequest { /// Builder for `CompletionRequest` #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] #[serde(rename_all = "snake_case")] -pub struct CompletionRequestBuilder { +pub struct RequestBuilder { /// The inner builder - inner: CompletionRequest, + inner: Request, } -impl CompletionRequestBuilder { +impl RequestBuilder { /// Creates a new `CompletionRequestBuilder` with default values pub fn new() -> Self { Self { - inner: CompletionRequest::default(), + inner: Request::default(), } } /// Creates a `CompletionRequestBuilder` from a `ServiceContext`. /// Convinient for building requests inside a service. - pub fn from_ctx(ctx: &ServiceContext

) -> Self { + pub fn from_ctx(ctx: &SessionContext

) -> Self { Self::new() .model(ctx.model_name.clone()) .system_prompt(ctx.system_prompt.clone()) @@ -161,7 +152,7 @@ impl CompletionRequestBuilder { } /// Builds the `CompletionRequest` - pub fn build(self) -> CompletionRequest { + pub fn build(self) -> Request { self.inner.clone() } } @@ -173,7 +164,7 @@ mod tests { #[test] fn test_completion_request_builder() { // Test building the request - let request = CompletionRequestBuilder::new() + let request = RequestBuilder::new() .prompt("Hello, world!".to_string()) .model("test".to_string()) .system_prompt("You are a helpful assistant.".to_string()) diff --git a/amico-sdk/src/ai/services/completion.rs b/amico-sdk/src/ai/completion/session.rs similarity index 81% rename from amico-sdk/src/ai/services/completion.rs rename to amico-sdk/src/ai/completion/session.rs index 75030f9..5613f00 100644 --- a/amico-sdk/src/ai/services/completion.rs +++ b/amico-sdk/src/ai/completion/session.rs @@ -1,8 +1,7 @@ use async_trait::async_trait; -use crate::ai::errors::ServiceError; use crate::ai::{ - models::CompletionModel, + completion::{Error, Model}, tool::{Tool, ToolSet}, }; @@ -13,77 +12,77 @@ use crate::ai::mcp::{McpClient, McpTool}; /// using a series of model provider calls. /// /// A service should contain a context that is used to configure the service. -pub trait CompletionService { +pub trait Session { /// The LLM API provider type the service uses - type Model: CompletionModel; + type Model: Model; /// A service should be built from a context - fn from(context: ServiceContext) -> Self; + fn from(context: SessionContext) -> Self; /// Generates text based on a prompt. fn generate_text( &mut self, prompt: String, - ) -> impl Future> + Send; + ) -> impl Future> + Send; } #[async_trait] -pub trait CompletionServiceDyn { +pub trait SessionDyn { /// Generates text based on a prompt. - async fn generate_text_dyn(&mut self, prompt: String) -> Result; + async fn generate_text_dyn(&mut self, prompt: String) -> Result; } #[async_trait(?Send)] -pub trait CompletionServiceLocal { +pub trait SessionLocal { /// Generates text based on a prompt. - async fn generate_text_local(&mut self, prompt: String) -> Result; + async fn generate_text_local(&mut self, prompt: String) -> Result; } #[async_trait] -impl CompletionServiceDyn for T { - async fn generate_text_dyn(&mut self, prompt: String) -> Result { +impl SessionDyn for T { + async fn generate_text_dyn(&mut self, prompt: String) -> Result { self.generate_text(prompt).await } } #[async_trait(?Send)] -impl CompletionServiceLocal for T { - async fn generate_text_local(&mut self, prompt: String) -> Result { +impl SessionLocal for T { + async fn generate_text_local(&mut self, prompt: String) -> Result { self.generate_text(prompt).await } } /// The context of a Service. #[derive(Debug)] -pub struct ServiceContext +pub struct SessionContext where - M: CompletionModel, + M: Model, { pub system_prompt: String, - pub completion_model: M, + pub model: M, pub model_name: String, pub temperature: f64, pub max_tokens: u64, pub tools: ToolSet, } -impl ServiceContext +impl SessionContext where - M: CompletionModel, + M: Model, { /// Updates the context with a function. pub fn update(&mut self, update: F) where - F: Fn(&mut ServiceContext), + F: Fn(&mut SessionContext), { update(self); } } /// A ServiceBuilder allows to configure a Service before it is used. -pub struct ServiceBuilder +pub struct SessionBuilder where - M: CompletionModel, + M: Model, { /// Temporarily stores tools in a vector. /// These are moved into the ServiceContext when the builder is built. @@ -95,9 +94,9 @@ where max_tokens: u64, } -impl ServiceBuilder +impl SessionBuilder where - M: CompletionModel, + M: Model, { /// Creates a new `ServiceBuilder` with default values. pub fn new(completion_model: M) -> Self { @@ -200,10 +199,10 @@ where /// Build the Service. pub fn build(self) -> S where - S: CompletionService, + S: Session, { - S::from(ServiceContext { - completion_model: self.completion_model, + S::from(SessionContext { + model: self.completion_model, model_name: self.model_name, system_prompt: self.system_prompt, temperature: self.temperature, @@ -216,9 +215,7 @@ where #[cfg(test)] mod test { use super::*; - use crate::ai::errors::CompletionModelError; - use crate::ai::models::ModelChoice; - use crate::ai::models::{CompletionRequest, CompletionRequestBuilder}; + use crate::ai::completion::{Error, ModelChoice, Request, RequestBuilder}; use crate::ai::tool::ToolBuilder; // Structs for testing @@ -226,40 +223,35 @@ mod test { struct TestCompletionModel; struct TestService { - ctx: ServiceContext, + ctx: SessionContext, } - impl CompletionModel for TestCompletionModel { - async fn completion( - &self, - _req: &CompletionRequest, - ) -> Result { + impl Model for TestCompletionModel { + async fn completion(&self, _req: &Request) -> Result { Ok(ModelChoice::Message("test".to_string())) } } - impl CompletionService for TestService { + impl Session for TestService { type Model = TestCompletionModel; - fn from(context: ServiceContext) -> Self { + fn from(context: SessionContext) -> Self { TestService { ctx: context } } - async fn generate_text(&mut self, prompt: String) -> Result { + async fn generate_text(&mut self, prompt: String) -> Result { // Build the request - let request = CompletionRequestBuilder::from_ctx(&self.ctx) - .prompt(prompt) - .build(); + let request = RequestBuilder::from_ctx(&self.ctx).prompt(prompt).build(); // Perform the completion self.ctx - .completion_model + .model .completion(&request) .await .map(|choice| match choice { ModelChoice::Message(text) => Ok(text), _ => { - return Err(ServiceError::UnexpectedResponse( + return Err(Error::BadResponse( "Expected a message, got a tool call".to_string(), )); } @@ -270,7 +262,7 @@ mod test { /// Builds a test service fn build_test_service() -> TestService { - ServiceBuilder::new(TestCompletionModel) + SessionBuilder::new(TestCompletionModel) .model("test".to_string()) .system_prompt("test".to_string()) .temperature(0.2) @@ -332,6 +324,6 @@ mod test { let service = build_test_service(); // Ensure the service is dynamically compatible - let _: Box = Box::new(service); + let _: Box = Box::new(service); } } diff --git a/amico-sdk/src/ai/errors.rs b/amico-sdk/src/ai/errors.rs index 4d1daf3..e3af329 100644 --- a/amico-sdk/src/ai/errors.rs +++ b/amico-sdk/src/ai/errors.rs @@ -9,16 +9,6 @@ pub enum CreationError { }, } -/// Errors during completion of chatting -#[derive(Debug, thiserror::Error)] -pub enum CompletionModelError { - #[error("Provider error: {0}")] - ProviderError(String), - - #[error("Model {0} is unavailable")] - ModelUnavailable(String), -} - /// Errors during tool call #[derive(Debug, Clone, thiserror::Error)] pub enum ToolCallError { @@ -39,16 +29,3 @@ pub enum ToolCallError { reason: String, }, } - -/// Errors during service call -#[derive(Debug, thiserror::Error)] -pub enum ServiceError { - #[error("Completion model error")] - CompletionModelError(#[from] CompletionModelError), - - #[error("Unexpected response: {0}")] - UnexpectedResponse(String), - - #[error("Tool error")] - ToolError(#[from] ToolCallError), -} diff --git a/amico-sdk/src/ai/mod.rs b/amico-sdk/src/ai/mod.rs index fde9f9c..851c933 100644 --- a/amico-sdk/src/ai/mod.rs +++ b/amico-sdk/src/ai/mod.rs @@ -1,7 +1,6 @@ +pub mod completion; pub mod errors; pub mod message; -pub mod models; -pub mod services; pub mod tool; #[cfg(feature = "mcp-client")] diff --git a/amico-sdk/src/ai/models/embedding.rs b/amico-sdk/src/ai/models/embedding.rs deleted file mode 100644 index dda6339..0000000 --- a/amico-sdk/src/ai/models/embedding.rs +++ /dev/null @@ -1 +0,0 @@ -// TODO: Define the interface for embedding RAG system to the executor diff --git a/amico-sdk/src/ai/models/mod.rs b/amico-sdk/src/ai/models/mod.rs deleted file mode 100644 index ce81979..0000000 --- a/amico-sdk/src/ai/models/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod completion; -mod embedding; - -pub use completion::*; diff --git a/amico-sdk/src/ai/services/mod.rs b/amico-sdk/src/ai/services/mod.rs deleted file mode 100644 index a66295e..0000000 --- a/amico-sdk/src/ai/services/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod completion; - -pub use completion::*; diff --git a/amico/src/engine/systems.rs b/amico/src/engine/systems.rs index 0eed5b9..074370b 100644 --- a/amico/src/engine/systems.rs +++ b/amico/src/engine/systems.rs @@ -1,7 +1,7 @@ use std::sync::mpsc::channel; use amico::resource::Resource; -use amico::{ai::services::CompletionServiceDyn, resource::ResourceMut}; +use amico::{ai::completion::SessionDyn, resource::ResourceMut}; use amico_core::{traits::System, world::HandlerRegistry}; use amico_mods::std::ai::{ providers::rig::RigProvider, diff --git a/amico/src/main.rs b/amico/src/main.rs index d7d1f1f..6f0dd1b 100644 --- a/amico/src/main.rs +++ b/amico/src/main.rs @@ -1,6 +1,6 @@ use std::process; -use amico::ai::services::ServiceBuilder; +use amico::ai::completion::SessionBuilder; use amico::resource::{IntoResource, IntoResourceMut}; use amico_core::{Agent, OnFinish}; use amico_mods::interface::Plugin; @@ -115,7 +115,7 @@ async fn main() { )); // Create the Service - let service = ServiceBuilder::new(provider) + let service = SessionBuilder::new(provider) .model("gpt-4o".to_string()) .system_prompt(AMICO_SYSTEM_PROMPT.to_string()) .temperature(0.2) From a1a4fcb633c719c66442ef4a18678cf8f73e367a Mon Sep 17 00:00:00 2001 From: Archer Date: Fri, 6 Jun 2025 14:00:32 +0800 Subject: [PATCH 3/7] Simplify Tool call with anyhow --- amico-mods/src/web3/solana/balance.rs | 27 ++---------------- amico-mods/src/web3/solana/trade.rs | 10 +------ amico-sdk/src/ai/errors.rs | 31 -------------------- amico-sdk/src/ai/mcp/tool.rs | 21 ++++---------- amico-sdk/src/ai/mod.rs | 1 - amico-sdk/src/ai/tool.rs | 18 ++++++------ amico/src/engine/a2a.rs | 41 +++++++-------------------- 7 files changed, 28 insertions(+), 121 deletions(-) delete mode 100644 amico-sdk/src/ai/errors.rs diff --git a/amico-mods/src/web3/solana/balance.rs b/amico-mods/src/web3/solana/balance.rs index 3f68afd..d050d38 100644 --- a/amico-mods/src/web3/solana/balance.rs +++ b/amico-mods/src/web3/solana/balance.rs @@ -1,10 +1,7 @@ use std::str::FromStr; use amico::{ - ai::{ - errors::ToolCallError, - tool::{Tool, ToolBuilder}, - }, + ai::tool::{Tool, ToolBuilder}, environment::Sensor, resource::{IntoResource, Resource}, }; @@ -53,22 +50,16 @@ impl BalanceSensor { .name("balance_sensor") .description("Get the balance of your own Solana account.") .parameters(serde_json::json!({})) - .build_async(move |args| { + .build_async(move |_| { // Clone the sensor and pubkey to move into the async block let sensor = sensor.clone(); let pubkey = pubkey; - let args = args.clone(); // Return a boxed future that is both Send and Sync async move { sensor .sense(BalanceSensorArgs { pubkey }) .await - .map_err(|err| ToolCallError::ExecutionError { - tool_name: "balance_sensor".to_string(), - params: args, - reason: err.to_string(), - }) .map(|result| { serde_json::json!({ "balance": result.lamports as f64 / LAMPORTS_PER_SOL as f64 @@ -104,26 +95,14 @@ impl BalanceSensor { // Clone the sensor and pubkey to move into the async block let sensor = sensor.clone(); let pubkey_arg = args["pubkey"].to_string(); - let args = args.clone(); // Return a boxed future that is both Send and Sync async move { // Parse the pubkey - let pubkey = Pubkey::from_str(&pubkey_arg).map_err(|err| { - ToolCallError::ExecutionError { - tool_name: "account_balance_tool".to_string(), - params: args.clone(), - reason: err.to_string(), - } - })?; + let pubkey = Pubkey::from_str(&pubkey_arg)?; sensor .sense(BalanceSensorArgs { pubkey }) .await - .map_err(|err| ToolCallError::ExecutionError { - tool_name: "account_balance_tool".to_string(), - params: args, - reason: err.to_string(), - }) .map(|result| { serde_json::json!({ "balance": result.lamports as f64 / LAMPORTS_PER_SOL as f64 diff --git a/amico-mods/src/web3/solana/trade.rs b/amico-mods/src/web3/solana/trade.rs index f726e95..c54c91b 100644 --- a/amico-mods/src/web3/solana/trade.rs +++ b/amico-mods/src/web3/solana/trade.rs @@ -1,8 +1,5 @@ use amico::{ - ai::{ - errors::ToolCallError, - tool::{Tool, ToolBuilder}, - }, + ai::tool::{Tool, ToolBuilder}, environment::Effector, resource::{IntoResource, Resource}, }; @@ -78,11 +75,6 @@ impl TradeEffector { .effect(effector_args) .await .map(|_| serde_json::json!({"status": "success"})) - .map_err(|err| ToolCallError::ExecutionError { - tool_name: "trade_solana_token".to_string(), - params: args, - reason: err.to_string(), - }) } }) } diff --git a/amico-sdk/src/ai/errors.rs b/amico-sdk/src/ai/errors.rs deleted file mode 100644 index e3af329..0000000 --- a/amico-sdk/src/ai/errors.rs +++ /dev/null @@ -1,31 +0,0 @@ -/// Errors during creation of AI Service -#[derive(Debug, thiserror::Error)] -pub enum CreationError { - #[error("Invalid API key")] - InvalidParam { - name: String, - value: serde_json::Value, - reason: String, - }, -} - -/// Errors during tool call -#[derive(Debug, Clone, thiserror::Error)] -pub enum ToolCallError { - #[error("Tool {0} is unavailable")] - ToolUnavailable(String), - - #[error("Invalid param {name} with value {value} for reason {reason}")] - InvalidParam { - name: String, - value: serde_json::Value, - reason: String, - }, - - #[error("Error executing {tool_name} with params {params} for reason {reason}")] - ExecutionError { - tool_name: String, - params: serde_json::Value, - reason: String, - }, -} diff --git a/amico-sdk/src/ai/mcp/tool.rs b/amico-sdk/src/ai/mcp/tool.rs index 39821d0..abcfb16 100644 --- a/amico-sdk/src/ai/mcp/tool.rs +++ b/amico-sdk/src/ai/mcp/tool.rs @@ -4,10 +4,7 @@ use rig::tool::ToolDyn; use std::str::FromStr; use std::sync::Arc; -use crate::ai::{ - errors::ToolCallError, - tool::{Tool, ToolBuilder}, -}; +use crate::ai::tool::{Tool, ToolBuilder}; use super::McpClient; @@ -72,21 +69,13 @@ impl From for Tool { .build_async(move |args| { let args = args.clone(); let args_str = args.to_string(); - let name = val.name.clone(); + // let name = val.name.clone(); let mcp_tool = mcp_tool.clone(); // Clone the Arc, not the inner value async move { - mcp_tool - .call(args_str) - .await - .map(|res| { - serde_json::Value::from_str(&res).unwrap_or(serde_json::json!(res)) - }) - .map_err(|err| ToolCallError::ExecutionError { - tool_name: name, - params: args, - reason: err.to_string(), - }) + mcp_tool.call(args_str).await.map(|res| { + serde_json::Value::from_str(&res).unwrap_or(serde_json::json!(res)) + }) } }) } diff --git a/amico-sdk/src/ai/mod.rs b/amico-sdk/src/ai/mod.rs index 851c933..bfebfac 100644 --- a/amico-sdk/src/ai/mod.rs +++ b/amico-sdk/src/ai/mod.rs @@ -1,5 +1,4 @@ pub mod completion; -pub mod errors; pub mod message; pub mod tool; diff --git a/amico-sdk/src/ai/tool.rs b/amico-sdk/src/ai/tool.rs index c23ef49..98d6b87 100644 --- a/amico-sdk/src/ai/tool.rs +++ b/amico-sdk/src/ai/tool.rs @@ -1,8 +1,7 @@ +use anyhow::Result; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, fmt::Debug, future::Future, pin::Pin, sync::Arc}; -use crate::ai::errors::ToolCallError; - /// Definition of a tool in natural language /// /// **TODO**: Restrict the parameters to be valid JSON Schema @@ -17,9 +16,6 @@ pub struct ToolDefinition { pub parameters: serde_json::Value, } -/// Result type of tool call -pub type ToolResult = Result; - /// A tool that can be called by AI Agent. #[derive(Clone)] pub struct Tool { @@ -34,7 +30,7 @@ impl Tool { } /// Calls the tool with the given arguments. - pub async fn call(&self, args: serde_json::Value) -> ToolResult { + pub async fn call(&self, args: serde_json::Value) -> Result { match &self.tool_call { ToolCallFn::Sync(f) => (f)(args), ToolCallFn::Async(f) => (f)(args.clone()).await, @@ -43,11 +39,13 @@ impl Tool { } /// Sync tool call function -pub type SyncToolCall = Arc ToolResult + Send + Sync>; +pub type SyncToolCall = Arc Result + Send + Sync>; /// Async tool call function pub type AsyncToolCall = Arc< - dyn Fn(serde_json::Value) -> Pin + Send + 'static>> + dyn Fn( + serde_json::Value, + ) -> Pin> + Send + 'static>> + Send + Sync, >; @@ -98,7 +96,7 @@ impl ToolBuilder { /// Builds the `Tool` with tool call function from the builder pub fn build(self, tool_call: F) -> Tool where - F: Fn(serde_json::Value) -> ToolResult + Send + Sync + 'static, + F: Fn(serde_json::Value) -> Result + Send + Sync + 'static, { Tool { definition: ToolDefinition { @@ -114,7 +112,7 @@ impl ToolBuilder { pub fn build_async(self, tool_call: F) -> Tool where F: Fn(serde_json::Value) -> Fut + Send + Sync + 'static, - Fut: Future + Send + 'static, + Fut: Future> + Send + 'static, { Tool { definition: ToolDefinition { diff --git a/amico/src/engine/a2a.rs b/amico/src/engine/a2a.rs index 0c73adc..f632cc7 100644 --- a/amico/src/engine/a2a.rs +++ b/amico/src/engine/a2a.rs @@ -1,10 +1,7 @@ use std::{collections::HashMap, future::Future, str::FromStr, time::Duration}; use amico::{ - ai::{ - errors::ToolCallError, - tool::{Tool, ToolBuilder}, - }, + ai::tool::{Tool, ToolBuilder}, resource::ResourceMut, runtime::storage::{Namespace, Storage}, }; @@ -14,6 +11,7 @@ use amico_mods::{ runtime::storage::fs::FsStorage, web3::wallet::WalletResource, }; +use anyhow::anyhow; use nostr::key::Keys; use serde_json::{json, to_value}; use solana_sdk::pubkey::Pubkey; @@ -69,35 +67,18 @@ impl A2aModule { tracing::debug!("Calling send_a2a_message({})", args.clone()); let network = network.clone(); async move { - let address = args.get("address").ok_or(ToolCallError::InvalidParam { - name: "address".to_string(), - value: json!({}), - reason: "Missing".to_string(), - })?; - let content = args.get("content").ok_or(ToolCallError::InvalidParam { - name: "content".to_string(), - value: json!({}), - reason: "Missing".to_string(), - })?; - - let pubkey = Pubkey::from_str(&content.to_string()).map_err(|err| { - ToolCallError::InvalidParam { - name: "address".to_string(), - value: address.clone(), - reason: err.to_string(), - } - })?; + let address = args + .get("address") + .ok_or(anyhow!("Missing address parameter"))?; + let content = args + .get("content") + .ok_or(anyhow!("Missing content parameter"))?; + + let pubkey = Pubkey::from_str(&address.to_string())?; tracing::info!("Sending {} to {}...", content, address); - network - .publish_dyn(pubkey, content.to_string()) - .await - .map_err(|err| ToolCallError::ExecutionError { - tool_name: "send_a2a_message".to_string(), - params: args, - reason: err.to_string(), - })?; + network.publish_dyn(pubkey, content.to_string()).await?; tracing::info!("Message sent."); From 448d19b3551041b3b35d5e8cfd8f86a38d62765b Mon Sep 17 00:00:00 2001 From: Archer Date: Fri, 6 Jun 2025 14:07:06 +0800 Subject: [PATCH 4/7] clean workspace --- Cargo.lock | 1 - amico-sdk/Cargo.toml | 7 ++----- amico-sdk/src/aoe.rs | 3 +++ amico-sdk/src/lib.rs | 3 +++ 4 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 amico-sdk/src/aoe.rs diff --git a/Cargo.lock b/Cargo.lock index b6289c3..cf4f4b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1125,7 +1125,6 @@ dependencies = [ name = "amico-sdk" version = "0.0.2" dependencies = [ - "amico-core", "anyhow", "async-trait", "mcp-core", diff --git a/amico-sdk/Cargo.toml b/amico-sdk/Cargo.toml index 72f9334..34a1d85 100644 --- a/amico-sdk/Cargo.toml +++ b/amico-sdk/Cargo.toml @@ -2,7 +2,7 @@ name = "amico-sdk" version = "0.0.2" edition = "2024" -description = "The SDK of the Amico AI Agent Framework" +description = "Amico AI Agent Framework core features SDK" repository = "https://github.com/AIMOverse/amico" license = "MIT OR Apache-2.0" @@ -11,7 +11,6 @@ name = "amico" path = "src/lib.rs" [features] -# core = ["dep:amico-core"] default = ["mcp-client", "a2a", "aoe"] mcp-client = [ "dep:rig-core", @@ -19,13 +18,11 @@ mcp-client = [ "dep:mcp-core", "mcp-core/sse", "mcp-core-macros", - "anyhow", ] a2a = [] aoe = [] [dependencies] -amico-core = { path = "../amico-core", optional = true } async-trait = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } @@ -33,7 +30,7 @@ serde = { workspace = true, features = ["derive"] } rig-core = { workspace = true, optional = true, default-features = false } mcp-core = { version = "0.1.46", optional = true } mcp-core-macros = { version = "0.1.22", optional = true } -anyhow = { workspace = true, optional = true } +anyhow = { workspace = true } tokio = { workspace = true, features = ["sync"] } tokio_with_wasm = { workspace = true } diff --git a/amico-sdk/src/aoe.rs b/amico-sdk/src/aoe.rs new file mode 100644 index 0000000..3c3811b --- /dev/null +++ b/amico-sdk/src/aoe.rs @@ -0,0 +1,3 @@ +//! AoE (Agent of Everything) +//! +//! TODO: Define AoE interface diff --git a/amico-sdk/src/lib.rs b/amico-sdk/src/lib.rs index 26cbefe..11e3d62 100644 --- a/amico-sdk/src/lib.rs +++ b/amico-sdk/src/lib.rs @@ -5,3 +5,6 @@ pub mod runtime; #[cfg(feature = "a2a")] pub mod a2a; + +#[cfg(feature = "aoe")] +pub mod aoe; From 01ce6de1533bcf9503657fb2c6fbab19727e0125 Mon Sep 17 00:00:00 2001 From: Archer Date: Fri, 6 Jun 2025 14:20:59 +0800 Subject: [PATCH 5/7] improve api and docs --- amico-mods/src/std/ai/services/in_memory.rs | 2 +- amico-sdk/src/ai/completion/model.rs | 2 +- amico-sdk/src/ai/completion/session.rs | 100 ++++++++++---------- 3 files changed, 54 insertions(+), 50 deletions(-) diff --git a/amico-mods/src/std/ai/services/in_memory.rs b/amico-mods/src/std/ai/services/in_memory.rs index 67e035a..25fde5b 100644 --- a/amico-mods/src/std/ai/services/in_memory.rs +++ b/amico-mods/src/std/ai/services/in_memory.rs @@ -49,7 +49,7 @@ impl Plugin for InMemoryService { impl Session for InMemoryService { type Model = M; - fn from(context: SessionContext) -> Self { + fn from_ctx(context: SessionContext) -> Self { Self { ctx: context, history: Vec::new(), diff --git a/amico-sdk/src/ai/completion/model.rs b/amico-sdk/src/ai/completion/model.rs index 4832a5a..0115382 100644 --- a/amico-sdk/src/ai/completion/model.rs +++ b/amico-sdk/src/ai/completion/model.rs @@ -82,7 +82,7 @@ impl Default for Request { } } -/// Builder for `CompletionRequest` +/// Builder for `Request` #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] #[serde(rename_all = "snake_case")] pub struct RequestBuilder { diff --git a/amico-sdk/src/ai/completion/session.rs b/amico-sdk/src/ai/completion/session.rs index 5613f00..3ff7f90 100644 --- a/amico-sdk/src/ai/completion/session.rs +++ b/amico-sdk/src/ai/completion/session.rs @@ -8,16 +8,16 @@ use crate::ai::{ #[cfg(feature = "mcp-client")] use crate::ai::mcp::{McpClient, McpTool}; -/// A Service executes a certain AI task, such as generating text. -/// using a series of model provider calls. +/// A completion `Session` is responsible for generating text based on a prompt, +/// managing the context of the session, and calling tools. /// -/// A service should contain a context that is used to configure the service. +/// A session should contain a context that is used to configure the session. pub trait Session { - /// The LLM API provider type the service uses + /// The completion `Model` type the session uses type Model: Model; - /// A service should be built from a context - fn from(context: SessionContext) -> Self; + /// A session should define how it is built from a context. + fn from_ctx(ctx: SessionContext) -> Self; /// Generates text based on a prompt. fn generate_text( @@ -52,7 +52,7 @@ impl SessionLocal for T { } } -/// The context of a Service. +/// The context of a Session. #[derive(Debug)] pub struct SessionContext where @@ -79,13 +79,14 @@ where } } -/// A ServiceBuilder allows to configure a Service before it is used. +/// A SessionBuilder allows to configure a Session before it is used. pub struct SessionBuilder where M: Model, { /// Temporarily stores tools in a vector. - /// These are moved into the ServiceContext when the builder is built. + /// + /// These tools will be moved into the `SessionContext` when the builder is built. tool_list: Vec, system_prompt: String, completion_model: M, @@ -98,7 +99,7 @@ impl SessionBuilder where M: Model, { - /// Creates a new `ServiceBuilder` with default values. + /// Creates a new `SessionBuilder` with default values. pub fn new(completion_model: M) -> Self { Self { tool_list: Vec::new(), @@ -110,31 +111,31 @@ where } } - /// Sets the model for the Service. + /// Sets the model for the Session. pub fn model(mut self, model_name: String) -> Self { self.model_name = model_name; self } - /// Set the system prompt for the Service. + /// Set the system prompt for the Session. pub fn system_prompt(mut self, prompt: String) -> Self { self.system_prompt = prompt; self } - /// Add a tool to the Service. + /// Add a tool to the Session. pub fn tool(mut self, tool: Tool) -> Self { self.tool_list.push(tool); self } - /// Add a list of tools to the Service. + /// Add a list of tools to the Session. pub fn tools(mut self, tools: Vec) -> Self { self.tool_list.extend(tools); self } - /// Add a MCP tool to the Service by definition. + /// Add a MCP tool to the Session by definition. #[cfg(feature = "mcp-client")] pub fn mcp_tool_definition( mut self, @@ -146,7 +147,7 @@ where self } - /// Add all MCP tools from a server to the Service. + /// Add all MCP tools from a server to the Session. #[cfg(feature = "mcp-client")] pub async fn mcp_tools_from_server(mut self, mcp_client: McpClient) -> anyhow::Result { mcp_client @@ -162,7 +163,7 @@ where Ok(self) } - /// Add a MCP tool to the Service by name. + /// Add a MCP tool to the Session by name. #[cfg(feature = "mcp-client")] pub async fn mcp_tool( mut self, @@ -184,24 +185,24 @@ where Ok(self) } - /// Sets the temperature for the Service. + /// Sets the temperature for the Session. pub fn temperature(mut self, temperature: f64) -> Self { self.temperature = temperature; self } - /// Sets the max tokens for the Service. + /// Sets the max tokens for the Session. pub fn max_tokens(mut self, max_tokens: u64) -> Self { self.max_tokens = max_tokens; self } - /// Build the Service. + /// Build the Session. pub fn build(self) -> S where S: Session, { - S::from(SessionContext { + S::from_ctx(SessionContext { model: self.completion_model, model_name: self.model_name, system_prompt: self.system_prompt, @@ -222,7 +223,7 @@ mod test { struct TestCompletionModel; - struct TestService { + struct TestSession { ctx: SessionContext, } @@ -232,11 +233,11 @@ mod test { } } - impl Session for TestService { + impl Session for TestSession { type Model = TestCompletionModel; - fn from(context: SessionContext) -> Self { - TestService { ctx: context } + fn from_ctx(context: SessionContext) -> Self { + TestSession { ctx: context } } async fn generate_text(&mut self, prompt: String) -> Result { @@ -260,8 +261,8 @@ mod test { } } - /// Builds a test service - fn build_test_service() -> TestService { + /// Builds a test session + fn build_test_session() -> TestSession { SessionBuilder::new(TestCompletionModel) .model("test".to_string()) .system_prompt("test".to_string()) @@ -274,7 +275,7 @@ mod test { .tools(vec![build_test_tool(3), build_test_tool(4)]) // Test adding tools after a list of tools are added .tool(build_test_tool(5)) - .build::() + .build::() } /// Builds a test tool @@ -287,24 +288,24 @@ mod test { } #[tokio::test] - async fn test_build_service() { - let mut service = build_test_service(); + async fn test_build_session() { + let mut session = build_test_session(); - assert_eq!(service.ctx.system_prompt, "test".to_string()); - assert_eq!(service.ctx.model_name, "test".to_string()); - assert_eq!(service.ctx.temperature, 0.2); - assert_eq!(service.ctx.max_tokens, 100); - assert_eq!(service.ctx.tools.tools.len(), 5); + assert_eq!(session.ctx.system_prompt, "test".to_string()); + assert_eq!(session.ctx.model_name, "test".to_string()); + assert_eq!(session.ctx.temperature, 0.2); + assert_eq!(session.ctx.max_tokens, 100); + assert_eq!(session.ctx.tools.tools.len(), 5); - let response = service.generate_text("test".to_string()).await.unwrap(); + let response = session.generate_text("test".to_string()).await.unwrap(); assert_eq!(response, "test".to_string()); } #[test] fn test_update_context() { - let mut service = build_test_service(); + let mut session = build_test_session(); - service.ctx.update(|ctx| { + session.ctx.update(|ctx| { ctx.system_prompt = "new test".to_string(); ctx.model_name = "new test".to_string(); ctx.temperature = 0.3; @@ -312,18 +313,21 @@ mod test { ctx.tools = ToolSet::from(vec![]); }); - assert_eq!(service.ctx.system_prompt, "new test".to_string()); - assert_eq!(service.ctx.model_name, "new test".to_string()); - assert_eq!(service.ctx.temperature, 0.3); - assert_eq!(service.ctx.max_tokens, 200); - assert_eq!(service.ctx.tools.tools.len(), 0); + assert_eq!(session.ctx.system_prompt, "new test".to_string()); + assert_eq!(session.ctx.model_name, "new test".to_string()); + assert_eq!(session.ctx.temperature, 0.3); + assert_eq!(session.ctx.max_tokens, 200); + assert_eq!(session.ctx.tools.tools.len(), 0); } - #[test] - fn test_service_dyn_compatibility() { - let service = build_test_service(); + #[tokio::test] + async fn test_session_dyn_compatibility() { + let session = build_test_session(); - // Ensure the service is dynamically compatible - let _: Box = Box::new(service); + // Ensure the session is dynamically compatible + let mut boxed: Box = Box::new(session); + + let response = boxed.generate_text_dyn("test".to_string()).await.unwrap(); + assert_eq!(response, "test".to_string()); } } From 4cb33e390b361e488c0f704049b13f18e705e009 Mon Sep 17 00:00:00 2001 From: Archer Date: Fri, 6 Jun 2025 14:37:24 +0800 Subject: [PATCH 6/7] update README --- amico-sdk/README.md | 64 +++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/amico-sdk/README.md b/amico-sdk/README.md index 37af1e7..2e4fe37 100644 --- a/amico-sdk/README.md +++ b/amico-sdk/README.md @@ -4,46 +4,48 @@ This crate is a part of the [**Amico** project](https://github.com/AIMOverse/ami ## What does this crate do -This crate provides the Software Development Kit (SDK) for the Amico AI Agent Framework, including the following features: +This crate provides the SDK for Amico AI Agent Framework's core features, including: -1. AI service abstractions and interfaces; -2. Task execution workflow and context management; -3. Environment interaction through sensors and effectors; -4. Core agent models and action handling. +1. Completion model and session management; +2. Core AI modules including tools and messages; +3. Agent-to-Agent (A2A) communication capabilities; +4. Agent on Environment (AoE) execution framework; +5. Runtime platform abstractions; +6. Global resource management. ## Directory Structure -The crate is organized as follows: - -### Core Components - - **`ai/`**: AI-related abstractions and implementations. - - **`completion/`**: Interfaces for text completion services. - - **`embedding/`**: Embedding generation and management. - - **`message/`**: Message structures for AI communication. - - **`provider/`**: Provider interfaces for AI services. - - **`service/`**: Service abstractions for AI capabilities. - - **`tool/`**: Tool definitions for AI agent interactions. - -- **`core/`**: Core functionality for agent operations. - - **`action_map/`**: Action mapping and selection. - - **`ai_action/`**: AI action definitions and handling. - - **`model/`**: Model definitions and abstractions. - -### Interaction Components + - **`completion/`**: Interfaces for text completion models and sessions. + - **`model.rs`**: Completion model abstractions. + - **`session.rs`**: Session management for stateful completions. + - **`error.rs`**: Error handling for completion operations. + - **`mcp/`**: **Model Context Protocol** implementation. + - **`client.rs`**: MCP client for model interaction. + - **`tool.rs`**: Tool implementations for MCP. + - **`message.rs`**: Message structures for AI communication. + - **`tool.rs`**: Tool definitions for AI agent interactions. + +- **`a2a/`**: Agent-to-Agent communication framework. + - **`network.rs`**: Networking components for agent communication. + +- **`runtime/`**: Runtime platform abstractions. + - **`storage.rs`**: Storage interfaces and implementations. - **`environment.rs`**: Environment interaction through sensors and effectors. -- **`interaction/`**: User and agent interaction interfaces. -- **`resource.rs`**: Resource management for agent operations. -- **`task.rs`**: Task definition and execution workflow. +- **`resource.rs`**: Global resource management for agent operations. +- **`aoe.rs`**: Agent on Environment (AoE) execution components. -> **Note**: The Amico SDK provides a high-level abstraction layer for building AI agents, allowing developers to focus on agent logic rather than implementation details of AI services and environment interactions. +## Key Concepts -## Documents +- **Completion Model and Session**: Abstractions for working with AI completion models and managing stateful completion sessions. +- **Tools and Messages**: Core components for AI interaction, with tools defining actions agents can perform and messages structuring communication. +- **Agent-to-Agent (A2A)**: Framework enabling agents to communicate and collaborate with each other. +- **Agent on Environment (AoE)**: System for agents to perceive and act upon their environment. +- **Runtime Platform Abstraction**: Cross-platform support allowing agents to operate in various environments. +- **Global Resources**: Centralized resource management for shared access across the agent ecosystem. -- [SDK Module reference](https://www.amico.dev/docs/modules/amico-sdk) -- [Agent development guide](https://www.amico.dev/docs/getting-started/sdk-guide) +## Documentation -## License +See Amico's website [https://amico.dev](https://amico.dev) -This crate is released under the [**MIT License**](https://github.com/AIMOverse/amico/blob/main/LICENSE) From fd65eacc41b2e1ca4549b6359a4480eb2b7a57ef Mon Sep 17 00:00:00 2001 From: Archer Date: Fri, 6 Jun 2025 14:38:30 +0800 Subject: [PATCH 7/7] Update version --- Cargo.lock | 2 +- amico-sdk/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf4f4b1..2cf60aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1123,7 +1123,7 @@ dependencies = [ [[package]] name = "amico-sdk" -version = "0.0.2" +version = "1.0.0" dependencies = [ "anyhow", "async-trait", diff --git a/amico-sdk/Cargo.toml b/amico-sdk/Cargo.toml index 34a1d85..e208966 100644 --- a/amico-sdk/Cargo.toml +++ b/amico-sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "amico-sdk" -version = "0.0.2" +version = "1.0.0" edition = "2024" description = "Amico AI Agent Framework core features SDK" repository = "https://github.com/AIMOverse/amico"