@providerkit/core 0.21.1 → 0.22.0
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/README.md +7 -7
- package/dist/attribution.d.ts +2 -2
- package/dist/capability.d.ts +9 -9
- package/dist/capability.js +9 -9
- package/dist/capability.js.map +1 -1
- package/dist/context.d.ts +4 -4
- package/dist/context.js +4 -4
- package/dist/errors.d.ts +15 -15
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +14 -14
- package/dist/image.d.ts +1 -1
- package/dist/image.d.ts.map +1 -1
- package/dist/jev.d.ts +9 -9
- package/dist/jev.d.ts.map +1 -1
- package/dist/jev.js +1 -1
- package/dist/key-pool.d.ts +4 -4
- package/dist/key-pool.js +6 -6
- package/dist/key-pool.js.map +1 -1
- package/dist/presets.d.ts +26 -22
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +13 -12
- package/dist/presets.js.map +1 -1
- package/dist/providers/anthropic.d.ts +5 -5
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +9 -9
- package/dist/providers/factory.d.ts +2 -2
- package/dist/providers/factory.d.ts.map +1 -1
- package/dist/providers/factory.js +2 -1
- package/dist/providers/factory.js.map +1 -1
- package/dist/providers/gemini.d.ts +2 -2
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +15 -14
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/openai.d.ts +12 -9
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +9 -7
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/responses.d.ts +3 -3
- package/dist/providers/responses.js +5 -5
- package/dist/providers/responses.js.map +1 -1
- package/dist/providers/zai.d.ts +2 -2
- package/dist/providers/zai.js +2 -2
- package/dist/rate-limit.d.ts +3 -3
- package/dist/rate-limit.js +3 -3
- package/dist/retry.d.ts +5 -5
- package/dist/retry.js +4 -4
- package/dist/schema.d.ts +6 -6
- package/dist/schema.js +8 -8
- package/dist/tool-args.d.ts +1 -1
- package/dist/tool-args.js +2 -2
- package/dist/tools.d.ts +3 -3
- package/dist/tools.js +2 -2
- package/dist/tools.js.map +1 -1
- package/dist/transport.d.ts +7 -7
- package/dist/transport.js +6 -6
- package/dist/types.d.ts +24 -23
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -3
- package/dist/types.js.map +1 -1
- package/dist/usage.d.ts +4 -4
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js +3 -3
- package/dist/usage.js.map +1 -1
- package/dist/watchdog.d.ts +12 -12
- package/dist/watchdog.js +10 -10
- package/dist/zod.d.ts +4 -4
- package/dist/zod.js +3 -3
- package/package.json +1 -1
- package/src/attribution.ts +2 -2
- package/src/capability.ts +12 -12
- package/src/context.ts +4 -4
- package/src/errors.ts +18 -18
- package/src/image.ts +1 -1
- package/src/jev.ts +11 -11
- package/src/key-pool.ts +7 -7
- package/src/presets.ts +26 -22
- package/src/providers/anthropic.ts +14 -14
- package/src/providers/factory.ts +4 -3
- package/src/providers/gemini.ts +19 -16
- package/src/providers/openai.ts +17 -12
- package/src/providers/responses.ts +11 -11
- package/src/providers/zai.ts +2 -2
- package/src/rate-limit.ts +4 -4
- package/src/retry.ts +5 -5
- package/src/schema.ts +8 -8
- package/src/tool-args.ts +2 -2
- package/src/tools.ts +4 -4
- package/src/transport.ts +7 -7
- package/src/types.ts +24 -23
- package/src/usage.ts +5 -5
- package/src/watchdog.ts +13 -13
- package/src/zod.ts +4 -4
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ handling you only learn in production.
|
|
|
9
9
|
bun add @providerkit/core # npm / pnpm / yarn all fine
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
Zero runtime dependencies. `fetch` only
|
|
12
|
+
Zero runtime dependencies. `fetch` only, with no vendor SDKs and no Node built-ins, so the same
|
|
13
13
|
build runs in Node 22+, Bun, Deno, Cloudflare Workers and a Chrome MV3 service worker.
|
|
14
14
|
|
|
15
15
|
## What this is
|
|
@@ -20,12 +20,12 @@ not where the time goes. The time goes here:
|
|
|
20
20
|
- a stream that opens, sends nothing, and never ends
|
|
21
21
|
- a socket that dies four `cause` levels down, with no HTTP status to read
|
|
22
22
|
- quota exhaustion arriving as `429` from one vendor, `402` from another, `403` from a
|
|
23
|
-
third and `400` from a fourth
|
|
23
|
+
third and `400` from a fourth, and "retry" is the wrong advice for all of them
|
|
24
24
|
- a `429` that is really a context overflow, where waiting fixes nothing and compaction
|
|
25
25
|
fixes everything
|
|
26
26
|
- a plan that never included the API, which neither a new key nor a top-up will fix
|
|
27
27
|
- Anthropic reporting cache tokens _outside_ the input count while OpenAI reports them
|
|
28
|
-
_inside_ it
|
|
28
|
+
_inside_ it, so the same conversation costs two different things
|
|
29
29
|
- `reasoning_content` that must be replayed on tool-call turns, and must _not_ be sent
|
|
30
30
|
when thinking is off
|
|
31
31
|
- a tool call's JSON truncated mid-argument, throwing away an answer that was right there
|
|
@@ -117,7 +117,7 @@ calls, so it remembers which models are spent.
|
|
|
117
117
|
Go also asks each client to send its own user agent, not the runtime's default. Pass
|
|
118
118
|
`headers: { "user-agent": "my-app" }`, and add it to each Go entry in `fallbacks` too.
|
|
119
119
|
|
|
120
|
-
**Full documentation lives at [providerkit.dev](https://providerkit.dev)
|
|
120
|
+
**Full documentation lives at [providerkit.dev](https://providerkit.dev)**. It is the single
|
|
121
121
|
source of truth for usage, and this README deliberately stays a front door so the two cannot
|
|
122
122
|
drift.
|
|
123
123
|
|
|
@@ -140,7 +140,7 @@ cannot drift either.
|
|
|
140
140
|
## Origin
|
|
141
141
|
|
|
142
142
|
This was extracted from five production codebases that had each independently grown the same
|
|
143
|
-
layer
|
|
143
|
+
layer: about 9,100 lines solving one ~2,000-line problem. They had three separate
|
|
144
144
|
60-second idle watchdogs, identical down to the constant. On one day in September 2026, two
|
|
145
145
|
of them shipped the same five fixes independently.
|
|
146
146
|
|
|
@@ -155,7 +155,7 @@ ever saw. That is the part worth having.
|
|
|
155
155
|
## In production
|
|
156
156
|
|
|
157
157
|
This is not a plan, it already happened. Four of the five codebases serve production traffic
|
|
158
|
-
through this package today, and the migrations that put it there were net-negative every time
|
|
158
|
+
through this package today, and the migrations that put it there were net-negative every time:
|
|
159
159
|
**−452, −1,621 and −197 lines** in the first three. The last one, `@falai/agent` v3, trades three
|
|
160
160
|
vendor SDKs for this package (−5,033 more) and ships with the release that carries this section.
|
|
161
161
|
|
|
@@ -163,7 +163,7 @@ vendor SDKs for this package (−5,033 more) and ships with the release that car
|
|
|
163
163
|
|
|
164
164
|
```
|
|
165
165
|
core/ the npm package `@providerkit/core`
|
|
166
|
-
site/ providerkit.dev
|
|
166
|
+
site/ providerkit.dev (Astro + Starlight), also open source
|
|
167
167
|
brand/ the mark, the OG card, and the generator for both
|
|
168
168
|
```
|
|
169
169
|
|
package/dist/attribution.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export interface Attribution {
|
|
2
|
-
/** Site URL, sent as `HTTP-Referer`
|
|
2
|
+
/** Site URL, sent as `HTTP-Referer` (e.g. "https://your.app"). */
|
|
3
3
|
siteUrl?: string;
|
|
4
|
-
/** App name, sent as `X-Title`
|
|
4
|
+
/** App name, sent as `X-Title` (e.g. "Your App"). */
|
|
5
5
|
siteName?: string;
|
|
6
6
|
}
|
|
7
7
|
/** Attribution headers not already covered by an explicit `headers` entry. */
|
package/dist/capability.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { JsonWithTools, Provider } from "./types.ts";
|
|
|
2
2
|
export interface JsonWithToolsProbe {
|
|
3
3
|
/**
|
|
4
4
|
* The shape to configure, or `null` when neither called the tool on every
|
|
5
|
-
* sample
|
|
5
|
+
* sample. That model cannot be trusted with tools and a schema together,
|
|
6
6
|
* whichever way the schema rides, and the honest fix is a different model.
|
|
7
7
|
*/
|
|
8
8
|
use: JsonWithTools | null;
|
|
@@ -13,8 +13,8 @@ export interface JsonWithToolsProbe {
|
|
|
13
13
|
}
|
|
14
14
|
export interface ProbeOptions {
|
|
15
15
|
/**
|
|
16
|
-
* Samples per shape. Above one because the interesting failures are partial
|
|
17
|
-
* `gemini-3.8-flash` called its tool 3/10
|
|
16
|
+
* Samples per shape. Above one because the interesting failures are partial:
|
|
17
|
+
* `gemini-3.8-flash` called its tool 3/10. A single sample reports a
|
|
18
18
|
* coin flip as a capability. A shape passes only when EVERY sample calls.
|
|
19
19
|
*/
|
|
20
20
|
samples?: number;
|
|
@@ -24,12 +24,12 @@ export interface ProbeOptions {
|
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Ask a model, on the wire, which {@link JsonWithTools} shape it actually
|
|
27
|
-
* serves
|
|
27
|
+
* serves. Then configure the provider with `probe.use`.
|
|
28
28
|
*
|
|
29
29
|
* Both shapes are always tried, because a result you can read beats a result
|
|
30
30
|
* you have to trust: `calls` is the table to log, and "0/3 and 3/3" is what
|
|
31
31
|
* makes a later regression obvious. It costs `samples × 2` short calls, made
|
|
32
|
-
* one after another, once, at whatever moment the app decides to ask
|
|
32
|
+
* one after another, once, at whatever moment the app decides to ask. Boot is
|
|
33
33
|
* the usual one.
|
|
34
34
|
*
|
|
35
35
|
* Probe each provider on its own, never a fallback chain: the shape is a fact
|
|
@@ -46,8 +46,8 @@ export interface ProbeOptions {
|
|
|
46
46
|
* report "this model cannot call tools", which is a much worse thing to
|
|
47
47
|
* believe than "the call failed".
|
|
48
48
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* It catches a structural failure: a model that cannot emit the call, every
|
|
50
|
+
* time, on the easiest question there is. A model that is merely
|
|
51
51
|
* unreliable will pass: `gemini-3.8-flash` answers this probe 3/3 and a real
|
|
52
52
|
* sales turn 3/10. That is the right line to draw. A harder probe would start
|
|
53
53
|
* failing good models for being terse, and "sometimes forgets its tools" is a
|
|
@@ -96,8 +96,8 @@ export interface ResolveModelOptions {
|
|
|
96
96
|
* - `deepseek/deepseek-v4.1-flash` matches `deepseek-v4.1-flash`
|
|
97
97
|
* - `accounts/fireworks/models/glm-5p3-flash` matches `glm-5.3-flash`
|
|
98
98
|
*
|
|
99
|
-
* Never throws
|
|
100
|
-
* returns `undefined` so capability lookups never break caller execution.
|
|
99
|
+
* Never throws. If the catalog cannot be retrieved or the model is unknown,
|
|
100
|
+
* it returns `undefined` so capability lookups never break caller execution.
|
|
101
101
|
*/
|
|
102
102
|
export declare function resolveModelCapabilities(modelId: string, options?: ResolveModelOptions): Promise<ModelCapabilities | undefined>;
|
|
103
103
|
//# sourceMappingURL=capability.d.ts.map
|
package/dist/capability.js
CHANGED
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
// run put `qwen3.8-flash` at 10/10 with the response format and 1/6 without it,
|
|
16
16
|
// so a global flip only moves the silence to different models. One call each
|
|
17
17
|
// way settles it for the model actually being served.
|
|
18
|
-
/**
|
|
19
|
-
* turn
|
|
18
|
+
/** A question the model cannot answer from memory, so a tool call is the only
|
|
19
|
+
* correct turn. Not making one is a real signal rather than a judgement call. */
|
|
20
20
|
const PROBE_TOOL = {
|
|
21
21
|
name: "get_current_time",
|
|
22
|
-
description: "The only source of the current time. You cannot know the time without calling this
|
|
22
|
+
description: "The only source of the current time. You cannot know the time without calling this. Never answer a time question from memory or guess.",
|
|
23
23
|
inputSchema: {
|
|
24
24
|
type: "object",
|
|
25
25
|
properties: { timezone: { type: "string", description: "IANA timezone, e.g. Asia/Tokyo" } },
|
|
@@ -55,12 +55,12 @@ async function callsTool(provider, shape, opts) {
|
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
57
|
* Ask a model, on the wire, which {@link JsonWithTools} shape it actually
|
|
58
|
-
* serves
|
|
58
|
+
* serves. Then configure the provider with `probe.use`.
|
|
59
59
|
*
|
|
60
60
|
* Both shapes are always tried, because a result you can read beats a result
|
|
61
61
|
* you have to trust: `calls` is the table to log, and "0/3 and 3/3" is what
|
|
62
62
|
* makes a later regression obvious. It costs `samples × 2` short calls, made
|
|
63
|
-
* one after another, once, at whatever moment the app decides to ask
|
|
63
|
+
* one after another, once, at whatever moment the app decides to ask. Boot is
|
|
64
64
|
* the usual one.
|
|
65
65
|
*
|
|
66
66
|
* Probe each provider on its own, never a fallback chain: the shape is a fact
|
|
@@ -77,8 +77,8 @@ async function callsTool(provider, shape, opts) {
|
|
|
77
77
|
* report "this model cannot call tools", which is a much worse thing to
|
|
78
78
|
* believe than "the call failed".
|
|
79
79
|
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
80
|
+
* It catches a structural failure: a model that cannot emit the call, every
|
|
81
|
+
* time, on the easiest question there is. A model that is merely
|
|
82
82
|
* unreliable will pass: `gemini-3.8-flash` answers this probe 3/3 and a real
|
|
83
83
|
* sales turn 3/10. That is the right line to draw. A harder probe would start
|
|
84
84
|
* failing good models for being terse, and "sometimes forgets its tools" is a
|
|
@@ -126,8 +126,8 @@ function normalizeId(id) {
|
|
|
126
126
|
* - `deepseek/deepseek-v4.1-flash` matches `deepseek-v4.1-flash`
|
|
127
127
|
* - `accounts/fireworks/models/glm-5p3-flash` matches `glm-5.3-flash`
|
|
128
128
|
*
|
|
129
|
-
* Never throws
|
|
130
|
-
* returns `undefined` so capability lookups never break caller execution.
|
|
129
|
+
* Never throws. If the catalog cannot be retrieved or the model is unknown,
|
|
130
|
+
* it returns `undefined` so capability lookups never break caller execution.
|
|
131
131
|
*/
|
|
132
132
|
export async function resolveModelCapabilities(modelId, options = {}) {
|
|
133
133
|
if (!modelId)
|
package/dist/capability.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,EAAE;AACF,2EAA2E;AAC3E,8EAA8E;AAC9E,0EAA0E;AAC1E,6EAA6E;AAC7E,gFAAgF;AAChF,6EAA6E;AAC7E,+EAA+E;AAC/E,gFAAgF;AAChF,6EAA6E;AAC7E,iBAAiB;AACjB,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,6EAA6E;AAC7E,sDAAsD;AAItD;
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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"}
|
package/dist/context.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ import type { ChatMessage } from "./types.ts";
|
|
|
3
3
|
* What the answer needs after the prompt: an output budget, plus the tools'
|
|
4
4
|
* own schemas, plus the slack no provider documents.
|
|
5
5
|
*
|
|
6
|
-
* Absolute rather than a percentage on purpose
|
|
6
|
+
* Absolute rather than a percentage on purpose: a 1M window does not need a
|
|
7
7
|
* 100k cushion, and a 128k window needs more than 12k.
|
|
8
8
|
*/
|
|
9
9
|
export declare const CONTEXT_RESERVE_TOKENS = 32000;
|
|
10
10
|
/**
|
|
11
|
-
* Four characters per token
|
|
11
|
+
* Four characters per token is the rule of thumb every provider's own
|
|
12
12
|
* calculator agrees with to within a fifth, which is all the precision this
|
|
13
13
|
* needs. It decides WHEN to fold: folding one turn early costs a cheap model
|
|
14
14
|
* call, folding one turn late costs the whole turn.
|
|
@@ -19,7 +19,7 @@ export declare function estimateTokens(text: string): number;
|
|
|
19
19
|
export declare function messageTokens(message: ChatMessage): number;
|
|
20
20
|
export declare function conversationTokens(messages: readonly ChatMessage[]): number;
|
|
21
21
|
/**
|
|
22
|
-
* The provider's own input count says the
|
|
22
|
+
* The provider's own input count says the limit is close. Fold before the next
|
|
23
23
|
* step rather than after the 400.
|
|
24
24
|
*
|
|
25
25
|
* Takes the REPORTED count, not an estimate, because it is the only figure
|
|
@@ -41,7 +41,7 @@ export declare function historyBudgetTokens(contextWindow: number): number;
|
|
|
41
41
|
*
|
|
42
42
|
* 1. Never split a tool call from its result. Every provider rejects a tool
|
|
43
43
|
* result whose call is missing, so a cut landing between them produces a
|
|
44
|
-
* 400 on the very next turn
|
|
44
|
+
* 400 on the very next turn, the failure compaction was called to avoid.
|
|
45
45
|
* 2. Never cut into the system prompt. It is not history.
|
|
46
46
|
*
|
|
47
47
|
* Returns the index the kept tail starts at, or 0 when everything already fits.
|
package/dist/context.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* What the answer needs after the prompt: an output budget, plus the tools'
|
|
3
3
|
* own schemas, plus the slack no provider documents.
|
|
4
4
|
*
|
|
5
|
-
* Absolute rather than a percentage on purpose
|
|
5
|
+
* Absolute rather than a percentage on purpose: a 1M window does not need a
|
|
6
6
|
* 100k cushion, and a 128k window needs more than 12k.
|
|
7
7
|
*/
|
|
8
8
|
export const CONTEXT_RESERVE_TOKENS = 32_000;
|
|
9
9
|
/**
|
|
10
|
-
* Four characters per token
|
|
10
|
+
* Four characters per token is the rule of thumb every provider's own
|
|
11
11
|
* calculator agrees with to within a fifth, which is all the precision this
|
|
12
12
|
* needs. It decides WHEN to fold: folding one turn early costs a cheap model
|
|
13
13
|
* call, folding one turn late costs the whole turn.
|
|
@@ -52,7 +52,7 @@ export function conversationTokens(messages) {
|
|
|
52
52
|
return messages.reduce((total, message) => total + messageTokens(message), 0);
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
* The provider's own input count says the
|
|
55
|
+
* The provider's own input count says the limit is close. Fold before the next
|
|
56
56
|
* step rather than after the 400.
|
|
57
57
|
*
|
|
58
58
|
* Takes the REPORTED count, not an estimate, because it is the only figure
|
|
@@ -86,7 +86,7 @@ export function historyBudgetTokens(contextWindow) {
|
|
|
86
86
|
*
|
|
87
87
|
* 1. Never split a tool call from its result. Every provider rejects a tool
|
|
88
88
|
* result whose call is missing, so a cut landing between them produces a
|
|
89
|
-
* 400 on the very next turn
|
|
89
|
+
* 400 on the very next turn, the failure compaction was called to avoid.
|
|
90
90
|
* 2. Never cut into the system prompt. It is not history.
|
|
91
91
|
*
|
|
92
92
|
* Returns the index the kept tail starts at, or 0 when everything already fits.
|
package/dist/errors.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type RateLimitWindow } from "./rate-limit.ts";
|
|
|
2
2
|
import type { FilePart } from "./types.ts";
|
|
3
3
|
/** What kind of failure this is, named by what actually fixes it. */
|
|
4
4
|
export type ErrorKind =
|
|
5
|
-
/** Our own cancel
|
|
5
|
+
/** Our own cancel: the caller pressed Stop. Never retried. */
|
|
6
6
|
"aborted"
|
|
7
7
|
/** Our own deadline, or the provider's 408. Retry. */
|
|
8
8
|
| "timeout"
|
|
@@ -11,13 +11,13 @@ export type ErrorKind =
|
|
|
11
11
|
/** Theirs, and temporary: 5xx, Anthropic's 529, "overloaded". Retry, and
|
|
12
12
|
* worth trying a different model. */
|
|
13
13
|
| "overload"
|
|
14
|
-
/** 429 per-minute throttle. Wait
|
|
14
|
+
/** 429 per-minute throttle. Wait, or rotate to another key or model. */
|
|
15
15
|
| "rate"
|
|
16
16
|
/** Balance or usage window exhausted. Waiting minutes will not fix it. */
|
|
17
17
|
| "quota"
|
|
18
18
|
/** The plan never included this API. Neither a new key nor a top-up fixes it. */
|
|
19
19
|
| "entitlement"
|
|
20
|
-
/** 401/403
|
|
20
|
+
/** 401/403: the key is wrong, not the request. */
|
|
21
21
|
| "auth"
|
|
22
22
|
/** The model id does not exist or is not served here. */
|
|
23
23
|
| "model"
|
|
@@ -25,7 +25,7 @@ export type ErrorKind =
|
|
|
25
25
|
| "context"
|
|
26
26
|
/** Safety filter or refusal. */
|
|
27
27
|
| "content"
|
|
28
|
-
/** Any other 4xx
|
|
28
|
+
/** Any other 4xx: a bug in what we sent. */
|
|
29
29
|
| "invalid" | "unknown";
|
|
30
30
|
export declare function isTransient(kind: ErrorKind): boolean;
|
|
31
31
|
export declare function isBackupEligible(kind: ErrorKind): boolean;
|
|
@@ -37,7 +37,7 @@ export declare function isBackupEligible(kind: ErrorKind): boolean;
|
|
|
37
37
|
* 1. Caller aborts are never retryable.
|
|
38
38
|
* 2. An explicit `shouldRetry` directive on ProviderError (e.g. from server `x-should-retry`)
|
|
39
39
|
* 3. Non-retryable kinds (quota, context, model, entitlement, content, invalid) return false.
|
|
40
|
-
* 4. Excessive retry-after waits (exceeding `maxWaitMs`) return false
|
|
40
|
+
* 4. Excessive retry-after waits (exceeding `maxWaitMs`) return false. Long waits belong to fallbacks.
|
|
41
41
|
* 5. Transient kinds (rate, overload, network, timeout) return true.
|
|
42
42
|
* 6. Transport-level network faults (fetch failed, connection lost, SSL blips) return true.
|
|
43
43
|
*/
|
|
@@ -55,7 +55,7 @@ export declare class ProviderError extends Error {
|
|
|
55
55
|
readonly window?: RateLimitWindow;
|
|
56
56
|
/** Explicit server directive (`x-should-retry`), overriding default classification. */
|
|
57
57
|
readonly shouldRetry?: boolean;
|
|
58
|
-
/** The provider's own response body, truncated
|
|
58
|
+
/** The provider's own response body, truncated. It carries the actual reason,
|
|
59
59
|
* otherwise lost behind "400 status code (no body)". */
|
|
60
60
|
readonly body?: string;
|
|
61
61
|
constructor(provider: string, kind: ErrorKind, message: string, opts?: {
|
|
@@ -79,7 +79,7 @@ export declare function messageOf(err: unknown): string;
|
|
|
79
79
|
* A transport fault: the socket died before or during the response, so there
|
|
80
80
|
* is NO status and no body for the patterns below to read.
|
|
81
81
|
*
|
|
82
|
-
* The chain is walked because the useful code is rarely on the thrown error
|
|
82
|
+
* The chain is walked because the useful code is rarely on the thrown error:
|
|
83
83
|
* it sits on `cause`, sometimes several wrappers deep. Without this walk every
|
|
84
84
|
* network blip classifies as permanent, and a long run dies on its first
|
|
85
85
|
* hiccup, which is the single likeliest way to lose a minutes-long job.
|
|
@@ -92,18 +92,18 @@ export declare function isTransportFailure(err: unknown): boolean;
|
|
|
92
92
|
* The kind of failure, from whatever was thrown.
|
|
93
93
|
*
|
|
94
94
|
* Body patterns outrank status for the 4xx family; within them, context beats
|
|
95
|
-
* entitlement beats quota beats auth
|
|
95
|
+
* entitlement beats quota beats auth. Each earlier category's fix is useless
|
|
96
96
|
* for the later ones.
|
|
97
97
|
*/
|
|
98
98
|
/**
|
|
99
|
-
* The kind of a failure that arrived as an HTTP response
|
|
99
|
+
* The kind of a failure that arrived as an HTTP response: a status and a body,
|
|
100
100
|
* with nothing thrown.
|
|
101
101
|
*
|
|
102
102
|
* `classify` below is for a caught error, and it reads `status` and the body
|
|
103
103
|
* text off that error when they are not passed separately. A response has no
|
|
104
104
|
* error object, so callers were inventing one to fill the slot: a bare body
|
|
105
105
|
* string, the same text twice, a `{ status, error }` literal. All three are
|
|
106
|
-
* inert
|
|
106
|
+
* inert (nothing on them can satisfy `isAbort` or `isTransportFailure`), so
|
|
107
107
|
* they were three spellings of `undefined`.
|
|
108
108
|
*/
|
|
109
109
|
export declare function classifyHttp(status: number | undefined, body: string): ErrorKind;
|
|
@@ -111,7 +111,7 @@ export declare function classify(err: unknown, status?: number, body?: string):
|
|
|
111
111
|
/**
|
|
112
112
|
* How long the provider asked us to wait, in ms. Two dialects: Gemini's
|
|
113
113
|
* RetryInfo (`"retryDelay": "52s"`, inside the body) and the `Retry-After`
|
|
114
|
-
* header, which SDKs keep on the error. Honouring it beats guessing
|
|
114
|
+
* header, which SDKs keep on the error. Honouring it beats guessing: a
|
|
115
115
|
* backoff shorter than the window just burns an attempt.
|
|
116
116
|
*/
|
|
117
117
|
export declare function parseRetryAfterMs(err: unknown, body?: string): number | undefined;
|
|
@@ -141,14 +141,14 @@ export declare function parseContextOverflow(err: unknown, body?: string): Conte
|
|
|
141
141
|
* completion: retry sees nothing to retry, and a key pool never rotates off an
|
|
142
142
|
* exhausted key.
|
|
143
143
|
*
|
|
144
|
-
* `error` is the vendor's own payload, whatever shape it came in
|
|
144
|
+
* `error` is the vendor's own payload, whatever shape it came in: the numeric
|
|
145
145
|
* HTTP `code` Gemini and OpenRouter use, the slug OpenAI and Anthropic put in
|
|
146
146
|
* `code`/`type`, the canonical `status` name. The whole thing serializes into
|
|
147
147
|
* the searchable body, so RetryInfo's `retryDelay` is honoured wherever it sits.
|
|
148
148
|
*
|
|
149
149
|
* `unknown` is floored to "overload" rather than kept: a stream that dies after
|
|
150
150
|
* its headers is by construction a transient upstream fault, and "unknown" is
|
|
151
|
-
* never retried. Everything the body
|
|
151
|
+
* never retried. Everything the body does name keeps its own kind, which is
|
|
152
152
|
* what tells the caller to wait, rotate a key, or compact instead of retrying
|
|
153
153
|
* a failure that will repeat.
|
|
154
154
|
*/
|
|
@@ -161,7 +161,7 @@ export declare function streamError(provider: string, error: unknown): ProviderE
|
|
|
161
161
|
* read it: a caller that never checks the finish keeps half an answer as if it
|
|
162
162
|
* were the whole one, the ledger records a billed turn as free, and no pool
|
|
163
163
|
* learns the endpoint is dropping streams. cc-proxy shipped the same fix
|
|
164
|
-
* (0.1.39) for the same reason
|
|
164
|
+
* (0.1.39) for the same reason: "instead of marking affected streamed
|
|
165
165
|
* responses as successful".
|
|
166
166
|
*
|
|
167
167
|
* `network`, because that is what it is: the same failure as a socket that
|
|
@@ -170,7 +170,7 @@ export declare function streamError(provider: string, error: unknown): ProviderE
|
|
|
170
170
|
* is not (invariant 1), and reaches the caller after everything it delivered.
|
|
171
171
|
*/
|
|
172
172
|
export declare function streamCut(provider: string): ProviderError;
|
|
173
|
-
/** The
|
|
173
|
+
/** The failure details you can log, so a dead run never reads
|
|
174
174
|
* "400 status code (no body)". */
|
|
175
175
|
export declare function describeProviderError(err: unknown): Record<string, unknown>;
|
|
176
176
|
/**
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAYA,OAAO,EAA+C,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACpG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,qEAAqE;AACrE,MAAM,MAAM,SAAS;AACnB
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.js
CHANGED
|
@@ -44,7 +44,7 @@ export function isBackupEligible(kind) {
|
|
|
44
44
|
* 1. Caller aborts are never retryable.
|
|
45
45
|
* 2. An explicit `shouldRetry` directive on ProviderError (e.g. from server `x-should-retry`)
|
|
46
46
|
* 3. Non-retryable kinds (quota, context, model, entitlement, content, invalid) return false.
|
|
47
|
-
* 4. Excessive retry-after waits (exceeding `maxWaitMs`) return false
|
|
47
|
+
* 4. Excessive retry-after waits (exceeding `maxWaitMs`) return false. Long waits belong to fallbacks.
|
|
48
48
|
* 5. Transient kinds (rate, overload, network, timeout) return true.
|
|
49
49
|
* 6. Transport-level network faults (fetch failed, connection lost, SSL blips) return true.
|
|
50
50
|
*/
|
|
@@ -80,7 +80,7 @@ export class ProviderError extends Error {
|
|
|
80
80
|
window;
|
|
81
81
|
/** Explicit server directive (`x-should-retry`), overriding default classification. */
|
|
82
82
|
shouldRetry;
|
|
83
|
-
/** The provider's own response body, truncated
|
|
83
|
+
/** The provider's own response body, truncated. It carries the actual reason,
|
|
84
84
|
* otherwise lost behind "400 status code (no body)". */
|
|
85
85
|
body;
|
|
86
86
|
constructor(provider, kind, message, opts = {}) {
|
|
@@ -163,7 +163,7 @@ export function messageOf(err) {
|
|
|
163
163
|
* Everything readable about the failure as one searchable string: the message
|
|
164
164
|
* plus the parsed provider body. SDKs park the parsed body on `.error`, and
|
|
165
165
|
* that is where the real reason lives ("max_tokens too large", the quotaId,
|
|
166
|
-
* `"type": "billing_error"`). Scanned as
|
|
166
|
+
* `"type": "billing_error"`). Scanned as text: the error-type strings
|
|
167
167
|
* serialize into it, so no JSON walking is needed.
|
|
168
168
|
*/
|
|
169
169
|
function bodyTextOf(err) {
|
|
@@ -238,7 +238,7 @@ function isAbort(err) {
|
|
|
238
238
|
* A transport fault: the socket died before or during the response, so there
|
|
239
239
|
* is NO status and no body for the patterns below to read.
|
|
240
240
|
*
|
|
241
|
-
* The chain is walked because the useful code is rarely on the thrown error
|
|
241
|
+
* The chain is walked because the useful code is rarely on the thrown error:
|
|
242
242
|
* it sits on `cause`, sometimes several wrappers deep. Without this walk every
|
|
243
243
|
* network blip classifies as permanent, and a long run dies on its first
|
|
244
244
|
* hiccup, which is the single likeliest way to lose a minutes-long job.
|
|
@@ -398,7 +398,7 @@ const CONTENT_PATTERNS = [
|
|
|
398
398
|
* A throttle said in words rather than in a 429.
|
|
399
399
|
*
|
|
400
400
|
* Every other kind has body evidence; rate had only the status, which is
|
|
401
|
-
* exactly the evidence an in-band failure lacks
|
|
401
|
+
* exactly the evidence an in-band failure lacks. An SSE response is already
|
|
402
402
|
* 200 when the throttle lands, so the reason arrives as a payload with no
|
|
403
403
|
* status line at all. Checked below the status branches, so it only ever
|
|
404
404
|
* catches what would otherwise fall through to "unknown".
|
|
@@ -440,18 +440,18 @@ const matches = (patterns, text) => patterns.some((pattern) => pattern.test(text
|
|
|
440
440
|
* The kind of failure, from whatever was thrown.
|
|
441
441
|
*
|
|
442
442
|
* Body patterns outrank status for the 4xx family; within them, context beats
|
|
443
|
-
* entitlement beats quota beats auth
|
|
443
|
+
* entitlement beats quota beats auth. Each earlier category's fix is useless
|
|
444
444
|
* for the later ones.
|
|
445
445
|
*/
|
|
446
446
|
/**
|
|
447
|
-
* The kind of a failure that arrived as an HTTP response
|
|
447
|
+
* The kind of a failure that arrived as an HTTP response: a status and a body,
|
|
448
448
|
* with nothing thrown.
|
|
449
449
|
*
|
|
450
450
|
* `classify` below is for a caught error, and it reads `status` and the body
|
|
451
451
|
* text off that error when they are not passed separately. A response has no
|
|
452
452
|
* error object, so callers were inventing one to fill the slot: a bare body
|
|
453
453
|
* string, the same text twice, a `{ status, error }` literal. All three are
|
|
454
|
-
* inert
|
|
454
|
+
* inert (nothing on them can satisfy `isAbort` or `isTransportFailure`), so
|
|
455
455
|
* they were three spellings of `undefined`.
|
|
456
456
|
*/
|
|
457
457
|
export function classifyHttp(status, body) {
|
|
@@ -521,7 +521,7 @@ export function classify(err, status, body) {
|
|
|
521
521
|
/**
|
|
522
522
|
* How long the provider asked us to wait, in ms. Two dialects: Gemini's
|
|
523
523
|
* RetryInfo (`"retryDelay": "52s"`, inside the body) and the `Retry-After`
|
|
524
|
-
* header, which SDKs keep on the error. Honouring it beats guessing
|
|
524
|
+
* header, which SDKs keep on the error. Honouring it beats guessing: a
|
|
525
525
|
* backoff shorter than the window just burns an attempt.
|
|
526
526
|
*/
|
|
527
527
|
export function parseRetryAfterMs(err, body) {
|
|
@@ -604,14 +604,14 @@ export function parseContextOverflow(err, body) {
|
|
|
604
604
|
* completion: retry sees nothing to retry, and a key pool never rotates off an
|
|
605
605
|
* exhausted key.
|
|
606
606
|
*
|
|
607
|
-
* `error` is the vendor's own payload, whatever shape it came in
|
|
607
|
+
* `error` is the vendor's own payload, whatever shape it came in: the numeric
|
|
608
608
|
* HTTP `code` Gemini and OpenRouter use, the slug OpenAI and Anthropic put in
|
|
609
609
|
* `code`/`type`, the canonical `status` name. The whole thing serializes into
|
|
610
610
|
* the searchable body, so RetryInfo's `retryDelay` is honoured wherever it sits.
|
|
611
611
|
*
|
|
612
612
|
* `unknown` is floored to "overload" rather than kept: a stream that dies after
|
|
613
613
|
* its headers is by construction a transient upstream fault, and "unknown" is
|
|
614
|
-
* never retried. Everything the body
|
|
614
|
+
* never retried. Everything the body does name keeps its own kind, which is
|
|
615
615
|
* what tells the caller to wait, rotate a key, or compact instead of retrying
|
|
616
616
|
* a failure that will repeat.
|
|
617
617
|
*/
|
|
@@ -629,7 +629,7 @@ export function streamError(provider, error) {
|
|
|
629
629
|
});
|
|
630
630
|
}
|
|
631
631
|
/** The reset a stream error carries: the body's clock, plus the rate-limit
|
|
632
|
-
* headers the ChatGPT backend mirrors
|
|
632
|
+
* headers the ChatGPT backend mirrors into its error frame, the only place a
|
|
633
633
|
* failure after the 200 can say which window ran out. */
|
|
634
634
|
function readReset(error, body) {
|
|
635
635
|
const raw = typeof error === "object" && error !== null
|
|
@@ -652,7 +652,7 @@ function readReset(error, body) {
|
|
|
652
652
|
* read it: a caller that never checks the finish keeps half an answer as if it
|
|
653
653
|
* were the whole one, the ledger records a billed turn as free, and no pool
|
|
654
654
|
* learns the endpoint is dropping streams. cc-proxy shipped the same fix
|
|
655
|
-
* (0.1.39) for the same reason
|
|
655
|
+
* (0.1.39) for the same reason: "instead of marking affected streamed
|
|
656
656
|
* responses as successful".
|
|
657
657
|
*
|
|
658
658
|
* `network`, because that is what it is: the same failure as a socket that
|
|
@@ -663,7 +663,7 @@ function readReset(error, body) {
|
|
|
663
663
|
export function streamCut(provider) {
|
|
664
664
|
return new ProviderError(provider, "network", `${provider}: the stream ended before the turn did`);
|
|
665
665
|
}
|
|
666
|
-
/** The
|
|
666
|
+
/** The failure details you can log, so a dead run never reads
|
|
667
667
|
* "400 status code (no body)". */
|
|
668
668
|
export function describeProviderError(err) {
|
|
669
669
|
if (err instanceof ProviderError) {
|
package/dist/image.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface ImageLimits {
|
|
|
5
5
|
minSide: number;
|
|
6
6
|
/** Smallest area, in square pixels. */
|
|
7
7
|
minArea: number;
|
|
8
|
-
/** Largest decoded size
|
|
8
|
+
/** Largest decoded size in bytes (width × height × bytes per pixel). */
|
|
9
9
|
maxDecodedBytes: number;
|
|
10
10
|
/** Most images in one request. The newest win; older ones become notes. */
|
|
11
11
|
maxImages: number;
|
package/dist/image.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAyC,MAAM,YAAY,CAAC;AAErF,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAyC,MAAM,YAAY,CAAC;AAErF,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC;IACxB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;CACnB;AAiID;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,WAAW,EAAE,CAmC/F"}
|
package/dist/jev.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type JevInstructions = string | Record<string, unknown> | readonly unknow
|
|
|
9
9
|
export interface ChoiceQuestion<Option extends string = string> {
|
|
10
10
|
type: "choice";
|
|
11
11
|
instructions?: JevInstructions;
|
|
12
|
-
/** Each option, mapped to what it means
|
|
12
|
+
/** Each option, mapped to what it means. Use `null` when its name says it all.
|
|
13
13
|
* TypeSafe takes up to 255. */
|
|
14
14
|
criteria: Record<Option, unknown>;
|
|
15
15
|
}
|
|
@@ -38,7 +38,7 @@ export interface ChoiceAnswer<Option extends string = string> {
|
|
|
38
38
|
* because a caller acting on it needs more than the pick: the runner-up,
|
|
39
39
|
* P(yes) when the pick was no, a joint probability across two questions. */
|
|
40
40
|
probabilities: Record<Option, number>;
|
|
41
|
-
/** How peaked `probabilities` is, 0 to 1
|
|
41
|
+
/** How peaked `probabilities` is, from 0 to 1. Not the probability of the pick.
|
|
42
42
|
* TypeSafe's own example spreads 0.57 / 0.43 and reports 0.35, so reading
|
|
43
43
|
* it as P(pick) would put the pick below the option it beat. Null when the
|
|
44
44
|
* host sent none. */
|
|
@@ -60,17 +60,17 @@ export interface ScoreAnswer {
|
|
|
60
60
|
confidence: number | null;
|
|
61
61
|
}
|
|
62
62
|
export type JevAnswer = ChoiceAnswer | NoulAnswer | ScoreAnswer;
|
|
63
|
-
/** The answer type a question gets back
|
|
63
|
+
/** The answer type a question gets back. A choice's options carry through. */
|
|
64
64
|
export type AnswerTo<Q> = Q extends ChoiceQuestion<infer Option extends string> ? ChoiceAnswer<Option> : Q extends NoulQuestion ? NoulAnswer : Q extends ScoreQuestion ? ScoreAnswer : never;
|
|
65
65
|
export interface JevReply<Q extends Record<string, JevQuestion>> {
|
|
66
|
-
/** One per question
|
|
66
|
+
/** One per question. `null` when that answer did not pass the checks in
|
|
67
67
|
* `readAnswer`. Each fails alone: in a fan-out, a malformed answer to a
|
|
68
68
|
* question the caller never acts on must not cost the one it does. */
|
|
69
69
|
answers: {
|
|
70
70
|
[Id in keyof Q]: AnswerTo<Q[Id]> | null;
|
|
71
71
|
};
|
|
72
72
|
usage: TokenUsage;
|
|
73
|
-
/** The model that answered, as the host names it
|
|
73
|
+
/** The model that answered, as the host names it: `jev-1.13.0` on
|
|
74
74
|
* TypeSafe, `typesafe/jev-1.13-20260917` on OpenRouter. */
|
|
75
75
|
model: string;
|
|
76
76
|
}
|
|
@@ -99,14 +99,14 @@ export interface JevClient {
|
|
|
99
99
|
}): Promise<JevReply<Q>>;
|
|
100
100
|
/** Proves the key, the account and the model work, with one real question:
|
|
101
101
|
* about 40 input tokens, a few millionths of a dollar. A free read (a
|
|
102
|
-
* model list, a balance) proves only the key
|
|
103
|
-
* run this model
|
|
102
|
+
* model list, a balance) proves only the key, not that this account can
|
|
103
|
+
* run this model. Vercel has no such free read. Throws the classified failure. */
|
|
104
104
|
checkKey(opts?: {
|
|
105
105
|
signal?: AbortSignal;
|
|
106
106
|
}): Promise<void>;
|
|
107
107
|
}
|
|
108
108
|
/**
|
|
109
|
-
* One answer, checked against the question that asked it
|
|
109
|
+
* One answer, checked against the question that asked it, or null.
|
|
110
110
|
*
|
|
111
111
|
* A Jev answer usually becomes an action (a click, a label, a route), so it is
|
|
112
112
|
* read fail-closed: the right type; for a choice, a pick among the offered
|
|
@@ -115,7 +115,7 @@ export interface JevClient {
|
|
|
115
115
|
* the pick.
|
|
116
116
|
*
|
|
117
117
|
* `ask` runs this on every answer. It is exported for the app that has to
|
|
118
|
-
* keep its own request
|
|
118
|
+
* keep its own request (its own error copy, its own auth refresh) and can
|
|
119
119
|
* still take the checks.
|
|
120
120
|
*/
|
|
121
121
|
export declare function readAnswer<Q extends JevQuestion>(question: Q, raw: unknown): AnswerTo<Q> | null;
|
package/dist/jev.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jev.d.ts","sourceRoot":"","sources":["../src/jev.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGxE,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;AAE1E;gEACgE;AAChE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,OAAO,EAAE,CAAC;AAEpF,uBAAuB;AACvB,MAAM,WAAW,cAAc,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM;IAC5D,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B;oCACgC;IAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,8BAA8B;AAC9B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,eAAe,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C;AAED,mCAAmC;AACnC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,wDAAwD;IACxD,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;CAC9B;AAED,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,YAAY,GAAG,aAAa,CAAC;AAExE,MAAM,WAAW,YAAY,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM;IAC1D,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf;;iFAE6E;IAC7E,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC;;;0BAGsB;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd;iCAC6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd;sBACkB;IAClB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,CAAC;AAEhE
|
|
1
|
+
{"version":3,"file":"jev.d.ts","sourceRoot":"","sources":["../src/jev.ts"],"names":[],"mappings":"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"}
|