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