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
//! 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 ;
use crate;
use crateWireRequest;
/// 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: the two keys, and Google's `strip` of a
/// leading `models/` so the id is usable in encode's path. 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
/// 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.
/// 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.