tiny-agent 0.1.0

一个小而完整的 Rust LLM Agent 运行时:可中断、可恢复、可观测、可插拔的 agent loop / A small but complete LLM agent runtime in Rust — an interruptible, resumable, observable, pluggable agent loop.
Documentation
use super::AgentRunTime;
use crate::{
    core::FailureKind, sandbox::Sandbox, state::AgentState, trajectory::TrajectoryEventKind,
};
use std::sync::Arc;
use tokio_util::sync::CancellationToken;

impl AgentRunTime {
    pub(super) async fn open_sandbox(
        &self,
        ctx: &AgentState,
        cancellation_token: CancellationToken,
    ) -> Result<Option<Arc<dyn Sandbox>>, String> {
        tokio::select! {
            _ = cancellation_token.cancelled() => Ok(None),
            sandbox = self.sandbox.clone().open(&ctx.session_id) => {
                sandbox.map(Some).map_err(|e| e.to_string())
            }
        }
    }

    /// best-effort 持久化:在失败 / 取消退出前调用。
    ///
    /// 工具一旦成功,它的 `tool_result` 会立即落 transcript;而沙箱状态默认只在整批
    /// 成功后才 `save()`。若中途失败就直接返回,下一轮 `open()` 会恢复到批次**之前**的
    /// 快照 —— 已落库的成功结果便与实际沙箱状态发散。这里在退出前补一次 save,让二者对齐。
    pub(super) async fn persist_sandbox(&self, session_id: &str, sandbox: &Arc<dyn Sandbox>) {
        if let Err(e) = sandbox.save().await {
            self.emit(
                session_id,
                TrajectoryEventKind::Failed {
                    kind: FailureKind::SandboxSave.as_str().to_string(),
                    message: format!("best-effort sandbox save failed: {}", e),
                },
            )
            .await;
        }
    }
}