@wudao-org/providers 0.0.0-stage → 0.4.21

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.
Files changed (156) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +8 -2
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/anthropic.d.ts +19 -0
  5. package/dist/anthropic.d.ts.map +1 -0
  6. package/dist/anthropic.js +621 -0
  7. package/dist/anthropic.js.map +1 -0
  8. package/dist/balance.d.ts +28 -0
  9. package/dist/balance.d.ts.map +1 -0
  10. package/dist/balance.js +105 -0
  11. package/dist/balance.js.map +1 -0
  12. package/dist/config.d.ts +328 -0
  13. package/dist/config.d.ts.map +1 -0
  14. package/dist/config.js +623 -0
  15. package/dist/config.js.map +1 -0
  16. package/dist/dispatcher.d.ts +5 -0
  17. package/dist/dispatcher.d.ts.map +1 -0
  18. package/dist/dispatcher.js +21 -0
  19. package/dist/dispatcher.js.map +1 -0
  20. package/dist/effort-catalog.d.ts +17 -0
  21. package/dist/effort-catalog.d.ts.map +1 -0
  22. package/dist/effort-catalog.js +73 -0
  23. package/dist/effort-catalog.js.map +1 -0
  24. package/dist/error-body.d.ts +32 -0
  25. package/dist/error-body.d.ts.map +1 -0
  26. package/dist/error-body.js +74 -0
  27. package/dist/error-body.js.map +1 -0
  28. package/dist/header-validation.d.ts +57 -0
  29. package/dist/header-validation.d.ts.map +1 -0
  30. package/dist/header-validation.js +130 -0
  31. package/dist/header-validation.js.map +1 -0
  32. package/dist/index.d.ts +42 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +110 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/json-arguments.d.ts +17 -0
  37. package/dist/json-arguments.d.ts.map +1 -0
  38. package/dist/json-arguments.js +227 -0
  39. package/dist/json-arguments.js.map +1 -0
  40. package/dist/key-pool.d.ts +66 -0
  41. package/dist/key-pool.d.ts.map +1 -0
  42. package/dist/key-pool.js +207 -0
  43. package/dist/key-pool.js.map +1 -0
  44. package/dist/missing-reasoning-circuit.d.ts +17 -0
  45. package/dist/missing-reasoning-circuit.d.ts.map +1 -0
  46. package/dist/missing-reasoning-circuit.js +38 -0
  47. package/dist/missing-reasoning-circuit.js.map +1 -0
  48. package/dist/model-failure.d.ts +156 -0
  49. package/dist/model-failure.d.ts.map +1 -0
  50. package/dist/model-failure.js +253 -0
  51. package/dist/model-failure.js.map +1 -0
  52. package/dist/model-fallback.d.ts +18 -0
  53. package/dist/model-fallback.d.ts.map +1 -0
  54. package/dist/model-fallback.js +87 -0
  55. package/dist/model-fallback.js.map +1 -0
  56. package/dist/models.d.ts +20 -0
  57. package/dist/models.d.ts.map +1 -0
  58. package/dist/models.js +55 -0
  59. package/dist/models.js.map +1 -0
  60. package/dist/openai-compatible.d.ts +87 -0
  61. package/dist/openai-compatible.d.ts.map +1 -0
  62. package/dist/openai-compatible.js +368 -0
  63. package/dist/openai-compatible.js.map +1 -0
  64. package/dist/openai-engine.d.ts +18 -0
  65. package/dist/openai-engine.d.ts.map +1 -0
  66. package/dist/openai-engine.js +515 -0
  67. package/dist/openai-engine.js.map +1 -0
  68. package/dist/openai-images.d.ts +38 -0
  69. package/dist/openai-images.d.ts.map +1 -0
  70. package/dist/openai-images.js +301 -0
  71. package/dist/openai-images.js.map +1 -0
  72. package/dist/openai-messages.d.ts +40 -0
  73. package/dist/openai-messages.d.ts.map +1 -0
  74. package/dist/openai-messages.js +135 -0
  75. package/dist/openai-messages.js.map +1 -0
  76. package/dist/openai-wire.d.ts +93 -0
  77. package/dist/openai-wire.d.ts.map +1 -0
  78. package/dist/openai-wire.js +151 -0
  79. package/dist/openai-wire.js.map +1 -0
  80. package/dist/persona/apply.d.ts +19 -0
  81. package/dist/persona/apply.d.ts.map +1 -0
  82. package/dist/persona/apply.js +98 -0
  83. package/dist/persona/apply.js.map +1 -0
  84. package/dist/persona/builtins.d.ts +3 -0
  85. package/dist/persona/builtins.d.ts.map +1 -0
  86. package/dist/persona/builtins.js +180 -0
  87. package/dist/persona/builtins.js.map +1 -0
  88. package/dist/persona/decorator.d.ts +4 -0
  89. package/dist/persona/decorator.d.ts.map +1 -0
  90. package/dist/persona/decorator.js +112 -0
  91. package/dist/persona/decorator.js.map +1 -0
  92. package/dist/persona/files.d.ts +20 -0
  93. package/dist/persona/files.d.ts.map +1 -0
  94. package/dist/persona/files.js +84 -0
  95. package/dist/persona/files.js.map +1 -0
  96. package/dist/persona/ids.d.ts +9 -0
  97. package/dist/persona/ids.d.ts.map +1 -0
  98. package/dist/persona/ids.js +11 -0
  99. package/dist/persona/ids.js.map +1 -0
  100. package/dist/persona/registry.d.ts +12 -0
  101. package/dist/persona/registry.d.ts.map +1 -0
  102. package/dist/persona/registry.js +54 -0
  103. package/dist/persona/registry.js.map +1 -0
  104. package/dist/persona/runtime.d.ts +23 -0
  105. package/dist/persona/runtime.d.ts.map +1 -0
  106. package/dist/persona/runtime.js +32 -0
  107. package/dist/persona/runtime.js.map +1 -0
  108. package/dist/persona/schema.d.ts +27 -0
  109. package/dist/persona/schema.d.ts.map +1 -0
  110. package/dist/persona/schema.js +165 -0
  111. package/dist/persona/schema.js.map +1 -0
  112. package/dist/persona/types.d.ts +38 -0
  113. package/dist/persona/types.d.ts.map +1 -0
  114. package/dist/persona/types.js +2 -0
  115. package/dist/persona/types.js.map +1 -0
  116. package/dist/pricing.d.ts +40 -0
  117. package/dist/pricing.d.ts.map +1 -0
  118. package/dist/pricing.js +70 -0
  119. package/dist/pricing.js.map +1 -0
  120. package/dist/quota-park.d.ts +53 -0
  121. package/dist/quota-park.d.ts.map +1 -0
  122. package/dist/quota-park.js +135 -0
  123. package/dist/quota-park.js.map +1 -0
  124. package/dist/rate-pause.d.ts +28 -0
  125. package/dist/rate-pause.d.ts.map +1 -0
  126. package/dist/rate-pause.js +72 -0
  127. package/dist/rate-pause.js.map +1 -0
  128. package/dist/registry.d.ts +142 -0
  129. package/dist/registry.d.ts.map +1 -0
  130. package/dist/registry.js +471 -0
  131. package/dist/registry.js.map +1 -0
  132. package/dist/responses.d.ts +5 -0
  133. package/dist/responses.d.ts.map +1 -0
  134. package/dist/responses.js +290 -0
  135. package/dist/responses.js.map +1 -0
  136. package/dist/retry-after.d.ts +13 -0
  137. package/dist/retry-after.d.ts.map +1 -0
  138. package/dist/retry-after.js +64 -0
  139. package/dist/retry-after.js.map +1 -0
  140. package/dist/retry-ladder.d.ts +176 -0
  141. package/dist/retry-ladder.d.ts.map +1 -0
  142. package/dist/retry-ladder.js +664 -0
  143. package/dist/retry-ladder.js.map +1 -0
  144. package/dist/split-inband-thinking.d.ts +35 -0
  145. package/dist/split-inband-thinking.d.ts.map +1 -0
  146. package/dist/split-inband-thinking.js +117 -0
  147. package/dist/split-inband-thinking.js.map +1 -0
  148. package/dist/stream-idle.d.ts +97 -0
  149. package/dist/stream-idle.d.ts.map +1 -0
  150. package/dist/stream-idle.js +127 -0
  151. package/dist/stream-idle.js.map +1 -0
  152. package/dist/tool-call-ids.d.ts +16 -0
  153. package/dist/tool-call-ids.d.ts.map +1 -0
  154. package/dist/tool-call-ids.js +36 -0
  155. package/dist/tool-call-ids.js.map +1 -0
  156. package/package.json +32 -3
@@ -0,0 +1,515 @@
1
+ import { truncateSafe } from "@wudao-org/core";
2
+ import { mandatoryRepairReasoningBody, pickReasoning, reasoningFormatBody, reasoningResponseFields, resolveReasoningContext, } from "./config.js";
3
+ import { applyWirePersona, mergeBodyOverlay } from "./persona/apply.js";
4
+ import { gatewayExtraHeaders } from "./header-validation.js";
5
+ import { cooldownClassForStatus } from "./key-pool.js";
6
+ import { DEFAULT_RATE_PAUSE_MS } from "./rate-pause.js";
7
+ import { createStreamIdleGuard } from "./stream-idle.js";
8
+ import { InbandThinkSplitter, resolveSplitInbandThinking } from "./split-inband-thinking.js";
9
+ import { dedupeToolCallIds } from "./tool-call-ids.js";
10
+ import { parseRetryAfterMs } from "./retry-after.js";
11
+ import { readErrorBody } from "./error-body.js";
12
+ import { tryQuotaParkError } from "./quota-park.js";
13
+ import { ProviderHttpError, ReasoningMandatoryError, isMandatoryReasoningRejection } from "./model-failure.js";
14
+ import { MAX_ACCUM_CHARS, TRUNCATED_MARK, canonicalJson, capAccumulated } from "./openai-messages.js";
15
+ import { parseToolCallArguments } from "./json-arguments.js";
16
+ import { armMandatoryReasoningFlag, buildOpenAIRequestBody, effectiveReasoningEffort, enrichUsage, replayedReasoningTokens, toModelUsage, } from "./openai-wire.js";
17
+ import { StreamOverflowError, TruncatedStreamError, classifyContextLength, isContextLengthFailure, isMaxTokensOverflow400, parseMaxTokensOverflow, selfRepairMaxTokensValue, } from "./retry-ladder.js";
18
+ /** One non-streaming attempt — the body the retry ladder calls. */
19
+ async function generateOnce(config, input, doFetch, keyPool, ratePause, imageCtx, persona, mr) {
20
+ const wire = applyWirePersona(persona, "openai-chat", config.provider);
21
+ const body = await buildOpenAIRequestBody(config, input, imageCtx, mr);
22
+ const finalBody = wire?.bodyOverlay !== undefined ? mergeBodyOverlay(body, wire.bodyOverlay) : body;
23
+ const apiKey = keyPool.select();
24
+ const startedAt = Date.now();
25
+ const res = await doFetch(`${config.baseURL}/chat/completions`, {
26
+ method: "POST",
27
+ headers: {
28
+ "content-type": "application/json",
29
+ authorization: `Bearer ${apiKey}`,
30
+ // ω99-64: registry card headers (per-provider baseline) spread after
31
+ // adapter auth and before persona wire.headers — adapter auth >
32
+ // persona > registry. gatewayExtraHeaders skips the full
33
+ // FORBIDDEN_HEADER_KEYS set (14 keys — single source
34
+ // header-validation.ts, ω99-69) so auth stays structurally the key
35
+ // pool's (auth lands BEFORE these spreads; an unfiltered key would
36
+ // silently replace it).
37
+ ...gatewayExtraHeaders(config.extraHeaders),
38
+ ...(wire?.headers ?? {}),
39
+ },
40
+ body: JSON.stringify(finalBody),
41
+ signal: input.signal,
42
+ });
43
+ if (!res.ok) {
44
+ // 夜移 007: status-classed cooldowns — auth (401/403) cools LONG, rate
45
+ // (429) keeps 60s, provider-side statuses never touch the key.
46
+ const cooldownClass = cooldownClassForStatus(res.status);
47
+ if (cooldownClass !== null)
48
+ keyPool.markCooldown(apiKey, cooldownClass);
49
+ const detail = await safeText(res);
50
+ // M58 §A: classify the overflow BEFORE the generic HTTP error — the retry
51
+ // ladder must never retry it (an oversized prompt cannot succeed on
52
+ // retry); the loop reacts instead (compact once, retry once). ω-2b: the
53
+ // trusted-parse observation rides the typed error when the body has one.
54
+ if (isContextLengthFailure(res.status, detail))
55
+ throw classifyContextLength(res.status, detail, config, input);
56
+ // ω99-42: the mandatory-reasoning rejection classifies BEFORE the generic
57
+ // HTTP error (hermes matches it ahead of request-validation in
58
+ // _classify_400) — typed, attributed, and repairable only when the
59
+ // disable on the wire was not the user's explicit "none".
60
+ if (isMandatoryReasoningRejection(res.status, detail)) {
61
+ throw classifyMandatoryRejection("request", res.status, detail, config, input, mr);
62
+ }
63
+ // r1a Task 4: the response's Retry-After rides the typed error (headers
64
+ // only — the request bytes never see this). 波次 7 #37: the same deadline
65
+ // also pauses the PROVIDER for later request entries — but only when the
66
+ // pool has no spare to rotate to (multi-key rotation is the cheaper cure).
67
+ const retryAfterMs = parseRetryAfterMs(res.headers);
68
+ if (res.status === 429 && keyPool.snapshot().available === 0) {
69
+ ratePause.trip(retryAfterMs ?? DEFAULT_RATE_PAUSE_MS);
70
+ }
71
+ // 113-B3: an account-level quota 429 with a parseable reset moment
72
+ // classifies BEFORE the generic error — the typed QuotaParkError (the
73
+ // CLI parks the run until reset instead of dying on the >60s hard stop).
74
+ // All four gates live in isQuotaParkFailure; a miss keeps today's path.
75
+ const quotaPark = tryQuotaParkError("request", res.status, detail, retryAfterMs, { provider: config.provider, model: config.model });
76
+ if (quotaPark !== undefined)
77
+ throw quotaPark;
78
+ throw new ProviderHttpError("request", res.status, detail, retryAfterMs, { provider: config.provider, model: config.model }); // v7 γ4: 失败腿的 provider/model 身份(结构化字段+消息尾)
79
+ }
80
+ // 波次 7 #37: a 2xx proves any active pause stale — the next concurrent
81
+ // entry is immediate (a recovered transient blip never stalls the fleet).
82
+ ratePause.clear();
83
+ // ω99-42: a SERVED request that ran under the repair arms the per-client
84
+ // flag — every later request of this client is pre-armed (no 400 first).
85
+ if (mr.body !== undefined)
86
+ armMandatoryReasoningFlag(mr.flag);
87
+ const json = (await res.json());
88
+ const choice = json.choices?.[0];
89
+ const message = choice?.message;
90
+ if (!message) {
91
+ throw new Error("provider response missing choices[0].message");
92
+ }
93
+ if (json.usage) {
94
+ // M70 §2: stamp the answering model's identity on the usage row (the
95
+ // loop's usage-anchor guard (a) keys on it).
96
+ input.onUsage?.(enrichUsage({ ...toModelUsage(json.usage), model: config.model }, Date.now() - startedAt, replayedReasoningTokens(input.messages, config.reasoningReplay ?? "never")));
97
+ }
98
+ // ω-1a: name-as-id endpoints echo the function name as the id — parallel
99
+ // same-name calls in this message would collide downstream (loop pairing /
100
+ // JSONL / outbound history), so the parsed list is deduped here.
101
+ const toolCalls = message.tool_calls
102
+ ? dedupeToolCallIds(message.tool_calls.map((tc) => ({
103
+ id: tc.id,
104
+ name: tc.function.name,
105
+ arguments: parseToolCallArguments(capAccumulated(tc.function.arguments)),
106
+ })))
107
+ : undefined;
108
+ // M28: the reasoning field name comes from the format matrix
109
+ // (reasoning_content / reasoning / thinking) — a new endpoint selects a
110
+ // format, the response sniffing follows.
111
+ const fieldReasoning = pickReasoning(reasoningResponseFields(resolveReasoningContext(config).format), message) ?? "";
112
+ let reasoning = capAccumulated(fieldReasoning);
113
+ // 夜移 011: no reasoning FIELD but an in-band lane → peel the think block
114
+ // out of content in one shot (field wins when both exist — a provider
115
+ // reporting reasoning properly never needs the peel).
116
+ let content = capAccumulated(message.content ?? "");
117
+ if (fieldReasoning === "" && content !== "" && resolveSplitInbandThinking(config)) {
118
+ const splitter = new InbandThinkSplitter();
119
+ const a = splitter.push(content);
120
+ const b = splitter.finish();
121
+ reasoning = capAccumulated((a.reasoning ?? "") + (b.reasoning ?? ""));
122
+ content = capAccumulated((a.content ?? "") + (b.content ?? ""));
123
+ }
124
+ return {
125
+ role: "assistant",
126
+ content,
127
+ toolCalls: toolCalls && toolCalls.length > 0 ? toolCalls : undefined,
128
+ reasoning: reasoning || undefined,
129
+ // M70 §1: the finish reason rides the message — the loop's truncated
130
+ // tool-call guard keys on "length" (cut mid-arguments). Review F1: falsy
131
+ // (null/empty) finish_reason values are skipped, not stored — the field
132
+ // stays OMITTED, per the omit-never-null discipline.
133
+ ...(choice?.finish_reason ? { stopReason: choice.finish_reason } : {}),
134
+ };
135
+ }
136
+ /** ω99-44: the openai wire's terminal signal, chunk form — any choice
137
+ * carrying a truthy finish_reason. ([DONE] is the other signal, checked at
138
+ * the data-string level before the parse.) Some gateways end WITHOUT [DONE]
139
+ * but always stamp the final chunk with finish_reason — either proves the
140
+ * stream was not cut. Per-adapter on purpose: the anthropic/responses
141
+ * predicates live next to their own consumers — no shared one-size-fits-all
142
+ * (falsy nulls on intermediate chunks never count, mirroring the
143
+ * finishReason assignment below). */
144
+ function isOpenAiStreamTerminal(chunk) {
145
+ return chunk.choices?.some((c) => Boolean(c.finish_reason)) ?? false;
146
+ }
147
+ /** One streaming attempt — the generator the retry ladder calls. */
148
+ export async function* streamOnce(config, input, doFetch, keyPool, ratePause, streamIdle, imageCtx, persona, mr) {
149
+ const wire = applyWirePersona(persona, "openai-chat", config.provider);
150
+ // stream_options rides AFTER the pinned key sequence, so the streaming
151
+ // body's bytes are the non-streaming body's bytes plus two appended keys
152
+ // — the prompt token stream itself is unchanged (cache-safe).
153
+ const body = { ...(wire?.bodyOverlay !== undefined ? mergeBodyOverlay(await buildOpenAIRequestBody(config, input, imageCtx, mr), wire.bodyOverlay) : await buildOpenAIRequestBody(config, input, imageCtx, mr)), stream: true, stream_options: { include_usage: true } };
154
+ const apiKey = keyPool.select();
155
+ const startedAt = Date.now();
156
+ const res = await doFetch(`${config.baseURL}/chat/completions`, {
157
+ method: "POST",
158
+ headers: {
159
+ "content-type": "application/json",
160
+ authorization: `Bearer ${apiKey}`,
161
+ // ω99-64: registry card headers (per-provider baseline) spread after
162
+ // adapter auth and before persona wire.headers — adapter auth >
163
+ // persona > registry. gatewayExtraHeaders skips the full
164
+ // FORBIDDEN_HEADER_KEYS set (14 keys — single source
165
+ // header-validation.ts, ω99-69) so auth stays structurally the key
166
+ // pool's (auth lands BEFORE these spreads; an unfiltered key would
167
+ // silently replace it).
168
+ ...gatewayExtraHeaders(config.extraHeaders),
169
+ ...(wire?.headers ?? {}),
170
+ },
171
+ body: JSON.stringify(body),
172
+ signal: input.signal,
173
+ });
174
+ if (!res.ok) {
175
+ // 夜移 007: status-classed cooldowns — auth (401/403) cools LONG, rate
176
+ // (429) keeps 60s, provider-side statuses never touch the key.
177
+ const cooldownClass = cooldownClassForStatus(res.status);
178
+ if (cooldownClass !== null)
179
+ keyPool.markCooldown(apiKey, cooldownClass);
180
+ const detail = await safeText(res);
181
+ // M58 §A: same classification on the streaming path (see generateOnce).
182
+ // ω-2b: same trusted-parse observation stamping.
183
+ if (isContextLengthFailure(res.status, detail))
184
+ throw classifyContextLength(res.status, detail, config, input);
185
+ // ω99-42: same mandatory-reasoning classification on the streaming path
186
+ // (see generateOnce) — the repair replays before the first delta.
187
+ if (isMandatoryReasoningRejection(res.status, detail)) {
188
+ throw classifyMandatoryRejection("stream", res.status, detail, config, input, mr);
189
+ }
190
+ // r1a Task 4 + 波次 7 #37: same Retry-After + provider-pause wiring as
191
+ // generateOnce (see there).
192
+ const retryAfterMs = parseRetryAfterMs(res.headers);
193
+ if (res.status === 429 && keyPool.snapshot().available === 0) {
194
+ ratePause.trip(retryAfterMs ?? DEFAULT_RATE_PAUSE_MS);
195
+ }
196
+ // 113-B3: same quota classification on the streaming path (see
197
+ // generateOnce) — the wake probe typically rides this path.
198
+ const quotaPark = tryQuotaParkError("stream", res.status, detail, retryAfterMs, { provider: config.provider, model: config.model });
199
+ if (quotaPark !== undefined)
200
+ throw quotaPark;
201
+ throw new ProviderHttpError("stream", res.status, detail, retryAfterMs, { provider: config.provider, model: config.model }); // v7 γ4: 失败腿的 provider/model 身份(结构化字段+消息尾)
202
+ }
203
+ // 波次 7 #37: a 2xx proves any active pause stale (see generateOnce).
204
+ ratePause.clear();
205
+ // ω99-42: headers-OK on a repaired request = the route served the enabled
206
+ // shape — arm the per-client pre-arm flag (see generateOnce).
207
+ if (mr.body !== undefined)
208
+ armMandatoryReasoningFlag(mr.flag);
209
+ const reader = res.body.getReader();
210
+ const decoder = new TextDecoder();
211
+ let buf = "";
212
+ let content = "";
213
+ let reasoning = "";
214
+ let usage;
215
+ // M70 §1: the stream's finish_reason (it rides the final content chunk,
216
+ // before the optional usage-only chunk) — surfaced on the done message so
217
+ // the loop's truncated tool-call guard can key on "length".
218
+ let finishReason;
219
+ // OOM fix: once an accumulator passes the cap it is frozen — later deltas
220
+ // for THAT channel are dropped (downstream consumers accumulate from the
221
+ // yielded deltas, so capping only the final message would not bound them)
222
+ // and the final message carries the truncation marker.
223
+ let contentCapped = false;
224
+ let reasoningCapped = false;
225
+ const cappedArgs = new Set();
226
+ const toolCalls = new Map();
227
+ // M28: reasoning deltas sniff the format's field order — no per-endpoint
228
+ // SSE parser edits for new reasoning field spellings.
229
+ const reasoningFields = reasoningResponseFields(resolveReasoningContext(config).format);
230
+ // ω99-44: terminal tracking — did this stream ever speak finish/stop
231
+ // semantics? ([DONE] marker, or any chunk carrying finish_reason — some
232
+ // gateways end WITHOUT [DONE] but always stamp the final chunk.) EOF with
233
+ // sawTerminal=false is a cut, not a completion (see TruncatedStreamError).
234
+ let sawTerminal = false;
235
+ // ω99-44: attribution — wire bytes that arrived before the EOF.
236
+ let sawBytes = 0;
237
+ // 夜移 011: the in-band <think> peel (vLLM chat-template lanes inline CoT
238
+ // into content). Null on every format that reports reasoning properly.
239
+ const inbandSplitter = resolveSplitInbandThinking(config) ? new InbandThinkSplitter() : undefined;
240
+ // M58 §B / ω99-315 — the dual-tier stream idle watchdog (stream-idle.ts).
241
+ // Armed only while a read is PENDING (active streaming): every resolved read
242
+ // re-arms the timers, a SOFT lapse fires onSoftWarning once (never cancels,
243
+ // never a model request — long reasoning silences are legal), a HARD lapse
244
+ // cancels the body — tearing down the HTTP download, the fetch's own abort —
245
+ // and raises the enriched typed StreamIdleError, which walks the existing
246
+ // retry ladder (the retried request re-serializes the same input →
247
+ // byte-identical body, so the prefix cache is untouched). The user's abort
248
+ // signal stays untouched: a USER abort surfaces as AbortError (never
249
+ // retried); only idle-timeout aborts retry.
250
+ const idleGuard = createStreamIdleGuard(streamIdle, {
251
+ ...(streamIdle.onSoftWarning !== undefined ? { onSoftWarning: streamIdle.onSoftWarning } : {}),
252
+ cancel: () => void reader.cancel().catch(() => { }),
253
+ });
254
+ // 124b 项 1(codex instant_interrupt):显式 abort 面(同 anthropic 的
255
+ // sseDataLines)——本地 cancel 立刻解阻塞挂起读,标志位把 cancel 的
256
+ // done:true 形态翻译回 AbortError(否则会走 TruncatedStreamError 被
257
+ // 梯子当可重试运输类重放一个刚被用户中断的请求)。signal 已触发时
258
+ // reclassifyTransportAbort 同族逻辑原样放行 AbortError(永不重试)。
259
+ let signalAborted = input.signal?.aborted === true;
260
+ const onAbort = () => {
261
+ signalAborted = true;
262
+ void reader.cancel().catch(() => { });
263
+ };
264
+ if (input.signal !== undefined && !input.signal.aborted)
265
+ input.signal.addEventListener("abort", onAbort, { once: true });
266
+ try {
267
+ // eslint-disable-next-line no-constant-condition
268
+ while (true) {
269
+ idleGuard.arm();
270
+ const { done, value } = await idleGuard.race(reader.read());
271
+ if (signalAborted) {
272
+ throw Object.assign(new Error("This operation was aborted"), { name: "AbortError" });
273
+ }
274
+ if (done) {
275
+ // ω99-44 (pi 64eeb82a4): EOF is a frame terminator — flush the decoder
276
+ // (multi-byte tails), then terminate a non-blank residual so the final
277
+ // `data:` line WITHOUT its trailing newline is still parsed (it was
278
+ // previously dropped on the floor). 残尾判界: the residual must still
279
+ // parse as a complete JSON line — a half-JSON tail falls to the
280
+ // JSON.parse discard below; an EOF that never saw terminal semantics
281
+ // throws after the loop regardless.
282
+ buf += decoder.decode();
283
+ buf = buf.trim() !== "" ? buf + "\n" : "";
284
+ }
285
+ else {
286
+ buf += decoder.decode(value, { stream: true });
287
+ sawBytes += value.byteLength;
288
+ // ω99-315: payload arrived — the silent gap is over; both tiers reset.
289
+ idleGuard.chunk(value.byteLength);
290
+ }
291
+ const lines = buf.split("\n");
292
+ buf = lines.pop() ?? "";
293
+ for (const line of lines) {
294
+ const trimmed = line.trim();
295
+ if (!trimmed.startsWith("data:"))
296
+ continue;
297
+ const data = trimmed.slice(5).trim();
298
+ if (data === "")
299
+ continue;
300
+ // ω99-44: [DONE] is one of the two openai terminal signals (the other
301
+ // is a finish_reason-bearing chunk, checked post-parse below).
302
+ if (data === "[DONE]") {
303
+ sawTerminal = true;
304
+ continue;
305
+ }
306
+ let chunk;
307
+ try {
308
+ chunk = JSON.parse(data);
309
+ }
310
+ catch {
311
+ continue;
312
+ }
313
+ // ω99-44: the chunk-form terminal signal (see isOpenAiStreamTerminal).
314
+ if (isOpenAiStreamTerminal(chunk))
315
+ sawTerminal = true;
316
+ // The usage-only trailing chunk (stream_options.include_usage) has an
317
+ // empty choices array — parse it BEFORE the delta guard skips it.
318
+ if (chunk.usage) {
319
+ usage = toModelUsage(chunk.usage);
320
+ }
321
+ const choice = chunk.choices?.[0];
322
+ // M70 review F1: OpenAI SSE chunks carry "finish_reason":null on every
323
+ // intermediate chunk — skip falsy values so a null never lands on the
324
+ // done message (omit-never-null, M56) and a trailing null after a real
325
+ // "length" can never disarm the truncated-tool-call guard.
326
+ if (choice?.finish_reason)
327
+ finishReason = choice.finish_reason;
328
+ const delta = choice?.delta;
329
+ if (!delta)
330
+ continue;
331
+ const reasoningDelta = pickReasoning(reasoningFields, delta);
332
+ if (reasoningDelta) {
333
+ if (!reasoningCapped) {
334
+ reasoning += reasoningDelta;
335
+ if (reasoning.length > MAX_ACCUM_CHARS) {
336
+ reasoning = truncateSafe(reasoning, MAX_ACCUM_CHARS); // 113-A4:累积帽代理对安全
337
+ reasoningCapped = true;
338
+ }
339
+ yield { type: "reasoning_delta", text: reasoningDelta };
340
+ }
341
+ }
342
+ if (delta.content) {
343
+ if (!contentCapped) {
344
+ // 夜移 011: content deltas pass through the in-band peel when the
345
+ // lane is on — a think block's bytes reclassify as reasoning
346
+ // (their own accumulator + events); everything after the block
347
+ // flows on as content. Lane off (every well-behaved format) →
348
+ // byte-identical to the historical path.
349
+ if (inbandSplitter !== undefined) {
350
+ const out = inbandSplitter.push(delta.content);
351
+ if (out.reasoning !== undefined && !reasoningCapped) {
352
+ reasoning += out.reasoning;
353
+ if (reasoning.length > MAX_ACCUM_CHARS) {
354
+ reasoning = truncateSafe(reasoning, MAX_ACCUM_CHARS); // 113-A4:累积帽代理对安全
355
+ reasoningCapped = true;
356
+ }
357
+ yield { type: "reasoning_delta", text: out.reasoning };
358
+ }
359
+ if (out.content !== undefined) {
360
+ content += out.content;
361
+ if (content.length > MAX_ACCUM_CHARS) {
362
+ content = truncateSafe(content, MAX_ACCUM_CHARS); // 113-A4
363
+ contentCapped = true;
364
+ }
365
+ yield { type: "text_delta", text: out.content };
366
+ }
367
+ }
368
+ else {
369
+ content += delta.content;
370
+ if (content.length > MAX_ACCUM_CHARS) {
371
+ content = truncateSafe(content, MAX_ACCUM_CHARS); // 113-A4
372
+ contentCapped = true;
373
+ }
374
+ yield { type: "text_delta", text: delta.content };
375
+ }
376
+ }
377
+ }
378
+ if (delta.tool_calls) {
379
+ for (const tc of delta.tool_calls) {
380
+ const idx = tc.index ?? 0;
381
+ const acc = toolCalls.get(idx) ?? { id: "", name: "", args: "" };
382
+ if (tc.id)
383
+ acc.id = tc.id;
384
+ if (tc.function?.name)
385
+ acc.name = tc.function.name;
386
+ if (tc.function?.arguments && !cappedArgs.has(idx)) {
387
+ acc.args += tc.function.arguments;
388
+ if (acc.args.length > MAX_ACCUM_CHARS) {
389
+ acc.args = truncateSafe(acc.args, MAX_ACCUM_CHARS); // 113-A4
390
+ cappedArgs.add(idx);
391
+ }
392
+ }
393
+ toolCalls.set(idx, acc);
394
+ }
395
+ }
396
+ }
397
+ // ω99-44: the done-flush above drained the residual through the normal
398
+ // line loop — exit only AFTER processing (previously `if (done) break`
399
+ // sat before the decode, so the unterminated final line never got here).
400
+ if (done)
401
+ break;
402
+ // r1b: cap the residual (unterminated) line — an active stream that
403
+ // never emits a "\n" would grow `buf` without bound, a hole the idle
404
+ // watchdog cannot catch (every read resolves on time). Checked AFTER
405
+ // this read's complete lines are consumed, so an abort that follows
406
+ // delivered deltas is never replayed (first-delta rule). Fail LOUD,
407
+ // never truncate: a sliced SSE line would fabricate garbage events.
408
+ if (buf.length > MAX_ACCUM_CHARS) {
409
+ void reader.cancel().catch(() => { });
410
+ throw new StreamOverflowError(MAX_ACCUM_CHARS);
411
+ }
412
+ }
413
+ }
414
+ finally {
415
+ if (input.signal !== undefined)
416
+ input.signal.removeEventListener("abort", onAbort);
417
+ idleGuard.dispose();
418
+ }
419
+ // ω99-44 (pi ebc374490): EOF without terminal semantics = the stream was
420
+ // cut (proxy EOF, connection drop). Fail LOUD with the typed error — never
421
+ // a synthetic done, never fabricated usage: finish_reason loss blinds the
422
+ // M70 stop-reason guard, usage loss kills the metering row. The ladder
423
+ // classifies it as retryable transport (the pre-first-delta replay is
424
+ // byte-identical, prefix-cache safe; a post-delta cut propagates).
425
+ if (!sawTerminal)
426
+ throw new TruncatedStreamError("openai-compatible", sawBytes);
427
+ // ω-1a: same dedupe as the non-streaming path, applied once the delta
428
+ // fragments have aggregated into complete calls (ids may ride only the
429
+ // first fragment per index — the aggregate is what must be unique).
430
+ const calls = dedupeToolCallIds([...toolCalls.entries()]
431
+ .sort((a, b) => a[0] - b[0])
432
+ .map(([idx, v]) => ({
433
+ id: v.id,
434
+ name: v.name,
435
+ arguments: parseToolCallArguments(cappedArgs.has(idx) ? v.args + TRUNCATED_MARK : v.args),
436
+ })));
437
+ // 夜移 011: stream-end flush — an unterminated think block's held tail
438
+ // (including a dangling close-tag prefix) lands as reasoning; a seeking-held
439
+ // partial open tag lands as content. The accumulators below pick both up.
440
+ if (inbandSplitter !== undefined) {
441
+ const tail = inbandSplitter.finish();
442
+ if (tail.reasoning !== undefined && !reasoningCapped)
443
+ reasoning += tail.reasoning;
444
+ if (tail.content !== undefined && !contentCapped)
445
+ content += tail.content;
446
+ }
447
+ if (usage !== undefined) {
448
+ // M70 §2: stamp the answering model's identity on the usage row (see
449
+ // generateOnce).
450
+ input.onUsage?.(enrichUsage({ ...usage, model: config.model }, Date.now() - startedAt, replayedReasoningTokens(input.messages, config.reasoningReplay ?? "never")));
451
+ }
452
+ yield {
453
+ type: "done",
454
+ message: {
455
+ role: "assistant",
456
+ content: contentCapped ? content + TRUNCATED_MARK : content,
457
+ toolCalls: calls.length > 0 ? calls : undefined,
458
+ reasoning: reasoning ? (reasoningCapped ? reasoning + TRUNCATED_MARK : reasoning) : undefined,
459
+ ...(finishReason !== undefined ? { stopReason: finishReason } : {}),
460
+ },
461
+ };
462
+ }
463
+ /** ω99-42: classify one matched mandatory-reasoning rejection. The repair
464
+ * verdict (hermes 63279301bc, wudao's two-row table):
465
+ * repairable — the effective "none"/disabled on the wire was NOT the
466
+ * user's explicit pin (default-sourced effort — no field sent; a
467
+ * thinkingLevelMap fold; or `softReasoningNone`, the code-defaulted
468
+ * none of cheap side-calls), no repair ran yet in this call, the format
469
+ * CAN express enablement, and the repair body actually differs from
470
+ * what was sent. Arms `mr` so the ladder's next attempt re-sends with
471
+ * reasoning enabled (messages bytes untouched — prefix cache safe).
472
+ * terminal — otherwise: the typed error surfaces with guidance and never
473
+ * retries, never falls back, never compresses. */
474
+ function classifyMandatoryRejection(which, status, detail, config, input, mr) {
475
+ const ctx = resolveReasoningContext(config);
476
+ const effort = effectiveReasoningEffort(input, config);
477
+ const sent = mr.body ?? (effort !== undefined ? reasoningFormatBody(ctx, effort) : {});
478
+ const repairBody = mandatoryRepairReasoningBody(ctx);
479
+ const repairable =
480
+ // The explicit user "none" is a pin, never silently rewritten.
481
+ (effort !== "none" || config.softReasoningNone === true)
482
+ // Exactly one repair per call (a second rejection means the enable
483
+ // shape itself failed — more retries are a dead ladder).
484
+ && mr.body === undefined
485
+ // The wire format must be able to say "reasoning on".
486
+ && Object.keys(repairBody).length > 0
487
+ // Already-enabled bytes: a repair would resend the identical request.
488
+ && canonicalJson(repairBody) !== canonicalJson(sent);
489
+ if (repairable)
490
+ mr.body = repairBody;
491
+ return new ReasoningMandatoryError(which, status, detail, config.provider ?? config.baseURL, effort, repairable);
492
+ }
493
+ /** One attempt + at most one max_tokens self-repair retry (non-streaming).
494
+ * The retryContext records the applied override (single-shot by its
495
+ * presence). Pure plumbing: the attempt receives the (possibly capped)
496
+ * config. */
497
+ export async function generateOnceWithSelfRepair(config, input, doFetch, keyPool, ratePause, imageCtx, retryContext, persona, mr) {
498
+ try {
499
+ return await generateOnce(config, input, doFetch, keyPool, ratePause, imageCtx, persona, mr);
500
+ }
501
+ catch (err) {
502
+ // M70 §4: parseable max_tokens overflow → retry once with the reduced cap.
503
+ if (!isMaxTokensOverflow400(err) || retryContext.maxTokensOverride !== undefined)
504
+ throw err;
505
+ retryContext.maxTokensOverride = selfRepairMaxTokensValue(parseMaxTokensOverflow(err.body));
506
+ return generateOnce({ ...config, maxTokens: retryContext.maxTokensOverride }, input, doFetch, keyPool, ratePause, imageCtx, persona, mr);
507
+ }
508
+ }
509
+ async function safeText(res) {
510
+ // 波次 8 #42 (hermes #24): bounded error-body read — byte cap + wall clock
511
+ // + cancel-on-abandon, so a stalled or huge error body can neither hang the
512
+ // request nor buffer unbounded. Never throws (the old catch contract).
513
+ return readErrorBody(res);
514
+ }
515
+ //# sourceMappingURL=openai-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-engine.js","sourceRoot":"","sources":["../src/openai-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { type ImageAttachmentRef, type ModelInput } from "@wudao-org/core";
2
+ import type { ProviderConfig } from "./config.js";
3
+ import { type InputModality } from "./models.js";
4
+ /** M79 §2: what the engine needs from an attachment store at the HTTP
5
+ * boundary. Structural (the core AttachmentStore satisfies it). */
6
+ export interface AttachmentResolver {
7
+ resolveDataUrl(ref: ImageAttachmentRef): Promise<string>;
8
+ }
9
+ /** Per-provider image request context (resolved once from options). */
10
+ export interface ImageRequestContext {
11
+ readonly budgetBytes: number;
12
+ readonly resolver?: AttachmentResolver;
13
+ }
14
+ /** Prefix of the synthetic user message that carries tool-result images. */
15
+ export declare const TOOL_IMAGE_NOTE = "Attached image(s) from tool result:";
16
+ /** β1 — the pure newest→oldest dedup walk over one window's content hashes
17
+ * (input in HISTORY order, oldest→newest). Returns per-frame verdicts:
18
+ * true = renders as image_url, false = the fixed note. A frame is omitted
19
+ * only when its hash equals its immediate NEWER neighbor's AND the
20
+ * omission streak stays under `omitCap`. Exported so the policy itself is
21
+ * unit-testable at any window width (the seam below only feeds it hashes
22
+ * — at K=3 the re-anchor branch needs a 4-wide window to show, which only
23
+ * the direct test can see). */
24
+ export declare function sameImageKeepVerdicts(hashes: readonly string[], omitCap: number): boolean[];
25
+ /** Does any message in the input carry image blocks? (Cheap pre-filter —
26
+ * the no-image path below is the byte-identical pre-M79 construction.) */
27
+ export declare function inputHasImages(input: ModelInput): boolean;
28
+ /** The pure pre-I/O capability/role gate. Throws the typed
29
+ * UnsupportedContentError — never retries (see isRetryableProviderError) —
30
+ * for (a) images addressed at a model without the `image` modality, and
31
+ * (b) ImageBlocks in assistant history (only user turns and tool results
32
+ * may carry images). Exported so the CLI can pre-check a submit. */
33
+ export declare function assertImagesSupported(input: ModelInput, modalities: readonly InputModality[]): void;
34
+ /** The image-bearing message walk (system + per-message shaping + the
35
+ * synthetic tool-image user message). Only called when inputHasImages —
36
+ * the text-only path is toOpenAIRequest's, byte-identical. */
37
+ export declare function imageWireMessages(config: ProviderConfig, input: ModelInput, imageCtx: ImageRequestContext): Promise<unknown[]>;
38
+ //# sourceMappingURL=openai-images.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-images.d.ts","sourceRoot":"","sources":["../src/openai-images.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,kBAAkB,EAEvB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAIzE;oEACoE;AACpE,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1D;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CACxC;AAsBD,4EAA4E;AAC5E,eAAO,MAAM,eAAe,wCAAwC,CAAC;AAuErE;;;;;;;gCAOgC;AAChC,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CAc3F;AAMD;2EAC2E;AAC3E,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAKzD;AAED;;;;qEAIqE;AACrE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAmBnG;AAYD;;+DAE+D;AAC/D,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,mBAAmB,GAC5B,OAAO,CAAC,OAAO,EAAE,CAAC,CA+IpB"}