Go to file
DaiChaoXiong bf92590fcd chore(workspace): project-wide cleanup, dependency trimming, docs sync
deps: focus-core no longer depends on tokio at all (the core is fully
synchronous); workspace-level tokio drops the fat feature list, members
declare only what they use (transport: net/io-util/time, providers: rt/time)

code: remove dead AgentHandle (never constructed) and the dead
App::clamp_scroll; wire focus-harness' describe_plan into the TUI compaction
note (it was unused public API); clean a no-op replace_messages + confusing
comment in the compaction integration test

docs: AGENTS.md §2.2 tokio table reflects the new feature sets; README test
count 177→181, new env-var section (FOCUS_DATA_DIR / FOCUS_SHELL /
FOCUS_DEBUG_FILE), wheel + two-level expansion keybindings; add LICENSE (MIT,
matching Cargo.toml); TUI /help notes the two-level expansion and merged
tool blocks; delete the .VSCodeCounter artifact dir

verification: fmt, clippy -D warnings, 181 tests, workspace build all green
2026-08-09 23:14:21 +08:00
crates chore(workspace): project-wide cleanup, dependency trimming, docs sync 2026-08-09 23:14:21 +08:00
docs/architecture INIT 2026-07-16 17:59:16 +08:00
.gitignore docs(workspace): whitelist ratatui/crossterm for focus-tui 2026-08-09 21:35:58 +08:00
AGENTS.md chore(workspace): project-wide cleanup, dependency trimming, docs sync 2026-08-09 23:14:21 +08:00
Cargo.lock chore(workspace): project-wide cleanup, dependency trimming, docs sync 2026-08-09 23:14:21 +08:00
Cargo.toml chore(workspace): project-wide cleanup, dependency trimming, docs sync 2026-08-09 23:14:21 +08:00
LICENSE chore(workspace): project-wide cleanup, dependency trimming, docs sync 2026-08-09 23:14:21 +08:00
README.md chore(workspace): project-wide cleanup, dependency trimming, docs sync 2026-08-09 23:14:21 +08:00
rust-toolchain.toml INIT 2026-07-16 17:59:16 +08:00

README.md

focus — 纯 Rust 实现的 LLM Agent 框架

参考 piTypeScript 原版)与 pi_agent_rustRust 移植)实现的 分层、极简依赖的 LLM agent 框架。核心目标:以最小的依赖面实现一个分层清晰、 可独立测试的 agent 框架,重点学习 pi 的核心设计——agent 循环、消息类型、工具抽象、流式协议。

核心特性

  • 双层 agent 循环:外层 follow-up、内层 steering + 工具执行,支持 sequential / parallel 两种工具执行模式
  • 流式输出SSE 增量解析,流式 assistant 消息随 delta 原地更新;Esc 随时中止
  • 多 provider 支持AnthropicMessages API+ OpenAIResponses API 与 Chat Completions 双协议),统一翻译为 StreamEvent 事件流,错误编码进事件而非中断循环
  • 内置工具read / write / editpi 风格精确替换)/ shell跨平台Windows + Linux
  • 会话管理:树形会话结构(id + parentId+ JSONL 追加写,支持分支与会话切换
  • 上下文压缩token 估算 + 压缩方案(切点 + 摘要指令),自动执行滚动总结
  • 交互式 TUI多行输入、Markdown 渲染、实时 transcript、折叠的思考/工具块、跨平台滚轮滚动
  • 类型安全:自研 focus-json 手写 JSON 编解码,不依赖 serde / serde_json
  • 依赖极简:运行时依赖仅 tokio + rustls 生态(另为 TUI 特批 ratatui + crossterm

🏗️ 架构设计

细粒度 7-crate workspace 拆分,每个 crate 职责单一、边界清晰、可独立测试。依赖严格单向向下,禁止循环。

focus/
├── crates/
│   ├── focus-json/        # 极简 JSON 解析器 / 序列化器(零外部依赖)
│   ├── focus-core/        # ★ 核心层:领域类型 + Agent 循环 + Tool / StreamProvider trait
│   ├── focus-transport/   # 传输层HTTPS 客户端tokio + rustls、HTTP/1.1、SSE 解析
│   ├── focus-providers/   # Provider 实现Anthropic / OpenAI
│   ├── focus-tools/       # 文件工具read / write / edit / shell
│   ├── focus-harness/     # 会话持久化 + 上下文压缩 + 系统提示模板
│   └── focus-tui/         # 终端交互层ratatui + crossterm组装所有模块
├── docs/architecture/     # 架构解读文档(三份精读笔记)
└── AGENTS.md              # 工程规范(依赖白名单、代码/测试/提交规范)

分层依赖图

focus-json        ←  零外部依赖,纯 std
focus-core        ←  focus-json, tokio
focus-transport   ←  focus-json, tokio, rustls, tokio-rustls, rustls-native-certs
focus-providers   ←  focus-core, focus-transport
focus-tools       ←  focus-core
focus-harness     ←  focus-core, focus-json
focus-tui         ←  focus-core, focus-providers, focus-tools, focus-harness, focus-json, ratatui, crossterm

核心设计要点

  • I/O 边界注入focus-core 是纯逻辑层,不碰网络 / 文件系统provider 与工具都通过 trait 注入
  • content / details 分离:工具结果的 content(模型可见)与 detailsUI / 日志可见)分开
  • 错误编码而非抛出StreamProvider 绝不用 Err 中断循环,错误编码进 StreamEvent::Error
  • 压缩只出方案harness 产出「压缩方案」,真正的摘要 LLM 调用由上层TUI执行——遵守依赖图约束

🚀 快速开始

构建与测试

# 构建整个 workspace
cargo build --workspace

# 运行全部测试181 个用例,全绿)
cargo test --workspace

# 代码质量检查
cargo fmt --all --check
cargo clippy --workspace -- -D warnings

运行 TUI

cargo run -p focus-tui

或直接运行构建产物 target/debug/focus

首次启动后先配置 provider

  1. 在 TUI 中输入 /config 打开配置表单(或直接编辑 ~/.focus/config.json
  2. 填写 apiKey、选择 provider 与模型
  3. 回到输入框即可开始对话

⚙️ 配置

配置文件位于 <data>/config.json<data> 默认为 ~/.focus Windows 为 %USERPROFILE%\.focus),可用环境变量 FOCUS_DATA_DIR 覆盖。

{
  "provider": "anthropic",
  "openaiProtocol": "responses",
  "baseUrl": "https://api.anthropic.com",
  "apiKey": "sk-...",
  "model": "claude-sonnet-4-5",
  "contextWindow": 200000
}
字段 说明
provider anthropicopenai
openaiProtocol OpenAI 协议:responses(默认)或 chatCompletions
baseUrl API 基址(可选,缺省用默认端点;具体端点路径由 provider 自行拼接)
apiKey API 密钥
model 模型 id
contextWindow 上下文窗口(可选,缺省按已知模型表自动查询,未知模型兜底 128k

数据目录

内容 位置
配置 <data>/config.json
会话 <data>/sessions/<session-id>.jsonlJSONL 追加写,树结构)

环境变量

变量 说明
FOCUS_DATA_DIR 覆盖数据根目录(默认 ~/.focus
FOCUS_SHELL 覆盖 shell 工具使用的 shell 程序Windows 默认 PowerShell、可回退 cmdLinux 默认 bash
FOCUS_DEBUG_FILE 设置后providers 把每个原始网络 chunk 追加到该文件(排查协议不兼容,如推理字段名差异)

⌨️ TUI 使用

命令

命令 功能
/new 新建会话
/sessions 查看 / 切换历史会话
/config 编辑配置provider / 模型 / 密钥)
/compact 手动触发上下文压缩
/help 显示帮助

键盘

按键 功能
Enter 发送消息
Shift+Enter 换行
Esc 运行中中止任务;空闲时退出
Ctrl+C 退出
Ctrl+D 继续(追问一轮)
Tab 展开 / 折叠最近的思考或工具块(两级:先预览,再全量)
鼠标滚轮 逐行滚动Linux / Windows 均支持;上滚暂停自动跟随)
Ctrl+U / PageUp / PageDown 滚动消息区(输入为空时 也可滚动)

🧪 测试

  • 所有测试位于各 crate 的 crates/<name>/tests/,禁止在 src/ 内联测试
  • 核心层(focus-core)测试零网络依赖,用 mock provider 驱动
  • provider 测试用录制 / 回放的 mock transport不打真实 API真实 API 测试用 #[ignore] 标记)
  • 当前共 181 个测试用例cargo test --workspace 全绿

📚 文档

📄 许可证

MIT