#![allow(dead_code)]
use super::*;
pub(in crate::scheduler) const GUARD_STOP_REQUEST_TIMEOUT: &str = "request_timeout";
pub(in crate::scheduler) const GUARD_STOP_TOOL_RESPONSE: &str = "tool_response_hard_stop";
pub(in crate::scheduler) const GUARD_STOP_THINK_SKIP: &str = "think_skip_watchdog";
pub(in crate::scheduler) const GUARD_STOP_INTER_TOOL_PROSE: &str = "inter_tool_prose_budget";
pub(in crate::scheduler) const GUARD_STOP_CONTENT_LOOP: &str = "content_loop_watchdog";
pub(in crate::scheduler) const GUARD_STOP_POST_THINK_CAP: &str = "post_think_content_cap";
pub(in crate::scheduler) struct ActiveSeq {
pub seq: SequenceState,
pub session_hash: u64,
pub last_token: u32,
pub output_tokens: Vec<u32>,
pub remaining: usize,
pub min_tokens: usize,
pub eos_tokens: Vec<u32>,
pub finished: bool,
pub error: Option<String>,
pub guard_stop: Option<&'static str>,
pub param_close_pending: u8,
pub sink: ResponseSink,
pub cancel_flag: Option<std::sync::Arc<std::sync::atomic::AtomicBool>>,
pub temperature: f32,
pub top_k: u32,
pub top_p: f32,
pub top_n_sigma: f32,
pub min_p: f32,
pub repetition_penalty: f32,
pub repetition_penalty_window: u32,
pub presence_penalty: f32,
pub frequency_penalty: f32,
pub lz_penalty: f32,
pub dry_multiplier: f32,
pub dry_base: f32,
pub dry_allowed_length: u32,
pub dry_sequence_breakers: Vec<u32>,
pub logit_bias: Vec<(u32, f32)>,
pub inside_thinking: bool,
pub enable_thinking: bool,
pub thinking_budget: Option<u32>,
pub repetition_detection: Option<RepetitionDetectionParams>,
pub spontaneous_think_budget: Option<u32>,
pub thinking_tokens: u32,
pub force_end_thinking: bool,
pub think_force_closed: bool,
pub sentence_defer_count: u32,
pub consecutive_confident: u32,
pub in_code_fence: bool,
pub think_end_token: Option<u32>,
pub think_start_token: Option<u32>,
pub think_ended: bool,
pub think_just_ended: bool,
pub post_think_emitted: u32,
pub spec_adapt: crate::scheduler::adaptive_spec::AdaptState,
pub think_skip_count: u32,
pub tool_call_end_token: Option<u32>,
pub require_tool_call: bool,
pub tool_request: bool,
pub tools_present: bool,
pub tool_call_start_token: Option<u32>,
pub tool_call_opened: bool,
pub inside_tool_body: bool,
pub tool_call_completed: bool,
pub post_completion_tool_opens: u32,
pub tool_body_streak_tokens: u32,
pub inside_parameter_body: bool,
pub param_body_chars_emitted: u32,
pub suppress_tool_call: bool,
pub disable_mtp: bool,
pub mtp_acct: crate::scheduler::mtp_accept_debug::RequestAccept,
pub content_started: bool,
pub content_tokens: u32,
pub prose_tokens_since_last_tool: u32,
pub think_watchdog_fires: u32,
pub rollback_count: u32,
pub ssm_rollback_ring: crate::scheduler::ssm_decode_ring::SsmDecodeRing,
pub grammar_state: Option<GrammarState>,
pub pending_drafts: Vec<u32>,
pub pending_draft_conf: Vec<f32>,
pub prompt_lookup: Option<Box<metrale_speculative::prompt_lookup::PromptLookupSeq>>,
pub last_token_time: Instant,
pub request_start: Instant,
pub decode_start: Instant,
pub seed: Option<u64>,
pub top_logprobs: Option<u8>,
pub logprobs_data: Vec<crate::api::TokenLogprobs>,
pub timeout_at: Option<Instant>,
pub adaptive: crate::adaptive_sampler::AdaptiveSamplingState,
pub cached_prompt_tokens: u32,
pub preempt_immune_until_tokens: usize,
}
impl ActiveSeq {
pub fn consume_generation_budget(&mut self) {
if !consume_budget(&mut self.remaining) {
tracing::warn!(
output_tokens = self.output_tokens.len(),
"generation budget decremented at 0 (token processed after \
length stop should have fired) — finishing sequence instead \
of wrapping"
);
self.finished = true;
}
}
}
pub(in crate::scheduler) fn consume_budget(remaining: &mut usize) -> bool {
if *remaining == 0 {
return false;
}
*remaining -= 1;
true
}