Skip to content

Commit

Permalink
chore: update anda_engine document
Browse files Browse the repository at this point in the history
  • Loading branch information
zensh committed Jan 22, 2025
1 parent 97f1390 commit 66087a6
Show file tree
Hide file tree
Showing 25 changed files with 1,078 additions and 46 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ chrono = "0.4"
dotenv = "0.15"
schemars = { version = "0.8" }
clap = { version = "4.5", features = ["derive", "env"] }
idna = "1.0" # https://github.com/ldclabs/anda/security/dependabot/1

[workspace.metadata.cargo-shear]
ignored = ["idna"]

[profile.release]
debug = false
Expand Down
2 changes: 1 addition & 1 deletion anda_core/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# `anda_core` Anda Core Library
# `anda_core`: Anda Core Library

![License](https://img.shields.io/crates/l/anda_core.svg)
[![Crates.io](https://img.shields.io/crates/d/anda_core.svg)](https://crates.io/crates/anda_core)
Expand Down
1 change: 1 addition & 0 deletions anda_core/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ pub struct CompletionRequest {
/// The system message to be sent to the completion model provider, as the "system" role
pub system: Option<String>,

/// The name of system role
pub system_name: Option<String>,

/// The chat history to be sent to the completion model provider
Expand Down
2 changes: 1 addition & 1 deletion anda_engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "anda_engine"
description = "Agents engine for Anda -- a framework for AI agent development."
repository = "https://github.com/ldclabs/anda/tree/main/anda_engine"
publish = true
version = "0.3.2"
version = "0.3.3"
edition.workspace = true
keywords.workspace = true
categories.workspace = true
Expand Down
22 changes: 18 additions & 4 deletions anda_engine/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
# `anda_engine`
# `anda_engine`: Anda Agents Engine

[![Crates.io](https://img.shields.io/crates/v/anda_engine)](https://crates.io/crates/anda_engine)
[![Documentation](https://docs.rs/anda_engine/badge.svg)](https://docs.rs/anda_engine)
![License](https://img.shields.io/crates/l/anda_engine.svg)
[![Crates.io](https://img.shields.io/crates/d/anda_engine.svg)](https://crates.io/crates/anda_engine)
[![Test](https://github.com/ldclabs/anda/actions/workflows/test.yml/badge.svg)](https://github.com/ldclabs/anda/actions/workflows/test.yml)
[![Docs.rs](https://docs.rs/anda_engine/badge.svg)](https://docs.rs/anda_engine)
[![Latest Version](https://img.shields.io/crates/v/anda_engine.svg)](https://crates.io/crates/anda_engine)

Agents engine for Anda.
Agents engine for Anda - A comprehensive framework for building and managing AI agents.

More information about this crate can be found in the [crate documentation][docs].

## Overview

`anda_engine` is a complete implementation of the [`anda_core`](https://github.com/ldclabs/anda/tree/main/anda_core) AI Agent definition, providing a robust foundation for creating, managing, and executing AI agents with the following core capabilities:

- **Agent Management**: Create, configure, and execute AI agents with customizable behaviors
- **Tool Integration**: Register and manage tools that agents can utilize
- **Context Management**: Handle execution contexts with cancellation support
- **Storage System**: Persistent storage with object and vector search capabilities
- **Model Integration**: Support for multiple AI model providers (OpenAI, DeepSeek, Cohere)
- **Extension System**: Additional capabilities including attention management and document processing

## License
Copyright © 2025 [LDC Labs](https://github.com/ldclabs).

Expand Down
143 changes: 141 additions & 2 deletions anda_engine/src/context/agent.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
//! Agent Context Implementation
//!
//! This module provides the core implementation of the Agent context ([`AgentCtx`]) which serves as
//! the primary execution environment for agents in the Anda system. The context provides:
//!
//! - Access to AI models for completions and embeddings
//! - Tool execution capabilities
//! - Agent-to-agent communication
//! - Cryptographic operations
//! - Storage and caching facilities
//! - Canister interaction capabilities
//! - HTTP communication features
//!
//! The [`AgentCtx`] implements multiple traits that provide different sets of functionality:
//! - [`AgentContext`]: Core agent operations and tool/agent management
//! - [`CompletionFeatures`]: AI model completion capabilities
//! - [`EmbeddingFeatures`]: Text embedding generation
//! - [`StateFeatures`]: Context state management
//! - [`KeysFeatures`]: Cryptographic key operations
//! - [`StoreFeatures`]: Persistent storage operations
//! - [`CacheFeatures`]: Caching mechanisms
//! - [`CanisterCaller`]: Canister interaction capabilities
//! - [`HttpFeatures`]: HTTPs communication features
//!
//! The context is designed to be hierarchical, allowing creation of child contexts for specific
//! agents or tools while maintaining access to the core functionality.
use anda_core::{
AgentContext, AgentOutput, AgentSet, BaseContext, BoxError, CacheExpiry, CacheFeatures,
CancellationToken, CanisterCaller, CompletionFeatures, CompletionRequest, Embedding,
Expand All @@ -11,15 +38,27 @@ use std::{future::Future, sync::Arc, time::Duration};
use super::base::BaseCtx;
use crate::model::Model;

/// Context for agent operations, providing access to models, tools, and other agents
#[derive(Clone)]
pub struct AgentCtx {
/// Base context providing fundamental operations
pub base: BaseCtx,
/// AI model used for completions and embeddings
pub(crate) model: Model,
/// Set of available tools that can be called
pub(crate) tools: Arc<ToolSet<BaseCtx>>,
/// Set of available agents that can be invoked
pub(crate) agents: Arc<AgentSet<AgentCtx>>,
}

impl AgentCtx {
/// Creates a new AgentCtx instance
///
/// # Arguments
/// * `base` - Base context
/// * `model` - AI model instance
/// * `tools` - Set of available tools
/// * `agents` - Set of available agents
pub(crate) fn new(
base: BaseCtx,
model: Model,
Expand All @@ -34,6 +73,10 @@ impl AgentCtx {
}
}

/// Creates a child context for a specific agent
///
/// # Arguments
/// * `agent_name` - Name of the agent to create context for
pub(crate) fn child(&self, agent_name: &str) -> Result<Self, BoxError> {
Ok(Self {
base: self.base.child(format!("A:{}", agent_name))?,
Expand All @@ -43,10 +86,20 @@ impl AgentCtx {
})
}

/// Creates a child base context for a specific tool
///
/// # Arguments
/// * `tool_name` - Name of the tool to create context for
pub(crate) fn child_base(&self, tool_name: &str) -> Result<BaseCtx, BoxError> {
self.base.child(format!("T:{}", tool_name))
}

/// Creates a child context with additional user and caller information
///
/// # Arguments
/// * `agent_name` - Name of the agent
/// * `user` - Optional user identifier
/// * `caller` - Optional caller principal
pub(crate) fn child_with(
&self,
agent_name: &str,
Expand All @@ -63,6 +116,12 @@ impl AgentCtx {
})
}

/// Creates a child base context with additional user and caller information
///
/// # Arguments
/// * `tool_name` - Name of the tool
/// * `user` - Optional user identifier
/// * `caller` - Optional caller principal
pub(crate) fn child_base_with(
&self,
tool_name: &str,
Expand All @@ -75,16 +134,36 @@ impl AgentCtx {
}

impl AgentContext for AgentCtx {
/// Gets definitions for multiple tools, optionally filtered by names
/// Retrieves definitions for available tools
///
/// # Arguments
/// * `names` - Optional filter for specific tool names
///
/// # Returns
/// Vector of function definitions for the requested tools
fn tool_definitions(&self, names: Option<&[&str]>) -> Vec<FunctionDefinition> {
self.tools.definitions(names)
}

/// Gets definitions for multiple agents, optionally filtered by names
/// Retrieves definitions for available agents
///
/// # Arguments
/// * `names` - Optional filter for specific agent names
///
/// # Returns
/// Vector of function definitions for the requested agents
fn agent_definitions(&self, names: Option<&[&str]>) -> Vec<FunctionDefinition> {
self.agents.definitions(names)
}

/// Executes a tool call with the given arguments
///
/// # Arguments
/// * `name` - Name of the tool to call
/// * `args` - Arguments for the tool call as a JSON string
///
/// # Returns
/// Tuple containing the result string and a boolean indicating if further processing is needed
async fn tool_call(&self, name: &str, args: String) -> Result<(String, bool), BoxError> {
if !self.tools.contains(name) {
return Err(format!("tool {} not found", name).into());
Expand All @@ -94,6 +173,12 @@ impl AgentContext for AgentCtx {
self.tools.call(name, ctx, args).await
}

/// Executes a remote tool call via HTTP RPC
///
/// # Arguments
/// * `endpoint` - Remote endpoint URL
/// * `tool_name` - Name of the tool to call
/// * `args` - Arguments for the tool call as a JSON string
async fn remote_tool_call(
&self,
endpoint: &str,
Expand All @@ -104,6 +189,15 @@ impl AgentContext for AgentCtx {
.await
}

/// Runs an agent with the given prompt and optional attachment
///
/// # Arguments
/// * `name` - Name of the agent to run
/// * `prompt` - Input prompt for the agent
/// * `attachment` - Optional binary attachment
///
/// # Returns
/// [`AgentOutput`] containing the result of the agent execution
async fn agent_run(
&self,
name: &str,
Expand All @@ -118,6 +212,13 @@ impl AgentContext for AgentCtx {
self.agents.run(name, ctx, prompt, attachment).await
}

/// Runs a remote agent via HTTP RPC
///
/// # Arguments
/// * `endpoint` - Remote endpoint URL
/// * `agent_name` - Name of the agent to run
/// * `prompt` - Input prompt for the agent
/// * `attachment` - Optional binary attachment
async fn remote_agent_run(
&self,
endpoint: &str,
Expand All @@ -131,6 +232,25 @@ impl AgentContext for AgentCtx {
}

impl CompletionFeatures for AgentCtx {
/// Executes a completion request with automatic tool call handling
///
/// This method handles the completion request in a loop, automatically executing
/// any tool calls that are returned by the model and feeding their results back
/// into the model until no more tool calls need to be processed.
///
/// # Arguments
/// * `req` - [`CompletionRequest`] containing the input parameters
///
/// # Returns
/// [`AgentOutput`] containing the final completion result
///
/// # Process Flow
/// 1. Makes initial completion request to the model
/// 2. If tool calls are returned:
/// - Executes each tool call
/// - Adds tool results to the chat history
/// - Repeats the completion with updated history
/// 3. Returns final result when no more tool calls need processing
async fn completion(&self, mut req: CompletionRequest) -> Result<AgentOutput, BoxError> {
let mut tool_calls_result: Vec<ToolCall> = Vec::new();
loop {
Expand Down Expand Up @@ -183,17 +303,32 @@ impl CompletionFeatures for AgentCtx {
}

impl EmbeddingFeatures for AgentCtx {
/// Gets the number of dimensions for the embedding model
fn ndims(&self) -> usize {
self.model.ndims()
}

/// Generates embeddings for a collection of texts
///
/// # Arguments
/// * `texts` - Collection of text strings to embed
///
/// # Returns
/// Vector of embeddings, one for each input text
async fn embed(
&self,
texts: impl IntoIterator<Item = String> + Send,
) -> Result<Vec<Embedding>, BoxError> {
self.model.embed(texts).await
}

/// Generates an embedding for a single query text
///
/// # Arguments
/// * `text` - Input text to embed
///
/// # Returns
/// Embedding vector for the input text
async fn embed_query(&self, text: &str) -> Result<Embedding, BoxError> {
self.model.embed_query(text).await
}
Expand All @@ -202,18 +337,22 @@ impl EmbeddingFeatures for AgentCtx {
impl BaseContext for AgentCtx {}

impl StateFeatures for AgentCtx {
/// Gets the current user identifier, if available
fn user(&self) -> Option<String> {
self.base.user()
}

/// Gets the current caller principal, if available
fn caller(&self) -> Option<Principal> {
self.base.caller()
}

/// Gets the cancellation token for the current context
fn cancellation_token(&self) -> CancellationToken {
self.base.cancellation_token()
}

/// Gets the elapsed time since the context was created
fn time_elapsed(&self) -> Duration {
self.base.time_elapsed()
}
Expand Down
Loading

0 comments on commit 66087a6

Please sign in to comment.