rustglm 1.0.0

Production-oriented async Rust SDK for Zhipu GLM, Realtime, Batch, RAG, and MCP
Documentation
use std::io::{self, Write};
use std::sync::Arc;

use async_trait::async_trait;
use rustglm::{
    AgentHistoryPolicy, AgentManifest, AgentPersona, AgentRuntime, AgentTool, FunctionDefinition,
    Result as SdkResult, ZhipuClient,
};
use serde_json::{Value, json};

struct DeviceInfoTool;

#[async_trait]
impl AgentTool for DeviceInfoTool {
    fn definition(&self) -> FunctionDefinition {
        FunctionDefinition::new(
            "device_info",
            json!({"type":"object","properties":{},"additionalProperties":false}),
        )
        .description("Return the operating system and CPU architecture running this application")
    }

    async fn execute(&self, _: Value) -> SdkResult<Value> {
        Ok(json!({"os":std::env::consts::OS,"arch":std::env::consts::ARCH}))
    }
}

fn read_line(prompt: &str) -> io::Result<String> {
    print!("{prompt}");
    io::stdout().flush()?;
    let mut value = String::new();
    io::stdin().read_line(&mut value)?;
    Ok(value.trim().to_owned())
}

#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let api_key = match std::env::var("ZHIPU_API_KEY") {
        Ok(value) if !value.trim().is_empty() => value,
        _ => read_line("请输入智谱 API Key(输入内容会显示): ")?,
    };
    let model = match read_line("模型名称,直接回车使用 glm-4-flash: ")? {
        value if value.is_empty() => "glm-4-flash".to_owned(),
        value => value,
    };
    let persona = AgentPersona::new("洛书", "跨平台 Rust 技术伙伴")
        .background("熟悉桌面、服务器和移动设备上的 Rust 应用部署")
        .trait_value("准确")
        .trait_value("有明确观点")
        .speaking_style("简洁、自然、先给结论")
        .language("简体中文")
        .instruction("需要设备信息时调用 device_info")
        .boundary("不要假装执行未注册的工具");
    let manifest =
        AgentManifest::new(model, persona).history(AgentHistoryPolicy::Recent { max_messages: 20 });
    println!("可部署清单不包含密钥:\n{}", manifest.to_json()?);

    let client = ZhipuClient::new(api_key)?;
    let mut agent = AgentRuntime::new(Arc::new(client), manifest)?;
    agent.register_tool(DeviceInfoTool)?;
    let question = match read_line("请输入问题,直接回车询问当前设备: ")? {
        value if value.is_empty() => "当前程序运行在什么设备架构上?".to_owned(),
        value => value,
    };
    let result = agent.run(question).await?;
    println!("{}", result.response.text().unwrap_or_default());
    println!("模型调用步数: {}", result.model_steps);
    println!("工具调用次数: {}", result.tool_executions.len());
    Ok(())
}