@plurnk/plurnk-providers 1.6.0 → 1.6.1

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 (86) hide show
  1. package/.env.defaults +9 -16
  2. package/README.md +15 -0
  3. package/SPEC.md +124 -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 +5 -3
  38. package/dist/errors.d.ts.map +1 -1
  39. package/dist/errors.js +33 -6
  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/sdkModels.d.ts +1 -0
  49. package/dist/sdkModels.d.ts.map +1 -1
  50. package/dist/sdkModels.js +5 -8
  51. package/dist/sdkModels.js.map +1 -1
  52. package/dist/types.d.ts +24 -4
  53. package/dist/types.d.ts.map +1 -1
  54. package/dist/usage.d.ts +1 -0
  55. package/dist/usage.d.ts.map +1 -1
  56. package/dist/usage.js +7 -2
  57. package/dist/usage.js.map +1 -1
  58. package/package.json +17 -7
  59. package/src/AiSdkProvider.test.ts +198 -37
  60. package/src/AiSdkProvider.ts +192 -59
  61. package/src/Mock.test.ts +32 -18
  62. package/src/Mock.ts +58 -19
  63. package/src/Pool.test.ts +71 -13
  64. package/src/Pool.ts +78 -13
  65. package/src/ProviderRegistry.test.ts +1 -1
  66. package/src/accounting.ts +0 -1
  67. package/src/accountingPublic.ts +9 -0
  68. package/src/boundaries.test.ts +1 -0
  69. package/src/capacity.test.ts +92 -0
  70. package/src/capacity.ts +140 -0
  71. package/src/catalogProvider.test.ts +82 -9
  72. package/src/catalogProvider.ts +24 -21
  73. package/src/compatibleProvider.test.ts +1 -2
  74. package/src/compatibleProvider.ts +10 -7
  75. package/src/cost.test.ts +31 -0
  76. package/src/env.test.ts +49 -20
  77. package/src/env.ts +114 -51
  78. package/src/errors.test.ts +33 -0
  79. package/src/errors.ts +41 -6
  80. package/src/index.ts +5 -2
  81. package/src/ollama.test.ts +1 -2
  82. package/src/promptTokens.ts +8 -5
  83. package/src/sdkModels.test.ts +2 -5
  84. package/src/sdkModels.ts +6 -8
  85. package/src/types.ts +41 -19
  86. 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,21 @@ 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 accounting
25
+
26
+ Browser and edge Workers import the accounting contract through its dedicated
27
+ runtime-neutral subpath ({§provider-runtime-neutral-accounting}):
28
+
29
+ ```js
30
+ import {
31
+ aggregateProviderAccounting,
32
+ estimateProviderCost,
33
+ } from "@plurnk/plurnk-providers/accounting";
34
+ ```
35
+
36
+ The package root composes the complete Node provider runtime, including plugin
37
+ discovery and environment-file defaults.
38
+
24
39
  ## Configure a model
25
40
 
26
41
  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,14 @@ 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
+ §provider-runtime-neutral-accounting The public
26
+ `@plurnk/plurnk-providers/accounting` subpath exposes provider-request
27
+ aggregation and Models.dev cost estimation, plus their wire types, without
28
+ evaluating Node-only provider discovery, filesystem defaults, or runtime
29
+ construction. It re-exports the package's sole accounting implementation. The
30
+ package root remains the Node provider-runtime composition surface and is not a
31
+ Worker entrypoint.
32
+
25
33
  ## §2 Provider interface
26
34
 
27
35
  §provider-interface `Provider` exposes immutable model facts and one generation
@@ -31,16 +39,24 @@ operation:
31
39
  interface Provider {
32
40
  readonly model: string;
33
41
  readonly contextWindow: number | null;
42
+ readonly maxInputTokens: number | null;
43
+ readonly maxOutputTokens: number | null;
44
+ readonly outputBudget: number | null;
45
+ readonly reasoningBudget: number | null;
46
+ readonly inputCapacity: number | null;
34
47
  readonly servedModel?: string;
35
48
  readonly constrainsOutput?: boolean;
36
- readonly requiresMaxTokens?: boolean;
37
- readonly reasoningReserve?: number | null;
38
- readonly completionReserve?: number | null;
49
+ readonly requiresOutputBudget?: boolean;
39
50
 
40
51
  countPromptTokens(
41
52
  messages: readonly ChatMessage[],
42
53
  signal?: AbortSignal,
43
54
  ): Promise<PromptTokenMeasurement>;
55
+ assessRequestCapacity(
56
+ messages: readonly ChatMessage[],
57
+ maxOutputTokens?: number,
58
+ signal?: AbortSignal,
59
+ ): Promise<ProviderRequestCapacity>;
44
60
  tokenize?(text: string): Promise<number[]>;
45
61
  generate(args: GenerateArgs): Promise<ProviderResponse>;
46
62
  }
@@ -52,22 +68,38 @@ operator cap. `null` means genuinely unknown; a consumer MUST NOT invent a
52
68
  stand-in. The context-window knob is a hard cap, never model-facing grinder
53
69
  pressure.
54
70
 
55
- `PromptTokenMeasurement` is a discriminated request-level result:
71
+ §provider-prompt-measurement `PromptTokenMeasurement` is a discriminated
72
+ request-level result:
56
73
 
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. |
74
+ | `kind` | Meaning | Capacity authority |
75
+ | --- | --- | --- |
76
+ | `exact` | Exact count for the complete provider request. | May prove fit or overflow. |
77
+ | `upper_bound` | Proven upper bound for the complete provider request. | May prove fit; exceeding a limit does not prove overflow. |
78
+ | `estimate` | Empirical prediction with required causal `detail`. | Cannot admit or reject. |
79
+ | `unavailable` | No quantified measurement, with required causal `detail`. | Cannot admit or reject. |
62
80
 
63
- Every result carries a non-negative integer `tokens` and a non-empty `source`.
81
+ Every result carries a non-empty `source`; quantified kinds carry non-negative
82
+ integer `tokens`.
64
83
  `countPromptTokens` receives the same messages supplied to `generate` and may
65
84
  perform cancellable provider I/O. The common fallback is chars/2 over message
66
85
  content; it is announced once and reported honestly as an estimate because it
67
86
  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.
87
+ An adapter may retain that estimate when an optional counting endpoint fails,
88
+ provided its detail names the cause; one unable to quantify anything returns
89
+ `unavailable`. A malformed measurement is a provider contract violation and
90
+ fails hard.
91
+
92
+ §provider-capacity-admission `assessRequestCapacity` intersects every known
93
+ physical input constraint: independent `maxInputTokens` and
94
+ `contextWindow - outputBudget`. Its result is `admit`, `reject`, or `defer` and
95
+ retains the complete limit and measurement evidence. Exact fit admits; exact
96
+ overflow rejects. A proven upper bound admits only when it fits. Unknown limits,
97
+ an upper bound above a limit, estimates, and unavailable measurements defer to
98
+ the upstream provider as capacity oracle. The same stable intersection is
99
+ exposed as `inputCapacity`; `null` means the available limits cannot establish
100
+ one. A known combined context and output budget must leave positive input
101
+ capacity. Consumers may display or use that fact as policy, but MUST NOT
102
+ substitute their own content heuristic for request-shaped admission.
71
103
 
72
104
  `tokenize` is the separate content-token capability and exists only when the
73
105
  endpoint exposes its real vocabulary. Content tokenization does not substitute
@@ -102,7 +134,7 @@ Providers MUST NOT interpret either value.
102
134
 
103
135
  - `messages`: system, user, and assistant text messages;
104
136
  - caller cancellation through `signal`;
105
- - optional `grammar` and `maxTokens`;
137
+ - optional `grammar` and call-specific `maxOutputTokens` tightening;
106
138
  - standard `sampling` intent;
107
139
  - the caller-owned `callKind` output contract when one applies;
108
140
  - opaque attribution tags plus client, strike, workspace, loop, and turn metadata.
@@ -117,9 +149,10 @@ The signal is request metadata and never enters model-facing messages. Generic
117
149
  provider callers MAY omit it; Core supplies it for every model call.
118
150
 
119
151
  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
152
+ finish reason, model identity, its ordered {§provider-request-accounting}, the
153
+ request's `ProviderRequestCapacity`, opaque evidence, optional metadata, and
154
+ optional notices. A `ProviderError` carries the same available capacity and
155
+ accounting evidence. The provider transports and observes model
123
156
  output; it never retries, discards, or repairs an otherwise completed exchange
124
157
  because PLURNK grammar did not accept it.
125
158
 
@@ -195,7 +228,7 @@ the provider adapter; Models.dev's reasoning bit remains capability metadata.
195
228
 
196
229
  The portable SDK surface has no boolean-enabled reasoning value. An unqualified
197
230
  `on` therefore projects to its conventional `medium` enabled posture. This is a
198
- wire activation value, not a reasoning reserve or output-token ceiling.
231
+ wire activation value, not a reasoning budget or output-token ceiling.
199
232
 
200
233
  §provider-cache-affinity **Cache affinity is route-owned request projection.**
201
234
  When a provider documents a semantics-preserving conversation, session, or
@@ -272,16 +305,20 @@ alias.
272
305
 
273
306
  Provider and model facts resolve independently:
274
307
 
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.
308
+ | Fact | Natural source | Operator source | Effective value |
309
+ | --- | --- | --- | --- |
310
+ | 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. |
311
+ | Maximum input | Catalog `limit.input`; no generic live probe. | None. | Catalog value or `null`; never reconstructed from context and output. |
312
+ | Maximum output | Catalog `limit.output`; no generic live probe. | None. | Minimum of catalog value and effective context, or `null`. |
313
+ | 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. |
314
+ | 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. |
315
+ | Reasoning capability | Catalog `reasoning: true`. | Runtime activation and adapter wire style. | Catalog bit remains informational; it neither activates nor blocks reasoning. |
316
+ | 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. |
317
+
318
+ Models.dev cache-read and cache-write rates default to the input rate, and the
319
+ reasoning rate defaults to the output rate, when omitted. A differently priced
320
+ category requires its corresponding usage detail or the request estimate is
321
+ unknown.
285
322
 
286
323
  `instantiateProvider` resolves in this order:
287
324
 
@@ -356,7 +393,7 @@ also expose:
356
393
  - EOS marker removal;
357
394
  - exact complete-request counting through `/v1/chat/completions/input_tokens`;
358
395
  - exact content token IDs through `/tokenize`;
359
- - the requirement that the caller provide `maxTokens`.
396
+ - the requirement that the adapter apply a finite output budget.
360
397
 
361
398
  `PLURNK_PROVIDERS_LLAMA_SERVER` may force or disable detection. Probe attempts
362
399
  and delay are knobs. A failed probe does not silently assert capabilities.
@@ -372,12 +409,11 @@ every request:
372
409
  | Posture | Template activation | `thinking_budget_tokens` |
373
410
  |---|---:|---:|
374
411
  | `off` | false | `0` |
375
- | `adaptive` | true | resolved reasoning reserve |
376
- | `on` | true | resolved reasoning reserve |
377
- | `on` + budget | true | explicit reasoning budget |
412
+ | `adaptive` | true | configured reasoning subset, otherwise omitted |
413
+ | `on` | true | configured reasoning subset, otherwise omitted |
378
414
 
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
415
+ The allowance is contained by the request's total output budget. Template calls
416
+ normally use `reasoning_format: "auto"` for a separate
381
417
  readable channel. A GBNF-bearing call uses `"none"` so the exact constrained
382
418
  sentence survives response projection; the adapter separates its leading
383
419
  reasoning enclosure only after preserving grammar evidence. Process-wide
@@ -425,6 +461,16 @@ normal value. Retry exhaustion is preserved as `attempts` and
425
461
  `retryExhausted`, and the resulting Problem is not marked retryable after the
426
462
  provider has consumed its automatic retry budget.
427
463
 
464
+ §provider-capacity-failure A proven exact preflight overflow and an upstream
465
+ context rejection normalize to `ProviderError(kind="capacity_exceeded")` and
466
+ an RFC 9457 status 413. `capacityStage` is `preflight` or `upstream`; a
467
+ non-413 upstream status remains `providerStatus`, while physical request
468
+ accounting retains the status actually received. Preflight rejection occurs
469
+ before provider I/O and therefore opens no request identity and creates no
470
+ request-accounting row. Capacity failures are not connectivity failures and are
471
+ never retried by the provider scheduler; bounded packet recovery belongs to the
472
+ consumer.
473
+
428
474
  §provider-connectivity The provider adapter owns one attempt scheduler around
429
475
  the complete generation exchange; SDK-internal retries are disabled.
430
476
  `PLURNK_PROVIDERS_RETRY_ATTEMPTS=N` permits at most `N + 1` physical requests.
@@ -492,7 +538,6 @@ The consumer validates `grammarEvidence.input` outside the enforcer's failure
492
538
  domain. `PLURNK_PROVIDERS_GBNF_DEBUG` still validates grammar syntax before the
493
539
  call and sets `transported: false` for the unconstrained comparison.
494
540
 
495
-
496
541
  ## §11 Evidence and metadata
497
542
 
498
543
  §provider-evidence `assistantRaw` is an opaque normalized transport record.
@@ -523,11 +568,35 @@ correlate them to an entity it actually created rather than reusing `id`.
523
568
 
524
569
  ## §12 Generation envelopes
525
570
 
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}.
571
+ §provider-generation-envelope Every request has at most one total output
572
+ budget. It includes visible output and hidden reasoning. An optional reasoning
573
+ budget is a strict subset of that total, never an additive reserve. The
574
+ configured total is a percentage of effective context or an absolute count;
575
+ percentages resolve to the nearest whole token with a one-token minimum. It is
576
+ capped by known context and model-output limits; `generate.maxOutputTokens` may
577
+ only tighten it for one call. The effective reasoning subset tightens with that
578
+ total and remains strictly smaller.
579
+
580
+ The adapter owns native projection. A backend whose generic SDK maximum already
581
+ includes reasoning receives the total directly. When a native SDK instead adds
582
+ an explicit reasoning allowance to its generic visible-output maximum, the
583
+ adapter sends `total - reasoning` through the generic field and the reasoning
584
+ subset through the documented provider option. Core and other callers never
585
+ reconstruct this arithmetic.
586
+
587
+ §provider-output-budget-conformance When a completed response reports
588
+ normalized output-token usage greater than its effective total output budget,
589
+ the exchange is an `invalid_response` at 502 rather than an admitted result or
590
+ a prompt-capacity 413. Its complete failed-attempt evidence and settled charged
591
+ request remain available. The violation is final and is never automatically
592
+ replayed. Missing output usage cannot prove a violation.
593
+
594
+ `PLURNK_PROVIDERS_OUTPUT_BUDGET` is required for standard providers and ships
595
+ as `35%`. `PLURNK_PROVIDERS_REASONING_BUDGET` is optional; leaving it unset
596
+ preserves provider-adaptive depth. A backend known to decode without a finite
597
+ limit advertises `requiresOutputBudget` and fails construction when no total can
598
+ be resolved. The retired additive reserve knobs fail hard rather than creating
599
+ a second envelope contract.
531
600
 
532
601
  ## §13 Capacity pool
533
602
 
@@ -540,8 +609,13 @@ availability and rate-limit failures that carry no normalized response attempt;
540
609
  {§provider-interrupted-attempt} propagates without overflow.
541
610
 
542
611
  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.
612
+ pool takes the largest quantified result; differing exact counts or any proven
613
+ bound yield an `upper_bound`, any estimate makes the aggregate an estimate, and
614
+ any unavailable backend makes it unavailable. Physical limits and budgets are
615
+ independent safe minima across the pool. `inputCapacity` is the minimum of each
616
+ backend's complete derived input capacity, never a synthetic subtraction across
617
+ minima from different backends; request-specific output tightening repeats the
618
+ complete-envelope derivation per backend before taking the minimum.
545
619
 
546
620
  ## §14 Conformance
547
621
 
@@ -553,7 +627,12 @@ Coverage MUST prove:
553
627
  - compatible extension preservation;
554
628
  - timeout, retry, cancellation, interrupted-attempt, and final-error behavior;
555
629
  - local capability probes and pins;
556
- - exact, bounded, and estimated complete-request token measurements;
630
+ - exact, bounded, estimated, and unavailable complete-request measurements;
631
+ - independent input/context/output limits, asymmetric admission, and normalized
632
+ local/upstream capacity failures;
633
+ - one total output budget and native additive-reasoning projection;
634
+ - provider-reported output beyond that budget failing once with complete
635
+ attempt and accounting evidence;
557
636
  - local reasoning activation, response-wide allowance, and GBNF coexistence;
558
637
  - explicit tagged-reasoning projection across streamed, buffered, capped, and
559
638
  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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"}