<p align="center">
<img src="https://raw.githubusercontent.com/0xhappyboy/hippox/main/assets/logo/logo-1.png" alt="Portal" width="100" height="100">
</p>
<h1 align="center">
HippoX
</h1>
<h4 align="center">
A reliable, autonomous LLM runtime and skill orchestration engine.<br>
Capable of processing natural language and automatically executing OS-native atomic skills, fundamentally enabling the LLM to truly take over the computer.
</h4>
<p align="center">
<a href="https://github.com/0xhappyboy/hippo/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache2.0-d1d1f6.svg?style=flat&labelColor=1C2C2E&color=BEC5C9&logo=googledocs&label=license&logoColor=BEC5C9" alt="License"></a>
<a href="https://crates.io/crates/hippox">
<img src="https://img.shields.io/badge/crates-hippox-20B2AA.svg?style=flat&labelColor=0F1F2D&color=FFD700&logo=rust&logoColor=FFD700">
</a><a href="https://crates.io/crates/hippox">
<img src="https://img.shields.io/crates/d/hippox?style=flat&labelColor=0F1F2D&color=20B2AA&logo=rust&logoColor=white&label=downloads" alt="Crates.io Downloads">
</a>
</p>
<p align="center">
<a href="./README_zh-CN.md">็ฎไฝไธญๆ</a> | <a href="./README.md">English</a>
</p>
## ๐ Quick Links
| ๐ **Website** | [https://hippox.vercel.app/](https://hippox.vercel.app/) |
| ๐ **Documentation** | [https://hippox-docs-en.vercel.app/](https://hippox-docs-en.vercel.app/) |
| ๐ฆ **Crates.io** | [https://crates.io/crates/hippox](https://crates.io/crates/hippox) |
| ๐ป **GitHub** | [https://github.com/0xhappyboy/hippo](https://github.com/0xhappyboy/hippo) |
## Basic Usage
### Instantiate
```rust
// =================== Method 1 ===================
let hippox = Hippox::builder(ModelProvider::OpenAI)
.api_key("sk-xxx")
.lang("zh")
.identity(|id| {
id.name = Some("agent".to_string());
id.role = Some("assistant".to_string());
id.personality = Some("friendly".to_string());
})
.build()
.await?;
// =================== Method 2 ===================
let mut config = HippoxConfig::default();
config.lang = "zh".to_string();
config.identity_information = IdentityInformation {
name: Some("agent".to_string()),
role: Some("assistant".to_string()),
personality: Some("friendly".to_string()),
..Default::default()
};
let hippox = Hippox::new(
ModelProvider::OpenAI,
Some("sk-xxx".to_string()),
None,
Some(config),
).await?;
// =================== Simple Method ===================
let hippox = Hippox::new(
ModelProvider::OpenAI,
Some("sk-xxx".to_string()),
None,
Some(HippoxConfig::default()),
).await?;
// builder
let hippox = Hippox::builder(ModelProvider::OpenAI)
.api_key("sk-xxx")
.build()
.await?;
```
### Task Execution
#### Submit
##### 1. Execution mode
- Asynchronous non-blocking submission. Task goes to background pool, returns task_id immediately. Result must be obtained via polling.
##### 2. How it works
- Call `submit()` method
- `NaturalLanguageTask` is created and pushed to global `TASK_POOL`
- Background execution engine processes tasks automatically
- Method `returns task_id immediately (does NOT wait for completion)`
- Caller repeatedly queries `get_task(task_id)` to check status
- When `task.status == TaskStatus::Completed`, extract result from `task.final_output`
##### 3. Use when
- You don't need immediate results, or want to run multiple tasks concurrently.
```rust
use hippox::{Hippox, TaskStatus};
use langhub::types::ModelProvider;
use std::time::Duration;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let hippox = Hippox::builder(ModelProvider::OpenAI)
.api_key("sk-xxx")
.build()
.await?;
// Submit task, returns task_id immediately
let task_id = hippox.submit("Calculate 15 * 3", None);
let result = hippox.wait_task(&task_id).await?;
println!("Result: {}", result);
Ok(())
}
```
#### Execute - Direct execution
##### 1. Execution mode
- Synchronous blocking call. The function waits until the task completes and returns the result directly.
##### 2. How it works
- Call `execute()` method
- Task starts immediately in the current thread
- Code pauses and waits for completion
- Returns `String` result directly
##### 3. Use when
- You need the result immediately and don't want to manage task state.
```rust
use hippox::Hippox;
use langhub::types::ModelProvider;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let hippox = Hippox::builder(ModelProvider::OpenAI)
.api_key("sk-xxx")
.build()
.await?;
// Execute and wait for result
let result = hippox.execute("Calculate 15 * 3", None).await;
println!("Result: {}", result);
Ok(())
}
```
### Configuration
#### 1. HippoxConfig
```rust
/// Hippox global configuration
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
pub struct HippoxConfig {
/// Language setting: "en" or "zh"
pub lang: String,
/// AI identity information (name, role, personality, etc.)
pub identity_information: IdentityInformation,
}
```
#### 2. IdentityInformation
```rust
/// AI identity configuration
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
pub struct IdentityInformation {
/// AI name, e.g., "Assistant", "Hippox"
pub name: Option<String>,
/// Gender, e.g., "male", "female", "neutral"
pub sex: Option<String>,
/// Age, e.g., "25", "young"
pub age: Option<String>,
/// Species, e.g., "AI", "human", "robot"
pub species: Option<String>,
/// Role, e.g., "assistant", "teacher", "life coach"
pub role: Option<String>,
/// Personality, e.g., "friendly", "humorous", "professional"
pub personality: Option<String>,
/// Tone style, e.g., "casual", "formal", "poetic"
pub tone_style: Option<String>,
/// Knowledge scope, e.g., "general", "medical", "programming"
pub knowledge_scope: Option<String>,
/// Catchphrase, e.g., "Haha", "I see", "Let's go"
pub catchphrase: Option<String>,
/// Prohibited topics, e.g., "no politics", "no medical advice"
pub taboos: Option<String>,
}
```
## Hippox Core Working Principle
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Hippox Core Working Principle โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 1. Task Submission (Non-blocking) โ โ
โ โ hippox.submit(input) โ NaturalLanguageTask โ TASK_POOL โ โ
โ โ โ TASK_NOTIFIER.notify_one() โ return task_id โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 2. Intent Analysis (Step 1) โ โ
โ โ build_intent_parser_prompt() โ LLM.generate() โ parse โ โ
โ โ Output: clean_intent, skill_categories โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 3. Workflow Execution (Step 2) using clean_intent โ โ
โ โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ ReAct โ โ Batch โ โ Chain โ โ PlanAndExecute โ โ โ
โ โ โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ โโโโโโโโโฌโโโโโโโโโโ โ โ
โ โ โโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโโโโโ โ โ
โ โ LLM generates SkillCall โ Executor.execute() โ raw_json โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 4. Response Formatting (Step 3) โ โ
โ โ needs_format_conversion(original_input)? โ โ
โ โ โโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ false โ โโโถ โ return raw_json directly โ โ โ
โ โ โโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ true โ โโโถ โ build_format_conversion_prompt() โ โ โ
โ โ โโโโโโโโโโโ โ โ LLM.generate() โ formatted output โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ final_output โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
## Pipe Line
```
User Input
โ
โผ
โโโโโโโโโโโโโโโ
โ Step 1 โ โ Intent Analysis
โ Analysis โ build_intent_parser_prompt() โ LLM
โโโโโโโโฌโโโโโโโ Output: clean_intent, skill_categories
โ
โผ
โโโโโโโโโโโโโโโ
โ Step 2 โ โ Workflow Execution
โ Execution โ Execute skills using clean_intent
โโโโโโโโฌโโโโโโโ Output: raw_json
โ
โผ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โ Need Format โ โโYesโโโถโ Step 3 โ โ Response Formatting
โ Conversion? โ โ Formatting โ build_format_conversion_prompt() โ LLM
โโโโโโโโฌโโโโโโโ โโโโโโโโฌโโโโโโโ
โ โ
โโโโโโโโโโโโฌโโโโโโโโโโ
โผ
Final Output
```
## Task Pool
### State Machine
```
Pending โโโบ Running โโโบ Completed
โ โ
โ โโโโบ Paused โโโบ Running (resume)
โ โ
โ โโโโบ Cancelled
โ
โโโโบ Cancelled
โ
โโโโบ Failed โโโบ Pending (retry)
```
### Architecture
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Global Static (Auto-Start) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ GLOBAL_TASK_POOL โ โ
โ โ (Initialized at program load) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Hippox Instance โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ TaskPool (Global) โ โ
โ โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ โ
โ โ โTask A โ โTask B โ โTask C โ โ โ
โ โ โPending โ โRunning โ โPending โ โ โ
โ โ โโโโโโฌโโโโโ โโโโโโฌโโโโโ โโโโโโฌโโโโโ โ โ
โ โ โโโโโโโโโโโโโโผโโโโโโโโโโโโโ โ โ
โ โ โผ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ Priority Queue โ โ โ
โ โ โ [Task A, Task C] โ โ โ
โ โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ โ
โ โ โ โ โ
โ โ โผ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ Execution Engine โ (max: 10 workers) โ โ
โ โ โ โโโโโโ โโโโโโ โโโโโโ โ โ
โ โ โ โ W1 โ โ W2 โ โ W3 โ ... โ โ
โ โ โ โโโโฌโโ โโโโฌโโ โโโโฌโโ โ โ
โ โ โ โโโโโโโโผโโโโโโโ โ โ
โ โ โ โผ โ โ
โ โ โ โโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ โ ExecutableTask โ โ โ
โ โ โ โ .execute() โ โ โ
โ โ โ โโโโโโโโโโโโโโโโโโโ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โฒ โ โ
โ โ โโโโโโโโโโโโดโโโโโโโโโโโ โ โ
โ โ โ Notifier (wakeup) โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ExecutableTask Implementation โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ NaturalLanguageTask โ โ โ
โ โ โ โข input: String โ โ โ
โ โ โ โข workflow_executor: WorkflowExecutor โ โ โ
โ โ โ โข scheduler: SkillScheduler โ โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ External APIs โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ handle_natural_language() โ task_id (non-blocking) โ
โ get_task_status() / cancel() / pause() / resume() / retry() โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
## Workflow Model
| ReAct | WorkflowMode::ReAct | Think โ Act โ Observe loop, LLM decides next step after each execution | 1 per skill + 1 final response | Open-ended tasks, dynamic decision making, error recovery |
| Batch | WorkflowMode::Batch | Execute multiple independent skills in parallel | 1 (generates batch plan) | Independent operations, bulk processing |
| Chain | WorkflowMode::Chain | Sequential execution with variable passing ({{variable}} syntax) | 1 (generates chain) | Linear pipelines, data transformation chains |
| PlanAndExecute | WorkflowMode::PlanAndExecute | One-time planning with conditional branching, variable references ({"$ref":"var"}), error handling (retry/skip/fail) | 1 plan + optional dynamic decisions | Complex workflows, conditional logic, deterministic tasks |
<table>
<tr>
<td align="left">
<h4>Chain</h4>
</td>
<td align="left">
<h4>Batch</h4>
</td>
</tr>
<tr>
<td align="center"><img src="./assets/architecture/chain_en.png" width="100%" ></td>
<td align="center"><img src="./assets/architecture/batch_en.png" width="100%"></td>
</tr>
<tr>
<td align="left">
<h4>ReAct</h4>
</td>
<td align="left">
<h4>PlanAndExecute</h4>
</td>
</tr>
<tr>
<td align="center"><img src="./assets/architecture/re-act_en.png" width="100%"></td>
<td align="center"><img src="./assets/architecture/plan-and-execute_en.png" width="100%"></td>
</tr>
</table>
## Atomic Skill Registry
> ๐ก **Hint**๏ผIn Hippox, an atomic skill represents a smallest indivisible unit of execution, This is a different concept from "Skill" in user business.
### Working Principle
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SKILL REGISTRY โ
โ โ
โ SkillRegistryMap = HashMap<SkillCategory, โ
โ HashMap<String, Arc<dyn Skill>>> โ
โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ File โ โ Math โ โ Net โ โ
โ โโโโโโโโโโโโค โโโโโโโโโโโโค โโโโโโโโโโโโค โ
โ โ read โ โ calc โ โ http โ โ
โ โ write โ โ power โ โ ping โ โ
โ โ delete โ โ stats โ โ dns โ โ
โ โ ... โ โ ... โ โ ... โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Registration:
Compile-time: file_register() / math_register() / net_register()
Runtime: register_skill(category, name, skill)
Query:
get_skill_by_name("read") โ Skill impl โ execute()
```
### Core Type
```rust
pub type SkillRegistryMap = HashMap<SkillCategory, HashMap<String, Arc<dyn Skill>>>;
```
### Main Functions
| get_registry() | Get read lock on the registry |
| get_registry_mut() | Get write lock on the registry |
| register_skill(category, name, skill) | Dynamically register a skill |
| get_all_skills() | Get all registered skills |
| get_skill_by_name(name) | Find a skill by name |
| get_skill_by_name_and_category(name, category) | Find a skill by name and category |
| has_skill(name) | Check if a skill exists |
| list_skills_names() | List all skill names |
| list_skills_name_by_category(category) | List skill names in a category |
| get_skills_by_category(category) | Get skills by category string |
| get_skills_by_category_list(categories) | Get skills by multiple categories |
| list_skills_name_by_category_list(categories) | List skill names by multiple categories |
| get_all_categorys() | Get all category names |
| get_skill_category() | Get categories with skill counts |
| get_skill_category_names() | Get all category names |
| get_skill_category_name_and_describe() | Get category names with descriptions |
| generate_skill_registry_table_json_str() | Generate registry JSON string |
### SkillCategory Methods
| from_str(s) | Convert string to enum |
| name() | Convert enum to string (lowercase) |
| display_name() | Get human-readable display name |
| description() | Get category description |
| icon() | Get category icon/emoji |
| priority() | Get display priority (lower = first) |
| metadata() | Get complete category metadata |
| all_categories() | Get metadata for all categories |