Skip to main content

gproxy_protocol/
spec.rs

1//! Declared wire surfaces, independent of routing and provider capabilities.
2//!
3//! This table describes the protocol models available in this crate. It is not
4//! a transform matrix or a list of operations every upstream must implement.
5//! Error responses can use other bodies. Paths, TLS/client configuration,
6//! authentication, billing and affinity belong to their respective adapters or
7//! engine layers. No request is validated or sent by consulting this table.
8
9use crate::{Dialect, Operation, OperationKey, connection::StreamFraming};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum HttpBodyFormat {
13    Empty,
14    Json,
15    Multipart,
16    Binary,
17    Text,
18    /// A sequence of JSON payloads carried using HTTP stream framing.
19    JsonStream(StreamFraming),
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum OperationTransport {
24    Http {
25        request: &'static [HttpBodyFormat],
26        response: &'static [HttpBodyFormat],
27    },
28    /// The HTTP handshake is followed by an independent duplex connection.
29    WebSocket,
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub struct OperationSpec {
34    pub key: OperationKey,
35    pub transport: OperationTransport,
36}
37
38const SSE: HttpBodyFormat = HttpBodyFormat::JsonStream(StreamFraming::Sse);
39const JSON_ARRAY: HttpBodyFormat = HttpBodyFormat::JsonStream(StreamFraming::JsonArray);
40
41const fn http(
42    operation: Operation,
43    dialect: Dialect,
44    request: &'static [HttpBodyFormat],
45    response: &'static [HttpBodyFormat],
46) -> OperationSpec {
47    OperationSpec {
48        key: OperationKey { operation, dialect },
49        transport: OperationTransport::Http { request, response },
50    }
51}
52
53const fn websocket(operation: Operation, dialect: Dialect) -> OperationSpec {
54    OperationSpec {
55        key: OperationKey { operation, dialect },
56        transport: OperationTransport::WebSocket,
57    }
58}
59
60/// Format alternatives describe the modelled wire surfaces, not runtime
61/// capabilities or default selection. Headers/query choose a format; ordering
62/// here does not imply a default or infer boundaries from transport chunks.
63pub const OPERATION_SPECS: &[OperationSpec] = {
64    use Dialect::*;
65    use HttpBodyFormat::*;
66    use Operation::*;
67    &[
68        http(ListModels, OpenAi, &[Empty], &[Json]),
69        http(ListModels, Claude, &[Empty], &[Json]),
70        http(ListModels, Gemini, &[Empty], &[Json]),
71        http(GetModel, OpenAi, &[Empty], &[Json]),
72        http(GetModel, Claude, &[Empty], &[Json]),
73        http(GetModel, Gemini, &[Empty], &[Json]),
74        http(CountTokens, OpenAi, &[Json], &[Json]),
75        http(CountTokens, Claude, &[Json], &[Json]),
76        http(CountTokens, Gemini, &[Json], &[Json]),
77        http(GenerateContent, OpenAi, &[Json], &[Json]),
78        http(GenerateContent, Claude, &[Json], &[Json]),
79        http(GenerateContent, Gemini, &[Json], &[Json]),
80        http(GenerateContent, OpenAiChat, &[Json], &[Json]),
81        http(StreamGenerateContent, OpenAi, &[Json], &[SSE]),
82        http(StreamGenerateContent, Claude, &[Json], &[SSE]),
83        http(StreamGenerateContent, OpenAiChat, &[Json], &[SSE]),
84        http(StreamGenerateContent, Gemini, &[Json], &[SSE, JSON_ARRAY]),
85        http(CreateModeration, OpenAi, &[Json], &[Json]),
86        http(CreateDecision, OpenAi, &[Json], &[Json]),
87        http(CompactContent, OpenAi, &[Json], &[Json]),
88        http(SummarizeMemory, OpenAi, &[Json], &[Json]),
89        http(CreateConversation, OpenAi, &[Json], &[Json]),
90        http(WebSearch, OpenAi, &[Json], &[Json]),
91        http(Rerank, OpenAi, &[Json], &[Json]),
92        http(CreateEmbedding, OpenAi, &[Json], &[Json]),
93        http(CreateEmbedding, Gemini, &[Json], &[Json]),
94        http(BatchCreateEmbedding, Gemini, &[Json], &[Json]),
95        http(CreateImage, OpenAi, &[Json], &[Json, SSE]),
96        http(EditImage, OpenAi, &[Json, Multipart], &[Json, SSE]),
97        http(CreateSpeech, OpenAi, &[Json], &[Binary, SSE]),
98        http(
99            CreateTranscription,
100            OpenAi,
101            &[Multipart],
102            &[Json, Text, SSE],
103        ),
104        http(CreateTranslation, OpenAi, &[Multipart], &[Json, Text]),
105        http(CreateFile, OpenAi, &[Multipart], &[Json]),
106        http(CreateFile, Claude, &[Multipart], &[Json]),
107        http(
108            CreateFile,
109            Gemini,
110            &[Multipart, Json, Binary],
111            &[Json, Empty],
112        ),
113        http(ListFiles, OpenAi, &[Empty], &[Json]),
114        http(ListFiles, Claude, &[Empty], &[Json]),
115        http(ListFiles, Gemini, &[Empty], &[Json]),
116        http(RetrieveFile, OpenAi, &[Empty], &[Json]),
117        http(RetrieveFile, Claude, &[Empty], &[Json]),
118        http(RetrieveFile, Gemini, &[Empty], &[Json]),
119        http(RetrieveFileContent, OpenAi, &[Empty], &[Binary]),
120        http(RetrieveFileContent, Claude, &[Empty], &[Binary]),
121        http(RetrieveFileContent, Gemini, &[Empty], &[Binary]),
122        http(DeleteFile, OpenAi, &[Empty], &[Json]),
123        http(DeleteFile, Claude, &[Empty], &[Json]),
124        http(DeleteFile, Gemini, &[Empty], &[Json]),
125        http(CreateVideo, OpenAi, &[Json, Multipart], &[Json]),
126        http(RetrieveVideo, OpenAi, &[Empty], &[Json]),
127        http(ListVideos, OpenAi, &[Empty], &[Json]),
128        http(DeleteVideo, OpenAi, &[Empty], &[Json]),
129        http(DownloadVideoContent, OpenAi, &[Empty], &[Binary]),
130        http(CreateVoice, OpenAi, &[Json, Multipart], &[Json]),
131        http(CreateRealtimeClientSecret, OpenAi, &[Json], &[Json]),
132        http(HangupRealtimeCall, OpenAi, &[Empty, Json], &[Empty]),
133        http(CreateLiveSession, OpenAi, &[Json], &[Json]),
134        http(HangupLiveSession, OpenAi, &[Empty, Json], &[Empty]),
135        websocket(ConnectLive, OpenAi),
136        http(CreateRealtimeCall, OpenAi, &[Multipart], &[Text]),
137        websocket(GenerateContent, OpenAiResponsesWebSocket),
138        websocket(StreamGenerateContent, OpenAiResponsesWebSocket),
139        websocket(ConnectRealtime, OpenAi),
140        websocket(ConnectRealtime, Gemini),
141    ]
142};