use chrono::prelude::*;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::fmt;
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Serialize, Deserialize)]
pub enum Status {
#[default]
Idle,
Active,
InUnitTesting,
Completed,
Thinking,
}
impl fmt::Display for Status {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Idle => write!(f, "Idle"),
Self::Active => write!(f, "Active"),
Self::InUnitTesting => write!(f, "InUnitTesting"),
Self::Completed => write!(f, "Completed"),
Self::Thinking => write!(f, "Thinking"),
}
}
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Serialize, Deserialize)]
pub struct Message {
pub role: Cow<'static, str>,
pub content: Cow<'static, str>,
}
impl Message {
pub fn new(role: impl Into<Cow<'static, str>>, content: impl Into<Cow<'static, str>>) -> Self {
Self {
role: role.into(),
content: content.into(),
}
}
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Serialize, Deserialize)]
pub struct Knowledge {
pub facts: HashMap<Cow<'static, str>, Cow<'static, str>>,
}
impl Knowledge {
pub fn insert(
&mut self,
key: impl Into<Cow<'static, str>>,
value: impl Into<Cow<'static, str>>,
) {
self.facts.insert(key.into(), value.into());
}
pub fn get(&self, key: &str) -> Option<&Cow<'static, str>> {
self.facts.get(key as &str)
}
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash)]
pub enum ToolName {
#[default]
Search,
Browser,
News,
Wiki,
Calc,
Math,
Format,
Exec,
Code,
Regex,
Read,
Write,
Pdf,
Summarize,
Email,
Calendar,
Translate,
Sentiment,
Classify,
Memory,
Plan,
Spawn,
Judge,
Plugin(String),
}
#[derive(Clone)]
pub struct Tool {
pub name: ToolName,
pub description: Cow<'static, str>,
pub invoke: fn(&str) -> String,
}
impl fmt::Debug for Tool {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Tool")
.field("name", &self.name)
.field("description", &self.description)
.finish_non_exhaustive()
}
}
impl PartialEq for Tool {
fn eq(&self, other: &Self) -> bool {
self.name == other.name && self.description == other.description
}
}
impl Default for Tool {
fn default() -> Self {
Self {
name: ToolName::default(),
description: Cow::Borrowed(""),
invoke: |_| String::new(),
}
}
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Serialize, Deserialize)]
pub struct Goal {
pub description: String,
pub priority: u8,
pub completed: bool,
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Serialize, Deserialize)]
pub struct Planner {
pub current_plan: Vec<Goal>,
}
impl Planner {
pub fn completed_count(&self) -> usize {
self.current_plan.iter().filter(|g| g.completed).count()
}
pub fn is_done(&self) -> bool {
self.current_plan.iter().all(|g| g.completed)
}
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Serialize, Deserialize)]
pub struct Profile {
pub name: Cow<'static, str>,
pub traits: Vec<Cow<'static, str>>,
pub behavior_script: Option<Cow<'static, str>>,
}
pub struct Reflection {
pub recent_logs: Vec<Cow<'static, str>>,
pub evaluation_fn: fn(&dyn crate::traits::agent::Agent) -> Cow<'static, str>,
}
impl fmt::Debug for Reflection {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Reflection")
.field("recent_logs", &self.recent_logs)
.finish_non_exhaustive()
}
}
impl PartialEq for Reflection {
fn eq(&self, other: &Self) -> bool {
self.recent_logs == other.recent_logs
}
}
impl Clone for Reflection {
fn clone(&self) -> Self {
Self {
recent_logs: self.recent_logs.clone(),
evaluation_fn: self.evaluation_fn,
}
}
}
impl Default for Reflection {
fn default() -> Self {
Self {
recent_logs: vec![],
evaluation_fn: default_eval_fn,
}
}
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Serialize, Deserialize)]
pub struct ScheduledTask {
pub time: DateTime<Utc>,
pub task: Task,
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Serialize, Deserialize)]
pub struct TaskScheduler {
pub scheduled_tasks: Vec<ScheduledTask>,
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Serialize, Deserialize)]
pub enum Capability {
#[default]
CodeGen,
UIDesign,
WebSearch,
SQLAccess,
RobotControl,
ApiIntegration,
TextToSpeech,
Custom(String),
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Serialize, Deserialize)]
pub struct ContextManager {
pub recent_messages: Vec<Message>,
pub focus_topics: Vec<Cow<'static, str>>,
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Copy, Hash, Serialize, Deserialize)]
pub struct Scope {
pub crud: bool,
pub auth: bool,
pub external: bool,
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Serialize, Deserialize)]
pub struct Route {
pub dynamic: Cow<'static, str>,
pub method: Cow<'static, str>,
pub body: Value,
pub response: Value,
pub path: Cow<'static, str>,
}
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Serialize, Deserialize)]
pub struct Task {
pub description: Cow<'static, str>,
pub scope: Option<Scope>,
pub urls: Option<Vec<Cow<'static, str>>>,
pub frontend_code: Option<Cow<'static, str>>,
pub backend_code: Option<Cow<'static, str>>,
pub api_schema: Option<Vec<Route>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ThinkResult {
pub converged: bool,
pub steps: usize,
pub final_error: f64,
pub memory_snapshot: Vec<String>,
pub signals: Vec<crate::cognition::signal::CognitionSignal>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum LearningMode {
QTable,
MetaAdapt,
Distill,
Federated,
Elastic,
Informal,
Smart,
}
impl LearningMode {
pub fn all() -> HashSet<LearningMode> {
[
LearningMode::QTable,
LearningMode::MetaAdapt,
LearningMode::Distill,
LearningMode::Federated,
LearningMode::Elastic,
LearningMode::Informal,
LearningMode::Smart,
]
.into_iter()
.collect()
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ExperienceRecord {
pub state: u64,
pub action: crate::cognition::learning::q_table::ActionKey,
pub reward: f64,
pub next_state: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentSnapshot {
pub agent_id: String,
pub q_table: crate::cognition::learning::q_table::QTable,
pub total_reward: f64,
}
impl Task {
pub fn from_description(description: impl Into<Cow<'static, str>>) -> Self {
Self {
description: description.into(),
..Default::default()
}
}
}
pub fn default_eval_fn(agent: &dyn crate::traits::agent::Agent) -> Cow<'static, str> {
if let Some(planner) = agent.planner() {
let total = planner.current_plan.len();
let completed = planner.completed_count();
let in_progress = total - completed;
let mut summary = format!(
"\n- Total Goals: {total}\n- Completed: {completed}\n- In Progress: {in_progress}\n\nGoals Summary:\n"
);
for goal in &planner.current_plan {
let state = if goal.completed { "✓" } else { "○" };
summary.push_str(&format!(
" [{state}] (priority {}) {}\n",
goal.priority, goal.description
));
}
Cow::Owned(summary)
} else {
Cow::Borrowed("No planner configured.")
}
}