Skip to main content

gproxy_protocol/adapt/
edges.rs

1//! The conversion edges this crate adapts.
2//!
3//! An edge reads: a client request in the source key is served by an
4//! upstream call in the target key, response mapping included. The return
5//! path is part of the edge, never a reverse edge of its own. There is no
6//! transitive closure: an edge exists only when it is listed here, and the
7//! host must not offer a conversion that is not. `design/transform-matrix.md`
8//! records why each family has the shape it has.
9//!
10//! Dialect letters follow the matrix: R = Responses, H = Chat Completions,
11//! C = Claude, G = Gemini, W = Responses over a websocket.
12
13use crate::{Dialect, Operation, OperationKey};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
16pub struct ConversionEdge {
17    pub source: OperationKey,
18    pub target: OperationKey,
19}
20
21const fn edge(
22    (source_operation, source_dialect): (Operation, Dialect),
23    (target_operation, target_dialect): (Operation, Dialect),
24) -> ConversionEdge {
25    ConversionEdge {
26        source: OperationKey {
27            operation: source_operation,
28            dialect: source_dialect,
29        },
30        target: OperationKey {
31            operation: target_operation,
32            dialect: target_dialect,
33        },
34    }
35}
36
37pub const CONVERSION_EDGES: &[ConversionEdge] = {
38    use Dialect::{
39        Claude as C, Gemini as G, OpenAi as R, OpenAiChat as H, OpenAiResponsesWebSocket as W,
40    };
41    use Operation::{GenerateContent as Generate, StreamGenerateContent as Stream, *};
42    &[
43        // ListModels
44        edge((ListModels, R), (ListModels, C)),
45        edge((ListModels, R), (ListModels, G)),
46        edge((ListModels, C), (ListModels, R)),
47        edge((ListModels, C), (ListModels, G)),
48        edge((ListModels, G), (ListModels, R)),
49        edge((ListModels, G), (ListModels, C)),
50        // GetModel
51        edge((GetModel, R), (GetModel, C)),
52        edge((GetModel, R), (GetModel, G)),
53        edge((GetModel, C), (GetModel, R)),
54        edge((GetModel, C), (GetModel, G)),
55        edge((GetModel, G), (GetModel, R)),
56        edge((GetModel, G), (GetModel, C)),
57        // CountTokens
58        edge((CountTokens, R), (CountTokens, C)),
59        edge((CountTokens, R), (CountTokens, G)),
60        edge((CountTokens, C), (CountTokens, G)),
61        edge((CountTokens, G), (CountTokens, C)),
62        // GenerateContent
63        edge((Generate, R), (Generate, C)),
64        edge((Generate, R), (Generate, G)),
65        edge((Generate, R), (Generate, H)),
66        edge((Generate, R), (Stream, R)),
67        edge((Generate, R), (Stream, C)),
68        edge((Generate, R), (Stream, G)),
69        edge((Generate, R), (Stream, H)),
70        edge((Generate, R), (Stream, W)),
71        edge((Generate, C), (Generate, R)),
72        edge((Generate, C), (Generate, G)),
73        edge((Generate, C), (Generate, H)),
74        edge((Generate, C), (Stream, R)),
75        edge((Generate, C), (Stream, C)),
76        edge((Generate, C), (Stream, G)),
77        edge((Generate, C), (Stream, H)),
78        edge((Generate, G), (Generate, R)),
79        edge((Generate, G), (Generate, C)),
80        edge((Generate, G), (Generate, H)),
81        edge((Generate, G), (Stream, R)),
82        edge((Generate, G), (Stream, C)),
83        edge((Generate, G), (Stream, G)),
84        edge((Generate, G), (Stream, H)),
85        edge((Generate, H), (Generate, R)),
86        edge((Generate, H), (Generate, C)),
87        edge((Generate, H), (Generate, G)),
88        edge((Generate, H), (Stream, R)),
89        edge((Generate, H), (Stream, C)),
90        edge((Generate, H), (Stream, G)),
91        edge((Generate, H), (Stream, H)),
92        // StreamGenerateContent
93        edge((Stream, R), (Generate, R)),
94        edge((Stream, R), (Generate, C)),
95        edge((Stream, R), (Generate, G)),
96        edge((Stream, R), (Generate, H)),
97        edge((Stream, R), (Stream, C)),
98        edge((Stream, R), (Stream, G)),
99        edge((Stream, R), (Stream, H)),
100        edge((Stream, R), (Stream, W)),
101        edge((Stream, C), (Generate, R)),
102        edge((Stream, C), (Generate, C)),
103        edge((Stream, C), (Generate, G)),
104        edge((Stream, C), (Generate, H)),
105        edge((Stream, C), (Stream, R)),
106        edge((Stream, C), (Stream, G)),
107        edge((Stream, C), (Stream, H)),
108        edge((Stream, C), (Stream, W)),
109        edge((Stream, H), (Generate, R)),
110        edge((Stream, H), (Generate, C)),
111        edge((Stream, H), (Generate, G)),
112        edge((Stream, H), (Generate, H)),
113        edge((Stream, H), (Stream, R)),
114        edge((Stream, H), (Stream, C)),
115        edge((Stream, H), (Stream, G)),
116        edge((Stream, H), (Stream, W)),
117        edge((Stream, G), (Generate, R)),
118        edge((Stream, G), (Generate, C)),
119        edge((Stream, G), (Generate, G)),
120        edge((Stream, G), (Generate, H)),
121        edge((Stream, G), (Stream, R)),
122        edge((Stream, G), (Stream, C)),
123        edge((Stream, G), (Stream, H)),
124        edge((Stream, G), (Stream, W)),
125        // CompactContent
126        edge((CompactContent, R), (Generate, R)),
127        edge((CompactContent, R), (Generate, C)),
128        edge((CompactContent, R), (Generate, G)),
129        edge((CompactContent, R), (Generate, H)),
130        // SummarizeMemory
131        edge((SummarizeMemory, R), (Generate, R)),
132        edge((SummarizeMemory, R), (Generate, C)),
133        edge((SummarizeMemory, R), (Generate, G)),
134        edge((SummarizeMemory, R), (Generate, H)),
135        // WebSearch
136        edge((WebSearch, R), (Generate, R)),
137        edge((WebSearch, R), (Generate, C)),
138        edge((WebSearch, R), (Generate, G)),
139        // CreateEmbedding
140        edge((CreateEmbedding, R), (CreateEmbedding, G)),
141        edge((CreateEmbedding, G), (CreateEmbedding, R)),
142        // BatchCreateEmbedding
143        edge((BatchCreateEmbedding, G), (CreateEmbedding, R)),
144        // CreateImage
145        edge((CreateImage, R), (Generate, G)),
146        // EditImage
147        edge((EditImage, R), (Generate, G)),
148        // CreateFile
149        edge((CreateFile, R), (CreateFile, C)),
150        edge((CreateFile, R), (CreateFile, G)),
151        edge((CreateFile, C), (CreateFile, R)),
152        edge((CreateFile, C), (CreateFile, G)),
153        edge((CreateFile, G), (CreateFile, R)),
154        edge((CreateFile, G), (CreateFile, C)),
155        // ListFiles
156        edge((ListFiles, R), (ListFiles, C)),
157        edge((ListFiles, R), (ListFiles, G)),
158        edge((ListFiles, C), (ListFiles, R)),
159        edge((ListFiles, C), (ListFiles, G)),
160        edge((ListFiles, G), (ListFiles, R)),
161        edge((ListFiles, G), (ListFiles, C)),
162        // RetrieveFile
163        edge((RetrieveFile, R), (RetrieveFile, C)),
164        edge((RetrieveFile, R), (RetrieveFile, G)),
165        edge((RetrieveFile, C), (RetrieveFile, R)),
166        edge((RetrieveFile, C), (RetrieveFile, G)),
167        edge((RetrieveFile, G), (RetrieveFile, R)),
168        edge((RetrieveFile, G), (RetrieveFile, C)),
169        // RetrieveFileContent
170        edge((RetrieveFileContent, R), (RetrieveFileContent, C)),
171        edge((RetrieveFileContent, R), (RetrieveFileContent, G)),
172        edge((RetrieveFileContent, C), (RetrieveFileContent, R)),
173        edge((RetrieveFileContent, C), (RetrieveFileContent, G)),
174        edge((RetrieveFileContent, G), (RetrieveFileContent, R)),
175        edge((RetrieveFileContent, G), (RetrieveFileContent, C)),
176        // DeleteFile
177        edge((DeleteFile, R), (DeleteFile, C)),
178        edge((DeleteFile, R), (DeleteFile, G)),
179        edge((DeleteFile, C), (DeleteFile, R)),
180        edge((DeleteFile, C), (DeleteFile, G)),
181        edge((DeleteFile, G), (DeleteFile, R)),
182        edge((DeleteFile, G), (DeleteFile, C)),
183        // CreateVideo
184        edge((CreateVideo, R), (CreateVideo, G)),
185        // RetrieveVideo
186        edge((RetrieveVideo, R), (RetrieveVideo, G)),
187        // DownloadVideoContent
188        edge((DownloadVideoContent, R), (DownloadVideoContent, G)),
189        // GenerateContent
190        edge((Generate, W), (Generate, R)),
191        edge((Generate, W), (Generate, C)),
192        edge((Generate, W), (Generate, G)),
193        edge((Generate, W), (Generate, H)),
194        edge((Generate, W), (Stream, R)),
195        edge((Generate, W), (Stream, C)),
196        edge((Generate, W), (Stream, G)),
197        edge((Generate, W), (Stream, H)),
198        // StreamGenerateContent
199        edge((Stream, W), (Generate, R)),
200        edge((Stream, W), (Generate, C)),
201        edge((Stream, W), (Generate, G)),
202        edge((Stream, W), (Generate, H)),
203        edge((Stream, W), (Stream, R)),
204        edge((Stream, W), (Stream, C)),
205        edge((Stream, W), (Stream, G)),
206        edge((Stream, W), (Stream, H)),
207    ]
208};
209
210pub fn is_conversion_edge(source: OperationKey, target: OperationKey) -> bool {
211    CONVERSION_EDGES.contains(&ConversionEdge { source, target })
212}
213
214/// Targets that can serve `source`, in table order.
215pub fn conversion_targets(source: OperationKey) -> impl Iterator<Item = OperationKey> {
216    CONVERSION_EDGES
217        .iter()
218        .filter(move |edge| edge.source == source)
219        .map(|edge| edge.target)
220}