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
This commit is contained in:
parent
ea22f3d9ea
commit
bf92590fcd
13
AGENTS.md
13
AGENTS.md
|
|
@ -96,12 +96,14 @@ let b = self.buf.pop_front();
|
|||
|
||||
| crate | 推荐 tokio features |
|
||||
|---|---|
|
||||
| `focus-core` | `rt`, `sync`, `macros` |
|
||||
| `focus-transport` | `rt`, `net`, `io-util`, `sync` |
|
||||
| `focus-providers` | `rt`, `sync`, `macros` |
|
||||
| `focus-core` | (无 tokio —— 核心层为纯同步逻辑) |
|
||||
| `focus-transport` | `net`, `io-util`, `time`(TCP/TLS、超时) |
|
||||
| `focus-providers` | `rt`, `time`(后台 current-thread 运行时) |
|
||||
| `focus-tools` | (无 tokio —— 工具为同步 `std` I/O) |
|
||||
| `focus-harness` | (无 tokio —— 会话/压缩为纯逻辑 + 同步 `std` I/O) |
|
||||
|
||||
> workspace 级 `tokio` 声明不带 features;由各成员按上表自行声明。
|
||||
|
||||
### 2.3 Rust 版本
|
||||
|
||||
- 使用**最新 stable** Rust。
|
||||
|
|
@ -189,8 +191,9 @@ focus-tui ← focus-core, focus-providers, focus-tools, focus-harness, f
|
|||
(`~/.focus/config.json`,TUI 内 `/config` 编辑;provider 构造时传入)、动态系统
|
||||
提示注入(方案 E 的 Usage/上下文占用)、自动上下文压缩的执行(harness 产出方案 →
|
||||
调 provider 摘要 → `Agent::replace_messages` 写回)、会话持久化(`~/.focus/sessions/`)。
|
||||
- **交互**:多行输入、流式显示、Esc 中止、折叠的思考/工具块(显示耗时与内容摘要,
|
||||
点击或 Tab 展开)、命令(`/new` `/sessions` `/config` `/compact`)。
|
||||
- **交互**:多行输入、Markdown 渲染、流式显示、Esc 中止、折叠的思考/工具块
|
||||
(显示耗时与内容摘要,点击或 Tab 两级展开——先预览后全量)、工具请求与结果合并
|
||||
为一块、命令(`/new` `/sessions` `/config` `/compact`)。
|
||||
- **禁止**:把业务逻辑放这里。这里只做**组装与呈现**。
|
||||
|
||||
## 4. 代码规范
|
||||
|
|
|
|||
|
|
@ -429,7 +429,6 @@ name = "focus-core"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"focus-json",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1702,23 +1701,10 @@ dependencies = [
|
|||
"libc",
|
||||
"mio",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.26.4"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ license = "MIT"
|
|||
|
||||
[workspace.dependencies]
|
||||
# --- allowed runtime dependencies (see AGENTS.md §2.1) ---------------------
|
||||
tokio = { version = "1", features = ["rt", "sync", "macros", "net", "io-util", "fs", "process", "rt-multi-thread", "signal", "time"] }
|
||||
# tokio features 由各成员 crate 按需声明(见 AGENTS.md §2.2)。
|
||||
# Each member declares the tokio features it actually needs (see AGENTS.md §2.2).
|
||||
tokio = { version = "1" }
|
||||
rustls = { version = "0.23", default-features = false, features = ["ring", "std"] }
|
||||
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "logging", "tls12"] }
|
||||
rustls-native-certs = "0.7"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2026 focus contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
15
README.md
15
README.md
|
|
@ -62,7 +62,7 @@ focus-tui ← focus-core, focus-providers, focus-tools, focus-harness,
|
|||
# 构建整个 workspace
|
||||
cargo build --workspace
|
||||
|
||||
# 运行全部测试(177 个用例,全绿)
|
||||
# 运行全部测试(181 个用例,全绿)
|
||||
cargo test --workspace
|
||||
|
||||
# 代码质量检查
|
||||
|
|
@ -116,6 +116,14 @@ cargo run -p focus-tui
|
|||
| 配置 | `<data>/config.json` |
|
||||
| 会话 | `<data>/sessions/<session-id>.jsonl`(JSONL 追加写,树结构) |
|
||||
|
||||
### 环境变量
|
||||
|
||||
| 变量 | 说明 |
|
||||
|---|---|
|
||||
| `FOCUS_DATA_DIR` | 覆盖数据根目录(默认 `~/.focus`) |
|
||||
| `FOCUS_SHELL` | 覆盖 `shell` 工具使用的 shell 程序(Windows 默认 PowerShell、可回退 cmd;Linux 默认 bash) |
|
||||
| `FOCUS_DEBUG_FILE` | 设置后,providers 把每个原始网络 chunk 追加到该文件(排查协议不兼容,如推理字段名差异) |
|
||||
|
||||
## ⌨️ TUI 使用
|
||||
|
||||
### 命令
|
||||
|
|
@ -137,7 +145,8 @@ cargo run -p focus-tui
|
|||
| `Esc` | 运行中中止任务;空闲时退出 |
|
||||
| `Ctrl+C` | 退出 |
|
||||
| `Ctrl+D` | 继续(追问一轮) |
|
||||
| `Tab` | 展开 / 折叠最近的思考或工具块 |
|
||||
| `Tab` | 展开 / 折叠最近的思考或工具块(两级:先预览,再全量) |
|
||||
| 鼠标滚轮 | 逐行滚动(Linux / Windows 均支持;上滚暂停自动跟随) |
|
||||
| `Ctrl+U` / `PageUp` / `PageDown` | 滚动消息区(输入为空时 `↑` `↓` 也可滚动) |
|
||||
|
||||
## 🧪 测试
|
||||
|
|
@ -145,7 +154,7 @@ cargo run -p focus-tui
|
|||
- 所有测试位于各 crate 的 `crates/<name>/tests/`,禁止在 `src/` 内联测试
|
||||
- 核心层(`focus-core`)测试**零网络依赖**,用 mock provider 驱动
|
||||
- provider 测试用**录制 / 回放**的 mock transport,不打真实 API(真实 API 测试用 `#[ignore]` 标记)
|
||||
- 当前共 **177 个测试用例**,`cargo test --workspace` 全绿
|
||||
- 当前共 **181 个测试用例**,`cargo test --workspace` 全绿
|
||||
|
||||
## 📚 文档
|
||||
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@ license.workspace = true
|
|||
description = "Core agent layer: domain types, agent loop, tool and provider traits"
|
||||
|
||||
[dependencies]
|
||||
# 核心层是纯同步逻辑(同步拉取式流模型),不依赖任何运行时。
|
||||
# The core layer is purely synchronous (pull-based streaming); no runtime.
|
||||
focus-json.workspace = true
|
||||
tokio = { workspace = true, features = ["rt", "sync", "macros"] }
|
||||
|
|
|
|||
|
|
@ -434,10 +434,6 @@ impl std::fmt::Debug for Agent {
|
|||
}
|
||||
}
|
||||
|
||||
/// 一次运行返回的句柄(目前仅作信息用途)。
|
||||
/// A handle returned from a run (currently just informational).
|
||||
pub struct AgentHandle;
|
||||
|
||||
/// 一批已执行工具调用的结果。
|
||||
/// The results of one executed batch of tool calls.
|
||||
struct ExecutedBatch {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub mod provider;
|
|||
/// The `Tool` trait, effects bitflag, and tool registry.
|
||||
pub mod tool;
|
||||
|
||||
pub use agent::{Agent, AgentConfig, AgentHandle};
|
||||
pub use agent::{Agent, AgentConfig};
|
||||
pub use error::{CoreError, CoreResult};
|
||||
pub use event::{AgentEvent, EventSink};
|
||||
pub use model::*;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ description = "LLM provider implementations (Anthropic, OpenAI) for the focus ag
|
|||
focus-core.workspace = true
|
||||
focus-transport.workspace = true
|
||||
focus-json.workspace = true
|
||||
tokio = { workspace = true, features = ["rt", "sync", "macros"] }
|
||||
tokio = { workspace = true, features = ["rt", "time"] }
|
||||
|
||||
[dev-dependencies]
|
||||
focus-harness.workspace = true
|
||||
|
|
|
|||
|
|
@ -165,10 +165,9 @@ fn full_conversation_compaction_and_continue() {
|
|||
// Re-inject a provider (the mock is single-use).
|
||||
let provider =
|
||||
AnthropicProvider::with_transport(ProviderConfig::new("sk-test"), Arc::new(mock3));
|
||||
agent.replace_messages(agent.messages().to_vec());
|
||||
// 通过内部字段替换 provider:直接重建 agent 以保留消息。
|
||||
// Rebuild the agent keeping the transcript, since the provider is not
|
||||
// swappable on an existing agent.
|
||||
// provider 不可在既有 agent 上替换,重建 agent 并保留 transcript。
|
||||
// The provider is not swappable on an existing agent; rebuild it keeping
|
||||
// the transcript.
|
||||
let mut agent2 = Agent::new(
|
||||
AgentConfig {
|
||||
model: "claude-sonnet-4".into(),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ description = "Transport layer: HTTPS client (tokio + rustls), HTTP/1.1, SSE par
|
|||
|
||||
[dependencies]
|
||||
focus-json.workspace = true
|
||||
tokio = { workspace = true, features = ["rt", "net", "io-util", "sync"] }
|
||||
tokio = { workspace = true, features = ["net", "io-util", "time"] }
|
||||
rustls.workspace = true
|
||||
tokio-rustls.workspace = true
|
||||
rustls-native-certs.workspace = true
|
||||
|
|
|
|||
|
|
@ -918,14 +918,6 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
/// 把输入框的滚动对齐到底部(跟随模式)。
|
||||
/// Align the scroll to the bottom when following.
|
||||
pub fn clamp_scroll(&mut self) {
|
||||
if self.follow {
|
||||
self.scroll = self.max_scroll();
|
||||
}
|
||||
}
|
||||
|
||||
/// 最大滚动偏移(由最近渲染的总行数决定;几何只含可展开块,不能用作依据)。
|
||||
/// Max scroll offset (based on the last render's total line count; the
|
||||
/// geometry only covers expandable blocks and is unusable for this).
|
||||
|
|
|
|||
|
|
@ -113,6 +113,10 @@ fn run_job(job: RunJob, tx: Sender<JobEvent>) {
|
|||
if let Some(plan) =
|
||||
plan_compaction(&transcript, window, COMPACT_THRESHOLD, DEFAULT_KEEP_RATIO)
|
||||
{
|
||||
let _ = tx.send(JobEvent::Note(format!(
|
||||
"compacting… ({})",
|
||||
focus_harness::compaction::describe_plan(&plan)
|
||||
)));
|
||||
match summarize(provider.as_ref(), &job.config, &plan) {
|
||||
Ok(summary) => {
|
||||
transcript = apply_summary(&summary, &plan);
|
||||
|
|
|
|||
|
|
@ -518,7 +518,8 @@ focus — 终端编码 agent
|
|||
/help 本帮助
|
||||
|
||||
思考块与工具调用默认折叠,只显示摘要(耗时 / 内容);
|
||||
点击或 Tab 可查看完整细节。";
|
||||
点击或 Tab 展开:第一次显示预览(剩余行数提示),再次展开显示全部;
|
||||
工具块把请求参数与执行结果合并展示。";
|
||||
|
||||
fn draw_help_modal(frame: &mut Frame, area: Rect) {
|
||||
let rect = centered_rect(70, 70, area);
|
||||
|
|
|
|||
Loading…
Reference in New Issue