@plurnk/plurnk-providers 1.6.0 → 1.7.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.
Files changed (91) hide show
  1. package/.env.defaults +9 -16
  2. package/README.md +17 -0
  3. package/SPEC.md +128 -45
  4. package/dist/AiSdkProvider.d.ts +16 -9
  5. package/dist/AiSdkProvider.d.ts.map +1 -1
  6. package/dist/AiSdkProvider.js +151 -54
  7. package/dist/AiSdkProvider.js.map +1 -1
  8. package/dist/Mock.d.ts +8 -4
  9. package/dist/Mock.d.ts.map +1 -1
  10. package/dist/Mock.js +53 -18
  11. package/dist/Mock.js.map +1 -1
  12. package/dist/Pool.d.ts +8 -4
  13. package/dist/Pool.d.ts.map +1 -1
  14. package/dist/Pool.js +68 -12
  15. package/dist/Pool.js.map +1 -1
  16. package/dist/accounting.d.ts.map +1 -1
  17. package/dist/accounting.js.map +1 -1
  18. package/dist/accountingPublic.d.ts +5 -0
  19. package/dist/accountingPublic.d.ts.map +1 -0
  20. package/dist/accountingPublic.js +3 -0
  21. package/dist/accountingPublic.js.map +1 -0
  22. package/dist/capacity.d.ts +26 -0
  23. package/dist/capacity.d.ts.map +1 -0
  24. package/dist/capacity.js +90 -0
  25. package/dist/capacity.js.map +1 -0
  26. package/dist/catalogProvider.d.ts +2 -1
  27. package/dist/catalogProvider.d.ts.map +1 -1
  28. package/dist/catalogProvider.js +18 -20
  29. package/dist/catalogProvider.js.map +1 -1
  30. package/dist/compatibleProvider.d.ts.map +1 -1
  31. package/dist/compatibleProvider.js +10 -7
  32. package/dist/compatibleProvider.js.map +1 -1
  33. package/dist/env.d.ts +8 -10
  34. package/dist/env.d.ts.map +1 -1
  35. package/dist/env.js +54 -37
  36. package/dist/env.js.map +1 -1
  37. package/dist/errors.d.ts +6 -22
  38. package/dist/errors.d.ts.map +1 -1
  39. package/dist/errors.js +30 -91
  40. package/dist/errors.js.map +1 -1
  41. package/dist/index.d.ts +4 -3
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +2 -1
  44. package/dist/index.js.map +1 -1
  45. package/dist/promptTokens.d.ts.map +1 -1
  46. package/dist/promptTokens.js +7 -4
  47. package/dist/promptTokens.js.map +1 -1
  48. package/dist/providerError.d.ts +25 -0
  49. package/dist/providerError.d.ts.map +1 -0
  50. package/dist/providerError.js +91 -0
  51. package/dist/providerError.js.map +1 -0
  52. package/dist/sdkModels.d.ts +1 -0
  53. package/dist/sdkModels.d.ts.map +1 -1
  54. package/dist/sdkModels.js +5 -8
  55. package/dist/sdkModels.js.map +1 -1
  56. package/dist/types.d.ts +24 -4
  57. package/dist/types.d.ts.map +1 -1
  58. package/dist/usage.d.ts +1 -0
  59. package/dist/usage.d.ts.map +1 -1
  60. package/dist/usage.js +7 -2
  61. package/dist/usage.js.map +1 -1
  62. package/package.json +22 -7
  63. package/src/AiSdkProvider.test.ts +198 -37
  64. package/src/AiSdkProvider.ts +192 -59
  65. package/src/Mock.test.ts +32 -18
  66. package/src/Mock.ts +58 -19
  67. package/src/Pool.test.ts +71 -13
  68. package/src/Pool.ts +78 -13
  69. package/src/ProviderRegistry.test.ts +1 -1
  70. package/src/accounting.ts +0 -1
  71. package/src/accountingPublic.ts +9 -0
  72. package/src/boundaries.test.ts +28 -15
  73. package/src/capacity.test.ts +92 -0
  74. package/src/capacity.ts +140 -0
  75. package/src/catalogProvider.test.ts +82 -9
  76. package/src/catalogProvider.ts +24 -21
  77. package/src/compatibleProvider.test.ts +1 -2
  78. package/src/compatibleProvider.ts +10 -7
  79. package/src/cost.test.ts +31 -0
  80. package/src/env.test.ts +49 -20
  81. package/src/env.ts +114 -51
  82. package/src/errors.test.ts +33 -0
  83. package/src/errors.ts +38 -134
  84. package/src/index.ts +5 -2
  85. package/src/ollama.test.ts +1 -2
  86. package/src/promptTokens.ts +8 -5
  87. package/src/providerError.ts +139 -0
  88. package/src/sdkModels.test.ts +2 -5
  89. package/src/sdkModels.ts +6 -8
  90. package/src/types.ts +41 -19
  91. package/src/usage.ts +7 -2
package/.env.defaults CHANGED
@@ -13,6 +13,14 @@
13
13
  # and model facts. {§model-fact-resolution} defines precedence per fact; there is
14
14
  # no live price fetch. Secret VALUES never belong here.
15
15
 
16
+ # --- Generation envelope ({§provider-generation-envelope}, #242) ---
17
+ # OUTPUT_BUDGET is one total response ceiling, including hidden reasoning. It accepts a
18
+ # percentage of the effective context window or an absolute token count and is always
19
+ # capped by known model output limits. REASONING_BUDGET is an optional subset of that
20
+ # total; leave it unset for provider-adaptive depth. Both are alias-scopable.
21
+ PLURNK_PROVIDERS_OUTPUT_BUDGET=35%
22
+ # PLURNK_PROVIDERS_REASONING_BUDGET=8192
23
+
16
24
  # --- Side-channel reasoning (SPEC §4, #32/#33/#399) ---
17
25
  # ACTIVATION and BUDGET are separate so a numeric can never silently flip wire flags.
18
26
  # off | adaptive | on. The provider maps intent to each backend's native mechanism
@@ -20,10 +28,6 @@
20
28
  # defer activation and depth to the backend's documented default. Use an alias-scoped
21
29
  # ON when a reasoning-capable model defaults off and the operator wants it enabled.
22
30
  PLURNK_PROVIDERS_REASONING=adaptive
23
- # Optional positive int when REASONING=on. Without one, ON activates reasoning at
24
- # the adapter's ordinary enabled posture. On llama-server an explicit value is a
25
- # request-scoped allowance and may tighten, but cannot exceed, the resolved reserve.
26
- # PLURNK_PROVIDERS_REASONING_BUDGET=4096
27
31
 
28
32
  # Response-content interpretation ({§provider-tagged-reasoning}) is independent
29
33
  # from request-side reasoning activation. The portable floor trusts only
@@ -112,7 +116,7 @@ PLURNK_PROVIDERS_PROBE_DELAY=250
112
116
  # Effective total context envelope. Unset derives natural capacity from a live endpoint probe
113
117
  # (n_ctx) or models.dev, else null (surfaced once via PLURNK_CONTEXT_UNKNOWN). A configured
114
118
  # value is a final hard cap on known capacity or declares the envelope when unknown. Model-facing
115
- # prompt pressure is separate consumer policy.
119
+ # curation pressure is separate consumer policy.
116
120
  # PLURNK_PROVIDERS_CONTEXT_WINDOW=200000
117
121
 
118
122
  # --- llama-server detection pin (#34) ---
@@ -176,14 +180,3 @@ OPENAI_BASE_URL=https://api.openai.com/v1
176
180
  # PLURNK_API_KEY is an optional bearer; the endpoint is eventually keyless.
177
181
  PLURNK_BASE_URL=https://plurnk.ai/v1
178
182
  # PLURNK_BASE_URL=http://plurnksnr2kihuukt6v22ko72r34dxeatbsfhgow3hvnlw6btanxphad.onion/v1 # Tor
179
-
180
- # --- Generation envelope (#507) - sane defaults from the DETECTED window ---
181
- # When a backend advertises its context window (llama-server n_ctx, the plurnk.ai router,
182
- # a cataloged cloud model), the reserves derive from it automatically - ZERO operator
183
- # tuning. Each accepts a percentage of the window ("10%") or an absolute token count
184
- # ("4096"; absolutes win outright, alias-scopable for measured envelopes). The prompt
185
- # budget is window - reasoning - completion - the consumer's own safety margin.
186
- # On llama-server, the resolved reasoning reserve is also the adaptive per-response
187
- # reasoning ceiling. It is one cumulative allowance across every reasoning block.
188
- PLURNK_PROVIDERS_REASONING_RESERVE=10%
189
- PLURNK_PROVIDERS_COMPLETION_RESERVE=25%
package/README.md CHANGED
@@ -21,6 +21,23 @@ reasoning activation, and estimated prices resolve independently
21
21
  ({§model-fact-resolution}). PLURNK does not fetch live per-token prices, and the
22
22
  local estimate is not an authoritative relay-settled charge.
23
23
 
24
+ ## Runtime-neutral contracts
25
+
26
+ Browser and edge Workers import accounting and normalized failures through
27
+ their dedicated runtime-neutral subpaths
28
+ ({§provider-runtime-neutral-accounting}, {§provider-runtime-neutral-errors}):
29
+
30
+ ```js
31
+ import {
32
+ aggregateProviderAccounting,
33
+ estimateProviderCost,
34
+ } from "@plurnk/plurnk-providers/accounting";
35
+ import { ProviderError } from "@plurnk/plurnk-providers/errors";
36
+ ```
37
+
38
+ The package root composes the complete Node provider runtime, including plugin
39
+ discovery and environment-file defaults.
40
+
24
41
  ## Configure a model
25
42
 
26
43
  Declare an alias, then select it:
package/SPEC.md CHANGED
@@ -9,8 +9,8 @@ ordinary provider protocols.
9
9
  The provider stack has four owners:
10
10
 
11
11
  1. Models.dev supplies a release-time snapshot of provider package, API
12
- endpoint, credential names, models, context windows, output limits,
13
- reasoning capability, and USD prices.
12
+ endpoint, credential names, models, context/input/output limits, reasoning
13
+ capability, and USD rates including distinct reasoning rates when supplied.
14
14
  2. Official AI SDK providers own vendor request and response protocols.
15
15
  3. This package owns the PLURNK contract: aliases, envelopes, normalized usage
16
16
  and errors, evidence, local capabilities, and first-party metadata.
@@ -22,6 +22,18 @@ model prefix, context window, price, or vendor request shape into a PLURNK
22
22
  table. A missing or wrong catalog fact is fixed upstream, overridden through a
23
23
  provider declaration, or left explicitly unknown.
24
24
 
25
+ The package exposes two runtime-neutral public surfaces:
26
+
27
+ | Surface | Contract |
28
+ | --- | --- |
29
+ | §provider-runtime-neutral-accounting `@plurnk/plurnk-providers/accounting` | Provider-request aggregation, Models.dev cost estimation, and their wire types. |
30
+ | §provider-runtime-neutral-errors `@plurnk/plurnk-providers/errors` | Normalized `ProviderError`, `ProviderErrorKind`, and the types of its attempt, accounting, and capacity evidence. |
31
+
32
+ Both surfaces re-export the package's sole implementations without evaluating
33
+ Node-only provider discovery, filesystem defaults, or runtime construction.
34
+ The package root remains the Node provider-runtime composition surface and is
35
+ not a Worker entrypoint.
36
+
25
37
  ## §2 Provider interface
26
38
 
27
39
  §provider-interface `Provider` exposes immutable model facts and one generation
@@ -31,16 +43,24 @@ operation:
31
43
  interface Provider {
32
44
  readonly model: string;
33
45
  readonly contextWindow: number | null;
46
+ readonly maxInputTokens: number | null;
47
+ readonly maxOutputTokens: number | null;
48
+ readonly outputBudget: number | null;
49
+ readonly reasoningBudget: number | null;
50
+ readonly inputCapacity: number | null;
34
51
  readonly servedModel?: string;
35
52
  readonly constrainsOutput?: boolean;
36
- readonly requiresMaxTokens?: boolean;
37
- readonly reasoningReserve?: number | null;
38
- readonly completionReserve?: number | null;
53
+ readonly requiresOutputBudget?: boolean;
39
54
 
40
55
  countPromptTokens(
41
56
  messages: readonly ChatMessage[],
42
57
  signal?: AbortSignal,
43
58
  ): Promise<PromptTokenMeasurement>;
59
+ assessRequestCapacity(
60
+ messages: readonly ChatMessage[],
61
+ maxOutputTokens?: number,
62
+ signal?: AbortSignal,
63
+ ): Promise<ProviderRequestCapacity>;
44
64
  tokenize?(text: string): Promise<number[]>;
45
65
  generate(args: GenerateArgs): Promise<ProviderResponse>;
46
66
  }
@@ -52,22 +72,38 @@ operator cap. `null` means genuinely unknown; a consumer MUST NOT invent a
52
72
  stand-in. The context-window knob is a hard cap, never model-facing grinder
53
73
  pressure.
54
74
 
55
- `PromptTokenMeasurement` is a discriminated request-level result:
75
+ §provider-prompt-measurement `PromptTokenMeasurement` is a discriminated
76
+ request-level result:
56
77
 
57
- | `kind` | Meaning | May authorize hard context-envelope admission |
58
- | ------------- | ------------------------------------------------------ | --------------------------------------------- |
59
- | `exact` | Exact count for the complete provider request. | Yes. |
60
- | `upper_bound` | Proven upper bound for the complete provider request. | Yes. |
61
- | `estimate` | Empirical prediction with required causal `detail`. | No. |
78
+ | `kind` | Meaning | Capacity authority |
79
+ | --- | --- | --- |
80
+ | `exact` | Exact count for the complete provider request. | May prove fit or overflow. |
81
+ | `upper_bound` | Proven upper bound for the complete provider request. | May prove fit; exceeding a limit does not prove overflow. |
82
+ | `estimate` | Empirical prediction with required causal `detail`. | Cannot admit or reject. |
83
+ | `unavailable` | No quantified measurement, with required causal `detail`. | Cannot admit or reject. |
62
84
 
63
- Every result carries a non-negative integer `tokens` and a non-empty `source`.
85
+ Every result carries a non-empty `source`; quantified kinds carry non-negative
86
+ integer `tokens`.
64
87
  `countPromptTokens` receives the same messages supplied to `generate` and may
65
88
  perform cancellable provider I/O. The common fallback is chars/2 over message
66
89
  content; it is announced once and reported honestly as an estimate because it
67
90
  knows neither the serving vocabulary nor provider-owned request framing.
68
- An unavailable optional counting endpoint likewise returns an estimate naming
69
- the cause. A malformed measurement is a provider contract violation and fails
70
- hard; consumers do not reinterpret it as ordinary unavailability.
91
+ An adapter may retain that estimate when an optional counting endpoint fails,
92
+ provided its detail names the cause; one unable to quantify anything returns
93
+ `unavailable`. A malformed measurement is a provider contract violation and
94
+ fails hard.
95
+
96
+ §provider-capacity-admission `assessRequestCapacity` intersects every known
97
+ physical input constraint: independent `maxInputTokens` and
98
+ `contextWindow - outputBudget`. Its result is `admit`, `reject`, or `defer` and
99
+ retains the complete limit and measurement evidence. Exact fit admits; exact
100
+ overflow rejects. A proven upper bound admits only when it fits. Unknown limits,
101
+ an upper bound above a limit, estimates, and unavailable measurements defer to
102
+ the upstream provider as capacity oracle. The same stable intersection is
103
+ exposed as `inputCapacity`; `null` means the available limits cannot establish
104
+ one. A known combined context and output budget must leave positive input
105
+ capacity. Consumers may display or use that fact as policy, but MUST NOT
106
+ substitute their own content heuristic for request-shaped admission.
71
107
 
72
108
  `tokenize` is the separate content-token capability and exists only when the
73
109
  endpoint exposes its real vocabulary. Content tokenization does not substitute
@@ -102,7 +138,7 @@ Providers MUST NOT interpret either value.
102
138
 
103
139
  - `messages`: system, user, and assistant text messages;
104
140
  - caller cancellation through `signal`;
105
- - optional `grammar` and `maxTokens`;
141
+ - optional `grammar` and call-specific `maxOutputTokens` tightening;
106
142
  - standard `sampling` intent;
107
143
  - the caller-owned `callKind` output contract when one applies;
108
144
  - opaque attribution tags plus client, strike, workspace, loop, and turn metadata.
@@ -117,9 +153,10 @@ The signal is request metadata and never enters model-facing messages. Generic
117
153
  provider callers MAY omit it; Core supplies it for every model call.
118
154
 
119
155
  A successful return carries the model's raw content and reasoning, normalized
120
- finish reason, model identity, its ordered {§provider-request-accounting},
121
- opaque evidence, optional metadata, and optional notices. A `ProviderError`
122
- carries the same accounting array. The provider transports and observes model
156
+ finish reason, model identity, its ordered {§provider-request-accounting}, the
157
+ request's `ProviderRequestCapacity`, opaque evidence, optional metadata, and
158
+ optional notices. A `ProviderError` carries the same available capacity and
159
+ accounting evidence. The provider transports and observes model
123
160
  output; it never retries, discards, or repairs an otherwise completed exchange
124
161
  because PLURNK grammar did not accept it.
125
162
 
@@ -195,7 +232,7 @@ the provider adapter; Models.dev's reasoning bit remains capability metadata.
195
232
 
196
233
  The portable SDK surface has no boolean-enabled reasoning value. An unqualified
197
234
  `on` therefore projects to its conventional `medium` enabled posture. This is a
198
- wire activation value, not a reasoning reserve or output-token ceiling.
235
+ wire activation value, not a reasoning budget or output-token ceiling.
199
236
 
200
237
  §provider-cache-affinity **Cache affinity is route-owned request projection.**
201
238
  When a provider documents a semantics-preserving conversation, session, or
@@ -272,16 +309,20 @@ alias.
272
309
 
273
310
  Provider and model facts resolve independently:
274
311
 
275
- | Fact | Natural source | Operator source | Effective value |
276
- | -------------------- | ------------------------------------------------------ | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
277
- | Context window | Catalog metadata or a local endpoint probe. | `PLURNK_PROVIDERS_CONTEXT_WINDOW`. | Minimum when both exist; the sole value otherwise. A cataloged cloud miss fails construction; a compatible probe miss remains `null` with one warning. |
278
- | Completion envelope | Catalog `maxOutput`; there is no live limit probe. | `PLURNK_PROVIDERS_COMPLETION_RESERVE`. | An absolute reserve wins. A percentage derives from the effective window and is capped by catalog `maxOutput` when present. |
279
- | Reasoning capability | Catalog `reasoning: true`, exposed by snapshot lookup. | Runtime activation, reserve, and adapter wire style. | The catalog bit is informational; provider construction neither activates nor blocks reasoning from it. |
280
- | Estimated USD rates | Models.dev input, output, and optional cache-read/cache-write rates. | None. | Missing differently-priced categories or rates produce unknown evidence; exact all-zero rates produce an estimated USD zero. No live price fetch exists. |
281
-
282
- Models.dev cache-read and cache-write cost default to input cost when omitted.
283
- When either differs from input, the corresponding usage detail must be known or
284
- the request estimate is unknown.
312
+ | Fact | Natural source | Operator source | Effective value |
313
+ | --- | --- | --- | --- |
314
+ | Context window | Catalog metadata or local endpoint probe. | `PLURNK_PROVIDERS_CONTEXT_WINDOW`. | Minimum when both exist; sole value otherwise. Cataloged cloud miss fails construction; compatible probe miss remains `null` with one warning. |
315
+ | Maximum input | Catalog `limit.input`; no generic live probe. | None. | Catalog value or `null`; never reconstructed from context and output. |
316
+ | Maximum output | Catalog `limit.output`; no generic live probe. | None. | Minimum of catalog value and effective context, or `null`. |
317
+ | Total output budget | None. | `PLURNK_PROVIDERS_OUTPUT_BUDGET`. | Percentage of effective context or absolute count, capped by known context/output limits; a call may only tighten it. |
318
+ | Reasoning budget | None. | Optional `PLURNK_PROVIDERS_REASONING_BUDGET`. | Percentage of effective context or absolute count; valid only as a strict subset of total output and effective only while reasoning is on or adaptive. |
319
+ | Reasoning capability | Catalog `reasoning: true`. | Runtime activation and adapter wire style. | Catalog bit remains informational; it neither activates nor blocks reasoning. |
320
+ | Estimated USD rates | Models.dev input, output, optional reasoning, and optional cache rates. | None. | Missing differently-priced usage or rates produces unknown; exact all-zero rates produces estimated USD zero. |
321
+
322
+ Models.dev cache-read and cache-write rates default to the input rate, and the
323
+ reasoning rate defaults to the output rate, when omitted. A differently priced
324
+ category requires its corresponding usage detail or the request estimate is
325
+ unknown.
285
326
 
286
327
  `instantiateProvider` resolves in this order:
287
328
 
@@ -356,7 +397,7 @@ also expose:
356
397
  - EOS marker removal;
357
398
  - exact complete-request counting through `/v1/chat/completions/input_tokens`;
358
399
  - exact content token IDs through `/tokenize`;
359
- - the requirement that the caller provide `maxTokens`.
400
+ - the requirement that the adapter apply a finite output budget.
360
401
 
361
402
  `PLURNK_PROVIDERS_LLAMA_SERVER` may force or disable detection. Probe attempts
362
403
  and delay are knobs. A failed probe does not silently assert capabilities.
@@ -372,12 +413,11 @@ every request:
372
413
  | Posture | Template activation | `thinking_budget_tokens` |
373
414
  |---|---:|---:|
374
415
  | `off` | false | `0` |
375
- | `adaptive` | true | resolved reasoning reserve |
376
- | `on` | true | resolved reasoning reserve |
377
- | `on` + budget | true | explicit reasoning budget |
416
+ | `adaptive` | true | configured reasoning subset, otherwise omitted |
417
+ | `on` | true | configured reasoning subset, otherwise omitted |
378
418
 
379
- The explicit budget may tighten but MUST NOT exceed the resolved reasoning
380
- reserve. Template calls normally use `reasoning_format: "auto"` for a separate
419
+ The allowance is contained by the request's total output budget. Template calls
420
+ normally use `reasoning_format: "auto"` for a separate
381
421
  readable channel. A GBNF-bearing call uses `"none"` so the exact constrained
382
422
  sentence survives response projection; the adapter separates its leading
383
423
  reasoning enclosure only after preserving grammar evidence. Process-wide
@@ -425,6 +465,16 @@ normal value. Retry exhaustion is preserved as `attempts` and
425
465
  `retryExhausted`, and the resulting Problem is not marked retryable after the
426
466
  provider has consumed its automatic retry budget.
427
467
 
468
+ §provider-capacity-failure A proven exact preflight overflow and an upstream
469
+ context rejection normalize to `ProviderError(kind="capacity_exceeded")` and
470
+ an RFC 9457 status 413. `capacityStage` is `preflight` or `upstream`; a
471
+ non-413 upstream status remains `providerStatus`, while physical request
472
+ accounting retains the status actually received. Preflight rejection occurs
473
+ before provider I/O and therefore opens no request identity and creates no
474
+ request-accounting row. Capacity failures are not connectivity failures and are
475
+ never retried by the provider scheduler; bounded packet recovery belongs to the
476
+ consumer.
477
+
428
478
  §provider-connectivity The provider adapter owns one attempt scheduler around
429
479
  the complete generation exchange; SDK-internal retries are disabled.
430
480
  `PLURNK_PROVIDERS_RETRY_ATTEMPTS=N` permits at most `N + 1` physical requests.
@@ -492,7 +542,6 @@ The consumer validates `grammarEvidence.input` outside the enforcer's failure
492
542
  domain. `PLURNK_PROVIDERS_GBNF_DEBUG` still validates grammar syntax before the
493
543
  call and sets `transported: false` for the unconstrained comparison.
494
544
 
495
-
496
545
  ## §11 Evidence and metadata
497
546
 
498
547
  §provider-evidence `assistantRaw` is an opaque normalized transport record.
@@ -523,11 +572,35 @@ correlate them to an entity it actually created rather than reusing `id`.
523
572
 
524
573
  ## §12 Generation envelopes
525
574
 
526
- §provider-generation-envelope Reasoning and completion reserves are percentages
527
- of the resolved context
528
- window or absolute token counts. Absolute pins win. The provider reports the
529
- resolved reserves; the consumer owns prompt packing and the per-call output
530
- cap. Model-limit precedence is defined once in {§model-fact-resolution}.
575
+ §provider-generation-envelope Every request has at most one total output
576
+ budget. It includes visible output and hidden reasoning. An optional reasoning
577
+ budget is a strict subset of that total, never an additive reserve. The
578
+ configured total is a percentage of effective context or an absolute count;
579
+ percentages resolve to the nearest whole token with a one-token minimum. It is
580
+ capped by known context and model-output limits; `generate.maxOutputTokens` may
581
+ only tighten it for one call. The effective reasoning subset tightens with that
582
+ total and remains strictly smaller.
583
+
584
+ The adapter owns native projection. A backend whose generic SDK maximum already
585
+ includes reasoning receives the total directly. When a native SDK instead adds
586
+ an explicit reasoning allowance to its generic visible-output maximum, the
587
+ adapter sends `total - reasoning` through the generic field and the reasoning
588
+ subset through the documented provider option. Core and other callers never
589
+ reconstruct this arithmetic.
590
+
591
+ §provider-output-budget-conformance When a completed response reports
592
+ normalized output-token usage greater than its effective total output budget,
593
+ the exchange is an `invalid_response` at 502 rather than an admitted result or
594
+ a prompt-capacity 413. Its complete failed-attempt evidence and settled charged
595
+ request remain available. The violation is final and is never automatically
596
+ replayed. Missing output usage cannot prove a violation.
597
+
598
+ `PLURNK_PROVIDERS_OUTPUT_BUDGET` is required for standard providers and ships
599
+ as `35%`. `PLURNK_PROVIDERS_REASONING_BUDGET` is optional; leaving it unset
600
+ preserves provider-adaptive depth. A backend known to decode without a finite
601
+ limit advertises `requiresOutputBudget` and fails construction when no total can
602
+ be resolved. The retired additive reserve knobs fail hard rather than creating
603
+ a second envelope contract.
531
604
 
532
605
  ## §13 Capacity pool
533
606
 
@@ -540,8 +613,13 @@ availability and rate-limit failures that carry no normalized response attempt;
540
613
  {§provider-interrupted-attempt} propagates without overflow.
541
614
 
542
615
  Prompt measurement covers every backend that could receive the request. The
543
- pool takes the largest result; differing exact counts or any proven bound yield
544
- an `upper_bound`, while any estimate makes the aggregate an estimate.
616
+ pool takes the largest quantified result; differing exact counts or any proven
617
+ bound yield an `upper_bound`, any estimate makes the aggregate an estimate, and
618
+ any unavailable backend makes it unavailable. Physical limits and budgets are
619
+ independent safe minima across the pool. `inputCapacity` is the minimum of each
620
+ backend's complete derived input capacity, never a synthetic subtraction across
621
+ minima from different backends; request-specific output tightening repeats the
622
+ complete-envelope derivation per backend before taking the minimum.
545
623
 
546
624
  ## §14 Conformance
547
625
 
@@ -553,7 +631,12 @@ Coverage MUST prove:
553
631
  - compatible extension preservation;
554
632
  - timeout, retry, cancellation, interrupted-attempt, and final-error behavior;
555
633
  - local capability probes and pins;
556
- - exact, bounded, and estimated complete-request token measurements;
634
+ - exact, bounded, estimated, and unavailable complete-request measurements;
635
+ - independent input/context/output limits, asymmetric admission, and normalized
636
+ local/upstream capacity failures;
637
+ - one total output budget and native additive-reasoning projection;
638
+ - provider-reported output beyond that budget failing once with complete
639
+ attempt and accounting evidence;
557
640
  - local reasoning activation, response-wide allowance, and GBNF coexistence;
558
641
  - explicit tagged-reasoning projection across streamed, buffered, capped, and
559
642
  literal-tag responses;
@@ -1,7 +1,7 @@
1
- import type { ChatMessage, PromptTokenMeasurement, Provider, ProviderCostNormalizer, ProviderGenerateArgs, ProviderResponse, ProviderUsage } from "./types.ts";
1
+ import type { ChatMessage, PromptTokenMeasurement, Provider, ProviderCostNormalizer, ProviderGenerateArgs, ProviderRequestCapacity, ProviderResponse, ProviderUsage } from "./types.ts";
2
2
  import type { ProviderCost } from "@plurnk/plurnk-contracts";
3
3
  import type { JSONValue } from "ai";
4
- import type { Reasoning, ReasoningResponseStyle, ReserveSpec } from "./env.ts";
4
+ import type { Reasoning, ReasoningResponseStyle } from "./env.ts";
5
5
  import type { LanguageModel } from "ai";
6
6
  import type { PluginAttribution, PluginAttributionContext } from "@plurnk/plurnk-meta";
7
7
  export type ProviderFetch = typeof globalThis.fetch;
@@ -28,6 +28,11 @@ export type AiSdkProviderConfig = {
28
28
  headers?: Record<string, string>;
29
29
  fetch?: ProviderFetch;
30
30
  contextWindow?: number | null;
31
+ maxInputTokens?: number | null;
32
+ maxOutputTokens?: number | null;
33
+ outputBudget?: number | null;
34
+ reasoningBudget?: number | null;
35
+ additiveReasoningProvider?: "anthropic" | "bedrock";
31
36
  reasoningStyle?: ReasoningStyle;
32
37
  reasoningResponseStyle?: ReasoningResponseStyle;
33
38
  countPromptTokens?: (messages: readonly ChatMessage[], signal?: AbortSignal) => PromptTokenMeasurement | Promise<PromptTokenMeasurement>;
@@ -49,7 +54,7 @@ export type AiSdkProviderConfig = {
49
54
  tokenizeUrl?: string;
50
55
  promptTokensUrl?: string;
51
56
  servedModel?: string;
52
- requiresMaxTokens?: boolean;
57
+ requiresOutputBudget?: boolean;
53
58
  reasoning: Reasoning;
54
59
  temperature: number;
55
60
  repeatPenalty: number;
@@ -62,8 +67,6 @@ export type AiSdkProviderConfig = {
62
67
  errorDetailLimit?: number;
63
68
  topLogprobs?: number | null;
64
69
  rawBody?: boolean;
65
- reasoningReserve?: ReserveSpec;
66
- completionReserve?: ReserveSpec;
67
70
  tuningFloors?: boolean;
68
71
  };
69
72
  export declare const effortFromBudget: (budget: number) => "low" | "medium" | "high";
@@ -73,13 +76,17 @@ export default class AiSdkProvider implements Provider {
73
76
  tokenize?: (text: string) => Promise<number[]>;
74
77
  constructor(config: AiSdkProviderConfig);
75
78
  get contextWindow(): number | null;
76
- get reasoningReserve(): number | null;
77
- get completionReserve(): number | null;
79
+ get maxInputTokens(): number | null;
80
+ get maxOutputTokens(): number | null;
81
+ get outputBudget(): number | null;
82
+ get reasoningBudget(): number | null;
83
+ get inputCapacity(): number | null;
78
84
  get model(): string;
79
85
  get servedModel(): string | undefined;
80
- get requiresMaxTokens(): boolean | undefined;
86
+ get requiresOutputBudget(): boolean | undefined;
81
87
  get constrainsOutput(): boolean;
82
88
  countPromptTokens(messages: readonly ChatMessage[], signal?: AbortSignal): Promise<PromptTokenMeasurement>;
83
- generate({ messages, workerId, primaryWorkerId, signal, grammar, maxTokens, attributions, client, strikes, workspaceId, loop, turn, sampling, observeRequest, callKind }: ProviderGenerateArgs): Promise<ProviderResponse>;
89
+ assessRequestCapacity(messages: readonly ChatMessage[], maxOutputTokens?: number, signal?: AbortSignal): Promise<ProviderRequestCapacity>;
90
+ generate({ messages, workerId, primaryWorkerId, signal, grammar, maxOutputTokens, attributions, client, strikes, workspaceId, loop, turn, sampling, observeRequest, callKind }: ProviderGenerateArgs): Promise<ProviderResponse>;
84
91
  }
85
92
  //# sourceMappingURL=AiSdkProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AiSdkProvider.d.ts","sourceRoot":"","sources":["../src/AiSdkProvider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AiSdkProvider.d.ts","sourceRoot":"","sources":["../src/AiSdkProvider.ts"],"names":[],"mappings":"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"}