atomr_infer_core/
tokens.rs1use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct TokenChunk {
10 pub request_id: String,
11 pub text_delta: String,
12 #[serde(default, skip_serializing_if = "Option::is_none")]
15 pub tool_call_delta: Option<serde_json::Value>,
16 #[serde(default, skip_serializing_if = "Option::is_none")]
17 pub usage: Option<TokenUsage>,
18 #[serde(default, skip_serializing_if = "Option::is_none")]
19 pub finish_reason: Option<FinishReason>,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
23#[serde(rename_all = "snake_case")]
24#[non_exhaustive]
25pub enum FinishReason {
26 Stop,
27 Length,
28 ToolCalls,
29 ContentFilter,
30 Error,
31}
32
33#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
34pub struct TokenUsage {
35 pub input_tokens: u32,
36 pub output_tokens: u32,
37 #[serde(default)]
39 pub reasoning_tokens: u32,
40 #[serde(default)]
43 pub cached_tokens: u32,
44}
45
46impl TokenUsage {
47 pub fn add(&mut self, other: TokenUsage) {
48 self.input_tokens += other.input_tokens;
49 self.output_tokens += other.output_tokens;
50 self.reasoning_tokens += other.reasoning_tokens;
51 self.cached_tokens += other.cached_tokens;
52 }
53}
54
55#[derive(Debug, Clone, Default, Serialize, Deserialize)]
59pub struct Tokens {
60 pub request_id: String,
61 pub text: String,
62 pub usage: TokenUsage,
63 pub finish_reason: Option<FinishReason>,
64}
65
66impl Tokens {
67 pub fn append(&mut self, chunk: &TokenChunk) {
68 self.text.push_str(&chunk.text_delta);
69 if let Some(u) = chunk.usage {
70 self.usage.add(u);
71 }
72 if let Some(r) = chunk.finish_reason {
73 self.finish_reason = Some(r);
74 }
75 }
76}