use crate::boundaries::*;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub type AgentId = String;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Agent {
pub id: AgentId,
pub system_prompt: SystemPrompt,
pub model_preference: ModelPreference,
pub declared_tools: Vec<String>,
pub routing_examples: Vec<String>,
pub capabilities: AgentCapabilities,
#[serde(default)]
pub tool_access: AgentToolAccess,
#[serde(default)]
pub tool_class_policy: AgentToolClassPolicy,
pub permissions: PermissionSet,
pub guardrails: Vec<Guardrail>,
pub context_budget: ContextBudget,
pub tool_policy: ToolPolicy,
pub communication_rules: CommunicationRules,
pub write_governance: WriteGovernance,
#[serde(default)]
pub cognitive_architecture: Option<crate::cognitive::CognitiveArchitecture>,
#[serde(default)]
pub metadata: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SystemPrompt {
Static(String),
Template {
template: String,
variables: HashMap<String, String>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelPreference {
pub primary: String,
#[serde(default)]
pub fallbacks: Vec<String>,
#[serde(default)]
pub params: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct AgentCapabilities {
#[serde(default)]
pub can_read_files: bool,
#[serde(default)]
pub can_write_files: bool,
#[serde(default)]
pub can_execute_code: bool,
#[serde(default)]
pub can_search_web: bool,
#[serde(default)]
pub custom: HashMap<String, bool>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct AgentToolAccess {
#[serde(default)]
pub collective_context_tools: Vec<String>,
#[serde(default)]
pub scoped_context_tools: Vec<String>,
#[serde(default)]
pub maintenance_tools: Vec<String>,
#[serde(default)]
pub scoped_memory_write_tools: Vec<String>,
#[serde(default)]
pub collective_memory_write_tools: Vec<String>,
#[serde(default)]
pub action_tools: Vec<String>,
#[serde(default)]
pub coordination_query_tools: Vec<String>,
#[serde(default)]
pub coordination_transfer_tools: Vec<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AgentToolClass {
CollectiveContext,
ScopedContext,
Maintenance,
ScopedMemoryWrite,
CollectiveMemoryWrite,
Action,
CoordinationQuery,
CoordinationTransfer,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct AgentToolClassPolicy {
pub collective_context: ToolClassConstraint,
pub scoped_context: ToolClassConstraint,
pub maintenance: ToolClassConstraint,
pub scoped_memory_write: ToolClassConstraint,
pub collective_memory_write: ToolClassConstraint,
pub action: ToolClassConstraint,
pub coordination_query: ToolClassConstraint,
pub coordination_transfer: ToolClassConstraint,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub enum ToolClassConstraint {
#[default]
Inherit,
Allowed,
RequiresApproval,
Denied,
}
impl Agent {
pub fn new(id: impl Into<String>, system_prompt: impl Into<String>) -> Self {
Self {
id: id.into(),
system_prompt: SystemPrompt::Static(system_prompt.into()),
model_preference: ModelPreference {
primary: "default".into(),
fallbacks: vec![],
params: HashMap::new(),
},
declared_tools: vec![],
routing_examples: vec![],
capabilities: AgentCapabilities::default(),
tool_access: AgentToolAccess::default(),
tool_class_policy: AgentToolClassPolicy::default(),
permissions: PermissionSet::default(),
guardrails: vec![],
context_budget: ContextBudget::default(),
tool_policy: ToolPolicy::default(),
communication_rules: CommunicationRules::default(),
write_governance: WriteGovernance::default(),
cognitive_architecture: None,
metadata: HashMap::new(),
}
}
#[must_use]
pub fn with_cognitive_architecture(
mut self,
arch: crate::cognitive::CognitiveArchitecture,
) -> Self {
self.cognitive_architecture = Some(arch);
self
}
#[must_use]
pub fn with_tool_access(mut self, tool_access: AgentToolAccess) -> Self {
self.tool_access = tool_access;
self
}
#[must_use]
pub fn with_tool_class_policy(mut self, tool_class_policy: AgentToolClassPolicy) -> Self {
self.tool_class_policy = tool_class_policy;
self
}
}
impl AgentToolAccess {
#[must_use]
pub fn tool_names(&self) -> Vec<String> {
let mut names = std::collections::BTreeSet::new();
names.extend(self.collective_context_tools.iter().cloned());
names.extend(self.scoped_context_tools.iter().cloned());
names.extend(self.maintenance_tools.iter().cloned());
names.extend(self.scoped_memory_write_tools.iter().cloned());
names.extend(self.collective_memory_write_tools.iter().cloned());
names.extend(self.action_tools.iter().cloned());
names.extend(self.coordination_query_tools.iter().cloned());
names.extend(self.coordination_transfer_tools.iter().cloned());
names.into_iter().collect()
}
#[must_use]
pub fn with_collective_context_tools(mut self, tools: Vec<String>) -> Self {
self.collective_context_tools = tools;
self
}
#[must_use]
pub fn with_scoped_context_tools(mut self, tools: Vec<String>) -> Self {
self.scoped_context_tools = tools;
self
}
#[must_use]
pub fn with_maintenance_tools(mut self, tools: Vec<String>) -> Self {
self.maintenance_tools = tools;
self
}
#[must_use]
pub fn with_scoped_memory_write_tools(mut self, tools: Vec<String>) -> Self {
self.scoped_memory_write_tools = tools;
self
}
#[must_use]
pub fn with_collective_memory_write_tools(mut self, tools: Vec<String>) -> Self {
self.collective_memory_write_tools = tools;
self
}
#[must_use]
pub fn with_action_tools(mut self, tools: Vec<String>) -> Self {
self.action_tools = tools;
self
}
#[must_use]
pub fn with_coordination_query_tools(mut self, tools: Vec<String>) -> Self {
self.coordination_query_tools = tools;
self
}
#[must_use]
pub fn with_coordination_transfer_tools(mut self, tools: Vec<String>) -> Self {
self.coordination_transfer_tools = tools;
self
}
#[must_use]
pub fn classify_tool(&self, tool_name: &str) -> Option<AgentToolClass> {
if self
.collective_context_tools
.iter()
.any(|name| name == tool_name)
{
Some(AgentToolClass::CollectiveContext)
} else if self
.scoped_context_tools
.iter()
.any(|name| name == tool_name)
{
Some(AgentToolClass::ScopedContext)
} else if self.maintenance_tools.iter().any(|name| name == tool_name) {
Some(AgentToolClass::Maintenance)
} else if self
.scoped_memory_write_tools
.iter()
.any(|name| name == tool_name)
{
Some(AgentToolClass::ScopedMemoryWrite)
} else if self
.collective_memory_write_tools
.iter()
.any(|name| name == tool_name)
{
Some(AgentToolClass::CollectiveMemoryWrite)
} else if self.action_tools.iter().any(|name| name == tool_name) {
Some(AgentToolClass::Action)
} else if self
.coordination_query_tools
.iter()
.any(|name| name == tool_name)
{
Some(AgentToolClass::CoordinationQuery)
} else if self
.coordination_transfer_tools
.iter()
.any(|name| name == tool_name)
{
Some(AgentToolClass::CoordinationTransfer)
} else {
None
}
}
}
impl AgentToolClassPolicy {
#[must_use]
pub fn constraint_for(&self, class: AgentToolClass) -> &ToolClassConstraint {
match class {
AgentToolClass::CollectiveContext => &self.collective_context,
AgentToolClass::ScopedContext => &self.scoped_context,
AgentToolClass::Maintenance => &self.maintenance,
AgentToolClass::ScopedMemoryWrite => &self.scoped_memory_write,
AgentToolClass::CollectiveMemoryWrite => &self.collective_memory_write,
AgentToolClass::Action => &self.action,
AgentToolClass::CoordinationQuery => &self.coordination_query,
AgentToolClass::CoordinationTransfer => &self.coordination_transfer,
}
}
#[must_use]
pub fn with_collective_context(mut self, constraint: ToolClassConstraint) -> Self {
self.collective_context = constraint;
self
}
#[must_use]
pub fn with_scoped_context(mut self, constraint: ToolClassConstraint) -> Self {
self.scoped_context = constraint;
self
}
#[must_use]
pub fn with_maintenance(mut self, constraint: ToolClassConstraint) -> Self {
self.maintenance = constraint;
self
}
#[must_use]
pub fn with_scoped_memory_write(mut self, constraint: ToolClassConstraint) -> Self {
self.scoped_memory_write = constraint;
self
}
#[must_use]
pub fn with_collective_memory_write(mut self, constraint: ToolClassConstraint) -> Self {
self.collective_memory_write = constraint;
self
}
#[must_use]
pub fn with_action(mut self, constraint: ToolClassConstraint) -> Self {
self.action = constraint;
self
}
#[must_use]
pub fn with_coordination_query(mut self, constraint: ToolClassConstraint) -> Self {
self.coordination_query = constraint;
self
}
#[must_use]
pub fn with_coordination_transfer(mut self, constraint: ToolClassConstraint) -> Self {
self.coordination_transfer = constraint;
self
}
}
impl AgentToolClass {
#[must_use]
pub fn stable_name(self) -> &'static str {
match self {
AgentToolClass::CollectiveContext => "collective_context",
AgentToolClass::ScopedContext => "scoped_context",
AgentToolClass::Maintenance => "maintenance",
AgentToolClass::ScopedMemoryWrite => "scoped_memory_write",
AgentToolClass::CollectiveMemoryWrite => "collective_memory_write",
AgentToolClass::Action => "action",
AgentToolClass::CoordinationQuery => "coordination_query",
AgentToolClass::CoordinationTransfer => "coordination_transfer",
}
}
}