执行摘要
该 PR 对 Rust 前端 engine-core-client crate 进行纯代码结构重构,将原本集中在 mod.rs 中的 engine-core DTO 定义(EngineCoreRequest、EngineCoreOutput、EngineCoreSamplingParams 等)拆分为 request、output、sampling、structured_outputs 等独立模块,并移除 crate 根级重新导出。涉及 54 个文件,无任何逻辑变更,编译与测试全部通过。
功能与动机
如 PR body 所述:"Pure code structure refactoring without any logic changes, making the engine-core-client crate cleaner than mixing all definitions into mod.rs." 随着 engine-core-client crate 支持更多功能,将不同语义的 DTO 拆分到各自模块有助于维持代码可读性,并为未来将北向接口形状与线表示解耦奠定基础。
实现拆解
-
创建子模块文件:
request.rs — 包含 EngineCoreRequestType、EngineCoreRequest、ReasoningParserKwargs 等请求相关类型。
output.rs — 重命名自原 classified_outputs.rs,并扩充包含 EngineCoreOutput、EngineCoreFinishReason、StopReason、EngineCoreEvent 等输出相关类型。
sampling.rs — 包含 EngineCoreSamplingParams 及其默认值函数。
structured_outputs.rs — 包含 StructuredOutputBackend 枚举和 StructuredOutputsParams 结构体。
-
精简 mod.rs:从约 600 行缩减到约 80 行,仅保留 OpaqueValue 类型别名、encode_msgpack / decode_msgpack 等低级编解码函数,以及子模块声明。原模块的单元测试按主题分配到各新文件。
-
更新导入路径:由于移除了 crate 根级 pub use 重导出,所有引用之前 mod.rs 中类型的地方(约 50 个文件)均改为完全限定路径,例如 crate::protocol::request::EngineCoreRequest。
-
测试与验证:测试随代码移动,无新测试逻辑。CI 编译和单元测试全部通过。
rust/src/engine-core-client/src/protocol/output.rs
核心输出 DTO 的定义文件,从 classified_outputs.rs 重命名并接收来自 mod.rs 的 EngineCoreOutput、EngineCoreFinishReason、StopReason 等类型,以及 resolve_in_place、finished 等方法。
/// Engine-core output for a single request.
///
/// Original Python definition:
/// <https://github.com/vllm-project/vllm/blob/d3af8c18317c0dc008d42e4367fbb9045cfb7bf6/vllm/v1/engine/__init__.py#L154-L184>
#[derive(Debug, Clone, PartialEq, Serialize_tuple, Deserialize_tuple, DefaultFromSerde)]
pub struct EngineCoreOutput {
pub request_id: String,
pub new_token_ids: Vec<u32>,
#[serde(default)]
pub new_logprobs: Option<MaybeWireLogprobs>,
#[serde(default)]
pub new_prompt_logprobs_tensors: Option<MaybeWireLogprobs>,
#[serde(default)]
pub pooling_output: Option<OpaqueValue>,
#[serde(default)]
pub finish_reason: Option<EngineCoreFinishReason>,
#[serde(default)]
pub stop_reason: Option<StopReason>,
#[serde(default)]
pub events: Option<Vec<EngineCoreEvent>>,
#[serde(default)]
pub kv_transfer_params: Option<serde_json::Value>,
#[serde(default)]
pub trace_headers: Option<OpaqueValue>,
#[serde(default)]
pub prefill_stats: Option<PrefillStats>,
#[serde(default)]
pub routed_experts: Option<OpaqueValue>,
#[serde(default)]
pub num_nans_in_logits: u32,
}
impl EngineCoreOutput {
/// Returns whether this output is terminal for the request.
pub fn finished(&self) -> bool {
self.finish_reason.is_some()
}
/// Resolve all wire-format fields in-place by looking up aux frames and
/// decoding raw-view payloads as needed.
fn resolve_in_place<Frame>(&mut self, frames: &[Frame]) -> Result<()>
where
Frame: AsRef<[u8]>,
{
self.new_logprobs = (self.new_logprobs.take())
.map(|value| value.resolve(frames, "new_logprobs"))
.transpose()?;
self.new_prompt_logprobs_tensors = (self.new_prompt_logprobs_tensors.take())
.map(|value| value.resolve(frames, "new_prompt_logprobs_tensors"))
.transpose()?;
// 其他 wire 字段 (pooling_output, trace_headers) 以类似方式解析
Ok(())
}
}
评论区精华
该 PR 无实质 review 讨论;njhill 直接批准,claude bot 自动提醒代码审查配置。
风险与影响
- 风险:仅代码移动和导入调整,无功能变更,风险极低。可能遗漏导入更新(但 CI 覆盖所有编译和单元测试)。
- 影响:所有依赖 engine-core-client 的 Rust 模块(server、parser、llm、chat 等)需要更新导入路径。影响范围明确,开发人员需了解新模块划分。
关联脉络
该 PR 是 Rust 前端逐步工程化的一部分。此前 PR #47166 修复了 Rust 前端的 max_tokens null 问题;该重构为后续功能(如更清晰的北向-南向接口分离)铺平道路。PR body 中标注了堆叠 PR #47283(本 PR 的下一个组件),预计将在本重构基础上进一步隔离类型。
参与讨论