systemprompt_models/wire/canonical/
response.rs1use super::request::CanonicalContent;
9
10#[derive(Debug, Clone, Copy, Default)]
11#[expect(
12 clippy::struct_field_names,
13 reason = "every field is a token count; the `_tokens` suffix is the domain vocabulary shared \
14 with the provider usage wire formats"
15)]
16pub struct CanonicalUsage {
17 pub input_tokens: u32,
18 pub output_tokens: u32,
19 pub cache_read_tokens: u32,
20 pub cache_creation_tokens: u32,
21 pub total_tokens: u32,
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub enum CanonicalStopReason {
26 EndTurn,
27 MaxTokens,
28 StopSequence,
29 ToolUse,
30 Other,
31}
32
33impl CanonicalStopReason {
34 pub const fn anthropic_str(self) -> &'static str {
35 match self {
36 Self::MaxTokens => "max_tokens",
37 Self::StopSequence => "stop_sequence",
38 Self::ToolUse => "tool_use",
39 Self::EndTurn | Self::Other => "end_turn",
40 }
41 }
42
43 pub const fn openai_str(self) -> &'static str {
44 match self {
45 Self::MaxTokens => "length",
46 Self::ToolUse => "tool_calls",
47 Self::EndTurn | Self::StopSequence | Self::Other => "stop",
48 }
49 }
50
51 pub fn from_anthropic(s: &str) -> Self {
52 match s {
53 "end_turn" => Self::EndTurn,
54 "max_tokens" => Self::MaxTokens,
55 "stop_sequence" => Self::StopSequence,
56 "tool_use" => Self::ToolUse,
57 _ => Self::Other,
58 }
59 }
60
61 pub fn from_openai(s: &str) -> Self {
62 match s {
63 "stop" => Self::EndTurn,
64 "length" => Self::MaxTokens,
65 "tool_calls" | "function_call" => Self::ToolUse,
66 _ => Self::Other,
67 }
68 }
69}
70
71#[derive(Debug, Clone, Default)]
72pub struct GroundedSource {
73 pub uri: String,
74 pub title: Option<String>,
75 pub snippet: Option<String>,
76 pub relevance: Option<f32>,
77}
78
79#[derive(Debug, Clone, Default)]
80pub struct Grounding {
81 pub sources: Vec<GroundedSource>,
82 pub queries: Vec<String>,
83}
84
85#[derive(Debug, Clone, Default)]
86pub struct CodeExecutionOutput {
87 pub language: Option<String>,
88 pub code: String,
89 pub result: Option<String>,
90 pub outcome: Option<String>,
91}
92
93#[derive(Debug, Clone)]
94pub struct CanonicalResponse {
95 pub id: String,
96 pub model: String,
97 pub content: Vec<CanonicalContent>,
98 pub stop_reason: Option<CanonicalStopReason>,
99 pub usage: CanonicalUsage,
100 pub grounding: Option<Grounding>,
101 pub code_execution: Option<CodeExecutionOutput>,
102 pub raw_finish_reason: Option<String>,
103}
104
105#[derive(Debug, Clone)]
106pub enum CanonicalEvent {
107 MessageStart {
108 id: String,
109 model: String,
110 usage: CanonicalUsage,
111 },
112 ContentBlockStart {
113 index: u32,
114 block: ContentBlockKind,
115 },
116 TextDelta {
117 index: u32,
118 text: String,
119 },
120 ThinkingDelta {
121 index: u32,
122 text: String,
123 },
124 SignatureDelta {
125 index: u32,
126 signature: String,
127 },
128 ToolUseDelta {
129 index: u32,
130 partial_json: String,
131 },
132 ContentBlockStop {
133 index: u32,
134 },
135 UsageDelta(CanonicalUsage),
136 MessageStop {
137 id: String,
138 stop_reason: Option<CanonicalStopReason>,
139 },
140 Error(String),
141}
142
143#[derive(Debug, Clone)]
144pub enum ContentBlockKind {
145 Text,
146 Thinking {
147 signature: Option<String>,
148 },
149 ToolUse {
150 id: String,
151 name: String,
152 signature: Option<String>,
153 },
154}