@wudao-org/providers 0.0.0-stage → 0.4.20

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 +17 -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 @@
1
+ {"version":3,"file":"key-pool.js","sourceRoot":"","sources":["../src/key-pool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface MissingReasoningCircuit {
2
+ /** Whether the one frozen replay may still be attempted for a
3
+ * missing-reasoning finish (the circuit is closed). */
4
+ allowsRetry(): boolean;
5
+ /** The frozen replay of a missing-reasoning finish ALSO came back missing —
6
+ * open the circuit: remediation is proven useless for this window. */
7
+ noteFailedReplay(): void;
8
+ /** A missing-reasoning finish settled as-is because the circuit was open —
9
+ * another observed regression resets the re-arm streak (an intermittent
10
+ * regression must not re-arm on a sparse streak). */
11
+ noteSuppressedMissing(): void;
12
+ /** A healthy tool-call turn under the replay contract settled — three
13
+ * consecutive re-arm the circuit. */
14
+ noteHealthyToolTurn(): void;
15
+ }
16
+ export declare function createMissingReasoningCircuit(): MissingReasoningCircuit;
17
+ //# sourceMappingURL=missing-reasoning-circuit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"missing-reasoning-circuit.d.ts","sourceRoot":"","sources":["../src/missing-reasoning-circuit.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,uBAAuB;IACtC;4DACwD;IACxD,WAAW,IAAI,OAAO,CAAC;IACvB;2EACuE;IACvE,gBAAgB,IAAI,IAAI,CAAC;IACzB;;0DAEsD;IACtD,qBAAqB,IAAI,IAAI,CAAC;IAC9B;0CACsC;IACtC,mBAAmB,IAAI,IAAI,CAAC;CAC7B;AAED,wBAAgB,6BAA6B,IAAI,uBAAuB,CAqBvE"}
@@ -0,0 +1,38 @@
1
+ // 夜移 023 (Reasonix reasoning_warn_state.go): a missing tool-call reasoning
2
+ // finish is a compatibility INCIDENT, not a permanent provider characteristic.
3
+ // One frozen replay per incident window; a replay that ALSO comes back
4
+ // reasoning-less opens the circuit (the replay tax stops while the regression
5
+ // lasts); three consecutive healthy tool turns re-arm it. Divergence from the
6
+ // source (recorded in the ledger): only a PROVEN-useless replay opens the
7
+ // circuit — a retry that recovers keeps full protection, because wudao has no
8
+ // history-projection machinery to fall back on when reasoning is lost.
9
+ // Session-scoped: one circuit per provider leg; the cross-process persisted
10
+ // variant (fingerprint + cooldown + file lock) is milestone-level, not here.
11
+ /** Reasonix missingReasoningHealthyResolveStreak — three consecutive healthy
12
+ * tool turns close an open incident, so a future isolated regression gets one
13
+ * fresh silent retry without flapping. */
14
+ const RE_ARM_HEALTHY_TURNS = 3;
15
+ export function createMissingReasoningCircuit() {
16
+ let retriesExhausted = false;
17
+ let healthyStreak = 0;
18
+ return {
19
+ allowsRetry: () => !retriesExhausted,
20
+ noteFailedReplay() {
21
+ retriesExhausted = true;
22
+ healthyStreak = 0;
23
+ },
24
+ noteSuppressedMissing() {
25
+ healthyStreak = 0;
26
+ },
27
+ noteHealthyToolTurn() {
28
+ if (!retriesExhausted)
29
+ return;
30
+ healthyStreak += 1;
31
+ if (healthyStreak >= RE_ARM_HEALTHY_TURNS) {
32
+ retriesExhausted = false;
33
+ healthyStreak = 0;
34
+ }
35
+ },
36
+ };
37
+ }
38
+ //# sourceMappingURL=missing-reasoning-circuit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"missing-reasoning-circuit.js","sourceRoot":"","sources":["../src/missing-reasoning-circuit.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,+EAA+E;AAC/E,uEAAuE;AACvE,8EAA8E;AAC9E,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAC9E,uEAAuE;AACvE,4EAA4E;AAC5E,6EAA6E;AAE7E;;2CAE2C;AAC3C,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAkB/B,MAAM,UAAU,6BAA6B;IAC3C,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAC7B,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,OAAO;QACL,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,gBAAgB;QACpC,gBAAgB;YACd,gBAAgB,GAAG,IAAI,CAAC;YACxB,aAAa,GAAG,CAAC,CAAC;QACpB,CAAC;QACD,qBAAqB;YACnB,aAAa,GAAG,CAAC,CAAC;QACpB,CAAC;QACD,mBAAmB;YACjB,IAAI,CAAC,gBAAgB;gBAAE,OAAO;YAC9B,aAAa,IAAI,CAAC,CAAC;YACnB,IAAI,aAAa,IAAI,oBAAoB,EAAE,CAAC;gBAC1C,gBAAgB,GAAG,KAAK,CAAC;gBACzB,aAAa,GAAG,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,156 @@
1
+ import { CONFIG_CAP_ALSO_CONFLICTS_FIELD } from "@wudao-org/core";
2
+ import type { ReasoningEffort } from "./config.js";
3
+ /** The z.ai / zhipu / bigmodel overload vocabulary. The JSON-coded 1301 is
4
+ * anchored on the `code` key so ordinary numeric fields (token counts) can
5
+ * never trip it. */
6
+ export declare const OVERLOAD_BODY_SIGNATURES: readonly RegExp[];
7
+ /** True when a 429 body carries a known overload signature. */
8
+ export declare function sniffOverloadBody(body: string): boolean;
9
+ /** The typed context-overflow failure (M58 §A). Stamped with the duck-type
10
+ * `name` the core port recognizes (core's isContextLengthError) — core stays
11
+ * provider-agnostic and never imports this class. ω-2b (I1-a): carries the
12
+ * trusted-parse observation when the body yielded one (parseContextLimitBody)
13
+ * — the loop's calibration + clip ladder read it. */
14
+ export declare class ContextLengthError extends Error {
15
+ readonly status: number;
16
+ readonly body: string;
17
+ readonly observed?: {
18
+ promptTokens: number;
19
+ windowTokens: number;
20
+ };
21
+ constructor(status: number, body: string, observed?: {
22
+ promptTokens: number;
23
+ windowTokens: number;
24
+ });
25
+ }
26
+ /** The typed immediate-bail failure for a background query on overload. The
27
+ * original error rides `cause` (and its message) for diagnostics. */
28
+ export declare class BackgroundOverloadError extends Error {
29
+ readonly source: string;
30
+ constructor(source: string, original: unknown);
31
+ }
32
+ /** The typed provider HTTP failure. The message keeps the pinned
33
+ * `provider request|stream failed: <status> <body>` format, so every
34
+ * message-regex consumer (retryReason, tests, the CLI) keeps working.
35
+ * r1a Task 4: carries the server's Retry-After deadline (ms) when the
36
+ * response headers had one — OMITTED otherwise (omit-never-null), so the
37
+ * serialized shape of every pre-existing error is byte-identical.
38
+ * v7 γ4 (pi 0c7bb7c5c 思想,digest-a C3 搭车件): carries the failing leg's
39
+ * provider/model identity as STRUCTURED fields — wudao is multi-provider
40
+ * (悟道/DeepSeek/GLM/Qwen) on one OpenAI-compatible face, and a generic
41
+ * "provider request failed: 500 …" made every vendor one fingerprint family.
42
+ * The provider id also appends to the MESSAGE (suffix — the anchored
43
+ * prefix regexes `^provider (?:request|stream) failed: (\d{3})` in
44
+ * retryReason/isRetryableProviderError keep matching; the fingerprint's
45
+ * normalizeFailureCause masks numbers but provider ids are digit-free, so
46
+ * the attribution SURVIVES normalization — γ2's end-cause ledger groups by
47
+ * it). Omitted when the config carries no registry identity (a raw
48
+ * baseURL leg has nothing honest to attribute): byte-identical shape,
49
+ * identical message. */
50
+ export declare class ProviderHttpError extends Error {
51
+ readonly status: number;
52
+ readonly body: string;
53
+ /** True iff status is 429 AND the body sniffs as overload. */
54
+ readonly overload: boolean;
55
+ /** r1a Task 4: the parsed retry-after / retry-after-ms wait, ms. The ladder
56
+ * waits EXACTLY this value (no jitter, no exponential) instead of its
57
+ * backoff; beyond RETRY_AFTER_FAIL_CAP_MS the ladder refuses to retry.
58
+ * `declare` (useDefineForClassFields): without a deadline the key is
59
+ * entirely ABSENT from the instance — the serialized shape of every
60
+ * pre-existing error stays byte-identical. */
61
+ readonly retryAfterMs?: number;
62
+ /** v7 γ4: the config's registry provider id (e.g. "deepseek"/"wudao") —
63
+ * ABSENT on identity-less constructions (omit-never-null). */
64
+ readonly provider?: string;
65
+ /** v7 γ4: the failing leg's model id (the fallback chain swaps it — the
66
+ * identity names the LEG, not the config default). ABSENT likewise. */
67
+ readonly model?: string;
68
+ constructor(which: "request" | "stream", status: number, body: string, retryAfterMs?: number, identity?: {
69
+ readonly provider?: string;
70
+ readonly model?: string;
71
+ });
72
+ }
73
+ /** wire-r2 follow-up ① — the typed request-construction conflict thrown by
74
+ * the anthropic adapter when an EXPLICIT maxTokens (input.maxTokens or
75
+ * config.maxTokens — either is a cap someone chose) sits at/below the
76
+ * thinking budget implied by reasoningEffort: the wire structurally
77
+ * requires max_tokens > thinking.budget_tokens, and silently raising a
78
+ * chosen cap (the pre-narrowing budget+1024 bump) was the fail-closed
79
+ * tension the wire-r2 review flagged. Only the adapter's own implicit
80
+ * default cap keeps the historic raise. Deterministic config conflict:
81
+ * thrown BEFORE the retry ladder (validatedInputEffort's spot — never
82
+ * sleeps, never hits the wire) and never model-fallback-eligible below
83
+ * (a sibling model re-hits the identical conflict). */
84
+ export declare class MaxTokensThinkingBudgetConflictError extends Error {
85
+ /** F1 (clip-conflict): the stable cross-package stamp. Core's loop duck-
86
+ * types this string to route COMPUTED-cap conflicts (the ω-2b admission
87
+ * clip / the ladder's clip-retry physical — context-budget arithmetic, not
88
+ * a chosen cap) into the reactive compact ladder instead of hard-failing;
89
+ * core never imports this class. The literal's single source is the core
90
+ * port constant (imported here so a core rename changes the stamp and the
91
+ * providers pin goes loud, never silently unfixed). A caller-chosen
92
+ * config.maxTokens conflict keeps the fail-closed propagation on both
93
+ * sides of the seam. */
94
+ readonly code = "MAXTOKENS_THINKING_BUDGET_CONFLICT";
95
+ readonly maxTokens: number;
96
+ readonly budgetTokens: number;
97
+ /** conflict-origin: TRUE when the caller-chosen PERSISTENT cap
98
+ * (config.maxTokens) ALSO sits at/below the thinking budget — compaction
99
+ * can never produce a servable request then (the post-compact resend's
100
+ * cap resolves back to the config cap and re-conflicts before the wire),
101
+ * so core skips the reactive compact ladder and keeps this typed
102
+ * fail-closed propagation. The FIELD NAME's single source is the core
103
+ * port constant (the computed name below); `declare` keeps the key
104
+ * ENTIRELY ABSENT when false (omit-never-null — the serialized shape of
105
+ * every pre-existing error stays byte-identical), and core's
106
+ * hasConfigCapConflict duck-types it without importing this class. */
107
+ readonly [CONFIG_CAP_ALSO_CONFLICTS_FIELD]?: true;
108
+ constructor(maxTokens: number, budgetTokens: number, configCapAlsoConflicts?: boolean);
109
+ }
110
+ /** Key-class failures (401/403) never fall back — those are the M56 key
111
+ * pool's domain (model故障 ≠ 凭据故障). */
112
+ export declare function isKeyClassFailure(err: unknown): boolean;
113
+ /** The mandatory-reasoning body vocabulary. The first pattern is the live
114
+ * recording from hermes f6bd1633f7 (Nous Portal / OpenRouter z-ai/glm-5.3,
115
+ * Sep 2026); the siblings are the same sentence family. Conservative on
116
+ * purpose — the caller may override per provider (the `signatures` param of
117
+ * {@link isMandatoryReasoningRejection}). */
118
+ export declare const MANDATORY_REASONING_BODY_SIGNATURES: readonly RegExp[];
119
+ /** True iff the status/body pair is a mandatory-reasoning rejection: HTTP 400
120
+ * (the class hermes matches in _classify_400; a 5xx/429 carrying the same
121
+ * text keeps its existing transport path) plus a body signature. `signatures`
122
+ * overrides the default vocabulary (per-provider calibration seam). */
123
+ export declare function isMandatoryReasoningRejection(status: number, body: string, signatures?: readonly RegExp[]): boolean;
124
+ /** The typed mandatory-reasoning rejection. Two flavors, one class:
125
+ * repairable — the disable on the wire was NOT a user pin (default-sourced
126
+ * effort, a thinkingLevelMap fold, or a code-defaulted soft none): the
127
+ * retry ladder re-sends ONCE with reasoning enabled (messages bytes
128
+ * untouched — the reasoning fields are request-level sampling params, so
129
+ * the prefix cache key is preserved by construction; the wudao reading of
130
+ * hermes 63279301bc's "same cache key").
131
+ * terminal — the disable WAS the user's explicit "none" (never silently
132
+ * rewritten), the repair already ran and failed, or the wire format
133
+ * cannot express enablement: the error surfaces with actionable guidance.
134
+ * Never walks the generic transport ladder as a 400, never compresses,
135
+ * never falls back to a sibling model (the rejection is route semantics,
136
+ * not model health). */
137
+ export declare class ReasoningMandatoryError extends Error {
138
+ readonly status: number;
139
+ readonly body: string;
140
+ /** Attribution: the config's provider id (fallback baseURL) + the effort
141
+ * the rejected request actually carried. */
142
+ readonly provider: string;
143
+ readonly effortSent?: ReasoningEffort;
144
+ readonly repairable: boolean;
145
+ constructor(which: "request" | "stream", status: number, body: string, provider: string, effortSent: ReasoningEffort | undefined, repairable: boolean);
146
+ }
147
+ /** True when an error may trigger the model-fallback chain: model-class
148
+ * HTTP failures and transport errors — never aborts (user intent), never
149
+ * context overflow (a prompt that does not fit the primary will not fit a
150
+ * sibling either; the loop's reactive compaction owns that), never
151
+ * key-class failures. M79: an UnsupportedContentError is eligible ONLY in
152
+ * its model-capability form — falling back to a sibling that declares the
153
+ * image modality is the recovery; the structural forms (role violation,
154
+ * missing attachment store) can never succeed on another model. */
155
+ export declare function isModelFallbackEligible(err: unknown): boolean;
156
+ //# sourceMappingURL=model-failure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-failure.d.ts","sourceRoot":"","sources":["../src/model-failure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,253 @@
1
+ // packages/providers/src/model-failure.ts — r1b A1:模型故障判定与它们依赖的
2
+ // 类型化错误,从 openai-compatible.ts 原样抽出。
3
+ //
4
+ // 为什么独立成模块:r1a Task 3 把 withModelFallback 抽到 model-fallback.ts 后,
5
+ // model-fallback → openai-compatible(isModelFallbackEligible)→ model-fallback
6
+ // (withModelFallback)成了环。判定需要 openai-compatible 里的类型化错误类
7
+ // (instanceof 判据),所以连同这三个类(及其构造器依赖 sniffOverloadBody)
8
+ // 一起下沉到本模块 —— 依赖图变为无环:
9
+ // model-failure(零包内依赖)← model-fallback ← openai-compatible(再 re-export)
10
+ // openai-compatible.ts 对这些名字逐名 re-export,既有导入方(anthropic/
11
+ // responses/测试/index)零改动;类的定义全仓唯一,instanceof 语义逐字节不变。
12
+ import { UnsupportedContentError, MAX_TOKENS_THINKING_BUDGET_CONFLICT_CODE, CONFIG_CAP_ALSO_CONFLICTS_FIELD } from "@wudao-org/core";
13
+ // ---------------------------------------------------------------------------
14
+ // M47 §7 (A6): 429 overload body-sniffing. Z.AI / Zhipu (bigmodel.cn) express
15
+ // WHOLE-FLEET overload as HTTP 429 with a recognizable body — not a per-key
16
+ // quota hit. Those failures classify as `overload`: the ladder backs off on the
17
+ // SAME key (never rotates — a fleet-wide signal says nothing about this
18
+ // key) with a longer doubling wait, capped at 32s.
19
+ // ---------------------------------------------------------------------------
20
+ /** The z.ai / zhipu / bigmodel overload vocabulary. The JSON-coded 1301 is
21
+ * anchored on the `code` key so ordinary numeric fields (token counts) can
22
+ * never trip it. */
23
+ export const OVERLOAD_BODY_SIGNATURES = [
24
+ /"code"\s*:\s*"?(?:1301)"?/, // zhipu/bigmodel: 集团内部忙 (fleet busy)
25
+ /overload/i, // z.ai: "The server is overloaded …"
26
+ /server is busy/i,
27
+ /当前集团内部忙/,
28
+ /服务器繁忙/,
29
+ /系统繁忙/,
30
+ /负载已满/,
31
+ ];
32
+ /** True when a 429 body carries a known overload signature. */
33
+ export function sniffOverloadBody(body) {
34
+ return OVERLOAD_BODY_SIGNATURES.some((re) => re.test(body));
35
+ }
36
+ /** The typed context-overflow failure (M58 §A). Stamped with the duck-type
37
+ * `name` the core port recognizes (core's isContextLengthError) — core stays
38
+ * provider-agnostic and never imports this class. ω-2b (I1-a): carries the
39
+ * trusted-parse observation when the body yielded one (parseContextLimitBody)
40
+ * — the loop's calibration + clip ladder read it. */
41
+ export class ContextLengthError extends Error {
42
+ status;
43
+ body;
44
+ observed;
45
+ constructor(status, body, observed) {
46
+ super(`provider context length exceeded: ${status} ${body}`.trim());
47
+ this.name = "ContextLengthError";
48
+ this.status = status;
49
+ this.body = body;
50
+ this.observed = observed;
51
+ }
52
+ }
53
+ /** The typed immediate-bail failure for a background query on overload. The
54
+ * original error rides `cause` (and its message) for diagnostics. */
55
+ export class BackgroundOverloadError extends Error {
56
+ source;
57
+ constructor(source, original) {
58
+ super(`background query '${source}' hit a provider overload — failing immediately instead of retrying ` +
59
+ `(foreground-only retry policy: during a capacity cascade every retry amplifies gateway load and nobody is waiting on this result): ` +
60
+ `${original instanceof Error ? original.message : String(original)}`);
61
+ this.name = "BackgroundOverloadError";
62
+ this.source = source;
63
+ // The base Error's own cause channel carries the original failure.
64
+ this.cause = original;
65
+ }
66
+ }
67
+ /** The typed provider HTTP failure. The message keeps the pinned
68
+ * `provider request|stream failed: <status> <body>` format, so every
69
+ * message-regex consumer (retryReason, tests, the CLI) keeps working.
70
+ * r1a Task 4: carries the server's Retry-After deadline (ms) when the
71
+ * response headers had one — OMITTED otherwise (omit-never-null), so the
72
+ * serialized shape of every pre-existing error is byte-identical.
73
+ * v7 γ4 (pi 0c7bb7c5c 思想,digest-a C3 搭车件): carries the failing leg's
74
+ * provider/model identity as STRUCTURED fields — wudao is multi-provider
75
+ * (悟道/DeepSeek/GLM/Qwen) on one OpenAI-compatible face, and a generic
76
+ * "provider request failed: 500 …" made every vendor one fingerprint family.
77
+ * The provider id also appends to the MESSAGE (suffix — the anchored
78
+ * prefix regexes `^provider (?:request|stream) failed: (\d{3})` in
79
+ * retryReason/isRetryableProviderError keep matching; the fingerprint's
80
+ * normalizeFailureCause masks numbers but provider ids are digit-free, so
81
+ * the attribution SURVIVES normalization — γ2's end-cause ledger groups by
82
+ * it). Omitted when the config carries no registry identity (a raw
83
+ * baseURL leg has nothing honest to attribute): byte-identical shape,
84
+ * identical message. */
85
+ export class ProviderHttpError extends Error {
86
+ status;
87
+ body;
88
+ /** True iff status is 429 AND the body sniffs as overload. */
89
+ overload;
90
+ constructor(which, status, body, retryAfterMs, identity) {
91
+ // v7 γ4: identity rides the tail — the pinned prefix bytes are untouched
92
+ // (every anchored-regex consumer and .toBe pin keeps working).
93
+ const tail = identity?.provider !== undefined && identity.provider !== "" ? ` — ${identity.provider}` : "";
94
+ super(`provider ${which} failed: ${status} ${body}${tail}`.trim());
95
+ this.name = "ProviderHttpError";
96
+ this.status = status;
97
+ this.body = body;
98
+ this.overload = status === 429 && sniffOverloadBody(body);
99
+ if (retryAfterMs !== undefined)
100
+ this.retryAfterMs = retryAfterMs;
101
+ if (identity?.provider !== undefined && identity.provider !== "")
102
+ this.provider = identity.provider;
103
+ if (identity?.model !== undefined && identity.model !== "")
104
+ this.model = identity.model;
105
+ }
106
+ }
107
+ /** wire-r2 follow-up ① — the typed request-construction conflict thrown by
108
+ * the anthropic adapter when an EXPLICIT maxTokens (input.maxTokens or
109
+ * config.maxTokens — either is a cap someone chose) sits at/below the
110
+ * thinking budget implied by reasoningEffort: the wire structurally
111
+ * requires max_tokens > thinking.budget_tokens, and silently raising a
112
+ * chosen cap (the pre-narrowing budget+1024 bump) was the fail-closed
113
+ * tension the wire-r2 review flagged. Only the adapter's own implicit
114
+ * default cap keeps the historic raise. Deterministic config conflict:
115
+ * thrown BEFORE the retry ladder (validatedInputEffort's spot — never
116
+ * sleeps, never hits the wire) and never model-fallback-eligible below
117
+ * (a sibling model re-hits the identical conflict). */
118
+ export class MaxTokensThinkingBudgetConflictError extends Error {
119
+ /** F1 (clip-conflict): the stable cross-package stamp. Core's loop duck-
120
+ * types this string to route COMPUTED-cap conflicts (the ω-2b admission
121
+ * clip / the ladder's clip-retry physical — context-budget arithmetic, not
122
+ * a chosen cap) into the reactive compact ladder instead of hard-failing;
123
+ * core never imports this class. The literal's single source is the core
124
+ * port constant (imported here so a core rename changes the stamp and the
125
+ * providers pin goes loud, never silently unfixed). A caller-chosen
126
+ * config.maxTokens conflict keeps the fail-closed propagation on both
127
+ * sides of the seam. */
128
+ code = MAX_TOKENS_THINKING_BUDGET_CONFLICT_CODE;
129
+ maxTokens;
130
+ budgetTokens;
131
+ constructor(maxTokens, budgetTokens, configCapAlsoConflicts = false) {
132
+ super(`explicit maxTokens ${maxTokens} conflicts with thinking budget_tokens ${budgetTokens} ` +
133
+ `(the anthropic wire requires max_tokens > budget_tokens, so this body can never be served) — ` +
134
+ `raise maxTokens above the thinking budget or lower reasoningEffort`);
135
+ this.name = "MaxTokensThinkingBudgetConflictError";
136
+ this.maxTokens = maxTokens;
137
+ this.budgetTokens = budgetTokens;
138
+ if (configCapAlsoConflicts)
139
+ this[CONFIG_CAP_ALSO_CONFLICTS_FIELD] = true;
140
+ }
141
+ }
142
+ /** Key-class failures (401/403) never fall back — those are the M56 key
143
+ * pool's domain (model故障 ≠ 凭据故障). */
144
+ export function isKeyClassFailure(err) {
145
+ return err instanceof ProviderHttpError && (err.status === 401 || err.status === 403);
146
+ }
147
+ // ---------------------------------------------------------------------------
148
+ // ω99-42 — the typed mandatory-reasoning rejection (hermes f6bd1633f7 +
149
+ // 63279301bc, wudao layering). A reasoning-mandatory route (GLM-5.3 via
150
+ // Nous/OpenRouter, kimi-k2.7-code-style deployments) answers a request that
151
+ // disabled thinking with HTTP 400 "Reasoning is mandatory for this endpoint
152
+ // and cannot be disabled". Before this class that 400 surfaced as a generic
153
+ // 4xx — unidentifiable, unhealable, unattributable.
154
+ // ---------------------------------------------------------------------------
155
+ /** The mandatory-reasoning body vocabulary. The first pattern is the live
156
+ * recording from hermes f6bd1633f7 (Nous Portal / OpenRouter z-ai/glm-5.3,
157
+ * Sep 2026); the siblings are the same sentence family. Conservative on
158
+ * purpose — the caller may override per provider (the `signatures` param of
159
+ * {@link isMandatoryReasoningRejection}). */
160
+ export const MANDATORY_REASONING_BODY_SIGNATURES = [
161
+ /reasoning is mandatory/i,
162
+ /thinking is mandatory/i,
163
+ /reasoning is required/i,
164
+ ];
165
+ /** True iff the status/body pair is a mandatory-reasoning rejection: HTTP 400
166
+ * (the class hermes matches in _classify_400; a 5xx/429 carrying the same
167
+ * text keeps its existing transport path) plus a body signature. `signatures`
168
+ * overrides the default vocabulary (per-provider calibration seam). */
169
+ export function isMandatoryReasoningRejection(status, body, signatures = MANDATORY_REASONING_BODY_SIGNATURES) {
170
+ return status === 400 && signatures.some((re) => re.test(body));
171
+ }
172
+ /** The typed mandatory-reasoning rejection. Two flavors, one class:
173
+ * repairable — the disable on the wire was NOT a user pin (default-sourced
174
+ * effort, a thinkingLevelMap fold, or a code-defaulted soft none): the
175
+ * retry ladder re-sends ONCE with reasoning enabled (messages bytes
176
+ * untouched — the reasoning fields are request-level sampling params, so
177
+ * the prefix cache key is preserved by construction; the wudao reading of
178
+ * hermes 63279301bc's "same cache key").
179
+ * terminal — the disable WAS the user's explicit "none" (never silently
180
+ * rewritten), the repair already ran and failed, or the wire format
181
+ * cannot express enablement: the error surfaces with actionable guidance.
182
+ * Never walks the generic transport ladder as a 400, never compresses,
183
+ * never falls back to a sibling model (the rejection is route semantics,
184
+ * not model health). */
185
+ export class ReasoningMandatoryError extends Error {
186
+ status;
187
+ body;
188
+ /** Attribution: the config's provider id (fallback baseURL) + the effort
189
+ * the rejected request actually carried. */
190
+ provider;
191
+ repairable;
192
+ constructor(which, status, body, provider, effortSent, repairable) {
193
+ super(repairable
194
+ ? `provider ${which} failed: ${status} ${body} — reasoning is mandatory on this endpoint; retrying with reasoning enabled (the disable was not user-configured)`.trim()
195
+ : `provider ${which} failed: ${status} ${body} — this endpoint requires reasoning and cannot serve a request that disables it; switch the reasoning effort off "none" (e.g. /effort medium) or use an endpoint that accepts disabled thinking`.trim());
196
+ this.name = "ReasoningMandatoryError";
197
+ this.status = status;
198
+ this.body = body;
199
+ this.provider = provider;
200
+ if (effortSent !== undefined)
201
+ this.effortSent = effortSent;
202
+ this.repairable = repairable;
203
+ }
204
+ }
205
+ /** True when an error may trigger the model-fallback chain: model-class
206
+ * HTTP failures and transport errors — never aborts (user intent), never
207
+ * context overflow (a prompt that does not fit the primary will not fit a
208
+ * sibling either; the loop's reactive compaction owns that), never
209
+ * key-class failures. M79: an UnsupportedContentError is eligible ONLY in
210
+ * its model-capability form — falling back to a sibling that declares the
211
+ * image modality is the recovery; the structural forms (role violation,
212
+ * missing attachment store) can never succeed on another model. */
213
+ export function isModelFallbackEligible(err) {
214
+ if (err instanceof ProviderHttpError)
215
+ return !isKeyClassFailure(err);
216
+ if (err instanceof ContextLengthError)
217
+ return false;
218
+ // ω99-42: a mandatory-reasoning rejection is ROUTE semantics, not model
219
+ // health — a sibling model on the same mandatory route re-hits the
220
+ // identical 400 (and the repairable flavor already rode the ladder once).
221
+ // The recovery is the typed guidance (or the repair), never a fallback.
222
+ if (err instanceof ReasoningMandatoryError)
223
+ return false;
224
+ // 113-B3: an account-level quota window is PROVIDER-scoped — a sibling
225
+ // model on the same capped account burns the same quota. The park lane
226
+ // (the CLI's parked run + reset wake) owns the recovery, never a fallback.
227
+ // Name-armed like HeaderValidationError below (no import edge to
228
+ // quota-park.ts at model-failure's zero-dependency floor).
229
+ if (err instanceof Error && err.name === "QuotaParkError")
230
+ return false;
231
+ // M70 §3: a background overload's immediate bail is final — re-issuing the
232
+ // call on a sibling model is the same cascade amplification the allowlist
233
+ // exists to stop.
234
+ if (err instanceof BackgroundOverloadError)
235
+ return false;
236
+ // wire-r2 follow-up ①: an explicit maxTokens/thinking-budget conflict is
237
+ // a deterministic config conflict — a sibling model hits the identical
238
+ // body rejection. Never falls back.
239
+ if (err instanceof MaxTokensThinkingBudgetConflictError)
240
+ return false;
241
+ // ω99-50: an unrepresentable persona header rides the config, not the
242
+ // model — a sibling leg re-hits the identical named rejection. Never
243
+ // falls back (name-armed: the class lives in header-validation.ts, no
244
+ // import edge to model-failure's zero-dependency floor).
245
+ if (err instanceof Error && err.name === "HeaderValidationError")
246
+ return false;
247
+ if (err instanceof UnsupportedContentError)
248
+ return err.reason === "model-no-image-modality";
249
+ if (err instanceof Error && err.name === "AbortError")
250
+ return false;
251
+ return err instanceof Error && err.name !== "AbortError" && !(err instanceof SyntaxError);
252
+ }
253
+ //# sourceMappingURL=model-failure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-failure.js","sourceRoot":"","sources":["../src/model-failure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { ModelClient, ModelInput, ModelStreamEvent } from "@wudao-org/core";
2
+ import type { ProviderConfig } from "./config.js";
3
+ /** One protocol adapter's per-model leg client: the shared retry ladder rides
4
+ * INSIDE each leg — the chain swaps the model only after a leg's ladder gave
5
+ * up. Both paths required (all three protocol adapters ship generate+stream). */
6
+ export interface StreamingModelClient extends ModelClient {
7
+ stream(input: ModelInput): AsyncGenerator<ModelStreamEvent>;
8
+ }
9
+ /** The seam each factory provides: build one leg for one (model-swapped)
10
+ * config. `config.fallbackModels` stays the single configuration surface —
11
+ * the decorator never invents a second one. */
12
+ export type ModelClientFactory = (config: ProviderConfig) => StreamingModelClient;
13
+ /** Wrap one protocol adapter's per-model leg factory with the ordered
14
+ * model-fallback chain. Zero `fallbackModels` = a one-leg chain: the wrapper
15
+ * is pass-through shape (same error, one extra async frame, no behavior
16
+ * change). */
17
+ export declare function withModelFallback(makeClient: ModelClientFactory, config: ProviderConfig): StreamingModelClient;
18
+ //# sourceMappingURL=model-fallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-fallback.d.ts","sourceRoot":"","sources":["../src/model-fallback.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAoB,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAc,MAAM,iBAAiB,CAAC;AAC/G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AASlD;;kFAEkF;AAClF,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACvD,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,cAAc,CAAC,gBAAgB,CAAC,CAAC;CAC7D;AAED;;gDAEgD;AAChD,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,oBAAoB,CAAC;AAElF;;;eAGe;AACf,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,kBAAkB,EAC9B,MAAM,EAAE,cAAc,GACrB,oBAAoB,CAoEtB"}
@@ -0,0 +1,87 @@
1
+ // r1b A1: 判定从 openai-compatible 下沉到 model-failure —— 消除
2
+ // openai-compatible ↔ model-fallback 的 import 环(语义零变,同一函数体)。
3
+ import { isModelFallbackEligible } from "./model-failure.js";
4
+ /** Consecutive primary failures after which the chain skips straight to the
5
+ * first fallback ("连续失败" — one blip retries the primary next call). */
6
+ const FALLBACK_PIN_STREAK = 2;
7
+ /** Wrap one protocol adapter's per-model leg factory with the ordered
8
+ * model-fallback chain. Zero `fallbackModels` = a one-leg chain: the wrapper
9
+ * is pass-through shape (same error, one extra async frame, no behavior
10
+ * change). */
11
+ export function withModelFallback(makeClient, config) {
12
+ // 有序链:主模型 + fallbackModels(过滤与主模型相同的项,与抽出前同款)。
13
+ // 各 leg 共享同一 key 池/梯子选项 —— 池在模型内换 key,链在梯子放弃后换模型。
14
+ const fallbacks = (config.fallbackModels ?? []).filter((m) => m !== config.model);
15
+ const chain = [
16
+ { client: makeClient(config), model: config.model, primary: true },
17
+ ...fallbacks.map((m) => ({ client: makeClient({ ...config, model: m }), model: m, primary: false })),
18
+ ];
19
+ let primaryFailStreak = 0;
20
+ const annotateUsage = (input, from, to) => ({
21
+ ...input,
22
+ onUsage: input.onUsage === undefined
23
+ ? undefined
24
+ // M70 §2: a failover row answers under the FALLBACK's name — the loop's
25
+ // usage-anchor guard (a) sees the model switch and drops the anchor.
26
+ : (u) => input.onUsage?.({ ...u, model: to, fallbackModel: to, fallbackFrom: from }),
27
+ });
28
+ return {
29
+ // M70 §2: the client's primary model identity (the loop's usage-anchor
30
+ // guards compare it against the answering model on each usage row).
31
+ modelId: config.model,
32
+ async generate(input) {
33
+ const startAt = primaryFailStreak >= FALLBACK_PIN_STREAK ? Math.min(1, chain.length - 1) : 0;
34
+ let lastErr;
35
+ for (let i = startAt; i < chain.length; i += 1) {
36
+ const leg = chain[i];
37
+ const callInput = !leg.primary ? annotateUsage(input, config.model, leg.model) : input;
38
+ try {
39
+ const out = await leg.client.generate(callInput);
40
+ if (leg.primary)
41
+ primaryFailStreak = 0;
42
+ return out;
43
+ }
44
+ catch (err) {
45
+ if (!isModelFallbackEligible(err))
46
+ throw err;
47
+ if (leg.primary)
48
+ primaryFailStreak += 1;
49
+ lastErr = err;
50
+ }
51
+ }
52
+ throw lastErr;
53
+ },
54
+ // M62 §7: the stream path mirrors generate; a fallback is only possible
55
+ // BEFORE the first yielded delta (a post-delta break is rethrown —
56
+ // replaying would duplicate output). The done message is always the last
57
+ // attempt's.
58
+ async *stream(input) {
59
+ const startAt = primaryFailStreak >= FALLBACK_PIN_STREAK ? Math.min(1, chain.length - 1) : 0;
60
+ let lastErr;
61
+ for (let i = startAt; i < chain.length; i += 1) {
62
+ const leg = chain[i];
63
+ const callInput = !leg.primary ? annotateUsage(input, config.model, leg.model) : input;
64
+ let produced = false;
65
+ try {
66
+ for await (const ev of leg.client.stream(callInput)) {
67
+ if (ev.type === "reasoning_delta" || ev.type === "text_delta")
68
+ produced = true;
69
+ yield ev;
70
+ }
71
+ if (leg.primary)
72
+ primaryFailStreak = 0;
73
+ return;
74
+ }
75
+ catch (err) {
76
+ if (produced || !isModelFallbackEligible(err))
77
+ throw err;
78
+ if (leg.primary)
79
+ primaryFailStreak += 1;
80
+ lastErr = err;
81
+ }
82
+ }
83
+ throw lastErr;
84
+ },
85
+ };
86
+ }
87
+ //# sourceMappingURL=model-fallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-fallback.js","sourceRoot":"","sources":["../src/model-fallback.ts"],"names":[],"mappings":"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"}