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
//! Shared streaming-virtual-fields module for e2e test codegen.
//!
//! Streaming fixtures assert on "virtual" fields that don't exist on the
//! stream result type itself. These fields require the `streaming` assertion
//! recipe unless the call explicitly maps the asserted root as a real result
//! field.
//!
//! [`StreamingFieldResolver`] provides two entry points:
//! - [`StreamingFieldResolver::accessor`] — the language-specific expression
//! for a virtual field given a local variable that holds the collected list.
//! - [`StreamingFieldResolver::collect_snippet`] — the language-specific
//! code snippet that drains a stream variable into the collected list.
//!
//! ## Convention
//!
//! The `chunks_var` parameter is the local variable name that holds the
//! collected list (default: `"chunks"`). The `stream_var` parameter is the
//! result variable produced by the stream call (default: `"result"`).
//!
//! The neutral streaming-virtual field names handled by this module:
//! - `stream.items` → the collected list itself
//! - `stream.items.length` → length/count of the collected list
//!
//! Legacy fixture fields still handled for explicitly streaming calls:
//! - `chunks` → the collected list itself
//! - `chunks.length` → length/count of the collected list
//! - `stream_content` → concatenation of all delta content strings
//! - `stream_complete` → boolean — last chunk has a non-null finish_reason
//! - `no_chunks_after_done` → structural invariant (true by construction for
//! channel/iterator-based APIs once the channel is closed; emitted as
//! `assert!(true)` / `assertTrue` for languages without post-DONE chunk plumbing)
//! - `tool_calls` → flat list of tool_calls from all chunk deltas
//! - `finish_reason` → finish_reason string from the last chunk
/// The set of field names treated as streaming-virtual fields.
pub const STREAMING_VIRTUAL_FIELDS: & = &;
/// The set of streaming-virtual root names that may have deep-path continuations.
///
/// A field like `tool_calls[0].function.name` starts with `tool_calls` and has
/// a continuation `[0].function.name`. These are handled by
/// [`StreamingFieldResolver::accessor`] via the deep-path logic.
///
/// `usage` is a stream-level root: `usage.total_tokens` resolves against the
/// last chunk that carried a usage payload (accessed via the collected chunks
/// list). Python accessor: `(chunks[-1].usage if chunks else None)`.
pub const STREAMING_VIRTUAL_ROOTS: & = &;
/// Returns `true` when `field` is a streaming-virtual field name, including
/// deep-nested paths that start with a known streaming-virtual root.
///
/// Examples that return `true`:
/// - `"tool_calls"` (exact root)
/// - `"tool_calls[0].function.name"` (deep path)
/// - `"tool_calls[0].id"` (deep path)
/// Split a field path into `(root, tail)` when it starts with a streaming-virtual
/// root and has a continuation.
///
/// Returns `None` when the field is an exact root match (no tail) or is not a
/// streaming-virtual root at all.
pub
/// Field names that unambiguously imply a streaming test (no overlap with
/// non-streaming response shapes). `usage`, `tool_calls`, and `finish_reason`
/// are intentionally excluded — they exist on non-streaming responses too
/// (`usage.total_tokens` on ChatCompletionResponse, `choices[0].finish_reason`,
/// etc.) and would otherwise drag non-streaming fixtures into streaming
/// codegen.
const STREAMING_ONLY_AUTO_DETECT_FIELDS: & = &;
/// Resolve whether a fixture should be treated as streaming, honoring the
/// call-level three-valued opt-in/out (`CallConfig::streaming`):
///
/// - `Some(true)` → forced streaming.
/// - `Some(false)` → forced non-streaming (skip the auto-detect even when an
/// assertion references a streaming-virtual-field name like `chunks`).
/// - `None` → auto-detect: streaming iff the fixture has a streaming mock
/// (`mock_response.stream_chunks`) or any assertion references one of the
/// unambiguous streaming-only field names.
///
/// All backends should use this helper so the opt-out is respected uniformly.
/// Shared streaming-virtual-fields resolver for e2e test codegen.
;