1use http::Method;
9
10use crate::operation::{Operation, OperationKind};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum Seg {
16 Lit(&'static str),
18 Param(&'static str),
20 ParamAction(&'static str, &'static str),
23 Rest(&'static str),
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub struct PathPattern(pub &'static [Seg]);
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub enum StreamDetect {
34 Never,
36 BodyFlag(&'static str),
39 BodyValue(&'static str, &'static str),
41 BodyFlagOrMultipart(&'static str),
44 Always,
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub enum StreamFraming {
50 Sse,
51 WebSocket,
52 JsonArray,
53}
54
55#[derive(Debug, Clone, Copy)]
57pub struct Ingress {
58 pub method: &'static Method,
59 pub pattern: PathPattern,
60 pub kind: OperationKind,
61 pub stream: StreamDetect,
62 pub framing: StreamFraming,
63 pub upgrade: bool,
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq)]
72pub enum SettleMode {
73 Free,
75 OnResponse,
77 OnSessionEnd,
80 OnCompletedStatus,
83}
84
85#[derive(Debug, Clone, Copy, PartialEq, Eq)]
87pub enum Affinity {
88 None,
89 Session,
91 Resource(&'static str),
94}
95
96#[derive(Debug, Clone, Copy)]
98pub struct OperationSpec {
99 pub ingress: &'static [Ingress],
100 pub settle: SettleMode,
101 pub affinity: Affinity,
102}
103
104#[derive(Debug)]
106pub struct Matched {
107 pub operation: Operation,
108 pub kind: OperationKind,
109 pub stream: StreamDetect,
110 pub framing: StreamFraming,
111 pub upgrade: bool,
112 pub params: Vec<(&'static str, String)>,
114}
115
116pub const fn default_framing(kind: OperationKind, upgrade: bool) -> StreamFraming {
117 if upgrade {
118 return StreamFraming::WebSocket;
119 }
120 match kind {
121 OperationKind::ContentGeneration(
122 crate::operation::ContentGenerationKind::GeminiGenerateContent,
123 ) => StreamFraming::JsonArray,
124 OperationKind::ContentGeneration(
125 crate::operation::ContentGenerationKind::OpenAiResponsesWebSocket,
126 ) => StreamFraming::WebSocket,
127 OperationKind::ContentGeneration(
128 crate::operation::ContentGenerationKind::OpenAiChat
129 | crate::operation::ContentGenerationKind::OpenAiResponses
130 | crate::operation::ContentGenerationKind::ClaudeMessages,
131 )
132 | OperationKind::Family(_) => StreamFraming::Sse,
133 }
134}
135
136pub const fn streaming_sibling(operation: Operation) -> Option<Operation> {
139 match operation {
140 Operation::GenerateContent => Some(Operation::StreamGenerateContent),
141 Operation::ListModels
142 | Operation::GetModel
143 | Operation::CountTokens
144 | Operation::SummarizeMemory
145 | Operation::StreamGenerateContent
146 | Operation::GuardianReview
147 | Operation::GuardianClassify
148 | Operation::CompactContent
149 | Operation::CreateConversation
150 | Operation::CreateEmbedding
151 | Operation::BatchCreateEmbedding
152 | Operation::Rerank
153 | Operation::WebSearch
154 | Operation::CreateImage
155 | Operation::EditImage
156 | Operation::CreateSpeech
157 | Operation::CreateTranscription
158 | Operation::CreateTranslation
159 | Operation::CreateFile
160 | Operation::ListFiles
161 | Operation::RetrieveFile
162 | Operation::RetrieveFileContent
163 | Operation::DeleteFile
164 | Operation::CreateVideo
165 | Operation::RetrieveVideo
166 | Operation::ListVideos
167 | Operation::DeleteVideo
168 | Operation::DownloadVideoContent
169 | Operation::RemixVideo
170 | Operation::CreateVideoCharacter
171 | Operation::GetVideoCharacter
172 | Operation::EditVideo
173 | Operation::ExtendVideo
174 | Operation::CreateRealtimeCall
175 | Operation::ConnectRealtime => None,
176 }
177}
178
179impl Operation {
180 pub fn spec(self) -> &'static OperationSpec {
183 crate::specs::spec(self)
184 }
185}