ferrox_models/hybrid_engine.rs
1//! Hybrid attn+SSM engine stub (Jamba / LFM2 / Nemotron-H / Qwen3.5 GDN / …).
2//!
3//! Fail-closed at load via [`HybridEngine::reject`] (used by
4//! [`crate::engine_factory`] for `nemotron_h` and other hybrid arches).
5//! Qwen-style GDN math: [`crate::gdn`]. GGUF hparams + GDN weight load
6//! skeleton: [`crate::hybrid_gguf_loader`] (`try_load` still
7//! `UnsupportedFeature` until this engine assembles layers for serve).
8
9use thiserror::Error;
10
11#[derive(Debug, Error)]
12#[error("hybrid engine not implemented for architecture {arch}")]
13pub struct HybridUnavailable {
14 pub arch: String,
15}
16
17/// Placeholder hybrid serve handle.
18///
19/// Holds the GGUF arch string and an optional note. Construction is via
20/// [`Self::stub`]; the factory still calls [`Self::reject`]. GGUF→GDN
21/// weight probing lives in [`crate::hybrid_gguf_loader::try_load`].
22#[derive(Debug)]
23pub struct HybridEngine {
24 pub arch: String,
25 /// e.g. that GDN + loader skeleton exist but assemble/serve is incomplete.
26 pub note: Option<String>,
27}
28
29impl HybridEngine {
30 /// Fail-closed entry used by the engine factory until HybridEngine assemble lands.
31 pub fn reject(arch: &str) -> Result<(), HybridUnavailable> {
32 Err(HybridUnavailable {
33 arch: arch.to_string(),
34 })
35 }
36
37 /// Non-serving stub: records arch + note that GDN + hybrid_gguf_loader
38 /// exist but serve assemble is not wired.
39 pub fn stub(arch: &str) -> Self {
40 Self {
41 arch: arch.to_string(),
42 note: Some(
43 "GDN + hybrid_gguf_loader skeleton exist; HybridEngine assemble/serve not wired — factory still reject()"
44 .into(),
45 ),
46 }
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn reject_is_fail_closed() {
56 assert!(HybridEngine::reject("jamba").is_err());
57 assert!(HybridEngine::reject("nemotron_h").is_err());
58 }
59
60 #[test]
61 fn stub_holds_arch_and_gdn_note() {
62 let eng = HybridEngine::stub("qwen35");
63 assert_eq!(eng.arch, "qwen35");
64 let note = eng.note.expect("note");
65 assert!(note.contains("GDN"));
66 assert!(note.contains("hybrid_gguf_loader"));
67 }
68}