prefix-safe-json 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/providers/anthropic.d.ts +1 -0
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +89 -8
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/gemini.d.ts +122 -0
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +442 -25
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/openai-compatible.d.ts +47 -1
- package/dist/providers/openai-compatible.d.ts.map +1 -1
- package/dist/providers/openai-compatible.js +381 -84
- package/dist/providers/openai-compatible.js.map +1 -1
- package/dist/providers/openai.d.ts +7 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +459 -67
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts.map +1 -1
- package/dist/providers/openrouter.js +14 -2
- package/dist/providers/openrouter.js.map +1 -1
- package/package.json +4 -1
package/dist/providers/gemini.js
CHANGED
|
@@ -1,11 +1,211 @@
|
|
|
1
|
-
import { PROJECTION_ONLY_ARGUMENTS_DIAGNOSTIC_CODE } from "../coordinator/diagnostic-codes.js";
|
|
1
|
+
import { PROJECTION_ONLY_ARGUMENTS_DIAGNOSTIC_CODE, TOOL_ARGUMENTS_AFTER_END_DIAGNOSTIC_CODE, DUPLICATE_TOOL_END_DIAGNOSTIC_CODE, INVALID_CHOICE_INDEX_DIAGNOSTIC_CODE, DUPLICATE_CHOICE_INDEX_DIAGNOSTIC_CODE, } from "../coordinator/diagnostic-codes.js";
|
|
2
|
+
// Reason priority for aggregating candidate-local terminal reasons into the
|
|
3
|
+
// ONE stream-wide reason, at adapter.finish() time. Same values/order/
|
|
4
|
+
// "worst wins" semantics as every other adapter's own REASON_PRIORITY in
|
|
5
|
+
// this codebase (see openai-compatible.ts's own doc comment for the full
|
|
6
|
+
// rationale) - duplicated locally rather than cross-imported, matching this
|
|
7
|
+
// project's established convention for self-contained provider files.
|
|
8
|
+
const REASON_PRIORITY = [
|
|
9
|
+
"provider_error",
|
|
10
|
+
"unknown",
|
|
11
|
+
"network_error",
|
|
12
|
+
"length",
|
|
13
|
+
"cancelled",
|
|
14
|
+
"complete",
|
|
15
|
+
];
|
|
16
|
+
// Phase B.7: re-checked against the installed @google/genai@2.21.0 SDK's
|
|
17
|
+
// own `FinishReason` enum, which is considerably larger than the four
|
|
18
|
+
// values previously handled: FINISH_REASON_UNSPECIFIED, STOP, MAX_TOKENS,
|
|
19
|
+
// SAFETY, RECITATION, LANGUAGE, OTHER, BLOCKLIST, PROHIBITED_CONTENT,
|
|
20
|
+
// SPII, MALFORMED_FUNCTION_CALL, IMAGE_SAFETY, UNEXPECTED_TOOL_CALL,
|
|
21
|
+
// TOO_MANY_TOOL_CALLS, IMAGE_PROHIBITED_CONTENT, NO_IMAGE,
|
|
22
|
+
// IMAGE_RECITATION, IMAGE_OTHER. Every value not explicitly recognized
|
|
23
|
+
// below - including every one of those newer/rarer values - intentionally
|
|
24
|
+
// falls through to "unknown", not "complete": unknown is non-executable
|
|
25
|
+
// (parser.ts's isExecutable() requires reason === "complete" exactly), so
|
|
26
|
+
// this is a safe, deliberate default, not a gap - see the regression
|
|
27
|
+
// coverage proving MALFORMED_FUNCTION_CALL/UNEXPECTED_TOOL_CALL/
|
|
28
|
+
// PROHIBITED_CONTENT/BLOCKLIST specifically cannot aggregate to "complete".
|
|
29
|
+
function mapFinishReason(finishReason) {
|
|
30
|
+
if (finishReason === "STOP")
|
|
31
|
+
return "complete";
|
|
32
|
+
if (finishReason === "MAX_TOKENS")
|
|
33
|
+
return "length";
|
|
34
|
+
if (finishReason === "SAFETY" || finishReason === "RECITATION" || finishReason === "OTHER")
|
|
35
|
+
return "cancelled";
|
|
36
|
+
return "unknown";
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Gemini `generateContentStream`-shaped streaming adapter.
|
|
40
|
+
*
|
|
41
|
+
* Terminal-ownership fix (Phase B hardening sweep, corrected in Phase B.1-
|
|
42
|
+
* B.7 after an identity-premise error was found in raw review):
|
|
43
|
+
* `candidate.finishReason` is candidate-LOCAL evidence only - a genuine
|
|
44
|
+
* multi-candidate (n>1) stream has one finishReason per candidate, each
|
|
45
|
+
* reporting only that candidate's own completion, never the whole provider
|
|
46
|
+
* stream's. Pre-fix, ANY candidate's finishReason directly emitted
|
|
47
|
+
* `provider_stream_end` and set this adapter's own global `finished` flag -
|
|
48
|
+
* the same "first choice to finish wrongly ends every choice" defect
|
|
49
|
+
* already found and fixed for OpenAI (Chat Completions plural and legacy
|
|
50
|
+
* singular) and Anthropic this session.
|
|
51
|
+
*
|
|
52
|
+
* Candidate IDENTITY correction (Phase B.1/B.2, the raw-review finding):
|
|
53
|
+
* this adapter used to key all candidate-local state by array POSITION
|
|
54
|
+
* within each chunk's own `candidates` list. The real wire field
|
|
55
|
+
* `candidate.index` ("Output only. The 0-based index of this candidate...
|
|
56
|
+
* useful for distinguishing between multiple candidates when
|
|
57
|
+
* candidate_count > 1" - confirmed against the installed
|
|
58
|
+
* `@google/genai@2.21.0` SDK's own types AND its real SSE parser, see
|
|
59
|
+
* test/integration/gemini-official-sdk-lifecycle.test.ts) is the
|
|
60
|
+
* authoritative identity instead. Array position silently breaks the
|
|
61
|
+
* moment a chunk omits an already-finished candidate (entirely normal - a
|
|
62
|
+
* provider has no reason to keep re-sending a candidate with nothing new
|
|
63
|
+
* to say) or reorders candidates within one chunk: real candidate 1's
|
|
64
|
+
* evidence arriving alone, at array position 0, was silently misattributed
|
|
65
|
+
* to candidate 0's own (already-terminal) identity - captured as genuine
|
|
66
|
+
* RED against real SDK-parsed chunks before this fix, not merely inferred.
|
|
67
|
+
*
|
|
68
|
+
* Fixed the same way as OpenAI's legacy path (P4.3) and Anthropic (P4.2):
|
|
69
|
+
* candidate.finishReason
|
|
70
|
+
* -> records that candidate's own terminal StreamEndReason
|
|
71
|
+
* -> does NOT emit provider_stream_end
|
|
72
|
+
* -> does NOT set this adapter's global `finished` flag
|
|
73
|
+
* finish(meta?)
|
|
74
|
+
* -> the ONE provider_stream_end for this adapter's whole lifetime,
|
|
75
|
+
* aggregating every recorded candidate-local reason (worst wins -
|
|
76
|
+
* see REASON_PRIORITY above) with meta.reason.
|
|
77
|
+
*
|
|
78
|
+
* Post-provider-terminal handling (Phase B.6): the top-of-push()
|
|
79
|
+
* `if (this.finished) return [];` guard, previously the only adapter in
|
|
80
|
+
* this codebase deliberately retaining the pre-P0 silent-drop pattern, is
|
|
81
|
+
* REMOVED here too - normalization continues after adapter.finish(), and
|
|
82
|
+
* coordinator.ts's own `isFinished` gate provides the canonical
|
|
83
|
+
* post-provider-terminal handling, exactly like every other adapter. This
|
|
84
|
+
* is future-proofing / architectural consistency, NOT the closing of a
|
|
85
|
+
* demonstrated execution-authority gap: independently re-verified, not
|
|
86
|
+
* merely trusted, that no Gemini call can ever reach `execute` -
|
|
87
|
+
* PROJECTION_ONLY_ARGUMENTS_DIAGNOSTIC_CODE is unconditional on every
|
|
88
|
+
* functionCall and checked by decide.ts before status is even considered;
|
|
89
|
+
* gate.ts's takeDecision() re-derives fresh and only ever returns
|
|
90
|
+
* something for action==="execute". See the two-part epistemic
|
|
91
|
+
* distinction in this program's own final report: CORRECTNESS/
|
|
92
|
+
* architecture-consistency, never claimed as an execution-integrity fix.
|
|
93
|
+
*
|
|
94
|
+
* Call IDENTITY correction (P4.5, a genuine RED confirmed against real
|
|
95
|
+
* @google/genai@2.21.0-parsed chunks, not merely inferred): within one
|
|
96
|
+
* candidate, this adapter used to key each functionCall's own sourceKey by
|
|
97
|
+
* PART ARRAY POSITION (`candidate:{i}/part:{j}`). Each Gemini functionCall
|
|
98
|
+
* is object-level final delivery, never incrementally streamed (no
|
|
99
|
+
* position needs to stay stable WITHIN one call's own lifetime) - but
|
|
100
|
+
* array position is NOT stable ACROSS separate, unrelated calls delivered
|
|
101
|
+
* in separate chunks: two genuinely independent functionCalls (confirmed
|
|
102
|
+
* via the real SDK parser to carry distinct `id`s, distinct names, and
|
|
103
|
+
* distinct args) that happen to land at the same part-array-position in
|
|
104
|
+
* their own respective chunks were silently treated as the SAME call - the
|
|
105
|
+
* second's evidence colliding with and corrupting the first's
|
|
106
|
+
* already-closed identity (coordinator.ts's own E_DUPLICATE_TOOL_CALL_START
|
|
107
|
+
* plus a parser E_TRAILING_DATA), with the second call never surfacing as
|
|
108
|
+
* its own decision at all. This is the same class of identity-loss defect
|
|
109
|
+
* already found and fixed for candidate identity itself (P4.4) and for
|
|
110
|
+
* every other provider's own call/item/block identity this session - now
|
|
111
|
+
* closed at the function-call level too.
|
|
112
|
+
*
|
|
113
|
+
* Fixed by preferring the official wire field `functionCall.id` ("Optional.
|
|
114
|
+
* The unique id of the function call...") as the call identity when a
|
|
115
|
+
* valid non-empty string is present:
|
|
116
|
+
* `candidate:{candidateIndex}/function-call-id:{id}`
|
|
117
|
+
* `id` is explicitly OPTIONAL per its own doc comment, and confirmed
|
|
118
|
+
* empirically (real SDK-parsed evidence) that the SDK passes through a
|
|
119
|
+
* functionCall with no `id` at all without complaint - never assumed
|
|
120
|
+
* present, never required, never a fail-closed precondition. When absent
|
|
121
|
+
* (or an empty string, treated identically to absent), this adapter falls
|
|
122
|
+
* back to a per-candidate, per-adapter-instance MONOTONIC OCCURRENCE
|
|
123
|
+
* COUNTER (`candidate:{candidateIndex}/function-call:{n}`) - deliberately
|
|
124
|
+
* NOT part array position: the counter is advanced by THIS adapter's own
|
|
125
|
+
* processing order, never by anything the provider could reorder or omit
|
|
126
|
+
* across chunks, so it remains genuinely unique for the adapter's whole
|
|
127
|
+
* lifetime regardless of where in a `parts[]` array a later, unrelated
|
|
128
|
+
* no-id call happens to land. This is real, forensically-traceable
|
|
129
|
+
* identity - never a claim of continuity between separate observations,
|
|
130
|
+
* and never a byte-level/positional reconstruction.
|
|
131
|
+
*
|
|
132
|
+
* A REPEATED identical `functionCall.id` under the same candidate (or a
|
|
133
|
+
* no-id counter value, which can never repeat by construction) is treated
|
|
134
|
+
* as late/duplicate evidence for the one already-delivered call that
|
|
135
|
+
* sourceKey names - exactly TOOL_ARGUMENTS_AFTER_END_DIAGNOSTIC_CODE's own
|
|
136
|
+
* existing meaning, reusing `candidateSourceKeys`'s own existing
|
|
137
|
+
* "every sourceKey ever started, never cleared" tracking rather than a new
|
|
138
|
+
* mechanism (see push()). Official Gemini semantics document no supported
|
|
139
|
+
* continuation/streaming mechanism for a single function call at all
|
|
140
|
+
* (`partialArgs`, `willContinue`, `FunctionCallingConfig.
|
|
141
|
+
* streamFunctionCallArguments` are all explicitly "not supported in Gemini
|
|
142
|
+
* API" per the installed SDK's own doc comments) - so a repeated id is
|
|
143
|
+
* never treated as a legitimate multi-chunk continuation of the same call,
|
|
144
|
+
* only as suspect duplicate evidence disqualifying the real call it names.
|
|
145
|
+
* A different `id` under a DIFFERENT candidate is never merged with this
|
|
146
|
+
* one: identity is candidate-scoped first, exactly as P4.4 already
|
|
147
|
+
* established - official semantics document `id` only as a response-
|
|
148
|
+
* correlation mechanism (implying uniqueness where populated) and never
|
|
149
|
+
* claim a cross-candidate-global uniqueness scope, so candidate-scoping
|
|
150
|
+
* remains the conservative, evidence-supported default.
|
|
151
|
+
*/
|
|
2
152
|
export class GeminiStreamAdapter {
|
|
3
153
|
provider = "gemini";
|
|
4
154
|
sequence = 0;
|
|
5
155
|
finished = false;
|
|
156
|
+
// candidateIndex (the real wire `candidate.index`, never array position)
|
|
157
|
+
// -> that candidate's own first-recorded terminal StreamEndReason. Never
|
|
158
|
+
// overwritten once set for a given candidate - a second/conflicting
|
|
159
|
+
// finishReason for the same candidate is reported as candidate-local
|
|
160
|
+
// post-terminal evidence (see push()), not silently applied over the
|
|
161
|
+
// first. Read by finish() to aggregate one stream-wide reason.
|
|
162
|
+
candidateTerminalReasons = new Map();
|
|
163
|
+
// The same candidates' own RAW (pre-normalization) finishReason strings,
|
|
164
|
+
// keyed identically - observability only, mirrored onto the aggregated
|
|
165
|
+
// provider_stream_end's own providerReason.
|
|
166
|
+
candidateTerminalProviderReasons = new Map();
|
|
167
|
+
// Phase B.5: every sourceKey EVER started under a real candidate index,
|
|
168
|
+
// never cleared. Read only when late/duplicate evidence arrives for an
|
|
169
|
+
// already-terminal candidate, so the disqualifying diagnostic can be
|
|
170
|
+
// attributed to every REAL, already-tracked call under that candidate
|
|
171
|
+
// (exact attribution) rather than a synthetic, never-resolvable
|
|
172
|
+
// "candidate:{i}" identity alone - mirrors
|
|
173
|
+
// OpenAICompatibleStreamAdapter's own allSourceKeysByChoice exactly, for
|
|
174
|
+
// the identical reason (a brand-new call is never created under an
|
|
175
|
+
// already-terminal candidate, so a diagnostic attached only to ITS OWN
|
|
176
|
+
// sourceKey could sit forever unresolved and disqualify nothing real).
|
|
177
|
+
candidateSourceKeys = new Map();
|
|
178
|
+
// P4.5: candidateIndex -> how many no-`functionCall.id` calls have been
|
|
179
|
+
// observed under that candidate so far, in THIS adapter's own processing
|
|
180
|
+
// order. Never reset, only ever incremented immediately before use - the
|
|
181
|
+
// fallback call identity when `functionCall.id` is absent/empty. Advanced
|
|
182
|
+
// by local processing order, never by provider-controlled array
|
|
183
|
+
// position, so it cannot collide across chunks the way raw part index
|
|
184
|
+
// could (see the class-level doc comment).
|
|
185
|
+
noIdFunctionCallCounters = new Map();
|
|
186
|
+
// P4.5: the real call identity for one functionCall observation under a
|
|
187
|
+
// known-valid candidateIndex. Prefers the official `functionCall.id`
|
|
188
|
+
// when it is a valid, non-empty string; otherwise advances and uses this
|
|
189
|
+
// candidate's own no-id occurrence counter. The two key shapes
|
|
190
|
+
// (`function-call-id:` vs `function-call:`) are deliberately distinct so
|
|
191
|
+
// an id-bearing call and a no-id call can never collide with each other
|
|
192
|
+
// even if a numeric id happened to look like a counter value.
|
|
193
|
+
callSourceKey(candidateIndex, fc) {
|
|
194
|
+
if (typeof fc.id === "string" && fc.id.length > 0) {
|
|
195
|
+
return `candidate:${candidateIndex}/function-call-id:${fc.id}`;
|
|
196
|
+
}
|
|
197
|
+
const next = (this.noIdFunctionCallCounters.get(candidateIndex) ?? 0) + 1;
|
|
198
|
+
this.noIdFunctionCallCounters.set(candidateIndex, next);
|
|
199
|
+
return `candidate:${candidateIndex}/function-call:${next - 1}`;
|
|
200
|
+
}
|
|
6
201
|
push(rawEvent) {
|
|
7
|
-
|
|
8
|
-
|
|
202
|
+
// No `finished` early return here (Phase B.6) - see the identical fix
|
|
203
|
+
// and rationale in every other adapter's push()
|
|
204
|
+
// (GHSA-3xpw-9694-2xxp-class invariant). Gemini has no live execution
|
|
205
|
+
// authority for this to protect today (see the class-level doc comment
|
|
206
|
+
// above), but the coordinator's own isFinished gate is still the
|
|
207
|
+
// canonical place post-provider-terminal handling belongs, not a
|
|
208
|
+
// second, adapter-local silent-drop mechanism.
|
|
9
209
|
const events = [];
|
|
10
210
|
if (!rawEvent || typeof rawEvent !== "object") {
|
|
11
211
|
events.push({
|
|
@@ -20,12 +220,170 @@ export class GeminiStreamAdapter {
|
|
|
20
220
|
}
|
|
21
221
|
const chunk = rawEvent;
|
|
22
222
|
if (Array.isArray(chunk.candidates)) {
|
|
23
|
-
|
|
223
|
+
// Duplicate-index detection within one chunk - mirrors
|
|
224
|
+
// OpenAICompatibleStreamAdapter's/OpenAIStreamAdapter's own
|
|
225
|
+
// choiceCounts pre-pass exactly (Phase B.3).
|
|
226
|
+
const candidateCounts = new Map();
|
|
227
|
+
for (const candidate of chunk.candidates) {
|
|
228
|
+
if (Number.isInteger(candidate.index) && candidate.index >= 0) {
|
|
229
|
+
candidateCounts.set(candidate.index, (candidateCounts.get(candidate.index) ?? 0) + 1);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
for (const candidate of chunk.candidates) {
|
|
233
|
+
// Choice-index validity (Phase B.3): a candidate with no
|
|
234
|
+
// trustworthy explicit index must never be silently assumed to be
|
|
235
|
+
// candidate 0 via array position - global, unattributable, fails
|
|
236
|
+
// the whole stream closed rather than guessing (same fail-closed
|
|
237
|
+
// posture INVALID_CHOICE_INDEX_DIAGNOSTIC_CODE already has for the
|
|
238
|
+
// OpenAI paths - reused rather than inventing a new code, since
|
|
239
|
+
// the identity ambiguity it represents is identical here). A
|
|
240
|
+
// finishReason-only candidate (no functionCall evidence at all)
|
|
241
|
+
// with an invalid index carries no tracked identity to protect
|
|
242
|
+
// and is simply skipped, not diagnosed - matches the identical,
|
|
243
|
+
// already-established design for OpenAI's legacy path.
|
|
244
|
+
const hasFunctionCall = !!(candidate.content && Array.isArray(candidate.content.parts) && candidate.content.parts.some((p) => p.functionCall));
|
|
245
|
+
if (!Number.isInteger(candidate.index) || candidate.index < 0) {
|
|
246
|
+
if (hasFunctionCall) {
|
|
247
|
+
events.push({
|
|
248
|
+
type: "provider_diagnostic",
|
|
249
|
+
sequence: ++this.sequence,
|
|
250
|
+
provider: this.provider,
|
|
251
|
+
code: INVALID_CHOICE_INDEX_DIAGNOSTIC_CODE,
|
|
252
|
+
severity: "error",
|
|
253
|
+
message: "Gemini candidate.index is missing, non-integer, or negative; candidate identity is ambiguous",
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
const candidateIndex = candidate.index;
|
|
259
|
+
if ((candidateCounts.get(candidateIndex) ?? 0) > 1) {
|
|
260
|
+
if (hasFunctionCall) {
|
|
261
|
+
// Phase B.5's own "exact attribution when real calls exist"
|
|
262
|
+
// principle applied consistently here too: a candidate-level
|
|
263
|
+
// synthetic "candidate:{i}" identity can never resolve to a
|
|
264
|
+
// real "candidate:{i}/part:{j}" sourceKey (this candidate may
|
|
265
|
+
// have multiple real parts, unlike OpenAI's legacy path,
|
|
266
|
+
// which has exactly one call per choice so the two happen to
|
|
267
|
+
// coincide there) - if this candidate already has real,
|
|
268
|
+
// already-tracked calls from earlier, legitimate evidence,
|
|
269
|
+
// attribute to every one of them so the violation actually
|
|
270
|
+
// disqualifies something real, not a permanently-unresolvable
|
|
271
|
+
// pending diagnostic.
|
|
272
|
+
const known = this.candidateSourceKeys.get(candidateIndex);
|
|
273
|
+
if (known && known.size > 0) {
|
|
274
|
+
for (const knownSourceKey of known) {
|
|
275
|
+
events.push({
|
|
276
|
+
type: "provider_diagnostic",
|
|
277
|
+
sequence: ++this.sequence,
|
|
278
|
+
provider: this.provider,
|
|
279
|
+
callRef: { sourceKey: knownSourceKey },
|
|
280
|
+
code: DUPLICATE_CHOICE_INDEX_DIAGNOSTIC_CODE,
|
|
281
|
+
severity: "error",
|
|
282
|
+
message: `candidate.index ${candidateIndex} is duplicated in one provider event; call ${knownSourceKey} is disqualified`,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
events.push({
|
|
288
|
+
type: "provider_diagnostic",
|
|
289
|
+
sequence: ++this.sequence,
|
|
290
|
+
provider: this.provider,
|
|
291
|
+
callRef: { sourceKey: `candidate:${candidateIndex}` },
|
|
292
|
+
code: DUPLICATE_CHOICE_INDEX_DIAGNOSTIC_CODE,
|
|
293
|
+
severity: "error",
|
|
294
|
+
message: `candidate.index ${candidateIndex} is duplicated in one provider event`,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
const candidateAlreadyTerminal = this.candidateTerminalReasons.has(candidateIndex);
|
|
24
301
|
if (candidate.content && Array.isArray(candidate.content.parts)) {
|
|
25
|
-
for (const
|
|
302
|
+
for (const part of candidate.content.parts) {
|
|
26
303
|
if (part.functionCall) {
|
|
27
304
|
const fc = part.functionCall;
|
|
28
|
-
|
|
305
|
+
// P4.5: real functionCall.id when present, never part array
|
|
306
|
+
// position - see the class-level doc comment and
|
|
307
|
+
// callSourceKey()'s own doc comment for the full rationale
|
|
308
|
+
// and evidence.
|
|
309
|
+
const sourceKey = this.callSourceKey(candidateIndex, fc);
|
|
310
|
+
if (candidateAlreadyTerminal) {
|
|
311
|
+
// Phase B.5: exact attribution. Each Gemini part is
|
|
312
|
+
// object-level final delivery (never incrementally
|
|
313
|
+
// streamed - see the class doc), so there is no
|
|
314
|
+
// in-progress call of this candidate's own to disqualify
|
|
315
|
+
// via THIS specific sourceKey - but if this candidate
|
|
316
|
+
// already has other REAL, tracked calls (earlier parts),
|
|
317
|
+
// late evidence disqualifies every one of them, not just
|
|
318
|
+
// a forensic record against its own never-resolvable
|
|
319
|
+
// identity - mirrors OpenAICompatibleStreamAdapter's own
|
|
320
|
+
// choiceAlreadyTerminal branch exactly.
|
|
321
|
+
const known = this.candidateSourceKeys.get(candidateIndex);
|
|
322
|
+
if (known && known.size > 0) {
|
|
323
|
+
for (const knownSourceKey of known) {
|
|
324
|
+
events.push({
|
|
325
|
+
type: "provider_diagnostic",
|
|
326
|
+
sequence: ++this.sequence,
|
|
327
|
+
provider: this.provider,
|
|
328
|
+
callRef: { sourceKey: knownSourceKey },
|
|
329
|
+
code: TOOL_ARGUMENTS_AFTER_END_DIAGNOSTIC_CODE,
|
|
330
|
+
severity: "error",
|
|
331
|
+
message: `Tool call evidence for candidate ${candidateIndex} arrived after that candidate's own finishReason; call ${knownSourceKey} is disqualified`,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
// No call was ever tracked for this candidate at all -
|
|
337
|
+
// nothing exists yet to disqualify, but the attempt
|
|
338
|
+
// itself is still worth a forensic record against its
|
|
339
|
+
// own (never-resolvable) sourceKey.
|
|
340
|
+
events.push({
|
|
341
|
+
type: "provider_diagnostic",
|
|
342
|
+
sequence: ++this.sequence,
|
|
343
|
+
provider: this.provider,
|
|
344
|
+
callRef: { sourceKey },
|
|
345
|
+
code: TOOL_ARGUMENTS_AFTER_END_DIAGNOSTIC_CODE,
|
|
346
|
+
severity: "error",
|
|
347
|
+
message: `Tool call evidence for candidate ${candidateIndex} arrived after that candidate's own finishReason`,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
// P4.5: this EXACT call (its own functionCall.id, or - for a
|
|
353
|
+
// no-id call - its own already-assigned counter value, which
|
|
354
|
+
// can never repeat by construction) was already delivered
|
|
355
|
+
// once before under this still-active candidate. Every real
|
|
356
|
+
// Gemini functionCall is object-level final delivery (see
|
|
357
|
+
// the class-level doc comment - no supported continuation
|
|
358
|
+
// mechanism exists), so a repeat of the SAME identity is
|
|
359
|
+
// late/duplicate evidence for that one already-closed call,
|
|
360
|
+
// never a legitimate multi-chunk continuation and never
|
|
361
|
+
// silently merged into it. Exact attribution: this reuses
|
|
362
|
+
// candidateSourceKeys's own existing "every sourceKey ever
|
|
363
|
+
// started, never cleared" tracking rather than a new
|
|
364
|
+
// mechanism - the disqualified call IS this sourceKey
|
|
365
|
+
// itself, so no "known vs forensic-only" split is needed
|
|
366
|
+
// here (unlike the candidate-already-terminal branch above,
|
|
367
|
+
// where the late evidence's own identity is never the thing
|
|
368
|
+
// being disqualified).
|
|
369
|
+
if (this.candidateSourceKeys.get(candidateIndex)?.has(sourceKey)) {
|
|
370
|
+
events.push({
|
|
371
|
+
type: "provider_diagnostic",
|
|
372
|
+
sequence: ++this.sequence,
|
|
373
|
+
provider: this.provider,
|
|
374
|
+
callRef: { sourceKey },
|
|
375
|
+
code: TOOL_ARGUMENTS_AFTER_END_DIAGNOSTIC_CODE,
|
|
376
|
+
severity: "error",
|
|
377
|
+
message: `Tool call evidence for candidate ${candidateIndex} repeats an already-delivered function call (${sourceKey}); call ${sourceKey} is disqualified`,
|
|
378
|
+
});
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
let known = this.candidateSourceKeys.get(candidateIndex);
|
|
382
|
+
if (!known) {
|
|
383
|
+
known = new Set();
|
|
384
|
+
this.candidateSourceKeys.set(candidateIndex, known);
|
|
385
|
+
}
|
|
386
|
+
known.add(sourceKey);
|
|
29
387
|
events.push({
|
|
30
388
|
type: "tool_call_start",
|
|
31
389
|
sequence: ++this.sequence,
|
|
@@ -44,7 +402,7 @@ export class GeminiStreamAdapter {
|
|
|
44
402
|
});
|
|
45
403
|
if (fc.args !== undefined) {
|
|
46
404
|
// Gemini currently emits structured objects.
|
|
47
|
-
// We serialize it to emulate a text delta, BUT it is documented in docs/providers/gemini.md
|
|
405
|
+
// We serialize it to emulate a text delta, BUT it is documented in docs/providers/gemini.md
|
|
48
406
|
// that this is NOT byte-level streaming. It is object-level final delivery.
|
|
49
407
|
try {
|
|
50
408
|
const projected = JSON.stringify(fc.args);
|
|
@@ -82,24 +440,52 @@ export class GeminiStreamAdapter {
|
|
|
82
440
|
}
|
|
83
441
|
}
|
|
84
442
|
if (candidate.finishReason) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
443
|
+
if (candidateAlreadyTerminal) {
|
|
444
|
+
// Duplicate/conflicting terminal for the SAME candidate
|
|
445
|
+
// (Phase B.5): never silently overwrite the first-recorded
|
|
446
|
+
// reason. Exact attribution, same as the late-functionCall
|
|
447
|
+
// case above: every REAL, already-tracked call under this
|
|
448
|
+
// candidate is disqualified, not merely a synthetic
|
|
449
|
+
// "candidate:{i}" identity that was never a real call.
|
|
450
|
+
const known = this.candidateSourceKeys.get(candidateIndex);
|
|
451
|
+
if (known && known.size > 0) {
|
|
452
|
+
for (const knownSourceKey of known) {
|
|
453
|
+
events.push({
|
|
454
|
+
type: "provider_diagnostic",
|
|
455
|
+
sequence: ++this.sequence,
|
|
456
|
+
provider: this.provider,
|
|
457
|
+
callRef: { sourceKey: knownSourceKey },
|
|
458
|
+
code: DUPLICATE_TOOL_END_DIAGNOSTIC_CODE,
|
|
459
|
+
severity: "error",
|
|
460
|
+
message: `candidate ${candidateIndex} received a second finishReason ("${candidate.finishReason}") after already terminating; call ${knownSourceKey} is disqualified`,
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
// No tool call ever existed under this candidate - the
|
|
466
|
+
// diagnostic is recorded for forensic visibility only and
|
|
467
|
+
// disqualifies nothing, because there is nothing to
|
|
468
|
+
// disqualify.
|
|
469
|
+
events.push({
|
|
470
|
+
type: "provider_diagnostic",
|
|
471
|
+
sequence: ++this.sequence,
|
|
472
|
+
provider: this.provider,
|
|
473
|
+
callRef: { sourceKey: `candidate:${candidateIndex}` },
|
|
474
|
+
code: DUPLICATE_TOOL_END_DIAGNOSTIC_CODE,
|
|
475
|
+
severity: "error",
|
|
476
|
+
message: `candidate ${candidateIndex} received a second finishReason ("${candidate.finishReason}") after already terminating`,
|
|
477
|
+
});
|
|
478
|
+
}
|
|
91
479
|
}
|
|
92
|
-
else
|
|
93
|
-
reason =
|
|
480
|
+
else {
|
|
481
|
+
const reason = mapFinishReason(candidate.finishReason);
|
|
482
|
+
this.candidateTerminalReasons.set(candidateIndex, reason);
|
|
483
|
+
this.candidateTerminalProviderReasons.set(candidateIndex, candidate.finishReason);
|
|
484
|
+
// No provider_stream_end here, and `this.finished` stays
|
|
485
|
+
// false: this candidate finishing is not, by itself, proof
|
|
486
|
+
// the whole provider stream (which may still have other
|
|
487
|
+
// candidates actively generating) has ended. See finish().
|
|
94
488
|
}
|
|
95
|
-
events.push({
|
|
96
|
-
type: "provider_stream_end",
|
|
97
|
-
sequence: ++this.sequence,
|
|
98
|
-
provider: this.provider,
|
|
99
|
-
reason,
|
|
100
|
-
providerReason: candidate.finishReason,
|
|
101
|
-
});
|
|
102
|
-
this.finished = true;
|
|
103
489
|
}
|
|
104
490
|
}
|
|
105
491
|
}
|
|
@@ -109,13 +495,44 @@ export class GeminiStreamAdapter {
|
|
|
109
495
|
if (this.finished)
|
|
110
496
|
return [];
|
|
111
497
|
this.finished = true;
|
|
498
|
+
const { reason, providerReason } = this.aggregateTermination(meta?.reason, meta?.providerReason);
|
|
112
499
|
return [{
|
|
113
500
|
type: "provider_stream_end",
|
|
114
501
|
sequence: ++this.sequence,
|
|
115
502
|
provider: this.provider,
|
|
116
|
-
reason
|
|
117
|
-
providerReason
|
|
503
|
+
reason,
|
|
504
|
+
providerReason,
|
|
118
505
|
}];
|
|
119
506
|
}
|
|
507
|
+
// One stream-wide StreamEndReason from every candidate-local reason
|
|
508
|
+
// recorded so far, plus any caller-supplied override - "complete" only
|
|
509
|
+
// if every single one of them was "complete". Mirrors every other
|
|
510
|
+
// adapter's own aggregateTermination()/aggregateLegacyTermination()
|
|
511
|
+
// exactly (see REASON_PRIORITY above for why it is duplicated locally
|
|
512
|
+
// rather than cross-imported).
|
|
513
|
+
aggregateTermination(callerReason, callerProviderReason) {
|
|
514
|
+
let worst;
|
|
515
|
+
let worstRank = Infinity;
|
|
516
|
+
let worstProviderReason;
|
|
517
|
+
for (const [candidateIndex, candidate] of this.candidateTerminalReasons.entries()) {
|
|
518
|
+
const rank = REASON_PRIORITY.indexOf(candidate);
|
|
519
|
+
if (rank !== -1 && rank < worstRank) {
|
|
520
|
+
worst = candidate;
|
|
521
|
+
worstRank = rank;
|
|
522
|
+
worstProviderReason = this.candidateTerminalProviderReasons.get(candidateIndex);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
if (callerReason !== undefined) {
|
|
526
|
+
const rank = REASON_PRIORITY.indexOf(callerReason);
|
|
527
|
+
if (rank !== -1 && rank < worstRank) {
|
|
528
|
+
worst = callerReason;
|
|
529
|
+
worstRank = rank;
|
|
530
|
+
worstProviderReason = callerProviderReason;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
if (worst === undefined)
|
|
534
|
+
return { reason: "unknown", providerReason: callerProviderReason };
|
|
535
|
+
return { reason: worst, providerReason: worstProviderReason };
|
|
536
|
+
}
|
|
120
537
|
}
|
|
121
538
|
//# sourceMappingURL=gemini.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/providers/gemini.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/providers/gemini.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,17 +18,63 @@ interface OpenAIChoice {
|
|
|
18
18
|
export interface OpenAICompatibleEvent {
|
|
19
19
|
choices?: OpenAIChoice[];
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Chat-Completions-shaped ("OpenAI-compatible") streaming adapter.
|
|
23
|
+
*
|
|
24
|
+
* Lifecycle contract (`@public (Experimental)` - see docs/COMPATIBILITY.md;
|
|
25
|
+
* this is a deliberate, disclosed lifecycle correction, not an accidental
|
|
26
|
+
* behavior change):
|
|
27
|
+
*
|
|
28
|
+
* choice.finish_reason
|
|
29
|
+
* -> closes ONLY the tool calls belonging to that exact choice index
|
|
30
|
+
* (tool_call_end per open call)
|
|
31
|
+
* -> records that choice's own terminal StreamEndReason
|
|
32
|
+
* -> does NOT emit provider_stream_end
|
|
33
|
+
* -> does NOT set this adapter's global `finished` state
|
|
34
|
+
*
|
|
35
|
+
* finish(meta?)
|
|
36
|
+
* -> the ONE provider_stream_end for this adapter's whole lifetime,
|
|
37
|
+
* closing any call whose own choice never reported a finish_reason
|
|
38
|
+
* at all, with a reason aggregated from every choice-local reason
|
|
39
|
+
* recorded so far plus `meta.reason` (see REASON_PRIORITY above) -
|
|
40
|
+
* call this once the caller has drained the raw provider iterator.
|
|
41
|
+
*
|
|
42
|
+
* Why: a single choice's finish_reason is call-local evidence only. For an
|
|
43
|
+
* ordinary single-choice (the overwhelmingly common, n=1) stream this was
|
|
44
|
+
* previously indistinguishable from the whole provider stream ending, so
|
|
45
|
+
* treating it as such was harmless. For a genuine multi-choice (n>1)
|
|
46
|
+
* stream it is not: this adapter has no visibility into the request's own
|
|
47
|
+
* `n`, and no wire-level signal available to `push()` proves no further,
|
|
48
|
+
* unseen choice can still appear - only the caller's own raw-iterator
|
|
49
|
+
* exhaustion (driving an explicit `finish()` call) can. Previously, the
|
|
50
|
+
* first choice to finish was wrongly treated as ending the entire stream:
|
|
51
|
+
* every OTHER choice's still-tracked calls were force-closed by a single,
|
|
52
|
+
* shared `knownSourceKeys` Set and the stream was declared over via a real
|
|
53
|
+
* `provider_stream_end` - which could make a call belonging to a
|
|
54
|
+
* completely different, still-generating choice genuinely, immediately
|
|
55
|
+
* executable (a real, empirically-confirmed `takeDecision()`-able
|
|
56
|
+
* authority window) purely because an unrelated choice finished first, and
|
|
57
|
+
* separately made a second finishing choice's own, entirely real
|
|
58
|
+
* termination look like corrupt/duplicate post-terminal evidence,
|
|
59
|
+
* poisoning every call in the stream via the coordinator's own
|
|
60
|
+
* EVENT_AFTER_STREAM_END/TERMINAL_REASON_CONFLICT protocol.
|
|
61
|
+
*/
|
|
21
62
|
export declare class OpenAICompatibleStreamAdapter implements ProviderStreamAdapter<unknown> {
|
|
22
63
|
readonly provider: ProviderName;
|
|
23
64
|
private sequence;
|
|
24
65
|
private startedSourceKeys;
|
|
25
|
-
private
|
|
66
|
+
private openSourceKeysByChoice;
|
|
67
|
+
private choiceTerminalReasons;
|
|
68
|
+
private choiceTerminalProviderReasons;
|
|
69
|
+
private allSourceKeysByChoice;
|
|
70
|
+
private choiceTerminalProtocolViolation;
|
|
26
71
|
private finished;
|
|
27
72
|
push(rawEvent: unknown): readonly NormalizedToolStreamEvent[];
|
|
28
73
|
finish(meta?: {
|
|
29
74
|
reason?: StreamEndReason;
|
|
30
75
|
providerReason?: string;
|
|
31
76
|
}): readonly NormalizedToolStreamEvent[];
|
|
77
|
+
private aggregateTermination;
|
|
32
78
|
}
|
|
33
79
|
export {};
|
|
34
80
|
//# sourceMappingURL=openai-compatible.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-compatible.d.ts","sourceRoot":"","sources":["../../src/providers/openai-compatible.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACtG,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"openai-compatible.d.ts","sourceRoot":"","sources":["../../src/providers/openai-compatible.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACtG,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAOrD,UAAU,iBAAiB;IACzB,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,QAAQ,CAAC,EAAE;YACT,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;KACH,CAAC,CAAC;CACJ;AAED,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAgCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAAa,6BAA8B,YAAW,qBAAqB,CAAC,OAAO,CAAC;IAClF,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAuB;IACtD,OAAO,CAAC,QAAQ,CAAK;IAGrB,OAAO,CAAC,iBAAiB,CAA0B;IAKnD,OAAO,CAAC,sBAAsB,CAAuC;IAOrE,OAAO,CAAC,qBAAqB,CAA2C;IAUxE,OAAO,CAAC,6BAA6B,CAAkC;IAWvE,OAAO,CAAC,qBAAqB,CAAuC;IAWpE,OAAO,CAAC,+BAA+B,CAAS;IAEhD,OAAO,CAAC,QAAQ,CAAS;IAEzB,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,yBAAyB,EAAE;IA8S7D,MAAM,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,eAAe,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,yBAAyB,EAAE;IAoD1G,OAAO,CAAC,oBAAoB;CA+C7B"}
|