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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
//! Leaf JSON accessors shared by every protocol decode/encode (protocol-dedup
//! spec, D1). Pure over `&Value`/`&[u8]` with zero wire knowledge — the canonical
//! "JSON access" mechanics, the single home for what was copied per provider. The
//! synthesized-stream mechanics (`next_index`/`open_text`/`drain`) live in `synth`.
use Entry;
use ;
use crate;
use crate;
/// Project a models-list body onto the canonical ordered `Vec<Model>` (model-discovery
/// §3.1), the single home every `decode_models` shares. The dialects coincide on the
/// shape — a top-level `array_key` array of objects each carrying the wire id at
/// `id_key` — so they differ only as DATA ([`ModelKeys`]): the id/array keys, Google's
/// `strip` of a leading `models/`, and the OPTIONAL metadata key paths (each `""` when
/// unserved, so the field stays `None`, never fabricated — §3). ORDER-PRESERVING: the
/// `Vec` index IS the provider's suggested order (§4 reads it). A body that is not the
/// expected `{array_key:[…]}` shape is a `Provider{502}` error — the list-models GET
/// drained a 2xx, so an unparseable list is an upstream contract violation, never a
/// silent empty list (§3.1). `default` is `false`: no dialect flags one today (§3).
pub
/// An optional `u32` metadata field (model-discovery §3): the value at `key` when it is
/// a non-negative integer that fits `u32`, else `None` — absent, non-numeric, or out of
/// range, and a `""` key (an unserved fact) is always absent ⇒ `None`. Distinct from
/// `u32_at`, which fabricates `0`: a provider that does not report the limit leaves it
/// UNKNOWN, not zero (the Usage zero-vs-unknown principle, AGENTS.md).
/// An optional string metadata field (model-discovery §3): the string at `key`, else
/// `None` — absent, non-string, or a `""` key. Distinct from `text_of`, which fabricates
/// `""`: an unserved label stays `None`, never an empty string.
/// A malformed/unexpected models-list body → `Provider{502}` (model-discovery §3.1):
/// the list-models GET drained a 2xx, so a body we cannot project is the upstream
/// returning an invalid response (Bad Gateway), retryable like any 5xx — distinct
/// from `parse`'s mid-stream `Transport`, which has no governing status.
/// Read the token count from a 2xx count-endpoint body (architecture §5.10.1, bl-24e5):
/// the number at the response `key` a [`CountRequest`](crate::protocol::CountRequest)
/// supplies (`input_tokens` Anthropic, `totalTokens` Google). The `--count-tokens`
/// round-trip drained a 2xx, so a body that is not JSON or carries no numeric `key` is a
/// `Provider{502}` — an upstream contract violation, the count analog of a malformed
/// models list (§3.1) — never a silent zero (fabricating a count is the lie the op
/// exists to avoid).
pub
/// A malformed/unexpected count body → `Provider{502}` (bl-24e5): the count GET drained
/// a 2xx, so a body we cannot read is the upstream returning an invalid response — the
/// sibling of [`models_error`], retryable like any 5xx.
/// Parse a frame's bytes as JSON; a malformed body surfaces as a `Transport`
/// error, never a panic (the wire never crashes us).
pub
/// A string field, or `""` when absent/non-string (the wire never panics us).
pub
/// A non-empty string at `v`, else `None` — collapses null / absent / `""` so a
/// role-only chunk and a stray empty fragment open no block.
pub
/// A `u32` wire index field, or `0` when absent — the wire never panics us.
pub
/// A `Value` → its JSON-encoded **string** (for a tool-call `arguments` slot, or a
/// single `JsonDelta` fragment): re-serialization of a `serde_json::Value` is
/// infallible.
pub
/// The byte-identical encoder tail every `encode` shares (protocol-dedup spec, D1):
/// serialize the assembled `body` (our own owned `Map<String,Value>` serializes
/// infallibly — the lone `expect_used` for the whole encoder layer lives here, not
/// once per dialect) and wrap it in a `WireRequest` at the caller-built `url`. Neither
/// content-type NOR the row's `beta_headers` are stamped here: both are row/dialect
/// facts the wire needs on BOTH the encoded and the `--raw` paths, so their single
/// home is `serve` (`Protocol::content_type()` and `ctx.beta_headers`, stamped once
/// for both) — not once per `encode`, which `--raw` would skip (bl-3e2f). The only
/// per-dialect variation is how `url` is computed, so the caller builds it and hands
/// it in.
pub
/// The ONE whole-body non-2xx HTTP error projection, shared by every protocol's
/// decode (bl-5fe6). The HTTP status is the authoritative fact — `kind` derives
/// from it via the single `ErrorKind::from_http_status` table — and the **RAW
/// response body rides `provider_detail` VERBATIM** so a provider error is never
/// undiagnosable, whatever envelope shape it took. We deliberately do NOT assume a
/// uniform `{"error":…}` schema: OpenAI's codex backend returns `{"detail":…}`,
/// Ollama a bare `{"error":"…"}` string, a proxy plain HTML — the bytes that
/// actually arrived are what diagnose the failure, so they are what we carry.
///
/// A JSON body rides as the parsed `Value`; a non-JSON body (proxy HTML, plain
/// text) rides as a `Value::String` of its bytes; an empty body degrades to
/// `None`. `message` is a best-effort human summary pulled from a known field
/// (`error.message`, a bare `error` string, or `detail`), else the body itself —
/// never empty when a body exists, so text mode (which shows only `message`) is
/// diagnosable too. The body is a RESPONSE — it carries no request creds, so there
/// is no secret to redact here.
pub
/// Best-effort human message from a parsed error body: a nested `error.message`, a
/// bare `error` string (Ollama), or a `detail` string (OpenAI codex) — else the
/// whole body re-serialized, so the message is never empty when a body parsed.
/// Fold the request's `extra` passthrough into an assembled body — the ONE home for
/// "typed fields win" every `encode` shares (architecture §4.4, config §4.1). A key the
/// encoder did not write is inserted whole; a key it DID write is kept, EXCEPT that two
/// objects MERGE ONE LEVEL: the typed value wins per second-level KEY, and a passthrough
/// key the encoder never wrote survives beside it.
///
/// The merge is what makes the valve reach a **nesting** dialect. Ollama nests every
/// generation param under `options` and Google under `generationConfig`, so a shallow
/// insert dropped a whole `body_defaults = { options = { num_ctx = N } }` object the
/// moment any typed gen scalar was set — and an agent harness always sets `max_tokens`,
/// so the row's one valve for a nested dialect field was unreachable for exactly the
/// dialects that nest (bl-f19d).
///
/// **One level, not recursive**, and the boundary is a fact rather than a limit: a body
/// map is a NAMESPACE of fields, and every dialect nests its generation params exactly
/// one namespace deep (`options`, `generationConfig`, `thinking`, `reasoning`,
/// `output_config`). Below that sits a VALUE the encoder owns whole — a JSON Schema
/// under `output_config.format`, a tool's `parameters` — and merging two schemas
/// key-by-key yields a chimera that is neither. So the fold composes namespaces and
/// never blends values; deeper, the typed value wins entire, exactly as it did before.
pub