hippox 0.3.4

🦛A reliable AI agent and skills orchestration runtime engine.
Documentation
mod config;
mod core;
mod envs;
mod executors;
mod global;
mod i18n;
mod memory;
mod skill_loader;
mod skill_scheduler;
mod types;

pub use config::{GLOBAL_CONFIG, HippoxConfig, get_config, init_config_from_env};
pub use core::Hippox;
pub use langhub::types::ModelProvider;

#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::tempdir;

    fn create_test_skill_md(dir: &tempfile::TempDir, skill_name: &str, description: &str) {
        let skill_dir = dir.path().join(skill_name);
        std::fs::create_dir_all(&skill_dir).unwrap();
        let skill_md = skill_dir.join("SKILL.md");
        let content = format!(
            r#"---
name: {}
description: {}
version: 1.0.0
author: Test Author
---

# {} Skill

This is a test workflow for {}.

## Instructions
Process the request and return a result.
"#,
            skill_name, description, skill_name, description
        );
        std::fs::write(skill_md, content).unwrap();
    }

    #[tokio::test]
    async fn test_hippox_new() {
        let temp_dir = tempdir().unwrap();
        let hippox = Hippox::new(
            temp_dir.path().to_str().unwrap(),
            ModelProvider::OpenAI,
            "en",
        )
        .await;
        assert!(hippox.is_ok());
    }

    #[tokio::test]
    async fn test_list_atomic_skills() {
        let temp_dir = tempdir().unwrap();
        let hippox = Hippox::new(
            temp_dir.path().to_str().unwrap(),
            ModelProvider::OpenAI,
            "en",
        )
        .await
        .unwrap();
        let skills = hippox.list_atomic_skills();
        assert!(skills.contains("calculator") || skills.contains("helloworld"));
    }

    #[tokio::test]
    async fn test_list_skill_md_files() {
        let temp_dir = tempdir().unwrap();
        create_test_skill_md(&temp_dir, "test-skill", "A test skill");
        let hippox = Hippox::new(
            temp_dir.path().to_str().unwrap(),
            ModelProvider::OpenAI,
            "en",
        )
        .await
        .unwrap();
        let list = hippox.list_skill_md_files();
        assert!(list.contains("test-skill"));
    }

    #[tokio::test]
    async fn test_clear_conversation() {
        let temp_dir = tempdir().unwrap();
        let hippox = Hippox::new(
            temp_dir.path().to_str().unwrap(),
            ModelProvider::OpenAI,
            "en",
        )
        .await
        .unwrap();
        hippox.clear_conversation("test-session");
        hippox.clear_all_conversations();
    }

    #[test]
    fn test_extract_json() {
        let text = r#"Some text {"action": "calculator", "parameters": {"input": "2+2"}}"#;
        let json = Hippox::extract_json(text);
        assert!(json.contains("calculator"));
        let text = "```json\n{\"action\": \"test\"}\n```";
        let json = Hippox::extract_json(text);
        assert_eq!(json, "{\"action\": \"test\"}");
    }

    #[test]
    fn test_get_atomic_skill_names() {
        let temp_dir = tempdir().unwrap();
        let hippox = tokio::runtime::Runtime::new().unwrap().block_on(async {
            Hippox::new(
                temp_dir.path().to_str().unwrap(),
                ModelProvider::OpenAI,
                "en",
            )
            .await
            .unwrap()
        });
        let names = hippox.get_atomic_skill_names();
        assert!(!names.is_empty());
        assert!(names.contains(&"calculator".to_string()));
    }

    #[test]
    fn test_has_atomic_skills() {
        let temp_dir = tempdir().unwrap();
        let hippox = tokio::runtime::Runtime::new().unwrap().block_on(async {
            Hippox::new(
                temp_dir.path().to_str().unwrap(),
                ModelProvider::OpenAI,
                "en",
            )
            .await
            .unwrap()
        });
        assert!(hippox.has_atomic_skills());
    }

    #[test]
    fn test_skills_directory() {
        let temp_dir = tempdir().unwrap();
        let path = temp_dir.path().to_str().unwrap();
        let hippox = tokio::runtime::Runtime::new().unwrap().block_on(async {
            Hippox::new(path, ModelProvider::OpenAI, "en")
                .await
                .unwrap()
        });
        assert_eq!(hippox.skills_directory().to_str().unwrap(), path);
    }
}