1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
//! The protocol seam (arch §4.1): the `Protocol` trait owning a wire dialect, the
//! secret-free `ProviderCtx` handed to encode/auth, and the `WireRequest` that
//! flows encode → auth → transport (in `wire`). The framing types live in `frame`; the five
//! concrete protocol impls are `anthropic` (Messages), `openai` (Chat Completions),
//! `openai_responses` (Responses), `google_genai`, and `ollama_chat`. The framers
//! live in `sse`.
use crate;
pub use ;
/// The ONE whole-body non-2xx HTTP error projection + the ONE generic models-list
/// decoder + the ONE generic token-count decoder (json.rs). `http_error` drains a
/// provider error body and carries it VERBATIM; `decode_models` projects a models-list
/// body onto `Vec<Model>` reading the `(array_key, id_key, strip)` a protocol's
/// [`ModelsShape`] supplies (overridden per row, model-discovery §3.2); `count_from_body`
/// reads the token count from a 2xx count body at the response key a [`CountRequest`]
/// supplies. The data plane's error fold reaches `http_error` through `decode`; the
/// model-discovery path (`run::models`) and the count path (`run::count`) route their
/// non-2xx round-trips through the SAME home and call the decoders directly (`json` is
/// private).
pub use ;
/// The wire request + the three delivery facts it carries (`wire.rs`): the HTTP
/// `Method`, the subprocess `ExecSpec`, and the `Envelope` its pipes carry.
pub use ;
/// The per-list-body projection keys the generic `decode_models` reads (model-discovery
/// §3): the top-level `array_key` array, and per entry the wire `id_key` (with the leading
/// `strip` removed) plus the OPTIONAL metadata key paths — `context_key` (input token
/// limit → `Model.context_window`), `max_output_key` (output limit → `max_output_tokens`),
/// `display_name_key` (→ `display_name`). Each metadata key is `""` when the dialect (or a
/// row override) does not serve that fact, so the `Model` field stays `None`, NEVER
/// fabricated (the Usage zero-vs-unknown principle, AGENTS.md). This struct is the SINGLE
/// home for the decode key set: it is the defaults embedded in [`ModelsShape`] AND the
/// resolved keys `models_req` hands `decode_models`, so it borrows either the `&'static`
/// protocol shape or a row's `'a` `[provider.models]` override (§3.2) — no second list.
/// A dialect's models-list shape as DATA (model-discovery §3.1): the GET `path` appended
/// to `base_url`, plus the default projection `keys`. `path` and the overridable members
/// of `keys` (`array_key`/`id_key` and the metadata keys) are the protocol DEFAULTS a
/// row's `[provider.models]` block may override (§3.2); `strip` is protocol-only. `&'static
/// str` throughout — every value is a compile-time constant.
/// Which canonical TUNING knobs a dialect PROJECTS onto its wire, as DATA (config
/// §6.1) — the [`ModelsShape`] pattern applied to request shaping. The fact lives
/// beside the `encode` that implements it, so the READ surface
/// (`bz --list-providers`) never re-derives it from a match on the protocol id, and a
/// consumer above brazen never keeps its own copy of one. There is deliberately NO
/// default impl: a new dialect must answer for itself, where a default would silently
/// claim (or deny) a capability its `encode` has not implemented. The claim is not
/// taken on trust — `src/tests/protocol_tuning.rs` proves each flag against the dialect's
/// OWN `encode`, key-agnostically: setting the knob changes the encoded request iff
/// the dialect projects it.
/// Derives are exactly what is used: `Debug`/`PartialEq` for the cross-check test.
/// It is not `Serialize` — the LISTING serializes its own `Row` booleans, and a second
/// serializable shape of one fact is the drift this crate refuses.
/// A dialect's token-count round-trip (architecture §5.10.1, bl-24e5): the POST
/// [`WireRequest`] targeting the count endpoint (URL + body built from the SAME
/// message/system/tool projection the dialect's `encode` uses) plus the response's
/// token-count JSON key (`input_tokens` Anthropic, `totalTokens` Google). Returned by
/// [`Protocol::count_tokens`]; the count runner stamps `content_type`/betas/auth (as
/// `serve` does), sends once, and reads `token_key` from the 2xx body via
/// [`count_from_body`]. Not the pure-data twin of [`ModelsShape`] — the count body is a
/// per-dialect projection of the request, not a static path — so the seam carries the
/// built request, not just keys.
/// The read-only, secret-free projection of the resolved row + flags handed to
/// `encode` (arch §4.1) — the ENTIRE interface between "which provider" and "how to
/// talk to it". No name, no `ProtocolId`/`AuthId`, no secret, and no `api_header`:
/// the auth header is auth's concern (it rides `AuthCtx`), and the vendor identity
/// was spent on the registry lookup before these run. The body-passthrough valve is
/// NOT here: config-level passthrough (top-level `extra` + a row's non-gen
/// `body_defaults`) is folded into `req.extra` by `fill_absent` and reaches the wire
/// through the one `req.extra` fold every encoder already runs (config §4.1, §9).
/// A wire dialect (arch §4.1): pure — no IO, no clock, no creds. `encode` projects
/// the canonical request onto the wire; `decode` is a pure `(frame, state)` state
/// machine yielding canonical events; `framing` declares the transport framing as
/// data. Object-safe: the pipeline holds `&dyn Protocol`.