@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.
- package/LICENSE +21 -0
- package/README.md +8 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/anthropic.d.ts +19 -0
- package/dist/anthropic.d.ts.map +1 -0
- package/dist/anthropic.js +621 -0
- package/dist/anthropic.js.map +1 -0
- package/dist/balance.d.ts +28 -0
- package/dist/balance.d.ts.map +1 -0
- package/dist/balance.js +105 -0
- package/dist/balance.js.map +1 -0
- package/dist/config.d.ts +328 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +623 -0
- package/dist/config.js.map +1 -0
- package/dist/dispatcher.d.ts +5 -0
- package/dist/dispatcher.d.ts.map +1 -0
- package/dist/dispatcher.js +21 -0
- package/dist/dispatcher.js.map +1 -0
- package/dist/effort-catalog.d.ts +17 -0
- package/dist/effort-catalog.d.ts.map +1 -0
- package/dist/effort-catalog.js +73 -0
- package/dist/effort-catalog.js.map +1 -0
- package/dist/error-body.d.ts +32 -0
- package/dist/error-body.d.ts.map +1 -0
- package/dist/error-body.js +74 -0
- package/dist/error-body.js.map +1 -0
- package/dist/header-validation.d.ts +57 -0
- package/dist/header-validation.d.ts.map +1 -0
- package/dist/header-validation.js +130 -0
- package/dist/header-validation.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -0
- package/dist/json-arguments.d.ts +17 -0
- package/dist/json-arguments.d.ts.map +1 -0
- package/dist/json-arguments.js +227 -0
- package/dist/json-arguments.js.map +1 -0
- package/dist/key-pool.d.ts +66 -0
- package/dist/key-pool.d.ts.map +1 -0
- package/dist/key-pool.js +207 -0
- package/dist/key-pool.js.map +1 -0
- package/dist/missing-reasoning-circuit.d.ts +17 -0
- package/dist/missing-reasoning-circuit.d.ts.map +1 -0
- package/dist/missing-reasoning-circuit.js +38 -0
- package/dist/missing-reasoning-circuit.js.map +1 -0
- package/dist/model-failure.d.ts +156 -0
- package/dist/model-failure.d.ts.map +1 -0
- package/dist/model-failure.js +253 -0
- package/dist/model-failure.js.map +1 -0
- package/dist/model-fallback.d.ts +18 -0
- package/dist/model-fallback.d.ts.map +1 -0
- package/dist/model-fallback.js +87 -0
- package/dist/model-fallback.js.map +1 -0
- package/dist/models.d.ts +20 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +55 -0
- package/dist/models.js.map +1 -0
- package/dist/openai-compatible.d.ts +87 -0
- package/dist/openai-compatible.d.ts.map +1 -0
- package/dist/openai-compatible.js +368 -0
- package/dist/openai-compatible.js.map +1 -0
- package/dist/openai-engine.d.ts +18 -0
- package/dist/openai-engine.d.ts.map +1 -0
- package/dist/openai-engine.js +515 -0
- package/dist/openai-engine.js.map +1 -0
- package/dist/openai-images.d.ts +38 -0
- package/dist/openai-images.d.ts.map +1 -0
- package/dist/openai-images.js +301 -0
- package/dist/openai-images.js.map +1 -0
- package/dist/openai-messages.d.ts +40 -0
- package/dist/openai-messages.d.ts.map +1 -0
- package/dist/openai-messages.js +135 -0
- package/dist/openai-messages.js.map +1 -0
- package/dist/openai-wire.d.ts +93 -0
- package/dist/openai-wire.d.ts.map +1 -0
- package/dist/openai-wire.js +151 -0
- package/dist/openai-wire.js.map +1 -0
- package/dist/persona/apply.d.ts +19 -0
- package/dist/persona/apply.d.ts.map +1 -0
- package/dist/persona/apply.js +98 -0
- package/dist/persona/apply.js.map +1 -0
- package/dist/persona/builtins.d.ts +3 -0
- package/dist/persona/builtins.d.ts.map +1 -0
- package/dist/persona/builtins.js +180 -0
- package/dist/persona/builtins.js.map +1 -0
- package/dist/persona/decorator.d.ts +4 -0
- package/dist/persona/decorator.d.ts.map +1 -0
- package/dist/persona/decorator.js +112 -0
- package/dist/persona/decorator.js.map +1 -0
- package/dist/persona/files.d.ts +20 -0
- package/dist/persona/files.d.ts.map +1 -0
- package/dist/persona/files.js +84 -0
- package/dist/persona/files.js.map +1 -0
- package/dist/persona/ids.d.ts +9 -0
- package/dist/persona/ids.d.ts.map +1 -0
- package/dist/persona/ids.js +11 -0
- package/dist/persona/ids.js.map +1 -0
- package/dist/persona/registry.d.ts +12 -0
- package/dist/persona/registry.d.ts.map +1 -0
- package/dist/persona/registry.js +54 -0
- package/dist/persona/registry.js.map +1 -0
- package/dist/persona/runtime.d.ts +23 -0
- package/dist/persona/runtime.d.ts.map +1 -0
- package/dist/persona/runtime.js +32 -0
- package/dist/persona/runtime.js.map +1 -0
- package/dist/persona/schema.d.ts +27 -0
- package/dist/persona/schema.d.ts.map +1 -0
- package/dist/persona/schema.js +165 -0
- package/dist/persona/schema.js.map +1 -0
- package/dist/persona/types.d.ts +38 -0
- package/dist/persona/types.d.ts.map +1 -0
- package/dist/persona/types.js +2 -0
- package/dist/persona/types.js.map +1 -0
- package/dist/pricing.d.ts +40 -0
- package/dist/pricing.d.ts.map +1 -0
- package/dist/pricing.js +70 -0
- package/dist/pricing.js.map +1 -0
- package/dist/quota-park.d.ts +53 -0
- package/dist/quota-park.d.ts.map +1 -0
- package/dist/quota-park.js +135 -0
- package/dist/quota-park.js.map +1 -0
- package/dist/rate-pause.d.ts +28 -0
- package/dist/rate-pause.d.ts.map +1 -0
- package/dist/rate-pause.js +72 -0
- package/dist/rate-pause.js.map +1 -0
- package/dist/registry.d.ts +142 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +471 -0
- package/dist/registry.js.map +1 -0
- package/dist/responses.d.ts +5 -0
- package/dist/responses.d.ts.map +1 -0
- package/dist/responses.js +290 -0
- package/dist/responses.js.map +1 -0
- package/dist/retry-after.d.ts +13 -0
- package/dist/retry-after.d.ts.map +1 -0
- package/dist/retry-after.js +64 -0
- package/dist/retry-after.js.map +1 -0
- package/dist/retry-ladder.d.ts +176 -0
- package/dist/retry-ladder.d.ts.map +1 -0
- package/dist/retry-ladder.js +664 -0
- package/dist/retry-ladder.js.map +1 -0
- package/dist/split-inband-thinking.d.ts +35 -0
- package/dist/split-inband-thinking.d.ts.map +1 -0
- package/dist/split-inband-thinking.js +117 -0
- package/dist/split-inband-thinking.js.map +1 -0
- package/dist/stream-idle.d.ts +97 -0
- package/dist/stream-idle.d.ts.map +1 -0
- package/dist/stream-idle.js +127 -0
- package/dist/stream-idle.js.map +1 -0
- package/dist/tool-call-ids.d.ts +16 -0
- package/dist/tool-call-ids.d.ts.map +1 -0
- package/dist/tool-call-ids.js +36 -0
- package/dist/tool-call-ids.js.map +1 -0
- 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"}
|