fix(agent): Phase 9 实施审查修复
- cycle.rs: run_tool_loop 实现 PreRequest hook(之前 `let _ = hook_executor.as_ref()` 是空操作,
导致 hook-based logging/monitoring 在流式工具循环中失效;现在与 submit_with_tools 行为对齐,
含 should_block 检查,阻断时通过 StreamEvent::Error 事件化)
- session.rs: 删除 submit_turn_stream 末尾的 `let _ = hook_executor;` 死代码(Arc 引用生命周期
由 Arc 自动管理)
- session.rs: 新增 2 个集成测试覆盖方案 §4 Step 5:
- submit_turn_stream_end_to_end:mock provider → 消费流 → finalize_turn 后 cost_so_far
正确更新(10/5 tokens)+ turn_index=1 + default slot 包含 user/assistant 消息
- submit_turn_stream_triggers_turn_hooks:OnTurnStart 在 submit_turn_stream 返回流前
触发(计数=1)+ OnTurnEnd 在 finalize_turn 前不触发(计数=0)+ finalize_turn 后触发(计数=1)
- docs/16-phase9-streaming-experience.md: 标注 finalize_turn Phase 10 签名变更(new_messages_from_cycle
+ Result 返回),Step 5 测试实现位置
- 测试 288 passed / 0 failed(基线 286 + 2 新增),clippy 0 警告,doc 0 warning
This commit is contained in:
+16
-3
@@ -18,7 +18,7 @@ use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||
use crate::llm::compact::{CompactConfig, CompactState, microcompact, should_compact};
|
||||
use crate::llm::cycle::retry::should_retry;
|
||||
use crate::llm::error::LlmError;
|
||||
use crate::llm::hooks::{HookContext, HookExecutor};
|
||||
use crate::llm::hooks::{HookContext, HookEvent, HookExecutor};
|
||||
use crate::llm::provider::LlmProvider;
|
||||
use crate::llm::stream::StreamEvent;
|
||||
use crate::llm::types::message::{ContentBlock, Message};
|
||||
@@ -774,8 +774,21 @@ async fn run_tool_loop(
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// ② PreRequest hook(fire-and-forget,仅占位保留以保持接口对称)
|
||||
let _ = hook_executor.as_ref();
|
||||
// ② PreRequest hook —— 与 `submit_with_tools` / `submit_stream` 行为对齐:
|
||||
// 触发 hook → 检查 should_block → 阻断则事件化 Error + return 结束 task。
|
||||
// 阻断原因透传,让消费者看到完整的拒绝原因。
|
||||
if let Some(ref executor) = hook_executor {
|
||||
let ctx = HookContext::new(HookEvent::PreRequest).with_request(&request);
|
||||
let results = executor.execute(HookEvent::PreRequest, &ctx).await;
|
||||
if let Some(blocking) = results.iter().find(|r| r.should_block) {
|
||||
let reason = blocking
|
||||
.reason
|
||||
.clone()
|
||||
.unwrap_or_else(|| "Blocked by pre-request hook".to_string());
|
||||
let _ = tx.send(StreamEvent::Error { message: reason });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ③ chat_stream —— 第一层错误
|
||||
let mut stream = match provider.chat_stream(request).await {
|
||||
|
||||
Reference in New Issue
Block a user