<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 driver orchestration engine.<br>
Capable of processing natural language and automatically executing OS-native drivers, 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, driver_categories â â
â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â â
â âŧ â
â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â 3. Workflow Execution (Step 2) using clean_intent â â
â â ââââââââââââ ââââââââââââ ââââââââââââ âââââââââââââââââââ â â
â â â ReAct â â Batch â â Chain â â PlanAndExecute â â â
â â ââââââŦââââââ ââââââŦââââââ ââââââŦââââââ âââââââââŦââââââââââ â â
â â ââââââââââââââ´âââââââââââââ´âââââââââââââââ â â
â â LLM generates DriverCall â 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, driver_categories
â
âŧ
âââââââââââââââ
â Step 2 â â Workflow Execution
â Execution â Execute drivers 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: DriverScheduler â â â
â â âââââââââââââââââââââââââââââââââââââââââââââââââââââââ â â
â âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â
âŧ
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â 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 driver + 1 final response | Open-ended tasks, dynamic decision making, error recovery |
| Batch | WorkflowMode::Batch | Execute multiple independent drivers 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="https://raw.githubusercontent.com/0xhappyboy/hippox/main/assets/architecture/chain_en.png" width="100%" ></td>
<td align="center"><img src="https://raw.githubusercontent.com/0xhappyboy/hippox/main/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="https://raw.githubusercontent.com/0xhappyboy/hippox/main/assets/architecture/re-act_en.png" width="100%"></td>
<td align="center"><img src="https://raw.githubusercontent.com/0xhappyboy/hippox/main/assets/architecture/plan-and-execute_en.png" width="100%"></td>
</tr>
</table>
## Workflow Atomic Driver Retry Strategy
<table>
<tr>
<td align="left">
<h4>ReAct</h4>
</td>
<td align="left">
<h4>PlanAndExecute</h4>
</td>
</tr>
<tr>
<td align="center"><img src="https://raw.githubusercontent.com/0xhappyboy/hippox/main/assets/retry_react_en.png" width="100%" ></td>
<td align="center"><img src="https://raw.githubusercontent.com/0xhappyboy/hippox/main/assets/retry_planandexecute_en.png" width="100%"></td>
</tr>
<tr>
<td align="left">
<h4>Chain</h4>
</td>
<td align="left">
<h4>Batch</h4>
</td>
</tr>
<tr>
<td align="center"><img src="https://raw.githubusercontent.com/0xhappyboy/hippox/main/assets/retry_chain_en.png" width="100%"></td>
<td align="center"><img src="https://raw.githubusercontent.com/0xhappyboy/hippox/main/assets/retry_batch_en.png" width="100%"></td>
</tr>
</table>
## Driver Registry
### Working Principle
```
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â DRIVER REGISTRY â
â â
â DriverRegistryMap = HashMap<DriverCategory, â
â HashMap<String, Arc<dyn Driver>>> â
â â
â ââââââââââââ ââââââââââââ ââââââââââââ â
â â File â â Math â â Net â â
â âââââââââââ⤠âââââââââââ⤠âââââââââââ⤠â
â â read â â calc â â http â â
â â write â â power â â ping â â
â â delete â â stats â â dns â â
â â ... â â ... â â ... â â
â ââââââââââââ ââââââââââââ ââââââââââââ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Registration:
Compile-time: file_register() / math_register() / net_register()
Runtime: register_driver(category, name, driver)
Query:
get_driver_by_name("read") â Driver impl â execute()
```
### Core Type
```rust
pub type DriverRegistryMap = HashMap<DriverCategory, HashMap<String, Arc<dyn Driver>>>;
```
### Main Functions
| get_registry() | Get read lock on the registry |
| get_registry_mut() | Get write lock on the registry |
| register_driver(category, name, driver) | Dynamically register a driver |
| get_all_drivers() | Get all registered drivers |
| get_driver_by_name(name) | Find a driver by name |
| get_driver_by_name_and_category(name, category) | Find a driver by name and category |
| has_driver(name) | Check if a driver exists |
| list_drivers_names() | List all driver names |
| list_drivers_name_by_category(category) | List driver names in a category |
| get_drivers_by_category(category) | Get drivers by category string |
| get_drivers_by_category_list(categories) | Get drivers by multiple categories |
| list_drivers_name_by_category_list(categories) | List driver names by multiple categories |
| get_all_categorys() | Get all category names |
| get_driver_category() | Get categories with driver counts |
| get_driver_category_names() | Get all category names |
| get_driver_category_name_and_describe() | Get category names with descriptions |
| generate_driver_registry_table_json_str() | Generate registry JSON string |
### DriverCategory 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 |