focus/crates/focus-tui/tests/fake/mod.rs

80 lines
2.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! 测试共享的假 provider把一段文本作为流式回复回放。
//! Shared test fake provider: replays a text as a streaming reply.
//!
//! 摘要调用(系统提示含 `<summary>`)与普通 agent 调用返回不同文本,
//! 从而在零网络的情况下测试自动压缩流程。
//! Summary calls (system prompt contains `<summary>`) and normal agent calls
//! return different texts, exercising auto-compaction with zero network.
use focus_core::provider::{
ProviderEventReducer, ProviderRequest, StreamEvent, StreamIterator, StreamProvider,
StreamResult,
};
use std::fmt;
/// 一个回放文本回复的假 provider。
/// A fake provider that replays a text reply.
#[derive(Debug, Clone)]
pub struct FakeProvider {
/// 普通 agent 调用的回复。
/// Reply for normal agent calls.
pub text: String,
/// 摘要调用的回复。
/// Reply for summary calls.
pub summary: String,
}
impl FakeProvider {
/// 构造假 provider。
/// Build the fake provider.
pub fn new(text: &str, summary: &str) -> Self {
Self {
text: text.to_string(),
summary: summary.to_string(),
}
}
}
impl StreamProvider for FakeProvider {
fn stream(&self, request: &ProviderRequest) -> StreamResult {
let is_summary = request.system_prompt.contains("<summary>");
let text = if is_summary {
self.summary.clone()
} else {
self.text.clone()
};
let mut reducer = ProviderEventReducer::new(&request.model);
let mut events = reducer.text_delta(&text);
events.extend(reducer.finalize_events());
let message = reducer.finish().expect("final message");
events.push(StreamEvent::Done { message });
Ok(Box::new(ReplayIter { events }))
}
}
/// 回放固定事件序列的流。
/// A stream that replays a fixed event sequence.
struct ReplayIter {
events: Vec<StreamEvent>,
}
impl StreamIterator for ReplayIter {
fn next_event(&mut self) -> Option<StreamEvent> {
if self.events.is_empty() {
None
} else {
Some(self.events.remove(0))
}
}
}
/// 供测试 debug 输出使用。
/// For test debug output.
impl fmt::Debug for ReplayIter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ReplayIter")
.field("remaining", &self.events.len())
.finish()
}
}