hippox 0.2.0

The most reliable AI agent.🦛
Documentation
use std::sync::Arc;

use crate::core::Hippox;
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
use tokio::net::{TcpListener, TcpStream};
use tracing::{error, info};

pub async fn run_tcp_server(hippox: Arc<Hippox>, addr: &str) -> anyhow::Result<()> {
    let listener = TcpListener::bind(addr).await?;
    info!("TCP server listening on {}", addr);
    loop {
        let (stream, addr) = listener.accept().await?;
        let hippox = hippox.clone();
        tokio::spawn(async move {
            if let Err(e) = handle_tcp_client(hippox, stream).await {
                error!("TCP client {} error: {}", addr, e);
            }
        });
    }
}

async fn handle_tcp_client(hippox: Arc<Hippox>, mut stream: TcpStream) -> anyhow::Result<()> {
    let (reader, mut writer) = stream.split();
    let mut reader = BufReader::new(reader);
    let mut line = String::new();
    writer
        .write_all(b"Hippo TCP Server\nAvailable skills: \n")
        .await?;
    writer.write_all(hippox.list_skills().as_bytes()).await?;
    writer.write_all(b"\n> ").await?;
    loop {
        line.clear();
        match reader.read_line(&mut line).await {
            Ok(0) => break,
            Ok(_) => {
                let input = line.trim();
                let result = hippox.process(input).await;
                if result.response == "goodbye" {
                    writer.write_all(b"Goodbye!\n").await?;
                    break;
                }
                if result.matched {
                    writer
                        .write_all(format!("🦛 {}\n> ", result.response).as_bytes())
                        .await?;
                } else {
                    writer
                        .write_all(format!("{}\n> ", result.response).as_bytes())
                        .await?;
                }
            }
            Err(e) => {
                writer
                    .write_all(format!("Error: {}\n", e).as_bytes())
                    .await?;
                break;
            }
        }
    }
    Ok(())
}