Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 4 additions & 10 deletions amico-mods/src/std/ai/providers/rig.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -22,7 +19,7 @@ async fn provider_completion(
provider: &RigProvider,
model_name: &str,
request: rc::CompletionRequest,
) -> Result<ModelChoice, CompletionModelError> {
) -> Result<ModelChoice, CompletionError> {
match provider {
RigProvider::Anthropic(client) => client
.completion_model(model_name)
Expand Down Expand Up @@ -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<ModelChoice, CompletionModelError> {
async fn completion(&self, req: &Request) -> Result<ModelChoice, CompletionError> {
provider_completion(self, &req.model, into_rig_request(req)).await
}
}
Expand Down
9 changes: 4 additions & 5 deletions amico-mods/src/std/ai/providers/rig_helpers.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -46,8 +45,8 @@ pub fn into_amico_choice<T>(response: rc::CompletionResponse<T>) -> 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`
Expand All @@ -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)

Expand Down
24 changes: 11 additions & 13 deletions amico-mods/src/std/ai/services/in_memory.rs
Original file line number Diff line number Diff line change
@@ -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},
};
Expand All @@ -31,15 +29,15 @@ fn debug_history(history: &[Message]) -> String {
}

#[derive(Debug)]
pub struct InMemoryService<M: CompletionModel + Send> {
pub struct InMemoryService<M: Model + Send> {
/// The context config for the service
pub ctx: ServiceContext<M>,
pub ctx: SessionContext<M>,

/// In-memory Chat history storage
pub history: Vec<Message>,
}

impl<M: CompletionModel + Send> Plugin for InMemoryService<M> {
impl<M: Model + Send> Plugin for InMemoryService<M> {
fn info(&self) -> &'static PluginInfo {
&PluginInfo {
name: "StdInMemoryService",
Expand All @@ -48,31 +46,31 @@ impl<M: CompletionModel + Send> Plugin for InMemoryService<M> {
}
}

impl<M: CompletionModel + Send> amico::ai::services::CompletionService for InMemoryService<M> {
impl<M: Model + Send> Session for InMemoryService<M> {
type Model = M;

fn from(context: ServiceContext<M>) -> Self {
fn from_ctx(context: SessionContext<M>) -> Self {
Self {
ctx: context,
history: Vec::new(),
}
}

async fn generate_text(&mut self, prompt: String) -> Result<String, ServiceError> {
async fn generate_text(&mut self, prompt: String) -> Result<String, Error> {
// 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);
Expand Down Expand Up @@ -128,14 +126,14 @@ impl<M: CompletionModel + Send> 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<M: CompletionModel + Send> IntoResourceMut<InMemoryService<M>> for InMemoryService<M> {
impl<M: Model + Send> IntoResourceMut<InMemoryService<M>> for InMemoryService<M> {
fn into_resource_mut(self) -> ResourceMut<InMemoryService<M>> {
ResourceMut::new(self.info().name, self)
}
Expand Down
27 changes: 3 additions & 24 deletions amico-mods/src/web3/solana/balance.rs
Original file line number Diff line number Diff line change
@@ -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},
};
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
10 changes: 1 addition & 9 deletions amico-mods/src/web3/solana/trade.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use amico::{
ai::{
errors::ToolCallError,
tool::{Tool, ToolBuilder},
},
ai::tool::{Tool, ToolBuilder},
environment::Effector,
resource::{IntoResource, Resource},
};
Expand Down Expand Up @@ -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(),
})
}
})
}
Expand Down
9 changes: 3 additions & 6 deletions amico-sdk/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "amico-sdk"
version = "0.0.2"
version = "1.0.0"
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"

Expand All @@ -11,29 +11,26 @@ name = "amico"
path = "src/lib.rs"

[features]
# core = ["dep:amico-core"]
default = ["mcp-client", "a2a", "aoe"]
mcp-client = [
"dep:rig-core",
"rig-core/mcp",
"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 }
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 }

Expand Down
64 changes: 33 additions & 31 deletions amico-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
14 changes: 14 additions & 0 deletions amico-sdk/src/ai/completion/error.rs
Original file line number Diff line number Diff line change
@@ -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),
}
7 changes: 7 additions & 0 deletions amico-sdk/src/ai/completion/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
mod error;
mod model;
mod session;

pub use error::*;
pub use model::*;
pub use session::*;
Loading
Loading