Skip to main content

Probe

Enum Probe 

Source
pub enum Probe {
    LogprobTokenIds,
    AllowedTokenIdsTopK,
    CompletionsTopK,
    LlamaCppNProbs,
}
Expand description

How the target service exposes option-token log probabilities.

Variants§

§

LogprobTokenIds

vLLM: restrict the distribution to the option tokens and ask for their exact token ids. This is the same contract fastjev’s own vLLM backend uses through SamplingParams.

§

AllowedTokenIdsTopK

vLLM without logprob_token_ids: restrict the distribution and read the top-k, which must then contain every option token.

§

CompletionsTopK

OpenAI-compatible completions: read the top-k of the unrestricted next-token distribution.

§

LlamaCppNProbs

llama.cpp native /completion with n_probs.

Implementations§

Source§

impl Probe

Source

pub fn name(self) -> &'static str

Stable identifier reported by GET /health.

Examples found in repository?
examples/serve.rs (line 60)
30async fn main() -> Result<()> {
31    let openai_base = std::env::var("JEV_BRIDGE_UPSTREAM_URL")
32        .unwrap_or_else(|_| "http://127.0.0.1:8080/v1".to_string());
33    let native_base = std::env::var("JEV_BRIDGE_NATIVE_URL")
34        .unwrap_or_else(|_| openai_base.trim_end_matches("/v1").to_string());
35    let upstream_model =
36        std::env::var("JEV_BRIDGE_UPSTREAM_MODEL").unwrap_or_else(|_| "local-model".to_string());
37
38    let bridge = Bridge::connect(
39        reqwest::Client::new(),
40        BridgeConfig {
41            openai_base,
42            native_base,
43            upstream_model,
44            upstream_key: std::env::var("JEV_BRIDGE_UPSTREAM_KEY").ok(),
45            served_model: "example-bridge".to_string(),
46            description: "example bridge over a generic inference API".to_string(),
47            release_date: "2026-09-22".to_string(),
48            chat_template_kwargs: json!({"enable_thinking": false}),
49            max_input_tokens: None,
50            local: Default::default(),
51            accept_any_model: false,
52            scoring: Default::default(),
53            confidence: Default::default(),
54            readout: Default::default(),
55        },
56    )
57    .await
58    .context("connecting to the upstream service failed")?;
59
60    println!("transport: {} via {}", bridge.probe().name(), bridge.probe().endpoint());
61
62    let state = Arc::new(AppState {
63        bridge,
64        api_key: std::env::var("JEV_BRIDGE_API_KEY").ok(),
65        readout_check: None,
66    });
67    let listener = tokio::net::TcpListener::bind(ADDRESS)
68        .await
69        .with_context(|| format!("binding {ADDRESS} failed"))?;
70    println!("listening on http://{ADDRESS}");
71    axum::serve(listener, router(state))
72        .with_graceful_shutdown(async {
73            let _ = tokio::signal::ctrl_c().await;
74        })
75        .await
76        .context("the HTTP server stopped unexpectedly")
77}
More examples
Hide additional examples
examples/score_rows.rs (line 65)
30async fn main() -> Result<()> {
31    let openai_base = std::env::var("JEV_BRIDGE_UPSTREAM_URL")
32        .unwrap_or_else(|_| "http://127.0.0.1:8080/v1".to_string());
33    let native_base = std::env::var("JEV_BRIDGE_NATIVE_URL")
34        .unwrap_or_else(|_| openai_base.trim_end_matches("/v1").to_string());
35    let upstream_key = std::env::var("JEV_BRIDGE_UPSTREAM_KEY").ok();
36    let upstream_model =
37        std::env::var("JEV_BRIDGE_UPSTREAM_MODEL").unwrap_or_else(|_| "local-model".to_string());
38
39    let started = Instant::now();
40    let bridge = Bridge::connect(
41        reqwest::Client::new(),
42        BridgeConfig {
43            openai_base,
44            native_base,
45            upstream_model,
46            upstream_key,
47            served_model: "example-bridge".to_string(),
48            description: "example bridge".to_string(),
49            release_date: "2026-09-22".to_string(),
50            chat_template_kwargs: json!({"enable_thinking": false}),
51            max_input_tokens: None,
52            local: Default::default(),
53            accept_any_model: false,
54            scoring: Default::default(),
55            confidence: Default::default(),
56            readout: Default::default(),
57        },
58    )
59    .await
60    .context("connecting to the upstream service failed")?;
61
62    println!(
63        "connected in {:.2?}: transport={} endpoint={} renders_locally={} tokenizes_locally={}",
64        started.elapsed(),
65        bridge.probe().name(),
66        bridge.probe().endpoint(),
67        bridge.renders_locally(),
68        bridge.tokenizes_locally(),
69    );
70
71    let rows = vec![
72        Row {
73            id: "refund".to_string(),
74            state: json!("I was charged twice and need a refund today."),
75            question: "Which queue should handle this request?".to_string(),
76            options: vec![
77                option("access", "Account access and authentication."),
78                option("billing", "Billing, payments, and refunds."),
79                option("sales", "Pricing and new contracts."),
80            ],
81        },
82        Row {
83            id: "outage".to_string(),
84            state: json!("The API returns 502 for every request since this morning."),
85            question: "Which queue should handle this request?".to_string(),
86            options: vec![
87                option("access", "Account access and authentication."),
88                option("billing", "Billing, payments, and refunds."),
89                option("sales", "Pricing and new contracts."),
90            ],
91        },
92    ];
93
94    let started = Instant::now();
95    // Independent decisions, each carrying its own state: one readout per row.
96    let mut scored = Vec::with_capacity(rows.len());
97    for row in &rows {
98        scored.push(bridge.score_row(row).await?);
99    }
100    println!("scored {} rows in {:.2?}\n", scored.len(), started.elapsed());
101
102    for row in &scored {
103        let winner = row
104            .answer
105            .probabilities
106            .iter()
107            .enumerate()
108            .max_by(|a, b| a.1.partial_cmp(b.1).unwrap())
109            .map(|(index, _)| row.answer.option_ids[index].as_str())
110            .unwrap();
111        println!("{} -> {winner}", row.answer.id);
112        for (id, probability) in row.answer.option_ids.iter().zip(&row.answer.probabilities) {
113            println!("    {id:<8} {probability:.4}");
114        }
115        println!(
116            "    input_tokens={} prompt_sha256={}",
117            row.answer.input_tokens,
118            &row.prompt_sha256[..16]
119        );
120    }
121
122    // Probabilities are conditional on the supplied options and uncalibrated.
123    println!("\nThese scores are conditional option probabilities, not calibrated confidence.");
124    Ok(())
125}
Source

pub fn note(self) -> &'static str

One line describing what this transport relies on.

Source

pub fn restricts_distribution(self) -> bool

Whether the request is expected to restrict the distribution to the answer tokens. A probe that claims restriction but returns foreign candidates is rejected rather than silently trusted.

Source

pub fn supports_batch(self) -> bool

Whether this transport can read several prompts in one request.

The OpenAI-shaped transports accept an array prompt, which a prefix-caching server prefills together. llama.cpp’s native /completion answers an array with a bare JSON array of response objects instead of one object, so it stays one prompt per request.

Source

pub fn endpoint(self) -> &'static str

The path this transport posts to.

Examples found in repository?
examples/serve.rs (line 60)
30async fn main() -> Result<()> {
31    let openai_base = std::env::var("JEV_BRIDGE_UPSTREAM_URL")
32        .unwrap_or_else(|_| "http://127.0.0.1:8080/v1".to_string());
33    let native_base = std::env::var("JEV_BRIDGE_NATIVE_URL")
34        .unwrap_or_else(|_| openai_base.trim_end_matches("/v1").to_string());
35    let upstream_model =
36        std::env::var("JEV_BRIDGE_UPSTREAM_MODEL").unwrap_or_else(|_| "local-model".to_string());
37
38    let bridge = Bridge::connect(
39        reqwest::Client::new(),
40        BridgeConfig {
41            openai_base,
42            native_base,
43            upstream_model,
44            upstream_key: std::env::var("JEV_BRIDGE_UPSTREAM_KEY").ok(),
45            served_model: "example-bridge".to_string(),
46            description: "example bridge over a generic inference API".to_string(),
47            release_date: "2026-09-22".to_string(),
48            chat_template_kwargs: json!({"enable_thinking": false}),
49            max_input_tokens: None,
50            local: Default::default(),
51            accept_any_model: false,
52            scoring: Default::default(),
53            confidence: Default::default(),
54            readout: Default::default(),
55        },
56    )
57    .await
58    .context("connecting to the upstream service failed")?;
59
60    println!("transport: {} via {}", bridge.probe().name(), bridge.probe().endpoint());
61
62    let state = Arc::new(AppState {
63        bridge,
64        api_key: std::env::var("JEV_BRIDGE_API_KEY").ok(),
65        readout_check: None,
66    });
67    let listener = tokio::net::TcpListener::bind(ADDRESS)
68        .await
69        .with_context(|| format!("binding {ADDRESS} failed"))?;
70    println!("listening on http://{ADDRESS}");
71    axum::serve(listener, router(state))
72        .with_graceful_shutdown(async {
73            let _ = tokio::signal::ctrl_c().await;
74        })
75        .await
76        .context("the HTTP server stopped unexpectedly")
77}
More examples
Hide additional examples
examples/score_rows.rs (line 66)
30async fn main() -> Result<()> {
31    let openai_base = std::env::var("JEV_BRIDGE_UPSTREAM_URL")
32        .unwrap_or_else(|_| "http://127.0.0.1:8080/v1".to_string());
33    let native_base = std::env::var("JEV_BRIDGE_NATIVE_URL")
34        .unwrap_or_else(|_| openai_base.trim_end_matches("/v1").to_string());
35    let upstream_key = std::env::var("JEV_BRIDGE_UPSTREAM_KEY").ok();
36    let upstream_model =
37        std::env::var("JEV_BRIDGE_UPSTREAM_MODEL").unwrap_or_else(|_| "local-model".to_string());
38
39    let started = Instant::now();
40    let bridge = Bridge::connect(
41        reqwest::Client::new(),
42        BridgeConfig {
43            openai_base,
44            native_base,
45            upstream_model,
46            upstream_key,
47            served_model: "example-bridge".to_string(),
48            description: "example bridge".to_string(),
49            release_date: "2026-09-22".to_string(),
50            chat_template_kwargs: json!({"enable_thinking": false}),
51            max_input_tokens: None,
52            local: Default::default(),
53            accept_any_model: false,
54            scoring: Default::default(),
55            confidence: Default::default(),
56            readout: Default::default(),
57        },
58    )
59    .await
60    .context("connecting to the upstream service failed")?;
61
62    println!(
63        "connected in {:.2?}: transport={} endpoint={} renders_locally={} tokenizes_locally={}",
64        started.elapsed(),
65        bridge.probe().name(),
66        bridge.probe().endpoint(),
67        bridge.renders_locally(),
68        bridge.tokenizes_locally(),
69    );
70
71    let rows = vec![
72        Row {
73            id: "refund".to_string(),
74            state: json!("I was charged twice and need a refund today."),
75            question: "Which queue should handle this request?".to_string(),
76            options: vec![
77                option("access", "Account access and authentication."),
78                option("billing", "Billing, payments, and refunds."),
79                option("sales", "Pricing and new contracts."),
80            ],
81        },
82        Row {
83            id: "outage".to_string(),
84            state: json!("The API returns 502 for every request since this morning."),
85            question: "Which queue should handle this request?".to_string(),
86            options: vec![
87                option("access", "Account access and authentication."),
88                option("billing", "Billing, payments, and refunds."),
89                option("sales", "Pricing and new contracts."),
90            ],
91        },
92    ];
93
94    let started = Instant::now();
95    // Independent decisions, each carrying its own state: one readout per row.
96    let mut scored = Vec::with_capacity(rows.len());
97    for row in &rows {
98        scored.push(bridge.score_row(row).await?);
99    }
100    println!("scored {} rows in {:.2?}\n", scored.len(), started.elapsed());
101
102    for row in &scored {
103        let winner = row
104            .answer
105            .probabilities
106            .iter()
107            .enumerate()
108            .max_by(|a, b| a.1.partial_cmp(b.1).unwrap())
109            .map(|(index, _)| row.answer.option_ids[index].as_str())
110            .unwrap();
111        println!("{} -> {winner}", row.answer.id);
112        for (id, probability) in row.answer.option_ids.iter().zip(&row.answer.probabilities) {
113            println!("    {id:<8} {probability:.4}");
114        }
115        println!(
116            "    input_tokens={} prompt_sha256={}",
117            row.answer.input_tokens,
118            &row.prompt_sha256[..16]
119        );
120    }
121
122    // Probabilities are conditional on the supplied options and uncalibrated.
123    println!("\nThese scores are conditional option probabilities, not calibrated confidence.");
124    Ok(())
125}

Trait Implementations§

Source§

impl Clone for Probe

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Probe

Source§

impl Debug for Probe

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for Probe

Source§

impl PartialEq for Probe

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Probe

Auto Trait Implementations§

§

impl Freeze for Probe

§

impl RefUnwindSafe for Probe

§

impl Send for Probe

§

impl Sync for Probe

§

impl Unpin for Probe

§

impl UnsafeUnpin for Probe

§

impl UnwindSafe for Probe

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more