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(GuardianReview, OpenAi, &[Json], &[SSE]),
88        http(GuardianClassify, OpenAi, &[Json], &[SSE]),
89        http(CompactContent, OpenAi, &[Json], &[Json]),
90        http(SummarizeMemory, OpenAi, &[Json], &[Json]),
91        http(CreateConversation, OpenAi, &[Json], &[Json]),
92        http(WebSearch, OpenAi, &[Json], &[Json]),
93        http(Rerank, OpenAi, &[Json], &[Json]),
94        http(CreateEmbedding, OpenAi, &[Json], &[Json]),
95        http(CreateEmbedding, Gemini, &[Json], &[Json]),
96        http(BatchCreateEmbedding, Gemini, &[Json], &[Json]),
97        http(CreateImage, OpenAi, &[Json], &[Json, SSE]),
98        http(EditImage, OpenAi, &[Json, Multipart], &[Json, SSE]),
99        http(CreateSpeech, OpenAi, &[Json], &[Binary, SSE]),
100        http(
101            CreateTranscription,
102            OpenAi,
103            &[Multipart],
104            &[Json, Text, SSE],
105        ),
106        http(CreateTranslation, OpenAi, &[Multipart], &[Json, Text]),
107        http(CreateFile, OpenAi, &[Multipart], &[Json]),
108        http(CreateFile, Claude, &[Multipart], &[Json]),
109        http(
110            CreateFile,
111            Gemini,
112            &[Multipart, Json, Binary],
113            &[Json, Empty],
114        ),
115        http(ListFiles, OpenAi, &[Empty], &[Json]),
116        http(ListFiles, Claude, &[Empty], &[Json]),
117        http(ListFiles, Gemini, &[Empty], &[Json]),
118        http(RetrieveFile, OpenAi, &[Empty], &[Json]),
119        http(RetrieveFile, Claude, &[Empty], &[Json]),
120        http(RetrieveFile, Gemini, &[Empty], &[Json]),
121        http(RetrieveFileContent, OpenAi, &[Empty], &[Binary]),
122        http(RetrieveFileContent, Claude, &[Empty], &[Binary]),
123        http(RetrieveFileContent, Gemini, &[Empty], &[Binary]),
124        http(DeleteFile, OpenAi, &[Empty], &[Json]),
125        http(DeleteFile, Claude, &[Empty], &[Json]),
126        http(DeleteFile, Gemini, &[Empty], &[Json]),
127        http(CreateVideo, OpenAi, &[Json, Multipart], &[Json]),
128        http(RetrieveVideo, OpenAi, &[Empty], &[Json]),
129        http(ListVideos, OpenAi, &[Empty], &[Json]),
130        http(DeleteVideo, OpenAi, &[Empty], &[Json]),
131        http(DownloadVideoContent, OpenAi, &[Empty], &[Binary]),
132        http(CreateRealtimeCall, OpenAi, &[Multipart], &[Text]),
133        websocket(GenerateContent, OpenAiResponsesWebSocket),
134        websocket(StreamGenerateContent, OpenAiResponsesWebSocket),
135        websocket(ConnectRealtime, OpenAi),
136        websocket(ConnectRealtime, Gemini),
137    ]
138};