# opi-agent
[](https://crates.io/crates/opi-agent)
[](https://docs.rs/opi-agent)
> [opi](https://github.com/OdradekAI/opi) 的通用 Agent 运行时:流式 turn、工具调用、hooks、事件、消息队列、会话、分支重建、上下文压缩、SDK 命令、扩展和 JSONL streaming proxy 原语。
## 当前状态
当前 crate 版本:`0.4.0`。
`opi-agent` 提供 `opi` 二进制使用的 Provider 无关运行时。它负责 turn 主循环、工具参数 JSON Schema 校验、并行/串行工具执行、支持 retry 的 Provider streaming、图片能力校验、事件订阅、steering/follow-up 队列、JSONL 会话存储、基于 leaf 的会话分支重建、阈值/手动/溢出触发的上下文压缩基础能力、SDK/RPC 命令与响应类型、extension hooks/tools/state,以及传输无关的 streaming proxy。
## 核心抽象
```rust
pub trait Tool: Send + Sync {
fn definition(&self) -> ToolDef;
fn execute(&self, call_id: &str, args: serde_json::Value,
signal: CancellationToken,
on_update: Option<UpdateCallback>) -> ...;
fn execution_mode(&self) -> ExecutionMode { ExecutionMode::Parallel }
}
pub trait AgentHooks: Send + Sync {
async fn transform_context(...) -> Result<Vec<AgentMessage>, AgentError>;
fn convert_to_llm(...) -> Result<Vec<Message>, AgentError>;
async fn before_tool_call(...) -> BeforeToolCallResult;
async fn after_tool_call(...) -> AfterToolCallResult;
async fn should_stop_after_turn(...) -> bool;
async fn prepare_next_turn(...) -> Option<PrepareNextTurnUpdate>;
}
```
`Agent` 在主循环外提供 `prompt`、`prompt_with_content`、`continue_`、`abort`、`subscribe`、`steer`、`follow_up`、`add_tool`、模型切换与消息缓冲区辅助方法。
## Agent 主循环
```text
agent_loop
-> transform_context
-> convert_to_llm
-> 校验请求能力
-> provider.stream(Request)
-> 发出并累积 AssistantStreamEvent
-> 检测工具调用
-> 用 jsonschema 校验参数
-> before_tool_call hook
-> 执行工具
-> 全部是 parallel 工具时一起执行
-> 只要有 sequential 工具,整批串行执行
-> after_tool_call hook
-> 所有工具结果 terminate 时停止
-> should_stop_after_turn hook
-> prepare_next_turn hook
-> drain steering 队列
-> 无待执行工具时弹出一条 follow-up 消息
```
可重试的 Provider 错误(`RateLimited`、`Timeout`)可以通过 `AgentLoopConfig.retry` 自动重试。retry 开始/结束会通过 `AgentEvent` 发出。
## 会话与压缩
会话存储采用 append-only JSONL:
- 第一行:`SessionHeader`。
- 条目:`MessageEntry`、`CompactionEntry`、`LeafEntry`。
- Reader 支持崩溃恢复,会跳过损坏条目和末尾截断行。
- `session_branch::SessionTree` 会根据 `parent_id` 关系和最新 `LeafEntry` 重建分支元数据与活跃分支。
上下文压缩能力包括:
- `CompactionConfig { enabled, threshold_tokens }`。
- `CompactionReason::{Manual, Threshold, Overflow}`。
- `CompactionEngine::should_compact`。
- `CompactionEngine::compact`。
- `CompactionHooks` 自定义摘要生成,缺省时使用 core fallback summary。
`opi-coding-agent` 负责把这些基础能力连接到运行时持久化。
## 事件
`AgentEvent` 覆盖 Agent 生命周期、turn 生命周期、消息流式更新、工具执行、队列、自动 retry、压缩、会话持久化错误和 Agent 结束。
`AgentSessionEvent` 是 JSON 输出使用的会话级 wire protocol。它包装 agent events,并增加 compaction、retry、thinking level、session info、session summary 等事件。
## SDK、扩展与 Proxy
- `sdk` 定义 RPC JSONL 模式和嵌入方共享的不稳定、带 schema version 的命令与响应类型:`prompt`、`continue`、`steer`、`follow_up`、`abort`、`set_model`、`set_thinking_level`、`compact`、`session_info` 和 `quit`。
- `extension` 提供 `Extension` 与 `ExtensionRegistry`,支持生命周期 hooks、自定义工具、自定义命令、每个 extension 的状态序列化、自定义 Provider 和模型覆盖。
- `streaming_proxy` 可以在任意 `BufRead`/`Write` 传输上转发 JSONL 命令/事件,输出 `proxy_ready` 头,提供有界事件缓冲,支持取消,并默认脱敏常见密钥模式。
## 简短示例
```rust
use opi_agent::{ExecutionMode, Tool, ToolError, ToolResult};
use opi_ai::message::{OutputContent, ToolDef};
struct EchoTool;
impl Tool for EchoTool {
fn definition(&self) -> ToolDef {
ToolDef {
name: "echo".into(),
description: "原样返回输入。".into(),
input_schema: serde_json::json!({
"type": "object",
"properties": { "text": { "type": "string" } },
"required": ["text"],
}),
}
}
fn execute(&self, _id: &str, args: serde_json::Value,
_signal: tokio_util::sync::CancellationToken,
_on_update: Option<opi_agent::tool::UpdateCallback>)
-> std::pin::Pin<Box<dyn std::future::Future<
Output = Result<ToolResult, ToolError>> + Send>>
{
let text = args.get("text").and_then(|v| v.as_str())
.unwrap_or("").to_owned();
Box::pin(async move {
Ok(ToolResult {
content: vec![OutputContent::Text { text }],
details: None,
is_error: false,
terminate: false,
})
})
}
fn execution_mode(&self) -> ExecutionMode { ExecutionMode::Parallel }
}
```
创建 `Agent` 时传入 boxed `opi_ai::Provider`、工具列表、模型、可选系统提示词、`AgentLoopConfig` 和 `AgentHooks` 实现即可。用户 turn 包含文本和图片时使用 `prompt_with_content`。
## 模块速查
| `agent` | 有状态 `Agent` 封装、模型切换、取消、队列与消息缓冲区管理 |
| 根模块 `agent_loop` | Provider/tool turn 主循环 |
| `tool` | `Tool`、`ToolResult`、`ToolError`、`ExecutionMode`、update callbacks |
| `hooks` | Hook trait 及其上下文/结果类型 |
| `event` | 运行时事件协议 |
| `session_event` | JSON 模式使用的会话级事件协议 |
| `session` | JSONL 会话 header、条目、writer、reader、恢复 |
| `session_branch` | 根据 session entry 的 parent links 和 leaf pointers 重建分支 |
| `compaction` | 上下文压缩引擎与 hooks |
| `sdk` | 共享 SDK/RPC schema version、命令、响应和事件转换 |
| `extension` | Extension trait、registry、hook 包装、自定义工具/Provider/模型 |
| `streaming_proxy` | 带密钥脱敏的传输无关 JSONL 命令/事件 proxy |
| `state` | 对话状态容器 |
| `message` | Agent 层消息变体 |
| `loop_types` | 主循环上下文、配置和错误 |
| `validation` | JSON Schema 参数校验 |
## 许可证
MIT。详见 workspace [LICENSE](../../LICENSE)。