mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
* feat: add initial project structure and documentation - Introduced the GNU General Public License (GPL) v3 in LICENSE file. - Added MCP configuration in .claude/mcp.json for server integration. - Created architecture documentation in docs/ARCHITECTURE.md outlining the platform's design and components. - Defined MVP specifications in docs/MVP.md for the Telegram-based Agent Assistant. - Established API reference for team management in docs/teams-api-reference.md. - Set up basic HTML structure in public/index.html and added logo image in public/logo.png. * feat: add initial project documentation and HTML structure - Introduced CODE_OF_CONDUCT.md to establish community guidelines and standards for behavior. - Created CONTRIBUTING.md to outline contribution process, development setup, and project conventions. - Added SECURITY.md to define the security policy, supported versions, and reporting procedures for vulnerabilities. - Established basic HTML structure in index.html for the application interface. * chore: remove hello-python skill files - Deleted skill.json and skill.py files for the Hello Python example runtime skill, as they are no longer needed in the project. * feat: port tinyhuman agent runtime from ZeroClaw into Tauri backend Port daemon supervisor, health registry, security (policy, secrets, audit, pairing), agent traits, and config modules from ZeroClaw (MIT) into a new tinyhuman/ module under src-tauri/src/. The daemon auto-starts on desktop and shuts down gracefully on app exit via CancellationToken. - health: global HealthRegistry with component tracking and JSON snapshots - security/policy: SecurityPolicy with command validation, risk levels, rate limiting - security/secrets: ChaCha20-Poly1305 SecretStore with legacy XOR migration - security/audit: AuditLogger with JSON-line events and log rotation - security/pairing: PairingGuard with brute-force protection and SHA-256 hashing - security/traits: Sandbox trait + NoopSandbox - config: minimal DaemonConfig with autonomy, reliability, secrets, audit sub-configs - daemon: supervisor with health state writer emitting Tauri events - agent/traits: Provider, Tool, Memory, Observer, RuntimeAdapter traits + Noop impls - commands/tinyhuman: Tauri commands for health, security policy, encrypt/decrypt - 185 inline unit tests across all modules - README updated with custom inference/tunneling/memory positioning Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: update README to reflect AlphaHuman Mk1 branding and enhanced description - Changed project title to "AlphaHuman Mk1" for clarity. - Revised project description to emphasize user-friendly AI capabilities and the use of the Neocortex Mk1 model. - Removed outdated sections on custom inference, tunneling, and memory, streamlining the content for better readability. * update readme * Port zeroclaw runtime into tinyhuman * Replace CLI mentions with UI language * Split gateway module into smaller units * Split channels and config schema modules * Fix tinyhuman build, tests, and tunnel integration * feat(tinyhuman): add missing modules and ui-friendly services * refactor: rename tinyhuman to alphahuman * chore: remove bottom text from Welcome component * feat(settings): add tauri command console * feat(daemon): enhance daemon mode handling and integrate rustls with ring feature * feat(settings): implement comprehensive configuration management in TauriCommandsPanel * refactor(TauriCommandsPanel): streamline error handling and enhance async function usage * feat(settings): add skill management functionality to TauriCommandsPanel * style(TauriCommandsPanel): update input styles for improved readability and user experience * feat(settings): add Skills and Agent Chat panels with navigation and integration management * feat(settings): implement browser access management in SkillsPanel and enhance AgentChatPanel with local storage functionality --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
139 lines
3.7 KiB
Rust
139 lines
3.7 KiB
Rust
use super::traits::{Channel, ChannelMessage, SendMessage};
|
|
use async_trait::async_trait;
|
|
use tokio::io::{self, AsyncBufReadExt, BufReader};
|
|
use uuid::Uuid;
|
|
|
|
/// Console channel — stdin/stdout, not used in the web UI, zero deps
|
|
pub struct CliChannel;
|
|
|
|
impl CliChannel {
|
|
pub fn new() -> Self {
|
|
Self
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl Channel for CliChannel {
|
|
fn name(&self) -> &str {
|
|
"cli"
|
|
}
|
|
|
|
async fn send(&self, message: &SendMessage) -> anyhow::Result<()> {
|
|
println!("{}", message.content);
|
|
Ok(())
|
|
}
|
|
|
|
async fn listen(&self, tx: tokio::sync::mpsc::Sender<ChannelMessage>) -> anyhow::Result<()> {
|
|
let stdin = io::stdin();
|
|
let reader = BufReader::new(stdin);
|
|
let mut lines = reader.lines();
|
|
|
|
while let Ok(Some(line)) = lines.next_line().await {
|
|
let line = line.trim().to_string();
|
|
if line.is_empty() {
|
|
continue;
|
|
}
|
|
if line == "/quit" || line == "/exit" {
|
|
break;
|
|
}
|
|
|
|
let msg = ChannelMessage {
|
|
id: Uuid::new_v4().to_string(),
|
|
sender: "user".to_string(),
|
|
reply_target: "user".to_string(),
|
|
content: line,
|
|
channel: "cli".to_string(),
|
|
timestamp: std::time::SystemTime::now()
|
|
.duration_since(std::time::UNIX_EPOCH)
|
|
.unwrap_or_default()
|
|
.as_secs(),
|
|
thread_ts: None,
|
|
};
|
|
|
|
if tx.send(msg).await.is_err() {
|
|
break;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn cli_channel_name() {
|
|
assert_eq!(CliChannel::new().name(), "cli");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn cli_channel_send_does_not_panic() {
|
|
let ch = CliChannel::new();
|
|
let result = ch
|
|
.send(&SendMessage {
|
|
content: "hello".into(),
|
|
recipient: "user".into(),
|
|
subject: None,
|
|
thread_ts: None,
|
|
})
|
|
.await;
|
|
assert!(result.is_ok());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn cli_channel_send_empty_message() {
|
|
let ch = CliChannel::new();
|
|
let result = ch
|
|
.send(&SendMessage {
|
|
content: String::new(),
|
|
recipient: String::new(),
|
|
subject: None,
|
|
thread_ts: None,
|
|
})
|
|
.await;
|
|
assert!(result.is_ok());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn cli_channel_health_check() {
|
|
let ch = CliChannel::new();
|
|
assert!(ch.health_check().await);
|
|
}
|
|
|
|
#[test]
|
|
fn channel_message_struct() {
|
|
let msg = ChannelMessage {
|
|
id: "test-id".into(),
|
|
sender: "user".into(),
|
|
reply_target: "user".into(),
|
|
content: "hello".into(),
|
|
channel: "cli".into(),
|
|
timestamp: 1_234_567_890,
|
|
thread_ts: None,
|
|
};
|
|
assert_eq!(msg.id, "test-id");
|
|
assert_eq!(msg.sender, "user");
|
|
assert_eq!(msg.reply_target, "user");
|
|
assert_eq!(msg.content, "hello");
|
|
assert_eq!(msg.channel, "cli");
|
|
assert_eq!(msg.timestamp, 1_234_567_890);
|
|
}
|
|
|
|
#[test]
|
|
fn channel_message_clone() {
|
|
let msg = ChannelMessage {
|
|
id: "id".into(),
|
|
sender: "s".into(),
|
|
reply_target: "s".into(),
|
|
content: "c".into(),
|
|
channel: "ch".into(),
|
|
timestamp: 0,
|
|
thread_ts: None,
|
|
};
|
|
let cloned = msg.clone();
|
|
assert_eq!(cloned.id, msg.id);
|
|
assert_eq!(cloned.content, msg.content);
|
|
}
|
|
}
|